diff --git a/autobuild.xml b/autobuild.xml index a10e11693771a334113bf44619746956e5bb835d..2257b22b1aec6ae007aa4f17771b6a0c95d1612a 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -524,11 +524,11 @@ <key>archive</key> <map> <key>hash</key> - <string>b335f8d0b189801f70497dfbae615961d54df73d7dea1294bf2c3b8eff12baff609df1e138b535f8840d1113d9aa1222c0361e8543e39ee26f49c8101e098a82</string> + <string>5690cfb770eac3d42728134b117a84b1430e2b81fd19e0924b098fd746acda119113dfef962108802f1f2e92abf744395d0cbb95f3131af422c2ec56b0050fe6</string> <key>hash_algorithm</key> <string>blake2b</string> <key>url</key> - <string>https://git.alchemyviewer.org/api/v4/projects/103/packages/generic/dullahan/1.12.3_101.0.15_gca159c5_chromium-101.0.4951.54.1523/dullahan-1.12.3_101.0.15_gca159c5_chromium-101.0.4951.54-darwin64-1523.tar.zst</string> + <string>https://git.alchemyviewer.org/api/v4/projects/103/packages/generic/dullahan/1.12.4_107.1.4_geb36a79_chromium-107.0.5304.68.1617/dullahan-1.12.4_107.1.4_geb36a79_chromium-107.0.5304.68-darwin64-1617.tar.zst</string> </map> <key>name</key> <string>darwin64</string> @@ -538,11 +538,11 @@ <key>archive</key> <map> <key>hash</key> - <string>ccda70482a1daa285465ce999acac76d44da2cd54fc848d66a46726a48b4c76ff9b50f18bc1b644f9b380a44d108417f093de5780bfe4692101de3f265451162</string> + <string>31ec77a986a864d1fe70370f27e22a2a1176052bd3f44941cd0b529a57d037d2e101e5f22e5ba14bfd13fe06e30ec00f8b78d8eebafb398fc1f827a097927dba</string> <key>hash_algorithm</key> <string>blake2b</string> <key>url</key> - <string>https://git.alchemyviewer.org/api/v4/projects/103/packages/generic/dullahan/1.12.3_97.1.5_g2b00258_chromium-97.0.4692.71.1523/dullahan-1.12.3_97.1.5_g2b00258_chromium-97.0.4692.71-linux64-1523.tar.zst</string> + <string>https://git.alchemyviewer.org/api/v4/projects/103/packages/generic/dullahan/1.12.4_107.1.4_geb36a79_chromium-107.0.5304.68.1617/dullahan-1.12.4_107.1.4_geb36a79_chromium-107.0.5304.68-linux64-1617.tar.zst</string> </map> <key>name</key> <string>linux64</string> @@ -552,18 +552,18 @@ <key>archive</key> <map> <key>hash</key> - <string>75b13e4f30eae31d5df27c28181e52bca58a9624ce9b6424a4e254270d41d2aecb42ab3b72f53e67a32bd45a9cf7be79d730ba427bf3e1f64da131761b1126b5</string> + <string>6097c0e4bd4f2c771f28bb605ca282d0b6ab878b7f05b237c37691435def9ca25c186b8706a54180aa09935c5e36a8cc088c04925afaa84606919725dadaf7a9</string> <key>hash_algorithm</key> <string>blake2b</string> <key>url</key> - <string>https://git.alchemyviewer.org/api/v4/projects/103/packages/generic/dullahan/1.12.3_101.0.15_gca159c5_chromium-101.0.4951.54.1523/dullahan-1.12.3_101.0.15_gca159c5_chromium-101.0.4951.54-windows64-1523.tar.zst</string> + <string>https://git.alchemyviewer.org/api/v4/projects/103/packages/generic/dullahan/1.12.4_107.1.7_g59a795c_chromium-107.0.5304.88.1617/dullahan-1.12.4_107.1.7_g59a795c_chromium-107.0.5304.88-windows64-1617.tar.zst</string> </map> <key>name</key> <string>windows64</string> </map> </map> <key>version</key> - <string>1.12.3_101.0.15_gca159c5_chromium-101.0.4951.54</string> + <string>1.12.4_107.1.4_geb36a79_chromium-107.0.5304.68</string> </map> <key>expat</key> <map> @@ -1936,11 +1936,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string> <key>archive</key> <map> <key>hash</key> - <string>ee960277ce5a3982aa04abbae482ce0b949a4a6d22a719f4d78fda77599cdca001b9cbaf28f00d013b4cd16eff76310cf1c7829b4e6bd5a16b4906daccdbbc88</string> - <key>hash_algorithm</key> - <string>blake2b</string> + <string>b583668b28fde0490e6953f10e93e4ab</string> <key>url</key> - <string>https://git.alchemyviewer.org/api/v4/projects/168/packages/generic/slvoice/4.10.0000.32327.5fc3fe7c.558436.1202/slvoice-4.10.0000.32327.5fc3fe7c.558436-darwin64-1202.tar.zst</string> + <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/98681/871545/slvoice-4.10.0000.32327.5fc3fe7c.571099-darwin64-571099.tar.bz2</string> </map> <key>name</key> <string>darwin64</string> @@ -1959,23 +1957,33 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string> <key>name</key> <string>linux64</string> </map> + <key>windows</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>6e0ed41653955afe8eeb8945776cf07b</string> + <key>url</key> + <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/98683/871560/slvoice-4.10.0000.32327.5fc3fe7c.571099-windows-571099.tar.bz2</string> + </map> + <key>name</key> + <string>windows</string> + </map> <key>windows64</key> <map> <key>archive</key> <map> <key>hash</key> - <string>b756951b908b487fb616c6e420d3bfb8d8729613572263ef57fcc17c6d865c1177750b5a3e11f12757004dbb3fd76a4b2082e93bc05b740af394250d5cd050ac</string> - <key>hash_algorithm</key> - <string>blake2b</string> + <string>c39735851fd05c194d0be09b8f9e8cb7</string> <key>url</key> - <string>https://git.alchemyviewer.org/api/v4/projects/168/packages/generic/slvoice/4.10.0000.32327.5fc3fe7c.558436.1202/slvoice-4.10.0000.32327.5fc3fe7c.558436-windows64-1202.tar.zst</string> + <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/98682/871552/slvoice-4.10.0000.32327.5fc3fe7c.571099-windows64-571099.tar.bz2</string> </map> <key>name</key> <string>windows64</string> </map> </map> <key>version</key> - <string>4.10.0000.32327.5fc3fe7c.558436</string> + <string>4.10.0000.32327.5fc3fe7c.571099</string> </map> <key>threejs</key> <map> @@ -2007,6 +2015,70 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string> <key>version</key> <string>0.135.0</string> </map> + <key>tracy</key> + <map> + <key>canonical_repo</key> + <string>https://bitbucket.org/lindenlab/3p-tracy</string> + <key>copyright</key> + <string>Copyright (c) 2017-2021, Bartosz Taudul (wolf@nereid.pl)</string> + <key>description</key> + <string>Tracy Profiler Library</string> + <key>license</key> + <string>bsd</string> + <key>license_file</key> + <string>LICENSES/tracy_license.txt</string> + <key>name</key> + <string>tracy</string> + <key>platforms</key> + <map> + <key>darwin64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>da7317e4a81609f624f84780f28b07de</string> + <key>url</key> + <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/86972/801630/tracy-v0.7.8.563351-darwin64-563351.tar.bz2</string> + </map> + <key>name</key> + <string>darwin64</string> + </map> + <key>windows</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>47c696cd2966c5cc3c8ba6115dd1f886</string> + <key>hash_algorithm</key> + <string>md5</string> + <key>url</key> + <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/86973/801641/tracy-v0.7.8.563351-windows-563351.tar.bz2</string> + </map> + <key>name</key> + <string>windows</string> + </map> + <key>windows64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>b649ee6591e67d2341e886b3fc3484a7</string> + <key>hash_algorithm</key> + <string>md5</string> + <key>url</key> + <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/86974/801642/tracy-v0.7.8.563351-windows64-563351.tar.bz2</string> + </map> + <key>name</key> + <string>windows64</string> + </map> + </map> + <key>source</key> + <string>https://bitbucket.org/lindenlab/3p-tracy</string> + <key>source_type</key> + <string>git</string> + <key>version</key> + <string>v0.7.8.563351</string> + </map> <key>tut</key> <map> <key>copyright</key> diff --git a/doc/contributions.txt b/doc/contributions.txt index 2a77dad1fc408d949fcb64a54fd11a0d6c66ead5..9368781c9a6cc27e81d9a2a3b4830da743a261eb 100755 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -236,6 +236,7 @@ Ansariel Hiller SL-15226 SL-15227 SL-15398 + SL-18432 Aralara Rajal Arare Chantilly CHUIBUG-191 @@ -279,6 +280,7 @@ Beq Janus SL-14766 SL-14927 SL-11300 + SL-15709 SL-16021 Beth Walcher Bezilon Kasei @@ -400,6 +402,7 @@ Cinder Roxley STORM-2127 STORM-2144 SL-3404 + SL-17634 Clara Young Coaldust Numbers VWR-1095 @@ -1109,16 +1112,19 @@ Nicky Dasmijn STORM-1937 OPEN-187 SL-15234 - STORM-2010 + STORM-2010 STORM-2082 MAINT-6665 SL-10291 SL-10293 SL-11061 - SL-11072 + SL-11072 SL-13141 SL-13642 + SL-14541 SL-16438 + SL-17218 + SL-17585 Nicky Perian OPEN-1 STORM-1087 @@ -1372,7 +1378,7 @@ Sovereign Engineer MAINT-7343 SL-11079 OPEN-343 - SL-11625 + SL-11625 BUG-229030 SL-14705 SL-14706 @@ -1380,6 +1386,7 @@ Sovereign Engineer SL-14731 SL-14732 SL-15096 + SL-16127 SpacedOut Frye VWR-34 VWR-45 diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt index 68047c77d7a976da037cd99c91f59459409d8714..e1ce8d7212611b96f86284ecca498369438e1bc4 100644 --- a/indra/CMakeLists.txt +++ b/indra/CMakeLists.txt @@ -42,6 +42,7 @@ add_subdirectory(${LIBS_OPEN_PREFIX}llkdu) add_subdirectory(${LIBS_OPEN_PREFIX}llimagej2coj) add_subdirectory(${LIBS_OPEN_PREFIX}llinventory) add_subdirectory(${LIBS_OPEN_PREFIX}llmath) +add_subdirectory(${LIBS_OPEN_PREFIX}llmeshoptimizer) add_subdirectory(${LIBS_OPEN_PREFIX}llmessage) add_subdirectory(${LIBS_OPEN_PREFIX}llprimitive) add_subdirectory(${LIBS_OPEN_PREFIX}llrender) diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake index 339e1adfbd6d72c7755a77419c1b9be8560db919..aa0cd8d255bd0badd9bef5d908cb287ba11fb335 100644 --- a/indra/cmake/00-Common.cmake +++ b/indra/cmake/00-Common.cmake @@ -191,6 +191,7 @@ if (WINDOWS) /D_WINSOCK_DEPRECATED_NO_WARNINGS /DBOOST_CONFIG_SUPPRESS_OUTDATED_MESSAGE /DBOOST_ALLOW_DEPRECATED_HEADERS + /D_SILENCE_CXX20_CISO646_REMOVED_WARNING ) # library linkage defines diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt index b561b437e21d40ad7f76e2dde7f41710ac4085d7..e8eec04e0fefd52755e16da0cc757828f3ca1ee7 100644 --- a/indra/cmake/CMakeLists.txt +++ b/indra/cmake/CMakeLists.txt @@ -30,6 +30,7 @@ set(cmake_SOURCE_FILES FindOpenJPEG.cmake FindURIPARSER.cmake FindXmlRpcEpi.cmake + FindZLIBNG.cmake FMODSTUDIO.cmake FreeType.cmake GLEXT.cmake @@ -48,6 +49,7 @@ set(cmake_SOURCE_FILES LLKDU.cmake LLLogin.cmake LLMath.cmake + LLMeshOptimizer.cmake LLMessage.cmake LLPhysicsExtensions.cmake LLPlugin.cmake @@ -61,6 +63,7 @@ set(cmake_SOURCE_FILES LLXML.cmake Linking.cmake MediaPluginBase.cmake + MESHOPTIMIZER.cmake NDOF.cmake OPENAL.cmake OpenGL.cmake @@ -84,7 +87,7 @@ set(cmake_SOURCE_FILES VisualLeakDetector.cmake LibVLCPlugin.cmake XmlRpcEpi.cmake - ZLIB.cmake + ZLIBNG.cmake ) source_group("Shared Rules" FILES ${cmake_SOURCE_FILES}) diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index 2ce9ee73d40dffbd7b1d68d62a67a1982a312f3d..1877c4dae466e04ab9b07dc7fb63ce695f640c47 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -125,6 +125,72 @@ if(WINDOWS) list(APPEND debug_files kdud.dll) list(APPEND release_files kdu.dll) endif (USE_KDU) + + #******************************* + # Copy MS C runtime dlls, required for packaging. + if (MSVC80) + set(MSVC_VER 80) + elseif (MSVC_VERSION EQUAL 1600) # VisualStudio 2010 + MESSAGE(STATUS "MSVC_VERSION ${MSVC_VERSION}") + elseif (MSVC_VERSION EQUAL 1800) # VisualStudio 2013, which is (sigh) VS 12 + set(MSVC_VER 120) + elseif (MSVC_VERSION GREATER_EQUAL 1910 AND MSVC_VERSION LESS 1940) # Visual Studio 2017 through 2022 + 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 2019 + set(MSVC_VER 140) + else (MSVC80) + MESSAGE(WARNING "New MSVC_VERSION ${MSVC_VERSION} of MSVC: adapt Copy3rdPartyLibs.cmake") + endif (MSVC80) + + if(ADDRESS_SIZE EQUAL 32) + # this folder contains the 32bit DLLs.. (yes really!) + set(registry_find_path "[HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Windows;Directory]/SysWOW64") + else(ADDRESS_SIZE EQUAL 32) + # this folder contains the 64bit DLLs.. (yes really!) + set(registry_find_path "[HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Windows;Directory]/System32") + endif(ADDRESS_SIZE EQUAL 32) + + # Having a string containing the system registry path is a start, but to + # get CMake to actually read the registry, we must engage some other + # operation. + get_filename_component(registry_path "${registry_find_path}" ABSOLUTE) + + # These are candidate DLL names. Empirically, VS versions before 2015 have + # msvcp*.dll and msvcr*.dll. VS 2017 has msvcp*.dll and vcruntime*.dll. + # Check each of them. + foreach(release_msvc_file + concrt${MSVC_VER}.dll + msvcp${MSVC_VER}.dll + msvcp${MSVC_VER}_1.dll + msvcp${MSVC_VER}_2.dll + msvcp${MSVC_VER}_atomic_wait.dll + msvcp${MSVC_VER}_codecvt_ids.dll + vccorlib${MSVC_VER}.dll + vcruntime${MSVC_VER}.dll + vcruntime${MSVC_VER}_1.dll + ) + if(EXISTS "${registry_path}/${release_msvc_file}") + to_relwithdeb_staging_dirs( + ${registry_path} + third_party_targets + ${release_msvc_file}) + to_release_staging_dirs( + ${registry_path} + third_party_targets + ${release_msvc_file}) + else() + # This isn't a WARNING because, as noted above, every VS version + # we've observed has only a subset of the specified DLL names. + MESSAGE(STATUS "Redist lib ${release_msvc_file} not found") + endif() + endforeach() + MESSAGE(STATUS "Will copy redist files for MSVC ${MSVC_VER}:") + foreach(target ${third_party_targets}) + MESSAGE(STATUS "${target}") + 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") diff --git a/indra/cmake/FindZLIBNG.cmake b/indra/cmake/FindZLIBNG.cmake new file mode 100644 index 0000000000000000000000000000000000000000..6e3c8cdddbfe283f10da559e345655f8dafe055e --- /dev/null +++ b/indra/cmake/FindZLIBNG.cmake @@ -0,0 +1,46 @@ +# -*- 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/LLCommon.cmake b/indra/cmake/LLCommon.cmake index e13bd41f6c9323b909c4781a6fdd525dfb8a5e91..798111560966b54bd35ecc92552433254f3686b2 100644 --- a/indra/cmake/LLCommon.cmake +++ b/indra/cmake/LLCommon.cmake @@ -3,12 +3,14 @@ include(APR) include(Boost) include(EXPAT) -include(ZLIB) +include(Tracy) +include(ZLIBNG) set(LLCOMMON_INCLUDE_DIRS ${LIBS_OPEN_DIR}/llcommon ${APRUTIL_INCLUDE_DIR} ${APR_INCLUDE_DIR} + ${TRACY_INCLUDE_DIR} ${Boost_INCLUDE_DIRS} ) set(LLCOMMON_SYSTEM_INCLUDE_DIRS @@ -32,7 +34,8 @@ else (LINUX) ${BOOST_CONTEXT_LIBRARY} ${BOOST_THREAD_LIBRARY} ${BOOST_STACKTRACE_LIBRARY} - ${BOOST_SYSTEM_LIBRARY} ) + ${BOOST_SYSTEM_LIBRARY} + ) endif (LINUX) set(LLCOMMON_LINK_SHARED OFF CACHE BOOL "Build the llcommon target as a static library.") diff --git a/indra/cmake/LLMeshOptimizer.cmake b/indra/cmake/LLMeshOptimizer.cmake new file mode 100644 index 0000000000000000000000000000000000000000..b79944f61875a2cffef4f51e06a531fc5d4479c2 --- /dev/null +++ b/indra/cmake/LLMeshOptimizer.cmake @@ -0,0 +1,7 @@ +# -*- cmake -*- + +set(LLMESHOPTIMIZER_INCLUDE_DIRS + ${LIBS_OPEN_DIR}/llmeshoptimizer + ) + +set(LLMESHOPTIMIZER_LIBRARIES llmeshoptimizer) diff --git a/indra/cmake/LLPrimitive.cmake b/indra/cmake/LLPrimitive.cmake index 8813be3bd103a5359a94857dd65a7d72d0725835..654cc0419ba05a8b2752ab6b17346c5af8bf5498 100644 --- a/indra/cmake/LLPrimitive.cmake +++ b/indra/cmake/LLPrimitive.cmake @@ -6,10 +6,10 @@ include(Prebuilt) include(Boost) include(LibXML2) include(URIPARSER) -include(ZLIB) +include(ZLIBNG) use_prebuilt_binary(colladadom) -use_prebuilt_binary(minizip-ng) +use_prebuilt_binary(minizip-ng) # needed for colladadom set(LLPRIMITIVE_INCLUDE_DIRS ${LIBS_OPEN_DIR}/llprimitive @@ -25,7 +25,7 @@ if (WINDOWS) ${LIBXML2_LIBRARIES} ${URIPARSER_LIBRARIES} ${MINIZIP_LIBRARIES} - ${ZLIB_LIBRARIES} + ${ZLIBNG_LIBRARIES} ) elseif (DARWIN) set(LLPRIMITIVE_LIBRARIES @@ -37,7 +37,7 @@ elseif (DARWIN) ${LIBXML2_LIBRARIES} ${URIPARSER_LIBRARIES} ${MINIZIP_LIBRARIES} - ${ZLIB_LIBRARIES} + ${ZLIBNG_LIBRARIES} ) elseif (LINUX) set(LLPRIMITIVE_LIBRARIES @@ -49,7 +49,7 @@ elseif (LINUX) ${LIBXML2_LIBRARIES} ${URIPARSER_LIBRARIES} ${MINIZIP_LIBRARIES} - ${ZLIB_LIBRARIES} + ${ZLIBNG_LIBRARIES} ) endif (WINDOWS) diff --git a/indra/cmake/MESHOPTIMIZER.cmake b/indra/cmake/MESHOPTIMIZER.cmake new file mode 100644 index 0000000000000000000000000000000000000000..c69f8a872be493a3eff60a7df059b3b8bb0fc0c2 --- /dev/null +++ b/indra/cmake/MESHOPTIMIZER.cmake @@ -0,0 +1,16 @@ +# -*- 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/Sentry.cmake b/indra/cmake/Sentry.cmake index 8df371de2a83eefa73f353bce9f13ef712718abe..4cf0fce0bf31a56118e44c38534a7cc1dd36f440 100644 --- a/indra/cmake/Sentry.cmake +++ b/indra/cmake/Sentry.cmake @@ -13,14 +13,14 @@ if (USE_SENTRY) include(CURL) include(NGHTTP2) include(OpenSSL) - include(ZLIB) + include(ZLIBNG) set(SENTRY_LIBRARIES ${ARCH_PREBUILT_DIRS_RELEASE}/libsentry.a ${ARCH_PREBUILT_DIRS_RELEASE}/libbreakpad_client.a ${CURL_LIBRARIES} ${NGHTTP2_LIBRARIES} ${OPENSSL_LIBRARIES} - ${ZLIB_LIBRARIES}) + ${ZLIBNG_LIBRARIES}) endif () else () find_package(Sentry REQUIRED) diff --git a/indra/cmake/Tracy.cmake b/indra/cmake/Tracy.cmake new file mode 100644 index 0000000000000000000000000000000000000000..cfff956bcf82f8c64a554c570471fc7905e62506 --- /dev/null +++ b/indra/cmake/Tracy.cmake @@ -0,0 +1,29 @@ +# -*- cmake -*- +include(Prebuilt) + +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_prebuilt_binary(tracy) + + if (WINDOWS) + MESSAGE(STATUS "Including Tracy for Windows: '${TRACY_INCLUDE_DIR}'") + endif (WINDOWS) + + 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 "") +endif (USE_TRACY) + diff --git a/indra/cmake/ZLIB.cmake b/indra/cmake/ZLIBNG.cmake similarity index 81% rename from indra/cmake/ZLIB.cmake rename to indra/cmake/ZLIBNG.cmake index a0f5914a7b4125152c0cd2d11471e51facca4427..770017f0d1bfb3c0781c2cacbe4b44e1f4a0529e 100644 --- a/indra/cmake/ZLIB.cmake +++ b/indra/cmake/ZLIBNG.cmake @@ -1,13 +1,13 @@ # -*- cmake -*- -set(ZLIB_FIND_QUIETLY ON) -set(ZLIB_FIND_REQUIRED ON) +set(ZLIBNG_FIND_QUIETLY ON) +set(ZLIBNG_FIND_REQUIRED ON) include(Prebuilt) include(Linking) if (USESYSTEMLIBS) - include(FindZLIB) + include(FindZLIBNG) else (USESYSTEMLIBS) use_prebuilt_binary(zlib-ng) use_prebuilt_binary(minizip-ng) @@ -16,7 +16,7 @@ else (USESYSTEMLIBS) debug ${ARCH_PREBUILT_DIRS_DEBUG}/libminizip.lib optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libminizip.lib) - set(ZLIB_LIBRARIES + set(ZLIBNG_LIBRARIES debug ${ARCH_PREBUILT_DIRS_DEBUG}/zlibd.lib optimized ${ARCH_PREBUILT_DIRS_RELEASE}/zlib.lib) elseif (LINUX) @@ -33,11 +33,11 @@ else (USESYSTEMLIBS) # second whole-archive load of the archive. See viewer's # CMakeLists.txt for more information. # - set(ZLIB_PRELOAD_ARCHIVES -Wl,--whole-archive z -Wl,--no-whole-archive) - set(ZLIB_LIBRARIES z) + set(ZLIBNG_PRELOAD_ARCHIVES -Wl,--whole-archive z -Wl,--no-whole-archive) + set(ZLIBNG_LIBRARIES z) elseif (DARWIN) set(MINIZIP_LIBRARIES minizip) - set(ZLIB_LIBRARIES -Wl,-force_load,${ARCH_PREBUILT_DIRS_RELEASE}/libz.a) + set(ZLIBNG_LIBRARIES -Wl,-force_load,${ARCH_PREBUILT_DIRS_RELEASE}/libz.a) endif (WINDOWS) - set(ZLIB_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/zlib) + set(ZLIBNG_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/zlib-ng) endif (USESYSTEMLIBS) diff --git a/indra/doxygen/CMakeLists.txt b/indra/doxygen/CMakeLists.txt index 37d1018b04e3a59f1e891a052602e91022ba05a9..6c4033276640025ecaa253d1ddf3ec1e503f95fb 100644 --- a/indra/doxygen/CMakeLists.txt +++ b/indra/doxygen/CMakeLists.txt @@ -1,4 +1,7 @@ # -*- cmake -*- + +cmake_minimum_required(VERSION 3.8.0 FATAL_ERROR) + project(doxygen) include(Variables) diff --git a/indra/edit-me-to-trigger-new-build.txt b/indra/edit-me-to-trigger-new-build.txt index 44913b1391854b36261074070ebb2e4e743d6255..eab7c17b71d5a7bf2c6444aa88a346d5e0c74d0d 100644 --- a/indra/edit-me-to-trigger-new-build.txt +++ b/indra/edit-me-to-trigger-new-build.txt @@ -1 +1,4 @@ -ryebarks +euclid 5/29/2020 +euclid 7/23/2020 +euclid 4/29/2021 +euclid 10/5/2021 DRTVWR-546 diff --git a/indra/lib/python/indra/util/llmanifest.py b/indra/lib/python/indra/util/llmanifest.py index 363bb7f2afc82725fc0ef114fdc57d8e5f8acd27..a2df5a44edb4b025137bbb56d514dc4e19a8424f 100755 --- a/indra/lib/python/indra/util/llmanifest.py +++ b/indra/lib/python/indra/util/llmanifest.py @@ -883,33 +883,47 @@ def try_path(src): return count def path_optional(self, src, dst=None): - """ - For a number of our self.path() calls, not only do we want - to deal with the absence of src, we also want to remember - which were present. Return either an empty list (absent) - or a list containing dst (present). Concatenate these - return values to get a list of all libs that are present. - """ - if dst is None: + sys.stdout.flush() + if src == None: + raise ManifestError("No source file, dst is " + dst) + if dst == None: dst = src + dst = os.path.join(self.get_dst_prefix(), dst) + sys.stdout.write("Processing %s => %s ... " % (src, self._relative_dst_path(dst))) - # This was simple before we started needing to pass - # wildcards. Fortunately, self.path() ends up appending a - # (source, dest) pair to self.file_list for every expanded - # file processed. Remember its size before the call. - oldlen = len(self.file_list) - try: - self.path(src, dst, False) - # The dest appended to self.file_list has been prepended - # with self.get_dst_prefix(). Strip it off again. - added = [os.path.relpath(d, self.get_dst_prefix()) - for s, d in self.file_list[oldlen:]] - except (ManifestError, MissingError) as err: - print("Warning: %s" % err.msg, file=sys.stderr) - added = [] - if not added: - print("Skipping %s" % dst) - return added + def try_path(src): + # expand globs + count = 0 + if self.wildcard_pattern.search(src): + for s,d in self.expand_globs(src, dst): + assert(s != d) + count += self.process_file(s, d) + else: + # if we're specifying a single path (not a glob), + # we should error out if it doesn't exist + self.check_file_exists(src) + count += self.process_either(src, dst) + return count + + try_prefixes = [self.get_src_prefix(), self.get_artwork_prefix(), self.get_build_prefix()] + for pfx in try_prefixes: + try: + count = try_path(os.path.join(pfx, src)) + except MissingError: + # if we produce MissingError, just try the next prefix + continue + # If we actually found nonzero files, stop looking + if count: + break + else: + sys.stdout.write("Skipping %s\n" % (src)) + return 0 + + print("%d files" % count) + + # Let caller check whether we processed as many files as expected. In + # particular, let caller notice 0. + return count def do(self, *actions): self.actions = actions diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp index 44609eb26675adb6d02f433a12c56b8d2e3de59a..be0a875848903cee851e3e2dac7a57f5f1b69dd7 100644 --- a/indra/llappearance/llavatarappearance.cpp +++ b/indra/llappearance/llavatarappearance.cpp @@ -924,6 +924,9 @@ BOOL LLAvatarAppearance::loadAvatar() return FALSE; } + // initialize mJointAliasMap + getJointAliases(); + // avatar_lad.xml : <skeleton> if( !loadSkeletonNode() ) { @@ -1044,7 +1047,6 @@ BOOL LLAvatarAppearance::loadAvatar() return FALSE; } } - return TRUE; } @@ -1583,7 +1585,7 @@ BOOL LLAvatarAppearance::allocateCollisionVolumes( U32 num ) delete_and_clear_array(mCollisionVolumes); mNumCollisionVolumes = 0; - mCollisionVolumes = new(std::nothrow) LLAvatarJointCollisionVolume[num]; + mCollisionVolumes = new LLAvatarJointCollisionVolume[num]; if (!mCollisionVolumes) { LL_WARNS() << "Failed to allocate collision volumes" << LL_ENDL; diff --git a/indra/llappearance/lldriverparam.h b/indra/llappearance/lldriverparam.h index 0e835da41576b657c5768b5b6ea2f9f00b939154..2305e45756b86536248deac0b62bab7e0b112cb7 100644 --- a/indra/llappearance/lldriverparam.h +++ b/indra/llappearance/lldriverparam.h @@ -77,39 +77,29 @@ class LLDriverParamInfo final : public LLViewerVisualParamInfo //----------------------------------------------------------------------------- -LL_ALIGN_PREFIX(16) -class LLDriverParam final : public LLViewerVisualParam +class alignas(16) LLDriverParam final : public LLViewerVisualParam { + LL_ALIGN_NEW public: // Delete the default constructor. Force construction with LLAvatarAppearance. LLDriverParam() = delete; - LLDriverParam(LLAvatarAppearance *appearance, LLWearable* wearable = NULL); + LLDriverParam(LLAvatarAppearance* appearance, LLWearable* wearable = NULL); ~LLDriverParam() = default; - void* operator new(size_t size) - { - return ll_aligned_malloc_16(size); - } + // Special: These functions are overridden by child classes + LLDriverParamInfo* getInfo() const { return (LLDriverParamInfo*)mInfo; } + // This sets mInfo and calls initialization functions + BOOL setInfo(LLDriverParamInfo* info); - void operator delete(void* ptr) - { - ll_aligned_free_16(ptr); - } + LLAvatarAppearance* getAvatarAppearance() { return mAvatarAppearance; } + const LLAvatarAppearance* getAvatarAppearance() const { return mAvatarAppearance; } - // Special: These functions are overridden by child classes - LLDriverParamInfo* getInfo() const { return (LLDriverParamInfo*)mInfo; } - // This sets mInfo and calls initialization functions - BOOL setInfo(LLDriverParamInfo *info); - - LLAvatarAppearance* getAvatarAppearance() { return mAvatarAppearance; } - const LLAvatarAppearance* getAvatarAppearance() const { return mAvatarAppearance; } - - void updateCrossDrivenParams(LLWearableType::EType driven_type); + void updateCrossDrivenParams(LLWearableType::EType driven_type); /*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const override; - // LLVisualParam Virtual functions + // LLVisualParam Virtual functions /*virtual*/ void apply( ESex sex ) override {} // apply is called separately for each driven param. /*virtual*/ void setWeight(F32 weight, bool upload_bake) override; /*virtual*/ void setAnimationTarget( F32 target_value, bool upload_bake) override; @@ -118,7 +108,7 @@ class LLDriverParam final : public LLViewerVisualParam /*virtual*/ void resetDrivenParams() override; /*virtual*/ bool isDriverParam() override { return true; } - // LLViewerVisualParam Virtual functions + // LLViewerVisualParam Virtual functions /*virtual*/ F32 getTotalDistortion() override; /*virtual*/ const LLVector4a& getAvgDistortion() override; /*virtual*/ F32 getMaxDistortion() override; @@ -126,25 +116,25 @@ class LLDriverParam final : public LLViewerVisualParam /*virtual*/ const LLVector4a* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh) override; /*virtual*/ const LLVector4a* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh) override; - S32 getDrivenParamsCount() const; - const LLViewerVisualParam* getDrivenParam(S32 index) const; + S32 getDrivenParamsCount() const; + const LLViewerVisualParam* getDrivenParam(S32 index) const; - typedef std::vector<LLDrivenEntry> entry_list_t; - entry_list_t& getDrivenList() { return mDriven; } + typedef std::vector<LLDrivenEntry> entry_list_t; + entry_list_t& getDrivenList() { return mDriven; } void setDrivenList(entry_list_t driven_list) { mDriven = std::move(driven_list); } protected: - LLDriverParam(const LLDriverParam& pOther); - F32 getDrivenWeight(const LLDrivenEntry* driven, F32 input_weight); + LLDriverParam(const LLDriverParam& pOther); + F32 getDrivenWeight(const LLDrivenEntry* driven, F32 input_weight); void setDrivenWeight(LLDrivenEntry *driven, F32 driven_weight, bool upload_bake); - LL_ALIGN_16(LLVector4a mDefaultVec); // temp holder - entry_list_t mDriven; - LLViewerVisualParam* mCurrentDistortionParam; - // Backlink only; don't make this an LLPointer. - LLAvatarAppearance* mAvatarAppearance; - LLWearable* mWearablep; -} LL_ALIGN_POSTFIX(16); + LL_ALIGN_16(LLVector4a mDefaultVec); // temp holder + entry_list_t mDriven; + LLViewerVisualParam* mCurrentDistortionParam; + // Backlink only; don't make this an LLPointer. + LLAvatarAppearance* mAvatarAppearance; + LLWearable* mWearablep; +}; #endif // LL_LLDRIVERPARAM_H diff --git a/indra/llappearance/llpolymesh.cpp b/indra/llappearance/llpolymesh.cpp index 88df607599ae942100b10a171ac54e08b9ef6b31..48e18176b505e0e418b614911330c6ec263bc6ef 100644 --- a/indra/llappearance/llpolymesh.cpp +++ b/indra/llappearance/llpolymesh.cpp @@ -616,14 +616,16 @@ BOOL LLPolyMeshSharedData::loadMesh( const std::string& fileName ) // we reached the end of the morphs break; } - LLPolyMorphData* morph_data = new LLPolyMorphData(std::string(morphName)); + std::string morph_name(morphName); + LLPolyMorphData* morph_data = new LLPolyMorphData(morph_name); BOOL result = morph_data->loadBinary(fp, this); if (!result) { - delete morph_data; - continue; + LL_WARNS() << "Failure loading " << morph_name << " from " << fileName << LL_ENDL; + delete morph_data; + continue; } mMorphData.insert(morph_data); diff --git a/indra/llappearance/llpolymorph.cpp b/indra/llappearance/llpolymorph.cpp index 45c0c860cc279aaf7ddff55404f6893a0182fd6d..651d0001d6f200e255bddd6ffaf9c917db5807e7 100644 --- a/indra/llappearance/llpolymorph.cpp +++ b/indra/llappearance/llpolymorph.cpp @@ -156,7 +156,9 @@ BOOL LLPolyMorphData::loadBinary(LLFILE *fp, LLPolyMeshSharedData *mesh) if (mVertexIndices[v] > 10000) { - LL_ERRS() << "Bad morph index: " << mVertexIndices[v] << LL_ENDL; + // Bad install? These are usually .llm files from 'character' fodler + LL_WARNS() << "Bad morph index " << v << ": " << mVertexIndices[v] << LL_ENDL; + return FALSE; } @@ -540,8 +542,6 @@ F32 LLPolyMorphTarget::getMaxDistortion() //----------------------------------------------------------------------------- // apply() //----------------------------------------------------------------------------- -static LLTrace::BlockTimerStatHandle FTM_APPLY_MORPH_TARGET("Apply Morph"); - void LLPolyMorphTarget::apply( ESex avatar_sex ) { if (!mMorphData || mNumMorphMasksPending > 0) @@ -549,7 +549,7 @@ void LLPolyMorphTarget::apply( ESex avatar_sex ) return; } - LL_RECORD_BLOCK_TIME(FTM_APPLY_MORPH_TARGET); + LL_PROFILE_ZONE_SCOPED; mLastSex = avatar_sex; diff --git a/indra/llappearance/llpolymorph.h b/indra/llappearance/llpolymorph.h index c1f4bde449a025cabcd57df2274454ee13e6c285..800b8baac35019d09170dc9bba4a457348987c1c 100644 --- a/indra/llappearance/llpolymorph.h +++ b/indra/llappearance/llpolymorph.h @@ -41,24 +41,14 @@ class LLWearable; //----------------------------------------------------------------------------- // LLPolyMorphData() //----------------------------------------------------------------------------- -LL_ALIGN_PREFIX(16) -class LLPolyMorphData +class alignas(16) LLPolyMorphData { + LL_ALIGN_NEW public: LLPolyMorphData(const std::string& morph_name); ~LLPolyMorphData(); LLPolyMorphData(const LLPolyMorphData &rhs); - void* operator new(size_t size) - { - return ll_aligned_malloc_16(size); - } - - void operator delete(void* ptr) - { - ll_aligned_free_16(ptr); - } - BOOL loadBinary(LLFILE* fp, LLPolyMeshSharedData *mesh); const std::string& getName() { return mName; } @@ -76,7 +66,7 @@ class LLPolyMorphData F32 mTotalDistortion; // vertex distortion summed over entire morph F32 mMaxDistortion; // maximum single vertex distortion in a given morph - LL_ALIGN_16(LLVector4a mAvgDistortion); // average vertex distortion, to infer directionality of the morph + LLVector4a mAvgDistortion; // average vertex distortion, to infer directionality of the morph LLPolyMeshSharedData* mMesh; private: @@ -154,8 +144,9 @@ class LLPolyMorphTargetInfo : public LLViewerVisualParamInfo // These morph targets must be topologically consistent with a given Polymesh // (share face sets) //----------------------------------------------------------------------------- -class LLPolyMorphTarget : public LLViewerVisualParam +class alignas(16) LLPolyMorphTarget : public LLViewerVisualParam { + LL_ALIGN_NEW public: LLPolyMorphTarget(LLPolyMesh *poly_mesh); ~LLPolyMorphTarget(); @@ -184,16 +175,6 @@ class LLPolyMorphTarget : public LLViewerVisualParam void applyVolumeChanges(F32 delta_weight); // SL-315 - for resetSkeleton() - void* operator new(size_t size) - { - return ll_aligned_malloc_16(size); - } - - void operator delete(void* ptr) - { - ll_aligned_free_16(ptr); - } - protected: LLPolyMorphTarget(const LLPolyMorphTarget& pOther); diff --git a/indra/llappearance/llpolyskeletaldistortion.cpp b/indra/llappearance/llpolyskeletaldistortion.cpp index 1a6242f023b7a1893657f3b0d6ae1ac82c560e52..41f8262383a8f894553d68b8e032ef307bd5df40 100644 --- a/indra/llappearance/llpolyskeletaldistortion.cpp +++ b/indra/llappearance/llpolyskeletaldistortion.cpp @@ -168,11 +168,9 @@ BOOL LLPolySkeletalDistortion::setInfo(LLPolySkeletalDistortionInfo *info) //----------------------------------------------------------------------------- // apply() //----------------------------------------------------------------------------- -static LLTrace::BlockTimerStatHandle FTM_POLYSKELETAL_DISTORTION_APPLY("Skeletal Distortion"); - void LLPolySkeletalDistortion::apply( ESex avatar_sex ) { - LL_RECORD_BLOCK_TIME(FTM_POLYSKELETAL_DISTORTION_APPLY); + LL_PROFILE_ZONE_SCOPED; F32 effective_weight = ( getSex() & avatar_sex ) ? mCurWeight : getDefaultWeight(); diff --git a/indra/llappearance/llpolyskeletaldistortion.h b/indra/llappearance/llpolyskeletaldistortion.h index 34ece7d5d020c770831ab9791b81d6ed413d3d51..c9228c4ee5f7914b6b45b678c7c941e422f2e3a1 100644 --- a/indra/llappearance/llpolyskeletaldistortion.h +++ b/indra/llappearance/llpolyskeletaldistortion.h @@ -62,9 +62,9 @@ struct LLPolySkeletalBoneInfo BOOL mHasPositionDeformation; }; -LL_ALIGN_PREFIX(16) -class LLPolySkeletalDistortionInfo : public LLViewerVisualParamInfo +class alignas(16) LLPolySkeletalDistortionInfo : public LLViewerVisualParamInfo { + LL_ALIGN_NEW friend class LLPolySkeletalDistortion; public: @@ -72,18 +72,6 @@ class LLPolySkeletalDistortionInfo : public LLViewerVisualParamInfo /*virtual*/ ~LLPolySkeletalDistortionInfo() = default; /*virtual*/ BOOL parseXml(LLXmlTreeNode* node) override; - - void* operator new(size_t size) - { - return ll_aligned_malloc_16(size); - } - - void operator delete(void* ptr) - { - ll_aligned_free_16(ptr); - } - - protected: typedef std::vector<LLPolySkeletalBoneInfo> bone_info_list_t; bone_info_list_t mBoneInfoList; @@ -93,19 +81,10 @@ class LLPolySkeletalDistortionInfo : public LLViewerVisualParamInfo // LLPolySkeletalDeformation // A set of joint scale data for deforming the avatar mesh //----------------------------------------------------------------------------- -class LLPolySkeletalDistortion : public LLViewerVisualParam +class alignas(16) LLPolySkeletalDistortion : public LLViewerVisualParam { + LL_ALIGN_NEW public: - void* operator new(size_t size) - { - return ll_aligned_malloc_16(size); - } - - void operator delete(void* ptr) - { - ll_aligned_free_16(ptr); - } - LLPolySkeletalDistortion(LLAvatarAppearance *avatarp); ~LLPolySkeletalDistortion() = default; diff --git a/indra/llappearance/lltexlayer.cpp b/indra/llappearance/lltexlayer.cpp index 2b091c0dc3789f1055350a2b04487d8963d9b237..be9ae7870438f2498b87c8e4e4070a047ee46d94 100644 --- a/indra/llappearance/lltexlayer.cpp +++ b/indra/llappearance/lltexlayer.cpp @@ -138,17 +138,8 @@ BOOL LLTexLayerSetBuffer::renderTexLayerSet(LLRenderTarget* bound_target) BOOL success = TRUE; - bool use_shaders = LLGLSLShader::sNoFixedFunction; - - if (use_shaders) - { - gAlphaMaskProgram.bind(); - gAlphaMaskProgram.setMinimumAlpha(0.004f); - } - else - { - gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.00f); - } + gAlphaMaskProgram.bind(); + gAlphaMaskProgram.setMinimumAlpha(0.004f); LLVertexBuffer::unbind(); @@ -160,10 +151,7 @@ BOOL LLTexLayerSetBuffer::renderTexLayerSet(LLRenderTarget* bound_target) midRenderTexLayerSet(success, bound_target); - if (use_shaders) - { - gAlphaMaskProgram.unbind(); - } + gAlphaMaskProgram.unbind(); LLVertexBuffer::unbind(); @@ -386,8 +374,6 @@ BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height, LLRenderTarget* } } - bool use_shaders = LLGLSLShader::sNoFixedFunction; - LLGLSUIDefault gls_ui; LLGLDepthTest gls_depth(GL_FALSE, GL_FALSE); gGL.setColorMask(true, true); @@ -396,20 +382,14 @@ BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height, LLRenderTarget* { gGL.flush(); LLGLDisable no_alpha(GL_ALPHA_TEST); - if (use_shaders) - { - gAlphaMaskProgram.setMinimumAlpha(0.0f); - } + gAlphaMaskProgram.setMinimumAlpha(0.0f); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); gGL.color4f( 0.f, 0.f, 0.f, 1.f ); gl_rect_2d_simple( width, height ); gGL.flush(); - if (use_shaders) - { - gAlphaMaskProgram.setMinimumAlpha(0.004f); - } + gAlphaMaskProgram.setMinimumAlpha(0.004f); } if (mIsVisible) @@ -436,10 +416,7 @@ BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height, LLRenderTarget* gGL.setSceneBlendType(LLRender::BT_REPLACE); LLGLDisable no_alpha(GL_ALPHA_TEST); - if (use_shaders) - { - gAlphaMaskProgram.setMinimumAlpha(0.f); - } + gAlphaMaskProgram.setMinimumAlpha(0.f); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); gGL.color4f( 0.f, 0.f, 0.f, 0.f ); @@ -448,10 +425,7 @@ BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height, LLRenderTarget* gGL.setSceneBlendType(LLRender::BT_ALPHA); gGL.flush(); - if (use_shaders) - { - gAlphaMaskProgram.setMinimumAlpha(0.004f); - } + gAlphaMaskProgram.setMinimumAlpha(0.004f); } return success; @@ -468,32 +442,6 @@ const std::string LLTexLayerSet::getBodyRegionName() const return mInfo->mBodyRegion; } - -// virtual -void LLTexLayerSet::asLLSD(LLSD& sd) const -{ - sd["visible"] = LLSD::Boolean(isVisible()); - LLSD layer_list_sd; - layer_list_t::const_iterator layer_iter = mLayerList.begin(); - layer_list_t::const_iterator layer_end = mLayerList.end(); - for(; layer_iter != layer_end; ++layer_iter) - { - LLSD layer_sd; - //LLTexLayerInterface* layer = (*layer_iter); - //if (layer) - //{ - // layer->asLLSD(layer_sd); - //} - layer_list_sd.append(layer_sd); - } - LLSD mask_list_sd; - LLSD info_sd; - sd["layers"] = layer_list_sd; - sd["masks"] = mask_list_sd; - sd["info"] = info_sd; -} - - void LLTexLayerSet::destroyComposite() { if( mComposite ) @@ -516,10 +464,9 @@ const LLTexLayerSetBuffer* LLTexLayerSet::getComposite() const return mComposite; } -static LLTrace::BlockTimerStatHandle FTM_GATHER_MORPH_MASK_ALPHA("gatherMorphMaskAlpha"); void LLTexLayerSet::gatherMorphMaskAlpha(U8 *data, S32 origin_x, S32 origin_y, S32 width, S32 height, LLRenderTarget* bound_target) { - LL_RECORD_BLOCK_TIME(FTM_GATHER_MORPH_MASK_ALPHA); + LL_PROFILE_ZONE_SCOPED; memset(data, 255, width * height); for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ ) @@ -532,14 +479,11 @@ void LLTexLayerSet::gatherMorphMaskAlpha(U8 *data, S32 origin_x, S32 origin_y, S renderAlphaMaskTextures(origin_x, origin_y, width, height, bound_target, true); } -static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_MASK_TEXTURES("renderAlphaMaskTextures"); void LLTexLayerSet::renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* bound_target, bool forceClear) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_MASK_TEXTURES); + LL_PROFILE_ZONE_SCOPED; const LLTexLayerSetInfo *info = getInfo(); - bool use_shaders = LLGLSLShader::sNoFixedFunction; - gGL.setColorMask(false, true); gGL.setSceneBlendType(LLRender::BT_REPLACE); @@ -548,12 +492,11 @@ void LLTexLayerSet::renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, { gGL.flush(); { - LLGLTexture* tex = LLTexLayerStaticImageList::getInstanceFast()->getTexture(info->mStaticAlphaFileName, TRUE); + LLGLTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(info->mStaticAlphaFileName, TRUE); if( tex ) { LLGLSUIDefault gls_ui; gGL.getTexUnit(0)->bind(tex); - gGL.getTexUnit(0)->setTextureBlendType( LLTexUnit::TB_REPLACE ); gl_rect_2d_simple_tex( width, height ); } } @@ -564,20 +507,14 @@ void LLTexLayerSet::renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, // Set the alpha channel to one (clean up after previous blending) gGL.flush(); LLGLDisable no_alpha(GL_ALPHA_TEST); - if (use_shaders) - { - gAlphaMaskProgram.setMinimumAlpha(0.f); - } + gAlphaMaskProgram.setMinimumAlpha(0.f); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); gGL.color4f( 0.f, 0.f, 0.f, 1.f ); gl_rect_2d_simple( width, height ); gGL.flush(); - if (use_shaders) - { - gAlphaMaskProgram.setMinimumAlpha(0.004f); - } + gAlphaMaskProgram.setMinimumAlpha(0.004f); } // (Optional) Mask out part of the baked texture with alpha masks @@ -585,7 +522,6 @@ void LLTexLayerSet::renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, if (mMaskLayerList.size() > 0) { gGL.setSceneBlendType(LLRender::BT_MULT_ALPHA); - gGL.getTexUnit(0)->setTextureBlendType( LLTexUnit::TB_REPLACE ); for (layer_list_t::iterator iter = mMaskLayerList.begin(); iter != mMaskLayerList.end(); iter++) { LLTexLayerInterface* layer = *iter; @@ -598,7 +534,6 @@ void LLTexLayerSet::renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); gGL.setColorMask(true, true); gGL.setSceneBlendType(LLRender::BT_ALPHA); } @@ -1121,13 +1056,6 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* bou // *TODO: Is this correct? //gPipeline.disableLights(); stop_glerror(); - if (!LLGLSLShader::sNoFixedFunction) - { - glDisable(GL_LIGHTING); - } - stop_glerror(); - - bool use_shaders = LLGLSLShader::sNoFixedFunction; LLColor4 net_color; BOOL color_specified = findNetColor(&net_color); @@ -1214,10 +1142,7 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* bou LLGLDisable alpha_test(no_alpha_test ? GL_ALPHA_TEST : 0); if (no_alpha_test) { - if (use_shaders) - { - gAlphaMaskProgram.setMinimumAlpha(0.f); - } + gAlphaMaskProgram.setMinimumAlpha(0.f); } LLTexUnit::eTextureAddressMode old_mode = tex->getAddressMode(); @@ -1231,10 +1156,7 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* bou gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); if (no_alpha_test) { - if (use_shaders) - { - gAlphaMaskProgram.setMinimumAlpha(0.004f); - } + gAlphaMaskProgram.setMinimumAlpha(0.004f); } } } @@ -1248,7 +1170,7 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* bou if( !getInfo()->mStaticImageFileName.empty() ) { { - LLGLTexture* tex = LLTexLayerStaticImageList::getInstanceFast()->getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask); + LLGLTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask); if( tex ) { gGL.getTexUnit(0)->bind(tex, TRUE); @@ -1268,18 +1190,12 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* bou color_specified ) { LLGLDisable no_alpha(GL_ALPHA_TEST); - if (use_shaders) - { - gAlphaMaskProgram.setMinimumAlpha(0.000f); - } + gAlphaMaskProgram.setMinimumAlpha(0.000f); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); gGL.color4fv( net_color.mV ); gl_rect_2d_simple( width, height ); - if (use_shaders) - { - gAlphaMaskProgram.setMinimumAlpha(0.004f); - } + gAlphaMaskProgram.setMinimumAlpha(0.004f); } if( alpha_mask_specified || getInfo()->mWriteAllChannels ) @@ -1367,25 +1283,17 @@ BOOL LLTexLayer::blendAlphaTexture(S32 x, S32 y, S32 width, S32 height) gGL.flush(); - bool use_shaders = LLGLSLShader::sNoFixedFunction; - if( !getInfo()->mStaticImageFileName.empty() ) { - LLGLTexture* tex = LLTexLayerStaticImageList::getInstanceFast()->getTexture( getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask ); + LLGLTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture( getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask ); if( tex ) { LLGLSNoAlphaTest gls_no_alpha_test; - if (use_shaders) - { - gAlphaMaskProgram.setMinimumAlpha(0.f); - } + gAlphaMaskProgram.setMinimumAlpha(0.f); gGL.getTexUnit(0)->bind(tex, TRUE); gl_rect_2d_simple_tex( width, height ); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - if (use_shaders) - { - gAlphaMaskProgram.setMinimumAlpha(0.004f); - } + gAlphaMaskProgram.setMinimumAlpha(0.004f); } else { @@ -1400,18 +1308,11 @@ BOOL LLTexLayer::blendAlphaTexture(S32 x, S32 y, S32 width, S32 height) if (tex) { LLGLSNoAlphaTest gls_no_alpha_test; - if (use_shaders) - { - gAlphaMaskProgram.setMinimumAlpha(0.f); - } + gAlphaMaskProgram.setMinimumAlpha(0.f); gGL.getTexUnit(0)->bind(tex); gl_rect_2d_simple_tex( width, height ); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - success = TRUE; - if (use_shaders) - { - gAlphaMaskProgram.setMinimumAlpha(0.004f); - } + gAlphaMaskProgram.setMinimumAlpha(0.004f); } } } @@ -1424,7 +1325,6 @@ BOOL LLTexLayer::blendAlphaTexture(S32 x, S32 y, S32 width, S32 height) addAlphaMask(data, originX, originY, width, height, bound_target); } -static LLTrace::BlockTimerStatHandle FTM_RENDER_MORPH_MASKS("renderMorphMasks"); void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color, LLRenderTarget* bound_target, bool force_render) { if (!force_render && !hasMorph()) @@ -1434,18 +1334,12 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC #endif return; } - LL_RECORD_BLOCK_TIME(FTM_RENDER_MORPH_MASKS); + LL_PROFILE_ZONE_SCOPED; BOOL success = TRUE; llassert( !mParamAlphaList.empty() ); - bool use_shaders = LLGLSLShader::sNoFixedFunction; - - if (use_shaders) - { - gAlphaMaskProgram.setMinimumAlpha(0.f); - } - + gAlphaMaskProgram.setMinimumAlpha(0.f); gGL.setColorMask(false, true); LLTexLayerParamAlpha* first_param = *mParamAlphaList.begin(); @@ -1504,7 +1398,7 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC if( !getInfo()->mStaticImageFileName.empty() && getInfo()->mStaticImageIsMask ) { - LLGLTexture* tex = LLTexLayerStaticImageList::getInstanceFast()->getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask); + LLGLTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask); if( tex ) { if( (tex->getComponents() == 4) || (tex->getComponents() == 1) ) @@ -1532,10 +1426,7 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC gl_rect_2d_simple( width, height ); } - if (use_shaders) - { - gAlphaMaskProgram.setMinimumAlpha(0.004f); - } + gAlphaMaskProgram.setMinimumAlpha(0.004f); LLGLSUIDefault gls_ui; @@ -1599,10 +1490,9 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC } } -static LLTrace::BlockTimerStatHandle FTM_ADD_ALPHA_MASK("addAlphaMask"); void LLTexLayer::addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 height, LLRenderTarget* bound_target) { - LL_RECORD_BLOCK_TIME(FTM_ADD_ALPHA_MASK); + LL_PROFILE_ZONE_SCOPED; S32 size = width * height; const U8* alphaData = getAlphaData(); if (!alphaData && hasAlphaParams()) @@ -1654,7 +1544,7 @@ LLUUID LLTexLayer::getUUID() const } if( !getInfo()->mStaticImageFileName.empty() ) { - LLGLTexture* tex = LLTexLayerStaticImageList::getInstanceFast()->getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask); + LLGLTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask); if( tex ) { uuid = tex->getID(); @@ -1939,10 +1829,9 @@ void LLTexLayerStaticImageList::deleteCachedImages() // Returns an LLImageTGA that contains the encoded data from a tga file named file_name. // Caches the result to speed identical subsequent requests. -static LLTrace::BlockTimerStatHandle FTM_LOAD_STATIC_TGA("getImageTGA"); LLImageTGA* LLTexLayerStaticImageList::getImageTGA(const std::string& file_name) { - LL_RECORD_BLOCK_TIME(FTM_LOAD_STATIC_TGA); + LL_PROFILE_ZONE_SCOPED; const char *namekey = mImageNames.addString(file_name); image_tga_map_t::const_iterator iter = mStaticImageListTGA.find(namekey); if( iter != mStaticImageListTGA.end() ) @@ -1969,10 +1858,9 @@ LLImageTGA* LLTexLayerStaticImageList::getImageTGA(const std::string& file_name) // Returns a GL Image (without a backing ImageRaw) that contains the decoded data from a tga file named file_name. // Caches the result to speed identical subsequent requests. -static LLTrace::BlockTimerStatHandle FTM_LOAD_STATIC_TEXTURE("getTexture"); LLGLTexture* LLTexLayerStaticImageList::getTexture(const std::string& file_name, BOOL is_mask) { - LL_RECORD_BLOCK_TIME(FTM_LOAD_STATIC_TEXTURE); + LL_PROFILE_ZONE_SCOPED; LLPointer<LLGLTexture> tex; const char *namekey = mImageNames.addString(file_name); @@ -2019,10 +1907,9 @@ LLGLTexture* LLTexLayerStaticImageList::getTexture(const std::string& file_name, // Reads a .tga file, decodes it, and puts the decoded data in image_raw. // Returns TRUE if successful. -static LLTrace::BlockTimerStatHandle FTM_LOAD_IMAGE_RAW("loadImageRaw"); BOOL LLTexLayerStaticImageList::loadImageRaw(const std::string& file_name, LLImageRaw* image_raw) { - LL_RECORD_BLOCK_TIME(FTM_LOAD_IMAGE_RAW); + LL_PROFILE_ZONE_SCOPED; BOOL success = FALSE; std::string path; path = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,file_name); diff --git a/indra/llappearance/lltexlayer.h b/indra/llappearance/lltexlayer.h index bfc0091bdef947992d445d55b46013f531578423..e5aefae248784ff06c5bd78dc1a35e7648b22359 100644 --- a/indra/llappearance/lltexlayer.h +++ b/indra/llappearance/lltexlayer.h @@ -220,8 +220,6 @@ class LLTexLayerSet static BOOL sHasCaches; - virtual void asLLSD(LLSD& sd) const; - protected: typedef std::vector<LLTexLayerInterface *> layer_list_t; layer_list_t mLayerList; diff --git a/indra/llappearance/lltexlayerparams.cpp b/indra/llappearance/lltexlayerparams.cpp index 4d6aba68ddf76be9b50b26a10043d3d42d52f620..c3dd9a6df34f50ac2c41e9ad5915d8626e66c738 100644 --- a/indra/llappearance/lltexlayerparams.cpp +++ b/indra/llappearance/lltexlayerparams.cpp @@ -254,10 +254,9 @@ BOOL LLTexLayerParamAlpha::getSkip() const } -static LLTrace::BlockTimerStatHandle FTM_TEX_LAYER_PARAM_ALPHA("alpha render"); BOOL LLTexLayerParamAlpha::render(S32 x, S32 y, S32 width, S32 height) { - LL_RECORD_BLOCK_TIME(FTM_TEX_LAYER_PARAM_ALPHA); + LL_PROFILE_ZONE_SCOPED; BOOL success = TRUE; if (!mTexLayer) @@ -288,7 +287,7 @@ BOOL LLTexLayerParamAlpha::render(S32 x, S32 y, S32 width, S32 height) if (mStaticImageTGA.isNull()) { // Don't load the image file until we actually need it the first time. Like now. - mStaticImageTGA = LLTexLayerStaticImageList::getInstanceFast()->getImageTGA(info->mStaticImageFileName); + mStaticImageTGA = LLTexLayerStaticImageList::getInstance()->getImageTGA(info->mStaticImageFileName); // We now have something in one of our caches LLTexLayerSet::sHasCaches |= mStaticImageTGA.notNull() ? TRUE : FALSE; diff --git a/indra/llappearance/lltexlayerparams.h b/indra/llappearance/lltexlayerparams.h index 5f08d8a0144397544597f861ab9a6c862c65dc28..393f53b0a003222c2cb4132b0d4bf286fb296963 100644 --- a/indra/llappearance/lltexlayerparams.h +++ b/indra/llappearance/lltexlayerparams.h @@ -63,23 +63,14 @@ class LLTexLayerParam : public LLViewerVisualParam // //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ LL_ALIGN_PREFIX(16) -class LLTexLayerParamAlpha final : public LLTexLayerParam +class alignas(16) LLTexLayerParamAlpha final : public LLTexLayerParam { + LL_ALIGN_NEW public: LLTexLayerParamAlpha( LLTexLayerInterface* layer ); LLTexLayerParamAlpha( LLAvatarAppearance* appearance ); /*virtual*/ ~LLTexLayerParamAlpha(); - void* operator new(size_t size) - { - return ll_aligned_malloc_16(size); - } - - void operator delete(void* ptr) - { - ll_aligned_free_16(ptr); - } - /*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable = nullptr) const override; // LLVisualParam Virtual functions @@ -146,9 +137,9 @@ class LLTexLayerParamAlphaInfo final : public LLViewerVisualParamInfo // //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -LL_ALIGN_PREFIX(16) -class LLTexLayerParamColor : public LLTexLayerParam +class alignas(16) LLTexLayerParamColor : public LLTexLayerParam { + LL_ALIGN_NEW public: enum EColorOperation { @@ -161,16 +152,6 @@ class LLTexLayerParamColor : public LLTexLayerParam LLTexLayerParamColor( LLTexLayerInterface* layer ); LLTexLayerParamColor( LLAvatarAppearance* appearance ); - void* operator new(size_t size) - { - return ll_aligned_malloc_16(size); - } - - void operator delete(void* ptr) - { - ll_aligned_free_16(ptr); - } - /* virtual */ ~LLTexLayerParamColor() = default; /*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable = NULL) const override; @@ -198,8 +179,8 @@ class LLTexLayerParamColor : public LLTexLayerParam virtual void onGlobalColorChanged(bool upload_bake) {} private: - LL_ALIGN_16(LLVector4a mAvgDistortionVec); -} LL_ALIGN_POSTFIX(16); + LLVector4a mAvgDistortionVec; +}; class LLTexLayerParamColorInfo final : public LLViewerVisualParamInfo { diff --git a/indra/llappearance/llviewervisualparam.cpp b/indra/llappearance/llviewervisualparam.cpp index c026ae6d9d9de50e1a3a91d2cd6d0a503609f6db..cc9a9c6356d4b980c7908897d775fd49c2b21a97 100644 --- a/indra/llappearance/llviewervisualparam.cpp +++ b/indra/llappearance/llviewervisualparam.cpp @@ -66,7 +66,7 @@ BOOL LLViewerVisualParamInfo::parseXml(LLXmlTreeNode *node) static LLStdStringHandle wearable_string = LLXmlTree::addAttributeString("wearable"); if( node->getFastAttributeString( wearable_string, wearable) ) { - mWearableType = LLWearableType::getInstanceFast()->typeNameToType( wearable ); + mWearableType = LLWearableType::getInstance()->typeNameToType( wearable ); } static LLStdStringHandle edit_group_string = LLXmlTree::addAttributeString("edit_group"); diff --git a/indra/llappearance/llwearable.cpp b/indra/llappearance/llwearable.cpp index 25e17a887160da42844af20d34cafbb5aa530aa2..c6d82e82b550625c8421d1e722e1637495ed337c 100644 --- a/indra/llappearance/llwearable.cpp +++ b/indra/llappearance/llwearable.cpp @@ -73,17 +73,17 @@ LLWearable::~LLWearable() const std::string& LLWearable::getTypeLabel() const { - return LLWearableType::getInstanceFast()->getTypeLabel(mType); + return LLWearableType::getInstance()->getTypeLabel(mType); } const std::string& LLWearable::getTypeName() const { - return LLWearableType::getInstanceFast()->getTypeName(mType); + return LLWearableType::getInstance()->getTypeName(mType); } LLAssetType::EType LLWearable::getAssetType() const { - return LLWearableType::getInstanceFast()->getAssetType(mType); + return LLWearableType::getInstance()->getAssetType(mType); } BOOL LLWearable::exportFile(const std::string& filename) const diff --git a/indra/llappearance/llwearabledata.cpp b/indra/llappearance/llwearabledata.cpp index eb8f960c24c6abce325e4c16e9e353b2cd1b712b..0bee0c7f075ffa94079a2120c2a6dfb697ecc2a7 100644 --- a/indra/llappearance/llwearabledata.cpp +++ b/indra/llappearance/llwearabledata.cpp @@ -236,7 +236,7 @@ BOOL LLWearableData::getWearableIndex(const LLWearable *wearable, U32& index_fou U32 LLWearableData::getClothingLayerCount() const { U32 count = 0; - LLWearableType *wr_inst = LLWearableType::getInstanceFast(); + LLWearableType *wr_inst = LLWearableType::getInstance(); for (S32 i = 0; i < LLWearableType::WT_COUNT; i++) { LLWearableType::EType type = (LLWearableType::EType)i; @@ -250,7 +250,7 @@ U32 LLWearableData::getClothingLayerCount() const BOOL LLWearableData::canAddWearable(const LLWearableType::EType type) const { - LLAssetType::EType a_type = LLWearableType::getInstanceFast()->getAssetType(type); + LLAssetType::EType a_type = LLWearableType::getInstance()->getAssetType(type); if (a_type==LLAssetType::AT_CLOTHING) { return (getClothingLayerCount() < MAX_CLOTHING_LAYERS); diff --git a/indra/llaudio/llaudiodecodemgr.cpp b/indra/llaudio/llaudiodecodemgr.cpp index d2d13a70e40a4a5b36158ba2e436ac9d091313cf..c5ab0028293adbeeb380ed5743bb9982314083d7 100644 --- a/indra/llaudio/llaudiodecodemgr.cpp +++ b/indra/llaudio/llaudiodecodemgr.cpp @@ -35,6 +35,8 @@ #include "llendianswizzle.h" #include "llassetstorage.h" #include "llrefcount.h" +#include "threadpool.h" +#include "workqueue.h" #include "llvorbisencode.h" @@ -53,15 +55,13 @@ extern LLAudioEngine *gAudiop; -LLAudioDecodeMgr *gAudioDecodeMgrp = NULL; - static const S32 WAV_HEADER_SIZE = 44; ////////////////////////////////////////////////////////////////////////////// -class LLVorbisDecodeState final : public LLRefCount +class LLVorbisDecodeState final : public LLThreadSafeRefCount { public: class WriteResponder : public LLLFSThread::Responder @@ -540,137 +540,254 @@ void LLVorbisDecodeState::flushBadFile() class LLAudioDecodeMgr::Impl { - friend class LLAudioDecodeMgr; -public: - Impl() = default; - ~Impl() = default; + friend class LLAudioDecodeMgr; + Impl(); + public: - void processQueue(const F32 num_secs = 0.005); + void processQueue(); -protected: - std::deque<LLUUID> mDecodeQueue; - LLPointer<LLVorbisDecodeState> mCurrentDecodep; + void startMoreDecodes(); + void enqueueFinishAudio(const LLUUID &decode_id, LLPointer<LLVorbisDecodeState>& decode_state); + void checkDecodesFinished(); + + protected: + std::deque<LLUUID> mDecodeQueue; + std::map<LLUUID, LLPointer<LLVorbisDecodeState>> mDecodes; }; +LLAudioDecodeMgr::Impl::Impl() +{ +} + +// Returns the in-progress decode_state, which may be an empty LLPointer if +// there was an error and there is no more work to be done. +LLPointer<LLVorbisDecodeState> beginDecodingAndWritingAudio(const LLUUID &decode_id); + +// Return true if finished +bool tryFinishAudio(const LLUUID &decode_id, LLPointer<LLVorbisDecodeState> decode_state); -void LLAudioDecodeMgr::Impl::processQueue(const F32 num_secs) +void LLAudioDecodeMgr::Impl::processQueue() { - LLTimer decode_timer; + // First, check if any audio from in-progress decodes are ready to play. If + // so, mark them ready for playback (or errored, in case of error). + checkDecodesFinished(); - BOOL done = FALSE; - while (!done) - { - if (mCurrentDecodep) - { - BOOL res; + // Second, start as many decodes from the queue as permitted + startMoreDecodes(); +} - // Decode in a loop until we're done or have run out of time. - while(!(res = mCurrentDecodep->decodeSection()) && (decode_timer.getElapsedTimeF32() < num_secs)) - { - // decodeSection does all of the work above - } +void LLAudioDecodeMgr::Impl::startMoreDecodes() +{ + llassert_always(gAudiop); + + LL::WorkQueue::ptr_t main_queue = LL::WorkQueue::getInstance("mainloop"); + // *NOTE: main_queue->postTo casts this refcounted smart pointer to a weak + // pointer + LL::WorkQueue::ptr_t general_queue = LL::WorkQueue::getInstance("General"); + const LL::ThreadPool::ptr_t general_thread_pool = LL::ThreadPool::getInstance("General"); + llassert_always(main_queue); + llassert_always(general_queue); + llassert_always(general_thread_pool); + // Set max decodes to double the thread count of the general work queue. + // This ensures the general work queue is full, but prevents theoretical + // buildup of buffers in memory due to disk writes once the + // LLVorbisDecodeState leaves the worker thread (see + // LLLFSThread::sLocal->write). This is probably as fast as we can get it + // without modifying/removing LLVorbisDecodeState, at which point we should + // consider decoding the audio during the asset download process. + // -Cosmic,2022-05-11 + const size_t max_decodes = general_thread_pool->getWidth() * 2; + + while (!mDecodeQueue.empty() && mDecodes.size() < max_decodes) + { + const LLUUID decode_id = mDecodeQueue.front(); + mDecodeQueue.pop_front(); + + // Don't decode the same file twice + if (mDecodes.find(decode_id) != mDecodes.end()) + { + continue; + } + if (gAudiop->hasDecodedFile(decode_id)) + { + continue; + } + + // Kick off a decode + mDecodes[decode_id] = LLPointer<LLVorbisDecodeState>(NULL); + try + { + main_queue->postTo( + general_queue, + [decode_id]() // Work done on general queue + { + LLPointer<LLVorbisDecodeState> decode_state = beginDecodingAndWritingAudio(decode_id); + + if (!decode_state) + { + // Audio decode has errored + return decode_state; + } + + // Disk write of decoded audio is now in progress off-thread + return decode_state; + }, + [decode_id, this](LLPointer<LLVorbisDecodeState> decode_state) // Callback to main thread + mutable { + if (!gAudiop) + { + // There is no LLAudioEngine anymore. This might happen if + // an audio decode is enqueued just before shutdown. + return; + } + + // At this point, we can be certain that the pointer to "this" + // is valid because the lifetime of "this" is dependent upon + // the lifetime of gAudiop. + + enqueueFinishAudio(decode_id, decode_state); + }); + } + catch (const LLThreadSafeQueueInterrupt&) + { + // Shutdown + // Consider making processQueue() do a cleanup instead + // of starting more decodes + LL_WARNS() << "Tried to start decoding on shutdown" << LL_ENDL; + } + } +} - if (mCurrentDecodep->isDone() && !mCurrentDecodep->isValid()) - { - // We had an error when decoding, abort. - LL_WARNS("AudioEngine") << mCurrentDecodep->getUUID() << " has invalid vorbis data, aborting decode" << LL_ENDL; - mCurrentDecodep->flushBadFile(); - - if (gAudiop) - { - LLAudioData *adp = gAudiop->getAudioData(mCurrentDecodep->getUUID()); - adp->setHasValidData(false); - adp->setHasCompletedDecode(true); - } - - mCurrentDecodep = NULL; - done = TRUE; - } +LLPointer<LLVorbisDecodeState> beginDecodingAndWritingAudio(const LLUUID &decode_id) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_MEDIA; + + LL_DEBUGS() << "Decoding " << decode_id << " from audio queue!" << LL_ENDL; + + std::string d_path = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, decode_id.asString()) + ".dsf"; + LLPointer<LLVorbisDecodeState> decode_state = new LLVorbisDecodeState(decode_id, d_path); + + if (!decode_state->initDecode()) + { + return NULL; + } + + // Decode in a loop until we're done + while (!decode_state->decodeSection()) + { + // decodeSection does all of the work above + } + + if (!decode_state->isDone()) + { + // Decode stopped early, or something bad happened to the file + // during decoding. + LL_WARNS("AudioEngine") << decode_id << " has invalid vorbis data or decode has been canceled, aborting decode" << LL_ENDL; + decode_state->flushBadFile(); + return NULL; + } + + if (!decode_state->isValid()) + { + // We had an error when decoding, abort. + LL_WARNS("AudioEngine") << decode_id << " has invalid vorbis data, aborting decode" << LL_ENDL; + decode_state->flushBadFile(); + return NULL; + } + + // Kick off the writing of the decoded audio to the disk cache. + // The receiving thread can then cheaply call finishDecode() again to check + // if writing has finished. Someone has to hold on to the refcounted + // decode_state to prevent it from getting destroyed during write. + decode_state->finishDecode(); + + return decode_state; +} - if (!res) - { - // We've used up out time slice, bail... - done = TRUE; - } - else if (mCurrentDecodep) - { - if (gAudiop && mCurrentDecodep->finishDecode()) - { - // We finished! - LLAudioData *adp = gAudiop->getAudioData(mCurrentDecodep->getUUID()); - if (!adp) - { - LL_WARNS("AudioEngine") << "Missing LLAudioData for decode of " << mCurrentDecodep->getUUID() << LL_ENDL; - } - else if (mCurrentDecodep->isValid() && mCurrentDecodep->isDone()) - { - adp->setHasCompletedDecode(true); - adp->setHasDecodedData(true); - adp->setHasValidData(true); - - // At this point, we could see if anyone needs this sound immediately, but - // I'm not sure that there's a reason to - we need to poll all of the playing - // sounds anyway. - //LL_INFOS("AudioEngine") << "Finished the vorbis decode, now what?" << LL_ENDL; - } - else - { - adp->setHasCompletedDecode(true); - LL_INFOS("AudioEngine") << "Vorbis decode failed for " << mCurrentDecodep->getUUID() << LL_ENDL; - } - mCurrentDecodep = NULL; - } - done = TRUE; // done for now - } - } +void LLAudioDecodeMgr::Impl::enqueueFinishAudio(const LLUUID &decode_id, LLPointer<LLVorbisDecodeState>& decode_state) +{ + // Assumed fast + if (tryFinishAudio(decode_id, decode_state)) + { + // Done early! + auto decode_iter = mDecodes.find(decode_id); + llassert(decode_iter != mDecodes.end()); + mDecodes.erase(decode_iter); + return; + } + + // Not done yet... enqueue it + mDecodes[decode_id] = decode_state; +} - if (!done) - { - if (mDecodeQueue.empty()) - { - // Nothing else on the queue. - done = TRUE; - } - else - { - LLUUID uuid; - uuid = mDecodeQueue.front(); - mDecodeQueue.pop_front(); - if (!gAudiop || gAudiop->hasDecodedFile(uuid)) - { - // This file has already been decoded, don't decode it again. - continue; - } - - LL_DEBUGS() << "Decoding " << uuid << " from audio queue!" << LL_ENDL; - - std::string d_path = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, uuid.asString()) + ".dsf"; - - mCurrentDecodep = new LLVorbisDecodeState(uuid, d_path); - if (!mCurrentDecodep->initDecode()) - { - mCurrentDecodep = NULL; - } - } - } - } +void LLAudioDecodeMgr::Impl::checkDecodesFinished() +{ + auto decode_iter = mDecodes.begin(); + while (decode_iter != mDecodes.end()) + { + const LLUUID& decode_id = decode_iter->first; + const LLPointer<LLVorbisDecodeState>& decode_state = decode_iter->second; + if (tryFinishAudio(decode_id, decode_state)) + { + decode_iter = mDecodes.erase(decode_iter); + } + else + { + ++decode_iter; + } + } +} + +bool tryFinishAudio(const LLUUID &decode_id, LLPointer<LLVorbisDecodeState> decode_state) +{ + // decode_state is a file write in progress unless finished is true + bool finished = decode_state && decode_state->finishDecode(); + if (!finished) + { + return false; + } + + llassert_always(gAudiop); + + LLAudioData *adp = gAudiop->getAudioData(decode_id); + if (!adp) + { + LL_WARNS("AudioEngine") << "Missing LLAudioData for decode of " << decode_id << LL_ENDL; + return true; + } + + bool valid = decode_state && decode_state->isValid(); + // Mark current decode finished regardless of success or failure + adp->setHasCompletedDecode(true); + // Flip flags for decoded data + adp->setHasDecodeFailed(!valid); + adp->setHasDecodedData(valid); + // When finished decoding, there will also be a decoded wav file cached on + // disk with the .dsf extension + if (valid) + { + adp->setHasWAVLoadFailed(false); + } + + return true; } ////////////////////////////////////////////////////////////////////////////// LLAudioDecodeMgr::LLAudioDecodeMgr() { - mImpl = new Impl; + mImpl = new Impl(); } LLAudioDecodeMgr::~LLAudioDecodeMgr() { - delete mImpl; + delete mImpl; + mImpl = nullptr; } -void LLAudioDecodeMgr::processQueue(const F32 num_secs) +void LLAudioDecodeMgr::processQueue() { - mImpl->processQueue(num_secs); + mImpl->processQueue(); } BOOL LLAudioDecodeMgr::addDecodeRequest(const LLUUID &uuid) @@ -686,7 +803,7 @@ BOOL LLAudioDecodeMgr::addDecodeRequest(const LLUUID &uuid) { // Just put it on the decode queue. LL_DEBUGS("AudioEngine") << "addDecodeRequest for " << uuid << " has local asset file already" << LL_ENDL; - mImpl->mDecodeQueue.push_back(uuid); + mImpl->mDecodeQueue.push_back(uuid); return TRUE; } diff --git a/indra/llaudio/llaudiodecodemgr.h b/indra/llaudio/llaudiodecodemgr.h index ceaff3f2d8254a97cf2f865a67fb2dc02cbb15c6..4c17b46156237557ae461b47b63a4e0a8dd7ca51 100644 --- a/indra/llaudio/llaudiodecodemgr.h +++ b/indra/llaudio/llaudiodecodemgr.h @@ -32,24 +32,23 @@ #include "llassettype.h" #include "llframetimer.h" +#include "llsingleton.h" +template<class T> class LLPointer; class LLVorbisDecodeState; -class LLAudioDecodeMgr +class LLAudioDecodeMgr : public LLSingleton<LLAudioDecodeMgr> { + LLSINGLETON(LLAudioDecodeMgr); + ~LLAudioDecodeMgr(); public: - LLAudioDecodeMgr(); - ~LLAudioDecodeMgr(); - - void processQueue(const F32 num_secs = 0.005); + void processQueue(); BOOL addDecodeRequest(const LLUUID &uuid); void addAudioRequest(const LLUUID &uuid); protected: class Impl; - Impl* mImpl; + Impl* mImpl; }; -extern LLAudioDecodeMgr *gAudioDecodeMgrp; - #endif diff --git a/indra/llaudio/llaudioengine.cpp b/indra/llaudio/llaudioengine.cpp index b2af4bf98fe6ab9c19b7d5108fbf15df6970c0dd..314b640e0a2aa04f97cd20e22011465a5eb67a41 100644 --- a/indra/llaudio/llaudioengine.cpp +++ b/indra/llaudio/llaudioengine.cpp @@ -78,18 +78,10 @@ void LLAudioEngine::setDefaults() mLastStatus = 0; - mNumChannels = 0; mEnableWind = false; - S32 i; - for (i = 0; i < MAX_CHANNELS; i++) - { - mChannels[i] = NULL; - } - for (i = 0; i < MAX_BUFFERS; i++) - { - mBuffers[i] = NULL; - } + mChannels.fill(nullptr); + mBuffers.fill(nullptr); mMasterGain = 1.f; // Setting mInternalGain to an out of range value fixes the issue reported in STORM-830. @@ -106,18 +98,14 @@ void LLAudioEngine::setDefaults() } -bool LLAudioEngine::init(const S32 num_channels, void* userdata, const std::string &app_title) +bool LLAudioEngine::init(void* userdata, const std::string &app_title) { setDefaults(); - mNumChannels = num_channels; mUserData = userdata; allocateListener(); - // Initialize the decode manager - gAudioDecodeMgrp = new LLAudioDecodeMgr; - LL_INFOS("AudioEngine") << "LLAudioEngine::init() AudioEngine successfully initialized" << LL_ENDL; return true; @@ -126,10 +114,6 @@ bool LLAudioEngine::init(const S32 num_channels, void* userdata, const std::stri void LLAudioEngine::shutdown() { - // Clean up decode manager - delete gAudioDecodeMgrp; - gAudioDecodeMgrp = nullptr; - // Clean up wind source cleanupWind(); @@ -155,14 +139,14 @@ void LLAudioEngine::shutdown() // Clean up channels S32 i; - for (i = 0; i < MAX_CHANNELS; i++) + for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++) { delete mChannels[i]; mChannels[i] = NULL; } // Clean up buffers - for (i = 0; i < MAX_BUFFERS; i++) + for (i = 0; i < LL_MAX_AUDIO_BUFFERS; i++) { delete mBuffers[i]; mBuffers[i] = NULL; @@ -228,7 +212,7 @@ std::string LLAudioEngine::getInternetStreamURL() void LLAudioEngine::updateChannels() { S32 i; - for (i = 0; i < MAX_CHANNELS; i++) + for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++) { if (mChannels[i]) { @@ -239,20 +223,14 @@ void LLAudioEngine::updateChannels() } } -static const F32 default_max_decode_time = .002f; // 2 ms -void LLAudioEngine::idle(F32 max_decode_time) +void LLAudioEngine::idle() { - if (max_decode_time <= 0.f) - { - max_decode_time = default_max_decode_time; - } - // "Update" all of our audio sources, clean up dead ones. // Primarily does position updating, cleanup of unused audio sources. // Also does regeneration of the current priority of each audio source. S32 i; - for (i = 0; i < MAX_BUFFERS; i++) + for (i = 0; i < LL_MAX_AUDIO_BUFFERS; i++) { if (mBuffers[i]) { @@ -469,7 +447,7 @@ void LLAudioEngine::idle(F32 max_decode_time) commitDeferredChanges(); // Flush unused buffers that are stale enough - for (i = 0; i < MAX_BUFFERS; i++) + for (i = 0; i < LL_MAX_AUDIO_BUFFERS; i++) { if (mBuffers[i]) { @@ -485,7 +463,7 @@ void LLAudioEngine::idle(F32 max_decode_time) // Clear all of the looped flags for the channels - for (i = 0; i < MAX_CHANNELS; i++) + for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++) { if (mChannels[i]) { @@ -494,7 +472,7 @@ void LLAudioEngine::idle(F32 max_decode_time) } // Decode audio files - gAudioDecodeMgrp->processQueue(max_decode_time); + LLAudioDecodeMgr::getInstance()->processQueue(); // Call this every frame, just in case we somehow // missed picking it up in all the places that can add @@ -528,7 +506,7 @@ bool LLAudioEngine::updateBufferForData(LLAudioData *adp, const LLUUID &audio_uu { if (audio_uuid.notNull()) { - gAudioDecodeMgrp->addDecodeRequest(audio_uuid); + LLAudioDecodeMgr::getInstance()->addDecodeRequest(audio_uuid); } } else @@ -557,7 +535,7 @@ void LLAudioEngine::enableWind(bool enable) LLAudioBuffer * LLAudioEngine::getFreeBuffer() { S32 i; - for (i = 0; i < MAX_BUFFERS; i++) + for (i = 0; i < LL_MAX_AUDIO_BUFFERS; i++) { if (!mBuffers[i]) { @@ -570,7 +548,7 @@ LLAudioBuffer * LLAudioEngine::getFreeBuffer() // Grab the oldest unused buffer F32 max_age = -1.f; S32 buffer_id = -1; - for (i = 0; i < MAX_BUFFERS; i++) + for (i = 0; i < LL_MAX_AUDIO_BUFFERS; i++) { if (mBuffers[i]) { @@ -601,7 +579,7 @@ LLAudioBuffer * LLAudioEngine::getFreeBuffer() LLAudioChannel * LLAudioEngine::getFreeChannel(const F32 priority) { S32 i; - for (i = 0; i < mNumChannels; i++) + for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++) { if (!mChannels[i]) { @@ -629,7 +607,7 @@ LLAudioChannel * LLAudioEngine::getFreeChannel(const F32 priority) F32 min_priority = 10000.f; LLAudioChannel *min_channelp = NULL; - for (i = 0; i < mNumChannels; i++) + for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++) { LLAudioChannel *channelp = mChannels[i]; LLAudioSource *sourcep = channelp->getSource(); @@ -656,7 +634,7 @@ LLAudioChannel * LLAudioEngine::getFreeChannel(const F32 priority) void LLAudioEngine::cleanupBuffer(LLAudioBuffer *bufferp) { S32 i; - for (i = 0; i < MAX_BUFFERS; i++) + for (i = 0; i < LL_MAX_AUDIO_BUFFERS; i++) { if (mBuffers[i] == bufferp) { @@ -674,7 +652,7 @@ bool LLAudioEngine::preloadSound(const LLUUID &uuid) getAudioData(uuid); // We don't care about the return value, this is just to make sure // that we have an entry, which will mean that the audio engine knows about this - if (gAudioDecodeMgrp->addDecodeRequest(uuid)) + if (LLAudioDecodeMgr::getInstance()->addDecodeRequest(uuid)) { // This means that we do have a local copy, and we're working on decoding it. return true; @@ -825,7 +803,8 @@ void LLAudioEngine::triggerSound(const LLUUID &audio_uuid, const LLUUID& owner_i addAudioSource(asp); if (pos_global.isExactlyZero()) { - asp->setAmbient(true); + // For sound preview and UI + asp->setForcedPriority(true); } else { @@ -967,6 +946,7 @@ LLAudioSource * LLAudioEngine::findAudioSource(const LLUUID &source_id) LLAudioData * LLAudioEngine::getAudioData(const LLUUID &audio_uuid) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_MEDIA; auto iter = mAllData.find(audio_uuid); if (iter == mAllData.end()) { @@ -1050,7 +1030,7 @@ void LLAudioEngine::startNextTransfer() // Check all channels for currently playing sounds. F32 max_pri = -1.f; - for (i = 0; i < MAX_CHANNELS; i++) + for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++) { if (!mChannels[i]) { @@ -1078,7 +1058,7 @@ void LLAudioEngine::startNextTransfer() continue; } - if (!adp->hasLocalData() && adp->hasValidData()) + if (!adp->hasLocalData() && !adp->hasDecodeFailed()) { asset_id = adp->getID(); max_pri = asp->getPriority(); @@ -1089,7 +1069,7 @@ void LLAudioEngine::startNextTransfer() if (asset_id.isNull()) { max_pri = -1.f; - for (i = 0; i < MAX_CHANNELS; i++) + for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++) { if (!mChannels[i]) { @@ -1114,7 +1094,7 @@ void LLAudioEngine::startNextTransfer() continue; } - if (!adp->hasLocalData() && adp->hasValidData()) + if (!adp->hasLocalData() && !adp->hasDecodeFailed()) { asset_id = adp->getID(); max_pri = asp->getPriority(); @@ -1126,7 +1106,7 @@ void LLAudioEngine::startNextTransfer() if (asset_id.isNull()) { max_pri = -1.f; - for (i = 0; i < MAX_CHANNELS; i++) + for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++) { if (!mChannels[i]) { @@ -1154,7 +1134,7 @@ void LLAudioEngine::startNextTransfer() continue; } - if (!adp->hasLocalData() && adp->hasValidData()) + if (!adp->hasLocalData() && !adp->hasDecodeFailed()) { asset_id = adp->getID(); max_pri = asp->getPriority(); @@ -1181,7 +1161,7 @@ void LLAudioEngine::startNextTransfer() } adp = asp->getCurrentData(); - if (adp && !adp->hasLocalData() && adp->hasValidData()) + if (adp && !adp->hasLocalData() && !adp->hasDecodeFailed()) { asset_id = adp->getID(); max_pri = asp->getPriority(); @@ -1189,7 +1169,7 @@ void LLAudioEngine::startNextTransfer() } adp = asp->getQueuedData(); - if (adp && !adp->hasLocalData() && adp->hasValidData()) + if (adp && !adp->hasLocalData() && !adp->hasDecodeFailed()) { asset_id = adp->getID(); max_pri = asp->getPriority(); @@ -1204,7 +1184,7 @@ void LLAudioEngine::startNextTransfer() continue; } - if (!adp->hasLocalData() && adp->hasValidData()) + if (!adp->hasLocalData() && !adp->hasDecodeFailed()) { asset_id = adp->getID(); max_pri = asp->getPriority(); @@ -1245,7 +1225,7 @@ void LLAudioEngine::assetCallback(const LLUUID &uuid, LLAssetType::EType type, v LLAudioData *adp = gAudiop->getAudioData(uuid); if (adp) { // Make sure everything is cleared - adp->setHasValidData(false); + adp->setHasDecodeFailed(true); adp->setHasLocalData(false); adp->setHasDecodedData(false); adp->setHasCompletedDecode(true); @@ -1262,9 +1242,9 @@ void LLAudioEngine::assetCallback(const LLUUID &uuid, LLAssetType::EType type, v else { // LL_INFOS() << "Got asset callback with good audio data for " << uuid << ", making decode request" << LL_ENDL; - adp->setHasValidData(true); + adp->setHasDecodeFailed(false); adp->setHasLocalData(true); - gAudioDecodeMgrp->addDecodeRequest(uuid); + LLAudioDecodeMgr::getInstance()->addDecodeRequest(uuid); } } gAudiop->mCurrentTransfer.setNull(); @@ -1343,7 +1323,7 @@ LLAudioSource::LLAudioSource(const LLUUID& id, const LLUUID& owner_id, const F32 mPriority(0.f), mGain(gain), mSourceMuted(false), - mAmbient(false), + mForcedPriority(false), mLoop(false), mSyncMaster(false), mSyncSlave(false), @@ -1401,11 +1381,15 @@ void LLAudioSource::update() { // Hack - try and load the sound. Will do this as a callback // on decode later. - if (adp->load() && adp->getBuffer()) + if (adp->getBuffer()) { play(adp->getID()); } - else if (adp->hasCompletedDecode()) // Only mark corrupted after decode is done + else if (adp->hasDecodedData() && !adp->hasWAVLoadFailed()) + { + adp->load(); + } + else if (adp->hasCompletedDecode() && adp->hasDecodeFailed()) // Only mark corrupted after decode is done { LL_WARNS() << "Marking LLAudioSource corrupted for " << adp->getID() << LL_ENDL; mCorrupted = true ; @@ -1416,7 +1400,7 @@ void LLAudioSource::update() void LLAudioSource::updatePriority() { - if (isAmbient()) + if (isForcedPriority()) { mPriority = 1.f; } @@ -1708,12 +1692,12 @@ bool LLAudioSource::hasPendingPreloads() const { LLAudioData *adp = preload_pair.second; // note: a bad UUID will forever be !hasDecodedData() - // but also !hasValidData(), hence the check for hasValidData() + // but also hasDecodeFailed(), hence the check for hasDecodeFailed() if (!adp) { continue; } - if (!adp->hasDecodedData() && adp->hasValidData()) + if (!adp->hasDecodedData() && !adp->hasDecodeFailed()) { // This source is still waiting for a preload return true; @@ -1870,7 +1854,8 @@ LLAudioData::LLAudioData(const LLUUID &uuid) : mHasLocalData(false), mHasDecodedData(false), mHasCompletedDecode(false), - mHasValidData(true) + mHasDecodeFailed(false), + mHasWAVLoadFailed(false) { if (uuid.isNull()) { @@ -1905,12 +1890,14 @@ bool LLAudioData::load() { // We already have this sound in a buffer, don't do anything. LL_INFOS() << "Already have a buffer for this sound, don't bother loading!" << LL_ENDL; + mHasWAVLoadFailed = false; return true; } if (!gAudiop) { LL_WARNS("AudioEngine") << "LLAudioEngine instance doesn't exist!" << LL_ENDL; + mHasWAVLoadFailed = true; return false; } @@ -1919,11 +1906,14 @@ bool LLAudioData::load() { // No free buffers, abort. LL_INFOS() << "Not able to allocate a new audio buffer, aborting." << LL_ENDL; + // *TODO: Mark this failure differently so the audio engine could retry loading this buffer in the future + mHasWAVLoadFailed = true; return true; } std::string wav_path = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, mID.asString()) + ".dsf"; - if (!mBufferp->loadWAV(wav_path)) + mHasWAVLoadFailed = !mBufferp->loadWAV(wav_path); + if (mHasWAVLoadFailed) { // Hrm. Right now, let's unset the buffer, since it's empty. gAudiop->cleanupBuffer(mBufferp); diff --git a/indra/llaudio/llaudioengine.h b/indra/llaudio/llaudioengine.h index b4f5254c3ba73f8b7d8485fa38473cf97df70007..95cc3870d764221dc3992065d5095b8d083e38df 100644 --- a/indra/llaudio/llaudioengine.h +++ b/indra/llaudio/llaudioengine.h @@ -49,8 +49,8 @@ const F32 LL_WIND_UNDERWATER_CENTER_FREQ = 20.f; const F32 ATTACHED_OBJECT_TIMEOUT = 5.0f; const F32 DEFAULT_MIN_DISTANCE = 2.0f; -#define MAX_CHANNELS 30 -#define MAX_BUFFERS 60 // Some extra for preloading, maybe? +#define LL_MAX_AUDIO_CHANNELS 30 +#define LL_MAX_AUDIO_BUFFERS 40 // Some extra for preloading, maybe? class LLAudioSource; class LLAudioData; @@ -91,7 +91,7 @@ class LLAudioEngine virtual ~LLAudioEngine() = default; // initialization/startup/shutdown - virtual bool init(const S32 num_channels, void *userdata, const std::string &app_title); + virtual bool init(void *userdata, const std::string &app_title); virtual std::string getDriverName(bool verbose) = 0; virtual void shutdown(); @@ -99,7 +99,7 @@ class LLAudioEngine //virtual void processQueue(const LLUUID &sound_guid); virtual void setListener(const LLVector3& pos, const LLVector3& vel, const LLVector3& up, const LLVector3& at); virtual void updateWind(LLVector3 direction, F32 camera_height_above_water) = 0; - virtual void idle(F32 max_decode_time = 0.f); + virtual void idle(); virtual void updateChannels(); // @@ -214,7 +214,6 @@ class LLAudioEngine S32 mLastStatus; - S32 mNumChannels; bool mEnableWind; LLUUID mCurrentTransfer; // Audio file currently being transferred by the system @@ -229,11 +228,11 @@ class LLAudioEngine source_map mAllSources; data_map mAllData; - LLAudioChannel *mChannels[MAX_CHANNELS]; + std::array<LLAudioChannel*, LL_MAX_AUDIO_CHANNELS> mChannels; // Buffers needs to change into a different data structure, as the number of buffers // that we have active should be limited by RAM usage, not count. - LLAudioBuffer *mBuffers[MAX_BUFFERS]; + std::array<LLAudioBuffer*, LL_MAX_AUDIO_BUFFERS> mBuffers; F32 mMasterGain; F32 mInternalGain; // Actual gain set; either mMasterGain or 0 when mMuted is true. @@ -282,8 +281,8 @@ class LLAudioSource void addAudioData(LLAudioData *adp, bool set_current = TRUE); - void setAmbient(const bool ambient) { mAmbient = ambient; } - bool isAmbient() const { return mAmbient; } + void setForcedPriority(const bool ambient) { mForcedPriority = ambient; } + bool isForcedPriority() const { return mForcedPriority; } void setLoop(const bool loop) { mLoop = loop; } bool isLoop() const { return mLoop; } @@ -344,7 +343,7 @@ class LLAudioSource F32 mPriority; F32 mGain; bool mSourceMuted; - bool mAmbient; + bool mForcedPriority; // ignore mute, set high priority, researved for sound preview and UI bool mLoop; bool mSyncMaster; bool mSyncSlave; @@ -381,32 +380,36 @@ class LLAudioSource class LLAudioData { -public: - LLAudioData(const LLUUID &uuid); - bool load(); - - LLUUID getID() const { return mID; } - LLAudioBuffer *getBuffer() const { return mBufferp; } - - bool hasLocalData() const { return mHasLocalData; } - bool hasDecodedData() const { return mHasDecodedData; } - bool hasCompletedDecode() const { return mHasCompletedDecode; } - bool hasValidData() const { return mHasValidData; } - - void setHasLocalData(const bool hld) { mHasLocalData = hld; } - void setHasDecodedData(const bool hdd) { mHasDecodedData = hdd; } - void setHasCompletedDecode(const bool hcd) { mHasCompletedDecode = hcd; } - void setHasValidData(const bool hvd) { mHasValidData = hvd; } - - friend class LLAudioEngine; // Severe laziness, bad. - -protected: - LLUUID mID; - LLAudioBuffer *mBufferp; // If this data is being used by the audio system, a pointer to the buffer will be set here. - bool mHasLocalData; // Set true if the sound asset file is available locally - bool mHasDecodedData; // Set true if the sound file has been decoded - bool mHasCompletedDecode; // Set true when the sound is decoded - bool mHasValidData; // Set false if decoding failed, meaning the sound asset is bad + public: + LLAudioData(const LLUUID &uuid); + bool load(); + + LLUUID getID() const { return mID; } + LLAudioBuffer *getBuffer() const { return mBufferp; } + + bool hasLocalData() const { return mHasLocalData; } + bool hasDecodedData() const { return mHasDecodedData; } + bool hasCompletedDecode() const { return mHasCompletedDecode; } + bool hasDecodeFailed() const { return mHasDecodeFailed; } + bool hasWAVLoadFailed() const { return mHasWAVLoadFailed; } + + void setHasLocalData(const bool hld) { mHasLocalData = hld; } + void setHasDecodedData(const bool hdd) { mHasDecodedData = hdd; } + void setHasCompletedDecode(const bool hcd) { mHasCompletedDecode = hcd; } + void setHasDecodeFailed(const bool hdf) { mHasDecodeFailed = hdf; } + void setHasWAVLoadFailed(const bool hwlf) { mHasWAVLoadFailed = hwlf; } + + friend class LLAudioEngine; // Severe laziness, bad. + + protected: + LLUUID mID; + LLAudioBuffer *mBufferp; // If this data is being used by the audio system, a pointer to the buffer will be set here. + bool mHasLocalData; // Set true if the encoded sound asset file is available locally + bool mHasDecodedData; // Set true if the decoded sound file is available on disk + bool mHasCompletedDecode; // Set true when the sound is decoded + bool mHasDecodeFailed; // Set true if decoding failed, meaning the sound asset is bad + bool mHasWAVLoadFailed; // Set true if loading the decoded WAV file failed, meaning the sound asset should be decoded instead if + // possible }; diff --git a/indra/llaudio/llaudioengine_fmodstudio.cpp b/indra/llaudio/llaudioengine_fmodstudio.cpp index 6a07432609a7888679b988e5da1a70843604d01f..595122ce175c1fd05546db6f1b2aa535d5b9af4d 100644 --- a/indra/llaudio/llaudioengine_fmodstudio.cpp +++ b/indra/llaudio/llaudioengine_fmodstudio.cpp @@ -69,7 +69,7 @@ inline bool Check_FMOD_Error(FMOD_RESULT result, const char *string) return true; } -bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata, const std::string& app_title) +bool LLAudioEngine_FMODSTUDIO::init(void* userdata, const std::string &app_title) { U32 version; FMOD_RESULT result; @@ -81,7 +81,7 @@ bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata, cons return false; //will call LLAudioEngine_FMODSTUDIO::allocateListener, which needs a valid mSystem pointer. - LLAudioEngine::init(num_channels, userdata, app_title); + LLAudioEngine::init(userdata, app_title); result = mSystem->getVersion(&version); Check_FMOD_Error(result, "FMOD::System::getVersion"); @@ -93,7 +93,7 @@ bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata, cons } // In this case, all sounds, PLUS wind and stream will be software. - result = mSystem->setSoftwareChannels(num_channels + EXTRA_SOUND_CHANNELS); + result = mSystem->setSoftwareChannels(LL_MAX_AUDIO_CHANNELS + EXTRA_SOUND_CHANNELS); Check_FMOD_Error(result,"FMOD::System::setSoftwareChannels"); FMOD_ADVANCEDSETTINGS adv_settings = { }; @@ -130,7 +130,7 @@ bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata, cons { LL_DEBUGS("AppInit") << "Trying PulseAudio audio output..." << LL_ENDL; if((result = mSystem->setOutput(FMOD_OUTPUTTYPE_PULSEAUDIO)) == FMOD_OK && - (result = mSystem->init(num_channels + EXTRA_SOUND_CHANNELS, fmod_flags, const_cast<char*>(app_title.c_str()))) == FMOD_OK) + (result = mSystem->init(LL_MAX_AUDIO_CHANNELS + EXTRA_SOUND_CHANNELS, fmod_flags, const_cast<char*>(app_title.c_str()))) == FMOD_OK) { LL_DEBUGS("AppInit") << "PulseAudio output initialized OKAY" << LL_ENDL; audio_ok = true; @@ -151,7 +151,7 @@ bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata, cons { LL_DEBUGS("AppInit") << "Trying ALSA audio output..." << LL_ENDL; if((result = mSystem->setOutput(FMOD_OUTPUTTYPE_ALSA)) == FMOD_OK && - (result = mSystem->init(num_channels + EXTRA_SOUND_CHANNELS, fmod_flags, 0)) == FMOD_OK) + (result = mSystem->init(LL_MAX_AUDIO_CHANNELS + EXTRA_SOUND_CHANNELS, fmod_flags, 0)) == FMOD_OK) { LL_DEBUGS("AppInit") << "ALSA audio output initialized OKAY" << LL_ENDL; audio_ok = true; @@ -192,7 +192,7 @@ bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata, cons #else // LL_LINUX // initialize the FMOD engine - result = mSystem->init( num_channels + EXTRA_SOUND_CHANNELS, fmod_flags, nullptr); + result = mSystem->init(LL_MAX_AUDIO_CHANNELS + EXTRA_SOUND_CHANNELS, fmod_flags, 0); if (result == FMOD_ERR_OUTPUT_CREATEBUFFER) { /* @@ -204,7 +204,7 @@ bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata, cons /* ... and re-init. */ - result = mSystem->init( num_channels + EXTRA_SOUND_CHANNELS, fmod_flags, nullptr); + result = mSystem->init(LL_MAX_AUDIO_CHANNELS + EXTRA_SOUND_CHANNELS, fmod_flags, 0); } if(Check_FMOD_Error(result, "Error initializing FMOD Studio")) return false; @@ -510,9 +510,9 @@ void LLAudioChannelFMODSTUDIO::update3DPosition() return; } - if (mCurrentSourcep->isAmbient()) + if (mCurrentSourcep->isForcedPriority()) { - // Ambient sound, don't need to do any positional updates. + // Prioritized UI and preview sounds don't need to do any positional updates. set3DMode(false); } else diff --git a/indra/llaudio/llaudioengine_fmodstudio.h b/indra/llaudio/llaudioengine_fmodstudio.h index 9f48ec6aab3cba59f1c7b16a371b7f5dbaf00768..89a58d3346b1a4fe41c83e6e4d72781319848cc9 100644 --- a/indra/llaudio/llaudioengine_fmodstudio.h +++ b/indra/llaudio/llaudioengine_fmodstudio.h @@ -57,7 +57,7 @@ class LLAudioEngine_FMODSTUDIO final : public LLAudioEngine virtual ~LLAudioEngine_FMODSTUDIO() = default; // initialization/startup/shutdown - bool init(const S32 num_channels, void *user_data, const std::string& app_title) final override; + virtual bool init(void *user_data, const std::string &app_title) final; std::string getDriverName(bool verbose) final override; void allocateListener() final override; diff --git a/indra/llaudio/llaudioengine_openal.cpp b/indra/llaudio/llaudioengine_openal.cpp index 142c779464323fb9311b2d05760c48fb867ecd05..0e1fb59a03e780bc6d714c544ea7f3a2a716ca2b 100644 --- a/indra/llaudio/llaudioengine_openal.cpp +++ b/indra/llaudio/llaudioengine_openal.cpp @@ -47,10 +47,10 @@ LLAudioEngine_OpenAL::LLAudioEngine_OpenAL() } // virtual -bool LLAudioEngine_OpenAL::init(const S32 num_channels, void* userdata, const std::string &app_title) +bool LLAudioEngine_OpenAL::init(void* userdata, const std::string &app_title) { mWindGen = NULL; - LLAudioEngine::init(num_channels, userdata, app_title); + LLAudioEngine::init(userdata, app_title); if(!alutInit(NULL, NULL)) { @@ -294,7 +294,7 @@ void LLAudioChannelOpenAL::update3DPosition() { return; } - if (mCurrentSourcep->isAmbient()) + if (mCurrentSourcep->isForcedPriority()) { alSource3f(mALSource, AL_POSITION, 0.0, 0.0, 0.0); alSource3f(mALSource, AL_VELOCITY, 0.0, 0.0, 0.0); diff --git a/indra/llaudio/llaudioengine_openal.h b/indra/llaudio/llaudioengine_openal.h index 29108d7a0f3b1c09e499aeb26dd91265426249c8..0a4c837315f54420a71b7d8fa41f6f26b5490de7 100644 --- a/indra/llaudio/llaudioengine_openal.h +++ b/indra/llaudio/llaudioengine_openal.h @@ -40,7 +40,7 @@ class LLAudioEngine_OpenAL final : public LLAudioEngine LLAudioEngine_OpenAL(); virtual ~LLAudioEngine_OpenAL() = default; - virtual bool init(const S32 num_channels, void *user_data, const std::string &app_title); + virtual bool init(void *user_data, const std::string &app_title); virtual std::string getDriverName(bool verbose); virtual void allocateListener(); diff --git a/indra/llaudio/llstreamingaudio_fmodstudio.cpp b/indra/llaudio/llstreamingaudio_fmodstudio.cpp index a1f54f50979eea721e987f4aa2d03cb4f95e258e..45ef7910f702b5a3357037b67b365fbc39058634 100644 --- a/indra/llaudio/llstreamingaudio_fmodstudio.cpp +++ b/indra/llaudio/llstreamingaudio_fmodstudio.cpp @@ -573,7 +573,7 @@ FMOD::Channel *LLAudioStreamManagerFMODSTUDIO::startStream() { // We need a live and opened stream before we try and play it. FMOD_OPENSTATE open_state; - if (getOpenState(open_state) != FMOD_OK || open_state != FMOD_OPENSTATE_READY) + if (!mInternetStream || (getOpenState(open_state) != FMOD_OK || open_state != FMOD_OPENSTATE_READY)) { LL_WARNS("FMOD") << "No internet stream to start playing!" << LL_ENDL; return nullptr; diff --git a/indra/llcharacter/llbvhloader.cpp b/indra/llcharacter/llbvhloader.cpp index 4f33b8d08021def5b438803f1b8687b017971186..bf1595b0f100a22317367e11fbd476ad7e28587e 100644 --- a/indra/llcharacter/llbvhloader.cpp +++ b/indra/llcharacter/llbvhloader.cpp @@ -44,6 +44,14 @@ using namespace std; #define INCHES_TO_METERS 0.02540005f +/// The .bvh does not have a formal spec, and different readers interpret things in their own way. +/// In OUR usage, frame 0 is used in optimization and is not considered to be part of the animation. +const S32 NUMBER_OF_IGNORED_FRAMES_AT_START = 1; +/// In our usage, the last frame is used only to indicate what the penultimate frame should be interpolated towards. +/// I.e., the animation only plays up to the start of the last frame. There is no hold or exptrapolation past that point.. +/// Thus there are two frame of the total that do not contribute to the total running time of the animation. +const S32 NUMBER_OF_UNPLAYED_FRAMES = NUMBER_OF_IGNORED_FRAMES_AT_START + 1; + const F32 POSITION_KEYFRAME_THRESHOLD_SQUARED = 0.03f * 0.03f; const F32 ROTATION_KEYFRAME_THRESHOLD = 0.01f; @@ -862,7 +870,10 @@ ELoadStatus LLBVHLoader::loadBVHFile(const char *buffer, char* error_text, S32 & return E_ST_NO_FRAME_TIME; } - mDuration = (F32)mNumFrames * mFrameTime; + // If the user only supplies one animation frame (after the ignored reference frame 0), hold for mFrameTime. + // If the user supples exactly one total frame, it isn't clear if that is a pose or reference frame, and the + // behavior is not defined. In this case, retain historical undefined behavior. + mDuration = llmax((F32)(mNumFrames - NUMBER_OF_UNPLAYED_FRAMES), 1.0f) * mFrameTime; if (!mLoop) { mLoopOutPoint = mDuration; @@ -1352,12 +1363,13 @@ BOOL LLBVHLoader::serialize(LLDataPacker& dp) LLQuaternion::Order order = bvhStringToOrder( joint->mOrder ); S32 outcount = 0; - S32 frame = 1; + S32 frame = 0; for ( ki = joint->mKeys.begin(); ki != joint->mKeys.end(); ++ki ) { - if ((frame == 1) && joint->mRelativeRotationKey) + + if ((frame == 0) && joint->mRelativeRotationKey) { first_frame_rot = mayaQ( ki->mRot[0], ki->mRot[1], ki->mRot[2], order); @@ -1370,7 +1382,7 @@ BOOL LLBVHLoader::serialize(LLDataPacker& dp) continue; } - time = (F32)frame * mFrameTime; + time = llmax((F32)(frame - NUMBER_OF_IGNORED_FRAMES_AT_START), 0.0f) * mFrameTime; // Time elapsed before this frame starts. if (mergeParent) { @@ -1430,12 +1442,12 @@ BOOL LLBVHLoader::serialize(LLDataPacker& dp) LLVector3 relPos = joint->mRelativePosition; LLVector3 relKey; - frame = 1; + frame = 0; for ( ki = joint->mKeys.begin(); ki != joint->mKeys.end(); ++ki ) { - if ((frame == 1) && joint->mRelativePositionKey) + if ((frame == 0) && joint->mRelativePositionKey) { relKey.setVec(ki->mPos); } @@ -1446,7 +1458,7 @@ BOOL LLBVHLoader::serialize(LLDataPacker& dp) continue; } - time = (F32)frame * mFrameTime; + time = llmax((F32)(frame - NUMBER_OF_IGNORED_FRAMES_AT_START), 0.0f) * mFrameTime; // Time elapsed before this frame starts. LLVector3 inPos = (LLVector3(ki->mPos) - relKey) * ~first_frame_rot;// * fixup_rot; LLVector3 outPos = inPos * frameRot * offsetRot; diff --git a/indra/llcharacter/llcharacter.cpp b/indra/llcharacter/llcharacter.cpp index cbcc817d5341aee7a497b312fadaf63e5b280f46..621fd814b9bc76ff309f3516ff000d677511fa8d 100644 --- a/indra/llcharacter/llcharacter.cpp +++ b/indra/llcharacter/llcharacter.cpp @@ -188,20 +188,15 @@ void LLCharacter::requestStopMotion( LLMotion* motion) //----------------------------------------------------------------------------- // updateMotions() //----------------------------------------------------------------------------- -static LLTrace::BlockTimerStatHandle FTM_UPDATE_ANIMATION("Update Animation"); -static LLTrace::BlockTimerStatHandle FTM_UPDATE_HIDDEN_ANIMATION("Update Hidden Anim"); -static LLTrace::BlockTimerStatHandle FTM_UPDATE_MOTIONS("Update Motions"); - void LLCharacter::updateMotions(e_update_t update_type) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; if (update_type == HIDDEN_UPDATE) { - LL_RECORD_BLOCK_TIME(FTM_UPDATE_HIDDEN_ANIMATION); mMotionController.updateMotionsMinimal(); } else { - LL_RECORD_BLOCK_TIME(FTM_UPDATE_ANIMATION); // unpause if the number of outstanding pause requests has dropped to the initial one if (mMotionController.isPaused() && mPauseRequest->getNumRefs() == 1) { @@ -209,7 +204,6 @@ void LLCharacter::updateMotions(e_update_t update_type) } bool force_update = (update_type == FORCE_UPDATE); { - LL_RECORD_BLOCK_TIME(FTM_UPDATE_MOTIONS); mMotionController.updateMotions(force_update); } } diff --git a/indra/llcharacter/lleditingmotion.cpp b/indra/llcharacter/lleditingmotion.cpp index c65a4bbfc87640af0d32113344bd2769397b96a1..530cea4c80f9b38f53317331bfb5609bd8baa2fa 100644 --- a/indra/llcharacter/lleditingmotion.cpp +++ b/indra/llcharacter/lleditingmotion.cpp @@ -155,6 +155,7 @@ BOOL LLEditingMotion::onActivate() //----------------------------------------------------------------------------- BOOL LLEditingMotion::onUpdate(F32 time, U8* joint_mask) { + LL_PROFILE_ZONE_SCOPED; LLVector3 focus_pt; LLVector3* pointAtPt = (LLVector3*)mCharacter->getAnimationData("PointAtPoint"); diff --git a/indra/llcharacter/lleditingmotion.h b/indra/llcharacter/lleditingmotion.h index 418eca7d2b048bd7b9249fdc7af5c3657aa7ef6e..89ad764e4ac519e6cc4e8fc2eda3c38bdcb84e42 100644 --- a/indra/llcharacter/lleditingmotion.h +++ b/indra/llcharacter/lleditingmotion.h @@ -42,9 +42,11 @@ //----------------------------------------------------------------------------- // class LLEditingMotion //----------------------------------------------------------------------------- +LL_ALIGN_PREFIX(16) class LLEditingMotion final : public LLMotion { + LL_ALIGN_NEW public: // Constructor LLEditingMotion(const LLUUID &id); @@ -108,6 +110,13 @@ class LLEditingMotion final : //------------------------------------------------------------------------- // joint states to be animated //------------------------------------------------------------------------- + LL_ALIGN_16(LLJoint mParentJoint); + LL_ALIGN_16(LLJoint mShoulderJoint); + LL_ALIGN_16(LLJoint mElbowJoint); + LL_ALIGN_16(LLJoint mWristJoint); + LL_ALIGN_16(LLJoint mTarget); + LLJointSolverRP3 mIKSolver; + LLCharacter *mCharacter; LLVector3 mWristOffset; @@ -117,17 +126,10 @@ class LLEditingMotion final : LLPointer<LLJointState> mWristState; LLPointer<LLJointState> mTorsoState; - LLJoint mParentJoint; - LLJoint mShoulderJoint; - LLJoint mElbowJoint; - LLJoint mWristJoint; - LLJoint mTarget; - LLJointSolverRP3 mIKSolver; - static S32 sHandPose; static S32 sHandPosePriority; LLVector3 mLastSelectPt; -}; +} LL_ALIGN_POSTFIX(16); #endif // LL_LLKEYFRAMEMOTION_H diff --git a/indra/llcharacter/llhandmotion.cpp b/indra/llcharacter/llhandmotion.cpp index ac94d552e170598f9503ffb9ae20e474fc546f08..f87553815a646067f1d7406b353428155e296001 100644 --- a/indra/llcharacter/llhandmotion.cpp +++ b/indra/llcharacter/llhandmotion.cpp @@ -113,6 +113,7 @@ BOOL LLHandMotion::onActivate() //----------------------------------------------------------------------------- BOOL LLHandMotion::onUpdate(F32 time, U8* joint_mask) { + LL_PROFILE_ZONE_SCOPED; eHandPose *requestedHandPose; F32 timeDelta = time - mLastTime; diff --git a/indra/llcharacter/llheadrotmotion.cpp b/indra/llcharacter/llheadrotmotion.cpp index 6d5d2fef65e08788513430c1dc8dd25778350025..4e056c78c2aab78cecd51e2822603a4aae6fab76 100644 --- a/indra/llcharacter/llheadrotmotion.cpp +++ b/indra/llcharacter/llheadrotmotion.cpp @@ -167,6 +167,7 @@ BOOL LLHeadRotMotion::onActivate() //----------------------------------------------------------------------------- BOOL LLHeadRotMotion::onUpdate(F32 time, U8* joint_mask) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; LLQuaternion targetHeadRotWorld; LLQuaternion currentRootRotWorld = mRootJoint->getWorldRotation(); LLQuaternion currentInvRootRotWorld = ~currentRootRotWorld; @@ -442,6 +443,7 @@ void LLEyeMotion::adjustEyeTarget(LLVector3* targetPos, LLJointState& left_eye_s //----------------------------------------------------------------------------- BOOL LLEyeMotion::onUpdate(F32 time, U8* joint_mask) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; //calculate jitter if (mEyeJitterTimer.getElapsedTimeF32() > mEyeJitterTime) { diff --git a/indra/llcharacter/lljoint.cpp b/indra/llcharacter/lljoint.cpp index 215e0e7186b80948b1d75ac0cac8d118b1fb985e..698d5d65c4ef73a82aa1f4a10eb26c9bcdf9bdc2 100644 --- a/indra/llcharacter/lljoint.cpp +++ b/indra/llcharacter/lljoint.cpp @@ -884,7 +884,7 @@ void LLJoint::setWorldRotation( const LLQuaternion& rot ) LLMatrix4a temp_mat(rota); LLMatrix4a invParentWorldMatrix = mParent->getWorldMatrix(); - invParentWorldMatrix.setTranslate_affine(LLVector3(0.f)); + invParentWorldMatrix.setTranslate_affine(LLVector3(0.f, 0.f, 0.f)); invParentWorldMatrix.invert(); @@ -950,6 +950,13 @@ const LLMatrix4a &LLJoint::getWorldMatrix() return mXform.getWorldMatrix(); } +const LLMatrix4a& LLJoint::getWorldMatrix4a() +{ + updateWorldMatrixParent(); + + return mWorldMatrix; +} + //-------------------------------------------------------------------- // setWorldMatrix() @@ -1031,6 +1038,7 @@ void LLJoint::updateWorldMatrix() { sNumUpdates++; mXform.updateMatrix(FALSE); + mWorldMatrix = mXform.getWorldMatrix(); mDirtyFlags = 0x0; } } diff --git a/indra/llcharacter/lljoint.h b/indra/llcharacter/lljoint.h index 6de398ac7d122d4443cfbf38cba3d543392c4786..f0fb5826a5900614f5422f0f22cf0db9be4434ee 100644 --- a/indra/llcharacter/lljoint.h +++ b/indra/llcharacter/lljoint.h @@ -39,6 +39,7 @@ #include "llmatrix4a.h" #include "llquaternion.h" #include "xform.h" +#include "llmatrix4a.h" class LLViewerJoint; class LLViewerJointAttachment; @@ -89,8 +90,10 @@ inline bool operator!=(const LLVector3OverrideMap& a, const LLVector3OverrideMap //----------------------------------------------------------------------------- // class LLJoint //----------------------------------------------------------------------------- +LL_ALIGN_PREFIX(16) class LLJoint { + LL_ALIGN_NEW public: // priority levels, from highest to lowest enum JointPriority @@ -118,16 +121,17 @@ class LLJoint SUPPORT_EXTENDED }; protected: - std::string mName; + // explicit transformation members + LL_ALIGN_16(LLMatrix4a mWorldMatrix); + LLXformMatrix mXform; + + std::string mName; SupportCategory mSupport; // parent joint LLJoint *mParent; - // explicit transformation members - LLXformMatrix mXform; - LLVector3 mDefaultPosition; LLVector3 mDefaultScale; @@ -266,6 +270,8 @@ class LLJoint const LLMatrix4a& getWorldMatrix(); void setWorldMatrix( const LLMatrix4& mat ); + const LLMatrix4a& getWorldMatrix4a(); + void updateWorldMatrixChildren(); void updateWorldMatrixParent(); @@ -303,6 +309,6 @@ class LLJoint // These are used in checks of whether a pos/scale override is considered significant. bool aboveJointPosThreshold(const LLVector3& pos) const; bool aboveJointScaleThreshold(const LLVector3& scale) const; -}; +} LL_ALIGN_POSTFIX(16); #endif // LL_LLJOINT_H diff --git a/indra/llcharacter/lljointsolverrp3.cpp b/indra/llcharacter/lljointsolverrp3.cpp index 083839c3ce3d2b4b61abf0c85aa89ffa32088c56..589f8415c95605afc32d0076286d5e4deb7bf409 100644 --- a/indra/llcharacter/lljointsolverrp3.cpp +++ b/indra/llcharacter/lljointsolverrp3.cpp @@ -1,6 +1,6 @@ /** * @file lljointsolverrp3.cpp - * @brief Implementation of LLJointSolverRP3 class. + * @brief Implementation of Joint Solver in 3D Real Projective space (RP3). See: https://en.wikipedia.org/wiki/Real_projective_space * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code @@ -35,6 +35,11 @@ #define F_EPSILON 0.00001f +#if LL_RELEASE + #define DEBUG_JOINT_SOLVER 0 +#else + #define DEBUG_JOINT_SOLVER 1 +#endif //----------------------------------------------------------------------------- // Constructor @@ -142,7 +147,7 @@ void LLJointSolverRP3::solve() LLVector3 cPos = mJointC->getWorldPosition(); LLVector3 gPos = mJointGoal->getWorldPosition(); -#ifdef SHOW_DEBUG +#if DEBUG_JOINT_SOLVER LL_DEBUGS("JointSolver") << "LLJointSolverRP3::solve()" << LL_NEWLINE << "bPosLocal = " << mJointB->getPosition() << LL_NEWLINE << "cPosLocal = " << mJointC->getPosition() << LL_NEWLINE @@ -190,7 +195,7 @@ void LLJointSolverRP3::solve() //------------------------------------------------------------------------- LLVector3 abacCompOrthoVec = abVec - acVec * ((abVec * acVec)/(acVec * acVec)); -#ifdef SHOW_DEBUG +#if DEBUG_JOINT_SOLVER LL_DEBUGS("JointSolver") << "abVec : " << abVec << LL_NEWLINE << "bcVec : " << bcVec << LL_NEWLINE << "acVec : " << acVec << LL_NEWLINE @@ -267,7 +272,7 @@ void LLJointSolverRP3::solve() LLQuaternion bRot(theta - abbcAng, abbcOrthoVec); -#ifdef SHOW_DEBUG +#if DEBUG_JOINT_SOLVER LL_DEBUGS("JointSolver") << "abbcAng : " << abbcAng << LL_NEWLINE << "abbcOrthoVec : " << abbcOrthoVec << LL_NEWLINE << "agLenSq : " << agLenSq << LL_NEWLINE @@ -293,7 +298,7 @@ void LLJointSolverRP3::solve() LLQuaternion cgRot; cgRot.shortestArc( acVec, agVec ); -#ifdef SHOW_DEBUG +#if DEBUG_JOINT_SOLVER LL_DEBUGS("JointSolver") << "bcVec : " << bcVec << LL_NEWLINE << "acVec : " << acVec << LL_NEWLINE << "cgRot : " << cgRot << LL_ENDL; @@ -360,7 +365,7 @@ void LLJointSolverRP3::solve() //------------------------------------------------------------------------- LLQuaternion twistRot( mTwist, agVec ); -#ifdef SHOW_DEBUG +#if DEBUG_JOINT_SOLVER LL_DEBUGS("JointSolver") << "abcNorm = " << abcNorm << LL_NEWLINE << "apgNorm = " << apgNorm << LL_NEWLINE << "pRot = " << pRot << LL_NEWLINE diff --git a/indra/llcharacter/llkeyframefallmotion.cpp b/indra/llcharacter/llkeyframefallmotion.cpp index e3ff1123ed46edd2480b19142158d53d01de636f..f7cade05a11c188969055fa5c870d7a5ad4bd069 100644 --- a/indra/llcharacter/llkeyframefallmotion.cpp +++ b/indra/llcharacter/llkeyframefallmotion.cpp @@ -112,6 +112,7 @@ BOOL LLKeyframeFallMotion::onActivate() //----------------------------------------------------------------------------- BOOL LLKeyframeFallMotion::onUpdate(F32 activeTime, U8* joint_mask) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; BOOL result = LLKeyframeMotion::onUpdate(activeTime, joint_mask); F32 slerp_amt = clamp_rescale(activeTime / getDuration(), 0.5f, 0.75f, 0.f, 1.f); diff --git a/indra/llcharacter/llkeyframemotion.cpp b/indra/llcharacter/llkeyframemotion.cpp index af94cce3c4d4f1009f6903ddd99d72f83331e2f9..e0a8eade8970279642580dfb9d270b6c868ffe6a 100644 --- a/indra/llcharacter/llkeyframemotion.cpp +++ b/indra/llcharacter/llkeyframemotion.cpp @@ -434,6 +434,7 @@ BOOL LLKeyframeMotion::onActivate() //----------------------------------------------------------------------------- BOOL LLKeyframeMotion::onUpdate(F32 time, U8* joint_mask) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; // llassert(time >= 0.f); // This will fire time = llmax(0.f, time); @@ -978,8 +979,11 @@ void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8 //----------------------------------------------------------------------------- // deserialize() +// +// allow_invalid_joints should be true when handling existing content, to avoid breakage. +// During upload, we should be more restrictive and reject such animations. //----------------------------------------------------------------------------- -BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id) +BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, bool allow_invalid_joints) { BOOL old_version = FALSE; auto joint_motion_list = std::make_unique<LLKeyframeMotion::JointMotionList>(); @@ -1100,6 +1104,15 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id) return FALSE; } + //SL-17206 hack to alter Female_land loop setting, while current behavior won't be changed serverside + LLUUID const female_land_anim("ca1baf4d-0a18-5a1f-0330-e4bd1e71f09e"); + LLUUID const formal_female_land_anim("6a9a173b-61fa-3ad5-01fa-a851cfc5f66a"); + 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; + } + //------------------------------------------------------------------------- // get easeIn and easeOut //------------------------------------------------------------------------- @@ -1199,6 +1212,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id) if (joint) { S32 joint_num = joint->getJointNum(); + joint_name = joint->getName(); // canonical name in case this is an alias. // LL_INFOS() << " joint: " << joint_name << LL_ENDL; if ((joint_num >= (S32)LL_CHARACTER_MAX_ANIMATED_JOINTS) || (joint_num < 0)) { @@ -1213,7 +1227,10 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id) { LL_WARNS() << "invalid joint name: " << joint_name << " for animation " << asset_id << LL_ENDL; - //return FALSE; + if (!allow_invalid_joints) + { + return FALSE; + } } joint_motion->mJointName = std::move(joint_name); // Do not use joint_name after this point. @@ -1864,8 +1881,9 @@ U32 LLKeyframeMotion::getFileSize() //----------------------------------------------------------------------------- // dumpToFile() //----------------------------------------------------------------------------- -void LLKeyframeMotion::dumpToFile(const std::string& name) +bool LLKeyframeMotion::dumpToFile(const std::string& name) { + bool succ = false; if (isLoaded()) { std::string outfile_base; @@ -1882,10 +1900,24 @@ void LLKeyframeMotion::dumpToFile(const std::string& name) const LLUUID& id = getID(); outfile_base = id.asString(); } - std::string outfilename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfile_base + ".anim"); + + if (gDirUtilp->getExtension(outfile_base).empty()) + { + outfile_base += ".anim"; + } + std::string outfilename; + if (gDirUtilp->getDirName(outfile_base).empty()) + { + outfilename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfile_base); + } + else + { + outfilename = outfile_base; + } if (LLFile::isfile(outfilename)) { - return; + LL_WARNS() << outfilename << " already exists, write failed" << LL_ENDL; + return false; } S32 file_size = getFileSize(); @@ -1899,11 +1931,13 @@ void LLKeyframeMotion::dumpToFile(const std::string& name) outfile.open(outfilename, LL_APR_WPB); if (outfile.getFileHandle()) { - outfile.write(buffer, file_size); + S32 wrote_bytes = outfile.write(buffer, file_size); + succ = (wrote_bytes == file_size); } } delete [] buffer; } + return succ; } //----------------------------------------------------------------------------- diff --git a/indra/llcharacter/llkeyframemotion.h b/indra/llcharacter/llkeyframemotion.h index 7a6c0366cbbccf1f01e5ea102bb102f77d2e0255..23a6cdff7ec82ad39e1615fb22217672e2108de8 100644 --- a/indra/llcharacter/llkeyframemotion.h +++ b/indra/llcharacter/llkeyframemotion.h @@ -174,9 +174,9 @@ class LLKeyframeMotion : public: U32 getFileSize(); BOOL serialize(LLDataPacker& dp) const; - BOOL deserialize(LLDataPacker& dp, const LLUUID& asset_id); + BOOL deserialize(LLDataPacker& dp, const LLUUID& asset_id, bool allow_invalid_joints = true); BOOL isLoaded() { return mJointMotionList != NULL; } - void dumpToFile(const std::string& name); + bool dumpToFile(const std::string& name); // setters for modifying a keyframe animation @@ -433,6 +433,9 @@ class LLKeyframeMotion : F32 mLastUpdateTime; F32 mLastLoopedTime; AssetStatus mAssetStatus; + +public: + void setCharacter(LLCharacter* character) { mCharacter = character; } }; class LLKeyframeDataCache diff --git a/indra/llcharacter/llkeyframestandmotion.h b/indra/llcharacter/llkeyframestandmotion.h index 7f516b942723cf3fba0ba8c0a8072088f91a840b..89f7a1615503f148a2861f1c42af4748b426d59b 100644 --- a/indra/llcharacter/llkeyframestandmotion.h +++ b/indra/llcharacter/llkeyframestandmotion.h @@ -37,9 +37,11 @@ //----------------------------------------------------------------------------- // class LLKeyframeStandMotion //----------------------------------------------------------------------------- +LL_ALIGN_PREFIX(16) class LLKeyframeStandMotion final : public LLKeyframeMotion { + LL_ALIGN_NEW public: // Constructor LLKeyframeStandMotion(const LLUUID &id); @@ -69,6 +71,18 @@ class LLKeyframeStandMotion final : //------------------------------------------------------------------------- // Member Data //------------------------------------------------------------------------- + LLJoint mPelvisJoint; + + LLJoint mHipLeftJoint; + LLJoint mKneeLeftJoint; + LLJoint mAnkleLeftJoint; + LLJoint mTargetLeft; + + LLJoint mHipRightJoint; + LLJoint mKneeRightJoint; + LLJoint mAnkleRightJoint; + LLJoint mTargetRight; + LLCharacter *mCharacter; BOOL mFlipFeet; @@ -83,18 +97,6 @@ class LLKeyframeStandMotion final : LLPointer<LLJointState> mKneeRightState; LLPointer<LLJointState> mAnkleRightState; - LLJoint mPelvisJoint; - - LLJoint mHipLeftJoint; - LLJoint mKneeLeftJoint; - LLJoint mAnkleLeftJoint; - LLJoint mTargetLeft; - - LLJoint mHipRightJoint; - LLJoint mKneeRightJoint; - LLJoint mAnkleRightJoint; - LLJoint mTargetRight; - LLJointSolverRP3 mIKLeft; LLJointSolverRP3 mIKRight; @@ -110,7 +112,7 @@ class LLKeyframeStandMotion final : BOOL mTrackAnkles; S32 mFrameNum; -}; +} LL_ALIGN_POSTFIX(16); #endif // LL_LLKEYFRAMESTANDMOTION_H diff --git a/indra/llcharacter/llkeyframewalkmotion.cpp b/indra/llcharacter/llkeyframewalkmotion.cpp index 565a009212f89c3b2a5d039f7467e77d6d46ef39..f0f2691c53551b21e1918c7641e0102f097c4d91 100644 --- a/indra/llcharacter/llkeyframewalkmotion.cpp +++ b/indra/llcharacter/llkeyframewalkmotion.cpp @@ -97,6 +97,7 @@ void LLKeyframeWalkMotion::onDeactivate() //----------------------------------------------------------------------------- BOOL LLKeyframeWalkMotion::onUpdate(F32 time, U8* joint_mask) { + LL_PROFILE_ZONE_SCOPED; // compute time since last update F32 deltaTime = time - mRealTimeLast; @@ -190,6 +191,7 @@ BOOL LLWalkAdjustMotion::onActivate() //----------------------------------------------------------------------------- BOOL LLWalkAdjustMotion::onUpdate(F32 time, U8* joint_mask) { + LL_PROFILE_ZONE_SCOPED; // delta_time is guaranteed to be non zero F32 delta_time = llclamp(time - mLastTime, TIME_EPSILON, MAX_TIME_DELTA); mLastTime = time; @@ -366,6 +368,7 @@ BOOL LLFlyAdjustMotion::onActivate() //----------------------------------------------------------------------------- BOOL LLFlyAdjustMotion::onUpdate(F32 time, U8* joint_mask) { + LL_PROFILE_ZONE_SCOPED; LLVector3 ang_vel = mCharacter->getCharacterAngularVelocity() * mCharacter->getTimeDilation(); F32 speed = mCharacter->getCharacterVelocity().magVec(); diff --git a/indra/llcharacter/llmotioncontroller.cpp b/indra/llcharacter/llmotioncontroller.cpp index 853f53cc9db43d5b10f0b7939398384c93f086b3..05281c9bba1e9c7d3f189d3434cdb9e397dbe6bb 100644 --- a/indra/llcharacter/llmotioncontroller.cpp +++ b/indra/llcharacter/llmotioncontroller.cpp @@ -494,6 +494,7 @@ void LLMotionController::resetJointSignatures() //----------------------------------------------------------------------------- void LLMotionController::updateIdleMotion(LLMotion* motionp) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; if (motionp->isStopped() && mAnimTime > motionp->getStopTime() + motionp->getEaseOutDuration()) { deactivateMotionInstance(motionp); @@ -532,6 +533,7 @@ void LLMotionController::updateIdleMotion(LLMotion* motionp) //----------------------------------------------------------------------------- void LLMotionController::updateIdleActiveMotions() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; for (motion_list_t::iterator iter = mActiveMotions.begin(); iter != mActiveMotions.end(); ) { @@ -544,10 +546,9 @@ void LLMotionController::updateIdleActiveMotions() //----------------------------------------------------------------------------- // updateMotionsByType() //----------------------------------------------------------------------------- -static LLTrace::BlockTimerStatHandle FTM_MOTION_ON_UPDATE("Motion onUpdate"); - void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_type) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; BOOL update_result = TRUE; U8 last_joint_signature[LL_CHARACTER_MAX_ANIMATED_JOINTS]; @@ -703,7 +704,6 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty // perform motion update { - LL_RECORD_BLOCK_TIME(FTM_MOTION_ON_UPDATE); update_result = motionp->onUpdate(mAnimTime - motionp->mActivationTimestamp, last_joint_signature); } } @@ -759,6 +759,7 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty //----------------------------------------------------------------------------- void LLMotionController::updateLoadingMotions() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; // query pending motions for completion for (motion_set_t::iterator iter = mLoadingMotions.begin(); iter != mLoadingMotions.end(); ) @@ -806,6 +807,7 @@ void LLMotionController::updateLoadingMotions() //----------------------------------------------------------------------------- void LLMotionController::updateMotions(bool force_update) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; // SL-763: "Distant animated objects run at super fast speed" // The use_quantum optimization or possibly the associated code in setTimeStamp() // does not work as implemented. @@ -898,6 +900,7 @@ void LLMotionController::updateMotions(bool force_update) //----------------------------------------------------------------------------- void LLMotionController::updateMotionsMinimal() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; // Always update mPrevTimerElapsed mPrevTimerElapsed = mTimer.getElapsedTimeF32(); @@ -915,6 +918,7 @@ void LLMotionController::updateMotionsMinimal() //----------------------------------------------------------------------------- BOOL LLMotionController::activateMotionInstance(LLMotion *motion, F32 time) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; // It's not clear why the getWeight() line seems to be crashing this, but // hopefully this fixes it. if (motion == NULL || motion->getPose() == NULL) diff --git a/indra/llcharacter/llpose.h b/indra/llcharacter/llpose.h index ba23ad489f55957c7902bf5d44f6a19ad54c4f78..5ca078ada6f88ff833f67f684815cf937b329734 100644 --- a/indra/llcharacter/llpose.h +++ b/indra/llcharacter/llpose.h @@ -82,8 +82,10 @@ class LLPose const S32 JSB_NUM_JOINT_STATES = 6; +LL_ALIGN_PREFIX(16) class LLJointStateBlender { + LL_ALIGN_NEW protected: LLPointer<LLJointState> mJointStates[JSB_NUM_JOINT_STATES]; S32 mPriorities[JSB_NUM_JOINT_STATES]; @@ -98,8 +100,8 @@ class LLJointStateBlender void resetCachedJoint(); public: - LLJoint mJointCache; -}; + LL_ALIGN_16(LLJoint mJointCache); +} LL_ALIGN_POSTFIX(16); class LLMotion; diff --git a/indra/llcharacter/lltargetingmotion.cpp b/indra/llcharacter/lltargetingmotion.cpp index e7331a68386dcce3a01a9971085ad734d949ac48..a3286c7d27cd049883214bf1f47a8410b3568cd4 100644 --- a/indra/llcharacter/lltargetingmotion.cpp +++ b/indra/llcharacter/lltargetingmotion.cpp @@ -95,6 +95,7 @@ BOOL LLTargetingMotion::onActivate() //----------------------------------------------------------------------------- BOOL LLTargetingMotion::onUpdate(F32 time, U8* joint_mask) { + LL_PROFILE_ZONE_SCOPED; F32 slerp_amt = LLSmoothInterpolation::getInterpolant(TORSO_TARGET_HALF_LIFE); LLVector3 target; diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 9332ae5538487c9b56d437048b281d2faee28654..1c0f61ab470324e48c06e2fa6ca43e35b36ff533 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -11,16 +11,18 @@ include(Boost) include(Sentry) include(LLSharedLibs) include(Copy3rdPartyLibs) -include(ZLIB) +include(ZLIBNG) include(URIPARSER) +include(Tracy) include(OpenSSL) include_directories( ${EXPAT_INCLUDE_DIRS} ${LLCOMMON_INCLUDE_DIRS} ${LLMATH_INCLUDE_DIRS} - ${ZLIB_INCLUDE_DIRS} + ${ZLIBNG_INCLUDE_DIRS} ${URIPARSER_INCLUDE_DIRS} + ${TRACY_INCLUDE_DIR} ) # add_executable(lltreeiterators lltreeiterators.cpp) @@ -118,14 +120,17 @@ set(llcommon_SOURCE_FILES lluriparser.cpp lluuid.cpp llworkerthread.cpp - timing.cpp u64.cpp + threadpool.cpp + workqueue.cpp StackWalker.cpp ) set(llcommon_HEADER_FILES CMakeLists.txt + chrono.h + classic_callback.h ctype_workaround.h fix_macros.h indra_constants.h @@ -198,6 +203,8 @@ set(llcommon_HEADER_FILES llmutex.h llnametable.h llpointer.h + llprofiler.h + llprofilercategories.h llpounceable.h llpredicate.h llpreprocessor.h @@ -253,10 +260,19 @@ set(llcommon_HEADER_FILES lockstatic.h stdtypes.h stringize.h + threadpool.h + threadsafeschedule.h timer.h + tuple.h u64.h + workqueue.h StackWalker.h ) + +if (DARWIN) + list(APPEND llcommon_HEADER_FILES llsys_objc.h) + list(APPEND llcommon_SOURCE_FILES llsys_objc.mm) +endif (DARWIN) if (DARWIN) list(APPEND llcommon_HEADER_FILES llsys_objc.h) @@ -287,7 +303,7 @@ target_link_libraries( ${APR_LIBRARIES} ${EXPAT_LIBRARIES} ${OPENSSL_LIBRARIES} - ${ZLIB_LIBRARIES} + ${ZLIBNG_LIBRARIES} ${WINDOWS_LIBRARIES} ${BOOST_FIBER_LIBRARY} ${BOOST_CONTEXT_LIBRARY} @@ -305,6 +321,7 @@ target_link_libraries( absl::strings nlohmann_json::nlohmann_json fmt::fmt + ${TRACY_LIBRARY} ${DL_LIBRARY} ${RT_LIBRARY} ) @@ -347,18 +364,19 @@ if (LL_TESTS) ${BOOST_THREAD_LIBRARY} ${BOOST_SYSTEM_LIBRARY} ${OPENSSL_LIBRARIES} - ${ZLIB_LIBRARIES} + ${ZLIBNG_LIBRARIES} ) - LL_ADD_INTEGRATION_TEST(commonmisc "" "${test_libs}") LL_ADD_INTEGRATION_TEST(bitpack "" "${test_libs}") + LL_ADD_INTEGRATION_TEST(classic_callback "" "${test_libs}") + LL_ADD_INTEGRATION_TEST(commonmisc "" "${test_libs}") LL_ADD_INTEGRATION_TEST(llbase64 "" "${test_libs}") LL_ADD_INTEGRATION_TEST(llcond "" "${test_libs}") LL_ADD_INTEGRATION_TEST(lldate "" "${test_libs}") LL_ADD_INTEGRATION_TEST(lldeadmantimer "" "${test_libs}") LL_ADD_INTEGRATION_TEST(lldependencies "" "${test_libs}") LL_ADD_INTEGRATION_TEST(llerror "" "${test_libs}") - LL_ADD_INTEGRATION_TEST(lleventdispatcher "" "${test_libs}") LL_ADD_INTEGRATION_TEST(lleventcoro "" "${test_libs}") + LL_ADD_INTEGRATION_TEST(lleventdispatcher "" "${test_libs}") LL_ADD_INTEGRATION_TEST(lleventfilter "" "${test_libs}") LL_ADD_INTEGRATION_TEST(llframetimer "" "${test_libs}") LL_ADD_INTEGRATION_TEST(llheteromap "" "${test_libs}") @@ -376,9 +394,12 @@ if (LL_TESTS) LL_ADD_INTEGRATION_TEST(llstring "" "${test_libs}") LL_ADD_INTEGRATION_TEST(lltrace "" "${test_libs}") LL_ADD_INTEGRATION_TEST(lltreeiterators "" "${test_libs}") - LL_ADD_INTEGRATION_TEST(lluri "" "${test_libs}") LL_ADD_INTEGRATION_TEST(llunits "" "${test_libs}") + LL_ADD_INTEGRATION_TEST(lluri "" "${test_libs}") LL_ADD_INTEGRATION_TEST(stringize "" "${test_libs}") + LL_ADD_INTEGRATION_TEST(threadsafeschedule "" "${test_libs}") + LL_ADD_INTEGRATION_TEST(tuple "" "${test_libs}") + LL_ADD_INTEGRATION_TEST(workqueue "" "${test_libs}") ## llexception_test.cpp isn't a regression test, and doesn't need to be run ## every build. It's to help a developer make implementation choices about diff --git a/indra/llcommon/chrono.h b/indra/llcommon/chrono.h new file mode 100644 index 0000000000000000000000000000000000000000..806e871892e4b38b352cb911740757aac5b986c1 --- /dev/null +++ b/indra/llcommon/chrono.h @@ -0,0 +1,65 @@ +/** + * @file chrono.h + * @author Nat Goodspeed + * @date 2021-10-05 + * @brief supplement <chrono> with utility functions + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$ + * Copyright (c) 2021, Linden Research, Inc. + * $/LicenseInfo$ + */ + +#if ! defined(LL_CHRONO_H) +#define LL_CHRONO_H + +#include <chrono> +#include <type_traits> // std::enable_if + +namespace LL +{ + +// time_point_cast() is derived from https://stackoverflow.com/a/35293183 +// without the iteration: we think errors in the ~1 microsecond range are +// probably acceptable. + +// This variant is for the optimal case when the source and dest use the same +// clock: that case is handled by std::chrono. +template <typename DestTimePoint, typename SrcTimePoint, + typename std::enable_if<std::is_same<typename DestTimePoint::clock, + typename SrcTimePoint::clock>::value, + bool>::type = true> +DestTimePoint time_point_cast(const SrcTimePoint& time) +{ + return std::chrono::time_point_cast<typename DestTimePoint::duration>(time); +} + +// This variant is for when the source and dest use different clocks -- see +// the linked StackOverflow answer, also Howard Hinnant's, for more context. +template <typename DestTimePoint, typename SrcTimePoint, + typename std::enable_if<! std::is_same<typename DestTimePoint::clock, + typename SrcTimePoint::clock>::value, + bool>::type = true> +DestTimePoint time_point_cast(const SrcTimePoint& time) +{ + // The basic idea is that we must adjust the passed time_point by the + // difference between the clocks' epochs. But since time_point doesn't + // expose its epoch, we fall back on what each of them thinks is now(). + // However, since we necessarily make sequential calls to those now() + // functions, the answers differ not only by the cycles spent executing + // those calls, but by potential OS interruptions between them. Try to + // reduce that error by capturing the source clock time both before and + // after the dest clock, and splitting the difference. Of course an + // interruption between two of these now() calls without a comparable + // interruption between the other two will skew the result, but better is + // more expensive. + const auto src_before = typename SrcTimePoint::clock::now(); + const auto dest_now = typename DestTimePoint::clock::now(); + const auto src_after = typename SrcTimePoint::clock::now(); + const auto src_diff = src_after - src_before; + const auto src_now = src_before + src_diff / 2; + return dest_now + (time - src_now); +} + +} // namespace LL + +#endif /* ! defined(LL_CHRONO_H) */ diff --git a/indra/llcommon/classic_callback.cpp b/indra/llcommon/classic_callback.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5674e0a44dac169a6bca5b73f301707759a4dead --- /dev/null +++ b/indra/llcommon/classic_callback.cpp @@ -0,0 +1,16 @@ +/** + * @file classic_callback.cpp + * @author Nat Goodspeed + * @date 2021-09-23 + * @brief Implementation for classic_callback. + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$ + * Copyright (c) 2021, Linden Research, Inc. + * $/LicenseInfo$ + */ + +namespace { + +const char dummy[] = "cpp file required to build test program"; + +} // anonymous namespace diff --git a/indra/llcommon/classic_callback.h b/indra/llcommon/classic_callback.h new file mode 100644 index 0000000000000000000000000000000000000000..1ad6dbc58fde86d77d461538297c2c9793f61dfb --- /dev/null +++ b/indra/llcommon/classic_callback.h @@ -0,0 +1,292 @@ +/** + * @file classic_callback.h + * @author Nat Goodspeed + * @date 2016-06-21 + * @brief ClassicCallback and HeapClassicCallback + * + * This header file addresses the problem of passing a method on a C++ object + * to an API that requires a classic-C function pointer. Typically such a + * callback API accepts a void* pointer along with the function pointer, and + * the function pointer signature accepts a void* parameter. The API passes + * the caller's pointer value into the callback function so it can find its + * data. In C++, there are a few ways to deal with this case: + * + * - Use a static method with correct signature. If you don't need access to a + * specific instance, that works fine. + * - Store the object statically (or store a static pointer to a non-static + * instance). As long as you only care about one instance, that works, but + * starts to get a little icky. As soon as there's more than one pertinent + * instance, fight valiantly against the temptation to stuff the instance + * pointer into a static pointer variable "just for a moment." + * - Code a static trampoline callback function that accepts the void* user + * data pointer, casts it to the appropriate class type and calls the actual + * method on that class. + * + * ClassicCallback encapsulates the last. You need only construct a + * ClassicCallback instance somewhere that will survive until the callback is + * called, binding the target C++ callable. You then call its get_callback() + * and get_userdata() methods to pass an appropriate classic-C function + * pointer and void* user data pointer, respectively, to the old-style + * callback API. get_callback() synthesizes a static trampoline function + * that casts the user data pointer and calls the bound C++ callable. + * + * $LicenseInfo:firstyear=2016&license=viewerlgpl$ + * Copyright (c) 2016, Linden Research, Inc. + * $/LicenseInfo$ + */ + +#if ! defined(LL_CLASSIC_CALLBACK_H) +#define LL_CLASSIC_CALLBACK_H + +#include <tuple> +#include <type_traits> // std::is_same + +/***************************************************************************** +* Helpers +*****************************************************************************/ + +// find a type in a parameter pack: http://stackoverflow.com/q/17844867/5533635 +// usage: index_of<0, sought_t, PackName...>::value +template <int idx, typename sought, typename candidate, typename ...rest> +struct index_of +{ + static constexpr int const value = + std::is_same<sought, candidate>::value ? + idx : index_of<idx + 1, sought, rest...>::value; +}; + +// recursion tail +template <int idx, typename sought, typename candidate> +struct index_of<idx, sought, candidate> +{ + static constexpr int const value = + std::is_same<sought, candidate>::value ? idx : -1; +}; + +/***************************************************************************** +* ClassicCallback +*****************************************************************************/ +/** + * Instantiate ClassicCallback in whatever storage will persist long enough + * for the callback to be called. It holds a modern C++ callable, providing a + * static function pointer and a USERDATA (default void*) capable of being + * passed through a classic-C callback API. When the static function is called + * with that USERDATA pointer, ClassicCallback forwards the call to the bound + * C++ callable. + * + * Usage: + * @code + * // callback signature required by the API of interest + * typedef void (*callback_t)(int, const char*, void*, double); + * // old-style API that accepts a classic-C callback function pointer + * void oldAPI(callback_t callback, void* userdata); + * // but I want to pass a lambda that references data local to my function! + * // (We don't need to name the void* parameter in the C++ callable; + * // ClassicCallback already used it to locate the lambda instance.) + * auto ccb{ + * makeClassicCallback<callback_t>( + * [=](int n, const char* s, void*, double f){ ... }) }; + * oldAPI(ccb.get_callback(), ccb.get_userdata()); + * // If the passed callback is called before oldAPI() returns, we can now + * // safely destroy ccb. If the callback might be called later, consider + * // HeapClassicCallback instead. + * @endcode + * + * If you have a callable object in hand, and you want to pass that to + * ClassicCallback, you may either consume it by passing std::move(object), or + * explicitly specify a reference to that object type as the CALLABLE template + * parameter: + * @code + * CallableObject obj; + * ClassicCallback<callback_t, void*, CallableObject&> ccb{obj}; + * @endcode + */ +// CALLABLE should either be deduced, e.g. by makeClassicCallback(), or +// specified explicitly. Its default type is meaningless, coded only so we can +// provide a useful default for USERDATA. +template <typename SIGNATURE, typename USERDATA=void*, typename CALLABLE=void(*)()> +class ClassicCallback +{ + typedef ClassicCallback<SIGNATURE, USERDATA, CALLABLE> self_t; + +public: + /// ClassicCallback binds any modern C++ callable. + ClassicCallback(CALLABLE&& callable): + mCallable(std::forward<CALLABLE>(callable)) + {} + + /** + * ClassicCallback must not itself be copied or moved! Once you've passed + * get_userdata() to some API, this object MUST remain at that address. + */ + // However, we can't yet count on C++17 Class Template Argument Deduction, + // which means makeClassicCallback() is still useful, which means we MUST + // be able to return one to construct into caller's instance (move ctor). + // Possible defense: bool 'referenced' data member set by get_userdata(), + // with an llassert_always(! referenced) check in the move constructor. + ClassicCallback(ClassicCallback const&) = delete; + ClassicCallback(ClassicCallback&&) = default; // delete; + ClassicCallback& operator=(ClassicCallback const&) = delete; + ClassicCallback& operator=(ClassicCallback&&) = delete; + + /// Call get_callback() to get the necessary function pointer. + SIGNATURE get_callback() const + { + // This declaration is where the compiler instantiates the correct + // signature for the call() function template. + SIGNATURE callback = call; + return callback; + } + + /// Call get_userdata() to get the opaque USERDATA pointer to pass + /// through the classic-C callback API. + USERDATA get_userdata() const + { + // The USERDATA userdata is of course a pointer to this object. + return static_cast<USERDATA>(const_cast<self_t*>(this)); + } + +protected: + /** + * This call() method accepts one or more callback arguments. It assumes + * the first USERDATA parameter is the userdata. + */ + // Note that we're not literally using C++ perfect forwarding here -- it + // doesn't work to specify (Args&&... args). But that's okay because we're + // dealing with a classic-C callback! It's not going to pass any move-only + // types. + template <typename... Args> + static auto call(Args... args) + { + auto userdata = extract_userdata(std::forward<Args>(args)...); + // cast the userdata param to 'this' and call mCallable + return static_cast<self_t*>(userdata)-> + mCallable(std::forward<Args>(args)...); + } + + template <typename... Args> + static USERDATA extract_userdata(Args... args) + { + // Search for the first USERDATA parameter type, then extract that pointer. + // extract value from parameter pack: http://stackoverflow.com/a/24710433/5533635 + return std::get<index_of<0, USERDATA, Args...>::value>(std::forward_as_tuple(args...)); + } + + CALLABLE mCallable; +}; + +/** + * Usage: + * @code + * auto ccb{ makeClassicCallback<classic_callback_signature>(actual_callback) }; + * @endcode + */ +template <typename SIGNATURE, typename USERDATA=void*, typename CALLABLE=void(*)()> +auto makeClassicCallback(CALLABLE&& callable) +{ + return std::move(ClassicCallback<SIGNATURE, USERDATA, CALLABLE> + (std::forward<CALLABLE>(callable))); +} + +/***************************************************************************** +* HeapClassicCallback +*****************************************************************************/ +/** + * HeapClassicCallback is like ClassicCallback, with this exception: it MUST + * be allocated on the heap because, once the callback has been called, it + * deletes itself. This addresses the problem of a callback whose lifespan + * must persist beyond the scope in which the callback API is engaged -- but + * naturally this callback must be called exactly ONCE. + * + * Usage: + * @code + * // callback signature required by the API of interest + * typedef void (*callback_t)(int, const char*, void*, double); + * // here's the old-style API + * void oldAPI(callback_t callback, void* userdata); + * // want to call someObjPtr->method() when oldAPI() fires the callback, + * // sometime in the future after the enclosing function has returned + * auto ccb{ + * makeHeapClassicCallback<callback_t>( + * [someObjPtr](int n, const char* s, void*, double f) + * { someObjPtr->method(); }) }; + * oldAPI(ccb.get_callback(), ccb.get_userdata()); + * // We don't need a smart pointer for ccb, because it will be deleted once + * // oldAPI() calls the bound lambda. HeapClassicCallback is for when the + * // callback will be called exactly once. If the classic API might call the + * // passed callback more than once -- or might never call it at all -- + * // manually construct a ClassicCallback on the heap and manage its lifespan + * // explicitly. + * @endcode + */ +template <typename SIGNATURE, typename USERDATA=void*, typename CALLABLE=void(*)()> +class HeapClassicCallback: public ClassicCallback<SIGNATURE, USERDATA, CALLABLE> +{ + typedef ClassicCallback<SIGNATURE, USERDATA, CALLABLE> super; + typedef HeapClassicCallback<SIGNATURE, USERDATA, CALLABLE> self_t; + + // This destructor is intentionally private to prevent allocation anywhere + // but the heap. (The Design and Evolution of C++, section 11.4.2: Control + // of Allocation) + ~HeapClassicCallback() {} + +public: + HeapClassicCallback(CALLABLE&& callable): + super(std::forward<CALLABLE>(callable)) + {} + + // makeHeapClassicCallback() only needs to return a pointer -- not an + // instance -- so we can lock down our move constructor too. + HeapClassicCallback(HeapClassicCallback&&) = delete; + + /// Replicate get_callback() from the base class because we must + /// instantiate OUR call() function template. + SIGNATURE get_callback() const + { + // This declaration is where the compiler instantiates the correct + // signature for the call() function template. + SIGNATURE callback = call; + return callback; + } + + /// Replicate get_userdata() from the base class because our call() + /// method must be able to reconstitute a pointer to this subclass. + USERDATA get_userdata() const + { + // The USERDATA userdata is of course a pointer to this object. + return static_cast<const USERDATA>(const_cast<self_t*>(this)); + } + +private: + // call() uses a helper class to delete the HeapClassicCallback when done, + // for two reasons. Most importantly, this deletes even if the callback + // throws an exception. But also, call() must directly return the callback + // result for return-type deduction. + struct Destroyer + { + Destroyer(self_t* p): mPtr(p) {} + ~Destroyer() { delete mPtr; } + + self_t* mPtr; + }; + + template <typename... Args> + static auto call(Args... args) + { + // extract userdata at this level too + USERDATA userdata = super::extract_userdata(std::forward<Args>(args)...); + // arrange to delete it when we leave by whatever means + Destroyer destroy(static_cast<self_t*>(userdata)); + + return super::call(std::forward<Args>(args)...); + } +}; + +template <typename SIGNATURE, typename USERDATA=void*, typename CALLABLE=void(*)()> +auto makeHeapClassicCallback(CALLABLE&& callable) +{ + return new HeapClassicCallback<SIGNATURE, USERDATA, CALLABLE> + (std::forward<CALLABLE>(callable)); +} + +#endif /* ! defined(LL_CLASSIC_CALLBACK_H) */ diff --git a/indra/llcommon/linden_common.h b/indra/llcommon/linden_common.h index e5a913a6a99c56214fc7365b2c13957aae0a810b..a228fd22be401a406931d193a3b86a5e8af526d9 100644 --- a/indra/llcommon/linden_common.h +++ b/indra/llcommon/linden_common.h @@ -27,6 +27,14 @@ #ifndef LL_LINDEN_COMMON_H #define LL_LINDEN_COMMON_H +#include "llprofiler.h" +#if TRACY_ENABLE && !defined(LL_PROFILER_ENABLE_TRACY_OPENGL) // hooks for memory profiling +void *tracy_aligned_malloc(size_t size, size_t alignment); +void tracy_aligned_free(void *memblock); +#define _aligned_malloc(X, Y) tracy_aligned_malloc((X), (Y)) +#define _aligned_free(X) tracy_aligned_free((X)) +#endif + // *NOTE: Please keep includes here to a minimum! // // Files included here are included in every library .cpp file and diff --git a/indra/llcommon/llalignedarray.h b/indra/llcommon/llalignedarray.h index b68e9e0f82d6eae65ea84c99e53776433119d6ae..da9d98c16ce0d75d0907ae706db00073db4e8433 100644 --- a/indra/llcommon/llalignedarray.h +++ b/indra/llcommon/llalignedarray.h @@ -116,14 +116,20 @@ void LLAlignedArray<T, alignment>::resize(U32 size) template <class T, U32 alignment> T& LLAlignedArray<T, alignment>::operator[](int idx) { - llassert(idx < mElementCount); + if(idx >= mElementCount || idx < 0) + { + LL_ERRS() << "Out of bounds LLAlignedArray, requested: " << (S32)idx << " size: " << mElementCount << LL_ENDL; + } return mArray[idx]; } template <class T, U32 alignment> const T& LLAlignedArray<T, alignment>::operator[](int idx) const { - llassert(idx < mElementCount); + if (idx >= mElementCount || idx < 0) + { + LL_ERRS() << "Out of bounds LLAlignedArray, requested: " << (S32)idx << " size: " << mElementCount << LL_ENDL; + } return mArray[idx]; } diff --git a/indra/llcommon/llassettype.cpp b/indra/llcommon/llassettype.cpp index b2bc9d410464f581372e191dfff66f05f1a58198..f73ad60cfe63d9b041b347b1dea78f3f6d56e3ab 100644 --- a/indra/llcommon/llassettype.cpp +++ b/indra/llcommon/llassettype.cpp @@ -107,13 +107,13 @@ const std::string LLAssetType::BADLOOKUP("llassettype_bad_lookup"); LLAssetType::EType LLAssetType::getType(std::string desc_name) { LLStringUtil::toUpper(desc_name); - return LLAssetDictionary::getInstanceFast()->lookup(desc_name); + return LLAssetDictionary::getInstance()->lookup(desc_name); } // static const std::string &LLAssetType::getDesc(LLAssetType::EType asset_type) { - const AssetEntry *entry = LLAssetDictionary::getInstanceFast()->lookup(asset_type); + const AssetEntry *entry = LLAssetDictionary::getInstance()->lookup(asset_type); if (entry) { return entry->mName; @@ -127,7 +127,7 @@ const std::string &LLAssetType::getDesc(LLAssetType::EType asset_type) // static const char *LLAssetType::lookup(LLAssetType::EType asset_type) { - const LLAssetDictionary *dict = LLAssetDictionary::getInstanceFast(); + const LLAssetDictionary *dict = LLAssetDictionary::getInstance(); const AssetEntry *entry = dict->lookup(asset_type); if (entry) { @@ -150,7 +150,7 @@ LLAssetType::EType LLAssetType::lookup(const std::string_view type_name) { if(type_name.empty()) return AT_UNKNOWN; - const LLAssetDictionary& dict = LLAssetDictionary::instanceFast(); + const LLAssetDictionary& dict = LLAssetDictionary::instance(); for (const auto& dict_pair : dict) { const AssetEntry *entry = dict_pair.second; @@ -165,7 +165,7 @@ LLAssetType::EType LLAssetType::lookup(const std::string_view type_name) // static const char *LLAssetType::lookupHumanReadable(LLAssetType::EType asset_type) { - const LLAssetDictionary *dict = LLAssetDictionary::getInstanceFast(); + const LLAssetDictionary *dict = LLAssetDictionary::getInstance(); const AssetEntry *entry = dict->lookup(asset_type); if (entry) { @@ -186,7 +186,7 @@ LLAssetType::EType LLAssetType::lookupHumanReadable(const char* name) // static LLAssetType::EType LLAssetType::lookupHumanReadable(const std::string_view readable_name) { - const LLAssetDictionary& dict = LLAssetDictionary::instanceFast(); + const LLAssetDictionary& dict = LLAssetDictionary::instance(); for (const auto& dict_pair : dict) { const AssetEntry *entry = dict_pair.second; @@ -201,7 +201,7 @@ LLAssetType::EType LLAssetType::lookupHumanReadable(const std::string_view reada // static bool LLAssetType::lookupCanLink(EType asset_type) { - const LLAssetDictionary *dict = LLAssetDictionary::getInstanceFast(); + const LLAssetDictionary *dict = LLAssetDictionary::getInstance(); const AssetEntry *entry = dict->lookup(asset_type); if (entry) { @@ -224,7 +224,7 @@ bool LLAssetType::lookupIsLinkType(EType asset_type) // static bool LLAssetType::lookupIsAssetFetchByIDAllowed(EType asset_type) { - const LLAssetDictionary *dict = LLAssetDictionary::getInstanceFast(); + const LLAssetDictionary *dict = LLAssetDictionary::getInstance(); const AssetEntry *entry = dict->lookup(asset_type); if (entry) { @@ -236,7 +236,7 @@ bool LLAssetType::lookupIsAssetFetchByIDAllowed(EType asset_type) // static bool LLAssetType::lookupIsAssetIDKnowable(EType asset_type) { - const LLAssetDictionary *dict = LLAssetDictionary::getInstanceFast(); + const LLAssetDictionary *dict = LLAssetDictionary::getInstance(); const AssetEntry *entry = dict->lookup(asset_type); if (entry) { @@ -248,7 +248,7 @@ bool LLAssetType::lookupIsAssetIDKnowable(EType asset_type) std::vector<std::string> LLAssetType::getAssetTypeNames() { std::vector<std::string> names; - const LLAssetDictionary& dict = LLAssetDictionary::instanceFast(); + const LLAssetDictionary& dict = LLAssetDictionary::instance(); for (const auto& dict_pair : dict) { const AssetEntry* entry = dict_pair.second; diff --git a/indra/llcommon/llcommon.cpp b/indra/llcommon/llcommon.cpp index 6972cef7cd11741d5afe0a008894021ba14fdbe7..1bd38729cfee4fde8827494cd143f9c1892bc1bf 100644 --- a/indra/llcommon/llcommon.cpp +++ b/indra/llcommon/llcommon.cpp @@ -33,6 +33,66 @@ #include "lltracethreadrecorder.h" #include "llcleanup.h" +thread_local bool gProfilerEnabled = false; + +#if (TRACY_ENABLE) +// Override new/delete for tracy memory profiling +void *operator new(size_t size) +{ + void* ptr; + if (gProfilerEnabled) + { + LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY; + ptr = (malloc)(size); + } + else + { + ptr = (malloc)(size); + } + if (!ptr) + { + throw std::bad_alloc(); + } + TracyAlloc(ptr, size); + return ptr; +} + +void operator delete(void *ptr) noexcept +{ + TracyFree(ptr); + if (gProfilerEnabled) + { + LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY; + (free)(ptr); + } + else + { + (free)(ptr); + } +} + +// C-style malloc/free can't be so easily overridden, so we define tracy versions and use +// a pre-processor #define in linden_common.h to redirect to them. The parens around the native +// functions below prevents recursive substitution by the preprocessor. +// +// Unaligned mallocs are rare in LL code but hooking them causes problems in 3p lib code (looking at +// you, Havok), so we'll only capture the aligned version. + +void *tracy_aligned_malloc(size_t size, size_t alignment) +{ + auto ptr = ll_aligned_malloc_fallback(size, alignment); + if (ptr) TracyAlloc(ptr, size); + return ptr; +} + +void tracy_aligned_free(void *memblock) +{ + TracyFree(memblock); + ll_aligned_free_fallback(memblock); +} + +#endif + //static BOOL LLCommon::sAprInitialized = FALSE; diff --git a/indra/llcommon/llcond.h b/indra/llcommon/llcond.h index e31b67d8937a495e2e4de51566ae01055a7abea3..da6e6affe1b7b17e43ea69aa58a4c051635e61c9 100644 --- a/indra/llcommon/llcond.h +++ b/indra/llcommon/llcond.h @@ -53,6 +53,8 @@ class LLCond LLCoros::Mutex mMutex; // Use LLCoros::ConditionVariable for the same reason. LLCoros::ConditionVariable mCond; + using LockType = LLCoros::LockType; + using cv_status = LLCoros::cv_status; public: /// LLCond can be explicitly initialized with a specific value for mData if @@ -65,10 +67,29 @@ class LLCond LLCond(const LLCond&) = delete; LLCond& operator=(const LLCond&) = delete; - /// get() returns a const reference to the stored DATA. The only way to - /// get a non-const reference -- to modify the stored DATA -- is via - /// update_one() or update_all(). - const value_type& get() const { return mData; } + /** + * get() returns the stored DATA by value -- so to use get(), DATA must + * be copyable. The only way to get a non-const reference -- to modify + * the stored DATA -- is via update_one() or update_all(). + */ + value_type get() + { + LockType lk(mMutex); + return mData; + } + + /** + * get(functor) returns whatever the functor returns. It allows us to peek + * at the stored DATA without copying the whole thing. The functor must + * accept a const reference to DATA. If you want to modify DATA, call + * update_one() or update_all() instead. + */ + template <typename FUNC> + auto get(FUNC&& func) + { + LockType lk(mMutex); + return std::forward<FUNC>(func)(const_data()); + } /** * Pass update_one() an invocable accepting non-const (DATA&). The @@ -80,11 +101,11 @@ class LLCond * update_one() when DATA is a struct or class. */ template <typename MODIFY> - void update_one(MODIFY modify) + void update_one(MODIFY&& modify) { { // scope of lock can/should end before notify_one() - LLCoros::LockType lk(mMutex); - modify(mData); + LockType lk(mMutex); + std::forward<MODIFY>(modify)(mData); } mCond.notify_one(); } @@ -99,11 +120,11 @@ class LLCond * update_all() when DATA is a struct or class. */ template <typename MODIFY> - void update_all(MODIFY modify) + void update_all(MODIFY&& modify) { { // scope of lock can/should end before notify_all() - LLCoros::LockType lk(mMutex); - modify(mData); + LockType lk(mMutex); + std::forward<MODIFY>(modify)(mData); } mCond.notify_all(); } @@ -116,9 +137,9 @@ class LLCond * wait() on the condition_variable. */ template <typename Pred> - void wait(Pred pred) + void wait(Pred&& pred) { - LLCoros::LockType lk(mMutex); + LockType lk(mMutex); // We must iterate explicitly since the predicate accepted by // condition_variable::wait() requires a different signature: // condition_variable::wait() calls its predicate with no arguments. @@ -127,7 +148,7 @@ class LLCond // But what if they instead pass a predicate accepting non-const // (DATA&)? Such a predicate could modify mData, which would be Bad. // Forbid that. - while (! pred(const_cast<const value_type&>(mData))) + while (! std::forward<Pred>(pred)(const_data())) { mCond.wait(lk); } @@ -144,7 +165,7 @@ class LLCond * returning true. */ template <typename Rep, typename Period, typename Pred> - bool wait_for(const std::chrono::duration<Rep, Period>& timeout_duration, Pred pred) + bool wait_for(const std::chrono::duration<Rep, Period>& timeout_duration, Pred&& pred) { // Instead of replicating wait_until() logic, convert duration to // time_point and just call wait_until(). @@ -153,7 +174,8 @@ class LLCond // wrong! We'd keep pushing the timeout time farther and farther into // the future. This way, we establish a definite timeout time and // stick to it. - return wait_until(std::chrono::steady_clock::now() + timeout_duration, pred); + return wait_until(std::chrono::steady_clock::now() + timeout_duration, + std::forward<Pred>(pred)); } /** @@ -163,9 +185,9 @@ class LLCond * generic wait_for() method. */ template <typename Pred> - bool wait_for(F32Milliseconds timeout_duration, Pred pred) + bool wait_for(F32Milliseconds timeout_duration, Pred&& pred) { - return wait_for(convert(timeout_duration), pred); + return wait_for(convert(timeout_duration), std::forward<Pred>(pred)); } protected: @@ -183,6 +205,10 @@ class LLCond } private: + // It's important to pass a const ref to certain user-specified functors + // that aren't supposed to be able to modify mData. + const value_type& const_data() const { return mData; } + /** * Pass wait_until() a chrono::time_point, indicating the time at which we * should stop waiting, and a predicate accepting (const DATA&), returning @@ -203,21 +229,21 @@ class LLCond * honoring a fixed timeout. */ template <typename Clock, typename Duration, typename Pred> - bool wait_until(const std::chrono::time_point<Clock, Duration>& timeout_time, Pred pred) + bool wait_until(const std::chrono::time_point<Clock, Duration>& timeout_time, Pred&& pred) { - LLCoros::LockType lk(mMutex); + LockType lk(mMutex); // We advise the caller to pass a predicate accepting (const DATA&). // But what if they instead pass a predicate accepting non-const // (DATA&)? Such a predicate could modify mData, which would be Bad. // Forbid that. - while (! pred(const_cast<const value_type&>(mData))) + while (! std::forward<Pred>(pred)(const_data())) { - if (LLCoros::cv_status::timeout == mCond.wait_until(lk, timeout_time)) + if (cv_status::timeout == mCond.wait_until(lk, timeout_time)) { // It's possible that wait_until() timed out AND the predicate // became true more or less simultaneously. Even though // wait_until() timed out, check the predicate one more time. - return pred(const_cast<const value_type&>(mData)); + return std::forward<Pred>(pred)(const_data()); } } return true; diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp index f7b4fbc826c51df3ccbfc55a86b23f11132484f7..2b10a1b691829308e98f79287b17e805e3c75125 100644 --- a/indra/llcommon/llcoros.cpp +++ b/indra/llcommon/llcoros.cpp @@ -35,6 +35,7 @@ // STL headers // std headers #include <atomic> +#include <stdexcept> // external library headers #include <boost/bind.hpp> #include <boost/fiber/fiber.hpp> @@ -210,6 +211,22 @@ std::string LLCoros::logname() return data.mName.empty()? data.getKey() : data.mName; } +void LLCoros::saveException(const std::string& name, std::exception_ptr exc) +{ + mExceptionQueue.emplace(name, exc); +} + +void LLCoros::rethrow() +{ + if (! mExceptionQueue.empty()) + { + ExceptionData front = mExceptionQueue.front(); + mExceptionQueue.pop(); + LL_WARNS("LLCoros") << "Rethrowing exception from coroutine " << front.name << LL_ENDL; + std::rethrow_exception(front.exception); + } +} + void LLCoros::setStackSize(S32 stacksize) { LL_DEBUGS("LLCoros") << "Setting coroutine stack size to " << stacksize << LL_ENDL; @@ -298,11 +315,11 @@ U32 cpp_exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop, } } -void LLCoros::winlevel(const std::string& name, const callable_t& callable) +void LLCoros::sehHandle(const std::string& name, const LLCoros::callable_t& callable) { __try { - toplevelTryWrapper(name, callable); + LLCoros::toplevelTryWrapper(name, callable); } __except (cpp_exception_filter(GetExceptionCode(), GetExceptionInformation(), name)) { @@ -317,7 +334,6 @@ void LLCoros::winlevel(const std::string& name, const callable_t& callable) throw std::exception(integer_string); } } - #endif void LLCoros::toplevelTryWrapper(const std::string& name, const callable_t& callable) @@ -346,11 +362,19 @@ 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, hopefully informatively. + // 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 } } @@ -360,8 +384,9 @@ void LLCoros::toplevelTryWrapper(const std::string& name, const callable_t& call void LLCoros::toplevel(std::string name, callable_t callable) { #if LL_WINDOWS - // Can not use __try in functions that require unwinding, so use one more wrapper - winlevel(name, callable); + // 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 diff --git a/indra/llcommon/llcoros.h b/indra/llcommon/llcoros.h index 8459ec6270150252b16f2e96d9562d090eeed422..a68e1ddbfcf685c4d9e4d3b087b3d9c2e4d32f5e 100644 --- a/indra/llcommon/llcoros.h +++ b/indra/llcommon/llcoros.h @@ -38,6 +38,8 @@ #include "llinstancetracker.h" #include <boost/function.hpp> #include <string> +#include <exception> +#include <queue> // e.g. #include LLCOROS_MUTEX_HEADER #define LLCOROS_MUTEX_HEADER <boost/fiber/mutex.hpp> @@ -156,6 +158,19 @@ class LL_COMMON_API LLCoros final : public LLSingleton<LLCoros> * LLCoros::launch()). */ static std::string getName(); + + /** + * rethrow() is called by the thread's main fiber to propagate an + * exception from any coroutine into the main fiber, where it can engage + * the normal unhandled-exception machinery, up to and including crash + * reporting. + * + * LLCoros maintains a queue of otherwise-uncaught exceptions from + * terminated coroutines. Each call to rethrow() pops the first of those + * and rethrows it. When the queue is empty (normal case), rethrow() is a + * no-op. + */ + void rethrow(); /** * This variation returns a name suitable for log messages: the explicit @@ -292,13 +307,27 @@ class LL_COMMON_API LLCoros final : public LLSingleton<LLCoros> private: std::string generateDistinctName(const std::string& prefix) const; + void toplevelTryWrapper(const std::string& name, const callable_t& callable); #if LL_WINDOWS - void winlevel(const std::string& name, const callable_t& callable); + void sehHandle(const std::string& name, const callable_t& callable); // calls toplevelTryWrapper #endif - void toplevelTryWrapper(const std::string& name, const callable_t& callable); - void toplevel(std::string name, callable_t callable); + void toplevel(std::string name, callable_t callable); // calls sehHandle or toplevelTryWrapper struct CoroData; static CoroData& get_CoroData(const std::string& caller); + void saveException(const std::string& name, std::exception_ptr exc); + + struct ExceptionData + { + ExceptionData(const std::string& nm, std::exception_ptr exc): + name(nm), + exception(exc) + {} + // name of coroutine that originally threw this exception + std::string name; + // the thrown exception + std::exception_ptr exception; + }; + std::queue<ExceptionData> mExceptionQueue; S32 mStackSize; diff --git a/indra/llcommon/lldate.cpp b/indra/llcommon/lldate.cpp index 838f6f7127b0a763bfb25e2663046b1940204d09..191c3715f59557ee4d753c732ec5b847b6026fa2 100644 --- a/indra/llcommon/lldate.cpp +++ b/indra/llcommon/lldate.cpp @@ -85,11 +85,9 @@ std::string LLDate::asRFC1123() const return toHTTPDateString (std::string ("%A, %d %b %Y %H:%M:%S GMT")); } -LLTrace::BlockTimerStatHandle FT_DATE_FORMAT("Date Format"); - std::string LLDate::toHTTPDateString (const std::string& fmt) const { - LL_RECORD_BLOCK_TIME(FT_DATE_FORMAT); + LL_PROFILE_ZONE_SCOPED; time_t locSeconds = (time_t) mSecondsSinceEpoch; struct tm * gmt = gmtime (&locSeconds); @@ -98,7 +96,7 @@ std::string LLDate::toHTTPDateString (const std::string& fmt) const std::string LLDate::toHTTPDateString (tm * gmt, const std::string& fmt) { - LL_RECORD_BLOCK_TIME(FT_DATE_FORMAT); + LL_PROFILE_ZONE_SCOPED; // avoid calling setlocale() unnecessarily - it's expensive. static std::string prev_locale = ""; @@ -185,6 +183,8 @@ bool LLDate::split(S32 *year, S32 *month, S32 *day, S32 *hour, S32 *min, S32 *se bool LLDate::fromString(const std::string& iso8601_date) { + if(iso8601_date.empty()) return false; + boost::iostreams::stream<boost::iostreams::array_source> stream(iso8601_date.data(), iso8601_date.size()); return fromStream(stream); } diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index 72ff14f02537eb7091b197dcbccf29919a8e84e9..8cdd8f94ecd1440a643da5842bd98a234375f30a 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -120,6 +120,7 @@ namespace { virtual void recordMessage(LLError::ELevel level, const std::string& message) override { + LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING int syslogPriority = LOG_CRIT; switch (level) { case LLError::LEVEL_DEBUG: syslogPriority = LOG_DEBUG; break; @@ -179,6 +180,7 @@ namespace { virtual void recordMessage(LLError::ELevel level, const std::string& message) override { + LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING if (LLError::getAlwaysFlush()) { mFile << message << std::endl; @@ -207,7 +209,7 @@ namespace { { return LLError::getEnabledLogTypesMask() & 0x04; } - + LL_FORCE_INLINE std::string createBoldANSI() { std::string ansi_code; @@ -233,10 +235,10 @@ namespace { LL_FORCE_INLINE std::string createANSI(const std::string& color) { std::string ansi_code; - ansi_code += '\033'; - ansi_code += "["; + ansi_code += '\033'; + ansi_code += "["; ansi_code += "38;5;"; - ansi_code += color; + ansi_code += color; ansi_code += "m"; return ansi_code; @@ -245,6 +247,7 @@ namespace { virtual void recordMessage(LLError::ELevel level, const std::string& message) override { + LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING // The default colors for error, warn and debug are now a bit more pastel // and easier to read on the default (black) terminal background but you // now have the option to set the color of each via an environment variables: @@ -274,6 +277,7 @@ namespace { } else { + LL_PROFILE_ZONE_NAMED("fprintf"); fprintf(stderr, "%s\n", message.c_str()); } } @@ -283,6 +287,7 @@ namespace { LL_FORCE_INLINE void writeANSI(const std::string& ansi_code, const std::string& message) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING static std::string s_ansi_bold = createBoldANSI(); // bold text static std::string s_ansi_reset = createResetANSI(); // reset // ANSI color code escape sequence, message, and reset in one fprintf call @@ -319,6 +324,7 @@ namespace { virtual void recordMessage(LLError::ELevel level, const std::string& message) override { + LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING mBuffer->addLine(message); } @@ -345,6 +351,7 @@ namespace { virtual void recordMessage(LLError::ELevel level, const std::string& message) override { + LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING debugger_print(message); } }; @@ -1226,6 +1233,7 @@ namespace void writeToRecorders(const LLError::CallSite& site, const std::string& message) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING LLError::ELevel level = site.mLevel; SettingsConfigPtr s = Globals::getInstance()->getSettingsConfig(); @@ -1302,26 +1310,16 @@ namespace { LOG_MUTEX, STACKS_MUTEX }; - - ABSL_CONST_INIT absl::Mutex sLogMutex(absl::kConstInit); - ABSL_CONST_INIT absl::Mutex sStackMutex(absl::kConstInit); - + // Some logging calls happen very early in processing -- so early that our + // module-static variables aren't yet initialized. getMutex() wraps a + // function-static LLMutex so that early calls can still have a valid + // LLMutex instance. template <MutexDiscriminator MTX> - absl::Mutex* getMutex() - { - return nullptr; - } - - template <> - absl::Mutex* getMutex<LOG_MUTEX>() - { - return &sLogMutex; - } - - template <> - absl::Mutex* getMutex<STACKS_MUTEX>() + LLMutex* getMutex() { - return &sStackMutex; + // guaranteed to be initialized the first time control reaches here + static LLMutex sMutex; + return &sMutex; } bool checkLevelMap(const LevelMap& map, const std::string& key, @@ -1369,7 +1367,8 @@ namespace LLError bool Log::shouldLog(CallSite& site) { - AbslMutexMaybeTrylock lock(getMutex<LOG_MUTEX>(), 5); + LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING + LLMutexTrylock lock(getMutex<LOG_MUTEX>(), 5); if (!lock.isLocked()) { return false; @@ -1413,7 +1412,8 @@ namespace LLError void Log::flush(const std::ostringstream& out, const CallSite& site) { - AbslMutexMaybeTrylock lock(getMutex<LOG_MUTEX>(),5); + LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING + LLMutexTrylock lock(getMutex<LOG_MUTEX>(),5); if (!lock.isLocked()) { return; @@ -1542,7 +1542,7 @@ namespace LLError //static void LLCallStacks::push(const char* function, const int line) { - AbslMutexMaybeTrylock lock(getMutex<STACKS_MUTEX>(), 5); + LLMutexTrylock lock(getMutex<STACKS_MUTEX>(), 5); if (!lock.isLocked()) { return; @@ -1567,7 +1567,7 @@ namespace LLError //static void LLCallStacks::end(const std::ostringstream& out) { - AbslMutexMaybeTrylock lock(getMutex<STACKS_MUTEX>(), 5); + LLMutexTrylock lock(getMutex<STACKS_MUTEX>(), 5); if (!lock.isLocked()) { return; @@ -1584,7 +1584,7 @@ namespace LLError //static void LLCallStacks::print() { - AbslMutexMaybeTrylock lock(getMutex<STACKS_MUTEX>(), 5); + LLMutexTrylock lock(getMutex<STACKS_MUTEX>(), 5); if (!lock.isLocked()) { return; @@ -1624,7 +1624,7 @@ namespace LLError bool debugLoggingEnabled(const std::string& tag) { - AbslMutexMaybeTrylock lock(getMutex<LOG_MUTEX>(), 5); + LLMutexTrylock lock(getMutex<LOG_MUTEX>(), 5); if (!lock.isLocked()) { return false; diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h index 98138af74061415a0ea23e13b481d14a69fa26ae..8040f069fdd4f844834c95c920bbe6845b645f22 100644 --- a/indra/llcommon/llerror.h +++ b/indra/llcommon/llerror.h @@ -35,8 +35,10 @@ #include "stdtypes.h" +#include "llprofiler.h" #include "llpreprocessor.h" + const int LL_ERR_NOERR = 0; // Define one of these for different error levels in release... @@ -53,7 +55,7 @@ const int LL_ERR_NOERR = 0; #define SHOW_ASSERT #else // _DEBUG -#if defined(LL_RELEASE_WITH_DEBUG_INFO) || defined(RELEASE_SHOW_ASSERT) +#ifdef LL_RELEASE_WITH_DEBUG_INFO #define SHOW_ASSERT #endif // LL_RELEASE_WITH_DEBUG_INFO @@ -69,6 +71,10 @@ const int LL_ERR_NOERR = 0; #define SHOW_INFO #endif +#ifdef RELEASE_SHOW_ASSERT +#define SHOW_ASSERT +#endif + #endif // !_DEBUG #define llassert_always_msg(func, msg) if (LL_UNLIKELY(!(func))) LL_ERRS() << "ASSERT (" << msg << ")" << LL_ENDL @@ -360,7 +366,8 @@ typedef LLError::NoClassInfo _LL_CLASS_TO_LOG; // if (condition) LL_INFOS() << "True" << LL_ENDL; else LL_INFOS()() << "False" << LL_ENDL; #define lllog(level, once, ...) \ - do { \ + do { \ + LL_PROFILE_ZONE_NAMED("lllog"); \ const char* tags[] = {"", ##__VA_ARGS__}; \ static LLError::CallSite _site(lllog_site_args_(level, once, tags)); \ lllog_test_() diff --git a/indra/llcommon/llerrorcontrol.h b/indra/llcommon/llerrorcontrol.h index 1d59eecc9912f9a679d2ed2cdbe0d489fe0c003f..3a1f01cc759f536c3de6d27f5d46e1f1a2d90c1f 100644 --- a/indra/llcommon/llerrorcontrol.h +++ b/indra/llcommon/llerrorcontrol.h @@ -190,6 +190,7 @@ namespace LLError {} void recordMessage(LLError::ELevel level, const std::string& message) override { + LL_PROFILE_ZONE_SCOPED mCallable(level, message); } private: diff --git a/indra/llcommon/lleventfilter.h b/indra/llcommon/lleventfilter.h index 5c9bd3698f070f76e0f76ca18858094a087f0d45..9dd2cbb684ed151d378dbd3de9016f062b6318de 100644 --- a/indra/llcommon/lleventfilter.h +++ b/indra/llcommon/lleventfilter.h @@ -429,6 +429,8 @@ class LLStoreListener: public LLEventFilter // path, then stores it to mTarget. virtual bool post(const LLSD& event) { + LL_PROFILE_ZONE_SCOPED + // Extract the element specified by 'mPath' from 'event'. To perform a // generic type-appropriate store through mTarget, construct an // LLSDParam<T> and store that, thus engaging LLSDParam's custom diff --git a/indra/llcommon/llexception.cpp b/indra/llcommon/llexception.cpp index b584b0ff8b53c2a4efb58e40f4d4aef210fb1466..46560b5e4ce39ac7c12dc45b7ae1d080448090d7 100644 --- a/indra/llcommon/llexception.cpp +++ b/indra/llcommon/llexception.cpp @@ -97,6 +97,11 @@ static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific U32 msc_exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop) { + const auto stack = to_string(boost::stacktrace::stacktrace()); + LL_WARNS() << "SEH Exception handled (that probably shouldn't be): Code " << code + << "\n Stack trace: \n" + << stack << LL_ENDL; + if (code == STATUS_MSC_EXCEPTION) { // C++ exception, go on diff --git a/indra/llcommon/llfasttimer.cpp b/indra/llcommon/llfasttimer.cpp index 193ea372d6555e7395fafa83c6a7c36e82bdba47..a6b8ddab01ee92077b107cb06747dc36c91c7269 100644 --- a/indra/llcommon/llfasttimer.cpp +++ b/indra/llcommon/llfasttimer.cpp @@ -70,7 +70,7 @@ U64 BlockTimer::sClockResolution = 1000000000; // Nanosecond resolution U64 BlockTimer::sClockResolution = 1000000; // Microsecond resolution #endif -static LLMutex sLogLock(LLMutex::E_CONST_INIT); +static LLMutex* sLogLock = NULL; static std::queue<LLSD> sLogQueue; block_timer_tree_df_iterator_t begin_block_timer_tree_df(BlockTimerStatHandle& id) @@ -139,11 +139,17 @@ BlockTimerStatHandle& BlockTimer::getRootTimeBlock() void BlockTimer::pushLog(LLSD log) { - LLMutexLock lock(&sLogLock); + LLMutexLock lock(sLogLock); sLogQueue.push(log); } +void BlockTimer::setLogLock(LLMutex* lock) +{ + sLogLock = lock; +} + + //static #if (LL_DARWIN || LL_LINUX) && !(defined(__i386__) || defined(__amd64__)) U64 BlockTimer::countsPerSecond() @@ -185,29 +191,30 @@ TimeBlockTreeNode& BlockTimerStatHandle::getTreeNode() const } + void BlockTimer::bootstrapTimerTree() { - for (auto& base : BlockTimerStatHandle::instance_snapshot()) - { - // because of indirect derivation from LLInstanceTracker, have to downcast - BlockTimerStatHandle& timer = static_cast<BlockTimerStatHandle&>(base); - if (&timer == &BlockTimer::getRootTimeBlock()) continue; - - // bootstrap tree construction by attaching to last timer to be on stack - // when this timer was called - if (timer.getParent() == &BlockTimer::getRootTimeBlock()) - { - TimeBlockAccumulator& accumulator = timer.getCurrentAccumulator(); - - if (accumulator.mLastCaller) - { - timer.setParent(accumulator.mLastCaller); - accumulator.mParent = accumulator.mLastCaller; - } - // no need to push up tree on first use, flag can be set spuriously - accumulator.mMoveUpTree = false; - } - } + for (auto& base : BlockTimerStatHandle::instance_snapshot()) + { + // because of indirect derivation from LLInstanceTracker, have to downcast + BlockTimerStatHandle& timer = static_cast<BlockTimerStatHandle&>(base); + if (&timer == &BlockTimer::getRootTimeBlock()) continue; + + // bootstrap tree construction by attaching to last timer to be on stack + // when this timer was called + if (timer.getParent() == &BlockTimer::getRootTimeBlock()) + { + TimeBlockAccumulator& accumulator = timer.getCurrentAccumulator(); + + if (accumulator.mLastCaller) + { + timer.setParent(accumulator.mLastCaller); + accumulator.mParent = accumulator.mLastCaller; + } + // no need to push up tree on first use, flag can be set spuriously + accumulator.mMoveUpTree = false; + } + } } // bump timers up tree if they have been flagged as being in the wrong place @@ -215,6 +222,7 @@ void BlockTimer::bootstrapTimerTree() // this preserves partial order derived from current frame's observations void BlockTimer::incrementalUpdateTimerTree() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; for(block_timer_tree_df_post_iterator_t it = begin_block_timer_tree_df_post(BlockTimer::getRootTimeBlock()), end = end_block_timer_tree_df_post(); it != end; ++it) @@ -256,7 +264,8 @@ void BlockTimer::incrementalUpdateTimerTree() void BlockTimer::updateTimes() - { +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; // walk up stack of active timers and accumulate current time while leaving timing structures active BlockTimerStackRecord* stack_record = LLThreadLocalSingletonPointer<BlockTimerStackRecord>::getInstance(); if (!stack_record) return; @@ -267,7 +276,7 @@ void BlockTimer::updateTimes() while(cur_timer && cur_timer->mParentTimerData.mActiveTimer != cur_timer) // root defined by parent pointing to self - { + { U64 cumulative_time_delta = cur_time - cur_timer->mStartTime; cur_timer->mStartTime = cur_time; @@ -290,7 +299,7 @@ static LLTrace::BlockTimerStatHandle FTM_PROCESS_TIMES("Process FastTimer Times" void BlockTimer::processTimes() { #if LL_TRACE_ENABLED - LL_ALWAYS_RECORD_BLOCK_TIME(FTM_PROCESS_TIMES); + LL_RECORD_BLOCK_TIME(FTM_PROCESS_TIMES); // set up initial tree bootstrapTimerTree(); @@ -374,7 +383,7 @@ void BlockTimer::logStats() sd["Total"]["Calls"] = (LLSD::Integer) 1; { - LLMutexLock lock(&sLogLock); + LLMutexLock lock(sLogLock); sLogQueue.push(sd); } } @@ -418,11 +427,11 @@ void BlockTimer::dumpCurTimes() //static void BlockTimer::writeLog(std::ostream& os) { - LLMutexLock lock(&sLogLock); while (!sLogQueue.empty()) { LLSD& sd = sLogQueue.front(); LLSDSerialize::toXML(sd, os); + LLMutexLock lock(sLogLock); sLogQueue.pop(); } } diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h index 35d58235c333da5c951bf37d7e6a5d2715ed3eaa..3c8b32b07e638ff4d40c8f54c8be80436db90a01 100644 --- a/indra/llcommon/llfasttimer.h +++ b/indra/llcommon/llfasttimer.h @@ -30,6 +30,7 @@ #include "llinstancetracker.h" #include "lltrace.h" #include "lltreeiterators.h" +#include "llprofiler.h" #if LL_WINDOWS #include <intrin.h> @@ -40,6 +41,8 @@ #define LL_FAST_TIMER_ON 1 #define LL_FASTTIMER_USE_RDTSC 1 +// NOTE: Also see llprofiler.h +#if !defined(LL_PROFILER_CONFIGURATION) #if AL_ENABLE_ALL_TIMERS #define LL_RECORD_BLOCK_TIME(timer_stat) const LLTrace::BlockTimer& LL_GLUE_TOKENS(block_time_recorder, __LINE__)(LLTrace::timeThisBlock(timer_stat)); (void)LL_GLUE_TOKENS(block_time_recorder, __LINE__); #else @@ -47,6 +50,7 @@ #endif #define LL_ALWAYS_RECORD_BLOCK_TIME(timer_stat) const LLTrace::BlockTimer& LL_GLUE_TOKENS(block_time_recorder, __LINE__)(LLTrace::timeThisBlock(timer_stat)); (void)LL_GLUE_TOKENS(block_time_recorder, __LINE__); +#endif // LL_PROFILER_CONFIGURATION namespace LLTrace { @@ -156,6 +160,7 @@ class BlockTimer static BlockTimerStatHandle& getRootTimeBlock(); static void pushLog(LLSD sd); + static void setLogLock(class LLMutex* mutex); static void writeLog(std::ostream& os); static void updateTimes(); diff --git a/indra/llcommon/llframetimer.cpp b/indra/llcommon/llframetimer.cpp index 1e9920746b0191efc8ef41346bfdccdd0266ac7f..c54029e8b440b87e5944dbfbfea6f1d7bbedb4ba 100644 --- a/indra/llcommon/llframetimer.cpp +++ b/indra/llcommon/llframetimer.cpp @@ -29,6 +29,11 @@ #include "llframetimer.h" +// We don't bother building a stand alone lib; we just need to include the one source file for Tracy support +#if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY || LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY_FAST_TIMER + #include "TracyClient.cpp" +#endif // LL_PROFILER_CONFIGURATION + // Static members //LLTimer LLFrameTimer::sInternalTimer; U64 LLFrameTimer::sStartTotalTime = totalTime(); diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h index eadb5ec17ae5eff9f910bfd1fbafbdaec2268b98..e12f048024790b21d07d4813259c3168e986b613 100644 --- a/indra/llcommon/llinstancetracker.h +++ b/indra/llcommon/llinstancetracker.h @@ -34,9 +34,8 @@ #include <typeinfo> #include <memory> #include <type_traits> -#include <mutex> -#include "absl/synchronization/mutex.h" +#include "mutex.h" #include <boost/iterator/transform_iterator.hpp> #include <boost/iterator/indirect_iterator.hpp> @@ -53,7 +52,7 @@ namespace LLInstanceTrackerPrivate struct StaticBase { // We need to be able to lock static data while manipulating it. - absl::Mutex mMutex; + std::mutex mMutex; }; void logerrs(const char* cls, const std::string&, const std::string&, const std::string&); @@ -81,16 +80,37 @@ class LLInstanceTracker { InstanceMap mMap; }; - typedef llthread::LockStaticAbsl<StaticData> LockStatic; + typedef llthread::LockStatic<StaticData> LockStatic; public: + using ptr_t = std::shared_ptr<T>; + using weak_t = std::weak_ptr<T>; + + /** + * Storing a dumb T* somewhere external is a bad idea, since + * LLInstanceTracker subclasses are explicitly destroyed rather than + * managed by smart pointers. It's legal to declare stack instances of an + * LLInstanceTracker subclass. But it's reasonable to store a + * std::weak_ptr<T>, which will become invalid when the T instance is + * destroyed. + */ + weak_t getWeak() + { + return mSelf; + } + + static S32 instanceCount() + { + return LockStatic()->mMap.size(); + } + // snapshot of std::pair<const KEY, std::shared_ptr<T>> pairs class snapshot { // It's very important that what we store in this snapshot are // weak_ptrs, NOT shared_ptrs. That's how we discover whether any // instance has been deleted during the lifespan of a snapshot. - typedef std::vector<std::pair<const KEY, std::weak_ptr<T>>> VectorType; + typedef std::vector<std::pair<const KEY, weak_t>> VectorType; // Dereferencing our iterator produces a std::shared_ptr for each // instance that still exists. Since we store weak_ptrs, that involves // two chained transformations: @@ -99,7 +119,7 @@ class LLInstanceTracker // It is very important that we filter lazily, that is, during // traversal. Any one of our stored weak_ptrs might expire during // traversal. - typedef std::pair<const KEY, std::shared_ptr<T>> strong_pair; + typedef std::pair<const KEY, ptr_t> strong_pair; // Note for future reference: nat has not yet had any luck (up to // Boost 1.67) trying to use boost::transform_iterator with a hand- // coded functor, only with actual functions. In my experience, an @@ -187,17 +207,12 @@ class LLInstanceTracker iterator end() { return iterator(snapshot::end(), key_getter); } }; - static T* getInstance(const KEY& k) + static ptr_t getInstance(const KEY& k) { LockStatic lock; const InstanceMap& map(lock->mMap); typename InstanceMap::const_iterator found = map.find(k); - return (found == map.end()) ? NULL : found->second.get(); - } - - static S32 instanceCount() - { - return LockStatic()->mMap.size(); + return (found == map.end()) ? NULL : found->second; } protected: @@ -207,7 +222,9 @@ class LLInstanceTracker // shared_ptr, so give it a no-op deleter. We store shared_ptrs in our // InstanceMap specifically so snapshot can store weak_ptrs so we can // detect deletions during traversals. - std::shared_ptr<T> ptr(static_cast<T*>(this), [](T*){}); + ptr_t ptr(static_cast<T*>(this), [](T*){}); + // save corresponding weak_ptr for future reference + mSelf = ptr; LockStatic lock; add_(lock, key, ptr); } @@ -242,7 +259,7 @@ class LLInstanceTracker static std::string report(const char* key) { return report(std::string(key)); } // caller must instantiate LockStatic - void add_(LockStatic& lock, const KEY& key, const std::shared_ptr<T>& ptr) + void add_(LockStatic& lock, const KEY& key, const ptr_t& ptr) { mInstanceKey = key; InstanceMap& map = lock->mMap; @@ -266,7 +283,7 @@ class LLInstanceTracker break; } } - std::shared_ptr<T> remove_(LockStatic& lock) + ptr_t remove_(LockStatic& lock) { InstanceMap& map = lock->mMap; typename InstanceMap::iterator iter = map.find(mInstanceKey); @@ -280,6 +297,9 @@ class LLInstanceTracker } private: + // Storing a weak_ptr to self is a bit like deriving from + // std::enable_shared_from_this(), except more explicit. + weak_t mSelf; KEY mInstanceKey; }; @@ -308,9 +328,12 @@ class LLInstanceTracker<T, void, KEY_COLLISION_BEHAVIOR> { InstanceSet mSet; }; - typedef llthread::LockStaticAbsl<StaticData> LockStatic; + typedef llthread::LockStatic<StaticData> LockStatic; public: + using ptr_t = std::shared_ptr<T>; + using weak_t = std::weak_ptr<T>; + /** * Storing a dumb T* somewhere external is a bad idea, since * LLInstanceTracker subclasses are explicitly destroyed rather than @@ -319,12 +342,15 @@ class LLInstanceTracker<T, void, KEY_COLLISION_BEHAVIOR> * std::weak_ptr<T>, which will become invalid when the T instance is * destroyed. */ - std::weak_ptr<T> getWeak() + weak_t getWeak() { return mSelf; } - static S32 instanceCount() { return LockStatic()->mSet.size(); } + static S32 instanceCount() + { + return LockStatic()->mSet.size(); + } // snapshot of std::shared_ptr<T> pointers class snapshot @@ -332,7 +358,7 @@ class LLInstanceTracker<T, void, KEY_COLLISION_BEHAVIOR> // It's very important that what we store in this snapshot are // weak_ptrs, NOT shared_ptrs. That's how we discover whether any // instance has been deleted during the lifespan of a snapshot. - typedef std::vector<std::weak_ptr<T>> VectorType; + typedef std::vector<weak_t> VectorType; // Dereferencing our iterator produces a std::shared_ptr for each // instance that still exists. Since we store weak_ptrs, that involves // two chained transformations: @@ -422,7 +448,7 @@ class LLInstanceTracker<T, void, KEY_COLLISION_BEHAVIOR> private: // Storing a weak_ptr to self is a bit like deriving from // std::enable_shared_from_this(), except more explicit. - std::weak_ptr<T> mSelf; + weak_t mSelf; }; #endif diff --git a/indra/llcommon/llleaplistener.cpp b/indra/llcommon/llleaplistener.cpp index 80eac176f8c6a2c57e87e4328cadd0b6dd7cbecb..5a9bf75b0a3b1d0dc2ea43029352c25a772b3684 100644 --- a/indra/llcommon/llleaplistener.cpp +++ b/indra/llcommon/llleaplistener.cpp @@ -219,7 +219,7 @@ void LLLeapListener::getAPI(const LLSD& request) const { Response reply(LLSD(), request); - LLEventAPI* found = LLEventAPI::getInstance(request["api"]); + auto found = LLEventAPI::getInstance(request["api"]); if (found) { reply["name"] = found->getName(); diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp index 1a6ba36c7219c845df32062ad898448b71a1e365..33825283893905a1f038c35a9e332ca787902d4b 100644 --- a/indra/llcommon/llmemory.cpp +++ b/indra/llcommon/llmemory.cpp @@ -84,6 +84,7 @@ void LLMemory::initMaxHeapSizeGB(F32Gigabytes max_heap_size) //static void LLMemory::updateMemoryInfo() { + LL_PROFILE_ZONE_SCOPED #if LL_WINDOWS PROCESS_MEMORY_COUNTERS_EX counters; counters.cb = sizeof(counters); @@ -187,6 +188,7 @@ void* LLMemory::tryToAlloc(void* address, U32 size) //static void LLMemory::logMemoryInfo(BOOL update) { + LL_PROFILE_ZONE_SCOPED if(update) { updateMemoryInfo() ; @@ -252,11 +254,9 @@ U64 LLMemory::getCurrentRSS() mach_msg_type_number_t basicInfoCount = MACH_TASK_BASIC_INFO_COUNT; if (task_info(mach_task_self(), MACH_TASK_BASIC_INFO, (task_info_t)&basicInfo, &basicInfoCount) == KERN_SUCCESS) { -// residentSize = basicInfo.resident_size; - // Although this method is defined to return the "resident set size," - // in fact what callers want from it is the total virtual memory - // consumed by the application. - residentSize = basicInfo.virtual_size; + residentSize = basicInfo.resident_size; + // 64-bit macos apps allocate 32 GB or more at startup, and this is reflected in virtual_size. + // basicInfo.virtual_size is not what we want. } else { diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h index a455c673fbdc25c51eb22594aa782944609e9512..2d7319af297c0818854aeefa166b8b45ae58c6f2 100644 --- a/indra/llcommon/llmemory.h +++ b/indra/llcommon/llmemory.h @@ -105,6 +105,29 @@ template <typename T> T* LL_NEXT_ALIGNED_ADDRESS_64(T* address) #define LL_ALIGN_16(var) LL_ALIGN_PREFIX(16) var LL_ALIGN_POSTFIX(16) +#define LL_ALIGN_NEW \ +public: \ + void* operator new(size_t size) \ + { \ + return ll_aligned_malloc_16(size); \ + } \ + \ + void operator delete(void* ptr) \ + { \ + ll_aligned_free_16(ptr); \ + } \ + \ + void* operator new[](size_t size) \ + { \ + return ll_aligned_malloc_16(size); \ + } \ + \ + void operator delete[](void* ptr) \ + { \ + ll_aligned_free_16(ptr); \ + } + + //------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------ // for enable buffer overrun detection predefine LL_DEBUG_BUFFER_OVERRUN in current library @@ -117,8 +140,9 @@ template <typename T> T* LL_NEXT_ALIGNED_ADDRESS_64(T* address) #else inline void* ll_aligned_malloc_fallback( size_t size, int align ) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY; #if defined(LL_WINDOWS) - return _aligned_malloc(size, align); + void* ret = _aligned_malloc(size, align); #else char* aligned = NULL; void* mem = malloc( size + (align - 1) + sizeof(void*) ); @@ -129,12 +153,16 @@ template <typename T> T* LL_NEXT_ALIGNED_ADDRESS_64(T* address) ((void**)aligned)[-1] = mem; } - return aligned; + void* ret = aligned; #endif + LL_PROFILE_ALLOC(ret, size); + return ret; } inline void ll_aligned_free_fallback( void* ptr ) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY; + LL_PROFILE_FREE(ptr); #if defined(LL_WINDOWS) _aligned_free(ptr); #else @@ -150,25 +178,28 @@ template <typename T> T* LL_NEXT_ALIGNED_ADDRESS_64(T* address) inline void* ll_aligned_malloc_16(size_t size) // returned hunk MUST be freed with ll_aligned_free_16(). { + LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY; #if (ADDRESS_SIZE == 64 && (defined(LL_WINDOWS) || defined(LL_DARWIN) || defined(LL_LINUX))) - return malloc(size); // default x86_64 malloc alignment on windows, mac, and linux is 16 byte aligned + void* ret = malloc(size); // default x86_64 malloc alignment on windows, mac, and linux is 16 byte aligned #else #if defined(LL_WINDOWS) - return _aligned_malloc(size, 16); + void* ret = _aligned_malloc(size, 16); #elif defined(LL_DARWIN) - return malloc(size); // default osx malloc is 16 byte aligned. + void* ret = malloc(size); // default osx malloc is 16 byte aligned. #else - void *rtn = NULL; - if (LL_LIKELY(0 == posix_memalign(&rtn, 16, size))) - return rtn; - else // bad alignment requested, or out of memory - return NULL; + void *ret; + if (0 != posix_memalign(&ret, 16, size)) + return nullptr; #endif #endif + LL_PROFILE_ALLOC(ret, size); + return ret; } inline void ll_aligned_free_16(void *p) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY; + LL_PROFILE_FREE(p); #if (ADDRESS_SIZE == 64 && (defined(LL_WINDOWS) || defined(LL_DARWIN) || defined(LL_LINUX))) free(p); // default x86_64 malloc alignment on windows, mac, and linux is 16 byte aligned #else @@ -184,13 +215,15 @@ inline void ll_aligned_free_16(void *p) inline void* ll_aligned_realloc_16(void* ptr, size_t size, size_t old_size) // returned hunk MUST be freed with ll_aligned_free_16(). { + LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY; + LL_PROFILE_FREE(ptr); #if (ADDRESS_SIZE == 64 && (defined(LL_WINDOWS) || defined(LL_DARWIN) || defined(LL_LINUX))) - return realloc(ptr, size); // default x86_64 malloc alignment on windows, mac, and linux is 16 byte aligned + void* ret = realloc(ptr, size); // default x86_64 malloc alignment on windows, mac, and linux is 16 byte aligned #else #if defined(LL_WINDOWS) - return _aligned_realloc(ptr, size, 16); + void* ret = _aligned_realloc(ptr, size, 16); #elif defined(LL_DARWIN) - return realloc(ptr,size); // default osx malloc is 16 byte aligned. + void* ret = realloc(ptr,size); // default osx malloc is 16 byte aligned. #else //FIXME: memcpy is SLOW but posix lacks aligned realloc void* ret = ll_aligned_malloc_16(size); @@ -206,23 +239,28 @@ inline void* ll_aligned_realloc_16(void* ptr, size_t size, size_t old_size) // r return ret; #endif #endif + LL_PROFILE_ALLOC(ptr, size); + return ret; } inline void* ll_aligned_malloc_32(size_t size) // returned hunk MUST be freed with ll_aligned_free_32(). { + LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY; #if defined(LL_WINDOWS) - return _aligned_malloc(size, 32); + void* ret = _aligned_malloc(size, 32); #else - void *rtn = NULL; - if (LL_LIKELY(0 == posix_memalign(&rtn, 32, size))) - return rtn; - else // bad alignment requested, or out of memory - return NULL; + void *ret; + if (0 != posix_memalign(&ret, 32, size)) + return nullptr; #endif + LL_PROFILE_ALLOC(ret, size); + return ret; } inline void ll_aligned_free_32(void *p) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY; + LL_PROFILE_FREE(p); #if defined(LL_WINDOWS) _aligned_free(p); #else @@ -232,19 +270,23 @@ inline void ll_aligned_free_32(void *p) inline void* ll_aligned_malloc_64(size_t size) // returned hunk MUST be freed with ll_aligned_free_64(). { + LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY; #if defined(LL_WINDOWS) - return _aligned_malloc(size, 64); + void* ret = _aligned_malloc(size, 64); #else - void *rtn = NULL; - if (LL_LIKELY(0 == posix_memalign(&rtn, 64, size))) - return rtn; - else // bad alignment requested, or out of memory - return NULL; + void *ret; + if (0 != posix_memalign(&ret, 64, size)) + return nullptr; #endif + LL_PROFILE_ALLOC(ret, size); + return ret; + } inline void ll_aligned_free_64(void *p) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY; + LL_PROFILE_FREE(p); #if defined(LL_WINDOWS) _aligned_free(p); #else @@ -256,33 +298,39 @@ inline void ll_aligned_free_64(void *p) template<size_t ALIGNMENT> LL_FORCE_INLINE void* ll_aligned_malloc(size_t size) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY; + void* ret; if (LL_DEFAULT_HEAP_ALIGN % ALIGNMENT == 0) { - return malloc(size); + ret = malloc(size); + LL_PROFILE_ALLOC(ret, size); } else if (ALIGNMENT == 16) { - return ll_aligned_malloc_16(size); + ret = ll_aligned_malloc_16(size); } else if (ALIGNMENT == 32) { - return ll_aligned_malloc_32(size); + ret = ll_aligned_malloc_32(size); } else if (ALIGNMENT == 64) { - return ll_aligned_malloc_64(size); + ret = ll_aligned_malloc_64(size); } else { - return ll_aligned_malloc_fallback(size, ALIGNMENT); + ret = ll_aligned_malloc_fallback(size, ALIGNMENT); } + return ret; } template<size_t ALIGNMENT> LL_FORCE_INLINE void ll_aligned_free(void* ptr) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY; if (ALIGNMENT == LL_DEFAULT_HEAP_ALIGN) { + LL_PROFILE_FREE(ptr); free(ptr); } else if (ALIGNMENT == 16) @@ -308,6 +356,7 @@ LL_FORCE_INLINE void ll_aligned_free(void* ptr) // inline void ll_memcpy_nonaliased_aligned_16(char* __restrict dst, const char* __restrict src, size_t bytes) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY; assert(src != NULL); assert(dst != NULL); assert(bytes > 0); diff --git a/indra/llcommon/llmutex.cpp b/indra/llcommon/llmutex.cpp index 216ad19495c4b302a1409f1b8a9a7b09088e03f0..638ff7e9285fc61f61ce56127f78496ec1730286 100644 --- a/indra/llcommon/llmutex.cpp +++ b/indra/llcommon/llmutex.cpp @@ -33,13 +33,14 @@ void LLMutex::lock() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD if(isSelfLocked()) { //redundant lock mCount++; return; } - mMutex.Lock(); + mMutex.lock(); #if MUTEX_DEBUG // Have to have the lock before we can access the debug info @@ -49,11 +50,12 @@ void LLMutex::lock() mIsLocked[id] = TRUE; #endif - mLockingThread = absl::Hash<std::thread::id>{}(LLThread::currentID()); + mLockingThread = LLThread::currentID(); } void LLMutex::unlock() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD if (mCount > 0) { //not the root unlock mCount--; @@ -68,37 +70,44 @@ void LLMutex::unlock() mIsLocked[id] = FALSE; #endif - mLockingThread = 0; - mMutex.Unlock(); + mLockingThread = LLThread::id_t(); + mMutex.unlock(); } bool LLMutex::isLocked() { - if (!mMutex.TryLock()) + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD + if (!mMutex.try_lock()) { return true; } else { - mMutex.Unlock(); + mMutex.unlock(); return false; } } bool LLMutex::isSelfLocked() { - return mLockingThread == absl::Hash<std::thread::id>{}(LLThread::currentID()); + return mLockingThread == LLThread::currentID(); +} + +LLThread::id_t LLMutex::lockingThread() const +{ + return mLockingThread; } bool LLMutex::trylock() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD if(isSelfLocked()) { //redundant lock mCount++; return true; } - if (!mMutex.TryLock()) + if (!mMutex.try_lock()) { return false; } @@ -111,7 +120,7 @@ bool LLMutex::trylock() mIsLocked[id] = TRUE; #endif - mLockingThread = absl::Hash<std::thread::id>{}(LLThread::currentID()); + mLockingThread = LLThread::currentID(); return true; } @@ -125,19 +134,21 @@ LLCondition::LLCondition() : void LLCondition::wait() { - mMutex.Lock(); - mCond.Wait(&mMutex); - mMutex.Unlock(); + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD + std::unique_lock< std::mutex > lock(mMutex); + mCond.wait(lock); } void LLCondition::signal() { - mCond.Signal(); + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD + mCond.notify_one(); } void LLCondition::broadcast() { - mCond.SignalAll(); + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD + mCond.notify_all(); } //============================================================================ diff --git a/indra/llcommon/llmutex.h b/indra/llcommon/llmutex.h index 733f51a615f60437e39cc69d113694f3c5426b3e..010b2e88f5af90ed59ed8b903cc9f5eacd6e1f4f 100644 --- a/indra/llcommon/llmutex.h +++ b/indra/llcommon/llmutex.h @@ -30,7 +30,8 @@ #include "stdtypes.h" #include "llthread.h" -#include "absl/synchronization/mutex.h" +#include "mutex.h" +#include <condition_variable> //============================================================================ @@ -45,32 +46,19 @@ class LL_COMMON_API LLMutex { public: - enum InitKey - { - E_CONST_INIT = 0 - }; - - - LLMutex() : - mMutex() - { - } + LLMutex() = default; - explicit constexpr LLMutex(InitKey) : - mMutex(absl::kConstInit) - { - } - void lock(); // blocks bool trylock(); // non-blocking, returns true if lock held. void unlock(); // undefined behavior when called on mutex not being held bool isLocked(); // non-blocking, but does do a lock/unlock so not free bool isSelfLocked(); //return true if locked in a same thread + LLThread::id_t lockingThread() const; //get ID of locking thread protected: - absl::Mutex mMutex; - mutable size_t mLockingThread = 0; + std::mutex mMutex; mutable U32 mCount = 0; + mutable LLThread::id_t mLockingThread; #if MUTEX_DEBUG std::map<LLThread::id_t, BOOL> mIsLocked; @@ -88,7 +76,7 @@ class LL_COMMON_API LLCondition final : public LLMutex void broadcast(); protected: - absl::CondVar mCond; + std::condition_variable mCond; }; class LLMutexLock @@ -119,8 +107,8 @@ class LLMutexLock { if (mMutex && mLocked) { - mMutex->unlock(); mLocked = false; + mMutex->unlock(); } } private: @@ -149,7 +137,7 @@ class LLMutexTrylock mLocked = mMutex->trylock(); } - LLMutexTrylock(LLMutex* mutex, U32 aTries, U32 delay_ms) + LLMutexTrylock(LLMutex* mutex, U32 aTries, U32 delay_ms = 10) : mMutex(mutex), mLocked(false) { @@ -202,99 +190,42 @@ class LLMutexTrylock bool mLocked; }; - -// This is here due to include order issues wrt llmutex.h and lockstatic.h -namespace llthread -{ - template <typename Static> - class LockStaticLL - { - typedef LLMutexLock lock_t; - public: - LockStaticLL() : - mData(getStatic()), - mLock(&mData->mMutex) - {} - Static* get() const { return mData; } - operator Static* () const { return get(); } - Static* operator->() const { return get(); } - // sometimes we must explicitly unlock... - void unlock() - { - // but once we do, access is no longer permitted - mData = nullptr; - mLock.unlock(); - } - protected: - Static* mData; - lock_t mLock; - private: - Static* getStatic() - { - // Static::mMutex must be function-local static rather than class- - // static. Some of our consumers must function properly (therefore - // lock properly) even when the containing module's static variables - // have not yet been runtime-initialized. A mutex requires - // construction. A static class member might not yet have been - // constructed. - // - // We could store a dumb mutex_t*, notice when it's NULL and allocate a - // heap mutex -- but that's vulnerable to race conditions. And we can't - // defend the dumb pointer with another mutex. - // - // We could store a std::atomic<mutex_t*> -- but a default-constructed - // std::atomic<T> does not contain a valid T, even a default-constructed - // T! Which means std::atomic, too, requires runtime initialization. - // - // But a function-local static is guaranteed to be initialized exactly - // once: the first time control reaches that declaration. - static Static sData; - return &sData; - } - }; -} - -class AbslMutexMaybeTrylock +/** +* @class LLScopedLock +* @brief Small class to help lock and unlock mutexes. +* +* The constructor handles the lock, and the destructor handles +* the unlock. Instances of this class are <b>not</b> thread safe. +*/ +class LL_COMMON_API LLScopedLock : private boost::noncopyable { public: - AbslMutexMaybeTrylock(absl::Mutex* mutex) - : mMutex(mutex), - mLocked(false) - { - if (mMutex) - mLocked = mMutex->TryLock(); - } - - AbslMutexMaybeTrylock(absl::Mutex* mutex, U32 aTries, U32 delay_ms = 10) - : mMutex(mutex), - mLocked(false) - { - if (!mMutex) - return; + /** + * @brief Constructor which accepts a mutex, and locks it. + * + * @param mutex An allocated mutex. If you pass in NULL, + * this wrapper will not lock. + */ + LLScopedLock(std::mutex* mutex); + + /** + * @brief Destructor which unlocks the mutex if still locked. + */ + ~LLScopedLock(); + + /** + * @brief Check lock. + */ + bool isLocked() const { return mLocked; } + + /** + * @brief This method unlocks the mutex. + */ + void unlock(); - for (U32 i = 0; i < aTries; ++i) - { - mLocked = mMutex->TryLock(); - if (mLocked) - break; - std::this_thread::sleep_for(std::chrono::milliseconds(delay_ms)); - } - } - - ~AbslMutexMaybeTrylock() - { - if (mMutex && mLocked) - mMutex->Unlock(); - } - - bool isLocked() const - { - return mLocked; - } - -private: - absl::Mutex* mMutex; - bool mLocked; +protected: + bool mLocked; + std::mutex* mMutex; }; #endif // LL_LLMUTEX_H diff --git a/indra/llcommon/llpreprocessor.h b/indra/llcommon/llpreprocessor.h index 8ac90d65bca29a36e881f43e5231f3296e0862b2..10ce307dc2561c08be3736ac91b211ce7c705f22 100644 --- a/indra/llcommon/llpreprocessor.h +++ b/indra/llcommon/llpreprocessor.h @@ -157,7 +157,9 @@ #define LL_DLLIMPORT #endif // LL_WINDOWS -#if ! defined(LL_WINDOWS) +#if __clang__ || ! defined(LL_WINDOWS) +// Only on Windows, and only with the Microsoft compiler (vs. clang) is +// wchar_t potentially not a distinct type. #define LL_WCHAR_T_NATIVE 1 #else // LL_WINDOWS // https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros diff --git a/indra/llcommon/llprocessor.cpp b/indra/llcommon/llprocessor.cpp index 7b4fa5f7afd3039107007b12461dd040e28be333..78d833817cd6f74ef4705556d584511f28711442 100644 --- a/indra/llcommon/llprocessor.cpp +++ b/indra/llcommon/llprocessor.cpp @@ -45,20 +45,6 @@ #include "llsd.h" -#if LL_MSVC && _M_X64 -# define LL_X86_64 1 -# define LL_X86 1 -#elif LL_MSVC && _M_IX86 -# define LL_X86 1 -#elif LL_GNUC && ( defined(__amd64__) || defined(__x86_64__) ) -# define LL_X86_64 1 -# define LL_X86 1 -#elif LL_GNUC && ( defined(__i386__) ) -# define LL_X86 1 -#elif LL_GNUC && ( defined(__powerpc__) || defined(__ppc__) ) -# define LL_PPC 1 -#endif - class LLProcessorInfoImpl; // foward declaration for the mImpl; namespace @@ -133,7 +119,11 @@ namespace eMONTIOR_MWAIT=33, eCPLDebugStore=34, eThermalMonitor2=35, - eAltivec=36 + eAltivec=36, + eSSE3S_Features = 37, + eSSE4_1_Features = 38, + eSSE4_2_Features = 39, + eSSE4a_Features = 40, }; const char* cpu_feature_names[] = @@ -176,7 +166,11 @@ namespace "CPL Qualified Debug Store", "Thermal Monitor 2", - "Altivec" + "Altivec", + "SSE3S Instructions", + "SSE4.1 Instructions", + "SSE4.2 Instructions", + "SSE4a Instructions", }; std::string intel_CPUFamilyName(int composed_family) @@ -265,6 +259,31 @@ class LLProcessorInfoImpl return hasExtension(cpu_feature_names[eSSE2_Ext]); } + bool hasSSE3() const + { + return hasExtension(cpu_feature_names[eSSE3_Features]); + } + + bool hasSSE3S() const + { + return hasExtension(cpu_feature_names[eSSE3S_Features]); + } + + bool hasSSE41() const + { + return hasExtension(cpu_feature_names[eSSE4_1_Features]); + } + + bool hasSSE42() const + { + return hasExtension(cpu_feature_names[eSSE4_2_Features]); + } + + bool hasSSE4a() const + { + return hasExtension(cpu_feature_names[eSSE4a_Features]); + } + bool hasAltivec() const { return hasExtension("Altivec"); @@ -524,6 +543,12 @@ class LLProcessorInfoWindowsImpl : public LLProcessorInfoImpl cpu_string[kVendorNameSize] = '\0'; std::string cpu_vendor(cpu_string); setInfo(eVendor, cpu_vendor); + std::string cmp_vendor(cpu_vendor); + bool is_amd = false; + if (cmp_vendor == "AuthenticAMD") + { + is_amd = true; + } if (ids > 0) { @@ -553,6 +578,7 @@ class LLProcessorInfoWindowsImpl : public LLProcessorInfoImpl if (cpu_info[2] & 0x8) { + // intel specific SSE3 suplements setExtension(cpu_feature_names[eMONTIOR_MWAIT]); } @@ -566,6 +592,26 @@ class LLProcessorInfoWindowsImpl : public LLProcessorInfoImpl setExtension(cpu_feature_names[eThermalMonitor2]); } + if (cpu_info[2] & 0x200) + { + setExtension(cpu_feature_names[eSSE3S_Features]); + } + + if (is_amd) + { + setExtension(cpu_feature_names[eSSE4a_Features]); + } + + if (cpu_info[2] & 0x80000) + { + setExtension(cpu_feature_names[eSSE4_1_Features]); + } + + if (cpu_info[2] & 0x100000) + { + setExtension(cpu_feature_names[eSSE4_2_Features]); + } + int feature_info = cpu_info[3]; for (int index = 0, bit = 1; index < eSSE3_Features; ++index, bit <<= 1) { @@ -734,6 +780,41 @@ class LLProcessorInfoDarwinImpl : public LLProcessorInfoImpl uint64_t ext_feature_info = getSysctlInt64("machdep.cpu.extfeature_bits"); S32 *ext_feature_infos = (S32*)(&ext_feature_info); setConfig(eExtFeatureBits, ext_feature_infos[0]); + + + char cpu_features[1024]; + len = sizeof(cpu_features); + memset(cpu_features, 0, len); + sysctlbyname("machdep.cpu.features", (void*)cpu_features, &len, NULL, 0); + + std::string cpu_features_str(cpu_features); + cpu_features_str = " " + cpu_features_str + " "; + + if (cpu_features_str.find(" SSE3 ") != std::string::npos) + { + setExtension(cpu_feature_names[eSSE3_Features]); + } + + if (cpu_features_str.find(" SSSE3 ") != std::string::npos) + { + setExtension(cpu_feature_names[eSSE3S_Features]); + } + + if (cpu_features_str.find(" SSE4.1 ") != std::string::npos) + { + setExtension(cpu_feature_names[eSSE4_1_Features]); + } + + if (cpu_features_str.find(" SSE4.2 ") != std::string::npos) + { + setExtension(cpu_feature_names[eSSE4_2_Features]); + } + + if (cpu_features_str.find(" SSE4A ") != std::string::npos) + { + // Not supposed to happen? + setExtension(cpu_feature_names[eSSE4a_Features]); + } } }; @@ -844,6 +925,31 @@ class LLProcessorInfoLinuxImpl : public LLProcessorInfoImpl { setExtension(cpu_feature_names[eSSE2_Ext]); } + + if (flags.find(" pni ") != std::string::npos) + { + setExtension(cpu_feature_names[eSSE3_Features]); + } + + if (flags.find(" ssse3 ") != std::string::npos) + { + setExtension(cpu_feature_names[eSSE3S_Features]); + } + + if (flags.find(" sse4_1 ") != std::string::npos) + { + setExtension(cpu_feature_names[eSSE4_1_Features]); + } + + if (flags.find(" sse4_2 ") != std::string::npos) + { + setExtension(cpu_feature_names[eSSE4_2_Features]); + } + + if (flags.find(" sse4a ") != std::string::npos) + { + setExtension(cpu_feature_names[eSSE4a_Features]); + } # endif // LL_X86 } @@ -903,6 +1009,11 @@ LLProcessorInfo::LLProcessorInfo() : mImpl(NULL) F64MegahertzImplicit LLProcessorInfo::getCPUFrequency() const { return mImpl->getCPUFrequency(); } bool LLProcessorInfo::hasSSE() const { return mImpl->hasSSE(); } bool LLProcessorInfo::hasSSE2() const { return mImpl->hasSSE2(); } +bool LLProcessorInfo::hasSSE3() const { return mImpl->hasSSE3(); } +bool LLProcessorInfo::hasSSE3S() const { return mImpl->hasSSE3S(); } +bool LLProcessorInfo::hasSSE41() const { return mImpl->hasSSE41(); } +bool LLProcessorInfo::hasSSE42() const { return mImpl->hasSSE42(); } +bool LLProcessorInfo::hasSSE4a() const { return mImpl->hasSSE4a(); } bool LLProcessorInfo::hasAltivec() const { return mImpl->hasAltivec(); } std::string LLProcessorInfo::getCPUFamilyName() const { return mImpl->getCPUFamilyName(); } std::string LLProcessorInfo::getCPUBrandName() const { return mImpl->getCPUBrandName(); } diff --git a/indra/llcommon/llprocessor.h b/indra/llcommon/llprocessor.h index 89c9cf4988ef28150cd1649f880040b11db787b1..ee886c7c0fa07438805ddc070522c0031fdabcd8 100644 --- a/indra/llcommon/llprocessor.h +++ b/indra/llcommon/llprocessor.h @@ -29,6 +29,20 @@ #define LLPROCESSOR_H #include "llunits.h" +#if LL_MSVC && _M_X64 +# define LL_X86_64 1 +# define LL_X86 1 +#elif LL_MSVC && _M_IX86 +# define LL_X86 1 +#elif LL_GNUC && ( defined(__amd64__) || defined(__x86_64__) ) +# define LL_X86_64 1 +# define LL_X86 1 +#elif LL_GNUC && ( defined(__i386__) ) +# define LL_X86 1 +#elif LL_GNUC && ( defined(__powerpc__) || defined(__ppc__) ) +# define LL_PPC 1 +#endif + class LLProcessorInfoImpl; class LL_COMMON_API LLProcessorInfo @@ -40,6 +54,11 @@ class LL_COMMON_API LLProcessorInfo F64MegahertzImplicit getCPUFrequency() const; bool hasSSE() const; bool hasSSE2() const; + bool hasSSE3() const; + bool hasSSE3S() const; + bool hasSSE41() const; + bool hasSSE42() const; + bool hasSSE4a() const; bool hasAltivec() const; std::string getCPUFamilyName() const; std::string getCPUBrandName() const; diff --git a/indra/llcommon/llprofiler.h b/indra/llcommon/llprofiler.h new file mode 100644 index 0000000000000000000000000000000000000000..f9d7ae7ce41c74bc1e45354dbfd44700eb580a36 --- /dev/null +++ b/indra/llcommon/llprofiler.h @@ -0,0 +1,151 @@ +/** + * @file llprofiler.h + * @brief Wrapper for Tracy and/or other profilers + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2021, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_PROFILER_H +#define LL_PROFILER_H + +// If you use the default macros LL_PROFILE_ZONE_SCOPED and LL_PROFILE_ZONE_NAMED to profile code ... +// +// void foo() +// { +// LL_PROFILE_ZONE_SCOPED; +// : +// +// { +// LL_PROFILE_ZONE_NAMED("widget bar"); +// : +// } +// { +// LL_PROFILE_ZONE_NAMED("widget qux"); +// : +// } +// } +// +// ... please be aware that ALL these will show up in a Tracy capture which can quickly exhaust memory. +// Instead, use LL_PROFILE_ZONE_SCOPED_CATEGORY_* and LL_PROFILE_ZONE_NAMED_CATEGORY_* to profile code ... +// +// void foo() +// { +// LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; +// : +// +// { +// LL_PROFILE_ZONE_NAMED_CATEGORY_UI("widget bar"); +// : +// } +// { +// LL_PROFILE_ZONE_NAMED_CATEGORY_UI("widget qux"); +// : +// } +// } +// +// ... as these can be selectively turned on/off. This will minimize memory usage and visual clutter in a Tracy capture. +// See llprofiler_categories.h for more details on profiling categories. + +#define LL_PROFILER_CONFIG_NONE 0 // No profiling +#define LL_PROFILER_CONFIG_FAST_TIMER 1 // Profiling on: Only Fast Timers +#define LL_PROFILER_CONFIG_TRACY 2 // Profiling on: Only Tracy +#define LL_PROFILER_CONFIG_TRACY_FAST_TIMER 3 // Profiling on: Fast Timers + Tracy + +#ifndef LL_PROFILER_CONFIGURATION +#define LL_PROFILER_CONFIGURATION LL_PROFILER_CONFIG_FAST_TIMER +#endif + +extern thread_local bool gProfilerEnabled; + +#if defined(LL_PROFILER_CONFIGURATION) && (LL_PROFILER_CONFIGURATION > LL_PROFILER_CONFIG_NONE) + #if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY || LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY_FAST_TIMER + #define TRACY_ENABLE 1 +// Normally these would be enabled but we want to be able to build any viewer with Tracy enabled and run the Tracy server on another machine +// They must be undefined in order to work across multiple machines +// #define TRACY_NO_BROADCAST 1 +// #define TRACY_ONLY_LOCALHOST 1 + #define TRACY_ONLY_IPV4 1 + #include "Tracy.hpp" + + // Mutually exclusive with detailed memory tracing + #define LL_PROFILER_ENABLE_TRACY_OPENGL 0 + #endif + + #if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY + #define LL_PROFILER_FRAME_END FrameMark + #define LL_PROFILER_SET_THREAD_NAME( name ) tracy::SetThreadName( name ); gProfilerEnabled = true; + #define LL_RECORD_BLOCK_TIME(name) ZoneScoped // Want descriptive names; was: ZoneNamedN( ___tracy_scoped_zone, #name, true ); + #define LL_PROFILE_ZONE_NAMED(name) ZoneNamedN( ___tracy_scoped_zone, name, true ); + #define LL_PROFILE_ZONE_NAMED_COLOR(name,color) ZoneNamedNC( ___tracy_scopped_zone, name, color, true ) // RGB + #define LL_PROFILE_ZONE_SCOPED ZoneScoped + + #define LL_PROFILE_ZONE_NUM( val ) ZoneValue( val ) + #define LL_PROFILE_ZONE_TEXT( text, size ) ZoneText( text, size ) + + #define LL_PROFILE_ZONE_ERR(name) LL_PROFILE_ZONE_NAMED_COLOR( name, 0XFF0000 ) // RGB yellow + #define LL_PROFILE_ZONE_INFO(name) LL_PROFILE_ZONE_NAMED_COLOR( name, 0X00FFFF ) // RGB cyan + #define LL_PROFILE_ZONE_WARN(name) LL_PROFILE_ZONE_NAMED_COLOR( name, 0x0FFFF00 ) // RGB red + #define LL_PROFILE_ALLOC(ptr, size) TracyAlloc(ptr, size) + #define LL_PROFILE_FREE(ptr) TracyFree(ptr) + #endif + #if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_FAST_TIMER + #define LL_PROFILER_FRAME_END + #define LL_PROFILER_SET_THREAD_NAME( name ) (void)(name) + #define LL_RECORD_BLOCK_TIME(name) const LLTrace::BlockTimer& LL_GLUE_TOKENS(block_time_recorder, __LINE__)(LLTrace::timeThisBlock(name)); (void)LL_GLUE_TOKENS(block_time_recorder, __LINE__); + #define LL_PROFILE_ZONE_NAMED(name) // LL_PROFILE_ZONE_NAMED is a no-op when Tracy is disabled + #define LL_PROFILE_ZONE_SCOPED // LL_PROFILE_ZONE_SCOPED is a no-op when Tracy is disabled + #define LL_PROFILE_ZONE_COLOR(name,color) // LL_RECORD_BLOCK_TIME(name) + + #define LL_PROFILE_ZONE_NUM( val ) (void)( val ); // Not supported + #define LL_PROFILE_ZONE_TEXT( text, size ) (void)( text ); void( size ); // Not supported + + #define LL_PROFILE_ZONE_ERR(name) (void)(name); // Not supported + #define LL_PROFILE_ZONE_INFO(name) (void)(name); // Not supported + #define LL_PROFILE_ZONE_WARN(name) (void)(name); // Not supported + #define LL_PROFILE_ALLOC(ptr, size) (void)(ptr); (void)(size); + #define LL_PROFILE_FREE(ptr) (void)(ptr); + #endif + #if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY_FAST_TIMER + #define LL_PROFILER_FRAME_END FrameMark + #define LL_PROFILER_SET_THREAD_NAME( name ) tracy::SetThreadName( name ); gProfilerEnabled = true; + #define LL_RECORD_BLOCK_TIME(name) ZoneNamedN(___tracy_scoped_zone, #name, true); const LLTrace::BlockTimer& LL_GLUE_TOKENS(block_time_recorder, __LINE__)(LLTrace::timeThisBlock(name)); (void)LL_GLUE_TOKENS(block_time_recorder, __LINE__); + #define LL_PROFILE_ZONE_NAMED(name) ZoneNamedN( ___tracy_scoped_zone, #name, true ); + #define LL_PROFILE_ZONE_NAMED_COLOR(name,color) ZoneNamedNC( ___tracy_scopped_zone, name, color, true ) // RGB + #define LL_PROFILE_ZONE_SCOPED ZoneScoped + + #define LL_PROFILE_ZONE_NUM( val ) ZoneValue( val ) + #define LL_PROFILE_ZONE_TEXT( text, size ) ZoneText( text, size ) + + #define LL_PROFILE_ZONE_ERR(name) LL_PROFILE_ZONE_NAMED_COLOR( name, 0XFF0000 ) // RGB yellow + #define LL_PROFILE_ZONE_INFO(name) LL_PROFILE_ZONE_NAMED_COLOR( name, 0X00FFFF ) // RGB cyan + #define LL_PROFILE_ZONE_WARN(name) LL_PROFILE_ZONE_NAMED_COLOR( name, 0x0FFFF00 ) // RGB red + #define LL_PROFILE_ALLOC(ptr, size) TracyAlloc(ptr, size) + #define LL_PROFILE_FREE(ptr) TracyFree(ptr) + #endif +#else + #define LL_PROFILER_FRAME_END + #define LL_PROFILER_SET_THREAD_NAME( name ) (void)(name) +#endif // LL_PROFILER + +#include "llprofilercategories.h" + +#endif // LL_PROFILER_H diff --git a/indra/llcommon/llprofilercategories.h b/indra/llcommon/llprofilercategories.h new file mode 100644 index 0000000000000000000000000000000000000000..8db29468cccae8370314911240047f74a1c1413f --- /dev/null +++ b/indra/llcommon/llprofilercategories.h @@ -0,0 +1,280 @@ +/** + * @file llprofiler_ategories.h + * @brief Profiling categories to minimize Tracy memory usage when viewing captures. + * + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Second Life Viewer Source Code + * 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 + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_PROFILER_CATEGORIES_H +#define LL_PROFILER_CATEGORIES_H + +// A Tracy capture can quickly consume memory. Use these defines to selectively turn on/off Tracy profiling for these categories. +// The biggest memory usage ones are: +// +// LL_PROFILER_CATEGORY_ENABLE_DRAWPOOL +// LL_PROFILER_CATEGORY_ENABLE_LLSD +// LL_PROFILER_CATEGORY_ENABLE_MEMORY +// LL_PROFILER_CATEGORY_ENABLE_SHADERS +// +// NOTE: You can still manually use: +// LL_PROFILE_ZONE_SCOPED(); +// LL_PROFILE_ZONE_NAMED("name"); +// but just be aware that those will ALWAYS show up in a Tracy capture +// a) using more memory, and +// b) adding visual clutter. +#define LL_PROFILER_CATEGORY_ENABLE_APP 1 +#define LL_PROFILER_CATEGORY_ENABLE_AVATAR 1 +#define LL_PROFILER_CATEGORY_ENABLE_DISPLAY 1 +#define LL_PROFILER_CATEGORY_ENABLE_DRAWABLE 1 +#define LL_PROFILER_CATEGORY_ENABLE_DRAWPOOL 1 +#define LL_PROFILER_CATEGORY_ENABLE_ENVIRONMENT 1 +#define LL_PROFILER_CATEGORY_ENABLE_FACE 1 +#define LL_PROFILER_CATEGORY_ENABLE_LLSD 1 +#define LL_PROFILER_CATEGORY_ENABLE_LOGGING 1 +#define LL_PROFILER_CATEGORY_ENABLE_MATERIAL 1 +#define LL_PROFILER_CATEGORY_ENABLE_MEDIA 1 +#define LL_PROFILER_CATEGORY_ENABLE_MEMORY 1 +#define LL_PROFILER_CATEGORY_ENABLE_NETWORK 1 +#define LL_PROFILER_CATEGORY_ENABLE_OCTREE 1 +#define LL_PROFILER_CATEGORY_ENABLE_PIPELINE 1 +#define LL_PROFILER_CATEGORY_ENABLE_SHADER 1 +#define LL_PROFILER_CATEGORY_ENABLE_SPATIAL 1 +#define LL_PROFILER_CATEGORY_ENABLE_STATS 1 +#define LL_PROFILER_CATEGORY_ENABLE_STRING 1 +#define LL_PROFILER_CATEGORY_ENABLE_TEXTURE 1 +#define LL_PROFILER_CATEGORY_ENABLE_THREAD 1 +#define LL_PROFILER_CATEGORY_ENABLE_UI 1 +#define LL_PROFILER_CATEGORY_ENABLE_VIEWER 1 +#define LL_PROFILER_CATEGORY_ENABLE_VERTEX 1 +#define LL_PROFILER_CATEGORY_ENABLE_VOLUME 1 +#define LL_PROFILER_CATEGORY_ENABLE_WIN32 1 + +#if LL_PROFILER_CATEGORY_ENABLE_APP + #define LL_PROFILE_ZONE_NAMED_CATEGORY_APP LL_PROFILE_ZONE_NAMED + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_APP LL_PROFILE_ZONE_SCOPED +#else + #define LL_PROFILE_ZONE_NAMED_CATEGORY_APP(name) + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_APP +#endif + +#if LL_PROFILER_CATEGORY_ENABLE_AVATAR + #define LL_PROFILE_ZONE_NAMED_CATEGORY_AVATAR LL_PROFILE_ZONE_NAMED + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR LL_PROFILE_ZONE_SCOPED +#else + #define LL_PROFILE_ZONE_NAMED_CATEGORY_AVATAR(name) + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR +#endif + +#if LL_PROFILER_CATEGORY_ENABLE_DISPLAY + #define LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY LL_PROFILE_ZONE_NAMED + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY LL_PROFILE_ZONE_SCOPED +#else + #define LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY(name) + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY +#endif + +#if LL_PROFILER_CATEGORY_ENABLE_DRAWABLE + #define LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWABLE LL_PROFILE_ZONE_NAMED + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE LL_PROFILE_ZONE_SCOPED +#else + #define LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWABLE(name) + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE +#endif + +#if LL_PROFILER_CATEGORY_ENABLE_DRAWPOOL + #define LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL LL_PROFILE_ZONE_NAMED + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL LL_PROFILE_ZONE_SCOPED +#else + #define LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL(name) + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL +#endif + +#if LL_PROFILER_CATEGORY_ENABLE_ENVIRONMENT + #define LL_PROFILE_ZONE_NAMED_CATEGORY_ENVIRONMENT LL_PROFILE_ZONE_NAMED + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_ENVIRONMENT LL_PROFILE_ZONE_SCOPED +#else + #define LL_PROFILE_ZONE_NAMED_CATEGORY_ENVIRONMENT(name) + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_ENVIRONMENT +#endif + +#if LL_PROFILER_CATEGORY_ENABLE_FACE + #define LL_PROFILE_ZONE_NAMED_CATEGORY_FACE LL_PROFILE_ZONE_NAMED + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE LL_PROFILE_ZONE_SCOPED +#else + #define LL_PROFILE_ZONE_NAMED_CATEGORY_FACE(name) + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE +#endif + +#if LL_PROFILER_CATEGORY_ENABLE_LLSD + #define LL_PROFILE_ZONE_NAMED_CATEGORY_LLSD LL_PROFILE_ZONE_NAMED + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD LL_PROFILE_ZONE_SCOPED +#else + #define LL_PROFILE_ZONE_NAMED_CATEGORY_LLSD(name) + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD +#endif + +#if LL_PROFILER_CATEGORY_ENABLE_LOGGING + #define LL_PROFILE_ZONE_NAMED_CATEGORY_LOGGING LL_PROFILE_ZONE_NAMED + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING LL_PROFILE_ZONE_SCOPED +#else + #define LL_PROFILE_ZONE_NAMED_CATEGORY_LOGGING(name) + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING +#endif + +#if LL_PROFILER_CATEGORY_ENABLE_MATERIAL + #define LL_PROFILE_ZONE_NAMED_CATEGORY_MATERIAL LL_PROFILE_ZONE_NAMED + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_MATERIAL LL_PROFILE_ZONE_SCOPED +#else + #define LL_PROFILE_ZONE_NAMED_CATEGORY_MATERIAL(name) + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_MATERIAL +#endif + +#if LL_PROFILER_CATEGORY_ENABLE_MEDIA + #define LL_PROFILE_ZONE_NAMED_CATEGORY_MEDIA LL_PROFILE_ZONE_NAMED + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_MEDIA LL_PROFILE_ZONE_SCOPED +#else + #define LL_PROFILE_ZONE_NAMED_CATEGORY_MEDIA(name) + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_MEDIA +#endif + +#if LL_PROFILER_CATEGORY_ENABLE_MEMORY + #define LL_PROFILE_ZONE_NAMED_CATEGORY_MEMORY LL_PROFILE_ZONE_NAMED + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY LL_PROFILE_ZONE_SCOPED +#else + #define LL_PROFILE_ZONE_NAMED_CATEGORY_MEMORY(name) + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY +#endif + +#if LL_PROFILER_CATEGORY_ENABLE_NETWORK + #define LL_PROFILE_ZONE_NAMED_CATEGORY_NETWORK LL_PROFILE_ZONE_NAMED + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK LL_PROFILE_ZONE_SCOPED +#else + #define LL_PROFILE_ZONE_NAMED_CATEGORY_NETWORK(name) + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK +#endif + +#if LL_PROFILER_CATEGORY_ENABLE_OCTREE + #define LL_PROFILE_ZONE_NAMED_CATEGORY_OCTREE LL_PROFILE_ZONE_NAMED + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_OCTREE LL_PROFILE_ZONE_SCOPED +#else + #define LL_PROFILE_ZONE_NAMED_CATEGORY_OCTREE(name) + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_OCTREE +#endif + +#if LL_PROFILER_CATEGORY_ENABLE_PIPELINE + #define LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE LL_PROFILE_ZONE_NAMED + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE LL_PROFILE_ZONE_SCOPED +#else + #define LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE(name) + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE +#endif + +#if LL_PROFILER_CATEGORY_ENABLE_SHADER + #define LL_PROFILE_ZONE_NAMED_CATEGORY_SHADER LL_PROFILE_ZONE_NAMED + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER LL_PROFILE_ZONE_SCOPED +#else + #define LL_PROFILE_ZONE_NAMED_CATEGORY_SHADER(name) + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER +#endif + +#if LL_PROFILER_CATEGORY_ENABLE_SPATIAL + #define LL_PROFILE_ZONE_NAMED_CATEGORY_SPATIAL LL_PROFILE_ZONE_NAMED + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL LL_PROFILE_ZONE_SCOPED +#else + #define LL_PROFILE_ZONE_NAMED_CATEGORY_SPATIAL(name) + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL +#endif + +#if LL_PROFILER_CATEGORY_ENABLE_STATS + #define LL_PROFILE_ZONE_NAMED_CATEGORY_STATS LL_PROFILE_ZONE_NAMED + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS LL_PROFILE_ZONE_SCOPED +#else + #define LL_PROFILE_ZONE_NAMED_CATEGORY_STATS(name) + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS +#endif + +#if LL_PROFILER_CATEGORY_ENABLE_STRING + #define LL_PROFILE_ZONE_NAMED_CATEGORY_STRING LL_PROFILE_ZONE_NAMED + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_STRING LL_PROFILE_ZONE_SCOPED +#else + #define LL_PROFILE_ZONE_NAMED_CATEGORY_STRING(name) + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_STRING +#endif + +#if LL_PROFILER_CATEGORY_ENABLE_TEXTURE + #define LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE LL_PROFILE_ZONE_NAMED + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE LL_PROFILE_ZONE_SCOPED +#else + #define LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE(name) + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE +#endif + +#if LL_PROFILER_CATEGORY_ENABLE_THREAD + #define LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD LL_PROFILE_ZONE_NAMED + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD LL_PROFILE_ZONE_SCOPED +#else + #define LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD(name) + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD +#endif + +#if LL_PROFILER_CATEGORY_ENABLE_UI + #define LL_PROFILE_ZONE_NAMED_CATEGORY_UI LL_PROFILE_ZONE_NAMED + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_UI LL_PROFILE_ZONE_SCOPED +#else + #define LL_PROFILE_ZONE_NAMED_CATEGORY_UI(name) + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_UI +#endif + +#if LL_PROFILER_CATEGORY_ENABLE_VERTEX + #define LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX LL_PROFILE_ZONE_NAMED + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX LL_PROFILE_ZONE_SCOPED +#else + #define LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX(name) + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX +#endif + +#if LL_PROFILER_CATEGORY_ENABLE_VIEWER + #define LL_PROFILE_ZONE_NAMED_CATEGORY_VIEWER LL_PROFILE_ZONE_NAMED + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_VIEWER LL_PROFILE_ZONE_SCOPED +#else + #define LL_PROFILE_ZONE_NAMED_CATEGORY_VIEWER(name) + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_VIEWER +#endif + +#if LL_PROFILER_CATEGORY_ENABLE_VOLUME + #define LL_PROFILE_ZONE_NAMED_CATEGORY_VOLUME LL_PROFILE_ZONE_NAMED + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME LL_PROFILE_ZONE_SCOPED +#else + #define LL_PROFILE_ZONE_NAMED_CATEGORY_VOLUME(name) + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME +#endif + +#if LL_PROFILER_CATEGORY_ENABLE_WIN32 + #define LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32 LL_PROFILE_ZONE_NAMED + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_WIN32 LL_PROFILE_ZONE_SCOPED +#else + #define LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32(name) + #define LL_PROFILE_ZONE_SCOPED_CATEGORY_WIN32 +#endif + +#endif // LL_PROFILER_CATEGORIES_H + diff --git a/indra/llcommon/llrefcount.cpp b/indra/llcommon/llrefcount.cpp index 29a5ca6f245cbec59e6be9205607a415fc4e050b..6852b5536aecdfebb1627ae218cfcfed26bacc78 100644 --- a/indra/llcommon/llrefcount.cpp +++ b/indra/llcommon/llrefcount.cpp @@ -29,6 +29,9 @@ #include "llerror.h" +// maximum reference count before sounding memory leak alarm +const S32 gMaxRefCount = S32_MAX; + LLRefCount::LLRefCount(const LLRefCount& other) : mRef(0) { @@ -47,7 +50,7 @@ LLRefCount::LLRefCount() : LLRefCount::~LLRefCount() { - if (mRef != 0) + if (mRef != LL_REFCOUNT_FREE && mRef != 0) { LL_ERRS() << "deleting non-zero reference" << LL_ENDL; } diff --git a/indra/llcommon/llrefcount.h b/indra/llcommon/llrefcount.h index 0e45a80e419055ed2283e78b1974cfddca35c409..43cef103280262b6aadde07c28b56f9392dea792 100644 --- a/indra/llcommon/llrefcount.h +++ b/indra/llcommon/llrefcount.h @@ -37,6 +37,10 @@ class LLMutex; // see llthread.h for LLThreadSafeRefCount //---------------------------------------------------------------------------- +//nonsense but recognizable value for freed LLRefCount (aids in debugging) +#define LL_REFCOUNT_FREE 1234567890 +extern const S32 gMaxRefCount; + class LL_COMMON_API LLRefCount { protected: @@ -47,17 +51,25 @@ class LL_COMMON_API LLRefCount public: LLRefCount(); + inline void validateRefCount() const + { + llassert(mRef > 0); // ref count below 0, likely corrupted + llassert(mRef < gMaxRefCount); // ref count excessive, likely memory leak + } + inline void ref() const { mRef++; + validateRefCount(); } inline S32 unref() const { - llassert(mRef >= 1); + validateRefCount(); if (0 == --mRef) { - delete this; + mRef = LL_REFCOUNT_FREE; // set to nonsense yet recognizable value to aid in debugging + delete this; return 0; } return mRef; diff --git a/indra/llcommon/llsd.cpp b/indra/llcommon/llsd.cpp index ccb676edca4579110865e27eb14018b5bea3c028..1d885ba28c53f2400967026159cf49770c3e571c 100644 --- a/indra/llcommon/llsd.cpp +++ b/indra/llcommon/llsd.cpp @@ -405,6 +405,7 @@ namespace ImplMap& ImplMap::makeMap(LLSD::Impl*& var) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD; if (shared()) { ImplMap* i = new ImplMap(mData); @@ -419,18 +420,21 @@ namespace bool ImplMap::has(const std::string_view k) const { + LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD; DataMap::const_iterator i = mData.find(k); return i != mData.end(); } LLSD ImplMap::get(const std::string_view k) const { + LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD; DataMap::const_iterator i = mData.find(k); return (i != mData.end()) ? i->second : LLSD(); } LLSD ImplMap::getKeys() const { + LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD; LLSD keys = LLSD::emptyArray(); DataMap::const_iterator iter = mData.begin(); while (iter != mData.end()) @@ -443,11 +447,13 @@ namespace void ImplMap::insert(const LLSD::String& k, const LLSD& v) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD; mData.emplace(DataMap::value_type(k, v)); } void ImplMap::erase(const LLSD::String& k) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD; mData.erase(k); } @@ -706,6 +712,7 @@ const LLSD::Impl& LLSD::Impl::safe(const Impl* impl) ImplMap& LLSD::Impl::makeMap(Impl*& var) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD; ImplMap* im = new ImplMap; reset(var, im); return *im; @@ -925,10 +932,15 @@ LLSD& LLSD::with(const String& k, const LLSD& v) void LLSD::erase(const String& k) { makeMap(impl).erase(k); } LLSD& LLSD::operator[](const std::string_view k) - { return makeMap(impl).ref(k); } +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD; + return makeMap(impl).ref(k); +} const LLSD& LLSD::operator[](const std::string_view k) const - { return safe(impl).ref(k); } - +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD; + return safe(impl).ref(k); +} LLSD LLSD::emptyArray() { @@ -951,10 +963,16 @@ LLSD& LLSD::with(Integer i, const LLSD& v) LLSD& LLSD::append(const LLSD& v) { return makeArray(impl).append(v); } void LLSD::erase(Integer i) { makeArray(impl).erase(i); } -LLSD& LLSD::operator[](Integer i) - { return makeArray(impl).ref(i); } +LLSD& LLSD::operator[](Integer i) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD; + return makeArray(impl).ref(i); +} const LLSD& LLSD::operator[](Integer i) const - { return safe(impl).ref(i); } +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD; + return safe(impl).ref(i); +} static const char *llsd_dump(const LLSD &llsd, bool useXMLFormat) { diff --git a/indra/llcommon/llsdparam.cpp b/indra/llcommon/llsdparam.cpp index 6a824e2faf2d9c163dee9e2637da4d8dce0c97a8..a84b320570a8d68f8a99fff36adec9b4a7e995d1 100644 --- a/indra/llcommon/llsdparam.cpp +++ b/indra/llcommon/llsdparam.cpp @@ -37,8 +37,6 @@ static LLInitParam::Parser::parser_write_func_map_t sWriteFuncs; static LLInitParam::Parser::parser_inspect_func_map_t sInspectFuncs; static const LLSD NO_VALUE_MARKER; -LLTrace::BlockTimerStatHandle FTM_SD_PARAM_ADAPTOR("LLSD to LLInitParam conversion"); - // // LLParamSDParser // diff --git a/indra/llcommon/llsdparam.h b/indra/llcommon/llsdparam.h index 89528365bd9e62745378ec2bd0beff9e1ee0a378..c91968a009dbfc5d66be3d7aab0d3094ff78d893 100644 --- a/indra/llcommon/llsdparam.h +++ b/indra/llcommon/llsdparam.h @@ -110,7 +110,6 @@ typedef LLInitParam::Parser parser_t; }; -extern LL_COMMON_API LLTrace::BlockTimerStatHandle FTM_SD_PARAM_ADAPTOR; template<typename T> class LLSDParamAdapter : public T { @@ -118,7 +117,7 @@ class LLSDParamAdapter : public T LLSDParamAdapter() = default; LLSDParamAdapter(const LLSD& sd) { - LL_RECORD_BLOCK_TIME(FTM_SD_PARAM_ADAPTOR); + LL_PROFILE_ZONE_SCOPED; LLParamSDParser parser; // don't spam for implicit parsing of LLSD, as we want to allow arbitrary freeform data and ignore most of it bool parse_silently = true; diff --git a/indra/llcommon/llsdutil.cpp b/indra/llcommon/llsdutil.cpp index ccd4bb071359fdb7ceb27683be9c874d8f308e7e..9fcb245e1f706520b508c6a1eac827d5f53acae1 100644 --- a/indra/llcommon/llsdutil.cpp +++ b/indra/llcommon/llsdutil.cpp @@ -218,6 +218,8 @@ BOOL compare_llsd_with_template( const LLSD& template_llsd, LLSD& resultant_llsd) { + LL_PROFILE_ZONE_SCOPED + if ( llsd_to_test.isUndefined() && template_llsd.isDefined() ) @@ -335,6 +337,8 @@ bool filter_llsd_with_template( const LLSD & template_llsd, LLSD & resultant_llsd) { + LL_PROFILE_ZONE_SCOPED + if (llsd_to_test.isUndefined() && template_llsd.isDefined()) { resultant_llsd = template_llsd; @@ -529,6 +533,8 @@ class TypeLookup public: TypeLookup() { + LL_PROFILE_ZONE_SCOPED + for (const LLSDTypeData *di(boost::begin(typedata)), *dend(boost::end(typedata)); di != dend; ++di) { mMap[di->type] = di->name; @@ -537,6 +543,8 @@ class TypeLookup std::string lookup(LLSD::Type type) const { + LL_PROFILE_ZONE_SCOPED + MapType::const_iterator found = mMap.find(type); if (found != mMap.end()) { @@ -587,6 +595,8 @@ static std::string match_types(LLSD::Type expect, // prototype.type() LLSD::Type actual, // type we're checking const std::string& pfx) // as for llsd_matches { + LL_PROFILE_ZONE_SCOPED + // Trivial case: if the actual type is exactly what we expect, we're good. if (actual == expect) return ""; @@ -624,6 +634,8 @@ static std::string match_types(LLSD::Type expect, // prototype.type() // see docstring in .h file std::string llsd_matches(const LLSD& prototype, const LLSD& data, const std::string& pfx) { + LL_PROFILE_ZONE_SCOPED + // An undefined prototype means that any data is valid. // An undefined slot in an array or map prototype means that any data // may fill that slot. @@ -756,6 +768,8 @@ std::string llsd_matches(const LLSD& prototype, const LLSD& data, const std::str bool llsd_equals(const LLSD& lhs, const LLSD& rhs, int bits) { + LL_PROFILE_ZONE_SCOPED + // We're comparing strict equality of LLSD representation rather than // performing any conversions. So if the types aren't equal, the LLSD // values aren't equal. @@ -864,6 +878,8 @@ namespace llsd LLSD& drill_ref(LLSD& blob, const LLSD& rawPath) { + LL_PROFILE_ZONE_SCOPED + // Treat rawPath uniformly as an array. If it's not already an array, // store it as the only entry in one. (But let's say Undefined means an // empty array.) @@ -889,6 +905,8 @@ LLSD& drill_ref(LLSD& blob, const LLSD& rawPath) // path entry that's bad. for (LLSD::Integer i = 0; i < path.size(); ++i) { + LL_PROFILE_ZONE_NUM( i ) + const LLSD& key{path[i]}; if (key.isString()) { @@ -917,6 +935,8 @@ LLSD& drill_ref(LLSD& blob, const LLSD& rawPath) LLSD drill(const LLSD& blob, const LLSD& path) { + LL_PROFILE_ZONE_SCOPED + // drill_ref() does exactly what we want. Temporarily cast away // const-ness and use that. return drill_ref(const_cast<LLSD&>(blob), path); @@ -929,6 +949,8 @@ LLSD drill(const LLSD& blob, const LLSD& path) // filter may be include to exclude/include keys in a map. LLSD llsd_clone(LLSD value, LLSD filter) { + LL_PROFILE_ZONE_SCOPED + LLSD clone; bool has_filter(filter.isMap()); diff --git a/indra/llcommon/llsingleton.cpp b/indra/llcommon/llsingleton.cpp index 4cabaf5e58c538761e0593dfa1682d6a6e23c9ba..76a36c900574d1b7c4f5620fd86c02fdcc238ce3 100644 --- a/indra/llcommon/llsingleton.cpp +++ b/indra/llcommon/llsingleton.cpp @@ -59,8 +59,8 @@ class LLSingletonBase::MasterList final : // manipulating some data in the master list, we must also check whether // it's safe to log -- which involves querying a different LLSingleton -- // which requires accessing the master list. - typedef LLMutex mutex_t; - typedef LLMutexLock lock_t; + typedef std::recursive_mutex mutex_t; + typedef std::unique_lock<mutex_t> lock_t; mutex_t mMutex; @@ -72,7 +72,7 @@ class LLSingletonBase::MasterList final : public: Lock(): mMasterList(MasterList::instance()), - mLock(&mMasterList.mMutex) + mLock(mMasterList.mMutex) {} Lock(const Lock&) = delete; Lock& operator=(const Lock&) = delete; diff --git a/indra/llcommon/llsingleton.h b/indra/llcommon/llsingleton.h index 49a0d9e923c2062e7fb6370c8705f1bc5e235e88..a48302cf00d8dcfae7058cc3d43e2922a6067b4f 100644 --- a/indra/llcommon/llsingleton.h +++ b/indra/llcommon/llsingleton.h @@ -34,7 +34,6 @@ #include "mutex.h" #include "lockstatic.h" #include "llthread.h" // on_main_thread() -#include "llmutex.h" #include "llmainthreadtask.h" class LLSingletonBase: private boost::noncopyable @@ -293,17 +292,13 @@ class LLSingleton : public LLSingletonBase { // Use a recursive_mutex in case of constructor circularity. With a // non-recursive mutex, that would result in deadlock. - typedef LLMutex mutex_t; + typedef std::recursive_mutex mutex_t; mutex_t mMutex; // LockStatic looks for mMutex EInitState mInitState{UNINITIALIZED}; DERIVED_TYPE* mInstance{nullptr}; }; - typedef llthread::LockStaticLL<SingletonData> LockStatic; - -protected: - inline static DERIVED_TYPE* sUnsafeInstance = nullptr; -private: + typedef llthread::LockStatic<SingletonData> LockStatic; // Allow LLParamSingleton subclass -- but NOT DERIVED_TYPE itself -- to // access our private members. @@ -352,9 +347,6 @@ class LLSingleton : public LLSingletonBase lk->mInstance->initSingleton(); lk->mInitState = INITIALIZED; - // Cache for fast unsafe access - sUnsafeInstance = lk->mInstance; - // pop this off stack of initializing singletons pop_initializing(lk->mInstance); } @@ -423,8 +415,6 @@ class LLSingleton : public LLSingletonBase // deleteSingleton() to defend against manual deletion. When we moved // cleanup to deleteSingleton(), we hit crashes due to dangling // pointers in the MasterList. - sUnsafeInstance = nullptr; - LockStatic lk; lk->mInstance = nullptr; lk->mInitState = DELETED; @@ -465,6 +455,7 @@ class LLSingleton : public LLSingletonBase static DERIVED_TYPE* getInstance() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; // We know the viewer has LLSingleton dependency circularities. If you // feel strongly motivated to eliminate them, cheers and good luck. // (At that point we could consider a much simpler locking mechanism.) @@ -586,17 +577,6 @@ class LLSingleton : public LLSingletonBase return instance; } - // Thread unsafe access - static DERIVED_TYPE* getInstanceFast() - { - if (!sUnsafeInstance) - { - // Dummy call to force populate - return getInstance(); - } - return sUnsafeInstance; - } - // Reference version of getInstance() // Preferred over getInstance() as it disallows checking for nullptr static DERIVED_TYPE& instance() @@ -604,12 +584,6 @@ class LLSingleton : public LLSingletonBase return *getInstance(); } - // Thread unsafe access - static DERIVED_TYPE& instanceFast() - { - return *getInstanceFast(); - } - // Has this singleton been created yet? // Use this to avoid accessing singletons before they can safely be constructed. static bool instanceExists() @@ -763,16 +737,6 @@ class LLParamSingleton : public LLSingleton<DERIVED_TYPE> return nullptr; } - static DERIVED_TYPE* getInstanceFast() - { - if (!super::sUnsafeInstance) - { - // Dummy call to force populate - return getInstance(); - } - return super::sUnsafeInstance; - } - // instance() is replicated here so it calls // LLParamSingleton::getInstance() rather than LLSingleton::getInstance() // -- avoid making getInstance() virtual @@ -780,11 +744,6 @@ class LLParamSingleton : public LLSingleton<DERIVED_TYPE> { return *getInstance(); } - - static DERIVED_TYPE& instanceFast() - { - return *getInstanceFast(); - } }; /** @@ -865,4 +824,36 @@ private: \ /* LLSINGLETON() is carefully implemented to permit exactly this */ \ LLSINGLETON(DERIVED_CLASS) = default; +// Relatively unsafe singleton implementation that is much faster +// and simpler than LLSingleton, but has no dependency tracking +// or inherent thread safety and requires manual invocation of +// createInstance before first use. +template<class T> +class LLSimpleton +{ +public: + template <typename... ARGS> + static void createInstance(ARGS&&... args) + { + llassert(sInstance == nullptr); + sInstance = new T(std::forward<ARGS>(args)...); + } + + static inline T* getInstance() { return sInstance; } + static inline T& instance() { return *getInstance(); } + static inline bool instanceExists() { return sInstance != nullptr; } + + static void deleteSingleton() + { + delete sInstance; + sInstance = nullptr; + } + +private: + static T* sInstance; +}; + +template <class T> +T* LLSimpleton<T>::sInstance{ nullptr }; + #endif diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp index 518aa406670e5fc069c80621ec51171030d14411..6a99937877e13051e94a0c3ca084ec07a1d54ba5 100644 --- a/indra/llcommon/llstring.cpp +++ b/indra/llcommon/llstring.cpp @@ -37,9 +37,6 @@ #include <winnls.h> // for WideCharToMultiByte #endif -LLTrace::BlockTimerStatHandle FT_STRING_FORMAT("String Format"); - - std::string ll_safe_string(const char* in) { if(in) return std::string(in); @@ -215,7 +212,7 @@ S32 utf16chars_to_wchar(const U16* inchars, llwchar* outchar) return inchars - base; } -llutf16string wstring_to_utf16str(const LLWString &utf32str, S32 len) +llutf16string wstring_to_utf16str(const llwchar* utf32str, size_t len) { llutf16string out; @@ -237,27 +234,19 @@ llutf16string wstring_to_utf16str(const LLWString &utf32str, S32 len) return out; } -llutf16string wstring_to_utf16str(const LLWString &utf32str) -{ - const S32 len = (S32)utf32str.length(); - return wstring_to_utf16str(utf32str, len); -} - -llutf16string utf8str_to_utf16str ( const std::string& utf8str ) +llutf16string utf8str_to_utf16str( const char* utf8str, size_t len ) { - LLWString wstr = utf8str_to_wstring ( utf8str ); + LLWString wstr = utf8str_to_wstring ( utf8str, len ); return wstring_to_utf16str ( wstr ); } - -LLWString utf16str_to_wstring(const llutf16string &utf16str, S32 len) +LLWString utf16str_to_wstring(const U16* utf16str, size_t len) { LLWString wout; - if((len <= 0) || utf16str.empty()) return wout; + if (len == 0) return wout; S32 i = 0; - // craziness to make gcc happy (llutf16string.c_str() is tweaked on linux): - const U16* chars16 = &(*(utf16str.begin())); + const U16* chars16 = utf16str; while (i < len) { llwchar cur_char; @@ -267,12 +256,6 @@ LLWString utf16str_to_wstring(const llutf16string &utf16str, S32 len) return wout; } -LLWString utf16str_to_wstring(const llutf16string &utf16str) -{ - const S32 len = (S32)utf16str.length(); - return utf16str_to_wstring(utf16str, len); -} - // Length in llwchar (UTF-32) of the first len units (16 bits) of the given UTF-16 string. S32 utf16str_wstring_length(const llutf16string &utf16str, const S32 utf16_len) { @@ -392,8 +375,7 @@ S32 wstring_utf8_length(const LLWString& wstr) return len; } - -LLWString utf8str_to_wstring(const std::string& utf8str, S32 len) +LLWString utf8str_to_wstring(const char* utf8str, size_t len) { LLWString wout; @@ -481,13 +463,7 @@ LLWString utf8str_to_wstring(const std::string& utf8str, S32 len) return wout; } -LLWString utf8str_to_wstring(const std::string& utf8str) -{ - const S32 len = (S32)utf8str.length(); - return utf8str_to_wstring(utf8str, len); -} - -std::string wstring_to_utf8str(const LLWString& utf32str, S32 len) +std::string wstring_to_utf8str(const llwchar* utf32str, size_t len) { std::string out; @@ -503,20 +479,9 @@ std::string wstring_to_utf8str(const LLWString& utf32str, S32 len) return out; } -std::string wstring_to_utf8str(const LLWString& utf32str) -{ - const S32 len = (S32)utf32str.length(); - return wstring_to_utf8str(utf32str, len); -} - -std::string utf16str_to_utf8str(const llutf16string& utf16str) -{ - return wstring_to_utf8str(utf16str_to_wstring(utf16str)); -} - -std::string utf16str_to_utf8str(const llutf16string& utf16str, S32 len) +std::string utf16str_to_utf8str(const U16* utf16str, size_t len) { - return wstring_to_utf8str(utf16str_to_wstring(utf16str, len), len); + return wstring_to_utf8str(utf16str_to_wstring(utf16str, len)); } std::string utf8str_trim(const std::string& utf8str) @@ -729,57 +694,70 @@ std::string utf8str_removeCRLF(const std::string& utf8str) } #if LL_WINDOWS -std::string ll_convert_wide_to_string(std::wstring_view in) +unsigned int ll_wstring_default_code_page() { - return ll_convert_wide_to_string(in, CP_UTF8); + return CP_UTF8; } -std::string ll_convert_wide_to_string(std::wstring_view in, unsigned int code_page) +std::string ll_convert_wide_to_string(const wchar_t* in, size_t len_in, unsigned int code_page) { - std::string out {}; - if (in.length() > 0) - { - int len = WideCharToMultiByte(code_page, 0, in.data(), in.length(), NULL, 0, 0, 0); - if (len == 0) - { - return out; - } - - out.resize(len); - - WideCharToMultiByte(code_page, 0, in.data(), in.length(), out.data(), out.length(), 0, 0); - } - return out; + std::string out; + if(in) + { + int len_out = WideCharToMultiByte( + code_page, + 0, + in, + len_in, + NULL, + 0, + 0, + 0); + // We will need two more bytes for the double NULL ending + // created in WideCharToMultiByte(). + char* pout = new char [len_out + 2]; + memset(pout, 0, len_out + 2); + if(pout) + { + WideCharToMultiByte( + code_page, + 0, + in, + len_in, + pout, + len_out, + 0, + 0); + out.assign(pout); + delete[] pout; + } + } + return out; } -std::wstring ll_convert_string_to_wide(std::string_view in) +std::wstring ll_convert_string_to_wide(const char* in, size_t len, unsigned int code_page) { - return ll_convert_string_to_wide(in, CP_UTF8); -} + // From review: + // We can preallocate a wide char buffer that is the same length (in wchar_t elements) as the utf8 input, + // plus one for a null terminator, and be guaranteed to not overflow. -std::wstring ll_convert_string_to_wide(std::string_view in, unsigned int code_page) -{ - std::wstring out{}; + // Normally, I'd call that sort of thing premature optimization, + // but we *are* seeing string operations taking a bunch of time, especially when constructing widgets. +// int output_str_len = MultiByteToWideChar(code_page, 0, in.c_str(), in.length(), NULL, 0); - if (in.length() > 0) - { - // Calculate target buffer size (not including the zero terminator). - int len = MultiByteToWideChar(code_page, 0, - in.data(), in.size(), NULL, 0); - if (len == 0) - { - return out; - } + // reserve an output buffer that will be destroyed on exit, with a place + // to put NULL terminator + std::vector<wchar_t> w_out(len + 1); - out.resize(len); - // No error checking. We already know, that the conversion will succeed. - MultiByteToWideChar(code_page, 0, - in.data(), in.size(), out.data(), out.size()); - // Use out.data() in place of &out[0] for C++17 - } + memset(&w_out[0], 0, w_out.size()); + int real_output_str_len = MultiByteToWideChar(code_page, 0, in, len, + &w_out[0], w_out.size() - 1); - return out; + //looks like MultiByteToWideChar didn't add null terminator to converted string, see EXT-4858. + w_out[real_output_str_len] = 0; + // construct string<wchar_t> from our temporary output buffer + return {&w_out[0]}; } S32 wchart_to_llwchar(const wchar_t* inchars, llwchar* outchar) @@ -802,15 +780,15 @@ S32 wchart_to_llwchar(const wchar_t* inchars, llwchar* outchar) return inchars - base; } -LLWString ll_convert_wide_to_wstring(std::wstring_view in) +LLWString ll_convert_wide_to_wstring(const wchar_t* in, size_t len) { LLWString wout; - if (in.empty()) return wout; + if (!in) return wout; S32 i = 0; // craziness to make gcc happy (llutf16string.c_str() is tweaked on linux): - const wchar_t* chars16 = &(*(in.begin())); - while (i < in.size()) + const wchar_t* chars16 = &in[0]; + while (i < len) { llwchar cur_char; i += wchart_to_llwchar(chars16 + i, &cur_char); @@ -819,12 +797,12 @@ LLWString ll_convert_wide_to_wstring(std::wstring_view in) return wout; } -std::wstring ll_convert_wstring_to_wide(LLWStringView in) +std::wstring ll_convert_wstring_to_wide(const llwchar* in, size_t len) { std::wstring out; S32 i = 0; - while (i < in.size()) + while (i < len) { U32 cur_char = in[i]; if (cur_char > 0xFFFF) @@ -841,12 +819,13 @@ std::wstring ll_convert_wstring_to_wide(LLWStringView in) return out; } -std::string ll_convert_string_to_utf8_string(std::string_view in) +std::string ll_convert_string_to_utf8_string(const std::string& in) { - auto w_mesg = ll_convert_string_to_wide(in, CP_ACP); - std::string out_utf8(ll_convert_wide_to_string(w_mesg, CP_UTF8)); - - return out_utf8; + // If you pass code_page, you must also pass length, otherwise the code + // page parameter will be mistaken for length. + auto w_mesg = ll_convert_string_to_wide(in, in.length(), CP_ACP); + // CP_UTF8 is default -- see ll_wstring_default_code_page() above. + return ll_convert_wide_to_string(w_mesg); } namespace @@ -1450,7 +1429,7 @@ bool LLStringUtil::formatDatetime(std::string& replacement, std::string token, template<> S32 LLStringUtil::format(std::string& s, const format_map_t& substitutions) { - LL_RECORD_BLOCK_TIME(FT_STRING_FORMAT); + LL_PROFILE_ZONE_SCOPED_CATEGORY_STRING; S32 res = 0; std::string output; @@ -1523,7 +1502,7 @@ S32 LLStringUtil::format(std::string& s, const format_map_t& substitutions) template<> S32 LLStringUtil::format(std::string& s, const LLSD& substitutions) { - LL_RECORD_BLOCK_TIME(FT_STRING_FORMAT); + LL_PROFILE_ZONE_SCOPED_CATEGORY_STRING; S32 res = 0; if (!substitutions.isMap()) diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h index 9ff0a24d75fa2e3bfa96b91b3c96519ca88471f1..4f22f3d098cda0a1efd1dcbc1cadd3d8bc300aba 100644 --- a/indra/llcommon/llstring.h +++ b/indra/llcommon/llstring.h @@ -31,6 +31,7 @@ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor" #endif +#include <boost/call_traits.hpp> #include <boost/optional/optional.hpp> #include <absl/container/flat_hash_map.h> #if LL_GNUC && GCC_VERSION >= 90000 @@ -38,6 +39,7 @@ #endif #include <string> #include <cstdio> +#include <cwchar> // std::wcslen() //#include <locale> #include <iomanip> #include <algorithm> @@ -539,14 +541,71 @@ struct ll_convert_impl<T, T> T operator()(const T& in) const { return in; } }; +// simple construction from char* +template<typename T> +struct ll_convert_impl<T, const typename T::value_type*> +{ + T operator()(const typename T::value_type* in) const { return { in }; } +}; + // specialize ll_convert_impl<TO, FROM> to return EXPR #define ll_convert_alias(TO, FROM, EXPR) \ template<> \ struct ll_convert_impl<TO, FROM> \ { \ - TO operator()(const FROM& in) const { return EXPR; } \ + /* param_type optimally passes both char* and string */ \ + TO operator()(typename boost::call_traits<FROM>::param_type in) const { return EXPR; } \ } +// If all we're doing is copying characters, pass this to ll_convert_alias as +// EXPR. Since it expands into the 'return EXPR' slot in the ll_convert_impl +// specialization above, it implies TO{ in.begin(), in.end() }. +#define LL_CONVERT_COPY_CHARS { in.begin(), in.end() } + +// Generic name for strlen() / wcslen() - the default implementation should +// (!) work with U16 and llwchar, but we don't intend to engage it. +template <typename CHARTYPE> +size_t ll_convert_length(const CHARTYPE* zstr) +{ + const CHARTYPE* zp; + // classic C string scan + for (zp = zstr; *zp; ++zp) + ; + return (zp - zstr); +} + +// specialize where we have a library function; may use intrinsic operations +template <> +inline size_t ll_convert_length<wchar_t>(const wchar_t* zstr) { return std::wcslen(zstr); } +template <> +inline size_t ll_convert_length<char> (const char* zstr) { return std::strlen(zstr); } + +// ll_convert_forms() is short for a bunch of boilerplate. It defines +// longname(const char*, len), longname(const char*), longname(const string&) +// and longname(const string&, len) so calls written pre-ll_convert() will +// work. Most of these overloads will be unified once we turn on C++17 and can +// use std::string_view. +// It also uses aliasmacro to ensure that both ll_convert<OUTSTR>(const char*) +// and ll_convert<OUTSTR>(const string&) will work. +#define ll_convert_forms(aliasmacro, OUTSTR, INSTR, longname) \ +LL_COMMON_API OUTSTR longname(const INSTR::value_type* in, size_t len); \ +inline auto longname(const INSTR& in, size_t len) \ +{ \ + return longname(in.c_str(), len); \ +} \ +inline auto longname(const INSTR::value_type* in) \ +{ \ + return longname(in, ll_convert_length(in)); \ +} \ +inline auto longname(const INSTR& in) \ +{ \ + return longname(in.c_str(), in.length()); \ +} \ +/* string param */ \ +aliasmacro(OUTSTR, INSTR, longname(in)); \ +/* char* param */ \ +aliasmacro(OUTSTR, const INSTR::value_type*, longname(in)) + // Make the incoming string a utf8 string. Replaces any unknown glyph // with the UNKNOWN_CHARACTER. Once any unknown glyph is found, the rest // of the data may not be recovered. @@ -583,63 +642,47 @@ LL_COMMON_API std::string rawstr_to_utf8(const std::string& raw); // LL_WCHAR_T_NATIVE. typedef std::basic_string<U16> llutf16string; -#if ! defined(LL_WCHAR_T_NATIVE) -// wchar_t is identical to U16, and std::wstring is identical to llutf16string. -// Defining an ll_convert alias involving llutf16string would collide with the -// comparable preferred alias involving std::wstring. (In this scenario, if -// you pass llutf16string, it will engage the std::wstring specialization.) -#define ll_convert_u16_alias(TO, FROM, EXPR) // nothing -#else // defined(LL_WCHAR_T_NATIVE) -// wchar_t is a distinct native type, so llutf16string is also a distinct -// type, and there IS a point to converting separately to/from llutf16string. -// (But why? Windows APIs are still defined in terms of wchar_t, and -// in this scenario llutf16string won't work for them!) -#define ll_convert_u16_alias(TO, FROM, EXPR) ll_convert_alias(TO, FROM, EXPR) +// Considering wchar_t, llwchar and U16, there are three relevant cases: +#if LLWCHAR_IS_WCHAR_T // every which way but Windows +// llwchar is identical to wchar_t, LLWString is identical to std::wstring. +// U16 is distinct, llutf16string is distinct (though pretty useless). +// Given conversions to/from LLWString and to/from llutf16string, conversions +// involving std::wstring would collide. +#define ll_convert_wstr_alias(TO, FROM, EXPR) // nothing +// but we can define conversions involving llutf16string without collisions +#define ll_convert_u16_alias(TO, FROM, EXPR) ll_convert_alias(TO, FROM, EXPR) + +#elif defined(LL_WCHAR_T_NATIVE) // Windows, either clang or MS /Zc:wchar_t +// llwchar (32-bit), wchar_t (16-bit) and U16 are all different types. +// Conversions to/from LLWString, to/from std::wstring and to/from llutf16string +// can all be defined. +#define ll_convert_wstr_alias(TO, FROM, EXPR) ll_convert_alias(TO, FROM, EXPR) +#define ll_convert_u16_alias(TO, FROM, EXPR) ll_convert_alias(TO, FROM, EXPR) + +#else // ! LL_WCHAR_T_NATIVE: Windows with MS /Zc:wchar_t- +// wchar_t is identical to U16, std::wstring is identical to llutf16string. +// Given conversions to/from LLWString and to/from std::wstring, conversions +// involving llutf16string would collide. +#define ll_convert_u16_alias(TO, FROM, EXPR) // nothing +// but we can define conversions involving std::wstring without collisions +#define ll_convert_wstr_alias(TO, FROM, EXPR) ll_convert_alias(TO, FROM, EXPR) +#endif + +ll_convert_forms(ll_convert_u16_alias, LLWString, llutf16string, utf16str_to_wstring); +ll_convert_forms(ll_convert_u16_alias, llutf16string, LLWString, wstring_to_utf16str); +ll_convert_forms(ll_convert_u16_alias, llutf16string, std::string, utf8str_to_utf16str); +ll_convert_forms(ll_convert_alias, LLWString, std::string, utf8str_to_wstring); -#if LL_WINDOWS -// LL_WCHAR_T_NATIVE is defined on non-Windows systems because, in fact, -// wchar_t is native. Everywhere but Windows, we use it for llwchar (see -// stdtypes.h). That makes LLWString identical to std::wstring, so these -// aliases for std::wstring would collide with those for LLWString. Only -// define on Windows, where converting between std::wstring and llutf16string -// means copying chars. -ll_convert_alias(llutf16string, std::wstring, llutf16string(in.begin(), in.end())); -ll_convert_alias(std::wstring, llutf16string, std::wstring(in.begin(), in.end())); -#endif // LL_WINDOWS -#endif // defined(LL_WCHAR_T_NATIVE) - -LL_COMMON_API LLWString utf16str_to_wstring(const llutf16string &utf16str, S32 len); -LL_COMMON_API LLWString utf16str_to_wstring(const llutf16string &utf16str); -ll_convert_u16_alias(LLWString, llutf16string, utf16str_to_wstring(in)); - -LL_COMMON_API llutf16string wstring_to_utf16str(const LLWString &utf32str, S32 len); -LL_COMMON_API llutf16string wstring_to_utf16str(const LLWString &utf32str); -ll_convert_u16_alias(llutf16string, LLWString, wstring_to_utf16str(in)); - -LL_COMMON_API llutf16string utf8str_to_utf16str ( const std::string& utf8str, S32 len); -LL_COMMON_API llutf16string utf8str_to_utf16str ( const std::string& utf8str ); -ll_convert_u16_alias(llutf16string, std::string, utf8str_to_utf16str(in)); - -LL_COMMON_API LLWString utf8str_to_wstring(const std::string &utf8str, S32 len); -LL_COMMON_API LLWString utf8str_to_wstring(const std::string &utf8str); // Same function, better name. JC inline LLWString utf8string_to_wstring(const std::string& utf8_string) { return utf8str_to_wstring(utf8_string); } -// best name of all -ll_convert_alias(LLWString, std::string, utf8string_to_wstring(in)); -// LL_COMMON_API S32 wchar_to_utf8chars(llwchar inchar, char* outchars); -LL_COMMON_API std::string wstring_to_utf8str(const LLWString &utf32str, S32 len); -LL_COMMON_API std::string wstring_to_utf8str(const LLWString &utf32str); -ll_convert_alias(std::string, LLWString, wstring_to_utf8str(in)); -LL_COMMON_API std::string utf16str_to_utf8str(const llutf16string &utf16str, S32 len); -LL_COMMON_API std::string utf16str_to_utf8str(const llutf16string &utf16str); -ll_convert_u16_alias(std::string, llutf16string, utf16str_to_utf8str(in)); +ll_convert_forms(ll_convert_alias, std::string, LLWString, wstring_to_utf8str); +ll_convert_forms(ll_convert_u16_alias, std::string, llutf16string, utf16str_to_utf8str); -#if LL_WINDOWS +// an older alias for utf16str_to_utf8str(llutf16string) inline std::string wstring_to_utf8str(const llutf16string &utf16str) { return utf16str_to_utf8str(utf16str);} -#endif // Length of this UTF32 string in bytes when transformed to UTF8 LL_COMMON_API S32 wstring_utf8_length(const LLWString& wstr); @@ -718,40 +761,54 @@ LL_COMMON_API std::string utf8str_removeCRLF(const std::string& utf8str); //@{ /** - * @brief Convert a wide string to std::string + * @brief Convert a wide string to/from std::string + * Convert a Windows wide string to/from our LLWString * * This replaces the unsafe W2A macro from ATL. */ -LL_COMMON_API std::string ll_convert_wide_to_string(std::wstring_view in, unsigned int code_page); -LL_COMMON_API std::string ll_convert_wide_to_string(std::wstring_view in); // default CP_UTF8 -ll_convert_alias(std::string, std::wstring, ll_convert_wide_to_string(in)); - -/** - * Converts a string to wide string. - */ -LL_COMMON_API std::wstring ll_convert_string_to_wide(std::string_view in, - unsigned int code_page); -// default CP_UTF8 -LL_COMMON_API std::wstring ll_convert_string_to_wide(std::string_view in); -ll_convert_alias(std::wstring, std::string, ll_convert_string_to_wide(in)); - -/** - * Convert a Windows wide string to our LLWString - */ -LL_COMMON_API LLWString ll_convert_wide_to_wstring(std::wstring_view in); -ll_convert_alias(LLWString, std::wstring, ll_convert_wide_to_wstring(in)); - -/** - * Convert LLWString to Windows wide string - */ -LL_COMMON_API std::wstring ll_convert_wstring_to_wide(LLWStringView in); -ll_convert_alias(std::wstring, LLWString, ll_convert_wstring_to_wide(in)); +// Avoid requiring this header to #include the Windows header file declaring +// our actual default code_page by delegating this function to our .cpp file. +LL_COMMON_API unsigned int ll_wstring_default_code_page(); + +// This is like ll_convert_forms(), with the added complexity of a code page +// parameter that may or may not be passed. +#define ll_convert_cp_forms(aliasmacro, OUTSTR, INSTR, longname) \ +/* declare the only nontrivial implementation (in .cpp file) */ \ +LL_COMMON_API OUTSTR longname( \ + const INSTR::value_type* in, \ + size_t len, \ + unsigned int code_page=ll_wstring_default_code_page()); \ +/* if passed only a char pointer, scan for nul terminator */ \ +inline auto longname(const INSTR::value_type* in) \ +{ \ + return longname(in, ll_convert_length(in)); \ +} \ +/* if passed string and length, extract its char pointer */ \ +inline auto longname( \ + const INSTR& in, \ + size_t len, \ + unsigned int code_page=ll_wstring_default_code_page()) \ +{ \ + return longname(in.c_str(), len, code_page); \ +} \ +/* if passed only a string object, no scan, pass known length */ \ +inline auto longname(const INSTR& in) \ +{ \ + return longname(in.c_str(), in.length()); \ +} \ +aliasmacro(OUTSTR, INSTR, longname(in)); \ +aliasmacro(OUTSTR, const INSTR::value_type*, longname(in)) + +ll_convert_cp_forms(ll_convert_wstr_alias, std::string, std::wstring, ll_convert_wide_to_string); +ll_convert_cp_forms(ll_convert_wstr_alias, std::wstring, std::string, ll_convert_string_to_wide); + ll_convert_forms(ll_convert_wstr_alias, LLWString, std::wstring, ll_convert_wide_to_wstring); + ll_convert_forms(ll_convert_wstr_alias, std::wstring, LLWString, ll_convert_wstring_to_wide); /** * Converts incoming string into utf8 string * */ -LL_COMMON_API std::string ll_convert_string_to_utf8_string(std::string_view in); +LL_COMMON_API std::string ll_convert_string_to_utf8_string(const std::string& in); /// Get Windows message string for passed GetLastError() code // VS 2013 doesn't let us forward-declare this template, which is what we @@ -1964,4 +2021,14 @@ void LLStringUtilBase<T>::truncate(string_type& string, size_type count) string.resize(count < cur_size ? count : cur_size); } +// The good thing about *declaration* macros, vs. usage macros, is that now +// we're done with them: we don't need them to bleed into the consuming source +// file. +#undef ll_convert_alias +#undef ll_convert_u16_alias +#undef ll_convert_wstr_alias +#undef LL_CONVERT_COPY_CHARS +#undef ll_convert_forms +#undef ll_convert_cp_forms + #endif // LL_STRING_H diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp index 9a956fb69990c1c804af4c3c0d94b81375a0ebeb..654226646d84f0dde939487e4ee54778c051e2e0 100644 --- a/indra/llcommon/llsys.cpp +++ b/indra/llcommon/llsys.cpp @@ -292,7 +292,7 @@ LLOSInfo::LLOSInfo() : { S32 major_version, minor_version, bugfix_version = 0; - if (LLSysDarwin::getOperatingSystemInfo(major_version, minor_version, bugfix_version)) + if (LLGetDarwinOSInfo(major_version, minor_version, bugfix_version)) { mMajorVer = major_version; mMinorVer = minor_version; @@ -467,6 +467,8 @@ LLOSInfo::LLOSInfo() : dotted_version_string << mMajorVer << "." << mMinorVer << "." << mBuild; mOSVersionString.append(dotted_version_string.str()); + mOSBitness = is64Bit() ? 64 : 32; + LL_INFOS("LLOSInfo") << "OS bitness: " << mOSBitness << LL_ENDL; } #ifndef LL_WINDOWS @@ -522,6 +524,11 @@ const std::string& LLOSInfo::getOSVersionString() const return mOSVersionString; } +const S32 LLOSInfo::getOSBitness() const +{ + return mOSBitness; +} + //static U32 LLOSInfo::getProcessVirtualSizeKB() { @@ -575,6 +582,25 @@ U32 LLOSInfo::getProcessResidentSizeKB() return resident_size; } +//static +bool LLOSInfo::is64Bit() +{ +#if LL_WINDOWS +#if defined(_WIN64) + return true; +#elif defined(_WIN32) + // 32-bit viewer may be run on both 32-bit and 64-bit Windows, need to elaborate + BOOL f64 = FALSE; + return IsWow64Process(GetCurrentProcess(), &f64) && f64; +#else + return false; +#endif +#else // ! LL_WINDOWS + // we only build a 64-bit mac viewer and currently we don't build for linux at all + return true; +#endif +} + LLCPUInfo::LLCPUInfo() { std::ostringstream out; @@ -582,6 +608,11 @@ LLCPUInfo::LLCPUInfo() // proc.WriteInfoTextFile("procInfo.txt"); mHasSSE = proc.hasSSE(); mHasSSE2 = proc.hasSSE2(); + mHasSSE3 = proc.hasSSE3(); + mHasSSE3S = proc.hasSSE3S(); + mHasSSE41 = proc.hasSSE41(); + mHasSSE42 = proc.hasSSE42(); + mHasSSE4a = proc.hasSSE4a(); mHasAltivec = proc.hasAltivec(); mCPUMHz = (F64)proc.getCPUFrequency(); mFamily = proc.getCPUFamilyName(); @@ -594,6 +625,35 @@ LLCPUInfo::LLCPUInfo() } mCPUString = out.str(); LLStringUtil::trim(mCPUString); + + if (mHasSSE) + { + mSSEVersions.append("1"); + } + if (mHasSSE2) + { + mSSEVersions.append("2"); + } + if (mHasSSE3) + { + mSSEVersions.append("3"); + } + if (mHasSSE3S) + { + mSSEVersions.append("3S"); + } + if (mHasSSE41) + { + mSSEVersions.append("4.1"); + } + if (mHasSSE42) + { + mSSEVersions.append("4.2"); + } + if (mHasSSE4a) + { + mSSEVersions.append("4a"); + } } bool LLCPUInfo::hasAltivec() const @@ -611,6 +671,31 @@ bool LLCPUInfo::hasSSE2() const return mHasSSE2; } +bool LLCPUInfo::hasSSE3() const +{ + return mHasSSE3; +} + +bool LLCPUInfo::hasSSE3S() const +{ + return mHasSSE3S; +} + +bool LLCPUInfo::hasSSE41() const +{ + return mHasSSE41; +} + +bool LLCPUInfo::hasSSE42() const +{ + return mHasSSE42; +} + +bool LLCPUInfo::hasSSE4a() const +{ + return mHasSSE4a; +} + F64 LLCPUInfo::getMHz() const { return mCPUMHz; @@ -621,6 +706,11 @@ std::string LLCPUInfo::getCPUString() const return mCPUString; } +const LLSD& LLCPUInfo::getSSEVersions() const +{ + return mSSEVersions; +} + void LLCPUInfo::stream(std::ostream& s) const { // gather machine information. @@ -630,6 +720,11 @@ void LLCPUInfo::stream(std::ostream& s) const // CPU's attributes regardless of platform s << "->mHasSSE: " << (U32)mHasSSE << std::endl; s << "->mHasSSE2: " << (U32)mHasSSE2 << std::endl; + s << "->mHasSSE3: " << (U32)mHasSSE3 << std::endl; + s << "->mHasSSE3S: " << (U32)mHasSSE3S << std::endl; + s << "->mHasSSE41: " << (U32)mHasSSE41 << std::endl; + s << "->mHasSSE42: " << (U32)mHasSSE42 << std::endl; + s << "->mHasSSE4a: " << (U32)mHasSSE4a << std::endl; s << "->mHasAltivec: " << (U32)mHasAltivec << std::endl; s << "->mCPUMHz: " << mCPUMHz << std::endl; s << "->mCPUString: " << mCPUString << std::endl; @@ -856,6 +951,7 @@ LLSD LLMemoryInfo::getStatsMap() const LLMemoryInfo& LLMemoryInfo::refresh() { + LL_PROFILE_ZONE_SCOPED mStatsMap = loadStatsMap(); #if SHOW_DEBUG @@ -867,11 +963,9 @@ LLMemoryInfo& LLMemoryInfo::refresh() return *this; } -static LLTrace::BlockTimerStatHandle FTM_MEMINFO_LOAD_STATS("MemInfo Load Stats"); - LLSD LLMemoryInfo::loadStatsMap() { - LL_RECORD_BLOCK_TIME(FTM_MEMINFO_LOAD_STATS); + LL_PROFILE_ZONE_SCOPED; // This implementation is derived from stream() code (as of 2011-06-29). Stats stats; diff --git a/indra/llcommon/llsys.h b/indra/llcommon/llsys.h index 044381155b896e2eb117c15650742387f2dfb8e0..fd3a55e4b3b70cf9cc208c9b3d170538adf282d5 100644 --- a/indra/llcommon/llsys.h +++ b/indra/llcommon/llsys.h @@ -51,6 +51,8 @@ class LL_COMMON_API LLOSInfo final : public LLSingleton<LLOSInfo> const std::string& getOSStringSimple() const; const std::string& getOSVersionString() const; + + const S32 getOSBitness() const; S32 mMajorVer; S32 mMinorVer; @@ -59,6 +61,7 @@ class LL_COMMON_API LLOSInfo final : public LLSingleton<LLOSInfo> #ifndef LL_WINDOWS static S32 getMaxOpenFiles(); #endif + static bool is64Bit(); static U32 getProcessVirtualSizeKB(); static U32 getProcessResidentSizeKB(); @@ -66,6 +69,7 @@ class LL_COMMON_API LLOSInfo final : public LLSingleton<LLOSInfo> std::string mOSString; std::string mOSStringSimple; std::string mOSVersionString; + S32 mOSBitness; }; @@ -76,10 +80,16 @@ class LL_COMMON_API LLCPUInfo void stream(std::ostream& s) const; std::string getCPUString() const; + const LLSD& getSSEVersions() const; bool hasAltivec() const; bool hasSSE() const; bool hasSSE2() const; + bool hasSSE3() const; + bool hasSSE3S() const; + bool hasSSE41() const; + bool hasSSE42() const; + bool hasSSE4a() const; F64 getMHz() const; // Family is "AMD Duron" or "Intel Pentium Pro" @@ -88,10 +98,16 @@ class LL_COMMON_API LLCPUInfo private: bool mHasSSE; bool mHasSSE2; + bool mHasSSE3; + bool mHasSSE3S; + bool mHasSSE41; + bool mHasSSE42; + bool mHasSSE4a; bool mHasAltivec; F64 mCPUMHz; std::string mFamily; std::string mCPUString; + LLSD mSSEVersions; }; //============================================================================= diff --git a/indra/llcommon/llsys_objc.h b/indra/llcommon/llsys_objc.h index 2d12ca7f2b276c6322e23b327e2f87fa0fe1949a..a528f2ceefc2e8386b624c42e1cbe4eabdbc89e7 100644 --- a/indra/llcommon/llsys_objc.h +++ b/indra/llcommon/llsys_objc.h @@ -1,46 +1,33 @@ -/* +/** * @file llsys_objc.h - * @brief Some objective-c crap for llcommon + * @brief Header file for llsys_objc.mm * - * (C) 2014 Cinder Roxley @ Second Life <cinder@alchemyviewer.org> + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2022, Linden Research, Inc. * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: + * 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. * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ */ -#ifndef LL_SYS_OBJC_H -#define LL_SYS_OBJC_H - -#ifndef LL_DARWIN -# error "This file should only be included when building on mac!" -#else - -namespace LLSysDarwin -{ +#ifndef LL_LLSYS_OBJC_H +#define LL_LLSYS_OBJC_H -bool getOperatingSystemInfo(int &major, int &minor, int &patch); -const char* getPreferredLanguage(); - -} +bool LLGetDarwinOSInfo(int &major, int &minor, int &patch); +const char* LLGetDarwinPreferredLanguage(); -#endif // !LL_DARWIN -#endif // LL_SYS_OBJC_H +#endif // LL_LLSYS_OBJC_H diff --git a/indra/llcommon/llsys_objc.mm b/indra/llcommon/llsys_objc.mm index 46b3337e7fb85f97a8b5d58d115e0861cdb68e56..bfede7839215e6c2cf7a175c7b3db9dbe0a1ddc8 100644 --- a/indra/llcommon/llsys_objc.mm +++ b/indra/llcommon/llsys_objc.mm @@ -1,54 +1,49 @@ -/* +/** * @file llsys_objc.mm - * @brief Some objective-c crap for llcommon + * @brief obj-c implementation of the system information functions * - * (C) 2014 Cinder Roxley @ Second Life <cinder@alchemyviewer.org> + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2022, Linden Research, Inc. * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: + * 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. * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ */ -#ifndef LL_DARWIN -# error "This file should only be included when building on mac!" -#else - #import "llsys_objc.h" -#import <Foundation/Foundation.h> -#import <AppKit/NSApplication.h> +#import <AppKit/AppKit.h> + +static int intAtStringIndex(NSArray *array, int index) +{ + return [(NSString *)[array objectAtIndex:index] integerValue]; +} -bool LLSysDarwin::getOperatingSystemInfo(int &major, int &minor, int &patch) +bool LLGetDarwinOSInfo(int &major, int &minor, int &patch) { NSOperatingSystemVersion osVersion = [[NSProcessInfo processInfo] operatingSystemVersion]; - major = osVersion.majorVersion; - minor = osVersion.minorVersion; - patch = osVersion.patchVersion; + major = (int)osVersion.majorVersion; + minor = (int)osVersion.minorVersion; + patch = (int)osVersion.patchVersion; return true; } -const char* LLSysDarwin::getPreferredLanguage() +const char* LLGetDarwinPreferredLanguage() { NSString* lang = [[NSLocale preferredLanguages] objectAtIndex:0]; const char* ret = [lang cStringUsingEncoding:NSASCIIStringEncoding]; return ret; } - -#endif // !LL_DARWIN diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index d8ec29b5b9409d298daec2b06a4ce749daa3f447..c6f2b5e1456af891119a7031e6c4059fb577211d 100644 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -135,6 +135,8 @@ void LLThread::threadRun() set_thread_name(mName.c_str()); #endif + LL_PROFILER_SET_THREAD_NAME( mName.c_str() ); + // this is the first point at which we're actually running in the new thread mID = currentID(); @@ -339,6 +341,7 @@ bool LLThread::runCondition(void) // Stop thread execution if requested until unpaused. void LLThread::checkPause() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD mDataLock->lock(); // This is in a while loop because the pthread API allows for spurious wakeups. @@ -370,17 +373,20 @@ void LLThread::setQuitting() // static LLThread::id_t LLThread::currentID() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD return std::this_thread::get_id(); } // static void LLThread::yield() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD std::this_thread::yield(); } void LLThread::wake() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD mDataLock->lock(); if(!shouldSleep()) { @@ -391,6 +397,7 @@ void LLThread::wake() void LLThread::wakeLocked() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD if(!shouldSleep()) { mRunCondition->signal(); @@ -399,11 +406,13 @@ void LLThread::wakeLocked() void LLThread::lockData() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD mDataLock->lock(); } void LLThread::unlockData() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD mDataLock->unlock(); } diff --git a/indra/llcommon/llthreadsafequeue.h b/indra/llcommon/llthreadsafequeue.h index 26e0d71d314341c4abf3b47231a12dfa3854dd96..68d79cdd12d7d565d824bdd6f981e8dbca8d0b7f 100644 --- a/indra/llcommon/llthreadsafequeue.h +++ b/indra/llcommon/llthreadsafequeue.h @@ -1,6 +1,6 @@ /** * @file llthreadsafequeue.h - * @brief Base classes for thread, mutex and condition handling. + * @brief Queue protected with mutexes for cross-thread use * * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code @@ -27,16 +27,19 @@ #ifndef LL_LLTHREADSAFEQUEUE_H #define LL_LLTHREADSAFEQUEUE_H -#include "llexception.h" -#include <deque> -#include <string> -#include <chrono> -#include "mutex.h" #include "llcoros.h" #include LLCOROS_MUTEX_HEADER #include <boost/fiber/timed_mutex.hpp> #include LLCOROS_CONDVAR_HEADER +#include "llexception.h" +#include "mutex.h" +#include <chrono> +#include <queue> +#include <string> +/***************************************************************************** +* LLThreadSafeQueue +*****************************************************************************/ // // A general queue exception. // @@ -66,70 +69,116 @@ class LL_COMMON_API LLThreadSafeQueueInterrupt: } }; -// -// Implements a thread safe FIFO. -// -template<typename ElementT> +/** + * Implements a thread safe FIFO. + */ +// Let the default std::queue default to underlying std::deque. Override if +// desired. +template<typename ElementT, typename QueueT=std::queue<ElementT>> class LLThreadSafeQueue { public: typedef ElementT value_type; - - // If the pool is set to NULL one will be allocated and managed by this - // queue. + + // Limiting the number of pending items prevents unbounded growth of the + // underlying queue. LLThreadSafeQueue(U32 capacity = 1024); - - // Add an element to the front of queue (will block if the queue has - // reached capacity). + virtual ~LLThreadSafeQueue() {} + + // Add an element to the queue (will block if the queue has reached + // capacity). // // This call will raise an interrupt error if the queue is closed while // the caller is blocked. - void pushFront(ElementT const & element); - - // Try to add an element to the front of queue without blocking. Returns + template <typename T> + void push(T&& element); + // legacy name + void pushFront(ElementT const & element) { return push(element); } + + // Add an element to the queue (will block if the queue has reached + // capacity). Return false if the queue is closed before push is possible. + template <typename T> + bool pushIfOpen(T&& element); + + // Try to add an element to the queue without blocking. Returns // true only if the element was actually added. - bool tryPushFront(ElementT const & element); + template <typename T> + bool tryPush(T&& element); + // legacy name + bool tryPushFront(ElementT const & element) { return tryPush(element); } - // Try to add an element to the front of queue, blocking if full but with - // timeout. Returns true if the element was added. + // Try to add an element to the queue, blocking if full but with timeout + // after specified duration. Returns true if the element was added. // There are potentially two different timeouts involved: how long to try // to lock the mutex, versus how long to wait for the queue to stop being // full. Careful settings for each timeout might be orders of magnitude // apart. However, this method conflates them. + template <typename Rep, typename Period, typename T> + bool tryPushFor(const std::chrono::duration<Rep, Period>& timeout, + T&& element); + // legacy name template <typename Rep, typename Period> bool tryPushFrontFor(const std::chrono::duration<Rep, Period>& timeout, - ElementT const & element); + ElementT const & element) { return tryPushFor(timeout, element); } + + // Try to add an element to the queue, blocking if full but with + // timeout at specified time_point. Returns true if the element was added. + template <typename Clock, typename Duration, typename T> + bool tryPushUntil(const std::chrono::time_point<Clock, Duration>& until, + T&& element); + // no legacy name because this is a newer method - // Pop the element at the end of the queue (will block if the queue is + // Pop the element at the head of the queue (will block if the queue is // empty). // // This call will raise an interrupt error if the queue is closed while // the caller is blocked. - ElementT popBack(void); - - // Pop an element from the end of the queue if there is one available. + ElementT pop(void); + // legacy name + ElementT popBack(void) { return pop(); } + + // Pop an element from the head of the queue if there is one available. // Returns true only if an element was popped. - bool tryPopBack(ElementT & element); - + bool tryPop(ElementT & element); + // legacy name + bool tryPopBack(ElementT & element) { return tryPop(element); } + + // Pop the element at the head of the queue, blocking if empty, with + // timeout after specified duration. Returns true if an element was popped. + template <typename Rep, typename Period> + bool tryPopFor(const std::chrono::duration<Rep, Period>& timeout, ElementT& element); + // no legacy name because this is a newer method + + // Pop the element at the head of the queue, blocking if empty, with + // timeout at specified time_point. Returns true if an element was popped. + template <typename Clock, typename Duration> + bool tryPopUntil(const std::chrono::time_point<Clock, Duration>& until, + ElementT& element); + // no legacy name because this is a newer method + // Returns the size of the queue. size_t size(); + //Returns the capacity of the queue. + U32 capacity() { return mCapacity; } + // closes the queue: - // - every subsequent pushFront() call will throw LLThreadSafeQueueInterrupt - // - every subsequent tryPushFront() call will return false - // - popBack() calls will return normally until the queue is drained, then - // every subsequent popBack() will throw LLThreadSafeQueueInterrupt - // - tryPopBack() calls will return normally until the queue is drained, - // then every subsequent tryPopBack() call will return false + // - every subsequent push() call will throw LLThreadSafeQueueInterrupt + // - every subsequent tryPush() call will return false + // - pop() calls will return normally until the queue is drained, then + // every subsequent pop() will throw LLThreadSafeQueueInterrupt + // - tryPop() calls will return normally until the queue is drained, + // then every subsequent tryPop() call will return false void close(); - // detect closed state + // producer end: are we prevented from pushing any additional items? bool isClosed(); - // inverse of isClosed() - explicit operator bool(); + // consumer end: are we done, is the queue entirely drained? + bool done(); -private: - std::deque< ElementT > mStorage; +protected: + typedef QueueT queue_type; + QueueT mStorage; U32 mCapacity; bool mClosed; @@ -137,37 +186,154 @@ class LLThreadSafeQueue typedef std::unique_lock<decltype(mLock)> lock_t; boost::fibers::condition_variable_any mCapacityCond; boost::fibers::condition_variable_any mEmptyCond; -}; -// LLThreadSafeQueue -//----------------------------------------------------------------------------- + enum pop_result { EMPTY, DONE, WAITING, POPPED }; + // implementation logic, suitable for passing to tryLockUntil() + template <typename Clock, typename Duration> + pop_result tryPopUntil_(lock_t& lock, + const std::chrono::time_point<Clock, Duration>& until, + ElementT& element); + // if we're able to lock immediately, do so and run the passed callable, + // which must accept lock_t& and return bool + template <typename CALLABLE> + bool tryLock(CALLABLE&& callable); + // if we're able to lock before the passed time_point, do so and run the + // passed callable, which must accept lock_t& and return bool + template <typename Clock, typename Duration, typename CALLABLE> + bool tryLockUntil(const std::chrono::time_point<Clock, Duration>& until, + CALLABLE&& callable); + // while lock is locked, really push the passed element, if we can + template <typename T> + bool push_(lock_t& lock, T&& element); + // while lock is locked, really pop the head element, if we can + pop_result pop_(lock_t& lock, ElementT& element); + // Is the current head element ready to pop? We say yes; subclass can + // override as needed. + virtual bool canPop(const ElementT& head) const { return true; } +}; -template<typename ElementT> -LLThreadSafeQueue<ElementT>::LLThreadSafeQueue(U32 capacity) : +/***************************************************************************** +* PriorityQueueAdapter +*****************************************************************************/ +namespace LL +{ + /** + * std::priority_queue's API is almost like std::queue, intentionally of + * course, but you must access the element about to pop() as top() rather + * than as front(). Make an adapter for use with LLThreadSafeQueue. + */ + template <typename T, typename Container=std::vector<T>, + typename Compare=std::less<typename Container::value_type>> + class PriorityQueueAdapter + { + public: + // publish all the same types + typedef std::priority_queue<T, Container, Compare> queue_type; + typedef typename queue_type::container_type container_type; + typedef typename queue_type::value_compare value_compare; + typedef typename queue_type::value_type value_type; + typedef typename queue_type::size_type size_type; + typedef typename queue_type::reference reference; + typedef typename queue_type::const_reference const_reference; + + // Although std::queue defines both const and non-const front() + // methods, std::priority_queue defines only const top(). + const_reference front() const { return mQ.top(); } + // std::priority_queue has no equivalent to back(), so it's good that + // LLThreadSafeQueue doesn't use it. + + // All the rest of these merely forward to the corresponding + // queue_type methods. + bool empty() const { return mQ.empty(); } + size_type size() const { return mQ.size(); } + void push(const value_type& value) { mQ.push(value); } + void push(value_type&& value) { mQ.push(std::move(value)); } + template <typename... Args> + void emplace(Args&&... args) { mQ.emplace(std::forward<Args>(args)...); } + void pop() { mQ.pop(); } + + private: + queue_type mQ; + }; +} // namespace LL + + +/***************************************************************************** +* LLThreadSafeQueue implementation +*****************************************************************************/ +template<typename ElementT, typename QueueT> +LLThreadSafeQueue<ElementT, QueueT>::LLThreadSafeQueue(U32 capacity) : mCapacity(capacity), mClosed(false) { } -template<typename ElementT> -void LLThreadSafeQueue<ElementT>::pushFront(ElementT const & element) +// if we're able to lock immediately, do so and run the passed callable, which +// must accept lock_t& and return bool +template <typename ElementT, typename QueueT> +template <typename CALLABLE> +bool LLThreadSafeQueue<ElementT, QueueT>::tryLock(CALLABLE&& callable) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; + lock_t lock1(mLock, std::defer_lock); + if (!lock1.try_lock()) + return false; + + return std::forward<CALLABLE>(callable)(lock1); +} + + +// if we're able to lock before the passed time_point, do so and run the +// passed callable, which must accept lock_t& and return bool +template <typename ElementT, typename QueueT> +template <typename Clock, typename Duration, typename CALLABLE> +bool LLThreadSafeQueue<ElementT, QueueT>::tryLockUntil( + const std::chrono::time_point<Clock, Duration>& until, + CALLABLE&& callable) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; + lock_t lock1(mLock, std::defer_lock); + if (!lock1.try_lock_until(until)) + return false; + + return std::forward<CALLABLE>(callable)(lock1); +} + + +// while lock is locked, really push the passed element, if we can +template <typename ElementT, typename QueueT> +template <typename T> +bool LLThreadSafeQueue<ElementT, QueueT>::push_(lock_t& lock, T&& element) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; + if (mStorage.size() >= mCapacity) + return false; + + mStorage.push(std::forward<T>(element)); + lock.unlock(); + // now that we've pushed, if somebody's been waiting to pop, signal them + mEmptyCond.notify_one(); + return true; +} + + +template <typename ElementT, typename QueueT> +template <typename T> +bool LLThreadSafeQueue<ElementT, QueueT>::pushIfOpen(T&& element) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; lock_t lock1(mLock); while (true) { + // On the producer side, it doesn't matter whether the queue has been + // drained or not: the moment either end calls close(), further push() + // operations will fail. if (mClosed) - { - LLTHROW(LLThreadSafeQueueInterrupt()); - } + return false; - if (mStorage.size() < mCapacity) - { - mStorage.push_front(element); - lock1.unlock(); - mEmptyCond.notify_one(); - return; - } + if (push_(lock1, std::forward<T>(element))) + return true; // Storage Full. Wait for signal. mCapacityCond.wait(lock1); @@ -175,142 +341,250 @@ void LLThreadSafeQueue<ElementT>::pushFront(ElementT const & element) } -template <typename ElementT> -template <typename Rep, typename Period> -bool LLThreadSafeQueue<ElementT>::tryPushFrontFor(const std::chrono::duration<Rep, Period>& timeout, - ElementT const & element) +template <typename ElementT, typename QueueT> +template<typename T> +void LLThreadSafeQueue<ElementT, QueueT>::push(T&& element) { - // Convert duration to time_point: passing the same timeout duration to - // each of multiple calls is wrong. - auto endpoint = std::chrono::steady_clock::now() + timeout; + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; + if (! pushIfOpen(std::forward<T>(element))) + { + LLTHROW(LLThreadSafeQueueInterrupt()); + } +} - lock_t lock1(mLock, std::defer_lock); - if (!lock1.try_lock_until(endpoint)) - return false; - while (true) - { - if (mClosed) +template<typename ElementT, typename QueueT> +template<typename T> +bool LLThreadSafeQueue<ElementT, QueueT>::tryPush(T&& element) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; + return tryLock( + [this, element=std::move(element)](lock_t& lock) { - return false; - } + if (mClosed) + return false; + return push_(lock, std::move(element)); + }); +} - if (mStorage.size() < mCapacity) - { - mStorage.push_front(element); - lock1.unlock(); - mEmptyCond.notify_one(); - return true; - } - // Storage Full. Wait for signal. - if (LLCoros::cv_status::timeout == mCapacityCond.wait_until(lock1, endpoint)) - { - // timed out -- formally we might recheck both conditions above - return false; - } - // If we didn't time out, we were notified for some reason. Loop back - // to check. - } +template <typename ElementT, typename QueueT> +template <typename Rep, typename Period, typename T> +bool LLThreadSafeQueue<ElementT, QueueT>::tryPushFor( + const std::chrono::duration<Rep, Period>& timeout, + T&& element) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; + // Convert duration to time_point: passing the same timeout duration to + // each of multiple calls is wrong. + return tryPushUntil(std::chrono::steady_clock::now() + timeout, + std::forward<T>(element)); } -template<typename ElementT> -bool LLThreadSafeQueue<ElementT>::tryPushFront(ElementT const & element) +template <typename ElementT, typename QueueT> +template <typename Clock, typename Duration, typename T> +bool LLThreadSafeQueue<ElementT, QueueT>::tryPushUntil( + const std::chrono::time_point<Clock, Duration>& until, + T&& element) { - lock_t lock1(mLock, std::defer_lock); - if (!lock1.try_lock()) - return false; + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; + return tryLockUntil( + until, + [this, until, element=std::move(element)](lock_t& lock) + { + while (true) + { + if (mClosed) + { + return false; + } + + if (push_(lock, std::move(element))) + return true; + + // Storage Full. Wait for signal. + if (LLCoros::cv_status::timeout == mCapacityCond.wait_until(lock, until)) + { + // timed out -- formally we might recheck both conditions above + return false; + } + // If we didn't time out, we were notified for some reason. Loop back + // to check. + } + }); +} - if (mClosed) - return false; - if (mStorage.size() >= mCapacity) - return false; +// while lock is locked, really pop the head element, if we can +template <typename ElementT, typename QueueT> +typename LLThreadSafeQueue<ElementT, QueueT>::pop_result +LLThreadSafeQueue<ElementT, QueueT>::pop_(lock_t& lock, ElementT& element) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; + // If mStorage is empty, there's no head element. + if (mStorage.empty()) + return mClosed? DONE : EMPTY; - mStorage.push_front(element); - lock1.unlock(); - mEmptyCond.notify_one(); - return true; + // If there's a head element, pass it to canPop() to see if it's ready to pop. + if (! canPop(mStorage.front())) + return WAITING; + + // std::queue::front() is the element about to pop() + element = mStorage.front(); + mStorage.pop(); + lock.unlock(); + // now that we've popped, if somebody's been waiting to push, signal them + mCapacityCond.notify_one(); + return POPPED; } -template<typename ElementT> -ElementT LLThreadSafeQueue<ElementT>::popBack(void) +template<typename ElementT, typename QueueT> +ElementT LLThreadSafeQueue<ElementT, QueueT>::pop(void) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; lock_t lock1(mLock); + ElementT value; while (true) { - if (!mStorage.empty()) - { - ElementT value = mStorage.back(); - mStorage.pop_back(); - lock1.unlock(); - mCapacityCond.notify_one(); - return value; - } - - if (mClosed) + // On the consumer side, we always try to pop before checking mClosed + // so we can finish draining the queue. + pop_result popped = pop_(lock1, value); + if (popped == POPPED) + return std::move(value); + + // Once the queue is DONE, there will never be any more coming. + if (popped == DONE) { LLTHROW(LLThreadSafeQueueInterrupt()); } - // Storage empty. Wait for signal. + // If we didn't pop because WAITING, i.e. canPop() returned false, + // then even if the producer end has been closed, there's still at + // least one item to drain: wait for it. Or we might be EMPTY, with + // the queue still open. Either way, wait for signal. mEmptyCond.wait(lock1); } } -template<typename ElementT> -bool LLThreadSafeQueue<ElementT>::tryPopBack(ElementT & element) +template<typename ElementT, typename QueueT> +bool LLThreadSafeQueue<ElementT, QueueT>::tryPop(ElementT & element) { - lock_t lock1(mLock, std::defer_lock); - if (!lock1.try_lock()) - return false; + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; + return tryLock( + [this, &element](lock_t& lock) + { + // conflate EMPTY, DONE, WAITING: tryPop() behavior when the queue + // is closed is implemented by simple inability to push any new + // elements + return pop_(lock, element) == POPPED; + }); +} - // no need to check mClosed: tryPopBack() behavior when the queue is - // closed is implemented by simple inability to push any new elements - if (mStorage.empty()) - return false; - element = mStorage.back(); - mStorage.pop_back(); - lock1.unlock(); - mCapacityCond.notify_one(); - return true; +template <typename ElementT, typename QueueT> +template <typename Rep, typename Period> +bool LLThreadSafeQueue<ElementT, QueueT>::tryPopFor( + const std::chrono::duration<Rep, Period>& timeout, + ElementT& element) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; + // Convert duration to time_point: passing the same timeout duration to + // each of multiple calls is wrong. + return tryPopUntil(std::chrono::steady_clock::now() + timeout, element); } -template<typename ElementT> -size_t LLThreadSafeQueue<ElementT>::size(void) +template <typename ElementT, typename QueueT> +template <typename Clock, typename Duration> +bool LLThreadSafeQueue<ElementT, QueueT>::tryPopUntil( + const std::chrono::time_point<Clock, Duration>& until, + ElementT& element) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; + return tryLockUntil( + until, + [this, until, &element](lock_t& lock) + { + // conflate EMPTY, DONE, WAITING + return tryPopUntil_(lock, until, element) == POPPED; + }); +} + + +// body of tryPopUntil(), called once we have the lock +template <typename ElementT, typename QueueT> +template <typename Clock, typename Duration> +typename LLThreadSafeQueue<ElementT, QueueT>::pop_result +LLThreadSafeQueue<ElementT, QueueT>::tryPopUntil_( + lock_t& lock, + const std::chrono::time_point<Clock, Duration>& until, + ElementT& element) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; + while (true) + { + pop_result popped = pop_(lock, element); + if (popped == POPPED || popped == DONE) + { + // If we succeeded, great! If we've drained the last item, so be + // it. Either way, break the loop and tell caller. + return popped; + } + + // EMPTY or WAITING: wait for signal. + if (LLCoros::cv_status::timeout == mEmptyCond.wait_until(lock, until)) + { + // timed out -- formally we might recheck + // as it is, break loop + return popped; + } + // If we didn't time out, we were notified for some reason. Loop back + // to check. + } +} + + +template<typename ElementT, typename QueueT> +size_t LLThreadSafeQueue<ElementT, QueueT>::size(void) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; lock_t lock(mLock); return mStorage.size(); } -template<typename ElementT> -void LLThreadSafeQueue<ElementT>::close() + +template<typename ElementT, typename QueueT> +void LLThreadSafeQueue<ElementT, QueueT>::close() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; lock_t lock(mLock); mClosed = true; lock.unlock(); - // wake up any blocked popBack() calls + // wake up any blocked pop() calls mEmptyCond.notify_all(); - // wake up any blocked pushFront() calls + // wake up any blocked push() calls mCapacityCond.notify_all(); } -template<typename ElementT> -bool LLThreadSafeQueue<ElementT>::isClosed() + +template<typename ElementT, typename QueueT> +bool LLThreadSafeQueue<ElementT, QueueT>::isClosed() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; lock_t lock(mLock); - return mClosed && mStorage.size() == 0; + return mClosed; } -template<typename ElementT> -LLThreadSafeQueue<ElementT>::operator bool() + +template<typename ElementT, typename QueueT> +bool LLThreadSafeQueue<ElementT, QueueT>::done() { - return ! isClosed(); + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; + lock_t lock(mLock); + return mClosed && mStorage.empty(); } #endif diff --git a/indra/llcommon/lltrace.cpp b/indra/llcommon/lltrace.cpp index 54079a4689e34db6c5006f14f93d0b8313b0d9c8..f59b207ded2d26634f8a8b266cb4ed7fc0e14637 100644 --- a/indra/llcommon/lltrace.cpp +++ b/indra/llcommon/lltrace.cpp @@ -61,6 +61,7 @@ TimeBlockTreeNode::TimeBlockTreeNode() void TimeBlockTreeNode::setParent( BlockTimerStatHandle* parent ) { + LL_PROFILE_ZONE_SCOPED; llassert_always(parent != mBlock); llassert_always(parent != NULL); diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index b0c6a0a6ea362fe91ba446320c1c78ae0e3036c1..616f7f4f06f789cd130d4a7df55ceb879089fa03 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -227,6 +227,7 @@ class MemStatHandle : public StatType<MemAccumulator> void setName(const char* name) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; mName = name; setKey(name); } @@ -234,12 +235,14 @@ class MemStatHandle : public StatType<MemAccumulator> /*virtual*/ const char* getUnitLabel() const { return "KB"; } StatType<MemAccumulator::AllocationFacet>& allocations() - { + { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; return static_cast<StatType<MemAccumulator::AllocationFacet>&>(*(StatType<MemAccumulator>*)this); } StatType<MemAccumulator::DeallocationFacet>& deallocations() - { + { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; return static_cast<StatType<MemAccumulator::DeallocationFacet>&>(*(StatType<MemAccumulator>*)this); } }; @@ -261,6 +264,7 @@ struct MeasureMem<T, typename T::mem_trackable_tag_t, IS_BYTES> { static size_t measureFootprint(const T& value) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; return sizeof(T) + value.getMemFootprint(); } }; @@ -270,6 +274,7 @@ struct MeasureMem<T, IS_MEM_TRACKABLE, typename T::is_unit_t> { static size_t measureFootprint(const T& value) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; return U32Bytes(value).value(); } }; @@ -279,6 +284,7 @@ struct MeasureMem<T*, IS_MEM_TRACKABLE, IS_BYTES> { static size_t measureFootprint(const T* value) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; if (!value) { return 0; @@ -323,6 +329,7 @@ struct MeasureMem<std::basic_string<T>, IS_MEM_TRACKABLE, IS_BYTES> { static size_t measureFootprint(const std::basic_string<T>& value) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; return value.capacity() * sizeof(T); } }; @@ -331,6 +338,7 @@ struct MeasureMem<std::basic_string<T>, IS_MEM_TRACKABLE, IS_BYTES> template<typename T> inline void claim_alloc(MemStatHandle& measurement, const T& value) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; #if LL_TRACE_ENABLED S32 size = MeasureMem<T>::measureFootprint(value); if(size == 0) return; @@ -343,6 +351,7 @@ inline void claim_alloc(MemStatHandle& measurement, const T& value) template<typename T> inline void disclaim_alloc(MemStatHandle& measurement, const T& value) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; #if LL_TRACE_ENABLED S32 size = MeasureMem<T>::measureFootprint(value); if(size == 0) return; @@ -352,140 +361,6 @@ inline void disclaim_alloc(MemStatHandle& measurement, const T& value) #endif } -template<typename DERIVED, size_t ALIGNMENT = LL_DEFAULT_HEAP_ALIGN> -class MemTrackableNonVirtual -{ -public: - typedef void mem_trackable_tag_t; - - MemTrackableNonVirtual(const char* name) -#if LL_TRACE_ENABLED - : mMemFootprint(0) -#endif - { -#if LL_TRACE_ENABLED - static bool name_initialized = false; - if (!name_initialized) - { - name_initialized = true; - sMemStat.setName(name); - } -#endif - } - -#if LL_TRACE_ENABLED - ~MemTrackableNonVirtual() - { - disclaimMem(mMemFootprint); - } - - static MemStatHandle& getMemStatHandle() - { - return sMemStat; - } - - S32 getMemFootprint() const { return mMemFootprint; } -#endif - - void* operator new(size_t size) - { -#if LL_TRACE_ENABLED - claim_alloc(sMemStat, size); -#endif - return ll_aligned_malloc<ALIGNMENT>(size); - } - - template<int CUSTOM_ALIGNMENT> - static void* aligned_new(size_t size) - { -#if LL_TRACE_ENABLED - claim_alloc(sMemStat, size); -#endif - return ll_aligned_malloc<CUSTOM_ALIGNMENT>(size); - } - - void operator delete(void* ptr, size_t size) - { -#if LL_TRACE_ENABLED - disclaim_alloc(sMemStat, size); -#endif - ll_aligned_free<ALIGNMENT>(ptr); - } - - template<int CUSTOM_ALIGNMENT> - static void aligned_delete(void* ptr, size_t size) - { -#if LL_TRACE_ENABLED - disclaim_alloc(sMemStat, size); -#endif - ll_aligned_free<CUSTOM_ALIGNMENT>(ptr); - } - - void* operator new [](size_t size) - { -#if LL_TRACE_ENABLED - claim_alloc(sMemStat, size); -#endif - return ll_aligned_malloc<ALIGNMENT>(size); - } - - void operator delete[](void* ptr, size_t size) - { -#if LL_TRACE_ENABLED - disclaim_alloc(sMemStat, size); -#endif - ll_aligned_free<ALIGNMENT>(ptr); - } - - // claim memory associated with other objects/data as our own, adding to our calculated footprint - template<typename CLAIM_T> - void claimMem(const CLAIM_T& value) const - { -#if LL_TRACE_ENABLED - S32 size = MeasureMem<CLAIM_T>::measureFootprint(value); - claim_alloc(sMemStat, size); - mMemFootprint += size; -#endif - } - - // remove memory we had claimed from our calculated footprint - template<typename CLAIM_T> - void disclaimMem(const CLAIM_T& value) const - { -#if LL_TRACE_ENABLED - S32 size = MeasureMem<CLAIM_T>::measureFootprint(value); - disclaim_alloc(sMemStat, size); - mMemFootprint -= size; -#endif - } - -private: -#if LL_TRACE_ENABLED - // use signed values so that we can temporarily go negative - // and reconcile in destructor - // NB: this assumes that no single class is responsible for > 2GB of allocations - mutable S32 mMemFootprint; - - static MemStatHandle sMemStat; -#endif - -}; - -#if LL_TRACE_ENABLED -template<typename DERIVED, size_t ALIGNMENT> -MemStatHandle MemTrackableNonVirtual<DERIVED, ALIGNMENT>::sMemStat(typeid(MemTrackableNonVirtual<DERIVED, ALIGNMENT>).name()); -#endif - -template<typename DERIVED, size_t ALIGNMENT = LL_DEFAULT_HEAP_ALIGN> -class MemTrackable : public MemTrackableNonVirtual<DERIVED, ALIGNMENT> -{ -public: - MemTrackable(const char* name) - : MemTrackableNonVirtual<DERIVED, ALIGNMENT>(name) - {} - - virtual ~MemTrackable() = default; -}; } #endif // LL_LLTRACE_H diff --git a/indra/llcommon/lltraceaccumulators.cpp b/indra/llcommon/lltraceaccumulators.cpp index b1c23c6fb7a35dfafb800f9d05b29f134ff9cfe2..34299f5a29a3f55188c5f7b465d0b1c4fdcb79db 100644 --- a/indra/llcommon/lltraceaccumulators.cpp +++ b/indra/llcommon/lltraceaccumulators.cpp @@ -41,6 +41,7 @@ extern MemStatHandle gTraceMemStat; AccumulatorBufferGroup::AccumulatorBufferGroup() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; claim_alloc(gTraceMemStat, mCounts.capacity() * sizeof(CountAccumulator)); claim_alloc(gTraceMemStat, mSamples.capacity() * sizeof(SampleAccumulator)); claim_alloc(gTraceMemStat, mEvents.capacity() * sizeof(EventAccumulator)); @@ -55,6 +56,7 @@ AccumulatorBufferGroup::AccumulatorBufferGroup(const AccumulatorBufferGroup& oth mStackTimers(other.mStackTimers), mMemStats(other.mMemStats) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; claim_alloc(gTraceMemStat, mCounts.capacity() * sizeof(CountAccumulator)); claim_alloc(gTraceMemStat, mSamples.capacity() * sizeof(SampleAccumulator)); claim_alloc(gTraceMemStat, mEvents.capacity() * sizeof(EventAccumulator)); @@ -64,6 +66,7 @@ AccumulatorBufferGroup::AccumulatorBufferGroup(const AccumulatorBufferGroup& oth AccumulatorBufferGroup::~AccumulatorBufferGroup() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; disclaim_alloc(gTraceMemStat, mCounts.capacity() * sizeof(CountAccumulator)); disclaim_alloc(gTraceMemStat, mSamples.capacity() * sizeof(SampleAccumulator)); disclaim_alloc(gTraceMemStat, mEvents.capacity() * sizeof(EventAccumulator)); @@ -73,6 +76,7 @@ AccumulatorBufferGroup::~AccumulatorBufferGroup() void AccumulatorBufferGroup::handOffTo(AccumulatorBufferGroup& other) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; other.mCounts.reset(&mCounts); other.mSamples.reset(&mSamples); other.mEvents.reset(&mEvents); @@ -82,6 +86,7 @@ void AccumulatorBufferGroup::handOffTo(AccumulatorBufferGroup& other) void AccumulatorBufferGroup::makeCurrent() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; mCounts.makeCurrent(); mSamples.makeCurrent(); mEvents.makeCurrent(); @@ -104,6 +109,7 @@ void AccumulatorBufferGroup::makeCurrent() //static void AccumulatorBufferGroup::clearCurrent() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; AccumulatorBuffer<CountAccumulator>::clearCurrent(); AccumulatorBuffer<SampleAccumulator>::clearCurrent(); AccumulatorBuffer<EventAccumulator>::clearCurrent(); @@ -118,6 +124,7 @@ bool AccumulatorBufferGroup::isCurrent() const void AccumulatorBufferGroup::append( const AccumulatorBufferGroup& other ) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; mCounts.addSamples(other.mCounts, SEQUENTIAL); mSamples.addSamples(other.mSamples, SEQUENTIAL); mEvents.addSamples(other.mEvents, SEQUENTIAL); @@ -127,6 +134,7 @@ void AccumulatorBufferGroup::append( const AccumulatorBufferGroup& other ) void AccumulatorBufferGroup::merge( const AccumulatorBufferGroup& other) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; mCounts.addSamples(other.mCounts, NON_SEQUENTIAL); mSamples.addSamples(other.mSamples, NON_SEQUENTIAL); mEvents.addSamples(other.mEvents, NON_SEQUENTIAL); @@ -137,6 +145,7 @@ void AccumulatorBufferGroup::merge( const AccumulatorBufferGroup& other) void AccumulatorBufferGroup::reset(AccumulatorBufferGroup* other) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; mCounts.reset(other ? &other->mCounts : NULL); mSamples.reset(other ? &other->mSamples : NULL); mEvents.reset(other ? &other->mEvents : NULL); @@ -146,6 +155,7 @@ void AccumulatorBufferGroup::reset(AccumulatorBufferGroup* other) void AccumulatorBufferGroup::sync() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; if (isCurrent()) { F64SecondsImplicit time_stamp = LLTimer::getTotalSeconds(); @@ -190,7 +200,7 @@ F64 SampleAccumulator::mergeSumsOfSquares(const SampleAccumulator& a, const Samp void SampleAccumulator::addSamples( const SampleAccumulator& other, EBufferAppendType append_type ) { - if (append_type == NON_SEQUENTIAL) + if (append_type == NON_SEQUENTIAL) { return; } @@ -289,7 +299,7 @@ void EventAccumulator::addSamples( const EventAccumulator& other, EBufferAppendT void EventAccumulator::reset( const EventAccumulator* other ) { - mNumSamples = 0; + mNumSamples = 0; mSum = 0; mMin = F32(NaN); mMax = F32(NaN); diff --git a/indra/llcommon/lltraceaccumulators.h b/indra/llcommon/lltraceaccumulators.h index 4d4484ae0e28af8590552445e66a6fc9c703da0c..09698f40f9dbf4d31fac94bd13d15d517c6536e7 100644 --- a/indra/llcommon/lltraceaccumulators.h +++ b/indra/llcommon/lltraceaccumulators.h @@ -66,6 +66,7 @@ namespace LLTrace : mStorageSize(0), mStorage(NULL) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; const AccumulatorBuffer& other = *getDefaultBuffer(); resize(sNextStorageSlot); for (S32 i = 0; i < sNextStorageSlot; i++) @@ -76,6 +77,7 @@ namespace LLTrace ~AccumulatorBuffer() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; if (isCurrent()) { LLThreadLocalSingletonPointer<ACCUMULATOR>::setInstance(NULL); @@ -98,6 +100,7 @@ namespace LLTrace : mStorageSize(0), mStorage(NULL) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; resize(sNextStorageSlot); for (S32 i = 0; i < sNextStorageSlot; i++) { @@ -107,6 +110,7 @@ namespace LLTrace void addSamples(const AccumulatorBuffer<ACCUMULATOR>& other, EBufferAppendType append_type) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; llassert(mStorageSize >= sNextStorageSlot && other.mStorageSize >= sNextStorageSlot); for (size_t i = 0; i < sNextStorageSlot; i++) { @@ -116,6 +120,7 @@ namespace LLTrace void copyFrom(const AccumulatorBuffer<ACCUMULATOR>& other) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; llassert(mStorageSize >= sNextStorageSlot && other.mStorageSize >= sNextStorageSlot); for (size_t i = 0; i < sNextStorageSlot; i++) { @@ -125,6 +130,7 @@ namespace LLTrace void reset(const AccumulatorBuffer<ACCUMULATOR>* other = NULL) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; llassert(mStorageSize >= sNextStorageSlot); for (size_t i = 0; i < sNextStorageSlot; i++) { @@ -134,6 +140,7 @@ namespace LLTrace void sync(F64SecondsImplicit time_stamp) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; llassert(mStorageSize >= sNextStorageSlot); for (size_t i = 0; i < sNextStorageSlot; i++) { @@ -153,12 +160,13 @@ namespace LLTrace static void clearCurrent() { - LLThreadLocalSingletonPointer<ACCUMULATOR>::setInstance(NULL); + LLThreadLocalSingletonPointer<ACCUMULATOR>::setInstance(NULL); } // NOTE: this is not thread-safe. We assume that slots are reserved in the main thread before any child threads are spawned size_t reserveSlot() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; size_t next_slot = sNextStorageSlot++; if (next_slot >= mStorageSize) { @@ -172,6 +180,7 @@ namespace LLTrace void resize(size_t new_size) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; if (new_size <= mStorageSize) return; ACCUMULATOR* old_storage = mStorage; @@ -212,6 +221,7 @@ namespace LLTrace static self_t* getDefaultBuffer() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; static bool sInitialized = false; if (!sInitialized) { @@ -326,6 +336,7 @@ namespace LLTrace void sample(F64 value) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; F64SecondsImplicit time_stamp = LLTimer::getTotalSeconds(); // store effect of last value @@ -444,9 +455,9 @@ namespace LLTrace S32 mNumSamples; }; - class TimeBlockAccumulator + class alignas(32) TimeBlockAccumulator { - public: + public: typedef F64Seconds value_t; static F64Seconds getDefaultValue() { return F64Seconds(0); } @@ -539,6 +550,7 @@ namespace LLTrace void addSamples(const MemAccumulator& other, EBufferAppendType append_type) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; mAllocations.addSamples(other.mAllocations, append_type); mDeallocations.addSamples(other.mDeallocations, append_type); @@ -557,6 +569,7 @@ namespace LLTrace void reset(const MemAccumulator* other) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; mSize.reset(other ? &other->mSize : NULL); mAllocations.reset(other ? &other->mAllocations : NULL); mDeallocations.reset(other ? &other->mDeallocations : NULL); diff --git a/indra/llcommon/lltracerecording.cpp b/indra/llcommon/lltracerecording.cpp index 2d2eb7e5d7baf7491b8b47a0b792ab6b9a45fd0b..00edb584e06b2d28cbe264345f535706fd4856e3 100644 --- a/indra/llcommon/lltracerecording.cpp +++ b/indra/llcommon/lltracerecording.cpp @@ -46,6 +46,7 @@ Recording::Recording(EPlayState state) : mElapsedSeconds(0), mActiveBuffers(NULL) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; claim_alloc(gTraceMemStat, this); mBuffers = new AccumulatorBufferGroup(); claim_alloc(gTraceMemStat, mBuffers); @@ -55,12 +56,14 @@ Recording::Recording(EPlayState state) Recording::Recording( const Recording& other ) : mActiveBuffers(NULL) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; claim_alloc(gTraceMemStat, this); *this = other; } Recording& Recording::operator = (const Recording& other) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; // this will allow us to seamlessly start without affecting any data we've acquired from other setPlayState(PAUSED); @@ -81,6 +84,7 @@ Recording& Recording::operator = (const Recording& other) Recording::~Recording() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; disclaim_alloc(gTraceMemStat, this); disclaim_alloc(gTraceMemStat, mBuffers); @@ -99,6 +103,7 @@ void Recording::update() #if LL_TRACE_ENABLED if (isStarted()) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; mElapsedSeconds += mSamplingTimer.getElapsedTimeF64(); // must have @@ -119,6 +124,7 @@ void Recording::update() void Recording::handleReset() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; #if LL_TRACE_ENABLED mBuffers.write()->reset(); @@ -129,6 +135,7 @@ void Recording::handleReset() void Recording::handleStart() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; #if LL_TRACE_ENABLED mSamplingTimer.reset(); mBuffers.setStayUnique(true); @@ -140,6 +147,7 @@ void Recording::handleStart() void Recording::handleStop() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; #if LL_TRACE_ENABLED mElapsedSeconds += mSamplingTimer.getElapsedTimeF64(); // must have thread recorder running on this thread @@ -269,7 +277,7 @@ F64Kilobytes Recording::getMean(const StatType<MemAccumulator>& stat) F64Kilobytes Recording::getMax(const StatType<MemAccumulator>& stat) { - update(); + update(); const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()]; const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL; return F64Bytes(llmax(accumulator.mSize.getMax(), active_accumulator && active_accumulator->mSize.hasValue() ? active_accumulator->mSize.getMax() : F32_MIN)); @@ -277,7 +285,7 @@ F64Kilobytes Recording::getMax(const StatType<MemAccumulator>& stat) F64Kilobytes Recording::getStandardDeviation(const StatType<MemAccumulator>& stat) { - update(); + update(); const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()]; const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL; if (active_accumulator && active_accumulator->hasValue()) @@ -293,7 +301,7 @@ F64Kilobytes Recording::getStandardDeviation(const StatType<MemAccumulator>& sta F64Kilobytes Recording::getLastValue(const StatType<MemAccumulator>& stat) { - update(); + update(); const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()]; const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL; return F64Bytes(active_accumulator ? active_accumulator->mSize.getLastValue() : accumulator.mSize.getLastValue()); @@ -301,7 +309,7 @@ F64Kilobytes Recording::getLastValue(const StatType<MemAccumulator>& stat) bool Recording::hasValue(const StatType<MemAccumulator::AllocationFacet>& stat) { - update(); + update(); const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()]; const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL; return accumulator.mAllocations.hasValue() || (active_accumulator ? active_accumulator->mAllocations.hasValue() : false); @@ -309,7 +317,7 @@ bool Recording::hasValue(const StatType<MemAccumulator::AllocationFacet>& stat) F64Kilobytes Recording::getSum(const StatType<MemAccumulator::AllocationFacet>& stat) { - update(); + update(); const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()]; const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL; return F64Bytes(accumulator.mAllocations.getSum() + (active_accumulator ? active_accumulator->mAllocations.getSum() : 0)); @@ -317,7 +325,7 @@ F64Kilobytes Recording::getSum(const StatType<MemAccumulator::AllocationFacet>& F64Kilobytes Recording::getPerSec(const StatType<MemAccumulator::AllocationFacet>& stat) { - update(); + update(); const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()]; const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL; return F64Bytes((accumulator.mAllocations.getSum() + (active_accumulator ? active_accumulator->mAllocations.getSum() : 0)) / mElapsedSeconds.value()); @@ -325,7 +333,7 @@ F64Kilobytes Recording::getPerSec(const StatType<MemAccumulator::AllocationFacet S32 Recording::getSampleCount(const StatType<MemAccumulator::AllocationFacet>& stat) { - update(); + update(); const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()]; const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL; return accumulator.mAllocations.getSampleCount() + (active_accumulator ? active_accumulator->mAllocations.getSampleCount() : 0); @@ -333,7 +341,7 @@ S32 Recording::getSampleCount(const StatType<MemAccumulator::AllocationFacet>& s bool Recording::hasValue(const StatType<MemAccumulator::DeallocationFacet>& stat) { - update(); + update(); const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()]; const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL; return accumulator.mDeallocations.hasValue() || (active_accumulator ? active_accumulator->mDeallocations.hasValue() : false); @@ -342,7 +350,7 @@ bool Recording::hasValue(const StatType<MemAccumulator::DeallocationFacet>& stat F64Kilobytes Recording::getSum(const StatType<MemAccumulator::DeallocationFacet>& stat) { - update(); + update(); const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()]; const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL; return F64Bytes(accumulator.mDeallocations.getSum() + (active_accumulator ? active_accumulator->mDeallocations.getSum() : 0)); @@ -350,7 +358,7 @@ F64Kilobytes Recording::getSum(const StatType<MemAccumulator::DeallocationFacet> F64Kilobytes Recording::getPerSec(const StatType<MemAccumulator::DeallocationFacet>& stat) { - update(); + update(); const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()]; const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL; return F64Bytes((accumulator.mDeallocations.getSum() + (active_accumulator ? active_accumulator->mDeallocations.getSum() : 0)) / mElapsedSeconds.value()); @@ -358,7 +366,7 @@ F64Kilobytes Recording::getPerSec(const StatType<MemAccumulator::DeallocationFac S32 Recording::getSampleCount(const StatType<MemAccumulator::DeallocationFacet>& stat) { - update(); + update(); const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()]; const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL; return accumulator.mDeallocations.getSampleCount() + (active_accumulator ? active_accumulator->mDeallocations.getSampleCount() : 0); @@ -366,7 +374,7 @@ S32 Recording::getSampleCount(const StatType<MemAccumulator::DeallocationFacet>& bool Recording::hasValue(const StatType<CountAccumulator>& stat) { - update(); + update(); const CountAccumulator& accumulator = mBuffers->mCounts[stat.getIndex()]; const CountAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mCounts[stat.getIndex()] : NULL; return accumulator.hasValue() || (active_accumulator ? active_accumulator->hasValue() : false); @@ -374,7 +382,7 @@ bool Recording::hasValue(const StatType<CountAccumulator>& stat) F64 Recording::getSum(const StatType<CountAccumulator>& stat) { - update(); + update(); const CountAccumulator& accumulator = mBuffers->mCounts[stat.getIndex()]; const CountAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mCounts[stat.getIndex()] : NULL; return accumulator.getSum() + (active_accumulator ? active_accumulator->getSum() : 0); @@ -382,7 +390,7 @@ F64 Recording::getSum(const StatType<CountAccumulator>& stat) F64 Recording::getPerSec( const StatType<CountAccumulator>& stat ) { - update(); + update(); const CountAccumulator& accumulator = mBuffers->mCounts[stat.getIndex()]; const CountAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mCounts[stat.getIndex()] : NULL; F64 sum = accumulator.getSum() + (active_accumulator ? active_accumulator->getSum() : 0); @@ -391,7 +399,7 @@ F64 Recording::getPerSec( const StatType<CountAccumulator>& stat ) S32 Recording::getSampleCount( const StatType<CountAccumulator>& stat ) { - update(); + update(); const CountAccumulator& accumulator = mBuffers->mCounts[stat.getIndex()]; const CountAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mCounts[stat.getIndex()] : NULL; return accumulator.getSampleCount() + (active_accumulator ? active_accumulator->getSampleCount() : 0); @@ -399,7 +407,7 @@ S32 Recording::getSampleCount( const StatType<CountAccumulator>& stat ) bool Recording::hasValue(const StatType<SampleAccumulator>& stat) { - update(); + update(); const SampleAccumulator& accumulator = mBuffers->mSamples[stat.getIndex()]; const SampleAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mSamples[stat.getIndex()] : NULL; return accumulator.hasValue() || (active_accumulator && active_accumulator->hasValue()); @@ -407,7 +415,7 @@ bool Recording::hasValue(const StatType<SampleAccumulator>& stat) F64 Recording::getMin( const StatType<SampleAccumulator>& stat ) { - update(); + update(); const SampleAccumulator& accumulator = mBuffers->mSamples[stat.getIndex()]; const SampleAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mSamples[stat.getIndex()] : NULL; return llmin(accumulator.getMin(), active_accumulator && active_accumulator->hasValue() ? active_accumulator->getMin() : F32_MAX); @@ -415,7 +423,7 @@ F64 Recording::getMin( const StatType<SampleAccumulator>& stat ) F64 Recording::getMax( const StatType<SampleAccumulator>& stat ) { - update(); + update(); const SampleAccumulator& accumulator = mBuffers->mSamples[stat.getIndex()]; const SampleAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mSamples[stat.getIndex()] : NULL; return llmax(accumulator.getMax(), active_accumulator && active_accumulator->hasValue() ? active_accumulator->getMax() : F32_MIN); @@ -423,7 +431,7 @@ F64 Recording::getMax( const StatType<SampleAccumulator>& stat ) F64 Recording::getMean( const StatType<SampleAccumulator>& stat ) { - update(); + update(); const SampleAccumulator& accumulator = mBuffers->mSamples[stat.getIndex()]; const SampleAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mSamples[stat.getIndex()] : NULL; if (active_accumulator && active_accumulator->hasValue()) @@ -444,7 +452,7 @@ F64 Recording::getMean( const StatType<SampleAccumulator>& stat ) F64 Recording::getStandardDeviation( const StatType<SampleAccumulator>& stat ) { - update(); + update(); const SampleAccumulator& accumulator = mBuffers->mSamples[stat.getIndex()]; const SampleAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mSamples[stat.getIndex()] : NULL; @@ -461,7 +469,7 @@ F64 Recording::getStandardDeviation( const StatType<SampleAccumulator>& stat ) F64 Recording::getLastValue( const StatType<SampleAccumulator>& stat ) { - update(); + update(); const SampleAccumulator& accumulator = mBuffers->mSamples[stat.getIndex()]; const SampleAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mSamples[stat.getIndex()] : NULL; return (active_accumulator && active_accumulator->hasValue() ? active_accumulator->getLastValue() : accumulator.getLastValue()); @@ -469,7 +477,7 @@ F64 Recording::getLastValue( const StatType<SampleAccumulator>& stat ) S32 Recording::getSampleCount( const StatType<SampleAccumulator>& stat ) { - update(); + update(); const SampleAccumulator& accumulator = mBuffers->mSamples[stat.getIndex()]; const SampleAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mSamples[stat.getIndex()] : NULL; return accumulator.getSampleCount() + (active_accumulator && active_accumulator->hasValue() ? active_accumulator->getSampleCount() : 0); @@ -477,7 +485,7 @@ S32 Recording::getSampleCount( const StatType<SampleAccumulator>& stat ) bool Recording::hasValue(const StatType<EventAccumulator>& stat) { - update(); + update(); const EventAccumulator& accumulator = mBuffers->mEvents[stat.getIndex()]; const EventAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mEvents[stat.getIndex()] : NULL; return accumulator.hasValue() || (active_accumulator && active_accumulator->hasValue()); @@ -485,7 +493,7 @@ bool Recording::hasValue(const StatType<EventAccumulator>& stat) F64 Recording::getSum( const StatType<EventAccumulator>& stat) { - update(); + update(); const EventAccumulator& accumulator = mBuffers->mEvents[stat.getIndex()]; const EventAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mEvents[stat.getIndex()] : NULL; return (F64)(accumulator.getSum() + (active_accumulator && active_accumulator->hasValue() ? active_accumulator->getSum() : 0)); @@ -493,7 +501,7 @@ F64 Recording::getSum( const StatType<EventAccumulator>& stat) F64 Recording::getMin( const StatType<EventAccumulator>& stat ) { - update(); + update(); const EventAccumulator& accumulator = mBuffers->mEvents[stat.getIndex()]; const EventAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mEvents[stat.getIndex()] : NULL; return llmin(accumulator.getMin(), active_accumulator && active_accumulator->hasValue() ? active_accumulator->getMin() : F32_MAX); @@ -501,7 +509,7 @@ F64 Recording::getMin( const StatType<EventAccumulator>& stat ) F64 Recording::getMax( const StatType<EventAccumulator>& stat ) { - update(); + update(); const EventAccumulator& accumulator = mBuffers->mEvents[stat.getIndex()]; const EventAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mEvents[stat.getIndex()] : NULL; return llmax(accumulator.getMax(), active_accumulator && active_accumulator->hasValue() ? active_accumulator->getMax() : F32_MIN); @@ -509,7 +517,7 @@ F64 Recording::getMax( const StatType<EventAccumulator>& stat ) F64 Recording::getMean( const StatType<EventAccumulator>& stat ) { - update(); + update(); const EventAccumulator& accumulator = mBuffers->mEvents[stat.getIndex()]; const EventAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mEvents[stat.getIndex()] : NULL; if (active_accumulator && active_accumulator->hasValue()) @@ -530,7 +538,7 @@ F64 Recording::getMean( const StatType<EventAccumulator>& stat ) F64 Recording::getStandardDeviation( const StatType<EventAccumulator>& stat ) { - update(); + update(); const EventAccumulator& accumulator = mBuffers->mEvents[stat.getIndex()]; const EventAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mEvents[stat.getIndex()] : NULL; @@ -547,7 +555,7 @@ F64 Recording::getStandardDeviation( const StatType<EventAccumulator>& stat ) F64 Recording::getLastValue( const StatType<EventAccumulator>& stat ) { - update(); + update(); const EventAccumulator& accumulator = mBuffers->mEvents[stat.getIndex()]; const EventAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mEvents[stat.getIndex()] : NULL; return active_accumulator ? active_accumulator->getLastValue() : accumulator.getLastValue(); @@ -555,7 +563,7 @@ F64 Recording::getLastValue( const StatType<EventAccumulator>& stat ) S32 Recording::getSampleCount( const StatType<EventAccumulator>& stat ) { - update(); + update(); const EventAccumulator& accumulator = mBuffers->mEvents[stat.getIndex()]; const EventAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mEvents[stat.getIndex()] : NULL; return accumulator.getSampleCount() + (active_accumulator ? active_accumulator->getSampleCount() : 0); @@ -571,17 +579,20 @@ PeriodicRecording::PeriodicRecording( S32 num_periods, EPlayState state) mNumRecordedPeriods(0), mRecordingPeriods(num_periods ? num_periods : 1) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; setPlayState(state); claim_alloc(gTraceMemStat, this); } PeriodicRecording::~PeriodicRecording() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; disclaim_alloc(gTraceMemStat, this); } void PeriodicRecording::nextPeriod() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; if (mAutoResize) { mRecordingPeriods.push_back(Recording()); @@ -596,6 +607,7 @@ void PeriodicRecording::nextPeriod() void PeriodicRecording::appendRecording(Recording& recording) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; getCurRecording().appendRecording(recording); nextPeriod(); } @@ -603,6 +615,7 @@ void PeriodicRecording::appendRecording(Recording& recording) void PeriodicRecording::appendPeriodicRecording( PeriodicRecording& other ) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; if (other.mRecordingPeriods.empty()) return; getCurRecording().update(); @@ -675,6 +688,7 @@ void PeriodicRecording::appendPeriodicRecording( PeriodicRecording& other ) F64Seconds PeriodicRecording::getDuration() const { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; F64Seconds duration; S32 num_periods = mRecordingPeriods.size(); for (S32 i = 1; i <= num_periods; i++) @@ -688,6 +702,7 @@ F64Seconds PeriodicRecording::getDuration() const LLTrace::Recording PeriodicRecording::snapshotCurRecording() const { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; Recording recording_copy(getCurRecording()); recording_copy.stop(); return recording_copy; @@ -730,16 +745,19 @@ const Recording& PeriodicRecording::getPrevRecording( S32 offset ) const void PeriodicRecording::handleStart() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; getCurRecording().start(); } void PeriodicRecording::handleStop() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; getCurRecording().pause(); } void PeriodicRecording::handleReset() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; getCurRecording().stop(); if (mAutoResize) @@ -763,11 +781,13 @@ void PeriodicRecording::handleReset() void PeriodicRecording::handleSplitTo(PeriodicRecording& other) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; getCurRecording().splitTo(other.getCurRecording()); } F64 PeriodicRecording::getPeriodMin( const StatType<EventAccumulator>& stat, S32 num_periods /*= S32_MAX*/ ) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); bool has_value = false; @@ -789,6 +809,7 @@ F64 PeriodicRecording::getPeriodMin( const StatType<EventAccumulator>& stat, S32 F64 PeriodicRecording::getPeriodMax( const StatType<EventAccumulator>& stat, S32 num_periods /*= S32_MAX*/ ) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); bool has_value = false; @@ -811,6 +832,7 @@ F64 PeriodicRecording::getPeriodMax( const StatType<EventAccumulator>& stat, S32 // calculates means using aggregates per period F64 PeriodicRecording::getPeriodMean( const StatType<EventAccumulator>& stat, S32 num_periods /*= S32_MAX*/ ) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); F64 mean = 0; @@ -831,9 +853,9 @@ F64 PeriodicRecording::getPeriodMean( const StatType<EventAccumulator>& stat, S3 : NaN; } - F64 PeriodicRecording::getPeriodStandardDeviation( const StatType<EventAccumulator>& stat, S32 num_periods /*= S32_MAX*/ ) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); F64 period_mean = getPeriodMean(stat, num_periods); @@ -858,6 +880,7 @@ F64 PeriodicRecording::getPeriodStandardDeviation( const StatType<EventAccumulat F64 PeriodicRecording::getPeriodMin( const StatType<SampleAccumulator>& stat, S32 num_periods /*= S32_MAX*/ ) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); bool has_value = false; @@ -879,6 +902,7 @@ F64 PeriodicRecording::getPeriodMin( const StatType<SampleAccumulator>& stat, S3 F64 PeriodicRecording::getPeriodMax(const StatType<SampleAccumulator>& stat, S32 num_periods /*= S32_MAX*/) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); bool has_value = false; @@ -901,6 +925,7 @@ F64 PeriodicRecording::getPeriodMax(const StatType<SampleAccumulator>& stat, S32 F64 PeriodicRecording::getPeriodMean( const StatType<SampleAccumulator>& stat, S32 num_periods /*= S32_MAX*/ ) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); S32 valid_period_count = 0; @@ -921,8 +946,35 @@ F64 PeriodicRecording::getPeriodMean( const StatType<SampleAccumulator>& stat, S : NaN; } +F64 PeriodicRecording::getPeriodMedian( const StatType<SampleAccumulator>& stat, S32 num_periods /*= S32_MAX*/ ) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; + num_periods = llmin(num_periods, getNumRecordedPeriods()); + + std::vector<F64> buf; + for (S32 i = 1; i <= num_periods; i++) + { + Recording& recording = getPrevRecording(i); + if (recording.getDuration() > (F32Seconds)0.f) + { + if (recording.hasValue(stat)) + { + buf.push_back(recording.getMean(stat)); + } + } + } + if (buf.size()==0) + { + return 0.0f; + } + std::sort(buf.begin(), buf.end()); + + return F64((buf.size() % 2 == 0) ? (buf[buf.size() / 2 - 1] + buf[buf.size() / 2]) / 2 : buf[buf.size() / 2]); +} + F64 PeriodicRecording::getPeriodStandardDeviation( const StatType<SampleAccumulator>& stat, S32 num_periods /*= S32_MAX*/ ) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); F64 period_mean = getPeriodMean(stat, num_periods); @@ -948,6 +1000,7 @@ F64 PeriodicRecording::getPeriodStandardDeviation( const StatType<SampleAccumula F64Kilobytes PeriodicRecording::getPeriodMin( const StatType<MemAccumulator>& stat, S32 num_periods /*= S32_MAX*/ ) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); F64Kilobytes min_val(std::numeric_limits<F64>::max()); @@ -967,6 +1020,7 @@ F64Kilobytes PeriodicRecording::getPeriodMin(const MemStatHandle& stat, S32 num_ F64Kilobytes PeriodicRecording::getPeriodMax(const StatType<MemAccumulator>& stat, S32 num_periods /*= S32_MAX*/) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); F64Kilobytes max_val(0.0); @@ -986,6 +1040,7 @@ F64Kilobytes PeriodicRecording::getPeriodMax(const MemStatHandle& stat, S32 num_ F64Kilobytes PeriodicRecording::getPeriodMean( const StatType<MemAccumulator>& stat, S32 num_periods /*= S32_MAX*/ ) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); F64Kilobytes mean(0); @@ -1006,6 +1061,7 @@ F64Kilobytes PeriodicRecording::getPeriodMean(const MemStatHandle& stat, S32 num F64Kilobytes PeriodicRecording::getPeriodStandardDeviation( const StatType<MemAccumulator>& stat, S32 num_periods /*= S32_MAX*/ ) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); F64Kilobytes period_mean = getPeriodMean(stat, num_periods); @@ -1039,6 +1095,7 @@ F64Kilobytes PeriodicRecording::getPeriodStandardDeviation(const MemStatHandle& void ExtendableRecording::extend() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; // push the data back to accepted recording mAcceptedRecording.appendRecording(mPotentialRecording); // flush data, so we can start from scratch @@ -1047,22 +1104,26 @@ void ExtendableRecording::extend() void ExtendableRecording::handleStart() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; mPotentialRecording.start(); } void ExtendableRecording::handleStop() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; mPotentialRecording.pause(); } void ExtendableRecording::handleReset() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; mAcceptedRecording.reset(); mPotentialRecording.reset(); } void ExtendableRecording::handleSplitTo(ExtendableRecording& other) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; mPotentialRecording.splitTo(other.mPotentialRecording); } @@ -1079,6 +1140,7 @@ ExtendablePeriodicRecording::ExtendablePeriodicRecording() void ExtendablePeriodicRecording::extend() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; // push the data back to accepted recording mAcceptedRecording.appendPeriodicRecording(mPotentialRecording); // flush data, so we can start from scratch @@ -1088,22 +1150,26 @@ void ExtendablePeriodicRecording::extend() void ExtendablePeriodicRecording::handleStart() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; mPotentialRecording.start(); } void ExtendablePeriodicRecording::handleStop() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; mPotentialRecording.pause(); } void ExtendablePeriodicRecording::handleReset() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; mAcceptedRecording.reset(); mPotentialRecording.reset(); } void ExtendablePeriodicRecording::handleSplitTo(ExtendablePeriodicRecording& other) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; mPotentialRecording.splitTo(other.mPotentialRecording); } @@ -1118,6 +1184,7 @@ PeriodicRecording& get_frame_recording() void LLStopWatchControlsMixinCommon::start() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; switch (mPlayState) { case STOPPED: @@ -1139,6 +1206,7 @@ void LLStopWatchControlsMixinCommon::start() void LLStopWatchControlsMixinCommon::stop() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; switch (mPlayState) { case STOPPED: @@ -1158,6 +1226,7 @@ void LLStopWatchControlsMixinCommon::stop() void LLStopWatchControlsMixinCommon::pause() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; switch (mPlayState) { case STOPPED: @@ -1177,6 +1246,7 @@ void LLStopWatchControlsMixinCommon::pause() void LLStopWatchControlsMixinCommon::unpause() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; switch (mPlayState) { case STOPPED: @@ -1196,6 +1266,7 @@ void LLStopWatchControlsMixinCommon::unpause() void LLStopWatchControlsMixinCommon::resume() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; switch (mPlayState) { case STOPPED: @@ -1216,6 +1287,7 @@ void LLStopWatchControlsMixinCommon::resume() void LLStopWatchControlsMixinCommon::restart() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; switch (mPlayState) { case STOPPED: @@ -1239,11 +1311,13 @@ void LLStopWatchControlsMixinCommon::restart() void LLStopWatchControlsMixinCommon::reset() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; handleReset(); } void LLStopWatchControlsMixinCommon::setPlayState( EPlayState state ) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; switch(state) { case STOPPED: diff --git a/indra/llcommon/lltracerecording.h b/indra/llcommon/lltracerecording.h index dae8d536106f3f0e9f8df7d5757c5070eba6d46a..e2f72e79d9cdc80800fcbec98655311370b37f9e 100644 --- a/indra/llcommon/lltracerecording.h +++ b/indra/llcommon/lltracerecording.h @@ -355,6 +355,7 @@ namespace LLTrace template <typename T> S32 getSampleCount(const StatType<T>& stat, S32 num_periods = S32_MAX) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); S32 num_samples = 0; @@ -374,6 +375,7 @@ namespace LLTrace template <typename T> typename T::value_t getPeriodMin(const StatType<T>& stat, S32 num_periods = S32_MAX) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); bool has_value = false; @@ -396,6 +398,7 @@ namespace LLTrace template<typename T> T getPeriodMin(const CountStatHandle<T>& stat, S32 num_periods = S32_MAX) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; return T(getPeriodMin(static_cast<const StatType<CountAccumulator>&>(stat), num_periods)); } @@ -403,6 +406,7 @@ namespace LLTrace template<typename T> T getPeriodMin(const SampleStatHandle<T>& stat, S32 num_periods = S32_MAX) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; return T(getPeriodMin(static_cast<const StatType<SampleAccumulator>&>(stat), num_periods)); } @@ -410,6 +414,7 @@ namespace LLTrace template<typename T> T getPeriodMin(const EventStatHandle<T>& stat, S32 num_periods = S32_MAX) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; return T(getPeriodMin(static_cast<const StatType<EventAccumulator>&>(stat), num_periods)); } @@ -419,6 +424,7 @@ namespace LLTrace template <typename T> typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMinPerSec(const StatType<T>& stat, S32 num_periods = S32_MAX) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); typename RelatedTypes<typename T::value_t>::fractional_t min_val(std::numeric_limits<F64>::max()); @@ -433,6 +439,7 @@ namespace LLTrace template<typename T> typename RelatedTypes<T>::fractional_t getPeriodMinPerSec(const CountStatHandle<T>& stat, S32 num_periods = S32_MAX) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; return typename RelatedTypes<T>::fractional_t(getPeriodMinPerSec(static_cast<const StatType<CountAccumulator>&>(stat), num_periods)); } @@ -444,6 +451,7 @@ namespace LLTrace template <typename T> typename T::value_t getPeriodMax(const StatType<T>& stat, S32 num_periods = S32_MAX) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); bool has_value = false; @@ -466,6 +474,7 @@ namespace LLTrace template<typename T> T getPeriodMax(const CountStatHandle<T>& stat, S32 num_periods = S32_MAX) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; return T(getPeriodMax(static_cast<const StatType<CountAccumulator>&>(stat), num_periods)); } @@ -473,6 +482,7 @@ namespace LLTrace template<typename T> T getPeriodMax(const SampleStatHandle<T>& stat, S32 num_periods = S32_MAX) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; return T(getPeriodMax(static_cast<const StatType<SampleAccumulator>&>(stat), num_periods)); } @@ -480,6 +490,7 @@ namespace LLTrace template<typename T> T getPeriodMax(const EventStatHandle<T>& stat, S32 num_periods = S32_MAX) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; return T(getPeriodMax(static_cast<const StatType<EventAccumulator>&>(stat), num_periods)); } @@ -489,6 +500,7 @@ namespace LLTrace template <typename T> typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMaxPerSec(const StatType<T>& stat, S32 num_periods = S32_MAX) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); F64 max_val = std::numeric_limits<F64>::min(); @@ -503,6 +515,7 @@ namespace LLTrace template<typename T> typename RelatedTypes<T>::fractional_t getPeriodMaxPerSec(const CountStatHandle<T>& stat, S32 num_periods = S32_MAX) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; return typename RelatedTypes<T>::fractional_t(getPeriodMaxPerSec(static_cast<const StatType<CountAccumulator>&>(stat), num_periods)); } @@ -514,6 +527,7 @@ namespace LLTrace template <typename T> typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMean(const StatType<T >& stat, S32 num_periods = S32_MAX) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); typename RelatedTypes<typename T::value_t>::fractional_t mean(0); @@ -534,12 +548,14 @@ namespace LLTrace template<typename T> typename RelatedTypes<T>::fractional_t getPeriodMean(const CountStatHandle<T>& stat, S32 num_periods = S32_MAX) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; return typename RelatedTypes<T>::fractional_t(getPeriodMean(static_cast<const StatType<CountAccumulator>&>(stat), num_periods)); } F64 getPeriodMean(const StatType<SampleAccumulator>& stat, S32 num_periods = S32_MAX); template<typename T> typename RelatedTypes<T>::fractional_t getPeriodMean(const SampleStatHandle<T>& stat, S32 num_periods = S32_MAX) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; return typename RelatedTypes<T>::fractional_t(getPeriodMean(static_cast<const StatType<SampleAccumulator>&>(stat), num_periods)); } @@ -547,6 +563,7 @@ namespace LLTrace template<typename T> typename RelatedTypes<T>::fractional_t getPeriodMean(const EventStatHandle<T>& stat, S32 num_periods = S32_MAX) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; return typename RelatedTypes<T>::fractional_t(getPeriodMean(static_cast<const StatType<EventAccumulator>&>(stat), num_periods)); } @@ -556,6 +573,7 @@ namespace LLTrace template <typename T> typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMeanPerSec(const StatType<T>& stat, S32 num_periods = S32_MAX) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); typename RelatedTypes<typename T::value_t>::fractional_t mean = 0; @@ -577,9 +595,39 @@ namespace LLTrace template<typename T> typename RelatedTypes<T>::fractional_t getPeriodMeanPerSec(const CountStatHandle<T>& stat, S32 num_periods = S32_MAX) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; return typename RelatedTypes<T>::fractional_t(getPeriodMeanPerSec(static_cast<const StatType<CountAccumulator>&>(stat), num_periods)); } + F64 getPeriodMedian( const StatType<SampleAccumulator>& stat, S32 num_periods = S32_MAX); + + template <typename T> + typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMedianPerSec(const StatType<T>& stat, S32 num_periods = S32_MAX) + { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; + num_periods = llmin(num_periods, getNumRecordedPeriods()); + + std::vector <typename RelatedTypes<typename T::value_t>::fractional_t> buf; + for (S32 i = 1; i <= num_periods; i++) + { + Recording& recording = getPrevRecording(i); + if (recording.getDuration() > (F32Seconds)0.f) + { + buf.push_back(recording.getPerSec(stat)); + } + } + std::sort(buf.begin(), buf.end()); + + return typename RelatedTypes<T>::fractional_t((buf.size() % 2 == 0) ? (buf[buf.size() / 2 - 1] + buf[buf.size() / 2]) / 2 : buf[buf.size() / 2]); + } + + template<typename T> + typename RelatedTypes<T>::fractional_t getPeriodMedianPerSec(const CountStatHandle<T>& stat, S32 num_periods = S32_MAX) + { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; + return typename RelatedTypes<T>::fractional_t(getPeriodMedianPerSec(static_cast<const StatType<CountAccumulator>&>(stat), num_periods)); + } + // // PERIODIC STANDARD DEVIATION // @@ -589,6 +637,7 @@ namespace LLTrace template<typename T> typename RelatedTypes<T>::fractional_t getPeriodStandardDeviation(const SampleStatHandle<T>& stat, S32 num_periods = S32_MAX) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; return typename RelatedTypes<T>::fractional_t(getPeriodStandardDeviation(static_cast<const StatType<SampleAccumulator>&>(stat), num_periods)); } @@ -596,6 +645,7 @@ namespace LLTrace template<typename T> typename RelatedTypes<T>::fractional_t getPeriodStandardDeviation(const EventStatHandle<T>& stat, S32 num_periods = S32_MAX) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; return typename RelatedTypes<T>::fractional_t(getPeriodStandardDeviation(static_cast<const StatType<EventAccumulator>&>(stat), num_periods)); } diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index 779127643ab14054ebe9e5a4bd164b87a802c887..0d7b5abdda4b1bc0f1e6bbddcdb1a409b420fb53 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -274,12 +274,10 @@ void ThreadRecorder::pushToParent() } -static LLTrace::BlockTimerStatHandle FTM_PULL_TRACE_DATA_FROM_CHILDREN("Pull child thread trace data"); - void ThreadRecorder::pullFromChildren() { #if LL_TRACE_ENABLED - LL_RECORD_BLOCK_TIME(FTM_PULL_TRACE_DATA_FROM_CHILDREN); + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; if (mActiveRecordings.empty()) return; { LLMutexLock child_list_lock(&mChildListMutex); diff --git a/indra/llcommon/lluuid.cpp b/indra/llcommon/lluuid.cpp index 120c15c6bc48fa6431fa71539d0b08d1111fb92c..b29592944c03966d9b43457fd5d9e4cf04c77960 100644 --- a/indra/llcommon/lluuid.cpp +++ b/indra/llcommon/lluuid.cpp @@ -49,9 +49,6 @@ const LLUUID LLUUID::null; const LLTransactionID LLTransactionID::tnull; -// static -LLMutex LLUUID::sMutex(LLMutex::E_CONST_INIT); - /* NOT DONE YET!!! @@ -979,6 +976,7 @@ void LLUUID::generate() // if clock hasn't changed or went backward, change clockseq if (cmpTime(×tamp, &time_last) != 1) { + static LLMutex sMutex; LLMutexLock lock(&sMutex); clock_seq = (clock_seq + 1) & 0x3FFF; if (clock_seq == 0) diff --git a/indra/llcommon/lockstatic.h b/indra/llcommon/lockstatic.h index 09e29026190b9b90b384b19529a1bc58a5f7ba1c..96c53c64732b6ab45900b1b53e1abab1e43becff 100644 --- a/indra/llcommon/lockstatic.h +++ b/indra/llcommon/lockstatic.h @@ -13,9 +13,7 @@ #if ! defined(LL_LOCKSTATIC_H) #define LL_LOCKSTATIC_H -#include <mutex> - -#include "absl/synchronization/mutex.h" +#include "mutex.h" // std::unique_lock namespace llthread { @@ -24,11 +22,11 @@ namespace llthread // instance of Static while holding a lock on that instance. Use of // Static::mMutex presumes that Static declares some suitable mMutex. template <typename Static> -class LockStaticStd +class LockStatic { typedef std::unique_lock<decltype(Static::mMutex)> lock_t; public: - LockStaticStd(): + LockStatic(): mData(getStatic()), mLock(mData->mMutex) {} @@ -70,100 +68,6 @@ class LockStaticStd } }; - -// The same as above but for absl::Mutex -template <typename Static> -class LockStaticAbsl -{ - typedef absl::ReleasableMutexLock lock_t; -public: - LockStaticAbsl() : - mData(getStatic()), - mLock(&mData->mMutex) - {} - Static* get() const { return mData; } - operator Static* () const { return get(); } - Static* operator->() const { return get(); } - // sometimes we must explicitly unlock... - void unlock() - { - // but once we do, access is no longer permitted - mData = nullptr; - mLock.Release(); - } -protected: - Static* mData; - lock_t mLock; -private: - Static* getStatic() - { - // Static::mMutex must be function-local static rather than class- - // static. Some of our consumers must function properly (therefore - // lock properly) even when the containing module's static variables - // have not yet been runtime-initialized. A mutex requires - // construction. A static class member might not yet have been - // constructed. - // - // We could store a dumb mutex_t*, notice when it's NULL and allocate a - // heap mutex -- but that's vulnerable to race conditions. And we can't - // defend the dumb pointer with another mutex. - // - // We could store a std::atomic<mutex_t*> -- but a default-constructed - // std::atomic<T> does not contain a valid T, even a default-constructed - // T! Which means std::atomic, too, requires runtime initialization. - // - // But a function-local static is guaranteed to be initialized exactly - // once: the first time control reaches that declaration. - static Static sData; - return &sData; - } -}; - -// Instantiate this template to obtain a pointer to the canonical static -// instance of Static with no lock. Aka NoOp -template <typename Static> -class LockStaticNoOp -{ -public: - LockStaticNoOp(): - mData(getStatic()) - {} - Static* get() const { return mData; } - operator Static*() const { return get(); } - Static* operator->() const { return get(); } - // sometimes we must explicitly unlock... - void unlock() - { - // but once we do, access is no longer permitted - mData = nullptr; - } -protected: - Static* mData; -private: - Static* getStatic() - { - // Static::mMutex must be function-local static rather than class- - // static. Some of our consumers must function properly (therefore - // lock properly) even when the containing module's static variables - // have not yet been runtime-initialized. A mutex requires - // construction. A static class member might not yet have been - // constructed. - // - // We could store a dumb mutex_t*, notice when it's NULL and allocate a - // heap mutex -- but that's vulnerable to race conditions. And we can't - // defend the dumb pointer with another mutex. - // - // We could store a std::atomic<mutex_t*> -- but a default-constructed - // std::atomic<T> does not contain a valid T, even a default-constructed - // T! Which means std::atomic, too, requires runtime initialization. - // - // But a function-local static is guaranteed to be initialized exactly - // once: the first time control reaches that declaration. - static Static sData; - return &sData; - } -}; - } // llthread namespace #endif /* ! defined(LL_LOCKSTATIC_H) */ diff --git a/indra/llcommon/stdtypes.h b/indra/llcommon/stdtypes.h index 887f6ab7332413fcd2a8bc043636935c516729e1..b07805b62831271404212e025f1b9151c76eb86b 100644 --- a/indra/llcommon/stdtypes.h +++ b/indra/llcommon/stdtypes.h @@ -42,10 +42,17 @@ typedef unsigned int U32; // Windows wchar_t is 16-bit, whichever way /Zc:wchar_t is set. In effect, // Windows wchar_t is always a typedef, either for unsigned short or __wchar_t. // (__wchar_t, available either way, is Microsoft's native 2-byte wchar_t type.) +// The version of clang available with VS 2019 also defines wchar_t as __wchar_t +// which is also 16 bits. // In any case, llwchar should be a UTF-32 type. typedef U32 llwchar; #else typedef wchar_t llwchar; +// What we'd actually want is a simple module-scope 'if constexpr' to test +// std::is_same<wchar_t, llwchar>::value and use that to define, or not +// define, string conversion specializations. Since we don't have that, we'll +// have to rely on #if instead. Sorry, Dr. Stroustrup. +#define LLWCHAR_IS_WCHAR_T 1 #endif #if LL_WINDOWS diff --git a/indra/llcommon/stringize.h b/indra/llcommon/stringize.h index 16b4227d610dd174e693f6d0442a7e3a2db57c70..12df6939108e47b3f0e05c8ccfa40ffae7f8f5c4 100644 --- a/indra/llcommon/stringize.h +++ b/indra/llcommon/stringize.h @@ -31,58 +31,109 @@ #include <sstream> #include <llstring.h> +#include <boost/call_traits.hpp> /** - * gstringize(item) encapsulates an idiom we use constantly, using + * stream_to(std::ostream&, items, ...) streams each item in the parameter list + * to the passed std::ostream using the insertion operator <<. This can be + * used, for instance, to make a simple print() function, e.g.: + * + * @code + * template <typename... Items> + * void print(Items&&... items) + * { + * stream_to(std::cout, std::forward<Items>(items)...); + * } + * @endcode + */ +// recursion tail +template <typename CHARTYPE> +void stream_to(std::basic_ostream<CHARTYPE>& out) {} +// stream one or more items +template <typename CHARTYPE, typename T, typename... Items> +void stream_to(std::basic_ostream<CHARTYPE>& out, T&& item, Items&&... items) +{ + out << std::forward<T>(item); + stream_to(out, std::forward<Items>(items)...); +} + +// why we use function overloads, not function template specializations: +// http://www.gotw.ca/publications/mill17.htm + +/** + * gstringize(item, ...) encapsulates an idiom we use constantly, using * operator<<(std::ostringstream&, TYPE) followed by std::ostringstream::str() - * or their wstring equivalents - * to render a string expressing some item. + * or their wstring equivalents to render a string expressing one or more items. */ -template <typename CHARTYPE, typename T> -std::basic_string<CHARTYPE> gstringize(const T& item) +// two or more args - the case of a single argument is handled separately +template <typename CHARTYPE, typename T0, typename T1, typename... Items> +auto gstringize(T0&& item0, T1&& item1, Items&&... items) { std::basic_ostringstream<CHARTYPE> out; - out << item; + stream_to(out, std::forward<T0>(item0), std::forward<T1>(item1), + std::forward<Items>(items)...); return out.str(); } -/** - *partial specialization of stringize for handling wstring - *TODO: we should have similar specializations for wchar_t[] but not until it is needed. - */ -//inline std::string stringize(const std::wstring& item) -//{ -// return wstring_to_utf8str(item); -//} +// generic single argument: stream to out, as above +template <typename CHARTYPE, typename T> +struct gstringize_impl +{ + auto operator()(typename boost::call_traits<T>::param_type arg) + { + std::basic_ostringstream<CHARTYPE> out; + out << arg; + return out.str(); + } +}; -/** - * Specialization of gstringize for std::string return types - */ -template <typename T> -std::string stringize(const T& item) +// partially specialize for a single STRING argument - +// note that ll_convert<T>(T) already handles the trivial case +template <typename OUTCHAR, typename INCHAR> +struct gstringize_impl<OUTCHAR, std::basic_string<INCHAR>> { - return gstringize<char>(item); + auto operator()(const std::basic_string<INCHAR>& arg) + { + return ll_convert<std::basic_string<OUTCHAR>>(arg); + } +}; + +// partially specialize for a single CHARTYPE* argument - +// since it's not a basic_string and we do want to optimize this common case +template <typename OUTCHAR, typename INCHAR> +struct gstringize_impl<OUTCHAR, INCHAR*> +{ + auto operator()(const INCHAR* arg) + { + return ll_convert<std::basic_string<OUTCHAR>>(arg); + } +}; + +// gstringize(single argument) +template <typename CHARTYPE, typename T> +auto gstringize(T&& item) +{ + // use decay<T> so we don't require separate specializations + // for T, const T, T&, const T& ... + return gstringize_impl<CHARTYPE, std::decay_t<T>>()(std::forward<T>(item)); } /** - * Specialization for generating wstring from string. - * Both a convenience function and saves a miniscule amount of overhead. + * Specialization of gstringize for std::string return types */ -inline std::wstring wstringize(const std::string& item) +template <typename... Items> +auto stringize(Items&&... items) { - // utf8str_to_wstring() returns LLWString, which isn't necessarily the - // same as std::wstring - LLWString s(utf8str_to_wstring(item)); - return std::wstring(s.begin(), s.end()); + return gstringize<char>(std::forward<Items>(items)...); } /** * Specialization of gstringize for std::wstring return types */ -template <typename T> -std::wstring wstringize(const T& item) +template <typename... Items> +auto wstringize(Items&&... items) { - return gstringize<wchar_t>(item); + return gstringize<wchar_t>(std::forward<Items>(items)...); } /** @@ -146,11 +197,9 @@ void destringize_f(std::basic_string<CHARTYPE> const & str, Functor const & f) * std::istringstream in(str); * in >> item1 >> item2 >> item3 ... ; * @endcode - * @NOTE - once we get generic lambdas, we shouldn't need DEWSTRINGIZE() any - * more since DESTRINGIZE() should do the right thing with a std::wstring. But - * until then, the lambda we pass must accept the right std::basic_istream. */ -#define DESTRINGIZE(STR, EXPRESSION) (destringize_f((STR), [&](std::istream& in){in >> EXPRESSION;})) -#define DEWSTRINGIZE(STR, EXPRESSION) (destringize_f((STR), [&](std::wistream& in){in >> EXPRESSION;})) +#define DESTRINGIZE(STR, EXPRESSION) (destringize_f((STR), [&](auto& in){in >> EXPRESSION;})) +// legacy name, just use DESTRINGIZE() going forward +#define DEWSTRINGIZE(STR, EXPRESSION) DESTRINGIZE(STR, EXPRESSION) #endif /* ! defined(LL_STRINGIZE_H) */ diff --git a/indra/llcommon/tests/classic_callback_test.cpp b/indra/llcommon/tests/classic_callback_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c060775c2418bc4ef3749288eb5ac166d5069f62 --- /dev/null +++ b/indra/llcommon/tests/classic_callback_test.cpp @@ -0,0 +1,144 @@ +/** + * @file classic_callback_test.cpp + * @author Nat Goodspeed + * @date 2021-09-22 + * @brief Test ClassicCallback and HeapClassicCallback. + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$ + * Copyright (c) 2021, Linden Research, Inc. + * $/LicenseInfo$ + */ + +// Precompiled header +#include "linden_common.h" +// associated header +#include "classic_callback.h" +// STL headers +#include <iostream> +#include <string> +// std headers +// external library headers +// other Linden headers +#include "../test/lltut.h" + +/***************************************************************************** +* example callback +*****************************************************************************/ +// callback_t is part of the specification of someAPI() +typedef void (*callback_t)(const char*, void*); +void someAPI(callback_t callback, void* userdata) +{ + callback("called", userdata); +} + +// C++ callable I want as the actual callback +struct MyCallback +{ + void operator()(const char* msg, void*) + { + mMsg = msg; + } + + void callback_with_extra(const std::string& extra, const char* msg) + { + mMsg = extra + ' ' + msg; + } + + std::string mMsg; +}; + +/***************************************************************************** +* example callback accepting several params, and void* userdata isn't first +*****************************************************************************/ +typedef std::string (*complex_callback)(int, const char*, void*, double); +std::string otherAPI(complex_callback callback, void* userdata) +{ + return callback(17, "hello world", userdata, 3.0); +} + +// struct into which we can capture complex_callback params +static struct Data +{ + void set(int i, const char* s, double f) + { + mi = i; + ms = s; + mf = f; + } + + void clear() { set(0, "", 0.0); } + + int mi; + std::string ms; + double mf; +} sData; + +// C++ callable I want to pass +struct OtherCallback +{ + std::string operator()(int num, const char* str, void*, double approx) + { + sData.set(num, str, approx); + return "hello back!"; + } +}; + +/***************************************************************************** +* TUT +*****************************************************************************/ +namespace tut +{ + struct classic_callback_data + { + }; + typedef test_group<classic_callback_data> classic_callback_group; + typedef classic_callback_group::object object; + classic_callback_group classic_callbackgrp("classic_callback"); + + template<> template<> + void object::test<1>() + { + set_test_name("ClassicCallback"); + // engage someAPI(MyCallback()) + auto ccb{ makeClassicCallback<callback_t>(MyCallback()) }; + someAPI(ccb.get_callback(), ccb.get_userdata()); + // Unfortunately, with the side effect confined to the bound + // MyCallback instance, that call was invisible. Bind a reference to a + // named instance by specifying a ref type. + MyCallback mcb; + ClassicCallback<callback_t, void*, MyCallback&> ccb2(mcb); + someAPI(ccb2.get_callback(), ccb2.get_userdata()); + ensure_equals("failed to call through ClassicCallback", mcb.mMsg, "called"); + + // try with HeapClassicCallback + mcb.mMsg.clear(); + auto hcbp{ makeHeapClassicCallback<callback_t>(mcb) }; + someAPI(hcbp->get_callback(), hcbp->get_userdata()); + ensure_equals("failed to call through HeapClassicCallback", mcb.mMsg, "called"); + + // lambda + // The tricky thing here is that a lambda is an unspecified type, so + // you can't declare a ClassicCallback<signature, void*, that type>. + mcb.mMsg.clear(); + auto xcb( + makeClassicCallback<callback_t>( + [&mcb](const char* msg, void*) + { mcb.callback_with_extra("extra", msg); })); + someAPI(xcb.get_callback(), xcb.get_userdata()); + ensure_equals("failed to call lambda", mcb.mMsg, "extra called"); + + // engage otherAPI(OtherCallback()) + OtherCallback ocb; + // Instead of specifying a reference type for the bound CALLBACK, as + // with ccb2 above, you can alternatively move the callable object + // into the ClassicCallback (of course AFTER any other reference). + // That's why OtherCallback uses external data for its observable side + // effect. + auto occb{ makeClassicCallback<complex_callback>(std::move(ocb)) }; + std::string result{ otherAPI(occb.get_callback(), occb.get_userdata()) }; + ensure_equals("failed to return callback result", result, "hello back!"); + ensure_equals("failed to set int", sData.mi, 17); + ensure_equals("failed to set string", sData.ms, "hello world"); + ensure_equals("failed to set double", sData.mf, 3.0); + } +} // namespace tut diff --git a/indra/llcommon/tests/llinstancetracker_test.cpp b/indra/llcommon/tests/llinstancetracker_test.cpp index 0eaa4abbe5ddac2afec40209de4e465ff6fd2d65..810ea1e02ef528740656f794f6b8aec2b8aace5f 100644 --- a/indra/llcommon/tests/llinstancetracker_test.cpp +++ b/indra/llcommon/tests/llinstancetracker_test.cpp @@ -89,19 +89,19 @@ namespace tut { Keyed one("one"); ensure_equals(Keyed::instanceCount(), 1); - Keyed* found = Keyed::getInstance("one"); - ensure("couldn't find stack Keyed", found); - ensure_equals("found wrong Keyed instance", found, &one); + auto found = Keyed::getInstance("one"); + ensure("couldn't find stack Keyed", bool(found)); + ensure_equals("found wrong Keyed instance", found.get(), &one); { std::unique_ptr<Keyed> two(new Keyed("two")); ensure_equals(Keyed::instanceCount(), 2); - Keyed* found = Keyed::getInstance("two"); - ensure("couldn't find heap Keyed", found); - ensure_equals("found wrong Keyed instance", found, two.get()); + auto found = Keyed::getInstance("two"); + ensure("couldn't find heap Keyed", bool(found)); + ensure_equals("found wrong Keyed instance", found.get(), two.get()); } ensure_equals(Keyed::instanceCount(), 1); } - Keyed* found = Keyed::getInstance("one"); + auto found = Keyed::getInstance("one"); ensure("Keyed key lives too long", ! found); ensure_equals(Keyed::instanceCount(), 0); } diff --git a/indra/llcommon/tests/llmainthreadtask_test.cpp b/indra/llcommon/tests/llmainthreadtask_test.cpp index 563759cc6bc532eefc369aaaf54ccfa1d3046bca..69b11ccafbbce3222207d78efed4f8111ea003c4 100644 --- a/indra/llcommon/tests/llmainthreadtask_test.cpp +++ b/indra/llcommon/tests/llmainthreadtask_test.cpp @@ -61,10 +61,10 @@ namespace tut struct StaticData { - LLMutex mMutex; // LockStatic looks for mMutex + std::mutex mMutex; // LockStatic looks for mMutex bool ran{false}; }; - typedef llthread::LockStaticLL<StaticData> LockStatic; + typedef llthread::LockStatic<StaticData> LockStatic; template<> template<> void object::test<2>() diff --git a/indra/llcommon/tests/llprocess_test.cpp b/indra/llcommon/tests/llprocess_test.cpp index ca65abecb95ce0dd12510782979329196f72d4bd..b75fcac68e4d6e807338a795709d8a59fcd1e790 100644 --- a/indra/llcommon/tests/llprocess_test.cpp +++ b/indra/llcommon/tests/llprocess_test.cpp @@ -355,14 +355,15 @@ namespace tut // Create a script file in a temporary place. NamedTempFile script("py", + "from __future__ import print_function" EOL "import sys" EOL "import time" EOL EOL "time.sleep(2)" EOL - "print('stdout after wait', file=sys.stdout)" EOL + "print('stdout after wait',file=sys.stdout)" EOL "sys.stdout.flush()" EOL "time.sleep(2)" EOL - "print('stderr after wait', file=sys.stderr)" EOL + "print('stderr after wait',file=sys.stderr)" EOL "sys.stderr.flush()" EOL ); @@ -569,12 +570,12 @@ namespace tut { set_test_name("arguments"); PythonProcessLauncher py(get_test_name(), - "from __future__ import with_statement\n" + "from __future__ import with_statement, print_function\n" "import sys\n" // note nonstandard output-file arg! "with open(sys.argv[3], 'w') as f:\n" " for arg in sys.argv[1:]:\n" - " print(arg, file=f)\n"); + " print(arg,file=f)\n"); // We expect that PythonProcessLauncher has already appended // its own NamedTempFile to mParams.args (sys.argv[0]). py.mParams.args.add("first arg"); // sys.argv[1] @@ -858,6 +859,7 @@ namespace tut set_test_name("'bogus' test"); CaptureLog recorder; PythonProcessLauncher py(get_test_name(), + "from __future__ import print_function\n" "print('Hello world')\n"); py.mParams.files.add(LLProcess::FileParam("bogus")); py.mPy = LLProcess::create(py.mParams); @@ -873,6 +875,7 @@ namespace tut // Replace this test with one or more real 'file' tests when we // implement 'file' support PythonProcessLauncher py(get_test_name(), + "from __future__ import print_function\n" "print('Hello world')\n"); py.mParams.files.add(LLProcess::FileParam()); py.mParams.files.add(LLProcess::FileParam("file")); @@ -888,6 +891,7 @@ namespace tut // implement 'tpipe' support CaptureLog recorder; PythonProcessLauncher py(get_test_name(), + "from __future__ import print_function\n" "print('Hello world')\n"); py.mParams.files.add(LLProcess::FileParam()); py.mParams.files.add(LLProcess::FileParam("tpipe")); @@ -905,6 +909,7 @@ namespace tut // implement 'npipe' support CaptureLog recorder; PythonProcessLauncher py(get_test_name(), + "from __future__ import print_function\n" "print('Hello world')\n"); py.mParams.files.add(LLProcess::FileParam()); py.mParams.files.add(LLProcess::FileParam()); @@ -981,7 +986,8 @@ namespace tut { set_test_name("get*Pipe() validation"); PythonProcessLauncher py(get_test_name(), - "print('this output is expected)'\n"); + "from __future__ import print_function\n" + "print('this output is expected')\n"); py.mParams.files.add(LLProcess::FileParam("pipe")); // pipe for stdin py.mParams.files.add(LLProcess::FileParam()); // inherit stdout py.mParams.files.add(LLProcess::FileParam("pipe")); // pipe for stderr @@ -1001,6 +1007,7 @@ namespace tut { set_test_name("talk to stdin/stdout"); PythonProcessLauncher py(get_test_name(), + "from __future__ import print_function\n" "import sys, time\n" "print('ok')\n" "sys.stdout.flush()\n" @@ -1119,6 +1126,7 @@ namespace tut { set_test_name("ReadPipe \"eof\" event"); PythonProcessLauncher py(get_test_name(), + "from __future__ import print_function\n" "print('Hello from Python!')\n"); py.mParams.files.add(LLProcess::FileParam()); // stdin py.mParams.files.add(LLProcess::FileParam("pipe")); // stdout diff --git a/indra/llcommon/tests/threadsafeschedule_test.cpp b/indra/llcommon/tests/threadsafeschedule_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c421cc7b1c3634ba4b81511a1097d136a50bb166 --- /dev/null +++ b/indra/llcommon/tests/threadsafeschedule_test.cpp @@ -0,0 +1,69 @@ +/** + * @file threadsafeschedule_test.cpp + * @author Nat Goodspeed + * @date 2021-10-04 + * @brief Test for threadsafeschedule. + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$ + * Copyright (c) 2021, Linden Research, Inc. + * $/LicenseInfo$ + */ + +// Precompiled header +#include "linden_common.h" +// associated header +#include "threadsafeschedule.h" +// STL headers +// std headers +#include <chrono> +// external library headers +// other Linden headers +#include "../test/lltut.h" + +using namespace std::literals::chrono_literals; // ms suffix +using namespace std::literals::string_literals; // s suffix +using Queue = LL::ThreadSafeSchedule<std::string>; + +/***************************************************************************** +* TUT +*****************************************************************************/ +namespace tut +{ + struct threadsafeschedule_data + { + Queue queue; + }; + typedef test_group<threadsafeschedule_data> threadsafeschedule_group; + typedef threadsafeschedule_group::object object; + threadsafeschedule_group threadsafeschedulegrp("threadsafeschedule"); + + template<> template<> + void object::test<1>() + { + set_test_name("push"); + // Simply calling push() a few times might result in indeterminate + // delivery order if the resolution of steady_clock is coarser than + // the real time required for each push() call. Explicitly increment + // the timestamp for each one -- but since we're passing explicit + // timestamps, make the queue reorder them. + queue.push(Queue::TimeTuple(Queue::Clock::now() + 200ms, "ghi")); + // Given the various push() overloads, you have to match the type + // exactly: conversions are ambiguous. + queue.push("abc"s); + queue.push(Queue::Clock::now() + 100ms, "def"); + queue.close(); + auto entry = queue.pop(); + ensure_equals("failed to pop first", std::get<0>(entry), "abc"s); + entry = queue.pop(); + ensure_equals("failed to pop second", std::get<0>(entry), "def"s); + ensure("queue not closed", queue.isClosed()); + ensure("queue prematurely done", ! queue.done()); + std::string s; + bool popped = queue.tryPopFor(1s, s); + ensure("failed to pop third", popped); + ensure_equals("third is wrong", s, "ghi"s); + popped = queue.tryPop(s); + ensure("queue not empty", ! popped); + ensure("queue not done", queue.done()); + } +} // namespace tut diff --git a/indra/llcommon/tests/tuple_test.cpp b/indra/llcommon/tests/tuple_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..af94e2086c12e41263431a19828b1ce10ab89b6b --- /dev/null +++ b/indra/llcommon/tests/tuple_test.cpp @@ -0,0 +1,47 @@ +/** + * @file tuple_test.cpp + * @author Nat Goodspeed + * @date 2021-10-04 + * @brief Test for tuple. + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$ + * Copyright (c) 2021, Linden Research, Inc. + * $/LicenseInfo$ + */ + +// Precompiled header +#include "linden_common.h" +// associated header +#include "tuple.h" +// STL headers +// std headers +// external library headers +// other Linden headers +#include "../test/lltut.h" + +/***************************************************************************** +* TUT +*****************************************************************************/ +namespace tut +{ + struct tuple_data + { + }; + typedef test_group<tuple_data> tuple_group; + typedef tuple_group::object object; + tuple_group tuplegrp("tuple"); + + template<> template<> + void object::test<1>() + { + set_test_name("tuple"); + std::tuple<std::string, int> tup{ "abc", 17 }; + std::tuple<int, std::string, int> ptup{ tuple_cons(34, tup) }; + std::tuple<std::string, int> tup2; + int i; + std::tie(i, tup2) = tuple_split(ptup); + ensure_equals("tuple_car() fail", i, 34); + ensure_equals("tuple_cdr() (0) fail", std::get<0>(tup2), "abc"); + ensure_equals("tuple_cdr() (1) fail", std::get<1>(tup2), 17); + } +} // namespace tut diff --git a/indra/llcommon/tests/workqueue_test.cpp b/indra/llcommon/tests/workqueue_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1d73f7aa0d47f913292f9fbfd4f7c5d8bb96d666 --- /dev/null +++ b/indra/llcommon/tests/workqueue_test.cpp @@ -0,0 +1,235 @@ +/** + * @file workqueue_test.cpp + * @author Nat Goodspeed + * @date 2021-10-07 + * @brief Test for workqueue. + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$ + * Copyright (c) 2021, Linden Research, Inc. + * $/LicenseInfo$ + */ + +// Precompiled header +#include "linden_common.h" +// associated header +#include "workqueue.h" +// STL headers +// std headers +#include <chrono> +#include <deque> +// external library headers +// other Linden headers +#include "../test/lltut.h" +#include "../test/catch_and_store_what_in.h" +#include "llcond.h" +#include "llcoros.h" +#include "lleventcoro.h" +#include "llstring.h" +#include "stringize.h" + +using namespace LL; +using namespace std::literals::chrono_literals; // ms suffix +using namespace std::literals::string_literals; // s suffix + +/***************************************************************************** +* TUT +*****************************************************************************/ +namespace tut +{ + struct workqueue_data + { + WorkQueue queue{"queue"}; + }; + typedef test_group<workqueue_data> workqueue_group; + typedef workqueue_group::object object; + workqueue_group workqueuegrp("workqueue"); + + template<> template<> + void object::test<1>() + { + set_test_name("name"); + ensure_equals("didn't capture name", queue.getKey(), "queue"); + ensure("not findable", WorkQueue::getInstance("queue") == queue.getWeak().lock()); + WorkQueue q2; + ensure("has no name", LLStringUtil::startsWith(q2.getKey(), "WorkQueue")); + } + + template<> template<> + void object::test<2>() + { + set_test_name("post"); + bool wasRun{ false }; + // We only get away with binding a simple bool because we're running + // the work on the same thread. + queue.post([&wasRun](){ wasRun = true; }); + queue.close(); + ensure("ran too soon", ! wasRun); + queue.runUntilClose(); + ensure("didn't run", wasRun); + } + + template<> template<> + void object::test<3>() + { + set_test_name("postEvery"); + // record of runs + using Shared = std::deque<WorkQueue::TimePoint>; + // This is an example of how to share data between the originator of + // postEvery(work) and the work item itself, since usually a WorkQueue + // is used to dispatch work to a different thread. Neither of them + // should call any of LLCond's wait methods: you don't want to stall + // either the worker thread or the originating thread (conventionally + // main). Use LLCond or a subclass even if all you want to do is + // signal the work item that it can quit; consider LLOneShotCond. + LLCond<Shared> data; + auto start = WorkQueue::TimePoint::clock::now(); + auto interval = 100ms; + queue.postEvery( + interval, + [&data, count = 0] + () mutable + { + // record the timestamp at which this instance is running + data.update_one( + [](Shared& data) + { + data.push_back(WorkQueue::TimePoint::clock::now()); + }); + // by the 3rd call, return false to stop + return (++count < 3); + }); + // no convenient way to close() our queue while we've got a + // postEvery() running, so run until we have exhausted the iterations + // or we time out waiting + for (auto finish = start + 10*interval; + WorkQueue::TimePoint::clock::now() < finish && + data.get([](const Shared& data){ return data.size(); }) < 3; ) + { + queue.runPending(); + std::this_thread::sleep_for(interval/10); + } + // Take a copy of the captured deque. + Shared result = data.get(); + ensure_equals("called wrong number of times", result.size(), 3); + // postEvery() assumes you want the first call to happen right away. + // Pretend our start time was (interval) earlier than that, to make + // our too early/too late tests uniform for all entries. + start -= interval; + for (size_t i = 0; i < result.size(); ++i) + { + auto diff = result[i] - start; + start += interval; + try + { + ensure(STRINGIZE("call " << i << " too soon"), diff >= interval); + ensure(STRINGIZE("call " << i << " too late"), diff < interval*1.5); + } + catch (const tut::failure&) + { + auto interval_ms = interval / 1ms; + auto diff_ms = diff / 1ms; + std::cerr << "interval " << interval_ms + << "ms; diff " << diff_ms << "ms" << std::endl; + throw; + } + } + } + + template<> template<> + void object::test<4>() + { + set_test_name("postTo"); + WorkQueue main("main"); + auto qptr = WorkQueue::getInstance("queue"); + int result = 0; + main.postTo( + qptr, + [](){ return 17; }, + // Note that a postTo() *callback* can safely bind a reference to + // a variable on the invoking thread, because the callback is run + // on the invoking thread. (Of course the bound variable must + // survive until the callback is called.) + [&result](int i){ result = i; }); + // this should post the callback to main + qptr->runOne(); + // this should run the callback + main.runOne(); + ensure_equals("failed to run int callback", result, 17); + + std::string alpha; + // postTo() handles arbitrary return types + main.postTo( + qptr, + [](){ return "abc"s; }, + [&alpha](const std::string& s){ alpha = s; }); + qptr->runPending(); + main.runPending(); + ensure_equals("failed to run string callback", alpha, "abc"); + } + + template<> template<> + void object::test<5>() + { + set_test_name("postTo with void return"); + WorkQueue main("main"); + auto qptr = WorkQueue::getInstance("queue"); + std::string observe; + main.postTo( + qptr, + // The ONLY reason we can get away with binding a reference to + // 'observe' in our work callable is because we're directly + // calling qptr->runOne() on this same thread. It would be a + // mistake to do that if some other thread were servicing 'queue'. + [&observe](){ observe = "queue"; }, + [&observe](){ observe.append(";main"); }); + qptr->runOne(); + main.runOne(); + ensure_equals("failed to run both lambdas", observe, "queue;main"); + } + + template<> template<> + void object::test<6>() + { + set_test_name("waitForResult"); + std::string stored; + // Try to call waitForResult() on this thread's main coroutine. It + // should throw because the main coroutine must service the queue. + auto what{ catch_what<WorkQueue::Error>( + [this, &stored](){ stored = queue.waitForResult( + [](){ return "should throw"; }); }) }; + ensure("lambda should not have run", stored.empty()); + ensure_not("waitForResult() should have thrown", what.empty()); + ensure(STRINGIZE("should mention waitForResult: " << what), + what.find("waitForResult") != std::string::npos); + + // Call waitForResult() on a coroutine, with a string result. + LLCoros::instance().launch( + "waitForResult string", + [this, &stored]() + { stored = queue.waitForResult( + [](){ return "string result"; }); }); + llcoro::suspend(); + // Nothing will have happened yet because, even if the coroutine did + // run immediately, all it did was to queue the inner lambda on + // 'queue'. Service it. + queue.runOne(); + llcoro::suspend(); + ensure_equals("bad waitForResult return", stored, "string result"); + + // Call waitForResult() on a coroutine, with a void callable. + stored.clear(); + bool done = false; + LLCoros::instance().launch( + "waitForResult void", + [this, &stored, &done]() + { + queue.waitForResult([&stored](){ stored = "ran"; }); + done = true; + }); + llcoro::suspend(); + queue.runOne(); + llcoro::suspend(); + ensure_equals("didn't run coroutine", stored, "ran"); + ensure("void waitForResult() didn't return", done); + } +} // namespace tut diff --git a/indra/llcommon/threadpool.cpp b/indra/llcommon/threadpool.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d5adf11264cfc25f8de690f545a2a80807355c50 --- /dev/null +++ b/indra/llcommon/threadpool.cpp @@ -0,0 +1,89 @@ +/** + * @file threadpool.cpp + * @author Nat Goodspeed + * @date 2021-10-21 + * @brief Implementation for threadpool. + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$ + * Copyright (c) 2021, Linden Research, Inc. + * $/LicenseInfo$ + */ + +// Precompiled header +#include "linden_common.h" +// associated header +#include "threadpool.h" +// STL headers +// std headers +// external library headers +// other Linden headers +#include "llerror.h" +#include "llevents.h" +#include "stringize.h" + +LL::ThreadPool::ThreadPool(const std::string& name, size_t threads, size_t capacity): + super(name), + mQueue(name, capacity), + mName("ThreadPool:" + name), + mThreadCount(threads) +{} + +void LL::ThreadPool::start() +{ + for (size_t i = 0; i < mThreadCount; ++i) + { + std::string tname{ stringize(mName, ':', (i+1), '/', mThreadCount) }; + mThreads.emplace_back(tname, [this, tname]() + { + LL_PROFILER_SET_THREAD_NAME(tname.c_str()); + run(tname); + }); + } + // Listen on "LLApp", and when the app is shutting down, close the queue + // and join the workers. + LLEventPumps::instance().obtain("LLApp").listen( + mName, + [this](const LLSD& stat) + { + std::string status(stat["status"]); + if (status != "running") + { + // viewer is starting shutdown -- proclaim the end is nigh! + LL_DEBUGS("ThreadPool") << mName << " saw " << status << LL_ENDL; + close(); + } + return false; + }); +} + +LL::ThreadPool::~ThreadPool() +{ + close(); +} + +void LL::ThreadPool::close() +{ + if (! mQueue.isClosed()) + { + LL_DEBUGS("ThreadPool") << mName << " closing queue and joining threads" << LL_ENDL; + mQueue.close(); + for (auto& pair: mThreads) + { + LL_DEBUGS("ThreadPool") << mName << " waiting on thread " << pair.first << LL_ENDL; + pair.second.join(); + } + LL_DEBUGS("ThreadPool") << mName << " shutdown complete" << LL_ENDL; + } +} + +void LL::ThreadPool::run(const std::string& name) +{ + LL_DEBUGS("ThreadPool") << name << " starting" << LL_ENDL; + run(); + LL_DEBUGS("ThreadPool") << name << " stopping" << LL_ENDL; +} + +void LL::ThreadPool::run() +{ + mQueue.runUntilClose(); +} diff --git a/indra/llcommon/threadpool.h b/indra/llcommon/threadpool.h new file mode 100644 index 0000000000000000000000000000000000000000..f8eec3b45744d8a18532811a24901fe84271f62a --- /dev/null +++ b/indra/llcommon/threadpool.h @@ -0,0 +1,73 @@ +/** + * @file threadpool.h + * @author Nat Goodspeed + * @date 2021-10-21 + * @brief ThreadPool configures a WorkQueue along with a pool of threads to + * service it. + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$ + * Copyright (c) 2021, Linden Research, Inc. + * $/LicenseInfo$ + */ + +#if ! defined(LL_THREADPOOL_H) +#define LL_THREADPOOL_H + +#include "workqueue.h" +#include <string> +#include <thread> +#include <utility> // std::pair +#include <vector> + +namespace LL +{ + + class ThreadPool: public LLInstanceTracker<ThreadPool, std::string> + { + private: + using super = LLInstanceTracker<ThreadPool, std::string>; + public: + /** + * Pass ThreadPool a string name. This can be used to look up the + * relevant WorkQueue. + */ + ThreadPool(const std::string& name, size_t threads=1, size_t capacity=1024); + virtual ~ThreadPool(); + + /** + * Launch the ThreadPool. Until this call, a constructed ThreadPool + * launches no threads. That permits coders to derive from ThreadPool, + * or store it as a member of some other class, but refrain from + * launching it until all other construction is complete. + */ + void start(); + + /** + * ThreadPool listens for application shutdown messages on the "LLApp" + * LLEventPump. Call close() to shut down this ThreadPool early. + */ + void close(); + + std::string getName() const { return mName; } + size_t getWidth() const { return mThreads.size(); } + /// obtain a non-const reference to the WorkQueue to post work to it + WorkQueue& getQueue() { return mQueue; } + + /** + * Override run() if you need special processing. The default run() + * implementation simply calls WorkQueue::runUntilClose(). + */ + virtual void run(); + + private: + void run(const std::string& name); + + WorkQueue mQueue; + std::string mName; + size_t mThreadCount; + std::vector<std::pair<std::string, std::thread>> mThreads; + }; + +} // namespace LL + +#endif /* ! defined(LL_THREADPOOL_H) */ diff --git a/indra/llcommon/threadsafeschedule.h b/indra/llcommon/threadsafeschedule.h new file mode 100644 index 0000000000000000000000000000000000000000..3e0da94c0278054c894f248bf613ee222f55de00 --- /dev/null +++ b/indra/llcommon/threadsafeschedule.h @@ -0,0 +1,399 @@ +/** + * @file threadsafeschedule.h + * @author Nat Goodspeed + * @date 2021-10-02 + * @brief ThreadSafeSchedule is an ordered queue in which every item has an + * associated timestamp. + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$ + * Copyright (c) 2021, Linden Research, Inc. + * $/LicenseInfo$ + */ + +#if ! defined(LL_THREADSAFESCHEDULE_H) +#define LL_THREADSAFESCHEDULE_H + +#include "chrono.h" +#include "llexception.h" +#include "llthreadsafequeue.h" +#include "tuple.h" +#include <chrono> +#include <tuple> + +namespace LL +{ + namespace ThreadSafeSchedulePrivate + { + using TimePoint = std::chrono::steady_clock::time_point; + // Bundle consumer's data with a TimePoint to order items by timestamp. + template <typename... Args> + using TimestampedTuple = std::tuple<TimePoint, Args...>; + + // comparison functor for TimedTuples -- see TimedQueue comments + struct ReverseTupleOrder + { + template <typename Tuple> + bool operator()(const Tuple& left, const Tuple& right) const + { + return std::get<0>(left) > std::get<0>(right); + } + }; + + template <typename... Args> + using TimedQueue = PriorityQueueAdapter< + TimestampedTuple<Args...>, + // std::vector is the default storage for std::priority_queue, + // have to restate to specify comparison template parameter + std::vector<TimestampedTuple<Args...>>, + // std::priority_queue uses a counterintuitive comparison + // behavior: the default std::less comparator is used to present + // the *highest* value as top(). So to sort by earliest timestamp, + // we must invert by using >. + ReverseTupleOrder>; + } // namespace ThreadSafeSchedulePrivate + + /** + * ThreadSafeSchedule is an ordered LLThreadSafeQueue in which every item + * is given an associated timestamp. That is, TimePoint is implicitly + * prepended to the std::tuple with the specified types. + * + * Items are popped in increasing chronological order. Moreover, any item + * with a timestamp in the future is held back until + * std::chrono::steady_clock reaches that timestamp. + */ + template <typename... Args> + class ThreadSafeSchedule: + public LLThreadSafeQueue<ThreadSafeSchedulePrivate::TimestampedTuple<Args...>, + ThreadSafeSchedulePrivate::TimedQueue<Args...>> + { + public: + using DataTuple = std::tuple<Args...>; + using TimeTuple = ThreadSafeSchedulePrivate::TimestampedTuple<Args...>; + + private: + using super = LLThreadSafeQueue<TimeTuple, ThreadSafeSchedulePrivate::TimedQueue<Args...>>; + using lock_t = typename super::lock_t; + // VS 2017 needs this due to a bug: + // https://developercommunity.visualstudio.com/t/cannot-access-protected-enumerator-of-enclosing-cl/203430 + enum pop_result { EMPTY=super::EMPTY, DONE=super::DONE, WAITING=super::WAITING, POPPED=super::POPPED }; + + public: + using Closed = LLThreadSafeQueueInterrupt; + using TimePoint = ThreadSafeSchedulePrivate::TimePoint; + using Clock = TimePoint::clock; + + ThreadSafeSchedule(U32 capacity=1024): + super(capacity) + {} + + /*----------------------------- push() -----------------------------*/ + /// explicitly pass TimeTuple + using super::push; + + /// pass DataTuple with implicit now + // This could be ambiguous for Args with a single type. Unfortunately + // we can't enable_if an individual method with a condition based on + // the *class* template arguments, only on that method's template + // arguments. We could specialize this class for the single-Args case; + // we could minimize redundancy by breaking out a common base class... + void push(const DataTuple& tuple) + { + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; + push(tuple_cons(Clock::now(), tuple)); + } + + /// individually pass each component of the TimeTuple + void push(const TimePoint& time, Args&&... args) + { + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; + push(TimeTuple(time, std::forward<Args>(args)...)); + } + + /// individually pass every component except the TimePoint (implies now) + // This could be ambiguous if the first specified template parameter + // type is also TimePoint. We could try to disambiguate, but a simpler + // approach would be for the caller to explicitly construct DataTuple + // and call that overload. + void push(Args&&... args) + { + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; + push(Clock::now(), std::forward<Args>(args)...); + } + + /*--------------------------- tryPush() ----------------------------*/ + /// explicit TimeTuple + using super::tryPush; + + /// DataTuple with implicit now + bool tryPush(const DataTuple& tuple) + { + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; + return tryPush(tuple_cons(Clock::now(), tuple)); + } + + /// individually pass components + bool tryPush(const TimePoint& time, Args&&... args) + { + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; + return tryPush(TimeTuple(time, std::forward<Args>(args)...)); + } + + /// individually pass components with implicit now + bool tryPush(Args&&... args) + { + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; + return tryPush(Clock::now(), std::forward<Args>(args)...); + } + + /*-------------------------- tryPushFor() --------------------------*/ + /// explicit TimeTuple + using super::tryPushFor; + + /// DataTuple with implicit now + template <typename Rep, typename Period> + bool tryPushFor(const std::chrono::duration<Rep, Period>& timeout, + const DataTuple& tuple) + { + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; + return tryPushFor(timeout, tuple_cons(Clock::now(), tuple)); + } + + /// individually pass components + template <typename Rep, typename Period> + bool tryPushFor(const std::chrono::duration<Rep, Period>& timeout, + const TimePoint& time, Args&&... args) + { + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; + return tryPushFor(TimeTuple(time, std::forward<Args>(args)...)); + } + + /// individually pass components with implicit now + template <typename Rep, typename Period> + bool tryPushFor(const std::chrono::duration<Rep, Period>& timeout, + Args&&... args) + { + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; + return tryPushFor(Clock::now(), std::forward<Args>(args)...); + } + + /*------------------------- tryPushUntil() -------------------------*/ + /// explicit TimeTuple + using super::tryPushUntil; + + /// DataTuple with implicit now + template <typename Clock, typename Duration> + bool tryPushUntil(const std::chrono::time_point<Clock, Duration>& until, + const DataTuple& tuple) + { + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; + return tryPushUntil(until, tuple_cons(Clock::now(), tuple)); + } + + /// individually pass components + template <typename Clock, typename Duration> + bool tryPushUntil(const std::chrono::time_point<Clock, Duration>& until, + const TimePoint& time, Args&&... args) + { + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; + return tryPushUntil(until, TimeTuple(time, std::forward<Args>(args)...)); + } + + /// individually pass components with implicit now + template <typename Clock, typename Duration> + bool tryPushUntil(const std::chrono::time_point<Clock, Duration>& until, + Args&&... args) + { + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; + return tryPushUntil(until, Clock::now(), std::forward<Args>(args)...); + } + + /*----------------------------- pop() ------------------------------*/ + // Our consumer may or may not care about the timestamp associated + // with each popped item, so we allow retrieving either DataTuple or + // TimeTuple. One potential use would be to observe, and possibly + // adjust for, the time lag between the item time and the actual + // current time. + + /// pop DataTuple by value + // It would be great to notice when sizeof...(Args) == 1 and directly + // return the first (only) value, instead of making pop()'s caller + // call std::get<0>(value). See push(DataTuple) remarks for why we + // haven't yet jumped through those hoops. + DataTuple pop() + { + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; + return tuple_cdr(popWithTime()); + } + + /// pop TimeTuple by value + TimeTuple popWithTime() + { + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; + lock_t lock(super::mLock); + // We can't just sit around waiting forever, given that there may + // be items in the queue that are not yet ready but will *become* + // ready in the near future. So in fact, with this class, every + // pop() becomes a tryPopUntil(), constrained to the timestamp of + // the head item. It almost doesn't matter what we specify for the + // caller's time constraint -- all we really care about is the + // head item's timestamp. Since pop() and popWithTime() are + // defined to wait until either an item becomes available or the + // queue is closed, loop until one of those things happens. The + // constraint we pass just determines how often we'll loop while + // waiting. + TimeTuple tt; + while (true) + { + // Pick a point suitably far into the future. + TimePoint until = TimePoint::clock::now() + std::chrono::hours(24); + pop_result popped = tryPopUntil_(lock, until, tt); + if (popped == POPPED) + return std::move(tt); + + // DONE: throw, just as super::pop() does + if (popped == DONE) + { + LLTHROW(LLThreadSafeQueueInterrupt()); + } + // WAITING: we've still got items to drain. + // EMPTY: not closed, so it's worth waiting for more items. + // Either way, loop back to wait. + } + } + + // We can use tryPop(TimeTuple&) just as it stands; the only behavior + // difference is in our canPop() override method. + using super::tryPop; + + /// tryPop(DataTuple&) + bool tryPop(DataTuple& tuple) + { + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; + TimeTuple tt; + if (! super::tryPop(tt)) + return false; + tuple = tuple_cdr(std::move(tt)); + return true; + } + + /// for when Args has exactly one type + bool tryPop(typename std::tuple_element<1, TimeTuple>::type& value) + { + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; + TimeTuple tt; + if (! super::tryPop(tt)) + return false; + value = std::get<1>(std::move(tt)); + return true; + } + + /// tryPopFor() + template <typename Rep, typename Period, typename Tuple> + bool tryPopFor(const std::chrono::duration<Rep, Period>& timeout, Tuple& tuple) + { + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; + // It's important to use OUR tryPopUntil() implementation, rather + // than delegating immediately to our base class. + return tryPopUntil(Clock::now() + timeout, tuple); + } + + /// tryPopUntil(TimeTuple&) + template <typename Clock, typename Duration> + bool tryPopUntil(const std::chrono::time_point<Clock, Duration>& until, + TimeTuple& tuple) + { + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; + // super::tryPopUntil() wakes up when an item becomes available or + // we hit 'until', whichever comes first. Thing is, the current + // head of the queue could become ready sooner than either of + // those events, and we need to deliver it as soon as it does. + // Don't wait past the TimePoint of the head item. + // Naturally, lock the queue before peeking at mStorage. + return super::tryLockUntil( + until, + [this, until, &tuple](lock_t& lock) + { + // Use our time_point_cast to allow for 'until' that's a + // time_point type other than TimePoint. + return POPPED == + tryPopUntil_(lock, LL::time_point_cast<TimePoint>(until), tuple); + }); + } + + pop_result tryPopUntil_(lock_t& lock, const TimePoint& until, TimeTuple& tuple) + { + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; + TimePoint adjusted = until; + if (! super::mStorage.empty()) + { + LL_PROFILE_ZONE_NAMED("tpu - adjust"); + // use whichever is earlier: the head item's timestamp, or + // the caller's limit + adjusted = min(std::get<0>(super::mStorage.front()), adjusted); + } + // now delegate to base-class tryPopUntil_() + pop_result popped; + { + LL_PROFILE_ZONE_NAMED("tpu - super"); + while ((popped = pop_result(super::tryPopUntil_(lock, adjusted, tuple))) == WAITING) + { + // If super::tryPopUntil_() returns WAITING, it means there's + // a head item, but it's not yet time. But it's worth looping + // back to recheck. + } + } + return popped; + } + + /// tryPopUntil(DataTuple&) + template <typename Clock, typename Duration> + bool tryPopUntil(const std::chrono::time_point<Clock, Duration>& until, + DataTuple& tuple) + { + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; + TimeTuple tt; + if (! tryPopUntil(until, tt)) + return false; + tuple = tuple_cdr(std::move(tt)); + return true; + } + + /// for when Args has exactly one type + template <typename Clock, typename Duration> + bool tryPopUntil(const std::chrono::time_point<Clock, Duration>& until, + typename std::tuple_element<1, TimeTuple>::type& value) + { + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; + TimeTuple tt; + if (! tryPopUntil(until, tt)) + return false; + value = std::get<1>(std::move(tt)); + return true; + } + + /*------------------------------ etc. ------------------------------*/ + // We can't hide items that aren't yet ready because we can't traverse + // the underlying priority_queue: it has no iterators, only top(). So + // a consumer could observe size() > 0 and yet tryPop() returns false. + // Shrug, in a multi-consumer scenario that would be expected behavior. + using super::size; + // open/closed state + using super::close; + using super::isClosed; + using super::done; + + private: + // this method is called by base class pop_() every time we're + // considering whether to deliver the current head element + bool canPop(const TimeTuple& head) const override + { + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; + // an item with a future timestamp isn't yet ready to pop + // (should we add some slop for overhead?) + return std::get<0>(head) <= Clock::now(); + } + }; + +} // namespace LL + +#endif /* ! defined(LL_THREADSAFESCHEDULE_H) */ diff --git a/indra/llcommon/tuple.h b/indra/llcommon/tuple.h new file mode 100644 index 0000000000000000000000000000000000000000..bfe7e3c2bad434a3e575fd75015597486c3e3141 --- /dev/null +++ b/indra/llcommon/tuple.h @@ -0,0 +1,84 @@ +/** + * @file tuple.h + * @author Nat Goodspeed + * @date 2021-10-04 + * @brief A couple tuple utilities + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$ + * Copyright (c) 2021, Linden Research, Inc. + * $/LicenseInfo$ + */ + +#if ! defined(LL_TUPLE_H) +#define LL_TUPLE_H + +#include <tuple> +#include <type_traits> // std::remove_reference +#include <utility> // std::pair + +/** + * tuple_cons() behaves like LISP cons: it uses std::tuple_cat() to prepend a + * new item of arbitrary type to an existing std::tuple. + */ +template <typename First, typename... Rest, typename Tuple_=std::tuple<Rest...>> +auto tuple_cons(First&& first, Tuple_&& rest) +{ + // All we need to do is make a tuple containing 'first', and let + // tuple_cat() do the hard part. + return std::tuple_cat(std::tuple<First>(std::forward<First>(first)), + std::forward<Tuple_>(rest)); +} + +/** + * tuple_car() behaves like LISP car: it extracts the first item from a + * std::tuple. + */ +template <typename... Args, typename Tuple_=std::tuple<Args...>> +auto tuple_car(Tuple_&& tuple) +{ + return std::get<0>(std::forward<Tuple_>(tuple)); +} + +/** + * tuple_cdr() behaves like LISP cdr: it returns a new tuple containing + * everything BUT the first item. + */ +// derived from https://stackoverflow.com/a/24046437 +template <typename Tuple, std::size_t... Indices> +auto tuple_cdr_(Tuple&& tuple, const std::index_sequence<Indices...>) +{ + // Given an index sequence from [0..N-1), extract tuple items [1..N) + return std::make_tuple(std::get<Indices+1u>(std::forward<Tuple>(tuple))...); +} + +template <typename Tuple> +auto tuple_cdr(Tuple&& tuple) +{ + return tuple_cdr_( + std::forward<Tuple>(tuple), + // Pass helper function an index sequence one item shorter than tuple + std::make_index_sequence< + std::tuple_size< + // tuple_size doesn't like reference types + typename std::remove_reference<Tuple>::type + >::value - 1u> + ()); +} + +/** + * tuple_split(), the opposite of tuple_cons(), has no direct analog in LISP. + * It returns a std::pair of tuple_car(), tuple_cdr(). We could call this + * function tuple_car_cdr(), or tuple_slice() or some such. But tuple_split() + * feels more descriptive. + */ +template <typename... Args, typename Tuple_=std::tuple<Args...>> +auto tuple_split(Tuple_&& tuple) +{ + // We're not really worried about forwarding multiple times a tuple that + // might contain move-only items, because the implementation above only + // applies std::get() exactly once to each item. + return std::make_pair(tuple_car(std::forward<Tuple_>(tuple)), + tuple_cdr(std::forward<Tuple_>(tuple))); +} + +#endif /* ! defined(LL_TUPLE_H) */ diff --git a/indra/llcommon/workqueue.cpp b/indra/llcommon/workqueue.cpp new file mode 100644 index 0000000000000000000000000000000000000000..eb06890468b7ae73b874fe7bd6d75c57354bee53 --- /dev/null +++ b/indra/llcommon/workqueue.cpp @@ -0,0 +1,158 @@ +/** + * @file workqueue.cpp + * @author Nat Goodspeed + * @date 2021-10-06 + * @brief Implementation for WorkQueue. + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$ + * Copyright (c) 2021, Linden Research, Inc. + * $/LicenseInfo$ + */ + +// Precompiled header +#include "linden_common.h" +// associated header +#include "workqueue.h" +// STL headers +// std headers +// external library headers +// other Linden headers +#include "llcoros.h" +#include LLCOROS_MUTEX_HEADER +#include "llerror.h" +#include "llexception.h" +#include "stringize.h" + +using Mutex = LLCoros::Mutex; +using Lock = LLCoros::LockType; + +LL::WorkQueue::WorkQueue(const std::string& name, size_t capacity): + super(makeName(name)), + mQueue(capacity) +{ + // TODO: register for "LLApp" events so we can implicitly close() on + // viewer shutdown. +} + +void LL::WorkQueue::close() +{ + mQueue.close(); +} + +size_t LL::WorkQueue::size() +{ + return mQueue.size(); +} + +bool LL::WorkQueue::isClosed() +{ + return mQueue.isClosed(); +} + +bool LL::WorkQueue::done() +{ + return mQueue.done(); +} + +void LL::WorkQueue::runUntilClose() +{ + try + { + for (;;) + { + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; + callWork(mQueue.pop()); + } + } + catch (const Queue::Closed&) + { + } +} + +bool LL::WorkQueue::runPending() +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; + for (Work work; mQueue.tryPop(work); ) + { + callWork(work); + } + return ! mQueue.done(); +} + +bool LL::WorkQueue::runOne() +{ + Work work; + if (mQueue.tryPop(work)) + { + callWork(work); + } + return ! mQueue.done(); +} + +bool LL::WorkQueue::runUntil(const TimePoint& until) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; + // Should we subtract some slop to allow for typical Work execution time? + // How much slop? + // runUntil() is simply a time-bounded runPending(). + for (Work work; TimePoint::clock::now() < until && mQueue.tryPop(work); ) + { + callWork(work); + } + return ! mQueue.done(); +} + +std::string LL::WorkQueue::makeName(const std::string& name) +{ + if (! name.empty()) + return name; + + static U32 discriminator = 0; + static Mutex mutex; + U32 num; + { + // Protect discriminator from concurrent access by different threads. + // It can't be thread_local, else two racing threads will come up with + // the same name. + Lock lk(mutex); + num = discriminator++; + } + return STRINGIZE("WorkQueue" << num); +} + +void LL::WorkQueue::callWork(const Queue::DataTuple& work) +{ + // ThreadSafeSchedule::pop() always delivers a tuple, even when + // there's only one data field per item, as for us. + callWork(std::get<0>(work)); +} + +void LL::WorkQueue::callWork(const Work& work) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; + try + { + work(); + } + catch (...) + { + // No matter what goes wrong with any individual work item, the worker + // thread must go on! Log our own instance name with the exception. + LOG_UNHANDLED_EXCEPTION(getKey()); + } +} + +void LL::WorkQueue::error(const std::string& msg) +{ + LL_ERRS("WorkQueue") << msg << LL_ENDL; +} + +void LL::WorkQueue::checkCoroutine(const std::string& method) +{ + // By convention, the default coroutine on each thread has an empty name + // string. See also LLCoros::logname(). + if (LLCoros::getName().empty()) + { + LLTHROW(Error("Do not call " + method + " from a thread's default coroutine")); + } +} diff --git a/indra/llcommon/workqueue.h b/indra/llcommon/workqueue.h new file mode 100644 index 0000000000000000000000000000000000000000..70fd65bd0cd71c1f6e5c9dd86639f45ef7c4cb5f --- /dev/null +++ b/indra/llcommon/workqueue.h @@ -0,0 +1,574 @@ +/** + * @file workqueue.h + * @author Nat Goodspeed + * @date 2021-09-30 + * @brief Queue used for inter-thread work passing. + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$ + * Copyright (c) 2021, Linden Research, Inc. + * $/LicenseInfo$ + */ + +#if ! defined(LL_WORKQUEUE_H) +#define LL_WORKQUEUE_H + +#include "llcoros.h" +#include "llexception.h" +#include "llinstancetracker.h" +#include "threadsafeschedule.h" +#include <chrono> +#include <exception> // std::current_exception +#include <functional> // std::function +#include <string> + +namespace LL +{ + /** + * A typical WorkQueue has a string name that can be used to find it. + */ + class WorkQueue: public LLInstanceTracker<WorkQueue, std::string> + { + private: + using super = LLInstanceTracker<WorkQueue, std::string>; + + public: + using Work = std::function<void()>; + + private: + using Queue = ThreadSafeSchedule<Work>; + // helper for postEvery() + template <typename Rep, typename Period, typename CALLABLE> + class BackJack; + + public: + using TimePoint = Queue::TimePoint; + using TimedWork = Queue::TimeTuple; + using Closed = Queue::Closed; + + struct Error: public LLException + { + Error(const std::string& what): LLException(what) {} + }; + + /** + * You may omit the WorkQueue name, in which case a unique name is + * synthesized; for practical purposes that makes it anonymous. + */ + WorkQueue(const std::string& name = std::string(), size_t capacity=1024); + + /** + * Since the point of WorkQueue is to pass work to some other worker + * thread(s) asynchronously, it's important that the WorkQueue continue + * to exist until the worker thread(s) have drained it. To communicate + * that it's time for them to quit, close() the queue. + */ + void close(); + + /** + * WorkQueue supports multiple producers and multiple consumers. In + * the general case it's misleading to test size(), since any other + * thread might change it the nanosecond the lock is released. On that + * basis, some might argue against publishing a size() method at all. + * + * But there are two specific cases in which a test based on size() + * might be reasonable: + * + * * If you're the only producer, noticing that size() == 0 is + * meaningful. + * * If you're the only consumer, noticing that size() > 0 is + * meaningful. + */ + size_t size(); + /// producer end: are we prevented from pushing any additional items? + bool isClosed(); + /// consumer end: are we done, is the queue entirely drained? + bool done(); + + /*---------------------- fire and forget API -----------------------*/ + + /// fire-and-forget, but at a particular (future?) time + template <typename CALLABLE> + void post(const TimePoint& time, CALLABLE&& callable) + { + // Defer reifying an arbitrary CALLABLE until we hit this or + // postIfOpen(). All other methods should accept CALLABLEs of + // arbitrary type to avoid multiple levels of std::function + // indirection. + mQueue.push(TimedWork(time, std::move(callable))); + } + + /// fire-and-forget + template <typename CALLABLE> + void post(CALLABLE&& callable) + { + // We use TimePoint::clock::now() instead of TimePoint's + // representation of the epoch because this WorkQueue may contain + // a mix of past-due TimedWork items and TimedWork items scheduled + // for the future. Sift this new item into the correct place. + post(TimePoint::clock::now(), std::move(callable)); + } + + /** + * post work for a particular time, unless the queue is closed before + * we can post + */ + template <typename CALLABLE> + bool postIfOpen(const TimePoint& time, CALLABLE&& callable) + { + // Defer reifying an arbitrary CALLABLE until we hit this or + // post(). All other methods should accept CALLABLEs of arbitrary + // type to avoid multiple levels of std::function indirection. + return mQueue.pushIfOpen(TimedWork(time, std::move(callable))); + } + + /** + * post work, unless the queue is closed before we can post + */ + template <typename CALLABLE> + bool postIfOpen(CALLABLE&& callable) + { + return postIfOpen(TimePoint::clock::now(), std::move(callable)); + } + + /** + * Post work to be run at a specified time to another WorkQueue, which + * may or may not still exist and be open. Return true if we were able + * to post. + */ + template <typename CALLABLE> + static bool postMaybe(weak_t target, const TimePoint& time, CALLABLE&& callable); + + /** + * Post work to another WorkQueue, which may or may not still exist + * and be open. Return true if we were able to post. + */ + template <typename CALLABLE> + static bool postMaybe(weak_t target, CALLABLE&& callable) + { + return postMaybe(target, TimePoint::clock::now(), + std::forward<CALLABLE>(callable)); + } + + /** + * Launch a callable returning bool that will trigger repeatedly at + * specified interval, until the callable returns false. + * + * If you need to signal that callable from outside, DO NOT bind a + * reference to a simple bool! That's not thread-safe. Instead, bind + * an LLCond variant, e.g. LLOneShotCond or LLBoolCond. + */ + template <typename Rep, typename Period, typename CALLABLE> + void postEvery(const std::chrono::duration<Rep, Period>& interval, + CALLABLE&& callable); + + template <typename CALLABLE> + bool tryPost(CALLABLE&& callable) + { + return mQueue.tryPush(TimedWork(TimePoint::clock::now(), std::move(callable))); + } + + /*------------------------- handshake API --------------------------*/ + + /** + * Post work to another WorkQueue to be run at a specified time, + * requesting a specific callback to be run on this WorkQueue on + * completion. + * + * Returns true if able to post, false if the other WorkQueue is + * inaccessible. + */ + // Apparently some Microsoft header file defines a macro CALLBACK? The + // natural template argument name CALLBACK produces very weird Visual + // Studio compile errors that seem utterly unrelated to this source + // code. + template <typename CALLABLE, typename FOLLOWUP> + bool postTo(weak_t target, + const TimePoint& time, CALLABLE&& callable, FOLLOWUP&& callback); + + /** + * Post work to another WorkQueue, requesting a specific callback to + * be run on this WorkQueue on completion. + * + * Returns true if able to post, false if the other WorkQueue is + * inaccessible. + */ + template <typename CALLABLE, typename FOLLOWUP> + bool postTo(weak_t target, CALLABLE&& callable, FOLLOWUP&& callback) + { + return postTo(target, TimePoint::clock::now(), + std::move(callable), std::move(callback)); + } + + /** + * Post work to another WorkQueue to be run at a specified time, + * blocking the calling coroutine until then, returning the result to + * caller on completion. + * + * In general, we assume that each thread's default coroutine is busy + * servicing its WorkQueue or whatever. To try to prevent mistakes, we + * forbid calling waitForResult() from a thread's default coroutine. + */ + template <typename CALLABLE> + auto waitForResult(const TimePoint& time, CALLABLE&& callable); + + /** + * Post work to another WorkQueue, blocking the calling coroutine + * until then, returning the result to caller on completion. + * + * In general, we assume that each thread's default coroutine is busy + * servicing its WorkQueue or whatever. To try to prevent mistakes, we + * forbid calling waitForResult() from a thread's default coroutine. + */ + template <typename CALLABLE> + auto waitForResult(CALLABLE&& callable) + { + return waitForResult(TimePoint::clock::now(), std::move(callable)); + } + + /*--------------------------- worker API ---------------------------*/ + + /** + * runUntilClose() pulls TimedWork items off this WorkQueue until the + * queue is closed, at which point it returns. This would be the + * typical entry point for a simple worker thread. + */ + void runUntilClose(); + + /** + * runPending() runs all TimedWork items that are ready to run. It + * returns true if the queue remains open, false if the queue has been + * closed. This could be used by a thread whose primary purpose is to + * serve the queue, but also wants to do other things with its idle time. + */ + bool runPending(); + + /** + * runOne() runs at most one ready TimedWork item -- zero if none are + * ready. It returns true if the queue remains open, false if the + * queue has been closed. + */ + bool runOne(); + + /** + * runFor() runs a subset of ready TimedWork items, until the + * timeslice has been exceeded. It returns true if the queue remains + * open, false if the queue has been closed. This could be used by a + * busy main thread to lend a bounded few CPU cycles to this WorkQueue + * without risking the WorkQueue blowing out the length of any one + * frame. + */ + template <typename Rep, typename Period> + bool runFor(const std::chrono::duration<Rep, Period>& timeslice) + { + LL_PROFILE_ZONE_SCOPED; + return runUntil(TimePoint::clock::now() + timeslice); + } + + /** + * runUntil() is just like runFor(), only with a specific end time + * instead of a timeslice duration. + */ + bool runUntil(const TimePoint& until); + + private: + template <typename CALLABLE, typename FOLLOWUP> + static auto makeReplyLambda(CALLABLE&& callable, FOLLOWUP&& callback); + /// general case: arbitrary C++ return type + template <typename CALLABLE, typename FOLLOWUP, typename RETURNTYPE> + struct MakeReplyLambda; + /// specialize for CALLABLE returning void + template <typename CALLABLE, typename FOLLOWUP> + struct MakeReplyLambda<CALLABLE, FOLLOWUP, void>; + + /// general case: arbitrary C++ return type + template <typename CALLABLE, typename RETURNTYPE> + struct WaitForResult; + /// specialize for CALLABLE returning void + template <typename CALLABLE> + struct WaitForResult<CALLABLE, void>; + + static void checkCoroutine(const std::string& method); + static void error(const std::string& msg); + static std::string makeName(const std::string& name); + void callWork(const Queue::DataTuple& work); + void callWork(const Work& work); + Queue mQueue; + }; + + /** + * BackJack is, in effect, a hand-rolled lambda, binding a WorkQueue, a + * CALLABLE that returns bool, a TimePoint and an interval at which to + * relaunch it. As long as the callable continues returning true, BackJack + * keeps resubmitting it to the target WorkQueue. + */ + // Why is BackJack a class and not a lambda? Because, unlike a lambda, a + // class method gets its own 'this' pointer -- which we need to resubmit + // the whole BackJack callable. + template <typename Rep, typename Period, typename CALLABLE> + class WorkQueue::BackJack + { + public: + // bind the desired data + BackJack(weak_t target, + const TimePoint& start, + const std::chrono::duration<Rep, Period>& interval, + CALLABLE&& callable): + mTarget(target), + mStart(start), + mInterval(interval), + mCallable(std::move(callable)) + {} + + // Call by target WorkQueue -- note that although WE require a + // callable returning bool, WorkQueue wants a void callable. We + // consume the bool. + void operator()() + { + // If mCallable() throws an exception, don't catch it here: if it + // throws once, it's likely to throw every time, so it's a waste + // of time to arrange to call it again. + if (mCallable()) + { + // Modify mStart to the new start time we desire. If we simply + // added mInterval to now, we'd get actual timings of + // (mInterval + slop), where 'slop' is the latency between the + // previous mStart and the WorkQueue actually calling us. + // Instead, add mInterval to mStart so that at least we + // register our intent to fire at exact mIntervals. + mStart += mInterval; + + // We're being called at this moment by the target WorkQueue. + // Assume it still exists, rather than checking the result of + // lock(). + // Resubmit the whole *this callable: that's why we're a class + // rather than a lambda. Allow moving *this so we can carry a + // move-only callable; but naturally this statement must be + // the last time we reference this instance, which may become + // moved-from. + try + { + mTarget.lock()->post(mStart, std::move(*this)); + } + catch (const Closed&) + { + // Once this queue is closed, oh well, just stop + } + } + } + + private: + weak_t mTarget; + TimePoint mStart; + std::chrono::duration<Rep, Period> mInterval; + CALLABLE mCallable; + }; + + template <typename Rep, typename Period, typename CALLABLE> + void WorkQueue::postEvery(const std::chrono::duration<Rep, Period>& interval, + CALLABLE&& callable) + { + if (interval.count() <= 0) + { + // It's essential that postEvery() be called with a positive + // interval, since each call to BackJack posts another instance of + // itself at (start + interval) and we order by target time. A + // zero or negative interval would result in that BackJack + // instance going to the head of the queue every time, immediately + // ready to run. Effectively that would produce an infinite loop, + // a denial of service on this WorkQueue. + error("postEvery(interval) may not be 0"); + } + // Instantiate and post a suitable BackJack, binding a weak_ptr to + // self, the current time, the desired interval and the desired + // callable. + post( + BackJack<Rep, Period, CALLABLE>( + getWeak(), TimePoint::clock::now(), interval, std::move(callable))); + } + + /// general case: arbitrary C++ return type + template <typename CALLABLE, typename FOLLOWUP, typename RETURNTYPE> + struct WorkQueue::MakeReplyLambda + { + auto operator()(CALLABLE&& callable, FOLLOWUP&& callback) + { + // Call the callable in any case -- but to minimize + // copying the result, immediately bind it into the reply + // lambda. The reply lambda also binds the original + // callback, so that when we, the originating WorkQueue, + // finally receive and process the reply lambda, we'll + // call the bound callback with the bound result -- on the + // same thread that originally called postTo(). + return + [result = std::forward<CALLABLE>(callable)(), + callback = std::move(callback)] + () + mutable { callback(std::move(result)); }; + } + }; + + /// specialize for CALLABLE returning void + template <typename CALLABLE, typename FOLLOWUP> + struct WorkQueue::MakeReplyLambda<CALLABLE, FOLLOWUP, void> + { + auto operator()(CALLABLE&& callable, FOLLOWUP&& callback) + { + // Call the callable, which produces no result. + std::forward<CALLABLE>(callable)(); + // Our completion callback is simply the caller's callback. + return std::move(callback); + } + }; + + template <typename CALLABLE, typename FOLLOWUP> + auto WorkQueue::makeReplyLambda(CALLABLE&& callable, FOLLOWUP&& callback) + { + return MakeReplyLambda<CALLABLE, FOLLOWUP, + decltype(std::forward<CALLABLE>(callable)())>() + (std::move(callable), std::move(callback)); + } + + template <typename CALLABLE, typename FOLLOWUP> + bool WorkQueue::postTo(weak_t target, + const TimePoint& time, CALLABLE&& callable, FOLLOWUP&& callback) + { + LL_PROFILE_ZONE_SCOPED; + // We're being asked to post to the WorkQueue at target. + // target is a weak_ptr: have to lock it to check it. + auto tptr = target.lock(); + if (! tptr) + // can't post() if the target WorkQueue has been destroyed + return false; + + // Here we believe target WorkQueue still exists. Post to it a + // lambda that packages our callable, our callback and a weak_ptr + // to this originating WorkQueue. + tptr->post( + time, + [reply = super::getWeak(), + callable = std::move(callable), + callback = std::move(callback)] + () + mutable { + // Use postMaybe() below in case this originating WorkQueue + // has been closed or destroyed. Remember, the outer lambda is + // now running on a thread servicing the target WorkQueue, and + // real time has elapsed since postTo()'s tptr->post() call. + try + { + // Make a reply lambda to repost to THIS WorkQueue. + // Delegate to makeReplyLambda() so we can partially + // specialize on void return. + postMaybe(reply, makeReplyLambda(std::move(callable), std::move(callback))); + } + catch (...) + { + // Either variant of makeReplyLambda() is responsible for + // calling the caller's callable. If that throws, return + // the exception to the originating thread. + postMaybe( + reply, + // Bind the current exception to transport back to the + // originating WorkQueue. Once there, rethrow it. + [exc = std::current_exception()](){ std::rethrow_exception(exc); }); + } + }); + + // looks like we were able to post() + return true; + } + + template <typename CALLABLE> + bool WorkQueue::postMaybe(weak_t target, const TimePoint& time, CALLABLE&& callable) + { + LL_PROFILE_ZONE_SCOPED; + // target is a weak_ptr: have to lock it to check it + auto tptr = target.lock(); + if (tptr) + { + try + { + tptr->post(time, std::forward<CALLABLE>(callable)); + // we were able to post() + return true; + } + catch (const Closed&) + { + // target WorkQueue still exists, but is Closed + } + } + // either target no longer exists, or its WorkQueue is Closed + return false; + } + + /// general case: arbitrary C++ return type + template <typename CALLABLE, typename RETURNTYPE> + struct WorkQueue::WaitForResult + { + auto operator()(WorkQueue* self, const TimePoint& time, CALLABLE&& callable) + { + LLCoros::Promise<RETURNTYPE> promise; + self->post( + time, + // We dare to bind a reference to Promise because it's + // specifically designed for cross-thread communication. + [&promise, callable = std::move(callable)]() + mutable { + try + { + // call the caller's callable and trigger promise with result + promise.set_value(callable()); + } + catch (...) + { + promise.set_exception(std::current_exception()); + } + }); + auto future{ LLCoros::getFuture(promise) }; + // now, on the calling thread, wait for that result + LLCoros::TempStatus st("waiting for WorkQueue::waitForResult()"); + return future.get(); + } + }; + + /// specialize for CALLABLE returning void + template <typename CALLABLE> + struct WorkQueue::WaitForResult<CALLABLE, void> + { + void operator()(WorkQueue* self, const TimePoint& time, CALLABLE&& callable) + { + LLCoros::Promise<void> promise; + self->post( + time, + // &promise is designed for cross-thread access + [&promise, callable = std::move(callable)]() + mutable { + try + { + callable(); + promise.set_value(); + } + catch (...) + { + promise.set_exception(std::current_exception()); + } + }); + auto future{ LLCoros::getFuture(promise) }; + // block until set_value() + LLCoros::TempStatus st("waiting for void WorkQueue::waitForResult()"); + future.get(); + } + }; + + template <typename CALLABLE> + auto WorkQueue::waitForResult(const TimePoint& time, CALLABLE&& callable) + { + checkCoroutine("waitForResult()"); + // derive callable's return type so we can specialize for void + return WaitForResult<CALLABLE, decltype(std::forward<CALLABLE>(callable)())>() + (this, time, std::forward<CALLABLE>(callable)); + } + +} // namespace LL + +#endif /* ! defined(LL_WORKQUEUE_H) */ diff --git a/indra/llcorehttp/CMakeLists.txt b/indra/llcorehttp/CMakeLists.txt index f3b74fa529f6cc442a873da8348884a57f84fbc5..97557d9c268a673b84c1f16de7a0538cbd7b1dd5 100644 --- a/indra/llcorehttp/CMakeLists.txt +++ b/indra/llcorehttp/CMakeLists.txt @@ -6,7 +6,7 @@ include(00-Common) include(CURL) include(OpenSSL) include(NGHTTP2) -include(ZLIB) +include(ZLIBNG) include(LLCoreHttp) include(LLAddBuildTest) include(LLMessage) diff --git a/indra/llcorehttp/httpcommon.cpp b/indra/llcorehttp/httpcommon.cpp index f3fd756de74eb424eba75a6a102c6a256b869e47..568b81e988edeed9396ab83b7e476b35953fb1ca 100644 --- a/indra/llcorehttp/httpcommon.cpp +++ b/indra/llcorehttp/httpcommon.cpp @@ -127,7 +127,7 @@ std::string HttpStatus::toString() const if (*this) { - return LLStringUtil::null; + return std::string(""); } switch (getType()) { @@ -309,9 +309,8 @@ CURL *getCurlTemplateHandle() LLMutex *getCurlMutex() { - static LLMutex sHandleMutexp(LLMutex::E_CONST_INIT); - - return &sHandleMutexp; + static LLMutex sHandleMutex; + return &sHandleMutex; } void deallocateEasyCurl(CURL *curlp) diff --git a/indra/llfilesystem/lldiskcache.cpp b/indra/llfilesystem/lldiskcache.cpp index dae794b71f91b108c2f75e167ba6b58687cae669..136a45cd3e611c5c87730b36a2eb764331a683db 100644 --- a/indra/llfilesystem/lldiskcache.cpp +++ b/indra/llfilesystem/lldiskcache.cpp @@ -151,6 +151,11 @@ void LLDiskCache::purge() LL_INFOS() << "Purging cache to a maximum of " << mMaxSizeBytes << " bytes" << LL_ENDL; // Extra accounting to track the retention of static assets + std::vector<bool> file_removed; + if (mEnableCacheDebugInfo) + { + file_removed.reserve(file_info.size()); + } int keep{0}; int del{0}; int skip{0}; @@ -159,9 +164,16 @@ void LLDiskCache::purge() { file_size_total += entry.second.first; + bool should_remove = file_size_total > mMaxSizeBytes; + if (mEnableCacheDebugInfo) + { + file_removed.push_back(should_remove); + } + std::string action = ""; - if (file_size_total > mMaxSizeBytes) + if (should_remove) { + action = "DELETE:"; auto uuid_as_string = LLUUID(gDirUtilp->getBaseFileName(entry.second.second.string(), true)); // LL_INFOS() << "checking UUID=" <<uuid_as_string<< LL_ENDL; @@ -187,11 +199,22 @@ void LLDiskCache::purge() else { keep++; - action = " KEEP:"; } + } - if (mEnableCacheDebugInfo) + if (mEnableCacheDebugInfo) + { + auto end_time = std::chrono::high_resolution_clock::now(); + auto execute_time = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time).count(); + + // Log afterward so it doesn't affect the time measurement + // Logging thousands of file results can take hundreds of milliseconds + for (size_t i = 0; i < file_info.size(); ++i) { + const file_info_t& entry = file_info[i]; + const bool removed = file_removed[i]; + const std::string action = removed ? "DELETE:" : "KEEP:"; + // have to do this because of LL_INFO/LL_END weirdness std::ostringstream line; @@ -202,12 +225,7 @@ void LLDiskCache::purge() line << " (" << file_size_total << "/" << mMaxSizeBytes << ")"; LL_INFOS() << line.str() << LL_ENDL; } - } - if (mEnableCacheDebugInfo) - { - auto end_time = std::chrono::high_resolution_clock::now(); - auto execute_time = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time).count(); LL_INFOS() << "Total dir size after purge is " << dirFileSize(sCacheDir) << LL_ENDL; LL_INFOS() << "Cache purge took " << execute_time << " ms to execute for " << file_info.size() << " files" << LL_ENDL; LL_INFOS() << "Deleted: " << del << " Skipped: " << skip << " Kept: " << keep << LL_ENDL; @@ -398,6 +416,38 @@ void LLDiskCache::clearCache() } } +void LLDiskCache::removeOldVFSFiles() +{ + //VFS files won't be created, so consider removing this code later + static const char CACHE_FORMAT[] = "inv.llsd"; + static const char DB_FORMAT[] = "db2.x"; + + boost::system::error_code ec; +#if LL_WINDOWS + std::wstring cache_path(ll_convert_string_to_wide(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""))); +#else + std::string cache_path(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "")); +#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), {})) + { + if (boost::filesystem::is_regular_file(entry, ec) && !ec.failed()) + { + if ((entry.path().string().find(CACHE_FORMAT) != std::string::npos) || + (entry.path().string().find(DB_FORMAT) != std::string::npos)) + { + boost::filesystem::remove(entry, ec); + if (ec.failed()) + { + LL_WARNS() << "Failed to delete cache file " << entry << ": " << ec.message() << LL_ENDL; + } + } + } + } + } +} + uintmax_t LLDiskCache::dirFileSize(const std::string dir) { uintmax_t total_file_size = 0; diff --git a/indra/llfilesystem/lldiskcache.h b/indra/llfilesystem/lldiskcache.h index bd38ffcfe560eb8bc9c7077692dea3f4d13ac2f9..315667ac2eb81bf5f3f3761920550c85ec46d4ac 100644 --- a/indra/llfilesystem/lldiskcache.h +++ b/indra/llfilesystem/lldiskcache.h @@ -144,6 +144,8 @@ class LLDiskCache final : */ const std::string getCacheInfo(); + void removeOldVFSFiles(); + private: /** * Utility function to gather the total size the files in a given diff --git a/indra/llimage/CMakeLists.txt b/indra/llimage/CMakeLists.txt index d21ffc626b24a04c8d6148145f83c4c49323deb2..0dbbcf11f5d7491efca3658897e7ad44a66528ba 100644 --- a/indra/llimage/CMakeLists.txt +++ b/indra/llimage/CMakeLists.txt @@ -10,7 +10,7 @@ include(LLFileSystem) include(LLKDU) include(LLImageJ2COJ) include(WebP) -include(ZLIB) +include(ZLIBNG) include(LLAddBuildTest) include(Tut) @@ -21,7 +21,7 @@ include_directories( ${LLFILESYSTEM_INCLUDE_DIRS} ${WEBP_INCLUDE_DIRS} ${PNG_INCLUDE_DIRS} - ${ZLIB_INCLUDE_DIRS} + ${ZLIBNG_INCLUDE_DIRS} ) set(llimage_SOURCE_FILES @@ -78,7 +78,7 @@ target_link_libraries(llimage ${WEBP_LIBRARIES} ${JPEG_LIBRARIES} ${PNG_LIBRARIES} - ${ZLIB_LIBRARIES} + ${ZLIBNG_LIBRARIES} readerwriterqueue ) diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp index b25336adf4f36d9111fa88a2593db066710c98b0..1182d3be814f14aab55b8c5717d19c8f37767919 100644 --- a/indra/llimage/llimage.cpp +++ b/indra/llimage/llimage.cpp @@ -586,7 +586,7 @@ static void bilinear_scale(const U8 *src, U32 srcW, U32 srcH, U32 srcCh, U32 src //static std::string LLImage::sLastErrorMessage; -LLMutex LLImage::sMutex(LLMutex::E_CONST_INIT); +LLMutex* LLImage::sMutex = NULL; bool LLImage::sUseNewByteRange = false; S32 LLImage::sMinimalReverseByteRangePercent = 75; @@ -595,11 +595,14 @@ void LLImage::initClass(bool use_new_byte_range, S32 minimal_reverse_byte_range_ { sUseNewByteRange = use_new_byte_range; sMinimalReverseByteRangePercent = minimal_reverse_byte_range_percent; + sMutex = new LLMutex(); } //static void LLImage::cleanupClass() { + delete sMutex; + sMutex = NULL; } //static @@ -612,7 +615,7 @@ const std::string& LLImage::getLastError() //static void LLImage::setLastError(const std::string& message) { - LLMutexLock m(&sMutex); + LLMutexLock m(sMutex); sLastErrorMessage = message; } @@ -621,8 +624,7 @@ void LLImage::setLastError(const std::string& message) //--------------------------------------------------------------------------- LLImageBase::LLImageBase() -: LLTrace::MemTrackable<LLImageBase>("LLImage"), - mData(NULL), +: mData(NULL), mDataSize(0), mWidth(0), mHeight(0), @@ -671,7 +673,6 @@ void LLImageBase::sanityCheck() void LLImageBase::deleteData() { ll_aligned_free_16(mData); - disclaimMem(mDataSize); mDataSize = 0; mData = NULL; } @@ -729,7 +730,6 @@ U8* LLImageBase::allocateData(S32 size) } } mDataSize = size; - claimMem(mDataSize); return mData; } @@ -750,9 +750,7 @@ U8* LLImageBase::reallocateData(S32 size) ll_aligned_free_16(mData) ; } mData = new_datap; - disclaimMem(mDataSize); mDataSize = size; - claimMem(mDataSize); mBadBufferAllocation = false; return mData; } @@ -863,6 +861,12 @@ U8* LLImageRaw::reallocateData(S32 size) return res; } +void LLImageRaw::releaseData() +{ + LLImageBase::setSize(0, 0, 0); + LLImageBase::setDataAndSize(nullptr, 0); +} + // virtual void LLImageRaw::deleteData() { @@ -881,8 +885,6 @@ void LLImageRaw::setDataAndSize(U8 *data, S32 width, S32 height, S8 components) LLImageBase::setSize(width, height, components) ; LLImageBase::setDataAndSize(data, width * height * components) ; - - sGlobalRawMemory += getDataSize(); } bool LLImageRaw::resize(U16 width, U16 height, S8 components) @@ -2253,9 +2255,7 @@ void LLImageBase::setDataAndSize(U8 *data, S32 size) { ll_assert_aligned(data, 16); mData = data; - disclaimMem(mDataSize); mDataSize = size; - claimMem(mDataSize); } //static diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h index 250125209030c2edc1c9f5b063e9bed749db38ac..6726d03cd5edd8755fd30d2f0078f7d24b553600 100644 --- a/indra/llimage/llimage.h +++ b/indra/llimage/llimage.h @@ -103,7 +103,7 @@ class LLImage static S32 getReverseByteRangePercent() { return sMinimalReverseByteRangePercent; } protected: - static LLMutex sMutex; + static LLMutex* sMutex; static std::string sLastErrorMessage; static bool sUseNewByteRange; static S32 sMinimalReverseByteRangePercent; @@ -113,8 +113,7 @@ class LLImage // Image base class class LLImageBase -: public LLThreadSafeRefCount, - public LLTrace::MemTrackable<LLImageBase> +: public LLThreadSafeRefCount { protected: virtual ~LLImageBase(); @@ -193,6 +192,12 @@ class LLImageRaw final : public LLImageBase /*virtual*/ void deleteData(); /*virtual*/ U8* allocateData(S32 size = -1); /*virtual*/ U8* reallocateData(S32 size); + + // use in conjunction with "no_copy" constructor to release data pointer before deleting + // so that deletion of this LLImageRaw will not free the memory at the "data" parameter + // provided to "no_copy" constructor + void releaseData(); + bool resize(U16 width, U16 height, S8 components); diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp index 30fbffe240bb6d88a2d6afec8f7de7946a83e81b..9fcf053730c5551d9d7517a6a16b7eb31c6c3c8d 100644 --- a/indra/llimage/llimagej2c.cpp +++ b/indra/llimage/llimagej2c.cpp @@ -59,7 +59,6 @@ LLImageJ2C::LLImageJ2C() : LLImageFormatted(IMG_CODEC_J2C), mAreaUsedForDataSizeCalcs(0) { mImpl.reset(fallbackCreateLLImageJ2CImpl()); - claimMem(mImpl); // Clear data size table for( S32 i = 0; i <= MAX_DISCARD_LEVEL; i++) diff --git a/indra/llimage/llimagejpeg.cpp b/indra/llimage/llimagejpeg.cpp index 3932e08fc1b8f3533888985910c577feea10489e..3b67afd0a5eb8a012bffef3d6bbb313c1c675421 100644 --- a/indra/llimage/llimagejpeg.cpp +++ b/indra/llimage/llimagejpeg.cpp @@ -393,9 +393,7 @@ boolean LLImageJPEG::encodeEmptyOutputBuffer( j_compress_ptr cinfo ) cinfo->dest->next_output_byte = self->mOutputBuffer + self->mOutputBufferSize; cinfo->dest->free_in_buffer = self->mOutputBufferSize; - self->disclaimMem(self->mOutputBufferSize); self->mOutputBufferSize = new_buffer_size; - self->claimMem(new_buffer_size); return true; } @@ -501,13 +499,10 @@ bool LLImageJPEG::encode( const LLImageRaw* raw_image, F32 encode_time ) // Allocate a temporary buffer big enough to hold the entire compressed image (and then some) // (Note: we make it bigger in emptyOutputBuffer() if we need to) delete[] mOutputBuffer; - disclaimMem(mOutputBufferSize); mOutputBufferSize = getWidth() * getHeight() * getComponents() + 1024; - claimMem(mOutputBufferSize); mOutputBuffer = new(std::nothrow) U8[ mOutputBufferSize ]; if (mOutputBuffer == NULL) { - disclaimMem(mOutputBufferSize); mOutputBufferSize = 0; setLastError("Failed to allocate output buffer"); return false; @@ -547,7 +542,6 @@ bool LLImageJPEG::encode( const LLImageRaw* raw_image, F32 encode_time ) jpeg_destroy_compress(&cinfo); delete[] mOutputBuffer; mOutputBuffer = NULL; - disclaimMem(mOutputBufferSize); mOutputBufferSize = 0; return false; } @@ -650,7 +644,6 @@ bool LLImageJPEG::encode( const LLImageRaw* raw_image, F32 encode_time ) // After finish_compress, we can release the temp output buffer. delete[] mOutputBuffer; mOutputBuffer = NULL; - disclaimMem(mOutputBufferSize); mOutputBufferSize = 0; //////////////////////////////////////// @@ -663,7 +656,6 @@ bool LLImageJPEG::encode( const LLImageRaw* raw_image, F32 encode_time ) jpeg_destroy_compress(&cinfo); delete[] mOutputBuffer; mOutputBuffer = NULL; - disclaimMem(mOutputBufferSize); mOutputBufferSize = 0; return false; } diff --git a/indra/llimage/llimageworker.cpp b/indra/llimage/llimageworker.cpp index d44f7ce25f4bfe6c9ab4093b3d8136e34b894b12..6239190b2545f4202ff5521847df26181f98815b 100644 --- a/indra/llimage/llimageworker.cpp +++ b/indra/llimage/llimageworker.cpp @@ -141,6 +141,7 @@ LLImageDecodeThread::~LLImageDecodeThread() // virtual S32 LLImageDecodeThread::update(F32 max_time_ms) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; if (mCreationListSize > 0) { LLMutexLock lock(mCreationMutex); @@ -172,6 +173,7 @@ S32 LLImageDecodeThread::update(F32 max_time_ms) LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(LLImageFormatted* image, U32 priority, S32 discard, BOOL needs_aux, Responder* responder) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; handle_t handle = generateHandle(); // If we have a thread pool dispatch this directly. // Note: addRequest could cause the handling to take place on the fetch thread, this is unlikely to be an issue. @@ -238,6 +240,7 @@ LLImageDecodeThread::ImageRequest::~ImageRequest() // Returns true when done, whether or not decode was successful. bool LLImageDecodeThread::ImageRequest::processRequest() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; // If not async, decode using this thread if ((mFlags & FLAG_ASYNC) == 0) return processRequestIntern(); @@ -323,6 +326,7 @@ bool LLImageDecodeThread::ImageRequest::processRequestIntern() void LLImageDecodeThread::ImageRequest::finishRequest(bool completed) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; if (mResponder.notNull()) { bool success = completed && mDecodedRaw && (!mNeedsAux || mDecodedAux); diff --git a/indra/llimage/tests/llimageworker_test.cpp b/indra/llimage/tests/llimageworker_test.cpp index a3f60a1c89278946de9847df05829f3c88f398ed..972fab34e4c5da8d56cdb1c6e771aa37d6206a75 100644 --- a/indra/llimage/tests/llimageworker_test.cpp +++ b/indra/llimage/tests/llimageworker_test.cpp @@ -45,8 +45,7 @@ // * A simulator for a class can be implemented here. Please comment and document thoroughly. LLImageBase::LLImageBase() -: LLTrace::MemTrackable<LLImageBase>("LLImageBase"), -mData(NULL), +: mData(NULL), mDataSize(0), mWidth(0), mHeight(0), diff --git a/indra/llinventory/llfoldertype.cpp b/indra/llinventory/llfoldertype.cpp index 3c20892f53a2916b976404202efd93b70b1a7c28..6608bd073f6fece9ea18828a7fc05238d1606a87 100644 --- a/indra/llinventory/llfoldertype.cpp +++ b/indra/llinventory/llfoldertype.cpp @@ -135,13 +135,13 @@ LLFolderDictionary::LLFolderDictionary() // static LLFolderType::EType LLFolderType::lookup(const std::string_view name) { - return LLFolderDictionary::getInstanceFast()->lookup(name); + return LLFolderDictionary::getInstance()->lookup(name); } // static const std::string &LLFolderType::lookup(LLFolderType::EType folder_type) { - const FolderEntry *entry = LLFolderDictionary::getInstanceFast()->lookup(folder_type); + const FolderEntry *entry = LLFolderDictionary::getInstance()->lookup(folder_type); if (entry) { return entry->mName; @@ -157,7 +157,7 @@ const std::string &LLFolderType::lookup(LLFolderType::EType folder_type) // you can't move, deleted, or change certain properties such as their type. bool LLFolderType::lookupIsProtectedType(EType folder_type) { - const LLFolderDictionary *dict = LLFolderDictionary::getInstanceFast(); + const LLFolderDictionary *dict = LLFolderDictionary::getInstance(); const FolderEntry *entry = dict->lookup(folder_type); if (entry) { diff --git a/indra/llinventory/llinventory.cpp b/indra/llinventory/llinventory.cpp index fbcaaafce9045f84b5d99f30fc3b71277c5cf3e4..a1da63aaf039763efe159024d5455413ceeb14fd 100644 --- a/indra/llinventory/llinventory.cpp +++ b/indra/llinventory/llinventory.cpp @@ -74,20 +74,17 @@ LLInventoryObject::LLInventoryObject(const LLUUID& uuid, const LLUUID& parent_uuid, LLAssetType::EType type, const std::string& name) -: LLTrace::MemTrackable<LLInventoryObject>("LLInventoryObject"), - mUUID(uuid), +: mUUID(uuid), mParentUUID(parent_uuid), mType(type), mName(name), mCreationDate(0) { - claimMem(mName); correctInventoryName(mName); } LLInventoryObject::LLInventoryObject() -: LLTrace::MemTrackable<LLInventoryObject>("LLInventoryObject"), - mType(LLAssetType::AT_NONE), +: mType(LLAssetType::AT_NONE), mCreationDate(0) { } @@ -97,9 +94,7 @@ void LLInventoryObject::copyObject(const LLInventoryObject* other) mUUID = other->mUUID; mParentUUID = other->mParentUUID; mType = other->mType; - disclaimMem(mName); mName = other->mName; - claimMem(mName); } const LLUUID& LLInventoryObject::getUUID() const @@ -152,9 +147,7 @@ void LLInventoryObject::rename(const std::string& n) correctInventoryName(new_name); if( !new_name.empty() && new_name != mName ) { - disclaimMem(mName); mName = new_name; - claimMem(mName); } } @@ -307,7 +300,6 @@ LLInventoryItem::LLInventoryItem(const LLUUID& uuid, LLStringUtil::replaceNonstandardASCII(mDescription, ' '); LLStringUtil::replaceChar(mDescription, '|', ' '); - claimMem(mDescription); mPermissions.initMasks(inv_type); } @@ -336,9 +328,7 @@ void LLInventoryItem::copyItem(const LLInventoryItem* other) copyObject(other); mPermissions = other->mPermissions; mAssetUUID = other->mAssetUUID; - disclaimMem(mDescription); mDescription = other->mDescription; - claimMem(mDescription); mSaleInfo = other->mSaleInfo; mInventoryType = other->mInventoryType; mFlags = other->mFlags; @@ -418,9 +408,7 @@ void LLInventoryItem::setDescription(const std::string& d) LLInventoryItem::correctInventoryDescription(new_desc); if( new_desc != mDescription ) { - disclaimMem(mDescription); mDescription = new_desc; - claimMem(mDescription); } } @@ -700,10 +688,8 @@ BOOL LLInventoryItem::importLegacyStream(std::istream& input_stream) valuestr[0] = '\000'; } - disclaimMem(mDescription); mDescription.assign(valuestr); LLStringUtil::replaceNonstandardASCII(mDescription, ' '); - claimMem(mDescription); /* TODO -- ask Ian about this code const char *donkey = mDescription.c_str(); if (donkey[0] == '|') @@ -832,11 +818,9 @@ void LLInventoryItem::asLLSD( LLSD& sd ) const sd[INV_CREATION_DATE_LABEL] = (S32) mCreationDate; } -LLTrace::BlockTimerStatHandle FTM_INVENTORY_SD_DESERIALIZE("Inventory SD Deserialize"); - bool LLInventoryItem::fromLLSD(const LLSD& sd, bool is_new) { - LL_RECORD_BLOCK_TIME(FTM_INVENTORY_SD_DESERIALIZE); + LL_PROFILE_ZONE_SCOPED; if (is_new) { // If we're adding LLSD to an existing object, need avoid @@ -953,10 +937,8 @@ bool LLInventoryItem::fromLLSD(const LLSD& sd, bool is_new) w = INV_DESC_LABEL; if (sd.has(w)) { - disclaimMem(mDescription); mDescription = sd[w].asString(); LLStringUtil::replaceNonstandardASCII(mDescription, ' '); - claimMem(mDescription); } w = INV_CREATION_DATE_LABEL; if (sd.has(w)) diff --git a/indra/llinventory/llinventory.h b/indra/llinventory/llinventory.h index adb75edd168fad39a5e4a2c5e4cb7ee1962ee730..8507496b411f6841570770850e1cdfe59a2ac9f4 100644 --- a/indra/llinventory/llinventory.h +++ b/indra/llinventory/llinventory.h @@ -44,7 +44,7 @@ class LLMessageSystem; // Base class for anything in the user's inventory. Handles the common code // between items and categories. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -class LLInventoryObject : public LLRefCount, public LLTrace::MemTrackable<LLInventoryObject> +class LLInventoryObject : public LLRefCount { public: typedef std::list<LLPointer<LLInventoryObject> > object_list_t; diff --git a/indra/llinventory/llinventorysettings.cpp b/indra/llinventory/llinventorysettings.cpp index 12ffac85d872ff3a8baf4d858e7c4d2b0b13cf6a..ee121f07eddb995fc6159c8f6b41e383c45ab031 100644 --- a/indra/llinventory/llinventorysettings.cpp +++ b/indra/llinventory/llinventorysettings.cpp @@ -93,7 +93,7 @@ LLSettingsType::type_e LLSettingsType::fromInventoryFlags(U32 flags) LLInventoryType::EIconName LLSettingsType::getIconName(LLSettingsType::type_e type) { - const SettingsEntry *entry = LLSettingsDictionary::instanceFast().lookup(type); + const SettingsEntry *entry = LLSettingsDictionary::instance().lookup(type); if (!entry) return getIconName(ST_INVALID); return entry->mIconName; @@ -101,7 +101,7 @@ LLInventoryType::EIconName LLSettingsType::getIconName(LLSettingsType::type_e ty std::string LLSettingsType::getDefaultName(LLSettingsType::type_e type) { - const SettingsEntry *entry = LLSettingsDictionary::instanceFast().lookup(type); + const SettingsEntry *entry = LLSettingsDictionary::instance().lookup(type); if (!entry) return getDefaultName(ST_INVALID); return entry->mDefaultNewName; diff --git a/indra/llinventory/llinventorytype.cpp b/indra/llinventory/llinventorytype.cpp index 40f8dbc14863b7ce7bd673a8085fe80fab43cfb1..87030a16f844e08b0e0505093b39ea7ead2051fe 100644 --- a/indra/llinventory/llinventorytype.cpp +++ b/indra/llinventory/llinventorytype.cpp @@ -160,7 +160,7 @@ DEFAULT_ASSET_FOR_INV_TYPE[LLAssetType::AT_COUNT] = // static const std::string &LLInventoryType::lookup(EType type) { - const InventoryEntry *entry = LLInventoryDictionary::getInstanceFast()->lookup(type); + const InventoryEntry *entry = LLInventoryDictionary::getInstance()->lookup(type); if (!entry) return empty_string; return entry->mName; } @@ -168,7 +168,7 @@ const std::string &LLInventoryType::lookup(EType type) // static LLInventoryType::EType LLInventoryType::lookup(const std::string_view name) { - return LLInventoryDictionary::getInstanceFast()->lookup(name); + return LLInventoryDictionary::getInstance()->lookup(name); } // XUI:translate @@ -176,7 +176,7 @@ LLInventoryType::EType LLInventoryType::lookup(const std::string_view name) // static const std::string &LLInventoryType::lookupHumanReadable(EType type) { - const InventoryEntry *entry = LLInventoryDictionary::getInstanceFast()->lookup(type); + const InventoryEntry *entry = LLInventoryDictionary::getInstance()->lookup(type); if (!entry) return empty_string; return entry->mHumanName; } @@ -223,7 +223,7 @@ bool inventory_and_asset_types_match(LLInventoryType::EType inventory_type, if (LLAssetType::lookupIsLinkType(asset_type)) return true; - const InventoryEntry *entry = LLInventoryDictionary::getInstanceFast()->lookup(inventory_type); + const InventoryEntry *entry = LLInventoryDictionary::getInstance()->lookup(inventory_type); if (!entry) return false; for (InventoryEntry::asset_vec_t::const_iterator iter = entry->mAssetTypes.begin(); diff --git a/indra/llinventory/llparcel.cpp b/indra/llinventory/llparcel.cpp index 26dfedef6be573a039a6b95a95e979b7fb720c5d..87b9df88857131b69a0010937ba9ef0f6f96263f 100644 --- a/indra/llinventory/llparcel.cpp +++ b/indra/llinventory/llparcel.cpp @@ -228,6 +228,8 @@ void LLParcel::init(const LLUUID &owner_id, setRegionAllowEnvironmentOverride(FALSE); setParcelEnvironmentVersion(INVALID_PARCEL_ENVIRONMENT_VERSION); + + setObscureMOAP(false); } void LLParcel::overrideOwner(const LLUUID& owner_id, BOOL is_group_owned) @@ -457,13 +459,13 @@ BOOL LLParcel::importAccessEntry(std::istream& input_stream, LLAccessEntry* entr } else if ("time" == keyword) { - S32 when = 0; + S32 when{}; LLStringUtil::convertToS32(value, when); entry->mTime = when; } else if ("flags" == keyword) { - U32 setting = 0; + U32 setting{}; LLStringUtil::convertToU32(value, setting); entry->mFlags = setting; } @@ -534,6 +536,7 @@ void LLParcel::packMessage(LLSD& msg) msg["see_avs"] = (LLSD::Boolean) getSeeAVs(); msg["group_av_sounds"] = (LLSD::Boolean) getAllowGroupAVSounds(); msg["any_av_sounds"] = (LLSD::Boolean) getAllowAnyAVSounds(); + msg["obscure_moap"] = (LLSD::Boolean) getObscureMOAP(); } diff --git a/indra/llinventory/llparcel.h b/indra/llinventory/llparcel.h index 496bc692d904b2d55d4e2e3b6a599ddcdbb872d5..dd926052acedee1c82b413dee9a2eac1c12e9f39 100644 --- a/indra/llinventory/llparcel.h +++ b/indra/llinventory/llparcel.h @@ -306,6 +306,7 @@ class LLParcel final void setRestrictPushObject(BOOL b) { setParcelFlag(PF_RESTRICT_PUSHOBJECT, b); } void setAllowGroupAVSounds(BOOL b) { mAllowGroupAVSounds = b; } void setAllowAnyAVSounds(BOOL b) { mAllowAnyAVSounds = b; } + void setObscureMOAP(bool b) { mObscureMOAP = b; } void setDrawDistance(F32 dist) { mDrawDistance = dist; } void setSalePrice(S32 price) { mSalePrice = price; } @@ -517,6 +518,8 @@ class LLParcel final BOOL getAllowGroupAVSounds() const { return mAllowGroupAVSounds; } BOOL getAllowAnyAVSounds() const { return mAllowAnyAVSounds; } + + bool getObscureMOAP() const { return mObscureMOAP; } F32 getDrawDistance() const { return mDrawDistance; } S32 getSalePrice() const { return mSalePrice; } @@ -670,6 +673,7 @@ class LLParcel final BOOL mRegionAllowEnvironmentOverride; BOOL mAllowGroupAVSounds; BOOL mAllowAnyAVSounds; + bool mObscureMOAP; S32 mCurrentEnvironmentVersion; bool mIsDefaultDayCycle; diff --git a/indra/llinventory/llsettingsbase.cpp b/indra/llinventory/llsettingsbase.cpp index 746dc420e8902cb1d9b14af21e14c336d61078a8..a1fcda5a93bc1c2ba5f96735d354813f3b5aec20 100644 --- a/indra/llinventory/llsettingsbase.cpp +++ b/indra/llinventory/llsettingsbase.cpp @@ -697,6 +697,7 @@ bool LLSettingsBase::Validator::verifyStringLength(LLSD &value, U32, S32 length) //========================================================================= void LLSettingsBlender::update(const LLSettingsBase::BlendFactor& blendf) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_ENVIRONMENT; F64 res = setBlendFactor(blendf); llassert(res >= 0.0 && res <= 1.0); (void)res; @@ -727,6 +728,7 @@ F64 LLSettingsBlender::setBlendFactor(const LLSettingsBase::BlendFactor& blendf_ void LLSettingsBlender::triggerComplete() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_ENVIRONMENT; if (mTarget) mTarget->replaceSettings(mFinal->getSettings()); LLSettingsBlender::ptr_t hold = shared_from_this(); // prevents this from deleting too soon @@ -739,11 +741,13 @@ const LLSettingsBase::BlendFactor LLSettingsBlenderTimeDelta::MIN_BLEND_DELTA(FL LLSettingsBase::BlendFactor LLSettingsBlenderTimeDelta::calculateBlend(const LLSettingsBase::TrackPosition& spanpos, const LLSettingsBase::TrackPosition& spanlen) const { + LL_PROFILE_ZONE_SCOPED_CATEGORY_ENVIRONMENT; return LLSettingsBase::BlendFactor(fmod((F64)spanpos, (F64)spanlen) / (F64)spanlen); } bool LLSettingsBlenderTimeDelta::applyTimeDelta(const LLSettingsBase::Seconds& timedelta) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_ENVIRONMENT; mTimeSpent += timedelta; if (mTimeSpent > mBlendSpan) diff --git a/indra/llinventory/llsettingsdaycycle.cpp b/indra/llinventory/llsettingsdaycycle.cpp index b1553508d36ef571d7606a89957cd60a098ad034..cd9d26e6607daf01f3e6c8bcb8ffd714eab55fb3 100644 --- a/indra/llinventory/llsettingsdaycycle.cpp +++ b/indra/llinventory/llsettingsdaycycle.cpp @@ -41,9 +41,6 @@ //========================================================================= namespace { - LLTrace::BlockTimerStatHandle FTM_BLEND_WATERVALUES("Blending Water Environment Day"); - LLTrace::BlockTimerStatHandle FTM_UPDATE_WATERVALUES("Update Water Environment Day"); - template<typename T> inline T get_wrapping_distance(T begin, T end) { diff --git a/indra/llinventory/llsettingssky.cpp b/indra/llinventory/llsettingssky.cpp index dc740a03f39e1559c67f91629ea7745ee435d6a3..2a395402417d89fa24cc6d9c8ad4977ca15a140f 100644 --- a/indra/llinventory/llsettingssky.cpp +++ b/indra/llinventory/llsettingssky.cpp @@ -66,11 +66,6 @@ namespace } //} -static LLTrace::BlockTimerStatHandle FTM_BLEND_SKYVALUES("Blending Sky Environment"); -static LLTrace::BlockTimerStatHandle FTM_RECALCULATE_SKYVALUES("Recalculate Sky"); -static LLTrace::BlockTimerStatHandle FTM_RECALCULATE_BODIES("Recalculate Heavenly Bodies"); -static LLTrace::BlockTimerStatHandle FTM_RECALCULATE_LIGHTING("Recalculate Lighting"); - //========================================================================= const std::string LLSettingsSky::SETTING_AMBIENT("ambient"); const std::string LLSettingsSky::SETTING_BLUE_DENSITY("blue_density"); @@ -441,6 +436,7 @@ void LLSettingsSky::replaceWithSky(LLSettingsSky::ptr_t pother) void LLSettingsSky::blend(const LLSettingsBase::ptr_t &end, F64 blendf) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_ENVIRONMENT; llassert(getSettingsType() == end->getSettingsType()); LLSettingsSky::ptr_t other = PTR_NAMESPACE::dynamic_pointer_cast<LLSettingsSky>(end); @@ -936,7 +932,7 @@ LLSD LLSettingsSky::translateLegacySettings(const LLSD& legacy) void LLSettingsSky::updateSettings() { - LL_RECORD_BLOCK_TIME(FTM_RECALCULATE_SKYVALUES); + LL_PROFILE_ZONE_SCOPED_CATEGORY_ENVIRONMENT; // base class clears dirty flag so as to not trigger recursive update LLSettingsBase::updateSettings(); @@ -1019,6 +1015,7 @@ LLColor3 LLSettingsSky::getLightDiffuse() const LLColor3 LLSettingsSky::getColor(const std::string& key, const LLColor3& default_value) const { + LL_PROFILE_ZONE_SCOPED_CATEGORY_ENVIRONMENT; const auto& settings_map = mSettings.map(); auto legacy_it = settings_map.find(SETTING_LEGACY_HAZE); if (legacy_it != settings_map.end()) @@ -1042,6 +1039,7 @@ LLColor3 LLSettingsSky::getColor(const std::string& key, const LLColor3& default F32 LLSettingsSky::getFloat(const std::string& key, F32 default_value) const { + LL_PROFILE_ZONE_SCOPED_CATEGORY_ENVIRONMENT; const auto& settings_map = mSettings.map(); auto legacy_it = settings_map.find(SETTING_LEGACY_HAZE); if (legacy_it != settings_map.end()) @@ -1245,8 +1243,10 @@ LLColor3 LLSettingsSky::getLightTransmittanceFast(const LLColor3& total_density, // performs soft scale clip and gamma correction ala the shader implementation // scales colors down to 0 - 1 range preserving relative ratios -LLColor3 LLSettingsSky::gammaCorrect(const LLColor3& in, F32 gamma) const +LLColor3 LLSettingsSky::gammaCorrect(const LLColor3& in,const F32 &gamma) const { + //F32 gamma = getGamma(); // SL-16127: Use cached gamma from atmospheric vars + LLColor3 v(in); // scale down to 0 to 1 range preserving relative ratio (aka homegenize) F32 max_color = llmax(llmax(in.mV[0], in.mV[1]), in.mV[2]); diff --git a/indra/llinventory/llsettingssky.h b/indra/llinventory/llsettingssky.h index 62be3c81a3abb5c40f86400433931dd80d4e6b01..0e0e1d79b0579bc02cd21a388e89488d223fd3dd 100644 --- a/indra/llinventory/llsettingssky.h +++ b/indra/llinventory/llsettingssky.h @@ -256,7 +256,7 @@ class LLSettingsSky: public LLSettingsBase LLColor3 getLightTransmittanceFast(const LLColor3& total_density, const F32 density_multiplier, const F32 distance) const; LLColor3 getTotalDensity() const; LLColor3 getTotalDensityFast(const LLColor3& blue_density, F32 haze_density) const; - LLColor3 gammaCorrect(const LLColor3& in, F32 gamma) const; + LLColor3 gammaCorrect(const LLColor3& in,const F32 &gamma) const; LLColor3 getBlueDensity() const; LLColor3 getBlueHorizon() const; diff --git a/indra/llinventory/llsettingswater.cpp b/indra/llinventory/llsettingswater.cpp index fec8902ab138ec8975d313cfdffa1790de4a4781..902ba92088798f8144174452bd586ef5a0fa6c0d 100644 --- a/indra/llinventory/llsettingswater.cpp +++ b/indra/llinventory/llsettingswater.cpp @@ -33,14 +33,6 @@ #include "v3colorutil.h" #include "indra_constants.h" -//========================================================================= -namespace -{ - LLTrace::BlockTimerStatHandle FTM_BLEND_WATERVALUES("Blending Water Environment"); - LLTrace::BlockTimerStatHandle FTM_UPDATE_WATERVALUES("Update Water Environment"); -} - -//========================================================================= const std::string LLSettingsWater::SETTING_BLUR_MULTIPLIER("blur_multiplier"); const std::string LLSettingsWater::SETTING_FOG_COLOR("water_fog_color"); const std::string LLSettingsWater::SETTING_FOG_DENSITY("water_fog_density"); diff --git a/indra/llkdu/tests/llimagej2ckdu_test.cpp b/indra/llkdu/tests/llimagej2ckdu_test.cpp index 0f1645e7daec4ac7a288db31d6550798b51305dc..e014f51576eb4d57db4fa906980b656c43506cb9 100644 --- a/indra/llkdu/tests/llimagej2ckdu_test.cpp +++ b/indra/llkdu/tests/llimagej2ckdu_test.cpp @@ -63,8 +63,7 @@ U8* LLImageRaw::reallocateData(S32 ) { return NULL; } bool LLImageRaw::resize(U16, U16, S8) { return true; } // this method always returns true... LLImageBase::LLImageBase() -: LLTrace::MemTrackable<LLImageBase>("LLImageBase"), -mData(NULL), +: mData(NULL), mDataSize(0), mWidth(0), mHeight(0), diff --git a/indra/llmath/CMakeLists.txt b/indra/llmath/CMakeLists.txt index 4ac85ec8c9496d4840d33a25551e066a296f63a2..444af803e5cca2cf50c1115c0353fe0b5cd122e0 100644 --- a/indra/llmath/CMakeLists.txt +++ b/indra/llmath/CMakeLists.txt @@ -4,6 +4,7 @@ project(llmath) include(00-Common) include(LLCommon) +include(LLMeshOptimizer) include(LLMath) include(Boost) @@ -11,6 +12,7 @@ include_directories( ${LLCOMMON_INCLUDE_DIRS} ${LLMATH_INCLUDE_DIRS} ${LLCOMMON_SYSTEM_INCLUDE_DIRS} + ${LLMESHOPTIMIZER_INCLUDE_DIRS} ) set(llmath_SOURCE_FILES @@ -115,6 +117,7 @@ target_link_libraries(llmath meshoptimizer PUBLIC ${LLCOMMON_LIBRARIES} + ${LLMESHOPTIMIZER_LIBRARIES} ) if(USE_PRECOMPILED_HEADERS AND ${CMAKE_VERSION} VERSION_GREATER "3.15.0") diff --git a/indra/llmath/llmatrix4a.h b/indra/llmath/llmatrix4a.h index 95745f361ee7fc3d02f4ae8954b9500bcb5774a1..d60f909848853042e8c99898fe50e9c705b2aa55 100644 --- a/indra/llmath/llmatrix4a.h +++ b/indra/llmath/llmatrix4a.h @@ -34,6 +34,7 @@ class alignas(16) LLMatrix4a { + LL_ALIGN_NEW public: LL_ALIGN_PREFIX(16) LLVector4a mMatrix[4] LL_ALIGN_POSTFIX(16); public: @@ -45,27 +46,12 @@ class alignas(16) LLMatrix4a ROW_TRANS }; - void* operator new(size_t size) - { - return ll_aligned_malloc_16(size); - } - - void* operator new[](size_t size) - { - return ll_aligned_malloc_16(size); - } - - void operator delete(void* ptr) - { - ll_aligned_free_16(ptr); - } - - void operator delete[](void* ptr) - { - ll_aligned_free_16(ptr); - } - LLMatrix4a() = default; + explicit LLMatrix4a(const LLMatrix4& val) + { + loadu(val); + } + LLMatrix4a(const LLQuad& q1,const LLQuad& q2,const LLQuad& q3,const LLQuad& q4) { mMatrix[0] = q1; @@ -73,7 +59,7 @@ class alignas(16) LLMatrix4a mMatrix[2] = q3; mMatrix[3] = q4; } - LLMatrix4a(const LLQuaternion2& quat) + explicit LLMatrix4a(const LLQuaternion2& quat) { const LLVector4a& xyzw = quat.getVector4a(); LLVector4a nyxwz = _mm_shuffle_ps(xyzw, xyzw, _MM_SHUFFLE(2,3,0,1)); @@ -443,6 +429,8 @@ class alignas(16) LLMatrix4a mMatrix[3] = _mm_movehl_ps(q4,q1); } + const LLVector4a& getTranslation() const { return mMatrix[3]; } + // Following procedure adapted from: // http://software.intel.com/en-us/articles/optimized-matrix-library-for-use-with-the-intel-pentiumr-4-processors-sse2-instructions/ // @@ -795,6 +783,38 @@ static_assert(std::is_trivial<LLMatrix4a>::value, "LLMatrix4a must be a trivial static_assert(std::is_standard_layout<LLMatrix4a>::value, "LLMatrix4a must be a standard layout type"); #endif +inline LLVector4a rowMul(const LLVector4a &row, const LLMatrix4a &mat) +{ + LLVector4a result; + result = _mm_mul_ps(_mm_shuffle_ps(row, row, _MM_SHUFFLE(0, 0, 0, 0)), mat.mMatrix[0]); + result = _mm_add_ps(result, _mm_mul_ps(_mm_shuffle_ps(row, row, _MM_SHUFFLE(1, 1, 1, 1)), mat.mMatrix[1])); + result = _mm_add_ps(result, _mm_mul_ps(_mm_shuffle_ps(row, row, _MM_SHUFFLE(2, 2, 2, 2)), mat.mMatrix[2])); + result = _mm_add_ps(result, _mm_mul_ps(_mm_shuffle_ps(row, row, _MM_SHUFFLE(3, 3, 3, 3)), mat.mMatrix[3])); + return result; +} + +inline void matMul(const LLMatrix4a &a, const LLMatrix4a &b, LLMatrix4a &res) +{ + LLVector4a row0 = rowMul(a.mMatrix[0], b); + LLVector4a row1 = rowMul(a.mMatrix[1], b); + LLVector4a row2 = rowMul(a.mMatrix[2], b); + LLVector4a row3 = rowMul(a.mMatrix[3], b); + + res.mMatrix[0] = row0; + res.mMatrix[1] = row1; + res.mMatrix[2] = row2; + res.mMatrix[3] = row3; +} + +//Faster version of matMul wehere res must not be a or b +inline void matMulUnsafe(const LLMatrix4a &a, const LLMatrix4a &b, LLMatrix4a &res) +{ + res.mMatrix[0] = rowMul(a.mMatrix[0], b); + res.mMatrix[1] = rowMul(a.mMatrix[1], b); + res.mMatrix[2] = rowMul(a.mMatrix[2], b); + res.mMatrix[3] = rowMul(a.mMatrix[3], b); +} + inline std::ostream& operator<<(std::ostream& s, const LLMatrix4a& m) { s << "[" << m.mMatrix[0] << ", " << m.mMatrix[1] << ", " << m.mMatrix[2] << ", " << m.mMatrix[3] << "]"; diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h index ffd63a9f267df040a9a629f7396f91e78d9db200..ef83838b10c14c222d6cef478701fdec56e8841f 100644 --- a/indra/llmath/lloctree.h +++ b/indra/llmath/lloctree.h @@ -36,6 +36,9 @@ #define OCT_ERRS LL_WARNS("OctreeErrors") +#define OCTREE_DEBUG_COLOR_REMOVE 0x0000FF // r +#define OCTREE_DEBUG_COLOR_INSERT 0x00FF00 // g +#define OCTREE_DEBUG_COLOR_BALANCE 0xFF0000 // b extern U32 gOctreeMaxCapacity; extern float gOctreeMinSize; @@ -47,141 +50,98 @@ extern float gOctreeMinSize; #define LL_OCTREE_MAX_CAPACITY 128 #endif*/ -#if !LL_DEBUG -#define LL_OCTREE_POOLS 1 -#endif - -template <class T> class LLOctreeNode; +// T is the type of the element referenced by the octree node. +// T_PTR determines how pointers to elements are stored internally. +// LLOctreeNode<T, LLPointer<T>> assumes ownership of inserted elements and +// deletes elements removed from the tree. +// LLOctreeNode<T, T*> doesn't take ownership of inserted elements, so the API +// user is responsible for managing the storage lifecycle of elements added to +// the tree. +template <class T, typename T_PTR> class LLOctreeNode; -template <class T> +template <class T, typename T_PTR> class LLOctreeListener: public LLTreeListener<T> { public: typedef LLTreeListener<T> BaseType; - typedef LLOctreeNode<T> oct_node; + typedef LLOctreeNode<T, T_PTR> oct_node; virtual void handleChildAddition(const oct_node* parent, oct_node* child) = 0; virtual void handleChildRemoval(const oct_node* parent, const oct_node* child) = 0; }; -template <class T> +template <class T, typename T_PTR> class LLOctreeTraveler { public: - virtual ~LLOctreeTraveler() = default; - - virtual void traverse(const LLOctreeNode<T>* node); - virtual void visit(const LLOctreeNode<T>* branch) = 0; + virtual void traverse(const LLOctreeNode<T, T_PTR>* node); + virtual void visit(const LLOctreeNode<T, T_PTR>* branch) = 0; }; -template <class T> -class LLOctreeTravelerDepthFirst : public LLOctreeTraveler<T> +template <class T, typename T_PTR> +class LLOctreeTravelerDepthFirst : public LLOctreeTraveler<T, T_PTR> { public: - virtual void traverse(const LLOctreeNode<T>* node); + virtual void traverse(const LLOctreeNode<T, T_PTR>* node) override; }; -template <class T> -class LLOctreeNode : public LLTreeNode<T> +template <class T, typename T_PTR> +class alignas(16) LLOctreeNode : public LLTreeNode<T> { + LL_ALIGN_NEW public: - typedef LLOctreeTraveler<T> oct_traveler; - typedef LLTreeTraveler<T> tree_traveler; - typedef std::vector< LLPointer<T> > element_list; // note: don't remove the whitespace between "> >" - typedef LLPointer<T>* element_iter; - typedef const LLPointer<T>* const_element_iter; + typedef LLOctreeTraveler<T, T_PTR> oct_traveler; + typedef LLTreeTraveler<T> tree_traveler; + typedef std::vector<T_PTR> element_list; + typedef typename element_list::iterator element_iter; + typedef typename element_list::const_iterator const_element_iter; typedef typename std::vector<LLTreeListener<T>*>::iterator tree_listener_iter; - typedef LLOctreeNode<T>** child_list; - typedef LLOctreeNode<T>** child_iter; + typedef LLOctreeNode<T, T_PTR>** child_list; + typedef LLOctreeNode<T, T_PTR>** child_iter; - typedef LLTreeNode<T> BaseType; - typedef LLOctreeNode<T> oct_node; - typedef LLOctreeListener<T> oct_listener; + typedef LLTreeNode<T> BaseType; + typedef LLOctreeNode<T, T_PTR> oct_node; + typedef LLOctreeListener<T, T_PTR> oct_listener; -#if LL_OCTREE_POOLS - struct octree_pool_alloc - { - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; - - static char * malloc(const size_type bytes) - { return (char *)ll_aligned_malloc_16(bytes); } - static void free(char * const block) - { ll_aligned_free_16(block); } - }; - static boost::pool<octree_pool_alloc>& getPool(const std::size_t& size) - { - static boost::pool<octree_pool_alloc> sPool((std::size_t)LL_NEXT_ALIGNED_ADDRESS((char*)size),1200); - llassert_always((std::size_t)LL_NEXT_ALIGNED_ADDRESS((char*)size) == sPool.get_requested_size()); - return sPool; - } - void* operator new(size_t size) - { - return getPool(size).malloc(); - } - void* operator new[](size_t size) - { - return getPool(size).malloc(); - } - void operator delete(void* ptr) - { - getPool(sizeof(LLOctreeNode<T>)).free(ptr); - } - void operator delete[](void* ptr) - { - getPool(sizeof(LLOctreeNode<T>)).free(ptr); - } -#else - void* operator new(size_t size) - { - return ll_aligned_malloc_16(size); - } - - void operator delete(void* ptr) - { - ll_aligned_free_16(ptr); - } -#endif + enum + { + NO_CHILD_NODES = 255 // Note: This is an U8 to match the max value in mChildMap[] + }; LLOctreeNode( const LLVector4a& center, const LLVector4a& size, BaseType* parent, - U8 octant = 255) - : mCenter(center), - mSize(size), - mParent((oct_node*)parent), + U8 octant = NO_CHILD_NODES) + : mParent((oct_node*)parent), mOctant(octant) { llassert(size[0] >= gOctreeMinSize*0.5f); - //always keep a NULL terminated list to avoid out of bounds exceptions in debug builds - mData.push_back(NULL); - mDataEnd = &mData[0]; + + mCenter = center; + mSize = size; updateMinMax(); - if ((mOctant == 255) && mParent) + if ((mOctant == NO_CHILD_NODES) && mParent) { mOctant = ((oct_node*) mParent)->getOctant(mCenter); } - mElementCount = 0; - clearChildren(); } - virtual ~LLOctreeNode() + virtual ~LLOctreeNode() { - BaseType::destroyListeners(); + BaseType::destroyListeners(); - for (U32 i = 0; i < mElementCount; ++i) + const U32 element_count = getElementCount(); + for (U32 i = 0; i < element_count; ++i) { mData[i]->setBinIndex(-1); mData[i] = NULL; } mData.clear(); - mData.push_back(NULL); - mDataEnd = &mData[0]; for (U32 i = 0; i < getChildCount(); i++) { @@ -210,7 +170,7 @@ class LLOctreeNode : public LLTreeNode<T> return rad <= mSize[0]*2.f && isInside(pos); } - inline bool isInside(T* data) const + inline bool isInside(T* data) const { return isInside(data->getPositionGroup(), data->getBinRadius()); } @@ -281,14 +241,12 @@ class LLOctreeNode : public LLTreeNode<T> void accept(oct_traveler* visitor) { visitor->visit(this); } virtual bool isLeaf() const { return mChildCount == 0; } - U32 getElementCount() const { return mElementCount; } - bool isEmpty() const { return mElementCount == 0; } - element_list& getData() { return mData; } - const element_list& getData() const { return mData; } - element_iter getDataBegin() { return &mData[0]; } - element_iter getDataEnd() { return mDataEnd; } - const_element_iter getDataBegin() const { return &mData[0]; } - const_element_iter getDataEnd() const { return mDataEnd; } + U32 getElementCount() const { return (U32)mData.size(); } + bool isEmpty() const { return mData.empty(); } + element_iter getDataBegin() { return mData.begin(); } + element_iter getDataEnd() { return mData.end(); } + const_element_iter getDataBegin() const { return mData.cbegin(); } + const_element_iter getDataEnd() const { return mData.cend(); } U32 getChildCount() const { return mChildCount; } oct_node* getChild(U32 index) { return mChild[index]; } @@ -304,9 +262,9 @@ class LLOctreeNode : public LLTreeNode<T> for (U32 i = 0; i < 8; i++) { U8 idx = mChildMap[i]; - if (idx != 255) + if (idx != NO_CHILD_NODES) { - LLOctreeNode<T>* child = mChild[idx]; + oct_node* child = mChild[idx]; if (child->getOctant() != i) { @@ -324,10 +282,10 @@ class LLOctreeNode : public LLTreeNode<T> oct_node* getNodeAt(const LLVector4a& pos, const F32& rad) { - LLOctreeNode<T>* node = this; + oct_node* node = this; if (node->isInside(pos, rad)) - { + { //do a quick search by octant U8 octant = node->getOctant(pos); @@ -337,7 +295,7 @@ class LLOctreeNode : public LLTreeNode<T> // the data U8 next_node = node->mChildMap[octant]; - while (next_node != 255 && node->getSize()[0] >= rad) + while (next_node != NO_CHILD_NODES && node->getSize()[0] >= rad) { node = node->getChild(next_node); octant = node->getOctant(pos); @@ -346,7 +304,7 @@ class LLOctreeNode : public LLTreeNode<T> } else if (!node->contains(rad) && node->getParent()) { //if we got here, data does not exist in this node - return ((LLOctreeNode<T>*) node->getParent())->getNodeAt(pos, rad); + return ((oct_node*) node->getParent())->getNodeAt(pos, rad); } return node; @@ -354,12 +312,14 @@ class LLOctreeNode : public LLTreeNode<T> virtual bool insert(T* data) { + //LL_PROFILE_ZONE_NAMED_COLOR("Octree::insert()",OCTREE_DEBUG_COLOR_INSERT); + if (data == NULL || data->getBinIndex() != -1) { OCT_ERRS << "!!! INVALID ELEMENT ADDED TO OCTREE BRANCH !!!" << LL_ENDL; return false; } - LLOctreeNode<T>* parent = getOctParent(); + oct_node* parent = getOctParent(); //is it here? if (isInside(data->getPositionGroup())) @@ -367,11 +327,8 @@ class LLOctreeNode : public LLTreeNode<T> if ((((getElementCount() < gOctreeMaxCapacity || getSize()[0] <= gOctreeMinSize) && contains(data->getBinRadius())) || (data->getBinRadius() > getSize()[0] && parent && parent->getElementCount() >= gOctreeMaxCapacity))) { //it belongs here - mData.push_back(NULL); - mData[mElementCount] = data; - mElementCount++; - mDataEnd = &mData[mElementCount]; - data->setBinIndex(mElementCount-1); + mData.push_back(data); + data->setBinIndex(getElementCount() - 1); BaseType::insert(data); return true; } @@ -395,7 +352,7 @@ class LLOctreeNode : public LLTreeNode<T> size.mul(0.5f); //push center in direction of data - LLOctreeNode<T>::pushCenter(center, size, data); + oct_node::pushCenter(center, size, data); // handle case where floating point number gets too small LLVector4a val; @@ -407,11 +364,8 @@ class LLOctreeNode : public LLTreeNode<T> if( lt == 0x7 ) { - mData.push_back(NULL); - mData[mElementCount] = data; - mElementCount++; - mDataEnd = &mData[mElementCount]; - data->setBinIndex(mElementCount-1); + mData.push_back(data); + data->setBinIndex(getElementCount() - 1); BaseType::insert(data); return true; } @@ -437,7 +391,7 @@ class LLOctreeNode : public LLTreeNode<T> llassert(size[0] >= gOctreeMinSize*0.5f); //make the new kid - child = new LLOctreeNode<T>(center, size, this); + child = new oct_node(center, size, this); addChild(child); child->insert(data); @@ -448,28 +402,25 @@ class LLOctreeNode : public LLTreeNode<T> } void _remove(T* data, S32 i) - { //precondition -- mElementCount > 0, idx is in range [0, mElementCount) + { //precondition -- getElementCount() > 0, idx is in range [0, getElementCount()) - mElementCount--; data->setBinIndex(-1); - if (mElementCount > 0) + const U32 new_element_count = getElementCount() - 1; + if (new_element_count > 0) { - if (mElementCount != i) + if (new_element_count != i) { - mData[i] = mData[mElementCount]; //might unref data, do not access data after this point + mData[i] = mData[new_element_count]; //might unref data, do not access data after this point mData[i]->setBinIndex(i); } - mData[mElementCount] = NULL; + mData[new_element_count] = NULL; mData.pop_back(); - mDataEnd = &mData[mElementCount]; } else { mData.clear(); - mData.push_back(NULL); - mDataEnd = &mData[0]; } this->notifyRemoval(data); @@ -478,9 +429,11 @@ class LLOctreeNode : public LLTreeNode<T> bool remove(T* data) { + //LL_PROFILE_ZONE_NAMED_COLOR("Octree::remove()", OCTREE_DEBUG_COLOR_REMOVE); + S32 i = data->getBinIndex(); - if (i >= 0 && i < mElementCount) + if (i >= 0 && i < getElementCount()) { if (mData[i] == data) { //found it @@ -523,7 +476,8 @@ class LLOctreeNode : public LLTreeNode<T> void removeByAddress(T* data) { - for (U32 i = 0; i < mElementCount; ++i) + const U32 element_count = getElementCount(); + for (U32 i = 0; i < element_count; ++i) { if (mData[i] == data) { //we have data @@ -535,7 +489,7 @@ class LLOctreeNode : public LLTreeNode<T> for (U32 i = 0; i < getChildCount(); i++) { //we don't contain data, so pass this guy down - LLOctreeNode<T>* child = (LLOctreeNode<T>*) getChild(i); + oct_node* child = (oct_node*) getChild(i); child->removeByAddress(data); } } @@ -543,9 +497,7 @@ class LLOctreeNode : public LLTreeNode<T> void clearChildren() { mChildCount = 0; - - U32* foo = (U32*) mChildMap; - foo[0] = foo[1] = 0xFFFFFFFF; + memset(mChildMap, NO_CHILD_NODES, sizeof(mChildMap)); } void validate() @@ -636,11 +588,9 @@ class LLOctreeNode : public LLTreeNode<T> --mChildCount; mChild[index] = mChild[mChildCount]; - //rebuild child map - U32* foo = (U32*) mChildMap; - foo[0] = foo[1] = 0xFFFFFFFF; + memset(mChildMap, NO_CHILD_NODES, sizeof(mChildMap)); for (U32 i = 0; i < mChildCount; ++i) { @@ -676,7 +626,7 @@ class LLOctreeNode : public LLTreeNode<T> OCT_ERRS << "Octree failed to delete requested child." << LL_ENDL; } -protected: +protected: typedef enum { CENTER = 0, @@ -693,23 +643,20 @@ class LLOctreeNode : public LLTreeNode<T> oct_node* mParent; U8 mOctant; - LLOctreeNode<T>* mChild[8]; + oct_node* mChild[8]; U8 mChildMap[8]; U32 mChildCount; element_list mData; - element_iter mDataEnd; - U32 mElementCount; - }; //just like a regular node, except it might expand on insert and compress on balance -template <class T> -class LLOctreeRoot : public LLOctreeNode<T> +template <class T, typename T_PTR> +class LLOctreeRoot : public LLOctreeNode<T, T_PTR> { public: - typedef LLOctreeNode<T> BaseType; - typedef LLOctreeNode<T> oct_node; + typedef LLOctreeNode<T, T_PTR> BaseType; + typedef LLOctreeNode<T, T_PTR> oct_node; LLOctreeRoot(const LLVector4a& center, const LLVector4a& size, @@ -717,48 +664,14 @@ class LLOctreeRoot : public LLOctreeNode<T> : BaseType(center, size, parent) { } - -#if LL_OCTREE_POOLS - void* operator new(size_t size) - { - return LLOctreeNode<T>::getPool(size).malloc(); - } - void* operator new[](size_t size) - { - return LLOctreeNode<T>::getPool(size).malloc(); - } - void operator delete(void* ptr) - { - LLOctreeNode<T>::getPool(sizeof(LLOctreeNode<T>)).free(ptr); - } - void operator delete[](void* ptr) - { - LLOctreeNode<T>::getPool(sizeof(LLOctreeNode<T>)).free(ptr); - } -#else - void* operator new(size_t size) - { - return ll_aligned_malloc_16(size); - } - void* operator new[](size_t size) - { - return ll_aligned_malloc_16(size); - } - void operator delete(void* ptr) - { - ll_aligned_free_16(ptr); - } - void operator delete[](void* ptr) - { - ll_aligned_free_16(ptr); - } -#endif - bool balance() + bool balance() override { + //LL_PROFILE_ZONE_NAMED_COLOR("Octree::balance()",OCTREE_DEBUG_COLOR_BALANCE); + if (this->getChildCount() == 1 && !(this->mChild[0]->isLeaf()) && - this->mChild[0]->getElementCount() == 0) + this->mChild[0]->getElementCount() == 0) { //if we have only one child and that child is an empty branch, make that child the root oct_node* child = this->mChild[0]; @@ -788,7 +701,7 @@ class LLOctreeRoot : public LLOctreeNode<T> } // LLOctreeRoot::insert - bool insert(T* data) + bool insert(T* data) override { if (data == NULL) { @@ -824,7 +737,7 @@ class LLOctreeRoot : public LLOctreeNode<T> oct_node* node = this->getNodeAt(data); if (node == this) { - LLOctreeNode<T>::insert(data); + oct_node::insert(data); } else if (node->isInside(data->getPositionGroup())) { @@ -844,13 +757,13 @@ class LLOctreeRoot : public LLOctreeNode<T> LLVector4a center, size; center = this->getCenter(); size = this->getSize(); - LLOctreeNode<T>::pushCenter(center, size, data); + oct_node::pushCenter(center, size, data); this->setCenter(center); size.mul(2.f); this->setSize(size); this->updateMinMax(); } - LLOctreeNode<T>::insert(data); + oct_node::insert(data); } else { @@ -862,7 +775,7 @@ class LLOctreeRoot : public LLOctreeNode<T> //expand this node LLVector4a newcenter(center); - LLOctreeNode<T>::pushCenter(newcenter, size, data); + oct_node::pushCenter(newcenter, size, data); this->setCenter(newcenter); LLVector4a size2 = size; size2.mul(2.f); @@ -872,11 +785,11 @@ class LLOctreeRoot : public LLOctreeNode<T> llassert(size[0] >= gOctreeMinSize); //copy our children to a new branch - LLOctreeNode<T>* newnode = new LLOctreeNode<T>(center, size, this); + oct_node* newnode = new oct_node(center, size, this); for (U32 i = 0; i < this->getChildCount(); i++) { - LLOctreeNode<T>* child = this->getChild(i); + oct_node* child = this->getChild(i); newnode->addChild(child); } @@ -891,13 +804,19 @@ class LLOctreeRoot : public LLOctreeNode<T> return false; } + + bool isLeaf() const override + { + // root can't be a leaf + return false; + } }; //======================== // LLOctreeTraveler //======================== -template <class T> -void LLOctreeTraveler<T>::traverse(const LLOctreeNode<T>* node) +template <class T, typename T_PTR> +void LLOctreeTraveler<T, T_PTR>::traverse(const LLOctreeNode<T, T_PTR>* node) { node->accept(this); for (U32 i = 0; i < node->getChildCount(); i++) @@ -906,8 +825,8 @@ void LLOctreeTraveler<T>::traverse(const LLOctreeNode<T>* node) } } -template <class T> -void LLOctreeTravelerDepthFirst<T>::traverse(const LLOctreeNode<T>* node) +template <class T, typename T_PTR> +void LLOctreeTravelerDepthFirst<T, T_PTR>::traverse(const LLOctreeNode<T, T_PTR>* node) { for (U32 i = 0; i < node->getChildCount(); i++) { diff --git a/indra/llmath/llrigginginfo.h b/indra/llmath/llrigginginfo.h index 54b9170ca8c0b392abd5bcf227efd418b999c8ad..9cd0b9c6b1538536253f20b132d616c8aaf6a04a 100644 --- a/indra/llmath/llrigginginfo.h +++ b/indra/llmath/llrigginginfo.h @@ -34,9 +34,9 @@ // Extents are in joint space // isRiggedTo is based on the state of all currently associated rigged meshes -LL_ALIGN_PREFIX(16) -class LLJointRiggingInfo +class alignas(16) LLJointRiggingInfo { + LL_ALIGN_NEW public: LLJointRiggingInfo(); bool isRiggedTo() const; @@ -45,31 +45,10 @@ class LLJointRiggingInfo const LLVector4a *getRiggedExtents() const; void merge(const LLJointRiggingInfo& other); - void* operator new(size_t size) - { - return ll_aligned_malloc_16(size); - } - - void operator delete(void* ptr) - { - ll_aligned_free_16(ptr); - } - - void* operator new[](size_t size) - { - return ll_aligned_malloc_16(size); - } - - void operator delete[](void* ptr) - { - ll_aligned_free_16(ptr); - } - - private: - LL_ALIGN_16(LLVector4a mRiggedExtents[2]); + LLVector4a mRiggedExtents[2]; bool mIsRiggedTo; -} LL_ALIGN_POSTFIX(16); +}; // For storing all the rigging info associated with a given avatar or // object, keyed by joint_num. diff --git a/indra/llmath/llvector4a.h b/indra/llmath/llvector4a.h index b84a454f6b17e0c9d1d2e627b1f5714fd8ec33dd..162a5372da604827fc43f7bad0a13949d3d74bab 100644 --- a/indra/llmath/llvector4a.h +++ b/indra/llmath/llvector4a.h @@ -47,12 +47,12 @@ class LLRotation; // of this writing, July 08, 2010) about getting it implemented before you resort to // LLVector3/LLVector4. ///////////////////////////////// -struct LLVector4a; -struct LLIVector4a; +class LLIVector4a; -struct alignas(16) LLVector4a +class alignas(16) LLVector4a { - friend struct LLIVector4a; + friend class LLIVector4a; + LL_ALIGN_NEW public: /////////////////////////////////// @@ -93,27 +93,6 @@ struct alignas(16) LLVector4a // Source and dest must be 16-byte aligned and size must be multiple of 16. static void memcpyNonAliased16(F32* __restrict dst, const F32* __restrict src, size_t bytes); - - void* operator new(size_t size) - { - return ll_aligned_malloc_16(size); - } - - void* operator new[](size_t size) - { - return ll_aligned_malloc_16(size); - } - - void operator delete(void* ptr) - { - ll_aligned_free_16(ptr); - } - - void operator delete[](void* ptr) - { - ll_aligned_free_16(ptr); - } - //////////////////////////////////// // CONSTRUCTORS //////////////////////////////////// @@ -168,10 +147,10 @@ struct alignas(16) LLVector4a // BASIC GET/SET //////////////////////////////////// - // Return a "this" as an F32 pointer. Do not use unless you have a very good reason. (Not sure? Ask Falcon) + // Return a "this" as an F32 pointer. inline F32* getF32ptr(); - // Return a "this" as a const F32 pointer. Do not use unless you have a very good reason. (Not sure? Ask Falcon) + // Return a "this" as a const F32 pointer. inline const F32* const getF32ptr() const; // Read-only access a single float in this vector. Do not use in proximity to any function call that manipulates @@ -400,10 +379,11 @@ inline std::ostream& operator<<(std::ostream& s, const LLVector4a& v) return s; } -LL_ALIGN_PREFIX(16) -struct LLIVector4a +class alignas(16) LLIVector4a { - friend struct LLVector4a; +public: + friend class LLVector4a; + LL_ALIGN_NEW // Constants // Return a vector of all zeros @@ -412,26 +392,6 @@ struct LLIVector4a return _mm_setzero_si128(); } - void* operator new(size_t size) - { - return ll_aligned_malloc_16(size); - } - - void* operator new[](size_t size) - { - return ll_aligned_malloc_16(size); - } - - void operator delete(void* ptr) - { - ll_aligned_free_16(ptr); - } - - void operator delete[](void* ptr) - { - ll_aligned_free_16(ptr); - } - //////////////////////////////////// // CONSTRUCTORS //////////////////////////////////// diff --git a/indra/llmath/llvector4a.inl b/indra/llmath/llvector4a.inl index bccda8a5f63019e090677dffc810f70bf9ab1d5c..3a69bcb14b1438d4b3b4a71cb5c7c862d823d3b5 100644 --- a/indra/llmath/llvector4a.inl +++ b/indra/llmath/llvector4a.inl @@ -58,13 +58,13 @@ inline void LLVector4a::store4a(F32* dst) const // BASIC GET/SET //////////////////////////////////// -// Return a "this" as an F32 pointer. Do not use unless you have a very good reason. (Not sure? Ask Falcon) +// Return a "this" as an F32 pointer. F32* LLVector4a::getF32ptr() { return (F32*) &mQ; } -// Return a "this" as a const F32 pointer. Do not use unless you have a very good reason. (Not sure? Ask Falcon) +// Return a "this" as a const F32 pointer. const F32* const LLVector4a::getF32ptr() const { return (const F32* const) &mQ; diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 8f6efe60472a099647b6c9b6572cb93482840ee4..f1892024abbfcb9dc800b2339fb74a96c5c30683 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -51,6 +51,7 @@ #include "llsdserialize.h" #include "llvector4a.h" #include "llmatrix4a.h" +#include "llmeshoptimizer.h" #include "lltimer.h" #define DEBUG_SILHOUETTE_BINORMALS 0 @@ -90,7 +91,7 @@ const F32 SKEW_MAX = 0.95f; const F32 SCULPT_MIN_AREA = 0.002f; const S32 SCULPT_MIN_AREA_DETAIL = 1; -BOOL gDebugGL = FALSE; +BOOL gDebugGL = FALSE; // See settings.xml "RenderDebugGL" BOOL check_same_clock_dir( const LLVector3& pt1, const LLVector3& pt2, const LLVector3& pt3, const LLVector3& norm) { @@ -372,7 +373,7 @@ BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, cons } } -class LLVolumeOctreeRebound : public LLOctreeTravelerDepthFirst<LLVolumeTriangle> +class LLVolumeOctreeRebound : public LLOctreeTravelerDepthFirst<LLVolumeTriangle, LLVolumeTriangle*> { public: const LLVolumeFace* mFace; @@ -382,9 +383,10 @@ class LLVolumeOctreeRebound : public LLOctreeTravelerDepthFirst<LLVolumeTriangle mFace = face; } - virtual void visit(const LLOctreeNode<LLVolumeTriangle>* branch) + virtual void visit(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* branch) { //this is a depth first traversal, so it's safe to assum all children have complete //bounding data + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME LLVolumeOctreeListener* node = (LLVolumeOctreeListener*) branch->getListener(0); @@ -399,8 +401,7 @@ class LLVolumeOctreeRebound : public LLOctreeTravelerDepthFirst<LLVolumeTriangle min = *(tri->mV[0]); max = *(tri->mV[0]); - for (LLOctreeNode<LLVolumeTriangle>::const_element_iter iter = - branch->getDataBegin(), iter_end = branch->getDataEnd(); iter != iter_end; ++iter) + for (LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>::const_element_iter iter = branch->getDataBegin(); iter != branch->getDataEnd(); ++iter) { //for each triangle in node //stretch by triangles in node @@ -415,7 +416,7 @@ class LLVolumeOctreeRebound : public LLOctreeTravelerDepthFirst<LLVolumeTriangle max.setMax(max, *tri->mV[2]); } } - else if (!branch->isLeaf()) + else if (branch->getChildCount() > 0) { //no data, but child nodes exist LLVolumeOctreeListener* child = (LLVolumeOctreeListener*) branch->getChild(0)->getListener(0); @@ -425,7 +426,7 @@ class LLVolumeOctreeRebound : public LLOctreeTravelerDepthFirst<LLVolumeTriangle } else { - LL_ERRS() << "Empty leaf" << LL_ENDL; + llassert(!branch->isLeaf()); // Empty leaf } for (S32 i = 0; i < branch->getChildCount(); ++i) @@ -682,7 +683,7 @@ LLProfile::Face* LLProfile::addHole(const LLProfileParams& params, BOOL flat, F3 Face *face = addFace(mTotalOut, mTotal-mTotalOut,0,LL_FACE_INNER_SIDE, flat); - static LLAlignedArray<LLVector4a,64> pt; + static thread_local LLAlignedArray<LLVector4a,64> pt; pt.resize(mTotal) ; for (S32 i=mTotalOut;i<mTotal;i++) @@ -822,6 +823,8 @@ S32 LLProfile::getNumPoints(const LLProfileParams& params, BOOL path_open,F32 de BOOL LLProfile::generate(const LLProfileParams& params, BOOL path_open,F32 detail, S32 split, BOOL is_sculpted, S32 sculpt_size) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME + if ((!mDirty) && (!is_sculpted)) { return FALSE; @@ -1298,6 +1301,8 @@ S32 LLPath::getNumNGonPoints(const LLPathParams& params, S32 sides, F32 startOff void LLPath::genNGon(const LLPathParams& params, S32 sides, F32 startOff, F32 end_scale, F32 twist_scale) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME + // Generates a circular path, starting at (1, 0, 0), counterclockwise along the xz plane. static const F32 tableScale[] = { 1, 1, 1, 0.5f, 0.707107f, 0.53f, 0.525f, 0.5f }; @@ -1533,6 +1538,8 @@ S32 LLPath::getNumPoints(const LLPathParams& params, F32 detail) BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split, BOOL is_sculpted, S32 sculpt_size) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME + if ((!mDirty) && (!is_sculpted)) { return FALSE; @@ -2100,6 +2107,8 @@ LLVolume::~LLVolume() BOOL LLVolume::generate() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME + LL_CHECK_MEMORY llassert_always(mProfilep); @@ -2361,6 +2370,8 @@ bool LLVolumeFace::VertexData::compareNormal(const LLVolumeFace::VertexData& rhs bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME + //input stream is now pointing at a zlib compressed block of LLSD //decompress block LLSD mdl; @@ -2424,6 +2435,13 @@ bool LLVolume::unpackVolumeFacesInternal(const LLSD& mdl) //copy out indices S32 num_indices = idx.size() / 2; + const S32 indices_to_discard = num_indices % 3; + if (indices_to_discard > 0) + { + // Invalid number of triangle indices + LL_WARNS() << "Incomplete triangle discarded from face! Indices count " << num_indices << " was not divisible by 3. face index: " << i << " Total: " << face_count << LL_ENDL; + num_indices -= indices_to_discard; + } face.resizeIndices(num_indices); if (num_indices > 2 && !face.mIndices) @@ -2439,8 +2457,7 @@ bool LLVolume::unpackVolumeFacesInternal(const LLSD& mdl) } U16* indices = (U16*) &(idx[0]); - U32 count = idx.size()/2; - for (U32 j = 0; j < count; ++j) + for (U32 j = 0; j < num_indices; ++j) { face.mIndices[j] = indices[j]; } @@ -2785,6 +2802,8 @@ S32 LLVolume::getNumFaces() const void LLVolume::createVolumeFaces() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME + if (mGenerateSingleFace) { // do nothing @@ -3772,6 +3791,8 @@ void LLVolume::generateSilhouetteVertices(std::vector<LLVector3> &vertices, const LLMatrix4a& norm_mat, S32 face_mask) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME + LLVector4a obj_cam_vec; obj_cam_vec.load3(obj_cam_vec_in.mV); @@ -3844,8 +3865,8 @@ void LLVolume::generateSilhouetteVertices(std::vector<LLVector3> &vertices, #if DEBUG_SILHOUETTE_EDGE_MAP //for each triangle - U32 count = face.mNumIndices; - for (U32 j = 0; j < count/3; j++) { + U32 tri_count = face.mNumIndices / 3; + for (U32 j = 0; j < tri_count; j++) { //get vertices S32 v1 = face.mIndices[j*3+0]; S32 v2 = face.mIndices[j*3+1]; @@ -3863,7 +3884,7 @@ void LLVolume::generateSilhouetteVertices(std::vector<LLVector3> &vertices, continue; } - if (nIndex >= (S32) count/3) { + if (nIndex >= (S32)tri_count) { continue; } //get neighbor vertices @@ -4155,13 +4176,13 @@ S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& en } else { - if (!face.mOctree) + if (!face.getOctree()) { face.createOctree(); } LLOctreeTriangleRayIntersect intersect(start, dir, &face, &closest_t, intersection, tex_coord, normal, tangent_out); - intersect.traverse(face.mOctree); + intersect.traverse(face.getOctree()); if (intersect.mHitFace) { hit_face = i; @@ -4710,6 +4731,7 @@ LLVolumeFace::LLVolumeFace() : mWeights(NULL), mWeightsScrubbed(FALSE), mOctree(NULL), + mOctreeTriangles(NULL), mOptimized(FALSE) { mExtents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*3); @@ -4736,8 +4758,9 @@ LLVolumeFace::LLVolumeFace(const LLVolumeFace& src) mWeights(NULL), mWeightsScrubbed(FALSE), mOctree(NULL), + mOctreeTriangles(NULL), mOptimized(FALSE) -{ +{ mExtents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*3); mCenter = mExtents+2; *this = src; @@ -4833,15 +4856,15 @@ void LLVolumeFace::freeData() allocateWeights(0); allocateIndices(0); - delete mOctree; - mOctree = NULL; + destroyOctree(); } BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME + //tree for this face is no longer valid - delete mOctree; - mOctree = NULL; + destroyOctree(); LL_CHECK_MEMORY BOOL ret = FALSE ; @@ -4907,6 +4930,50 @@ bool LLVolumeFace::VertexMapData::ComparePosition::operator()(const LLVector3& a return a.mV[2] < b.mV[2]; } +void LLVolumeFace::remap() +{ + // Generate a remap buffer + std::vector<unsigned int> remap(mNumVertices); + S32 remap_vertices_count = LLMeshOptimizer::generateRemapMultiU16(&remap[0], + mIndices, + mNumIndices, + mPositions, + mNormals, + mTexCoords, + mNumVertices); + + // Allocate new buffers + S32 size = ((mNumIndices * sizeof(U16)) + 0xF) & ~0xF; + U16* remap_indices = (U16*)ll_aligned_malloc_16(size); + + S32 tc_bytes_size = ((remap_vertices_count * sizeof(LLVector2)) + 0xF) & ~0xF; + LLVector4a* remap_positions = (LLVector4a*)ll_aligned_malloc<64>(sizeof(LLVector4a) * 2 * remap_vertices_count + tc_bytes_size); + LLVector4a* remap_normals = remap_positions + remap_vertices_count; + LLVector2* remap_tex_coords = (LLVector2*)(remap_normals + remap_vertices_count); + + // Fill the buffers + LLMeshOptimizer::remapIndexBufferU16(remap_indices, mIndices, mNumIndices, &remap[0]); + LLMeshOptimizer::remapPositionsBuffer(remap_positions, mPositions, mNumVertices, &remap[0]); + LLMeshOptimizer::remapNormalsBuffer(remap_normals, mNormals, mNumVertices, &remap[0]); + LLMeshOptimizer::remapUVBuffer(remap_tex_coords, mTexCoords, mNumVertices, &remap[0]); + + // Free unused buffers + ll_aligned_free_16(mIndices); + ll_aligned_free<64>(mPositions); + + // Tangets are now invalid + ll_aligned_free_16(mTangents); + mTangents = NULL; + + // Assign new values + mIndices = remap_indices; + mPositions = remap_positions; + mNormals = remap_normals; + mTexCoords = remap_tex_coords; + mNumVertices = remap_vertices_count; + mNumAllocatedVertices = remap_vertices_count; +} + void LLVolumeFace::optimize(F32 angle_cutoff) { LLVolumeFace new_face; @@ -5400,21 +5467,29 @@ bool LLVolumeFace::cacheOptimize() void LLVolumeFace::createOctree(F32 scaler, const LLVector4a& center, const LLVector4a& size) { - if (mOctree) + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME + + if (getOctree()) { return; } - mOctree = new LLOctreeRoot<LLVolumeTriangle>(center, size, NULL); + llassert(mNumIndices % 3 == 0); + + mOctree = new LLOctreeRoot<LLVolumeTriangle, LLVolumeTriangle*>(center, size, NULL); new LLVolumeOctreeListener(mOctree); + const U32 num_triangles = mNumIndices / 3; + // Initialize all the triangles we need + mOctreeTriangles = new LLVolumeTriangle[num_triangles]; - for (U32 i = 0; i < mNumIndices; i+= 3) + for (U32 triangle_index = 0; triangle_index < num_triangles; ++triangle_index) { //for each triangle - LLPointer<LLVolumeTriangle> tri = new LLVolumeTriangle(); + const U32 index = triangle_index * 3; + LLVolumeTriangle* tri = &mOctreeTriangles[triangle_index]; - const LLVector4a& v0 = mPositions[mIndices[i]]; - const LLVector4a& v1 = mPositions[mIndices[i+1]]; - const LLVector4a& v2 = mPositions[mIndices[i+2]]; + const LLVector4a& v0 = mPositions[mIndices[index]]; + const LLVector4a& v1 = mPositions[mIndices[index + 1]]; + const LLVector4a& v2 = mPositions[mIndices[index + 2]]; //store pointers to vertex data tri->mV[0] = &v0; @@ -5422,9 +5497,9 @@ void LLVolumeFace::createOctree(F32 scaler, const LLVector4a& center, const LLVe tri->mV[2] = &v2; //store indices - tri->mIndex[0] = mIndices[i]; - tri->mIndex[1] = mIndices[i+1]; - tri->mIndex[2] = mIndices[i+2]; + tri->mIndex[0] = mIndices[index]; + tri->mIndex[1] = mIndices[index + 1]; + tri->mIndex[2] = mIndices[index + 2]; //get minimum point LLVector4a min = v0; @@ -5467,6 +5542,19 @@ void LLVolumeFace::createOctree(F32 scaler, const LLVector4a& center, const LLVe } } +void LLVolumeFace::destroyOctree() +{ + delete mOctree; + mOctree = NULL; + delete[] mOctreeTriangles; + mOctreeTriangles = NULL; +} + +const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* LLVolumeFace::getOctree() const +{ + return mOctree; +} + void LLVolumeFace::swapData(LLVolumeFace& rhs) { @@ -6183,6 +6271,8 @@ void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVe void LLVolumeFace::createTangents() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME + if (!mTangents) { allocateTangents(mNumVertices); @@ -6344,6 +6434,7 @@ bool LLVolumeFace::allocateVertices(S32 num_verts, bool copy) bool LLVolumeFace::allocateIndices(S32 num_indices, bool copy) { + llassert(num_indices % 3 == 0); if (num_indices == mNumIndices) { return true; @@ -6420,6 +6511,8 @@ void LLVolumeFace::fillFromLegacyData(std::vector<LLVolumeFace::VertexData>& v, BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME + LL_CHECK_MEMORY BOOL flat = mTypeMask & FLAT_MASK; @@ -6495,13 +6588,19 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) else { // Get s value for tex-coord. - if (!flat) + S32 index = mBeginS + s; + if (index >= profile.size()) + { + // edge? + ss = flat ? 1.f - begin_stex : 1.f; + } + else if (!flat) { - ss = profile[mBeginS + s][2]; + ss = profile[index][2]; } else { - ss = profile[mBeginS + s][2] - begin_stex; + ss = profile[index][2] - begin_stex; } } @@ -6687,7 +6786,7 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) LLVector4a* norm = mNormals; - static LLAlignedArray<LLVector4a, 64> triangle_normals; + static thread_local LLAlignedArray<LLVector4a, 64> triangle_normals; try { triangle_normals.resize(count); @@ -6928,6 +7027,8 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal, const LLVector2 *texcoord, U32 triangleCount, const U16* index_array, LLVector4a *tangent) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME + //LLVector4a *tan1 = new LLVector4a[vertexCount * 2]; LLVector4a* tan1 = (LLVector4a*) ll_aligned_malloc_16(vertexCount*2*sizeof(LLVector4a)); // new(tan1) LLVector4a; diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index 67f7f48e9c89847ca4500b8240fb4bc174939bf2..cd2547e943b71bea3413abf4f6082bd12ea0a32a 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -35,7 +35,8 @@ class LLVolumeParams; class LLProfile; class LLPath; -template <class T> class LLOctreeNode; +template<class T> class LLPointer; +template <class T, typename T_PTR> class LLOctreeNode; class LLVolumeFace; class LLVolume; @@ -906,10 +907,17 @@ class LLVolumeFace typedef std::map<LLVector3, std::vector<VertexMapData>, VertexMapData::ComparePosition > PointMap; }; + // Eliminates non unique triangles, takes positions, + // normals and texture coordinates into account. + void remap(); + void optimize(F32 angle_cutoff = 2.f); bool cacheOptimize(); void createOctree(F32 scaler = 0.25f, const LLVector4a& center = LLVector4a(0,0,0), const LLVector4a& size = LLVector4a(0.5f,0.5f,0.5f)); + void destroyOctree(); + // Get a reference to the octree, which may be null + const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* getOctree() const; enum { @@ -940,17 +948,23 @@ class LLVolumeFace LLVector4a* mCenter; LLVector2 mTexCoordExtents[2]; //minimum and maximum of texture coordinates of the face. - S32 mNumVertices; + S32 mNumVertices; // num vertices == num normals == num texcoords S32 mNumAllocatedVertices; S32 mNumIndices; - LLVector4a* mPositions; - LLVector4a* mNormals; + LLVector4a* mPositions; // Contains vertices, nortmals and texcoords + LLVector4a* mNormals; // pointer into mPositions LLVector4a* mTangents; - LLVector2* mTexCoords; + LLVector2* mTexCoords; // pointer into mPositions + + // mIndices contains mNumIndices amount of elements. + // It contains triangles, each 3 indices describe one triangle. + // If mIndices contains {0, 2, 3, 1, 2, 4}, it means there + // are two triangles {0, 2, 3} and {1, 2, 4} with values being + // indexes for mPositions/mNormals/mTexCoords U16* mIndices; - //vertex buffer filled in by LLFace to cache this volume face geometry in vram + // vertex buffer filled in by LLFace to cache this volume face geometry in vram // (declared as a LLPointer to LLRefCount to avoid dependency on LLVertexBuffer) mutable LLPointer<LLRefCount> mVertexBuffer; @@ -966,13 +980,14 @@ class LLVolumeFace // Which joints are rigged to, and the bounding box of any rigged // vertices per joint. LLJointRiggingInfoTab mJointRiggingInfoTab; - - LLOctreeNode<LLVolumeTriangle>* mOctree; //whether or not face has been cache optimized BOOL mOptimized; private: + LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* mOctree; + LLVolumeTriangle* mOctreeTriangles; + BOOL createUnCutCubeCap(LLVolume* volume, BOOL partial_build = FALSE); BOOL createCap(LLVolume* volume, BOOL partial_build = FALSE); BOOL createSide(LLVolume* volume, BOOL partial_build = FALSE); diff --git a/indra/llmath/llvolumeoctree.cpp b/indra/llmath/llvolumeoctree.cpp index 0c83cb6e4f1df3c2d0a1b64029191851e297e51c..e753cc688c33dae45f1fd53ca4e9ce57c9743423 100644 --- a/indra/llmath/llvolumeoctree.cpp +++ b/indra/llmath/llvolumeoctree.cpp @@ -75,18 +75,17 @@ BOOL LLLineSegmentBoxIntersect(const LLVector4a& start, const LLVector4a& end, c } -LLVolumeOctreeListener::LLVolumeOctreeListener(LLOctreeNode<LLVolumeTriangle>* node) +LLVolumeOctreeListener::LLVolumeOctreeListener(LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* node) { node->addListener(this); } -void LLVolumeOctreeListener::handleChildAddition(const LLOctreeNode<LLVolumeTriangle>* parent, - LLOctreeNode<LLVolumeTriangle>* child) +void LLVolumeOctreeListener::handleChildAddition(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* parent, + LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* child) { new LLVolumeOctreeListener(child); } - LLOctreeTriangleRayIntersect::LLOctreeTriangleRayIntersect(const LLVector4a& start, const LLVector4a& dir, const LLVolumeFace* face, F32* closest_t, LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent) @@ -103,7 +102,7 @@ LLOctreeTriangleRayIntersect::LLOctreeTriangleRayIntersect(const LLVector4a& sta mEnd.setAdd(mStart, mDir); } -void LLOctreeTriangleRayIntersect::traverse(const LLOctreeNode<LLVolumeTriangle>* node) +void LLOctreeTriangleRayIntersect::traverse(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* node) { LLVolumeOctreeListener* vl = (LLVolumeOctreeListener*) node->getListener(0); @@ -117,9 +116,9 @@ void LLOctreeTriangleRayIntersect::traverse(const LLOctreeNode<LLVolumeTriangle> } } -void LLOctreeTriangleRayIntersect::visit(const LLOctreeNode<LLVolumeTriangle>* node) +void LLOctreeTriangleRayIntersect::visit(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* node) { - for (LLOctreeNode<LLVolumeTriangle>::const_element_iter iter = + for (typename LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>::const_element_iter iter = node->getDataBegin(), iter_end = node->getDataEnd(); iter != iter_end; ++iter) { const LLVolumeTriangle* tri = *iter; @@ -214,7 +213,7 @@ const F32& LLVolumeTriangle::getBinRadius() const //TEST CODE -void LLVolumeOctreeValidate::visit(const LLOctreeNode<LLVolumeTriangle>* branch) +void LLVolumeOctreeValidate::visit(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* branch) { LLVolumeOctreeListener* node = (LLVolumeOctreeListener*) branch->getListener(0); @@ -251,7 +250,7 @@ void LLVolumeOctreeValidate::visit(const LLOctreeNode<LLVolumeTriangle>* branch) } //children fit, check data - for (LLOctreeNode<LLVolumeTriangle>::const_element_iter iter = branch->getDataBegin(), iter_end = branch->getDataEnd(); + for (typename LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>::const_element_iter iter = branch->getDataBegin(), iter_end = branch->getDataEnd(); iter != iter_end; ++iter) { const LLVolumeTriangle* tri = *iter; @@ -268,4 +267,3 @@ void LLVolumeOctreeValidate::visit(const LLOctreeNode<LLVolumeTriangle>* branch) } } - diff --git a/indra/llmath/llvolumeoctree.h b/indra/llmath/llvolumeoctree.h index 9967548ae7eda5d038024104506f65e14c76b994..7bb158a895f69fec75cb6a5998f190f489e4ff82 100644 --- a/indra/llmath/llvolumeoctree.h +++ b/indra/llmath/llvolumeoctree.h @@ -34,19 +34,10 @@ #include "llvolume.h" #include "llvector4a.h" -class LLVolumeTriangle final : public LLRefCount +class alignas(16) LLVolumeTriangle final : public LLRefCount { + LL_ALIGN_NEW public: - void* operator new(size_t size) - { - return ll_aligned_malloc_16(size); - } - - void operator delete(void* ptr) - { - ll_aligned_free_16(ptr); - } - LLVolumeTriangle() { mBinIndex = -1; @@ -75,32 +66,20 @@ class LLVolumeTriangle final : public LLRefCount }; -class LLVolumeOctreeListener final : public LLOctreeListener<LLVolumeTriangle> +class alignas(16) LLVolumeOctreeListener final : public LLOctreeListener<LLVolumeTriangle, LLVolumeTriangle*> { + LL_ALIGN_NEW public: - - void* operator new(size_t size) - { - return ll_aligned_malloc_16(size); - } - - void operator delete(void* ptr) - { - ll_aligned_free_16(ptr); - } - - LLVolumeOctreeListener(LLOctreeNode<LLVolumeTriangle>* node); + LLVolumeOctreeListener(LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* node); ~LLVolumeOctreeListener() = default; LLVolumeOctreeListener(const LLVolumeOctreeListener& rhs) = delete; LLVolumeOctreeListener& operator=(const LLVolumeOctreeListener& rhs) = delete; //LISTENER FUNCTIONS - virtual void handleChildAddition(const LLOctreeNode<LLVolumeTriangle>* parent, - LLOctreeNode<LLVolumeTriangle>* child); + virtual void handleChildAddition(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* parent, LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* child); virtual void handleStateChange(const LLTreeNode<LLVolumeTriangle>* node) { } - virtual void handleChildRemoval(const LLOctreeNode<LLVolumeTriangle>* parent, - const LLOctreeNode<LLVolumeTriangle>* child) { } + virtual void handleChildRemoval(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* parent, const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* child) { } virtual void handleInsertion(const LLTreeNode<LLVolumeTriangle>* node, LLVolumeTriangle* tri) { } virtual void handleRemoval(const LLTreeNode<LLVolumeTriangle>* node, LLVolumeTriangle* tri) { } virtual void handleDestruction(const LLTreeNode<LLVolumeTriangle>* node) { } @@ -111,7 +90,7 @@ class LLVolumeOctreeListener final : public LLOctreeListener<LLVolumeTriangle> LL_ALIGN_16(LLVector4a mExtents[2]); // extents (min, max) of this node and all its children }; -class LLOctreeTriangleRayIntersect : public LLOctreeTraveler<LLVolumeTriangle> +class LLOctreeTriangleRayIntersect : public LLOctreeTraveler<LLVolumeTriangle, LLVolumeTriangle*> { public: const LLVolumeFace* mFace; @@ -129,14 +108,14 @@ class LLOctreeTriangleRayIntersect : public LLOctreeTraveler<LLVolumeTriangle> const LLVolumeFace* face, F32* closest_t, LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent); - void traverse(const LLOctreeNode<LLVolumeTriangle>* node); + void traverse(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* node); - virtual void visit(const LLOctreeNode<LLVolumeTriangle>* node); + virtual void visit(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* node); }; -class LLVolumeOctreeValidate final : public LLOctreeTraveler<LLVolumeTriangle> +class LLVolumeOctreeValidate final : public LLOctreeTraveler<LLVolumeTriangle, LLVolumeTriangle*> { - virtual void visit(const LLOctreeNode<LLVolumeTriangle>* branch); + virtual void visit(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* branch); }; #endif diff --git a/indra/llmath/m4math.cpp b/indra/llmath/m4math.cpp index 7cd9625ed4a090e8613743b54de045c5662bd309..fda6d9e37690333ac35b27fad3941c9d085a9f99 100644 --- a/indra/llmath/m4math.cpp +++ b/indra/llmath/m4math.cpp @@ -32,8 +32,7 @@ #include "m4math.h" #include "m3math.h" #include "llquaternion.h" - - +#include "llmatrix4a.h" // LLMatrix4 @@ -115,6 +114,12 @@ LLMatrix4::LLMatrix4(const LLQuaternion &q) *this = initRotation(q); } +LLMatrix4::LLMatrix4(const LLMatrix4a& mat) + : LLMatrix4(mat.getF32ptr()) +{ + +} + LLMatrix4::LLMatrix4(const LLQuaternion &q, const LLVector4 &pos) { *this = initRotTrans(q, pos); diff --git a/indra/llmath/m4math.h b/indra/llmath/m4math.h index cc5ae638c63e570eeece721034a81bf3163c3e48..4773ddc03501f68c8da9d096c1e03dcad43396b3 100644 --- a/indra/llmath/m4math.h +++ b/indra/llmath/m4math.h @@ -32,6 +32,7 @@ class LLVector4; class LLMatrix3; class LLQuaternion; +class LLMatrix4a; // NOTA BENE: Currently assuming a right-handed, x-forward, y-left, z-up universe @@ -110,6 +111,7 @@ class LLMatrix4 explicit LLMatrix4(const F32 *mat); // Initializes Matrix to values in mat explicit LLMatrix4(const LLMatrix3 &mat); // Initializes Matrix to values in mat and sets position to (0,0,0) explicit LLMatrix4(const LLQuaternion &q); // Initializes Matrix with rotation q and sets position to (0,0,0) + explicit LLMatrix4(const LLMatrix4a& mat); LLMatrix4(const LLMatrix3 &mat, const LLVector4 &pos); // Initializes Matrix to values in mat and pos diff --git a/indra/llmath/v3math.cpp b/indra/llmath/v3math.cpp index b04c67d92631fac6535c0f161631487c66c66e1f..93010d2250a6471d717f7a2460280a256353fec6 100644 --- a/indra/llmath/v3math.cpp +++ b/indra/llmath/v3math.cpp @@ -316,6 +316,12 @@ LLVector3::LLVector3(const LLVector4 &vec) mV[VZ] = (F32)vec.mV[VZ]; } +LLVector3::LLVector3(const LLVector4a& vec) + : LLVector3(vec.getF32ptr()) +{ + +} + LLVector3::LLVector3(const LLSD& sd) { setValue(sd); diff --git a/indra/llmath/v3math.h b/indra/llmath/v3math.h index 270e098c077c2be7125f74748a60ad922f664fc1..8b9d60b437fb9028f7b8f041733ebbb83c670194 100644 --- a/indra/llmath/v3math.h +++ b/indra/llmath/v3math.h @@ -33,6 +33,7 @@ #include "llsd.h" class LLVector2; class LLVector4; +class LLVector4a; class LLMatrix3; class LLMatrix4; class LLVector3d; @@ -62,7 +63,9 @@ class LLVector3 explicit LLVector3(const LLVector2 &vec); // Initializes LLVector3 to (vec[0]. vec[1], 0) explicit LLVector3(const LLVector3d &vec); // Initializes LLVector3 to (vec[0]. vec[1], vec[2]) explicit LLVector3(const LLVector4 &vec); // Initializes LLVector4 to (vec[0]. vec[1], vec[2]) - explicit LLVector3(const LLSD& sd); + explicit LLVector3(const LLVector4a& vec); // Initializes LLVector4 to (vec[0]. vec[1], vec[2]) + explicit LLVector3(const LLSD& sd); + LLSD getValue() const; diff --git a/indra/llmeshoptimizer/CMakeLists.txt b/indra/llmeshoptimizer/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..652fe6ed6f3d39dd3f3256300244ea3c254fbf64 --- /dev/null +++ b/indra/llmeshoptimizer/CMakeLists.txt @@ -0,0 +1,43 @@ +# -*- cmake -*- + +project(llmeshoptimizer) + +include(MESHOPTIMIZER) + +include(00-Common) +include(LLCommon) +include(LLMath) + +include_directories( + ${LLCOMMON_INCLUDE_DIRS} + ${LLMATH_INCLUDE_DIRS} + ${LLMESHOPTIMIZER_INCLUDE_DIR} + ${LIBS_PREBUILT_DIR}/include #access to boost headers, needed for LLError + ) + +set(llmeshoptimizer_SOURCE_FILES + llmeshoptimizer.cpp + ) + +set(llmeshoptimizer_HEADER_FILES + CMakeLists.txt + + llmeshoptimizer.h + ) + +set_source_files_properties(${llmeshoptimizer_HEADER_FILES} + PROPERTIES HEADER_FILE_ONLY TRUE) + +list(APPEND llmeshoptimizer_SOURCE_FILES ${llmeshoptimizer_HEADER_FILES}) + +#if (USE_MESHOPT) + add_library (llmeshoptimizer ${llmeshoptimizer_SOURCE_FILES}) + + target_link_libraries(llmeshoptimizer + ${LLCOMMON_LIBRARIES} + ${LLMATH_LIBRARIES} + meshoptimizer) + + # Add tests + +#endif (USE_MESHOPT) diff --git a/indra/llmeshoptimizer/llmeshoptimizer.cpp b/indra/llmeshoptimizer/llmeshoptimizer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c178348968c24599183bec3b560686f32afd1534 --- /dev/null +++ b/indra/llmeshoptimizer/llmeshoptimizer.cpp @@ -0,0 +1,339 @@ + /** +* @file llmeshoptimizer.cpp +* @brief Wrapper around meshoptimizer +* +* $LicenseInfo:firstyear=2021&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2021, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ + +#include "llmeshoptimizer.h" + +#include "meshoptimizer.h" + +#include "llmath.h" +#include "v2math.h" + +LLMeshOptimizer::LLMeshOptimizer() +{ + // Todo: Looks like for memory management, we can add allocator and deallocator callbacks + // Should be one time + // meshopt_setAllocator(allocate, deallocate); +} + +LLMeshOptimizer::~LLMeshOptimizer() +{ +} + +//static +void LLMeshOptimizer::generateShadowIndexBufferU32(U32 *destination, + const U32 *indices, + U64 index_count, + const LLVector4a * vertex_positions, + const LLVector4a * normals, + const LLVector2 * text_coords, + U64 vertex_count +) +{ + meshopt_Stream streams[3]; + + S32 index = 0; + if (vertex_positions) + { + streams[index].data = (const float*)vertex_positions; + // Despite being LLVector4a, only x, y and z are in use + streams[index].size = sizeof(F32) * 3; + streams[index].stride = sizeof(F32) * 4; + index++; + } + if (normals) + { + streams[index].data = (const float*)normals; + streams[index].size = sizeof(F32) * 3; + streams[index].stride = sizeof(F32) * 4; + index++; + } + if (text_coords) + { + streams[index].data = (const float*)text_coords; + streams[index].size = sizeof(F32) * 2; + streams[index].stride = sizeof(F32) * 2; + index++; + } + + if (index == 0) + { + // invalid + return; + } + + meshopt_generateShadowIndexBufferMulti<unsigned int>(destination, + indices, + index_count, + vertex_count, + streams, + index + ); +} + +//static +void LLMeshOptimizer::generateShadowIndexBufferU16(U16 *destination, + const U16 *indices, + U64 index_count, + const LLVector4a * vertex_positions, + const LLVector4a * normals, + const LLVector2 * text_coords, + U64 vertex_count +) +{ + meshopt_Stream streams[3]; + + S32 index = 0; + if (vertex_positions) + { + streams[index].data = (const float*)vertex_positions; + streams[index].size = sizeof(F32) * 3; + streams[index].stride = sizeof(F32) * 4; + index++; + } + if (normals) + { + streams[index].data = (const float*)normals; + streams[index].size = sizeof(F32) * 3; + streams[index].stride = sizeof(F32) * 4; + index++; + } + if (text_coords) + { + streams[index].data = (const float*)text_coords; + streams[index].size = sizeof(F32) * 2; + streams[index].stride = sizeof(F32) * 2; + index++; + } + + if (index == 0) + { + // invalid + return; + } + + meshopt_generateShadowIndexBufferMulti<unsigned short>(destination, + indices, + index_count, + vertex_count, + streams, + index); +} + +void LLMeshOptimizer::optimizeVertexCacheU32(U32 * destination, const U32 * indices, U64 index_count, U64 vertex_count) +{ + meshopt_optimizeVertexCache<unsigned int>(destination, indices, index_count, vertex_count); +} + +void LLMeshOptimizer::optimizeVertexCacheU16(U16 * destination, const U16 * indices, U64 index_count, U64 vertex_count) +{ + meshopt_optimizeVertexCache<unsigned short>(destination, indices, index_count, vertex_count); +} + +size_t LLMeshOptimizer::generateRemapMultiU32( + unsigned int* remap, + const U32 * indices, + U64 index_count, + const LLVector4a * vertex_positions, + const LLVector4a * normals, + const LLVector2 * text_coords, + U64 vertex_count) +{ + meshopt_Stream streams[] = { + {(const float*)vertex_positions, sizeof(F32) * 3, sizeof(F32) * 4}, + {(const float*)normals, sizeof(F32) * 3, sizeof(F32) * 4}, + {(const float*)text_coords, sizeof(F32) * 2, sizeof(F32) * 2}, + }; + + // Remap can function without indices, + // but providing indices helps with removing unused vertices + U64 indeces_cmp = indices ? index_count : vertex_count; + + // meshopt_generateVertexRemapMulti will throw an assert if (indices[i] >= vertex_count) + return meshopt_generateVertexRemapMulti(&remap[0], indices, indeces_cmp, vertex_count, streams, sizeof(streams) / sizeof(streams[0])); +} + +size_t LLMeshOptimizer::generateRemapMultiU16( + unsigned int* remap, + const U16 * indices, + U64 index_count, + const LLVector4a * vertex_positions, + const LLVector4a * normals, + const LLVector2 * text_coords, + U64 vertex_count) +{ + S32 out_of_range_count = 0; + U32* indices_u32 = NULL; + if (indices) + { + indices_u32 = (U32*)ll_aligned_malloc_32(index_count * sizeof(U32)); + for (U64 i = 0; i < index_count; i++) + { + if (indices[i] < vertex_count) + { + indices_u32[i] = (U32)indices[i]; + } + else + { + out_of_range_count++; + indices_u32[i] = 0; + } + } + } + + if (out_of_range_count) + { + LL_WARNS() << out_of_range_count << " indices are out of range." << LL_ENDL; + } + + size_t unique = generateRemapMultiU32(remap, indices_u32, index_count, vertex_positions, normals, text_coords, vertex_count); + + ll_aligned_free_32(indices_u32); + + return unique; +} + +void LLMeshOptimizer::remapIndexBufferU32(U32 * destination_indices, + const U32 * indices, + U64 index_count, + const unsigned int* remap) +{ + meshopt_remapIndexBuffer<unsigned int>(destination_indices, indices, index_count, remap); +} + +void LLMeshOptimizer::remapIndexBufferU16(U16 * destination_indices, + const U16 * indices, + U64 index_count, + const unsigned int* remap) +{ + meshopt_remapIndexBuffer<unsigned short>(destination_indices, indices, index_count, remap); +} + +void LLMeshOptimizer::remapPositionsBuffer(LLVector4a * destination_vertices, + const LLVector4a * vertex_positions, + U64 vertex_count, + const unsigned int* remap) +{ + meshopt_remapVertexBuffer((float*)destination_vertices, (const float*)vertex_positions, vertex_count, sizeof(LLVector4a), remap); +} + +void LLMeshOptimizer::remapNormalsBuffer(LLVector4a * destination_normalss, + const LLVector4a * normals, + U64 mormals_count, + const unsigned int* remap) +{ + meshopt_remapVertexBuffer((float*)destination_normalss, (const float*)normals, mormals_count, sizeof(LLVector4a), remap); +} + +void LLMeshOptimizer::remapUVBuffer(LLVector2 * destination_uvs, + const LLVector2 * uv_positions, + U64 uv_count, + const unsigned int* remap) +{ + meshopt_remapVertexBuffer((float*)destination_uvs, (const float*)uv_positions, uv_count, sizeof(LLVector2), remap); +} + +//static +U64 LLMeshOptimizer::simplifyU32(U32 *destination, + const U32 *indices, + U64 index_count, + const LLVector4a *vertex_positions, + U64 vertex_count, + U64 vertex_positions_stride, + U64 target_index_count, + F32 target_error, + bool sloppy, + F32* result_error +) +{ + if (sloppy) + { + return meshopt_simplifySloppy<unsigned int>(destination, + indices, + index_count, + (const float*)vertex_positions, + vertex_count, + vertex_positions_stride, + target_index_count, + target_error, + result_error + ); + } + else + { + return meshopt_simplify<unsigned int>(destination, + indices, + index_count, + (const float*)vertex_positions, + vertex_count, + vertex_positions_stride, + target_index_count, + target_error, + result_error + ); + } +} + +//static +U64 LLMeshOptimizer::simplify(U16 *destination, + const U16 *indices, + U64 index_count, + const LLVector4a *vertex_positions, + U64 vertex_count, + U64 vertex_positions_stride, + U64 target_index_count, + F32 target_error, + bool sloppy, + F32* result_error + ) +{ + if (sloppy) + { + return meshopt_simplifySloppy<unsigned short>(destination, + indices, + index_count, + (const float*)vertex_positions, + vertex_count, + vertex_positions_stride, + target_index_count, + target_error, + result_error + ); + } + else + { + return meshopt_simplify<unsigned short>(destination, + indices, + index_count, + (const float*)vertex_positions, + vertex_count, + vertex_positions_stride, + target_index_count, + target_error, + result_error + ); + } +} + diff --git a/indra/llmeshoptimizer/llmeshoptimizer.h b/indra/llmeshoptimizer/llmeshoptimizer.h new file mode 100644 index 0000000000000000000000000000000000000000..ea965d6b47c1311f9bf8e7738b83f88b7cdc4cd6 --- /dev/null +++ b/indra/llmeshoptimizer/llmeshoptimizer.h @@ -0,0 +1,156 @@ +/** +* @file llmeshoptimizer.h +* @brief Wrapper around meshoptimizer +* +* $LicenseInfo:firstyear=2021&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2021, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ +#ifndef LLMESHOPTIMIZER_H +#define LLMESHOPTIMIZER_H + +#include "linden_common.h" + +class LLVector4a; +class LLVector2; + +class LLMeshOptimizer +{ +public: + LLMeshOptimizer(); + ~LLMeshOptimizer(); + + static void generateShadowIndexBufferU32( + U32 *destination, + const U32 *indices, + U64 index_count, + const LLVector4a * vertex_positions, + const LLVector4a * normals, + const LLVector2 * text_coords, + U64 vertex_count); + + static void generateShadowIndexBufferU16( + U16 *destination, + const U16 *indices, + U64 index_count, + const LLVector4a * vertex_positions, + const LLVector4a * normals, + const LLVector2 * text_coords, + U64 vertex_count); + + static void optimizeVertexCacheU32( + U32 *destination, + const U32 *indices, + U64 index_count, + U64 vertex_count); + + static void optimizeVertexCacheU16( + U16 *destination, + const U16 *indices, + U64 index_count, + U64 vertex_count); + + // Remap functions + // Welds indentical vertexes together. + // Removes unused vertices if indices were provided. + + static size_t generateRemapMultiU32( + unsigned int* remap, + const U32 * indices, + U64 index_count, + const LLVector4a * vertex_positions, + const LLVector4a * normals, + const LLVector2 * text_coords, + U64 vertex_count); + + static size_t generateRemapMultiU16( + unsigned int* remap, + const U16 * indices, + U64 index_count, + const LLVector4a * vertex_positions, + const LLVector4a * normals, + const LLVector2 * text_coords, + U64 vertex_count); + + static void remapIndexBufferU32(U32 * destination_indices, + const U32 * indices, + U64 index_count, + const unsigned int* remap); + + static void remapIndexBufferU16(U16 * destination_indices, + const U16 * indices, + U64 index_count, + const unsigned int* remap); + + + static void remapPositionsBuffer(LLVector4a * destination_vertices, + const LLVector4a * vertex_positions, + U64 vertex_count, + const unsigned int* remap); + + static void remapNormalsBuffer(LLVector4a * destination_normalss, + const LLVector4a * normals, + U64 mormals_count, + const unsigned int* remap); + + static void remapUVBuffer(LLVector2 * destination_uvs, + const LLVector2 * uv_positions, + U64 uv_count, + const unsigned int* remap); + + // Simplification + + // returns amount of indices in destiantion + // sloppy engages a variant of a mechanizm that does not respect topology as much + // but is much more efective for simpler models + // result_error returns how far from original the model is in % if not NULL + // Works with U32 indices (LLFace uses U16 indices) + static U64 simplifyU32( + U32 *destination, + const U32 *indices, + U64 index_count, + const LLVector4a *vertex_positions, + U64 vertex_count, + U64 vertex_positions_stride, + U64 target_index_count, + F32 target_error, + bool sloppy, + F32* result_error); + + // Returns amount of indices in destiantion + // sloppy engages a variant of a mechanizm that does not respect topology as much + // but is much better for simpler models + // result_error returns how far from original the model is in % if not NULL + // Meant for U16 indices (LLFace uses U16 indices) + static U64 simplify( + U16 *destination, + const U16 *indices, + U64 index_count, + const LLVector4a *vertex_positions, + U64 vertex_count, + U64 vertex_positions_stride, + U64 target_index_count, + F32 target_error, + bool sloppy, + F32* result_error); +private: +}; + +#endif //LLMESHOPTIMIZER_H diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp index 3c92bcdeaee501ff92774c33a0b78a2c3507abad..b3cfa82f80d3fedf09a6db663bb9d415e3efe1f0 100644 --- a/indra/llmessage/llavatarnamecache.cpp +++ b/indra/llmessage/llavatarnamecache.cpp @@ -199,6 +199,10 @@ void LLAvatarNameCache::requestAvatarNameCache_(std::string url, std::vector<LLU LLAvatarNameCache::getInstance()->handleAvNameCacheSuccess(results, httpResults); } } + catch (const LLCoros::Stop&) + { + LL_DEBUGS("AvNameCache") << "Received a shutdown exception" << LL_ENDL; + } catch (...) { LOG_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << LLCoros::getName() diff --git a/indra/llmessage/lldatapacker.cpp b/indra/llmessage/lldatapacker.cpp index bf05b8b33be7fb8fcdd8c62d1bf3046e67afcdd5..64cd1c2ad0a5259190faf420c3c17d76863d5a05 100644 --- a/indra/llmessage/lldatapacker.cpp +++ b/indra/llmessage/lldatapacker.cpp @@ -126,13 +126,7 @@ BOOL LLDataPacker::unpackFixed(F32 &value, const char *name, total_bits++; } - S32 min_val; U32 max_val; - if (is_signed) - { - min_val = 1 << int_bits; - min_val *= -1; - } max_val = 1 << int_bits; F32 fixed_val; diff --git a/indra/llmessage/llfiltersd2xmlrpc.cpp b/indra/llmessage/llfiltersd2xmlrpc.cpp index 1bbb3e01f63f9f9f129dafb12b46aa266e7fca07..075338fd5622e7091686104a731f1e8cbe7eae91 100644 --- a/indra/llmessage/llfiltersd2xmlrpc.cpp +++ b/indra/llmessage/llfiltersd2xmlrpc.cpp @@ -295,7 +295,6 @@ void LLFilterSD2XMLRPC::streamOut(std::ostream& ostr, const LLSD& sd) * LLFilterSD2XMLRPCResponse */ -static LLTrace::BlockTimerStatHandle FTM_PROCESS_SD2XMLRPC_RESPONSE("SD2XMLRPC Response"); // virtual LLIOPipe::EStatus LLFilterSD2XMLRPCResponse::process_impl( const LLChannelDescriptors& channels, @@ -304,7 +303,7 @@ LLIOPipe::EStatus LLFilterSD2XMLRPCResponse::process_impl( LLSD& context, LLPumpIO* pump) { - LL_RECORD_BLOCK_TIME(FTM_PROCESS_SD2XMLRPC_RESPONSE); + LL_PROFILE_ZONE_SCOPED; PUMP_DEBUG; // This pipe does not work if it does not have everyting. This @@ -364,8 +363,6 @@ LLFilterSD2XMLRPCRequest::LLFilterSD2XMLRPCRequest(const char* method) } } -static LLTrace::BlockTimerStatHandle FTM_PROCESS_SD2XMLRPC_REQUEST("S22XMLRPC Request"); - // virtual LLIOPipe::EStatus LLFilterSD2XMLRPCRequest::process_impl( const LLChannelDescriptors& channels, @@ -374,7 +371,7 @@ LLIOPipe::EStatus LLFilterSD2XMLRPCRequest::process_impl( LLSD& context, LLPumpIO* pump) { - LL_RECORD_BLOCK_TIME(FTM_PROCESS_SD2XMLRPC_REQUEST); + LL_PROFILE_ZONE_SCOPED; // This pipe does not work if it does not have everyting. This // could be addressed by making a stream parser for llsd which // handled partial information. @@ -563,8 +560,6 @@ LLIOPipe::EStatus stream_out(std::ostream& ostr, XMLRPC_VALUE value) return status; } -static LLTrace::BlockTimerStatHandle FTM_PROCESS_XMLRPC2LLSD_RESPONSE("XMLRPC2LLSD Response"); - LLIOPipe::EStatus LLFilterXMLRPCResponse2LLSD::process_impl( const LLChannelDescriptors& channels, buffer_ptr_t& buffer, @@ -572,7 +567,7 @@ LLIOPipe::EStatus LLFilterXMLRPCResponse2LLSD::process_impl( LLSD& context, LLPumpIO* pump) { - LL_RECORD_BLOCK_TIME(FTM_PROCESS_XMLRPC2LLSD_RESPONSE); + LL_PROFILE_ZONE_SCOPED; PUMP_DEBUG; if(!eos) return STATUS_BREAK; @@ -641,7 +636,6 @@ LLIOPipe::EStatus LLFilterXMLRPCResponse2LLSD::process_impl( /** * LLFilterXMLRPCRequest2LLSD */ -static LLTrace::BlockTimerStatHandle FTM_PROCESS_XMLRPC2LLSD_REQUEST("XMLRPC2LLSD Request"); LLIOPipe::EStatus LLFilterXMLRPCRequest2LLSD::process_impl( const LLChannelDescriptors& channels, buffer_ptr_t& buffer, @@ -649,7 +643,7 @@ LLIOPipe::EStatus LLFilterXMLRPCRequest2LLSD::process_impl( LLSD& context, LLPumpIO* pump) { - LL_RECORD_BLOCK_TIME(FTM_PROCESS_XMLRPC2LLSD_REQUEST); + LL_PROFILE_ZONE_SCOPED; PUMP_DEBUG; if(!eos) return STATUS_BREAK; if(!buffer) return STATUS_ERROR; diff --git a/indra/llmessage/llhttpnode.cpp b/indra/llmessage/llhttpnode.cpp index 58a784d62b4eabf74ad303c08038931c82b850f5..fd2d6a29acebdaf0f036868c9da48312f519f740 100644 --- a/indra/llmessage/llhttpnode.cpp +++ b/indra/llmessage/llhttpnode.cpp @@ -121,6 +121,7 @@ LLSD LLHTTPNode::simplePost(const LLSD& input) const // virtual void LLHTTPNode::get(LLHTTPNode::ResponsePtr response, const LLSD& context) const { + LL_PROFILE_ZONE_SCOPED; try { response->result(simpleGet()); @@ -134,6 +135,7 @@ void LLHTTPNode::get(LLHTTPNode::ResponsePtr response, const LLSD& context) cons // virtual void LLHTTPNode::put(LLHTTPNode::ResponsePtr response, const LLSD& context, const LLSD& input) const { + LL_PROFILE_ZONE_SCOPED; try { response->result(simplePut(input)); @@ -147,6 +149,7 @@ void LLHTTPNode::put(LLHTTPNode::ResponsePtr response, const LLSD& context, cons // virtual void LLHTTPNode::post(LLHTTPNode::ResponsePtr response, const LLSD& context, const LLSD& input) const { + LL_PROFILE_ZONE_SCOPED; try { response->result(simplePost(input)); @@ -160,6 +163,7 @@ void LLHTTPNode::post(LLHTTPNode::ResponsePtr response, const LLSD& context, con // virtual void LLHTTPNode::del(LLHTTPNode::ResponsePtr response, const LLSD& context) const { + LL_PROFILE_ZONE_SCOPED; try { response->result(simpleDel(context)); diff --git a/indra/llmessage/lliohttpserver.cpp b/indra/llmessage/lliohttpserver.cpp index 650efa8094afcd6a64aa2b5b938dea325756466f..7e489769523577f4a18aa3fbd995fd6b08de78b1 100644 --- a/indra/llmessage/lliohttpserver.cpp +++ b/indra/llmessage/lliohttpserver.cpp @@ -132,12 +132,6 @@ class LLHTTPPipe : public LLIOPipe LLSD mHeaders; }; -static LLTrace::BlockTimerStatHandle FTM_PROCESS_HTTP_PIPE("HTTP Pipe"); -static LLTrace::BlockTimerStatHandle FTM_PROCESS_HTTP_GET("HTTP Get"); -static LLTrace::BlockTimerStatHandle FTM_PROCESS_HTTP_PUT("HTTP Put"); -static LLTrace::BlockTimerStatHandle FTM_PROCESS_HTTP_POST("HTTP Post"); -static LLTrace::BlockTimerStatHandle FTM_PROCESS_HTTP_DELETE("HTTP Delete"); - LLIOPipe::EStatus LLHTTPPipe::process_impl( const LLChannelDescriptors& channels, buffer_ptr_t& buffer, @@ -145,7 +139,7 @@ LLIOPipe::EStatus LLHTTPPipe::process_impl( LLSD& context, LLPumpIO* pump) { - LL_RECORD_BLOCK_TIME(FTM_PROCESS_HTTP_PIPE); + LL_PROFILE_ZONE_SCOPED; PUMP_DEBUG; LL_DEBUGS() << "LLSDHTTPServer::process_impl" << LL_ENDL; @@ -174,12 +168,10 @@ LLIOPipe::EStatus LLHTTPPipe::process_impl( std::string verb = context[CONTEXT_REQUEST][CONTEXT_VERB]; if(verb == HTTP_VERB_GET) { - LL_RECORD_BLOCK_TIME(FTM_PROCESS_HTTP_GET); mNode.get(LLHTTPNode::ResponsePtr(mResponse), context); } else if(verb == HTTP_VERB_PUT) { - LL_RECORD_BLOCK_TIME(FTM_PROCESS_HTTP_PUT); LLSD input; if (mNode.getContentType() == LLHTTPNode::CONTENT_TYPE_LLSD) { @@ -195,7 +187,6 @@ LLIOPipe::EStatus LLHTTPPipe::process_impl( } else if(verb == HTTP_VERB_POST) { - LL_RECORD_BLOCK_TIME(FTM_PROCESS_HTTP_POST); LLSD input; if (mNode.getContentType() == LLHTTPNode::CONTENT_TYPE_LLSD) { @@ -211,7 +202,6 @@ LLIOPipe::EStatus LLHTTPPipe::process_impl( } else if(verb == HTTP_VERB_DELETE) { - LL_RECORD_BLOCK_TIME(FTM_PROCESS_HTTP_DELETE); mNode.del(LLHTTPNode::ResponsePtr(mResponse), context); } else if(verb == HTTP_VERB_OPTIONS) @@ -450,8 +440,6 @@ class LLHTTPResponseHeader : public LLIOPipe * LLHTTPResponseHeader */ -static LLTrace::BlockTimerStatHandle FTM_PROCESS_HTTP_HEADER("HTTP Header"); - // virtual LLIOPipe::EStatus LLHTTPResponseHeader::process_impl( const LLChannelDescriptors& channels, @@ -460,7 +448,7 @@ LLIOPipe::EStatus LLHTTPResponseHeader::process_impl( LLSD& context, LLPumpIO* pump) { - LL_RECORD_BLOCK_TIME(FTM_PROCESS_HTTP_HEADER); + LL_PROFILE_ZONE_SCOPED; PUMP_DEBUG; if(eos) { @@ -650,8 +638,6 @@ void LLHTTPResponder::markBad( << "</body>\n</html>\n"; } -static LLTrace::BlockTimerStatHandle FTM_PROCESS_HTTP_RESPONDER("HTTP Responder"); - // virtual LLIOPipe::EStatus LLHTTPResponder::process_impl( const LLChannelDescriptors& channels, @@ -660,7 +646,7 @@ LLIOPipe::EStatus LLHTTPResponder::process_impl( LLSD& context, LLPumpIO* pump) { - LL_RECORD_BLOCK_TIME(FTM_PROCESS_HTTP_RESPONDER); + LL_PROFILE_ZONE_SCOPED; PUMP_DEBUG; LLIOPipe::EStatus status = STATUS_OK; diff --git a/indra/llmessage/lliosocket.cpp b/indra/llmessage/lliosocket.cpp index febdc9d9b3600edc61c353200a37f8dc7cb2cb2f..c70eb68eaeea8cf9b9c1e43a122dba0d22ff3208 100644 --- a/indra/llmessage/lliosocket.cpp +++ b/indra/llmessage/lliosocket.cpp @@ -301,8 +301,6 @@ LLIOSocketReader::~LLIOSocketReader() //LL_DEBUGS() << "Destroying LLIOSocketReader" << LL_ENDL; } -static LLTrace::BlockTimerStatHandle FTM_PROCESS_SOCKET_READER("Socket Reader"); - // virtual LLIOPipe::EStatus LLIOSocketReader::process_impl( const LLChannelDescriptors& channels, @@ -311,7 +309,7 @@ LLIOPipe::EStatus LLIOSocketReader::process_impl( LLSD& context, LLPumpIO* pump) { - LL_RECORD_BLOCK_TIME(FTM_PROCESS_SOCKET_READER); + LL_PROFILE_ZONE_SCOPED; PUMP_DEBUG; if(!mSource) return STATUS_PRECONDITION_NOT_MET; if(!mInitialized) @@ -401,7 +399,6 @@ LLIOSocketWriter::~LLIOSocketWriter() //LL_DEBUGS() << "Destroying LLIOSocketWriter" << LL_ENDL; } -static LLTrace::BlockTimerStatHandle FTM_PROCESS_SOCKET_WRITER("Socket Writer"); // virtual LLIOPipe::EStatus LLIOSocketWriter::process_impl( const LLChannelDescriptors& channels, @@ -410,7 +407,7 @@ LLIOPipe::EStatus LLIOSocketWriter::process_impl( LLSD& context, LLPumpIO* pump) { - LL_RECORD_BLOCK_TIME(FTM_PROCESS_SOCKET_WRITER); + LL_PROFILE_ZONE_SCOPED; PUMP_DEBUG; if(!mDestination) return STATUS_PRECONDITION_NOT_MET; if(!mInitialized) @@ -557,7 +554,6 @@ void LLIOServerSocket::setResponseTimeout(F32 timeout_secs) mResponseTimeout = timeout_secs; } -static LLTrace::BlockTimerStatHandle FTM_PROCESS_SERVER_SOCKET("Server Socket"); // virtual LLIOPipe::EStatus LLIOServerSocket::process_impl( const LLChannelDescriptors& channels, @@ -566,7 +562,7 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl( LLSD& context, LLPumpIO* pump) { - LL_RECORD_BLOCK_TIME(FTM_PROCESS_SERVER_SOCKET); + LL_PROFILE_ZONE_SCOPED; PUMP_DEBUG; if(!pump) { diff --git a/indra/llmessage/llioutil.cpp b/indra/llmessage/llioutil.cpp index b8443c0600d8cb23dddef45c1f1f57bd6950f468..850bc2a6167c9079367c7017e02e50f71dd2b75c 100644 --- a/indra/llmessage/llioutil.cpp +++ b/indra/llmessage/llioutil.cpp @@ -45,7 +45,6 @@ LLIOPipe::EStatus LLIOFlush::process_impl( } -static LLTrace::BlockTimerStatHandle FTM_PROCESS_SLEEP("IO Sleep"); /** * @class LLIOSleep */ @@ -56,7 +55,7 @@ LLIOPipe::EStatus LLIOSleep::process_impl( LLSD& context, LLPumpIO* pump) { - LL_RECORD_BLOCK_TIME(FTM_PROCESS_SLEEP); + LL_PROFILE_ZONE_SCOPED; if(mSeconds > 0.0) { if(pump) pump->sleepChain(mSeconds); @@ -66,7 +65,6 @@ LLIOPipe::EStatus LLIOSleep::process_impl( return STATUS_DONE; } -static LLTrace::BlockTimerStatHandle FTM_PROCESS_ADD_CHAIN("Add Chain"); /** * @class LLIOAddChain */ @@ -77,7 +75,7 @@ LLIOPipe::EStatus LLIOAddChain::process_impl( LLSD& context, LLPumpIO* pump) { - LL_RECORD_BLOCK_TIME(FTM_PROCESS_ADD_CHAIN); + LL_PROFILE_ZONE_SCOPED; pump->addChain(mChain, mTimeout); return STATUS_DONE; } diff --git a/indra/llmessage/llpartdata.cpp b/indra/llmessage/llpartdata.cpp index 4816daa8cb7f436b33c98cd1da327b91bf498057..20a43a91194f1f6ff806911f5325869a7ec0c100 100644 --- a/indra/llmessage/llpartdata.cpp +++ b/indra/llmessage/llpartdata.cpp @@ -311,8 +311,9 @@ BOOL LLPartSysData::unpack(LLDataPacker &dp) std::ostream& operator<<(std::ostream& s, const LLPartSysData &data) { s << "Flags: " << std::hex << data.mFlags; - s << " Pattern: " << std::hex << (U32) data.mPattern << "\n"; - s << "Age: [" << data.mStartAge << ", " << data.mMaxAge << "]\n"; + s << "Pattern: " << std::hex << (U32) data.mPattern << "\n"; + s << "Source Age: [" << data.mStartAge << ", " << data.mMaxAge << "]\n"; + s << "Particle Age: " << data.mPartData.mMaxAge << "\n"; s << "Angle: [" << data.mInnerAngle << ", " << data.mOuterAngle << "]\n"; s << "Burst Rate: " << data.mBurstRate << "\n"; s << "Burst Radius: " << data.mBurstRadius << "\n"; diff --git a/indra/llmessage/llpumpio.cpp b/indra/llmessage/llpumpio.cpp index b7142b70940caf1dd3334e68ab2ee5a2dac23314..5420e3e328155344fb9492bcccd09bf199588f95 100644 --- a/indra/llmessage/llpumpio.cpp +++ b/indra/llmessage/llpumpio.cpp @@ -416,9 +416,6 @@ void LLPumpIO::pump() pump(DEFAULT_POLL_TIMEOUT); } -static LLTrace::BlockTimerStatHandle FTM_PUMP_IO("Pump IO"); -static LLTrace::BlockTimerStatHandle FTM_PUMP_POLL("Pump Poll"); - LLPumpIO::current_chain_t LLPumpIO::removeRunningChain(LLPumpIO::current_chain_t& run_chain) { std::for_each( @@ -431,7 +428,7 @@ LLPumpIO::current_chain_t LLPumpIO::removeRunningChain(LLPumpIO::current_chain_t //timeout is in microseconds void LLPumpIO::pump(const S32& poll_timeout) { - LL_RECORD_BLOCK_TIME(FTM_PUMP_IO); + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; //LL_INFOS() << "LLPumpIO::pump()" << LL_ENDL; // Run any pending runners. @@ -509,7 +506,7 @@ void LLPumpIO::pump(const S32& poll_timeout) S32 count = 0; S32 client_id = 0; { - LL_RECORD_BLOCK_TIME(FTM_PUMP_POLL); + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; apr_pollset_poll(mPollset, poll_timeout, &count, &poll_fd); } PUMP_DEBUG; @@ -737,10 +734,9 @@ bool LLPumpIO::respond( return true; } -static LLTrace::BlockTimerStatHandle FTM_PUMP_CALLBACK_CHAIN("Chain"); - void LLPumpIO::callback() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; //LL_INFOS() << "LLPumpIO::callback()" << LL_ENDL; if(true) { @@ -756,7 +752,6 @@ void LLPumpIO::callback() callbacks_t::iterator end = mCallbacks.end(); for(; it != end; ++it) { - LL_RECORD_BLOCK_TIME(FTM_PUMP_CALLBACK_CHAIN); // it's always the first and last time for respone chains (*it).mHead = (*it).mChainLinks.begin(); (*it).mInit = true; diff --git a/indra/llmessage/lltemplatemessagereader.cpp b/indra/llmessage/lltemplatemessagereader.cpp index 6d6c3482e06e097aa99de721372033ad316f6ba4..d937ba96ce31b86434dc059dacd9b64225edd35b 100644 --- a/indra/llmessage/lltemplatemessagereader.cpp +++ b/indra/llmessage/lltemplatemessagereader.cpp @@ -537,6 +537,8 @@ static LLTrace::BlockTimerStatHandle FTM_PROCESS_MESSAGES("Process Messages"); // decode a given message BOOL LLTemplateMessageReader::decodeData(const U8* buffer, const LLHost& sender, bool custom ) { + LL_RECORD_BLOCK_TIME(FTM_PROCESS_MESSAGES); + llassert( mReceiveSize >= 0 ); llassert( mCurrentRMessageTemplate); llassert( !mCurrentRMessageData ); @@ -715,12 +717,9 @@ BOOL LLTemplateMessageReader::decodeData(const U8* buffer, const LLHost& sender, decode_timer.reset(); } + if( !mCurrentRMessageTemplate->callHandlerFunc(gMessageSystem) ) { - LL_RECORD_BLOCK_TIME(FTM_PROCESS_MESSAGES); - if( !mCurrentRMessageTemplate->callHandlerFunc(gMessageSystem) ) - { - LL_WARNS() << "Message from " << sender << " with no handler function received: " << mCurrentRMessageTemplate->mName << LL_ENDL; - } + LL_WARNS() << "Message from " << sender << " with no handler function received: " << mCurrentRMessageTemplate->mName << LL_ENDL; } if(LLMessageReader::getTimeDecodes() || gMessageSystem->getTimingCallback()) diff --git a/indra/llmessage/llthrottle.cpp b/indra/llmessage/llthrottle.cpp index 7605da4d3fa9b06c0f5700eb351bf8d1f56226be..935af2aa5a551b04c45b54cc6d8bc637c296d664 100644 --- a/indra/llmessage/llthrottle.cpp +++ b/indra/llmessage/llthrottle.cpp @@ -374,7 +374,6 @@ BOOL LLThrottleGroup::dynamicAdjust() } mDynamicAdjustTime = mt_sec; - S32 total = 0; // Update historical information for (i = 0; i < TC_EOF; i++) { @@ -391,7 +390,6 @@ BOOL LLThrottleGroup::dynamicAdjust() } mBitsSentThisPeriod[i] = 0; - total += ll_round(mBitsSentHistory[i]); } // Look for busy channels diff --git a/indra/llmessage/message_prehash.cpp b/indra/llmessage/message_prehash.cpp index d334aad3c1c7c24eaa8bc1eb91d1e9f81c902fef..44e091bde28177809043bfd37041c97bcd3605f3 100644 --- a/indra/llmessage/message_prehash.cpp +++ b/indra/llmessage/message_prehash.cpp @@ -1445,7 +1445,7 @@ char const* const _PREHASH_AvatarNotesReply = LLMessageStringTable::getInstance( char const* const _PREHASH_CacheID = LLMessageStringTable::getInstance()->getString("CacheID"); char const* const _PREHASH_OwnerMask = LLMessageStringTable::getInstance()->getString("OwnerMask"); char const* const _PREHASH_TransferInventoryAck = LLMessageStringTable::getInstance()->getString("TransferInventoryAck"); - +char const* const _PREHASH_ParcelExtendedFlags = LLMessageStringTable::getInstance()->getString("ParcelExtendedFlags"); char const* const _PREHASH_RegionSizeX = LLMessageStringTable::getInstance()->getString("RegionSizeX"); char const* const _PREHASH_RegionSizeY = LLMessageStringTable::getInstance()->getString("RegionSizey"); char const* const _PREHASH_SizeX = LLMessageStringTable::getInstance()->getString("SizeX"); diff --git a/indra/llmessage/message_prehash.h b/indra/llmessage/message_prehash.h index a672a06e02dc42f71ab3b9788cad9a43b6d169a7..f65ee501f92789e16dd91970feb63e8f407f977f 100644 --- a/indra/llmessage/message_prehash.h +++ b/indra/llmessage/message_prehash.h @@ -1445,6 +1445,7 @@ extern char const* const _PREHASH_AvatarNotesReply; extern char const* const _PREHASH_CacheID; extern char const* const _PREHASH_OwnerMask; extern char const* const _PREHASH_TransferInventoryAck; +extern char const* const _PREHASH_ParcelExtendedFlags; extern char const* const _PREHASH_RegionSizeX; extern char const* const _PREHASH_RegionSizeY; extern char const* const _PREHASH_SizeX; diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp index 37a66269fea541bf52b0075a77f848e29bf43780..f8b1626259fb9c1d8cc31796921f4aa331108b46 100644 --- a/indra/llplugin/llpluginclassmedia.cpp +++ b/indra/llplugin/llpluginclassmedia.cpp @@ -1599,6 +1599,7 @@ void LLPluginClassMedia::seek(float time) LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME, "seek"); message.setValueReal("time", time); + mCurrentTime = time; // assume that it worked and we will receive an update later sendMessage(message); } diff --git a/indra/llplugin/llpluginclassmedia.h b/indra/llplugin/llpluginclassmedia.h index 8d392d17c7f3c2f0dc0df06fce89895a41f79870..b31f61507b90af990f05a00fad60dd6239bd3bc9 100644 --- a/indra/llplugin/llpluginclassmedia.h +++ b/indra/llplugin/llpluginclassmedia.h @@ -350,7 +350,7 @@ class LLPluginClassMedia final : public LLPluginProcessParentOwner // "init_history" message void initializeUrlHistory(const LLSD& url_history); - std::shared_ptr<LLPluginClassMedia> getSharedPrt() { return std::dynamic_pointer_cast<LLPluginClassMedia>(shared_from_this()); } // due to enable_shared_from_this + std::shared_ptr<LLPluginClassMedia> getSharedPtr() { return std::dynamic_pointer_cast<LLPluginClassMedia>(shared_from_this()); } // due to enable_shared_from_this protected: diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp index 1a09c2b3ea9b52b9ab96d54d20a5b8524cede2c0..ef9a315864cd92bbc7bb835ed4cfea58a98f836f 100644 --- a/indra/llplugin/llpluginprocessparent.cpp +++ b/indra/llplugin/llpluginprocessparent.cpp @@ -40,7 +40,7 @@ bool LLPluginProcessParent::sUseReadThread = false; apr_pollset_t *LLPluginProcessParent::sPollSet = NULL; bool LLPluginProcessParent::sPollsetNeedsRebuild = false; -LLMutex LLPluginProcessParent::sInstancesMutex(LLMutex::E_CONST_INIT); +LLMutex *LLPluginProcessParent::sInstancesMutex = nullptr; LLPluginProcessParent::mapInstances_t LLPluginProcessParent::sInstances; LLThread *LLPluginProcessParent::sReadThread = NULL; @@ -99,6 +99,11 @@ LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner): mIncomingQueueMutex(), pProcessCreationThread(NULL) { + if(!sInstancesMutex) + { + sInstancesMutex = new LLMutex(); + } + mOwner = owner; mBoundPort = 0; mState = STATE_UNINITIALIZED; @@ -163,7 +168,7 @@ LLPluginProcessParent::ptr_t LLPluginProcessParent::create(LLPluginProcessParent // Don't add to the global list until fully constructed. { - LLMutexLock lock(&sInstancesMutex); + LLMutexLock lock(sInstancesMutex); sInstances.emplace(that.get(), that); } @@ -173,7 +178,7 @@ LLPluginProcessParent::ptr_t LLPluginProcessParent::create(LLPluginProcessParent /*static*/ void LLPluginProcessParent::shutdown() { - LLMutexLock lock(&sInstancesMutex); + LLMutexLock lock(sInstancesMutex); mapInstances_t::iterator it; for (it = sInstances.begin(); it != sInstances.end(); ++it) @@ -231,7 +236,7 @@ bool LLPluginProcessParent::pollTick() { // this grabs a copy of the smart pointer to ourselves to ensure that we do not // get destroyed until after this method returns. - LLMutexLock lock(&sInstancesMutex); + LLMutexLock lock(sInstancesMutex); mapInstances_t::iterator it = sInstances.find(this); if (it != sInstances.end()) that = (*it).second; @@ -250,7 +255,7 @@ void LLPluginProcessParent::removeFromProcessing() // Remove from the global list before beginning destruction. { // Make sure to get the global mutex _first_ here, to avoid a possible deadlock against LLPluginProcessParent::poll() - LLMutexLock lock(&sInstancesMutex); + LLMutexLock lock(sInstancesMutex); { LLMutexLock lock2(&mIncomingQueueMutex); sInstances.erase(this); @@ -854,7 +859,7 @@ void LLPluginProcessParent::dirtyPollSet() void LLPluginProcessParent::updatePollset() { - LLMutexLock lock(&sInstancesMutex); + LLMutexLock lock(sInstancesMutex); if (sInstances.empty()) { // No instances have been created yet. There's no work to do. @@ -958,7 +963,7 @@ void LLPluginProcessParent::setUseReadThread(bool use_read_thread) bool LLPluginProcessParent::poll(F64 timeout) { { - LLMutexLock mtxLock(&sInstancesMutex); + LLMutexLock mtxLock(sInstancesMutex); if (sInstances.empty()) { return false; @@ -990,7 +995,7 @@ bool LLPluginProcessParent::poll(F64 timeout) mapInstances_t::iterator it; { - LLMutexLock lock(&sInstancesMutex); + LLMutexLock lock(sInstancesMutex); it = sInstances.find(thatId); if (it != sInstances.end()) that = (*it).second; @@ -1023,12 +1028,12 @@ bool LLPluginProcessParent::poll(F64 timeout) // Remove instances in the done state from the sInstances map. { - LLMutexLock inst_lock(&sInstancesMutex); + LLMutexLock inst_lock(sInstancesMutex); mapInstances_t::iterator itClean = sInstances.begin(); while (itClean != sInstances.end()) { if (itClean->second->isDone()) - sInstances.erase(itClean++); + itClean = sInstances.erase(itClean); else ++itClean; } diff --git a/indra/llplugin/llpluginprocessparent.h b/indra/llplugin/llpluginprocessparent.h index f7e675a676fb76ee88d758b63735b961c4d66912..e5f277d8b09bd326135c67cc4f6cad16c0a4fd59 100644 --- a/indra/llplugin/llpluginprocessparent.h +++ b/indra/llplugin/llpluginprocessparent.h @@ -206,7 +206,7 @@ class LLPluginProcessParent final : public LLPluginMessagePipeOwner apr_pollfd_t mPollFD; static apr_pollset_t *sPollSet; static bool sPollsetNeedsRebuild; - static LLMutex sInstancesMutex; + static LLMutex *sInstancesMutex; static mapInstances_t sInstances; static void dirtyPollSet(); static void updatePollset(); diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp index a49f321a40303c359bd59c8512fa6365437e2f3e..0c63c62946a91ee9055083b06df30a537ad704ac 100644 --- a/indra/llprimitive/lldaeloader.cpp +++ b/indra/llprimitive/lldaeloader.cpp @@ -1152,7 +1152,7 @@ bool LLDAELoader::OpenFile(const std::string& filename) bool badElement = false; - processElement( scene, badElement, &dae ); + processElement( scene, badElement, &dae); if ( badElement ) { @@ -1233,18 +1233,19 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do LLMeshSkinInfo& skin_info = model->mSkinInfo; - LLMatrix4 mat; - for (auto i = 0; i < 4; i++) + LLMatrix4 mat; + for (int i = 0; i < 4; i++) { - for(auto j = 0; j < 4; j++) + for(int j = 0; j < 4; j++) { - mat.mMatrix[i][j] = dom_value[i + j*4]; + mat.mMatrix[i][j] = dom_value[i + j*4]; } } - LLMatrix4 trans = normalized_transformation; - trans *= mat; - skin_info.mBindShapeMatrix.loadu(trans); + skin_info.mBindShapeMatrix.loadu(mat); + + LLMatrix4a trans(normalized_transformation); + matMul(trans, skin_info.mBindShapeMatrix, skin_info.mBindShapeMatrix); } @@ -1451,21 +1452,18 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do domListOfFloats& transform = t->getValue(); S32 count = transform.getCount()/16; - for (auto k = 0; k < count; ++k) + for (S32 k = 0; k < count; ++k) { LLMatrix4 mat; - for (auto i = 0; i < 4; i++) + for (int i = 0; i < 4; i++) { - for(auto j = 0; j < 4; j++) + for(int j = 0; j < 4; j++) { mat.mMatrix[i][j] = transform[k*16 + i + j*4]; } } - - LLMatrix4a mat4a; - mat4a.loadu(mat); - model->mSkinInfo.mInvBindMatrix.push_back(mat4a); + model->mSkinInfo.mInvBindMatrix.push_back(LLMatrix4a(mat)); } } } @@ -1539,11 +1537,9 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do if (mJointMap.find(lookingForJoint) != mJointMap.end() && model->mSkinInfo.mInvBindMatrix.size() > i) { - alignas(16) F32 bind_matrix[16]; - model->mSkinInfo.mInvBindMatrix[i].store4a(bind_matrix); - LLMatrix4 newInverse(bind_matrix); + LLMatrix4 newInverse = LLMatrix4(model->mSkinInfo.mInvBindMatrix[i].getF32ptr()); newInverse.setTranslation( mJointList[lookingForJoint].getTranslation() ); - model->mSkinInfo.mAlternateBindMatrix.push_back( newInverse ); + model->mSkinInfo.mAlternateBindMatrix.push_back( LLMatrix4a(newInverse) ); } else { @@ -2006,7 +2002,7 @@ daeElement* LLDAELoader::getChildFromElement( daeElement* pElement, std::string return NULL; } -void LLDAELoader::processElement( daeElement* element, bool& badElement, DAE* dae ) +void LLDAELoader::processElement( daeElement* element, bool& badElement, DAE* dae) { LLMatrix4 saved_transform; bool pushed_mat = false; @@ -2493,6 +2489,7 @@ bool LLDAELoader::addVolumeFacesFromDomMesh(LLModel* pModel,domMesh* mesh, LLSD& for (U32 i = 0; i < polygons.getCount(); ++i) { domPolygonsRef& poly = polygons.get(i); + status = load_face_from_dom_polygons(pModel->getVolumeFaces(), pModel->getMaterialList(), poly); if(status != LLModel::NO_ERRORS) @@ -2578,7 +2575,7 @@ bool LLDAELoader::loadModelsFromDomMesh(domMesh* mesh, std::vector<LLModel*>& mo if (!mNoOptimize) { - ret->optimizeVolumeFaces(); + ret->remapVolumeFaces(); } volume_faces = remainder.size(); diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index 8e234e23318d38bea289f2d19e69809876209cb9..e4e107cd7ed5d0f759d110a704bf761fc864cf9c 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -31,6 +31,7 @@ #include "llconvexdecomposition.h" #include "llsdserialize.h" #include "llvector4a.h" +#include "llmd5.h" #ifdef LL_USESYSTEMLIBS # include <zlib.h> @@ -106,6 +107,14 @@ void LLModel::offsetMesh( const LLVector3& pivotPoint ) } } +void LLModel::remapVolumeFaces() +{ + for (U32 i = 0; i < getNumVolumeFaces(); ++i) + { + mVolumeFaces[i].remap(); + } +} + void LLModel::optimizeVolumeFaces() { for (U32 i = 0; i < getNumVolumeFaces(); ++i) @@ -370,6 +379,8 @@ void LLModel::setVolumeFaceData( U32 num_verts, U32 num_indices) { + llassert(num_indices % 3 == 0); + LLVolumeFace& face = mVolumeFaces[f]; face.resizeVertices(num_verts); @@ -834,7 +845,7 @@ LLSD LLModel::writeModel( { LLVector3 pos(face.mPositions[j].getF32ptr()); - weight_list& weights = high->getJointInfluences(pos); + weight_list& weights = model[idx]->getJointInfluences(pos); S32 count = 0; for (weight_list::iterator iter = weights.begin(); iter != weights.end(); ++iter) @@ -1407,10 +1418,8 @@ void LLMeshSkinInfo::fromLLSD(const LLSD& skin) mat.mMatrix[j][k] = inv_bind_mat[i][j*4+k].asReal(); } } - LLMatrix4a in_mat; - in_mat.loadu(mat); - mInvBindMatrix.emplace_back(in_mat); + mInvBindMatrix.push_back(LLMatrix4a(mat)); } if (mJointNames.size() != mInvBindMatrix.size()) @@ -1450,7 +1459,7 @@ void LLMeshSkinInfo::fromLLSD(const LLSD& skin) } } - mAlternateBindMatrix.emplace_back(mat); + mAlternateBindMatrix.push_back(LLMatrix4a(mat)); } } @@ -1467,6 +1476,8 @@ void LLMeshSkinInfo::fromLLSD(const LLSD& skin) { mLockScaleIfJointPosition = false; } + + updateHash(); } LLSD LLMeshSkinInfo::asLLSD(bool include_joints, bool lock_scale_if_joint_position) const @@ -1522,6 +1533,57 @@ LLSD LLMeshSkinInfo::asLLSD(bool include_joints, bool lock_scale_if_joint_positi return ret; } +void LLMeshSkinInfo::updateHash() +{ + // get hash of data relevant to render batches + LLMD5 hash; + + //mJointNames + for (auto& name : mJointNames) + { + hash.update(name); + } + + //mJointNums + hash.update((U8*)&(mJointNums[0]), sizeof(S32) * mJointNums.size()); + + //mInvBindMatrix + F32* src = mInvBindMatrix[0].getF32ptr(); + + for (int i = 0; i < mInvBindMatrix.size() * 16; ++i) + { + S32 t = llround(src[i] * 10000.f); + hash.update((U8*)&t, sizeof(S32)); + } + //hash.update((U8*)&(mInvBindMatrix[0]), sizeof(LLMatrix4a) * mInvBindMatrix.size()); + + hash.finalize(); + + U64 digest[2]; + hash.raw_digest((U8*) digest); + + mHash = digest[0]; +} + +U32 LLMeshSkinInfo::sizeBytes() const +{ + U32 res = sizeof(LLUUID); // mMeshID + + res += sizeof(std::vector<std::string>) + sizeof(std::string) * mJointNames.size(); + for (U32 i = 0; i < mJointNames.size(); ++i) + { + res += mJointNames[i].size(); // actual size, not capacity + } + + res += sizeof(std::vector<S32>) + sizeof(S32) * mJointNums.size(); + res += sizeof(std::vector<LLMatrix4>) + 16 * sizeof(float) * mInvBindMatrix.size(); + res += sizeof(std::vector<LLMatrix4>) + 16 * sizeof(float) * mAlternateBindMatrix.size(); + res += 16 * sizeof(float); //mBindShapeMatrix + res += sizeof(float) + 3 * sizeof(bool); + + return res; +} + LLModel::Decomposition::Decomposition(LLSD& data) { fromLLSD(data); @@ -1628,6 +1690,30 @@ void LLModel::Decomposition::fromLLSD(LLSD& decomp) } } +U32 LLModel::Decomposition::sizeBytes() const +{ + U32 res = sizeof(LLUUID); // mMeshID + + res += sizeof(LLModel::convex_hull_decomposition) + sizeof(std::vector<LLVector3>) * mHull.size(); + for (U32 i = 0; i < mHull.size(); ++i) + { + res += mHull[i].size() * sizeof(LLVector3); + } + + res += sizeof(LLModel::hull) + sizeof(LLVector3) * mBaseHull.size(); + + res += sizeof(std::vector<LLModel::PhysicsMesh>) + sizeof(std::vector<LLModel::PhysicsMesh>) * mMesh.size(); + for (U32 i = 0; i < mMesh.size(); ++i) + { + res += mMesh[i].sizeBytes(); + } + + res += sizeof(std::vector<LLModel::PhysicsMesh>) * 2; + res += mBaseHullMesh.sizeBytes() + mPhysicsShapeMesh.sizeBytes(); + + return res; +} + bool LLModel::Decomposition::hasHullList() const { return !mHull.empty() ; diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index 2ff5e1b4d515db3281ab789e8c9ab3797e499523..43c511822386d56b8eb3dacfd79e34d2af93ae3c 100644 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -33,13 +33,17 @@ #include "m4math.h" #include <queue> +#include <boost/align/aligned_allocator.hpp> + class daeElement; class domMesh; #define MAX_MODEL_FACES 8 +LL_ALIGN_PREFIX(16) class LLMeshSkinInfo : public LLRefCount { + LL_ALIGN_NEW public: LLMeshSkinInfo(); LLMeshSkinInfo(const LLSD& data); @@ -47,22 +51,29 @@ class LLMeshSkinInfo : public LLRefCount ~LLMeshSkinInfo() = default; void fromLLSD(const LLSD& data); LLSD asLLSD(bool include_joints, bool lock_scale_if_joint_position) const; + void updateHash(); + U32 sizeBytes() const; LLUUID mMeshID; std::vector<std::string> mJointNames; mutable std::vector<S32> mJointNums; - std::vector<LLMatrix4a> mInvBindMatrix; - std::vector<LLMatrix4> mAlternateBindMatrix; + typedef std::vector<LLMatrix4a, boost::alignment::aligned_allocator<LLMatrix4a, 16>> matrix_list_t; + matrix_list_t mInvBindMatrix; + matrix_list_t mAlternateBindMatrix; + + LL_ALIGN_16(LLMatrix4a mBindShapeMatrix); - LLMatrix4a mBindShapeMatrix; float mPelvisOffset; bool mLockScaleIfJointPosition; bool mInvalidJointsScrubbed; bool mJointNumsInitialized; -}; + U64 mHash = 0; +} LL_ALIGN_POSTFIX(16); +LL_ALIGN_PREFIX(16) class LLModel final : public LLVolume { + LL_ALIGN_NEW public: enum @@ -104,6 +115,14 @@ class LLModel final : public LLVolume { return mPositions.empty(); } + + U32 sizeBytes() const + { + U32 res = sizeof(std::vector<LLVector3>) * 2; + res += sizeof(LLVector3) * mPositions.size(); + res += sizeof(LLVector3) * mNormals.size(); + return res; + } }; class Decomposition @@ -114,6 +133,7 @@ class LLModel final : public LLVolume void fromLLSD(LLSD& data); LLSD asLLSD() const; bool hasHullList() const; + U32 sizeBytes() const; void merge(const Decomposition* rhs); @@ -176,6 +196,7 @@ class LLModel final : public LLVolume void sortVolumeFacesByMaterialName(); void normalizeVolumeFaces(); void trimVolumeFacesToSize(U32 new_count = LL_SCULPT_MESH_MAX_FACES, LLVolume::face_list_t* remainder = NULL); + void remapVolumeFaces(); void optimizeVolumeFaces(); void offsetMesh( const LLVector3& pivotPoint ); void getNormalizedScaleTranslation(LLVector3& scale_out, LLVector3& translation_out); @@ -283,8 +304,10 @@ class LLModel final : public LLVolume EModelStatus mStatus ; + // A model/object can only have 8 faces, spillover faces will + // be moved to new model/object and assigned a submodel id. int mSubmodelID; -}; +} LL_ALIGN_POSTFIX(16); typedef std::vector<LLPointer<LLModel> > model_list; typedef std::queue<LLPointer<LLModel> > model_queue; diff --git a/indra/llrender/llcubemap.cpp b/indra/llrender/llcubemap.cpp index d2c69c5f8aa6d34154ceffa37865916ad25f496a..aa36953edaa99052c5d52ebb16184a230206cc3d 100644 --- a/indra/llrender/llcubemap.cpp +++ b/indra/llrender/llcubemap.cpp @@ -47,7 +47,6 @@ bool LLCubeMap::sUseCubeMaps = true; LLCubeMap::LLCubeMap(bool init_as_srgb) : mTextureStage(0), - mTextureCoordStage(0), mMatrixStage(0), mIssRGB(init_as_srgb) { @@ -146,6 +145,7 @@ void LLCubeMap::initRawData(const std::vector<LLPointer<LLImageRaw> >& rawimages void LLCubeMap::initGLData() { + LL_PROFILE_ZONE_SCOPED; for (int i = 0; i < 6; i++) { mImages[i]->setSubImage(mRawImages[i], 0, 0, RESOLUTION, RESOLUTION); @@ -175,7 +175,6 @@ void LLCubeMap::bind() void LLCubeMap::enable(S32 stage) { enableTexture(stage); - enableTextureCoords(stage); } void LLCubeMap::enableTexture(S32 stage) @@ -187,35 +186,9 @@ void LLCubeMap::enableTexture(S32 stage) } } -void LLCubeMap::enableTextureCoords(S32 stage) -{ - mTextureCoordStage = stage; - if (!LLGLSLShader::sNoFixedFunction && gGLManager.mHasCubeMap && stage >= 0 && LLCubeMap::sUseCubeMaps) - { - if (stage > 0) - { - gGL.getTexUnit(stage)->activate(); - } - - glEnable(GL_TEXTURE_GEN_R); - glEnable(GL_TEXTURE_GEN_S); - glEnable(GL_TEXTURE_GEN_T); - - glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); - glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); - glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); - - if (stage > 0) - { - gGL.getTexUnit(0)->activate(); - } - } -} - void LLCubeMap::disable(void) { disableTexture(); - disableTextureCoords(); } void LLCubeMap::disableTexture(void) @@ -230,24 +203,6 @@ void LLCubeMap::disableTexture(void) } } -void LLCubeMap::disableTextureCoords(void) -{ - if (!LLGLSLShader::sNoFixedFunction && gGLManager.mHasCubeMap && mTextureCoordStage >= 0 && LLCubeMap::sUseCubeMaps) - { - if (mTextureCoordStage > 0) - { - gGL.getTexUnit(mTextureCoordStage)->activate(); - } - glDisable(GL_TEXTURE_GEN_S); - glDisable(GL_TEXTURE_GEN_T); - glDisable(GL_TEXTURE_GEN_R); - if (mTextureCoordStage > 0) - { - gGL.getTexUnit(0)->activate(); - } - } -} - void LLCubeMap::setMatrix(S32 stage) { mMatrixStage = stage; @@ -444,6 +399,7 @@ BOOL LLCubeMap::project(F32& v_min, F32& v_max, F32& h_min, F32& h_max, void LLCubeMap::paintIn(LLVector3 dir[4], const LLColor4U& col) { + LL_PROFILE_ZONE_SCOPED; F32 v_min, v_max, h_min, h_max; LLVector3 center = dir[0] + dir[1] + dir[2] + dir[3]; center.normVec(); diff --git a/indra/llrender/llcubemap.h b/indra/llrender/llcubemap.h index 7b494c85f9dfb3be0f315c081c22e4fe418dc221..6b1aeca944a49a17e9c330abbd766e53fc133adf 100644 --- a/indra/llrender/llcubemap.h +++ b/indra/llrender/llcubemap.h @@ -48,12 +48,10 @@ class LLCubeMap : public LLRefCount void enable(S32 stage); void enableTexture(S32 stage); - void enableTextureCoords(S32 stage); S32 getStage(void) { return mTextureStage; } void disable(void); void disableTexture(void); - void disableTextureCoords(void); void setMatrix(S32 stage); void restoreMatrix(); void setReflection (void); @@ -80,7 +78,6 @@ class LLCubeMap : public LLRefCount LLPointer<LLImageGL> mImages[6]; LLPointer<LLImageRaw> mRawImages[6]; S32 mTextureStage; - S32 mTextureCoordStage; S32 mMatrixStage; }; diff --git a/indra/llrender/llfontbitmapcache.cpp b/indra/llrender/llfontbitmapcache.cpp index 4a1edf257d5f46a5fce5c43f6b5eea64bd24ae89..95f498e0b58a2fbb79e630a87284210cad7a2569 100644 --- a/indra/llrender/llfontbitmapcache.cpp +++ b/indra/llrender/llfontbitmapcache.cpp @@ -30,8 +30,7 @@ #include "llfontbitmapcache.h" LLFontBitmapCache::LLFontBitmapCache() -: LLTrace::MemTrackable<LLFontBitmapCache>("LLFontBitmapCache"), - mNumComponents(0), +: mNumComponents(0), mBitmapWidth(0), mBitmapHeight(0), mBitmapNum(-1), @@ -120,9 +119,6 @@ BOOL LLFontBitmapCache::nextOpenPos(S32 width, S32 &pos_x, S32 &pos_y, S32& bitm image_gl->createGLTexture(0, image_raw); gGL.getTexUnit(0)->bind(image_gl); image_gl->setFilteringOption(LLTexUnit::TFO_POINT); // was setMipFilterNearest(TRUE, TRUE); - - claimMem(image_raw); - claimMem(image_gl); } else { @@ -152,20 +148,8 @@ void LLFontBitmapCache::destroyGL() void LLFontBitmapCache::reset() { - for (std::vector<LLPointer<LLImageRaw> >::iterator it = mImageRawVec.begin(), end_it = mImageRawVec.end(); - it != end_it; - ++it) - { - disclaimMem(**it); - } mImageRawVec.clear(); - for (std::vector<LLPointer<LLImageGL> >::iterator it = mImageGLVec.begin(), end_it = mImageGLVec.end(); - it != end_it; - ++it) - { - disclaimMem(**it); - } mImageGLVec.clear(); mBitmapWidth = 0; diff --git a/indra/llrender/llfontbitmapcache.h b/indra/llrender/llfontbitmapcache.h index ecbb8ca6259bb49e09a78404e2fd60832fb2d4b1..b63fc749744c2aeaa289c0a1bb7fe8fd35efa281 100644 --- a/indra/llrender/llfontbitmapcache.h +++ b/indra/llrender/llfontbitmapcache.h @@ -32,7 +32,7 @@ // Maintain a collection of bitmaps containing rendered glyphs. // Generalizes the single-bitmap logic from LLFontFreetype and LLFontGL. -class LLFontBitmapCache : public LLTrace::MemTrackable<LLFontBitmapCache> +class LLFontBitmapCache { public: LLFontBitmapCache(); diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp index 636d140827147db9aa43ff9da7fb2c5e672bfc52..ddf6214be7ffa5d7f9c9b87af53ead2fe28f1f8b 100644 --- a/indra/llrender/llfontfreetype.cpp +++ b/indra/llrender/llfontfreetype.cpp @@ -143,8 +143,7 @@ LLFontGlyphInfo::LLFontGlyphInfo(U32 index) } LLFontFreetype::LLFontFreetype() -: LLTrace::MemTrackable<LLFontFreetype>("LLFontFreetype"), - mFontBitmapCachep(new LLFontBitmapCache), +: mFontBitmapCachep(new LLFontBitmapCache), mAscender(0.f), mDescender(0.f), mLineHeight(0.f), @@ -237,8 +236,6 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v S32 max_char_height = ll_round(0.5f + (y_max - y_min)); mFontBitmapCachep->init(components, max_char_width, max_char_height); - claimMem(mFontBitmapCachep); - if (!mFTFace->charmap) { @@ -253,7 +250,6 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v } mName = filename; - claimMem(mName); mPointSize = point_size; mStyle = LLFontGL::NORMAL; @@ -439,6 +435,7 @@ LLFontGlyphInfo* LLFontFreetype::addGlyph(llwchar wch) const LLFontGlyphInfo* LLFontFreetype::addGlyphFromFont(const LLFontFreetype *fontp, llwchar wch, U32 glyph_index) const { + LL_PROFILE_ZONE_SCOPED; if (mFTFace == NULL) return NULL; @@ -566,7 +563,6 @@ void LLFontFreetype::insertGlyphInfo(llwchar wch, LLFontGlyphInfo* gi) const } else { - claimMem(gi); mCharGlyphInfoMap[wch] = gi; } } @@ -610,11 +606,9 @@ void LLFontFreetype::resetBitmapCache() { for (auto& glyph_pair : mCharGlyphInfoMap) { - disclaimMem(glyph_pair.second); delete glyph_pair.second; } mCharGlyphInfoMap.clear(); - disclaimMem(mFontBitmapCachep); mFontBitmapCachep->reset(); // Adding default glyph is skipped for fallback fonts here as well as in loadFace(). diff --git a/indra/llrender/llfontfreetype.h b/indra/llrender/llfontfreetype.h index 9507ef0c90f1030d196dcbc14246bdf84a8a7694..cea3f2c2e2d6dbf8b717db3aba96740111816a17 100644 --- a/indra/llrender/llfontfreetype.h +++ b/indra/llrender/llfontfreetype.h @@ -97,7 +97,7 @@ struct LLFontGlyphInfo extern LLFontManager *gFontManagerp; -class LLFontFreetype final : public LLRefCount, public LLTrace::MemTrackable<LLFontFreetype> +class LLFontFreetype final : public LLRefCount { public: LLFontFreetype(); diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index 6ea0ab5a71b0f8bbfd6ecde3e0249ce54af97d0a..22c86862fe33c7666b1f86f996a752c498b807aa 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -103,8 +103,6 @@ S32 LLFontGL::getNumFaces(const std::string& filename) return mFontFreetype->getNumFaces(filename); } -static LLTrace::BlockTimerStatHandle FTM_RENDER_FONTS("Fonts"); - S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, const LLRect& rect, const LLColor4 &color, HAlign halign, VAlign valign, U8 style, ShadowType shadow, S32 max_chars, F32* right_x, BOOL use_ellipses) const { @@ -141,7 +139,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, const LLRectf& rec S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style, ShadowType shadow, S32 max_chars, S32 max_pixels, F32* right_x, BOOL use_ellipses) const { - LL_RECORD_BLOCK_TIME(FTM_RENDER_FONTS); + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; if(!sDisplayFont) //do not display texts { @@ -535,9 +533,19 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars, S32 begin_offset, S32 max_chars return cur_x / sScaleX; } +void LLFontGL::generateASCIIglyphs() +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI + for (U32 i = 32; (i < 127); i++) + { + mFontFreetype->getGlyphInfo(i); + } +} + // Returns the max number of complete characters from text (up to max_chars) that can be drawn in max_pixels S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_chars, EWordWrapStyle end_on_word_boundary) const { + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI if (!wchars || !wchars[0] || max_chars == 0) { return 0; @@ -807,6 +815,8 @@ void LLFontGL::initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, const std::st { sFontRegistry->reset(); } + + LLFontGL::loadDefaultFonts(); } // Force standard fonts to get generated up front. @@ -816,6 +826,7 @@ void LLFontGL::initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, const std::st // static bool LLFontGL::loadDefaultFonts() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI bool succ = true; succ &= (NULL != getFontSansSerifSmall()); succ &= (NULL != getFontSansSerif()); @@ -823,10 +834,18 @@ bool LLFontGL::loadDefaultFonts() succ &= (NULL != getFontSansSerifHuge()); succ &= (NULL != getFontSansSerifBold()); succ &= (NULL != getFontMonospace()); - succ &= (NULL != getFontExtChar()); return succ; } +void LLFontGL::loadCommonFonts() +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI + getFont(LLFontDescriptor("SansSerif", "Small", BOLD)); + getFont(LLFontDescriptor("SansSerif", "Large", BOLD)); + getFont(LLFontDescriptor("SansSerif", "Huge", BOLD)); + getFont(LLFontDescriptor("Monospace", "Medium", 0)); +} + // static void LLFontGL::destroyDefaultFonts() { @@ -1008,12 +1027,6 @@ LLFontGL* LLFontGL::getFontSansSerifBold() return fontp; } -//static -LLFontGL* LLFontGL::getFontExtChar() -{ - return getFontSansSerif(); -} - //static LLFontGL* LLFontGL::getFont(const LLFontDescriptor& desc) { diff --git a/indra/llrender/llfontgl.h b/indra/llrender/llfontgl.h index 90b741264a2b36051aa98d7c3b68f1fbd5cd7430..f7461af3dfbb6c7afeccb731c8b50de5f2323649 100644 --- a/indra/llrender/llfontgl.h +++ b/indra/llrender/llfontgl.h @@ -160,12 +160,15 @@ class LLFontGL const LLFontDescriptor& getFontDesc() const; + void generateASCIIglyphs(); + static void initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, const std::string& app_dir, bool create_gl_textures = true); // Load sans-serif, sans-serif-small, etc. // Slow, requires multiple seconds to load fonts. static bool loadDefaultFonts(); + static void loadCommonFonts(); static void destroyDefaultFonts(); static void destroyAllGL(); @@ -190,7 +193,6 @@ class LLFontGL static LLFontGL* getFontSansSerifBig(); static LLFontGL* getFontSansSerifHuge(); static LLFontGL* getFontSansSerifBold(); - static LLFontGL* getFontExtChar(); static LLFontGL* getFont(const LLFontDescriptor& desc); // Use with legacy names like "SANSSERIF_SMALL" or "OCRA" static LLFontGL* getFontByName(const std::string& name); diff --git a/indra/llrender/llfontregistry.cpp b/indra/llrender/llfontregistry.cpp index 33a33af160d2e086061ac4ac1f54cac25b1af404..bc1a2f888709813f5b31dccb90aa57c4f5112525 100644 --- a/indra/llrender/llfontregistry.cpp +++ b/indra/llrender/llfontregistry.cpp @@ -597,6 +597,11 @@ LLFontGL *LLFontRegistry::getFont(const LLFontDescriptor& desc) <<" style=[" << ((S32) desc.getStyle()) << "]" << " size=[" << desc.getSize() << "]" << LL_ENDL; } + else + { + //generate glyphs for ASCII chars to avoid stalls later + fontp->generateASCIIglyphs(); + } return fontp; } } diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index afbff22862048d809b898c911472ff301268fd03..efbbeff646137495e4d9f83e1790153728976739 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -53,9 +53,10 @@ #endif BOOL gDebugSession = FALSE; +BOOL gDebugGLSession = FALSE; BOOL gHeadlessClient = FALSE; +BOOL gNonInteractive = FALSE; BOOL gGLActive = FALSE; -BOOL gGLDebugLoggingEnabled = TRUE; static const std::string HEADLESS_VENDOR_STRING("Linden Lab"); static const std::string HEADLESS_RENDERER_STRING("Headless"); @@ -75,25 +76,29 @@ void APIENTRY gl_debug_callback(GLenum source, const GLchar* message, GLvoid* userParam) { - if (gGLDebugLoggingEnabled) + if (severity != GL_DEBUG_SEVERITY_HIGH && + severity != GL_DEBUG_SEVERITY_MEDIUM && + severity != GL_DEBUG_SEVERITY_LOW) + { //suppress out-of-spec messages sent by nvidia driver (mostly vertexbuffer hints) + return; + } + + if (severity == GL_DEBUG_SEVERITY_HIGH) { - if (severity == GL_DEBUG_SEVERITY_HIGH) - { - LL_WARNS() << "----- GL ERROR --------" << LL_ENDL; - } - else - { - LL_WARNS() << "----- GL WARNING -------" << LL_ENDL; - } - LL_WARNS() << "Type: " << std::hex << type << LL_ENDL; - LL_WARNS() << "ID: " << std::hex << id << LL_ENDL; - LL_WARNS() << "Severity: " << std::hex << severity << LL_ENDL; - LL_WARNS() << "Message: " << message << LL_ENDL; - LL_WARNS() << "-----------------------" << LL_ENDL; - if (severity == GL_DEBUG_SEVERITY_HIGH) - { - LL_ERRS() << "Halting on GL Error" << LL_ENDL; - } + LL_WARNS() << "----- GL ERROR --------" << LL_ENDL; + } + else + { + LL_WARNS() << "----- GL WARNING -------" << LL_ENDL; + } + LL_WARNS() << "Type: " << std::hex << type << LL_ENDL; + LL_WARNS() << "ID: " << std::hex << id << LL_ENDL; + LL_WARNS() << "Severity: " << std::hex << severity << LL_ENDL; + LL_WARNS() << "Message: " << message << LL_ENDL; + LL_WARNS() << "-----------------------" << LL_ENDL; + if (severity == GL_DEBUG_SEVERITY_HIGH) + { + LL_ERRS() << "Halting on GL Error" << LL_ENDL; } } @@ -158,15 +163,13 @@ LLGLManager::LLGLManager() : mHasMapBufferRange(FALSE), mHasFlushBufferRange(FALSE), mHasPBuffer(FALSE), - mHasShaderObjects(FALSE), - mHasVertexShader(FALSE), - mHasFragmentShader(FALSE), mNumTextureImageUnits(0), mHasOcclusionQuery(FALSE), mHasTimerQuery(FALSE), mHasOcclusionQuery2(FALSE), mHasPointParameters(FALSE), mHasDrawBuffers(FALSE), + mHasDepthClamp(FALSE), mHasTextureRectangle(FALSE), mHasTextureMultisample(FALSE), mHasTransformFeedback(FALSE), @@ -183,14 +186,9 @@ LLGLManager::LLGLManager() : mHasTextureSwizzle(false), mHasGPUShader4(false), mHasClipControl(false), - mIsATI(FALSE), + mIsAMD(FALSE), mIsNVIDIA(FALSE), mIsIntel(FALSE), - mIsGF2or4MX(FALSE), - mIsGF3(FALSE), - mIsGFFX(FALSE), - mATIOffsetVerticalLines(FALSE), - mATIOldDriver(FALSE), #if LL_DARWIN mIsMobileGF(FALSE), #endif @@ -315,59 +313,17 @@ bool LLGLManager::initGL() // Trailing space necessary to keep "nVidia Corpor_ati_on" cards // from being recognized as ATI. + // NOTE: AMD has been pretty good about not breaking this check, do not rename without good reason if (mGLVendor.substr(0,4) == "ATI ") { - mGLVendorShort = "ATI"; + mGLVendorShort = "AMD"; // *TODO: Fix this? - mIsATI = TRUE; - -#if LL_WINDOWS && !LL_MESA_HEADLESS - if (mDriverVersionRelease < 3842) - { - mATIOffsetVerticalLines = TRUE; - } -#endif // LL_WINDOWS - -#if (LL_WINDOWS || LL_LINUX) && !LL_MESA_HEADLESS - // count any pre OpenGL 3.0 implementation as an old driver - if (mGLVersion < 3.f) - { - mATIOldDriver = TRUE; - } -#endif // (LL_WINDOWS || LL_LINUX) && !LL_MESA_HEADLESS + mIsAMD = TRUE; } else if (mGLVendor.find("NVIDIA ") != std::string::npos) { mGLVendorShort = "NVIDIA"; mIsNVIDIA = TRUE; - if ( mGLRenderer.find("GEFORCE4 MX") != std::string::npos - || mGLRenderer.find("GEFORCE2") != std::string::npos - || mGLRenderer.find("GEFORCE 2") != std::string::npos - || mGLRenderer.find("GEFORCE4 460 GO") != std::string::npos - || mGLRenderer.find("GEFORCE4 440 GO") != std::string::npos - || mGLRenderer.find("GEFORCE4 420 GO") != std::string::npos) - { - mIsGF2or4MX = TRUE; - } - else if (mGLRenderer.find("GEFORCE FX") != std::string::npos - || mGLRenderer.find("QUADRO FX") != std::string::npos - || mGLRenderer.find("NV34") != std::string::npos) - { - mIsGFFX = TRUE; - } - else if(mGLRenderer.find("GEFORCE3") != std::string::npos) - { - mIsGF3 = TRUE; - } -#if LL_DARWIN - else if ((mGLRenderer.find("9400M") != std::string::npos) - || (mGLRenderer.find("9600M") != std::string::npos) - || (mGLRenderer.find("9800M") != std::string::npos)) - { - mIsMobileGF = TRUE; - } -#endif - } else if (mGLVendor.find("INTEL") != std::string::npos #if LL_LINUX @@ -480,29 +436,29 @@ bool LLGLManager::initGL() stop_glerror(); - if (mHasFragmentShader) - { - GLint num_tex_image_units; - glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &num_tex_image_units); - mNumTextureImageUnits = llmin(num_tex_image_units, 32); - } + GLint num_tex_image_units; + glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &num_tex_image_units); + mNumTextureImageUnits = llmin(num_tex_image_units, 32); LL_INFOS() << "NUM TEX IMAGE UNITS: " << mNumTextureImageUnits << LL_ENDL; - if (LLRender::sGLCoreProfile) - { - mNumTextureUnits = llmin(mNumTextureImageUnits, MAX_GL_TEXTURE_UNITS); - } - else if (mHasMultitexture) - { - GLint num_tex_units; - glGetIntegerv(GL_MAX_TEXTURE_UNITS, &num_tex_units); - mNumTextureUnits = llmin(num_tex_units, (GLint)MAX_GL_TEXTURE_UNITS); - if (mIsIntel) - { - mNumTextureUnits = llmin(mNumTextureUnits, 2); - } - } + if (mHasMultitexture) + { + if (LLRender::sGLCoreProfile) + { + mNumTextureUnits = llmin(mNumTextureImageUnits, MAX_GL_TEXTURE_UNITS); + } + else + { + GLint num_tex_units; + glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &num_tex_units); + mNumTextureUnits = llmin(num_tex_units, (GLint)MAX_GL_TEXTURE_UNITS); + if (mIsIntel) + { + mNumTextureUnits = llmin(mNumTextureUnits, 2); + } + } + } else { mHasRequirements = FALSE; @@ -511,6 +467,14 @@ bool LLGLManager::initGL() LL_WARNS("RenderInit") << "GL Drivers do not support GL_ARB_multitexture" << LL_ENDL; return false; } + + if (!mHasFramebufferObject) + { + mHasRequirements = FALSE; + + LL_WARNS("RenderInit") << "GL Drivers do not support GL_ARB_framebuffer_object" << LL_ENDL; + return false; + } stop_glerror(); @@ -534,29 +498,8 @@ bool LLGLManager::initGL() stop_glerror(); - if (mHasDebugOutput && gDebugGL) - { //setup debug output callback - glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW, 0, NULL, GL_TRUE); - glDebugMessageCallback((GLDEBUGPROC) gl_debug_callback, NULL); - glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); - } - - stop_glerror(); - //HACK always disable texture multisample, use FXAA instead mHasTextureMultisample = FALSE; -#if LL_WINDOWS - if (mIsATI) - { //using multisample textures on ATI results in black screen for some reason - mHasTextureMultisample = FALSE; - } - - - if (mIsIntel && mGLVersion <= 3.f) - { //never try to use framebuffer objects on older intel drivers (crashy) - mHasFramebufferObject = FALSE; - } -#endif if (mHasFramebufferObject) { @@ -732,9 +675,9 @@ void LLGLManager::asLLSD(LLSD& info) info["has_map_buffer_range"] = mHasMapBufferRange; info["has_flush_buffer_range"] = mHasFlushBufferRange; info["has_pbuffer"] = mHasPBuffer; - info["has_shader_objects"] = mHasShaderObjects; - info["has_vertex_shader"] = mHasVertexShader; - info["has_fragment_shader"] = mHasFragmentShader; + info["has_shader_objects"] = std::string("Assumed TRUE"); // was mHasShaderObjects; + info["has_vertex_shader"] = std::string("Assumed TRUE"); // was mHasVertexShader; + info["has_fragment_shader"] = std::string("Assumed TRUE"); // was mHasFragmentShader; info["num_texture_image_units"] = mNumTextureImageUnits; info["has_occlusion_query"] = mHasOcclusionQuery; info["has_timer_query"] = mHasTimerQuery; @@ -762,14 +705,9 @@ void LLGLManager::asLLSD(LLSD& info) info["has_clip_control"] = mHasClipControl; // Vendor-specific extensions - info["is_ati"] = mIsATI; + info["is_ati"] = mIsAMD; // note, do not rename is_ati to is_amd without coordinating with DW info["is_nvidia"] = mIsNVIDIA; info["is_intel"] = mIsIntel; - info["is_gf2or4mx"] = mIsGF2or4MX; - info["is_gf3"] = mIsGF3; - info["is_gf_gfx"] = mIsGFFX; - info["ati_offset_vertical_lines"] = mATIOffsetVerticalLines; - info["ati_old_driver"] = mATIOldDriver; // Other fields info["has_requirements"] = mHasRequirements; @@ -842,9 +780,6 @@ void LLGLManager::initExtensions() mHasCubeMap = FALSE; mHasOcclusionQuery = FALSE; mHasPointParameters = FALSE; - mHasShaderObjects = FALSE; - mHasVertexShader = FALSE; - mHasFragmentShader = FALSE; mHasTextureRectangle = FALSE; #else // LL_MESA_HEADLESS mHasMultitexture = mGLVersion >= 1.3f || epoxy_has_gl_extension("GL_ARB_multitexture"); @@ -864,7 +799,8 @@ void LLGLManager::initExtensions() mHasSync = mGLVersion >= 3.2f || epoxy_has_gl_extension("GL_ARB_sync"); mHasMapBufferRange = mGLVersion >= 3.0f || epoxy_has_gl_extension("GL_ARB_map_buffer_range"); mHasFlushBufferRange = epoxy_has_gl_extension("GL_APPLE_flush_buffer_range"); - mHasDepthClamp = mGLVersion >= 3.2f || (epoxy_has_gl_extension("GL_ARB_depth_clamp") || epoxy_has_gl_extension("GL_NV_depth_clamp")); + // NOTE: Using extensions breaks reflections when Shadows are set to projector. See: SL-16727 + //mHasDepthClamp = mGLVersion >= 3.2f || (epoxy_has_gl_extension("GL_ARB_depth_clamp") || epoxy_has_gl_extension("GL_NV_depth_clamp")); // mask out FBO support when packed_depth_stencil isn't there 'cause we need it for LLRenderTarget -Brad #ifdef GL_ARB_framebuffer_object mHasFramebufferObject = mGLVersion >= 3.0f || epoxy_has_gl_extension("GL_ARB_framebuffer_object"); @@ -901,10 +837,6 @@ void LLGLManager::initExtensions() #if !LL_DARWIN mHasPointParameters = mGLVersion >= 1.4f || epoxy_has_gl_extension("GL_ARB_point_parameters"); #endif - mHasShaderObjects = mGLVersion >= 2.0f || (epoxy_has_gl_extension("GL_ARB_shader_objects") && (LLRender::sGLCoreProfile || epoxy_has_gl_extension("GL_ARB_shading_language_100"))); - mHasVertexShader = mGLVersion >= 2.0f || (epoxy_has_gl_extension("GL_ARB_vertex_program") && epoxy_has_gl_extension("GL_ARB_vertex_shader") - && (LLRender::sGLCoreProfile || epoxy_has_gl_extension("GL_ARB_shading_language_100"))); - mHasFragmentShader = mGLVersion >= 2.0f || (epoxy_has_gl_extension("GL_ARB_fragment_shader") && (LLRender::sGLCoreProfile || epoxy_has_gl_extension("GL_ARB_shading_language_100"))); mHasTextureSwizzle = mGLVersion >= 3.3f || epoxy_has_gl_extension("GL_ARB_texture_swizzle"); mHasGPUShader4 = mGLVersion >= 3.0f || epoxy_has_gl_extension("GL_EXT_gpu_shader4"); @@ -931,9 +863,6 @@ void LLGLManager::initExtensions() mHasCubeMap = FALSE; mHasOcclusionQuery = FALSE; mHasPointParameters = FALSE; - mHasShaderObjects = FALSE; - mHasVertexShader = FALSE; - mHasFragmentShader = FALSE; mHasTextureSwizzle = FALSE; mHasGPUShader4 = FALSE; mHasClipControl = FALSE; @@ -949,9 +878,6 @@ void LLGLManager::initExtensions() mHasAnisotropic = FALSE; //mHasCubeMap = FALSE; // apparently fatal on Intel 915 & similar //mHasOcclusionQuery = FALSE; // source of many ATI system hangs - mHasShaderObjects = FALSE; - mHasVertexShader = FALSE; - mHasFragmentShader = FALSE; mHasBlendFuncSeparate = FALSE; LL_WARNS("RenderInit") << "GL extension support forced to SIMPLE level via LL_GL_BASICEXT" << LL_ENDL; } @@ -973,9 +899,6 @@ void LLGLManager::initExtensions() if (strchr(blacklist,'j')) mHasCubeMap = FALSE;//S // if (strchr(blacklist,'k')) mHasATIVAO = FALSE;//S if (strchr(blacklist,'l')) mHasOcclusionQuery = FALSE; - if (strchr(blacklist,'m')) mHasShaderObjects = FALSE;//S - if (strchr(blacklist,'n')) mHasVertexShader = FALSE;//S - if (strchr(blacklist,'o')) mHasFragmentShader = FALSE;//S if (strchr(blacklist,'p')) mHasPointParameters = FALSE;//S if (strchr(blacklist,'q')) mHasFramebufferObject = FALSE;//S if (strchr(blacklist,'r')) mHasDrawBuffers = FALSE;//S @@ -1022,18 +945,6 @@ void LLGLManager::initExtensions() { LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_point_parameters" << LL_ENDL; } - if (!mHasShaderObjects) - { - LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_shader_objects" << LL_ENDL; - } - if (!mHasVertexShader) - { - LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_vertex_shader" << LL_ENDL; - } - if (!mHasFragmentShader) - { - LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_fragment_shader" << LL_ENDL; - } if (!mHasBlendFuncSeparate) { LL_INFOS("RenderInit") << "Couldn't initialize GL_EXT_blend_func_separate" << LL_ENDL; @@ -1049,7 +960,6 @@ void LLGLManager::initExtensions() // LL_INFOS("RenderInit") << "Disabling mip-map generation for Intel GPUs" << LL_ENDL; // mHasMipMapGeneration = FALSE; // } - // Misc glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, (GLint*) &mGLMaxVertexRange); glGetIntegerv(GL_MAX_ELEMENTS_INDICES, (GLint*) &mGLMaxIndexRange); @@ -1470,206 +1380,30 @@ void LLGLState::checkTextureChannels(const std::string& msg) #endif } -void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask) -{ - if (!gDebugGL || LLGLSLShader::sNoFixedFunction) - { - return; - } - - stop_glerror(); - BOOL error = FALSE; - - GLint active_texture; - glGetIntegerv(GL_CLIENT_ACTIVE_TEXTURE, &active_texture); - - if (active_texture != GL_TEXTURE0) - { - LL_WARNS() << "Client active texture corrupted: " << active_texture << LL_ENDL; - if (gDebugSession) - { - gFailLog << "Client active texture corrupted: " << active_texture << std::endl; - } - error = TRUE; - } - - /*glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture); - if (active_texture != GL_TEXTURE0) - { - LL_WARNS() << "Active texture corrupted: " << active_texture << LL_ENDL; - if (gDebugSession) - { - gFailLog << "Active texture corrupted: " << active_texture << std::endl; - } - error = TRUE; - }*/ - - static const char* label[] = - { - "GL_VERTEX_ARRAY", - "GL_NORMAL_ARRAY", - "GL_COLOR_ARRAY", - "GL_TEXTURE_COORD_ARRAY" - }; - - static GLint value[] = - { - GL_VERTEX_ARRAY, - GL_NORMAL_ARRAY, - GL_COLOR_ARRAY, - GL_TEXTURE_COORD_ARRAY - }; - - static const U32 mask[] = - { //copied from llvertexbuffer.h - 0x0001, //MAP_VERTEX, - 0x0002, //MAP_NORMAL, - 0x0010, //MAP_COLOR, - 0x0004, //MAP_TEXCOORD - }; - - - for (S32 j = 1; j < 4; j++) - { - if (glIsEnabled(value[j])) - { - if (!(mask[j] & data_mask)) - { - error = TRUE; - LL_WARNS("RenderState") << "GL still has " << label[j] << " enabled." << LL_ENDL; - if (gDebugSession) - { - gFailLog << "GL still has " << label[j] << " enabled." << std::endl; - } - } - } - else - { - if (mask[j] & data_mask) - { - error = TRUE; - LL_WARNS("RenderState") << "GL does not have " << label[j] << " enabled." << LL_ENDL; - if (gDebugSession) - { - gFailLog << "GL does not have " << label[j] << " enabled." << std::endl; - } - } - } - } - - glClientActiveTexture(GL_TEXTURE1); - gGL.getTexUnit(1)->activate(); - if (glIsEnabled(GL_TEXTURE_COORD_ARRAY)) - { - if (!(data_mask & 0x0008)) - { - error = TRUE; - LL_WARNS("RenderState") << "GL still has GL_TEXTURE_COORD_ARRAY enabled on channel 1." << LL_ENDL; - if (gDebugSession) - { - gFailLog << "GL still has GL_TEXTURE_COORD_ARRAY enabled on channel 1." << std::endl; - } - } - } - else - { - if (data_mask & 0x0008) - { - error = TRUE; - LL_WARNS("RenderState") << "GL does not have GL_TEXTURE_COORD_ARRAY enabled on channel 1." << LL_ENDL; - if (gDebugSession) - { - gFailLog << "GL does not have GL_TEXTURE_COORD_ARRAY enabled on channel 1." << std::endl; - } - } - } - - /*if (glIsEnabled(GL_TEXTURE_2D)) - { - if (!(data_mask & 0x0008)) - { - error = TRUE; - LL_WARNS("RenderState") << "GL still has GL_TEXTURE_2D enabled on channel 1." << LL_ENDL; - if (gDebugSession) - { - gFailLog << "GL still has GL_TEXTURE_2D enabled on channel 1." << std::endl; - } - } - } - else - { - if (data_mask & 0x0008) - { - error = TRUE; - LL_WARNS("RenderState") << "GL does not have GL_TEXTURE_2D enabled on channel 1." << LL_ENDL; - if (gDebugSession) - { - gFailLog << "GL does not have GL_TEXTURE_2D enabled on channel 1." << std::endl; - } - } - }*/ - - glClientActiveTexture(GL_TEXTURE0); - gGL.getTexUnit(0)->activate(); - - if (gGLManager.mHasVertexShader && LLGLSLShader::sNoFixedFunction) - { //make sure vertex attribs are all disabled - GLint count; - glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &count); - for (GLint i = 0; i < count; i++) - { - GLint enabled; - glGetVertexAttribiv((GLuint) i, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &enabled); - if (enabled) - { - error = TRUE; - LL_WARNS("RenderState") << "GL still has vertex attrib array " << i << " enabled." << LL_ENDL; - if (gDebugSession) - { - gFailLog << "GL still has vertex attrib array " << i << " enabled." << std::endl; - } - } - } - } - - if (error) - { - if (gDebugSession) - { - ll_fail("LLGLState::checkClientArrays failed."); - } - else - { - LL_GL_ERRS << "GL client array corruption detected. " << msg << LL_ENDL; - } - } -} - /////////////////////////////////////////////////////////////////////// LLGLState::LLGLState(LLGLenum state, S32 enabled) : mState(state), mWasEnabled(FALSE), mIsEnabled(FALSE) { - if (LLGLSLShader::sNoFixedFunction) - { //always ignore state that's deprecated post GL 3.0 - switch (state) - { - case GL_ALPHA_TEST: - case GL_NORMALIZE: - case GL_TEXTURE_GEN_R: - case GL_TEXTURE_GEN_S: - case GL_TEXTURE_GEN_T: - case GL_TEXTURE_GEN_Q: - case GL_LIGHTING: - case GL_COLOR_MATERIAL: - case GL_FOG: - case GL_LINE_STIPPLE: - case GL_POLYGON_STIPPLE: - mState = 0; - break; - } + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; + switch (state) + { + case GL_ALPHA_TEST: + case GL_NORMALIZE: + case GL_TEXTURE_GEN_R: + case GL_TEXTURE_GEN_S: + case GL_TEXTURE_GEN_T: + case GL_TEXTURE_GEN_Q: + case GL_LIGHTING: + case GL_COLOR_MATERIAL: + case GL_FOG: + case GL_LINE_STIPPLE: + case GL_POLYGON_STIPPLE: + mState = 0; + break; } + stop_glerror(); if (mState) { @@ -1708,6 +1442,7 @@ void LLGLState::setEnabled(S32 enabled) LLGLState::~LLGLState() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; stop_glerror(); if (mState) { @@ -1894,7 +1629,8 @@ LLGLUserClipPlane::LLGLUserClipPlane(const LLPlane& p, const LLMatrix4a& modelvi mModelview = modelview; mProjection = projection; - setPlane(p[0], p[1], p[2], p[3]); + //flip incoming LLPlane to get consistent behavior compared to frustum culling + setPlane(-p[0], -p[1], -p[2], -p[3]); } } @@ -2144,22 +1880,10 @@ LLGLSPipelineSkyBox::LLGLSPipelineSkyBox() , mCullFace(GL_CULL_FACE) , mSquashClip() { - if (!LLGLSLShader::sNoFixedFunction) - { - glDisable(GL_LIGHTING); - glDisable(GL_FOG); - glDisable(GL_CLIP_PLANE0); - } } LLGLSPipelineSkyBox::~LLGLSPipelineSkyBox() { - if (!LLGLSLShader::sNoFixedFunction) - { - glEnable(GL_LIGHTING); - glEnable(GL_FOG); - glEnable(GL_CLIP_PLANE0); - } } LLGLSPipelineDepthTestSkyBox::LLGLSPipelineDepthTestSkyBox(bool depth_test, bool depth_write) @@ -2186,3 +1910,4 @@ extern "C" } #endif + diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h index b804b71e24cd3eb515ea2243032a14f9fab70911..bb40a809a816e263d1dc830b20b5fd3c6565833f 100644 --- a/indra/llrender/llgl.h +++ b/indra/llrender/llgl.h @@ -47,6 +47,7 @@ extern BOOL gDebugGL; extern BOOL gDebugSession; +extern BOOL gDebugGLSession; extern llofstream gFailLog; #define LL_GL_ERRS LL_ERRS("RenderState") @@ -96,9 +97,6 @@ class LLGLManager BOOL mHasMapBufferRange; BOOL mHasFlushBufferRange; BOOL mHasPBuffer; - BOOL mHasShaderObjects; - BOOL mHasVertexShader; - BOOL mHasFragmentShader; S32 mNumTextureImageUnits; BOOL mHasOcclusionQuery; BOOL mHasTimerQuery; @@ -127,14 +125,9 @@ class LLGLManager bool mHasClipControl = false; // Vendor-specific extensions - BOOL mIsATI; + BOOL mIsAMD; BOOL mIsNVIDIA; BOOL mIsIntel; - BOOL mIsGF2or4MX; - BOOL mIsGF3; - BOOL mIsGFFX; - BOOL mATIOffsetVerticalLines; - BOOL mATIOldDriver; #if LL_DARWIN // Needed to distinguish problem cards on older Macs that break with Materials @@ -275,7 +268,6 @@ class LLGLState static void dumpStates(); static void checkStates(const std::string& msg = ""); static void checkTextureChannels(const std::string& msg = ""); - static void checkClientArrays(const std::string& msg = "", U32 data_mask = 0); protected: static absl::flat_hash_map<LLGLenum, LLGLboolean> sStateMap; @@ -445,6 +437,7 @@ void init_glstates(); void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor_specific, std::string* version_string ); extern BOOL gHeadlessClient; +extern BOOL gNonInteractive; extern BOOL gGLActive; #endif // LL_LLGL_H diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h index 20b82e462d6c8519e4893a55a3c0521f13588d00..633bd36a83ccd815a9bc0d0d165a5e350c80c3fb 100644 --- a/indra/llrender/llglheaders.h +++ b/indra/llrender/llglheaders.h @@ -55,4 +55,23 @@ #endif // LL_MESA +#if defined(TRACY_ENABLE) && LL_PROFILER_ENABLE_TRACY_OPENGL + // Tracy uses the following: + // glGenQueries + // glGetQueryiv + // glGetQueryObjectiv + #define glGenQueries glGenQueriesARB + #define glGetQueryiv glGetQueryivARB + #define glGetQueryObjectiv glGetQueryObjectivARB + #include <tracy/TracyOpenGL.hpp> + + #define LL_PROFILER_GPU_ZONEC(name,color) TracyGpuZoneC(name,color); + #define LL_PROFILER_GPU_COLLECT TracyGpuCollect + #define LL_PROFILER_GPU_CONTEXT TracyGpuContext +#else + #define LL_PROFILER_GPU_ZONEC(name,color) (void)name;(void)color; + #define LL_PROFILER_GPU_COLLECT + #define LL_PROFILER_GPU_CONTEXT +#endif + #endif // LL_LLGLHEADERS_H diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index 54b3e92999535ed42e77b19fa84be7b4bee24674..0b113ee43b6eceeb9e459ef9c37aae5d1fea8a48 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -46,7 +46,6 @@ using std::string; GLuint LLGLSLShader::sCurBoundShader = 0; LLGLSLShader* LLGLSLShader::sCurBoundShaderPtr = NULL; S32 LLGLSLShader::sIndexedTextureChannels = 0; -bool LLGLSLShader::sNoFixedFunction = false; bool LLGLSLShader::sProfileEnabled = false; std::set<LLGLSLShader*> LLGLSLShader::sInstances; U64 LLGLSLShader::sTotalTimeElapsed = 0; @@ -203,6 +202,7 @@ void LLGLSLShader::dumpStats() //static void LLGLSLShader::startProfile() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER; if (sProfileEnabled && sCurBoundShaderPtr) { sCurBoundShaderPtr->placeProfileQuery(); @@ -213,6 +213,7 @@ void LLGLSLShader::startProfile() //static void LLGLSLShader::stopProfile(U32 count, U32 mode) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER; if (sProfileEnabled && sCurBoundShaderPtr) { sCurBoundShaderPtr->readProfileQuery(count, mode); @@ -378,6 +379,8 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * attributes, U32 varying_count, const char** varyings) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER; + unloadInternal(); sInstances.insert(this); @@ -557,6 +560,8 @@ void LLGLSLShader::attachObjects(GLuint* objects, S32 count) BOOL LLGLSLShader::mapAttributes(const std::vector<LLStaticHashedString> * attributes) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER; + //before linking, make sure reserved attributes always have consistent locations for (U32 i = 0; i < LLShaderMgr::instance()->mReservedAttribs.size(); i++) { @@ -618,6 +623,8 @@ BOOL LLGLSLShader::mapAttributes(const std::vector<LLStaticHashedString> * attri void LLGLSLShader::mapUniform(const gl_uniform_data_t& gl_uniform, const std::vector<LLStaticHashedString> * uniforms) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER; + char* name = (char*)gl_uniform.name.c_str(); //blegh #if !LL_DARWIN GLint size = gl_uniform.size; @@ -738,6 +745,8 @@ void LLGLSLShader::removePermutation(std::string name) GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER; + if ((type >= GL_SAMPLER_1D && type <= GL_SAMPLER_2D_RECT_SHADOW) || type == GL_SAMPLER_2D_MULTISAMPLE) { //this here is a texture @@ -750,7 +759,9 @@ GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type) BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms) { - BOOL res = TRUE; + LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER; + + BOOL res = TRUE; const auto& reservedUniforms = LLShaderMgr::instance()->mReservedUniforms; @@ -839,6 +850,8 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms) BOOL LLGLSLShader::link(BOOL suppress_errors) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER; + BOOL success = LLShaderMgr::instance()->linkProgramObject(mProgramObject, suppress_errors); if (!success && !suppress_errors) @@ -851,56 +864,65 @@ BOOL LLGLSLShader::link(BOOL suppress_errors) void LLGLSLShader::bind() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER; + gGL.flush(); - if (gGLManager.mHasShaderObjects) + + if (sCurBoundShader != mProgramObject) // Don't re-bind current shader { LLVertexBuffer::unbind(); glUseProgram(mProgramObject); sCurBoundShader = mProgramObject; sCurBoundShaderPtr = this; - if (mUniformsDirty) - { - LLShaderMgr::instance()->updateShaderUniforms(this); - mUniformsDirty = FALSE; - } + } + + if (mUniformsDirty) + { + LLShaderMgr::instance()->updateShaderUniforms(this); + mUniformsDirty = FALSE; } } -void LLGLSLShader::unbind() +void LLGLSLShader::bind(bool rigged) { - gGL.flush(); - if (gGLManager.mHasShaderObjects) + if (rigged) { - stop_glerror(); - if (gGLManager.mIsNVIDIA) - { - for (U32 i = 0; i < mAttribute.size(); ++i) - { - vertexAttrib4f(i, 0,0,0,1); - stop_glerror(); - } - } - LLVertexBuffer::unbind(); - glUseProgram(0); - sCurBoundShader = 0; - sCurBoundShaderPtr = NULL; - stop_glerror(); + llassert(mRiggedVariant); + mRiggedVariant->bind(); + } + else + { + bind(); } } +void LLGLSLShader::unbind() +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER; + + gGL.flush(); + stop_glerror(); + LLVertexBuffer::unbind(); + glUseProgram(0); + sCurBoundShader = 0; + sCurBoundShaderPtr = NULL; + stop_glerror(); +} + void LLGLSLShader::bindNoShader(void) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER; + LLVertexBuffer::unbind(); - if (gGLManager.mHasShaderObjects) - { - glUseProgram(0); - sCurBoundShader = 0; - sCurBoundShaderPtr = NULL; - } + glUseProgram(0); + sCurBoundShader = 0; + sCurBoundShaderPtr = NULL; } S32 LLGLSLShader::bindTexture(const std::string &uniform, LLTexture *texture, LLTexUnit::eTextureType mode, LLTexUnit::eTextureColorSpace colorspace) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER; + S32 channel = 0; channel = getUniformLocation(uniform); @@ -909,6 +931,8 @@ S32 LLGLSLShader::bindTexture(const std::string &uniform, LLTexture *texture, LL S32 LLGLSLShader::bindTexture(S32 uniform, LLTexture *texture, LLTexUnit::eTextureType mode, LLTexUnit::eTextureColorSpace colorspace) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER; + if (uniform < 0 || uniform >= (S32)mTexture.size()) { LL_SHADER_UNIFORM_ERRS() << "Uniform out of range: " << uniform << LL_ENDL; @@ -919,7 +943,7 @@ S32 LLGLSLShader::bindTexture(S32 uniform, LLTexture *texture, LLTexUnit::eTextu if (uniform > -1) { - gGL.getTexUnit(uniform)->bind(texture, mode); + gGL.getTexUnit(uniform)->bindFast(texture); //gGL.getTexUnit(uniform)->setTextureColorSpace(colorspace); } @@ -928,6 +952,8 @@ S32 LLGLSLShader::bindTexture(S32 uniform, LLTexture *texture, LLTexUnit::eTextu S32 LLGLSLShader::unbindTexture(const std::string &uniform, LLTexUnit::eTextureType mode) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER; + S32 channel = 0; channel = getUniformLocation(uniform); @@ -936,6 +962,8 @@ S32 LLGLSLShader::unbindTexture(const std::string &uniform, LLTexUnit::eTextureT S32 LLGLSLShader::unbindTexture(S32 uniform, LLTexUnit::eTextureType mode) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER; + if (uniform < 0 || uniform >= (S32)mTexture.size()) { LL_SHADER_UNIFORM_ERRS() << "Uniform out of range: " << uniform << LL_ENDL; @@ -946,7 +974,7 @@ S32 LLGLSLShader::unbindTexture(S32 uniform, LLTexUnit::eTextureType mode) if (uniform > -1) { - gGL.getTexUnit(uniform)->unbind(mode); + gGL.getTexUnit(uniform)->unbindFast(mode); } return uniform; @@ -954,6 +982,8 @@ S32 LLGLSLShader::unbindTexture(S32 uniform, LLTexUnit::eTextureType mode) S32 LLGLSLShader::enableTexture(S32 uniform, LLTexUnit::eTextureType mode, LLTexUnit::eTextureColorSpace space) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER; + if (uniform < 0 || uniform >= (S32)mTexture.size()) { LL_SHADER_UNIFORM_ERRS() << "Uniform out of range: " << uniform << LL_ENDL; @@ -971,6 +1001,8 @@ S32 LLGLSLShader::enableTexture(S32 uniform, LLTexUnit::eTextureType mode, LLTex S32 LLGLSLShader::disableTexture(S32 uniform, LLTexUnit::eTextureType mode, LLTexUnit::eTextureColorSpace space) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER; + if (uniform < 0 || uniform >= (S32)mTexture.size()) { LL_SHADER_UNIFORM_ERRS() << "Uniform out of range: " << uniform << LL_ENDL; @@ -998,6 +1030,7 @@ S32 LLGLSLShader::disableTexture(S32 uniform, LLTexUnit::eTextureType mode, LLTe void LLGLSLShader::uniform1i(U32 index, GLint x) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER if (mProgramObject) { if (mUniform.size() <= index) @@ -1008,7 +1041,7 @@ void LLGLSLShader::uniform1i(U32 index, GLint x) if (mUniform[index] >= 0) { - std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); + const auto& iter = mValue.find(mUniform[index]); if (iter == mValue.end() || iter->second.mV[0] != x) { glUniform1i(mUniform[index], x); @@ -1020,6 +1053,7 @@ void LLGLSLShader::uniform1i(U32 index, GLint x) void LLGLSLShader::uniform1f(U32 index, GLfloat x) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER if (mProgramObject) { if (mUniform.size() <= index) @@ -1030,7 +1064,7 @@ void LLGLSLShader::uniform1f(U32 index, GLfloat x) if (mUniform[index] >= 0) { - std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); + const auto& iter = mValue.find(mUniform[index]); if (iter == mValue.end() || iter->second.mV[0] != x) { glUniform1f(mUniform[index], x); @@ -1052,7 +1086,7 @@ void LLGLSLShader::uniform2f(U32 index, GLfloat x, GLfloat y) if (mUniform[index] >= 0) { - std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); + const auto& iter = mValue.find(mUniform[index]); LLVector4 vec(x,y,0.f,0.f); if (iter == mValue.end() || shouldChange(iter->second,vec)) { @@ -1075,7 +1109,7 @@ void LLGLSLShader::uniform3f(U32 index, GLfloat x, GLfloat y, GLfloat z) if (mUniform[index] >= 0) { - std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); + const auto& iter = mValue.find(mUniform[index]); LLVector4 vec(x,y,z,0.f); if (iter == mValue.end() || shouldChange(iter->second,vec)) { @@ -1098,7 +1132,7 @@ void LLGLSLShader::uniform4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat if (mUniform[index] >= 0) { - std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); + const auto& iter = mValue.find(mUniform[index]); LLVector4 vec(x,y,z,w); if (iter == mValue.end() || shouldChange(iter->second,vec)) { @@ -1121,7 +1155,7 @@ void LLGLSLShader::uniform1iv(U32 index, U32 count, const GLint* v) if (mUniform[index] >= 0) { - std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); + const auto& iter = mValue.find(mUniform[index]); LLVector4 vec(v[0],0.f,0.f,0.f); if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) { @@ -1144,7 +1178,7 @@ void LLGLSLShader::uniform1fv(U32 index, U32 count, const GLfloat* v) if (mUniform[index] >= 0) { - std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); + const auto& iter = mValue.find(mUniform[index]); LLVector4 vec(v[0],0.f,0.f,0.f); if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) { @@ -1167,7 +1201,7 @@ void LLGLSLShader::uniform2fv(U32 index, U32 count, const GLfloat* v) if (mUniform[index] >= 0) { - std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); + const auto& iter = mValue.find(mUniform[index]); LLVector4 vec(v[0],v[1],0.f,0.f); if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) { @@ -1190,7 +1224,7 @@ void LLGLSLShader::uniform3fv(U32 index, U32 count, const GLfloat* v) if (mUniform[index] >= 0) { - std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); + const auto& iter = mValue.find(mUniform[index]); LLVector4 vec(v[0],v[1],v[2],0.f); if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) { @@ -1213,10 +1247,11 @@ void LLGLSLShader::uniform4fv(U32 index, U32 count, const GLfloat* v) if (mUniform[index] >= 0) { - std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); + const auto& iter = mValue.find(mUniform[index]); LLVector4 vec(v[0],v[1],v[2],v[3]); if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER; glUniform4fv(mUniform[index], count, v); mValue[mUniform[index]] = vec; } @@ -1260,6 +1295,8 @@ void LLGLSLShader::uniformMatrix3fv(U32 index, U32 count, GLboolean transpose, c void LLGLSLShader::uniformMatrix3x4fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER; + if (mProgramObject) { if (mUniform.size() <= index) @@ -1294,6 +1331,8 @@ void LLGLSLShader::uniformMatrix4fv(U32 index, U32 count, GLboolean transpose, c GLint LLGLSLShader::getUniformLocation(const LLStaticHashedString& uniform) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER; + GLint ret = -1; if (mProgramObject) { @@ -1318,10 +1357,16 @@ GLint LLGLSLShader::getUniformLocation(const LLStaticHashedString& uniform) GLint LLGLSLShader::getUniformLocation(U32 index) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER; + GLint ret = -1; if (mProgramObject) { - llassert(index < mUniform.size()); + if (index >= mUniform.size()) + { + LL_WARNS_ONCE("Shader") << "Uniform index " << index << " out of bounds " << (S32)mUniform.size() << LL_ENDL; + return ret; + } return mUniform[index]; } @@ -1330,6 +1375,8 @@ GLint LLGLSLShader::getUniformLocation(U32 index) GLint LLGLSLShader::getAttribLocation(U32 attrib) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER; + if (attrib < mAttribute.size()) { return mAttribute[attrib]; @@ -1346,7 +1393,7 @@ void LLGLSLShader::uniform1i(const LLStaticHashedString& uniform, GLint v) if (location >= 0) { - std::map<GLint, LLVector4>::iterator iter = mValue.find(location); + const auto& iter = mValue.find(location); LLVector4 vec(v,0.f,0.f,0.f); if (iter == mValue.end() || shouldChange(iter->second,vec)) { @@ -1362,7 +1409,7 @@ void LLGLSLShader::uniform2i(const LLStaticHashedString& uniform, GLint i, GLint if (location >= 0) { - std::map<GLint, LLVector4>::iterator iter = mValue.find(location); + const auto& iter = mValue.find(location); LLVector4 vec(i,j,0.f,0.f); if (iter == mValue.end() || shouldChange(iter->second,vec)) { @@ -1379,7 +1426,7 @@ void LLGLSLShader::uniform1f(const LLStaticHashedString& uniform, GLfloat v) if (location >= 0) { - std::map<GLint, LLVector4>::iterator iter = mValue.find(location); + const auto& iter = mValue.find(location); LLVector4 vec(v,0.f,0.f,0.f); if (iter == mValue.end() || shouldChange(iter->second,vec)) { @@ -1395,7 +1442,7 @@ void LLGLSLShader::uniform2f(const LLStaticHashedString& uniform, GLfloat x, GLf if (location >= 0) { - std::map<GLint, LLVector4>::iterator iter = mValue.find(location); + const auto& iter = mValue.find(location); LLVector4 vec(x,y,0.f,0.f); if (iter == mValue.end() || shouldChange(iter->second,vec)) { @@ -1412,7 +1459,7 @@ void LLGLSLShader::uniform3f(const LLStaticHashedString& uniform, GLfloat x, GLf if (location >= 0) { - std::map<GLint, LLVector4>::iterator iter = mValue.find(location); + const auto& iter = mValue.find(location); LLVector4 vec(x,y,z,0.f); if (iter == mValue.end() || shouldChange(iter->second,vec)) { @@ -1428,7 +1475,7 @@ void LLGLSLShader::uniform1fv(const LLStaticHashedString& uniform, U32 count, co if (location >= 0) { - std::map<GLint, LLVector4>::iterator iter = mValue.find(location); + const auto& iter = mValue.find(location); LLVector4 vec(v[0],0.f,0.f,0.f); if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) { @@ -1444,7 +1491,7 @@ void LLGLSLShader::uniform2fv(const LLStaticHashedString& uniform, U32 count, co if (location >= 0) { - std::map<GLint, LLVector4>::iterator iter = mValue.find(location); + const auto& iter = mValue.find(location); LLVector4 vec(v[0],v[1],0.f,0.f); if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) { @@ -1460,7 +1507,7 @@ void LLGLSLShader::uniform3fv(const LLStaticHashedString& uniform, U32 count, co if (location >= 0) { - std::map<GLint, LLVector4>::iterator iter = mValue.find(location); + const auto& iter = mValue.find(location); LLVector4 vec(v[0],v[1],v[2],0.f); if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) { @@ -1477,12 +1524,11 @@ void LLGLSLShader::uniform4fv(const LLStaticHashedString& uniform, U32 count, co if (location >= 0) { LLVector4 vec(v); - std::map<GLint, LLVector4>::iterator iter = mValue.find(location); + const auto& iter = mValue.find(location); if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) { - stop_glerror(); + LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER; glUniform4fv(location, count, v); - stop_glerror(); mValue[location] = vec; } } @@ -1515,3 +1561,27 @@ void LLGLSLShader::setMinimumAlpha(F32 minimum) gGL.flush(); uniform1f(LLShaderMgr::MINIMUM_ALPHA, minimum); } + +void LLShaderUniforms::apply(LLGLSLShader* shader) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER; + for (auto& uniform : mIntegers) + { + shader->uniform1i(uniform.mUniform, uniform.mValue); + } + + for (auto& uniform : mFloats) + { + shader->uniform1f(uniform.mUniform, uniform.mValue); + } + + for (auto& uniform : mVectors) + { + shader->uniform4fv(uniform.mUniform, 1, uniform.mValue.mV); + } + + for (auto& uniform : mVector3s) + { + shader->uniform3fv(uniform.mUniform, 1, uniform.mValue.mV); + } +} diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h index fb664bcab938dea28faeaac3bbea5292e2d1bc6f..14d25dc4c009f3d6a7925426f40d0c3020de02ad 100644 --- a/indra/llrender/llglslshader.h +++ b/indra/llrender/llglslshader.h @@ -30,8 +30,7 @@ #include "llgl.h" #include "llrender.h" #include "llstaticstringtable.h" - -#include <boost/unordered_map.hpp> +#include <unordered_map> class LLShaderFeatures { @@ -65,16 +64,79 @@ class LLShaderFeatures LLShaderFeatures(); }; +// ============= Structure for caching shader uniforms =============== +class LLGLSLShader; + +class LLShaderUniforms +{ +public: + + template<typename T> + struct UniformSetting + { + S32 mUniform; + T mValue; + }; + + typedef UniformSetting<S32> IntSetting; + typedef UniformSetting<F32> FloatSetting; + typedef UniformSetting<LLVector4> VectorSetting; + typedef UniformSetting<LLVector3> Vector3Setting; + + void clear() + { + mIntegers.resize(0); + mFloats.resize(0); + mVectors.resize(0); + mVector3s.resize(0); + } + + void uniform1i(S32 index, S32 value) + { + mIntegers.push_back({ index, value }); + } + + void uniform1f(S32 index, F32 value) + { + mFloats.push_back({ index, value }); + } + + void uniform4fv(S32 index, const LLVector4& value) + { + mVectors.push_back({ index, value }); + } + + void uniform4fv(S32 index, const F32* value) + { + mVectors.push_back({ index, LLVector4(value) }); + } + + void uniform3fv(S32 index, const LLVector3& value) + { + mVector3s.push_back({ index, value }); + } + + void apply(LLGLSLShader* shader); + + + std::vector<IntSetting> mIntegers; + std::vector<FloatSetting> mFloats; + std::vector<VectorSetting> mVectors; + std::vector<Vector3Setting> mVector3s; +}; class LLGLSLShader { public: - enum + // enum primarily used to control application sky settings uniforms + typedef enum { - SG_DEFAULT = 0, - SG_SKY, - SG_WATER - }; + SG_DEFAULT = 0, // not sky or water specific + SG_SKY, // + SG_WATER, + SG_ANY, + SG_COUNT + } eGroup; struct gl_uniform_data_t { std::string name; @@ -92,7 +154,6 @@ class LLGLSLShader static GLuint sCurBoundShader; static LLGLSLShader* sCurBoundShaderPtr; static S32 sIndexedTextureChannels; - static bool sNoFixedFunction; static void initProfile(); static void finishProfile(bool emit_report = true); @@ -184,6 +245,8 @@ class LLGLSLShader BOOL link(BOOL suppress_errors = FALSE); void bind(); + //helper to conditionally bind mRiggedVariant instead of this + void bind(bool rigged); void unbind(); // Unbinds any previously bound shader by explicitly binding no shader. @@ -208,18 +271,21 @@ class LLGLSLShader U32 mAttributeMask; //mask of which reserved attributes are set (lines up with LLVertexBuffer::getTypeMask()) std::vector<GLint> mUniform; //lookup table of uniform enum to uniform location LLStaticStringTable<GLint> mUniformMap; //lookup map of uniform name to uniform location - std::map<GLint, std::string> mUniformNameMap; //lookup map of uniform location to uniform name - std::map<GLint, LLVector4> mValue; //lookup map of uniform location to last known value + typedef std::unordered_map<GLint, std::string> uniform_name_map_t; + typedef std::unordered_map<GLint, LLVector4> uniform_value_map_t; + uniform_name_map_t mUniformNameMap; //lookup map of uniform location to uniform name + uniform_value_map_t mValue; //lookup map of uniform location to last known value std::vector<GLint> mTexture; S32 mTotalUniformSize; S32 mActiveTextureChannels; S32 mShaderLevel; - S32 mShaderGroup; + S32 mShaderGroup; // see LLGLSLShader::eGroup BOOL mUniformsDirty; LLShaderFeatures mFeatures; std::vector< std::pair< std::string, GLenum > > mShaderFiles; std::string mName; - boost::unordered_map<std::string, std::string> mDefines; + typedef std::unordered_map<std::string, std::string> defines_map_t; + defines_map_t mDefines; //statistcis for profiling shader performance U32 mTimerQuery; @@ -237,6 +303,9 @@ class LLGLSLShader std::vector<U32> mTextureMagFilter; std::vector<U32> mTextureMinFilter; + // this pointer should be set to whichever shader represents this shader's rigged variant + LLGLSLShader* mRiggedVariant = nullptr; + private: void unloadInternal(); }; diff --git a/indra/llrender/llgltexture.cpp b/indra/llrender/llgltexture.cpp index 121066854c6aaebbed0b7996e2160fdfcd6f0fea..a520898340dc2193d8e8f5b828b6e2e96f785e83 100644 --- a/indra/llrender/llgltexture.cpp +++ b/indra/llrender/llgltexture.cpp @@ -164,11 +164,11 @@ BOOL LLGLTexture::createGLTexture() return mGLTexturep->createGLTexture() ; } -BOOL LLGLTexture::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename, BOOL to_create, S32 category) +BOOL LLGLTexture::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename, BOOL to_create, S32 category, bool defer_copy, LLGLuint* tex_name) { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()); - BOOL ret = mGLTexturep->createGLTexture(discard_level, imageraw, usename, to_create, category) ; + BOOL ret = mGLTexturep->createGLTexture(discard_level, imageraw, usename, to_create, category, defer_copy, tex_name) ; if(ret) { @@ -260,18 +260,20 @@ LLTexUnit::eTextureType LLGLTexture::getTarget(void) const return mGLTexturep->getTarget() ; } -BOOL LLGLTexture::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height) +BOOL LLGLTexture::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, LLGLuint use_name) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; llassert(mGLTexturep.notNull()) ; - return mGLTexturep->setSubImage(imageraw, x_pos, y_pos, width, height) ; + return mGLTexturep->setSubImage(imageraw, x_pos, y_pos, width, height, 0, use_name) ; } -BOOL LLGLTexture::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height) +BOOL LLGLTexture::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, LLGLuint use_name) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; llassert(mGLTexturep.notNull()) ; - return mGLTexturep->setSubImage(datap, data_width, data_height, x_pos, y_pos, width, height) ; + return mGLTexturep->setSubImage(datap, data_width, data_height, x_pos, y_pos, width, height, 0, use_name) ; } void LLGLTexture::setGLTextureCreated (bool initialized) diff --git a/indra/llrender/llgltexture.h b/indra/llrender/llgltexture.h index 788ea83de4d6bc82deee661f0da1275ccadc8794..377ef3d0ec15a621bc1d1f67b2b2272e63430d9f 100644 --- a/indra/llrender/llgltexture.h +++ b/indra/llrender/llgltexture.h @@ -124,13 +124,22 @@ class LLGLTexture : public LLTexture BOOL hasGLTexture() const ; LLGLuint getTexName() const ; BOOL createGLTexture() ; - BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0, BOOL to_create = TRUE, S32 category = LLGLTexture::OTHER); + + // Create a GL Texture from an image raw + // discard_level - mip level, 0 for highest resultion mip + // imageraw - the image to copy from + // usename - explicit GL name override + // to_create - set to FALSE to force gl texture to not be created + // category - LLGLTexture category for this LLGLTexture + // defer_copy - set to true to allocate GL texture but NOT initialize with imageraw data + // tex_name - if not null, will be set to the GL name of the texture created + BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0, BOOL to_create = TRUE, S32 category = LLGLTexture::OTHER, bool defer_copy = false, LLGLuint* tex_name = nullptr); void setFilteringOption(LLTexUnit::eTextureFilterOptions option); void setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format = 0, BOOL swap_bytes = FALSE); void setAddressMode(LLTexUnit::eTextureAddressMode mode); - BOOL setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height); - BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height); + BOOL setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, LLGLuint use_name = 0); + BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, LLGLuint use_name = 0); void setGLTextureCreated (bool initialized); void setCategory(S32 category) ; void setTexName(LLGLuint); // for forcing w/ externally created textures only @@ -185,7 +194,7 @@ class LLGLTexture : public LLTexture protected: void setTexelsPerImage(); - //note: do not make this function public. +public: /*virtual*/ LLImageGL* getGLTexture() const ; protected: diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index a69fcd8ca81115b00f0206a143ffc87532fa8806..c330dc2661e79ce50b66eed252c0c3163dfd7a21 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -39,6 +39,12 @@ #include "llgl.h" #include "llglslshader.h" #include "llrender.h" +#include "llwindow.h" +#include "llframetimer.h" + +#if !LL_IMAGEGL_THREAD_CHECK +#define checkActiveThread() +#endif //---------------------------------------------------------------------------- const F32 MIN_TEXTURE_LIFETIME = 10.f; @@ -60,9 +66,11 @@ F32 LLImageGL::sLastFrameTime = 0.f; BOOL LLImageGL::sAllowReadBackRaw = FALSE ; LLImageGL* LLImageGL::sDefaultGLTexture = NULL ; bool LLImageGL::sCompressTextures = false; - std::set<LLImageGL*> LLImageGL::sImageList; + +bool LLImageGLThread::sEnabled = false; + //**************************************************************************************************** //The below for texture auditing use only //**************************************************************************************************** @@ -169,15 +177,24 @@ BOOL is_little_endian() return (*c == 0x78) ; } + //static -void LLImageGL::initClass(S32 num_catagories, BOOL skip_analyze_alpha /* = false */) +void LLImageGL::initClass(LLWindow* window, S32 num_catagories, BOOL skip_analyze_alpha /* = false */, bool multi_threaded /* = false */) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; sSkipAnalyzeAlpha = skip_analyze_alpha; + + if (multi_threaded) + { + LLImageGLThread::createInstance(window); + } } //static void LLImageGL::cleanupClass() -{ +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; + LLImageGLThread::deleteSingleton(); } //static @@ -193,6 +210,7 @@ S32 LLImageGL::dataFormatBits(S32 dataformat) case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: return 8; case GL_LUMINANCE: return 8; case GL_ALPHA: return 8; + case GL_RED: return 8; case GL_COLOR_INDEX: return 8; case GL_LUMINANCE_ALPHA: return 16; case GL_RGB: return 24; @@ -242,6 +260,7 @@ S32 LLImageGL::dataFormatComponents(S32 dataformat) case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: return 4; case GL_LUMINANCE: return 1; case GL_ALPHA: return 1; + case GL_RED: return 1; case GL_COLOR_INDEX: return 1; case GL_LUMINANCE_ALPHA: return 2; case GL_RGB: return 3; @@ -257,11 +276,10 @@ S32 LLImageGL::dataFormatComponents(S32 dataformat) //---------------------------------------------------------------------------- -static LLTrace::BlockTimerStatHandle FTM_IMAGE_UPDATE_STATS("Image Stats"); // static void LLImageGL::updateStats(F32 current_time) { - LL_RECORD_BLOCK_TIME(FTM_IMAGE_UPDATE_STATS); + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; sLastFrameTime = current_time; sBoundTextureMemory = sCurBoundTextureMemory; sCurBoundTextureMemory = S64Bytes(0); @@ -294,10 +312,8 @@ void LLImageGL::destroyGL(BOOL save_state) if (save_state && glimage->isGLTextureCreated() && glimage->mComponents) { glimage->mSaveData = new LLImageRaw; - glimage->claimMem(glimage->mSaveData); if(!glimage->readBackRaw(glimage->mCurrentDiscardLevel, glimage->mSaveData, false)) //necessary, keep it. { - glimage->disclaimMem(glimage->mSaveData); glimage->mSaveData = NULL ; } } @@ -371,8 +387,7 @@ BOOL LLImageGL::create(LLPointer<LLImageGL>& dest, const LLImageRaw* imageraw, B //---------------------------------------------------------------------------- LLImageGL::LLImageGL(BOOL usemipmaps) -: LLTrace::MemTrackable<LLImageGL>("LLImageGL"), - mSaveData(0), mExternalTexture(FALSE) +: mSaveData(0), mExternalTexture(FALSE) { init(usemipmaps); setSize(0, 0, 0); @@ -381,8 +396,7 @@ LLImageGL::LLImageGL(BOOL usemipmaps) } LLImageGL::LLImageGL(U32 width, U32 height, U8 components, BOOL usemipmaps) -: LLTrace::MemTrackable<LLImageGL>("LLImageGL"), - mSaveData(0), mExternalTexture(FALSE) +: mSaveData(0), mExternalTexture(FALSE) { llassert( components <= 4 ); init(usemipmaps); @@ -392,8 +406,7 @@ LLImageGL::LLImageGL(U32 width, U32 height, U8 components, BOOL usemipmaps) } LLImageGL::LLImageGL(const LLImageRaw* imageraw, BOOL usemipmaps) -: LLTrace::MemTrackable<LLImageGL>("LLImageGL"), - mSaveData(0), mExternalTexture(FALSE) +: mSaveData(0), mExternalTexture(FALSE) { init(usemipmaps); setSize(0, 0, 0); @@ -411,7 +424,6 @@ LLImageGL::LLImageGL( LLGLenum formatPrimary, LLGLenum formatType, LLTexUnit::eTextureAddressMode addressMode) - : LLTrace::MemTrackable<LLImageGL>("LLImageGL"), mSaveData(0), mExternalTexture(TRUE) { init(false); mTexName = texName; @@ -426,7 +438,7 @@ LLImageGL::LLImageGL( LLImageGL::~LLImageGL() { - if (!mExternalTexture) + if (!mExternalTexture && gGLManager.mInited) { LLImageGL::cleanup(); sImageList.erase(this); @@ -439,6 +451,10 @@ const S8 INVALID_OFFSET = -99 ; void LLImageGL::init(BOOL usemipmaps) { +#if LL_IMAGEGL_THREAD_CHECK + mActiveThread = LLThread::currentID(); +#endif + // keep these members in the same order as declared in llimagehl.h // so that it is obvious by visual inspection if we forgot to // init a field. @@ -497,6 +513,9 @@ void LLImageGL::init(BOOL usemipmaps) #endif mCategory = -1; + + // Sometimes we have to post work for the main thread. + mMainQueue = LL::WorkQueue::getInstance("mainloop"); } void LLImageGL::cleanup() @@ -539,19 +558,13 @@ bool LLImageGL::setSize(S32 width, S32 height, S32 ncomponents, S32 discard_leve { #ifdef NO_STUPID // Check if dimensions are a power of two! - if (!checkSize(width,height)) + if (!checkSize(width, height)) { LL_WARNS() << llformat("Texture has non power of two dimension: %dx%d",width,height) << LL_ENDL; return false; } #endif - if (mTexName) - { -// LL_WARNS() << "Setting Size of LLImageGL with existing mTexName = " << mTexName << LL_ENDL; - destroyGLTexture(); - } - // pickmask validity depends on old image size, delete it freePickMask(); @@ -662,6 +675,7 @@ void LLImageGL::setExplicitFormat( LLGLint internal_format, LLGLenum primary_for void LLImageGL::setImage(const LLImageRaw* imageraw) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; llassert((imageraw->getWidth() == getWidth(mCurrentDiscardLevel)) && (imageraw->getHeight() == getHeight(mCurrentDiscardLevel)) && (imageraw->getComponents() == getComponents())); @@ -669,10 +683,9 @@ void LLImageGL::setImage(const LLImageRaw* imageraw) setImage(rawdata, FALSE); } -static LLTrace::BlockTimerStatHandle FTM_SET_IMAGE("setImage"); -BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) +BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips /* = FALSE */, S32 usename /* = 0 */) { - LL_RECORD_BLOCK_TIME(FTM_SET_IMAGE); + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; bool is_compressed = false; switch (mFormatPrimary) @@ -689,12 +702,11 @@ BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) break; } - - if (mUseMipMaps) { //set has mip maps to true before binding image so tex parameters get set properly - gGL.getTexUnit(0)->unbind(mBindTarget); + gGL.getTexUnit(0)->unbind(mBindTarget); + mHasMipMaps = true; mTexOptionsDirty = true; setFilteringOption(LLTexUnit::TFO_ANISOTROPIC); @@ -704,10 +716,16 @@ BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) mHasMipMaps = false; } - llverify(gGL.getTexUnit(0)->bind(this)); - - - if (mUseMipMaps) + gGL.getTexUnit(0)->bind(this, false, false, usename); + + if (data_in == nullptr) + { + S32 w = getWidth(); + S32 h = getHeight(); + LLImageGL::setManualImage(mTarget, 0, mFormatInternal, w, h, + mFormatPrimary, mFormatType, (GLvoid*)data_in, mAllowCompression); + } + else if (mUseMipMaps) { if (data_hasmips) { @@ -734,8 +752,6 @@ BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) } else { -// LL_RECORD_BLOCK_TIME(FTM_TEMP4); - if(mFormatSwapBytes) { glPixelStorei(GL_UNPACK_SWAP_BYTES, 1); @@ -766,8 +782,6 @@ BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) { stop_glerror(); { -// LL_RECORD_BLOCK_TIME(FTM_TEMP4); - if(mFormatSwapBytes) { glPixelStorei(GL_UNPACK_SWAP_BYTES, 1); @@ -787,7 +801,7 @@ BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) glTexParameteri(mTarget, GL_GENERATE_MIPMAP, GL_TRUE); } - LLImageGL::setManualImage(mTarget, 0, mFormatInternal, + LLImageGL::setManualImage(mTarget, 0, mFormatInternal, w, h, mFormatPrimary, mFormatType, data_in, mAllowCompression); @@ -877,14 +891,13 @@ BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) llassert(w > 0 && h > 0 && cur_mip_data); (void)cur_mip_data; { -// LL_RECORD_BLOCK_TIME(FTM_TEMP4); if(mFormatSwapBytes) { glPixelStorei(GL_UNPACK_SWAP_BYTES, 1); stop_glerror(); } - LLImageGL::setManualImage(mTarget, m, mFormatInternal, w, h, mFormatPrimary, mFormatType, cur_mip_data, mAllowCompression); + LLImageGL::setManualImage(mTarget, m, mFormatInternal, w, h, mFormatPrimary, mFormatType, cur_mip_data, mAllowCompression); if (m == 0) { analyzeAlpha(data_in, w, h); @@ -1071,13 +1084,15 @@ void LLImageGL::postAddToAtlas() stop_glerror(); } -BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update) +BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update /* = FALSE */, LLGLuint use_name) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; if (!width || !height) { return TRUE; } - if (mTexName == 0) + LLGLuint tex_name = use_name != 0 ? use_name : mTexName; + if (0 == tex_name) { // *TODO: Re-enable warning? Ran into thread locking issues? DK 2011-02-18 //LL_WARNS() << "Setting subimage on image without GL texture" << LL_ENDL; @@ -1093,7 +1108,7 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3 // HACK: allow the caller to explicitly force the fast path (i.e. using glTexSubImage2D here instead of calling setImage) even when updating the full texture. if (!force_fast_update && x_pos == 0 && y_pos == 0 && width == getWidth() && height == getHeight() && data_width == width && data_height == height) { - setImage(datap, FALSE); + setImage(datap, FALSE, tex_name); } else { @@ -1145,12 +1160,11 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3 datap += (y_pos * data_width + x_pos) * getComponents(); // Update the GL texture - BOOL res = gGL.getTexUnit(0)->bindManual(mBindTarget, mTexName); + BOOL res = gGL.getTexUnit(0)->bindManual(mBindTarget, tex_name); if (!res) LL_ERRS() << "LLImageGL::setSubImage(): bindTexture failed" << LL_ENDL; stop_glerror(); - glTexSubImage2D(mTarget, 0, x_pos, y_pos, - width, height, mFormatPrimary, mFormatType, datap); + glTexSubImage2D(mTarget, 0, x_pos, y_pos, width, height, mFormatPrimary, mFormatType, datap); gGL.getTexUnit(0)->disable(); stop_glerror(); @@ -1167,9 +1181,10 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3 return TRUE; } -BOOL LLImageGL::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update) +BOOL LLImageGL::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update /* = FALSE */, LLGLuint use_name) { - return setSubImage(imageraw->getData(), imageraw->getWidth(), imageraw->getHeight(), x_pos, y_pos, width, height, force_fast_update); + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; + return setSubImage(imageraw->getData(), imageraw->getWidth(), imageraw->getHeight(), x_pos, y_pos, width, height, force_fast_update, use_name); } // Copy sub image from frame buffer @@ -1189,15 +1204,36 @@ BOOL LLImageGL::setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_ } // static -static LLTrace::BlockTimerStatHandle FTM_GENERATE_TEXTURES("generate textures"); void LLImageGL::generateTextures(S32 numTextures, U32 *textures) { - LL_RECORD_BLOCK_TIME(FTM_GENERATE_TEXTURES); - glGenTextures(numTextures, textures); + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; + static constexpr U32 pool_size = 1024; + static thread_local U32 name_pool[pool_size]; // pool of texture names + static thread_local U32 name_count = 0; // number of available names in the pool + + if (name_count == 0) + { + LL_PROFILE_ZONE_NAMED("iglgt - reup pool"); + // pool is emtpy, refill it + glGenTextures(pool_size, name_pool); + name_count = pool_size; + } + + if (numTextures <= name_count) + { + //copy teture names off the end of the pool + memcpy(textures, name_pool + name_count - numTextures, sizeof(U32) * numTextures); + name_count -= numTextures; + } + else + { + LL_PROFILE_ZONE_NAMED("iglgt - pool miss"); + glGenTextures(numTextures, textures); + } } // static -void LLImageGL::deleteTextures(S32 numTextures, U32 *textures) +void LLImageGL::deleteTextures(S32 numTextures, const U32 *textures) { if (gGLManager.mInited) { @@ -1206,13 +1242,12 @@ void LLImageGL::deleteTextures(S32 numTextures, U32 *textures) } // static -static LLTrace::BlockTimerStatHandle FTM_SET_MANUAL_IMAGE("setManualImage"); -void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels, bool allow_compression) +void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void* pixels, bool allow_compression) { - LL_RECORD_BLOCK_TIME(FTM_SET_MANUAL_IMAGE); + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; std::vector<U32> scratch; - if (LLRender::sGLCoreProfile) - { + if (LLRender::sGLCoreProfile) + { #ifdef GL_ARB_texture_swizzle if (gGLManager.mHasTextureSwizzle) { @@ -1245,155 +1280,16 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt { if (pixformat == GL_ALPHA && pixtype == GL_UNSIGNED_BYTE) { //GL_ALPHA is deprecated, convert to RGBA - scratch.resize(width * height); - - U32 pixel_count = (U32)(width * height); - for (U32 i = 0; i < pixel_count; i++) + try { - U8* pix = (U8*)&scratch[i]; - pix[0] = pix[1] = pix[2] = 0; - pix[3] = ((U8*)pixels)[i]; + scratch.resize(width * height); } - - pixels = &scratch[0]; - - pixformat = GL_RGBA; - intformat = GL_RGBA8; - } - - if (pixformat == GL_LUMINANCE_ALPHA && pixtype == GL_UNSIGNED_BYTE) - { //GL_LUMINANCE_ALPHA is deprecated, convert to RGBA - scratch.resize(width * height); - - U32 pixel_count = (U32)(width * height); - for (U32 i = 0; i < pixel_count; i++) + catch(const std::bad_alloc&) { - U8 lum = ((U8*)pixels)[i * 2 + 0]; - U8 alpha = ((U8*)pixels)[i * 2 + 1]; - - U8* pix = (U8*)&scratch[i]; - pix[0] = pix[1] = pix[2] = lum; - pix[3] = alpha; + LL_ERRS() << "Failed to allocate " << (U32)(width * height * sizeof(U32)) + << " bytes for a manual image W" << width << " H" << height << LL_ENDL; } - pixels = &scratch[0]; - - pixformat = GL_RGBA; - intformat = GL_RGBA8; - } - - if (pixformat == GL_LUMINANCE && pixtype == GL_UNSIGNED_BYTE) - { //GL_LUMINANCE_ALPHA is deprecated, convert to RGB - scratch.resize(width * height); - - U32 pixel_count = (U32)(width * height); - for (U32 i = 0; i < pixel_count; i++) - { - U8 lum = ((U8*)pixels)[i]; - - U8* pix = (U8*)&scratch[i]; - pix[0] = pix[1] = pix[2] = lum; - pix[3] = 255; - } - - pixels = &scratch[0]; - - pixformat = GL_RGBA; - intformat = GL_RGB8; - } - } - } - if (LLImageGL::sCompressTextures && allow_compression) - { - switch (intformat) - { - case GL_RED: - case GL_R8: - intformat = GL_COMPRESSED_RED; - break; - case GL_RG: - case GL_RG8: - intformat = GL_COMPRESSED_RG; - break; - case GL_RGB: - case GL_RGB8: - intformat = GL_COMPRESSED_RGB; - break; - case GL_SRGB: - case GL_SRGB8: - intformat = GL_COMPRESSED_SRGB; - break; - case GL_RGBA: - case GL_RGBA8: - intformat = GL_COMPRESSED_RGBA; - break; - case GL_SRGB_ALPHA: - case GL_SRGB8_ALPHA8: - intformat = GL_COMPRESSED_SRGB_ALPHA; - break; - case GL_LUMINANCE: - case GL_LUMINANCE8: - intformat = GL_COMPRESSED_LUMINANCE; - break; - case GL_LUMINANCE_ALPHA: - case GL_LUMINANCE8_ALPHA8: - intformat = GL_COMPRESSED_LUMINANCE_ALPHA; - break; - case GL_ALPHA: - case GL_ALPHA8: - intformat = GL_COMPRESSED_ALPHA; - break; - default: - LL_WARNS() << "Could not compress format: " << std::hex << intformat << std::dec << LL_ENDL; - break; - } - } - - stop_glerror(); - glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, pixels); - stop_glerror(); -} - -void LLImageGL::setManualImage3D(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, S32 depth, U32 pixformat, U32 pixtype, const void* pixels, bool allow_compression) -{ - LL_RECORD_BLOCK_TIME(FTM_SET_MANUAL_IMAGE); - std::vector<U32> scratch; - if (LLRender::sGLCoreProfile) - { -#ifdef GL_ARB_texture_swizzle - if (gGLManager.mHasTextureSwizzle) - { - if (pixformat == GL_ALPHA) - { //GL_ALPHA is deprecated, convert to RGBA - const GLint mask[] = { GL_ZERO, GL_ZERO, GL_ZERO, GL_RED }; - glTexParameteriv(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_RGBA, mask); - pixformat = GL_RED; - intformat = GL_R8; - } - - if (pixformat == GL_LUMINANCE) - { //GL_LUMINANCE is deprecated, convert to GL_RGBA - const GLint mask[] = { GL_RED, GL_RED, GL_RED, GL_ONE }; - glTexParameteriv(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_RGBA, mask); - pixformat = GL_RED; - intformat = GL_R8; - } - - if (pixformat == GL_LUMINANCE_ALPHA) - { //GL_LUMINANCE_ALPHA is deprecated, convert to RGBA - const GLint mask[] = { GL_RED, GL_RED, GL_RED, GL_GREEN }; - glTexParameteriv(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_RGBA, mask); - pixformat = GL_RG; - intformat = GL_RG8; - } - } - else -#endif - { - if (pixformat == GL_ALPHA && pixtype == GL_UNSIGNED_BYTE) - { //GL_ALPHA is deprecated, convert to RGBA - scratch.resize(width * height); - U32 pixel_count = (U32)(width * height); for (U32 i = 0; i < pixel_count; i++) { @@ -1410,7 +1306,15 @@ void LLImageGL::setManualImage3D(U32 target, S32 miplevel, S32 intformat, S32 wi if (pixformat == GL_LUMINANCE_ALPHA && pixtype == GL_UNSIGNED_BYTE) { //GL_LUMINANCE_ALPHA is deprecated, convert to RGBA - scratch.resize(width * height); + try + { + scratch.resize(width * height); + } + catch(const std::bad_alloc&) + { + LL_ERRS() << "Failed to allocate " << (U32)(width * height * sizeof(U32)) + << " bytes for a manual image W" << width << " H" << height << LL_ENDL; + } U32 pixel_count = (U32)(width * height); for (U32 i = 0; i < pixel_count; i++) @@ -1431,7 +1335,15 @@ void LLImageGL::setManualImage3D(U32 target, S32 miplevel, S32 intformat, S32 wi if (pixformat == GL_LUMINANCE && pixtype == GL_UNSIGNED_BYTE) { //GL_LUMINANCE_ALPHA is deprecated, convert to RGB - scratch.resize(width * height); + try + { + scratch.resize(width * height); + } + catch(const std::bad_alloc&) + { + LL_ERRS() << "Failed to allocate " << (U32)(width * height * sizeof(U32)) + << " bytes for a manual image W" << width << " H" << height << LL_ENDL; + } U32 pixel_count = (U32)(width * height); for (U32 i = 0; i < pixel_count; i++) @@ -1452,50 +1364,61 @@ void LLImageGL::setManualImage3D(U32 target, S32 miplevel, S32 intformat, S32 wi } if (LLImageGL::sCompressTextures && allow_compression) { - switch (intformat) - { - case GL_RED: - case GL_R8: - intformat = GL_COMPRESSED_RED; - break; - case GL_RG: - case GL_RG8: - intformat = GL_COMPRESSED_RG; - break; - case GL_RGB: - case GL_RGB8: - intformat = GL_COMPRESSED_RGB; - break; - case GL_SRGB: - case GL_SRGB8: - intformat = GL_COMPRESSED_SRGB; - break; - case GL_RGBA: - case GL_RGBA8: - intformat = GL_COMPRESSED_RGBA; - break; - case GL_SRGB_ALPHA: - case GL_SRGB8_ALPHA8: - intformat = GL_COMPRESSED_SRGB_ALPHA; - break; - case GL_LUMINANCE: - case GL_LUMINANCE8: - intformat = GL_COMPRESSED_LUMINANCE; - break; - case GL_LUMINANCE_ALPHA: - case GL_LUMINANCE8_ALPHA8: - intformat = GL_COMPRESSED_LUMINANCE_ALPHA; - break; - case GL_ALPHA: - case GL_ALPHA8: - intformat = GL_COMPRESSED_ALPHA; - break; - default: - LL_WARNS() << "Could not compress format: " << std::hex << intformat << std::dec << LL_ENDL; - break; - } - } + switch (intformat) + { + case GL_RED: + case GL_R8: + intformat = GL_COMPRESSED_RED; + break; + case GL_RG: + case GL_RG8: + intformat = GL_COMPRESSED_RG; + break; + case GL_RGB: + case GL_RGB8: + intformat = GL_COMPRESSED_RGB; + break; + case GL_SRGB: + case GL_SRGB8: + intformat = GL_COMPRESSED_SRGB; + break; + case GL_RGBA: + case GL_RGBA8: + intformat = GL_COMPRESSED_RGBA; + break; + case GL_SRGB_ALPHA: + case GL_SRGB8_ALPHA8: + intformat = GL_COMPRESSED_SRGB_ALPHA; + break; + case GL_LUMINANCE: + case GL_LUMINANCE8: + intformat = GL_COMPRESSED_LUMINANCE; + break; + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE8_ALPHA8: + intformat = GL_COMPRESSED_LUMINANCE_ALPHA; + break; + case GL_ALPHA: + case GL_ALPHA8: + intformat = GL_COMPRESSED_ALPHA; + break; + default: + LL_WARNS() << "Could not compress format: " << std::hex << intformat << std::dec << LL_ENDL; + break; + } + } + + stop_glerror(); + { + LL_PROFILE_ZONE_NAMED("glTexImage2D"); + glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, pixels); + } + stop_glerror(); +} +void LLImageGL::setManualImage3D(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, S32 depth, U32 pixformat, U32 pixtype, const void* pixels, bool allow_compression) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; stop_glerror(); glTexImage3D(target, miplevel, intformat, width, height, depth, 0, pixformat, pixtype, pixels); stop_glerror(); @@ -1503,10 +1426,11 @@ void LLImageGL::setManualImage3D(U32 target, S32 miplevel, S32 intformat, S32 wi //create an empty GL texture: just create a texture name //the texture is assiciate with some image by calling glTexImage outside LLImageGL -static LLTrace::BlockTimerStatHandle FTM_CREATE_GL_TEXTURE1("createGLTexture()"); BOOL LLImageGL::createGLTexture() { - LL_RECORD_BLOCK_TIME(FTM_CREATE_GL_TEXTURE1); + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; + checkActiveThread(); + if (gGLManager.mIsDisabled) { LL_WARNS() << "Trying to create a texture while GL is disabled!" << LL_ENDL; @@ -1521,6 +1445,7 @@ BOOL LLImageGL::createGLTexture() if(mTexName) { LLImageGL::deleteTextures(1, (reinterpret_cast<GLuint*>(&mTexName))) ; + mTexName = 0; } @@ -1535,23 +1460,24 @@ BOOL LLImageGL::createGLTexture() return TRUE ; } -static LLTrace::BlockTimerStatHandle FTM_CREATE_GL_TEXTURE2("createGLTexture(raw)"); -BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename/*=0*/, BOOL to_create, S32 category) +BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename/*=0*/, BOOL to_create, S32 category, bool defer_copy, LLGLuint* tex_name) { - LL_RECORD_BLOCK_TIME(FTM_CREATE_GL_TEXTURE2); + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; + checkActiveThread(); + if (gGLManager.mIsDisabled) { LL_WARNS() << "Trying to create a texture while GL is disabled!" << LL_ENDL; return FALSE; } - mGLTextureCreated = false ; llassert(gGLManager.mInited); stop_glerror(); if (!imageraw || imageraw->isBufferInvalid()) { LL_WARNS() << "Trying to create a texture from invalid image data" << LL_ENDL; + mGLTextureCreated = false; return FALSE; } @@ -1564,6 +1490,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S // Actual image width/height = raw image width/height * 2^discard_level S32 raw_w = imageraw->getWidth() ; S32 raw_h = imageraw->getHeight() ; + S32 w = raw_w << discard_level; S32 h = raw_h << discard_level; @@ -1572,6 +1499,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S if (!setSize(w, h, imageraw->getComponents(), discard_level)) { LL_WARNS() << "Trying to create a texture with incorrect dimensions!" << LL_ENDL; + mGLTextureCreated = false; return FALSE; } #else @@ -1639,115 +1567,236 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S destroyGLTexture(); mCurrentDiscardLevel = discard_level; mLastBindTime = sLastFrameTime; + mGLTextureCreated = false; return TRUE ; } setCategory(category); const U8* rawdata = imageraw->getData(); - return createGLTexture(discard_level, rawdata, FALSE, usename); + return createGLTexture(discard_level, rawdata, FALSE, usename, defer_copy, tex_name); } -static LLTrace::BlockTimerStatHandle FTM_CREATE_GL_TEXTURE3("createGLTexture3(data)"); -BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_hasmips, S32 usename) +BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_hasmips, S32 usename, bool defer_copy, LLGLuint* tex_name) +// Call with void data, vmem is allocated but unitialized { - LL_RECORD_BLOCK_TIME(FTM_CREATE_GL_TEXTURE3); - llassert(data_in); - stop_glerror(); + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; + checkActiveThread(); - if (discard_level < 0) - { - llassert(mCurrentDiscardLevel >= 0); - discard_level = mCurrentDiscardLevel; - } - discard_level = llclamp(discard_level, 0, (S32)mMaxDiscardLevel); + bool main_thread = on_main_thread(); - if (mTexName != 0 && discard_level == mCurrentDiscardLevel) - { - // This will only be true if the size has not changed - return setImage(data_in, data_hasmips); - } - - U32 old_name = mTexName; -// S32 old_discard = mCurrentDiscardLevel; - - if (usename != 0) - { - mTexName = usename; - } - else - { - LLImageGL::generateTextures(1, &mTexName); - stop_glerror(); - { - llverify(gGL.getTexUnit(0)->bind(this)); - stop_glerror(); - glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_BASE_LEVEL, 0); - stop_glerror(); - glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MAX_LEVEL, mMaxDiscardLevel-discard_level); - stop_glerror(); - } - } - if (!mTexName) - { - if (old_name) - { - sGlobalTextureMemory -= mTextureMemory; - LLImageGL::deleteTextures(1, &old_name); - disclaimMem(mTextureMemory); - stop_glerror(); - } + if (defer_copy) + { + data_in = nullptr; + } + else + { + llassert(data_in); + } - LL_WARNS() << "LLImageGL::createGLTexture failed to make texture" << LL_ENDL; - return FALSE; - } + stop_glerror(); - if (mUseMipMaps) - { - mAutoGenMips = gGLManager.mHasMipMapGeneration; -#if LL_DARWIN - // On the Mac GF2 and GF4MX drivers, auto mipmap generation doesn't work right with alpha-only textures. - if(gGLManager.mIsGF2or4MX && (mFormatInternal == GL_ALPHA8) && (mFormatPrimary == GL_ALPHA)) - { - mAutoGenMips = FALSE; - } -#endif - } + if (discard_level < 0) + { + llassert(mCurrentDiscardLevel >= 0); + discard_level = mCurrentDiscardLevel; + } + discard_level = llclamp(discard_level, 0, (S32)mMaxDiscardLevel); - mCurrentDiscardLevel = discard_level; + if (main_thread // <--- always force creation of new_texname when not on main thread ... + && !defer_copy // <--- ... or defer copy is set + && mTexName != 0 && discard_level == mCurrentDiscardLevel) + { + LL_PROFILE_ZONE_NAMED("cglt - early setImage"); + // This will only be true if the size has not changed + if (tex_name != nullptr) + { + *tex_name = mTexName; + } + return setImage(data_in, data_hasmips); + } - if (!setImage(data_in, data_hasmips)) - { - stop_glerror(); - return FALSE; - } + GLuint old_texname = mTexName; + GLuint new_texname = 0; + if (usename != 0) + { + llassert(main_thread); + new_texname = usename; + } + else + { + LLImageGL::generateTextures(1, &new_texname); + { + gGL.getTexUnit(0)->bind(this, false, false, new_texname); + glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MAX_LEVEL, mMaxDiscardLevel - discard_level); + } + } - // Set texture options to our defaults. - gGL.getTexUnit(0)->setHasMipMaps(mHasMipMaps); - gGL.getTexUnit(0)->setTextureAddressMode(mAddressMode); - gGL.getTexUnit(0)->setTextureFilteringOption(mFilterOption); + if (tex_name != nullptr) + { + *tex_name = new_texname; + } - // things will break if we don't unbind after creation - gGL.getTexUnit(0)->unbind(mBindTarget); - stop_glerror(); + if (mUseMipMaps) + { + mAutoGenMips = gGLManager.mHasMipMapGeneration; + } - if (old_name != 0) - { - sGlobalTextureMemory -= mTextureMemory; + mCurrentDiscardLevel = discard_level; - LLImageGL::deleteTextures(1, &old_name); + { + LL_PROFILE_ZONE_NAMED("cglt - late setImage"); + if (!setImage(data_in, data_hasmips, new_texname)) + { + return FALSE; + } + } - stop_glerror(); - } + // Set texture options to our defaults. + gGL.getTexUnit(0)->setHasMipMaps(mHasMipMaps); + gGL.getTexUnit(0)->setTextureAddressMode(mAddressMode); + gGL.getTexUnit(0)->setTextureFilteringOption(mFilterOption); - disclaimMem(mTextureMemory); - mTextureMemory = S64Bytes(getMipBytes(discard_level)); - claimMem(mTextureMemory); - sGlobalTextureMemory += mTextureMemory; - mTexelsInGLTexture = getWidth() * getHeight() ; + // things will break if we don't unbind after creation + gGL.getTexUnit(0)->unbind(mBindTarget); - // mark this as bound at this point, so we don't throw it out immediately - mLastBindTime = sLastFrameTime; - return TRUE; + if (old_texname != 0) + { + sGlobalTextureMemory -= mTextureMemory; + } + + //if we're on the image loading thread, be sure to delete old_texname and update mTexName on the main thread + if (!defer_copy) + { + if (!main_thread) + { + syncToMainThread(new_texname); + } + else + { + //not on background thread, immediately set mTexName + if (old_texname != 0 && old_texname != new_texname) + { + LLImageGL::deleteTextures(1, &old_texname); + } + mTexName = new_texname; + } + } + + + mTextureMemory = S64Bytes(getMipBytes(mCurrentDiscardLevel)); + sGlobalTextureMemory += mTextureMemory; + mTexelsInGLTexture = getWidth() * getHeight(); + + // mark this as bound at this point, so we don't throw it out immediately + mLastBindTime = sLastFrameTime; + + checkActiveThread(); + return TRUE; +} + +void LLImageGLThread::updateClass() +{ + LL_PROFILE_ZONE_SCOPED; + + // update available vram one per second + static LLFrameTimer sTimer; + + if (sTimer.getElapsedSeconds() < 1.f) + { + return; + } + + sTimer.reset(); + + auto func = []() + { + if (gGLManager.mHasATIMemInfo) + { + S32 meminfo[4]; + glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, meminfo); + LLImageGLThread::sFreeVRAMMegabytes = meminfo[0]; + + } + else if (gGLManager.mHasNVXMemInfo) + { + S32 free_memory; + glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &free_memory); + LLImageGLThread::sFreeVRAMMegabytes = free_memory / 1024; + } + }; + + + // post update to background thread if available, otherwise execute immediately + auto queue = LL::WorkQueue::getInstance("LLImageGL"); + if (sEnabled) + { + queue->post(func); + } + else + { + llassert(queue == nullptr); + func(); + } +} + +void LLImageGL::syncToMainThread(LLGLuint new_tex_name) +{ + LL_PROFILE_ZONE_SCOPED; + llassert(!on_main_thread()); + + { + LL_PROFILE_ZONE_NAMED("cglt - sync"); + if (gGLManager.mHasSync) + { + // post a sync to the main thread (will execute before tex name swap lambda below) + // glFlush calls here are partly superstitious and partly backed by observation + // on AMD hardware + glFlush(); + auto sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + glFlush(); + LL::WorkQueue::postMaybe( + mMainQueue, + [=]() + { + LL_PROFILE_ZONE_NAMED("cglt - wait sync"); + { + LL_PROFILE_ZONE_NAMED("glWaitSync"); + glWaitSync(sync, 0, GL_TIMEOUT_IGNORED); + } + { + LL_PROFILE_ZONE_NAMED("glDeleteSync"); + glDeleteSync(sync); + } + }); + } + else + { + glFinish(); + } + } + + ref(); + LL::WorkQueue::postMaybe( + mMainQueue, + [=]() + { + LL_PROFILE_ZONE_NAMED("cglt - delete callback"); + syncTexName(new_tex_name); + unref(); + }); +} + +void LLImageGL::syncTexName(LLGLuint texname) +{ + if (texname != 0) + { + if (mTexName != 0 && mTexName != texname) + { + LLImageGL::deleteTextures(1, &mTexName); + } + mTexName = texname; + } } BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok) const @@ -1861,37 +1910,29 @@ BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre return TRUE ; } -void LLImageGL::deleteDeadTextures() -{ - bool reset = false; - - if (reset) - { - gGL.getTexUnit(0)->activate(); - } -} - void LLImageGL::destroyGLTexture() { + checkActiveThread(); + if (mTexName != 0) { if(mTextureMemory != S64Bytes(0)) { sGlobalTextureMemory -= mTextureMemory; - disclaimMem(mTextureMemory); mTextureMemory = (S64Bytes)0; } - LLImageGL::deleteTextures(1, &mTexName); + LLImageGL::deleteTextures(1, &mTexName); mCurrentDiscardLevel = -1 ; //invalidate mCurrentDiscardLevel. mTexName = 0; mGLTextureCreated = FALSE ; - } + } } //force to invalidate the gl texture, most likely a sculpty texture void LLImageGL::forceToInvalidateGLTexture() { + checkActiveThread(); if (mTexName != 0) { destroyGLTexture(); @@ -2059,6 +2100,7 @@ void LLImageGL::calcAlphaChannelOffsetAndStride() case GL_LUMINANCE_ALPHA: mAlphaStride = 2; break; + case GL_RED: case GL_RGB: case GL_SRGB: setNeedsAlphaAndPickMask(FALSE); @@ -2274,7 +2316,6 @@ U32 LLImageGL::createPickMask(S32 pWidth, S32 pHeight) U32 size = pick_width * pick_height; size = (size + 7) / 8; // pixelcount-to-bits mPickMask = new U8[size]; - claimMem(size); mPickMaskWidth = pick_width - 1; mPickMaskHeight = pick_height - 1; @@ -2289,7 +2330,6 @@ void LLImageGL::freePickMask() // pickmask validity depends on old image size, delete it if (mPickMask != NULL) { - disclaimMem((mPickMaskWidth * mPickMaskHeight + 7) / 8); delete [] mPickMask; } mPickMask = NULL; @@ -2416,6 +2456,12 @@ void LLImageGL::resetCurTexSizebar() sCurTexPickSize = -1 ; } //---------------------------------------------------------------------------- +#if LL_IMAGEGL_THREAD_CHECK +void LLImageGL::checkActiveThread() +{ + llassert(mActiveThread == LLThread::currentID()); +} +#endif //---------------------------------------------------------------------------- @@ -2469,3 +2515,38 @@ void LLImageGL::resetCurTexSizebar() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, nummips); */ + +std::atomic<S32> LLImageGLThread::sFreeVRAMMegabytes(4096); //if free vram is unknown, default to 4GB + +LLImageGLThread::LLImageGLThread(LLWindow* window) + // We want exactly one thread, but a very large capacity: we never want + // anyone, especially inner-loop render code, to have to block on post() + // because we're full. + : ThreadPool("LLImageGL", 1, 1024*1024) + , mWindow(window) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; + sEnabled = true; + mFinished = false; + + mContext = mWindow->createSharedContext(); + ThreadPool::start(); +} + +void LLImageGLThread::run() +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; + // We must perform setup on this thread before actually servicing our + // WorkQueue, likewise cleanup afterwards. + mWindow->makeContextCurrent(mContext); + gGL.init(false); + ThreadPool::run(); + gGL.shutdown(); + mWindow->destroySharedContext(mContext); +} + +S32 LLImageGLThread::getFreeVRAMMegabytes() +{ + return sFreeVRAMMegabytes; +} + diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index 27d7d30b048401803f223f42391627840e73364f..9c45640b9865bf48b66d60f4b920a4f594426d35 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -35,21 +35,26 @@ #include "llrefcount.h" #include "v2math.h" #include "llunits.h" - +#include "llthreadsafequeue.h" #include "llrender.h" -class LLTextureAtlas ; +#include "threadpool.h" +#include "workqueue.h" + +#define LL_IMAGEGL_THREAD_CHECK 0 //set to 1 to enable thread debugging for ImageGL + +class LLWindow; + #define BYTES_TO_MEGA_BYTES(x) ((x) >> 20) #define MEGA_BYTES_TO_BYTES(x) ((x) << 20) //============================================================================ -class LLImageGL : public LLRefCount, public LLTrace::MemTrackable<LLImageGL> +class LLImageGL : public LLRefCount { friend class LLTexUnit; public: // These 2 functions replace glGenTextures() and glDeleteTextures() static void generateTextures(S32 numTextures, U32 *textures); - static void deleteTextures(S32 numTextures, U32 *textures); - static void deleteDeadTextures(); + static void deleteTextures(S32 numTextures, const U32 *textures); // Size calculation static S32 dataFormatBits(S32 dataformat); @@ -103,17 +108,21 @@ class LLImageGL : public LLRefCount, public LLTrace::MemTrackable<LLImageGL> static void setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels, bool allow_compression = true); static void setManualImage3D(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, S32 depth, U32 pixformat, U32 pixtype, const void* pixels, bool allow_compression = true); - + BOOL createGLTexture() ; BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0, BOOL to_create = TRUE, - S32 category = sMaxCategories-1); - BOOL createGLTexture(S32 discard_level, const U8* data, BOOL data_hasmips = FALSE, S32 usename = 0); + S32 category = sMaxCategories-1, bool defer_copy = false, LLGLuint* tex_name = nullptr); + BOOL createGLTexture(S32 discard_level, const U8* data, BOOL data_hasmips = FALSE, S32 usename = 0, bool defer_copy = false, LLGLuint* tex_name = nullptr); void setImage(const LLImageRaw* imageraw); - BOOL setImage(const U8* data_in, BOOL data_hasmips = FALSE); - BOOL setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update = FALSE); - BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update = FALSE); + BOOL setImage(const U8* data_in, BOOL data_hasmips = FALSE, S32 usename = 0); + BOOL setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update = FALSE, LLGLuint use_name = 0); + BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update = FALSE, LLGLuint use_name = 0); BOOL setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_pos, S32 width, S32 height); - + + // wait for gl commands to finish on current thread and push + // a lambda to main thread to swap mNewTexName and mTexName + void syncToMainThread(LLGLuint new_tex_name); + // Read back a raw image for this discard level, if it exists BOOL readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok) const; void destroyGLTexture(); @@ -188,6 +197,12 @@ class LLImageGL : public LLRefCount, public LLTrace::MemTrackable<LLImageGL> BOOL preAddToAtlas(S32 discard_level, const LLImageRaw* raw_image); void postAddToAtlas() ; +#if LL_IMAGEGL_THREAD_CHECK + // thread debugging + std::thread::id mActiveThread; + void checkActiveThread(); +#endif + public: // Various GL/Rendering options S64Bytes mTextureMemory; @@ -198,6 +213,7 @@ class LLImageGL : public LLRefCount, public LLTrace::MemTrackable<LLImageGL> void freePickMask(); LLPointer<LLImageRaw> mSaveData; // used for destroyGL/restoreGL + LL::WorkQueue::weak_t mMainQueue; U8* mPickMask; //downsampled bitmap approximation of alpha channel. NULL if no alpha channel U16 mPickMaskWidth; U16 mPickMaskHeight; @@ -214,8 +230,9 @@ class LLImageGL : public LLRefCount, public LLTrace::MemTrackable<LLImageGL> bool mGLTextureCreated ; LLGLuint mTexName; + //LLGLuint mNewTexName = 0; // tex name set by background thread to be applied in main thread U16 mWidth; - U16 mHeight; + U16 mHeight; S8 mCurrentDiscardLevel; S8 mDiscardLevelInAtlas; @@ -270,7 +287,7 @@ class LLImageGL : public LLRefCount, public LLTrace::MemTrackable<LLImageGL> #endif public: - static void initClass(S32 num_catagories, BOOL skip_analyze_alpha = false); + static void initClass(LLWindow* window, S32 num_catagories, BOOL skip_analyze_alpha = false, bool multi_threaded = false); static void cleanupClass() ; private: @@ -292,6 +309,9 @@ class LLImageGL : public LLRefCount, public LLTrace::MemTrackable<LLImageGL> void setTexName(GLuint texName) { mTexName = texName; } + //similar to setTexName, but will call deleteTextures on mTexName if mTexName is not 0 or texname + void syncTexName(LLGLuint texname); + //for debug use: show texture size distribution //---------------------------------------- static S32 sCurTexSizeBar ; @@ -306,4 +326,36 @@ class LLImageGL : public LLRefCount, public LLTrace::MemTrackable<LLImageGL> }; +class LLImageGLThread : public LLSimpleton<LLImageGLThread>, LL::ThreadPool +{ +public: + // follows gSavedSettings "RenderGLMultiThreaded" + static bool sEnabled; + + // app should call this function periodically + static void updateClass(); + + // free video memory in megabytes + static std::atomic<S32> sFreeVRAMMegabytes; + + LLImageGLThread(LLWindow* window); + + // post a function to be executed on the LLImageGL background thread + template <typename CALLABLE> + bool post(CALLABLE&& func) + { + return getQueue().postIfOpen(std::forward<CALLABLE>(func)); + } + + void run() override; + + static S32 getFreeVRAMMegabytes(); + +private: + LLWindow* mWindow; + void* mContext = nullptr; + LLAtomicBool mFinished; +}; + + #endif // LL_LLIMAGEGL_H diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index e6f853375279aaab59634327a0b0690b90dfffeb..ea0f2523a05cc6683bb015fecb29972f5ef5762f 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -38,7 +38,20 @@ #include "llmatrix4a.h" #include "alglmath.h" -LLRender gGL; +#ifndef APIENTRY +#define APIENTRY +#endif + +extern void APIENTRY gl_debug_callback(GLenum source, + GLenum type, + GLuint id, + GLenum severity, + GLsizei length, + const GLchar* message, + GLvoid* userParam) +; + +thread_local LLRender gGL; // Handy copies of last good GL matrices LLMatrix4a gGLModelView; @@ -74,18 +87,6 @@ static const GLint sGLAddressMode[] = GL_CLAMP_TO_EDGE }; -static const GLenum sGLCompareFunc[] = -{ - GL_NEVER, - GL_ALWAYS, - GL_LESS, - GL_LEQUAL, - GL_EQUAL, - GL_NOTEQUAL, - GL_GEQUAL, - GL_GREATER -}; - const U32 immediate_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXCOORD0; static const GLenum sGLBlendFactor[] = @@ -105,10 +106,7 @@ static const GLenum sGLBlendFactor[] = }; LLTexUnit::LLTexUnit(S32 index) - : mCurrTexType(TT_NONE), mCurrBlendType(TB_MULT), - mCurrColorOp(TBO_MULT), mCurrAlphaOp(TBO_MULT), - mCurrColorSrc1(TBS_TEX_COLOR), mCurrColorSrc2(TBS_PREV_COLOR), - mCurrAlphaSrc1(TBS_TEX_ALPHA), mCurrAlphaSrc2(TBS_PREV_ALPHA), + : mCurrTexType(TT_NONE), mCurrColorScale(1), mCurrAlphaScale(1), mCurrTexture(0), mTexColorSpace(TCS_SRGB), mHasMipMaps(false), mIndex(index) @@ -131,42 +129,15 @@ void LLTexUnit::refreshState(void) glActiveTexture(GL_TEXTURE0 + mIndex); - // - // Per apple spec, don't call glEnable/glDisable when index exceeds max texture units - // http://www.mailinglistarchive.com/html/mac-opengl@lists.apple.com/2008-07/msg00653.html - // - bool enableDisable = !LLGLSLShader::sNoFixedFunction && - (mIndex < gGLManager.mNumTextureUnits) && mCurrTexType != LLTexUnit::TT_MULTISAMPLE_TEXTURE; - if (mCurrTexType != TT_NONE) { - if (enableDisable) - { - glEnable(sGLTextureType[mCurrTexType]); - } - glBindTexture(sGLTextureType[mCurrTexType], mCurrTexture); } else { - if (enableDisable) - { - glDisable(GL_TEXTURE_2D); - } - glBindTexture(GL_TEXTURE_2D, 0); } - if (mCurrBlendType != TB_COMBINE) - { - setTextureBlendType(mCurrBlendType); - } - else - { - setTextureCombiner(mCurrColorOp, mCurrColorSrc1, mCurrColorSrc2, false); - setTextureCombiner(mCurrAlphaOp, mCurrAlphaSrc1, mCurrAlphaSrc2, true); - } - setTextureColorSpace(mTexColorSpace); } @@ -199,14 +170,6 @@ void LLTexUnit::enable(eTextureType type) mCurrTexType = type; gGL.flush(); - if (!LLGLSLShader::sNoFixedFunction && - type != LLTexUnit::TT_MULTISAMPLE_TEXTURE && - mIndex < gGLManager.mNumTextureUnits) - { - stop_glerror(); - glEnable(sGLTextureType[type]); - stop_glerror(); - } } } @@ -219,21 +182,34 @@ void LLTexUnit::disable(void) activate(); unbind(mCurrTexType); gGL.flush(); - if (!LLGLSLShader::sNoFixedFunction && - mCurrTexType != LLTexUnit::TT_MULTISAMPLE_TEXTURE && - mIndex < gGLManager.mNumTextureUnits) - { - glDisable(sGLTextureType[mCurrTexType]); - } - setTextureColorSpace(TCS_SRGB); mCurrTexType = TT_NONE; } } +void LLTexUnit::bindFast(LLTexture* texture) +{ + LLImageGL* gl_tex = texture->getGLTexture(); + + glActiveTextureARB(GL_TEXTURE0_ARB + mIndex); + gGL.mCurrTextureUnitIndex = mIndex; + mCurrTexture = gl_tex->getTexName(); + if (!mCurrTexture) + { + LL_PROFILE_ZONE_NAMED("MISSING TEXTURE"); + //if deleted, will re-generate it immediately + texture->forceImmediateUpdate(); + gl_tex->forceUpdateBindStats(); + texture->bindDefaultImage(mIndex); + } + glBindTexture(sGLTextureType[gl_tex->getTarget()], mCurrTexture); + mHasMipMaps = gl_tex->mHasMipMaps; +} + bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; stop_glerror(); if (mIndex >= 0) { @@ -299,11 +275,13 @@ bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind) return true; } -bool LLTexUnit::bind(LLImageGL* texture, bool for_rendering, bool forceBind) +bool LLTexUnit::bind(LLImageGL* texture, bool for_rendering, bool forceBind, S32 usename) { stop_glerror(); if (mIndex < 0) return false; + U32 texname = usename ? usename : texture->getTexName(); + if(!texture) { #if SHOW_DEBUG @@ -312,7 +290,7 @@ bool LLTexUnit::bind(LLImageGL* texture, bool for_rendering, bool forceBind) return false; } - if(!texture->getTexName()) + if(!texname) { if(LLImageGL::sDefaultGLTexture && LLImageGL::sDefaultGLTexture->getTexName()) { @@ -322,7 +300,7 @@ bool LLTexUnit::bind(LLImageGL* texture, bool for_rendering, bool forceBind) return false ; } - if ((mCurrTexture != texture->getTexName()) || forceBind) + if ((mCurrTexture != texname) || forceBind) { gGL.flush(); stop_glerror(); @@ -330,7 +308,7 @@ bool LLTexUnit::bind(LLImageGL* texture, bool for_rendering, bool forceBind) stop_glerror(); enable(texture->getTarget()); stop_glerror(); - mCurrTexture = texture->getTexName(); + mCurrTexture = texname; glBindTexture(sGLTextureType[texture->getTarget()], mCurrTexture); stop_glerror(); texture->updateBindStats(texture->mTextureMemory); @@ -454,7 +432,7 @@ void LLTexUnit::unbind(eTextureType type) // Always make sure our texture color space is reset to linear. SRGB sampling should be opt-in in the vast majority of cases. Also prevents color space "popping". mTexColorSpace = TCS_SRGB; - if (LLGLSLShader::sNoFixedFunction && type == LLTexUnit::TT_TEXTURE) + if (type == LLTexUnit::TT_TEXTURE) { glBindTexture(sGLTextureType[type], sWhiteTexture); } @@ -466,6 +444,28 @@ void LLTexUnit::unbind(eTextureType type) } } +void LLTexUnit::unbindFast(eTextureType type) +{ + activate(); + + // Disabled caching of binding state. + if (mCurrTexType == type) + { + mCurrTexture = 0; + + // Always make sure our texture color space is reset to linear. SRGB sampling should be opt-in in the vast majority of cases. Also prevents color space "popping". + mTexColorSpace = TCS_LINEAR; + if (type == LLTexUnit::TT_TEXTURE) + { + glBindTexture(sGLTextureType[type], sWhiteTexture); + } + else + { + glBindTexture(sGLTextureType[type], 0); + } + } +} + void LLTexUnit::setTextureAddressMode(eTextureAddressMode mode) { if (mIndex < 0 || mCurrTexture == 0) return; @@ -538,55 +538,6 @@ void LLTexUnit::setTextureFilteringOption(LLTexUnit::eTextureFilterOptions optio } } -void LLTexUnit::setTextureBlendType(eTextureBlendType type) -{ - if (LLGLSLShader::sNoFixedFunction) - { //texture blend type means nothing when using shaders - return; - } - - if (mIndex < 0) return; - - // Do nothing if it's already correctly set. - if (mCurrBlendType == type && !gGL.mDirty) - { - return; - } - - gGL.flush(); - - activate(); - mCurrBlendType = type; - S32 scale_amount = 1; - switch (type) - { - case TB_REPLACE: - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - break; - case TB_ADD: - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD); - break; - case TB_MULT: - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - break; - case TB_MULT_X2: - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - scale_amount = 2; - break; - case TB_ALPHA_BLEND: - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); - break; - case TB_COMBINE: - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); - break; - default: - LL_ERRS() << "Unknown Texture Blend Type: " << type << LL_ENDL; - break; - } - setColorScale(scale_amount); - setAlphaScale(1); -} - GLint LLTexUnit::getTextureSource(eTextureBlendSrc src) { switch(src) @@ -663,159 +614,6 @@ GLint LLTexUnit::getTextureSourceType(eTextureBlendSrc src, bool isAlpha) } } -void LLTexUnit::setTextureCombiner(eTextureBlendOp op, eTextureBlendSrc src1, eTextureBlendSrc src2, bool isAlpha) -{ - if (LLGLSLShader::sNoFixedFunction) - { //register combiners do nothing when not using fixed function - return; - } - - if (mIndex < 0) return; - - activate(); - if (mCurrBlendType != TB_COMBINE || gGL.mDirty) - { - mCurrBlendType = TB_COMBINE; - gGL.flush(); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); - } - - // We want an early out, because this function does a LOT of stuff. - if ( ( (isAlpha && (mCurrAlphaOp == op) && (mCurrAlphaSrc1 == src1) && (mCurrAlphaSrc2 == src2)) - || (!isAlpha && (mCurrColorOp == op) && (mCurrColorSrc1 == src1) && (mCurrColorSrc2 == src2)) ) && !gGL.mDirty) - { - return; - } - - gGL.flush(); - - // Get the gl source enums according to the eTextureBlendSrc sources passed in - GLint source1 = getTextureSource(src1); - GLint source2 = getTextureSource(src2); - // Get the gl operand enums according to the eTextureBlendSrc sources passed in - GLint operand1 = getTextureSourceType(src1, isAlpha); - GLint operand2 = getTextureSourceType(src2, isAlpha); - // Default the scale amount to 1 - S32 scale_amount = 1; - GLenum comb_enum, src0_enum, src1_enum, src2_enum, operand0_enum, operand1_enum, operand2_enum; - - if (isAlpha) - { - // Set enums to ALPHA ones - comb_enum = GL_COMBINE_ALPHA; - src0_enum = GL_SOURCE0_ALPHA; - src1_enum = GL_SOURCE1_ALPHA; - src2_enum = GL_SOURCE2_ALPHA; - operand0_enum = GL_OPERAND0_ALPHA; - operand1_enum = GL_OPERAND1_ALPHA; - operand2_enum = GL_OPERAND2_ALPHA; - - // cache current combiner - mCurrAlphaOp = op; - mCurrAlphaSrc1 = src1; - mCurrAlphaSrc2 = src2; - } - else - { - // Set enums to RGB ones - comb_enum = GL_COMBINE_RGB; - src0_enum = GL_SOURCE0_RGB; - src1_enum = GL_SOURCE1_RGB; - src2_enum = GL_SOURCE2_RGB; - operand0_enum = GL_OPERAND0_RGB; - operand1_enum = GL_OPERAND1_RGB; - operand2_enum = GL_OPERAND2_RGB; - - // cache current combiner - mCurrColorOp = op; - mCurrColorSrc1 = src1; - mCurrColorSrc2 = src2; - } - - switch(op) - { - case TBO_REPLACE: - // Slightly special syntax (no second sources), just set all and return. - glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_REPLACE); - glTexEnvi(GL_TEXTURE_ENV, src0_enum, source1); - glTexEnvi(GL_TEXTURE_ENV, operand0_enum, operand1); - (isAlpha) ? setAlphaScale(1) : setColorScale(1); - return; - - case TBO_MULT: - glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_MODULATE); - break; - - case TBO_MULT_X2: - glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_MODULATE); - scale_amount = 2; - break; - - case TBO_MULT_X4: - glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_MODULATE); - scale_amount = 4; - break; - - case TBO_ADD: - glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_ADD); - break; - - case TBO_ADD_SIGNED: - glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_ADD_SIGNED); - break; - - case TBO_SUBTRACT: - glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_SUBTRACT); - break; - - case TBO_LERP_VERT_ALPHA: - glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_INTERPOLATE); - glTexEnvi(GL_TEXTURE_ENV, src2_enum, GL_PRIMARY_COLOR); - glTexEnvi(GL_TEXTURE_ENV, operand2_enum, GL_SRC_ALPHA); - break; - - case TBO_LERP_TEX_ALPHA: - glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_INTERPOLATE); - glTexEnvi(GL_TEXTURE_ENV, src2_enum, GL_TEXTURE); - glTexEnvi(GL_TEXTURE_ENV, operand2_enum, GL_SRC_ALPHA); - break; - - case TBO_LERP_PREV_ALPHA: - glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_INTERPOLATE); - glTexEnvi(GL_TEXTURE_ENV, src2_enum, GL_PREVIOUS); - glTexEnvi(GL_TEXTURE_ENV, operand2_enum, GL_SRC_ALPHA); - break; - - case TBO_LERP_CONST_ALPHA: - glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_INTERPOLATE); - glTexEnvi(GL_TEXTURE_ENV, src2_enum, GL_CONSTANT); - glTexEnvi(GL_TEXTURE_ENV, operand2_enum, GL_SRC_ALPHA); - break; - - case TBO_LERP_VERT_COLOR: - glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_INTERPOLATE); - glTexEnvi(GL_TEXTURE_ENV, src2_enum, GL_PRIMARY_COLOR); - glTexEnvi(GL_TEXTURE_ENV, operand2_enum, (isAlpha) ? GL_SRC_ALPHA : GL_SRC_COLOR); - break; - - default: - LL_WARNS() << "Unknown eTextureBlendOp: " << op << ". Setting op to replace." << LL_ENDL; - // Slightly special syntax (no second sources), just set all and return. - glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_REPLACE); - glTexEnvi(GL_TEXTURE_ENV, src0_enum, source1); - glTexEnvi(GL_TEXTURE_ENV, operand0_enum, operand1); - (isAlpha) ? setAlphaScale(1) : setColorScale(1); - return; - } - - // Set sources, operands, and scale accordingly - glTexEnvi(GL_TEXTURE_ENV, src0_enum, source1); - glTexEnvi(GL_TEXTURE_ENV, operand0_enum, operand1); - glTexEnvi(GL_TEXTURE_ENV, src1_enum, source2); - glTexEnvi(GL_TEXTURE_ENV, operand1_enum, operand2); - (isAlpha) ? setAlphaScale(scale_amount) : setColorScale(scale_amount); -} - void LLTexUnit::setColorScale(S32 scale) { if (mCurrColorScale != scale || gGL.mDirty) @@ -898,26 +696,12 @@ LLLightState::LLLightState(S32 index) void LLLightState::enable() { - if (!mEnabled) - { - if (!LLGLSLShader::sNoFixedFunction) - { - glEnable(GL_LIGHT0+mIndex); - } - mEnabled = true; - } + mEnabled = true; } void LLLightState::disable() { - if (mEnabled) - { - if (!LLGLSLShader::sNoFixedFunction) - { - glDisable(GL_LIGHT0+mIndex); - } - mEnabled = false; - } + mEnabled = false; } void LLLightState::setDiffuse(const LLColor4& diffuse) @@ -926,10 +710,6 @@ void LLLightState::setDiffuse(const LLColor4& diffuse) { ++gGL.mLightHash; mDiffuse = diffuse; - if (!LLGLSLShader::sNoFixedFunction) - { - glLightfv(GL_LIGHT0+mIndex, GL_DIFFUSE, mDiffuse.mV); - } } } @@ -957,10 +737,6 @@ void LLLightState::setAmbient(const LLColor4& ambient) { ++gGL.mLightHash; mAmbient = ambient; - if (!LLGLSLShader::sNoFixedFunction) - { - glLightfv(GL_LIGHT0+mIndex, GL_AMBIENT, mAmbient.mV); - } } } @@ -970,10 +746,6 @@ void LLLightState::setSpecular(const LLColor4& specular) { ++gGL.mLightHash; mSpecular = specular; - if (!LLGLSLShader::sNoFixedFunction) - { - glLightfv(GL_LIGHT0+mIndex, GL_SPECULAR, mSpecular.mV); - } } } @@ -982,20 +754,11 @@ void LLLightState::setPosition(const LLVector4& position) //always set position because modelview matrix may have changed ++gGL.mLightHash; mPosition = position; - if (!LLGLSLShader::sNoFixedFunction) - { - glLightfv(GL_LIGHT0+mIndex, GL_POSITION, mPosition.mV); - } - else - { //transform position by current modelview matrix - LLVector4a pos; - pos.loadua(position.mV); - - gGL.getModelviewMatrix().rotate4(pos,pos); - - mPosition.set(pos.getF32ptr()); - } - + //transform position by current modelview matrix + LLVector4a pos; + pos.loadua(position.mV); + gGL.getModelviewMatrix().rotate4(pos,pos); + mPosition.set(pos.getF32ptr()); } void LLLightState::setConstantAttenuation(const F32& atten) @@ -1004,10 +767,6 @@ void LLLightState::setConstantAttenuation(const F32& atten) { mConstantAtten = atten; ++gGL.mLightHash; - if (!LLGLSLShader::sNoFixedFunction) - { - glLightf(GL_LIGHT0+mIndex, GL_CONSTANT_ATTENUATION, atten); - } } } @@ -1017,10 +776,6 @@ void LLLightState::setLinearAttenuation(const F32& atten) { ++gGL.mLightHash; mLinearAtten = atten; - if (!LLGLSLShader::sNoFixedFunction) - { - glLightf(GL_LIGHT0+mIndex, GL_LINEAR_ATTENUATION, atten); - } } } @@ -1030,10 +785,6 @@ void LLLightState::setQuadraticAttenuation(const F32& atten) { ++gGL.mLightHash; mQuadraticAtten = atten; - if (!LLGLSLShader::sNoFixedFunction) - { - glLightf(GL_LIGHT0+mIndex, GL_QUADRATIC_ATTENUATION, atten); - } } } @@ -1043,10 +794,6 @@ void LLLightState::setSpotExponent(const F32& exponent) { ++gGL.mLightHash; mSpotExponent = exponent; - if (!LLGLSLShader::sNoFixedFunction) - { - glLightf(GL_LIGHT0+mIndex, GL_SPOT_EXPONENT, exponent); - } } } @@ -1056,10 +803,6 @@ void LLLightState::setSpotCutoff(const F32& cutoff) { ++gGL.mLightHash; mSpotCutoff = cutoff; - if (!LLGLSLShader::sNoFixedFunction) - { - glLightf(GL_LIGHT0+mIndex, GL_SPOT_CUTOFF, cutoff); - } } } @@ -1068,19 +811,12 @@ void LLLightState::setSpotDirection(const LLVector3& direction) //always set direction because modelview matrix may have changed ++gGL.mLightHash; mSpotDirection = direction; - if (!LLGLSLShader::sNoFixedFunction) - { - glLightfv(GL_LIGHT0+mIndex, GL_SPOT_DIRECTION, direction.mV); - } - else - { //transform direction by current modelview matrix - LLVector4a dir; - dir.load3(direction.mV); - - gGL.getModelviewMatrix().rotate(dir,dir); + //transform direction by current modelview matrix + LLVector4a dir; + dir.load3(direction.mV); + gGL.getModelviewMatrix().rotate(dir,dir); - mSpotDirection.set(dir.getF32ptr()); - } + mSpotDirection.set(dir.getF32ptr()); } LLRender::LLRender() @@ -1108,8 +844,6 @@ LLRender::LLRender() mCurrColorMask[i] = true; } - mCurrAlphaFunc = CF_DEFAULT; - mCurrAlphaFuncVal = 0.01f; mCurrBlendColorSFactor = BF_UNDEF; mCurrBlendAlphaSFactor = BF_UNDEF; mCurrBlendColorDFactor = BF_UNDEF; @@ -1139,9 +873,48 @@ LLRender::~LLRender() shutdown(); } -void LLRender::init() +void LLRender::init(bool needs_vertex_buffer) +{ + if (gGLManager.mHasDebugOutput && gDebugGL) + { //setup debug output callback + //glDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW_ARB, 0, NULL, GL_TRUE); + glDebugMessageCallbackARB((GLDEBUGPROCARB) gl_debug_callback, NULL); + glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB); + } + + glPixelStorei(GL_PACK_ALIGNMENT, 1); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + gGL.setSceneBlendType(LLRender::BT_ALPHA); + gGL.setAmbientLightColor(LLColor4::black); + + glCullFace(GL_BACK); + + if (needs_vertex_buffer) + { + initVertexBuffer(); + } +} + +void LLRender::initVertexBuffer() +{ + llassert_always(mBuffer.isNull()); + stop_glerror(); + mBuffer = new LLVertexBuffer(immediate_mask, 0); + stop_glerror(); + mBuffer->allocateBuffer(4096, 0, TRUE); + stop_glerror(); + mBuffer->getVertexStrider(mVerticesp); + stop_glerror(); + mBuffer->getTexCoord0Strider(mTexcoordsp); + stop_glerror(); + mBuffer->getColorStrider(mColorsp); + stop_glerror(); +} + +void LLRender::resetVertexBuffer() { - restoreVertexBuffers(); + mBuffer = NULL; } void LLRender::shutdown() @@ -1159,8 +932,7 @@ void LLRender::shutdown() delete mLightState[i]; } mLightState.clear(); - - mBuffer = nullptr; + resetVertexBuffer(); } void LLRender::refreshState(void) @@ -1175,38 +947,14 @@ void LLRender::refreshState(void) } mTexUnits[active_unit]->activate(); - stop_glerror(); setColorMask(mCurrColorMask[0], mCurrColorMask[1], mCurrColorMask[2], mCurrColorMask[3]); - stop_glerror(); - setAlphaRejectSettings(mCurrAlphaFunc, mCurrAlphaFuncVal); - stop_glerror(); + flush(); mDirty = false; } -void LLRender::resetVertexBuffers() -{ - mBuffer = nullptr; -} - -void LLRender::restoreVertexBuffers() -{ - llassert_always(mBuffer.isNull()); - stop_glerror(); - mBuffer = new LLVertexBuffer(immediate_mask, 0); - stop_glerror(); - mBuffer->allocateBuffer(4096, 0, TRUE); - stop_glerror(); - mBuffer->getVertexStrider(mVerticesp); - stop_glerror(); - mBuffer->getTexCoord0Strider(mTexcoordsp); - stop_glerror(); - mBuffer->getColorStrider(mColorsp); - stop_glerror(); -} - void LLRender::syncLightState() { LLGLSLShader *shader = LLGLSLShader::sCurBoundShaderPtr; @@ -1249,9 +997,7 @@ void LLRender::syncLightState() void LLRender::syncMatrices() { - stop_glerror(); - - static const U32 name[] = + static const U32 name[] = { LLShaderMgr::MODELVIEW_MATRIX, LLShaderMgr::PROJECTION_MATRIX, @@ -1372,41 +1118,6 @@ void LLRender::syncMatrices() syncLightState(); } } - else if (!LLGLSLShader::sNoFixedFunction) - { - static const GLenum mode[] = - { - GL_MODELVIEW, - GL_PROJECTION, - GL_TEXTURE, - GL_TEXTURE, - GL_TEXTURE, - GL_TEXTURE, - }; - - for (U32 i = 0; i < MM_TEXTURE0; ++i) - { - if (mMatHash[i] != mCurMatHash[i]) - { - glMatrixMode(mode[i]); - glLoadMatrixf(mMatrix[i][mMatIdx[i]].getF32ptr()); - mCurMatHash[i] = mMatHash[i]; - } - } - - for (U32 i = MM_TEXTURE0; i < NUM_MATRIX_MODES; ++i) - { - if (mMatHash[i] != mCurMatHash[i]) - { - gGL.getTexUnit(i-MM_TEXTURE0)->activate(); - glMatrixMode(mode[i]); - glLoadMatrixf(mMatrix[i][mMatIdx[i]].getF32ptr()); - mCurMatHash[i] = mMatHash[i]; - } - } - } - - stop_glerror(); } void LLRender::translatef(const GLfloat& x, const GLfloat& y, const GLfloat& z) @@ -1757,55 +1468,6 @@ void LLRender::setSceneBlendType(eBlendType type) } } -void LLRender::setAlphaRejectSettings(eCompareFunc func, F32 value) -{ - flush(); - - if (LLGLSLShader::sNoFixedFunction) - { //glAlphaFunc is deprecated in OpenGL 3.3 - return; - } - - if (mCurrAlphaFunc != func || - mCurrAlphaFuncVal != value) - { - mCurrAlphaFunc = func; - mCurrAlphaFuncVal = value; - if (func == CF_DEFAULT) - { - glAlphaFunc(GL_GREATER, 0.01f); - } - else - { - glAlphaFunc(sGLCompareFunc[func], value); - } - } - - if (gDebugGL) - { //make sure cached state is correct - GLint cur_func = 0; - glGetIntegerv(GL_ALPHA_TEST_FUNC, &cur_func); - - if (func == CF_DEFAULT) - { - func = CF_GREATER; - } - - if (cur_func != sGLCompareFunc[func]) - { - LL_ERRS() << "Alpha test function corrupted!" << LL_ENDL; - } - - F32 ref = 0.f; - glGetFloatv(GL_ALPHA_TEST_REF, &ref); - - if (ref != value) - { - LL_ERRS() << "Alpha test value corrupted!" << LL_ENDL; - } - } -} - void LLRender::blendFunc(eBlendFactor sfactor, eBlendFactor dfactor) { llassert(sfactor < BF_UNDEF); @@ -1875,14 +1537,11 @@ LLLightState* LLRender::getLight(U32 index) void LLRender::setAmbientLightColor(const LLColor4& color) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE if (color != mAmbientLightColor) { ++mLightHash; mAmbientLightColor = color; - if (!LLGLSLShader::sNoFixedFunction) - { - glLightModelfv(GL_LIGHT_MODEL_AMBIENT, color.mV); - } } } void LLRender::setLineWidth(F32 line_width) @@ -1969,6 +1628,7 @@ void LLRender::flush() { if (mCount > 0) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; if (!mUIOffset.empty()) { sUICalls++; @@ -1998,16 +1658,25 @@ void LLRender::flush() mCount = 0; - if (mBuffer->useVBOs() && !mBuffer->isLocked()) - { //hack to only flush the part of the buffer that was updated (relies on stream draw using buffersubdata) - mBuffer->getVertexStrider(mVerticesp, 0, count); - mBuffer->getTexCoord0Strider(mTexcoordsp, 0, count); - mBuffer->getColorStrider(mColorsp, 0, count); - } - - mBuffer->flush(); - mBuffer->setBuffer(immediate_mask); - mBuffer->drawArrays(mMode, 0, count); + if (mBuffer) + { + if (mBuffer->useVBOs() && !mBuffer->isLocked()) + { //hack to only flush the part of the buffer that was updated (relies on stream draw using buffersubdata) + mBuffer->getVertexStrider(mVerticesp, 0, count); + mBuffer->getTexCoord0Strider(mTexcoordsp, 0, count); + mBuffer->getColorStrider(mColorsp, 0, count); + } + + mBuffer->flush(); + mBuffer->setBuffer(immediate_mask); + mBuffer->drawArrays(mMode, 0, count); + } + else + { + // mBuffer is present in main thread and not present in an image thread + LL_ERRS() << "A flush call from outside main rendering thread" << LL_ENDL; + } + mVerticesp[0] = mVerticesp[count]; mTexcoordsp[0] = mTexcoordsp[count]; @@ -2291,7 +1960,7 @@ void LLRender::color3fv(const GLfloat* c) void LLRender::diffuseColor3f(F32 r, F32 g, F32 b) { LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; - llassert(!LLGLSLShader::sNoFixedFunction || shader != NULL); + llassert(shader != NULL); if (shader) { @@ -2306,7 +1975,7 @@ void LLRender::diffuseColor3f(F32 r, F32 g, F32 b) void LLRender::diffuseColor3fv(const F32* c) { LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; - llassert(!LLGLSLShader::sNoFixedFunction || shader != NULL); + llassert(shader != NULL); if (shader) { @@ -2321,7 +1990,7 @@ void LLRender::diffuseColor3fv(const F32* c) void LLRender::diffuseColor4f(F32 r, F32 g, F32 b, F32 a) { LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; - llassert(!LLGLSLShader::sNoFixedFunction || shader != NULL); + llassert(shader != NULL); if (shader) { @@ -2336,7 +2005,7 @@ void LLRender::diffuseColor4f(F32 r, F32 g, F32 b, F32 a) void LLRender::diffuseColor4fv(const F32* c) { LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; - llassert(!LLGLSLShader::sNoFixedFunction || shader != NULL); + llassert(shader != NULL); if (shader) { @@ -2351,7 +2020,7 @@ void LLRender::diffuseColor4fv(const F32* c) void LLRender::diffuseColor4ubv(const U8* c) { LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; - llassert(!LLGLSLShader::sNoFixedFunction || shader != NULL); + llassert(shader != NULL); if (shader) { @@ -2366,7 +2035,7 @@ void LLRender::diffuseColor4ubv(const U8* c) void LLRender::diffuseColor4ub(U8 r, U8 g, U8 b, U8 a) { LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; - llassert(!LLGLSLShader::sNoFixedFunction || shader != NULL); + llassert(shader != NULL); if (shader) { diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index 1ea8911320e8dac47f8b73cb5124ac9ec53dad1f..2c5dd81ee685c0593b18555afc2ee58dbcd30691 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -108,10 +108,7 @@ class LLTexUnit TBO_LERP_VERT_ALPHA, // Interpolate based on Vertex Alpha (VA): ( Source1 * VA + Source2 * (1-VA) ) TBO_LERP_TEX_ALPHA, // Interpolate based on Texture Alpha (TA): ( Source1 * TA + Source2 * (1-TA) ) TBO_LERP_PREV_ALPHA, // Interpolate based on Previous Alpha (PA): ( Source1 * PA + Source2 * (1-PA) ) - TBO_LERP_CONST_ALPHA, // Interpolate based on Const Alpha (CA): ( Source1 * CA + Source2 * (1-CA) ) - TBO_LERP_VERT_COLOR // Interpolate based on Vertex Col (VC): ( Source1 * VC + Source2 * (1-VC) ) - // *Note* TBO_LERP_VERTEX_COLOR only works with setTextureColorBlend(), - // and falls back to TBO_LERP_VERTEX_ALPHA for setTextureAlphaBlend(). + TBO_LERP_CONST_ALPHA // Interpolate based on Const Alpha (CA): ( Source1 * CA + Source2 * (1-CA) ) } eTextureBlendOp; typedef enum @@ -161,9 +158,20 @@ class LLTexUnit // Binds the LLImageGL to this texture unit // (automatically enables the unit for the LLImageGL's texture type) - bool bind(LLImageGL* texture, bool for_rendering = false, bool forceBind = false); + bool bind(LLImageGL* texture, bool for_rendering = false, bool forceBind = false, S32 usename = 0); bool bind(LLTexture* texture, bool for_rendering = false, bool forceBind = false); + // bind implementation for inner loops + // makes the following assumptions: + // - No need for gGL.flush() + // - texture is not null + // - gl_tex->getTexName() is not zero + // - This texture is not being bound redundantly + // - USE_SRGB_DECODE is disabled + // - mTexOptionsDirty is false + // - + void bindFast(LLTexture* texture); + // Binds a cubemap to this texture unit // (automatically enables the texture unit for cubemaps) bool bind(LLCubeMap* cubeMap); @@ -180,6 +188,9 @@ class LLTexUnit // (only if there's a texture of the given type currently bound) void unbind(eTextureType type); + // Fast but unsafe version of unbind + void unbindFast(eTextureType type); + // Sets the addressing mode used to sample the texture // Warning: this stays set for the bound texture forever, // make sure you want to permanently change the address mode for the bound texture. @@ -190,15 +201,6 @@ class LLTexUnit // make sure you want to permanently change the filtering for the bound texture. void setTextureFilteringOption(LLTexUnit::eTextureFilterOptions option); - void setTextureBlendType(eTextureBlendType type); - - inline void setTextureColorBlend(eTextureBlendOp op, eTextureBlendSrc src1, eTextureBlendSrc src2 = TBS_PREV_COLOR) - { setTextureCombiner(op, src1, src2, false); } - - // NOTE: If *_COLOR enums are passed to src1 or src2, the corresponding *_ALPHA enum will be used instead. - inline void setTextureAlphaBlend(eTextureBlendOp op, eTextureBlendSrc src1, eTextureBlendSrc src2 = TBS_PREV_ALPHA) - { setTextureCombiner(op, src1, src2, true); } - static U32 getInternalType(eTextureType type); U32 getCurrTexture(void) { return mCurrTexture; } @@ -215,13 +217,6 @@ class LLTexUnit const S32 mIndex; U32 mCurrTexture; eTextureType mCurrTexType; - eTextureBlendType mCurrBlendType; - eTextureBlendOp mCurrColorOp; - eTextureBlendSrc mCurrColorSrc1; - eTextureBlendSrc mCurrColorSrc2; - eTextureBlendOp mCurrAlphaOp; - eTextureBlendSrc mCurrAlphaSrc1; - eTextureBlendSrc mCurrAlphaSrc2; eTextureColorSpace mTexColorSpace; S32 mCurrColorScale; S32 mCurrAlphaScale; @@ -232,7 +227,6 @@ class LLTexUnit void setAlphaScale(S32 scale); GLint getTextureSource(eTextureBlendSrc src); GLint getTextureSourceType(eTextureBlendSrc src, bool isAlpha = false); - void setTextureCombiner(eTextureBlendOp op, eTextureBlendSrc src1, eTextureBlendSrc src2, bool isAlpha = false); }; class LLLightState @@ -362,16 +356,15 @@ class LLRender LLRender(); ~LLRender(); - void init() ; + void init(bool needs_vertex_buffer); + void initVertexBuffer(); + void resetVertexBuffer(); void shutdown(); // Refreshes renderer state to the cached values // Needed when the render context has changed and invalidated the current state void refreshState(void); - void resetVertexBuffers(); - void restoreVertexBuffers(); - void translatef(const GLfloat& x, const GLfloat& y, const GLfloat& z); void scalef(const GLfloat& x, const GLfloat& y, const GLfloat& z); //rotatef requires generation of a transform matrix involving sine/cosine. If rotating by a constant value, use genRot, store the result in a static variable, and pass that var to rotatef. @@ -448,8 +441,6 @@ class LLRender void setColorMask(bool writeColorR, bool writeColorG, bool writeColorB, bool writeAlpha); void setSceneBlendType(eBlendType type); - void setAlphaRejectSettings(eCompareFunc func, F32 value = 0.01f); - // applies blend func to both color and alpha void blendFunc(eBlendFactor sfactor, eBlendFactor dfactor); // applies separate blend functions to color and alpha @@ -502,8 +493,6 @@ class LLRender U32 mMode; U32 mCurrTextureUnitIndex; bool mCurrColorMask[4]; - eCompareFunc mCurrAlphaFunc; - F32 mCurrAlphaFuncVal; F32 mLineWidth; LLPointer<LLVertexBuffer> mBuffer; @@ -532,7 +521,7 @@ extern LLMatrix4a gGLLastProjection; extern LLMatrix4a gGLProjection; extern S32 gGLViewport[4]; -extern LLRender gGL; +extern thread_local LLRender gGL; // This rotation matrix moves the default OpenGL reference frame // (-Z at, Y up) to Cory's favorite reference frame (X at, Z up) diff --git a/indra/llrender/llrender2dutils.cpp b/indra/llrender/llrender2dutils.cpp index a4bf1d22bbb1ef0ac457e358a3a6e135f0ca4a8d..6a6a70e8beebb1c5fd0c01c6cd48d7eb921ba425 100644 --- a/indra/llrender/llrender2dutils.cpp +++ b/indra/llrender/llrender2dutils.cpp @@ -134,40 +134,15 @@ void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, BOOL filled ) } else { - if( gGLManager.mATIOffsetVerticalLines ) - { - // Work around bug in ATI driver: vertical lines are offset by (-1,-1) - gGL.begin( LLRender::LINES ); - - // Verticals - gGL.vertex2i(left + 1, top); - gGL.vertex2i(left + 1, bottom); - - gGL.vertex2i(right, bottom); - gGL.vertex2i(right, top); - - // Horizontals - top--; - right--; - gGL.vertex2i(left, bottom); - gGL.vertex2i(right, bottom); - - gGL.vertex2i(left, top); - gGL.vertex2i(right, top); - gGL.end(); - } - else - { - top--; - right--; - gGL.begin( LLRender::LINE_STRIP ); - gGL.vertex2i(left, top); - gGL.vertex2i(left, bottom); - gGL.vertex2i(right, bottom); - gGL.vertex2i(right, top); - gGL.vertex2i(left, top); - gGL.end(); - } + top--; + right--; + gGL.begin( LLRender::LINE_STRIP ); + gGL.vertex2i(left, top); + gGL.vertex2i(left, bottom); + gGL.vertex2i(right, bottom); + gGL.vertex2i(right, top); + gGL.vertex2i(left, top); + gGL.end(); } stop_glerror(); } @@ -263,15 +238,6 @@ void gl_drop_shadow(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &st void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2 ) { - // Work around bug in ATI driver: vertical lines are offset by (-1,-1) - if( (x1 == x2) && gGLManager.mATIOffsetVerticalLines ) - { - x1++; - x2++; - y1++; - y2++; - } - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); gGL.begin(LLRender::LINES); @@ -282,15 +248,6 @@ void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2 ) void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2, const LLColor4 &color ) { - // Work around bug in ATI driver: vertical lines are offset by (-1,-1) - if( (x1 == x2) && gGLManager.mATIOffsetVerticalLines ) - { - x1++; - x2++; - y1++; - y2++; - } - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); gGL.color4fv( color.mV ); @@ -408,15 +365,7 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTex if (solid_color) { - if (LLGLSLShader::sNoFixedFunction) - { - gSolidColorProgram.bind(); - } - else - { - gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR); - gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_ALPHA, LLTexUnit::TBS_VERT_ALPHA); - } + gSolidColorProgram.bind(); } if (center_rect.mLeft == 0.f @@ -633,14 +582,7 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTex if (solid_color) { - if (LLGLSLShader::sNoFixedFunction) - { - gUIProgram.bind(); - } - else - { - gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); - } + gUIProgram.bind(); } } @@ -757,10 +699,6 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase ) { - phase = fmod(phase, 1.f); - - S32 shift = S32(phase * 4.f) % 4; - // Stippled line LLGLEnable stipple(GL_LINE_STIPPLE); @@ -769,11 +707,6 @@ void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LL gGL.flush(); gGL.setLineWidth(2.5f); - if (!LLGLSLShader::sNoFixedFunction) - { - glLineStipple(2, 0x3333 << shift); - } - gGL.begin(LLRender::LINES); { gGL.vertex3fv( start.mV ); @@ -913,52 +846,16 @@ void gl_ring( F32 radius, F32 width, const LLColor4& center_color, const LLColor // Draw gray and white checkerboard with black border void gl_rect_2d_checkerboard(const LLRect& rect, GLfloat alpha) { - if (!LLGLSLShader::sNoFixedFunction) - { - // Initialize the first time this is called. - const S32 PIXELS = 32; - static GLubyte checkerboard[PIXELS * PIXELS]; - static BOOL first = TRUE; - if( first ) - { - for( S32 i = 0; i < PIXELS; i++ ) - { - for( S32 j = 0; j < PIXELS; j++ ) - { - checkerboard[i * PIXELS + j] = ((i & 1) ^ (j & 1)) * 0xFF; - } - } - first = FALSE; - } - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - // ...white squares - gGL.color4f( 1.f, 1.f, 1.f, alpha ); - gl_rect_2d(rect); - - // ...gray squares - gGL.color4f( .7f, .7f, .7f, alpha ); - gGL.flush(); + //polygon stipple is deprecated, use "Checker" texture + LLPointer<LLUIImage> img = LLRender2D::getInstance()->getUIImage("Checker"); + gGL.getTexUnit(0)->bind(img->getImage()); + gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_WRAP); + gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); - glPolygonStipple( checkerboard ); + LLColor4 color(1.f, 1.f, 1.f, alpha); + LLRectf uv_rect(0, 0, rect.getWidth()/32.f, rect.getHeight()/32.f); - LLGLEnable polygon_stipple(GL_POLYGON_STIPPLE); - gl_rect_2d(rect); - } - else - { //polygon stipple is deprecated, use "Checker" texture - LLUIImagePtr img = LLRender2D::getInstanceFast()->getUIImage("Checker"); - gGL.getTexUnit(0)->bind(img->getImage()); - gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_WRAP); - gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); - - LLColor4 color(1.f, 1.f, 1.f, alpha); - LLRectf uv_rect(0, 0, rect.getWidth()/32.f, rect.getHeight()/32.f); - - gl_draw_scaled_image(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(), - img->getImage(), color, uv_rect); - } + gl_draw_scaled_image(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(), img->getImage(), color, uv_rect); gGL.flush(); } @@ -1070,8 +967,6 @@ void gl_rect_2d_simple( S32 width, S32 height ) gGL.end(); } -static LLTrace::BlockTimerStatHandle FTM_RENDER_SEGMENTED_RECT ("Render segmented rectangle"); - void gl_segmented_rect_2d_tex(const S32 left, const S32 top, const S32 right, @@ -1081,7 +976,7 @@ void gl_segmented_rect_2d_tex(const S32 left, const S32 border_size, const U32 edges) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_SEGMENTED_RECT); + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; S32 width = llabs(right - left); S32 height = llabs(top - bottom); @@ -1211,7 +1106,7 @@ void gl_segmented_rect_2d_fragment_tex(const LLRect& rect, const F32 end_fragment, const U32 edges) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_SEGMENTED_RECT); + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; const S32 left = rect.mLeft; const S32 right = rect.mRight; const S32 top = rect.mTop; @@ -1368,7 +1263,7 @@ void gl_segmented_rect_2d_fragment_tex(const LLRect& rect, void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv_rect, const LLRectf& center_draw_rect, const LLVector3& width_vec, const LLVector3& height_vec) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_SEGMENTED_RECT); + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; gGL.begin(LLRender::TRIANGLE_STRIP); { diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp index 5c6d7d37646bfc7947aae63b62a0b468ca9c71ec..fe6dbb981283b7a48a877ddb518f85c406b315e7 100644 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -135,7 +135,7 @@ bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, boo mUsage = usage; mUseDepth = depth; - if ((sUseFBO || use_fbo) && gGLManager.mHasFramebufferObject) + if (sUseFBO || use_fbo) { if (depth) { @@ -172,6 +172,53 @@ bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, boo return addColorAttachment(color_fmt, pix_format, pix_type); } +void LLRenderTarget::setColorAttachment(LLImageGL* img, LLGLuint use_name) +{ + LL_PROFILE_ZONE_SCOPED; + llassert(img != nullptr); // img must not be null + llassert(sUseFBO); // FBO support must be enabled + llassert(mDepth == 0); // depth buffers not supported with this mode + llassert(mTex.empty()); // mTex must be empty with this mode (binding target should be done via LLImageGL) + + if (mFBO == 0) + { + glGenFramebuffers(1, (GLuint*)&mFBO); + } + + mResX = img->getWidth(); + mResY = img->getHeight(); + mUsage = img->getTarget(); + + if (use_name == 0) + { + use_name = img->getTexName(); + } + + mTex.push_back(use_name); + + glBindFramebuffer(GL_FRAMEBUFFER, mFBO); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + LLTexUnit::getInternalType(mUsage), use_name, 0); + stop_glerror(); + + check_framebuffer_status(); + + glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO); +} + +void LLRenderTarget::releaseColorAttachment() +{ + LL_PROFILE_ZONE_SCOPED; + llassert(mTex.size() == 1); //cannot use releaseColorAttachment with LLRenderTarget managed color targets + llassert(mFBO != 0); // mFBO must be valid + + glBindFramebuffer(GL_FRAMEBUFFER, mFBO); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, LLTexUnit::getInternalType(mUsage), 0, 0); + glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO); + + mTex.clear(); +} + bool LLRenderTarget::addColorAttachment(U32 color_fmt, U32 pix_format, U32 pix_type) { if (color_fmt == 0) @@ -425,11 +472,13 @@ void LLRenderTarget::bindTarget() GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3}; + LL_PROFILER_GPU_ZONEC( "gl.DrawBuffersARB", 0x4000FF ) glDrawBuffers(mTex.size(), drawbuffers); } if (mTex.empty()) { //no color buffer to draw to + LL_PROFILER_GPU_ZONEC( "gl.DrawBuffer", 0x0000FF ) glDrawBuffer(GL_NONE); glReadBuffer(GL_NONE); } diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h index 0f58b8805ceec87b6a807f56157b62e1b8a19f89..d5bf7203a0bf0fb1911e349d9ad0859f7c25d6a4 100644 --- a/indra/llrender/llrendertarget.h +++ b/indra/llrender/llrendertarget.h @@ -81,6 +81,24 @@ class LLRenderTarget // DO use for render targets that resize often and aren't likely to ruin someone's day if they break void resize(U32 resx, U32 resy); + //point this render target at a particular LLImageGL + // Intended usage: + // LLRenderTarget target; + // target.addColorAttachment(image); + // target.bindTarget(); + // < issue GL calls> + // target.flush(); + // target.releaseColorAttachment(); + // + // attachment -- LLImageGL to render into + // use_name -- optional texture name to target instead of attachment->getTexName() + // NOTE: setColorAttachment and releaseColorAttachment cannot be used in conjuction with + // addColorAttachment, allocateDepth, resize, etc. + void setColorAttachment(LLImageGL* attachment, LLGLuint use_name = 0); + + // detach from current color attachment + void releaseColorAttachment(); + //add color buffer attachment //limit of 4 color attachments per render target bool addColorAttachment(U32 color_fmt, U32 pix_format = GL_RGBA, U32 pix_type = GL_UNSIGNED_BYTE); diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 14957a72442a7e87917576848d49e1ba8db4972b..e7b94245a5746dd73922c7bdd8b55f888df4d65b 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -152,6 +152,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader) if (features->hasObjectSkinning) { + shader->mRiggedVariant = shader; if (!shader->attachVertexObject("avatar/objectSkinV.glsl")) { return FALSE; @@ -596,7 +597,7 @@ void LLShaderMgr::dumpObjectLog(bool is_program, GLuint ret, BOOL warns, const s } } -GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, boost::unordered_map<std::string, std::string>* defines, S32 texture_index_channels) +GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, std::unordered_map<std::string, std::string>* defines, S32 texture_index_channels) { // endsure work-around for missing GLSL funcs gets propogated to feature shader files (e.g. srgbF.glsl) @@ -661,7 +662,7 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev if (file == NULL) { - LL_SHADER_LOADING_WARNS() << "GLSL Shader file not found: " << open_file_name << LL_ENDL; + LL_WARNS("ShaderLoading") << "GLSL Shader file not found: " << open_file_name << LL_ENDL; return 0; } @@ -792,14 +793,14 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev if (defines) { - for (boost::unordered_map<std::string,std::string>::iterator iter = defines->begin(); iter != defines->end(); ++iter) + for (std::unordered_map<std::string,std::string>::iterator iter = defines->begin(); iter != defines->end(); ++iter) { std::string define = "#define " + iter->first + " " + iter->second + "\n"; extra_code_text[extra_code_count++] = (GLchar*) strdup(define.c_str()); } } - if( gGLManager.mIsATI ) + if( gGLManager.mIsAMD ) { extra_code_text[extra_code_count++] = strdup( "#define IS_AMD_CARD 1\n" ); } @@ -1071,43 +1072,6 @@ BOOL LLShaderMgr::linkProgramObject(GLuint obj, BOOL suppress_errors) LL_SHADER_LOADING_WARNS() << "GLSL Linker Error:" << LL_ENDL; } -#if LL_DARWIN - - // For some reason this absolutely kills the frame rate when VBO's are enabled - /*if (0) - { - // Force an evaluation of the gl state so the driver can tell if the shader will run in hardware or software - // per Apple's suggestion - LLGLSLShader::sNoFixedFunction = false; - - glUseProgram(obj); - - gGL.begin(LLRender::TRIANGLES); - gGL.vertex3f(0.0f, 0.0f, 0.0f); - gGL.vertex3f(0.0f, 0.0f, 0.0f); - gGL.vertex3f(0.0f, 0.0f, 0.0f); - gGL.end(); - gGL.flush(); - - glUseProgram(0); - - LLGLSLShader::sNoFixedFunction = true; - - // Query whether the shader can or cannot run in hardware - // http://developer.apple.com/qa/qa2007/qa1502.html - GLint vertexGPUProcessing, fragmentGPUProcessing; - CGLContextObj ctx = CGLGetCurrentContext(); - CGLGetParameter(ctx, kCGLCPGPUVertexProcessing, &vertexGPUProcessing); - CGLGetParameter(ctx, kCGLCPGPUFragmentProcessing, &fragmentGPUProcessing); - if (!fragmentGPUProcessing || !vertexGPUProcessing) - { - LL_SHADER_LOADING_WARNS() << "GLSL Linker: Running in Software:" << LL_ENDL; - success = GL_FALSE; - suppress_errors = FALSE; - } - }*/ - -#else std::string log = get_program_log(obj); LLStringUtil::toLower(log); if (log.find("software") != std::string::npos) @@ -1116,7 +1080,6 @@ BOOL LLShaderMgr::linkProgramObject(GLuint obj, BOOL suppress_errors) success = GL_FALSE; suppress_errors = FALSE; } -#endif return success; } diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index 760f2200f9d33823e21c5cd42659a82e0410424a..aaee8c3bcf454c1941213e70386730d8d012b8b9 100644 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -244,7 +244,7 @@ class LLShaderMgr void dumpShaderSource(U32 shader_code_count, GLchar** shader_code_text); BOOL linkProgramObject(GLuint obj, BOOL suppress_errors = FALSE); BOOL validateProgramObject(GLuint obj); - GLuint loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, boost::unordered_map<std::string, std::string>* defines = NULL, S32 texture_index_channels = -1); + GLuint loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, std::unordered_map<std::string, std::string>* defines = NULL, S32 texture_index_channels = -1); // Implemented in the application to actually point to the shader directory. virtual std::string getShaderDirPrefix(void) = 0; // Pure Virtual diff --git a/indra/llrender/lltexture.h b/indra/llrender/lltexture.h index 41ef6030eedaf6b4ef3fe541f27089ff58dbeb47..321c509bd806465ef359ffb39cec48ee259dca7e 100644 --- a/indra/llrender/lltexture.h +++ b/indra/llrender/lltexture.h @@ -42,7 +42,7 @@ class LLFontGL ; // //this is an abstract class as the parent for the class LLGLTexture // -class LLTexture : public virtual LLRefCount, public LLTrace::MemTrackable<LLTexture> +class LLTexture : public virtual LLRefCount { friend class LLTexUnit ; friend class LLFontGL ; @@ -52,7 +52,6 @@ class LLTexture : public virtual LLRefCount, public LLTrace::MemTrackable<LLText public: LLTexture() - : LLTrace::MemTrackable<LLTexture>("LLTexture") {} // @@ -67,11 +66,9 @@ class LLTexture : public virtual LLRefCount, public LLTrace::MemTrackable<LLText virtual S32 getWidth(S32 discard_level = -1) const; virtual S32 getHeight(S32 discard_level = -1) const; virtual bool isActiveFetching(); + virtual LLImageGL* getGLTexture() const; private: - //note: do not make this function public. - virtual LLImageGL* getGLTexture() const; - virtual void updateBindStatsForTester(); }; #endif diff --git a/indra/llrender/lluiimage.cpp b/indra/llrender/lluiimage.cpp index 1f555cbed39e79f950656edfcc34411670570f2d..db6b1c0c7bb2f353bc74d496e65d2bb07126c595 100644 --- a/indra/llrender/lluiimage.cpp +++ b/indra/llrender/lluiimage.cpp @@ -138,7 +138,7 @@ namespace LLInitParam return; } - LLUIImage* imagep = LLRender2D::getInstanceFast()->getUIImage(name()); + LLUIImage* imagep = LLRender2D::getInstance()->getUIImage(name()); if (imagep) { updateValue(imagep); diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 803af79dfba6a32d778ece57bee1b162e34b51f0..7897b7393de1f712b4f33248d35a78f2e6296043 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -92,6 +92,8 @@ LLVBOPool LLVertexBuffer::sDynamicIBOPool(GL_DYNAMIC_DRAW, GL_ELEMENT_ARRAY_BUFF U64 LLVBOPool::sBytesPooled = 0; U64 LLVBOPool::sIndexBytesPooled = 0; +U32 LLVBOPool::sNameIdx = 0; +U32 LLVBOPool::sNamePool[1024]; std::vector<U32> LLVBOPool::sPendingDeletions; std::vector<U32> LLVertexBuffer::sAvailableVAOName; @@ -194,16 +196,20 @@ void clean_validate_buffers() U32 LLVBOPool::genBuffer() { - U32 ret = 0; + LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX - glGenBuffers(1, &ret); - validate_add_buffer(ret); - - return ret; + if (sNameIdx == 0) + { + glGenBuffersARB(1024, sNamePool); + sNameIdx = 1024; + } + + return sNamePool[--sNameIdx]; } void LLVBOPool::deleteBuffer(U32 name) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX if (gGLManager.mInited) { //LLVertexBuffer::unbind(); @@ -234,6 +240,7 @@ LLVBOPool::LLVBOPool(U32 vboUsage, U32 vboType) U8* LLVBOPool::allocate(U32& name, U32 size, U32 seed) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX llassert(vbo_block_size(size) == size); U8* ret = nullptr; @@ -356,8 +363,10 @@ void LLVBOPool::release(U32 name, U8* buffer, U32 size) void LLVBOPool::seedPool() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX if (mMissCountDirty) { + LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("VBOPool Resize"); U32 dummy_name = 0; static std::vector< U32 > sizes; @@ -532,6 +541,7 @@ void LLVertexBuffer::releaseVAOName(U32 name) //static void LLVertexBuffer::seedPools() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX sStreamVBOPool.seedPool(); sDynamicVBOPool.seedPool(); sStreamIBOPool.seedPool(); @@ -550,135 +560,26 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask) data_mask = data_mask & ~MAP_TEXTURE_INDEX; } - if (LLGLSLShader::sNoFixedFunction) + for (U32 i = 0; i < TYPE_MAX; ++i) { - for (U32 i = 0; i < TYPE_MAX; ++i) - { - S32 loc = i; + S32 loc = i; - U32 mask = 1 << i; - - if (sLastMask & (1 << i)) - { //was enabled - if (!(data_mask & mask)) - { //needs to be disabled - glDisableVertexAttribArray(loc); - } - } - else - { //was disabled - if (data_mask & mask) - { //needs to be enabled - glEnableVertexAttribArray(loc); - } - } - } - } - else - { - - static const GLenum array[] = - { - GL_VERTEX_ARRAY, - GL_NORMAL_ARRAY, - GL_TEXTURE_COORD_ARRAY, - GL_COLOR_ARRAY, - }; - - static const GLenum mask[] = - { - MAP_VERTEX, - MAP_NORMAL, - MAP_TEXCOORD0, - MAP_COLOR - }; - - - - for (U32 i = 0; i < 4; ++i) - { - if (sLastMask & mask[i]) - { //was enabled - if (!(data_mask & mask[i])) - { //needs to be disabled - glDisableClientState(array[i]); - } - else if (gDebugGL) - { //needs to be enabled, make sure it was (DEBUG) - if (!glIsEnabled(array[i])) - { - if (gDebugSession) - { - gFailLog << "Bad client state! " << array[i] << " disabled." << std::endl; - } - else - { - LL_ERRS() << "Bad client state! " << array[i] << " disabled." << LL_ENDL; - } - } - } - } - else - { //was disabled - if (data_mask & mask[i]) - { //needs to be enabled - glEnableClientState(array[i]); - } - else if (gDebugGL && glIsEnabled(array[i])) - { //needs to be disabled, make sure it was (DEBUG TEMPORARY) - if (gDebugSession) - { - gFailLog << "Bad client state! " << array[i] << " enabled." << std::endl; - } - else - { - LL_ERRS() << "Bad client state! " << array[i] << " enabled." << LL_ENDL; - } - } - } - } - - static const U32 map_tc[] = - { - MAP_TEXCOORD1, - MAP_TEXCOORD2, - MAP_TEXCOORD3 - }; + U32 mask = 1 << i; - for (U32 i = 0; i < 3; i++) - { - if (sLastMask & map_tc[i]) - { - if (!(data_mask & map_tc[i])) - { //disable - glClientActiveTexture(GL_TEXTURE1+i); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glClientActiveTexture(GL_TEXTURE0); - } - } - else if (data_mask & map_tc[i]) - { - glClientActiveTexture(GL_TEXTURE1+i); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glClientActiveTexture(GL_TEXTURE0); + if (sLastMask & (1 << i)) + { //was enabled + if (!(data_mask & mask)) + { //needs to be disabled + glDisableVertexAttribArray(loc); } } - - if (sLastMask & MAP_TANGENT) - { - if (!(data_mask & MAP_TANGENT)) - { - glClientActiveTexture(GL_TEXTURE2); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glClientActiveTexture(GL_TEXTURE0); + else + { //was disabled + if (data_mask & mask) + { //needs to be enabled + glEnableVertexAttribArray(loc); } } - else if (data_mask & MAP_TANGENT) - { - glClientActiveTexture(GL_TEXTURE2); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glClientActiveTexture(GL_TEXTURE0); - } } sLastMask = data_mask; @@ -686,101 +587,55 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask) } //static -static LLTrace::BlockTimerStatHandle FTM_VB_DRAW_ARRAYS("drawArrays"); -void LLVertexBuffer::drawArrays(U32 mode, const std::vector<LLVector3>& pos, const std::vector<LLVector3>& norm) +void LLVertexBuffer::drawArrays(U32 mode, const std::vector<LLVector3>& pos) { - //LL_RECORD_BLOCK_TIME(FTM_VB_DRAW_ARRAYS); - llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL); - gGL.syncMatrices(); - - U32 count = pos.size(); - - llassert(norm.size() >= pos.size()); - llassert(count > 0); - - if( count == 0 ) - { - LL_WARNS() << "Called drawArrays with 0 vertices" << LL_ENDL; - return; - } - - if( norm.size() < pos.size() ) - { - LL_WARNS() << "Called drawArrays with #" << norm.size() << " normals and #" << pos.size() << " vertices" << LL_ENDL; - return; - } - - if (!sUtilityBuffer) - { - sUtilityBuffer = new LLVertexBuffer(MAP_VERTEX | MAP_NORMAL | MAP_TEXCOORD0, GL_STREAM_DRAW); - sUtilityBuffer->allocateBuffer(count, count, true); - } - if (sUtilityBuffer->getNumVerts() < (S32) count) - { - sUtilityBuffer->resizeBuffer(count, count); - } - - LLStrider<LLVector3> vertex_strider; - LLStrider<LLVector3> normal_strider; - sUtilityBuffer->getVertexStrider(vertex_strider); - sUtilityBuffer->getNormalStrider(normal_strider); - vertex_strider.copyArray(0, pos.data(), count); - normal_strider.copyArray(0, norm.data(), count); - - sUtilityBuffer->setBuffer(MAP_VERTEX | MAP_NORMAL); - sUtilityBuffer->drawArrays(mode, 0, pos.size()); + LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX; + gGL.begin(mode); + for (auto& v : pos) + { + gGL.vertex3fv(v.mV); + } + gGL.end(); + gGL.flush(); } //static -void LLVertexBuffer::drawElements(U32 mode, const S32 num_vertices, const LLVector4a* pos, const LLVector2* tc, S32 num_indices, const U16* indicesp) +void LLVertexBuffer::drawElements(U32 mode, const LLVector4a* pos, const LLVector2* tc, S32 num_indices, const U16* indicesp) { - llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL); - - if (num_vertices <= 0) - { - LL_WARNS() << "Called drawElements with 0 vertices" << LL_ENDL; - return; - } - - if (num_indices <= 0) - { - LL_WARNS() << "Called drawElements with 0 indices" << LL_ENDL; - return; - } + LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX; + llassert(LLGLSLShader::sCurBoundShaderPtr != NULL); gGL.syncMatrices(); - if (!sUtilityBuffer) - { - sUtilityBuffer = new LLVertexBuffer(MAP_VERTEX | MAP_NORMAL | MAP_TEXCOORD0, GL_STREAM_DRAW); - sUtilityBuffer->allocateBuffer(num_vertices, num_indices, true); - } - if (sUtilityBuffer->getNumVerts() < num_vertices || sUtilityBuffer->getNumIndices() < num_indices) - { - sUtilityBuffer->resizeBuffer(llmax(sUtilityBuffer->getNumVerts(), num_vertices), llmax(sUtilityBuffer->getNumIndices(), num_indices)); - } - U32 mask = LLVertexBuffer::MAP_VERTEX; - - LLStrider<U16> index_strider; - LLStrider<LLVector4a> vertex_strider; - sUtilityBuffer->getIndexStrider(index_strider); - sUtilityBuffer->getVertexStrider(vertex_strider); - const S32 index_size = ((num_indices * sizeof(U16)) + 0xF) & ~0xF; - const S32 vertex_size = ((num_vertices * 4 * sizeof(F32)) + 0xF) & ~0xF; - LLVector4a::memcpyNonAliased16((F32*)index_strider.get(), (F32*)indicesp, index_size); - LLVector4a::memcpyNonAliased16((F32*)vertex_strider.get(), (F32*)pos, vertex_size); if (tc) { mask = mask | LLVertexBuffer::MAP_TEXCOORD0; - LLStrider<LLVector2> tc_strider; - sUtilityBuffer->getTexCoord0Strider(tc_strider); - const S32 tc_size = ((num_vertices * 2 * sizeof(F32)) + 0xF) & ~0xF; - LLVector4a::memcpyNonAliased16((F32*)tc_strider.get(), (F32*)tc, tc_size); } - sUtilityBuffer->setBuffer(mask); - sUtilityBuffer->draw(mode, num_indices, 0); + unbind(); + + gGL.begin(mode); + + if (tc != nullptr) + { + for (int i = 0; i < num_indices; ++i) + { + U16 idx = indicesp[i]; + gGL.texCoord2fv(tc[idx].mV); + gGL.vertex3fv(pos[idx].getF32ptr()); + } + } + else + { + for (int i = 0; i < num_indices; ++i) + { + U16 idx = indicesp[i]; + gGL.vertex3fv(pos[idx].getF32ptr()); + } + } + gGL.end(); + gGL.flush(); } void LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_offset) const @@ -845,7 +700,7 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi gGL.syncMatrices(); llassert(mNumVerts >= 0); - llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL); + llassert(LLGLSLShader::sCurBoundShaderPtr != NULL); if (mGLArray) { @@ -888,6 +743,7 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi stop_glerror(); LLGLSLShader::startProfile(); + LL_PROFILER_GPU_ZONEC( "gl.DrawRangeElements", 0xFFFF00 ) glDrawRangeElements(sGLMode[mode], start, end, count, GL_UNSIGNED_SHORT, idx); LLGLSLShader::stopProfile(count, mode); @@ -898,9 +754,21 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi placeFence(); } +void LLVertexBuffer::drawRangeFast(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const +{ + mMappable = false; + gGL.syncMatrices(); + + U16* idx = ((U16*)getIndicesPointer()) + indices_offset; + + LL_PROFILER_GPU_ZONEC("gl.DrawRangeElements", 0xFFFF00) + glDrawRangeElements(sGLMode[mode], start, end, count, GL_UNSIGNED_SHORT, + idx); +} + void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const { - llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL); + llassert(LLGLSLShader::sCurBoundShaderPtr != NULL); mMappable = false; gGL.syncMatrices(); @@ -939,6 +807,7 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const stop_glerror(); LLGLSLShader::startProfile(); + LL_PROFILER_GPU_ZONEC( "gl.DrawElements", 0xA0FFA0 ) glDrawElements(sGLMode[mode], count, GL_UNSIGNED_SHORT, ((U16*) getIndicesPointer()) + indices_offset); LLGLSLShader::stopProfile(count, mode); @@ -946,53 +815,53 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const placeFence(); } -static LLTrace::BlockTimerStatHandle FTM_GL_DRAW_ARRAYS("GL draw arrays"); + void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const { - llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL); - mMappable = false; - gGL.syncMatrices(); - - llassert(mNumVerts >= 0); - if (first >= (U32) mNumVerts || - first + count > (U32) mNumVerts) - { - LL_ERRS() << "Bad vertex buffer draw range: [" << first << ", " << first+count << "]" << LL_ENDL; - } + LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX; + llassert(LLGLSLShader::sCurBoundShaderPtr != NULL); + mMappable = false; + gGL.syncMatrices(); + +#ifndef LL_RELEASE_FOR_DOWNLOAD + llassert(mNumVerts >= 0); + if (first >= (U32)mNumVerts || + first + count > (U32)mNumVerts) + { + LL_ERRS() << "Bad vertex buffer draw range: [" << first << ", " << first + count << "]" << LL_ENDL; + } - if (mGLArray) - { - if (mGLArray != sGLRenderArray) - { - LL_ERRS() << "Wrong vertex array bound." << LL_ENDL; - } - } - else - { - if (mGLBuffer != sGLRenderBuffer || useVBOs() != sVBOActive) - { - LL_ERRS() << "Wrong vertex buffer bound." << LL_ENDL; - } - } + if (mGLArray) + { + if (mGLArray != sGLRenderArray) + { + LL_ERRS() << "Wrong vertex array bound." << LL_ENDL; + } + } + else + { + if (mGLBuffer != sGLRenderBuffer || useVBOs() != sVBOActive) + { + LL_ERRS() << "Wrong vertex buffer bound." << LL_ENDL; + } + } - if (mode >= LLRender::NUM_MODES) - { - LL_ERRS() << "Invalid draw mode: " << mode << LL_ENDL; - return; - } + if (mode >= LLRender::NUM_MODES) + { + LL_ERRS() << "Invalid draw mode: " << mode << LL_ENDL; + return; + } +#endif - { - //LL_RECORD_BLOCK_TIME(FTM_GL_DRAW_ARRAYS); - stop_glerror(); - LLGLSLShader::startProfile(); - stop_glerror(); - glDrawArrays(sGLMode[mode], first, count); - stop_glerror(); - LLGLSLShader::stopProfile(count, mode); - } + LLGLSLShader::startProfile(); + { + LL_PROFILER_GPU_ZONEC("gl.DrawArrays", 0xFF4040) + glDrawArrays(sGLMode[mode], first, count); + } + LLGLSLShader::stopProfile(count, mode); - stop_glerror(); - placeFence(); + stop_glerror(); + placeFence(); } //static @@ -1127,8 +996,7 @@ S32 LLVertexBuffer::determineUsage(S32 usage) } LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) -: LLTrace::MemTrackable<LLVertexBuffer>("LLVertexBuffer"), - LLRefCount(), +: LLRefCount(), mNumVerts(0), mNumIndices(0), @@ -1276,9 +1144,7 @@ void LLVertexBuffer::waitFence() const void LLVertexBuffer::genBuffer(U32 size) { - disclaimMem(mSize); mSize = vbo_block_size(size); - claimMem(mSize); if (mUsage == GL_STREAM_DRAW) { @@ -1344,7 +1210,7 @@ void LLVertexBuffer::releaseIndices() bool LLVertexBuffer::createGLBuffer(U32 size) { - if (mGLBuffer) + if (mGLBuffer || mMappedData) { destroyGLBuffer(); } @@ -1370,9 +1236,7 @@ bool LLVertexBuffer::createGLBuffer(U32 size) static int gl_buffer_idx = 0; mGLBuffer = ++gl_buffer_idx; mMappedData = (U8*)ll_aligned_malloc_16(size); - disclaimMem(mSize); mSize = size; - claimMem(mSize); } if (!mMappedData) @@ -1544,8 +1408,6 @@ bool LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create) return success; } -static LLTrace::BlockTimerStatHandle FTM_SETUP_VERTEX_ARRAY("Setup VAO"); - void LLVertexBuffer::setupVertexArray() { if (!mGLArray) @@ -1553,7 +1415,7 @@ void LLVertexBuffer::setupVertexArray() return; } - LL_RECORD_BLOCK_TIME(FTM_SETUP_VERTEX_ARRAY); + LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX; #if GL_ARB_vertex_array_object glBindVertexArray(mGLArray); #endif @@ -1726,12 +1588,11 @@ bool expand_region(LLVertexBuffer::MappedRegion& region, U32 offset, U32 length) return true; } -static LLTrace::BlockTimerStatHandle FTM_VBO_MAP_BUFFER_RANGE("VBO Map Range"); -static LLTrace::BlockTimerStatHandle FTM_VBO_MAP_BUFFER("VBO Map"); // Map for data access U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX; bindGLBuffer(true); if (mFinal) { @@ -1806,14 +1667,13 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran } else { - U8* src = nullptr; + U8* src = NULL; waitFence(); if (gGLManager.mHasMapBufferRange) { if (map_range) { #ifdef GL_ARB_map_buffer_range - LL_RECORD_BLOCK_TIME(FTM_VBO_MAP_BUFFER_RANGE); S32 offset = mOffsets[type] + sTypeSize[type]*index; S32 length = (sTypeSize[type]*count+0xF) & ~0xF; src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER, offset, length, @@ -1837,7 +1697,6 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran } } - LL_RECORD_BLOCK_TIME(FTM_VBO_MAP_BUFFER); src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER, 0, mSize, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT); @@ -1923,11 +1782,9 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran } -static LLTrace::BlockTimerStatHandle FTM_VBO_MAP_INDEX_RANGE("IBO Map Range"); -static LLTrace::BlockTimerStatHandle FTM_VBO_MAP_INDEX("IBO Map"); - U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX; bindGLIndices(true); if (mFinal) { @@ -2020,7 +1877,6 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) if (map_range) { #ifdef GL_ARB_map_buffer_range - LL_RECORD_BLOCK_TIME(FTM_VBO_MAP_INDEX_RANGE); S32 offset = sizeof(U16)*index; S32 length = sizeof(U16)*count; src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, offset, length, @@ -2032,7 +1888,6 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) else { #ifdef GL_ARB_map_buffer_range - LL_RECORD_BLOCK_TIME(FTM_VBO_MAP_INDEX); src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(U16)*mNumIndices, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT); @@ -2056,7 +1911,6 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) } else { - LL_RECORD_BLOCK_TIME(FTM_VBO_MAP_INDEX); map_range = false; src = (U8*) glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY); } @@ -2107,13 +1961,6 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) } } -static LLTrace::BlockTimerStatHandle FTM_VBO_UNMAP("VBO Unmap"); -static LLTrace::BlockTimerStatHandle FTM_VBO_FLUSH_RANGE("Flush VBO Range"); - - -static LLTrace::BlockTimerStatHandle FTM_IBO_UNMAP("IBO Unmap"); -static LLTrace::BlockTimerStatHandle FTM_IBO_FLUSH_RANGE("Flush IBO Range"); - void LLVertexBuffer::unmapBuffer() { if (!useVBOs()) @@ -2122,10 +1969,10 @@ void LLVertexBuffer::unmapBuffer() } bool updated_all = false; - + LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX; if (mMappedData && mVertexLocked) { - LL_RECORD_BLOCK_TIME(FTM_VBO_UNMAP); + LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("unmapBuffer - vertex"); bindGLBuffer(true); updated_all = mIndexLocked; //both vertex and index buffers done updating @@ -2168,7 +2015,7 @@ void LLVertexBuffer::unmapBuffer() { if (!mMappedVertexRegions.empty()) { - stop_glerror(); + LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("unmapBuffer - flush vertex"); for (U32 i = 0; i < mMappedVertexRegions.size(); ++i) { const MappedRegion& region = mMappedVertexRegions[i]; @@ -2176,18 +2023,16 @@ void LLVertexBuffer::unmapBuffer() U32 length = region.mLength; if (gGLManager.mHasMapBufferRange) { - LL_RECORD_BLOCK_TIME(FTM_VBO_FLUSH_RANGE); #ifdef GL_ARB_map_buffer_range glFlushMappedBufferRange(GL_ARRAY_BUFFER, offset, length); #endif } else if (gGLManager.mHasFlushBufferRange) - { + { #ifndef LL_MESA_HEADLESS glFlushMappedBufferRangeAPPLE(GL_ARRAY_BUFFER, offset, length); #endif } - stop_glerror(); } mMappedVertexRegions.clear(); @@ -2206,7 +2051,7 @@ void LLVertexBuffer::unmapBuffer() if (mMappedIndexData && mIndexLocked) { - LL_RECORD_BLOCK_TIME(FTM_IBO_UNMAP); + LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("unmapBuffer - index"); bindGLIndices(); if(!mMappable) { @@ -2248,12 +2093,12 @@ void LLVertexBuffer::unmapBuffer() { for (U32 i = 0; i < mMappedIndexRegions.size(); ++i) { + LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("unmapBuffer - flush index"); const MappedRegion& region = mMappedIndexRegions[i]; U32 offset = region.mOffset; U32 length = region.mLength; if (gGLManager.mHasMapBufferRange) { - LL_RECORD_BLOCK_TIME(FTM_IBO_FLUSH_RANGE); #ifdef GL_ARB_map_buffer_range glFlushMappedBufferRange(GL_ELEMENT_ARRAY_BUFFER, offset, length); #endif @@ -2272,9 +2117,8 @@ void LLVertexBuffer::unmapBuffer() mMappedIndexRegions.clear(); } } - stop_glerror(); + glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); - stop_glerror(); mMappedIndexData = nullptr; } @@ -2410,13 +2254,12 @@ bool LLVertexBuffer::getClothWeightStrider(LLStrider<LLVector4a>& strider, S32 i //---------------------------------------------------------------------------- -static LLTrace::BlockTimerStatHandle FTM_BIND_GL_ARRAY("Bind Array"); bool LLVertexBuffer::bindGLArray() { if (mGLArray && sGLRenderArray != mGLArray) { { - //LL_RECORD_BLOCK_TIME(FTM_BIND_GL_ARRAY); + LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX; #if GL_ARB_vertex_array_object glBindVertexArray(mGLArray); #endif @@ -2433,8 +2276,6 @@ bool LLVertexBuffer::bindGLArray() return false; } -static LLTrace::BlockTimerStatHandle FTM_BIND_GL_BUFFER("Bind Buffer"); - bool LLVertexBuffer::bindGLBuffer(bool force_bind) { stop_glerror(); @@ -2445,12 +2286,10 @@ bool LLVertexBuffer::bindGLBuffer(bool force_bind) if (useVBOs() && (force_bind || (mGLBuffer && (mGLBuffer != sGLRenderBuffer || !sVBOActive)))) { - //LL_RECORD_BLOCK_TIME(FTM_BIND_GL_BUFFER); - + LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX; validate_bind_buffer(mGLBuffer); glBindBuffer(GL_ARRAY_BUFFER, mGLBuffer); sGLRenderBuffer = mGLBuffer; - stop_glerror(); sBindCount++; sVBOActive = true; @@ -2462,16 +2301,29 @@ bool LLVertexBuffer::bindGLBuffer(bool force_bind) return ret; } -static LLTrace::BlockTimerStatHandle FTM_BIND_GL_INDICES("Bind Indices"); +bool LLVertexBuffer::bindGLBufferFast() +{ + if (mGLBuffer != sGLRenderBuffer || !sVBOActive) + { + glBindBufferARB(GL_ARRAY_BUFFER_ARB, mGLBuffer); + sGLRenderBuffer = mGLBuffer; + sBindCount++; + sVBOActive = true; + + return true; + } + + return false; +} bool LLVertexBuffer::bindGLIndices(bool force_bind) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX; bindGLArray(); bool ret = false; if (useVBOs() && (force_bind || (mGLIndices && (mGLIndices != sGLRenderIndices || !sIBOActive)))) { - //LL_RECORD_BLOCK_TIME(FTM_BIND_GL_INDICES); /*if (sMapped) { LL_ERRS() << "VBO bound while another VBO mapped!" << LL_ENDL; @@ -2488,6 +2340,21 @@ bool LLVertexBuffer::bindGLIndices(bool force_bind) return ret; } +bool LLVertexBuffer::bindGLIndicesFast() +{ + if (mGLIndices != sGLRenderIndices || !sIBOActive) + { + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mGLIndices); + sGLRenderIndices = mGLIndices; + sBindCount++; + sIBOActive = true; + + return true; + } + + return false; +} + void LLVertexBuffer::flush() { if (useVBOs()) @@ -2668,6 +2535,34 @@ void LLVertexBuffer::setBuffer(U32 data_mask) } } +void LLVertexBuffer::setBufferFast(U32 data_mask) +{ + if (useVBOs()) + { + //set up pointers if the data mask is different ... + bool setup = (sLastMask != data_mask); + + const bool bindBuffer = bindGLBufferFast(); + const bool bindIndices = bindGLIndicesFast(); + + setup = setup || bindBuffer || bindIndices; + + setupClientArrays(data_mask); + + if (data_mask && setup) + { + setupVertexBufferFast(data_mask); + sSetCount++; + } + } + else + { + //fallback to slow path when not using VBOs + setBuffer(data_mask); + } +} + + // virtual (default) void LLVertexBuffer::setupVertexBuffer(U32 data_mask) { @@ -2687,144 +2582,191 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) LL_ERRS() << "LLVertexBuffer::setupVertexBuffer missing required components for supplied data mask." << LL_ENDL; } - if (LLGLSLShader::sNoFixedFunction) + if (data_mask & MAP_NORMAL) { - if (data_mask & MAP_NORMAL) - { - S32 loc = TYPE_NORMAL; - void* ptr = (void*)(base + mOffsets[TYPE_NORMAL]); - glVertexAttribPointer(loc, 3, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_NORMAL], ptr); - } - if (data_mask & MAP_TEXCOORD3) - { - S32 loc = TYPE_TEXCOORD3; - void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD3]); - glVertexAttribPointer(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], ptr); - } - if (data_mask & MAP_TEXCOORD2) - { - S32 loc = TYPE_TEXCOORD2; - void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD2]); - glVertexAttribPointer(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], ptr); - } - if (data_mask & MAP_TEXCOORD1) - { - S32 loc = TYPE_TEXCOORD1; - void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD1]); - glVertexAttribPointer(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], ptr); - } - if (data_mask & MAP_TANGENT) - { - S32 loc = TYPE_TANGENT; - void* ptr = (void*)(base + mOffsets[TYPE_TANGENT]); - glVertexAttribPointer(loc, 4,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TANGENT], ptr); - } - if (data_mask & MAP_TEXCOORD0) - { - S32 loc = TYPE_TEXCOORD0; - void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD0]); - glVertexAttribPointer(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], ptr); - } - if (data_mask & MAP_COLOR) - { - S32 loc = TYPE_COLOR; - //bind emissive instead of color pointer if emissive is present - void* ptr = (data_mask & MAP_EMISSIVE) ? (void*)(base + mOffsets[TYPE_EMISSIVE]) : (void*)(base + mOffsets[TYPE_COLOR]); - glVertexAttribPointer(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_COLOR], ptr); - } - if (data_mask & MAP_EMISSIVE) - { - S32 loc = TYPE_EMISSIVE; - void* ptr = (void*)(base + mOffsets[TYPE_EMISSIVE]); - glVertexAttribPointer(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr); + S32 loc = TYPE_NORMAL; + void* ptr = (void*)(base + mOffsets[TYPE_NORMAL]); + glVertexAttribPointer(loc, 3, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_NORMAL], ptr); + } + if (data_mask & MAP_TEXCOORD3) + { + S32 loc = TYPE_TEXCOORD3; + void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD3]); + glVertexAttribPointer(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], ptr); + } + if (data_mask & MAP_TEXCOORD2) + { + S32 loc = TYPE_TEXCOORD2; + void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD2]); + glVertexAttribPointer(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], ptr); + } + if (data_mask & MAP_TEXCOORD1) + { + S32 loc = TYPE_TEXCOORD1; + void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD1]); + glVertexAttribPointer(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], ptr); + } + if (data_mask & MAP_TANGENT) + { + S32 loc = TYPE_TANGENT; + void* ptr = (void*)(base + mOffsets[TYPE_TANGENT]); + glVertexAttribPointer(loc, 4,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TANGENT], ptr); + } + if (data_mask & MAP_TEXCOORD0) + { + S32 loc = TYPE_TEXCOORD0; + void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD0]); + glVertexAttribPointer(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], ptr); + } + if (data_mask & MAP_COLOR) + { + S32 loc = TYPE_COLOR; + //bind emissive instead of color pointer if emissive is present + void* ptr = (data_mask & MAP_EMISSIVE) ? (void*)(base + mOffsets[TYPE_EMISSIVE]) : (void*)(base + mOffsets[TYPE_COLOR]); + glVertexAttribPointer(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_COLOR], ptr); + } + if (data_mask & MAP_EMISSIVE) + { + S32 loc = TYPE_EMISSIVE; + void* ptr = (void*)(base + mOffsets[TYPE_EMISSIVE]); + glVertexAttribPointer(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr); - if (!(data_mask & MAP_COLOR)) - { //map emissive to color channel when color is not also being bound to avoid unnecessary shader swaps - loc = TYPE_COLOR; - glVertexAttribPointer(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr); - } - } - if (data_mask & MAP_WEIGHT) - { - S32 loc = TYPE_WEIGHT; - void* ptr = (void*)(base + mOffsets[TYPE_WEIGHT]); - glVertexAttribPointer(loc, 1, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT], ptr); - } - if (data_mask & MAP_WEIGHT4) - { - S32 loc = TYPE_WEIGHT4; - void* ptr = (void*)(base+mOffsets[TYPE_WEIGHT4]); - glVertexAttribPointer(loc, 4, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT4], ptr); - } - if (data_mask & MAP_CLOTHWEIGHT) - { - S32 loc = TYPE_CLOTHWEIGHT; - void* ptr = (void*)(base + mOffsets[TYPE_CLOTHWEIGHT]); - glVertexAttribPointer(loc, 4, GL_FLOAT, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_CLOTHWEIGHT], ptr); + if (!(data_mask & MAP_COLOR)) + { //map emissive to color channel when color is not also being bound to avoid unnecessary shader swaps + loc = TYPE_COLOR; + glVertexAttribPointer(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr); } - if (data_mask & MAP_TEXTURE_INDEX && - (gGLManager.mGLSLVersionMajor >= 2 || gGLManager.mGLSLVersionMinor >= 30)) //indexed texture rendering requires GLSL 1.30 or later - { + } + if (data_mask & MAP_WEIGHT) + { + S32 loc = TYPE_WEIGHT; + void* ptr = (void*)(base + mOffsets[TYPE_WEIGHT]); + glVertexAttribPointer(loc, 1, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT], ptr); + } + if (data_mask & MAP_WEIGHT4) + { + S32 loc = TYPE_WEIGHT4; + void* ptr = (void*)(base+mOffsets[TYPE_WEIGHT4]); + glVertexAttribPointer(loc, 4, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT4], ptr); + } + if (data_mask & MAP_CLOTHWEIGHT) + { + S32 loc = TYPE_CLOTHWEIGHT; + void* ptr = (void*)(base + mOffsets[TYPE_CLOTHWEIGHT]); + glVertexAttribPointer(loc, 4, GL_FLOAT, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_CLOTHWEIGHT], ptr); + } + if (data_mask & MAP_TEXTURE_INDEX && + (gGLManager.mGLSLVersionMajor >= 2 || gGLManager.mGLSLVersionMinor >= 30)) //indexed texture rendering requires GLSL 1.30 or later + { #if !LL_DARWIN - S32 loc = TYPE_TEXTURE_INDEX; - void *ptr = (void*) (base + mOffsets[TYPE_VERTEX] + 12); - glVertexAttribIPointer(loc, 1, GL_UNSIGNED_INT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr); + S32 loc = TYPE_TEXTURE_INDEX; + void *ptr = (void*) (base + mOffsets[TYPE_VERTEX] + 12); + glVertexAttribIPointer(loc, 1, GL_UNSIGNED_INT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr); #endif - } - if (data_mask & MAP_VERTEX) - { - S32 loc = TYPE_VERTEX; - void* ptr = (void*)(base + mOffsets[TYPE_VERTEX]); - glVertexAttribPointer(loc, 3,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr); - } - } - else - { - if (data_mask & MAP_NORMAL) - { - glNormalPointer(GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_NORMAL], (void*)(base + mOffsets[TYPE_NORMAL])); - } - if (data_mask & MAP_TEXCOORD3) - { - glClientActiveTexture(GL_TEXTURE3); - glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], (void*)(base + mOffsets[TYPE_TEXCOORD3])); - glClientActiveTexture(GL_TEXTURE0); - } - if (data_mask & MAP_TEXCOORD2) - { - glClientActiveTexture(GL_TEXTURE2); - glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], (void*)(base + mOffsets[TYPE_TEXCOORD2])); - glClientActiveTexture(GL_TEXTURE0); - } - if (data_mask & MAP_TEXCOORD1) - { - glClientActiveTexture(GL_TEXTURE1); - glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1])); - glClientActiveTexture(GL_TEXTURE0); - } - if (data_mask & MAP_TANGENT) - { - glClientActiveTexture(GL_TEXTURE2); - glTexCoordPointer(4,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TANGENT], (void*)(base + mOffsets[TYPE_TANGENT])); - glClientActiveTexture(GL_TEXTURE0); - } - if (data_mask & MAP_TEXCOORD0) - { - glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], (void*)(base + mOffsets[TYPE_TEXCOORD0])); - } - if (data_mask & MAP_COLOR) - { - glColorPointer(4, GL_UNSIGNED_BYTE, LLVertexBuffer::sTypeSize[TYPE_COLOR], (void*)(base + mOffsets[TYPE_COLOR])); - } - if (data_mask & MAP_VERTEX) - { - glVertexPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0)); - } } + if (data_mask & MAP_VERTEX) + { + S32 loc = TYPE_VERTEX; + void* ptr = (void*)(base + mOffsets[TYPE_VERTEX]); + glVertexAttribPointer(loc, 3,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr); + } llglassertok(); } +void LLVertexBuffer::setupVertexBufferFast(U32 data_mask) +{ + U8* base = (U8*)mAlignedOffset; + + if (data_mask & MAP_NORMAL) + { + S32 loc = TYPE_NORMAL; + void* ptr = (void*)(base + mOffsets[TYPE_NORMAL]); + glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_NORMAL], ptr); + } + if (data_mask & MAP_TEXCOORD3) + { + S32 loc = TYPE_TEXCOORD3; + void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD3]); + glVertexAttribPointerARB(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], ptr); + } + if (data_mask & MAP_TEXCOORD2) + { + S32 loc = TYPE_TEXCOORD2; + void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD2]); + glVertexAttribPointerARB(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], ptr); + } + if (data_mask & MAP_TEXCOORD1) + { + S32 loc = TYPE_TEXCOORD1; + void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD1]); + glVertexAttribPointerARB(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], ptr); + } + if (data_mask & MAP_TANGENT) + { + S32 loc = TYPE_TANGENT; + void* ptr = (void*)(base + mOffsets[TYPE_TANGENT]); + glVertexAttribPointerARB(loc, 4, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TANGENT], ptr); + } + if (data_mask & MAP_TEXCOORD0) + { + S32 loc = TYPE_TEXCOORD0; + void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD0]); + glVertexAttribPointerARB(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], ptr); + } + if (data_mask & MAP_COLOR) + { + S32 loc = TYPE_COLOR; + //bind emissive instead of color pointer if emissive is present + void* ptr = (data_mask & MAP_EMISSIVE) ? (void*)(base + mOffsets[TYPE_EMISSIVE]) : (void*)(base + mOffsets[TYPE_COLOR]); + glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_COLOR], ptr); + } + if (data_mask & MAP_EMISSIVE) + { + S32 loc = TYPE_EMISSIVE; + void* ptr = (void*)(base + mOffsets[TYPE_EMISSIVE]); + glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr); + + if (!(data_mask & MAP_COLOR)) + { //map emissive to color channel when color is not also being bound to avoid unnecessary shader swaps + loc = TYPE_COLOR; + glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr); + } + } + if (data_mask & MAP_WEIGHT) + { + S32 loc = TYPE_WEIGHT; + void* ptr = (void*)(base + mOffsets[TYPE_WEIGHT]); + glVertexAttribPointerARB(loc, 1, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT], ptr); + } + if (data_mask & MAP_WEIGHT4) + { + S32 loc = TYPE_WEIGHT4; + void* ptr = (void*)(base + mOffsets[TYPE_WEIGHT4]); + glVertexAttribPointerARB(loc, 4, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT4], ptr); + } + if (data_mask & MAP_CLOTHWEIGHT) + { + S32 loc = TYPE_CLOTHWEIGHT; + void* ptr = (void*)(base + mOffsets[TYPE_CLOTHWEIGHT]); + glVertexAttribPointerARB(loc, 4, GL_FLOAT, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_CLOTHWEIGHT], ptr); + } + if (data_mask & MAP_TEXTURE_INDEX) + { +#if !LL_DARWIN + S32 loc = TYPE_TEXTURE_INDEX; + void* ptr = (void*)(base + mOffsets[TYPE_VERTEX] + 12); + glVertexAttribIPointer(loc, 1, GL_UNSIGNED_INT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr); +#endif + } + if (data_mask & MAP_VERTEX) + { + S32 loc = TYPE_VERTEX; + void* ptr = (void*)(base + mOffsets[TYPE_VERTEX]); + glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr); + } +} + LLVertexBuffer::MappedRegion::MappedRegion(S32 type, U32 offset, U32 length) : mType(type), mOffset(offset), mLength(length) { diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index e9103c7271db688b7ff91e4068d7e823aa52d542..2937b25dc0ffb36c19f41e291eae52b9f5ad8a92 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -94,12 +94,15 @@ class LLVBOPool std::vector<U32> mMissCount; bool mMissCountDirty; // flag any changes to mFreeList or mMissCount + //used to avoid calling glGenBuffers for every VBO creation + static U32 sNamePool[1024]; + static U32 sNameIdx; }; //============================================================================ // base class -class LLVertexBuffer final : public LLRefCount, public LLTrace::MemTrackable<LLVertexBuffer> +class LLVertexBuffer final : public LLRefCount { public: class MappedRegion @@ -137,8 +140,8 @@ class LLVertexBuffer final : public LLRefCount, public LLTrace::MemTrackable<LLV static void initClass(bool use_vbo, bool no_vbo_mapping); static void cleanupClass(); static void setupClientArrays(U32 data_mask); - static void drawArrays(U32 mode, const std::vector<LLVector3>& pos, const std::vector<LLVector3>& norm); - static void drawElements(U32 mode, const S32 num_vertices, const LLVector4a* pos, const LLVector2* tc, S32 num_indices, const U16* indicesp); + static void drawArrays(U32 mode, const std::vector<LLVector3>& pos); + static void drawElements(U32 mode, const LLVector4a* pos, const LLVector2* tc, S32 num_indices, const U16* indicesp); static void unbind(); //unbind any bound vertex buffer @@ -201,12 +204,16 @@ class LLVertexBuffer final : public LLRefCount, public LLTrace::MemTrackable<LLV ~LLVertexBuffer() override; // use unref() void setupVertexBuffer(U32 data_mask); // called from mapBuffer() + void setupVertexBufferFast(U32 data_mask); + void setupVertexArray(); void genBuffer(U32 size); void genIndices(U32 size); bool bindGLBuffer(bool force_bind = false); + bool bindGLBufferFast(); bool bindGLIndices(bool force_bind = false); + bool bindGLIndicesFast(); bool bindGLArray(); void releaseBuffer(); void releaseIndices(); @@ -227,6 +234,8 @@ class LLVertexBuffer final : public LLRefCount, public LLTrace::MemTrackable<LLV // set for rendering void setBuffer(U32 data_mask); // calls setupVertexBuffer() if data_mask is not 0 + void setBufferFast(U32 data_mask); // calls setupVertexBufferFast(), assumes data_mask is not 0 among other assumptions + void flush(); //flush pending data to GL memory // allocate buffer bool allocateBuffer(S32 nverts, S32 nindices, bool create); @@ -250,7 +259,6 @@ class LLVertexBuffer final : public LLRefCount, public LLTrace::MemTrackable<LLV bool getTangentStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false); bool getTangentStrider(LLStrider<LLVector4a>& strider, S32 index=0, S32 count = -1, bool map_range = false); bool getColorStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false); - bool getTextureIndexStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false); bool getEmissiveStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false); bool getWeightStrider(LLStrider<F32>& strider, S32 index=0, S32 count = -1, bool map_range = false); bool getWeight4Strider(LLStrider<LLVector4a>& strider, S32 index=0, S32 count = -1, bool map_range = false); @@ -279,6 +287,9 @@ class LLVertexBuffer final : public LLRefCount, public LLTrace::MemTrackable<LLV void drawArrays(U32 mode, U32 offset, U32 count) const; void drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const; + //implementation for inner loops that does no safety checking + void drawRangeFast(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const; + //for debugging, validate data in given range is valid void validateRange(U32 start, U32 end, U32 count, U32 offset) const; diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt index 5e69dae3f2f91e14fc8f447960118d805ff225f0..3e2be39d780de3f1017e69eecec8383d5a6e1e14 100644 --- a/indra/llui/CMakeLists.txt +++ b/indra/llui/CMakeLists.txt @@ -349,6 +349,10 @@ if(LL_TESTS) ${BOOST_SYSTEM_LIBRARY} ${WINDOWS_LIBRARIES}) if(NOT LINUX AND NOT DARWIN) - LL_ADD_INTEGRATION_TEST(llurlentry llurlentry.cpp "${test_libs}") + 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) endif() endif(LL_TESTS) diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index 050c21781a5828343ab52a0afb6778b02f3c5c2e..acf119a205c4db337409ab85f016b26e51bedb67 100644 --- a/indra/llui/llbutton.cpp +++ b/indra/llui/llbutton.cpp @@ -102,6 +102,7 @@ LLButton::Params::Params() scale_image("scale_image", true), hover_glow_amount("hover_glow_amount"), commit_on_return("commit_on_return", true), + commit_on_capture_lost("commit_on_capture_lost", false), display_pressed_state("display_pressed_state", true), use_draw_context_alpha("use_draw_context_alpha", true), badge("badge"), @@ -166,6 +167,7 @@ LLButton::LLButton(const LLButton::Params& p) mBottomVPad(p.pad_bottom), mHoverGlowStrength(p.hover_glow_amount), mCommitOnReturn(p.commit_on_return), + mCommitOnCaptureLost(p.commit_on_capture_lost), mFadeWhenDisabled(FALSE), mForcePressedState(false), mDisplayPressedState(p.display_pressed_state), @@ -481,6 +483,10 @@ BOOL LLButton::handleMouseUp(S32 x, S32 y, MASK mask) // We only handle the click if the click both started and ended within us if( hasMouseCapture() ) { + // reset timers before focus change, to not cause + // additional commits if mCommitOnCaptureLost. + resetMouseDownTimer(); + // Always release the mouse gFocusMgr.setMouseCapture( NULL ); @@ -501,8 +507,6 @@ BOOL LLButton::handleMouseUp(S32 x, S32 y, MASK mask) // Regardless of where mouseup occurs, handle callback if(mMouseUpSignal) (*mMouseUpSignal)(this, LLSD()); - resetMouseDownTimer(); - // DO THIS AT THE VERY END to allow the button to be destroyed as a result of being clicked. // If mouseup in the widget, it's been clicked if (pointInView(x, y)) @@ -1216,6 +1220,18 @@ void LLButton::setImageOverlay(const LLUUID& image_id, LLFontGL::HAlign alignmen void LLButton::onMouseCaptureLost() { + if (mCommitOnCaptureLost + && mMouseDownTimer.getStarted()) + { + if (mMouseUpSignal) (*mMouseUpSignal)(this, LLSD()); + + if (mIsToggle) + { + toggleState(); + } + + LLUICtrl::onCommit(); + } resetMouseDownTimer(); } @@ -1297,10 +1313,10 @@ void LLButton::showHelp(LLUICtrl* ctrl, const LLSD& sdname) // search back through the button's parents for a panel // with a help_topic string defined std::string help_topic; - if (LLUI::getInstanceFast()->mHelpImpl && + if (LLUI::getInstance()->mHelpImpl && ctrl->findHelpTopic(help_topic)) { - LLUI::getInstanceFast()->mHelpImpl->showTopic(help_topic); + LLUI::getInstance()->mHelpImpl->showTopic(help_topic); return; // success } diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h index c69b5368a5a43db7010cf5172a8ef395dc090cb5..28ec03c3deddc3997d74790a78c94fdb49bb3af7 100644 --- a/indra/llui/llbutton.h +++ b/indra/llui/llbutton.h @@ -125,6 +125,7 @@ class LLButton Optional<bool> is_toggle, scale_image, commit_on_return, + commit_on_capture_lost, display_pressed_state; Optional<F32> hover_glow_amount; @@ -378,6 +379,7 @@ class LLButton F32 mCurGlowStrength; bool mCommitOnReturn; + bool mCommitOnCaptureLost; bool mFadeWhenDisabled; bool mForcePressedState; bool mDisplayPressedState; diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp index 52d0d116162a64205d24df3e8df9cb2cf3fc8bdb..6d26f237b5f87de51cf9f72d3953dee29df91b2c 100644 --- a/indra/llui/llcombobox.cpp +++ b/indra/llui/llcombobox.cpp @@ -113,6 +113,10 @@ LLComboBox::LLComboBox(const LLComboBox::Params& p) } mArrowImage = button_params.image_unselected; + if (mArrowImage.notNull()) + { + mImageLoadedConnection = mArrowImage->addLoadedCallback(boost::bind(&LLComboBox::imageLoaded, this)); + } mButton = LLUICtrlFactory::create<LLButton>(button_params); @@ -183,6 +187,7 @@ LLComboBox::~LLComboBox() // explicitly disconect this signal, since base class destructor might fire top lost mTopLostSignalConnection.disconnect(); + mImageLoadedConnection.disconnect(); } @@ -676,7 +681,7 @@ void LLComboBox::showList() mButton->setToggleState(TRUE); mList->setVisible(TRUE); - LLUI::getInstanceFast()->addPopup(this); + LLUI::getInstance()->addPopup(this); setUseBoundingRect(TRUE); // updateBoundingRect(); @@ -702,7 +707,7 @@ void LLComboBox::hideList() mList->mouseOverHighlightNthItem(-1); setUseBoundingRect(FALSE); - LLUI::getInstanceFast()->removePopup(this); + LLUI::getInstance()->removePopup(this); // updateBoundingRect(); } } @@ -794,7 +799,7 @@ BOOL LLComboBox::handleToolTip(S32 x, S32 y, MASK mask) if( !tool_tip.empty() ) { - LLToolTipMgr::instanceFast().show(LLToolTip::Params() + LLToolTipMgr::instance().show(LLToolTip::Params() .message(tool_tip) .sticky_rect(calcScreenRect())); } @@ -1075,6 +1080,30 @@ void LLComboBox::onSetHighlight() const } } +void LLComboBox::imageLoaded() +{ + static LLUICachedControl<S32> drop_shadow_button("DropShadowButton", 0); + + if (mAllowTextEntry) + { + LLRect rect = getLocalRect(); + S32 arrow_width = mArrowImage ? mArrowImage->getWidth() : 0; + S32 shadow_size = drop_shadow_button; + mButton->setRect(LLRect(getRect().getWidth() - llmax(8, arrow_width) - 2 * shadow_size, + rect.mTop, rect.mRight, rect.mBottom)); + if (mButton->getVisible()) + { + // recalculate field size + if (mTextEntry) + { + LLRect text_entry_rect(0, getRect().getHeight(), getRect().getWidth(), 0); + text_entry_rect.mRight -= llmax(8, arrow_width) + 2 * drop_shadow_button; + mTextEntry->reshape(text_entry_rect.getWidth(), text_entry_rect.getHeight(), TRUE); + } + } + } +} + //============================================================================ // LLCtrlListInterface functions diff --git a/indra/llui/llcombobox.h b/indra/llui/llcombobox.h index 67a5a8af5809e7ca98a3895ca03a73a65d959b0e..a4b5a91fe29e90af02a5fbac6f07a59654d2dace 100644 --- a/indra/llui/llcombobox.h +++ b/indra/llui/llcombobox.h @@ -105,6 +105,8 @@ class LLComboBox std::string _getSearchText() const override; void onSetHighlight() const override; + void imageLoaded(); + public: // LLView interface void onFocusLost() override; @@ -245,6 +247,7 @@ class LLComboBox commit_callback_t mTextChangedCallback; commit_callback_t mSelectionCallback; boost::signals2::connection mTopLostSignalConnection; + boost::signals2::connection mImageLoadedConnection; commit_signal_t mOnReturnSignal; S32 mLastSelectedIndex; }; diff --git a/indra/llui/llconsole.cpp b/indra/llui/llconsole.cpp index 408dbde0293a9498159d83e15aa3d1d1a249a438..c283cdc4007751b5672fc305201de878590796e3 100644 --- a/indra/llui/llconsole.cpp +++ b/indra/llui/llconsole.cpp @@ -68,7 +68,7 @@ LLConsole::LLConsole(const LLConsole::Params& p) setFontSize(p.font_size_index); } mFadeTime = mLinePersistTime - FADE_DURATION; - setMaxLines(LLUI::getInstanceFast()->mSettingGroups["config"]->getS32("ConsoleMaxLines")); + setMaxLines(LLUI::getInstance()->mSettingGroups["config"]->getS32("ConsoleMaxLines")); mBackgroundImagep = LLUI::getUIImage("transparent"); } diff --git a/indra/llui/llconsole.h b/indra/llui/llconsole.h index 11cb9b45e87b5d23dcac5035ced3c59d0ce3b8a0..1c08458fe570da98bc04e869dd802cd39d69b023 100644 --- a/indra/llui/llconsole.h +++ b/indra/llui/llconsole.h @@ -51,7 +51,7 @@ class LLConsole : public LLFixedBuffer, public LLUICtrl, public LLInstanceTracke Optional<F32> persist_time; Optional<S32> font_size_index; Params() - : max_lines("max_lines", LLUI::getInstanceFast()->mSettingGroups["config"]->getS32("ConsoleMaxLines")), + : max_lines("max_lines", LLUI::getInstance()->mSettingGroups["config"]->getS32("ConsoleMaxLines")), persist_time("persist_time", 0.f), // forever font_size_index("font_size_index") { diff --git a/indra/llui/lldraghandle.h b/indra/llui/lldraghandle.h index 4b8c74ca69f8f44a5b337682c8a5a57906425e5b..e095e577b1e555d711bf56c87567ec1f396ba4fa 100644 --- a/indra/llui/lldraghandle.h +++ b/indra/llui/lldraghandle.h @@ -48,8 +48,8 @@ class LLDragHandle : public LLView Params() : label("label"), - drag_highlight_color("drag_highlight_color", LLUIColorTable::instanceFast().getColor("DefaultHighlightLight")), - drag_shadow_color("drag_shadow_color", LLUIColorTable::instanceFast().getColor("DefaultShadowDark")) + drag_highlight_color("drag_highlight_color", LLUIColorTable::instance().getColor("DefaultHighlightLight")), + drag_shadow_color("drag_shadow_color", LLUIColorTable::instance().getColor("DefaultShadowDark")) { changeDefault(mouse_opaque, true); changeDefault(follows.flags, FOLLOWS_ALL); diff --git a/indra/llui/llflashtimer.cpp b/indra/llui/llflashtimer.cpp index dc8063738cc16dba1f8978a71ee09a0df5591000..39793316f438db32e90ebaf0fcd3fba7b982e4d3 100644 --- a/indra/llui/llflashtimer.cpp +++ b/indra/llui/llflashtimer.cpp @@ -40,10 +40,10 @@ LLFlashTimer::LLFlashTimer(callback_t cb, S32 count, F32 period) // By default use settings from settings.xml to be able change them via Debug settings. See EXT-5973. // Due to Timer is implemented as derived class from EventTimer it is impossible to change period // in runtime. So, both settings are made as required restart. - mFlashCount = 2 * ((count > 0) ? count : LLUI::getInstanceFast()->mSettingGroups["config"]->getS32("FlashCount")); + mFlashCount = 2 * ((count > 0) ? count : LLUI::getInstance()->mSettingGroups["config"]->getS32("FlashCount")); if (mPeriod <= 0) { - mPeriod = LLUI::getInstanceFast()->mSettingGroups["config"]->getF32("FlashPeriod"); + mPeriod = LLUI::getInstance()->mSettingGroups["config"]->getF32("FlashPeriod"); } } diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 852c5ced14cc6b64a79aafb16a94c485a39a95d8..9b49438a0ebd4f56344317f8c1104319394c0a95 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -598,7 +598,7 @@ std::string LLFloater::getControlName(const std::string& name, const LLSD& key) LLControlGroup* LLFloater::getControlGroup() { // Floater size, position, visibility, etc are saved in per-account settings. - return LLUI::getInstanceFast()->mSettingGroups["account"]; + return LLUI::getInstance()->mSettingGroups["account"]; } void LLFloater::setVisible( BOOL visible ) @@ -611,7 +611,7 @@ void LLFloater::setVisible( BOOL visible ) if( !visible ) { - LLUI::getInstanceFast()->removePopup(this); + LLUI::getInstance()->removePopup(this); if( gFocusMgr.childHasMouseCapture( this ) ) { @@ -776,17 +776,13 @@ void LLFloater::closeFloater(bool app_quitting) for(handle_set_iter_t dependent_it = mDependents.begin(); dependent_it != mDependents.end(); ) { - LLFloater* floaterp = dependent_it->get(); - if (floaterp) - { - ++dependent_it; - floaterp->closeFloater(app_quitting); - } - else - { - mDependents.erase(dependent_it++); - } + dependent_it = mDependents.erase(dependent_it); + if (floaterp) + { + floaterp->mDependeeHandle = LLHandle<LLFloater>(); + floaterp->closeFloater(app_quitting); + } } cleanupHandles(); @@ -847,7 +843,7 @@ void LLFloater::reshape(S32 width, S32 height, BOOL called_from_parent) void LLFloater::releaseFocus() { - LLUI::getInstanceFast()->removePopup(this); + LLUI::getInstance()->removePopup(this); setFocus(FALSE); @@ -1457,7 +1453,7 @@ void LLFloater::cleanupHandles() LLFloater* floaterp = dependent_it->get(); if (!floaterp) { - mDependents.erase(dependent_it++); + dependent_it = mDependents.erase(dependent_it); } else { @@ -1821,13 +1817,13 @@ void LLFloater::onClickDock(LLFloater* self) // static void LLFloater::onClickHelp( LLFloater* self ) { - if (self && LLUI::getInstanceFast()->mHelpImpl) + if (self && LLUI::getInstance()->mHelpImpl) { // find the current help context for this floater std::string help_topic; if (self->findHelpTopic(help_topic)) { - LLUI::getInstanceFast()->mHelpImpl->showTopic(help_topic); + LLUI::getInstance()->mHelpImpl->showTopic(help_topic); } } } @@ -3055,7 +3051,7 @@ void LLFloaterView::syncFloaterTabOrder() if (modal_dialog) { // If we have a visible modal dialog, make sure that it has focus - LLUI::getInstanceFast()->addPopup(modal_dialog); + LLUI::getInstance()->addPopup(modal_dialog); if( !gFocusMgr.childHasKeyboardFocus( modal_dialog ) ) { @@ -3311,11 +3307,9 @@ boost::signals2::connection LLFloater::setCloseCallback( const commit_signal_t:: return mCloseSignal.connect(cb); } -LLTrace::BlockTimerStatHandle POST_BUILD("Floater Post Build"); -static LLTrace::BlockTimerStatHandle FTM_EXTERNAL_FLOATER_LOAD("Load Extern Floater Reference"); - bool LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, const std::string& filename, LLXMLNodePtr output_node) { + LL_PROFILE_ZONE_SCOPED; Params default_params(LLUICtrlFactory::getDefaultParams<LLFloater>()); Params params(default_params); @@ -3326,7 +3320,7 @@ bool LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, const std::str if (!xml_filename.empty()) { - auto& uifactory_inst = LLUICtrlFactory::instanceFast(); + auto& uifactory_inst = LLUICtrlFactory::instance(); LLXMLNodePtr referenced_xml; @@ -3346,7 +3340,6 @@ bool LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, const std::str uifactory_inst.pushFileName(xml_filename); - LL_RECORD_BLOCK_TIME(FTM_EXTERNAL_FLOATER_LOAD); if (!LLUICtrlFactory::getLayeredXMLNode(xml_filename, referenced_xml)) { LL_WARNS() << "Couldn't parse panel from: " << xml_filename << LL_ENDL; @@ -3360,7 +3353,7 @@ bool LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, const std::str // add children using dimensions from referenced xml for consistent layout setShape(params.rect); - LLUICtrlFactory::createChildren(this, referenced_xml, child_registry_t::instanceFast()); + LLUICtrlFactory::createChildren(this, referenced_xml, child_registry_t::instance()); uifactory_inst.popFileName(); } @@ -3397,7 +3390,7 @@ bool LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, const std::str LLFloater::setFloaterHost((LLMultiFloater*) this); } - LLUICtrlFactory::createChildren(this, node, child_registry_t::instanceFast(), output_node); + LLUICtrlFactory::createChildren(this, node, child_registry_t::instance(), output_node); if (node->hasName("multi_floater")) { @@ -3422,12 +3415,8 @@ bool LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, const std::str } BOOL result; - { - LL_RECORD_BLOCK_TIME(POST_BUILD); - - result = postBuild(); - } - + result = postBuild(); + if (!result) { LL_ERRS() << "Failed to construct floater " << getName() << LL_ENDL; @@ -3471,11 +3460,9 @@ bool LLFloater::isVisible(const LLFloater* floater) return floater && floater->getVisible(); } -static LLTrace::BlockTimerStatHandle FTM_BUILD_FLOATERS("Build Floaters"); - bool LLFloater::buildFromFile(const std::string& filename) { - LL_RECORD_BLOCK_TIME(FTM_BUILD_FLOATERS); + LL_PROFILE_ZONE_SCOPED; LLXMLNodePtr root; if (!LLUICtrlFactory::getLayeredXMLNode(filename, root)) @@ -3494,7 +3481,7 @@ bool LLFloater::buildFromFile(const std::string& filename) bool res = true; LL_DEBUGS() << "Building floater " << filename << LL_ENDL; - auto& uictrl_factory = LLUICtrlFactory::instanceFast(); + auto& uictrl_factory = LLUICtrlFactory::instance(); uictrl_factory.pushFileName(filename); { if (!getFactoryMap().empty()) diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h index 9c29933bb2b61023a785eee380756e34e7abb6a5..69661047b1b1813794fd85e74adbbf5ca059bf8a 100644 --- a/indra/llui/llfloater.h +++ b/indra/llui/llfloater.h @@ -349,6 +349,8 @@ class LLFloater : public LLPanel, public LLInstanceTracker<LLFloater> // handle refocusing. static void closeFrontmostFloater(); + static bool isQuitRequested() { return sQuitting; } + // LLNotification::Params contextualNotification(const std::string& name) // { // return LLNotification::Params(name).context(mNotificationContext); diff --git a/indra/llui/llfloaterreg.cpp b/indra/llui/llfloaterreg.cpp index 9cc5e0afd7b47947d52cba79c50caa9c689c29ee..860de774956f7525ef01701ca5f9da9ead7b42ad 100644 --- a/indra/llui/llfloaterreg.cpp +++ b/indra/llui/llfloaterreg.cpp @@ -481,7 +481,7 @@ void LLFloaterReg::registerControlVariables() } } - const LLSD& exclude_list = LLUI::getInstanceFast()->mSettingGroups["config"]->getLLSD("always_showable_floaters"); + const LLSD& exclude_list = LLUI::getInstance()->mSettingGroups["config"]->getLLSD("always_showable_floaters"); for (const auto& llsd_var : exclude_list.array()) { sAlwaysShowableList.insert(llsd_var.asString()); diff --git a/indra/llui/llfocusmgr.cpp b/indra/llui/llfocusmgr.cpp index f117c8237dc9b371dd2f27b907bc62bdaae1fe1b..419d1489cdaf4a11b16aa2a88f14b7a40bf2b831 100644 --- a/indra/llui/llfocusmgr.cpp +++ b/indra/llui/llfocusmgr.cpp @@ -183,7 +183,7 @@ void LLFocusMgr::releaseFocusIfNeeded( LLView* view ) } } - LLUI::getInstanceFast()->removePopup(view); + LLUI::getInstance()->removePopup(view); } void LLFocusMgr::setKeyboardFocus(LLFocusableElement* new_focus, BOOL lock, BOOL keystrokes_only) @@ -492,7 +492,7 @@ void LLFocusMgr::setAppHasFocus(BOOL focus) // release focus from "top ctrl"s, which generally hides them if (!focus) { - LLUI::getInstanceFast()->clearPopups(); + LLUI::getInstance()->clearPopups(); } mAppHasFocus = focus; } diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp index 791c3d7a14eeac50a6903431279280e3dd7e2de3..73b8f54c7070024deb03778ca27fab3cb3ef8275 100644 --- a/indra/llui/llfolderview.cpp +++ b/indra/llui/llfolderview.cpp @@ -193,7 +193,6 @@ LLFolderView::LLFolderView(const Params& p) mViewModel(p.view_model), mGroupedItemModel(p.grouped_item_model) { - claimMem(mViewModel); LLPanel* panel = p.parent_panel; mParentPanel = panel->getHandle(); mViewModel->setFolderView(this); @@ -340,11 +339,9 @@ S32 LLFolderView::arrange( S32* unused_width, S32* unused_height ) return ll_round(mTargetHeight); } -static LLTrace::BlockTimerStatHandle FTM_FILTER("Filter Folder View"); - void LLFolderView::filter( LLFolderViewFilter& filter ) { - LL_RECORD_BLOCK_TIME(FTM_FILTER); + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; static LLUICachedControl<S32> time_visible("FilterItemsMaxTimePerFrameVisible", 10); static LLUICachedControl<S32> time_invisible("FilterItemsMaxTimePerFrameUnvisible", 1); filter.resetTime(llclamp(mParentPanel.get()->getVisible() ? time_visible() : time_invisible(), 1, 100)); @@ -506,10 +503,9 @@ BOOL LLFolderView::changeSelection(LLFolderViewItem* selection, BOOL selected) return rv; } -static LLTrace::BlockTimerStatHandle FTM_SANITIZE_SELECTION("Sanitize Selection"); void LLFolderView::sanitizeSelection() { - LL_RECORD_BLOCK_TIME(FTM_SANITIZE_SELECTION); + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; // store off current item in case it is automatically deselected // and we want to preserve context LLFolderViewItem* original_selected_item = getCurSelectedItem(); @@ -743,7 +739,7 @@ void LLFolderView::closeRenamer( void ) if (mRenamer && mRenamer->getVisible()) { // Triggers onRenamerLost() that actually closes the renamer. - LLUI::getInstanceFast()->removePopup(mRenamer); + LLUI::getInstance()->removePopup(mRenamer); } } @@ -921,7 +917,7 @@ BOOL LLFolderView::canCopy() const void LLFolderView::copy() { // *NOTE: total hack to clear the inventory clipboard - LLClipboard::instanceFast().reset(); + LLClipboard::instance().reset(); S32 count = mSelectedItems.size(); if(getVisible() && getEnabled() && (count > 0)) { @@ -965,7 +961,7 @@ BOOL LLFolderView::canCut() const void LLFolderView::cut() { // clear the inventory clipboard - LLClipboard::instanceFast().reset(); + LLClipboard::instance().reset(); if(getVisible() && getEnabled() && (mSelectedItems.size() > 0)) { // Find out which item will be selected once the selection will be cut @@ -1080,7 +1076,7 @@ void LLFolderView::startRenamingSelectedItem( void ) // set focus will fail unless item is visible mRenamer->setFocus( TRUE ); mRenamer->setTopLostCallback(boost::bind(&LLFolderView::onRenamerLost, this)); - LLUI::getInstanceFast()->addPopup(mRenamer); + LLUI::getInstance()->addPopup(mRenamer); } } @@ -1463,12 +1459,12 @@ BOOL LLFolderView::handleRightMouseDown( S32 x, S32 y, MASK mask ) mEnableRegistrar->pushScope(); } llassert(LLMenuGL::sMenuContainer != NULL); - menu = LLUICtrlFactory::getInstanceFast()->createFromFile<LLMenuGL>(mMenuFileName, LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instanceFast()); + menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>(mMenuFileName, LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance()); if (!menu) { menu = LLUICtrlFactory::getDefaultWidget<LLMenuGL>("inventory_menu"); } - menu->setBackgroundColor(LLUIColorTable::instanceFast().getColor("MenuPopupBgColor")); + menu->setBackgroundColor(LLUIColorTable::instance().getColor("MenuPopupBgColor")); mPopupMenuHandle = menu->getHandle(); if (mEnableRegistrar) { @@ -1666,7 +1662,6 @@ void LLFolderView::setShowSingleSelection(bool show) } } -static LLTrace::BlockTimerStatHandle FTM_AUTO_SELECT("Open and Select"); static LLTrace::BlockTimerStatHandle FTM_INVENTORY("Inventory"); // Main idle routine @@ -1674,7 +1669,7 @@ void LLFolderView::update() { // If this is associated with the user's inventory, don't do anything // until that inventory is loaded up. - LL_RECORD_BLOCK_TIME(FTM_INVENTORY); + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; //LL_RECORD_BLOCK_TIME(FTM_INVENTORY); // If there's no model, the view is in suspended state (being deleted) and shouldn't be updated if (getFolderViewModel() == NULL) @@ -1702,7 +1697,6 @@ void LLFolderView::update() // automatically show matching items, and select first one if we had a selection if (mNeedsAutoSelect) { - LL_RECORD_BLOCK_TIME(FTM_AUTO_SELECT); // select new item only if a filtered item not currently selected and there was a selection LLFolderViewItem* selected_itemp = mSelectedItems.empty() ? NULL : mSelectedItems.back(); if (!mAutoSelectOverride && selected_itemp && !selected_itemp->getViewModelItem()->potentiallyVisible()) diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp index 918c883d1bd8c8081963fff133c2d1aba85f37c3..77b99f22e680de4d3cb39135d11e02d904d8e34b 100644 --- a/indra/llui/llfolderviewitem.cpp +++ b/indra/llui/llfolderviewitem.cpp @@ -746,7 +746,7 @@ void LLFolderViewItem::drawOpenFolderArrow(const Params& default_params, const L /*virtual*/ bool LLFolderViewItem::isFadeItem() { - LLClipboard& clipboard = LLClipboard::instanceFast(); + LLClipboard& clipboard = LLClipboard::instance(); if (mCutGeneration != clipboard.getGeneration()) { mCutGeneration = clipboard.getGeneration(); diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h index 923faf3331387011198087aa517e5aaeea8f3d16..3618a866b9efa2b63902405cd08ead075fead051 100644 --- a/indra/llui/llfolderviewmodel.h +++ b/indra/llui/llfolderviewmodel.h @@ -109,11 +109,10 @@ class LLFolderViewFilter virtual S32 getFirstRequiredGeneration() const = 0; }; -class LLFolderViewModelInterface : public LLTrace::MemTrackable<LLFolderViewModelInterface> +class LLFolderViewModelInterface { public: LLFolderViewModelInterface() - : LLTrace::MemTrackable<LLFolderViewModelInterface>("LLFolderViewModelInterface") {} virtual ~LLFolderViewModelInterface() = default; @@ -134,11 +133,10 @@ class LLFolderViewModelInterface : public LLTrace::MemTrackable<LLFolderViewMode // This is an abstract base class that users of the folderview classes // would use to bridge the folder view with the underlying data -class LLFolderViewModelItem : public LLRefCount, public LLTrace::MemTrackable<LLFolderViewModelItem> +class LLFolderViewModelItem : public LLRefCount { public: LLFolderViewModelItem() - : LLTrace::MemTrackable<LLFolderViewModelItem>("LLFolderViewModelItem") {} virtual ~LLFolderViewModelItem() = default; diff --git a/indra/llui/llfunctorregistry.h b/indra/llui/llfunctorregistry.h index 9e2ced38c9dd660276cf1e9e942bbc61aef846d0..25ffc975b7ff4efafd5c2ec585cbd3cebdd22641 100644 --- a/indra/llui/llfunctorregistry.h +++ b/indra/llui/llfunctorregistry.h @@ -132,7 +132,7 @@ class LLFunctorRegistration public: LLFunctorRegistration(const std::string& name, FUNCTOR_TYPE functor) { - LLFunctorRegistry<FUNCTOR_TYPE>::instanceFast().registerFunctor(name, functor); + LLFunctorRegistry<FUNCTOR_TYPE>::instance().registerFunctor(name, functor); } }; diff --git a/indra/llui/lliconctrl.cpp b/indra/llui/lliconctrl.cpp index 82b01e705dce945f4d7d366b463c4a03daa5b4a5..e01aba402e50ccb7a8f73679cc59fce1ded48094 100644 --- a/indra/llui/lliconctrl.cpp +++ b/indra/llui/lliconctrl.cpp @@ -35,6 +35,7 @@ #include "llui.h" #include "lluictrlfactory.h" #include "lluiimage.h" +#include "llwindow.h" static LLDefaultChildRegistry::Register<LLIconCtrl> r("icon"); @@ -42,6 +43,7 @@ LLIconCtrl::Params::Params() : image("image_name"), color("color"), use_draw_context_alpha("use_draw_context_alpha", true), + interactable("interactable", false), scale_image("scale_image"), min_width("min_width", 0), min_height("min_height", 0) @@ -52,6 +54,7 @@ LLIconCtrl::LLIconCtrl(const LLIconCtrl::Params& p) mColor(p.color()), mImagep(p.image), mUseDrawContextAlpha(p.use_draw_context_alpha), + mInteractable(p.interactable), mPriority(0), mMinWidth(p.min_width), mMinHeight(p.min_height), @@ -81,6 +84,16 @@ void LLIconCtrl::draw() LLUICtrl::draw(); } +BOOL LLIconCtrl::handleHover(S32 x, S32 y, MASK mask) +{ + if (mInteractable && getEnabled()) + { + getWindow()->setCursor(UI_CURSOR_HAND); + return TRUE; + } + return LLUICtrl::handleHover(x, y, mask); +} + // virtual // value might be a string or a UUID void LLIconCtrl::setValue(const LLSD& value) diff --git a/indra/llui/lliconctrl.h b/indra/llui/lliconctrl.h index dd83e78fd33e3cf413c4939fb0665f226357794f..9c3b517bca8d4451f1d7d4ae16345026282ca1fe 100644 --- a/indra/llui/lliconctrl.h +++ b/indra/llui/lliconctrl.h @@ -48,7 +48,8 @@ class LLIconCtrl { Optional<LLUIImage*> image; Optional<LLUIColor> color; - Optional<bool> use_draw_context_alpha; + Optional<bool> use_draw_context_alpha, + interactable; Optional<S32> min_width, min_height; Ignored scale_image; @@ -67,6 +68,9 @@ class LLIconCtrl // llview overrides virtual void draw(); + // llview overrides + virtual BOOL handleHover(S32 x, S32 y, MASK mask); + // lluictrl overrides virtual void setValue(const LLSD& value ); @@ -88,6 +92,7 @@ class LLIconCtrl // If set to true (default), use the draw context transparency. // If false, will use transparency returned by getCurrentTransparency(). See STORM-698. bool mUseDrawContextAlpha; + bool mInteractable; private: LLUIColor mColor; diff --git a/indra/llui/llkeywords.cpp b/indra/llui/llkeywords.cpp index 23daa2ca05298fd46883d556777e4406c8bafe12..e3275762200832b44f8ae7a10aa16d774134aff4 100644 --- a/indra/llui/llkeywords.cpp +++ b/indra/llui/llkeywords.cpp @@ -183,14 +183,14 @@ LLColor4 LLKeywords::getColorGroup(std::string_view key_in) static std::vector<LLUIColor> script_colors; if (script_colors.empty()) { - script_colors.push_back(LLUIColorTable::instanceFast().getColor("ScriptText")); - script_colors.push_back(LLUIColorTable::instanceFast().getColor("SyntaxLslFunction")); - script_colors.push_back(LLUIColorTable::instanceFast().getColor("SyntaxLslControlFlow")); - script_colors.push_back(LLUIColorTable::instanceFast().getColor("SyntaxLslEvent")); - script_colors.push_back(LLUIColorTable::instanceFast().getColor("SyntaxLslDataType")); - script_colors.push_back(LLUIColorTable::instanceFast().getColor("SyntaxLslDeprecated")); - script_colors.push_back(LLUIColorTable::instanceFast().getColor("SyntaxLslGodMode")); - script_colors.push_back(LLUIColorTable::instanceFast().getColor("SyntaxLslConstant")); + script_colors.push_back(LLUIColorTable::instance().getColor("ScriptText")); + script_colors.push_back(LLUIColorTable::instance().getColor("SyntaxLslFunction")); + script_colors.push_back(LLUIColorTable::instance().getColor("SyntaxLslControlFlow")); + script_colors.push_back(LLUIColorTable::instance().getColor("SyntaxLslEvent")); + script_colors.push_back(LLUIColorTable::instance().getColor("SyntaxLslDataType")); + script_colors.push_back(LLUIColorTable::instance().getColor("SyntaxLslDeprecated")); + script_colors.push_back(LLUIColorTable::instance().getColor("SyntaxLslGodMode")); + script_colors.push_back(LLUIColorTable::instance().getColor("SyntaxLslConstant")); } if (key_in == "functions") @@ -253,7 +253,7 @@ void LLKeywords::processTokens() } // Add 'standard' stuff: Quotes, Comments, Strings, Labels, etc. before processing the LLSD - static LLUIColor syntax_lsl_comment_color = LLUIColorTable::instanceFast().getColor("SyntaxLslComment"); + static LLUIColor syntax_lsl_comment_color = LLUIColorTable::instance().getColor("SyntaxLslComment"); std::string delimiter; addToken(LLKeywordToken::TT_LABEL, "@", getColorGroup("misc-flow-label"), "Label\nTarget for jump statement", delimiter ); addToken(LLKeywordToken::TT_ONE_SIDED_DELIMITER, "//", syntax_lsl_comment_color, "Comment (single-line)\nNon-functional commentary or disabled code", delimiter ); diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp index c1d74b7bc3e3e33038dd50678a4f06654936a33a..dad94168f1d3aeca23c7b9938601609018b772e7 100644 --- a/indra/llui/lllayoutstack.cpp +++ b/indra/llui/lllayoutstack.cpp @@ -210,7 +210,7 @@ LLLayoutStack::Params::Params() open_time_constant("open_time_constant", 0.02f), close_time_constant("close_time_constant", 0.03f), resize_bar_overlap("resize_bar_overlap", 1), - border_size("border_size", LLUI::getInstanceFast()->mSettingGroups["config"]->getS32("UIResizeBarHeight")), + border_size("border_size", LLUI::getInstance()->mSettingGroups["config"]->getS32("UIResizeBarHeight")), show_drag_handle("show_drag_handle", false), drag_handle_first_indent("drag_handle_first_indent", 0), drag_handle_second_indent("drag_handle_second_indent", 0), @@ -341,8 +341,6 @@ void LLLayoutStack::collapsePanel(LLPanel* panel, BOOL collapsed) mNeedsLayout = true; } -static LLTrace::BlockTimerStatHandle FTM_UPDATE_LAYOUT("Update LayoutStacks"); - class LLImagePanel : public LLPanel { public: @@ -370,7 +368,7 @@ class LLImagePanel : public LLPanel void LLLayoutStack::updateLayout() { - LL_RECORD_BLOCK_TIME(FTM_UPDATE_LAYOUT); + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; if (!mNeedsLayout) return; @@ -399,7 +397,6 @@ void LLLayoutStack::updateLayout() space_to_distribute += panelp ? ll_round((F32)mPanelSpacing * panelp->getVisibleAmount()) : 0; S32 remaining_space = space_to_distribute; -// F32 fraction_distributed = 0.f; if (space_to_distribute > 0 && total_visible_fraction > 0.f) { // give space proportionally to visible auto resize panels for (LLLayoutPanel* panelp : mPanels) @@ -408,7 +405,6 @@ void LLLayoutStack::updateLayout() { F32 fraction_to_distribute = (panelp->mFractionalSize * panelp->getAutoResizeFactor()) / (total_visible_fraction); S32 delta = ll_round((F32)space_to_distribute * fraction_to_distribute); -// fraction_distributed += fraction_to_distribute; panelp->mTargetDim += delta; remaining_space -= delta; } @@ -567,11 +563,11 @@ void LLLayoutStack::createResizeBar(LLLayoutPanel* panelp) resize_bar_bg_panel_p.follows.flags = FOLLOWS_ALL; resize_bar_bg_panel_p.tab_stop = false; resize_bar_bg_panel_p.background_visible = true; - resize_bar_bg_panel_p.bg_alpha_color = LLUIColorTable::instanceFast().getColor("ResizebarBody"); + resize_bar_bg_panel_p.bg_alpha_color = LLUIColorTable::instance().getColor("ResizebarBody"); resize_bar_bg_panel_p.has_border = true; resize_bar_bg_panel_p.border.border_thickness = 1; - resize_bar_bg_panel_p.border.highlight_light_color = LLUIColorTable::instanceFast().getColor("ResizebarBorderLight"); - resize_bar_bg_panel_p.border.shadow_dark_color = LLUIColorTable::instanceFast().getColor("ResizebarBorderDark"); + resize_bar_bg_panel_p.border.highlight_light_color = LLUIColorTable::instance().getColor("ResizebarBorderLight"); + resize_bar_bg_panel_p.border.shadow_dark_color = LLUIColorTable::instance().getColor("ResizebarBorderDark"); LLPanel* resize_bar_bg_panel = LLUICtrlFactory::create<LLPanel>(resize_bar_bg_panel_p); diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index 0a2ef245936a4a03f4f0d56ac9564bebe853f208..224f45fa174be6ec1e690eeb1dbbc3f276d0c820 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -606,7 +606,7 @@ void LLLineEditor::addToDictionary() { if (canAddToDictionary()) { - LLSpellChecker::instanceFast().addToCustomDictionary(getMisspelledWord(mCursorPos)); + LLSpellChecker::instance().addToCustomDictionary(getMisspelledWord(mCursorPos)); } } @@ -619,7 +619,7 @@ void LLLineEditor::addToIgnore() { if (canAddToIgnore()) { - LLSpellChecker::instanceFast().addToIgnoreList(getMisspelledWord(mCursorPos)); + LLSpellChecker::instance().addToIgnoreList(getMisspelledWord(mCursorPos)); } } @@ -1252,7 +1252,7 @@ void LLLineEditor::copy() BOOL LLLineEditor::canPaste() const { - return !mReadOnly && LLClipboard::instanceFast().isTextAvailable(); + return !mReadOnly && LLClipboard::instance().isTextAvailable(); } void LLLineEditor::paste() @@ -1375,7 +1375,7 @@ void LLLineEditor::copyPrimary() BOOL LLLineEditor::canPastePrimary() const { - return !mReadOnly && LLClipboard::instanceFast().isTextAvailable(true); + return !mReadOnly && LLClipboard::instance().isTextAvailable(true); } void LLLineEditor::updatePrimary() @@ -2002,7 +2002,7 @@ void LLLineEditor::draw() // Don't process words shorter than 3 characters std::string word = wstring_to_utf8str(text.substr(word_start, word_end - word_start)); - if ( (word.length() >= 3) && (!LLSpellChecker::instanceFast().checkSpelling(word)) ) + if ( (word.length() >= 3) && (!LLSpellChecker::instance().checkSpelling(word)) ) { mMisspellRanges.push_back(std::pair<U32, U32>(start + word_start, start + word_end)); } @@ -2699,7 +2699,7 @@ void LLLineEditor::showContextMenu(S32 x, S32 y) std::string misspelled_word = getMisspelledWord(mCursorPos); if ((is_misspelled = !misspelled_word.empty()) == true) { - LLSpellChecker::instanceFast().getSuggestions(misspelled_word, mSuggestionList); + LLSpellChecker::instance().getSuggestions(misspelled_word, mSuggestionList); } } diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index 371bc3501d96aa7c0b10ecc2ac072be891f8b73a..44681bfeb937609de66ee365dce86506fce0a6c6 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -1360,6 +1360,9 @@ class LLMenuItemBranchDownGL : public LLMenuItemBranchGL virtual BOOL handleKeyHere(KEY key, MASK mask); virtual BOOL handleAcceleratorKey(KEY key, MASK mask); + + virtual void onFocusLost(); + virtual void setFocus(BOOL b); }; LLMenuItemBranchDownGL::LLMenuItemBranchDownGL( const Params& p) : @@ -1514,6 +1517,21 @@ BOOL LLMenuItemBranchDownGL::handleAcceleratorKey(KEY key, MASK mask) return handled; } +void LLMenuItemBranchDownGL::onFocusLost() +{ + // needed for tab-based selection + LLMenuItemBranchGL::onFocusLost(); + LLMenuGL::setKeyboardMode(FALSE); + setHighlight(FALSE); +} + +void LLMenuItemBranchDownGL::setFocus(BOOL b) +{ + // needed for tab-based selection + LLMenuItemBranchGL::setFocus(b); + LLMenuGL::setKeyboardMode(b); + setHighlight(b); +} BOOL LLMenuItemBranchDownGL::handleKeyHere(KEY key, MASK mask) { @@ -3932,8 +3950,8 @@ void LLTearOffMenu::draw() { // animate towards target height reshape(getRect().getWidth(), llceil(ll_lerp((F32)getRect().getHeight(), (F32)mTargetHeight, LLSmoothInterpolation::getInterpolant(0.05f)))); - mMenu->needsArrange(); } + mMenu->needsArrange(); LLFloater::draw(); } diff --git a/indra/llui/llmodaldialog.cpp b/indra/llui/llmodaldialog.cpp index fd67259fdad8ae5334fd74503e46095ece3c026b..661ebc64157bb5b96b6f5d889d003fcf39c88e6a 100644 --- a/indra/llui/llmodaldialog.cpp +++ b/indra/llui/llmodaldialog.cpp @@ -100,15 +100,25 @@ void LLModalDialog::onOpen(const LLSD& key) if (!sModalStack.empty()) { LLModalDialog* front = sModalStack.front(); - front->setVisible(FALSE); + if (front != this) + { + front->setVisible(FALSE); + } } // This is a modal dialog. It sucks up all mouse and keyboard operations. gFocusMgr.setMouseCapture( this ); - LLUI::getInstanceFast()->addPopup(this); + LLUI::getInstance()->addPopup(this); setFocus(TRUE); - sModalStack.push_front( this ); + std::list<LLModalDialog*>::iterator iter = std::find(sModalStack.begin(), sModalStack.end(), this); + if (iter != sModalStack.end()) + { + // if already present, we want to move it to front. + sModalStack.erase(iter); + } + + sModalStack.push_front(this); } } @@ -147,7 +157,7 @@ void LLModalDialog::setVisible( BOOL visible ) gFocusMgr.setMouseCapture( this ); // The dialog view is a root view - LLUI::getInstanceFast()->addPopup(this); + LLUI::getInstance()->addPopup(this); setFocus( TRUE ); } else @@ -318,7 +328,7 @@ void LLModalDialog::onAppFocusGained() // This is a modal dialog. It sucks up all mouse and keyboard operations. gFocusMgr.setMouseCapture( instance ); instance->setFocus(TRUE); - LLUI::getInstanceFast()->addPopup(instance); + LLUI::getInstance()->addPopup(instance); instance->centerOnScreen(); } diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index b5276cbf491e1ee4b66b9dd7a48ed5219f7e3d66..d0d40d28107ee13b38ac50f232dd5a3854a85c27 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -131,7 +131,7 @@ bool handleIgnoredNotification(const LLSD& payload) response = pNotif->getResponseTemplate(LLNotification::WITH_DEFAULT_BUTTON); break; case LLNotificationForm::IGNORE_WITH_LAST_RESPONSE: - response = LLUI::getInstanceFast()->mSettingGroups["ignores"]->getLLSD("Default" + pNotif->getName()); + response = LLUI::getInstance()->mSettingGroups["ignores"]->getLLSD("Default" + pNotif->getName()); break; case LLNotificationForm::IGNORE_SHOW_AGAIN: break; @@ -199,7 +199,7 @@ LLNotificationForm::LLNotificationForm(const std::string& name, const LLNotifica // For all cases but IGNORE_CHECKBOX_ONLY this is name for use in preferences mIgnoreMsg = p.ignore.text; - LLUI *ui_inst = LLUI::getInstanceFast(); + LLUI *ui_inst = LLUI::getInstance(); if (p.ignore.checkbox_only) { mIgnore = IGNORE_CHECKBOX_ONLY; @@ -426,7 +426,7 @@ LLNotificationTemplate::LLNotificationTemplate(const LLNotificationTemplate::Par mSoundName("") { if (p.sound.isProvided() - && LLUI::getInstanceFast()->mSettingGroups["config"]->controlExists(p.sound.getValue())) + && LLUI::getInstance()->mSettingGroups["config"]->controlExists(p.sound.getValue())) { mSoundName = p.sound; } @@ -694,7 +694,7 @@ void LLNotification::respond(const LLSD& response) mForm->setIgnored(mIgnored); if (mIgnored && mForm->getIgnoreType() == LLNotificationForm::IGNORE_WITH_LAST_RESPONSE) { - LLUI::getInstanceFast()->mSettingGroups["ignores"]->setLLSD(absl::StrCat("Default", getName()), response); + LLUI::getInstance()->mSettingGroups["ignores"]->setLLSD(absl::StrCat("Default", getName()), response); } } @@ -1380,7 +1380,7 @@ bool LLNotifications::failedUniquenessTest(const LLSD& payload) LLNotificationChannelPtr LLNotifications::getChannel(const std::string& channelName) { - return LLNotificationChannelPtr(LLNotificationChannel::getInstance(channelName)); + return LLNotificationChannelPtr(LLNotificationChannel::getInstance(channelName).get()); } diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp index 91f4f1d29aba883119e8e6bac26e5dd199b94480..475a27247bc27fbbb28bd54cf539edc8d31062b9 100644 --- a/indra/llui/llpanel.cpp +++ b/indra/llui/llpanel.cpp @@ -398,7 +398,7 @@ LLView* LLPanel::fromXML(LLXMLNodePtr node, LLView* parent, LLXMLNodePtr output_ if(!class_attr.empty()) { - panelp = LLRegisterPanelClass::instanceFast().createPanelClass(class_attr); + panelp = LLRegisterPanelClass::instance().createPanelClass(class_attr); if (!panelp) { LL_WARNS() << "Panel class \"" << class_attr << "\" not registered." << LL_ENDL; @@ -518,7 +518,7 @@ BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr outpu setXMLFilename(xml_filename); } - auto& uictrl_factory = LLUICtrlFactory::instanceFast(); + auto& uictrl_factory = LLUICtrlFactory::instance(); LLXUIParser parser; @@ -550,7 +550,7 @@ BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr outpu // add children using dimensions from referenced xml for consistent layout setShape(params.rect); - LLUICtrlFactory::createChildren(this, referenced_xml, child_registry_t::instanceFast()); + LLUICtrlFactory::createChildren(this, referenced_xml, child_registry_t::instance()); uictrl_factory.popFileName(); } @@ -574,7 +574,7 @@ BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr outpu } // add children - LLUICtrlFactory::createChildren(this, node, child_registry_t::instanceFast(), output_node); + LLUICtrlFactory::createChildren(this, node, child_registry_t::instance(), output_node); // Connect to parent after children are built, because tab containers // do a reshape() on their child panels, which requires that the children @@ -609,7 +609,7 @@ std::string LLPanel::getString(std::string_view name, const LLStringUtil::format return formatted_string.getString(); } std::string err_str = absl::StrCat("Failed to find string ", name, " in panel ", getName()); //*TODO: Translate - if(LLUI::getInstanceFast()->mSettingGroups["config"]->getBOOL("QAMode")) + if(LLUI::getInstance()->mSettingGroups["config"]->getBOOL("QAMode")) { LL_ERRS() << err_str << LL_ENDL; } @@ -628,7 +628,7 @@ std::string LLPanel::getString(std::string_view name) const return found_it->second; } std::string err_str = absl::StrCat("Failed to find string ", name, " in panel ", getName()); //*TODO: Translate - if(LLUI::getInstanceFast()->mSettingGroups["config"]->getBOOL("QAMode")) + if(LLUI::getInstance()->mSettingGroups["config"]->getBOOL("QAMode")) { LL_ERRS() << err_str << LL_ENDL; } @@ -800,14 +800,12 @@ boost::signals2::connection LLPanel::setVisibleCallback( const commit_signal_t:: return mVisibleSignal->connect(cb); } -static LLTrace::BlockTimerStatHandle FTM_BUILD_PANELS("Build Panels"); - //----------------------------------------------------------------------------- // buildPanel() //----------------------------------------------------------------------------- BOOL LLPanel::buildFromFile(const std::string& filename, const LLPanel::Params& default_params) { - LL_RECORD_BLOCK_TIME(FTM_BUILD_PANELS); + LL_PROFILE_ZONE_SCOPED; BOOL didPost = FALSE; LLXMLNodePtr root; @@ -828,7 +826,7 @@ BOOL LLPanel::buildFromFile(const std::string& filename, const LLPanel::Params& LL_DEBUGS() << "Building panel " << filename << LL_ENDL; #endif - LLUICtrlFactory::instanceFast().pushFileName(filename); + LLUICtrlFactory::instance().pushFileName(filename); { if (!getFactoryMap().empty()) { @@ -851,7 +849,7 @@ BOOL LLPanel::buildFromFile(const std::string& filename, const LLPanel::Params& sFactoryStack.pop_back(); } } - LLUICtrlFactory::instanceFast().popFileName(); + LLUICtrlFactory::instance().popFileName(); return didPost; } diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h index 772b6f20ce9ac690c07cd9d78916dc300a9f9d8d..71dd64db31c54d8d85af4180d6973627b13f0f9c 100644 --- a/indra/llui/llpanel.h +++ b/indra/llui/llpanel.h @@ -310,7 +310,7 @@ template<typename T> template<typename T> LLPanelInjector<T>::LLPanelInjector(const std::string& tag) { - LLRegisterPanelClass::instanceFast().addPanelClass(tag,&LLRegisterPanelClass::defaultPanelClassBuilder<T>); + LLRegisterPanelClass::instance().addPanelClass(tag,&LLRegisterPanelClass::defaultPanelClassBuilder<T>); } void set_child_visible(LLView* parent, const std::string& child_name, bool visible); diff --git a/indra/llui/llprogressbar.cpp b/indra/llui/llprogressbar.cpp index 209796565c7410cc197cfdcef40e2e632ea4513c..cf57b1fe76e0030277690bfd88228af162f2afda 100644 --- a/indra/llui/llprogressbar.cpp +++ b/indra/llui/llprogressbar.cpp @@ -69,16 +69,22 @@ void LLProgressBar::draw() static LLTimer timer; F32 alpha = getDrawContext().mAlpha; - LLColor4 image_bar_color = mColorBackground.get(); - image_bar_color.setAlpha(alpha); - mImageBar->draw(getLocalRect(), image_bar_color); + if (mImageBar) // optional according to parameters + { + LLColor4 image_bar_color = mColorBackground.get(); + image_bar_color.setAlpha(alpha); + mImageBar->draw(getLocalRect(), image_bar_color); + } - alpha *= 0.5f + 0.5f*0.5f*(1.f + (F32)sin(3.f*timer.getElapsedTimeF32())); - LLColor4 bar_color = mColorBar.get(); - bar_color.mV[VALPHA] *= alpha; // modulate alpha - LLRect progress_rect = getLocalRect(); - progress_rect.mRight = ll_round(getRect().getWidth() * (mPercentDone / 100.f)); - mImageFill->draw(progress_rect, bar_color); + if (mImageFill) + { + alpha *= 0.5f + 0.5f*0.5f*(1.f + (F32)sin(3.f*timer.getElapsedTimeF32())); + LLColor4 bar_color = mColorBar.get(); + bar_color.mV[VALPHA] *= alpha; // modulate alpha + LLRect progress_rect = getLocalRect(); + progress_rect.mRight = ll_round(getRect().getWidth() * (mPercentDone / 100.f)); + mImageFill->draw(progress_rect, bar_color); + } } void LLProgressBar::setValue(const LLSD& value) diff --git a/indra/llui/llscrollbar.cpp b/indra/llui/llscrollbar.cpp index bdaf6572acb0c8a0adc5b99eefd19a6696b2bc01..42c628adab5b7ba975bf48e2107a94124eb8b2dc 100644 --- a/indra/llui/llscrollbar.cpp +++ b/indra/llui/llscrollbar.cpp @@ -84,7 +84,7 @@ LLScrollbar::LLScrollbar(const Params & p) mThumbImageH(p.thumb_image_horizontal), mTrackImageV(p.track_image_vertical), mTrackImageH(p.track_image_horizontal), - mThickness(p.thickness.isProvided() ? p.thickness : LLUI::getInstanceFast()->mSettingGroups["config"]->getS32("UIScrollbarSize")), + mThickness(p.thickness.isProvided() ? p.thickness : LLUI::getInstance()->mSettingGroups["config"]->getS32("UIScrollbarSize")), mBGVisible(p.bg_visible), mBGColor(p.bg_color) { @@ -659,5 +659,5 @@ void LLScrollbar::onLineDownBtnPressed( const LLSD& data ) void LLScrollbar::setThickness(S32 thickness) { - mThickness = thickness < 0 ? LLUI::getInstanceFast()->mSettingGroups["config"]->getS32("UIScrollbarSize") : thickness; + mThickness = thickness < 0 ? LLUI::getInstance()->mSettingGroups["config"]->getS32("UIScrollbarSize") : thickness; } diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index 33834889acc8da21456c9a8535e27067e4153ffb..1fe64993af27fc01b12a30f3732a23017719e730 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -1397,6 +1397,84 @@ BOOL LLScrollListCtrl::selectItemByPrefix(const LLWString& target, BOOL case_sen return found; } +U32 LLScrollListCtrl::searchItems(const std::string& substring, bool case_sensitive, bool focus) +{ + return searchItems(utf8str_to_wstring(substring), case_sensitive, focus); +} + +U32 LLScrollListCtrl::searchItems(const LLWString& substring, bool case_sensitive, bool focus) +{ + U32 found = 0; + + LLWString substring_trimmed(substring); + S32 len = substring_trimmed.size(); + + if (0 == len) + { + // at the moment search for empty element is not supported + return 0; + } + else + { + deselectAllItems(TRUE); + if (!case_sensitive) + { + // do comparisons in lower case + LLWStringUtil::toLower(substring_trimmed); + } + + for (item_list::iterator iter = mItemList.begin(); iter != mItemList.end(); iter++) + { + LLScrollListItem* item = *iter; + // Only select enabled items with matching names + if (!item->getEnabled()) + { + continue; + } + LLScrollListCell* cellp = item->getColumn(getSearchColumn()); + if (!cellp) + { + continue; + } + LLWString item_label = utf8str_to_wstring(cellp->getValue().asString()); + if (!case_sensitive) + { + LLWStringUtil::toLower(item_label); + } + // remove extraneous whitespace from searchable label + LLWStringUtil::trim(item_label); + + size_t found_iter = item_label.find(substring_trimmed); + + if (found_iter != std::string::npos) + { + // find offset of matching text + cellp->highlightText(found_iter, substring_trimmed.size()); + selectItem(item, -1, FALSE); + + found++; + + if (!mAllowMultipleSelection) + { + break; + } + } + } + } + + if (focus && found != 0) + { + mNeedsScroll = true; + } + + if (mCommitOnSelectionChange) + { + commitIfChanged(); + } + + return found; +} + const std::string LLScrollListCtrl::getSelectedItemLabel(S32 column) const { LLScrollListItem* item; @@ -1736,7 +1814,7 @@ BOOL LLScrollListCtrl::handleToolTip(S32 x, S32 y, MASK mask) localRectToScreen(cell_rect, &sticky_rect); // display tooltip exactly over original cell, in same font - LLToolTipMgr::instanceFast().show(LLToolTip::Params() + LLToolTipMgr::instance().show(LLToolTip::Params() .message(hit_cell->getToolTip()) .font(LLFontGL::getFontSansSerifSmall()) .pos(LLCoordGL(sticky_rect.mLeft - 5, sticky_rect.mTop + 6)) @@ -1924,6 +2002,7 @@ BOOL LLScrollListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask) registrar.add("Url.SendIM", boost::bind(&LLScrollListCtrl::sendIM, id)); registrar.add("Url.AddFriend", boost::bind(&LLScrollListCtrl::addFriend, id)); registrar.add("Url.RemoveFriend", boost::bind(&LLScrollListCtrl::removeFriend, id)); + registrar.add("Url.ReportAbuse", boost::bind(&LLScrollListCtrl::reportAbuse, id, is_group)); registrar.add("Url.Execute", boost::bind(&LLScrollListCtrl::showNameDetails, id, is_group)); registrar.add("Url.CopyLabel", boost::bind(&LLScrollListCtrl::copyNameToClipboard, id, is_group)); registrar.add("Url.CopyUrl", boost::bind(&LLScrollListCtrl::copySLURLToClipboard, id, is_group)); @@ -1993,6 +2072,15 @@ void LLScrollListCtrl::removeFriend(std::string id) LLUrlAction::removeFriend(slurl); } +void LLScrollListCtrl::reportAbuse(std::string id, bool is_group) +{ + if (!is_group) + { + std::string slurl = "secondlife:///app/agent/" + id + "/about"; + LLUrlAction::reportAbuse(slurl); + } +} + void LLScrollListCtrl::showNameDetails(std::string id, bool is_group) { // open the resident's details or the group details @@ -3078,10 +3166,9 @@ LLScrollListColumn* LLScrollListCtrl::getColumn(std::string_view name) return NULL; } -LLTrace::BlockTimerStatHandle FTM_ADD_SCROLLLIST_ELEMENT("Add Scroll List Item"); LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& element, EAddPosition pos, void* userdata) { - LL_RECORD_BLOCK_TIME(FTM_ADD_SCROLLLIST_ELEMENT); + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; LLScrollListItem::Params item_params; LLParamSDParser parser; parser.readSD(element, item_params); @@ -3091,14 +3178,14 @@ LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& element, EAddPosition LLScrollListItem* LLScrollListCtrl::addRow(const LLScrollListItem::Params& item_p, EAddPosition pos) { - LL_RECORD_BLOCK_TIME(FTM_ADD_SCROLLLIST_ELEMENT); + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; LLScrollListItem *new_item = new LLScrollListItem(item_p); return addRow(new_item, item_p, pos); } LLScrollListItem* LLScrollListCtrl::addRow(LLScrollListItem *new_item, const LLScrollListItem::Params& item_p, EAddPosition pos) { - LL_RECORD_BLOCK_TIME(FTM_ADD_SCROLLLIST_ELEMENT); + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; if (!item_p.validateBlock() || !new_item) return NULL; new_item->setNumColumns(mColumns.size()); diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index 9a10735945aa08358b5e6c25bf3513b2835f6339..90e91de1c8bbbf488e7c631d5ea7ed968ddc6552 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -268,6 +268,14 @@ class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler, const std::string getSelectedItemLabel(S32 column = 0) const; LLSD getSelectedValue(); + // If multi select is on, select all element that include substring, + // otherwise select first match only. + // If focus is true will scroll to selection. + // Returns number of results. + // Note: at the moment search happens in one go and is expensive + U32 searchItems(const std::string& substring, bool case_sensitive = false, bool focus = true); + U32 searchItems(const LLWString& substring, bool case_sensitive = false, bool focus = true); + // DEPRECATED: Use LLSD versions of setCommentText() and getSelectedValue(). // "StringUUID" interface: use this when you're creating a list that contains non-unique strings each of which // has an associated, unique UUID, and only one of which can be selected at a time. @@ -327,6 +335,7 @@ class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler, // support right-click context menus for avatar/group lists enum ContextMenuType { MENU_NONE, MENU_AVATAR, MENU_GROUP }; void setContextMenu(const ContextMenuType &menu) { mContextMenuType = menu; } + ContextMenuType getContextMenuType() { return mContextMenuType; } // Overridden from LLView /*virtual*/ void draw(); @@ -462,6 +471,7 @@ class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler, static void sendIM(std::string id); static void addFriend(std::string id); static void removeFriend(std::string id); + static void reportAbuse(std::string id, bool is_group); static void showNameDetails(std::string id, bool is_group); static void copyNameToClipboard(std::string id, bool is_group); static void copySLURLToClipboard(std::string id, bool is_group); diff --git a/indra/llui/llspellcheck.cpp b/indra/llui/llspellcheck.cpp index 427eb16b6d6360b6b50851b5418971c381db75b0..a80d577ff070477e5371a752de8bf02579893553 100644 --- a/indra/llui/llspellcheck.cpp +++ b/indra/llui/llspellcheck.cpp @@ -402,7 +402,7 @@ const std::string LLSpellChecker::getDictionaryUserPath() // static bool LLSpellChecker::getUseSpellCheck() { - return LLSpellChecker::instanceFast().mHunspell; + return LLSpellChecker::instance().mHunspell; } bool LLSpellChecker::canRemoveDictionary(const std::string& dict_language) @@ -481,8 +481,8 @@ boost::signals2::connection LLSpellChecker::setSettingsChangeCallback(const sett void LLSpellChecker::setUseSpellCheck(const std::string& dict_language) { if ( (((dict_language.empty()) && (getUseSpellCheck())) || (!dict_language.empty())) && - (LLSpellChecker::instanceFast().mDictLanguage != dict_language) ) + (LLSpellChecker::instance().mDictLanguage != dict_language) ) { - LLSpellChecker::instanceFast().initHunspell(dict_language); + LLSpellChecker::instance().initHunspell(dict_language); } } diff --git a/indra/llui/llspinctrl.cpp b/indra/llui/llspinctrl.cpp index a06ce6c637d6d8341367244efa367bdf78c106b7..4716dc79b8b800da4b9f207f3043e7d4874735bc 100644 --- a/indra/llui/llspinctrl.cpp +++ b/indra/llui/llspinctrl.cpp @@ -103,6 +103,7 @@ LLSpinCtrl::LLSpinCtrl(const LLSpinCtrl::Params& p) up_button_params.rect = LLRect(btn_left, getRect().getHeight(), btn_right, getRect().getHeight() - spinctrl_btn_height); up_button_params.click_callback.function(boost::bind(&LLSpinCtrl::onUpBtn, this, _2)); up_button_params.mouse_held_callback.function(boost::bind(&LLSpinCtrl::onUpBtn, this, _2)); + up_button_params.commit_on_capture_lost = true; mUpBtn = LLUICtrlFactory::create<LLButton>(up_button_params); addChild(mUpBtn); @@ -111,6 +112,7 @@ LLSpinCtrl::LLSpinCtrl(const LLSpinCtrl::Params& p) down_button_params.rect = LLRect(btn_left, getRect().getHeight() - spinctrl_btn_height, btn_right, getRect().getHeight() - 2 * spinctrl_btn_height); down_button_params.click_callback.function(boost::bind(&LLSpinCtrl::onDownBtn, this, _2)); down_button_params.mouse_held_callback.function(boost::bind(&LLSpinCtrl::onDownBtn, this, _2)); + down_button_params.commit_on_capture_lost = true; mDownBtn = LLUICtrlFactory::create<LLButton>(down_button_params); addChild(mDownBtn); diff --git a/indra/llui/llstatbar.cpp b/indra/llui/llstatbar.cpp index 0101868f21f422580ad036a3c5384c3c99b62bfa..43408543be021f540c9f182fba43a7c5572a7881 100644 --- a/indra/llui/llstatbar.cpp +++ b/indra/llui/llstatbar.cpp @@ -160,6 +160,7 @@ LLStatBar::Params::Params() tick_spacing("tick_spacing", 0.f), decimal_digits("decimal_digits", 3), show_bar("show_bar", false), + show_median("show_median", false), show_history("show_history", false), scale_range("scale_range", true), num_frames("num_frames", 200), @@ -186,6 +187,7 @@ LLStatBar::LLStatBar(const Params& p) mNumShortHistoryFrames(p.num_frames_short), mMaxHeight(p.max_height), mDisplayBar(p.show_bar), + mShowMedian(p.show_median), mDisplayHistory(p.show_history), mOrientation(p.orientation), mAutoScaleMax(!p.bar_max.isProvided()), @@ -212,16 +214,16 @@ BOOL LLStatBar::handleHover(S32 x, S32 y, MASK mask) switch(mStatType) { case STAT_COUNT: - LLToolTipMgr::instanceFast().show(LLToolTip::Params().message(mStat.countStatp->getDescription()).sticky_rect(calcScreenRect())); + LLToolTipMgr::instance().show(LLToolTip::Params().message(mStat.countStatp->getDescription()).sticky_rect(calcScreenRect())); break; case STAT_EVENT: - LLToolTipMgr::instanceFast().show(LLToolTip::Params().message(mStat.eventStatp->getDescription()).sticky_rect(calcScreenRect())); + LLToolTipMgr::instance().show(LLToolTip::Params().message(mStat.eventStatp->getDescription()).sticky_rect(calcScreenRect())); break; case STAT_SAMPLE: - LLToolTipMgr::instanceFast().show(LLToolTip::Params().message(mStat.sampleStatp->getDescription()).sticky_rect(calcScreenRect())); + LLToolTipMgr::instance().show(LLToolTip::Params().message(mStat.sampleStatp->getDescription()).sticky_rect(calcScreenRect())); break; case STAT_MEM: - LLToolTipMgr::instanceFast().show(LLToolTip::Params().message(mStat.memStatp->getDescription()).sticky_rect(calcScreenRect())); + LLToolTipMgr::instance().show(LLToolTip::Params().message(mStat.memStatp->getDescription()).sticky_rect(calcScreenRect())); break; default: break; @@ -318,7 +320,14 @@ void LLStatBar::draw() min = frame_recording.getPeriodMinPerSec(count_stat, num_frames); max = frame_recording.getPeriodMaxPerSec(count_stat, num_frames); mean = frame_recording.getPeriodMeanPerSec(count_stat, num_frames); - display_value = mean; + if (mShowMedian) + { + display_value = frame_recording.getPeriodMedianPerSec(count_stat, num_frames); + } + else + { + display_value = mean; + } } break; case STAT_EVENT: @@ -344,7 +353,11 @@ void LLStatBar::draw() mean = frame_recording.getPeriodMean(sample_stat, num_frames); num_rapid_changes = calc_num_rapid_changes(frame_recording, sample_stat, RAPID_CHANGE_WINDOW); - if (num_rapid_changes / RAPID_CHANGE_WINDOW.value() > MAX_RAPID_CHANGES_PER_SEC) + if (mShowMedian) + { + display_value = frame_recording.getPeriodMedian(sample_stat, num_frames); + } + else if (num_rapid_changes / RAPID_CHANGE_WINDOW.value() > MAX_RAPID_CHANGES_PER_SEC) { display_value = mean; } @@ -559,29 +572,25 @@ void LLStatBar::draw() void LLStatBar::setStat(const std::string& stat_name) { using namespace LLTrace; - const StatType<CountAccumulator>* count_stat; - const StatType<EventAccumulator>* event_stat; - const StatType<SampleAccumulator>* sample_stat; - const StatType<MemAccumulator>* mem_stat; - if ((count_stat = StatType<CountAccumulator>::getInstance(stat_name))) + if (auto count_stat = StatType<CountAccumulator>::getInstance(stat_name)) { - mStat.countStatp = count_stat; + mStat.countStatp = count_stat.get(); mStatType = STAT_COUNT; } - else if ((event_stat = StatType<EventAccumulator>::getInstance(stat_name))) + else if (auto event_stat = StatType<EventAccumulator>::getInstance(stat_name)) { - mStat.eventStatp = event_stat; + mStat.eventStatp = event_stat.get(); mStatType = STAT_EVENT; } - else if ((sample_stat = StatType<SampleAccumulator>::getInstance(stat_name))) + else if (auto sample_stat = StatType<SampleAccumulator>::getInstance(stat_name)) { - mStat.sampleStatp = sample_stat; + mStat.sampleStatp = sample_stat.get(); mStatType = STAT_SAMPLE; } - else if ((mem_stat = StatType<MemAccumulator>::getInstance(stat_name))) + else if (auto mem_stat = StatType<MemAccumulator>::getInstance(stat_name)) { - mStat.memStatp = mem_stat; + mStat.memStatp = mem_stat.get(); mStatType = STAT_MEM; } } diff --git a/indra/llui/llstatbar.h b/indra/llui/llstatbar.h index 08bce6ca18551299346c160eebc80b902695018d..37adf51f5b87a0f0302753a8d538da183e6b1bd4 100644 --- a/indra/llui/llstatbar.h +++ b/indra/llui/llstatbar.h @@ -44,9 +44,10 @@ class LLStatBar : public LLView bar_max, tick_spacing; - Optional<bool> show_bar, + Optional<bool> show_bar, show_history, - scale_range; + scale_range, + show_median; // default is mean Optional<S32> decimal_digits, num_frames, @@ -112,6 +113,7 @@ class LLStatBar : public LLView bool mDisplayBar, // Display the bar graph. mDisplayHistory, + mShowMedian, mAutoScaleMax, mAutoScaleMin; }; diff --git a/indra/llui/llstatview.cpp b/indra/llui/llstatview.cpp index 9f2e2f7b0781b58421cf285934ccd8a42d37e3a7..bb4969c81f1d74c2f86c206b909f6fc6872225d7 100644 --- a/indra/llui/llstatview.cpp +++ b/indra/llui/llstatview.cpp @@ -43,7 +43,7 @@ LLStatView::LLStatView(const LLStatView::Params& p) BOOL isopen = getDisplayChildren(); if (mSetting.length() > 0) { - isopen = LLUI::getInstanceFast()->mSettingGroups["config"]->getBOOL(mSetting); + isopen = LLUI::getInstance()->mSettingGroups["config"]->getBOOL(mSetting); } setDisplayChildren(isopen); } @@ -54,7 +54,7 @@ LLStatView::~LLStatView() if (mSetting.length() > 0) { BOOL isopen = getDisplayChildren(); - LLUI::getInstanceFast()->mSettingGroups["config"]->setBOOL(mSetting, isopen); + LLUI::getInstance()->mSettingGroups["config"]->setBOOL(mSetting, isopen); } } diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index b84c85a439b5068f7b76cd53e88235436c3c80a4..b3e40fb2e496c0d59197835686ac754a53921bf7 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -743,7 +743,7 @@ void LLTextBase::drawText(const std::pair<S32, S32>& line_range) std::string word = wstring_to_utf8str(wstrText.substr(word_start, word_end - word_start)); // Don't process words shorter than 3 characters - if ( (word.length() >= 3) && (!LLSpellChecker::instanceFast().checkSpelling(word)) ) + if ( (word.length() >= 3) && (!LLSpellChecker::instance().checkSpelling(word)) ) { mMisspellRanges.push_back(std::pair<U32, U32>(word_start, word_end)); } @@ -1495,7 +1495,7 @@ void LLTextBase::addToDictionary() { if (canAddToDictionary()) { - LLSpellChecker::instanceFast().addToCustomDictionary(getMisspelledWord(mCursorPos)); + LLSpellChecker::instance().addToCustomDictionary(getMisspelledWord(mCursorPos)); } } @@ -1508,7 +1508,7 @@ void LLTextBase::addToIgnore() { if (canAddToIgnore()) { - LLSpellChecker::instanceFast().addToIgnoreList(getMisspelledWord(mCursorPos)); + LLSpellChecker::instance().addToIgnoreList(getMisspelledWord(mCursorPos)); } } @@ -1600,11 +1600,9 @@ S32 LLTextBase::getLeftOffset(S32 width) } } - -static LLTrace::BlockTimerStatHandle FTM_TEXT_REFLOW ("Text Reflow"); void LLTextBase::reflow() { - LL_RECORD_BLOCK_TIME(FTM_TEXT_REFLOW); + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; updateSegments(); @@ -1970,10 +1968,9 @@ void LLTextBase::removeDocumentChild(LLView* view) } -static LLTrace::BlockTimerStatHandle FTM_UPDATE_TEXT_SEGMENTS("Update Text Segments"); void LLTextBase::updateSegments() { - LL_RECORD_BLOCK_TIME(FTM_UPDATE_TEXT_SEGMENTS); + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; createDefaultSegment(); } @@ -2114,7 +2111,7 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url) // work out the XUI menu file to use for this url LLUrlMatch match; std::string url = in_url; - if (! LLUrlRegistry::instanceFast().findUrl(url, match)) + if (! LLUrlRegistry::instance().findUrl(url, match)) { return; } @@ -2138,6 +2135,7 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url) registrar.add("Url.ShowProfile", boost::bind(&LLUrlAction::showProfile, url)); registrar.add("Url.AddFriend", boost::bind(&LLUrlAction::addFriend, url)); registrar.add("Url.RemoveFriend", boost::bind(&LLUrlAction::removeFriend, url)); + registrar.add("Url.ReportAbuse", boost::bind(&LLUrlAction::reportAbuse, url)); registrar.add("Url.SendIM", boost::bind(&LLUrlAction::sendIM, url)); registrar.add("Url.ShowOnMap", boost::bind(&LLUrlAction::showLocationOnMap, url)); registrar.add("Url.CopyLabel", boost::bind(&LLUrlAction::copyLabelToClipboard, url)); @@ -2233,18 +2231,16 @@ static LLUIImagePtr image_from_icon_name(const std::string& icon_name) } } -static LLTrace::BlockTimerStatHandle FTM_PARSE_HTML("Parse HTML"); - - void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Params& input_params) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; LLStyle::Params style_params(input_params); style_params.fillFrom(getStyleParams()); // [SL:KB] - Patch: Control-TextParser | Checked: 2012-07-10 (Catznip-3.3) const LLHighlightEntry* pEntry = NULL; - if ( (mParseHighlights) && (LLTextParser::instanceFast().parseFullLineHighlights(new_text, mHighlightsMask, &pEntry)) ) + if ( (mParseHighlights) && (LLTextParser::instance().parseFullLineHighlights(new_text, mHighlightsMask, &pEntry)) ) { if (mHighlightsSignal) (*mHighlightsSignal)(new_text, pEntry); @@ -2258,11 +2254,10 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para S32 part = (S32)LLTextParser::WHOLE; if (mParseHTML && !style_params.is_link) // Don't search for URLs inside a link segment (STORM-358). { - LL_RECORD_BLOCK_TIME(FTM_PARSE_HTML); S32 start=0,end=0; LLUrlMatch match; std::string text = new_text; - auto& url_reg = LLUrlRegistry::instanceFast(); + auto& url_reg = LLUrlRegistry::instance(); while (url_reg.findUrl(text, match, boost::bind(&LLTextBase::replaceUrl, this, _1, _2, _3),isContentTrusted() || mAlwaysShowIcons)) { @@ -2353,11 +2348,9 @@ void LLTextBase::setLastSegmentToolTip(const std::string &tooltip) } } -static LLTrace::BlockTimerStatHandle FTM_APPEND_TEXT("Append Text"); - void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, const LLStyle::Params& input_params) { - LL_RECORD_BLOCK_TIME(FTM_APPEND_TEXT); + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; if (new_text.empty()) return; @@ -2486,10 +2479,10 @@ void LLTextBase::appendAndHighlightTextImpl(const std::string &new_text, S32 hig { LLStyle::Params highlight_params(style_params); -// LLSD pieces = LLTextParser::instanceFast().parsePartialLineHighlights(new_text, highlight_params.color(), (LLTextParser::EHighlightPosition)highlight_part); +// LLSD pieces = LLTextParser::instance().parsePartialLineHighlights(new_text, highlight_params.color(), (LLTextParser::EHighlightPosition)highlight_part); // for (S32 i = 0; i < pieces.size(); i++) // [SL:KB] - Patch: Control-TextParser | Checked: 2012-07-10 (Catznip-3.3) - LLTextParser::partial_results_t results = LLTextParser::instanceFast().parsePartialLineHighlights(new_text, mHighlightsMask, (LLTextParser::EHighlightPosition)highlight_part); + LLTextParser::partial_results_t results = LLTextParser::instance().parsePartialLineHighlights(new_text, mHighlightsMask, (LLTextParser::EHighlightPosition)highlight_part); for (LLTextParser::partial_results_t::const_iterator itResult = results.begin(); itResult != results.end(); ++itResult) // [/SL:KB] { @@ -3624,13 +3617,13 @@ BOOL LLNormalTextSegment::handleToolTip(S32 x, S32 y, MASK mask) if (mToken && !mToken->getToolTip().empty()) { const LLWString& wmsg = mToken->getToolTip(); - LLToolTipMgr::instanceFast().show(wstring_to_utf8str(wmsg)); + LLToolTipMgr::instance().show(wstring_to_utf8str(wmsg)); return TRUE; } // or do we have an explicitly set tooltip (e.g., for Urls) if (!mTooltip.empty()) { - LLToolTipMgr::instanceFast().show(mTooltip); + LLToolTipMgr::instance().show(mTooltip); return TRUE; } @@ -3970,7 +3963,7 @@ BOOL LLImageTextSegment::handleToolTip(S32 x, S32 y, MASK mask) { if (!mTooltip.empty()) { - LLToolTipMgr::instanceFast().show(mTooltip); + LLToolTipMgr::instance().show(mTooltip); return TRUE; } diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index 8fd549eabf774ad8cee129502579375dd26a1a6f..2484790189c94882f3ff2ef9eeb32fa9b3963605 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -466,6 +466,8 @@ class LLTextBase void setSkipLinkUnderline(bool skip_link_underline) { mSkipLinkUnderline = skip_link_underline; } bool getSkipLinkUnderline() { return mSkipLinkUnderline; } + void setParseURLs(bool parse_urls) { mParseHTML = parse_urls; } + void setPlainText(bool value) { mPlainText = value;} bool getPlainText() const { return mPlainText; } @@ -759,8 +761,8 @@ class LLTextBase bool mPlainText; // didn't use Image or Icon segments bool mAutoIndent; S32 mMaxTextByteLength; // Maximum length mText is allowed to be in bytes - bool mAlwaysShowIcons; bool mSkipTripleClick; + bool mAlwaysShowIcons; bool mSkipLinkUnderline; // support widgets diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index b0478f9b0241510adc9f33bf667252173eee7de0..3290bce938980e1fe5b83bc2cc3dd8c36ec75d69 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -1495,7 +1495,7 @@ void LLTextEditor::copy() BOOL LLTextEditor::canPaste() const { - return !mReadOnly && LLClipboard::instanceFast().isTextAvailable(); + return !mReadOnly && LLClipboard::instance().isTextAvailable(); } // paste from clipboard @@ -1632,7 +1632,7 @@ void LLTextEditor::copyPrimary() BOOL LLTextEditor::canPastePrimary() const { - return !mReadOnly && LLClipboard::instanceFast().isTextAvailable(true); + return !mReadOnly && LLClipboard::instance().isTextAvailable(true); } void LLTextEditor::updatePrimary() @@ -1889,11 +1889,11 @@ BOOL LLTextEditor::handleKeyHere(KEY key, MASK mask ) else { if (mEnableTooltipPaste && - LLToolTipMgr::instanceFast().toolTipVisible() && + LLToolTipMgr::instance().toolTipVisible() && KEY_TAB == key) { // Paste the first line of a tooltip into the editor std::string message; - LLToolTipMgr::instanceFast().getToolTipMessage(message); + LLToolTipMgr::instance().getToolTipMessage(message); LLWString tool_tip_text(utf8str_to_wstring(message)); if (tool_tip_text.size() > 0) @@ -2219,7 +2219,7 @@ void LLTextEditor::showContextMenu(S32 x, S32 y) std::string misspelled_word = getMisspelledWord(mCursorPos); if ((is_misspelled = !misspelled_word.empty()) == true) { - LLSpellChecker::instanceFast().getSuggestions(misspelled_word, mSuggestionList); + LLSpellChecker::instance().getSuggestions(misspelled_word, mSuggestionList); } } @@ -2605,7 +2605,7 @@ void LLTextEditor::updateLinkSegments() const LLWString& wtext = getWText(); // update any segments that contain a link - auto& url_registry = LLUrlRegistry::instanceFast(); + auto& url_registry = LLUrlRegistry::instance(); for (segment_set_t::iterator it = mSegments.begin(); it != mSegments.end(); ++it) { LLTextSegment *segment = *it; @@ -2788,7 +2788,10 @@ bool LLTextEditor::loadFromFile(const std::string& filename) buffer[nread] = '\0'; fclose(file); - setText(LLStringExplicit(buffer)); + std::string text = std::string(buffer); + LLStringUtil::replaceTabsWithSpaces(text, LLTextEditor::spacesPerTab()); + + setText(LLStringExplicit(text)); delete[] buffer; return true; diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h index c7c024cdb47a4c185b91197c70db0969893e3ff1..ff3e38365bc8aaeacabb1ada4d655ac9cea5c77a 100644 --- a/indra/llui/lltexteditor.h +++ b/indra/llui/lltexteditor.h @@ -207,6 +207,7 @@ class LLTextEditor : const LLUUID& getSourceID() const { return mSourceID; } const LLTextSegmentPtr getPreviousSegment() const; + const LLTextSegmentPtr getLastSegment() const; void getSelectedSegments(segment_vec_t& segments) const; void setShowContextMenu(bool show) { mShowContextMenu = show; } diff --git a/indra/llui/lltoolbar.cpp b/indra/llui/lltoolbar.cpp index d8af0a628740514b95d669639cb9354b5c8cec58..235321697fe0b459e69ac21015c82e3f3341740c 100644 --- a/indra/llui/lltoolbar.cpp +++ b/indra/llui/lltoolbar.cpp @@ -176,7 +176,7 @@ void LLToolBar::createContextMenu() // Create the context menu llassert(LLMenuGL::sMenuContainer != NULL); - LLContextMenu* menu = LLUICtrlFactory::createFromFile<LLContextMenu>("menu_toolbars.xml", LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instanceFast()); + LLContextMenu* menu = LLUICtrlFactory::createFromFile<LLContextMenu>("menu_toolbars.xml", LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance()); if (menu) { diff --git a/indra/llui/lltooltip.cpp b/indra/llui/lltooltip.cpp index 73a379cca04b3c53986fbd29c637d1e2c9526d1e..19fdca684626f9abdce722ca311541030bf55493 100644 --- a/indra/llui/lltooltip.cpp +++ b/indra/llui/lltooltip.cpp @@ -65,7 +65,7 @@ LLToolTipView::LLToolTipView(const LLToolTipView::Params& p) void LLToolTipView::draw() { - LLToolTipMgr::instanceFast().updateToolTipVisibility(); + LLToolTipMgr::instance().updateToolTipVisibility(); // do the usual thing LLView::draw(); @@ -76,7 +76,7 @@ BOOL LLToolTipView::handleHover(S32 x, S32 y, MASK mask) static S32 last_x = x; static S32 last_y = y; - LLToolTipMgr& tooltip_mgr = LLToolTipMgr::instanceFast(); + LLToolTipMgr& tooltip_mgr = LLToolTipMgr::instance(); if (x != last_x && y != last_y && !tooltip_mgr.getMouseNearRect().pointInRect(x, y)) { @@ -91,7 +91,7 @@ BOOL LLToolTipView::handleHover(S32 x, S32 y, MASK mask) BOOL LLToolTipView::handleMouseDown(S32 x, S32 y, MASK mask) { - LLToolTipMgr::instanceFast().blockToolTips(); + LLToolTipMgr::instance().blockToolTips(); if (LLView::handleMouseDown(x, y, mask)) { @@ -106,26 +106,26 @@ BOOL LLToolTipView::handleMouseDown(S32 x, S32 y, MASK mask) BOOL LLToolTipView::handleMiddleMouseDown(S32 x, S32 y, MASK mask) { - LLToolTipMgr::instanceFast().blockToolTips(); + LLToolTipMgr::instance().blockToolTips(); return LLView::handleMiddleMouseDown(x, y, mask); } BOOL LLToolTipView::handleRightMouseDown(S32 x, S32 y, MASK mask) { - LLToolTipMgr::instanceFast().blockToolTips(); + LLToolTipMgr::instance().blockToolTips(); return LLView::handleRightMouseDown(x, y, mask); } BOOL LLToolTipView::handleScrollWheel( S32 x, S32 y, S32 clicks ) { - LLToolTipMgr::instanceFast().blockToolTips(); + LLToolTipMgr::instance().blockToolTips(); return FALSE; } void LLToolTipView::drawStickyRect() { - gl_rect_2d(LLToolTipMgr::instanceFast().getMouseNearRect(), LLColor4::white, false); + gl_rect_2d(LLToolTipMgr::instance().getMouseNearRect(), LLColor4::white, false); } // defaults for floater param block pulled from widgets/floater.xml diff --git a/indra/llui/lltrans.cpp b/indra/llui/lltrans.cpp index 03257980dc071a32a828edbaadf6f9d39468d479..93a2a4ca8a6650c6c3e7f3b1b2fc6ebc512fe601 100644 --- a/indra/llui/lltrans.cpp +++ b/indra/llui/lltrans.cpp @@ -150,7 +150,7 @@ std::string LLTrans::getString(std::string_view xml_desc, const LLStringUtil::fo { // Don't care about time as much as call count. Make sure we're not // calling LLTrans::getString() in an inner loop. JC - LL_RECORD_BLOCK_TIME(FTM_GET_TRANS); + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; if (def_string) { @@ -199,7 +199,7 @@ std::string LLTrans::getString(std::string_view xml_desc, const LLSD& msg_args, { // Don't care about time as much as call count. Make sure we're not // calling LLTrans::getString() in an inner loop. JC - LL_RECORD_BLOCK_TIME(FTM_GET_TRANS); + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; if (def_string) { @@ -240,7 +240,7 @@ std::string LLTrans::getDefString(std::string_view xml_desc, const LLSD& msg_arg //static bool LLTrans::findString(std::string &result, std::string_view xml_desc, const LLStringUtil::format_map_t& msg_args) { - LL_RECORD_BLOCK_TIME(FTM_GET_TRANS); + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; template_map_t::iterator iter = sStringTemplates.find(xml_desc); if (iter != sStringTemplates.end()) @@ -262,7 +262,7 @@ bool LLTrans::findString(std::string &result, std::string_view xml_desc, const L //static bool LLTrans::findString(std::string &result, std::string_view xml_desc, const LLSD& msg_args) { - LL_RECORD_BLOCK_TIME(FTM_GET_TRANS); + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; template_map_t::iterator iter = sStringTemplates.find(xml_desc); if (iter != sStringTemplates.end()) diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index 2dad987088755a30d5eee46554457573f92d477f..d58c03160924a1627b494df02ce014230559e91c 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -96,7 +96,7 @@ LLFrameTimer LLUI::sMouseIdleTimer(LLFrameTimer::kConstInit); LLUUID find_ui_sound(std::string_view name) { LLUUID uuid = LLUUID(NULL); - LLUI& ui_inst = LLUI::instanceFast(); + LLUI& ui_inst = LLUI::instance(); if (!ui_inst.mSettingGroups["config"]->controlExists(name)) { LL_WARNS() << "tried to make UI sound for unknown sound name: " << name << LL_ENDL; @@ -140,7 +140,7 @@ void make_ui_sound(const char* namep) LLUUID soundUUID = find_ui_sound(absl::NullSafeStringView(namep)); if(soundUUID.notNull()) { - LLUI::getInstanceFast()->mAudioCallback(soundUUID); + LLUI::getInstance()->mAudioCallback(soundUUID); } } @@ -149,7 +149,7 @@ void make_ui_sound_deferred(const char* namep) LLUUID soundUUID = find_ui_sound(absl::NullSafeStringView(namep)); if(soundUUID.notNull()) { - LLUI::getInstanceFast()->mDeferredAudioCallback(soundUUID); + LLUI::getInstance()->mDeferredAudioCallback(soundUUID); } } @@ -288,7 +288,7 @@ std::string LLUI::getUILanguage() std::string LLUI::getLanguage() { // Note: lldateutil_test redefines this function - return LLUI::getInstanceFast()->getUILanguage(); + return LLUI::getInstance()->getUILanguage(); } struct SubDir : public LLInitParam::Block<SubDir> @@ -554,7 +554,7 @@ namespace LLInitParam { if (control.isProvided() && !control().empty()) { - updateValue(LLUIColorTable::instanceFast().getColor(control.getValue())); + updateValue(LLUIColorTable::instance().getColor(control.getValue())); } else { diff --git a/indra/llui/llui.h b/indra/llui/llui.h index dd555c9b6e371324325909cf71c5af4ed0cf1ee0..3c485f2a53cf98c0dc6e0580a2814289b80ba5ea 100644 --- a/indra/llui/llui.h +++ b/indra/llui/llui.h @@ -318,9 +318,9 @@ class LLUI final : public LLParamSingleton<LLUI> static void setScaleFactor(const LLVector2& scale_factor); static void setLineWidth(F32 width) { LLRender2D::setLineWidth(width); } static LLPointer<LLUIImage> getUIImageByID(const LLUUID& image_id, S32 priority = 0) - { return LLRender2D::getInstanceFast()->getUIImageByID(image_id, priority); } + { return LLRender2D::getInstance()->getUIImageByID(image_id, priority); } static LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority = 0) - { return LLRender2D::getInstanceFast()->getUIImage(name, priority); } + { return LLRender2D::getInstance()->getUIImage(name, priority); } // // Data @@ -361,7 +361,7 @@ class LLUICachedControl : public LLCachedControl<T> LLUICachedControl(const std::string& name, const T& default_value, const std::string& comment = "Declared In Code") - : LLCachedControl<T>(LLUI::getInstanceFast()->getControlControlGroup(name), name, default_value, comment) + : LLCachedControl<T>(LLUI::getInstance()->getControlControlGroup(name), name, default_value, comment) {} }; diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp index 22c0babaefa24ea2b117c0149d688d977638f5d1..cbf8eb07258c4abc1ed824004bb2d2e6cf76901a 100644 --- a/indra/llui/lluictrl.cpp +++ b/indra/llui/lluictrl.cpp @@ -120,7 +120,6 @@ LLUICtrl::LLUICtrl(const LLUICtrl::Params& p, const LLViewModelPtr& viewmodel) mDoubleClickSignal(NULL), mTransparencyType(TT_DEFAULT) { - claimMem(viewmodel.get()); } void LLUICtrl::initFromParams(const Params& p) @@ -484,6 +483,7 @@ LLViewModel* LLUICtrl::getViewModel() const //virtual BOOL LLUICtrl::postBuild() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; // // Find all of the children that want to be in front and move them to the front // @@ -789,12 +789,9 @@ BOOL LLUICtrl::getIsChrome() const } - -LLTrace::BlockTimerStatHandle FTM_FOCUS_FIRST_ITEM("Focus First Item"); - BOOL LLUICtrl::focusFirstItem(BOOL prefer_text_fields, BOOL focus_flash) { - LL_RECORD_BLOCK_TIME(FTM_FOCUS_FIRST_ITEM); + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; // try to select default tab group child LLViewQuery query = getTabOrderQuery(); child_list_t result = query(this); @@ -816,7 +813,7 @@ BOOL LLUICtrl::focusFirstItem(BOOL prefer_text_fields, BOOL focus_flash) if(prefer_text_fields) { LLViewQuery query = getTabOrderQuery(); - query.addPreFilter(LLUICtrl::LLTextInputFilter::getInstanceFast()); + query.addPreFilter(LLUICtrl::LLTextInputFilter::getInstance()); child_list_t result = query(this); if(result.size() > 0) { @@ -860,7 +857,7 @@ BOOL LLUICtrl::focusNextItem(BOOL text_fields_only) static LLUICachedControl<bool> tab_to_text_fields_only ("TabToTextFieldsOnly", false); if(text_fields_only || tab_to_text_fields_only) { - query.addPreFilter(LLUICtrl::LLTextInputFilter::getInstanceFast()); + query.addPreFilter(LLUICtrl::LLTextInputFilter::getInstance()); } child_list_t result = query(this); return focusNext(result); @@ -873,7 +870,7 @@ BOOL LLUICtrl::focusPrevItem(BOOL text_fields_only) static LLUICachedControl<bool> tab_to_text_fields_only ("TabToTextFieldsOnly", false); if(text_fields_only || tab_to_text_fields_only) { - query.addPreFilter(LLUICtrl::LLTextInputFilter::getInstanceFast()); + query.addPreFilter(LLUICtrl::LLTextInputFilter::getInstance()); } child_list_t result = query(this); return focusPrev(result); @@ -1013,7 +1010,6 @@ boost::signals2::connection LLUICtrl::setCommitCallback( boost::function<void (L boost::signals2::connection LLUICtrl::setValidateBeforeCommit( boost::function<bool (const LLSD& data)> cb ) { if (!mValidateSignal) mValidateSignal = new enable_signal_t(); - claimMem(mValidateSignal); return mValidateSignal->connect(boost::bind(cb, _2)); } @@ -1078,7 +1074,6 @@ boost::signals2::connection LLUICtrl::setValidateCallback(const EnableCallbackPa boost::signals2::connection LLUICtrl::setCommitCallback( const commit_signal_t::slot_type& cb ) { if (!mCommitSignal) mCommitSignal = new commit_signal_t(); - claimMem(mCommitSignal); return mCommitSignal->connect(cb); } @@ -1086,7 +1081,6 @@ boost::signals2::connection LLUICtrl::setCommitCallback( const commit_signal_t:: boost::signals2::connection LLUICtrl::setValidateCallback( const enable_signal_t::slot_type& cb ) { if (!mValidateSignal) mValidateSignal = new enable_signal_t(); - claimMem(mValidateSignal); return mValidateSignal->connect(cb); } @@ -1094,7 +1088,6 @@ boost::signals2::connection LLUICtrl::setValidateCallback( const enable_signal_t boost::signals2::connection LLUICtrl::setMouseEnterCallback( const commit_signal_t::slot_type& cb ) { if (!mMouseEnterSignal) mMouseEnterSignal = new commit_signal_t(); - claimMem(mMouseEnterSignal); return mMouseEnterSignal->connect(cb); } @@ -1102,7 +1095,6 @@ boost::signals2::connection LLUICtrl::setMouseEnterCallback( const commit_signal boost::signals2::connection LLUICtrl::setMouseLeaveCallback( const commit_signal_t::slot_type& cb ) { if (!mMouseLeaveSignal) mMouseLeaveSignal = new commit_signal_t(); - claimMem(mMouseLeaveSignal); return mMouseLeaveSignal->connect(cb); } @@ -1110,7 +1102,6 @@ boost::signals2::connection LLUICtrl::setMouseLeaveCallback( const commit_signal boost::signals2::connection LLUICtrl::setMouseDownCallback( const mouse_signal_t::slot_type& cb ) { if (!mMouseDownSignal) mMouseDownSignal = new mouse_signal_t(); - claimMem(mMouseDownSignal); return mMouseDownSignal->connect(cb); } @@ -1118,7 +1109,6 @@ boost::signals2::connection LLUICtrl::setMouseDownCallback( const mouse_signal_t boost::signals2::connection LLUICtrl::setMouseUpCallback( const mouse_signal_t::slot_type& cb ) { if (!mMouseUpSignal) mMouseUpSignal = new mouse_signal_t(); - claimMem(mMouseUpSignal); return mMouseUpSignal->connect(cb); } @@ -1126,7 +1116,6 @@ boost::signals2::connection LLUICtrl::setMouseUpCallback( const mouse_signal_t:: boost::signals2::connection LLUICtrl::setRightMouseDownCallback( const mouse_signal_t::slot_type& cb ) { if (!mRightMouseDownSignal) mRightMouseDownSignal = new mouse_signal_t(); - claimMem(mRightMouseDownSignal); return mRightMouseDownSignal->connect(cb); } @@ -1134,7 +1123,6 @@ boost::signals2::connection LLUICtrl::setRightMouseDownCallback( const mouse_sig boost::signals2::connection LLUICtrl::setRightMouseUpCallback( const mouse_signal_t::slot_type& cb ) { if (!mRightMouseUpSignal) mRightMouseUpSignal = new mouse_signal_t(); - claimMem(mRightMouseUpSignal); return mRightMouseUpSignal->connect(cb); } @@ -1142,7 +1130,6 @@ boost::signals2::connection LLUICtrl::setRightMouseUpCallback( const mouse_signa boost::signals2::connection LLUICtrl::setDoubleClickCallback( const mouse_signal_t::slot_type& cb ) { if (!mDoubleClickSignal) mDoubleClickSignal = new mouse_signal_t(); - claimMem(mDoubleClickSignal); return mDoubleClickSignal->connect(cb); } diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp index e595e586de51123da7948273bc07e0005847e982..a85db17c7ff02d77b8fc311610e6e2276e1eda6d 100644 --- a/indra/llui/lluictrlfactory.cpp +++ b/indra/llui/lluictrlfactory.cpp @@ -44,10 +44,6 @@ // this library includes #include "llpanel.h" -LLTrace::BlockTimerStatHandle FTM_WIDGET_CONSTRUCTION("Widget Construction"); -LLTrace::BlockTimerStatHandle FTM_INIT_FROM_PARAMS("Widget InitFromParams"); -LLTrace::BlockTimerStatHandle FTM_WIDGET_SETUP("Widget Setup"); - //----------------------------------------------------------------------------- // UI Ctrl class for padding @@ -104,7 +100,7 @@ void LLUICtrlFactory::loadWidgetTemplate(const std::string& widget_tag, LLInitPa std::string base_filename = search_paths.front(); if (!base_filename.empty()) { - LLUICtrlFactory::instanceFast().pushFileName(base_filename); + LLUICtrlFactory::instance().pushFileName(base_filename); if (!LLXMLNode::getLayeredXMLNode(root_node, search_paths)) { @@ -113,16 +109,14 @@ void LLUICtrlFactory::loadWidgetTemplate(const std::string& widget_tag, LLInitPa } LLXUIParser parser; parser.readXUI(root_node, block, base_filename); - LLUICtrlFactory::instanceFast().popFileName(); + LLUICtrlFactory::instance().popFileName(); } } -static LLTrace::BlockTimerStatHandle FTM_CREATE_CHILDREN("Create XUI Children"); - //static void LLUICtrlFactory::createChildren(LLView* viewp, LLXMLNodePtr node, const widget_registry_t& registry, LLXMLNodePtr output_node) { - LL_RECORD_BLOCK_TIME(FTM_CREATE_CHILDREN); + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; if (node.isNull()) return; for (LLXMLNodePtr child_node = node->getFirstChild(); child_node.notNull(); child_node = child_node->getNextSibling()) @@ -133,11 +127,11 @@ void LLUICtrlFactory::createChildren(LLView* viewp, LLXMLNodePtr node, const wid outputChild = output_node->createChild("", FALSE); } - if (!instanceFast().createFromXML(child_node, viewp, LLStringUtil::null, registry, outputChild)) + if (!instance().createFromXML(child_node, viewp, LLStringUtil::null, registry, outputChild)) { // child_node is not a valid child for the current parent std::string child_name = std::string(child_node->getName()->mString); - if (LLDefaultChildRegistry::instanceFast().getValue(child_name)) + if (LLDefaultChildRegistry::instance().getValue(child_name)) { // This means that the registry assocaited with the parent widget does not have an entry // for the child widget @@ -159,14 +153,13 @@ void LLUICtrlFactory::createChildren(LLView* viewp, LLXMLNodePtr node, const wid } -static LLTrace::BlockTimerStatHandle FTM_XML_PARSE("XML Reading/Parsing"); //----------------------------------------------------------------------------- // getLayeredXMLNode() //----------------------------------------------------------------------------- bool LLUICtrlFactory::getLayeredXMLNode(const std::string &xui_filename, LLXMLNodePtr& root, LLDir::ESkinConstraint constraint) { - LL_RECORD_BLOCK_TIME(FTM_XML_PARSE); + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; std::vector<std::string> paths = gDirUtilp->findSkinnedFilenames(LLDir::XUI, xui_filename, constraint); @@ -191,11 +184,9 @@ S32 LLUICtrlFactory::saveToXML(LLView* viewp, const std::string& filename) //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- -static LLTrace::BlockTimerStatHandle FTM_CREATE_FROM_XML("Create child widget"); - LLView *LLUICtrlFactory::createFromXML(LLXMLNodePtr node, LLView* parent, const std::string& filename, const widget_registry_t& registry, LLXMLNodePtr output_node) { - LL_RECORD_BLOCK_TIME(FTM_CREATE_FROM_XML); + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; std::string ctrl_type = node->getName()->mString; LLStringUtil::toLower(ctrl_type); @@ -262,7 +253,7 @@ const LLInitParam::BaseBlock& get_empty_param_block() void LLUICtrlFactory::registerWidget(const std::type_info* widget_type, const std::type_info* param_block_type, const std::string& name) { // associate parameter block type with template .xml file - std::string* existing_name = LLWidgetNameRegistry::instanceFast().getValue(param_block_type); + std::string* existing_name = LLWidgetNameRegistry::instance().getValue(param_block_type); if (existing_name != NULL) { if(*existing_name != name) @@ -279,7 +270,7 @@ void LLUICtrlFactory::registerWidget(const std::type_info* widget_type, const st } } - LLWidgetNameRegistry::instanceFast().defaultRegistrar().add(param_block_type, name); + LLWidgetNameRegistry::instance().defaultRegistrar().add(param_block_type, name); //FIXME: comment this in when working on schema generation //LLWidgetTypeRegistry::instance().defaultRegistrar().add(tag, widget_type); //LLDefaultParamBlockRegistry::instance().defaultRegistrar().add(widget_type, &get_empty_param_block<T>); diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h index 1c0e6ec1c24f4e1a090295e6f647af112b5c6e44..6bdf237e43171e0bf4b2048258b00b582dbd91d9 100644 --- a/indra/llui/lluictrlfactory.h +++ b/indra/llui/lluictrlfactory.h @@ -79,10 +79,6 @@ class LLWidgetNameRegistry final // LLSINGLETON(LLDefaultParamBlockRegistry); //}; -extern LLTrace::BlockTimerStatHandle FTM_WIDGET_SETUP; -extern LLTrace::BlockTimerStatHandle FTM_WIDGET_CONSTRUCTION; -extern LLTrace::BlockTimerStatHandle FTM_INIT_FROM_PARAMS; - // Build time optimization, generate this once in .cpp file #ifndef LLUICTRLFACTORY_CPP extern template class LLUICtrlFactory* LLSingleton<class LLUICtrlFactory>::getInstance(); @@ -122,7 +118,7 @@ class LLUICtrlFactory final : public LLSingleton<LLUICtrlFactory> template<typename T> static const typename T::Params& getDefaultParams() { - return instanceFast().mParamDefaultsMap.obtain< ParamDefaults<typename T::Params, 0> >().get(); + return instance().mParamDefaultsMap.obtain< ParamDefaults<typename T::Params, 0> >().get(); } // Does what you want for LLFloaters and LLPanels @@ -137,7 +133,7 @@ class LLUICtrlFactory final : public LLSingleton<LLUICtrlFactory> template<typename T> static T* create(typename T::Params& params, LLView* parent = NULL) { - params.fillFrom(instanceFast().mParamDefaultsMap.obtain< + params.fillFrom(instance().mParamDefaultsMap.obtain< ParamDefaults<typename T::Params, 0> >().get()); T* widget = createWidgetImpl<T>(params, parent); @@ -156,17 +152,17 @@ class LLUICtrlFactory final : public LLSingleton<LLUICtrlFactory> { T* widget = NULL; - instanceFast().pushFileName(filename); + instance().pushFileName(filename); { LLXMLNodePtr root_node; if (!LLUICtrlFactory::getLayeredXMLNode(filename, root_node)) { - LL_WARNS() << "Couldn't parse XUI from path: " << instanceFast().getCurFileName() << ", from filename: " << filename << LL_ENDL; + LL_WARNS() << "Couldn't parse XUI from path: " << instance().getCurFileName() << ", from filename: " << filename << LL_ENDL; goto fail; } - LLView* view = getInstanceFast()->createFromXML(root_node, parent, filename, registry, NULL); + LLView* view = getInstance()->createFromXML(root_node, parent, filename, registry, NULL); if (view) { widget = dynamic_cast<T*>(view); @@ -181,7 +177,7 @@ class LLUICtrlFactory final : public LLSingleton<LLUICtrlFactory> } } fail: - instanceFast().popFileName(); + instance().popFileName(); return widget; } @@ -213,20 +209,18 @@ class LLUICtrlFactory final : public LLSingleton<LLUICtrlFactory> template<typename T> static T* createWidgetImpl(const typename T::Params& params, LLView* parent = NULL) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; T* widget = NULL; if (!params.validateBlock()) { - LL_WARNS() << getInstanceFast()->getCurFileName() << ": Invalid parameter block for " << typeid(T).name() << LL_ENDL; + LL_WARNS() << getInstance()->getCurFileName() << ": Invalid parameter block for " << typeid(T).name() << LL_ENDL; //return NULL; } - { LL_RECORD_BLOCK_TIME(FTM_WIDGET_CONSTRUCTION); - widget = new T(params); - } - { LL_RECORD_BLOCK_TIME(FTM_INIT_FROM_PARAMS); - widget->initFromParams(params); - } + widget = new T(params); + + widget->initFromParams(params); if (parent) { @@ -239,12 +233,12 @@ class LLUICtrlFactory final : public LLSingleton<LLUICtrlFactory> template<typename T> static T* defaultBuilder(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node) { - LL_RECORD_BLOCK_TIME(FTM_WIDGET_SETUP); + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; typename T::Params params(getDefaultParams<T>()); LLXUIParser parser; - parser.readXUI(node, params, LLUICtrlFactory::getInstanceFast()->getCurFileName()); + parser.readXUI(node, params, LLUICtrlFactory::getInstance()->getCurFileName()); if (output_node) { @@ -262,7 +256,7 @@ class LLUICtrlFactory final : public LLSingleton<LLUICtrlFactory> typedef typename T::child_registry_t registry_t; - createChildren(widget, node, registry_t::instanceFast(), output_node); + createChildren(widget, node, registry_t::instance(), output_node); if (widget && !widget->postBuild()) { @@ -296,7 +290,7 @@ template <typename PARAM_BLOCK, int DUMMY> LLUICtrlFactory::ParamDefaults<PARAM_BLOCK, DUMMY>::ParamDefaults() { // look up template file for this param block... - const std::string* param_block_tag = LLWidgetNameRegistry::instanceFast().getValue(&typeid(PARAM_BLOCK)); + const std::string* param_block_tag = LLWidgetNameRegistry::instance().getValue(&typeid(PARAM_BLOCK)); if (param_block_tag) { // ...and if it exists, back fill values using the most specific template first PARAM_BLOCK params; @@ -305,7 +299,7 @@ LLUICtrlFactory::ParamDefaults<PARAM_BLOCK, DUMMY>::ParamDefaults() } // recursively fill from base class param block ((typename PARAM_BLOCK::base_block_t&)mPrototype).fillFrom( - LLUICtrlFactory::instanceFast().mParamDefaultsMap.obtain< + LLUICtrlFactory::instance().mParamDefaultsMap.obtain< ParamDefaults<typename PARAM_BLOCK::base_block_t, DUMMY> >().get()); } @@ -320,12 +314,12 @@ LLChildRegistry<DERIVED>::Register<T>::Register(const char* tag, LLWidgetCreator : LLChildRegistry<DERIVED>::StaticRegistrar(tag, func.empty() ? (LLWidgetCreatorFunc)&LLUICtrlFactory::defaultBuilder<T> : func) { // add this widget to various registries - LLUICtrlFactory::instanceFast().registerWidget(&typeid(T), &typeid(typename T::Params), tag); + LLUICtrlFactory::instance().registerWidget(&typeid(T), &typeid(typename T::Params), tag); // since registry_t depends on T, do this in line here // TODO: uncomment this for schema generation //typedef typename T::child_registry_t registry_t; - //LLChildRegistryRegistry::instanceFast().defaultRegistrar().add(&typeid(T), registry_t::instanceFast()); + //LLChildRegistryRegistry::instance().defaultRegistrar().add(&typeid(T), registry_t::instance()); } #endif //LLUICTRLFACTORY_H diff --git a/indra/llui/llurlaction.cpp b/indra/llui/llurlaction.cpp index 84ea770a8d80457ccd0c6fcc7dd7516a77869d18..8216046174668d162ca1b415e26cd29a3fa19e96 100644 --- a/indra/llui/llurlaction.cpp +++ b/indra/llui/llurlaction.cpp @@ -222,6 +222,15 @@ void LLUrlAction::removeFriend(std::string url) } } +void LLUrlAction::reportAbuse(std::string url) +{ + std::string id_str = getUserID(url); + if (LLUUID::validate(id_str)) + { + executeSLURL("secondlife:///app/agent/" + id_str + "/reportAbuse"); + } +} + void LLUrlAction::blockObject(std::string url) { std::string object_id = getObjectId(url); diff --git a/indra/llui/llurlaction.h b/indra/llui/llurlaction.h index 2d2a8dfef19835b75ffacedebe9bcc3890d454f2..c2c576254dc638055e43a0ab4216bc06a80aa958 100644 --- a/indra/llui/llurlaction.h +++ b/indra/llui/llurlaction.h @@ -82,6 +82,7 @@ class LLUrlAction static void sendIM(std::string url); static void addFriend(std::string url); static void removeFriend(std::string url); + static void reportAbuse(std::string url); static void blockObject(std::string url); static void unblockObject(std::string url); diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index 1c00f34ac3be3b21c158cb6410fba6e1644e2f00..169d71f9b4886723740136b6c0b45a36159b4dc1 100644 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -315,7 +315,7 @@ LLUrlEntryHTTPLabel::LLUrlEntryHTTPLabel() std::string LLUrlEntryHTTPLabel::getLabel(const std::string &url, const LLUrlLabelCallback &cb) { std::string label = getLabelFromWikiLink(url); - return (!LLUrlRegistry::instanceFast().hasUrl(label)) ? label : getUrl(url); + return (!LLUrlRegistry::instance().hasUrl(label)) ? label : getUrl(url); } std::string LLUrlEntryHTTPLabel::getTooltip(const std::string &string) const @@ -1344,7 +1344,7 @@ LLUrlEntrySLLabel::LLUrlEntrySLLabel() std::string LLUrlEntrySLLabel::getLabel(const std::string &url, const LLUrlLabelCallback &cb) { std::string label = getLabelFromWikiLink(url); - return (!LLUrlRegistry::instanceFast().hasUrl(label)) ? label : getUrl(url); + return (!LLUrlRegistry::instance().hasUrl(label)) ? label : getUrl(url); } std::string LLUrlEntrySLLabel::getUrl(const std::string &string) const @@ -1357,7 +1357,7 @@ std::string LLUrlEntrySLLabel::getTooltip(const std::string &string) const // return a tooltip corresponding to the URL type instead of the generic one (EXT-4574) std::string url = getUrl(string); LLUrlMatch match; - if (LLUrlRegistry::instanceFast().findUrl(url, match)) + if (LLUrlRegistry::instance().findUrl(url, match)) { return match.getTooltip(); } @@ -1370,7 +1370,7 @@ bool LLUrlEntrySLLabel::underlineOnHoverOnly(const std::string &string) const { std::string url = getUrl(string); LLUrlMatch match; - if (LLUrlRegistry::instanceFast().findUrl(url, match)) + if (LLUrlRegistry::instance().findUrl(url, match)) { return match.underlineOnHoverOnly(); } diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index a578e71fa07cb70f596fb6bd66b45f1af5b13c20..a53c95242eb680967214c7ef11d8996439cc9cee 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -140,8 +140,7 @@ LLView::Params::Params() } LLView::LLView(const LLView::Params& p) -: LLTrace::MemTrackable<LLView>("LLView"), - mVisible(p.visible), +: mVisible(p.visible), mInDraw(false), mName(p.name), mParentView(NULL), @@ -905,14 +904,14 @@ BOOL LLView::handleToolTip(S32 x, S32 y, MASK mask) static LLUICachedControl<bool> allow_ui_tooltips("BasicUITooltips", true); // allow "scrubbing" over ui by showing next tooltip immediately // if previous one was still visible - F32 timeout = LLToolTipMgr::instanceFast().toolTipVisible() + F32 timeout = LLToolTipMgr::instance().toolTipVisible() ? tooltip_fast_delay : tooltip_delay; // Even if we don't show tooltips, consume the event, nothing below should show tooltip if (allow_ui_tooltips) { - LLToolTipMgr::instanceFast().show(LLToolTip::Params() + LLToolTipMgr::instance().show(LLToolTip::Params() .message(tooltip) .sticky_rect(calcScreenRect()) .delay_time(timeout)); @@ -1613,15 +1612,11 @@ LLView* LLView::getChildView(std::string_view name, BOOL recurse) const return getChild<LLView>(name, recurse); } -static LLTrace::BlockTimerStatHandle FTM_FIND_VIEWS("Find Widgets"); - LLView* LLView::findChildView(std::string_view name, BOOL recurse) const { - LL_RECORD_BLOCK_TIME(FTM_FIND_VIEWS); - //richard: should we allow empty names? - //if(name.empty()) - // return NULL; - // Look for direct children *first* + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; + + // Look for direct children *first* for (LLView* childp : mChildList) { llassert(childp); @@ -1985,11 +1980,11 @@ const LLViewQuery & LLView::getTabOrderQuery() { static LLViewQuery query; if(query.getPreFilters().size() == 0) { - query.addPreFilter(LLVisibleFilter::getInstanceFast()); - query.addPreFilter(LLEnabledFilter::getInstanceFast()); - query.addPreFilter(LLTabStopFilter::getInstanceFast()); - query.addPostFilter(LLLeavesFilter::getInstanceFast()); - query.setSorter(SortByTabOrder::getInstanceFast()); + query.addPreFilter(LLVisibleFilter::getInstance()); + query.addPreFilter(LLEnabledFilter::getInstance()); + query.addPreFilter(LLTabStopFilter::getInstance()); + query.addPostFilter(LLLeavesFilter::getInstance()); + query.setSorter(SortByTabOrder::getInstance()); } return query; } @@ -2009,10 +2004,10 @@ const LLViewQuery & LLView::getFocusRootsQuery() { static LLViewQuery query; if(query.getPreFilters().size() == 0) { - query.addPreFilter(LLVisibleFilter::getInstanceFast()); - query.addPreFilter(LLEnabledFilter::getInstanceFast()); - query.addPreFilter(LLFocusRootsFilter::getInstanceFast()); - query.addPostFilter(LLRootsFilter::getInstanceFast()); + query.addPreFilter(LLVisibleFilter::getInstance()); + query.addPreFilter(LLEnabledFilter::getInstance()); + query.addPreFilter(LLFocusRootsFilter::getInstance()); + query.addPostFilter(LLRootsFilter::getInstance()); } return query; } @@ -2281,9 +2276,9 @@ LLControlVariable *LLView::findControl(std::string_view name) std::string control_group_key(name.substr(0, key_pos)); LLControlVariable* control; // check if it's in the control group that name indicated - if(LLUI::getInstanceFast()->mSettingGroups[control_group_key]) + if(LLUI::getInstance()->mSettingGroups[control_group_key]) { - control = LLUI::getInstanceFast()->mSettingGroups[control_group_key]->getControl(name); + control = LLUI::getInstance()->mSettingGroups[control_group_key]->getControl(name); if (control) { return control; @@ -2291,7 +2286,7 @@ LLControlVariable *LLView::findControl(std::string_view name) } } - LLControlGroup& control_group = LLUI::getInstanceFast()->getControlControlGroup(name); + LLControlGroup& control_group = LLUI::getInstance()->getControlControlGroup(name); return control_group.getControl(name); } diff --git a/indra/llui/llview.h b/indra/llui/llview.h index 01242e13e29ea443b61b92004944b1d2895b987e..6080d6797e82dd684669607ae3c692f577c8c60a 100644 --- a/indra/llui/llview.h +++ b/indra/llui/llview.h @@ -100,8 +100,7 @@ class LLView : public LLMouseHandler, // handles mouse events public LLFocusableElement, // handles keyboard events public LLMortician, // lazy deletion - public LLHandleProvider<LLView>, // passes out weak references to self - public LLTrace::MemTrackable<LLView> // track memory usage + public LLHandleProvider<LLView> // passes out weak references to self { public: diff --git a/indra/llui/llviewereventrecorder.cpp b/indra/llui/llviewereventrecorder.cpp index 8365eaa0255d593132b50b3527bceb596f7e3622..26a6b26d08ba2d7d46ef3da4ee82dcf82c069849 100644 --- a/indra/llui/llviewereventrecorder.cpp +++ b/indra/llui/llviewereventrecorder.cpp @@ -45,7 +45,7 @@ LLViewerEventRecorder::LLViewerEventRecorder() { bool LLViewerEventRecorder::displayViewerEventRecorderMenuItems() { - return LLUI::getInstanceFast()->mSettingGroups["config"]->getBOOL("ShowEventRecorderMenuItems"); + return LLUI::getInstance()->mSettingGroups["config"]->getBOOL("ShowEventRecorderMenuItems"); } @@ -218,7 +218,7 @@ void LLViewerEventRecorder::playbackRecording() { LLSD LeapCommand; // ivita sets this on startup, it also sends commands to the viewer to make start, stop, and playback menu items visible in viewer - LeapCommand =LLUI::getInstanceFast()->mSettingGroups["config"]->getLLSD("LeapPlaybackEventsCommand"); + LeapCommand =LLUI::getInstance()->mSettingGroups["config"]->getLLSD("LeapPlaybackEventsCommand"); LL_DEBUGS() << "[VITA] launching playback - leap command is: " << LLSDXMLStreamer(LeapCommand) << LL_ENDL; LLLeap::create("", LeapCommand, false); // exception=false diff --git a/indra/llui/llviewereventrecorder.h b/indra/llui/llviewereventrecorder.h index 2b7a560e1f0265a9bba827c6b468dfe4b6dd23ad..237e00e49995b4521d9cfbbc822b428c6153df1d 100644 --- a/indra/llui/llviewereventrecorder.h +++ b/indra/llui/llviewereventrecorder.h @@ -43,12 +43,12 @@ #include "llsingleton.h" // includes llerror which we need here so we can skip the include here -class LLViewerEventRecorder final : public LLSingleton<LLViewerEventRecorder> +class LLViewerEventRecorder final : public LLSimpleton<LLViewerEventRecorder> { - LLSINGLETON(LLViewerEventRecorder); - ~LLViewerEventRecorder(); - - public: +public: + LLViewerEventRecorder(); + ~LLViewerEventRecorder(); + void updateMouseEventInfo(S32 local_x,S32 local_y, S32 global_x, S32 global_y, std::string mName); void setMouseLocalCoords(S32 x,S32 y); void setMouseGlobalCoords(S32 x,S32 y); diff --git a/indra/llui/llviewmodel.cpp b/indra/llui/llviewmodel.cpp index 4f40f9835eee785db7c8b7d8df0604836b0b8e20..e472aa8d6fc243166db74e7ee5f936730a479a2f 100644 --- a/indra/llui/llviewmodel.cpp +++ b/indra/llui/llviewmodel.cpp @@ -37,15 +37,13 @@ /// LLViewModel::LLViewModel() -: LLTrace::MemTrackable<LLViewModel>("LLViewModel"), - mDirty(false) +: mDirty(false) { } /// Instantiate an LLViewModel with an existing data value LLViewModel::LLViewModel(const LLSD& value) -: LLTrace::MemTrackable<LLViewModel>("LLViewModel"), - mDirty(false) +: mDirty(false) { setValue(value); } @@ -82,15 +80,9 @@ LLTextViewModel::LLTextViewModel(const LLSD& value) void LLTextViewModel::setValue(const LLSD& value) { // approximate LLSD storage usage - disclaimMem(mDisplay.size()); LLViewModel::setValue(value); - disclaimMem(mDisplay); mDisplay = utf8str_to_wstring(value.asString()); - claimMem(mDisplay); - // approximate LLSD storage usage - claimMem(mDisplay.size()); - // mDisplay and mValue agree mUpdateFromDisplay = false; } @@ -101,12 +93,8 @@ void LLTextViewModel::setDisplay(const LLWString& value) // and do the utf8str_to_wstring() to get the corresponding mDisplay // value. But a text editor might want to edit the display string // directly, then convert back to UTF8 on commit. - disclaimMem(mDisplay.size()); - disclaimMem(mDisplay); - mDisplay = value; - claimMem(mDisplay); - claimMem(mDisplay.size()); - mDirty = true; + mDisplay = value; + mDirty = true; // Don't immediately convert to UTF8 -- do it lazily -- we expect many // more setDisplay() calls than getValue() calls. Just flag that it needs // doing. diff --git a/indra/llui/llviewmodel.h b/indra/llui/llviewmodel.h index 579fe34c288624fe678fcb1eda960441d46c9346..4bf1f4b1f104935ffb889fd170e76d5c3dd5d67a 100644 --- a/indra/llui/llviewmodel.h +++ b/indra/llui/llviewmodel.h @@ -62,8 +62,7 @@ typedef LLPointer<LLListViewModel> LLListViewModelPtr; * last referencing widget is destroyed. */ class LLViewModel -: public LLRefCount, - public LLTrace::MemTrackable<LLViewModel> +: public LLRefCount { public: LLViewModel(); diff --git a/indra/llui/llxuiparser.cpp b/indra/llui/llxuiparser.cpp index 9c8105037468c41f5f5e996b39c2673e0cac7de2..2d54f91f9d8d71ff46e1e2dbbcd3b458511b88b6 100644 --- a/indra/llui/llxuiparser.cpp +++ b/indra/llui/llxuiparser.cpp @@ -600,8 +600,8 @@ void LLXUIXSDWriter::writeXSD(const std::string& type_name, const std::string& p LLXSDWriter::writeXSD(type_name, root_nodep, block, "http://www.lindenlab.com/xui"); // add includes for all possible children - const std::type_info* type = *LLWidgetTypeRegistry::instanceFast().getValue(type_name); - const widget_registry_t* widget_registryp = LLChildRegistryRegistry::instanceFast().getValue(type); + const std::type_info* type = *LLWidgetTypeRegistry::instance().getValue(type_name); + const widget_registry_t* widget_registryp = LLChildRegistryRegistry::instance().getValue(type); // add choices for valid children if (widget_registryp) diff --git a/indra/llwindow/CMakeLists.txt b/indra/llwindow/CMakeLists.txt index 1391a1cf158cac7404324681de2f34926579409c..56bf8302e14c43533d29d3295c0661799f3537ec 100644 --- a/indra/llwindow/CMakeLists.txt +++ b/indra/llwindow/CMakeLists.txt @@ -195,6 +195,12 @@ if (SDL_FOUND) endif (SDL_FOUND) target_link_libraries (llwindow llcommon ${llwindow_LINK_LIBRARIES} readerwriterqueue) + +if (DARWIN) + include(CMakeFindFrameworks) + find_library(CARBON_LIBRARY Carbon) + target_link_libraries(llwindow ${CARBON_LIBRARY}) +endif (DARWIN) if(USE_PRECOMPILED_HEADERS AND ${CMAKE_VERSION} VERSION_GREATER "3.15.0") target_precompile_headers(llwindow diff --git a/indra/llwindow/lldxhardware.cpp b/indra/llwindow/lldxhardware.cpp index 4de34368553814aec20e27c440d804a4268d4110..8fb6640ca883f5ecf805a02a52702b806ed3b8be 100644 --- a/indra/llwindow/lldxhardware.cpp +++ b/indra/llwindow/lldxhardware.cpp @@ -63,7 +63,7 @@ typedef BOOL ( WINAPI* PfnCoSetProxyBlanket )( IUnknown* pProxy, DWORD dwAuthnSv RPC_AUTH_IDENTITY_HANDLE pAuthInfo, DWORD dwCapabilities ); //Getting the version of graphics controller driver via WMI -std::string LLDXHardware::getDriverVersionWMI() +std::string LLDXHardware::getDriverVersionWMI(EGPUVendor vendor) { std::string mDriverVersion; HRESULT hrCoInitialize = S_OK; @@ -159,15 +159,68 @@ std::string LLDXHardware::getDriverVersionWMI() { break; // If quantity less then 1. } + + if (vendor != GPU_ANY) + { + VARIANT vtCaptionProp; + // Might be preferable to check "AdapterCompatibility" here instead of caption. + hr = pclsObj->Get(L"Caption", 0, &vtCaptionProp, 0, 0); + + if (FAILED(hr)) + { + LL_WARNS("AppInit") << "Query for Caption property failed." << " Error code = 0x" << hr << LL_ENDL; + pSvc->Release(); + pLoc->Release(); + CoUninitialize(); + return std::string(); // Program has failed. + } + + // use characters in the returned driver version + BSTR caption(vtCaptionProp.bstrVal); + + //convert BSTR to std::string + std::wstring ws(caption, SysStringLen(caption)); + std::string caption_str(ws.begin(), ws.end()); + LLStringUtil::toLower(caption_str); + + bool found = false; + switch (vendor) + { + case GPU_INTEL: + found = caption_str.find("intel") != std::string::npos; + break; + case GPU_NVIDIA: + found = caption_str.find("nvidia") != std::string::npos; + break; + case GPU_AMD: + found = caption_str.find("amd") != std::string::npos + || caption_str.find("ati ") != std::string::npos + || caption_str.find("radeon") != std::string::npos; + break; + default: + break; + } - VARIANT vtProp; + if (found) + { + VariantClear(&vtCaptionProp); + } + else + { + VariantClear(&vtCaptionProp); + pclsObj->Release(); + continue; + } + } - // Get the value of the Name property - hr = pclsObj->Get(L"DriverVersion", 0, &vtProp, 0, 0); + VARIANT vtVersionProp; + + // Get the value of the DriverVersion property + hr = pclsObj->Get(L"DriverVersion", 0, &vtVersionProp, 0, 0); if (FAILED(hr)) { - LL_WARNS("AppInit") << "Query for name property failed." << " Error code = 0x" << hr << LL_ENDL; + LL_WARNS("AppInit") << "Query for DriverVersion property failed." << " Error code = 0x" << hr << LL_ENDL; pSvc->Release(); pLoc->Release(); CoUninitialize(); @@ -175,7 +228,7 @@ std::string LLDXHardware::getDriverVersionWMI() } // use characters in the returned driver version - BSTR driverVersion(vtProp.bstrVal); + BSTR driverVersion(vtVersionProp.bstrVal); //convert BSTR to std::string std::wstring ws(driverVersion, SysStringLen(driverVersion)); @@ -188,10 +241,19 @@ std::string LLDXHardware::getDriverVersionWMI() } else if (mDriverVersion != str) { - LL_WARNS("DriverVersion") << "Different versions of drivers. Version of second driver : " << str << LL_ENDL; + if (vendor == GPU_ANY) + { + // Expected from systems with gpus from different vendors + LL_INFOS("DriverVersion") << "Multiple video drivers detected. Version of second driver: " << str << LL_ENDL; + } + else + { + // Not Expected! + LL_WARNS("DriverVersion") << "Multiple video drivers detected from same vendor. Version of second driver : " << str << LL_ENDL; + } } - VariantClear(&vtProp); + VariantClear(&vtVersionProp); pclsObj->Release(); } diff --git a/indra/llwindow/lldxhardware.h b/indra/llwindow/lldxhardware.h index e4f0736b6b9081e8c422f2d3fa52f054afd8d667..b3e5b1c59e76332435175b2b6c7ffdcf28d79a47 100644 --- a/indra/llwindow/lldxhardware.h +++ b/indra/llwindow/lldxhardware.h @@ -88,7 +88,15 @@ class LLDXHardware // vram_only TRUE does a "light" probe. BOOL updateVRAM(); - std::string getDriverVersionWMI(); + // WMI can return multiple GPU drivers + // specify which one to output + typedef enum { + GPU_INTEL, + GPU_NVIDIA, + GPU_AMD, + GPU_ANY + } EGPUVendor; + std::string getDriverVersionWMI(EGPUVendor vendor); S32 getVRAM() const { return mVRAM; } diff --git a/indra/llwindow/llkeyboard.cpp b/indra/llwindow/llkeyboard.cpp index 555d378773f69655e99e2cc5013bea4935716788..6cf58277ba595fcd51c54aa6816f09496d3941a8 100644 --- a/indra/llwindow/llkeyboard.cpp +++ b/indra/llwindow/llkeyboard.cpp @@ -148,6 +148,22 @@ void LLKeyboard::addKeyName(KEY key, const std::string& name) sNamesToKeys[nameuc] = key; } +void LLKeyboard::resetKeyDownAndHandle() +{ + MASK mask = currentMask(FALSE); + for (S32 i = 0; i < KEY_COUNT; i++) + { + if (mKeyLevel[i]) + { + mKeyDown[i] = FALSE; + mKeyLevel[i] = FALSE; + mKeyUp[i] = TRUE; + mCurTranslatedKey = (KEY)i; + mCallbacks->handleTranslatedKeyUp(i, mask); + } + } +} + // BUG this has to be called when an OS dialog is shown, otherwise modifier key state // is wrong because the keyup event is never received by the main window. JC void LLKeyboard::resetKeys() diff --git a/indra/llwindow/llkeyboard.h b/indra/llwindow/llkeyboard.h index 2371e11e6f4dc6a6b6efc9a8090fb387f3c4f5a8..981b343a89dddd101cb2c9c97316e416795d9ff2 100644 --- a/indra/llwindow/llkeyboard.h +++ b/indra/llwindow/llkeyboard.h @@ -58,7 +58,8 @@ class LLKeyboard LLKeyboard(); virtual ~LLKeyboard(); - void resetKeys(); + void resetKeyDownAndHandle(); + void resetKeys(); F32 getCurKeyElapsedTime() { return getKeyDown(mCurScanKey) ? getKeyElapsedTime( mCurScanKey ) : 0.f; } diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm index bae950143cc949ac59331dcfb2824f1188b42ea2..580be288efdbfe455e530e0da68672cd093aa119 100644 --- a/indra/llwindow/llopenglview-objc.mm +++ b/indra/llwindow/llopenglview-objc.mm @@ -447,14 +447,14 @@ attributedStringInfo getSegments(NSAttributedString *str) // e.g. OS Window for upload something or Input Window... // mModifiers instance variable is for insertText: or insertText:replacementRange: (by Pell Smit) mModifiers = [theEvent modifierFlags]; + unichar ch = [[theEvent charactersIgnoringModifiers] characterAtIndex:0]; + bool acceptsText = mHasMarkedText ? false : callKeyDown(&eventData, keycode, mModifiers, ch); - bool acceptsText = mHasMarkedText ? false : callKeyDown(&eventData, keycode, mModifiers, [[theEvent characters] characterAtIndex:0]); - unichar ch; if (acceptsText && !mMarkedTextAllowed && !(mModifiers & (NSEventModifierFlagControl | NSEventModifierFlagCommand)) && // commands don't invoke InputWindow ![(LLAppDelegate*)[NSApp delegate] romanScript] && - (ch = [[theEvent charactersIgnoringModifiers] characterAtIndex:0]) > ' ' && + ch > ' ' && ch != NSDeleteCharacter && (ch < 0xF700 || ch > 0xF8FF)) // 0xF700-0xF8FF: reserved for function keys on the keyboard(from NSEvent.h) { diff --git a/indra/llwindow/llwindow.cpp b/indra/llwindow/llwindow.cpp index 1952166876a1aa63c7088ae4d6de15259591fe14..bb478af52b288eaf0724349a2e88c9294fd8e254 100644 --- a/indra/llwindow/llwindow.cpp +++ b/indra/llwindow/llwindow.cpp @@ -133,6 +133,12 @@ BOOL LLWindow::canDelete() return TRUE; } +//virtual +void LLWindow::setTitle(const std::string title) +{ + // the action happens in the platform specific impl +} + // virtual void LLWindow::incBusyCount() { @@ -393,7 +399,7 @@ LLWindow* LLWindowManager::createWindow( const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height, U32 flags, BOOL fullscreen, BOOL clearBg, - BOOL disable_vsync, + BOOL enable_vsync, BOOL use_gl, BOOL ignore_pixel_depth, U32 fsaa_samples) @@ -405,26 +411,26 @@ LLWindow* LLWindowManager::createWindow( #if LL_MESA_HEADLESS new_window = new LLWindowMesaHeadless(callbacks, title, name, x, y, width, height, flags, - fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth); + fullscreen, clearBg, enable_vsync, use_gl, ignore_pixel_depth); #elif LL_SDL new_window = new LLWindowSDL(callbacks, - title, x, y, width, height, flags, - fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth, fsaa_samples); + title, name, x, y, width, height, flags, + fullscreen, clearBg, enable_vsync, use_gl, ignore_pixel_depth, fsaa_samples); #elif LL_WINDOWS new_window = new LLWindowWin32(callbacks, title, name, x, y, width, height, flags, - fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth, fsaa_samples); + fullscreen, clearBg, enable_vsync, use_gl, ignore_pixel_depth, fsaa_samples); #elif LL_DARWIN new_window = new LLWindowMacOSX(callbacks, title, name, x, y, width, height, flags, - fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth, fsaa_samples); + fullscreen, clearBg, enable_vsync, use_gl, ignore_pixel_depth, fsaa_samples); #endif } else { new_window = new LLWindowHeadless(callbacks, title, name, x, y, width, height, flags, - fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth); + fullscreen, clearBg, enable_vsync, use_gl, ignore_pixel_depth); } if (FALSE == new_window->isValid()) diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h index e269c4b8e8e13fb34b0540441ddec3bd43a3c2a6..251d6bf5bb852be48ebf68b1d30d46ce747f81bd 100644 --- a/indra/llwindow/llwindow.h +++ b/indra/llwindow/llwindow.h @@ -77,15 +77,37 @@ class LLWindow : public LLInstanceTracker<LLWindow> BOOL setSize(LLCoordScreen size); BOOL setSize(LLCoordWindow size); virtual void setMinSize(U32 min_width, U32 min_height, bool enforce_immediately = true); - virtual BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp = NULL) = 0; - virtual BOOL setCursorPosition(LLCoordWindow position) = 0; + virtual BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL enable_vsync, const LLCoordScreen * const posp = NULL) = 0; + + //create a new GL context that shares a namespace with this Window's main GL context and make it current on the current thread + // returns a pointer to be handed back to destroySharedConext/makeContextCurrent + virtual void* createSharedContext() = 0; + //make the given context current on the current thread + virtual void makeContextCurrent(void* context) = 0; + //destroy the given context that was retrieved by createSharedContext() + //Must be called on the same thread that called createSharedContext() + virtual void destroySharedContext(void* context) = 0; + + virtual void toggleVSync(bool enable_vsync) = 0; + + virtual BOOL setCursorPosition(LLCoordWindow position) = 0; virtual BOOL getCursorPosition(LLCoordWindow *position) = 0; +#if LL_WINDOWS + virtual BOOL getCursorDelta(LLCoordCommon* delta) = 0; +#endif virtual void showCursor() = 0; virtual void hideCursor() = 0; virtual BOOL isCursorHidden() = 0; virtual void showCursorFromMouseMove() = 0; virtual void hideCursorUntilMouseMove() = 0; + // Provide a way to set the Viewer window title after the + // windows has been created. The initial use case for this + // is described in SL-16102 (update window title with agent + // name, location etc. for non-interactive viewer) but it + // may also be useful in other cases. + virtual void setTitle(const std::string title); + // These two functions create a way to make a busy cursor instead // of an arrow when someone's busy doing something. Draw an // arrow/hour if busycount > 0. @@ -111,7 +133,6 @@ class LLWindow : public LLInstanceTracker<LLWindow> virtual BOOL pasteTextFromPrimary(LLWString &dst); virtual BOOL copyTextToPrimary(const LLWString &src); - virtual void setWindowTitle(const std::string& title) {} virtual void flashIcon(F32 seconds) = 0; virtual F32 getGamma() = 0; virtual BOOL setGamma(const F32 gamma) = 0; // Set the gamma @@ -274,7 +295,7 @@ class LLWindowManager U32 flags = 0, BOOL fullscreen = FALSE, BOOL clearBg = FALSE, - BOOL disable_vsync = TRUE, + BOOL enable_vsync = FALSE, BOOL use_gl = TRUE, BOOL ignore_pixel_depth = FALSE, U32 fsaa_samples = 0); diff --git a/indra/llwindow/llwindowheadless.cpp b/indra/llwindow/llwindowheadless.cpp index 3840a50a0caa9eb944ad3ec719fd0b8c3c6472a9..05a4cd5d8f0ba4bab8f730eeefa78c108636ca6a 100644 --- a/indra/llwindow/llwindowheadless.cpp +++ b/indra/llwindow/llwindowheadless.cpp @@ -35,7 +35,7 @@ // LLWindowHeadless::LLWindowHeadless(LLWindowCallbacks* callbacks, const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height, U32 flags, BOOL fullscreen, BOOL clear_background, - BOOL disable_vsync, BOOL use_gl, BOOL ignore_pixel_depth) + BOOL enable_vsync, BOOL use_gl, BOOL ignore_pixel_depth) : LLWindow(callbacks, fullscreen, flags) { // Initialize a headless keyboard. diff --git a/indra/llwindow/llwindowheadless.h b/indra/llwindow/llwindowheadless.h index fc75e7a691a323024eed5b6d4f8c510c007b76bf..27501c7804fdcf1f5b713b6a169dac53cd1b2a7e 100644 --- a/indra/llwindow/llwindowheadless.h +++ b/indra/llwindow/llwindowheadless.h @@ -48,9 +48,16 @@ class LLWindowHeadless : public LLWindow /*virtual*/ BOOL setPosition(LLCoordScreen position) {return FALSE;}; /*virtual*/ BOOL setSizeImpl(LLCoordScreen size) {return FALSE;}; /*virtual*/ BOOL setSizeImpl(LLCoordWindow size) {return FALSE;}; - /*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp = NULL) {return FALSE;}; - /*virtual*/ BOOL setCursorPosition(LLCoordWindow position) {return FALSE;}; - /*virtual*/ BOOL getCursorPosition(LLCoordWindow *position) {return FALSE;}; + /*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL enable_vsync, const LLCoordScreen * const posp = NULL) {return FALSE;}; + void* createSharedContext() { return nullptr; } + void makeContextCurrent(void*) {} + void destroySharedContext(void*) {} + /*virtual*/ void toggleVSync(bool enable_vsync) { } + /*virtual*/ BOOL setCursorPosition(LLCoordWindow position) {return FALSE;}; + /*virtual*/ BOOL getCursorPosition(LLCoordWindow *position) {return FALSE;}; +#if LL_WINDOWS + /*virtual*/ BOOL getCursorDelta(LLCoordCommon* delta) { return FALSE; } +#endif /*virtual*/ void showCursor() {}; /*virtual*/ void hideCursor() {}; /*virtual*/ void showCursorFromMouseMove() {}; @@ -97,7 +104,7 @@ class LLWindowHeadless : public LLWindow S32 x, S32 y, S32 width, S32 height, U32 flags, BOOL fullscreen, BOOL clear_background, - BOOL disable_vsync, BOOL use_gl, BOOL ignore_pixel_depth); + BOOL enable_vsync, BOOL use_gl, BOOL ignore_pixel_depth); virtual ~LLWindowHeadless() = default; private: diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h index d8cacb76d3b5b9926bf44d2a8b0905ad7533c655..f8d40cd3ae5bd98fffd7d29c69a74d83e956e37e 100644 --- a/indra/llwindow/llwindowmacosx-objc.h +++ b/indra/llwindow/llwindowmacosx-objc.h @@ -96,6 +96,7 @@ void setCrossCursor(); void setNotAllowedCursor(); void hideNSCursor(); void showNSCursor(); +bool isCGCursorVisible(); void hideNSCursorTillMove(bool hide); void requestUserAttention(); long showAlert(std::string title, std::string text, int type); diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm index 14530f703f7ebbb06b8b2626001bd88d4b7df6a8..3fe898f5ae69474ee9e4ae75ab0bd0095e9f9dd6 100644 --- a/indra/llwindow/llwindowmacosx-objc.mm +++ b/indra/llwindow/llwindowmacosx-objc.mm @@ -107,7 +107,7 @@ CursorRef createImageCursor(const char *fullpath, int hotspotX, int hotspotY) [[NSCursor alloc] initWithImage: [[NSImage alloc] initWithContentsOfFile: - [NSString stringWithFormat:@"%s", fullpath] + [NSString stringWithUTF8String:fullpath] ] hotSpot:NSMakePoint(hotspotX, hotspotY) ]; @@ -163,6 +163,11 @@ void showNSCursor() [NSCursor unhide]; } +bool isCGCursorVisible() +{ + return CGCursorIsVisible(); +} + void hideNSCursorTillMove(bool hide) { [NSCursor setHiddenUntilMouseMoves:hide]; diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 49d0cad91bc389c75ed23cabd3b2bd949e1f09f2..6c94e110d09f44c4354f1a9ee796894503c9f5c4 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -110,7 +110,7 @@ LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks, const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height, U32 flags, BOOL fullscreen, BOOL clearBg, - BOOL disable_vsync, BOOL use_gl, + BOOL enable_vsync, BOOL use_gl, BOOL ignore_pixel_depth, U32 fsaa_samples) : LLWindow(NULL, fullscreen, flags) @@ -164,7 +164,7 @@ LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks, // Stash an object pointer for OSMessageBox() gWindowImplementation = this; // Create the GL context and set it up for windowed or fullscreen, as appropriate. - if(createContext(x, y, width, height, 32, fullscreen, disable_vsync)) + if(createContext(x, y, width, height, 32, fullscreen, enable_vsync)) { if(mWindow != NULL) { @@ -606,7 +606,7 @@ void LLWindowMacOSX::getMouseDeltas(float* delta) delta[1] = mCursorLastEventDeltaY; } -BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits, BOOL fullscreen, BOOL disable_vsync) +BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits, BOOL fullscreen, BOOL enable_vsync) { mFullscreen = fullscreen; @@ -619,9 +619,8 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits { // Our OpenGL view is already defined within SecondLife.xib. // Get the view instead. - mGLView = createOpenGLView(mWindow, mFSAASamples, !disable_vsync); + mGLView = createOpenGLView(mWindow, mFSAASamples, enable_vsync); mContext = getCGLContextObj(mGLView); - gGLManager.mVRAM = getVramSize(mGLView); } @@ -643,17 +642,7 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits } // Disable vertical sync for swap - GLint frames_per_swap = 0; - if (disable_vsync) - { - frames_per_swap = 0; - } - else - { - frames_per_swap = 1; - } - - CGLSetParameter(mContext, kCGLCPSwapInterval, &frames_per_swap); + toggleVSync(enable_vsync); //enable multi-threaded OpenGL CGLError cgl_err; @@ -678,7 +667,7 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits // We only support OS X 10.7's fullscreen app mode which is literally a full screen window that fills a virtual desktop. // This makes this method obsolete. -BOOL LLWindowMacOSX::switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp) +BOOL LLWindowMacOSX::switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL enable_vsync, const LLCoordScreen * const posp) { return FALSE; } @@ -1266,7 +1255,7 @@ BOOL LLWindowMacOSX::copyTextToClipboard(const LLWString &s) return result; } -void LLWindowMacOSX::setWindowTitle(const std::string& title) +void LLWindowMacOSX::setTitle(const std::string title) { setTitle(title); } @@ -1496,6 +1485,11 @@ void LLWindowMacOSX::updateCursor() if(mCurrentCursor == mNextCursor) { + if(mCursorHidden && mHideCursorPermanent && isCGCursorVisible()) + { + hideNSCursor(); + adjustCursorDecouple(); + } return; } @@ -1659,7 +1653,7 @@ void LLWindowMacOSX::hideCursor() void LLWindowMacOSX::showCursor() { - if(mCursorHidden) + if(mCursorHidden || !isCGCursorVisible()) { // LL_INFOS() << "showCursor: showing" << LL_ENDL; mCursorHidden = FALSE; @@ -1870,6 +1864,49 @@ void LLWindowMacOSX::allowLanguageTextInput(LLPreeditor *preeditor, BOOL b) allowDirectMarkedTextInput(b, mGLView); // mLanguageTextInputAllowed and mMarkedTextAllowed should be updated at once (by Pell Smit } +class sharedContext +{ +public: + CGLContextObj mContext; +}; + +void* LLWindowMacOSX::createSharedContext() +{ + sharedContext* sc = new sharedContext(); + CGLCreateContext(mPixelFormat, mContext, &(sc->mContext)); + + return (void *)sc; +} + +void LLWindowMacOSX::makeContextCurrent(void* context) +{ + CGLSetCurrentContext(((sharedContext*)context)->mContext); +} + +void LLWindowMacOSX::destroySharedContext(void* context) +{ + sharedContext* sc = (sharedContext*)context; + + CGLDestroyContext(sc->mContext); + + delete sc; +} + +void LLWindowMacOSX::toggleVSync(bool enable_vsync) +{ + GLint frames_per_swap = 0; + if (!enable_vsync) + { + frames_per_swap = 0; + } + else + { + frames_per_swap = 1; + } + + CGLSetParameter(mContext, kCGLCPSwapInterval, &frames_per_swap); +} + void LLWindowMacOSX::interruptLanguageTextInput() { commitCurrentPreedit(mGLView); diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h index b048dacc70435d21965f9dba8a560ba70314f882..8067e8644bf59545e2ee4b03a3943fda8cecf700 100644 --- a/indra/llwindow/llwindowmacosx.h +++ b/indra/llwindow/llwindowmacosx.h @@ -41,86 +41,85 @@ #undef verify #undef require - class LLWindowMacOSX : public LLWindow { public: - /*virtual*/ void show(); - /*virtual*/ void hide(); - /*virtual*/ void close(); - /*virtual*/ BOOL getVisible(); - /*virtual*/ BOOL getMinimized(); - /*virtual*/ BOOL getMaximized(); - /*virtual*/ BOOL maximize(); - /*virtual*/ void minimize(); - /*virtual*/ void restore(); - /*virtual*/ BOOL getFullscreen(); - /*virtual*/ BOOL getPosition(LLCoordScreen *position); - /*virtual*/ BOOL getSize(LLCoordScreen *size); - /*virtual*/ BOOL getSize(LLCoordWindow *size); - /*virtual*/ BOOL setPosition(LLCoordScreen position); - /*virtual*/ BOOL setSizeImpl(LLCoordScreen size); - /*virtual*/ BOOL setSizeImpl(LLCoordWindow size); - /*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp = NULL); - /*virtual*/ BOOL setCursorPosition(LLCoordWindow position); - /*virtual*/ BOOL getCursorPosition(LLCoordWindow *position); - /*virtual*/ void showCursor(); - /*virtual*/ void hideCursor(); - /*virtual*/ void showCursorFromMouseMove(); - /*virtual*/ void hideCursorUntilMouseMove(); - /*virtual*/ BOOL isCursorHidden(); - /*virtual*/ void updateCursor(); - /*virtual*/ ECursorType getCursor() const; - /*virtual*/ void captureMouse(); - /*virtual*/ void releaseMouse(); - /*virtual*/ void setMouseClipping( BOOL b ); - /*virtual*/ BOOL isClipboardTextAvailable(); - /*virtual*/ BOOL pasteTextFromClipboard(LLWString &dst); - /*virtual*/ BOOL copyTextToClipboard(const LLWString & src); - /*virtual*/ void setWindowTitle(const std::string& title); - /*virtual*/ void flashIcon(F32 seconds); - /*virtual*/ F32 getGamma(); - /*virtual*/ BOOL setGamma(const F32 gamma); // Set the gamma - /*virtual*/ U32 getFSAASamples(); - /*virtual*/ void setFSAASamples(const U32 fsaa_samples); - /*virtual*/ BOOL restoreGamma(); // Restore original gamma table (before updating gamma) - /*virtual*/ ESwapMethod getSwapMethod() { return mSwapMethod; } - /*virtual*/ void gatherInput(); - /*virtual*/ void delayInputProcessing() {}; - /*virtual*/ void swapBuffers(); + void show() override; + void hide() override; + void close() override; + BOOL getVisible() override; + BOOL getMinimized() override; + BOOL getMaximized() override; + BOOL maximize() override; + void minimize() override; + void restore() override; + BOOL getFullscreen(); + BOOL getPosition(LLCoordScreen *position) override; + BOOL getSize(LLCoordScreen *size) override; + BOOL getSize(LLCoordWindow *size) override; + BOOL setPosition(LLCoordScreen position) override; + BOOL setSizeImpl(LLCoordScreen size) override; + BOOL setSizeImpl(LLCoordWindow size) override; + BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL enable_vsync, const LLCoordScreen * const posp = NULL) override; + BOOL setCursorPosition(LLCoordWindow position) override; + BOOL getCursorPosition(LLCoordWindow *position) override; + void showCursor() override; + void hideCursor() override; + void showCursorFromMouseMove() override; + void hideCursorUntilMouseMove() override; + BOOL isCursorHidden() override; + void updateCursor() override; + ECursorType getCursor() const override; + void captureMouse() override; + void releaseMouse() override; + void setMouseClipping( BOOL b ) override; + BOOL isClipboardTextAvailable() override; + BOOL pasteTextFromClipboard(LLWString &dst) override; + BOOL copyTextToClipboard(const LLWString & src) override; + void setTitle(const std::string title) override; + void flashIcon(F32 seconds) override; + F32 getGamma() override; + BOOL setGamma(const F32 gamma) override; // Set the gamma + U32 getFSAASamples() override; + void setFSAASamples(const U32 fsaa_samples) override; + BOOL restoreGamma() override; // Restore original gamma table (before updating gamma) + ESwapMethod getSwapMethod() override { return mSwapMethod; } + void gatherInput() override; + void delayInputProcessing() override {}; + void swapBuffers() override; // handy coordinate space conversion routines - /*virtual*/ BOOL convertCoords(LLCoordScreen from, LLCoordWindow *to); - /*virtual*/ BOOL convertCoords(LLCoordWindow from, LLCoordScreen *to); - /*virtual*/ BOOL convertCoords(LLCoordWindow from, LLCoordGL *to); - /*virtual*/ BOOL convertCoords(LLCoordGL from, LLCoordWindow *to); - /*virtual*/ BOOL convertCoords(LLCoordScreen from, LLCoordGL *to); - /*virtual*/ BOOL convertCoords(LLCoordGL from, LLCoordScreen *to); + BOOL convertCoords(LLCoordScreen from, LLCoordWindow *to) override; + BOOL convertCoords(LLCoordWindow from, LLCoordScreen *to) override; + BOOL convertCoords(LLCoordWindow from, LLCoordGL *to) override; + BOOL convertCoords(LLCoordGL from, LLCoordWindow *to) override; + BOOL convertCoords(LLCoordScreen from, LLCoordGL *to) override; + BOOL convertCoords(LLCoordGL from, LLCoordScreen *to) override; - /*virtual*/ LLWindowResolution* getSupportedResolutions(S32 &num_resolutions); - /*virtual*/ F32 getNativeAspectRatio(); - /*virtual*/ F32 getPixelAspectRatio(); - /*virtual*/ void setNativeAspectRatio(F32 ratio) { mOverrideAspectRatio = ratio; } + LLWindowResolution* getSupportedResolutions(S32 &num_resolutions) override; + F32 getNativeAspectRatio() override; + F32 getPixelAspectRatio() override; + void setNativeAspectRatio(F32 ratio) override { mOverrideAspectRatio = ratio; } - /*virtual*/ void beforeDialog(); - /*virtual*/ void afterDialog(); + void beforeDialog() override; + void afterDialog() override; - /*virtual*/ BOOL dialogColorPicker(F32 *r, F32 *g, F32 *b); + BOOL dialogColorPicker(F32 *r, F32 *g, F32 *b) override; - /*virtual*/ void *getPlatformWindow(); - /*virtual*/ void bringToFront() {}; + void *getPlatformWindow() override; + void bringToFront() override {}; - /*virtual*/ void allowLanguageTextInput(LLPreeditor *preeditor, BOOL b); - /*virtual*/ void interruptLanguageTextInput(); - /*virtual*/ void spawnWebBrowser(const std::string& escaped_url, bool async); - /*virtual*/ F32 getSystemUISize(); + void allowLanguageTextInput(LLPreeditor *preeditor, BOOL b) override; + void interruptLanguageTextInput() override; + void spawnWebBrowser(const std::string& escaped_url, bool async) override; + F32 getSystemUISize() override; static std::vector<std::string> getDisplaysResolutionList(); static std::vector<std::string> getDynamicFallbackFontList(); // Provide native key event data - /*virtual*/ LLSD getNativeKeyData(); + LLSD getNativeKeyData() override; void* getWindow() { return mWindow; } LLWindowCallbacks* getCallbacks() { return mCallbacks; } @@ -133,16 +132,27 @@ class LLWindowMacOSX : public LLWindow bool allowsLanguageInput() { return mLanguageTextInputAllowed; } + //create a new GL context that shares a namespace with this Window's main GL context and make it current on the current thread + // returns a pointer to be handed back to destroySharedConext/makeContextCurrent + void* createSharedContext() override; + //make the given context current on the current thread + void makeContextCurrent(void* context) override; + //destroy the given context that was retrieved by createSharedContext() + //Must be called on the same thread that called createSharedContext() + void destroySharedContext(void* context) override; + + void toggleVSync(bool enable_vsync) override; + protected: LLWindowMacOSX(LLWindowCallbacks* callbacks, const std::string& title, const std::string& name, int x, int y, int width, int height, U32 flags, - BOOL fullscreen, BOOL clearBg, BOOL disable_vsync, BOOL use_gl, + BOOL fullscreen, BOOL clearBg, BOOL enable_vsync, BOOL use_gl, BOOL ignore_pixel_depth, U32 fsaa_samples); ~LLWindowMacOSX(); void initCursors(); - BOOL isValid(); + BOOL isValid() override; void moveWindow(const LLCoordScreen& position,const LLCoordScreen& size); @@ -166,7 +176,7 @@ class LLWindowMacOSX : public LLWindow // // create or re-create the GL context/window. Called from the constructor and switchContext(). - BOOL createContext(int x, int y, int width, int height, int bits, BOOL fullscreen, BOOL disable_vsync); + BOOL createContext(int x, int y, int width, int height, int bits, BOOL fullscreen, BOOL enable_vsync); void destroyContext(); void setupFailure(const std::string& text, const std::string& caption, U32 type); void adjustCursorDecouple(bool warpingMouse = false); @@ -229,9 +239,9 @@ class LLSplashScreenMacOSX : public LLSplashScreen LLSplashScreenMacOSX(); virtual ~LLSplashScreenMacOSX() = default; - /*virtual*/ void showImpl(); - /*virtual*/ void updateImpl(const std::string& mesg); - /*virtual*/ void hideImpl(); + void showImpl(); + void updateImpl(const std::string& mesg); + void hideImpl(); private: WindowRef mWindow; diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp index af2440a0d8f2eb31e129b1259f4bba729be20ce5..c5dd9115d0abe12f136ee84b5516d5697e920112 100644 --- a/indra/llwindow/llwindowsdl.cpp +++ b/indra/llwindow/llwindowsdl.cpp @@ -240,10 +240,11 @@ void sdlLogOutputFunc(void *userdata, int category, SDL_LogPriority priority, co } LLWindowSDL::LLWindowSDL(LLWindowCallbacks* callbacks, - const std::string& title, S32 x, S32 y, S32 width, + const std::string& title, const std::string& name, + S32 x, S32 y, S32 width, S32 height, U32 flags, BOOL fullscreen, BOOL clearBg, - BOOL disable_vsync, BOOL use_gl, + BOOL enable_vsync, BOOL use_gl, BOOL ignore_pixel_depth, U32 fsaa_samples) : LLWindow(callbacks, fullscreen, flags), mGamma(1.0f) @@ -294,7 +295,7 @@ LLWindowSDL::LLWindowSDL(LLWindowCallbacks* callbacks, mWindowTitle = title; // Create the GL context and set it up for windowed or fullscreen, as appropriate. - if(createContext(x, y, width, height, 32, fullscreen, disable_vsync)) + if(createContext(x, y, width, height, 32, fullscreen, enable_vsync)) { gGLManager.initGL(); @@ -480,7 +481,7 @@ static int x11_detect_VRAM_kb() } #endif // LL_X11 -BOOL LLWindowSDL::createContext(int x, int y, int width, int height, int bits, BOOL fullscreen, BOOL disable_vsync) +BOOL LLWindowSDL::createContext(int x, int y, int width, int height, int bits, BOOL fullscreen, BOOL enable_vsync) { //bool glneedsinit = false; @@ -547,7 +548,6 @@ BOOL LLWindowSDL::createContext(int x, int y, int width, int height, int bits, B if (LLRender::sGLCoreProfile) { SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); - LLGLSLShader::sNoFixedFunction = true; } U32 context_flags = 0; @@ -748,15 +748,6 @@ BOOL LLWindowSDL::createContext(int x, int y, int width, int height, int bits, B LL_INFOS() << "Created OpenGL " << llformat("%d.%d", major_gl_version, minor_gl_version) << (LLRender::sGLCoreProfile ? " core" : " compatibility") << " context." << LL_ENDL; - int vsync_enable = 1; - if(disable_vsync) - vsync_enable = 0; - - if(SDL_GL_SetSwapInterval(vsync_enable) == -1) - { - LL_INFOS() << "Swap interval not supported with sdl err: " << SDL_GetError() << LL_ENDL; - } - SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &redBits); SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &greenBits); SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &blueBits); @@ -801,6 +792,8 @@ BOOL LLWindowSDL::createContext(int x, int y, int width, int height, int bits, B return FALSE; } + // Disable vertical sync for swap + toggleVSync(enable_vsync); setIcon(); @@ -835,15 +828,57 @@ BOOL LLWindowSDL::createContext(int x, int y, int width, int height, int bits, B } # endif // LL_X11 - // make sure multisampling is disabled by default - glDisable(GL_MULTISAMPLE_ARB); - // Don't need to get the current gamma, since there's a call that restores it to the system defaults. return TRUE; } +void* LLWindowSDL::createSharedContext() +{ + SDL_GLContext shared_context = SDL_GL_CreateContext(mWindow); + if (shared_context) + { + SDL_GL_MakeCurrent(mWindow, shared_context); + SDL_GL_SetSwapInterval(0); + SDL_GL_MakeCurrent(mWindow, mGLContext); + + LL_INFOS() << "Creating shared OpenGL context successful!" << LL_ENDL; + + return (void*)shared_context; + } + + LL_WARNS() << "Creating shared OpenGL context failed!" << LL_ENDL; + + return nullptr; +} + +void LLWindowSDL::makeContextCurrent(void* context) +{ + LL_PROFILER_GPU_CONTEXT; + SDL_GL_MakeCurrent(mWindow, context); +} + +void LLWindowSDL::destroySharedContext(void* context) +{ + SDL_GL_DeleteContext(context); +} + +void LLWindowSDL::toggleVSync(bool enable_vsync) +{ + if(enable_vsync) + { + if(SDL_GL_SetSwapInterval(-1) != 0) + { + SDL_GL_SetSwapInterval(1); + } + } + else + { + SDL_GL_SetSwapInterval(0); + } +} + // changing fullscreen resolution, or switching between windowed and fullscreen mode. -BOOL LLWindowSDL::switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp) +BOOL LLWindowSDL::switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL enable_vsync, const LLCoordScreen * const posp) { const BOOL needsRebuild = TRUE; // Just nuke the context and start over. BOOL result = true; @@ -853,7 +888,7 @@ BOOL LLWindowSDL::switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL if(needsRebuild) { destroyContext(); - result = createContext(0, 0, size.mX, size.mY, 32, fullscreen, disable_vsync); + result = createContext(0, 0, size.mX, size.mY, 32, fullscreen, enable_vsync); if (result) { gGLManager.initGL(); @@ -2908,7 +2943,7 @@ std::vector<std::string> LLWindowSDL::getDynamicFallbackFontList() #endif } -void LLWindowSDL::setWindowTitle(const std::string& title) +void LLWindowSDL::setTitle(const std::string title) { if(mWindow) { diff --git a/indra/llwindow/llwindowsdl.h b/indra/llwindow/llwindowsdl.h index a6e45f21823bd11011c1b1c181b726726eb46aeb..30c4f4adbcfa51aa9ebd8269ecda23efb45efe90 100644 --- a/indra/llwindow/llwindowsdl.h +++ b/indra/llwindow/llwindowsdl.h @@ -30,6 +30,11 @@ // Simple Directmedia Layer (http://libsdl.org/) implementation of LLWindow class #include "llwindow.h" + +#if LL_WINDOWS +#include "llwin32headers.h" +#endif + #include "lltimer.h" #include "llpreeditor.h" @@ -70,9 +75,12 @@ class LLWindowSDL final : public LLWindow /*virtual*/ BOOL setPosition(LLCoordScreen position) override; /*virtual*/ BOOL setSizeImpl(LLCoordScreen size) override; /*virtual*/ BOOL setSizeImpl(LLCoordWindow size) override; - /*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp = NULL) override; + /*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL enable_vsync, const LLCoordScreen * const posp = NULL) override; /*virtual*/ BOOL setCursorPosition(LLCoordWindow position) override; /*virtual*/ BOOL getCursorPosition(LLCoordWindow *position) override; +#if LL_WINDOWS + /*virtual*/ BOOL getCursorDelta(LLCoordCommon* delta) override { return FALSE; } +#endif /*virtual*/ void showCursor() override; /*virtual*/ void hideCursor() override; /*virtual*/ void showCursorFromMouseMove() override; @@ -91,7 +99,11 @@ class LLWindowSDL final : public LLWindow /*virtual*/ BOOL isPrimaryTextAvailable() override; /*virtual*/ BOOL pasteTextFromPrimary(LLWString &dst) override; /*virtual*/ BOOL copyTextToPrimary(const LLWString & src) override; - /*virtual*/ void setWindowTitle(const std::string& title) override; + /*virtual*/ void setTitle(const std::string title) override; + void* createSharedContext() override; + void makeContextCurrent(void* context) override; + void destroySharedContext(void* context) override; + /*virtual*/ void toggleVSync(bool enable_vsync) override; /*virtual*/ void flashIcon(F32 seconds) override; /*virtual*/ F32 getGamma() override; /*virtual*/ BOOL setGamma(const F32 gamma) override; // Set the gamma @@ -155,7 +167,7 @@ class LLWindowSDL final : public LLWindow protected: LLWindowSDL(LLWindowCallbacks* callbacks, - const std::string& title, int x, int y, int width, int height, U32 flags, + const std::string& title, const std::string& name, int x, int y, int width, int height, U32 flags, BOOL fullscreen, BOOL clearBg, BOOL disable_vsync, BOOL use_gl, BOOL ignore_pixel_depth, U32 fsaa_samples); ~LLWindowSDL(); @@ -241,6 +253,10 @@ class LLSplashScreenSDL : public LLSplashScreen /*virtual*/ void showImpl() override; /*virtual*/ void updateImpl(const std::string& mesg) override; /*virtual*/ void hideImpl() override; +private: +#if LL_WINDOWS + HWND mWindow; +#endif }; S32 OSMessageBoxSDL(const std::string& text, const std::string& caption, U32 type); diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index a5cbef0cf6eefbe23b54f3d7ba3e15ce5f2c6aba..eb8642d0873d6f2a4c47253239741c68b5ae7ae3 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -45,6 +45,8 @@ #include "lldir.h" #include "llsdutil.h" #include "llglslshader.h" +#include "llthreadsafequeue.h" +#include "stringize.h" // System includes #include <commdlg.h> @@ -54,6 +56,10 @@ #include <shellapi.h> #include <fstream> #include <Imm.h> +#include <iomanip> +#include <future> +#include <sstream> +#include <utility> // std::pair // Require DirectInput version 8 #define DIRECTINPUT_VERSION 0x0800 @@ -72,6 +78,22 @@ const S32 BITS_PER_PIXEL = 32; const S32 MAX_NUM_RESOLUTIONS = 32; const F32 ICON_FLASH_TIME = 0.5f; +// Claim a couple unused GetMessage() message IDs +const UINT WM_DUMMY_(WM_USER + 0x0017); +const UINT WM_POST_FUNCTION_(WM_USER + 0x0018); + + +static std::thread::id sWindowThreadId; +static std::thread::id sMainThreadId; + +#if 1 // flip to zero to enable assertions for functions being called from wrong thread +#define ASSERT_MAIN_THREAD() +#define ASSERT_WINDOW_THREAD() +#else +#define ASSERT_MAIN_THREAD() llassert(LLThread::currentID() == sMainThreadId) +#define ASSERT_WINDOW_THREAD() llassert(LLThread::currentID() == sWindowThreadId) +#endif + LPDIRECTINPUT8 gDirectInput8; // @@ -122,23 +144,19 @@ DWORD LLWindowWin32::sWinIMESentenceMode = IME_SMODE_AUTOMATIC; LLCoordWindow LLWindowWin32::sWinIMEWindowPosition(-1,-1); // The following class LLWinImm delegates Windows IMM APIs. -// We need this because some language versions of Windows, -// e.g., US version of Windows XP, doesn't install IMM32.DLL -// as a default, and we can't link against imm32.lib statically. -// I believe DLL loading of this type is best suited to do -// in a static initialization of a class. What I'm not sure is -// whether it follows the Linden Conding Standard... -// See http://wiki.secondlife.com/wiki/Coding_standards#Static_Members +// It was originally introduced to support US Windows XP, on which we needed +// to dynamically load IMM32.DLL and use GetProcAddress to resolve its entry +// points. Now that that's moot, we retain this wrapper only for hooks for +// metrics. class LLWinImm { public: - static bool isAvailable() { return sTheInstance.mHImmDll != NULL; } + static bool isAvailable() { return true; } public: // Wrappers for IMM API. static BOOL isIME(HKL hkl); - static HWND getDefaultIMEWnd(HWND hwnd); static HIMC getContext(HWND hwnd); static BOOL releaseContext(HWND hwnd, HIMC himc); static BOOL getOpenStatus(HIMC himc); @@ -152,236 +170,96 @@ class LLWinImm static BOOL setCompositionFont(HIMC himc, LPLOGFONTW logfont); static BOOL setCandidateWindow(HIMC himc, LPCANDIDATEFORM candidate_form); static BOOL notifyIME(HIMC himc, DWORD action, DWORD index, DWORD value); - -private: - LLWinImm(); - ~LLWinImm(); - -private: - // Pointers to IMM API. - BOOL (WINAPI *mImmIsIME)(HKL); - HWND (WINAPI *mImmGetDefaultIMEWnd)(HWND); - HIMC (WINAPI *mImmGetContext)(HWND); - BOOL (WINAPI *mImmReleaseContext)(HWND, HIMC); - BOOL (WINAPI *mImmGetOpenStatus)(HIMC); - BOOL (WINAPI *mImmSetOpenStatus)(HIMC, BOOL); - BOOL (WINAPI *mImmGetConversionStatus)(HIMC, LPDWORD, LPDWORD); - BOOL (WINAPI *mImmSetConversionStatus)(HIMC, DWORD, DWORD); - BOOL (WINAPI *mImmGetCompostitionWindow)(HIMC, LPCOMPOSITIONFORM); - BOOL (WINAPI *mImmSetCompostitionWindow)(HIMC, LPCOMPOSITIONFORM); - LONG (WINAPI *mImmGetCompositionString)(HIMC, DWORD, LPVOID, DWORD); - BOOL (WINAPI *mImmSetCompositionString)(HIMC, DWORD, LPVOID, DWORD, LPVOID, DWORD); - BOOL (WINAPI *mImmSetCompositionFont)(HIMC, LPLOGFONTW); - BOOL (WINAPI *mImmSetCandidateWindow)(HIMC, LPCANDIDATEFORM); - BOOL (WINAPI *mImmNotifyIME)(HIMC, DWORD, DWORD, DWORD); - -private: - HMODULE mHImmDll; - static LLWinImm sTheInstance; }; -LLWinImm LLWinImm::sTheInstance; - -LLWinImm::LLWinImm() : mHImmDll(NULL) -{ - // Check system metrics - if ( !GetSystemMetrics( SM_IMMENABLED ) ) - return; - - mHImmDll = LoadLibrary(TEXT("Imm32")); - if (mHImmDll != NULL) - { - mImmIsIME = (BOOL (WINAPI *)(HKL)) GetProcAddress(mHImmDll, "ImmIsIME"); - mImmGetDefaultIMEWnd = (HWND (WINAPI *)(HWND)) GetProcAddress(mHImmDll, "ImmGetDefaultIMEWnd"); - mImmGetContext = (HIMC (WINAPI *)(HWND)) GetProcAddress(mHImmDll, "ImmGetContext"); - mImmReleaseContext = (BOOL (WINAPI *)(HWND, HIMC)) GetProcAddress(mHImmDll, "ImmReleaseContext"); - mImmGetOpenStatus = (BOOL (WINAPI *)(HIMC)) GetProcAddress(mHImmDll, "ImmGetOpenStatus"); - mImmSetOpenStatus = (BOOL (WINAPI *)(HIMC, BOOL)) GetProcAddress(mHImmDll, "ImmSetOpenStatus"); - mImmGetConversionStatus = (BOOL (WINAPI *)(HIMC, LPDWORD, LPDWORD)) GetProcAddress(mHImmDll, "ImmGetConversionStatus"); - mImmSetConversionStatus = (BOOL (WINAPI *)(HIMC, DWORD, DWORD)) GetProcAddress(mHImmDll, "ImmSetConversionStatus"); - mImmGetCompostitionWindow = (BOOL (WINAPI *)(HIMC, LPCOMPOSITIONFORM)) GetProcAddress(mHImmDll, "ImmGetCompositionWindow"); - mImmSetCompostitionWindow = (BOOL (WINAPI *)(HIMC, LPCOMPOSITIONFORM)) GetProcAddress(mHImmDll, "ImmSetCompositionWindow"); - mImmGetCompositionString= (LONG (WINAPI *)(HIMC, DWORD, LPVOID, DWORD)) GetProcAddress(mHImmDll, "ImmGetCompositionStringW"); - mImmSetCompositionString= (BOOL (WINAPI *)(HIMC, DWORD, LPVOID, DWORD, LPVOID, DWORD)) GetProcAddress(mHImmDll, "ImmSetCompositionStringW"); - mImmSetCompositionFont = (BOOL (WINAPI *)(HIMC, LPLOGFONTW)) GetProcAddress(mHImmDll, "ImmSetCompositionFontW"); - mImmSetCandidateWindow = (BOOL (WINAPI *)(HIMC, LPCANDIDATEFORM)) GetProcAddress(mHImmDll, "ImmSetCandidateWindow"); - mImmNotifyIME = (BOOL (WINAPI *)(HIMC, DWORD, DWORD, DWORD)) GetProcAddress(mHImmDll, "ImmNotifyIME"); - - if (mImmIsIME == NULL || - mImmGetDefaultIMEWnd == NULL || - mImmGetContext == NULL || - mImmReleaseContext == NULL || - mImmGetOpenStatus == NULL || - mImmSetOpenStatus == NULL || - mImmGetConversionStatus == NULL || - mImmSetConversionStatus == NULL || - mImmGetCompostitionWindow == NULL || - mImmSetCompostitionWindow == NULL || - mImmGetCompositionString == NULL || - mImmSetCompositionString == NULL || - mImmSetCompositionFont == NULL || - mImmSetCandidateWindow == NULL || - mImmNotifyIME == NULL) - { - // If any of the above API entires are not found, we can't use IMM API. - // So, turn off the IMM support. We should log some warning message in - // the case, since it is very unusual; these APIs are available from - // the beginning, and all versions of IMM32.DLL should have them all. - // Unfortunately, this code may be executed before initialization of - // the logging channel (LL_WARNS()), and we can't do it here... Yes, this - // is one of disadvantages to use static constraction to DLL loading. - FreeLibrary(mHImmDll); - mHImmDll = NULL; - - // If we unload the library, make sure all the function pointers are cleared - mImmIsIME = NULL; - mImmGetDefaultIMEWnd = NULL; - mImmGetContext = NULL; - mImmReleaseContext = NULL; - mImmGetOpenStatus = NULL; - mImmSetOpenStatus = NULL; - mImmGetConversionStatus = NULL; - mImmSetConversionStatus = NULL; - mImmGetCompostitionWindow = NULL; - mImmSetCompostitionWindow = NULL; - mImmGetCompositionString = NULL; - mImmSetCompositionString = NULL; - mImmSetCompositionFont = NULL; - mImmSetCandidateWindow = NULL; - mImmNotifyIME = NULL; - } - } -} - - // static -BOOL LLWinImm::isIME(HKL hkl) +BOOL LLWinImm::isIME(HKL hkl) { - if ( sTheInstance.mImmIsIME ) - return sTheInstance.mImmIsIME(hkl); - return FALSE; + return ImmIsIME(hkl); } // static HIMC LLWinImm::getContext(HWND hwnd) { - if ( sTheInstance.mImmGetContext ) - return sTheInstance.mImmGetContext(hwnd); - return 0; + return ImmGetContext(hwnd); } //static BOOL LLWinImm::releaseContext(HWND hwnd, HIMC himc) { - if ( sTheInstance.mImmIsIME ) - return sTheInstance.mImmReleaseContext(hwnd, himc); - return FALSE; + return ImmReleaseContext(hwnd, himc); } // static BOOL LLWinImm::getOpenStatus(HIMC himc) { - if ( sTheInstance.mImmGetOpenStatus ) - return sTheInstance.mImmGetOpenStatus(himc); - return FALSE; + return ImmGetOpenStatus(himc); } // static -BOOL LLWinImm::setOpenStatus(HIMC himc, BOOL status) +BOOL LLWinImm::setOpenStatus(HIMC himc, BOOL status) { - if ( sTheInstance.mImmSetOpenStatus ) - return sTheInstance.mImmSetOpenStatus(himc, status); - return FALSE; + return ImmSetOpenStatus(himc, status); } // static BOOL LLWinImm::getConversionStatus(HIMC himc, LPDWORD conversion, LPDWORD sentence) { - if ( sTheInstance.mImmGetConversionStatus ) - return sTheInstance.mImmGetConversionStatus(himc, conversion, sentence); - return FALSE; + return ImmGetConversionStatus(himc, conversion, sentence); } // static BOOL LLWinImm::setConversionStatus(HIMC himc, DWORD conversion, DWORD sentence) { - if ( sTheInstance.mImmSetConversionStatus ) - return sTheInstance.mImmSetConversionStatus(himc, conversion, sentence); - return FALSE; + return ImmSetConversionStatus(himc, conversion, sentence); } // static BOOL LLWinImm::getCompositionWindow(HIMC himc, LPCOMPOSITIONFORM form) { - if ( sTheInstance.mImmGetCompostitionWindow ) - return sTheInstance.mImmGetCompostitionWindow(himc, form); - return FALSE; + return ImmGetCompositionWindow(himc, form); } // static BOOL LLWinImm::setCompositionWindow(HIMC himc, LPCOMPOSITIONFORM form) { - if ( sTheInstance.mImmSetCompostitionWindow ) - return sTheInstance.mImmSetCompostitionWindow(himc, form); - return FALSE; + return ImmSetCompositionWindow(himc, form); } // static LONG LLWinImm::getCompositionString(HIMC himc, DWORD index, LPVOID data, DWORD length) { - if ( sTheInstance.mImmGetCompositionString ) - return sTheInstance.mImmGetCompositionString(himc, index, data, length); - return FALSE; + return ImmGetCompositionString(himc, index, data, length); } // static BOOL LLWinImm::setCompositionString(HIMC himc, DWORD index, LPVOID pComp, DWORD compLength, LPVOID pRead, DWORD readLength) { - if ( sTheInstance.mImmSetCompositionString ) - return sTheInstance.mImmSetCompositionString(himc, index, pComp, compLength, pRead, readLength); - return FALSE; + return ImmSetCompositionString(himc, index, pComp, compLength, pRead, readLength); } // static BOOL LLWinImm::setCompositionFont(HIMC himc, LPLOGFONTW pFont) { - if ( sTheInstance.mImmSetCompositionFont ) - return sTheInstance.mImmSetCompositionFont(himc, pFont); - return FALSE; + return ImmSetCompositionFont(himc, pFont); } // static BOOL LLWinImm::setCandidateWindow(HIMC himc, LPCANDIDATEFORM form) { - if ( sTheInstance.mImmSetCandidateWindow ) - return sTheInstance.mImmSetCandidateWindow(himc, form); - return FALSE; + return ImmSetCandidateWindow(himc, form); } // static BOOL LLWinImm::notifyIME(HIMC himc, DWORD action, DWORD index, DWORD value) { - if ( sTheInstance.mImmNotifyIME ) - return sTheInstance.mImmNotifyIME(himc, action, index, value); - return FALSE; + return ImmNotifyIME(himc, action, index, value); } - -// ---------------------------------------------------------------------------------------- -LLWinImm::~LLWinImm() -{ - if (mHImmDll != NULL) - { - FreeLibrary(mHImmDll); - mHImmDll = NULL; - } -} - - class LLMonitorInfo { public: @@ -415,11 +293,77 @@ class LLMonitorInfo static LLMonitorInfo sMonitorInfo; + +// Thread that owns the Window Handle +// This whole struct is private to LLWindowWin32, which needs to mess with its +// members, which is why it's a struct rather than a class. In effect, we make +// the containing class a friend. +struct LLWindowWin32::LLWindowWin32Thread : public LL::ThreadPool +{ + static const int MAX_QUEUE_SIZE = 2048; + + LLThreadSafeQueue<MSG> mMessageQueue; + + LLWindowWin32Thread(); + + void run() override; + + /// called by main thread to post work to this window thread + template <typename CALLABLE> + void post(CALLABLE&& func) + { + try + { + getQueue().post(std::forward<CALLABLE>(func)); + } + catch (const LLThreadSafeQueueInterrupt&) + { + // Shutdown timing is tricky. The main thread can end up trying + // to post a cursor position after having closed the WorkQueue. + } + } + + /** + * Like post(), Post() is a way of conveying a single work item to this + * thread. Its virtue is that it will definitely be executed "soon" rather + * than potentially waiting for the next frame: it uses PostMessage() to + * break us out of the window thread's blocked GetMessage() call. It's + * more expensive, though, not only from the Windows API latency of + * PostMessage() and GetMessage(), but also because it involves heap + * allocation and release. + * + * Require HWND from caller, even though we store an HWND locally. + * Otherwise, if our mWindowHandle was accessed from both threads, we'd + * have to protect it with a mutex. + */ + template <typename CALLABLE> + void Post(HWND windowHandle, CALLABLE&& func) + { + // Move func to the heap. If we knew FuncType could fit into LPARAM, + // we could simply instantiate FuncType and pass it by value. But + // since we don't, we must put that on the heap as well as the + // internal heap allocation it likely requires to store func. + auto ptr = new FuncType(std::move(func)); + WPARAM wparam{ 0xF1C }; + LL_DEBUGS("Window") << "PostMessage(" << std::hex << windowHandle + << ", " << WM_POST_FUNCTION_ + << ", " << wparam << std::dec << LL_ENDL; + PostMessage(windowHandle, WM_POST_FUNCTION_, wparam, LPARAM(ptr)); + } + + using FuncType = std::function<void()>; + // call GetMessage() and pull enqueue messages for later processing + void gatherInput(); + HWND mWindowHandle = NULL; + HDC mhDC = 0; +}; + + LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks, const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height, U32 flags, BOOL fullscreen, BOOL clearBg, - BOOL disable_vsync, BOOL use_gl, + BOOL enable_vsync, BOOL use_gl, BOOL ignore_pixel_depth, U32 fsaa_samples) : LLWindow(callbacks, fullscreen, flags) @@ -434,7 +378,8 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks, , pAdjustWindowRectExForDpi(nullptr) , pGetSystemMetricsForDpi(nullptr) { - + sMainThreadId = LLThread::currentID(); + mWindowThread = new LLWindowWin32Thread(); //MAINT-516 -- force a load of opengl32.dll just in case windows went sideways //mOpenGL32DLL = LoadLibrary(TEXT("opengl32.dll")); @@ -509,7 +454,6 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks, mIconResource = MAKEINTRESOURCE(IDI_LL_ICON); mOverrideAspectRatio = 0.f; mNativeAspectRatio = 0.f; - mMousePositionModified = FALSE; mInputProcessingPaused = FALSE; mPreeditor = NULL; mKeyCharCode = 0; @@ -521,6 +465,9 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks, memset(mPrevGammaRamp, 0, sizeof(mPrevGammaRamp)); mCustomGammaSet = FALSE; mWindowHandle = NULL; + + mRect = {0, 0, 0, 0}; + mClientRect = {0, 0, 0, 0}; if (!SystemParametersInfo(SPI_GETMOUSEVANISH, 0, &mMouseVanish, 0)) { @@ -575,7 +522,6 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks, // Make an instance of our window then define the window class mhInstance = GetModuleHandle(NULL); - mWndProc = NULL; // Init Direct Input - needed for joystick / Spacemouse @@ -856,7 +802,7 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks, LLCoordScreen windowPos(x,y); LLCoordScreen windowSize(window_rect.right - window_rect.left, window_rect.bottom - window_rect.top); - if (!switchContext(mFullscreen, windowSize, disable_vsync, &windowPos)) + if (!switchContext(mFullscreen, windowSize, enable_vsync, &windowPos)) { return; } @@ -865,6 +811,13 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks, initCursors(); setCursor( UI_CURSOR_ARROW ); + mRawMouse.usUsagePage = 0x01; // HID_USAGE_PAGE_GENERIC + mRawMouse.usUsage = 0x02; // HID_USAGE_GENERIC_MOUSE + mRawMouse.dwFlags = 0; // adds mouse and also ignores legacy mouse messages + mRawMouse.hwndTarget = 0; + + RegisterRawInputDevices(&mRawMouse, 1, sizeof(mRawMouse)); + // Initialize (boot strap) the Language text input management, // based on the system's (or user's) default settings. allowLanguageTextInput(NULL, FALSE); @@ -898,6 +851,8 @@ LLWindowWin32::~LLWindowWin32() { FreeLibrary(mOpenGL32DLL); } + + delete mWindowThread; } void LLWindowWin32::show() @@ -937,7 +892,7 @@ void LLWindowWin32::restore() // I'm turning off optimizations for this part to be sure code executes as intended // (it is a straw, but I have no idea why else __try can get overruled) #pragma optimize("", off) -bool destroy_window_handler(HWND &hWnd) +bool destroy_window_handler(HWND hWnd) { bool res; __try @@ -1016,37 +971,48 @@ void LLWindowWin32::close() // Restore gamma to the system values. restoreGamma(); - if (mhDC) - { - if (!ReleaseDC(mWindowHandle, mhDC)) - { - LL_WARNS("Window") << "Release of mhDC failed" << LL_ENDL; - } - mhDC = NULL; - } - LL_DEBUGS("Window") << "Destroying Window" << LL_ENDL; - if (IsWindow(mWindowHandle)) - { - // Make sure we don't leave a blank toolbar button. - ShowWindow(mWindowHandle, SW_HIDE); - - // This causes WM_DESTROY to be sent *immediately* - if (!destroy_window_handler(mWindowHandle)) + mWindowThread->post([=]() { - OSMessageBox(mCallbacks->translateString("MBDestroyWinFailed"), - mCallbacks->translateString("MBShutdownErr"), - OSMB_OK); - } - } - else - { - // Something killed the window while we were busy destroying gl or handle somehow got broken - LL_WARNS("Window") << "Failed to destroy Window, invalid handle!" << LL_ENDL; - } + if (IsWindow(mWindowHandle)) + { + if (mhDC) + { + if (!ReleaseDC(mWindowHandle, mhDC)) + { + LL_WARNS("Window") << "Release of ghDC failed!" << LL_ENDL; + } + } + + // Make sure we don't leave a blank toolbar button. + ShowWindow(mWindowHandle, SW_HIDE); + + // This causes WM_DESTROY to be sent *immediately* + if (!destroy_window_handler(mWindowHandle)) + { + OSMessageBox(mCallbacks->translateString("MBDestroyWinFailed"), + mCallbacks->translateString("MBShutdownErr"), + OSMB_OK); + } + } + else + { + // Something killed the window while we were busy destroying gl or handle somehow got broken + LL_WARNS("Window") << "Failed to destroy Window, invalid handle!" << LL_ENDL; + } - mWindowHandle = NULL; + }); + // Window thread might be waiting for a getMessage(), give it + // a push to enshure it will process destroy_window_handler + kickWindowThread(); + + // Even though the above lambda might not yet have run, we've already + // bound mWindowHandle into it by value, which should suffice for the + // operations we're asking. That's the last time WE should touch it. + mhDC = NULL; + mWindowHandle = NULL; + mWindowThread->close(); } BOOL LLWindowWin32::isValid() @@ -1093,49 +1059,22 @@ BOOL LLWindowWin32::getFullscreen() BOOL LLWindowWin32::getPosition(LLCoordScreen *position) { - RECT window_rect; - - if (!mWindowHandle || - !GetWindowRect(mWindowHandle, &window_rect) || - NULL == position) - { - return FALSE; - } - - position->mX = window_rect.left; - position->mY = window_rect.top; + position->mX = mRect.left; + position->mY = mRect.top; return TRUE; } BOOL LLWindowWin32::getSize(LLCoordScreen *size) { - RECT window_rect; - - if (!mWindowHandle || - !GetWindowRect(mWindowHandle, &window_rect) || - NULL == size) - { - return FALSE; - } - - size->mX = window_rect.right - window_rect.left; - size->mY = window_rect.bottom - window_rect.top; + size->mX = mRect.right - mRect.left; + size->mY = mRect.bottom - mRect.top; return TRUE; } BOOL LLWindowWin32::getSize(LLCoordWindow *size) { - RECT client_rect; - - if (!mWindowHandle || - !GetClientRect(mWindowHandle, &client_rect) || - NULL == size) - { - return FALSE; - } - - size->mX = client_rect.right - client_rect.left; - size->mY = client_rect.bottom - client_rect.top; + size->mX = mClientRect.right - mClientRect.left; + size->mY = mClientRect.bottom - mClientRect.top; return TRUE; } @@ -1162,14 +1101,17 @@ BOOL LLWindowWin32::setSizeImpl(const LLCoordScreen size) return FALSE; } - WINDOWPLACEMENT placement; - placement.length = sizeof(WINDOWPLACEMENT); - - if (!GetWindowPlacement(mWindowHandle, &placement)) return FALSE; - - placement.showCmd = SW_RESTORE; + mWindowThread->post([=]() + { + WINDOWPLACEMENT placement; + placement.length = sizeof(WINDOWPLACEMENT); - if (!SetWindowPlacement(mWindowHandle, &placement)) return FALSE; + if (GetWindowPlacement(mWindowHandle, &placement)) + { + placement.showCmd = SW_RESTORE; + SetWindowPlacement(mWindowHandle, &placement); + } + }); moveWindow(position, size); return TRUE; @@ -1202,171 +1144,159 @@ BOOL LLWindowWin32::setSizeImpl(const LLCoordWindow size) } // changing fullscreen resolution -BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp) +BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen& size, BOOL enable_vsync, const LLCoordScreen* const posp) { - GLuint pixel_format; - DEVMODE dev_mode; - ::ZeroMemory(&dev_mode, sizeof(DEVMODE)); - dev_mode.dmSize = sizeof(DEVMODE); - DWORD current_refresh; - DWORD dw_ex_style; - DWORD dw_style; - RECT window_rect = {0, 0, 0, 0}; - S32 width = size.mX; - S32 height = size.mY; - BOOL auto_show = FALSE; - - if (mhRC) - { - auto_show = TRUE; - resetDisplayResolution(); - } - - if (EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dev_mode)) - { - current_refresh = dev_mode.dmDisplayFrequency; - } - else - { - current_refresh = 60; - } - - gGLManager.shutdownGL(); - //destroy gl context - if (mhRC) - { - if (!wglMakeCurrent(NULL, NULL)) - { - LL_WARNS("Window") << "Release of DC and RC failed" << LL_ENDL; - } + //called from main thread + GLuint pixel_format; + DEVMODE dev_mode; + ::ZeroMemory(&dev_mode, sizeof(DEVMODE)); + dev_mode.dmSize = sizeof(DEVMODE); + DWORD current_refresh; + DWORD dw_ex_style; + DWORD dw_style; + RECT window_rect = { 0, 0, 0, 0 }; + S32 width = size.mX; + S32 height = size.mY; + BOOL auto_show = FALSE; + + if (mhRC) + { + auto_show = TRUE; + resetDisplayResolution(); + } - if (!wglDeleteContext(mhRC)) - { - LL_WARNS("Window") << "Release of rendering context failed" << LL_ENDL; - } + if (EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dev_mode)) + { + current_refresh = dev_mode.dmDisplayFrequency; + } + else + { + current_refresh = 60; + } - mhRC = NULL; - } + gGLManager.shutdownGL(); + //destroy gl context + if (mhRC) + { + if (!wglMakeCurrent(NULL, NULL)) + { + LL_WARNS("Window") << "Release of DC and RC failed" << LL_ENDL; + } - if (fullscreen) - { - mFullscreen = TRUE; - BOOL success = FALSE; - DWORD closest_refresh = 0; + if (!wglDeleteContext(mhRC)) + { + LL_WARNS("Window") << "Release of rendering context failed" << LL_ENDL; + } - for (S32 mode_num = 0;; mode_num++) - { - if (!EnumDisplaySettings(NULL, mode_num, &dev_mode)) - { - break; - } + mhRC = NULL; + } - if (dev_mode.dmPelsWidth == width && - dev_mode.dmPelsHeight == height && - dev_mode.dmBitsPerPel == BITS_PER_PIXEL) - { - success = TRUE; - if ((dev_mode.dmDisplayFrequency - current_refresh) - < (closest_refresh - current_refresh)) - { - closest_refresh = dev_mode.dmDisplayFrequency; - } - } - } + if (fullscreen) + { + mFullscreen = TRUE; + BOOL success = FALSE; + DWORD closest_refresh = 0; - if (closest_refresh == 0) - { - LL_WARNS("Window") << "Couldn't find display mode " << width << " by " << height << " at " << BITS_PER_PIXEL << " bits per pixel" << LL_ENDL; - return FALSE; - } + for (S32 mode_num = 0;; mode_num++) + { + if (!EnumDisplaySettings(NULL, mode_num, &dev_mode)) + { + break; + } - // If we found a good resolution, use it. - if (success) - { - success = setDisplayResolution(width, height, BITS_PER_PIXEL, closest_refresh); - } + if (dev_mode.dmPelsWidth == width && + dev_mode.dmPelsHeight == height && + dev_mode.dmBitsPerPel == BITS_PER_PIXEL) + { + success = TRUE; + if ((dev_mode.dmDisplayFrequency - current_refresh) + < (closest_refresh - current_refresh)) + { + closest_refresh = dev_mode.dmDisplayFrequency; + } + } + } - // Keep a copy of the actual current device mode in case we minimize - // and change the screen resolution. JC - EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dev_mode); + if (closest_refresh == 0) + { + LL_WARNS("Window") << "Couldn't find display mode " << width << " by " << height << " at " << BITS_PER_PIXEL << " bits per pixel" << LL_ENDL; + return FALSE; + } - if (success) - { - mFullscreen = TRUE; - mFullscreenWidth = dev_mode.dmPelsWidth; - mFullscreenHeight = dev_mode.dmPelsHeight; - mFullscreenBits = dev_mode.dmBitsPerPel; - mFullscreenRefresh = dev_mode.dmDisplayFrequency; + // If we found a good resolution, use it. + if (success) + { + success = setDisplayResolution(width, height, BITS_PER_PIXEL, closest_refresh); + } - LL_INFOS("Window") << "Running at " << dev_mode.dmPelsWidth - << "x" << dev_mode.dmPelsHeight - << "x" << dev_mode.dmBitsPerPel - << " @ " << dev_mode.dmDisplayFrequency - << LL_ENDL; + // Keep a copy of the actual current device mode in case we minimize + // and change the screen resolution. JC + EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dev_mode); - window_rect.left = (long) 0; - window_rect.right = (long) width; // Windows GDI rects don't include rightmost pixel - window_rect.top = (long) 0; - window_rect.bottom = (long) height; - dw_ex_style = WS_EX_APPWINDOW; - dw_style = WS_POPUP; + if (success) + { + mFullscreen = TRUE; + mFullscreenWidth = dev_mode.dmPelsWidth; + mFullscreenHeight = dev_mode.dmPelsHeight; + mFullscreenBits = dev_mode.dmBitsPerPel; + mFullscreenRefresh = dev_mode.dmDisplayFrequency; + + LL_INFOS("Window") << "Running at " << dev_mode.dmPelsWidth + << "x" << dev_mode.dmPelsHeight + << "x" << dev_mode.dmBitsPerPel + << " @ " << dev_mode.dmDisplayFrequency + << LL_ENDL; + + window_rect.left = (long)0; + window_rect.right = (long)width; // Windows GDI rects don't include rightmost pixel + window_rect.top = (long)0; + window_rect.bottom = (long)height; + dw_ex_style = WS_EX_APPWINDOW; + dw_style = WS_POPUP; + + // Move window borders out not to cover window contents. + // This converts client rect to window rect, i.e. expands it by the window border size. + AdjustWindowRectEx(&window_rect, dw_style, FALSE, dw_ex_style); + } + // If it failed, we don't want to run fullscreen + else + { + mFullscreen = FALSE; + mFullscreenWidth = -1; + mFullscreenHeight = -1; + mFullscreenBits = -1; + mFullscreenRefresh = -1; - // Move window borders out not to cover window contents. - // This converts client rect to window rect, i.e. expands it by the window border size. - AdjustWindowRectEx(&window_rect, dw_style, FALSE, dw_ex_style); - } - // If it failed, we don't want to run fullscreen - else - { - mFullscreen = FALSE; - mFullscreenWidth = -1; - mFullscreenHeight = -1; - mFullscreenBits = -1; - mFullscreenRefresh = -1; + LL_INFOS("Window") << "Unable to run fullscreen at " << width << "x" << height << LL_ENDL; + return FALSE; + } + } + else + { + mFullscreen = FALSE; + window_rect.left = (long)(posp ? posp->mX : 0); + window_rect.right = (long)width + window_rect.left; // Windows GDI rects don't include rightmost pixel + window_rect.top = (long)(posp ? posp->mY : 0); + window_rect.bottom = (long)height + window_rect.top; + // Window with an edge + dw_ex_style = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; + dw_style = WS_OVERLAPPEDWINDOW; + } - LL_INFOS("Window") << "Unable to run fullscreen at " << width << "x" << height << LL_ENDL; - return FALSE; - } - } - else - { - mFullscreen = FALSE; - window_rect.left = (long) (posp ? posp->mX : 0); - window_rect.right = (long) width + window_rect.left; // Windows GDI rects don't include rightmost pixel - window_rect.top = (long) (posp ? posp->mY : 0); - window_rect.bottom = (long) height + window_rect.top; - // Window with an edge - dw_ex_style = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; - dw_style = WS_OVERLAPPEDWINDOW; - } + // don't post quit messages when destroying old windows + mPostQuit = FALSE; - // don't post quit messages when destroying old windows - mPostQuit = FALSE; - // create window + // create window LL_DEBUGS("Window") << "Creating window with X: " << window_rect.left << " Y: " << window_rect.top << " Width: " << (window_rect.right - window_rect.left) << " Height: " << (window_rect.bottom - window_rect.top) << " Fullscreen: " << mFullscreen << LL_ENDL; - if (mWindowHandle && !destroy_window_handler(mWindowHandle)) - { - LL_WARNS("Window") << "Failed to properly close window before recreating it!" << LL_ENDL; - } - mWindowHandle = CreateWindowEx(dw_ex_style, - mWindowClassName, - mWindowTitle, - WS_CLIPSIBLINGS | WS_CLIPCHILDREN | dw_style, - window_rect.left, // x pos - window_rect.top, // y pos - window_rect.right - window_rect.left, // width - window_rect.bottom - window_rect.top, // height - NULL, - NULL, - mhInstance, - NULL); + + recreateWindow(window_rect, dw_ex_style, dw_style); if (mWindowHandle) { @@ -1400,7 +1330,7 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO 0, 0, 0 }; - if (!(mhDC = GetDC(mWindowHandle))) + if (!mhDC) { close(); OSMessageBox(mCallbacks->translateString("MBDevContextErr"), @@ -1437,9 +1367,9 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO if (!DescribePixelFormat(mhDC, pixel_format, sizeof(PIXELFORMATDESCRIPTOR), &pfd)) { - close(); OSMessageBox(mCallbacks->translateString("MBPixelFmtDescErr"), mCallbacks->translateString("MBError"), OSMB_OK); + close(); return FALSE; } @@ -1476,42 +1406,42 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO if (pfd.cColorBits < 32) { - close(); OSMessageBox(mCallbacks->translateString("MBTrueColorWindow"), mCallbacks->translateString("MBError"), OSMB_OK); + close(); return FALSE; } if (pfd.cAlphaBits < 8) { - close(); OSMessageBox(mCallbacks->translateString("MBAlpha"), mCallbacks->translateString("MBError"), OSMB_OK); + close(); return FALSE; } if (!SetPixelFormat(mhDC, pixel_format, &pfd)) { - close(); OSMessageBox(mCallbacks->translateString("MBPixelFmtSetErr"), mCallbacks->translateString("MBError"), OSMB_OK); + close(); return FALSE; } if (!(mhRC = SafeCreateContext(mhDC))) { - close(); OSMessageBox(mCallbacks->translateString("MBGLContextErr"), mCallbacks->translateString("MBError"), OSMB_OK); + close(); return FALSE; } if (!wglMakeCurrent(mhDC, mhRC)) { - close(); OSMessageBox(mCallbacks->translateString("MBGLContextActErr"), mCallbacks->translateString("MBError"), OSMB_OK); + close(); return FALSE; } @@ -1682,38 +1612,35 @@ const S32 max_format = (S32)num_formats - 1; ++cur_format; } - + pixel_format = pixel_formats[cur_format]; - - if (mWindowHandle != nullptr) + + if (mWindowHandle) { - if (mhDC != nullptr) // Does The Window Have A Device Context? + if (mhDC) // Does the window have a device context ? { - if (mhRC != nullptr) // Does The Window Have A Rendering Context? + if (mhRC) { oldRC = mhRC; - mhRC = nullptr; // Zero The Rendering Context + mhRC = NULL; // Zero the rendering context } oldDC = mhDC; - mhDC = nullptr; // Zero The Device Context } - oldWND = mWindowHandle; } - mWindowHandle = CreateWindowEx(dw_ex_style, - mWindowClassName, - mWindowTitle, - WS_CLIPSIBLINGS | WS_CLIPCHILDREN | dw_style, - window_rect.left, // x pos - window_rect.top, // y pos - window_rect.right - window_rect.left, // width - window_rect.bottom - window_rect.top, // height - NULL, - NULL, - mhInstance, - NULL); - + // will release and recreate mhDC, mWindowHandle + recreateWindow(window_rect, dw_ex_style, dw_style, true); + + RECT rect; + RECT client_rect; + //initialize immediately on main thread + if (GetWindowRect(mWindowHandle, &rect) && + GetClientRect(mWindowHandle, &client_rect)) + { + mRect = rect; + mClientRect = client_rect; + }; if (mWindowHandle) { @@ -1725,18 +1652,18 @@ const S32 max_format = (S32)num_formats - 1; LL_WARNS("Window") << "Window recreation failed, code: " << GetLastError() << LL_ENDL; } - if (!(mhDC = GetDC(mWindowHandle))) + if (!mhDC) { - close(); OSMessageBox(mCallbacks->translateString("MBDevContextErr"), mCallbacks->translateString("MBError"), OSMB_OK); + close(); return FALSE; } if (!SetPixelFormat(mhDC, pixel_format, &pfd)) { - close(); OSMessageBox(mCallbacks->translateString("MBPixelFmtSetErr"), mCallbacks->translateString("MBError"), OSMB_OK); + close(); return FALSE; } @@ -1772,8 +1699,8 @@ const S32 max_format = (S32)num_formats - 1; if (!DescribePixelFormat(mhDC, pixel_format, sizeof(PIXELFORMATDESCRIPTOR), &pfd)) { - close(); OSMessageBox(mCallbacks->translateString("MBPixelFmtDescErr"), mCallbacks->translateString("MBError"), OSMB_OK); + close(); return FALSE; } @@ -1785,120 +1712,91 @@ const S32 max_format = (S32)num_formats - 1; // make sure we have 32 bits per pixel if (pfd.cColorBits < 32 || GetDeviceCaps(mhDC, BITSPIXEL) < 32) { - close(); OSMessageBox(mCallbacks->translateString("MBTrueColorWindow"), mCallbacks->translateString("MBError"), OSMB_OK); + close(); return FALSE; } if (pfd.cAlphaBits < 8) { - close(); OSMessageBox(mCallbacks->translateString("MBAlpha"), mCallbacks->translateString("MBError"), OSMB_OK); + close(); return FALSE; } mhRC = 0; if (epoxy_has_wgl_extension(mhDC, "WGL_ARB_create_context")) { //attempt to create a specific versioned context - S32 attribs[] = - { //start at 4.2 - WGL_CONTEXT_MAJOR_VERSION_ARB, 4, - WGL_CONTEXT_MINOR_VERSION_ARB, 6, - WGL_CONTEXT_PROFILE_MASK_ARB, LLRender::sGLCoreProfile ? WGL_CONTEXT_CORE_PROFILE_BIT_ARB : WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, - WGL_CONTEXT_FLAGS_ARB, gDebugGL ? WGL_CONTEXT_DEBUG_BIT_ARB : 0, - 0 - }; - - bool done = false; - while (!done) - { - mhRC = wglCreateContextAttribsARB(mhDC, mhRC, attribs); - - if (!mhRC) - { - if (attribs[3] > 0) - { //decrement minor version - attribs[3]--; - } - else if (attribs[1] > 3) - { //decrement major version and start minor version over at 3 - attribs[1]--; - attribs[3] = 3; - } - else - { //we reached 3.0 and still failed, bail out - done = true; - } - } - else - { - LL_INFOS() << "Created OpenGL " << llformat("%d.%d", attribs[1], attribs[3]) << - (LLRender::sGLCoreProfile ? " core" : " compatibility") << " context." << LL_ENDL; - done = true; - - // force sNoFixedFunction iff we're trying to use nsight debugging which does not support many legacy API uses - - // nSight doesn't support use of legacy API funcs in the fixed function pipe - if (LLRender::sGLCoreProfile || LLRender::sNsightDebugSupport) - { - LLGLSLShader::sNoFixedFunction = true; - } - } - } - } - - if (!mhRC && !(mhRC = wglCreateContext(mhDC))) - { - close(); - OSMessageBox(mCallbacks->translateString("MBGLContextErr"), mCallbacks->translateString("MBError"), OSMB_OK); - return FALSE; + mhRC = (HGLRC) createSharedContext(); + if (!mhRC) + { + return FALSE; + } } if (!wglMakeCurrent(mhDC, mhRC)) { - close(); OSMessageBox(mCallbacks->translateString("MBGLContextActErr"), mCallbacks->translateString("MBError"), OSMB_OK); + close(); return FALSE; } - if (oldWND != nullptr) + if (oldRC) { - if (oldDC != nullptr) // Does The Window Have A Device Context? + wglDeleteContext(oldRC); // Release The Old Rendering Context + + std::promise<bool> promise; + // What follows must be done on the window thread. + auto window_work = + [this, + self = mWindowThread, + oldWND, + oldDC, + &promise] + () { - if (oldRC != nullptr) // Does The Window Have A Rendering Context? + if (oldWND) { - wglDeleteContext(oldRC); // Release The Rendering Context - oldRC = nullptr; // Zero The Rendering Context + if (oldDC && !ReleaseDC(oldWND, oldDC)) + { + LL_WARNS("Window") << "Failed to ReleaseDC" << LL_ENDL; + } + // important to call DestroyWindow() from the window thread + if (!destroy_window_handler(oldWND)) + { + + LL_WARNS("Window") << "Failed to properly close window before recreating it!" + << LL_ENDL; + } } - ReleaseDC(oldWND, oldDC); // Release The Device Context - oldDC = nullptr; // Zero The Device Context - } - destroy_window_handler(oldWND); // Destroy The Window - oldWND = nullptr; + + // It's important to wake up the future either way. + promise.set_value(true); + LL_DEBUGS("Window") << "recreateWindow(): window_work done" << LL_ENDL; + }; + + LL_DEBUGS("Window") << "posting window_work to message queue" << LL_ENDL; + mWindowThread->Post(mWindowHandle, window_work); + + auto future = promise.get_future(); + // This blocks until mWindowThread processes CreateWindowEx() and calls + // promise.set_value(). + auto destroyed = future.get(); + LL_DEBUGS() << destroyed << LL_ENDL; } + LL_PROFILER_GPU_CONTEXT + if (!gGLManager.initGL()) { - close(); OSMessageBox(mCallbacks->translateString("MBVideoDrvErr"), mCallbacks->translateString("MBError"), OSMB_OK); + close(); return FALSE; } // Disable vertical sync for swap - if (epoxy_has_wgl_extension(mhDC, "WGL_EXT_swap_control")) - { - if (disable_vsync) - { - LL_INFOS("Window") << "Disabling vertical sync" << LL_ENDL; - wglSwapIntervalEXT(0); - } - else - { - LL_INFOS("Window") << "Keeping vertical sync" << LL_ENDL; - wglSwapIntervalEXT(1); - } - } + toggleVSync(enable_vsync); SetWindowLongPtr(mWindowHandle, GWLP_USERDATA, (LONG_PTR)this); @@ -1924,6 +1822,192 @@ const S32 max_format = (S32)num_formats - 1; return TRUE; } +void LLWindowWin32::recreateWindow(RECT window_rect, DWORD dw_ex_style, DWORD dw_style, bool no_destroy) +{ + auto oldWindowHandle = mWindowHandle; + auto oldDCHandle = mhDC; + + // zero out mWindowHandle and mhDC before destroying window so window + // thread falls back to peekmessage + mWindowHandle = 0; + mhDC = 0; + + std::promise<std::pair<HWND, HDC>> promise; + // What follows must be done on the window thread. + auto window_work = + [this, + self=mWindowThread, + oldWindowHandle, + oldDCHandle, + // bind CreateWindowEx() parameters by value instead of + // back-referencing LLWindowWin32 members + windowClassName=mWindowClassName, + windowTitle=mWindowTitle, + hInstance=mhInstance, + window_rect, + dw_ex_style, + dw_style, + no_destroy, + &promise] + () + { + LL_DEBUGS("Window") << "recreateWindow(): window_work entry" << LL_ENDL; + self->mWindowHandle = 0; + self->mhDC = 0; + + if (!no_destroy && oldWindowHandle) + { + if (oldDCHandle && !ReleaseDC(oldWindowHandle, oldDCHandle)) + { + LL_WARNS("Window") << "Failed to ReleaseDC" << LL_ENDL; + } + + // important to call DestroyWindow() from the window thread + if (!destroy_window_handler(oldWindowHandle)) + { + + LL_WARNS("Window") << "Failed to properly close window before recreating it!" + << LL_ENDL; + } + } + + auto handle = CreateWindowEx(dw_ex_style, + windowClassName, + windowTitle, + WS_CLIPSIBLINGS | WS_CLIPCHILDREN | dw_style, + window_rect.left, // x pos + window_rect.top, // y pos + window_rect.right - window_rect.left, // width + window_rect.bottom - window_rect.top, // height + NULL, + NULL, + hInstance, + NULL); + + if (! handle) + { + // Failed to create window: clear the variables. This + // assignment is valid because we're running on mWindowThread. + self->mWindowHandle = NULL; + self->mhDC = 0; + } + else + { + // Update mWindowThread's own mWindowHandle and mhDC. + self->mWindowHandle = handle; + self->mhDC = GetDC(handle); + } + + updateWindowRect(); + + // It's important to wake up the future either way. + promise.set_value(std::make_pair(self->mWindowHandle, self->mhDC)); + LL_DEBUGS("Window") << "recreateWindow(): window_work done" << LL_ENDL; + }; + // But how we pass window_work to the window thread depends on whether we + // already have a window handle. + if (!oldWindowHandle) + { + // Pass window_work using the WorkQueue: without an existing window + // handle, the window thread can't call GetMessage(). + LL_DEBUGS("Window") << "posting window_work to WorkQueue" << LL_ENDL; + mWindowThread->post(window_work); + } + else + { + // Pass window_work using PostMessage(). We can still + // PostMessage(oldHandle) because oldHandle won't be destroyed until + // the window thread has retrieved and executed window_work. + LL_DEBUGS("Window") << "posting window_work to message queue" << LL_ENDL; + mWindowThread->Post(oldWindowHandle, window_work); + } + + auto future = promise.get_future(); + // This blocks until mWindowThread processes CreateWindowEx() and calls + // promise.set_value(). + auto pair = future.get(); + mWindowHandle = pair.first; + mhDC = pair.second; +} + +void* LLWindowWin32::createSharedContext() +{ + S32 attribs[] = + { + WGL_CONTEXT_MAJOR_VERSION_ARB, 4, + WGL_CONTEXT_MINOR_VERSION_ARB, 6, + WGL_CONTEXT_PROFILE_MASK_ARB, LLRender::sGLCoreProfile ? WGL_CONTEXT_CORE_PROFILE_BIT_ARB : WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, + WGL_CONTEXT_FLAGS_ARB, gDebugGL ? WGL_CONTEXT_DEBUG_BIT_ARB : 0, + 0 + }; + + HGLRC rc = 0; + + bool done = false; + while (!done) + { + rc = wglCreateContextAttribsARB(mhDC, mhRC, attribs); + + if (!rc) + { + if (attribs[3] > 0) + { //decrement minor version + attribs[3]--; + } + else if (attribs[1] > 3) + { //decrement major version and start minor version over at 3 + attribs[1]--; + attribs[3] = 3; + } + else + { //we reached 3.0 and still failed, bail out + done = true; + } + } + else + { + LL_INFOS() << "Created OpenGL " << llformat("%d.%d", attribs[1], attribs[3]) << + (LLRender::sGLCoreProfile ? " core" : " compatibility") << " context." << LL_ENDL; + done = true; + } + } + + if (!rc && !(rc = wglCreateContext(mhDC))) + { + close(); + OSMessageBox(mCallbacks->translateString("MBGLContextErr"), mCallbacks->translateString("MBError"), OSMB_OK); + } + + return rc; +} + +void LLWindowWin32::makeContextCurrent(void* contextPtr) +{ + wglMakeCurrent(mhDC, (HGLRC) contextPtr); +} + +void LLWindowWin32::destroySharedContext(void* contextPtr) +{ + wglDeleteContext((HGLRC)contextPtr); +} + +void LLWindowWin32::toggleVSync(bool enable_vsync) +{ + if(epoxy_has_wgl_extension(mhDC, "WGL_EXT_swap_control")) + { + if (!enable_vsync) + { + LL_INFOS("Window") << "Disabling vertical sync" << LL_ENDL; + wglSwapIntervalEXT(0); + } + else + { + LL_INFOS("Window") << "Enabling vertical sync" << LL_ENDL; + wglSwapIntervalEXT(1); + } + } +} + void LLWindowWin32::moveWindow( const LLCoordScreen& position, const LLCoordScreen& size ) { if( mIsMouseClipping ) @@ -1942,66 +2026,106 @@ void LLWindowWin32::moveWindow( const LLCoordScreen& position, const LLCoordScre // THIS CAUSES DEV-15484 and DEV-15949 //ShowWindow(mWindowHandle, SW_RESTORE); // NOW we can call MoveWindow - MoveWindow(mWindowHandle, position.mX, position.mY, size.mX, size.mY, TRUE); + mWindowThread->post([=]() + { + MoveWindow(mWindowHandle, position.mX, position.mY, size.mX, size.mY, TRUE); + }); +} + +void LLWindowWin32::setTitle(const std::string title) +{ + // TODO: Do we need to use the wide string version of this call + // to support non-ascii usernames (and region names?) + mWindowThread->post([=]() + { + SetWindowText(mWindowHandle, ll_convert_string_to_wide(title).c_str()); + }); } BOOL LLWindowWin32::setCursorPosition(const LLCoordWindow position) { - mMousePositionModified = TRUE; - if (!mWindowHandle) - { - return FALSE; - } + ASSERT_MAIN_THREAD(); + if (!mWindowHandle) + { + return FALSE; + } - // Inform the application of the new mouse position (needed for per-frame - // hover/picking to function). - mCallbacks->handleMouseMove(this, position.convert(), (MASK)0); - - // DEV-18951 VWR-8524 Camera moves wildly when alt-clicking. - // Because we have preemptively notified the application of the new - // mouse position via handleMouseMove() above, we need to clear out - // any stale mouse move events. RN/JC - MSG msg; - while (PeekMessage(&msg, NULL, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE)) - { } - - LLCoordScreen screen_pos(position.convert()); - return ::SetCursorPos(screen_pos.mX, screen_pos.mY); + LLCoordScreen screen_pos(position.convert()); + + // instantly set the cursor position from the app's point of view + mCursorPosition = position; + mLastCursorPosition = position; + + // Inform the application of the new mouse position (needed for per-frame + // hover/picking to function). + mCallbacks->handleMouseMove(this, position.convert(), (MASK)0); + + // actually set the cursor position on the window thread + mWindowThread->post([=]() + { + // actually set the OS cursor position + SetCursorPos(screen_pos.mX, screen_pos.mY); + }); + + return TRUE; } BOOL LLWindowWin32::getCursorPosition(LLCoordWindow *position) { - POINT cursor_point; - - if (!mWindowHandle - || !GetCursorPos(&cursor_point) - || !position) - { - return FALSE; - } + ASSERT_MAIN_THREAD(); + if (!position) + { + return FALSE; + } - *position = LLCoordScreen(cursor_point.x, cursor_point.y).convert(); + *position = mCursorPosition; return TRUE; } +BOOL LLWindowWin32::getCursorDelta(LLCoordCommon* delta) +{ + if (delta == nullptr) + { + return FALSE; + } + + *delta = mMouseFrameDelta; + + return TRUE; +} + void LLWindowWin32::hideCursor() { - while (ShowCursor(FALSE) >= 0) - { - // nothing, wait for cursor to push down - } + ASSERT_MAIN_THREAD(); + + mWindowThread->post([=]() + { + while (ShowCursor(FALSE) >= 0) + { + // nothing, wait for cursor to push down + } + }); + mCursorHidden = TRUE; mHideCursorPermanent = TRUE; } void LLWindowWin32::showCursor() { - // makes sure the cursor shows up - while (ShowCursor(TRUE) < 0) - { - // do nothing, wait for cursor to pop out - } + LL_PROFILE_ZONE_SCOPED_CATEGORY_WIN32; + + ASSERT_MAIN_THREAD(); + + mWindowThread->post([=]() + { + // makes sure the cursor shows up + while (ShowCursor(TRUE) < 0) + { + // do nothing, wait for cursor to pop out + } + }); + mCursorHidden = FALSE; mHideCursorPermanent = FALSE; } @@ -2105,6 +2229,8 @@ void LLWindowWin32::initCursors() void LLWindowWin32::updateCursor() { + ASSERT_MAIN_THREAD(); + LL_PROFILE_ZONE_SCOPED_CATEGORY_WIN32 if (mNextCursor == UI_CURSOR_ARROW && mBusyCount > 0) { @@ -2114,7 +2240,11 @@ void LLWindowWin32::updateCursor() if( mCurrentCursor != mNextCursor ) { mCurrentCursor = mNextCursor; - SetCursor( mCursor[mNextCursor] ); + auto nextCursor = mCursor[mNextCursor]; + mWindowThread->post([=]() + { + SetCursor(nextCursor); + }); } } @@ -2130,13 +2260,8 @@ void LLWindowWin32::captureMouse() void LLWindowWin32::releaseMouse() { - // *NOTE:Mani ReleaseCapture will spawn new windows messages... - // which will in turn call our MainWindowProc. It therefore requires - // pausing *and more importantly resumption* of the mainlooptimeout... - // just like DispatchMessage below. - mCallbacks->handlePauseWatchdog(this); + LL_PROFILE_ZONE_SCOPED_CATEGORY_WIN32; ReleaseCapture(); - mCallbacks->handleResumeWatchdog(this); } @@ -2145,998 +2270,1015 @@ void LLWindowWin32::delayInputProcessing() mInputProcessingPaused = TRUE; } + void LLWindowWin32::gatherInput() { - MSG msg; - int msg_count = 0; + ASSERT_MAIN_THREAD(); + LL_PROFILE_ZONE_SCOPED_CATEGORY_WIN32 + MSG msg; - while ((msg_count < MAX_MESSAGE_PER_UPDATE) && PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) - { - mCallbacks->handlePingWatchdog(this, "Main:TranslateGatherInput"); - TranslateMessage(&msg); + { + LLMutexLock lock(&mRawMouseMutex); + mMouseFrameDelta = mRawMouseDelta; - // turn watchdog off in here to not fail if windows is doing something wacky - mCallbacks->handlePauseWatchdog(this); - DispatchMessage(&msg); - mCallbacks->handleResumeWatchdog(this); - msg_count++; + mRawMouseDelta.mX = 0; + mRawMouseDelta.mY = 0; + } - if ( mInputProcessingPaused ) - { - break; - } - /* Attempted workaround for problem where typing fast and hitting - return would result in only part of the text being sent. JC - BOOL key_posted = TranslateMessage(&msg); - DispatchMessage(&msg); - msg_count++; + if (mWindowThread->getQueue().size()) + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("gi - PostMessage"); + kickWindowThread(); + } + + while (mWindowThread->mMessageQueue.tryPopBack(msg)) + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("gi - message queue"); + if (mInputProcessingPaused) + { + continue; + } + } + + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("gi - PeekMessage"); + S32 msg_count = 0; + while ((msg_count < MAX_MESSAGE_PER_UPDATE) && PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_REMOVE)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + msg_count++; + } + } - // If a key was translated, a WM_CHAR might have been posted to the end - // of the event queue. We need it immediately. - if (key_posted && msg.message == WM_KEYDOWN) - { - if (PeekMessage(&msg, NULL, WM_CHAR, WM_CHAR, PM_REMOVE)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - msg_count++; - } - } - */ - mCallbacks->handlePingWatchdog(this, "Main:AsyncCallbackGatherInput"); - } + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("gi - function queue"); + //process any pending functions + std::function<void()> curFunc; + while (mFunctionQueue.tryPopBack(curFunc)) + { + curFunc(); + } + } + + // send one and only one mouse move event per frame BEFORE handling mouse button presses + if (mLastCursorPosition != mCursorPosition) + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("gi - mouse move"); + mCallbacks->handleMouseMove(this, mCursorPosition.convert(), mMouseMask); + } + + mLastCursorPosition = mCursorPosition; + + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("gi - mouse queue"); + // handle mouse button presses AFTER updating mouse cursor position + std::function<void()> curFunc; + while (mMouseQueue.tryPopBack(curFunc)) + { + curFunc(); + } + } mInputProcessingPaused = FALSE; updateCursor(); - - // clear this once we've processed all mouse messages that might have occurred after - // we slammed the mouse position - mMousePositionModified = FALSE; } static LLTrace::BlockTimerStatHandle FTM_KEYHANDLER("Handle Keyboard"); static LLTrace::BlockTimerStatHandle FTM_MOUSEHANDLER("Handle Mouse"); +#define WINDOW_IMP_POST(x) window_imp->post([=]() { x; }) + LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_param, LPARAM l_param) { - // Ignore clicks not originated in the client area, i.e. mouse-up events not preceded with a WM_LBUTTONDOWN. - // This helps prevent avatar walking after maximizing the window by double-clicking the title bar. - static bool sHandleLeftMouseUp = true; - - // Ignore the double click received right after activating app. - // This is to avoid triggering double click teleport after returning focus (see MAINT-3786). - static bool sHandleDoubleClick = true; - - LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLongPtr( h_wnd, GWLP_USERDATA ); - - bool debug_window_proc = gDebugWindowProc; + ASSERT_WINDOW_THREAD(); + LL_PROFILE_ZONE_SCOPED_CATEGORY_WIN32; + LL_DEBUGS("Window") << "mainWindowProc(" << std::hex << h_wnd + << ", " << u_msg + << ", " << w_param << ")" << std::dec << LL_ENDL; - if (NULL != window_imp) - { - window_imp->mCallbacks->handleResumeWatchdog(window_imp); - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:StartWndProc"); - // Has user provided their own window callback? - if (NULL != window_imp->mWndProc) - { - if (!window_imp->mWndProc(h_wnd, u_msg, w_param, l_param)) - { - // user has handled window message - return 0; - } - } - - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:PreSwitchWndProc"); - - // Juggle to make sure we can get negative positions for when - // mouse is outside window. - LLCoordWindow window_coord((S32)(S16)LOWORD(l_param), (S32)(S16)HIWORD(l_param)); - - // This doesn't work, as LOWORD returns unsigned short. - //LLCoordWindow window_coord(LOWORD(l_param), HIWORD(l_param)); - LLCoordGL gl_coord; - - // pass along extended flag in mask - MASK mask = (l_param>>16 & KF_EXTENDED) ? MASK_EXTENDED : 0x0; - BOOL eat_keystroke = TRUE; - - switch(u_msg) - { - RECT update_rect; - S32 update_width; - S32 update_height; - - case WM_TIMER: - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_TIMER"); - window_imp->mCallbacks->handleTimerEvent(window_imp); - break; - - case WM_DEVICECHANGE: - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_DEVICECHANGE"); - if (debug_window_proc) - { - LL_INFOS("Window") << " WM_DEVICECHANGE: wParam=" << w_param - << "; lParam=" << l_param << LL_ENDL; - } - if (w_param == DBT_DEVNODES_CHANGED || w_param == DBT_DEVICEARRIVAL) - { - if (window_imp->mCallbacks->handleDeviceChange(window_imp)) - { - return 0; - } - } - break; - - case WM_PAINT: - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_PAINT"); - GetUpdateRect(window_imp->mWindowHandle, &update_rect, FALSE); - update_width = update_rect.right - update_rect.left + 1; - update_height = update_rect.bottom - update_rect.top + 1; - window_imp->mCallbacks->handlePaint(window_imp, update_rect.left, update_rect.top, - update_width, update_height); - break; - case WM_PARENTNOTIFY: - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_PARENTNOTIFY"); - u_msg = u_msg; - break; - - case WM_SETCURSOR: - // This message is sent whenever the cursor is moved in a window. - // You need to set the appropriate cursor appearance. - - // Only take control of cursor over client region of window - // This allows Windows(tm) to handle resize cursors, etc. - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_SETCURSOR"); - if (LOWORD(l_param) == HTCLIENT) - { - SetCursor(window_imp->mCursor[ window_imp->mCurrentCursor] ); - return 0; - } - break; - - case WM_ENTERMENULOOP: - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_ENTERMENULOOP"); - window_imp->mCallbacks->handleWindowBlock(window_imp); - break; - - case WM_EXITMENULOOP: - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_EXITMENULOOP"); - window_imp->mCallbacks->handleWindowUnblock(window_imp); - break; - - case WM_ACTIVATEAPP: - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_ACTIVATEAPP"); - { - // This message should be sent whenever the app gains or loses focus. - BOOL activating = (BOOL) w_param; - BOOL minimized = window_imp->getMinimized(); - - if (debug_window_proc) - { - LL_INFOS("Window") << "WINDOWPROC ActivateApp " - << " activating " << S32(activating) - << " minimized " << S32(minimized) - << " fullscreen " << S32(window_imp->mFullscreen) - << LL_ENDL; - } - - if (window_imp->mFullscreen) - { - // When we run fullscreen, restoring or minimizing the app needs - // to switch the screen resolution - if (activating) - { - window_imp->setFullscreenResolution(); - window_imp->restore(); - } - else - { - window_imp->minimize(); - window_imp->resetDisplayResolution(); - } - } - - if (!activating) - { - sHandleDoubleClick = false; - } - - window_imp->mCallbacks->handleActivateApp(window_imp, activating); - - break; - } - - case WM_ACTIVATE: - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_ACTIVATE"); - { - // Can be one of WA_ACTIVE, WA_CLICKACTIVE, or WA_INACTIVE - BOOL activating = (LOWORD(w_param) != WA_INACTIVE); - - BOOL minimized = BOOL(HIWORD(w_param)); - - if (!activating && LLWinImm::isAvailable() && window_imp->mPreeditor) - { - window_imp->interruptLanguageTextInput(); - } - - // JC - I'm not sure why, but if we don't report that we handled the - // WM_ACTIVATE message, the WM_ACTIVATEAPP messages don't work - // properly when we run fullscreen. - if (debug_window_proc) - { - LL_INFOS("Window") << "WINDOWPROC Activate " - << " activating " << S32(activating) - << " minimized " << S32(minimized) - << LL_ENDL; - } - - // Don't handle this. - break; - } - - case WM_QUERYOPEN: - // TODO: use this to return a nice icon - break; - - case WM_SYSCOMMAND: - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_SYSCOMMAND"); - switch(w_param) - { - case SC_KEYMENU: - // Disallow the ALT key from triggering the default system menu. - return 0; - - case SC_SCREENSAVE: - case SC_MONITORPOWER: - // eat screen save messages and prevent them! - return 0; - } - break; - - case WM_CLOSE: - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_CLOSE"); - // Will the app allow the window to close? - if (window_imp->mCallbacks->handleCloseRequest(window_imp)) - { - // Get the app to initiate cleanup. - window_imp->mCallbacks->handleQuit(window_imp); - // The app is responsible for calling destroyWindow when done with GL - } - return 0; - - case WM_DESTROY: - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_DESTROY"); - if (window_imp->shouldPostQuit()) - { - PostQuitMessage(0); // Posts WM_QUIT with an exit code of 0 - } - return 0; - - case WM_COMMAND: - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_COMMAND"); - if (!HIWORD(w_param)) // this message is from a menu - { - window_imp->mCallbacks->handleMenuSelect(window_imp, LOWORD(w_param)); - } - break; - - case WM_SYSKEYDOWN: - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_SYSKEYDOWN"); - // allow system keys, such as ALT-F4 to be processed by Windows - eat_keystroke = FALSE; - case WM_KEYDOWN: - window_imp->mKeyCharCode = 0; // don't know until wm_char comes in next - window_imp->mKeyScanCode = ( l_param >> 16 ) & 0xff; - window_imp->mKeyVirtualKey = w_param; - window_imp->mRawMsg = u_msg; - window_imp->mRawWParam = w_param; - window_imp->mRawLParam = l_param; - - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_KEYDOWN"); - { - if (debug_window_proc) - { - LL_INFOS("Window") << "Debug WindowProc WM_KEYDOWN " - << " key " << S32(w_param) - << LL_ENDL; - } - if(gKeyboard->handleKeyDown(w_param, mask) && eat_keystroke) - { - return 0; - } - // pass on to windows if we didn't handle it - break; - } - case WM_SYSKEYUP: - eat_keystroke = FALSE; - case WM_KEYUP: - { - window_imp->mKeyScanCode = ( l_param >> 16 ) & 0xff; - window_imp->mKeyVirtualKey = w_param; - window_imp->mRawMsg = u_msg; - window_imp->mRawWParam = w_param; - window_imp->mRawLParam = l_param; - - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_KEYUP"); - LL_RECORD_BLOCK_TIME(FTM_KEYHANDLER); - - if (debug_window_proc) - { - LL_INFOS("Window") << "Debug WindowProc WM_KEYUP " - << " key " << S32(w_param) - << LL_ENDL; - } - if (gKeyboard->handleKeyUp(w_param, mask) && eat_keystroke) - { - return 0; - } + if (u_msg == WM_POST_FUNCTION_) + { + LL_DEBUGS("Window") << "WM_POST_FUNCTION_" << LL_ENDL; + // from LLWindowWin32Thread::Post() + // Cast l_param back to the pointer to the heap FuncType + // allocated by Post(). Capture in unique_ptr so we'll delete + // once we're done with it. + std::unique_ptr<LLWindowWin32Thread::FuncType> + ptr(reinterpret_cast<LLWindowWin32Thread::FuncType*>(l_param)); + (*ptr)(); + return 0; + } - // pass on to windows - break; - } - case WM_IME_SETCONTEXT: - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_IME_SETCONTEXT"); - if (debug_window_proc) - { - LL_INFOS("Window") << "WM_IME_SETCONTEXT" << LL_ENDL; - } - if (LLWinImm::isAvailable() && window_imp->mPreeditor) - { - l_param &= ~ISC_SHOWUICOMPOSITIONWINDOW; - // Invoke DefWinProc with the modified LPARAM. - } - break; + // Ignore clicks not originated in the client area, i.e. mouse-up events not preceded with a WM_LBUTTONDOWN. + // This helps prevent avatar walking after maximizing the window by double-clicking the title bar. + static bool sHandleLeftMouseUp = true; - case WM_IME_STARTCOMPOSITION: - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_IME_STARTCOMPOSITION"); - if (debug_window_proc) - { - LL_INFOS() << "WM_IME_STARTCOMPOSITION" << LL_ENDL; - } - if (LLWinImm::isAvailable() && window_imp->mPreeditor) - { - window_imp->handleStartCompositionMessage(); - return 0; - } - break; + // Ignore the double click received right after activating app. + // This is to avoid triggering double click teleport after returning focus (see MAINT-3786). + static bool sHandleDoubleClick = true; - case WM_IME_ENDCOMPOSITION: - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_IME_ENDCOMPOSITION"); - if (debug_window_proc) - { - LL_INFOS() << "WM_IME_ENDCOMPOSITION" << LL_ENDL; - } - if (LLWinImm::isAvailable() && window_imp->mPreeditor) - { - return 0; - } - break; + LLWindowWin32* window_imp = (LLWindowWin32*)GetWindowLongPtr(h_wnd, GWLP_USERDATA); - case WM_IME_COMPOSITION: - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_IME_COMPOSITION"); - if (debug_window_proc) - { - LL_INFOS() << "WM_IME_COMPOSITION" << LL_ENDL; - } - if (LLWinImm::isAvailable() && window_imp->mPreeditor) - { - window_imp->handleCompositionMessage(l_param); - return 0; - } - break; + bool debug_window_proc = false; // gDebugWindowProc || debugLoggingEnabled("Window"); - case WM_IME_REQUEST: - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_IME_REQUEST"); - if (debug_window_proc) - { - LL_INFOS() << "WM_IME_REQUEST" << LL_ENDL; - } - if (LLWinImm::isAvailable() && window_imp->mPreeditor) - { - LRESULT result = 0; - if (window_imp->handleImeRequests(w_param, l_param, &result)) - { - return result; - } - } - break; + if (NULL != window_imp) + { + // Juggle to make sure we can get negative positions for when + // mouse is outside window. + LLCoordWindow window_coord((S32)(S16)LOWORD(l_param), (S32)(S16)HIWORD(l_param)); - case WM_CHAR: - window_imp->mKeyCharCode = w_param; - window_imp->mRawMsg = u_msg; - window_imp->mRawWParam = w_param; - window_imp->mRawLParam = l_param; - - // Should really use WM_UNICHAR eventually, but it requires a specific Windows version and I need - // to figure out how that works. - Doug - // - // ... Well, I don't think so. - // How it works is explained in Win32 API document, but WM_UNICHAR didn't work - // as specified at least on Windows XP SP1 Japanese version. I have never used - // it since then, and I'm not sure whether it has been fixed now, but I don't think - // it is worth trying. The good old WM_CHAR works just fine even for supplementary - // characters. We just need to take care of surrogate pairs sent as two WM_CHAR's - // by ourselves. It is not that tough. -- Alissa Sabre @ SL - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_CHAR"); - if (debug_window_proc) - { - LL_INFOS("Window") << "Debug WindowProc WM_CHAR " - << " key " << S32(w_param) - << LL_ENDL; - } - // Even if LLWindowCallbacks::handleUnicodeChar(llwchar, BOOL) returned FALSE, - // we *did* processed the event, so I believe we should not pass it to DefWindowProc... - window_imp->handleUnicodeUTF16((U16)w_param, gKeyboard->currentMask(FALSE)); - return 0; + // pass along extended flag in mask + MASK mask = (l_param >> 16 & KF_EXTENDED) ? MASK_EXTENDED : 0x0; + BOOL eat_keystroke = TRUE; - case WM_NCLBUTTONDOWN: - { - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_NCLBUTTONDOWN"); - // A click in a non-client area, e.g. title bar or window border. - sHandleLeftMouseUp = false; - sHandleDoubleClick = true; - } - break; + switch (u_msg) + { + RECT update_rect; + S32 update_width; + S32 update_height; - case WM_LBUTTONDOWN: - { - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_LBUTTONDOWN"); - LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); - sHandleLeftMouseUp = true; + case WM_TIMER: + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_TIMER"); + WINDOW_IMP_POST(window_imp->mCallbacks->handleTimerEvent(window_imp)); + break; + } - if (LLWinImm::isAvailable() && window_imp->mPreeditor) - { - window_imp->interruptLanguageTextInput(); - } + case WM_DEVICECHANGE: + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_DEVICECHANGE"); + if (debug_window_proc) + { + LL_INFOS("Window") << " WM_DEVICECHANGE: wParam=" << w_param + << "; lParam=" << l_param << LL_ENDL; + } + if (w_param == DBT_DEVNODES_CHANGED || w_param == DBT_DEVICEARRIVAL) + { + WINDOW_IMP_POST(window_imp->mCallbacks->handleDeviceChange(window_imp)); + + return TRUE; + } + break; + } - // Because we move the cursor position in the app, we need to query - // to find out where the cursor at the time the event is handled. - // If we don't do this, many clicks could get buffered up, and if the - // first click changes the cursor position, all subsequent clicks - // will occur at the wrong location. JC - if (window_imp->mMousePositionModified) - { - LLCoordWindow cursor_coord_window; - window_imp->getCursorPosition(&cursor_coord_window); - gl_coord = cursor_coord_window.convert(); - } - else - { - gl_coord = window_coord.convert(); - } - MASK mask = gKeyboard->currentMask(TRUE); - // generate move event to update mouse coordinates - window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask); - if (window_imp->mCallbacks->handleMouseDown(window_imp, gl_coord, mask)) - { - return 0; - } - } - break; + case WM_PAINT: + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_PAINT"); + GetUpdateRect(window_imp->mWindowHandle, &update_rect, FALSE); + update_width = update_rect.right - update_rect.left + 1; + update_height = update_rect.bottom - update_rect.top + 1; + + WINDOW_IMP_POST(window_imp->mCallbacks->handlePaint(window_imp, update_rect.left, update_rect.top, + update_width, update_height)); + break; + } + case WM_PARENTNOTIFY: + { + break; + } - case WM_LBUTTONDBLCLK: - //RN: ignore right button double clicks for now - //case WM_RBUTTONDBLCLK: - { - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_LBUTTONDBLCLK"); + case WM_SETCURSOR: + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_SETCURSOR"); + // This message is sent whenever the cursor is moved in a window. + // You need to set the appropriate cursor appearance. - if (!sHandleDoubleClick) - { - sHandleDoubleClick = true; - break; - } + // Only take control of cursor over client region of window + // This allows Windows(tm) to handle resize cursors, etc. + if (LOWORD(l_param) == HTCLIENT) + { + SetCursor(window_imp->mCursor[window_imp->mCurrentCursor]); + return 0; + } + break; + } + case WM_ENTERMENULOOP: + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_ENTERMENULOOP"); + WINDOW_IMP_POST(window_imp->mCallbacks->handleWindowBlock(window_imp)); + break; + } - // Because we move the cursor position in the app, we need to query - // to find out where the cursor at the time the event is handled. - // If we don't do this, many clicks could get buffered up, and if the - // first click changes the cursor position, all subsequent clicks - // will occur at the wrong location. JC - if (window_imp->mMousePositionModified) - { - LLCoordWindow cursor_coord_window; - window_imp->getCursorPosition(&cursor_coord_window); - gl_coord = cursor_coord_window.convert(); - } - else - { - gl_coord = window_coord.convert(); - } - MASK mask = gKeyboard->currentMask(TRUE); - // generate move event to update mouse coordinates - window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask); - if (window_imp->mCallbacks->handleDoubleClick(window_imp, gl_coord, mask) ) - { - return 0; - } - } - break; + case WM_EXITMENULOOP: + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_EXITMENULOOP"); + WINDOW_IMP_POST(window_imp->mCallbacks->handleWindowUnblock(window_imp)); + break; + } - case WM_LBUTTONUP: - { - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_LBUTTONUP"); - LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); + case WM_ACTIVATEAPP: + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_ACTIVATEAPP"); + window_imp->post([=]() + { + // This message should be sent whenever the app gains or loses focus. + BOOL activating = (BOOL)w_param; + BOOL minimized = window_imp->getMinimized(); + + if (debug_window_proc) + { + LL_INFOS("Window") << "WINDOWPROC ActivateApp " + << " activating " << S32(activating) + << " minimized " << S32(minimized) + << " fullscreen " << S32(window_imp->mFullscreen) + << LL_ENDL; + } + + if (window_imp->mFullscreen) + { + // When we run fullscreen, restoring or minimizing the app needs + // to switch the screen resolution + if (activating) + { + window_imp->setFullscreenResolution(); + window_imp->restore(); + } + else + { + window_imp->minimize(); + window_imp->resetDisplayResolution(); + } + } + + if (!activating) + { + sHandleDoubleClick = false; + } + + window_imp->mCallbacks->handleActivateApp(window_imp, activating); + }); + break; + } + case WM_ACTIVATE: + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_ACTIVATE"); + window_imp->post([=]() + { + // Can be one of WA_ACTIVE, WA_CLICKACTIVE, or WA_INACTIVE + BOOL activating = (LOWORD(w_param) != WA_INACTIVE); + + BOOL minimized = BOOL(HIWORD(w_param)); + + if (!activating && LLWinImm::isAvailable() && window_imp->mPreeditor) + { + window_imp->interruptLanguageTextInput(); + } + + // JC - I'm not sure why, but if we don't report that we handled the + // WM_ACTIVATE message, the WM_ACTIVATEAPP messages don't work + // properly when we run fullscreen. + if (debug_window_proc) + { + LL_INFOS("Window") << "WINDOWPROC Activate " + << " activating " << S32(activating) + << " minimized " << S32(minimized) + << LL_ENDL; + } + }); + + break; + } - if (!sHandleLeftMouseUp) - { - sHandleLeftMouseUp = true; - break; - } - sHandleDoubleClick = true; - - //if (gDebugClicks) - //{ - // LL_INFOS("Window") << "WndProc left button up" << LL_ENDL; - //} - // Because we move the cursor position in the app, we need to query - // to find out where the cursor at the time the event is handled. - // If we don't do this, many clicks could get buffered up, and if the - // first click changes the cursor position, all subsequent clicks - // will occur at the wrong location. JC - if (window_imp->mMousePositionModified) - { - LLCoordWindow cursor_coord_window; - window_imp->getCursorPosition(&cursor_coord_window); - gl_coord = cursor_coord_window.convert(); - } - else - { - gl_coord = window_coord.convert(); - } - MASK mask = gKeyboard->currentMask(TRUE); - // generate move event to update mouse coordinates - window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask); - if (window_imp->mCallbacks->handleMouseUp(window_imp, gl_coord, mask)) - { - return 0; - } - } - break; + case WM_QUERYOPEN: + // TODO: use this to return a nice icon + break; - case WM_RBUTTONDBLCLK: - case WM_RBUTTONDOWN: - { - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_RBUTTONDOWN"); - LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); - if (LLWinImm::isAvailable() && window_imp->mPreeditor) - { - window_imp->interruptLanguageTextInput(); - } + case WM_SYSCOMMAND: + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_SYSCOMMAND"); + switch (w_param) + { + case SC_KEYMENU: + // Disallow the ALT key from triggering the default system menu. + return 0; + + case SC_SCREENSAVE: + case SC_MONITORPOWER: + // eat screen save messages and prevent them! + return 0; + } + break; + } + case WM_CLOSE: + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_CLOSE"); + window_imp->post([=]() + { + // Will the app allow the window to close? + if (window_imp->mCallbacks->handleCloseRequest(window_imp)) + { + // Get the app to initiate cleanup. + window_imp->mCallbacks->handleQuit(window_imp); + // The app is responsible for calling destroyWindow when done with GL + } + }); + return 0; + } + case WM_DESTROY: + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_DESTROY"); + if (window_imp->shouldPostQuit()) + { + PostQuitMessage(0); // Posts WM_QUIT with an exit code of 0 + } + return 0; + } + case WM_COMMAND: + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_COMMAND"); + if (!HIWORD(w_param)) // this message is from a menu + { + WINDOW_IMP_POST(window_imp->mCallbacks->handleMenuSelect(window_imp, LOWORD(w_param))); + } + break; + } + case WM_SYSKEYDOWN: + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_SYSKEYDOWN"); + // allow system keys, such as ALT-F4 to be processed by Windows + eat_keystroke = FALSE; + // intentional fall-through here + } + case WM_KEYDOWN: + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_KEYDOWN"); + window_imp->post([=]() + { + window_imp->mKeyCharCode = 0; // don't know until wm_char comes in next + window_imp->mKeyScanCode = (l_param >> 16) & 0xff; + window_imp->mKeyVirtualKey = w_param; + window_imp->mRawMsg = u_msg; + window_imp->mRawWParam = w_param; + window_imp->mRawLParam = l_param; + + { + if (debug_window_proc) + { + LL_INFOS("Window") << "Debug WindowProc WM_KEYDOWN " + << " key " << S32(w_param) + << LL_ENDL; + } + + gKeyboard->handleKeyDown(w_param, mask); + } + }); + if (eat_keystroke) return 0; // skip DefWindowProc() handling if we're consuming the keypress + break; + } + case WM_SYSKEYUP: + eat_keystroke = FALSE; + // intentional fall-through here + case WM_KEYUP: + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_KEYUP"); + window_imp->post([=]() + { + window_imp->mKeyScanCode = (l_param >> 16) & 0xff; + window_imp->mKeyVirtualKey = w_param; + window_imp->mRawMsg = u_msg; + window_imp->mRawWParam = w_param; + window_imp->mRawLParam = l_param; + + { + LL_RECORD_BLOCK_TIME(FTM_KEYHANDLER); + + if (debug_window_proc) + { + LL_INFOS("Window") << "Debug WindowProc WM_KEYUP " + << " key " << S32(w_param) + << LL_ENDL; + } + gKeyboard->handleKeyUp(w_param, mask); + } + }); + if (eat_keystroke) return 0; // skip DefWindowProc() handling if we're consuming the keypress + break; + } + case WM_IME_SETCONTEXT: + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_IME_SETCONTEXT"); + if (debug_window_proc) + { + LL_INFOS("Window") << "WM_IME_SETCONTEXT" << LL_ENDL; + } + if (LLWinImm::isAvailable() && window_imp->mPreeditor) + { + l_param &= ~ISC_SHOWUICOMPOSITIONWINDOW; + // Invoke DefWinProc with the modified LPARAM. + } + break; + } + case WM_IME_STARTCOMPOSITION: + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_IME_STARTCOMPOSITION"); + if (debug_window_proc) + { + LL_INFOS() << "WM_IME_STARTCOMPOSITION" << LL_ENDL; + } + if (LLWinImm::isAvailable() && window_imp->mPreeditor) + { + WINDOW_IMP_POST(window_imp->handleStartCompositionMessage()); + return 0; + } + break; + } + case WM_IME_ENDCOMPOSITION: + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_IME_ENDCOMPOSITION"); + if (debug_window_proc) + { + LL_INFOS() << "WM_IME_ENDCOMPOSITION" << LL_ENDL; + } + if (LLWinImm::isAvailable() && window_imp->mPreeditor) + { + return 0; + } + break; + } + case WM_IME_COMPOSITION: + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_IME_COMPOSITION"); + if (debug_window_proc) + { + LL_INFOS() << "WM_IME_COMPOSITION" << LL_ENDL; + } + if (LLWinImm::isAvailable() && window_imp->mPreeditor) + { + WINDOW_IMP_POST(window_imp->handleCompositionMessage(l_param)); + return 0; + } + break; + } + case WM_IME_REQUEST: + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_IME_REQUEST"); + if (debug_window_proc) + { + LL_INFOS() << "WM_IME_REQUEST" << LL_ENDL; + } + if (LLWinImm::isAvailable() && window_imp->mPreeditor) + { + LRESULT result; + window_imp->handleImeRequests(w_param, l_param, &result); + return result; + } + break; + } + case WM_CHAR: + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_CHAR"); + window_imp->post([=]() + { + window_imp->mKeyCharCode = w_param; + window_imp->mRawMsg = u_msg; + window_imp->mRawWParam = w_param; + window_imp->mRawLParam = l_param; + + // Should really use WM_UNICHAR eventually, but it requires a specific Windows version and I need + // to figure out how that works. - Doug + // + // ... Well, I don't think so. + // How it works is explained in Win32 API document, but WM_UNICHAR didn't work + // as specified at least on Windows XP SP1 Japanese version. I have never used + // it since then, and I'm not sure whether it has been fixed now, but I don't think + // it is worth trying. The good old WM_CHAR works just fine even for supplementary + // characters. We just need to take care of surrogate pairs sent as two WM_CHAR's + // by ourselves. It is not that tough. -- Alissa Sabre @ SL + if (debug_window_proc) + { + LL_INFOS("Window") << "Debug WindowProc WM_CHAR " + << " key " << S32(w_param) + << LL_ENDL; + } + // Even if LLWindowCallbacks::handleUnicodeChar(llwchar, BOOL) returned FALSE, + // we *did* processed the event, so I believe we should not pass it to DefWindowProc... + window_imp->handleUnicodeUTF16((U16)w_param, gKeyboard->currentMask(FALSE)); + }); + return 0; + } + case WM_NCLBUTTONDOWN: + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_NCLBUTTONDOWN"); + { + // A click in a non-client area, e.g. title bar or window border. + window_imp->post([=]() + { + sHandleLeftMouseUp = false; + sHandleDoubleClick = true; + }); + } + break; + } + case WM_LBUTTONDOWN: + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_LBUTTONDOWN"); + { + LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); + window_imp->postMouseButtonEvent([=]() + { + sHandleLeftMouseUp = true; + + if (LLWinImm::isAvailable() && window_imp->mPreeditor) + { + window_imp->interruptLanguageTextInput(); + } + + MASK mask = gKeyboard->currentMask(TRUE); + auto gl_coord = window_imp->mCursorPosition.convert(); + window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask); + window_imp->mCallbacks->handleMouseDown(window_imp, gl_coord, mask); + }); + + return 0; + } + break; + } - // Because we move the cursor position in the llviewerapp, we need to query - // to find out where the cursor at the time the event is handled. - // If we don't do this, many clicks could get buffered up, and if the - // first click changes the cursor position, all subsequent clicks - // will occur at the wrong location. JC - if (window_imp->mMousePositionModified) - { - LLCoordWindow cursor_coord_window; - window_imp->getCursorPosition(&cursor_coord_window); - gl_coord = cursor_coord_window.convert(); - } - else - { - gl_coord = window_coord.convert(); - } - MASK mask = gKeyboard->currentMask(TRUE); - // generate move event to update mouse coordinates - window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask); - if (window_imp->mCallbacks->handleRightMouseDown(window_imp, gl_coord, mask)) - { - return 0; - } - } - break; + case WM_LBUTTONDBLCLK: + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_LBUTTONDBLCLK"); + window_imp->postMouseButtonEvent([=]() + { + //RN: ignore right button double clicks for now + //case WM_RBUTTONDBLCLK: + if (!sHandleDoubleClick) + { + sHandleDoubleClick = true; + return; + } + MASK mask = gKeyboard->currentMask(TRUE); + + // generate move event to update mouse coordinates + window_imp->mCursorPosition = window_coord; + window_imp->mCallbacks->handleDoubleClick(window_imp, window_imp->mCursorPosition.convert(), mask); + }); + + return 0; + } + case WM_LBUTTONUP: + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_LBUTTONUP"); + { + window_imp->postMouseButtonEvent([=]() + { + LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); + if (!sHandleLeftMouseUp) + { + sHandleLeftMouseUp = true; + return; + } + sHandleDoubleClick = true; + + + MASK mask = gKeyboard->currentMask(TRUE); + // generate move event to update mouse coordinates + window_imp->mCursorPosition = window_coord; + window_imp->mCallbacks->handleMouseUp(window_imp, window_imp->mCursorPosition.convert(), mask); + }); + } + return 0; + } + case WM_RBUTTONDBLCLK: + case WM_RBUTTONDOWN: + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_RBUTTONDOWN"); + { + LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); + window_imp->post([=]() + { + if (LLWinImm::isAvailable() && window_imp->mPreeditor) + { + WINDOW_IMP_POST(window_imp->interruptLanguageTextInput()); + } + + MASK mask = gKeyboard->currentMask(TRUE); + // generate move event to update mouse coordinates + auto gl_coord = window_imp->mCursorPosition.convert(); + window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask); + window_imp->mCallbacks->handleRightMouseDown(window_imp, gl_coord, mask); + }); + } + return 0; + } + break; - case WM_RBUTTONUP: - { - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_RBUTTONUP"); - LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); - // Because we move the cursor position in the app, we need to query - // to find out where the cursor at the time the event is handled. - // If we don't do this, many clicks could get buffered up, and if the - // first click changes the cursor position, all subsequent clicks - // will occur at the wrong location. JC - if (window_imp->mMousePositionModified) - { - LLCoordWindow cursor_coord_window; - window_imp->getCursorPosition(&cursor_coord_window); - gl_coord = cursor_coord_window.convert(); - } - else - { - gl_coord = window_coord.convert(); - } - MASK mask = gKeyboard->currentMask(TRUE); - // generate move event to update mouse coordinates - window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask); - if (window_imp->mCallbacks->handleRightMouseUp(window_imp, gl_coord, mask)) - { - return 0; - } - } - break; + case WM_RBUTTONUP: + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_RBUTTONUP"); + { + LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); + window_imp->postMouseButtonEvent([=]() + { + MASK mask = gKeyboard->currentMask(TRUE); + window_imp->mCallbacks->handleRightMouseUp(window_imp, window_imp->mCursorPosition.convert(), mask); + }); + } + } + break; - case WM_MBUTTONDOWN: -// case WM_MBUTTONDBLCLK: - { - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_MBUTTONDOWN"); - LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); - if (LLWinImm::isAvailable() && window_imp->mPreeditor) - { - window_imp->interruptLanguageTextInput(); - } + case WM_MBUTTONDOWN: + // case WM_MBUTTONDBLCLK: + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_MBUTTONDOWN"); + { + LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); + window_imp->postMouseButtonEvent([=]() + { + if (LLWinImm::isAvailable() && window_imp->mPreeditor) + { + window_imp->interruptLanguageTextInput(); + } + + MASK mask = gKeyboard->currentMask(TRUE); + window_imp->mCallbacks->handleMiddleMouseDown(window_imp, window_imp->mCursorPosition.convert(), mask); + }); + } + } + break; - // Because we move the cursor position in tllviewerhe app, we need to query - // to find out where the cursor at the time the event is handled. - // If we don't do this, many clicks could get buffered up, and if the - // first click changes the cursor position, all subsequent clicks - // will occur at the wrong location. JC - if (window_imp->mMousePositionModified) - { - LLCoordWindow cursor_coord_window; - window_imp->getCursorPosition(&cursor_coord_window); - gl_coord = cursor_coord_window.convert(); - } - else - { - gl_coord = window_coord.convert(); - } - MASK mask = gKeyboard->currentMask(TRUE); - // generate move event to update mouse coordinates - window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask); - if (window_imp->mCallbacks->handleMiddleMouseDown(window_imp, gl_coord, mask)) - { - return 0; - } - } - break; + case WM_MBUTTONUP: + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_MBUTTONUP"); + { + LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); + window_imp->postMouseButtonEvent([=]() + { + MASK mask = gKeyboard->currentMask(TRUE); + window_imp->mCallbacks->handleMiddleMouseUp(window_imp, window_imp->mCursorPosition.convert(), mask); + }); + } + } + break; + case WM_XBUTTONDOWN: + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_XBUTTONDOWN"); + window_imp->postMouseButtonEvent([=]() + { + LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); + S32 button = GET_XBUTTON_WPARAM(w_param); + if (LLWinImm::isAvailable() && window_imp->mPreeditor) + { + window_imp->interruptLanguageTextInput(); + } + + MASK mask = gKeyboard->currentMask(TRUE); + // Windows uses numbers 1 and 2 for buttons, remap to 4, 5 + window_imp->mCallbacks->handleOtherMouseDown(window_imp, window_imp->mCursorPosition.convert(), mask, button + 3); + }); + + } + break; - case WM_MBUTTONUP: - { - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_MBUTTONUP"); - LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); - // Because we move the cursor position in the llviewer app, we need to query - // to find out where the cursor at the time the event is handled. - // If we don't do this, many clicks could get buffered up, and if the - // first click changes the cursor position, all subsequent clicks - // will occur at the wrong location. JC - if (window_imp->mMousePositionModified) - { - LLCoordWindow cursor_coord_window; - window_imp->getCursorPosition(&cursor_coord_window); - gl_coord = cursor_coord_window.convert(); - } - else - { - gl_coord = window_coord.convert(); - } - MASK mask = gKeyboard->currentMask(TRUE); - // generate move event to update mouse coordinates - window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask); - if (window_imp->mCallbacks->handleMiddleMouseUp(window_imp, gl_coord, mask)) - { - return 0; - } - } - break; - case WM_XBUTTONDOWN: - { - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_MBUTTONDOWN"); - LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); - S32 button = GET_XBUTTON_WPARAM(w_param); - if (LLWinImm::isAvailable() && window_imp->mPreeditor) - { - window_imp->interruptLanguageTextInput(); - } + case WM_XBUTTONUP: + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_XBUTTONUP"); + window_imp->postMouseButtonEvent([=]() + { - // Because we move the cursor position in tllviewerhe app, we need to query - // to find out where the cursor at the time the event is handled. - // If we don't do this, many clicks could get buffered up, and if the - // first click changes the cursor position, all subsequent clicks - // will occur at the wrong location. JC - if (window_imp->mMousePositionModified) - { - LLCoordWindow cursor_coord_window; - window_imp->getCursorPosition(&cursor_coord_window); - gl_coord = cursor_coord_window.convert(); - } - else - { - gl_coord = window_coord.convert(); - } - MASK mask = gKeyboard->currentMask(TRUE); - // generate move event to update mouse coordinates - window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask); - // Windows uses numbers 1 and 2 for buttons, remap to 4, 5 - if (window_imp->mCallbacks->handleOtherMouseDown(window_imp, gl_coord, mask, button + 3)) - { - return 0; - } - } - break; + LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); - case WM_XBUTTONUP: - { - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_MBUTTONUP"); - LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); - S32 button = GET_XBUTTON_WPARAM(w_param); - // Because we move the cursor position in the llviewer app, we need to query - // to find out where the cursor at the time the event is handled. - // If we don't do this, many clicks could get buffered up, and if the - // first click changes the cursor position, all subsequent clicks - // will occur at the wrong location. JC - if (window_imp->mMousePositionModified) - { - LLCoordWindow cursor_coord_window; - window_imp->getCursorPosition(&cursor_coord_window); - gl_coord = cursor_coord_window.convert(); - } - else - { - gl_coord = window_coord.convert(); - } - MASK mask = gKeyboard->currentMask(TRUE); - // generate move event to update mouse coordinates - window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask); - // Windows uses numbers 1 and 2 for buttons, remap to 4, 5 - if (window_imp->mCallbacks->handleOtherMouseUp(window_imp, gl_coord, mask, button + 3)) - { - return 0; - } - } - break; + S32 button = GET_XBUTTON_WPARAM(w_param); + MASK mask = gKeyboard->currentMask(TRUE); + // Windows uses numbers 1 and 2 for buttons, remap to 4, 5 + window_imp->mCallbacks->handleOtherMouseUp(window_imp, window_imp->mCursorPosition.convert(), mask, button + 3); + }); + } + break; - case WM_MOUSEWHEEL: - { - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_MOUSEWHEEL"); - static short z_delta = 0; + case WM_MOUSEWHEEL: + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_MOUSEWHEEL"); + static short z_delta = 0; - RECT client_rect; + RECT client_rect; - // eat scroll events that occur outside our window, since we use mouse position to direct scroll - // instead of keyboard focus - // NOTE: mouse_coord is in *window* coordinates for scroll events - POINT mouse_coord = {GET_X_LPARAM(l_param), GET_Y_LPARAM(l_param)}; + // eat scroll events that occur outside our window, since we use mouse position to direct scroll + // instead of keyboard focus + // NOTE: mouse_coord is in *window* coordinates for scroll events + POINT mouse_coord = {GET_X_LPARAM(l_param), GET_Y_LPARAM(l_param)}; - if (ScreenToClient(window_imp->mWindowHandle, &mouse_coord) - && GetClientRect(window_imp->mWindowHandle, &client_rect)) - { - // we have a valid mouse point and client rect - if (mouse_coord.x < client_rect.left || client_rect.right < mouse_coord.x - || mouse_coord.y < client_rect.top || client_rect.bottom < mouse_coord.y) - { - // mouse is outside of client rect, so don't do anything - return 0; - } - } + if (ScreenToClient(window_imp->mWindowHandle, &mouse_coord) + && GetClientRect(window_imp->mWindowHandle, &client_rect)) + { + // we have a valid mouse point and client rect + if (mouse_coord.x < client_rect.left || client_rect.right < mouse_coord.x + || mouse_coord.y < client_rect.top || client_rect.bottom < mouse_coord.y) + { + // mouse is outside of client rect, so don't do anything + return 0; + } + } - S16 incoming_z_delta = GET_WHEEL_DELTA_WPARAM(w_param); - z_delta += incoming_z_delta; - // cout << "z_delta " << z_delta << endl; - - // current mouse wheels report changes in increments of zDelta (+120, -120) - // Future, higher resolution mouse wheels may report smaller deltas. - // So we sum the deltas and only act when we've exceeded WHEEL_DELTA - // - // If the user rapidly spins the wheel, we can get messages with - // large deltas, like 480 or so. Thus we need to scroll more quickly. - if (z_delta <= -WHEEL_DELTA || WHEEL_DELTA <= z_delta) - { - window_imp->mCallbacks->handleScrollWheel(window_imp, -z_delta / WHEEL_DELTA); - z_delta = 0; - } - return 0; - } - /* - // TODO: add this after resolving _WIN32_WINNT issue - case WM_MOUSELEAVE: - { - window_imp->mCallbacks->handleMouseLeave(window_imp); - - // TRACKMOUSEEVENT track_mouse_event; - // track_mouse_event.cbSize = sizeof( TRACKMOUSEEVENT ); - // track_mouse_event.dwFlags = TME_LEAVE; - // track_mouse_event.hwndTrack = h_wnd; - // track_mouse_event.dwHoverTime = HOVER_DEFAULT; - // TrackMouseEvent( &track_mouse_event ); - return 0; - } - */ - case WM_MOUSEHWHEEL: - { - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_MOUSEHWHEEL"); - static short h_delta = 0; + S16 incoming_z_delta = GET_WHEEL_DELTA_WPARAM(w_param); + z_delta += incoming_z_delta; + // cout << "z_delta " << z_delta << endl; + + // current mouse wheels report changes in increments of zDelta (+120, -120) + // Future, higher resolution mouse wheels may report smaller deltas. + // So we sum the deltas and only act when we've exceeded WHEEL_DELTA + // + // If the user rapidly spins the wheel, we can get messages with + // large deltas, like 480 or so. Thus we need to scroll more quickly. + if (z_delta <= -WHEEL_DELTA || WHEEL_DELTA <= z_delta) + { + short clicks = -z_delta / WHEEL_DELTA; + WINDOW_IMP_POST(window_imp->mCallbacks->handleScrollWheel(window_imp, clicks)); + z_delta = 0; + } + return 0; + } + /* + // TODO: add this after resolving _WIN32_WINNT issue + case WM_MOUSELEAVE: + { + window_imp->mCallbacks->handleMouseLeave(window_imp); + + // TRACKMOUSEEVENT track_mouse_event; + // track_mouse_event.cbSize = sizeof( TRACKMOUSEEVENT ); + // track_mouse_event.dwFlags = TME_LEAVE; + // track_mouse_event.hwndTrack = h_wnd; + // track_mouse_event.dwHoverTime = HOVER_DEFAULT; + // TrackMouseEvent( &track_mouse_event ); + return 0; + } + */ + case WM_MOUSEHWHEEL: + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_MOUSEHWHEEL"); + static short h_delta = 0; - RECT client_rect; + RECT client_rect; - // eat scroll events that occur outside our window, since we use mouse position to direct scroll - // instead of keyboard focus - // NOTE: mouse_coord is in *window* coordinates for scroll events - POINT mouse_coord = {GET_X_LPARAM(l_param), GET_Y_LPARAM(l_param)}; - - if (ScreenToClient(window_imp->mWindowHandle, &mouse_coord) - && GetClientRect(window_imp->mWindowHandle, &client_rect)) - { - // we have a valid mouse point and client rect - if (mouse_coord.x < client_rect.left || client_rect.right < mouse_coord.x - || mouse_coord.y < client_rect.top || client_rect.bottom < mouse_coord.y) - { - // mouse is outside of client rect, so don't do anything - return 0; - } - } + // eat scroll events that occur outside our window, since we use mouse position to direct scroll + // instead of keyboard focus + // NOTE: mouse_coord is in *window* coordinates for scroll events + POINT mouse_coord = {GET_X_LPARAM(l_param), GET_Y_LPARAM(l_param)}; - S16 incoming_h_delta = GET_WHEEL_DELTA_WPARAM(w_param); - h_delta += incoming_h_delta; + if (ScreenToClient(window_imp->mWindowHandle, &mouse_coord) + && GetClientRect(window_imp->mWindowHandle, &client_rect)) + { + // we have a valid mouse point and client rect + if (mouse_coord.x < client_rect.left || client_rect.right < mouse_coord.x + || mouse_coord.y < client_rect.top || client_rect.bottom < mouse_coord.y) + { + // mouse is outside of client rect, so don't do anything + return 0; + } + } - // If the user rapidly spins the wheel, we can get messages with - // large deltas, like 480 or so. Thus we need to scroll more quickly. - if (h_delta <= -WHEEL_DELTA || WHEEL_DELTA <= h_delta) - { - window_imp->mCallbacks->handleScrollHWheel(window_imp, h_delta / WHEEL_DELTA); - h_delta = 0; - } - return 0; - } - // Handle mouse movement within the window - case WM_MOUSEMOVE: - { - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_MOUSEMOVE"); - MASK mask = gKeyboard->currentMask(TRUE); - window_imp->mCallbacks->handleMouseMove(window_imp, window_coord.convert(), mask); - return 0; - } + S16 incoming_h_delta = GET_WHEEL_DELTA_WPARAM(w_param); + h_delta += incoming_h_delta; - case WM_GETMINMAXINFO: - { - LPMINMAXINFO min_max = (LPMINMAXINFO)l_param; - min_max->ptMinTrackSize.x = window_imp->mMinWindowWidth; - min_max->ptMinTrackSize.y = window_imp->mMinWindowHeight; - return 0; - } + // If the user rapidly spins the wheel, we can get messages with + // large deltas, like 480 or so. Thus we need to scroll more quickly. + if (h_delta <= -WHEEL_DELTA || WHEEL_DELTA <= h_delta) + { + WINDOW_IMP_POST(window_imp->mCallbacks->handleScrollHWheel(window_imp, h_delta / WHEEL_DELTA)); + h_delta = 0; + } + return 0; + } + // Handle mouse movement within the window + case WM_MOUSEMOVE: + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_MOUSEMOVE"); + // DO NOT use mouse event queue for move events to ensure cursor position is updated + // when button events are handled + WINDOW_IMP_POST( + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_MOUSEMOVE lambda"); + + MASK mask = gKeyboard->currentMask(TRUE); + window_imp->mMouseMask = mask; + window_imp->mCursorPosition = window_coord; + }); + return 0; + } - case WM_SIZE: - { - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_SIZE"); - S32 width = S32( LOWORD(l_param) ); - S32 height = S32( HIWORD(l_param) ); + case WM_GETMINMAXINFO: + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_GETMINMAXINFO"); + LPMINMAXINFO min_max = (LPMINMAXINFO)l_param; + min_max->ptMinTrackSize.x = window_imp->mMinWindowWidth; + min_max->ptMinTrackSize.y = window_imp->mMinWindowHeight; + return 0; + } - if (debug_window_proc) - { - BOOL maximized = ( w_param == SIZE_MAXIMIZED ); - BOOL restored = ( w_param == SIZE_RESTORED ); - BOOL minimized = ( w_param == SIZE_MINIMIZED ); - - LL_INFOS("Window") << "WINDOWPROC Size " - << width << "x" << height - << " max " << S32(maximized) - << " min " << S32(minimized) - << " rest " << S32(restored) - << LL_ENDL; - } + case WM_MOVE: + { + window_imp->updateWindowRect(); + return 0; + } + case WM_SIZE: + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_SIZE"); + window_imp->updateWindowRect(); + S32 width = S32(LOWORD(l_param)); + S32 height = S32(HIWORD(l_param)); - // There's an odd behavior with WM_SIZE that I would call a bug. If - // the window is maximized, and you call MoveWindow() with a size smaller - // than a maximized window, it ends up sending WM_SIZE with w_param set - // to SIZE_MAXIMIZED -- which isn't true. So the logic below doesn't work. - // (SL-44655). Fixed it by calling ShowWindow(SW_RESTORE) first (see - // LLWindowWin32::moveWindow in this file). + + if (debug_window_proc) + { + BOOL maximized = (w_param == SIZE_MAXIMIZED); + BOOL restored = (w_param == SIZE_RESTORED); + BOOL minimized = (w_param == SIZE_MINIMIZED); + + LL_INFOS("Window") << "WINDOWPROC Size " + << width << "x" << height + << " max " << S32(maximized) + << " min " << S32(minimized) + << " rest " << S32(restored) + << LL_ENDL; + } - // If we are now restored, but we weren't before, this - // means that the window was un-minimized. - if (w_param == SIZE_RESTORED && window_imp->mLastSizeWParam != SIZE_RESTORED) - { - window_imp->mCallbacks->handleActivate(window_imp, TRUE); - } + // There's an odd behavior with WM_SIZE that I would call a bug. If + // the window is maximized, and you call MoveWindow() with a size smaller + // than a maximized window, it ends up sending WM_SIZE with w_param set + // to SIZE_MAXIMIZED -- which isn't true. So the logic below doesn't work. + // (SL-44655). Fixed it by calling ShowWindow(SW_RESTORE) first (see + // LLWindowWin32::moveWindow in this file). - // handle case of window being maximized from fully minimized state - if (w_param == SIZE_MAXIMIZED && window_imp->mLastSizeWParam != SIZE_MAXIMIZED) - { - window_imp->mCallbacks->handleActivate(window_imp, TRUE); - } + // If we are now restored, but we weren't before, this + // means that the window was un-minimized. + if (w_param == SIZE_RESTORED && window_imp->mLastSizeWParam != SIZE_RESTORED) + { + WINDOW_IMP_POST(window_imp->mCallbacks->handleActivate(window_imp, TRUE)); + } - // Also handle the minimization case - if (w_param == SIZE_MINIMIZED && window_imp->mLastSizeWParam != SIZE_MINIMIZED) - { - window_imp->mCallbacks->handleActivate(window_imp, FALSE); - } + // handle case of window being maximized from fully minimized state + if (w_param == SIZE_MAXIMIZED && window_imp->mLastSizeWParam != SIZE_MAXIMIZED) + { + WINDOW_IMP_POST(window_imp->mCallbacks->handleActivate(window_imp, TRUE)); + } - // Actually resize all of our views - if (w_param != SIZE_MINIMIZED) - { - // Ignore updates for minimizing and minimized "windows" - window_imp->mCallbacks->handleResize( window_imp, - LOWORD(l_param), - HIWORD(l_param) ); - } + // Also handle the minimization case + if (w_param == SIZE_MINIMIZED && window_imp->mLastSizeWParam != SIZE_MINIMIZED) + { + WINDOW_IMP_POST(window_imp->mCallbacks->handleActivate(window_imp, FALSE)); + } - window_imp->mLastSizeWParam = w_param; + // Actually resize all of our views + if (w_param != SIZE_MINIMIZED) + { + // Ignore updates for minimizing and minimized "windows" + WINDOW_IMP_POST(window_imp->mCallbacks->handleResize(window_imp, + LOWORD(l_param), + HIWORD(l_param))); + } - return 0; - } - - case WM_DPICHANGED: - { - LPRECT lprc_new_scale; - F32 new_scale = F32(LOWORD(w_param)) / F32(USER_DEFAULT_SCREEN_DPI); - lprc_new_scale = (LPRECT)l_param; - S32 new_width = lprc_new_scale->right - lprc_new_scale->left; - S32 new_height = lprc_new_scale->bottom - lprc_new_scale->top; - if (window_imp->mCallbacks->handleDPIChanged(window_imp, new_scale, new_width, new_height)) - { - SetWindowPos(h_wnd, - HWND_TOP, - lprc_new_scale->left, - lprc_new_scale->top, - new_width, - new_height, - SWP_NOZORDER | SWP_NOACTIVATE); - } - return 0; - } + window_imp->mLastSizeWParam = w_param; - case WM_SETFOCUS: - if (debug_window_proc) - { - LL_INFOS("Window") << "WINDOWPROC SetFocus" << LL_ENDL; - } - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_SETFOCUS"); - window_imp->mCallbacks->handleFocus(window_imp); - return 0; + return 0; + } - case WM_KILLFOCUS: - if (debug_window_proc) - { - LL_INFOS("Window") << "WINDOWPROC KillFocus" << LL_ENDL; - } - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_KILLFOCUS"); - window_imp->mCallbacks->handleFocusLost(window_imp); - return 0; + case WM_DPICHANGED: + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_DPICHANGED"); + LPRECT lprc_new_scale; + F32 new_scale = F32(LOWORD(w_param)) / F32(USER_DEFAULT_SCREEN_DPI); + lprc_new_scale = (LPRECT)l_param; + S32 new_width = lprc_new_scale->right - lprc_new_scale->left; + S32 new_height = lprc_new_scale->bottom - lprc_new_scale->top; + WINDOW_IMP_POST(window_imp->mCallbacks->handleDPIChanged(window_imp, new_scale, new_width, new_height)); + + SetWindowPos(h_wnd, + HWND_TOP, + lprc_new_scale->left, + lprc_new_scale->top, + new_width, + new_height, + SWP_NOZORDER | SWP_NOACTIVATE); + + return 0; + } - case WM_COPYDATA: - { - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_COPYDATA"); - // received a URL - PCOPYDATASTRUCT myCDS = (PCOPYDATASTRUCT) l_param; - window_imp->mCallbacks->handleDataCopy(window_imp, myCDS->dwData, myCDS->lpData); - }; - return 0; + case WM_SETFOCUS: + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_SETFOCUS"); + if (debug_window_proc) + { + LL_INFOS("Window") << "WINDOWPROC SetFocus" << LL_ENDL; + } + WINDOW_IMP_POST(window_imp->mCallbacks->handleFocus(window_imp)); + return 0; + } - break; + case WM_KILLFOCUS: + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_KILLFOCUS"); + if (debug_window_proc) + { + LL_INFOS("Window") << "WINDOWPROC KillFocus" << LL_ENDL; + } + WINDOW_IMP_POST(window_imp->mCallbacks->handleFocusLost(window_imp)); + return 0; + } - case WM_SETTINGCHANGE: - { - if (w_param == SPI_SETMOUSEVANISH) - { - if (!SystemParametersInfo(SPI_GETMOUSEVANISH, 0, &window_imp->mMouseVanish, 0)) - { - window_imp->mMouseVanish = TRUE; - } - } - } - break; - default: - { - if (debug_window_proc) - { - LL_INFOS("Window") << "Unhandled windows message code: " << U32(u_msg) << LL_ENDL; - } - } - break; - } + case WM_COPYDATA: + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_COPYDATA"); + { + // received a URL + PCOPYDATASTRUCT myCDS = (PCOPYDATASTRUCT)l_param; + void* data = new U8[myCDS->cbData]; + memcpy(data, myCDS->lpData, myCDS->cbData); + auto myType = myCDS->dwData; + + window_imp->post([=]() + { + window_imp->mCallbacks->handleDataCopy(window_imp, myType, data); + delete[] data; + }); + }; + return 0; + + break; + } + case WM_SETTINGCHANGE: + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_SETTINGCHANGE"); + if (w_param == SPI_SETMOUSEVANISH) + { + if (!SystemParametersInfo(SPI_GETMOUSEVANISH, 0, &window_imp->mMouseVanish, 0)) + { + WINDOW_IMP_POST(window_imp->mMouseVanish = TRUE); + } + } + } + break; + + case WM_INPUT: + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("MWP - WM_INPUT"); + + UINT dwSize = 0; + GetRawInputData((HRAWINPUT)l_param, RID_INPUT, NULL, &dwSize, sizeof(RAWINPUTHEADER)); + llassert(dwSize < 1024); + + U8 lpb[1024]; + + if (GetRawInputData((HRAWINPUT)l_param, RID_INPUT, (void*)lpb, &dwSize, sizeof(RAWINPUTHEADER)) == dwSize) + { + RAWINPUT* raw = (RAWINPUT*)lpb; + + if (raw->header.dwType == RIM_TYPEMOUSE) + { + LLMutexLock lock(&window_imp->mRawMouseMutex); + + S32 speed; + const S32 DEFAULT_SPEED(10); + SystemParametersInfo(SPI_GETMOUSESPEED, 0, &speed, 0); + if (speed == DEFAULT_SPEED) + { + window_imp->mRawMouseDelta.mX += raw->data.mouse.lLastX; + window_imp->mRawMouseDelta.mY -= raw->data.mouse.lLastY; + } + else + { + window_imp->mRawMouseDelta.mX += round((F32)raw->data.mouse.lLastX * (F32)speed / DEFAULT_SPEED); + window_imp->mRawMouseDelta.mY -= round((F32)raw->data.mouse.lLastY * (F32)speed / DEFAULT_SPEED); + } + } + } + } - window_imp->mCallbacks->handlePauseWatchdog(window_imp); - } + //list of messages we get often that we don't care to log about + case WM_NCHITTEST: + case WM_NCMOUSEMOVE: + case WM_NCMOUSELEAVE: + case WM_MOVING: + case WM_WINDOWPOSCHANGING: + case WM_WINDOWPOSCHANGED: + break; + + default: + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - default"); + if (debug_window_proc) + { + LL_INFOS("Window") << "Unhandled windows message code: 0x" << std::hex << U32(u_msg) << LL_ENDL; + } + } + break; + } + } else { // (NULL == window_imp) LL_DEBUGS("Window") << "No window implementation to handle message with, message code: " << U32(u_msg) << LL_ENDL; } - // pass unhandled messages down to Windows - return DefWindowProc(h_wnd, u_msg, w_param, l_param); + // pass unhandled messages down to Windows + LRESULT ret; + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - DefWindowProc"); + ret = DefWindowProc(h_wnd, u_msg, w_param, l_param); + } + return ret; } BOOL LLWindowWin32::convertCoords(LLCoordGL from, LLCoordWindow *to) @@ -3274,11 +3416,6 @@ BOOL LLWindowWin32::pasteTextFromClipboard(LLWString &dst) return success; } -void LLWindowWin32::setWindowTitle(const std::string& title) -{ - SetWindowText(mWindowHandle, ll_convert_string_to_wide(title).c_str()); -} - BOOL LLWindowWin32::copyTextToClipboard(const LLWString& wstr) { BOOL success = FALSE; @@ -3319,6 +3456,8 @@ BOOL LLWindowWin32::copyTextToClipboard(const LLWString& wstr) // Constrains the mouse to the window. void LLWindowWin32::setMouseClipping( BOOL b ) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_WIN32; + ASSERT_MAIN_THREAD(); if( b != mIsMouseClipping ) { BOOL success = FALSE; @@ -3349,43 +3488,46 @@ void LLWindowWin32::setMouseClipping( BOOL b ) BOOL LLWindowWin32::getClientRectInScreenSpace( RECT* rectp ) { - BOOL success = FALSE; + BOOL success = FALSE; - RECT client_rect; - if( mWindowHandle && GetClientRect(mWindowHandle, &client_rect) ) - { - POINT top_left; - top_left.x = client_rect.left; - top_left.y = client_rect.top; - ClientToScreen(mWindowHandle, &top_left); - - POINT bottom_right; - bottom_right.x = client_rect.right; - bottom_right.y = client_rect.bottom; - ClientToScreen(mWindowHandle, &bottom_right); - - SetRect( rectp, - top_left.x, - top_left.y, - bottom_right.x, - bottom_right.y ); - - success = TRUE; - } + RECT client_rect; + if (mWindowHandle && GetClientRect(mWindowHandle, &client_rect)) + { + POINT top_left; + top_left.x = client_rect.left; + top_left.y = client_rect.top; + ClientToScreen(mWindowHandle, &top_left); + + POINT bottom_right; + bottom_right.x = client_rect.right; + bottom_right.y = client_rect.bottom; + ClientToScreen(mWindowHandle, &bottom_right); + + SetRect(rectp, + top_left.x, + top_left.y, + bottom_right.x, + bottom_right.y); + + success = TRUE; + } - return success; + return success; } void LLWindowWin32::flashIcon(F32 seconds) { - FLASHWINFO flash_info; - - flash_info.cbSize = sizeof(FLASHWINFO); - flash_info.hwnd = mWindowHandle; - flash_info.dwFlags = FLASHW_TRAY; - flash_info.uCount = UINT(seconds / ICON_FLASH_TIME); - flash_info.dwTimeout = DWORD(1000.f * ICON_FLASH_TIME); // milliseconds - FlashWindowEx(&flash_info); + mWindowThread->post([=]() + { + FLASHWINFO flash_info; + + flash_info.cbSize = sizeof(FLASHWINFO); + flash_info.hwnd = mWindowHandle; + flash_info.dwFlags = FLASHW_TRAY; + flash_info.uCount = UINT(seconds / ICON_FLASH_TIME); + flash_info.dwTimeout = DWORD(1000.f * ICON_FLASH_TIME); // milliseconds + FlashWindowEx(&flash_info); + }); } F32 LLWindowWin32::getGamma() @@ -3395,6 +3537,7 @@ F32 LLWindowWin32::getGamma() BOOL LLWindowWin32::restoreGamma() { + ASSERT_MAIN_THREAD(); if (mCustomGammaSet != FALSE) { LL_DEBUGS("Window") << "Restoring gamma" << LL_ENDL; @@ -3406,6 +3549,7 @@ BOOL LLWindowWin32::restoreGamma() BOOL LLWindowWin32::setGamma(const F32 gamma) { + ASSERT_MAIN_THREAD(); mCurrentGamma = gamma; //Get the previous gamma ramp to restore later. @@ -3444,6 +3588,7 @@ BOOL LLWindowWin32::setGamma(const F32 gamma) void LLWindowWin32::setFSAASamples(const U32 fsaa_samples) { + ASSERT_MAIN_THREAD(); mFSAASamples = fsaa_samples; } @@ -3454,6 +3599,7 @@ U32 LLWindowWin32::getFSAASamples() LLWindow::LLWindowResolution* LLWindowWin32::getSupportedResolutions(S32 &num_resolutions) { + ASSERT_MAIN_THREAD(); if (!mSupportedResolutions) { mSupportedResolutions = new LLWindowResolution[MAX_NUM_RESOLUTIONS]; @@ -3608,7 +3754,12 @@ BOOL LLWindowWin32::resetDisplayResolution() void LLWindowWin32::swapBuffers() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_WIN32; + ASSERT_MAIN_THREAD(); + glFlush(); //superstitious flush for maybe frame stall removal? SwapBuffers(mhDC); + + LL_PROFILER_GPU_COLLECT } @@ -3833,13 +3984,19 @@ void *LLWindowWin32::getPlatformWindow() void LLWindowWin32::bringToFront() { - BringWindowToTop(mWindowHandle); + mWindowThread->post([=]() + { + BringWindowToTop(mWindowHandle); + }); } // set (OS) window focus back to the client void LLWindowWin32::focusClient() { - SetFocus ( mWindowHandle ); + mWindowThread->post([=]() + { + SetFocus(mWindowHandle); + }); } void LLWindowWin32::allowLanguageTextInput(LLPreeditor *preeditor, BOOL b) @@ -4081,6 +4238,7 @@ void LLWindowWin32::updateLanguageTextInputArea() void LLWindowWin32::interruptLanguageTextInput() { + ASSERT_MAIN_THREAD(); if (mPreeditor && LLWinImm::isAvailable()) { HIMC himc = LLWinImm::getContext(mWindowHandle); @@ -4283,6 +4441,7 @@ static LLWString find_context(const LLWString & wtext, S32 focus, S32 focus_leng // for files and via IDropTarget interface requests. LLWindowCallbacks::DragNDropResult LLWindowWin32::completeDragNDropRequest( const LLCoordGL gl_coord, const MASK mask, LLWindowCallbacks::DragNDropAction action, const std::string url ) { + ASSERT_MAIN_THREAD(); return mCallbacks->handleDragNDrop( this, gl_coord, mask, action, url ); } @@ -4331,6 +4490,7 @@ BOOL LLWindowWin32::handleImeRequests(WPARAM request, LPARAM param, LRESULT *res LL_WARNS("Window") << "*** IMR_QUERYCHARPOSITON called but getPreeditLocation failed." << LL_ENDL; return FALSE; } + fillCharPosition(caret_coord, preedit_bounds, text_control, char_position); *result = 1; @@ -4505,3 +4665,153 @@ std::vector<std::string> LLWindowWin32::getDynamicFallbackFontList() #endif // LL_WINDOWS + +inline LLWindowWin32::LLWindowWin32Thread::LLWindowWin32Thread() + : ThreadPool("Window Thread", 1, MAX_QUEUE_SIZE) +{ + ThreadPool::start(); +} + +/** + * LogChange is to log changes in status while trying to avoid spamming the + * log with repeated messages, especially in a tight loop. It refuses to log + * a continuous run of identical messages, but logs every time the message + * changes. (It will happily spam when messages quickly bounce back and + * forth.) + */ +class LogChange +{ +public: + LogChange(const std::string& tag): + mTag(tag) + {} + + template <typename... Items> + void always(Items&&... items) + { + // This odd construct ensures that the stringize() call is only + // executed if DEBUG logging is enabled for the passed tag. + LL_DEBUGS(mTag.c_str()); + log(LL_CONT, stringize(std::forward<Items>(items)...)); + LL_ENDL; + } + + template <typename... Items> + void onChange(Items&&... items) + { + LL_DEBUGS(mTag.c_str()); + auto str = stringize(std::forward<Items>(items)...); + if (str != mPrev) + { + log(LL_CONT, str); + } + LL_ENDL; + } + +private: + void log(std::ostream& out, const std::string& message) + { + mPrev = message; + out << message; + } + std::string mTag; + std::string mPrev; +}; + +void LLWindowWin32::LLWindowWin32Thread::run() +{ + sWindowThreadId = std::this_thread::get_id(); + LogChange logger("Window"); + + while (! getQueue().done()) + { + LL_PROFILE_ZONE_SCOPED_CATEGORY_WIN32; + + if (mWindowHandle != 0) + { + MSG msg; + BOOL status; + if (mhDC == 0) + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("w32t - PeekMessage"); + logger.onChange("PeekMessage(", std::hex, mWindowHandle, ")"); + status = PeekMessage(&msg, mWindowHandle, 0, 0, PM_REMOVE); + } + else + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("w32t - GetMessage"); + logger.always("GetMessage(", std::hex, mWindowHandle, ")"); + status = GetMessage(&msg, NULL, 0, 0); + } + if (status > 0) + { + logger.always("got MSG (", std::hex, msg.hwnd, ", ", msg.message, + ", ", msg.wParam, ")"); + TranslateMessage(&msg); + DispatchMessage(&msg); + + mMessageQueue.pushFront(msg); + } + } + + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("w32t - Function Queue"); + logger.onChange("runPending()"); + //process any pending functions + getQueue().runPending(); + } + +#if 0 + { + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("w32t - Sleep"); + logger.always("sleep(1)"); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } +#endif + } +} + +void LLWindowWin32::post(const std::function<void()>& func) +{ + mFunctionQueue.pushFront(func); +} + +void LLWindowWin32::postMouseButtonEvent(const std::function<void()>& func) +{ + mMouseQueue.pushFront(func); +} + +void LLWindowWin32::kickWindowThread(HWND windowHandle) +{ + if (! windowHandle) + windowHandle = mWindowHandle; + if (windowHandle) + { + // post a nonsense user message to wake up the Window Thread in + // case any functions are pending and no windows events came + // through this frame + WPARAM wparam{ 0xB0B0 }; + LL_DEBUGS("Window") << "PostMessage(" << std::hex << windowHandle + << ", " << WM_DUMMY_ + << ", " << wparam << ")" << std::dec << LL_ENDL; + PostMessage(windowHandle, WM_DUMMY_, wparam, 0x1337); + } +} + +void LLWindowWin32::updateWindowRect() +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_WIN32; + //called from window thread + RECT rect; + RECT client_rect; + + if (GetWindowRect(mWindowHandle, &rect) && + GetClientRect(mWindowHandle, &client_rect)) + { + post([=] + { + mRect = rect; + mClientRect = client_rect; + }); + } +} diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h index 1f712cd276cf11d3da2d49ea658dd3890cef8408..7b46c55d69f20fedc3306c5905c5416e23f0a619 100644 --- a/indra/llwindow/llwindowwin32.h +++ b/indra/llwindow/llwindowwin32.h @@ -33,6 +33,10 @@ #include "llwindow.h" #include "llwindowcallbacks.h" #include "lldragdropwin32.h" +#include "llthread.h" +#include "llthreadsafequeue.h" +#include "llmutex.h" +#include "workqueue.h" #ifndef DPI_ENUMS_DECLARED @@ -97,9 +101,15 @@ class LLWindowWin32 : public LLWindow /*virtual*/ BOOL setPosition(LLCoordScreen position); /*virtual*/ BOOL setSizeImpl(LLCoordScreen size); /*virtual*/ BOOL setSizeImpl(LLCoordWindow size); - /*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp = NULL); + /*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL enable_vsync, const LLCoordScreen * const posp = NULL); + /*virtual*/ void setTitle(const std::string title); + void* createSharedContext() override; + void makeContextCurrent(void* context) override; + void destroySharedContext(void* context) override; + /*virtual*/ void toggleVSync(bool enable_vsync); /*virtual*/ BOOL setCursorPosition(LLCoordWindow position); /*virtual*/ BOOL getCursorPosition(LLCoordWindow *position); + /*virtual*/ BOOL getCursorDelta(LLCoordCommon* delta); /*virtual*/ void showCursor(); /*virtual*/ void hideCursor(); /*virtual*/ void showCursorFromMouseMove(); @@ -113,7 +123,6 @@ class LLWindowWin32 : public LLWindow /*virtual*/ BOOL isClipboardTextAvailable(); /*virtual*/ BOOL pasteTextFromClipboard(LLWString &dst); /*virtual*/ BOOL copyTextToClipboard(const LLWString &src); - /*virtual*/ void setWindowTitle(const std::string& title) override; /*virtual*/ void flashIcon(F32 seconds); /*virtual*/ F32 getGamma(); /*virtual*/ BOOL setGamma(const F32 gamma); // Set the gamma @@ -166,7 +175,7 @@ class LLWindowWin32 : public LLWindow protected: LLWindowWin32(LLWindowCallbacks* callbacks, const std::string& title, const std::string& name, int x, int y, int width, int height, U32 flags, - BOOL fullscreen, BOOL clearBg, BOOL disable_vsync, BOOL use_gl, + BOOL fullscreen, BOOL clearBg, BOOL enable_vsync, BOOL use_gl, BOOL ignore_pixel_depth, U32 fsaa_samples); ~LLWindowWin32(); @@ -215,17 +224,24 @@ class LLWindowWin32 : public LLWindow WCHAR *mWindowTitle; WCHAR *mWindowClassName; - HWND mWindowHandle; // window handle - HGLRC mhRC; // OpenGL rendering context - HDC mhDC; // Windows Device context handle + HWND mWindowHandle = 0; // window handle + HGLRC mhRC = 0; // OpenGL rendering context + HDC mhDC = 0; // Windows Device context handle HINSTANCE mhInstance; // handle to application instance - WNDPROC mWndProc; // user-installable window proc RECT mOldMouseClip; // Screen rect to which the mouse cursor was globally constrained before we changed it in clipMouse() WPARAM mLastSizeWParam; F32 mOverrideAspectRatio; F32 mNativeAspectRatio; HCURSOR mCursor[ UI_CURSOR_COUNT ]; // Array of all mouse cursors + LLCoordWindow mCursorPosition; // mouse cursor position, should only be mutated on main thread + LLMutex mRawMouseMutex; + RAWINPUTDEVICE mRawMouse; + LLCoordWindow mLastCursorPosition; // mouse cursor position from previous frame + LLCoordCommon mRawMouseDelta; // raw mouse delta according to window thread + LLCoordCommon mMouseFrameDelta; // how much the mouse moved between the last two calls to gatherInput + + MASK mMouseMask; static BOOL sIsClassRegistered; // has the window class been registered? @@ -236,7 +252,6 @@ class LLWindowWin32 : public LLWindow BOOL mCustomGammaSet; LPWSTR mIconResource; - BOOL mMousePositionModified; BOOL mInputProcessingPaused; // The following variables are for Language Text Input control. @@ -276,6 +291,20 @@ class LLWindowWin32 : public LLWindow AdjustWindowRectExForDpi_t pAdjustWindowRectExForDpi; GetSystemMetricsForDpi_t pGetSystemMetricsForDpi; + // Cached values of GetWindowRect and GetClientRect to be used by app thread + void updateWindowRect(); + RECT mRect; + RECT mClientRect; + + struct LLWindowWin32Thread; + LLWindowWin32Thread* mWindowThread = nullptr; + LLThreadSafeQueue<std::function<void()>> mFunctionQueue; + LLThreadSafeQueue<std::function<void()>> mMouseQueue; + void post(const std::function<void()>& func); + void postMouseButtonEvent(const std::function<void()>& func); + void recreateWindow(RECT window_rect, DWORD dw_ex_style, DWORD dw_style, bool no_destroy = false); + void kickWindowThread(HWND windowHandle=0); + friend class LLWindowManager; }; diff --git a/indra/llxml/llcontrol.h b/indra/llxml/llcontrol.h index 5029bc7c80106074b1c32313244f08c767b7459a..9735ef02d2177552fc61e9dbd9f558ee1b63e736 100644 --- a/indra/llxml/llcontrol.h +++ b/indra/llxml/llcontrol.h @@ -237,6 +237,7 @@ class LLControlGroup final : public LLInstanceTracker<LLControlGroup, std::strin // generic getter template<typename T> T get(std::string_view name) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD; LLControlVariable* control = getControl(name); LLSD value; eControlType type = TYPE_COUNT; @@ -395,8 +396,8 @@ class LLCachedControl const T& default_value, const std::string& comment = "Declared In Code") { - mCachedControlPtr = LLControlCache<T>::getInstance(name); - if (mCachedControlPtr.isNull()) + mCachedControlPtr = LLControlCache<T>::getInstance(name).get(); + if (! mCachedControlPtr) { mCachedControlPtr = new LLControlCache<T>(group, name, default_value, comment); } @@ -405,8 +406,8 @@ class LLCachedControl LLCachedControl(LLControlGroup& group, const std::string& name) { - mCachedControlPtr = LLControlCache<T>::getInstance(name); - if (mCachedControlPtr.isNull()) + mCachedControlPtr = LLControlCache<T>::getInstance(name).get(); + if (! mCachedControlPtr) { mCachedControlPtr = new LLControlCache<T>(group, name); } diff --git a/indra/media_plugins/cef/CMakeLists.txt b/indra/media_plugins/cef/CMakeLists.txt index df33098d090f4fddc4d85cb9bf7df9f1bbb244e5..0d144fdb48111926abea92a6f99b7529e48c1a86 100644 --- a/indra/media_plugins/cef/CMakeLists.txt +++ b/indra/media_plugins/cef/CMakeLists.txt @@ -102,6 +102,4 @@ if (DARWIN) LINK_FLAGS "-exported_symbols_list ${CMAKE_CURRENT_SOURCE_DIR}/../base/media_plugin_base.exp" ) - ## turns on C++11 using Cmake - target_compile_features(media_plugin_cef PRIVATE cxx_range_for) endif (DARWIN) diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index 00b0dafa2b3f5093149a27647cf366eae2969953..006c29874e9444672f4905b26c6d175b4b45b33b 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -34,6 +34,7 @@ #include "llplugininstance.h" #include "llpluginmessage.h" #include "llpluginmessageclasses.h" +#include "llstring.h" #include "volume_catcher.h" #include "media_plugin_base.h" @@ -55,7 +56,7 @@ class MediaPluginCEF : bool init(); void onPageChangedCallback(const unsigned char* pixels, int x, int y, const int width, const int height); - void onCustomSchemeURLCallback(std::string url); + void onCustomSchemeURLCallback(std::string url, bool user_gesture, bool is_redirect); void onConsoleMessageCallback(std::string message, std::string source, int line); void onStatusMessageCallback(std::string value); void onTitleChangeCallback(std::string title); @@ -318,11 +319,18 @@ void MediaPluginCEF::onOpenPopupCallback(std::string url, std::string target) //////////////////////////////////////////////////////////////////////////////// // -void MediaPluginCEF::onCustomSchemeURLCallback(std::string url) +void MediaPluginCEF::onCustomSchemeURLCallback(std::string url, bool user_gesture, bool is_redirect) { LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_nofollow"); - message.setValue("uri", url); - message.setValue("nav_type", "clicked"); // TODO: differentiate between click and navigate to + message.setValue("uri", url); + + // indicate if this interaction was from a user click (okay on a SLAPP) or + // via a navigation (e.g. a data URL - see SL-18151) (not okay on a SLAPP) + const std::string nav_type = user_gesture ? "clicked" : "navigated"; + + message.setValue("nav_type", nav_type); + message.setValueBoolean("is_redirect", is_redirect); + sendMessage(message); } @@ -619,7 +627,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string) { // event callbacks from Dullahan mCEFLib->setOnPageChangedCallback(std::bind(&MediaPluginCEF::onPageChangedCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5)); - mCEFLib->setOnCustomSchemeURLCallback(std::bind(&MediaPluginCEF::onCustomSchemeURLCallback, this, std::placeholders::_1)); + mCEFLib->setOnCustomSchemeURLCallback(std::bind(&MediaPluginCEF::onCustomSchemeURLCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); mCEFLib->setOnConsoleMessageCallback(std::bind(&MediaPluginCEF::onConsoleMessageCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); mCEFLib->setOnStatusMessageCallback(std::bind(&MediaPluginCEF::onStatusMessageCallback, this, std::placeholders::_1)); mCEFLib->setOnTitleChangeCallback(std::bind(&MediaPluginCEF::onTitleChangeCallback, this, std::placeholders::_1)); diff --git a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp index b541d53862539c929c1f53d51e912ef6062026b4..65b5794ca98e21fa6e3003d973d4a04ca3a260ab 100644 --- a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp +++ b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp @@ -72,6 +72,7 @@ class MediaPluginLibVLC : static void display(void* data, void* id); /*virtual*/ void setDirty(int left, int top, int right, int bottom) /* override, but that is not supported in gcc 4.6 */; + void setDurationDirty(); static void eventCallbacks(const libvlc_event_t* event, void* ptr); @@ -92,8 +93,8 @@ class MediaPluginLibVLC : bool mIsLooping; - float mCurTime; - float mDuration; + F64 mCurTime; + F64 mDuration; EStatus mVlcStatus; }; @@ -212,6 +213,19 @@ void MediaPluginLibVLC::setDirty(int left, int top, int right, int bottom) sendMessage(message); } +//////////////////////////////////////////////////////////////////////////////// +// *virtual* +void MediaPluginLibVLC::setDurationDirty() +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "updated"); + + message.setValueReal("current_time", mCurTime); + message.setValueReal("duration", mDuration); + message.setValueReal("current_rate", 1.0f); + + sendMessage(message); +} + //////////////////////////////////////////////////////////////////////////////// // void MediaPluginLibVLC::eventCallbacks(const libvlc_event_t* event, void* ptr) @@ -232,6 +246,7 @@ void MediaPluginLibVLC::eventCallbacks(const libvlc_event_t* event, void* ptr) parent->mDuration = (float)(libvlc_media_get_duration(parent->mLibVLCMedia)) / 1000.0f; parent->mVlcStatus = STATUS_PLAYING; parent->setVolumeVLC(); + parent->setDurationDirty(); break; case libvlc_MediaPlayerPaused: @@ -244,6 +259,8 @@ void MediaPluginLibVLC::eventCallbacks(const libvlc_event_t* event, void* ptr) case libvlc_MediaPlayerEndReached: parent->mVlcStatus = STATUS_DONE; + parent->mCurTime = parent->mDuration; + parent->setDurationDirty(); break; case libvlc_MediaPlayerEncounteredError: @@ -252,6 +269,11 @@ void MediaPluginLibVLC::eventCallbacks(const libvlc_event_t* event, void* ptr) case libvlc_MediaPlayerTimeChanged: parent->mCurTime = (float)libvlc_media_player_get_time(parent->mLibVLCMediaPlayer) / 1000.0f; + if (parent->mVlcStatus == STATUS_DONE && libvlc_media_player_is_playing(parent->mLibVLCMediaPlayer)) + { + parent->mVlcStatus = STATUS_PLAYING; + } + parent->setDurationDirty(); break; case libvlc_MediaPlayerPositionChanged: @@ -259,6 +281,7 @@ void MediaPluginLibVLC::eventCallbacks(const libvlc_event_t* event, void* ptr) case libvlc_MediaPlayerLengthChanged: parent->mDuration = (float)libvlc_media_get_duration(parent->mLibVLCMedia) / 1000.0f; + parent->setDurationDirty(); break; case libvlc_MediaPlayerTitleChanged: @@ -561,7 +584,24 @@ void MediaPluginLibVLC::receiveMessage(const char* message_string) mTextureWidth = texture_width; mTextureHeight = texture_height; + libvlc_time_t time = 1000.0 * mCurTime; + playMedia(); + + if (mLibVLCMediaPlayer) + { + libvlc_media_player_set_time(mLibVLCMediaPlayer, time); + time = libvlc_media_player_get_time(mLibVLCMediaPlayer); + if (time < 0) + { + // -1 if there is no media + mCurTime = 0; + } + else + { + mCurTime = (F64)time / 1000.0; + } + } }; }; @@ -593,6 +633,13 @@ void MediaPluginLibVLC::receiveMessage(const char* message_string) { if (mLibVLCMediaPlayer) { + if (mVlcStatus == STATUS_DONE && !libvlc_media_player_is_playing(mLibVLCMediaPlayer)) + { + // stop or vlc will ignore 'play', it will just + // make an MediaPlayerEndReached event even if + // seek was used + libvlc_media_player_stop(mLibVLCMediaPlayer); + } libvlc_media_player_play(mLibVLCMediaPlayer); } } @@ -605,15 +652,32 @@ void MediaPluginLibVLC::receiveMessage(const char* message_string) } else if (message_name == "seek") { - if (mDuration > 0) - { - F64 normalized_offset = message_in.getValueReal("time") / mDuration; - libvlc_media_player_set_position(mLibVLCMediaPlayer, normalized_offset); - } + if (mLibVLCMediaPlayer) + { + libvlc_time_t time = 1000.0 * message_in.getValueReal("time"); + libvlc_media_player_set_time(mLibVLCMediaPlayer, time); + time = libvlc_media_player_get_time(mLibVLCMediaPlayer); + if (time < 0) + { + // -1 if there is no media + mCurTime = 0; + } + else + { + mCurTime = (F64)time / 1000.0; + } + + if (!libvlc_media_player_is_playing(mLibVLCMediaPlayer)) + { + // if paused, won't trigger update, update now + setDurationDirty(); + } + } } else if (message_name == "set_loop") { - mIsLooping = true; + bool loop = message_in.getValueBoolean("loop"); + mIsLooping = loop; } else if (message_name == "set_volume") { diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 75992dcfedce391f07df457d3fd5d37837f11893..a6179be48d1abdf5b3b4dca4a95dc1acb6c6dd68 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -34,6 +34,7 @@ include(LLInventory) include(LLKDU) include(LLLogin) include(LLMath) +include(LLMeshOptimizer) include(LLMessage) include(LLPhysicsExtensions) include(LLPlugin) @@ -51,12 +52,13 @@ include(PNG) include(Sentry) include(TemplateCheck) include(ThreeJS) +include(Tracy) include(UI) include(UnixInstall) include(ViewerMiscLibs) include(ViewerManager) include(VisualLeakDetector) -include(ZLIB) +include(ZLIBNG) include(URIPARSER) if( LLPHYSICSEXTENSIONS_SRC_DIR ) @@ -73,7 +75,7 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${DBUSGLIB_INCLUDE_DIRS} - ${ZLIB_INCLUDE_DIRS} + ${ZLIBNG_INCLUDE_DIRS} ${LIBXML2_INCLUDE_DIRS} ${LLAUDIO_INCLUDE_DIRS} ${LLCHARACTER_INCLUDE_DIRS} @@ -84,6 +86,7 @@ include_directories( ${LLKDU_INCLUDE_DIRS} ${LLINVENTORY_INCLUDE_DIRS} ${LLMATH_INCLUDE_DIRS} + ${LLMESHOPTIMIZER_INCLUDE_DIRS} ${LLMESSAGE_INCLUDE_DIRS} ${LLPLUGIN_INCLUDE_DIRS} ${LLPRIMITIVE_INCLUDE_DIRS} @@ -99,6 +102,7 @@ include_directories( ${FREEALUT_INCLUDE_DIRS} "${LIBS_PREBUILT_DIR}/include/collada/1.4" ${LLAPPEARANCE_INCLUDE_DIRS} + ${TRACY_INCLUDE_DIR} ) if(USE_FMODSTUDIO) @@ -270,6 +274,7 @@ set(viewer_SOURCE_FILES llfloatercamerapresets.cpp llfloaterchatalerts.cpp llfloaterchatvoicevolume.cpp + llfloaterclassified.cpp llfloatercolorpicker.cpp llfloaterconversationlog.cpp llfloaterconversationpreview.cpp @@ -327,7 +332,7 @@ set(viewer_SOURCE_FILES llfloaternewlocalinventory.cpp llfloaternotificationsconsole.cpp llfloaternotificationstabbed.cpp - llfloateroutfitphotopreview.cpp + llfloateroutfitphotopreview.cpp llfloateroutfitsnapshot.cpp llfloaterobjectweights.cpp llfloateropenobject.cpp @@ -342,6 +347,7 @@ set(viewer_SOURCE_FILES llfloaterpreference.cpp llfloaterpreferenceviewadvanced.cpp llfloaterpreviewtrash.cpp + llfloaterprofiletexture.cpp llfloaterprogressview.cpp llfloaterproperties.cpp llfloaterregiondebugconsole.cpp @@ -534,7 +540,6 @@ set(viewer_SOURCE_FILES llpanelpeople.cpp llpanelpeoplemenus.cpp llpanelpermissions.cpp - llpanelpick.cpp llpanelplaceinfo.cpp llpanelplaceprofile.cpp llpanelplaces.cpp @@ -650,11 +655,8 @@ set(viewer_SOURCE_FILES llsyntaxid.cpp llsyswellitem.cpp llsyswellwindow.cpp - lltelemetry.cpp llteleporthistory.cpp llteleporthistorystorage.cpp - lltextureatlas.cpp - lltextureatlasmanager.cpp lltexturecache.cpp lltexturectrl.cpp lltexturefetch.cpp @@ -974,6 +976,7 @@ set(viewer_HEADER_FILES llfloatercamera.h llfloaterchatalerts.h llfloaterchatvoicevolume.h + llfloaterclassified.h llfloatercolorpicker.h llfloaterconversationlog.h llfloaterconversationpreview.h @@ -1049,6 +1052,7 @@ set(viewer_HEADER_FILES llfloaterpreference.h llfloaterpreferenceviewadvanced.h llfloaterpreviewtrash.h + llfloaterprofiletexture.h llfloaterprogressview.h llfloaterproperties.h llfloaterregiondebugconsole.h @@ -1231,7 +1235,6 @@ set(viewer_HEADER_FILES llpanelpeople.h llpanelpeoplemenus.h llpanelpermissions.h - llpanelpick.h llpanelplaceinfo.h llpanelplaceprofile.h llpanelplaces.h @@ -1348,8 +1351,6 @@ set(viewer_HEADER_FILES lltable.h llteleporthistory.h llteleporthistorystorage.h - lltextureatlas.h - lltextureatlasmanager.h lltexturecache.h lltexturectrl.h lltexturefetch.h @@ -1724,6 +1725,7 @@ if (WINDOWS) ${WINDOWS_LIBRARIES} comdlg32 dxguid + imm32 kernel32 odbc32 odbccp32 @@ -1789,6 +1791,8 @@ set(viewer_APPSETTINGS_FILES ${CMAKE_SOURCE_DIR}/../etc/message.xml ${CMAKE_SOURCE_DIR}/../scripts/messages/message_template.msg packages-info.txt + featuretable.txt + featuretable_mac.txt ) source_group("App Settings" FILES ${viewer_APPSETTINGS_FILES}) @@ -2140,7 +2144,7 @@ endif (WINDOWS) # one of these being libz where you can find four or more versions in play # at once. On Linux, libz can be found at link and run time via a number # of paths: -# +# # => -lfreetype # => libz.so.1 (on install machine, not build) # => -lSDL @@ -2151,19 +2155,20 @@ endif (WINDOWS) # # We generally want the newest version of the library to provide all symbol # resolution. To that end, when using static archives, the *_PRELOAD_ARCHIVES -# variables, PNG_PRELOAD_ARCHIVES and ZLIB_PRELOAD_ARCHIVES, get the archives +# variables, PNG_PRELOAD_ARCHIVES and ZLIBNG_PRELOAD_ARCHIVES, get the archives # dumped into the target binary and runtime lookup will find the most # modern version. target_link_libraries(${VIEWER_BINARY_NAME} ${PNG_PRELOAD_ARCHIVES} - ${ZLIB_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} @@ -2200,6 +2205,7 @@ target_link_libraries(${VIEWER_BINARY_NAME} ${LLPHYSICS_LIBRARIES} ${LLPHYSICSEXTENSIONS_LIBRARIES} ${LLAPPEARANCE_LIBRARIES} + ${TRACY_LIBRARY} ${MINIZIP_LIBRARIES} absl::flat_hash_map absl::node_hash_map @@ -2331,7 +2337,7 @@ if (DARWIN) 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") - + configure_file( "${CMAKE_CURRENT_SOURCE_DIR}/Info-Alchemy.plist" "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/Info-Alchemy.plist" @@ -2545,7 +2551,7 @@ if (LL_TESTS) llworldmap.cpp llworldmipmap.cpp PROPERTIES - LL_TEST_ADDITIONAL_SOURCE_FILES + LL_TEST_ADDITIONAL_SOURCE_FILES tests/llviewertexture_stub.cpp #llviewertexturelist.cpp ) @@ -2578,7 +2584,7 @@ if (LL_TESTS) llworldmap.cpp llworldmipmap.cpp PROPERTIES - LL_TEST_ADDITIONAL_SOURCE_FILES + LL_TEST_ADDITIONAL_SOURCE_FILES tests/llviewertexture_stub.cpp #llviewertexturelist.cpp LL_TEST_ADDITIONAL_LIBRARIES "${BOOST_SYSTEM_LIBRARY}" diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index cc81d718c3b6f077fd712540699a0dff7c885dba..4aa5a3a58e8c27e16189402e6ab0e13712de35f8 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -6.5.5 +6.6.8 diff --git a/indra/newview/alavataractions.cpp b/indra/newview/alavataractions.cpp index e67b9d77ebb75baddb16b908b17b9c879d46c256..06d2943706baebe3080bb83cf6ef7910d1af110c 100644 --- a/indra/newview/alavataractions.cpp +++ b/indra/newview/alavataractions.cpp @@ -190,7 +190,7 @@ bool ALAvatarActions::canTeleportTo(const LLUUID& avatar_id) return false; LLWorld::pos_map_t positions; - LLWorld::getInstanceFast()->getAvatars(&positions); + LLWorld::getInstance()->getAvatars(&positions); auto iter = positions.find(avatar_id); if (iter != positions.cend()) { @@ -211,7 +211,7 @@ void ALAvatarActions::teleportTo(const LLUUID& avatar_id) return; LLWorld::pos_map_t positions; - LLWorld::getInstanceFast()->getAvatars(&positions); + LLWorld::getInstance()->getAvatars(&positions); auto iter = positions.find(avatar_id); if (iter != positions.cend()) { @@ -256,7 +256,7 @@ bool ALAvatarActions::canFreezeEject(const uuid_vec_t& ids) return true; LLWorld::region_gpos_map_t idRegions; - LLWorld::getInstanceFast()->getAvatars(&idRegions); + LLWorld::getInstance()->getAvatars(&idRegions); auto ret = false; @@ -273,12 +273,12 @@ bool ALAvatarActions::canFreezeEject(const uuid_vec_t& ids) { // Estate owners / managers can freeze // Parcel owners can also freeze - LLParcelSelectionHandle selection = LLViewerParcelMgr::getInstanceFast()->selectParcelAt(pos_global); + LLParcelSelectionHandle selection = LLViewerParcelMgr::getInstance()->selectParcelAt(pos_global); const LLParcel* parcel = selection->getParcel(); auto local_pos = region->getPosRegionFromGlobal(pos_global); if ((region->getOwner() == gAgent.getID() || region->isEstateManager() || region->isOwnedSelf(local_pos)) - || (region->isOwnedGroup(local_pos) && parcel && LLViewerParcelMgr::getInstanceFast()->isParcelOwnedByAgent(parcel, GP_LAND_ADMIN))) + || (region->isOwnedGroup(local_pos) && parcel && LLViewerParcelMgr::getInstance()->isParcelOwnedByAgent(parcel, GP_LAND_ADMIN))) { ret = true; } @@ -351,7 +351,7 @@ void ALAvatarActions::parcelEject(const uuid_vec_t& ids) return; LLWorld::pos_map_t avatar_positions; - LLWorld::getInstanceFast()->getAvatars(&avatar_positions); + LLWorld::getInstance()->getAvatars(&avatar_positions); LLSD payload; payload["avatar_ids"] = LLSD::emptyArray(); @@ -370,10 +370,10 @@ void ALAvatarActions::parcelEject(const uuid_vec_t& ids) if (pos_it != avatar_positions.cend()) { const auto& pos = pos_it->second; - LLParcel* parcel = LLViewerParcelMgr::getInstanceFast()->selectParcelAt(pos)->getParcel(); + LLParcel* parcel = LLViewerParcelMgr::getInstance()->selectParcelAt(pos)->getParcel(); if (parcel) { - ban_enabled = LLViewerParcelMgr::getInstanceFast()->isParcelOwnedByAgent(parcel, GP_LAND_MANAGE_BANNED); + ban_enabled = LLViewerParcelMgr::getInstance()->isParcelOwnedByAgent(parcel, GP_LAND_MANAGE_BANNED); if (!ban_enabled) { ban_killed = true; @@ -429,7 +429,7 @@ bool ALAvatarActions::canManageAvatarsEstate(const uuid_vec_t& ids) return true; LLWorld::region_gpos_map_t idRegions; - LLWorld::getInstanceFast()->getAvatars(&idRegions); + LLWorld::getInstance()->getAvatars(&idRegions); auto ret = false; @@ -699,7 +699,7 @@ bool ALAvatarActions::handleEstateTeleportHome(const LLSD& notification, const L if (option == 0) { LLWorld::region_gpos_map_t idRegions; - LLWorld::getInstanceFast()->getAvatars(&idRegions); + LLWorld::getInstance()->getAvatars(&idRegions); const auto& avatar_ids = notification["payload"]["avatar_ids"]; for (LLSD::array_const_iterator it = avatar_ids.beginArray(), it_end = avatar_ids.endArray(); it != it_end; ++it) { @@ -741,7 +741,7 @@ bool ALAvatarActions::handleEstateKick(const LLSD& notification, const LLSD& res if (option == 0) { LLWorld::region_gpos_map_t idRegions; - LLWorld::getInstanceFast()->getAvatars(&idRegions); + LLWorld::getInstance()->getAvatars(&idRegions); const auto& avatar_ids = notification["payload"]["avatar_ids"]; for (LLSD::array_const_iterator it = avatar_ids.beginArray(), it_end = avatar_ids.endArray(); it != it_end; ++it) { diff --git a/indra/newview/alfloaterparticleeditor.cpp b/indra/newview/alfloaterparticleeditor.cpp index 5a87e8a11ed4f07b8e2aa5e3a5978e70e69e4946..ba1a018adeb7fc179feaa707088d9502b26a70c7 100644 --- a/indra/newview/alfloaterparticleeditor.cpp +++ b/indra/newview/alfloaterparticleeditor.cpp @@ -373,7 +373,7 @@ void ALFloaterParticleEditor::onClickTargetPicker() mPickTargetButton->setToggleState(TRUE); mPickTargetButton->setEnabled(FALSE); LLToolObjPicker::getInstance()->setExitCallback(onTargetPicked, this); - LLToolMgr::getInstanceFast()->setTransientTool(LLToolObjPicker::getInstance()); + LLToolMgr::getInstance()->setTransientTool(LLToolObjPicker::getInstance()); } // static @@ -383,7 +383,7 @@ void ALFloaterParticleEditor::onTargetPicked(void* userdata) const LLUUID picked = LLToolObjPicker::getInstance()->getObjectID(); - LLToolMgr::getInstanceFast()->clearTransientTool(); + LLToolMgr::getInstance()->clearTransientTool(); self->mPickTargetButton->setEnabled(TRUE); self->mPickTargetButton->setToggleState(FALSE); diff --git a/indra/newview/alfloaterregiontracker.cpp b/indra/newview/alfloaterregiontracker.cpp index c7eda4293d7c51b90e86e8388e94135082ade203..b33587e2bb72efab9a53844aa6b0ce93b6764818 100644 --- a/indra/newview/alfloaterregiontracker.cpp +++ b/indra/newview/alfloaterregiontracker.cpp @@ -131,7 +131,7 @@ void ALFloaterRegionTracker::refresh() maturity.column("region_maturity_icon").type("icon").font_halign(LLFontGL::HCENTER); region.column("region_name").type("text").value(sim_name); count.column("region_agent_count").type("text").value("..."); - if (LLSimInfo* info = LLWorldMap::getInstanceFast()->simInfoFromName(sim_name)) + if (LLSimInfo* info = LLWorldMap::getInstance()->simInfoFromName(sim_name)) { maturity.value(info->getAccessIcon()); @@ -188,13 +188,13 @@ void ALFloaterRegionTracker::requestRegionData() for (LLSD::map_const_iterator it = mRegionMap.beginMap(), end = mRegionMap.endMap(); it != end; ++it) { const auto& name = it->first; - if (LLSimInfo* info = LLWorldMap::getInstanceFast()->simInfoFromName(name)) + if (LLSimInfo* info = LLWorldMap::getInstance()->simInfoFromName(name)) { info->updateAgentCount(LLTimer::getElapsedSeconds()); } else { - LLWorldMapMessage::getInstanceFast()->sendNamedRegionRequest(name); + LLWorldMapMessage::getInstance()->sendNamedRegionRequest(name); } } mEventTimer.start(); diff --git a/indra/newview/altoolalign.cpp b/indra/newview/altoolalign.cpp index c804a7c070d80540212efb302e6cbd7de536ed59..8cbe3ddbe8b5d967da19022632b1cdb294aaf0ea 100644 --- a/indra/newview/altoolalign.cpp +++ b/indra/newview/altoolalign.cpp @@ -68,17 +68,17 @@ void ALToolAlign::pickCallback(const LLPickInfo& pick_info) // If object not selected, select it if (!object->isSelected()) { - LLSelectMgr::getInstanceFast()->selectObjectAndFamily(object); + LLSelectMgr::getInstance()->selectObjectAndFamily(object); } else { - LLSelectMgr::getInstanceFast()->deselectObjectAndFamily(object); + LLSelectMgr::getInstance()->deselectObjectAndFamily(object); } } else { - LLSelectMgr::getInstanceFast()->deselectAll(); - LLSelectMgr::getInstanceFast()->selectObjectAndFamily(object); + LLSelectMgr::getInstance()->deselectAll(); + LLSelectMgr::getInstance()->selectObjectAndFamily(object); } } @@ -86,11 +86,11 @@ void ALToolAlign::pickCallback(const LLPickInfo& pick_info) { if (pick_info.mKeyMask != MASK_SHIFT) { - LLSelectMgr::getInstanceFast()->deselectAll(); + LLSelectMgr::getInstance()->deselectAll(); } } - LLSelectMgr::getInstanceFast()->promoteSelectionToRoot(); + LLSelectMgr::getInstance()->promoteSelectionToRoot(); } void ALToolAlign::handleSelect() @@ -98,7 +98,7 @@ void ALToolAlign::handleSelect() // no parts, please LL_DEBUGS("ALIGNTOOL") << "in select" << LL_ENDL; - LLSelectMgr::getInstanceFast()->promoteSelectionToRoot(); + LLSelectMgr::getInstance()->promoteSelectionToRoot(); } void ALToolAlign::handleDeselect() @@ -110,10 +110,10 @@ BOOL ALToolAlign::findSelectedManipulator(S32 x, S32 y) mHighlightedAxis = -1; mHighlightedDirection = 0; - LLViewerCamera* camera = LLViewerCamera::getInstanceFast(); + LLViewerCamera* camera = LLViewerCamera::getInstance(); LLMatrix4 transform; - if (LLSelectMgr::getInstanceFast()->getSelection()->getSelectType() == SELECT_TYPE_HUD) + if (LLSelectMgr::getInstance()->getSelection()->getSelectType() == SELECT_TYPE_HUD) { LLVector4 translation(mBBox.getCenterAgent()); transform.initRotTrans(mBBox.getRotation(), translation); @@ -231,7 +231,7 @@ void render_cone_bbox(LLBBox bbox) // should this be cached in the selection manager? yes. LLBBox get_selection_axis_aligned_bbox() { - auto& select_mgr = LLSelectMgr::instanceFast(); + auto& select_mgr = LLSelectMgr::instance(); LLBBox selection_bbox = select_mgr.getBBoxOfSelection(); LLVector3 position = selection_bbox.getPositionAgent(); @@ -259,7 +259,7 @@ void ALToolAlign::computeManipulatorSize() { LLViewerCamera* camera = LLViewerCamera::getInstance(); - if (LLSelectMgr::getInstanceFast()->getSelection()->getSelectType() == SELECT_TYPE_HUD) + if (LLSelectMgr::getInstance()->getSelection()->getSelectType() == SELECT_TYPE_HUD) { mManipulatorSize = MANIPULATOR_SIZE / (camera->getViewHeightInPixels() * gAgentCamera.mHUDCurZoom); @@ -348,7 +348,7 @@ BOOL ALToolAlign::canAffectSelection() // and it does not have any sitting agents. In case of editing linked parts, // the object itself has to be modifiable. static LLCachedControl<bool> edit_linked_parts(gSavedSettings, "EditLinkedParts"); - BOOL can_scale = LLSelectMgr::getInstanceFast()->getSelection()->getObjectCount() != 0; + BOOL can_scale = LLSelectMgr::getInstance()->getSelection()->getObjectCount() != 0; if (can_scale) { struct f : public LLSelectedObjectFunctor @@ -358,7 +358,7 @@ BOOL ALToolAlign::canAffectSelection() return (!edit_linked_parts || objectp->permModify()) && objectp->permMove() && !objectp->isSeat(); } } func; - can_scale = LLSelectMgr::getInstanceFast()->getSelection()->applyToObjects(&func); + can_scale = LLSelectMgr::getInstance()->getSelection()->applyToObjects(&func); } return can_scale; } @@ -423,7 +423,7 @@ class BBoxCompare void ALToolAlign::align() { // no linkset parts, please - auto& select_mgr = LLSelectMgr::instanceFast(); + auto& select_mgr = LLSelectMgr::instance(); select_mgr.promoteSelectionToRoot(); std::vector<LLPointer<LLViewerObject> > objects; diff --git a/indra/newview/alviewermenu.cpp b/indra/newview/alviewermenu.cpp index 005fd7ed45319db5322a2065b83df563130d75d3..321aca0d772e930e14578635a81fe08fac07daf0 100644 --- a/indra/newview/alviewermenu.cpp +++ b/indra/newview/alviewermenu.cpp @@ -51,7 +51,7 @@ namespace { bool enable_edit_particle_source() { - LLObjectSelectionHandle selection = LLSelectMgr::getInstanceFast()->getSelection(); + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); for (LLObjectSelection::valid_root_iterator iter = selection->valid_root_begin(); iter != selection->valid_root_end(); ++iter) { @@ -66,7 +66,7 @@ namespace void edit_particle_source() { - LLViewerObject* objectp = LLSelectMgr::getInstanceFast()->getSelection()->getPrimaryObject(); + LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); if (objectp) { ALFloaterParticleEditor* particleEditor = LLFloaterReg::showTypedInstance<ALFloaterParticleEditor>("particle_editor", LLSD(objectp->getID()), TAKE_FOCUS_YES); @@ -102,7 +102,7 @@ namespace void avatar_copy_data(const LLSD& userdata) { - LLViewerObject* objectp = LLSelectMgr::getInstanceFast()->getSelection()->getPrimaryObject(); + LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); if (!objectp) return; @@ -143,7 +143,7 @@ namespace void object_copy_key() { - LLViewerObject* objectp = LLSelectMgr::getInstanceFast()->getSelection()->getPrimaryObject(); + LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); if (!objectp) return; @@ -154,7 +154,7 @@ namespace bool can_teleport_to() { - LLVOAvatar* avatarp = find_avatar_from_object(LLSelectMgr::getInstanceFast()->getSelection()->getPrimaryObject()); + LLVOAvatar* avatarp = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()); if (avatarp) { return ALAvatarActions::canTeleportTo(avatarp->getID()); @@ -164,7 +164,7 @@ namespace void teleport_to() { - LLVOAvatar* avatarp = find_avatar_from_object(LLSelectMgr::getInstanceFast()->getSelection()->getPrimaryObject()); + LLVOAvatar* avatarp = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()); if (avatarp) { ALAvatarActions::teleportTo(avatarp->getID()); @@ -173,7 +173,7 @@ namespace bool can_manage_avatar_estate() { - LLVOAvatar* avatarp = find_avatar_from_object(LLSelectMgr::getInstanceFast()->getSelection()->getPrimaryObject()); + LLVOAvatar* avatarp = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()); if (avatarp) { return ALAvatarActions::canManageAvatarsEstate(avatarp->getID()); @@ -183,7 +183,7 @@ namespace void manage_estate(const LLSD& param) { - LLVOAvatar* avatarp = find_avatar_from_object(LLSelectMgr::getInstanceFast()->getSelection()->getPrimaryObject()); + LLVOAvatar* avatarp = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()); if (avatarp) { S32 action = param.asInteger(); @@ -237,7 +237,7 @@ namespace bool is_powerful_wizard_object() { - LLViewerObject* objpos = LLSelectMgr::getInstanceFast()->getSelection()->getFirstRootObject(); + LLViewerObject* objpos = LLSelectMgr::getInstance()->getSelection()->getFirstRootObject(); if (objpos) { if (objpos->permYouOwner() && gSavedSettings.getBOOL("AlchemyPowerfulWizard")) @@ -249,7 +249,7 @@ namespace void object_explode() { - LLViewerObject* objpos = LLSelectMgr::getInstanceFast()->getSelection()->getFirstRootObject(); + LLViewerObject* objpos = LLSelectMgr::getInstance()->getSelection()->getFirstRootObject(); if (objpos) { if (!objpos->permYouOwner()) @@ -263,16 +263,16 @@ namespace /* NOTE: oh god how did this get here */ - LLSelectMgr::getInstanceFast()->selectionUpdateTemporary(1);//set temp to TRUE - LLSelectMgr::getInstanceFast()->selectionUpdatePhysics(1); - LLSelectMgr::getInstanceFast()->sendDelink(); - LLSelectMgr::getInstanceFast()->deselectAll(); + LLSelectMgr::getInstance()->selectionUpdateTemporary(1);//set temp to TRUE + LLSelectMgr::getInstance()->selectionUpdatePhysics(1); + LLSelectMgr::getInstance()->sendDelink(); + LLSelectMgr::getInstance()->deselectAll(); } } void object_destroy() { - LLViewerObject* objpos = LLSelectMgr::getInstanceFast()->getSelection()->getFirstRootObject(); + LLViewerObject* objpos = LLSelectMgr::getInstance()->getSelection()->getFirstRootObject(); if (objpos) { if (!objpos->permYouOwner()) @@ -289,17 +289,17 @@ namespace So we do selectionUpdateTemporary(1) */ - LLSelectMgr::getInstanceFast()->selectionUpdateTemporary(1);//set temp to TRUE + LLSelectMgr::getInstance()->selectionUpdateTemporary(1);//set temp to TRUE LLVector3 pos = objpos->getPosition();//get the x and the y pos.mV[VZ] = FLT_MAX;//create the z objpos->setPositionParent(pos);//set the x y z - LLSelectMgr::getInstanceFast()->sendMultipleUpdate(UPD_POSITION);//send the data + LLSelectMgr::getInstance()->sendMultipleUpdate(UPD_POSITION);//send the data } } void object_force_delete() { - LLViewerObject* objpos = LLSelectMgr::getInstanceFast()->getSelection()->getFirstRootObject(); + LLViewerObject* objpos = LLSelectMgr::getInstance()->getSelection()->getFirstRootObject(); if (objpos) { if (!objpos->permYouOwner()) @@ -307,7 +307,7 @@ namespace LLNotificationsUtil::add("AlchemyUnpoweredWizard", LLSD()); return; } - LLSelectMgr::getInstanceFast()->selectForceDelete(); + LLSelectMgr::getInstance()->selectForceDelete(); } } diff --git a/indra/newview/app_settings/cmd_line.xml b/indra/newview/app_settings/cmd_line.xml index 3100baf9430dbb00b61ddd6f8bc4cdf84de3535c..e16a5c7e76014ece4bdc11a137a51c10aa9803e8 100644 --- a/indra/newview/app_settings/cmd_line.xml +++ b/indra/newview/app_settings/cmd_line.xml @@ -55,7 +55,7 @@ <key>debugsession</key> <map> <key>desc</key> - <string>Run as if RenderDebugGL is TRUE, but log errors until end of session.</string> + <string>Run as if RenderDebugGLSession is TRUE, but log errors until end of session.</string> <key>map-to</key> <string>DebugSession</string> </map> @@ -209,6 +209,14 @@ <string>NoAudio</string> </map> + <key>noninteractive</key> + <map> + <key>desc</key> + <string>Run in semi-headless mode where only login and logout need to work.</string> + <key>map-to</key> + <string>NonInteractive</string> + </map> + <key>nonotifications</key> <map> <key>desc</key> diff --git a/indra/newview/app_settings/high_graphics.xml b/indra/newview/app_settings/high_graphics.xml index 662f7e39dd1739742cb25140eee1f3e5fac53210..f64937f4437388bd470e1431aa7f079d7b0af4a6 100644 --- a/indra/newview/app_settings/high_graphics.xml +++ b/indra/newview/app_settings/high_graphics.xml @@ -6,8 +6,6 @@ <RenderAvatarLODFactor value="1.0"/> <!--Default for now--> <RenderAvatarPhysicsLODFactor value="0.9"/> - <!--NO SHADERS--> - <RenderAvatarVP value="TRUE"/> <!--Short Range--> <RenderFarClip value="128"/> <!--Default for now--> diff --git a/indra/newview/app_settings/key_bindings.xml b/indra/newview/app_settings/key_bindings.xml index 3ff9762767bc577f5418680a205f1d1b7e2dc2ca..4a1abff711e9f667b2f265103ff4ad1341a8e6ae 100644 --- a/indra/newview/app_settings/key_bindings.xml +++ b/indra/newview/app_settings/key_bindings.xml @@ -87,7 +87,6 @@ <binding key="DOWN" mask="CTL_ALT_SHIFT" command="pan_down"/> <binding key="" mask="NONE" mouse="MMB" command="toggle_voice"/> - <binding key="" mask="NONE" mouse="LMB" command="walk_to"/> <binding key="" mask="NONE" mouse="LMB" command="script_trigger_lbutton"/> </third_person> diff --git a/indra/newview/app_settings/low_graphics.xml b/indra/newview/app_settings/low_graphics.xml index 0ee8e7a05988a3ed78101e7f064c27b1253c1a53..b31a040d67e9e0b6be2a12d78955600451d03ffb 100644 --- a/indra/newview/app_settings/low_graphics.xml +++ b/indra/newview/app_settings/low_graphics.xml @@ -6,8 +6,6 @@ <RenderAvatarLODFactor value="0.5"/> <!--Default for now--> <RenderAvatarPhysicsLODFactor value="0.0"/> - <!--NO SHADERS--> - <RenderAvatarVP value="FALSE"/> <!--Short Range--> <RenderFarClip value="64"/> <!--Default for now--> diff --git a/indra/newview/app_settings/mid_graphics.xml b/indra/newview/app_settings/mid_graphics.xml index c89e060307a72a0777b8a863fd5f3ac1570d374f..9c2c17fc6081ddf36a0cc9c4c9e3e17ebececf05 100644 --- a/indra/newview/app_settings/mid_graphics.xml +++ b/indra/newview/app_settings/mid_graphics.xml @@ -6,8 +6,6 @@ <RenderAvatarLODFactor value="0.5"/> <!--Default for now--> <RenderAvatarPhysicsLODFactor value="0.75"/> - <!--NO SHADERS--> - <RenderAvatarVP value="TRUE"/> <!--Short Range--> <RenderFarClip value="96"/> <!--Default for now--> diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 54e493edcee02a959e6b7e7cb735f992d4d0c804..70bc2529bb9b49e7b4b978dff46b524e04cdbc0a 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -867,17 +867,6 @@ <key>Value</key> <integer>1</integer> </map> - <key>AvalinePhoneSeparator</key> - <map> - <key>Comment</key> - <string>Separator of phone parts to have Avaline numbers human readable in Voice Control Panel</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>String</string> - <key>Value</key> - <string>-</string> - </map> <key>AvatarAxisDeadZone0</key> <map> <key>Comment</key> @@ -1135,17 +1124,6 @@ <key>Value</key> <integer>0</integer> </map> - <key>FramePerSecondLimit</key> - <map> - <key>Comment</key> - <string>Controls upper limit of frames per second</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>U32</string> - <key>Value</key> - <integer>120</integer> - </map> <key>BackgroundYieldTime</key> <map> <key>Comment</key> @@ -1716,7 +1694,7 @@ <key>Type</key> <string>F32</string> <key>Value</key> - <real>20.0</real> + <real>40.0</real> </map> <key>DiskCacheDirName</key> <map> @@ -3776,10 +3754,10 @@ <key>Value</key> <integer>0</integer> </map> - <key>DisableVerticalSync</key> + <key>RenderVSyncEnable</key> <map> <key>Comment</key> - <string>Update frames as fast as possible (FALSE = update frames between display scans)</string> + <string>Update frames between display scans (FALSE = Update frames as fast as possible).</string> <key>Persist</key> <integer>1</integer> <key>Type</key> @@ -3952,7 +3930,7 @@ <key>Value</key> <integer>0</integer> </map> - <key>DoubleClickTeleport</key> + <key>DoubleClickTeleport</key> <map> <key>Comment</key> <string>Enable double-click to teleport where allowed (afects minimap and people panel)</string> @@ -4225,7 +4203,7 @@ <key>Type</key> <string>String</string> <key>Value</key> - <string>http://events.secondlife.com/viewer/embed/event/</string> + <string>http://events.[GRID]/viewer/embed/event/[EVENT_ID]</string> </map> <key>FastCacheFetchEnabled</key> <map> @@ -4282,6 +4260,17 @@ <key>Value</key> <integer>1</integer> </map> + <key>MainWorkTime</key> + <map> + <key>Comment</key> + <string>Max time per frame devoted to mainloop work queue (in milliseconds)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>0.1</real> + </map> <key>QueueInventoryFetchTimeout</key> <map> <key>Comment</key> @@ -5136,7 +5125,7 @@ <key>Type</key> <string>String</string> <key>Value</key> - <string>https://search.[GRID]/viewer/[CATEGORY]/?q=[QUERY]&r=[MATURITY]&lang=[LANGUAGE]&g=[GODLIKE]&sid=[SESSION_ID]&rid=[REGION_ID]&pid=[PARCEL_ID]&channel=[CHANNEL]&version=[VERSION]&major=[VERSION_MAJOR]&minor=[VERSION_MINOR]&patch=[VERSION_PATCH]&build=[VERSION_BUILD]</string> + <string>https://search.[GRID]/?query_term=[QUERY]&search_type=[TYPE][COLLECTION]&maturity=[MATURITY]&lang=[LANGUAGE]&g=[GODLIKE]&sid=[SESSION_ID]&rid=[REGION_ID]&pid=[PARCEL_ID]&channel=[CHANNEL]&version=[VERSION]&major=[VERSION_MAJOR]&minor=[VERSION_MINOR]&patch=[VERSION_PATCH]&build=[VERSION_BUILD]</string> </map> <key>GuidebookURL</key> <map> @@ -6184,6 +6173,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>DiskCacheVersion</key> + <map> + <key>Comment</key> + <string>Version number of disk cache</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>0</integer> + </map> <key>LocalFileSystemBrowsingEnabled</key> <map> <key>Comment</key> @@ -6848,7 +6848,7 @@ <key>MaxHeapSize</key> <map> <key>Comment</key> - <string>Maximum heap size (GB)</string> + <string>Maximum heap size on 32-bit builds (GB)</string> <key>Persist</key> <integer>1</integer> <key>Type</key> @@ -6856,6 +6856,17 @@ <key>Value</key> <real>1.6</real> </map> + <key>MaxHeapSize64</key> + <map> + <key>Comment</key> + <string>Maximum heap size on 64-bit builds (GB)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>16.0</real> + </map> <key>MaxPersistentNotifications</key> <map> <key>Comment</key> @@ -7219,6 +7230,9 @@ <key>Type</key> <string>Boolean</string> <key>Value</key> + <!-- *HACK: On first run, set this to 0 for new users, + otherwise the default is 1 to maintain consistent experience + for existing users. Hardcoded in llnetmap.cpp --> <integer>1</integer> </map> <key>MiniMapScale</key> @@ -7232,6 +7246,17 @@ <key>Value</key> <real>128.0</real> </map> + <key>MiniMapShowPropertyLines</key> + <map> + <key>Comment</key> + <string>Whether or not to show parcel borders on the MiniMap.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <real>1</real> + </map> <key>MouseSensitivity</key> <map> <key>Comment</key> @@ -7496,16 +7521,27 @@ <key>Value</key> <integer>0</integer> </map> + <key>NonInteractive</key> + <map> + <key>Comment</key> + <string>Run in a semi-headless mode where only logging in and logging out needs to work.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>NonvisibleObjectsInMemoryTime</key> <map> <key>Comment</key> - <string>Number of frames non-visible objects stay in memory before being removed. 0 means never to remove.</string> + <string>Number of frames non-visible objects stay in memory before being removed. 0 means max.</string> <key>Persist</key> <integer>1</integer> <key>Type</key> <string>U32</string> <key>Value</key> - <integer>300</integer> + <integer>64</integer> </map> <key>NoPreload</key> <map> @@ -8521,9 +8557,9 @@ <string>Color4</string> <key>Value</key> <array> - <real>1.0</real> - <real>1.0</real> - <real>1.0</real> + <real>0.33</real> + <real>0.33</real> + <real>0.33</real> <real>1.0</real> </array> </map> @@ -9046,6 +9082,17 @@ <key>Value</key> <integer>1</integer> </map> + <key>UpdateRememberPasswordSetting</key> + <map> + <key>Comment</key> + <string>Save 'rememeber password' setting for current user.</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>OctreeMaxNodeCapacity</key> <map> <key>Comment</key> @@ -9126,28 +9173,6 @@ </array> </map> - <key>RenderAlphaBatchFullbrights</key> - <map> - <key>Comment</key> - <string>Render fullbright alpha content more efficiently, but with possible visual differences from prev viewers.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>0</integer> - </map> - <key>RenderAlphaBatchEmissives</key> - <map> - <key>Comment</key> - <string>Render emissive alpha content more efficiently, but with possible visual differences from prev viewers.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> <key>RenderAnisotropic</key> <map> <key>Comment</key> @@ -9339,17 +9364,6 @@ <key>Value</key> <real>1.0</real> </map> - <key>RenderAvatarVP</key> - <map> - <key>Comment</key> - <string>Use vertex programs to perform hardware skinning of avatar</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> <key>RenderCompressTextures</key> <map> <key>Comment</key> @@ -9361,7 +9375,7 @@ <key>Value</key> <integer>0</integer> </map> - <key>RenderHiDPI</key> + <key>RenderHiDPI</key> <map> <key>Comment</key> <string>Enable support for HiDPI displays, like Retina (MacOS X ONLY, requires restart)</string> @@ -9596,10 +9610,10 @@ <key>Value</key> <real>0.5</real> </map> - <key>RenderDebugGL</key> + <key>RenderDebugGLSession</key> <map> <key>Comment</key> - <string>Enable strict GL debugging.</string> + <string>Enable strict GL debugging on the start of next session.</string> <key>Persist</key> <integer>1</integer> <key>Type</key> @@ -10319,7 +10333,7 @@ <key>Value</key> <real>2.2</real> </map> - <key>RenderGLCoreProfile</key> + <key>RenderGLContextCoreProfile</key> <map> <key>Comment</key> <string>Don't use a compatibility profile OpenGL context. Requires restart. Basic shaders MUST be enabled.</string> @@ -10330,6 +10344,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>RenderGLMultiThreaded</key> + <map> + <key>Comment</key> + <string>Allow OpenGL to use multiple render contexts (reduces frame stutters from loading textures, doesn't play nice with Intel drivers).</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>RenderGlow</key> <map> <key>Comment</key> @@ -11455,7 +11480,7 @@ <key>Type</key> <string>U32</string> <key>Value</key> - <integer>1024</integer> + <integer>2048</integer> </map> <key>SceneLoadLowMemoryBound</key> <map> @@ -12083,7 +12108,7 @@ <string>Boolean</string> <key>Value</key> <integer>0</integer> - </map> + </map> <key>NearbyListShowMap</key> <map> <key>Comment</key> @@ -13199,6 +13224,20 @@ <key>Value</key> <string /> </map> + <key>ThreadPoolSizes</key> + <map> + <key>Comment</key> + <string>Map of size overrides for specific thread pools.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>LLSD</string> + <key>Value</key> + <map> + <key>General</key> + <integer>4</integer> + </map> + </map> <key>ThrottleBandwidthKBPS</key> <map> <key>Comment</key> @@ -14640,17 +14679,6 @@ <string>Boolean</string> <key>Value</key> <integer>1</integer> - </map> - <key>RenderSynchronousOcclusion</key> - <map> - <key>Comment</key> - <string>Don't let occlusion queries get more than one frame behind (block until they complete).</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> </map> <key>RenderDelayVBUpdate</key> <map> @@ -16187,6 +16215,17 @@ <string>Boolean</string> <key>Value</key> <integer>1</integer> + </map> + <key>AllowSelectAvatar</key> + <map> + <key>Comment</key> + <string>Allows user to select and move avatars, move is viewer sided, does not propagate to server, also supresses avatar position updates while avatars are selected</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> </map> <key>WebProfileFloaterRect</key> <map> @@ -17212,8 +17251,8 @@ <key>Type</key> <string>Boolean</string> <key>Value</key> - <integer>1</integer> - </map> + <integer>1</integer> + </map> <key>360CaptureUseInterestListCap</key> <map> <key>Comment</key> @@ -17291,6 +17330,17 @@ <key>Value</key> <integer>3</integer> </map> + <key>UpdateAppWindowTitleBar</key> + <map> + <key>Comment</key> + <string>Updates the application window title bar with brief information about user/location</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>MFAHash</key> <map> <key>Comment</key> diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl index 4457356e38610d0e1c152c8c16d472406f796b30..e0282cbf8acc0e8ec5a3a25ccc1def594fbb4c8a 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl @@ -56,6 +56,10 @@ VARYING vec3 vary_norm; VARYING vec4 vertex_color; //vertex color should be treated as sRGB #endif +#ifdef HAS_ALPHA_MASK +uniform float minimum_alpha; +#endif + uniform mat4 proj_mat; uniform mat4 inv_proj; uniform vec2 screen_res; @@ -86,6 +90,14 @@ float getAmbientClamp(); vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 diffuse, vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight, float ambiance) { + // SL-14895 inverted attenuation work-around + // This routine is tweaked to match deferred lighting, but previously used an inverted la value. To reconstruct + // that previous value now that the inversion is corrected, we reverse the calculations in LLPipeline::setupHWLights() + // to recover the `adjusted_radius` value previously being sent as la. + float falloff_factor = (12.0 * fa) - 9.0; + float inverted_la = falloff_factor / la; + // Yes, it makes me want to cry as well. DJH + vec3 col = vec3(0); //get light vector @@ -95,7 +107,7 @@ vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 diffuse, vec3 v, vec3 n, vec float dist = length(lv); float da = 1.0; - /*if (dist > la) + /*if (dist > inverted_la) { return col; } @@ -113,9 +125,9 @@ vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 diffuse, vec3 v, vec3 n, vec return col; }*/ - if (dist > 0.0 && la > 0.0) + if (dist > 0.0 && inverted_la > 0.0) { - dist /= la; + dist /= inverted_la; //normalize light vector lv = normalize(lv); @@ -187,6 +199,11 @@ void main() #ifdef USE_VERTEX_COLOR final_alpha *= vertex_color.a; + if (final_alpha < minimum_alpha) + { // TODO: figure out how to get invisible faces out of + // render batches without breaking glow + discard; + } diffuse_srgb.rgb *= vertex_color.rgb; #endif @@ -197,7 +214,7 @@ void main() // Insure we don't pollute depth with invis pixels in impostor rendering // - if (final_alpha < 0.01) + if (final_alpha < minimum_alpha) { discard; } @@ -229,11 +246,11 @@ void main() #if !defined(AMBIENT_KILL) color.rgb = amblit; color.rgb *= ambient; -#endif +#endif // !defined(AMBIENT_KILL) #if !defined(SUNLIGHT_KILL) color.rgb += sun_contrib; -#endif +#endif // !defined(SUNLIGHT_KILL) color.rgb *= diffuse_srgb.rgb; @@ -259,7 +276,7 @@ void main() // sum local light contrib in linear colorspace #if !defined(LOCAL_LIGHT_KILL) color.rgb += light.rgb; -#endif +#endif // !defined(LOCAL_LIGHT_KILL) #ifdef WATER_FOG color.rgb = linear_to_srgb(color.rgb); diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl index 506118d381deb83ef7db62fc92acf6586016c751..6a93bc2fd2577cddc3cb02e5b6624a4718b7f514 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl @@ -105,9 +105,9 @@ void main() vec4 vert = vec4(position.xyz, 1.0); pos = (modelview_matrix * vert); gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0); -#endif +#endif //IS_AVATAR_SKIN -#endif +#endif // HAS_SKIN #ifdef USE_INDEXED_TEX passTextureIndex(); diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl index ef49b6f4e826bafdd0daf3a14bf8655ec62ec19d..1b16e4eb09e9d3a930aa7218d41f10e4bc135e04 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl @@ -40,11 +40,11 @@ VARYING vec4 post_pos; VARYING float pos_w; VARYING float target_pos_x; VARYING vec2 vary_texcoord0; -VARYING vec4 vertex_color; +uniform vec4 color; void main() { - float alpha = texture2D(diffuseMap, vary_texcoord0.xy).a * vertex_color.a; + float alpha = texture2D(diffuseMap, vary_texcoord0.xy).a * color.a; if (alpha < 0.05) // treat as totally transparent { diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl index d1d7ece6febb89a622fabc6845eae0c067bbe862..1c5b142ebd10b30f72e52c54c0ccc8cff5b503d1 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl @@ -30,7 +30,6 @@ uniform float shadow_target_width; mat4 getSkinnedTransform(); void passTextureIndex(); -ATTRIBUTE vec4 diffuse_color; ATTRIBUTE vec3 position; ATTRIBUTE vec3 normal; ATTRIBUTE vec2 texcoord0; @@ -41,7 +40,6 @@ VARYING vec4 post_pos; VARYING float pos_w; VARYING float target_pos_x; VARYING vec2 vary_texcoord0; -VARYING vec4 vertex_color; void main() { @@ -68,7 +66,6 @@ void main() vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; - vertex_color = diffuse_color; #if !DEPTH_CLAMP post_pos = pos; diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl deleted file mode 100644 index 10144f3e1612621f2f56f4d6fc3dab5f7853d501..0000000000000000000000000000000000000000 --- a/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl +++ /dev/null @@ -1,64 +0,0 @@ -/** - * @file bumpV.glsl - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2007, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -uniform mat4 projection_matrix; -uniform mat4 texture_matrix0; -uniform mat4 modelview_matrix; - -ATTRIBUTE vec3 position; -ATTRIBUTE vec4 diffuse_color; -ATTRIBUTE vec3 normal; -ATTRIBUTE vec2 texcoord0; -ATTRIBUTE vec4 tangent; - -VARYING vec3 vary_mat0; -VARYING vec3 vary_mat1; -VARYING vec3 vary_mat2; -VARYING vec4 vertex_color; -VARYING vec2 vary_texcoord0; - -mat4 getObjectSkinnedTransform(); - -void main() -{ - vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; - - mat4 mat = getObjectSkinnedTransform(); - - mat = modelview_matrix * mat; - - vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz; - - - vec3 n = normalize((mat * vec4(normal.xyz+position.xyz, 1.0)).xyz-pos.xyz); - vec3 t = normalize((mat * vec4(tangent.xyz+position.xyz, 1.0)).xyz-pos.xyz); - vec3 b = cross(n, t) * tangent.w; - - vary_mat0 = vec3(t.x, b.x, n.x); - vary_mat1 = vec3(t.y, b.y, n.y); - vary_mat2 = vec3(t.z, b.z, n.z); - - gl_Position = projection_matrix*vec4(pos, 1.0); - vertex_color = diffuse_color; -} diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl index 9f9749394e023beaf336ff30a9bcf93b9c2203bb..d90891aa208dfbbad9ad59eb177487cacc3de316 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl @@ -39,16 +39,32 @@ VARYING vec3 vary_mat2; VARYING vec4 vertex_color; VARYING vec2 vary_texcoord0; +#ifdef HAS_SKIN +mat4 getObjectSkinnedTransform(); +uniform mat4 projection_matrix; +uniform mat4 modelview_matrix; +#endif + void main() { //transform vertex +#ifdef HAS_SKIN + mat4 mat = getObjectSkinnedTransform(); + mat = modelview_matrix * mat; + vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz; + gl_Position = projection_matrix*vec4(pos, 1.0); + + vec3 n = normalize((mat * vec4(normal.xyz+position.xyz, 1.0)).xyz-pos.xyz); + vec3 t = normalize((mat * vec4(tangent.xyz+position.xyz, 1.0)).xyz-pos.xyz); +#else gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); - vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; - vec3 n = normalize(normal_matrix * normal); vec3 t = normalize(normal_matrix * tangent.xyz); +#endif + vec3 b = cross(n, t) * tangent.w; - + vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; + vary_mat0 = vec3(t.x, b.x, n.x); vary_mat1 = vec3(t.y, b.y, n.y); vary_mat2 = vec3(t.z, b.z, n.z); diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl index 3c026796c8b3a7fdd9e8df4076dfbc3561c12218..d64bcefade713da5d18cab55311371f346afea88 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl @@ -39,14 +39,28 @@ VARYING vec2 vary_texcoord0; void passTextureIndex(); +#ifdef HAS_SKIN +mat4 getObjectSkinnedTransform(); +uniform mat4 projection_matrix; +uniform mat4 modelview_matrix; +#endif + void main() { - //transform vertex +#ifdef HAS_SKIN + mat4 mat = getObjectSkinnedTransform(); + mat = modelview_matrix * mat; + vec4 pos = mat * vec4(position.xyz, 1.0); + gl_Position = projection_matrix * pos; + vary_normal = normalize((mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz); +#else gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); + vary_normal = normalize(normal_matrix * normal); +#endif + vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; passTextureIndex(); - vary_normal = normalize(normal_matrix * normal); - + vertex_color = diffuse_color; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/emissiveV.glsl b/indra/newview/app_settings/shaders/class1/deferred/emissiveV.glsl index 5e4f08b0174b4e3b7aa650f7e2a4a1c693e5dfc0..08b1147ab0b1a63f19dfdeacdbb96b7023b99889 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/emissiveV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/emissiveV.glsl @@ -40,15 +40,26 @@ vec3 atmosAffectDirectionalLight(float lightIntensity); VARYING vec4 vertex_color; VARYING vec2 vary_texcoord0; +#ifdef HAS_SKIN +mat4 getObjectSkinnedTransform(); +uniform mat4 projection_matrix; +#endif void main() { //transform vertex - vec4 vert = vec4(position.xyz, 1.0); - vec4 pos = (modelview_matrix * vert); passTextureIndex(); - gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0); +#ifdef HAS_SKIN + mat4 mat = getObjectSkinnedTransform(); + mat = modelview_matrix * mat; + + vec4 pos = mat * vec4(position.xyz, 1.0); + gl_Position = projection_matrix * pos; +#else + gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); + vec4 pos = (modelview_matrix * vec4(position.xyz, 1.0)); +#endif vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl index 0b668286c0073ecda7eb5c12a8e11005ce506924..a922fa5c467b8917c254861ab52403a71613f60f 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl @@ -43,19 +43,32 @@ VARYING vec2 vary_texcoord0; VARYING vec3 vary_texcoord1; VARYING vec4 vary_position; +#ifdef HAS_SKIN +mat4 getObjectSkinnedTransform(); +uniform mat4 projection_matrix; +#endif + void main() { //transform vertex vec4 vert = vec4(position.xyz,1.0); passTextureIndex(); + +#ifdef HAS_SKIN + mat4 mat = getObjectSkinnedTransform(); + mat = modelview_matrix * mat; + vec4 pos = mat * vert; + vary_position = gl_Position = projection_matrix * pos; + vec3 norm = normalize((mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz); +#else vec4 pos = (modelview_matrix * vert); vary_position = gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0); - vec3 norm = normalize(normal_matrix * normal); +#endif vec3 ref = reflect(pos.xyz, -norm); vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; - vary_texcoord1 = (texture_matrix1*vec4(ref,1.0)).xyz; + vary_texcoord1 = (texture_matrix1 * vec4(ref,1.0)).xyz; calcAtmospherics(pos.xyz); diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl index bdf3546aa5f7b5c052af16032593115f56ce6cba..e71636f2c9ec444b0772b903222e94f9dc6615eb 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl @@ -45,15 +45,26 @@ VARYING vec3 vary_position; VARYING vec4 vertex_color; VARYING vec2 vary_texcoord0; +#ifdef HAS_SKIN +mat4 getObjectSkinnedTransform(); +uniform mat4 projection_matrix; +#endif void main() { //transform vertex vec4 vert = vec4(position.xyz, 1.0); - vec4 pos = (modelview_matrix * vert); passTextureIndex(); +#ifdef HAS_SKIN + mat4 mat = getObjectSkinnedTransform(); + mat = modelview_matrix * mat; + vec4 pos = mat * vert; + gl_Position = projection_matrix * pos; +#else + vec4 pos = (modelview_matrix * vert); gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0); +#endif #ifdef WATER_FOG vary_position = pos.xyz; diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl index 9f9a1a3567c94c54b726a0dcfb0dfa0903349b3c..9085a491a57ce80df5defccb245b250f64df94e4 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl @@ -92,6 +92,14 @@ float getAmbientClamp(); vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 npos, vec3 diffuse, vec4 spec, vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight, inout float glare, float ambiance) { + // SL-14895 inverted attenuation work-around + // This routine is tweaked to match deferred lighting, but previously used an inverted la value. To reconstruct + // that previous value now that the inversion is corrected, we reverse the calculations in LLPipeline::setupHWLights() + // to recover the `adjusted_radius` value previously being sent as la. + float falloff_factor = (12.0 * fa) - 9.0; + float inverted_la = falloff_factor / la; + // Yes, it makes me want to cry as well. DJH + vec3 col = vec3(0); //get light vector @@ -101,9 +109,9 @@ vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 npos, vec3 diffuse, vec4 spe float dist = length(lv); float da = 1.0; - dist /= la; + dist /= inverted_la; - if (dist > 0.0 && la > 0.0) + if (dist > 0.0 && inverted_la > 0.0) { //normalize light vector lv = normalize(lv); @@ -195,7 +203,7 @@ VARYING vec2 vary_texcoord2; uniform float env_intensity; uniform vec4 specular_color; // specular color RGB and specular exponent (glossiness) in alpha -#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK) +#ifdef HAS_ALPHA_MASK uniform float minimum_alpha; #endif @@ -220,11 +228,12 @@ void main() vec4 diffcol = texture2D(diffuseMap, vary_texcoord0.xy); diffcol.rgb *= vertex_color.rgb; -#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK) - - // Comparing floats cast from 8-bit values, produces acne right at the 8-bit transition points - float bias = 0.001953125; // 1/512, or half an 8-bit quantization - if (diffcol.a < minimum_alpha-bias) +#ifdef HAS_ALPHA_MASK +#if DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND + if (diffcol.a*vertex_color.a < minimum_alpha) +#else + if (diffcol.a < minimum_alpha) +#endif { discard; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/normgenF.glsl b/indra/newview/app_settings/shaders/class1/deferred/normgenF.glsl index d0c06cd51f6e7a9341742e346ccb341afa7a239d..7a941674b87363f6ceeb7dc635cab45e55b37aa7 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/normgenF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/normgenF.glsl @@ -43,18 +43,18 @@ uniform float norm_scale; void main() { - float alpha = texture2D(alphaMap, vary_texcoord0).a; + float c = texture2D(alphaMap, vary_texcoord0).r; - vec3 right = vec3(norm_scale, 0, (texture2D(alphaMap, vary_texcoord0+vec2(stepX, 0)).a-alpha)*255); - vec3 left = vec3(-norm_scale, 0, (texture2D(alphaMap, vary_texcoord0-vec2(stepX, 0)).a-alpha)*255); - vec3 up = vec3(0, -norm_scale, (texture2D(alphaMap, vary_texcoord0-vec2(0, stepY)).a-alpha)*255); - vec3 down = vec3(0, norm_scale, (texture2D(alphaMap, vary_texcoord0+vec2(0, stepY)).a-alpha)*255); + vec3 right = vec3(norm_scale, 0, (texture2D(alphaMap, vary_texcoord0+vec2(stepX, 0)).r-c)*255); + vec3 left = vec3(-norm_scale, 0, (texture2D(alphaMap, vary_texcoord0-vec2(stepX, 0)).r-c)*255); + vec3 up = vec3(0, -norm_scale, (texture2D(alphaMap, vary_texcoord0-vec2(0, stepY)).r-c)*255); + vec3 down = vec3(0, norm_scale, (texture2D(alphaMap, vary_texcoord0+vec2(0, stepY)).r-c)*255); vec3 norm = cross(right, down) + cross(down, left) + cross(left,up) + cross(up, right); norm = normalize(norm); norm *= 0.5; norm += 0.5; - - frag_color = vec4(norm, alpha); + + frag_color = vec4(norm, c); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskSkinnedV.glsl similarity index 69% rename from indra/newview/app_settings/shaders/class1/deferred/diffuseSkinnedV.glsl rename to indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskSkinnedV.glsl index 24871106242a9e334dfc470a4968e9ca21fe857e..2b17aea75a80f338b10400a42f3b553f14e1e7a7 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseSkinnedV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskSkinnedV.glsl @@ -1,8 +1,9 @@ /** - * @file diffuseSkinnedV.glsl - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * @file shadowAlphaMaskSkinnedV.glsl + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2007, Linden Research, Inc. + * Copyright (C) 2011, 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 @@ -22,38 +23,48 @@ * $/LicenseInfo$ */ -uniform mat4 projection_matrix; uniform mat4 texture_matrix0; uniform mat4 modelview_matrix; +uniform mat4 projection_matrix; +uniform float shadow_target_width; ATTRIBUTE vec3 position; ATTRIBUTE vec4 diffuse_color; -ATTRIBUTE vec3 normal; ATTRIBUTE vec2 texcoord0; -VARYING vec3 vary_normal; +VARYING vec4 post_pos; +VARYING float target_pos_x; VARYING vec4 vertex_color; VARYING vec2 vary_texcoord0; +void passTextureIndex(); + mat4 getObjectSkinnedTransform(); void main() { - vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; - + //transform vertex + vec4 pre_pos = vec4(position.xyz, 1.0); + mat4 mat = getObjectSkinnedTransform(); mat = modelview_matrix * mat; - vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz; - vec4 norm = vec4(position.xyz, 1.0); - norm.xyz += normal.xyz; - norm.xyz = (mat*norm).xyz; - norm.xyz = normalize(norm.xyz-pos.xyz); + vec4 pos = mat * pre_pos; + pos = projection_matrix * pos; - vary_normal = norm.xyz; - - vertex_color = diffuse_color; + target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x; + + post_pos = pos; + +#if !defined(DEPTH_CLAMP) + gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w); +#else + gl_Position = pos; +#endif - gl_Position = projection_matrix*vec4(pos, 1.0); + passTextureIndex(); + + vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; + vertex_color = diffuse_color; } diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowSkinnedV.glsl similarity index 59% rename from indra/newview/app_settings/shaders/class1/objects/simpleSkinnedV.glsl rename to indra/newview/app_settings/shaders/class1/deferred/shadowSkinnedV.glsl index df31b5a79f149f344d3cd4ef80bcc540576fd57f..bdf8e0854d08c2055a1953497c44c4107721b0de 100644 --- a/indra/newview/app_settings/shaders/class1/objects/simpleSkinnedV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/shadowSkinnedV.glsl @@ -1,6 +1,7 @@ /** - * @file simpleSkinnedV.glsl - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * @file shadowSkinnedV.glsl + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2007, Linden Research, Inc. * @@ -22,44 +23,30 @@ * $/LicenseInfo$ */ -uniform mat4 texture_matrix0; uniform mat4 modelview_matrix; uniform mat4 projection_matrix; ATTRIBUTE vec3 position; -ATTRIBUTE vec3 normal; -ATTRIBUTE vec4 diffuse_color; -ATTRIBUTE vec2 texcoord0; -VARYING vec4 vertex_color; -VARYING vec2 vary_texcoord0; +VARYING vec4 post_pos; - -vec4 calcLighting(vec3 pos, vec3 norm, vec4 color); -void calcAtmospherics(vec3 inPositionEye); mat4 getObjectSkinnedTransform(); void main() { //transform vertex - vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; - mat4 mat = getObjectSkinnedTransform(); mat = modelview_matrix * mat; - vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz; - - vec4 norm = vec4(position.xyz, 1.0); - norm.xyz += normal.xyz; - norm.xyz = (mat*norm).xyz; - norm.xyz = normalize(norm.xyz-pos.xyz); - - calcAtmospherics(pos.xyz); + vec4 pos = (mat*vec4(position.xyz, 1.0)); + pos = projection_matrix*pos; + + post_pos = pos; + +#if !defined(DEPTH_CLAMP) + gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w); +#else + gl_Position = pos; +#endif - vec4 color = calcLighting(pos.xyz, norm.xyz, diffuse_color); - vertex_color = color; - - gl_Position = projection_matrix*vec4(pos, 1.0); - - } diff --git a/indra/newview/app_settings/shaders/class1/objects/emissiveSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeShadowSkinnedV.glsl similarity index 76% rename from indra/newview/app_settings/shaders/class1/objects/emissiveSkinnedV.glsl rename to indra/newview/app_settings/shaders/class1/deferred/treeShadowSkinnedV.glsl index 90649041917c1ffdc64a441ae9dc30fb9c2e2197..d9ca6d3a46378e3537dbdd7d15b953eca7227e56 100644 --- a/indra/newview/app_settings/shaders/class1/objects/emissiveSkinnedV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/treeShadowSkinnedV.glsl @@ -1,7 +1,7 @@ /** - * @file emissiveSkinnedV.glsl + * @file treeShadowV.glsl * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2007, Linden Research, Inc. * @@ -23,34 +23,31 @@ * $/LicenseInfo$ */ -uniform mat4 projection_matrix; uniform mat4 texture_matrix0; uniform mat4 modelview_matrix; - +uniform mat4 projection_matrix; + ATTRIBUTE vec3 position; -ATTRIBUTE vec4 emissive; ATTRIBUTE vec2 texcoord0; -VARYING vec4 vertex_color; +VARYING vec4 post_pos; VARYING vec2 vary_texcoord0; - -void calcAtmospherics(vec3 inPositionEye); mat4 getObjectSkinnedTransform(); void main() { //transform vertex - vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; - - mat4 mat = getObjectSkinnedTransform(); + mat4 mat = getObjectSkinnedTransform(); mat = modelview_matrix * mat; - vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz; - vertex_color = emissive; - - calcAtmospherics(pos.xyz); - - gl_Position = projection_matrix*vec4(pos, 1.0); + vec4 pos = mat * vec4(position.xyz, 1.0); + pos = projection_matrix * pos; + + post_pos = pos; + + gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w); + + vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; } diff --git a/indra/newview/app_settings/shaders/class1/interface/debugV.glsl b/indra/newview/app_settings/shaders/class1/interface/debugV.glsl index f4d704577ad5e6f83bfb83971895255c2258397d..153998f1d5d745baae4c6f17270f9d4f0a53b0b8 100644 --- a/indra/newview/app_settings/shaders/class1/interface/debugV.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/debugV.glsl @@ -27,8 +27,21 @@ uniform mat4 modelview_projection_matrix; ATTRIBUTE vec3 position; +#ifdef HAS_SKIN +mat4 getObjectSkinnedTransform(); +uniform mat4 projection_matrix; +uniform mat4 modelview_matrix; +#endif + void main() { +#ifdef HAS_SKIN + mat4 mat = getObjectSkinnedTransform(); + mat = modelview_matrix * mat; + vec4 pos = mat * vec4(position.xyz,1.0); + gl_Position = projection_matrix * pos; +#else gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); +#endif } diff --git a/indra/newview/app_settings/shaders/class1/interface/highlightV.glsl b/indra/newview/app_settings/shaders/class1/interface/highlightV.glsl index 9bf7b60eb76a709653d9a379a1d3392ca9aa79b0..0b362cf46c4e6c3ccae1789b0586a136a9448a41 100644 --- a/indra/newview/app_settings/shaders/class1/interface/highlightV.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/highlightV.glsl @@ -31,10 +31,23 @@ ATTRIBUTE vec2 texcoord0; VARYING vec2 vary_texcoord0; +#ifdef HAS_SKIN +mat4 getObjectSkinnedTransform(); +uniform mat4 projection_matrix; +uniform mat4 modelview_matrix; +#endif + void main() { //transform vertex +#ifdef HAS_SKIN + mat4 mat = getObjectSkinnedTransform(); + mat = modelview_matrix * mat; + vec4 pos = mat * vec4(position.xyz,1.0); + gl_Position = projection_matrix * pos; +#else gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); +#endif vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; } diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/interface/occlusionSkinnedV.glsl similarity index 73% rename from indra/newview/app_settings/shaders/class1/objects/fullbrightSkinnedV.glsl rename to indra/newview/app_settings/shaders/class1/interface/occlusionSkinnedV.glsl index eff75435a9459409ffa579611fca663c6c942fbb..7305065a057e6bd1ef66352d0563f578ef65f323 100644 --- a/indra/newview/app_settings/shaders/class1/objects/fullbrightSkinnedV.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/occlusionSkinnedV.glsl @@ -1,6 +1,7 @@ /** - * @file fullbrightSkinnedV.glsl - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * @file occlusionSkinnedV.glsl + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2007, Linden Research, Inc. * @@ -23,35 +24,17 @@ */ uniform mat4 projection_matrix; -uniform mat4 texture_matrix0; uniform mat4 modelview_matrix; ATTRIBUTE vec3 position; -ATTRIBUTE vec4 diffuse_color; -ATTRIBUTE vec2 texcoord0; -void calcAtmospherics(vec3 inPositionEye); mat4 getObjectSkinnedTransform(); -VARYING vec4 vertex_color; -VARYING vec2 vary_texcoord0; - - void main() { - //transform vertex - vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; - mat4 mat = getObjectSkinnedTransform(); - mat = modelview_matrix * mat; vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz; - - calcAtmospherics(pos.xyz); - - vertex_color = diffuse_color; - gl_Position = projection_matrix*vec4(pos, 1.0); - - } + diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightAlphaMaskF.glsl index 1855cfceeb8c4b277e3fe3142d9a98791c4ecb3a..ad2170bbd3aa3f98f0032c221fd1f1be4cb77078 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightAlphaMaskF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightAlphaMaskF.glsl @@ -50,7 +50,7 @@ void fullbright_lighting() discard; } - color.rgb *= vertex_color.rgb; + color *= vertex_color; color.rgb = pow(color.rgb, vec3(texture_gamma)); diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl index 5fcdf3107c63954568173fa3f64013e34af75428..89be8195f0f3d7fcabfd8e2986fd6e544e9d6999 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl @@ -56,5 +56,6 @@ void fullbright_lighting() color.rgb = pow(color.rgb, vec3(1.0/texture_gamma)); frag_color = color; + } diff --git a/indra/newview/app_settings/shaders/class1/objects/bumpV.glsl b/indra/newview/app_settings/shaders/class1/objects/bumpV.glsl index a7738087dcc940f41229140b89a9fa54502d85fc..ee9970bc70ae6e04fafd25cb448224e9280fa175 100644 --- a/indra/newview/app_settings/shaders/class1/objects/bumpV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/bumpV.glsl @@ -33,10 +33,23 @@ ATTRIBUTE vec2 texcoord1; VARYING vec2 vary_texcoord0; VARYING vec2 vary_texcoord1; +#ifdef HAS_SKIN +mat4 getObjectSkinnedTransform(); +uniform mat4 projection_matrix; +uniform mat4 modelview_matrix; +#endif + void main() { //transform vertex +#ifdef HAS_SKIN + mat4 mat = getObjectSkinnedTransform(); + mat = modelview_matrix * mat; + vec4 pos = mat * vec4(position.xyz, 1.0); + gl_Position = projection_matrix * pos; +#else gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0); +#endif vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; vary_texcoord1 = (texture_matrix0 * vec4(texcoord1,0,1)).xy; } diff --git a/indra/newview/app_settings/shaders/class1/objects/emissiveV.glsl b/indra/newview/app_settings/shaders/class1/objects/emissiveV.glsl index e984deb0c89c10a12ce0547ce4596dce9cad820d..d762239e5116d101d38993ba4a70c30b21a4642c 100644 --- a/indra/newview/app_settings/shaders/class1/objects/emissiveV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/emissiveV.glsl @@ -37,20 +37,30 @@ VARYING vec2 vary_texcoord0; void calcAtmospherics(vec3 inPositionEye); - - +#ifdef HAS_SKIN +mat4 getObjectSkinnedTransform(); +uniform mat4 projection_matrix; +#endif void main() { //transform vertex passTextureIndex(); + +#ifdef HAS_SKIN + mat4 mat = getObjectSkinnedTransform(); + mat = modelview_matrix * mat; + + vec4 pos = mat * vec4(position.xyz, 1.0); + gl_Position = projection_matrix * pos; +#else gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); + vec4 pos = (modelview_matrix * vec4(position.xyz, 1.0)); +#endif vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; - vec4 pos = (modelview_matrix * vec4(position.xyz, 1.0)); + calcAtmospherics(pos.xyz); vertex_color = emissive; - - } diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinySkinnedV.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinySkinnedV.glsl deleted file mode 100644 index 1e244d9dfdae3d0e1ef7920ba3ff2b58c0e75431..0000000000000000000000000000000000000000 --- a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinySkinnedV.glsl +++ /dev/null @@ -1,71 +0,0 @@ -/** - * @file shinySimpleSkinnedV.glsl - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2007, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -uniform mat4 texture_matrix0; -uniform mat4 texture_matrix1; -uniform mat4 modelview_matrix; -uniform mat4 projection_matrix; - -ATTRIBUTE vec3 position; -ATTRIBUTE vec3 normal; -ATTRIBUTE vec4 diffuse_color; -ATTRIBUTE vec2 texcoord0; - -VARYING vec4 vertex_color; -VARYING vec2 vary_texcoord0; -VARYING vec3 vary_texcoord1; -VARYING vec4 vary_position; - - -void calcAtmospherics(vec3 inPositionEye); -mat4 getObjectSkinnedTransform(); - -void main() -{ - mat4 mat = getObjectSkinnedTransform(); - - mat = modelview_matrix * mat; - vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz; - - mat4 mvp = modelview_matrix * projection_matrix; - vary_position = mvp * vec4(position, 1.0); - - vec4 norm = vec4(position.xyz, 1.0); - norm.xyz += normal.xyz; - norm.xyz = (mat*norm).xyz; - norm.xyz = normalize(norm.xyz-pos.xyz); - - vec3 ref = reflect(pos.xyz, -norm.xyz); - - vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; - vary_texcoord1 = (texture_matrix1*vec4(ref,1.0)).xyz; - - calcAtmospherics(pos.xyz); - - vertex_color = diffuse_color; - - gl_Position = projection_matrix*vec4(pos, 1.0); - - -} diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyV.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyV.glsl index 2e998d80aa036c37ab493cf0301759ceb3af9bd4..a4fac4813f3c74378c3cb3a64457a7fd73623a97 100644 --- a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyV.glsl @@ -42,20 +42,32 @@ VARYING vec4 vertex_color; VARYING vec2 vary_texcoord0; VARYING vec3 vary_texcoord1; +#ifdef HAS_SKIN +mat4 getObjectSkinnedTransform(); +uniform mat4 projection_matrix; +#endif void main() { //transform vertex vec4 vert = vec4(position.xyz,1.0); passTextureIndex(); + +#ifdef HAS_SKIN + mat4 mat = getObjectSkinnedTransform(); + mat = modelview_matrix * mat; + vec4 pos = mat * vert; + gl_Position = projection_matrix * pos; + vec3 norm = normalize((mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz); +#else vec4 pos = (modelview_matrix * vert); gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0); - vec3 norm = normalize(normal_matrix * normal); +#endif vec3 ref = reflect(pos.xyz, -norm); vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; - vary_texcoord1 = (texture_matrix1*vec4(ref,1.0)).xyz; + vary_texcoord1 = (texture_matrix1 * vec4(ref,1.0)).xyz; calcAtmospherics(pos.xyz); diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl index fc20d3270e2a349931b972de5e8a1117b9d0597c..5af42f1fcf99600e4d773aabfea17b4c95cb1032 100644 --- a/indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl @@ -33,26 +33,33 @@ ATTRIBUTE vec2 texcoord0; ATTRIBUTE vec3 normal; ATTRIBUTE vec4 diffuse_color; - void calcAtmospherics(vec3 inPositionEye); - VARYING vec4 vertex_color; VARYING vec2 vary_texcoord0; +#ifdef HAS_SKIN +mat4 getObjectSkinnedTransform(); +uniform mat4 projection_matrix; +#endif void main() { //transform vertex vec4 vert = vec4(position.xyz,1.0); passTextureIndex(); - vec4 pos = (modelview_matrix * vert); +#ifdef HAS_SKIN + mat4 mat = getObjectSkinnedTransform(); + mat = modelview_matrix * mat; + vec4 pos = mat * vert; + gl_Position = projection_matrix * pos; +#else + vec4 pos = (modelview_matrix * vert); gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0); +#endif vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; calcAtmospherics(pos.xyz); vertex_color = diffuse_color; - - } diff --git a/indra/llcommon/timing.cpp b/indra/newview/app_settings/shaders/class1/objects/previewPhysicsF.glsl similarity index 63% rename from indra/llcommon/timing.cpp rename to indra/newview/app_settings/shaders/class1/objects/previewPhysicsF.glsl index c2dc695ef33304af0abd3df0c6fc78c0f2cb5a92..3a5e6fdf7c440e14e541af9553c1824b502ec1b6 100644 --- a/indra/llcommon/timing.cpp +++ b/indra/newview/app_settings/shaders/class1/objects/previewPhysicsF.glsl @@ -1,10 +1,9 @@ /** - * @file timing.cpp - * @brief This file will be deprecated in the future. + * @file previewPhysicsF.glsl * - * $LicenseInfo:firstyear=2000&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 @@ -23,3 +22,21 @@ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ + +#ifdef DEFINE_GL_FRAGCOLOR +out vec4 frag_color; +#else +#define frag_color gl_FragColor +#endif + +uniform sampler2D diffuseMap; +uniform vec4 color; + +VARYING vec2 vary_texcoord0; + +//==================================================================================================== + +void main() +{ + frag_color = texture2D(diffuseMap,vary_texcoord0.xy) * color; +} diff --git a/indra/newview/app_settings/shaders/class1/objects/previewPhysicsV.glsl b/indra/newview/app_settings/shaders/class1/objects/previewPhysicsV.glsl new file mode 100644 index 0000000000000000000000000000000000000000..913dec83bd711f9419cb77369df3865a69a308bd --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/objects/previewPhysicsV.glsl @@ -0,0 +1,42 @@ +/** + * @file previewPhysicsV.glsl + * + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Second Life Viewer Source Code + * 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 + * 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 texture_matrix0; +uniform mat4 modelview_matrix; +uniform mat4 modelview_projection_matrix; + +ATTRIBUTE vec3 position; +ATTRIBUTE vec2 texcoord0; + +VARYING vec2 vary_texcoord0; + +//==================================================================================================== + +void main() +{ + //transform vertex + gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); + vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; +} diff --git a/indra/newview/app_settings/shaders/class1/objects/previewV.glsl b/indra/newview/app_settings/shaders/class1/objects/previewV.glsl index 4bb588335ad9809773dd08cf7d2f062a8cfe0adb..5886f47cbce323205f8e6725cc8e317f6d3762c4 100644 --- a/indra/newview/app_settings/shaders/class1/objects/previewV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/previewV.glsl @@ -51,30 +51,6 @@ float calcDirectionalLight(vec3 n, vec3 l) return a; } - -float calcLocalLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight) -{ - //get light vector - vec3 lv = lp.xyz-v; - - //get distance - float d = length(lv); - - //normalize light vector - lv *= 1.0/d; - - //distance attenuation - float da = clamp(1.0/(la * d), 0.0, 1.0); - - // spotlight coefficient. - float spot = max(dot(-ln, lv), is_pointlight); - da *= spot*spot; // GL_SPOT_EXPONENT=2 - - //angular attenuation - da *= calcDirectionalLight(n, lv); - - return da; -} //==================================================================================================== @@ -91,7 +67,8 @@ void main() // Collect normal lights (need to be divided by two, as we later multiply by 2) col.rgb += light_diffuse[1].rgb * calcDirectionalLight(norm, light_position[1].xyz); - col.rgb += light_diffuse[2].rgb*calcLocalLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].z); - col.rgb += light_diffuse[3].rgb*calcLocalLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].z); + col.rgb += light_diffuse[2].rgb * calcDirectionalLight(norm, light_position[2].xyz); + col.rgb += light_diffuse[3].rgb * calcDirectionalLight(norm, light_position[3].xyz); + vertex_color = col*color; } diff --git a/indra/newview/app_settings/shaders/class1/objects/shinySimpleSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/objects/shinySimpleSkinnedV.glsl deleted file mode 100644 index 727bae19c06f70d3050afce866eb15cc6b0718f4..0000000000000000000000000000000000000000 --- a/indra/newview/app_settings/shaders/class1/objects/shinySimpleSkinnedV.glsl +++ /dev/null @@ -1,66 +0,0 @@ -/** - * @file shinySimpleSkinnedV.glsl - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2007, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -uniform mat4 projection_matrix; -uniform mat4 texture_matrix0; -uniform mat4 texture_matrix1; -uniform mat4 modelview_matrix; - -ATTRIBUTE vec3 position; -ATTRIBUTE vec3 normal; -ATTRIBUTE vec4 diffuse_color; -ATTRIBUTE vec2 texcoord0; - -VARYING vec4 vertex_color; -VARYING vec2 vary_texcoord0; -VARYING vec3 vary_texcoord1; - -vec4 calcLighting(vec3 pos, vec3 norm, vec4 color); -void calcAtmospherics(vec3 inPositionEye); -mat4 getObjectSkinnedTransform(); - -void main() -{ - mat4 mat = getObjectSkinnedTransform(); - - mat = modelview_matrix * mat; - vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz; - - vec4 norm = vec4(position.xyz, 1.0); - norm.xyz += normal.xyz; - norm.xyz = (mat*norm).xyz; - norm.xyz = normalize(norm.xyz-pos.xyz); - - vec3 ref = reflect(pos.xyz, -norm.xyz); - - vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; - vary_texcoord1 = (texture_matrix1*vec4(ref,1.0)).xyz; - - calcAtmospherics(pos.xyz); - - vec4 color = calcLighting(pos.xyz, norm.xyz, diffuse_color); - vertex_color = color; - - gl_Position = projection_matrix*vec4(pos, 1.0); -} diff --git a/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl b/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl index 233dc2171f40a1d87f8a974f8d0ee4e1974ffa44..3ad7bcaa50f7bb14f0ccf8cee61ece51c7e53f4b 100644 --- a/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl @@ -43,19 +43,34 @@ vec4 calcLighting(vec3 pos, vec3 norm, vec4 color); void calcAtmospherics(vec3 inPositionEye); +uniform vec4 origin; + +#ifdef HAS_SKIN +mat4 getObjectSkinnedTransform(); +uniform mat4 projection_matrix; +#endif + void main() { //transform vertex vec4 vert = vec4(position.xyz,1.0); passTextureIndex(); + +#ifdef HAS_SKIN + mat4 mat = getObjectSkinnedTransform(); + mat = modelview_matrix * mat; + vec4 pos = mat * vert; + gl_Position = projection_matrix * pos; + vec3 norm = normalize((mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz); +#else vec4 pos = (modelview_matrix * vert); gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0); - vec3 norm = normalize(normal_matrix * normal); +#endif vec3 ref = reflect(pos.xyz, -norm); - vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; - vary_texcoord1 = (texture_matrix1*vec4(ref,1.0)).xyz; + vary_texcoord0 = (texture_matrix0*vec4(texcoord0,0,1)).xy; + vary_texcoord1 = (texture_matrix1 * vec4(ref,1.0)).xyz; calcAtmospherics(pos.xyz); diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl index 9ef7704b7038ad6ae074a8d3b5011c3fce7b48b7..2025174f7decf7d25318022ee702a3867ef58c95 100644 --- a/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl @@ -44,12 +44,16 @@ void calcAtmospherics(vec3 inPositionEye); VARYING vec4 vertex_color; VARYING vec2 vary_texcoord0; +#ifdef HAS_SKIN +mat4 getObjectSkinnedTransform(); +uniform mat4 projection_matrix; +#endif + void main() { //transform vertex vec4 vert = vec4(position.xyz,1.0); - gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0); passTextureIndex(); vary_texcoord0 = (texture_matrix0 * vec4(texcoord0, 0, 1)).xy; @@ -58,11 +62,23 @@ void main() if (no_atmo == 1) { vertex_color = diffuse_color; + gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0); } else { +#ifdef HAS_SKIN + mat4 mat = getObjectSkinnedTransform(); + mat = modelview_matrix * mat; + + vec4 pos = mat * vert; + vec3 norm = normalize((mat*vec4(normal.xyz+vert.xyz,1.0)).xyz-pos.xyz); + + gl_Position = projection_matrix * pos; +#else vec4 pos = (modelview_matrix * vert); vec3 norm = normalize(normal_matrix * normal); + gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0); +#endif calcAtmospherics(pos.xyz); diff --git a/indra/newview/app_settings/ultra_graphics.xml b/indra/newview/app_settings/ultra_graphics.xml index fe58bd0d430c4195136962884498df9a9ac31451..394d881fb0ffa74d85cdb62039ac8f44e1125ecd 100644 --- a/indra/newview/app_settings/ultra_graphics.xml +++ b/indra/newview/app_settings/ultra_graphics.xml @@ -6,8 +6,6 @@ <RenderAvatarLODFactor value="1.0"/> <!--Default for now--> <RenderAvatarPhysicsLODFactor value="1.0"/> - <!--NO SHADERS--> - <RenderAvatarVP value="TRUE"/> <!--Short Range--> <RenderFarClip value="256"/> <!--Default for now--> diff --git a/indra/newview/character/avatar_skeleton.xml b/indra/newview/character/avatar_skeleton.xml index 2241a12545ffd942b86c3ed87422cdceb0ac0798..6cfc0b0be284682bd42dc83bcee42acc60c74cf5 100644 --- a/indra/newview/character/avatar_skeleton.xml +++ b/indra/newview/character/avatar_skeleton.xml @@ -2,15 +2,15 @@ <bone aliases="hip avatar_mPelvis" connected="false" end="0.000 0.000 0.084" group="Torso" name="mPelvis" pivot="0.000000 0.000000 1.067015" pos="0.000 0.000 1.067" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"> <collision_volume end="0.030 0.000 0.095" group="Collision" name="PELVIS" pos="-0.01 0 -0.02" rot="0.000000 8.00000 0.000000" scale="0.12 0.16 0.17" support="base"/> <collision_volume end="-0.100 0.000 0.000" group="Collision" name="BUTT" pos="-0.06 0 -0.1" rot="0.000000 0.00000 0.000000" scale="0.1 0.1 0.1" support="base"/> - <bone connected="true" end="0.000 0.000 -0.084" group="Spine" name="mSpine1" pivot="0.000000 0.000000 0.084073" pos="0.000 0.000 0.084" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"> - <bone connected="true" end="0.000 0.000 0.084" group="Spine" name="mSpine2" pivot="0.000000 0.000000 -0.084073" pos="0.000 0.000 -0.084" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="avatar_mSpine1" connected="true" end="0.000 0.000 -0.084" group="Spine" name="mSpine1" pivot="0.000000 0.000000 0.084073" pos="0.000 0.000 0.084" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="avatar_mSpine2" connected="true" end="0.000 0.000 0.084" group="Spine" name="mSpine2" pivot="0.000000 0.000000 -0.084073" pos="0.000 0.000 -0.084" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"> <bone aliases="abdomen avatar_mTorso" connected="true" end="-0.015 0.000 0.205" group="Torso" name="mTorso" pivot="0.000000 0.000000 0.084073" pos="0.000 0.000 0.084" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"> <collision_volume end="0.028 0.000 0.094" group="Collision" name="BELLY" pos="0.028 0 0.04" rot="0.000000 8.00000 0.000000" scale="0.09 0.13 0.15" support="base"/> <collision_volume end="0.000 0.100 0.000" group="Collision" name="LEFT_HANDLE" pos="0.0 0.10 0.058" rot="0.000000 0.00000 0.000000" scale="0.05 0.05 0.05" support="base"/> <collision_volume end="0.000 -0.100 0.000" group="Collision" name="RIGHT_HANDLE" pos="0.0 -0.10 0.058" rot="0.000000 0.00000 0.000000" scale="0.05 0.05 0.05" support="base"/> <collision_volume end="-0.100 0.000 0.000" group="Collision" name="LOWER_BACK" pos="0.0 0.0 0.023" rot="0.000000 0.00000 0.000000" scale="0.09 0.13 0.15" support="base"/> - <bone connected="true" end="0.015 0.000 -0.205" group="Spine" name="mSpine3" pivot="-0.015368 0.000000 0.204877" pos="-0.015 0.000 0.205" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"> - <bone connected="true" end="-0.015 0.000 0.205" group="Spine" name="mSpine4" pivot="0.015368 0.000000 -0.204877" pos="0.015 0.000 -0.205" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="avatar_mSpine3" connected="true" end="0.015 0.000 -0.205" group="Spine" name="mSpine3" pivot="-0.015368 0.000000 0.204877" pos="-0.015 0.000 0.205" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="avatar_mSpine4" connected="true" end="-0.015 0.000 0.205" group="Spine" name="mSpine4" pivot="0.015368 0.000000 -0.204877" pos="0.015 0.000 -0.205" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"> <bone aliases="chest avatar_mChest" connected="true" end="-0.010 0.000 0.250" group="Torso" name="mChest" pivot="-0.015368 0.000000 0.204877" pos="-0.015 0.000 0.205" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"> <collision_volume end="-0.096 0.000 0.152" group="Collision" name="CHEST" pos="0.028 0 0.07" rot="0.000000 -10.00000 0.000000" scale="0.11 0.15 0.2" support="base"/> <collision_volume end="0.080 0.000 -0.006" group="Collision" name="LEFT_PEC" pos="0.119 0.082 0.042" rot="0.000000 4.29000 0.000000" scale="0.05 0.05 0.05" support="base"/> @@ -23,58 +23,58 @@ <bone aliases="figureHair avatar_mSkull" connected="false" end="0.000 0.000 0.033" group="Extra" name="mSkull" pivot="0.000000 0.000000 0.079000" pos="0.000 0.000 0.079" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"/> <bone aliases="avatar_mEyeRight" connected="false" end="0.025 0.000 0.000" group="Extra" name="mEyeRight" pivot="0.098466 -0.036000 0.079000" pos="0.098 -0.036 0.079" rot="0.000000 0.000000 -0.000000" scale="1.000 1.000 1.000" support="base"/> <bone aliases="avatar_mEyeLeft" connected="false" end="0.025 0.000 0.000" group="Extra" name="mEyeLeft" pivot="0.098461 0.036000 0.079000" pos="0.098 0.036 0.079" rot="0.000000 -0.000000 0.000000" scale="1.000 1.000 1.000" support="base"/> - <bone connected="false" end="0.020 0.000 0.000" group="Face" name="mFaceRoot" pivot="0.025000 0.000000 0.045000" pos="0.025 0.000 0.045" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"> - <bone connected="false" end="0.025 0.000 0.000" group="Face" name="mFaceEyeAltRight" pivot="0.073466 -0.036000 0.0339300" pos="0.073 -0.036 0.034" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"/> - <bone connected="false" end="0.025 0.000 0.000" group="Face" name="mFaceEyeAltLeft" pivot="0.073461 0.036000 0.0339300" pos="0.073 0.036 0.034" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"/> - <bone connected="false" end="0.024 0.004 0.018" group="Face" name="mFaceForeheadLeft" pivot="0.061 0.035 0.083" pos="0.061 0.035 0.083" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> - <bone connected="false" end="0.024 -0.004 0.018" group="Face" name="mFaceForeheadRight" pivot="0.061 -0.035 0.083" pos="0.061 -0.035 0.083" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> - <bone connected="false" end="0.023 0.013 0.000" group="Eyes" name="mFaceEyebrowOuterLeft" pivot="0.064 0.051 0.048" pos="0.064 0.051 0.048" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> - <bone connected="false" end="0.027 0.000 0.000" group="Eyes" name="mFaceEyebrowCenterLeft" pivot="0.070 0.043 0.056" pos="0.070 0.043 0.056" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> - <bone connected="false" end="0.026 0.000 0.000" group="Eyes" name="mFaceEyebrowInnerLeft" pivot="0.075 0.022 0.051" pos="0.075 0.022 0.051" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> - <bone connected="false" end="0.023 -0.013 0.000" group="Eyes" name="mFaceEyebrowOuterRight" pivot="0.064 -0.051 0.048" pos="0.064 -0.051 0.048" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> - <bone connected="false" end="0.027 0.000 0.000" group="Eyes" name="mFaceEyebrowCenterRight" pivot="0.070 -0.043 0.056" pos="0.070 -0.043 0.056" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> - <bone connected="false" end="0.026 0.000 0.000" group="Eyes" name="mFaceEyebrowInnerRight" pivot="0.075 -0.022 0.051" pos="0.075 -0.022 0.051" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> - <bone connected="false" end="0.027 0.000 0.005" group="Eyes" name="mFaceEyeLidUpperLeft" pivot="0.073 0.036 0.034" pos="0.073 0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> - <bone connected="false" end="0.024 0.000 -0.007" group="Eyes" name="mFaceEyeLidLowerLeft" pivot="0.073 0.036 0.034" pos="0.073 0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> - <bone connected="false" end="0.027 0.000 0.005" group="Eyes" name="mFaceEyeLidUpperRight" pivot="0.073 -0.036 0.034" pos="0.073 -0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> - <bone connected="false" end="0.024 0.000 -0.007" group="Eyes" name="mFaceEyeLidLowerRight" pivot="0.073 -0.036 0.034" pos="0.073 -0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> - <bone connected="false" end="-0.019 0.018 0.025" group="Ears" name="mFaceEar1Left" pivot="0.000 0.080 0.002" pos="0.000 0.080 0.002" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> - <bone connected="true" end="0.000 0.000 0.033" group="Ears" name="mFaceEar2Left" pivot="-0.019 0.018 0.025" pos="-0.019 0.018 0.025" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mFaceRoot" connected="false" end="0.020 0.000 0.000" group="Face" name="mFaceRoot" pivot="0.025000 0.000000 0.045000" pos="0.025 0.000 0.045" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="avatar_mFaceEyeAltRight" connected="false" end="0.025 0.000 0.000" group="Face" name="mFaceEyeAltRight" pivot="0.073466 -0.036000 0.0339300" pos="0.073 -0.036 0.034" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mFaceEyeAltLeft" connected="false" end="0.025 0.000 0.000" group="Face" name="mFaceEyeAltLeft" pivot="0.073461 0.036000 0.0339300" pos="0.073 0.036 0.034" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mFaceForeheadLeft" connected="false" end="0.024 0.004 0.018" group="Face" name="mFaceForeheadLeft" pivot="0.061 0.035 0.083" pos="0.061 0.035 0.083" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mFaceForeheadRight" connected="false" end="0.024 -0.004 0.018" group="Face" name="mFaceForeheadRight" pivot="0.061 -0.035 0.083" pos="0.061 -0.035 0.083" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mFaceEyebrowOuterLeft" connected="false" end="0.023 0.013 0.000" group="Eyes" name="mFaceEyebrowOuterLeft" pivot="0.064 0.051 0.048" pos="0.064 0.051 0.048" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mFaceEyebrowCenterLeft" connected="false" end="0.027 0.000 0.000" group="Eyes" name="mFaceEyebrowCenterLeft" pivot="0.070 0.043 0.056" pos="0.070 0.043 0.056" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mFaceEyebrowInnerLeft" connected="false" end="0.026 0.000 0.000" group="Eyes" name="mFaceEyebrowInnerLeft" pivot="0.075 0.022 0.051" pos="0.075 0.022 0.051" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mFaceEyebrowOuterRight" connected="false" end="0.023 -0.013 0.000" group="Eyes" name="mFaceEyebrowOuterRight" pivot="0.064 -0.051 0.048" pos="0.064 -0.051 0.048" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mFaceEyebrowCenterRight" connected="false" end="0.027 0.000 0.000" group="Eyes" name="mFaceEyebrowCenterRight" pivot="0.070 -0.043 0.056" pos="0.070 -0.043 0.056" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mFaceEyebrowInnerRight" connected="false" end="0.026 0.000 0.000" group="Eyes" name="mFaceEyebrowInnerRight" pivot="0.075 -0.022 0.051" pos="0.075 -0.022 0.051" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mFaceEyeLidUpperLeft" connected="false" end="0.027 0.000 0.005" group="Eyes" name="mFaceEyeLidUpperLeft" pivot="0.073 0.036 0.034" pos="0.073 0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mFaceEyeLidLowerLeft" connected="false" end="0.024 0.000 -0.007" group="Eyes" name="mFaceEyeLidLowerLeft" pivot="0.073 0.036 0.034" pos="0.073 0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mFaceEyeLidUpperRight" connected="false" end="0.027 0.000 0.005" group="Eyes" name="mFaceEyeLidUpperRight" pivot="0.073 -0.036 0.034" pos="0.073 -0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mFaceEyeLidLowerRight" connected="false" end="0.024 0.000 -0.007" group="Eyes" name="mFaceEyeLidLowerRight" pivot="0.073 -0.036 0.034" pos="0.073 -0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mFaceEar1Left" connected="false" end="-0.019 0.018 0.025" group="Ears" name="mFaceEar1Left" pivot="0.000 0.080 0.002" pos="0.000 0.080 0.002" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="avatar_mFaceEar2Left" connected="true" end="0.000 0.000 0.033" group="Ears" name="mFaceEar2Left" pivot="-0.019 0.018 0.025" pos="-0.019 0.018 0.025" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> </bone> - <bone connected="false" end="-0.019 -0.018 0.025" group="Ears" name="mFaceEar1Right" pivot="0.000 -0.080 0.002" pos="0.000 -0.080 0.002" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> - <bone connected="true" end="0.000 0.000 0.033" group="Ears" name="mFaceEar2Right" pivot="-0.019 -0.018 0.025" pos="-0.019 -0.018 0.025" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mFaceEar1Right" connected="false" end="-0.019 -0.018 0.025" group="Ears" name="mFaceEar1Right" pivot="0.000 -0.080 0.002" pos="0.000 -0.080 0.002" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="avatar_mFaceEar2Right" connected="true" end="0.000 0.000 0.033" group="Ears" name="mFaceEar2Right" pivot="-0.019 -0.018 0.025" pos="-0.019 -0.018 0.025" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> </bone> - <bone connected="false" end="0.015 0.004 0.000" group="Face" name="mFaceNoseLeft" pivot="0.086 0.015 -0.004" pos="0.086 0.015 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> - <bone connected="false" end="0.025 0.000 0.000" group="Face" name="mFaceNoseCenter" pivot="0.102 0.000 0.000" pos="0.102 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> - <bone connected="false" end="0.015 -0.004 0.000" group="Face" name="mFaceNoseRight" pivot="0.086 -0.015 -0.004" pos="0.086 -0.015 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> - <bone connected="false" end="0.013 0.030 0.000" group="Face" name="mFaceCheekLowerLeft" pivot="0.050 0.034 -0.031" pos="0.050 0.034 -0.031" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> - <bone connected="false" end="0.022 0.015 0.000" group="Face" name="mFaceCheekUpperLeft" pivot="0.070 0.034 -0.005" pos="0.070 0.034 -0.005" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> - <bone connected="false" end="0.013 -0.030 0.000" group="Face" name="mFaceCheekLowerRight" pivot="0.050 -0.034 -0.031" pos="0.050 -0.034 -0.031" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> - <bone connected="false" end="0.022 -0.015 0.000" group="Face" name="mFaceCheekUpperRight" pivot="0.070 -0.034 -0.005" pos="0.070 -0.034 -0.005" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> - <bone connected="false" end="0.059 0.000 -0.039" group="Mouth" name="mFaceJaw" pivot="-0.001 0.000 -0.015" pos="-0.001 0.000 -0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> - <bone connected="false" end="0.021 0.000 -0.018" group="Mouth" name="mFaceChin" pivot="0.074 0.000 -0.054" pos="0.074 0.000 -0.054" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> - <bone connected="false" end="0.035 0.000 0.000" group="Mouth" name="mFaceTeethLower" pivot="0.021 0.000 -0.039" pos="0.021 0.000 -0.039" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> - <bone connected="false" end="0.034 0.017 0.005" group="Lips" name="mFaceLipLowerLeft" pivot="0.045 0.000 0.000" pos="0.045 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> - <bone connected="false" end="0.034 -0.017 0.005" group="Lips" name="mFaceLipLowerRight" pivot="0.045 0.000 0.000" pos="0.045 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> - <bone connected="false" end="0.040 0.000 0.002" group="Lips" name="mFaceLipLowerCenter" pivot="0.045 0.000 0.000" pos="0.045 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> - <bone connected="false" end="0.022 0.000 0.007" group="Mouth" name="mFaceTongueBase" pivot="0.039 0.000 0.005" pos="0.039 0.000 0.005" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> - <bone connected="true" end="0.010 0.000 0.000" group="Mouth" name="mFaceTongueTip" pivot="0.022 0.000 0.007" pos="0.022 0.000 0.007" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mFaceNoseLeft" connected="false" end="0.015 0.004 0.000" group="Face" name="mFaceNoseLeft" pivot="0.086 0.015 -0.004" pos="0.086 0.015 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mFaceNoseCenter" connected="false" end="0.025 0.000 0.000" group="Face" name="mFaceNoseCenter" pivot="0.102 0.000 0.000" pos="0.102 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mFaceNoseRight" connected="false" end="0.015 -0.004 0.000" group="Face" name="mFaceNoseRight" pivot="0.086 -0.015 -0.004" pos="0.086 -0.015 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mFaceCheekLowerLeft" connected="false" end="0.013 0.030 0.000" group="Face" name="mFaceCheekLowerLeft" pivot="0.050 0.034 -0.031" pos="0.050 0.034 -0.031" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mFaceCheekUpperLeft" connected="false" end="0.022 0.015 0.000" group="Face" name="mFaceCheekUpperLeft" pivot="0.070 0.034 -0.005" pos="0.070 0.034 -0.005" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mFaceCheekLowerRight" connected="false" end="0.013 -0.030 0.000" group="Face" name="mFaceCheekLowerRight" pivot="0.050 -0.034 -0.031" pos="0.050 -0.034 -0.031" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mFaceCheekUpperRight" connected="false" end="0.022 -0.015 0.000" group="Face" name="mFaceCheekUpperRight" pivot="0.070 -0.034 -0.005" pos="0.070 -0.034 -0.005" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mFaceJaw" connected="false" end="0.059 0.000 -0.039" group="Mouth" name="mFaceJaw" pivot="-0.001 0.000 -0.015" pos="-0.001 0.000 -0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="avatar_mFaceChin" connected="false" end="0.021 0.000 -0.018" group="Mouth" name="mFaceChin" pivot="0.074 0.000 -0.054" pos="0.074 0.000 -0.054" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mFaceTeethLower" connected="false" end="0.035 0.000 0.000" group="Mouth" name="mFaceTeethLower" pivot="0.021 0.000 -0.039" pos="0.021 0.000 -0.039" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="avatar_mFaceLipLowerLeft" connected="false" end="0.034 0.017 0.005" group="Lips" name="mFaceLipLowerLeft" pivot="0.045 0.000 0.000" pos="0.045 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mFaceLipLowerRight" connected="false" end="0.034 -0.017 0.005" group="Lips" name="mFaceLipLowerRight" pivot="0.045 0.000 0.000" pos="0.045 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mFaceLipLowerCenter" connected="false" end="0.040 0.000 0.002" group="Lips" name="mFaceLipLowerCenter" pivot="0.045 0.000 0.000" pos="0.045 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mFaceTongueBase" connected="false" end="0.022 0.000 0.007" group="Mouth" name="mFaceTongueBase" pivot="0.039 0.000 0.005" pos="0.039 0.000 0.005" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="avatar_mFaceTongueTip" connected="true" end="0.010 0.000 0.000" group="Mouth" name="mFaceTongueTip" pivot="0.022 0.000 0.007" pos="0.022 0.000 0.007" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> </bone> </bone> </bone> - <bone connected="false" end="-0.017 0.000 0.000" group="Face" name="mFaceJawShaper" pivot="0.000 0.000 0.000" pos="0.000 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> - <bone connected="false" end="0.036 0.000 0.000" group="Face" name="mFaceForeheadCenter" pivot="0.069 0.000 0.065" pos="0.069 0.000 0.065" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> - <bone connected="false" end="0.014 0.000 0.000" group="Nose" name="mFaceNoseBase" pivot="0.094 0.000 -0.016" pos="0.094 0.000 -0.016" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> - <bone connected="false" end="0.035 0.000 0.000" group="Mouth" name="mFaceTeethUpper" pivot="0.020 0.000 -0.030" pos="0.020 0.000 -0.030" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> - <bone connected="false" end="0.041 0.015 0.000" group="Lips" name="mFaceLipUpperLeft" pivot="0.045 0.000 -0.003" pos="0.045 0.000 -0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> - <bone connected="false" end="0.041 -0.015 0.000" group="Lips" name="mFaceLipUpperRight" pivot="0.045 0.000 -0.003" pos="0.045 0.000 -0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> - <bone connected="false" end="0.045 0.051 0.000" group="Lips" name="mFaceLipCornerLeft" pivot="0.028 -0.019 -0.010" pos="0.028 -0.019 -0.010" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> - <bone connected="false" end="0.045 -0.051 0.000" group="Lips" name="mFaceLipCornerRight" pivot="0.028 0.019 -0.010" pos="0.028 0.019 -0.010" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> - <bone connected="false" end="0.043 0.000 0.002" group="Lips" name="mFaceLipUpperCenter" pivot="0.045 0.000 -0.003" pos="0.045 0.000 -0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mFaceJawShaper" connected="false" end="-0.017 0.000 0.000" group="Face" name="mFaceJawShaper" pivot="0.000 0.000 0.000" pos="0.000 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mFaceForeheadCenter" connected="false" end="0.036 0.000 0.000" group="Face" name="mFaceForeheadCenter" pivot="0.069 0.000 0.065" pos="0.069 0.000 0.065" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mFaceNoseBase" connected="false" end="0.014 0.000 0.000" group="Nose" name="mFaceNoseBase" pivot="0.094 0.000 -0.016" pos="0.094 0.000 -0.016" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mFaceTeethUpper" connected="false" end="0.035 0.000 0.000" group="Mouth" name="mFaceTeethUpper" pivot="0.020 0.000 -0.030" pos="0.020 0.000 -0.030" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="avatar_mFaceLipUpperLeft" connected="false" end="0.041 0.015 0.000" group="Lips" name="mFaceLipUpperLeft" pivot="0.045 0.000 -0.003" pos="0.045 0.000 -0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mFaceLipUpperRight" connected="false" end="0.041 -0.015 0.000" group="Lips" name="mFaceLipUpperRight" pivot="0.045 0.000 -0.003" pos="0.045 0.000 -0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mFaceLipCornerLeft" connected="false" end="0.045 0.051 0.000" group="Lips" name="mFaceLipCornerLeft" pivot="0.028 -0.019 -0.010" pos="0.028 -0.019 -0.010" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mFaceLipCornerRight" connected="false" end="0.045 -0.051 0.000" group="Lips" name="mFaceLipCornerRight" pivot="0.028 0.019 -0.010" pos="0.028 0.019 -0.010" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mFaceLipUpperCenter" connected="false" end="0.043 0.000 0.002" group="Lips" name="mFaceLipUpperCenter" pivot="0.045 0.000 -0.003" pos="0.045 0.000 -0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> </bone> - <bone connected="false" end="0.016 0.000 0.000" group="Face" name="mFaceEyecornerInnerLeft" pivot="0.075 0.017 0.032" pos="0.075 0.017 0.032" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> - <bone connected="false" end="0.016 0.000 0.000" group="Face" name="mFaceEyecornerInnerRight" pivot="0.075 -0.017 0.032" pos="0.075 -0.017 0.032" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> - <bone connected="false" end="0.015 0.000 0.008" group="Nose" name="mFaceNoseBridge" pivot="0.091 0.000 0.020" pos="0.091 0.000 0.020" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mFaceEyecornerInnerLeft" connected="false" end="0.016 0.000 0.000" group="Face" name="mFaceEyecornerInnerLeft" pivot="0.075 0.017 0.032" pos="0.075 0.017 0.032" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mFaceEyecornerInnerRight" connected="false" end="0.016 0.000 0.000" group="Face" name="mFaceEyecornerInnerRight" pivot="0.075 -0.017 0.032" pos="0.075 -0.017 0.032" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mFaceNoseBridge" connected="false" end="0.015 0.000 0.008" group="Nose" name="mFaceNoseBridge" pivot="0.091 0.000 0.020" pos="0.091 0.000 0.020" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> </bone> </bone> </bone> @@ -86,29 +86,29 @@ <collision_volume end="0.000 0.100 -0.001" group="Collision" name="L_LOWER_ARM" pos="0.0 0.1 0.0" rot="-3.000000 0.00000 0.000000" scale="0.04 0.14 0.04" support="base"/> <bone aliases="lHand avatar_mWristLeft" connected="true" end="0.000 0.060 0.000" group="Arms" name="mWristLeft" pivot="-0.000000 0.204846 0.000000" pos="-0.000 0.205 0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"> <collision_volume end="0.005 0.049 -0.001" group="Collision" name="L_HAND" pos="0.01 0.05 0.0" rot="-3.000000 0.00000 -10.000000" scale="0.05 0.08 0.03" support="base"/> - <bone connected="false" end="-0.001 0.040 -0.006" group="Hand" name="mHandMiddle1Left" pivot="0.013 0.101 0.015" pos="0.013 0.101 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> - <bone connected="true" end="-0.001 0.049 -0.008" group="Hand" name="mHandMiddle2Left" pivot="-0.001 0.040 -0.006" pos="-0.001 0.040 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> - <bone connected="true" end="-0.002 0.033 -0.006" group="Hand" name="mHandMiddle3Left" pivot="-0.001 0.049 -0.008" pos="-0.001 0.049 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mHandMiddle1Left" connected="false" end="-0.001 0.040 -0.006" group="Hand" name="mHandMiddle1Left" pivot="0.013 0.101 0.015" pos="0.013 0.101 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="avatar_mHandMiddle2Left" connected="true" end="-0.001 0.049 -0.008" group="Hand" name="mHandMiddle2Left" pivot="-0.001 0.040 -0.006" pos="-0.001 0.040 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="avatar_mHandMiddle3Left" connected="true" end="-0.002 0.033 -0.006" group="Hand" name="mHandMiddle3Left" pivot="-0.001 0.049 -0.008" pos="-0.001 0.049 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> </bone> </bone> - <bone connected="false" end="0.017 0.036 -0.006" group="Hand" name="mHandIndex1Left" pivot="0.038 0.097 0.015" pos="0.038 0.097 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> - <bone connected="true" end="0.014 0.032 -0.006" group="Hand" name="mHandIndex2Left" pivot="0.017 0.036 -0.006" pos="0.017 0.036 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> - <bone connected="true" end="0.011 0.025 -0.004" group="Hand" name="mHandIndex3Left" pivot="0.014 0.032 -0.006" pos="0.014 0.032 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mHandIndex1Left" connected="false" end="0.017 0.036 -0.006" group="Hand" name="mHandIndex1Left" pivot="0.038 0.097 0.015" pos="0.038 0.097 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="avatar_mHandIndex2Left" connected="true" end="0.014 0.032 -0.006" group="Hand" name="mHandIndex2Left" pivot="0.017 0.036 -0.006" pos="0.017 0.036 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="avatar_mHandIndex3Left" connected="true" end="0.011 0.025 -0.004" group="Hand" name="mHandIndex3Left" pivot="0.014 0.032 -0.006" pos="0.014 0.032 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> </bone> </bone> - <bone connected="false" end="-0.013 0.038 -0.008" group="Hand" name="mHandRing1Left" pivot="-0.010 0.099 0.009" pos="-0.010 0.099 0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> - <bone connected="true" end="-0.013 0.040 -0.009" group="Hand" name="mHandRing2Left" pivot="-0.013 0.038 -0.008" pos="-0.013 0.038 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> - <bone connected="true" end="-0.010 0.028 -0.006" group="Hand" name="mHandRing3Left" pivot="-0.013 0.040 -0.009" pos="-0.013 0.040 -0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mHandRing1Left" connected="false" end="-0.013 0.038 -0.008" group="Hand" name="mHandRing1Left" pivot="-0.010 0.099 0.009" pos="-0.010 0.099 0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="avatar_mHandRing2Left" connected="true" end="-0.013 0.040 -0.009" group="Hand" name="mHandRing2Left" pivot="-0.013 0.038 -0.008" pos="-0.013 0.038 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="avatar_mHandRing3Left" connected="true" end="-0.010 0.028 -0.006" group="Hand" name="mHandRing3Left" pivot="-0.013 0.040 -0.009" pos="-0.013 0.040 -0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> </bone> </bone> - <bone connected="false" end="-0.024 0.025 -0.006" group="Hand" name="mHandPinky1Left" pivot="-0.031 0.095 0.003" pos="-0.031 0.095 0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> - <bone connected="true" end="-0.015 0.018 -0.004" group="Hand" name="mHandPinky2Left" pivot="-0.024 0.025 -0.006" pos="-0.024 0.025 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> - <bone connected="true" end="-0.013 0.016 -0.004" group="Hand" name="mHandPinky3Left" pivot="-0.015 0.018 -0.004" pos="-0.015 0.018 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mHandPinky1Left" connected="false" end="-0.024 0.025 -0.006" group="Hand" name="mHandPinky1Left" pivot="-0.031 0.095 0.003" pos="-0.031 0.095 0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="avatar_mHandPinky2Left" connected="true" end="-0.015 0.018 -0.004" group="Hand" name="mHandPinky2Left" pivot="-0.024 0.025 -0.006" pos="-0.024 0.025 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="avatar_mHandPinky3Left" connected="true" end="-0.013 0.016 -0.004" group="Hand" name="mHandPinky3Left" pivot="-0.015 0.018 -0.004" pos="-0.015 0.018 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> </bone> </bone> - <bone connected="false" end="0.028 0.032 0.000" group="Hand" name="mHandThumb1Left" pivot="0.031 0.026 0.004" pos="0.031 0.026 0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> - <bone connected="true" end="0.023 0.031 0.000" group="Hand" name="mHandThumb2Left" pivot="0.028 0.032 -0.001" pos="0.028 0.032 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> - <bone connected="true" end="0.015 0.025 0.000" group="Hand" name="mHandThumb3Left" pivot="0.023 0.031 -0.001" pos="0.023 0.031 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mHandThumb1Left" connected="false" end="0.028 0.032 0.000" group="Hand" name="mHandThumb1Left" pivot="0.031 0.026 0.004" pos="0.031 0.026 0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="avatar_mHandThumb2Left" connected="true" end="0.023 0.031 0.000" group="Hand" name="mHandThumb2Left" pivot="0.028 0.032 -0.001" pos="0.028 0.032 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="avatar_mHandThumb3Left" connected="true" end="0.015 0.025 0.000" group="Hand" name="mHandThumb3Left" pivot="0.023 0.031 -0.001" pos="0.023 0.031 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> </bone> </bone> </bone> @@ -123,49 +123,49 @@ <collision_volume end="0.000 -0.100 -0.001" group="Collision" name="R_LOWER_ARM" pos="0.0 -0.1 0.0" rot="3.000000 0.00000 0.000000" scale="0.04 0.14 0.04" support="base"/> <bone aliases="rHand avatar_mWristRight" connected="true" end="0.000 -0.060 0.000" group="Arms" name="mWristRight" pivot="-0.000000 -0.205000 -0.000000" pos="0.000 -0.205 -0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"> <collision_volume end="0.005 -0.049 -0.001" group="Collision" name="R_HAND" pos="0.01 -0.05 0.0" rot="3.000000 0.00000 10.000000" scale="0.05 0.08 0.03" support="base"/> - <bone connected="false" end="-0.001 -0.040 -0.006" group="Hand" name="mHandMiddle1Right" pivot="0.013 -0.101 0.015" pos="0.013 -0.101 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> - <bone connected="true" end="-0.001 -0.049 -0.008" group="Hand" name="mHandMiddle2Right" pivot="-0.001 -0.040 -0.006" pos="-0.001 -0.040 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> - <bone connected="true" end="-0.002 -0.033 -0.006" group="Hand" name="mHandMiddle3Right" pivot="-0.001 -0.049 -0.008" pos="-0.001 -0.049 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mHandMiddle1Right" connected="false" end="-0.001 -0.040 -0.006" group="Hand" name="mHandMiddle1Right" pivot="0.013 -0.101 0.015" pos="0.013 -0.101 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="avatar_mHandMiddle2Right" connected="true" end="-0.001 -0.049 -0.008" group="Hand" name="mHandMiddle2Right" pivot="-0.001 -0.040 -0.006" pos="-0.001 -0.040 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="avatar_mHandMiddle3Right" connected="true" end="-0.002 -0.033 -0.006" group="Hand" name="mHandMiddle3Right" pivot="-0.001 -0.049 -0.008" pos="-0.001 -0.049 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> </bone> </bone> - <bone connected="false" end="0.017 -0.036 -0.006" group="Hand" name="mHandIndex1Right" pivot="0.038 -0.097 0.015" pos="0.038 -0.097 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> - <bone connected="true" end="0.014 -0.032 -0.006" group="Hand" name="mHandIndex2Right" pivot="0.017 -0.036 -0.006" pos="0.017 -0.036 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> - <bone connected="true" end="0.011 -0.025 -0.004" group="Hand" name="mHandIndex3Right" pivot="0.014 -0.032 -0.006" pos="0.014 -0.032 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mHandIndex1Right" connected="false" end="0.017 -0.036 -0.006" group="Hand" name="mHandIndex1Right" pivot="0.038 -0.097 0.015" pos="0.038 -0.097 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="avatar_mHandIndex2Right" connected="true" end="0.014 -0.032 -0.006" group="Hand" name="mHandIndex2Right" pivot="0.017 -0.036 -0.006" pos="0.017 -0.036 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="avatar_mHandIndex3Right" connected="true" end="0.011 -0.025 -0.004" group="Hand" name="mHandIndex3Right" pivot="0.014 -0.032 -0.006" pos="0.014 -0.032 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> </bone> </bone> - <bone connected="false" end="-0.013 -0.038 -0.008" group="Hand" name="mHandRing1Right" pivot="-0.010 -0.099 0.009" pos="-0.010 -0.099 0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> - <bone connected="true" end="-0.013 -0.040 -0.009" group="Hand" name="mHandRing2Right" pivot="-0.013 -0.038 -0.008" pos="-0.013 -0.038 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> - <bone connected="true" end="-0.010 -0.028 -0.006" group="Hand" name="mHandRing3Right" pivot="-0.013 -0.040 -0.009" pos="-0.013 -0.040 -0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mHandRing1Right" connected="false" end="-0.013 -0.038 -0.008" group="Hand" name="mHandRing1Right" pivot="-0.010 -0.099 0.009" pos="-0.010 -0.099 0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="avatar_mHandRing2Right" connected="true" end="-0.013 -0.040 -0.009" group="Hand" name="mHandRing2Right" pivot="-0.013 -0.038 -0.008" pos="-0.013 -0.038 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="avatar_mHandRing3Right" connected="true" end="-0.010 -0.028 -0.006" group="Hand" name="mHandRing3Right" pivot="-0.013 -0.040 -0.009" pos="-0.013 -0.040 -0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> </bone> </bone> - <bone connected="false" end="-0.024 -0.025 -0.006" group="Hand" name="mHandPinky1Right" pivot="-0.031 -0.095 0.003" pos="-0.031 -0.095 0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> - <bone connected="true" end="-0.015 -0.018 -0.004" group="Hand" name="mHandPinky2Right" pivot="-0.024 -0.025 -0.006" pos="-0.024 -0.025 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> - <bone connected="true" end="-0.013 -0.016 -0.004" group="Hand" name="mHandPinky3Right" pivot="-0.015 -0.018 -0.004" pos="-0.015 -0.018 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mHandPinky1Right" connected="false" end="-0.024 -0.025 -0.006" group="Hand" name="mHandPinky1Right" pivot="-0.031 -0.095 0.003" pos="-0.031 -0.095 0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="avatar_mHandPinky2Right" connected="true" end="-0.015 -0.018 -0.004" group="Hand" name="mHandPinky2Right" pivot="-0.024 -0.025 -0.006" pos="-0.024 -0.025 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="avatar_mHandPinky3Right" connected="true" end="-0.013 -0.016 -0.004" group="Hand" name="mHandPinky3Right" pivot="-0.015 -0.018 -0.004" pos="-0.015 -0.018 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> </bone> </bone> - <bone connected="false" end="0.028 -0.032 0.000" group="Hand" name="mHandThumb1Right" pivot="0.031 -0.026 0.004" pos="0.031 -0.026 0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> - <bone connected="true" end="0.023 -0.031 0.000" group="Hand" name="mHandThumb2Right" pivot="0.028 -0.032 -0.001" pos="0.028 -0.032 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> - <bone connected="true" end="0.015 -0.025 0.000" group="Hand" name="mHandThumb3Right" pivot="0.023 -0.031 -0.001" pos="0.023 -0.031 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mHandThumb1Right" connected="false" end="0.028 -0.032 0.000" group="Hand" name="mHandThumb1Right" pivot="0.031 -0.026 0.004" pos="0.031 -0.026 0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="avatar_mHandThumb2Right" connected="true" end="0.023 -0.031 0.000" group="Hand" name="mHandThumb2Right" pivot="0.028 -0.032 -0.001" pos="0.028 -0.032 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="avatar_mHandThumb3Right" connected="true" end="0.015 -0.025 0.000" group="Hand" name="mHandThumb3Right" pivot="0.023 -0.031 -0.001" pos="0.023 -0.031 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> </bone> </bone> </bone> </bone> </bone> </bone> - <bone connected="false" end="-0.061 0.000 0.000" group="Wing" name="mWingsRoot" pivot="-0.014 0.000 0.000" pos="-0.014 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> - <bone connected="false" end="-0.168 0.169 0.067" group="Wing" name="mWing1Left" pivot="-0.099 0.105 0.181" pos="-0.099 0.105 0.181" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> - <bone connected="true" end="-0.181 0.183 0.000" group="Wing" name="mWing2Left" pivot="-0.168 0.169 0.067" pos="-0.168 0.169 0.067" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> - <bone connected="true" end="-0.171 0.173 0.000" group="Wing" name="mWing3Left" pivot="-0.181 0.183 0.000" pos="-0.181 0.183 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> - <bone connected="true" end="-0.146 0.132 0.000" group="Wing" name="mWing4Left" pivot="-0.171 0.173 0.000" pos="-0.171 0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> - <bone connected="true" end="-0.068 0.062 -0.159" group="Wing" name="mWing4FanLeft" pivot="-0.171 0.173 0.000" pos="-0.171 0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mWingsRoot" connected="false" end="-0.061 0.000 0.000" group="Wing" name="mWingsRoot" pivot="-0.014 0.000 0.000" pos="-0.014 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="avatar_mWing1Left" connected="false" end="-0.168 0.169 0.067" group="Wing" name="mWing1Left" pivot="-0.099 0.105 0.181" pos="-0.099 0.105 0.181" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="avatar_mWing2Left" connected="true" end="-0.181 0.183 0.000" group="Wing" name="mWing2Left" pivot="-0.168 0.169 0.067" pos="-0.168 0.169 0.067" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="avatar_mWing3Left" connected="true" end="-0.171 0.173 0.000" group="Wing" name="mWing3Left" pivot="-0.181 0.183 0.000" pos="-0.181 0.183 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="avatar_mWing4Left" connected="true" end="-0.146 0.132 0.000" group="Wing" name="mWing4Left" pivot="-0.171 0.173 0.000" pos="-0.171 0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mWing4FanLeft" connected="true" end="-0.068 0.062 -0.159" group="Wing" name="mWing4FanLeft" pivot="-0.171 0.173 0.000" pos="-0.171 0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> </bone> </bone> </bone> - <bone connected="false" end="-0.168 -0.169 0.067" group="Wing" name="mWing1Right" pivot="-0.099 -0.105 0.181" pos="-0.099 -0.105 0.181" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> - <bone connected="true" end="-0.181 -0.183 0.000" group="Wing" name="mWing2Right" pivot="-0.168 -0.169 0.067" pos="-0.168 -0.169 0.067" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> - <bone connected="true" end="-0.171 -0.173 0.000" group="Wing" name="mWing3Right" pivot="-0.181 -0.183 0.000" pos="-0.181 -0.183 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> - <bone connected="true" end="-0.146 -0.132 0.000" group="Wing" name="mWing4Right" pivot="-0.171 -0.173 0.000" pos="-0.171 -0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> - <bone connected="true" end="-0.068 -0.062 -0.159" group="Wing" name="mWing4FanRight" pivot="-0.171 -0.173 0.000" pos="-0.171 -0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mWing1Right" connected="false" end="-0.168 -0.169 0.067" group="Wing" name="mWing1Right" pivot="-0.099 -0.105 0.181" pos="-0.099 -0.105 0.181" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="avatar_mWing2Right" connected="true" end="-0.181 -0.183 0.000" group="Wing" name="mWing2Right" pivot="-0.168 -0.169 0.067" pos="-0.168 -0.169 0.067" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="avatar_mWing3Right" connected="true" end="-0.171 -0.173 0.000" group="Wing" name="mWing3Right" pivot="-0.181 -0.183 0.000" pos="-0.181 -0.183 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="avatar_mWing4Right" connected="true" end="-0.146 -0.132 0.000" group="Wing" name="mWing4Right" pivot="-0.171 -0.173 0.000" pos="-0.171 -0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mWing4FanRight" connected="true" end="-0.068 -0.062 -0.159" group="Wing" name="mWing4FanRight" pivot="-0.171 -0.173 0.000" pos="-0.171 -0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> </bone> </bone> </bone> @@ -200,30 +200,30 @@ </bone> </bone> </bone> - <bone connected="false" end="-0.197 0.000 0.000" group="Tail" name="mTail1" pivot="-0.116 0.000 0.047" pos="-0.116 0.000 0.047" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> - <bone connected="true" end="-0.168 0.000 0.000" group="Tail" name="mTail2" pivot="-0.197 0.000 0.000" pos="-0.197 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> - <bone connected="true" end="-0.142 0.000 0.000" group="Tail" name="mTail3" pivot="-0.168 0.000 0.000" pos="-0.168 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> - <bone connected="true" end="-0.112 0.000 0.000" group="Tail" name="mTail4" pivot="-0.142 0.000 0.000" pos="-0.142 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> - <bone connected="true" end="-0.094 0.000 0.000" group="Tail" name="mTail5" pivot="-0.112 0.000 0.000" pos="-0.112 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> - <bone connected="true" end="-0.089 0.000 0.000" group="Tail" name="mTail6" pivot="-0.094 0.000 0.000" pos="-0.094 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mTail1" connected="false" end="-0.197 0.000 0.000" group="Tail" name="mTail1" pivot="-0.116 0.000 0.047" pos="-0.116 0.000 0.047" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="avatar_mTail2" connected="true" end="-0.168 0.000 0.000" group="Tail" name="mTail2" pivot="-0.197 0.000 0.000" pos="-0.197 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="avatar_mTail3" connected="true" end="-0.142 0.000 0.000" group="Tail" name="mTail3" pivot="-0.168 0.000 0.000" pos="-0.168 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="avatar_mTail4" connected="true" end="-0.112 0.000 0.000" group="Tail" name="mTail4" pivot="-0.142 0.000 0.000" pos="-0.142 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="avatar_mTail5" connected="true" end="-0.094 0.000 0.000" group="Tail" name="mTail5" pivot="-0.112 0.000 0.000" pos="-0.112 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="avatar_mTail6" connected="true" end="-0.089 0.000 0.000" group="Tail" name="mTail6" pivot="-0.094 0.000 0.000" pos="-0.094 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> </bone> </bone> </bone> </bone> </bone> - <bone connected="false" end="0.004 0.000 -0.066" group="Groin" name="mGroin" pivot="0.064 0.000 -0.097" pos="0.064 0.000 -0.097" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> - <bone connected="false" end="-0.204 0.000 0.000" group="Limb" name="mHindLimbsRoot" pivot="-0.200 0.000 0.084" pos="-0.200 0.000 0.084" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> - <bone connected="false" end="0.002 -0.046 -0.491" group="Limb" name="mHindLimb1Left" pivot="-0.204 0.129 -0.125" pos="-0.204 0.129 -0.125" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> - <bone connected="true" end="-0.030 -0.003 -0.468" group="Limb" name="mHindLimb2Left" pivot="0.002 -0.046 -0.491" pos="0.002 -0.046 -0.491" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> - <bone connected="true" end="0.112 0.000 -0.061" group="Limb" name="mHindLimb3Left" pivot="-0.030 -0.003 -0.468" pos="-0.030 -0.003 -0.468" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> - <bone connected="true" end="0.105 0.008 0.000" group="Limb" name="mHindLimb4Left" pivot="0.112 0.000 -0.061" pos="0.112 0.000 -0.061" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mGroin" connected="false" end="0.004 0.000 -0.066" group="Groin" name="mGroin" pivot="0.064 0.000 -0.097" pos="0.064 0.000 -0.097" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mHindLimbsRoot" connected="false" end="-0.204 0.000 0.000" group="Limb" name="mHindLimbsRoot" pivot="-0.200 0.000 0.084" pos="-0.200 0.000 0.084" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="avatar_mHindLimb1Left" connected="false" end="0.002 -0.046 -0.491" group="Limb" name="mHindLimb1Left" pivot="-0.204 0.129 -0.125" pos="-0.204 0.129 -0.125" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="avatar_mHindLimb2Left" connected="true" end="-0.030 -0.003 -0.468" group="Limb" name="mHindLimb2Left" pivot="0.002 -0.046 -0.491" pos="0.002 -0.046 -0.491" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="avatar_mHindLimb3Left" connected="true" end="0.112 0.000 -0.061" group="Limb" name="mHindLimb3Left" pivot="-0.030 -0.003 -0.468" pos="-0.030 -0.003 -0.468" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="avatar_mHindLimb4Left" connected="true" end="0.105 0.008 0.000" group="Limb" name="mHindLimb4Left" pivot="0.112 0.000 -0.061" pos="0.112 0.000 -0.061" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> </bone> </bone> </bone> - <bone connected="false" end="0.002 0.046 -0.491" group="Limb" name="mHindLimb1Right" pivot="-0.204 -0.129 -0.125" pos="-0.204 -0.129 -0.125" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> - <bone connected="true" end="-0.030 0.003 -0.468" group="Limb" name="mHindLimb2Right" pivot="0.002 0.046 -0.491" pos="0.002 0.046 -0.491" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> - <bone connected="true" end="0.112 0.000 -0.061" group="Limb" name="mHindLimb3Right" pivot="-0.030 0.003 -0.468" pos="-0.030 0.003 -0.468" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> - <bone connected="true" end="0.105 -0.008 0.000" group="Limb" name="mHindLimb4Right" pivot="0.112 0.000 -0.061" pos="0.112 0.000 -0.061" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> + <bone aliases="avatar_mHindLimb1Right" connected="false" end="0.002 0.046 -0.491" group="Limb" name="mHindLimb1Right" pivot="-0.204 -0.129 -0.125" pos="-0.204 -0.129 -0.125" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="avatar_mHindLimb2Right" connected="true" end="-0.030 0.003 -0.468" group="Limb" name="mHindLimb2Right" pivot="0.002 0.046 -0.491" pos="0.002 0.046 -0.491" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="avatar_mHindLimb3Right" connected="true" end="0.112 0.000 -0.061" group="Limb" name="mHindLimb3Right" pivot="-0.030 0.003 -0.468" pos="-0.030 0.003 -0.468" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> + <bone aliases="avatar_mHindLimb4Right" connected="true" end="0.105 -0.008 0.000" group="Limb" name="mHindLimb4Right" pivot="0.112 0.000 -0.061" pos="0.112 0.000 -0.061" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> </bone> </bone> </bone> diff --git a/indra/newview/cube.dae b/indra/newview/cube.dae new file mode 100644 index 0000000000000000000000000000000000000000..085b2c73099e6bce7e46de084b04fa5666ff3784 --- /dev/null +++ b/indra/newview/cube.dae @@ -0,0 +1,103 @@ +<?xml version="1.0" encoding="UTF-8"?> +<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1"> + <asset> + <contributor> + modified from https://gist.github.com/wtsnz/bfa11c40e04594b260255b5dc7956f26 + </contributor> + <created>2018-10-25T16:29:03Z</created> + <modified>2022-02-18T00:00:00Z</modified> + <unit meter="1.000000"/> + <up_axis>Y_UP</up_axis> + </asset> + + <library_materials> + <material id="Blue" name="Blue"> + <instance_effect url="#effect_Blue"/> + </material> + </library_materials> + + + <library_effects> + <effect id="effect_Blue"> + <profile_COMMON> + <technique sid="common"> + <phong> + <ambient> + <color>0 0 0 1</color> + </ambient> + <diffuse> + <color>0.137255 0.403922 0.870588 1</color> + </diffuse> + <specular> + <color>0.5 0.5 0.5 1</color> + </specular> + <shininess> + <float>16</float> + </shininess> + <transparent opaque="A_ONE"> + <color>0 0 0 1</color> + </transparent> + <transparency> + <float>1</float> + </transparency> + <index_of_refraction> + <float>1</float> + </index_of_refraction> + </phong> + </technique> + </profile_COMMON> + </effect> + </library_effects> + + + <library_geometries> + <geometry id="F1" name="default_physics_shape"> + <mesh> + + <source id="cube-vertex-positions"> + <float_array id="ID2-array" count="72">-0.5 0.5 0.5 -0.5 -0.5 0.5 0.5 -0.5 0.5 0.5 0.5 0.5 -0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 -0.5 -0.5 0.5 -0.5 -0.5 -0.5 -0.5 0.5 -0.5 -0.5 0.5 -0.5 0.5 -0.5 -0.5 0.5 -0.5 0.5 0.5 -0.5 0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5 0.5 0.5 -0.5 0.5 0.5 -0.5 -0.5 0.5 0.5 -0.5 0.5 0.5 0.5 0.5 0.5 -0.5 0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5 0.5 -0.5 </float_array> + <technique_common> + <accessor source="#ID2-array" count="24" stride="3"> + <param name="X" type="float"/> + <param name="Y" type="float"/> + <param name="Z" type="float"/> + </accessor> + </technique_common> + </source> + + <vertices id="cube-vertices"> + <input semantic="POSITION" source="#cube-vertex-positions"/> + </vertices> + + <triangles count="12" material="geometryElement5"> + <input semantic="VERTEX" offset="0" source="#cube-vertices"/> + <p>0 1 2 0 2 3 4 5 6 4 6 7 8 9 10 8 10 11 12 13 14 12 14 15 16 17 18 16 18 19 20 21 22 20 22 23 </p> + </triangles> + + </mesh> + </geometry> + </library_geometries> + <library_visual_scenes> + + + <visual_scene id="reportScene"> + <!-- No Spaces allowed in Name --> + <node id="F1" name="Face1"> + <instance_geometry url="#F1"> + <bind_material> + <technique_common> + <instance_material symbol="geometryElement5" target="#Blue"/> + </technique_common> + </bind_material> + </instance_geometry> + </node> + </visual_scene> + </library_visual_scenes> + + + <scene> + <instance_visual_scene url="#reportScene"/> + </scene> + + +</COLLADA> diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index d1b12d87cbfd748aaf4c944b3b2e406c10bce512..b334a7773b6d15c1357362143ab07e4241b6c5d7 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -69,36 +69,9 @@ RenderShadowDetail 1 2 RenderUseStreamVBO 1 1 RenderFSAASamples 1 16 RenderMaxTextureIndex 1 16 +RenderGLContextCoreProfile 1 1 +RenderGLMultiThreaded 1 1 -// -// Low Graphics Settings (fixed function) -// -list LowFixedFunction -RenderAnisotropicLevel 1 0 -RenderAvatarCloth 1 0 -RenderAvatarLODFactor 1 0 -RenderAvatarPhysicsLODFactor 1 0 -RenderAvatarMaxNonImpostors 1 3 -RenderAvatarMaxComplexity 1 25000 -RenderAvatarVP 1 0 -RenderFarClip 1 64 -RenderFlexTimeFactor 1 0 -RenderGlowResolutionPow 1 8 -RenderLocalLights 1 0 -RenderMaxPartCount 1 0 -RenderObjectBump 1 0 -RenderReflectionDetail 1 0 -RenderTerrainDetail 1 0 -RenderTerrainLODFactor 1 1 -RenderTransparentWater 1 0 -RenderTreeLODFactor 1 0 -RenderVolumeLODFactor 1 1.125 -WindLightUseAtmosShaders 1 0 -RenderDeferred 1 0 -RenderDeferredSSAO 1 0 -RenderShadowDetail 1 0 -WLSkyDetail 1 48 -RenderFSAASamples 1 0 // // Low Graphics Settings @@ -110,7 +83,6 @@ RenderAvatarLODFactor 1 0 RenderAvatarPhysicsLODFactor 1 0 RenderAvatarMaxNonImpostors 1 3 RenderAvatarMaxComplexity 1 35000 -RenderAvatarVP 1 0 RenderFarClip 1 64 RenderFlexTimeFactor 1 0 RenderGlowResolutionPow 1 8 @@ -139,7 +111,6 @@ RenderAvatarCloth 1 0 RenderAvatarLODFactor 1 0.5 RenderAvatarMaxComplexity 1 100000 RenderAvatarPhysicsLODFactor 1 0.75 -RenderAvatarVP 1 1 RenderFarClip 1 96 RenderFlexTimeFactor 1 1.0 RenderGlowResolutionPow 1 8 @@ -168,7 +139,6 @@ RenderAvatarCloth 1 0 RenderAvatarLODFactor 1 1.0 RenderAvatarMaxComplexity 1 200000 RenderAvatarPhysicsLODFactor 1 1.0 -RenderAvatarVP 1 1 RenderFarClip 1 128 RenderFlexTimeFactor 1 1.0 RenderGlowResolutionPow 1 9 @@ -197,7 +167,6 @@ RenderAvatarCloth 1 0 RenderAvatarLODFactor 1 1.0 RenderAvatarMaxComplexity 1 250000 RenderAvatarPhysicsLODFactor 1 1.0 -RenderAvatarVP 1 1 RenderFarClip 1 128 RenderFlexTimeFactor 1 1.0 RenderGlowResolutionPow 1 10 @@ -226,7 +195,6 @@ RenderAvatarCloth 1 0 RenderAvatarLODFactor 1 1.0 RenderAvatarMaxComplexity 1 300000 RenderAvatarPhysicsLODFactor 1 1.0 -RenderAvatarVP 1 1 RenderFarClip 1 128 RenderFlexTimeFactor 1 1.0 RenderGlowResolutionPow 1 10 @@ -255,7 +223,6 @@ RenderAvatarCloth 1 0 RenderAvatarLODFactor 1 1.0 RenderAvatarMaxComplexity 1 350000 RenderAvatarPhysicsLODFactor 1 1.0 -RenderAvatarVP 1 1 RenderFarClip 1 128 RenderFlexTimeFactor 1 1.0 RenderGlowResolutionPow 1 10 @@ -283,7 +250,6 @@ RenderAnisotropicLevel 1 16 RenderAvatarCloth 1 1 RenderAvatarLODFactor 1 1.0 RenderAvatarPhysicsLODFactor 1 1.0 -RenderAvatarVP 1 1 RenderFarClip 1 256 RenderFlexTimeFactor 1 1.0 RenderGlowResolutionPow 1 10 @@ -307,83 +273,16 @@ RenderFSAASamples 1 16 // Class Unknown Hardware (unknown) // list Unknown -RenderVBOEnable 1 0 RenderShadowDetail 1 0 RenderDeferred 1 0 RenderDeferredSSAO 1 0 -// -// Class 0 Hardware (just old) -// -list Class0 -RenderVBOEnable 1 1 - -// -// Class 1 Hardware -// -list Class1 -RenderVBOEnable 1 1 - -// -// Class 2 Hardware -// -list Class2 -RenderVBOEnable 1 1 - -// -// Class 3 Hardware -// -list Class3 -RenderVBOEnable 1 1 - -// -// Class 4 Hardware -// -list Class4 -RenderVBOEnable 1 1 - -// -// Class 5 Hardware -// -list Class5 -RenderVBOEnable 1 1 - // // VRAM > 512MB // list VRAMGT512 RenderCompressTextures 1 0 -// -// No Pixel Shaders available -// -list NoPixelShaders -RenderAvatarVP 0 0 -RenderAvatarCloth 0 0 -RenderReflectionDetail 0 0 -WindLightUseAtmosShaders 0 0 -RenderDeferred 0 0 -RenderDeferredSSAO 0 0 -RenderShadowDetail 0 0 - -// -// No Vertex Shaders available -// -list NoVertexShaders -RenderAvatarVP 0 0 -RenderAvatarCloth 0 0 -RenderReflectionDetail 0 0 -WindLightUseAtmosShaders 0 0 -RenderDeferred 0 0 -RenderDeferredSSAO 0 0 -RenderShadowDetail 0 0 - -// -// GL_ARB_map_buffer_range exists -// -list MapBufferRange -RenderVBOMappingDisable 1 1 - // // AF Missing or AF < 2 // @@ -396,327 +295,28 @@ RenderAnisotropicLevel 0 0 list safe RenderAnisotropicLevel 1 0 RenderAvatarCloth 0 0 -RenderAvatarVP 0 0 RenderAvatarMaxNonImpostors 1 16 RenderAvatarMaxComplexity 1 80000 RenderObjectBump 0 0 RenderLocalLights 1 0 RenderMaxPartCount 1 1024 RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 RenderReflectionDetail 0 0 WindLightUseAtmosShaders 0 0 RenderDeferred 0 0 RenderDeferredSSAO 0 0 RenderShadowDetail 0 0 -// -// CPU based feature masks -// - -// 1Ghz or less (equiv) -list CPUSlow -RenderMaxPartCount 1 1024 - -// -// RAM based feature masks -// -list RAM256MB -RenderObjectBump 0 0 - -// -// Graphics card based feature masks -// -list OpenGLPre15 -RenderVBOEnable 1 0 - -list OpenGLPre30 -RenderDeferred 0 0 -RenderMaxTextureIndex 1 1 - list Intel RenderAnisotropicLevel 1 0 -RenderVBOEnable 1 0 RenderFSAASamples 1 0 +RenderGLMultiThreaded 1 0 +RenderGLContextCoreProfile 1 0 -list GeForce2 -RenderAnisotropicLevel 1 0 -RenderMaxPartCount 1 2048 -RenderTerrainDetail 1 0 -RenderVBOEnable 1 1 - -list SiS -UseOcclusion 0 0 - - -list Intel_830M -RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 - -list Intel_845G -RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 - -list Intel_855GM -RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 - -list Intel_865G -RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 - -list Intel_900 -RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 - -list Intel_915GM -RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 - -list Intel_915G -RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 - -list Intel_945GM -RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 - -list Intel_945G -RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 - -list Intel_950 -RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 - -list Intel_965 -RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 -UseOcclusion 0 0 - -list Intel_G33 -RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 - -list Intel_G45 -WindLightUseAtmosShaders 0 0 - -list Intel_Bear_Lake -RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 - -list Intel_Broadwater -RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 - -list Intel_Brookdale -RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 - -list Intel_Eaglelake -WindLightUseAtmosShaders 0 0 - -list Intel_Montara -RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 - -list Intel_Springdale -RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 - - -list ATI_FireGL_5200 -RenderVBOEnable 1 0 -WindLightUseAtmosShaders 0 0 - - -list ATI_Mobility_Radeon_7xxx -RenderVBOEnable 0 0 - -list ATI_Radeon_7xxx -RenderVBOEnable 0 0 - -list ATI_All-in-Wonder_Radeon -RenderVBOEnable 0 0 - -list ATI_All-in-Wonder_7500 -RenderVBOEnable 0 0 - -list ATI_Mobility_Radeon_9600 -Disregard96DefaultDrawDistance 1 0 - - -/// tweaked ATI to 96 Draw distance - -list ATI_Radeon_9000 -Disregard96DefaultDrawDistance 1 0 -list ATI_Radeon_9200 -Disregard96DefaultDrawDistance 1 0 -list ATI_Radeon_9500 -Disregard96DefaultDrawDistance 1 0 -list ATI_Radeon_9600 -Disregard96DefaultDrawDistance 1 0 - -/// tweaked ATI to 128 draw distance - -list ATI_Radeon_X300 -Disregard128DefaultDrawDistance 1 0 -RenderVBOEnable 1 0 -list ATI_Radeon_X400 -Disregard128DefaultDrawDistance 1 0 -RenderVBOEnable 1 0 -list ATI_Radeon_X500 -Disregard128DefaultDrawDistance 1 0 -RenderVBOEnable 1 0 -list ATI_Radeon_X600 -Disregard128DefaultDrawDistance 1 0 -RenderVBOEnable 1 0 -list ATI_Radeon_X700 -Disregard128DefaultDrawDistance 1 0 -RenderVBOEnable 1 0 -list ATI_Radeon_X1300 -Disregard128DefaultDrawDistance 1 0 -RenderVBOEnable 1 0 -UseStartScreen 0 0 -list ATI_Radeon_X1400 -Disregard128DefaultDrawDistance 1 0 -RenderVBOEnable 1 0 -list ATI_Radeon_X1500 -Disregard128DefaultDrawDistance 1 0 -RenderVBOEnable 1 0 -UseStartScreen 0 0 -list ATI_Radeon_X1600 -Disregard128DefaultDrawDistance 1 0 -RenderVBOEnable 1 0 -list ATI_Radeon_X1700 -Disregard128DefaultDrawDistance 1 0 -RenderVBOEnable 1 0 -list ATI_Mobility_Radeon_X1xxx -Disregard128DefaultDrawDistance 1 0 -RenderVBOEnable 1 0 - -list ATI_Radeon_HD_2300 -Disregard128DefaultDrawDistance 1 0 -list ATI_Radeon_HD_2400 -Disregard128DefaultDrawDistance 1 0 -list ATI_ASUS_AH24xx -Disregard128DefaultDrawDistance 1 0 - - -// Avatar hardware skinning causes invisible avatars -// on various ATI chipsets on drivers before 8.2 - -list ATIOldDriver -RenderAvatarVP 0 0 -RenderAvatarCloth 0 0 -RenderVBOEnable 1 0 - -// ATI cards generally perform better when not using VBOs for streaming data - -list ATI +// AMD cards generally perform better when not using VBOs for streaming data +// AMD cards also prefer an OpenGL Compatibility Profile Context +list AMD RenderUseStreamVBO 1 0 +RenderGLContextCoreProfile 1 0 -// Disable vertex buffer objects by default for ATI cards with little video memory -list ATIVramLT256 -RenderVBOEnable 1 0 - -/// Tweaked NVIDIA - -list NVIDIA_GeForce_FX_5100 -Disregard96DefaultDrawDistance 1 0 -list NVIDIA_GeForce_FX_5200 -Disregard96DefaultDrawDistance 1 0 -list NVIDIA_GeForce_FX_5500 -Disregard96DefaultDrawDistance 1 0 -list NVIDIA_GeForce_FX_5600 -Disregard96DefaultDrawDistance 1 0 - -list NVIDIA_GeForce_FX_Go5100 -Disregard96DefaultDrawDistance 1 0 -list NVIDIA_GeForce_FX_Go5200 -Disregard96DefaultDrawDistance 1 0 -list NVIDIA_GeForce_FX_Go5300 -Disregard96DefaultDrawDistance 1 0 -list NVIDIA_GeForce_FX_Go5500 -Disregard96DefaultDrawDistance 1 0 -list NVIDIA_GeForce_FX_Go5600 -Disregard96DefaultDrawDistance 1 0 - -list NVIDIA_GeForce_6100 -Disregard128DefaultDrawDistance 1 0 -list NVIDIA_GeForce_6200 -Disregard128DefaultDrawDistance 1 0 -list NVIDIA_GeForce_6500 -Disregard128DefaultDrawDistance 1 0 -list NVIDIA_GeForce_6600 -Disregard128DefaultDrawDistance 1 0 - -list NVIDIA_G73 -Disregard128DefaultDrawDistance 1 0 - -list NVIDIA_GeForce_Go_6100 -RenderVBOEnable 1 0 -Disregard128DefaultDrawDistance 1 0 -list NVIDIA_GeForce_Go_6200 -RenderVBOEnable 1 0 -Disregard128DefaultDrawDistance 1 0 -list NVIDIA_GeForce_Go_6500 -RenderVBOEnable 1 0 -Disregard128DefaultDrawDistance 1 0 -list NVIDIA_GeForce_Go_6600 -RenderVBOEnable 1 0 -Disregard128DefaultDrawDistance 1 0 -list NVIDIA_GeForce_Go_6700 -RenderVBOEnable 1 0 -Disregard128DefaultDrawDistance 1 0 -list NVIDIA_GeForce_Go_6800 -RenderVBOEnable 1 0 -Disregard128DefaultDrawDistance 1 0 -list NVIDIA_GeForce_Go_6 -RenderVBOEnable 1 0 -Disregard128DefaultDrawDistance 1 0 - -list NVIDIA_GeForce_7000 -RenderShaderLightingMaxLevel 1 2 -list NVIDIA_GeForce_7100 -RenderShaderLightingMaxLevel 1 2 -list NVIDIA_GeForce_7200 -Disregard128DefaultDrawDistance 1 0 -RenderShaderLightingMaxLevel 1 2 -list NVIDIA_GeForce_7300 -Disregard128DefaultDrawDistance 1 0 -RenderShaderLightingMaxLevel 1 2 -list NVIDIA_GeForce_7400 -Disregard128DefaultDrawDistance 1 0 -RenderShaderLightingMaxLevel 1 2 -list NVIDIA_GeForce_7500 -RenderShaderLightingMaxLevel 1 2 -list NVIDIA_GeForce_7600 -RenderShaderLightingMaxLevel 1 2 -list NVIDIA_GeForce_7700 -RenderShaderLightingMaxLevel 1 2 -list NVIDIA_GeForce_7800 -RenderShaderLightingMaxLevel 1 2 -list NVIDIA_GeForce_7900 -RenderShaderLightingMaxLevel 1 2 - -list NVIDIA_GeForce_Go_7200 -Disregard128DefaultDrawDistance 1 0 -RenderShaderLightingMaxLevel 1 2 -list NVIDIA_GeForce_Go_7300 -Disregard128DefaultDrawDistance 1 0 -RenderShaderLightingMaxLevel 1 2 -list NVIDIA_GeForce_Go_7300_LE -RenderShaderLightingMaxLevel 1 2 -list NVIDIA_GeForce_Go_7400 -Disregard128DefaultDrawDistance 1 0 -RenderShaderLightingMaxLevel 1 2 -list NVIDIA_GeForce_Go_7600 -RenderShaderLightingMaxLevel 1 2 -list NVIDIA_GeForce_Go_7700 -RenderShaderLightingMaxLevel 1 2 -list NVIDIA_GeForce_Go_7800 -RenderShaderLightingMaxLevel 1 2 -list NVIDIA_GeForce_Go_7900 -RenderShaderLightingMaxLevel 1 2 diff --git a/indra/newview/featuretable_linux.txt b/indra/newview/featuretable_linux.txt index e039b218fe5a124b5a218c7d415adb8e3ae85e16..ad114880095353f829cf58e29fa6f26cb6b42dcf 100644 --- a/indra/newview/featuretable_linux.txt +++ b/indra/newview/featuretable_linux.txt @@ -69,6 +69,8 @@ RenderShadowDetail 1 2 RenderUseStreamVBO 1 1 RenderFSAASamples 1 16 RenderMaxTextureIndex 1 16 +RenderGLContextCoreProfile 1 1 +RenderGLMultiThreaded 1 1 // // Low Graphics Settings (fixed function) diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index df5b6de8adda43e949ea7fe66c85f56eed2f2a45..37d1c56907ed17941508b036207af42357973c23 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -69,36 +69,8 @@ RenderShadowDetail 1 2 RenderUseStreamVBO 1 1 RenderFSAASamples 1 16 RenderMaxTextureIndex 1 16 - -// -// Low Graphics Settings (fixed function) -// -list LowFixedFunction -RenderAnisotropicLevel 1 0 -RenderAvatarCloth 1 0 -RenderAvatarLODFactor 1 0 -RenderAvatarPhysicsLODFactor 1 0 -RenderAvatarMaxNonImpostors 1 3 -RenderAvatarMaxComplexity 1 25000 -RenderAvatarVP 1 0 -RenderFarClip 1 64 -RenderFlexTimeFactor 1 0 -RenderGlowResolutionPow 1 8 -RenderLocalLights 1 0 -RenderMaxPartCount 1 0 -RenderObjectBump 1 0 -RenderReflectionDetail 1 0 -RenderTerrainDetail 1 0 -RenderTerrainLODFactor 1 1 -RenderTransparentWater 1 0 -RenderTreeLODFactor 1 0 -RenderVolumeLODFactor 1 0.5 -WindLightUseAtmosShaders 1 0 -RenderDeferred 1 0 -RenderDeferredSSAO 1 0 -RenderShadowDetail 1 0 -WLSkyDetail 1 48 -RenderFSAASamples 1 0 +RenderGLContextCoreProfile 1 0 +RenderGLMultiThreaded 1 0 // // Low Graphics Settings @@ -110,7 +82,6 @@ RenderAvatarLODFactor 1 0 RenderAvatarPhysicsLODFactor 1 0 RenderAvatarMaxNonImpostors 1 3 RenderAvatarMaxComplexity 1 35000 -RenderAvatarVP 1 0 RenderFarClip 1 64 RenderFlexTimeFactor 1 0 RenderGlowResolutionPow 1 8 @@ -139,7 +110,6 @@ RenderAvatarCloth 1 0 RenderAvatarLODFactor 1 0.5 RenderAvatarMaxComplexity 1 100000 RenderAvatarPhysicsLODFactor 1 0.75 -RenderAvatarVP 1 1 RenderFarClip 1 96 RenderFlexTimeFactor 1 1.0 RenderGlowResolutionPow 1 8 @@ -168,7 +138,6 @@ RenderAvatarCloth 1 0 RenderAvatarLODFactor 1 1.0 RenderAvatarMaxComplexity 1 200000 RenderAvatarPhysicsLODFactor 1 1.0 -RenderAvatarVP 1 1 RenderFarClip 1 128 RenderFlexTimeFactor 1 1.0 RenderGlowResolutionPow 1 9 @@ -197,7 +166,6 @@ RenderAvatarCloth 1 0 RenderAvatarLODFactor 1 1.0 RenderAvatarMaxComplexity 1 250000 RenderAvatarPhysicsLODFactor 1 1.0 -RenderAvatarVP 1 1 RenderFarClip 1 128 RenderFlexTimeFactor 1 1.0 RenderGlowResolutionPow 1 9 @@ -226,7 +194,6 @@ RenderAvatarCloth 1 0 RenderAvatarLODFactor 1 1.0 RenderAvatarMaxComplexity 1 300000 RenderAvatarPhysicsLODFactor 1 1.0 -RenderAvatarVP 1 1 RenderFarClip 1 128 RenderFlexTimeFactor 1 1.0 RenderGlowResolutionPow 1 9 @@ -255,7 +222,6 @@ RenderAvatarCloth 1 0 RenderAvatarLODFactor 1 1.0 RenderAvatarMaxComplexity 1 350000 RenderAvatarPhysicsLODFactor 1 1.0 -RenderAvatarVP 1 1 RenderFarClip 1 128 RenderFlexTimeFactor 1 1.0 RenderGlowResolutionPow 1 10 @@ -283,7 +249,6 @@ RenderAnisotropicLevel 1 8 RenderAvatarCloth 1 1 RenderAvatarLODFactor 1 1.0 RenderAvatarPhysicsLODFactor 1 1.0 -RenderAvatarVP 1 1 RenderFarClip 1 256 RenderFlexTimeFactor 1 1.0 RenderGlowResolutionPow 1 10 @@ -307,72 +272,10 @@ RenderFSAASamples 1 2 // Class Unknown Hardware (unknown) // list Unknown -RenderVBOEnable 1 0 RenderShadowDetail 1 0 RenderDeferred 1 0 RenderDeferredSSAO 1 0 -// -// Class 0 Hardware (just old) -// -list Class0 -RenderVBOEnable 1 1 - -// -// Class 1 Hardware -// -list Class1 -RenderVBOEnable 1 1 - -// -// Class 2 Hardware -// -list Class2 -RenderVBOEnable 1 1 - -// -// Class 3 Hardware -// -list Class3 -RenderVBOEnable 1 1 - -// -// Class 4 Hardware -// -list Class4 -RenderVBOEnable 1 1 - -// -// Class 5 Hardware -// -list Class5 -RenderVBOEnable 1 1 - -// -// No Pixel Shaders available -// -list NoPixelShaders -RenderAvatarVP 0 0 -RenderAvatarCloth 0 0 -RenderReflectionDetail 0 0 -WindLightUseAtmosShaders 0 0 -RenderDeferred 0 0 -RenderDeferredSSAO 0 0 -RenderUseAdvancedAtmospherics 0 0 -RenderShadowDetail 0 0 - -// -// No Vertex Shaders available -// -list NoVertexShaders -RenderAvatarVP 0 0 -RenderAvatarCloth 0 0 -RenderReflectionDetail 0 0 -WindLightUseAtmosShaders 0 0 -RenderDeferred 0 0 -RenderDeferredSSAO 0 0 -RenderUseAdvancedAtmospherics 0 0 -RenderShadowDetail 0 0 // // VRAM > 512MB @@ -393,45 +296,22 @@ RenderAnisotropicLevel 0 0 list safe RenderAnisotropicLevel 1 0 RenderAvatarCloth 0 0 -RenderAvatarVP 0 0 RenderAvatarMaxNonImpostors 1 16 RenderAvatarMaxComplexity 1 80000 RenderObjectBump 0 0 RenderLocalLights 1 0 RenderMaxPartCount 1 1024 RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 RenderReflectionDetail 0 0 WindLightUseAtmosShaders 0 0 RenderDeferred 0 0 RenderDeferredSSAO 0 0 RenderShadowDetail 0 0 -// -// CPU based feature masks -// - -// 1Ghz or less (equiv) -list CPUSlow -RenderMaxPartCount 1 1024 - -// -// RAM based feature masks -// -list RAM256MB -RenderObjectBump 0 0 - -// -// Graphics card based feature masks -// -list OpenGLPre15 -RenderVBOEnable 1 0 - - list TexUnit8orLess RenderDeferredSSAO 0 0 -list ATI +list AMD RenderDeferredSSAO 1 0 list Intel @@ -439,191 +319,6 @@ RenderAnisotropicLevel 1 0 RenderLocalLights 1 0 RenderFSAASamples 1 0 -list GeForce2 -RenderAnisotropicLevel 1 0 -RenderLocalLights 1 0 -RenderMaxPartCount 1 2048 -RenderTerrainDetail 1 0 -RenderVBOEnable 1 1 - -list Intel_830M -RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 - -list Intel_845G -RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 - -list Intel_855GM -RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 - -list Intel_865G -RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 - -list Intel_900 -RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 - -list Intel_915GM -RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 - -list Intel_915G -RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 - -list Intel_945GM -RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 - -list Intel_945G -RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 - -list Intel_950 -RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 -RenderGround 1 0 - -list Intel_965 -RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 -UseOcclusion 0 0 - -list Intel_G33 -RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 - -list Intel_Bear_Lake -RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 - -list Intel_Broadwater -RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 - -list Intel_Brookdale -RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 - -list Intel_X3100 -WindLightUseAtmosShaders 0 0 - -list Intel_Montara -RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 - -list Intel_Springdale -RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 - -list ATI_Mobility_Radeon_9600 -Disregard96DefaultDrawDistance 1 0 - -list NVIDIA_GeForce_8600 -RenderTextureMemoryMultiple 1 1 -UseOcclusion 0 0 - -/// tweaked ATI to 96 Draw distance - -list ATI_Radeon_9000 -Disregard96DefaultDrawDistance 1 0 -list ATI_Radeon_9200 -Disregard96DefaultDrawDistance 1 0 -list ATI_Radeon_9500 -Disregard96DefaultDrawDistance 1 0 -list ATI_Radeon_9600 -Disregard96DefaultDrawDistance 1 0 - -/// tweaked ATI to 128 draw distance - -list ATI_Radeon_X300 -Disregard128DefaultDrawDistance 1 0 -list ATI_Radeon_X400 -Disregard128DefaultDrawDistance 1 0 -list ATI_Radeon_X500 -Disregard128DefaultDrawDistance 1 0 -list ATI_Radeon_X600 -Disregard128DefaultDrawDistance 1 0 -list ATI_Radeon_X700 -Disregard128DefaultDrawDistance 1 0 -list ATI_Radeon_X1300 -Disregard128DefaultDrawDistance 1 0 -list ATI_Radeon_X1400 -Disregard128DefaultDrawDistance 1 0 -list ATI_Radeon_X1500 -Disregard128DefaultDrawDistance 1 0 -list ATI_Radeon_X1600 -Disregard128DefaultDrawDistance 1 0 -list ATI_Radeon_X1700 -Disregard128DefaultDrawDistance 1 0 -list ATI_Mobility_Radeon_X1xxx -Disregard128DefaultDrawDistance 1 0 - -/// Tweaked NVIDIA - -list NVIDIA_GeForce_FX_5100 -Disregard96DefaultDrawDistance 1 0 -list NVIDIA_GeForce_FX_5200 -Disregard96DefaultDrawDistance 1 0 -list NVIDIA_GeForce_FX_5500 -Disregard96DefaultDrawDistance 1 0 - -list NVIDIA_GeForce_FX_Go5100 -Disregard96DefaultDrawDistance 1 0 -list NVIDIA_GeForce_FX_Go5200 -Disregard96DefaultDrawDistance 1 0 -list NVIDIA_GeForce_FX_Go5300 -Disregard96DefaultDrawDistance 1 0 -list NVIDIA_GeForce_FX_Go5500 -Disregard96DefaultDrawDistance 1 0 -list NVIDIA_GeForce_FX_Go5600 -Disregard96DefaultDrawDistance 1 0 - -list NVIDIA_GeForce_6100 -Disregard128DefaultDrawDistance 1 0 -list NVIDIA_GeForce_6200 -Disregard128DefaultDrawDistance 1 0 -list NVIDIA_GeForce_6500 -Disregard128DefaultDrawDistance 1 0 -list NVIDIA_GeForce_6600 -Disregard128DefaultDrawDistance 1 0 - - -list NVIDIA_GeForce_Go_6100 -RenderVBOEnable 1 0 -Disregard128DefaultDrawDistance 1 0 -list NVIDIA_GeForce_Go_6200 -RenderVBOEnable 1 0 -Disregard128DefaultDrawDistance 1 0 -list NVIDIA_GeForce_Go_6500 -RenderVBOEnable 1 0 -Disregard128DefaultDrawDistance 1 0 -list NVIDIA_GeForce_Go_6600 -RenderVBOEnable 1 0 -Disregard128DefaultDrawDistance 1 0 -list NVIDIA_GeForce_Go_6700 -RenderVBOEnable 1 0 -Disregard128DefaultDrawDistance 1 0 -list NVIDIA_GeForce_Go_6800 -RenderVBOEnable 1 0 -Disregard128DefaultDrawDistance 1 0 -list NVIDIA_GeForce_Go_6 -RenderVBOEnable 1 0 -Disregard128DefaultDrawDistance 1 0 - -list NVIDIA_GeForce_7200 -Disregard128DefaultDrawDistance 1 0 -list NVIDIA_GeForce_7300 -Disregard128DefaultDrawDistance 1 0 -list NVIDIA_GeForce_7400 -Disregard128DefaultDrawDistance 1 0 +list OSX_10_6_8 +RenderDeferred 0 0 -list NVIDIA_GeForce_Go_7200 -Disregard128DefaultDrawDistance 1 0 -list NVIDIA_GeForce_Go_7300 -Disregard128DefaultDrawDistance 1 0 -list NVIDIA_GeForce_Go_7400 -Disregard128DefaultDrawDistance 1 0 diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi index 019ac4423d36cab0710c7c5e83a8a9d31fe6e768..c782c901c37d4fb4b38fc7470f06a3467295694e 100644 --- a/indra/newview/installers/windows/installer_template.nsi +++ b/indra/newview/installers/windows/installer_template.nsi @@ -343,11 +343,29 @@ Call CloseSecondLife # Make sure Second Life not currently running ClearErrors +INSTALL_FILES_START: + Call RemoveProgFilesOnInst # Remove existing files to prevent certain errors when running the new version of the viewer # This placeholder is replaced by the complete list of all the files in the installer, by viewer_manifest.py %%INSTALL_FILES%% +IfErrors 0 INSTALL_FILES_DONE + StrCmp $SKIP_DIALOGS "true" INSTALL_FILES_DONE + MessageBox MB_ABORTRETRYIGNORE $(ErrorSecondLifeInstallRetry) IDABORT INSTALL_FILES_CANCEL IDRETRY INSTALL_FILES_START + # MB_ABORTRETRYIGNORE does not accept IDIGNORE + Goto INSTALL_FILES_DONE + +INSTALL_FILES_CANCEL: + # We are quiting, cleanup. + # Silence warnings from RemoveProgFilesOnInst. + StrCpy $SKIP_DIALOGS "true" + Call RemoveProgFilesOnInst + MessageBox MB_OK $(ErrorSecondLifeInstallSupport) + Quit + +INSTALL_FILES_DONE: + # Pass the installer's language to the client to use as a default StrCpy $SHORTCUT_LANG_PARAM "--set InstallLanguage $(LanguageCode)" @@ -574,7 +592,9 @@ Function RemoveProgFilesOnInst Push $0 StrCpy $0 0 -PREINSTALLREMOVE: +ClearErrors + +PREINSTALL_REMOVE: # Remove old SecondLife.exe to invalidate any old shortcuts to it that may be in non-standard locations. See MAINT-3575 Delete "$INSTDIR\$INSTEXE" @@ -594,17 +614,17 @@ RMDir /r "$INSTDIR\llplugin" IntOp $0 $0 + 1 -IfErrors 0 PREINSTALLDONE - IntCmp $0 1 PREINSTALLREMOVE #try again once - StrCmp $SKIP_DIALOGS "true" PREINSTALLDONE - MessageBox MB_ABORTRETRYIGNORE $(CloseSecondLifeInstRM) IDABORT PREINSTALLFAIL IDRETRY PREINSTALLREMOVE +IfErrors 0 PREINSTALL_DONE + IntCmp $0 1 PREINSTALL_REMOVE #try again once + StrCmp $SKIP_DIALOGS "true" PREINSTALL_DONE + MessageBox MB_ABORTRETRYIGNORE $(CloseSecondLifeInstRM) IDABORT PREINSTALL_FAIL IDRETRY PREINSTALL_REMOVE # MB_ABORTRETRYIGNORE does not accept IDIGNORE - Goto PREINSTALLDONE + Goto PREINSTALL_DONE -PREINSTALLFAIL: +PREINSTALL_FAIL: Quit -PREINSTALLDONE: +PREINSTALL_DONE: # We are no longer including release notes with the viewer, so remove them. Delete "$SMPROGRAMS\$INSTSHORTCUT\SL Release Notes.lnk" diff --git a/indra/newview/installers/windows/lang_da.nsi b/indra/newview/installers/windows/lang_da.nsi index 648ddbfb8502e1bee254d26c8c01ce8e40d1026c..73f23086be22efa016f61757a0246ad56a929a6c 100644 Binary files a/indra/newview/installers/windows/lang_da.nsi and b/indra/newview/installers/windows/lang_da.nsi differ diff --git a/indra/newview/installers/windows/lang_de.nsi b/indra/newview/installers/windows/lang_de.nsi index 2556a262e234242b8d34bb36555c3a3243cc9dba..f67a09f84c6f81d44099fcfab04729e8af9e0850 100755 --- a/indra/newview/installers/windows/lang_de.nsi +++ b/indra/newview/installers/windows/lang_de.nsi @@ -73,6 +73,10 @@ LangString CloseSecondLifeUnInstMB ${LANG_GERMAN} "Second Life kann nicht entfer ; CheckNetworkConnection LangString CheckNetworkConnectionDP ${LANG_GERMAN} "Prüfe Netzwerkverbindung..." +; error during installation +LangString ErrorSecondLifeInstallRetry ${LANG_GERMAN} "Second Life konnte nicht korrekt installiert werden, einige Dateien wurden eventuell nicht korrekt von der Installationroutine kopiert." +LangString ErrorSecondLifeInstallSupport ${LANG_GERMAN} "Bitte laden Sie den Viewer erneut von https://secondlife.com/support/downloads/ und versuchen Sie die Installation erneut. Sollte das Problem weiterhin bestehen, dann kontaktieren Sie unseren Support unter https://support.secondlife.com." + ; ask to remove user's data files LangString RemoveDataFilesMB ${LANG_GERMAN} "Möchten Sie alle anderen zu Second Life gehörigen Dateien ebenfalls ENTFERNEN?$\n$\nWir empfehlen, die Einstellungen und Cache-Dateien zu behalten, wenn Sie andere Versionen von Second Life installiert haben oder eine Deinstallation durchführen, um Second Life auf eine neuere Version zu aktualisieren." diff --git a/indra/newview/installers/windows/lang_en-us.nsi b/indra/newview/installers/windows/lang_en-us.nsi index b924ae39a4ed75fac65a3c2c11a9602a9b6bce23..a375c55541a5f4111899ff3128da4f903fbfbf86 100644 Binary files a/indra/newview/installers/windows/lang_en-us.nsi and b/indra/newview/installers/windows/lang_en-us.nsi differ diff --git a/indra/newview/installers/windows/lang_es.nsi b/indra/newview/installers/windows/lang_es.nsi index ee30651a38983aec3b199fb9f7c27adf122d595d..364cc9f67e2f9aa7b05498d848d38b56ab22e429 100755 Binary files a/indra/newview/installers/windows/lang_es.nsi and b/indra/newview/installers/windows/lang_es.nsi differ diff --git a/indra/newview/installers/windows/lang_fr.nsi b/indra/newview/installers/windows/lang_fr.nsi index 7cd90ec3148fdd30e01e9c2aee2408511618eb67..2f34c0c87a1552dd0632baf63dd53cc9bf1edf7b 100755 Binary files a/indra/newview/installers/windows/lang_fr.nsi and b/indra/newview/installers/windows/lang_fr.nsi differ diff --git a/indra/newview/installers/windows/lang_it.nsi b/indra/newview/installers/windows/lang_it.nsi index 194062da9a8ea42fb5bb5265b974764fdb9d263e..51214d3a9ce88d5a594a6ab02ea3b8f4b09af8e2 100755 Binary files a/indra/newview/installers/windows/lang_it.nsi and b/indra/newview/installers/windows/lang_it.nsi differ diff --git a/indra/newview/installers/windows/lang_ja.nsi b/indra/newview/installers/windows/lang_ja.nsi index a54005ba1466c4e82247fa46d144ad9037b00262..296703d1a3e94080fe18709d1e5ac3031887cde7 100755 Binary files a/indra/newview/installers/windows/lang_ja.nsi and b/indra/newview/installers/windows/lang_ja.nsi differ diff --git a/indra/newview/installers/windows/lang_pl.nsi b/indra/newview/installers/windows/lang_pl.nsi index 355d806866959266519b0c3069ac600ff23a0c29..299645bbb78010298d43366cfa5dd3299081a096 100644 Binary files a/indra/newview/installers/windows/lang_pl.nsi and b/indra/newview/installers/windows/lang_pl.nsi differ diff --git a/indra/newview/installers/windows/lang_pt-br.nsi b/indra/newview/installers/windows/lang_pt-br.nsi index 97f5d2b44a946ea8d58ae8eec42a1a966d4d30a3..542c8654b5bffbe4d6f57a90c878c329ce7eb997 100755 Binary files a/indra/newview/installers/windows/lang_pt-br.nsi and b/indra/newview/installers/windows/lang_pt-br.nsi differ diff --git a/indra/newview/installers/windows/lang_ru.nsi b/indra/newview/installers/windows/lang_ru.nsi index 65a9f4846d42a2331b25181fe99750e6e7e7682c..4e53a4957d49d2cf9b11df0b1ac0849a3101dfaa 100755 Binary files a/indra/newview/installers/windows/lang_ru.nsi and b/indra/newview/installers/windows/lang_ru.nsi differ diff --git a/indra/newview/installers/windows/lang_tr.nsi b/indra/newview/installers/windows/lang_tr.nsi index e71886cc6609f89a090c31a2c5d9c6cb714dc907..bae5029ad1ce56a2fd347c95de656848400c052e 100755 Binary files a/indra/newview/installers/windows/lang_tr.nsi and b/indra/newview/installers/windows/lang_tr.nsi differ diff --git a/indra/newview/installers/windows/lang_zh.nsi b/indra/newview/installers/windows/lang_zh.nsi index f5f0c6cbdf6539d8683151de663a23a58ede11c1..7922d9df5228d652bf08955f00c0eb62b6794965 100755 Binary files a/indra/newview/installers/windows/lang_zh.nsi and b/indra/newview/installers/windows/lang_zh.nsi differ diff --git a/indra/newview/licenses-mac.txt b/indra/newview/licenses-mac.txt index d0747ccd0309c4221c900836f299879e9af6e08b..fba6a55da345572ae009a227a711e1832a22d7df 100644 --- a/indra/newview/licenses-mac.txt +++ b/indra/newview/licenses-mac.txt @@ -693,3 +693,29 @@ From Vivox: Attn: customer support 40 Speen Street Suite 402 Framingham, MA 01701 + + +============= +meshoptimizer +============= +MIT License + +Copyright (c) 2016-2021 Arseny Kapoulkine + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/indra/newview/licenses-win32.txt b/indra/newview/licenses-win32.txt index cdc50f679d0082865966b08cf7ffed0c896b0fc6..837d92139d5c9a5f48aff4d423b0aa854e5702b9 100644 --- a/indra/newview/licenses-win32.txt +++ b/indra/newview/licenses-win32.txt @@ -769,3 +769,30 @@ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +============= +meshoptimizer +============= +MIT License + +Copyright (c) 2016-2021 Arseny Kapoulkine + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 0099fc440f216b5605095894fad35800dad0f02f..0562f8ee389b114fa14e6dd0320fef0e94ae89c2 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -299,7 +299,7 @@ bool handleSlowMotionAnimation(const LLSD& newvalue) void LLAgent::setCanEditParcel() // called via mParcelChangedSignal { - bool can_edit = LLToolMgr::getInstanceFast()->canEdit(); + bool can_edit = LLToolMgr::getInstance()->canEdit(); gAgent.mCanEditParcel = can_edit; } @@ -319,7 +319,7 @@ bool LLAgent::isActionAllowed(const LLSD& sdname) if (channel->getSessionName().empty() && channel->getSessionID().isNull()) { // default channel - allow_agent_voice = LLViewerParcelMgr::getInstanceFast()->allowAgentVoice(); + allow_agent_voice = LLViewerParcelMgr::getInstance()->allowAgentVoice(); } else { @@ -581,7 +581,7 @@ void LLAgent::onAppFocusGained() // if (CAMERA_MODE_MOUSELOOK == gAgentCamera.getCameraMode()) // { // gAgentCamera.changeCameraToDefault(); -// LLToolMgr::getInstanceFast()->clearSavedTool(); +// LLToolMgr::getInstance()->clearSavedTool(); // } } @@ -750,6 +750,15 @@ void LLAgent::moveYaw(F32 mag, bool reset_view) setControlFlags(AGENT_CONTROL_YAW_NEG); } + U32 mask = AGENT_CONTROL_YAW_POS | AGENT_CONTROL_YAW_NEG; + if ((getControlFlags() & mask) == mask) + { + // Rotation into both directions should cancel out + // But keep sending controls to simulator, + // it's needed for script based controls + gAgentCamera.setYawKey(0); + } + if (reset_view) { gAgentCamera.resetView(mMovementResetCamera); @@ -795,7 +804,7 @@ BOOL LLAgent::canFly() LLViewerRegion* regionp = getRegion(); if (regionp && regionp->getBlockFly()) return FALSE; - LLParcel* parcel = LLViewerParcelMgr::getInstanceFast()->getAgentParcel(); + LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); if (!parcel) return FALSE; // Allow owners to fly on their own land. @@ -1002,11 +1011,11 @@ void LLAgent::setRegion(LLViewerRegion *regionp) setPositionAgent(getPositionAgent() - delta); - LLVector3 camera_position_agent = LLViewerCamera::getInstanceFast()->getOrigin(); - LLViewerCamera::getInstanceFast()->setOrigin(camera_position_agent - delta); + LLVector3 camera_position_agent = LLViewerCamera::getInstance()->getOrigin(); + LLViewerCamera::getInstance()->setOrigin(camera_position_agent - delta); // Update all of the regions. - LLWorld::getInstanceFast()->updateAgentOffset(agent_offset_global); + LLWorld::getInstance()->updateAgentOffset(agent_offset_global); // Hack to keep sky in the agent's region, otherwise it may get deleted - DJS 08/02/02 // *TODO: possibly refactor into gSky->setAgentRegion(regionp)? -Brad @@ -1040,11 +1049,11 @@ void LLAgent::setRegion(LLViewerRegion *regionp) delta.setVec(regionp->getOriginGlobal()); setPositionAgent(getPositionAgent() - delta); - LLVector3 camera_position_agent = LLViewerCamera::getInstanceFast()->getOrigin(); - LLViewerCamera::getInstanceFast()->setOrigin(camera_position_agent - delta); + LLVector3 camera_position_agent = LLViewerCamera::getInstance()->getOrigin(); + LLViewerCamera::getInstance()->setOrigin(camera_position_agent - delta); // Update all of the regions. - LLWorld::getInstanceFast()->updateAgentOffset(mAgentOriginGlobal); + LLWorld::getInstance()->updateAgentOffset(mAgentOriginGlobal); if (regionp->capabilitiesReceived()) { @@ -1070,7 +1079,7 @@ void LLAgent::setRegion(LLViewerRegion *regionp) // Must shift hole-covering water object locations because local // coordinate frame changed. - LLWorld::getInstanceFast()->updateWaterObjects(); + LLWorld::getInstance()->updateWaterObjects(); // keep a list of regions we've been too // this is just an interesting stat, logged at the dataserver @@ -1078,7 +1087,7 @@ void LLAgent::setRegion(LLViewerRegion *regionp) U64 handle = regionp->getHandle(); mRegionsVisited.insert(handle); - LLSelectMgr::getInstanceFast()->updateSelectionCenter(); + LLSelectMgr::getInstance()->updateSelectionCenter(); // LLFloaterMove::sUpdateFlyingStatus(); // [RLVa:KB] - Checked: 2011-05-27 (RLVa-1.4.0a) | Added: RLVa-1.4.0a @@ -1587,7 +1596,7 @@ void LLAgent::resetControlFlags() //----------------------------------------------------------------------------- void LLAgent::setAFK() { - if (!gAgent.getRegion()) + if (gNonInteractive || !gAgent.getRegion()) { // Don't set AFK if we're not talking to a region yet. return; @@ -1698,7 +1707,7 @@ void LLAgent::startAutoPilotGlobal( LLVector3d intersection; LLVector3 normal; LLViewerObject *hit_obj; - F32 heightDelta = LLWorld::getInstanceFast()->resolveStepHeightGlobal(NULL, target_global, trace_target, intersection, normal, &hit_obj); + F32 heightDelta = LLWorld::getInstance()->resolveStepHeightGlobal(NULL, target_global, trace_target, intersection, normal, &hit_obj); if (stop_distance > 0.f) { @@ -1775,7 +1784,7 @@ void LLAgent::setAutoPilotTargetGlobal(const LLVector3d &target_global) LLVector3 groundNorm; LLViewerObject *obj; - LLWorld::getInstanceFast()->resolveStepHeightGlobal(NULL, target_global, traceEndPt, targetOnGround, groundNorm, &obj); + LLWorld::getInstance()->resolveStepHeightGlobal(NULL, target_global, traceEndPt, targetOnGround, groundNorm, &obj); // Note: this might malfunction for sitting agent, since pelvis stays same, but agent's position becomes lower // But for autopilot to work we assume that agent is standing and ready to go. F64 target_height = llmax((F64)gAgentAvatarp->getPelvisToFoot(), target_global.mdV[VZ] - targetOnGround.mdV[VZ]); @@ -2111,6 +2120,27 @@ void LLAgent::updateAgentPosition(const F32 dt, const F32 yaw_radians, const S32 // gAgentCamera.updateLookAt(mouse_x, mouse_y); + + // When agent has no parents, position updates come from setPositionAgent() + // But when agent has a parent (ex: is seated), position remains unchanged + // relative to parent and no parent's position update trigger + // setPositionAgent(). + // But EEP's sky track selection still needs an update if agent has a parent + // and parent moves (ex: vehicles). + if (isAgentAvatarValid() + && gAgentAvatarp->getParent() + && !mOnPositionChanged.empty() + ) + { + LLVector3d new_position = getPositionGlobal(); + if ((mLastTestGlobal - new_position).lengthSquared() > 1.0) + { + // If the position has changed by more than 1 meter since the last time we triggered. + // filters out some noise. + mLastTestGlobal = new_position; + mOnPositionChanged(mFrameAgent.getOrigin(), new_position); + } + } } // friends and operators @@ -2233,8 +2263,8 @@ U8 LLAgent::getRenderState() stopTyping(); } - if ((!LLSelectMgr::getInstanceFast()->getSelection()->isEmpty() && LLSelectMgr::getInstanceFast()->shouldShowSelection()) - || LLToolMgr::getInstanceFast()->getCurrentTool()->isEditing() ) + if ((!LLSelectMgr::getInstance()->getSelection()->isEmpty() && LLSelectMgr::getInstance()->shouldShowSelection()) + || LLToolMgr::getInstance()->getCurrentTool()->isEditing() ) { setRenderState(AGENT_STATE_EDITING); } @@ -2289,7 +2319,7 @@ void LLAgent::endAnimationUpdateUI() LLPanelStandStopFlying::getInstance()->setVisible(TRUE); - LLToolMgr::getInstanceFast()->setCurrentToolset(gBasicToolset); + LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset); LLFloaterCamera::onLeavingMouseLook(); @@ -2366,7 +2396,7 @@ void LLAgent::endAnimationUpdateUI() { // make sure we ask to save changes - LLToolMgr::getInstanceFast()->setCurrentToolset(gBasicToolset); + LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset); if( gMorphView ) { @@ -2416,7 +2446,7 @@ void LLAgent::endAnimationUpdateUI() // JC - Added for always chat in third person option gFocusMgr.setKeyboardFocus(NULL); - LLToolMgr::getInstanceFast()->setCurrentToolset(gMouselookToolset); + LLToolMgr::getInstance()->setCurrentToolset(gMouselookToolset); mViewsPushed = TRUE; @@ -2473,7 +2503,7 @@ void LLAgent::endAnimationUpdateUI() } if (gAgentAvatarp->getParent()) { - LLVector3 at_axis = LLViewerCamera::getInstanceFast()->getAtAxis(); + LLVector3 at_axis = LLViewerCamera::getInstance()->getAtAxis(); LLViewerObject* root_object = (LLViewerObject*)gAgentAvatarp->getRoot(); if (root_object->flagCameraDecoupled()) { @@ -2488,7 +2518,7 @@ void LLAgent::endAnimationUpdateUI() } else if (gAgentCamera.getCameraMode() == CAMERA_MODE_CUSTOMIZE_AVATAR) { - LLToolMgr::getInstanceFast()->setCurrentToolset(gFaceEditToolset); + LLToolMgr::getInstance()->setCurrentToolset(gFaceEditToolset); if( gMorphView ) { @@ -2607,7 +2637,7 @@ void LLAgent::setStartPosition( U32 location_id ) // Don't let them go below ground, or too high. agent_pos.mV[VZ] = llclamp( agent_pos.mV[VZ], mRegionp->getLandHeightRegion( agent_pos ), - LLWorld::getInstanceFast()->getRegionMaxHeight() ); + LLWorld::getInstance()->getRegionMaxHeight() ); // Send the CapReq LLSD request; LLSD body; @@ -2766,7 +2796,7 @@ bool LLAgent::canAccessAdult() const bool LLAgent::canAccessMaturityInRegion( U64 region_handle ) const { - LLViewerRegion *regionp = LLWorld::getInstanceFast()->getRegionFromHandle( region_handle ); + LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle( region_handle ); if( regionp ) { switch( regionp->getSimAccess() ) @@ -3265,7 +3295,7 @@ LLQuaternion LLAgent::getHeadRotation() } // We must be in mouselook - LLVector3 look_dir( LLViewerCamera::getInstanceFast()->getAtAxis() ); + LLVector3 look_dir( LLViewerCamera::getInstance()->getAtAxis() ); LLVector3 up = look_dir % mFrameAgent.getLeftAxis(); LLVector3 left = up % look_dir; @@ -4371,7 +4401,7 @@ void LLAgent::handleTeleportFailed() void LLAgent::addTPNearbyChatSeparator() { LLViewerRegion* agent_region = gAgent.getRegion(); - LLParcel* agent_parcel = LLViewerParcelMgr::getInstanceFast()->getAgentParcel(); + LLParcel* agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); if (!agent_region || !agent_parcel) { return; @@ -4446,7 +4476,7 @@ void LLAgent::teleportRequest(const LLVector3d& pos_global, const LLVector3& loo pos_local = LLVector3(pos_global - other_regionp->getOriginGlobal()); region_handle = other_regionp->getHandle(); } - else if (LLSimInfo* sim_info = LLWorldMap::getInstanceFast()->simInfoFromPosGlobal(pos_global)) + else if (LLSimInfo* sim_info = LLWorldMap::getInstance()->simInfoFromPosGlobal(pos_global)) { pos_local = sim_info->getLocalPos(pos_global); region_handle = sim_info->getHandle(); @@ -4653,7 +4683,7 @@ void LLAgent::doTeleportViaLocation(const LLVector3d& pos_global) pos_local = LLVector3(pos_global - other_regionp->getOriginGlobal()); handle = other_regionp->getHandle(); } - else if (LLSimInfo* sim_info = LLWorldMap::getInstanceFast()->simInfoFromPosGlobal(pos_global)) + else if (LLSimInfo* sim_info = LLWorldMap::getInstance()->simInfoFromPosGlobal(pos_global)) { pos_local = sim_info->getLocalPos(pos_global); handle = sim_info->getHandle(); @@ -4796,7 +4826,7 @@ void LLAgent::setTeleportState(ETeleportState state) //LLViewerStats::getInstance()->mAgentPositionSnaps.mCountOfNextUpdatesToIgnore = 2; // Let the interested parties know we've teleported. - LLViewerParcelMgr::getInstanceFast()->onTeleportFinished(false, getPositionGlobal()); + LLViewerParcelMgr::getInstance()->onTeleportFinished(false, getPositionGlobal()); break; default: @@ -5708,7 +5738,7 @@ LLUUID LLAgent::getGroupForRezzing() { if (gSavedSettings.getBOOL("AlchemyRezUnderLandGroup")) { - LLParcel* land_parcel = LLViewerParcelMgr::getInstanceFast()->getAgentParcel(); + LLParcel* land_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); if (land_parcel) { // Is the agent in the land group diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index 3e8b55293aa8198cd68778145a5e3964c3a9cc28..ae07bff59a77203a51bbcd6b63f89f5fe678e789 100644 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -204,12 +204,12 @@ void LLAgentCamera::init() mDrawDistance = gSavedSettings.getF32("RenderFarClip"); - LLViewerCamera::getInstanceFast()->setView(DEFAULT_FIELD_OF_VIEW); + LLViewerCamera::getInstance()->setView(DEFAULT_FIELD_OF_VIEW); // Leave at 0.1 meters until we have real near clip management - LLViewerCamera::getInstanceFast()->setNear(0.1f); - LLViewerCamera::getInstanceFast()->setFar(mDrawDistance); // if you want to change camera settings, do so in camera.h - LLViewerCamera::getInstanceFast()->setAspect( gViewerWindow->getWorldViewAspectRatio() ); // default, overridden in LLViewerWindow::reshape - LLViewerCamera::getInstanceFast()->setViewHeightInPixels(768); // default, overridden in LLViewerWindow::reshape + LLViewerCamera::getInstance()->setNear(0.1f); + LLViewerCamera::getInstance()->setFar(mDrawDistance); // if you want to change camera settings, do so in camera.h + LLViewerCamera::getInstance()->setAspect( gViewerWindow->getWorldViewAspectRatio() ); // default, overridden in LLViewerWindow::reshape + LLViewerCamera::getInstance()->setViewHeightInPixels(768); // default, overridden in LLViewerWindow::reshape mCameraFocusOffsetTarget = LLVector4(gSavedSettings.getVector3("CameraOffsetBuild")); @@ -308,16 +308,16 @@ void LLAgentCamera::resetView(BOOL reset_camera, BOOL change_camera) gAgent.stopAutoPilot(TRUE); } - LLSelectMgr::getInstanceFast()->unhighlightAll(); + LLSelectMgr::getInstance()->unhighlightAll(); // By popular request, keep land selection while walking around. JC // LLViewerParcelMgr::getInstance()->deselectLand(); // force deselect when walking and attachment is selected // this is so people don't wig out when their avatar moves without animating - if (LLSelectMgr::getInstanceFast()->getSelection()->isAttachment()) + if (LLSelectMgr::getInstance()->getSelection()->isAttachment()) { - LLSelectMgr::getInstanceFast()->deselectAll(); + LLSelectMgr::getInstance()->deselectAll(); } if (gMenuHolder != NULL) @@ -330,15 +330,15 @@ void LLAgentCamera::resetView(BOOL reset_camera, BOOL change_camera) { changeCameraToDefault(); - if (LLViewerJoystick::getInstanceFast()->getOverrideCamera()) + if (LLViewerJoystick::getInstance()->getOverrideCamera()) { handle_toggle_flycam(); } // reset avatar mode from eventual residual motion - if (LLToolMgr::getInstanceFast()->inBuildMode()) + if (LLToolMgr::getInstance()->inBuildMode()) { - LLViewerJoystick::getInstanceFast()->moveAvatar(true); + LLViewerJoystick::getInstance()->moveAvatar(true); } //Camera Tool is needed for Free Camera Control Mode @@ -349,7 +349,7 @@ void LLAgentCamera::resetView(BOOL reset_camera, BOOL change_camera) LLFloaterReg::hideInstance("build"); // Switch back to basic toolset - LLToolMgr::getInstanceFast()->setCurrentToolset(gBasicToolset); + LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset); } gViewerWindow->showCursor(); @@ -375,15 +375,15 @@ void LLAgentCamera::resetView(BOOL reset_camera, BOOL change_camera) resetOrbitDiff(); mHUDTargetZoom = 1.f; - if (LLSelectMgr::getInstanceFast()->mAllowSelectAvatar) + if (LLSelectMgr::getInstance()->mAllowSelectAvatar) { // resetting camera also resets position overrides in debug mode 'AllowSelectAvatar' - LLObjectSelectionHandle selected_handle = LLSelectMgr::getInstanceFast()->getSelection(); + LLObjectSelectionHandle selected_handle = LLSelectMgr::getInstance()->getSelection(); if (selected_handle->getObjectCount() == 1 && selected_handle->getFirstObject() != NULL && selected_handle->getFirstObject()->isAvatar()) { - LLSelectMgr::getInstanceFast()->resetObjectOverrides(selected_handle); + LLSelectMgr::getInstance()->resetObjectOverrides(selected_handle); } } } @@ -424,10 +424,9 @@ LLVector3 LLAgentCamera::calcFocusOffset(LLViewerObject *object, LLVector3 origi const LLQuaternion obj_rot = object->getRenderRotation(); const LLVector3 obj_pos = object->getRenderPosition(); - BOOL is_avatar = object->isAvatar(); // if is avatar - don't do any funk heuristics to position the focal point // see DEV-30589 - if (is_avatar) + if (object->isAvatar() || (object->isAnimatedObject() && object->getControlAvatar())) { return original_focus_point - obj_pos; } @@ -438,7 +437,7 @@ LLVector3 LLAgentCamera::calcFocusOffset(LLViewerObject *object, LLVector3 origi // make sure they object extents are non-zero object_extents.clamp(0.001f, F32_MAX); - auto& viewerCamera = LLViewerCamera::instanceFast(); + auto& viewerCamera = LLViewerCamera::instance(); const auto& viewer_camera_origin = viewerCamera.getOrigin(); // obj_to_cam_ray is unit vector pointing from object center to camera, in the coordinate frame of the object @@ -554,7 +553,6 @@ LLVector3 LLAgentCamera::calcFocusOffset(LLViewerObject *object, LLVector3 origi // or keep the focus point in the object middle when (relatively) far // NOTE: leave focus point in middle of avatars, since the behavior you want when alt-zooming on avatars // is almost always "tumble about middle" and not "spin around surface point" - if (!is_avatar) { LLVector3 obj_rel = original_focus_point - obj_pos; @@ -750,7 +748,7 @@ BOOL LLAgentCamera::calcCameraMinDistance(F32 &obj_min_distance) // clamp obj distance to diagonal of 10 by 10 cube obj_min_distance = llmin(obj_min_distance, 10.f * F_SQRT3); - obj_min_distance += LLViewerCamera::getInstanceFast()->getNear() + (soft_limit ? 0.1f : 0.2f); + obj_min_distance += LLViewerCamera::getInstance()->getNear() + (soft_limit ? 0.1f : 0.2f); return TRUE; } @@ -759,7 +757,7 @@ F32 LLAgentCamera::getCameraZoomFraction(bool get_third_person) { // 0.f -> camera zoomed all the way out // 1.f -> camera zoomed all the way in - LLObjectSelectionHandle selection = LLSelectMgr::getInstanceFast()->getSelection(); + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); if (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD) { // already [0,1] @@ -804,7 +802,7 @@ void LLAgentCamera::setCameraZoomFraction(F32 fraction) { // 0.f -> camera zoomed all the way out // 1.f -> camera zoomed all the way in - LLObjectSelectionHandle selection = LLSelectMgr::getInstanceFast()->getSelection(); + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); if (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD) { @@ -853,7 +851,7 @@ void LLAgentCamera::setCameraZoomFraction(F32 fraction) F32 LLAgentCamera::getAgentHUDTargetZoom() { static LLCachedControl<F32> hud_scale_factor(gSavedSettings, "HUDScaleFactor"); - LLObjectSelectionHandle selection = LLSelectMgr::getInstanceFast()->getSelection(); + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); return (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD) ? hud_scale_factor*gAgentCamera.mHUDTargetZoom : hud_scale_factor; } @@ -862,7 +860,7 @@ F32 LLAgentCamera::getAgentHUDTargetZoom() //----------------------------------------------------------------------------- void LLAgentCamera::cameraOrbitAround(const F32 radians) { - LLObjectSelectionHandle selection = LLSelectMgr::getInstanceFast()->getSelection(); + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); if (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD) { // do nothing for hud selection @@ -886,7 +884,7 @@ void LLAgentCamera::cameraOrbitAround(const F32 radians) //----------------------------------------------------------------------------- void LLAgentCamera::cameraOrbitOver(const F32 angle) { - LLObjectSelectionHandle selection = LLSelectMgr::getInstanceFast()->getSelection(); + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); if (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD) { // do nothing for hud selection @@ -903,7 +901,7 @@ void LLAgentCamera::cameraOrbitOver(const F32 angle) F32 angle_from_up = acos( camera_offset_unit * gAgent.getReferenceUpVector() ); LLVector3d left_axis; - left_axis.setVec(LLViewerCamera::getInstanceFast()->getLeftAxis()); + left_axis.setVec(LLViewerCamera::getInstance()->getLeftAxis()); F32 new_angle = llclamp(angle_from_up - angle, 1.f * DEG_TO_RAD, 179.f * DEG_TO_RAD); mOrbitOverAngle += angle_from_up - new_angle; mCameraFocusOffsetTarget.rotVec(angle_from_up - new_angle, left_axis); @@ -918,7 +916,7 @@ void LLAgentCamera::resetCameraOrbit() camera_offset_unit.normalize(); LLVector3d left_axis; - left_axis.setVec(LLViewerCamera::getInstanceFast()->getLeftAxis()); + left_axis.setVec(LLViewerCamera::getInstance()->getLeftAxis()); mCameraFocusOffsetTarget.rotVec(-mOrbitOverAngle, left_axis); mCameraFocusOffsetTarget.rotVec(-mOrbitAroundRadians, 0.f, 0.f, 1.f); @@ -943,8 +941,8 @@ void LLAgentCamera::cameraZoomIn(const F32 fraction) return; } - LLObjectSelectionHandle selection = LLSelectMgr::getInstanceFast()->getSelection(); - if (LLToolMgr::getInstanceFast()->inBuildMode() && selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD) + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); + if (LLToolMgr::getInstance()->inBuildMode() && selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD) { // just update hud zoom level mHUDTargetZoom /= fraction; @@ -1091,7 +1089,7 @@ void LLAgentCamera::cameraOrbitIn(const F32 meters) void LLAgentCamera::cameraPanIn(F32 meters) { LLVector3d at_axis; - at_axis.setVec(LLViewerCamera::getInstanceFast()->getAtAxis()); + at_axis.setVec(LLViewerCamera::getInstance()->getAtAxis()); mPanFocusDiff += meters * at_axis; @@ -1109,7 +1107,7 @@ void LLAgentCamera::cameraPanIn(F32 meters) void LLAgentCamera::cameraPanLeft(F32 meters) { LLVector3d left_axis; - left_axis.setVec(LLViewerCamera::getInstanceFast()->getLeftAxis()); + left_axis.setVec(LLViewerCamera::getInstance()->getLeftAxis()); mPanFocusDiff += meters * left_axis; @@ -1131,7 +1129,7 @@ void LLAgentCamera::cameraPanLeft(F32 meters) void LLAgentCamera::cameraPanUp(F32 meters) { LLVector3d up_axis; - up_axis.setVec(LLViewerCamera::getInstanceFast()->getUpAxis()); + up_axis.setVec(LLViewerCamera::getInstance()->getUpAxis()); mPanFocusDiff += meters * up_axis; @@ -1209,7 +1207,7 @@ void LLAgentCamera::updateLookAt(const S32 mouse_x, const S32 mouse_y) // Move head based on cursor position ELookAtType lookAtType = LOOKAT_TARGET_NONE; LLVector3 headLookAxis; - LLCoordFrame frameCamera = *((LLCoordFrame*)LLViewerCamera::getInstanceFast()); + LLCoordFrame frameCamera = *((LLCoordFrame*)LLViewerCamera::getInstance()); if (cameraMouselook()) { @@ -1304,7 +1302,7 @@ void LLAgentCamera::updateCamera() gAgentCamera.getPanDownKey() > 0.f); // bottom } - auto& vwr_camera = LLViewerCamera::instanceFast(); + auto& vwr_camera = LLViewerCamera::instance(); // Handle camera movement based on keyboard. const F32 ORBIT_OVER_RATE = 90.f * DEG_TO_RAD; // radians per second @@ -1376,7 +1374,7 @@ void LLAgentCamera::updateCamera() mFollowCam.copyParams(*current_cam); mFollowCam.setSubjectPositionAndRotation( gAgentAvatarp->getRenderPosition(), avatarRotationForFollowCam ); mFollowCam.update(); - LLViewerJoystick::getInstanceFast()->setCameraNeedsUpdate(true); + LLViewerJoystick::getInstance()->setCameraNeedsUpdate(true); } else { @@ -1467,7 +1465,7 @@ void LLAgentCamera::updateCamera() LLVector3d camera_pos_agent = camera_pos_global - agent_pos; // Sitting on what you're manipulating can cause camera jitter with smoothing. // This turns off smoothing while editing. -MG - bool in_build_mode = LLToolMgr::getInstanceFast()->inBuildMode(); + bool in_build_mode = LLToolMgr::getInstance()->inBuildMode(); mCameraSmoothingStop = mCameraSmoothingStop || in_build_mode; if (cameraThirdPerson() && !mCameraSmoothingStop) @@ -1477,7 +1475,7 @@ void LLAgentCamera::updateCamera() static const LLCachedControl<F32> cam_pos_smoothing(gSavedSettings, "CameraPositionSmoothing"); F32 smoothing = LLSmoothInterpolation::getInterpolant(cam_pos_smoothing * SMOOTHING_HALF_LIFE, FALSE); - if (!mFocusObject) // we differentiate on avatar mode + if (mFocusOnAvatar && !mFocusObject) // we differentiate on avatar mode { // for avatar-relative focus, we smooth in avatar space - // the avatar moves too jerkily w/r/t global space to smooth there. @@ -1749,18 +1747,18 @@ LLVector3d LLAgentCamera::calcFocusPositionTargetGlobal() LLVector3d LLAgentCamera::calcThirdPersonFocusOffset() { // ...offset from avatar - LLVector3d focus_offset; + LLVector3d focus_offset_initial; LLQuaternion agent_rot = gAgent.getFrameAgent().getQuaternion(); if (isAgentAvatarValid() && gAgentAvatarp->getParent()) { agent_rot *= ((LLViewerObject*)(gAgentAvatarp->getParent()))->getRenderRotation(); } -// focus_offset = convert_from_llsd<LLVector3d>(mFocusOffsetInitial->get(), TYPE_VEC3D, ""); + //static LLCachedControl<LLVector3d> focus_offset_initial(gSavedSettings, "FocusOffsetRearView", LLVector3d()); // [RLVa:KB] - @setcam_focusoffset - focus_offset = getFocusOffsetInitial(); + focus_offset_initial = getFocusOffsetInitial(); // [/RLVa:KB] - return focus_offset * agent_rot; + return focus_offset_initial * agent_rot; } void LLAgentCamera::setupSitCamera() @@ -1782,7 +1780,7 @@ void LLAgentCamera::setupSitCamera() //----------------------------------------------------------------------------- const LLVector3 &LLAgentCamera::getCameraPositionAgent() const { - return LLViewerCamera::getInstanceFast()->getOrigin(); + return LLViewerCamera::getInstance()->getOrigin(); } //----------------------------------------------------------------------------- @@ -1790,7 +1788,7 @@ const LLVector3 &LLAgentCamera::getCameraPositionAgent() const //----------------------------------------------------------------------------- LLVector3d LLAgentCamera::getCameraPositionGlobal() const { - return gAgent.getPosGlobalFromAgent(LLViewerCamera::getInstanceFast()->getOrigin()); + return gAgent.getPosGlobalFromAgent(LLViewerCamera::getInstance()->getOrigin()); } //----------------------------------------------------------------------------- @@ -1904,8 +1902,9 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit) // [RLVa:KB] - @setcam_eyeoffsetscale local_camera_offset = mCameraZoomFraction * getCameraOffsetInitial() * getCameraOffsetScale(); // [/RLVa:KB] -// local_camera_offset = mCameraZoomFraction * getCameraOffsetInitial() * gSavedSettings.getF32("CameraOffsetScale"); - +// static LLCachedControl<F32> camera_offset_scale(gSavedSettings, "CameraOffsetScale"); +// local_camera_offset = mCameraZoomFraction * getCameraOffsetInitial() * camera_offset_scale; + // are we sitting down? if (isAgentAvatarValid() && gAgentAvatarp->getParent()) { @@ -2044,7 +2043,7 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit) camera_position_global = focusPosGlobal + mCameraFocusOffset; } - auto& worldInst = LLWorld::instanceFast(); + auto& worldInst = LLWorld::instance(); if (!ALControlCache::DisableCameraConstraints && !gAgent.isGodlike()) { @@ -2185,7 +2184,7 @@ bool LLAgentCamera::clampCameraPosition(LLVector3d& posCamGlobal, const LLVector LLVector3 LLAgentCamera::getCurrentCameraOffset() { - return (LLViewerCamera::getInstanceFast()->getOrigin() - getAvatarRootPosition() - mThirdPersonHeadOffset) * ~getCurrentAvatarRotation(); + return (LLViewerCamera::getInstance()->getOrigin() - getAvatarRootPosition() - mThirdPersonHeadOffset) * ~getCurrentAvatarRotation(); } LLVector3d LLAgentCamera::getCurrentFocusOffset() @@ -2209,18 +2208,21 @@ bool LLAgentCamera::isJoystickCameraUsed() LLVector3 LLAgentCamera::getCameraOffsetInitial() { + // getCameraOffsetInitial and getFocusOffsetInitial can be called on update from idle before init() + static LLCachedControl<LLVector3> camera_offset_initial (gSavedSettings, "CameraOffsetRearView", LLVector3()); // [RLVa:KB] - @setcam_eyeoffset - return convert_from_llsd<LLVector3>( (ECameraPreset::CAMERA_RLV_SETCAM_VIEW != mCameraPreset) ? mCameraOffsetInitialControl->get() : mRlvCameraOffsetInitialControl->get(), TYPE_VEC3, ""); -// [/RLVa:KB] -// return convert_from_llsd<LLVector3>(mCameraOffsetInitial->get(), TYPE_VEC3, ""); + return (ECameraPreset::CAMERA_RLV_SETCAM_VIEW != mCameraPreset) ? camera_offset_initial : convert_from_llsd<LLVector3>(mRlvCameraOffsetInitialControl->get(), TYPE_VEC3, ""); +// [/RLVa:KB] +// return camera_offset_initial; } LLVector3d LLAgentCamera::getFocusOffsetInitial() { + static LLCachedControl<LLVector3d> focus_offset_initial(gSavedSettings, "FocusOffsetRearView", LLVector3d()); // [RLVa:KB] - @setcam_focusoffset - return convert_from_llsd<LLVector3d>( (ECameraPreset::CAMERA_RLV_SETCAM_VIEW != mCameraPreset) ? mFocusOffsetInitialControl->get() : mRlvFocusOffsetInitialControl->get(), TYPE_VEC3D, ""); + return (ECameraPreset::CAMERA_RLV_SETCAM_VIEW != mCameraPreset) ? focus_offset_initial :convert_from_llsd<LLVector3d>(mRlvFocusOffsetInitialControl->get(), TYPE_VEC3D, ""); // [/RLVa:KB] -// return convert_from_llsd<LLVector3d>(mFocusOffsetInitial->get(), TYPE_VEC3D, ""); +// return focus_offset_initial; } // [RLVa:KB] - @setcam_eyeoffsetscale @@ -2238,7 +2240,7 @@ F32 LLAgentCamera::getCameraMaxZoomDistance(bool allow_disabled_constraints/* = ? INT_MAX : llmin(MAX_CAMERA_DISTANCE_FROM_OBJECT, mDrawDistance - 1, // convenience, don't hit draw limit when focusing on something - LLWorld::getInstanceFast()->getRegionWidthInMeters() - CAMERA_FUDGE_FROM_OBJECT); + LLWorld::getInstance()->getRegionWidthInMeters() - CAMERA_FUDGE_FROM_OBJECT); } LLVector3 LLAgentCamera::getAvatarRootPosition() @@ -2265,7 +2267,7 @@ void LLAgentCamera::handleScrollWheel(S32 clicks) } else { - LLObjectSelectionHandle selection = LLSelectMgr::getInstanceFast()->getSelection(); + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); const F32 ROOT_ROOT_TWO = sqrt(F_SQRT2); // Block if camera is animating @@ -2342,7 +2344,7 @@ void LLAgentCamera::changeCameraToMouselook(BOOL animate) || ( (RlvActions::isRlvEnabled()) && (!RlvActions::canChangeToMouselook()) ) // [/RLVa:KB] - || LLViewerJoystick::getInstanceFast()->getOverrideCamera()) + || LLViewerJoystick::getInstance()->getOverrideCamera()) { return; } @@ -2352,12 +2354,12 @@ void LLAgentCamera::changeCameraToMouselook(BOOL animate) // Menus should not remain open on switching to mouselook... LLMenuGL::sMenuContainer->hideMenus(); - LLUI::getInstanceFast()->clearPopups(); + LLUI::getInstance()->clearPopups(); // unpause avatar animation gAgent.unpauseAnimation(); - LLToolMgr::getInstanceFast()->setCurrentToolset(gMouselookToolset); + LLToolMgr::getInstance()->setCurrentToolset(gMouselookToolset); if (isAgentAvatarValid()) { @@ -2366,7 +2368,7 @@ void LLAgentCamera::changeCameraToMouselook(BOOL animate) } //gViewerWindow->stopGrab(); - LLSelectMgr::getInstanceFast()->deselectAll(); + LLSelectMgr::getInstance()->deselectAll(); // gViewerWindow->hideCursor(); // gViewerWindow->moveCursorToCenter(); @@ -2402,12 +2404,12 @@ void LLAgentCamera::changeCameraToMouselook(BOOL animate) //----------------------------------------------------------------------------- void LLAgentCamera::changeCameraToDefault() { - if (LLViewerJoystick::getInstanceFast()->getOverrideCamera()) + if (LLViewerJoystick::getInstance()->getOverrideCamera()) { return; } - if (LLFollowCamMgr::getInstanceFast()->getActiveFollowCamParams()) + if (LLFollowCamMgr::getInstance()->getActiveFollowCamParams()) { changeCameraToFollow(); } @@ -2428,7 +2430,7 @@ void LLAgentCamera::changeCameraToDefault() //----------------------------------------------------------------------------- void LLAgentCamera::changeCameraToFollow(BOOL animate) { - if (LLViewerJoystick::getInstanceFast()->getOverrideCamera()) + if (LLViewerJoystick::getInstance()->getOverrideCamera()) { return; } @@ -2446,11 +2448,11 @@ void LLAgentCamera::changeCameraToFollow(BOOL animate) ALAOEngine::getInstance()->inMouselook(false); // bang-in the current focus, position, and up vector of the follow cam - mFollowCam.reset(mCameraPositionAgent, LLViewerCamera::getInstanceFast()->getPointOfInterest(), LLVector3::z_axis); + mFollowCam.reset(mCameraPositionAgent, LLViewerCamera::getInstance()->getPointOfInterest(), LLVector3::z_axis); if (gBasicToolset) { - LLToolMgr::getInstanceFast()->setCurrentToolset(gBasicToolset); + LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset); } if (isAgentAvatarValid()) @@ -2483,7 +2485,7 @@ void LLAgentCamera::changeCameraToFollow(BOOL animate) //----------------------------------------------------------------------------- void LLAgentCamera::changeCameraToThirdPerson(BOOL animate) { - if (LLViewerJoystick::getInstanceFast()->getOverrideCamera()) + if (LLViewerJoystick::getInstance()->getOverrideCamera()) { return; } @@ -2512,7 +2514,7 @@ void LLAgentCamera::changeCameraToThirdPerson(BOOL animate) { if (gBasicToolset) { - LLToolMgr::getInstanceFast()->setCurrentToolset(gBasicToolset); + LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset); } mCameraLag.clearVec(); @@ -2554,7 +2556,7 @@ void LLAgentCamera::changeCameraToThirdPerson(BOOL animate) //----------------------------------------------------------------------------- void LLAgentCamera::changeCameraToCustomizeAvatar() { - if (LLViewerJoystick::getInstanceFast()->getOverrideCamera() || !isAgentAvatarValid()) + if (LLViewerJoystick::getInstance()->getOverrideCamera() || !isAgentAvatarValid()) { return; } @@ -2571,7 +2573,7 @@ void LLAgentCamera::changeCameraToCustomizeAvatar() if (gFaceEditToolset) { - LLToolMgr::getInstanceFast()->setCurrentToolset(gFaceEditToolset); + LLToolMgr::getInstance()->setCurrentToolset(gFaceEditToolset); } startCameraAnimation(); @@ -2939,7 +2941,7 @@ void LLAgentCamera::setFocusOnAvatar(BOOL focus_on_avatar, BOOL animate, BOOL re LLVector3 vect = getCameraOffsetInitial(); F32 rotxy = F32(atan2(vect.mV[VY], vect.mV[VX])); - LLCoordFrame frameCamera = *((LLCoordFrame*)LLViewerCamera::getInstanceFast()); + LLCoordFrame frameCamera = *((LLCoordFrame*)LLViewerCamera::getInstance()); // front view angle rotxy is zero, rear view rotxy angle is 180, compensate frameCamera.yaw((180 * DEG_TO_RAD) - rotxy); at_axis = frameCamera.getAtAxis(); @@ -2987,7 +2989,7 @@ BOOL LLAgentCamera::setLookAt(ELookAtType target_type, LLViewerObject *object, L } if(!mLookAt || mLookAt->isDead()) { - mLookAt = (LLHUDEffectLookAt *)LLHUDManager::getInstanceFast()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_LOOKAT); + mLookAt = (LLHUDEffectLookAt *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_LOOKAT); mLookAt->setSourceObject(gAgentAvatarp); } @@ -3098,7 +3100,7 @@ BOOL LLAgentCamera::setPointAt(EPointAtType target_type, LLViewerObject *object, } if (!mPointAt || mPointAt->isDead()) { - mPointAt = (LLHUDEffectPointAt *)LLHUDManager::getInstanceFast()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINTAT); + mPointAt = (LLHUDEffectPointAt *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINTAT); mPointAt->setSourceObject(gAgentAvatarp); } return mPointAt->setPointAt(target_type, object, position); diff --git a/indra/newview/llagentpicksinfo.cpp b/indra/newview/llagentpicksinfo.cpp index 15efbd0061a1b5c14930f348e0d7d1738014c932..cbb92e3545aea3dec140788b4e15912b031db778 100644 --- a/indra/newview/llagentpicksinfo.cpp +++ b/indra/newview/llagentpicksinfo.cpp @@ -39,18 +39,18 @@ class LLAgentPicksInfo::LLAgentPicksObserver : public LLAvatarPropertiesObserver public: LLAgentPicksObserver() { - LLAvatarPropertiesProcessor::getInstanceFast()->addObserver(gAgent.getID(), this); + LLAvatarPropertiesProcessor::getInstance()->addObserver(gAgent.getID(), this); } ~LLAgentPicksObserver() { if (LLAvatarPropertiesProcessor::instanceExists()) - LLAvatarPropertiesProcessor::getInstanceFast()->removeObserver(gAgent.getID(), this); + LLAvatarPropertiesProcessor::getInstance()->removeObserver(gAgent.getID(), this); } void sendAgentPicksRequest() { - LLAvatarPropertiesProcessor::getInstanceFast()->sendAvatarPicksRequest(gAgent.getID()); + LLAvatarPropertiesProcessor::getInstance()->sendAvatarPicksRequest(gAgent.getID()); } typedef boost::function<void(LLAvatarPicks*)> server_respond_callback_t; diff --git a/indra/newview/llagentpicksinfo.h b/indra/newview/llagentpicksinfo.h index 7b327e5c21f75fbb7240942b9e089ae169689f2c..05c95473457000d17ef1c3c8757bec5897b278e4 100644 --- a/indra/newview/llagentpicksinfo.h +++ b/indra/newview/llagentpicksinfo.h @@ -74,10 +74,10 @@ class LLAgentPicksInfo final : public LLSingleton<LLAgentPicksInfo> void decrementNumberOfPicks() { --mNumberOfPicks; } -private: - void onServerRespond(LLAvatarPicks* picks); +private: + /** * Sets number of Picks. */ diff --git a/indra/newview/llagentui.cpp b/indra/newview/llagentui.cpp index 4710eb3ad3d6eb6f4467ac4df290594a578acda9..8d877999aef8322cf3f7851a374fb8fde87b376b 100644 --- a/indra/newview/llagentui.cpp +++ b/indra/newview/llagentui.cpp @@ -73,13 +73,13 @@ BOOL LLAgentUI::checkAgentDistance(const LLVector3& pole, F32 radius) BOOL LLAgentUI::buildLocationString(std::string& str, ELocationFormat fmt,const LLVector3& agent_pos_region) { LLViewerRegion* region = gAgent.getRegion(); - LLViewerParcelMgr& parcelMGr = LLViewerParcelMgr::instanceFast(); + LLViewerParcelMgr& parcelMGr = LLViewerParcelMgr::instance(); LLParcel* parcel = parcelMGr.getAgentParcel(); if (!region || !parcel) return FALSE; - std::string remote_grid = LLGridManager::instanceFast().getGridByProbing(region->getHGGrid()); - std::string cur_grid = LLGridManager::instanceFast().getGrid(); + std::string remote_grid = LLGridManager::instance().getGridByProbing(region->getHGGrid()); + std::string cur_grid = LLGridManager::instance().getGrid(); bool is_hypergrid = remote_grid != cur_grid; S32 pos_x = S32(agent_pos_region.mV[VX]); diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index 2c270716491e607d2dfa1d4d5d47bb0766624434..4903fbd935309d4b08fbdc8eaec19b34bc0a0389 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -37,6 +37,7 @@ #include "llgesturemgr.h" #include "llinventorybridge.h" #include "llinventoryfunctions.h" +#include "llinventorymodelbackgroundfetch.h" #include "llinventoryobserver.h" #include "llinventorypanel.h" #include "lllocaltextureobject.h" @@ -1413,7 +1414,7 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it } // updating inventory - LLWearableType* wearable_type_inst = LLWearableType::getInstanceFast(); + LLWearableType* wearable_type_inst = LLWearableType::getInstance(); // TODO: Removed check for ensuring that teens don't remove undershirt and underwear. Handle later // note: shirt is the first non-body part wearable item. Update if wearable order changes. @@ -2082,6 +2083,14 @@ void LLAgentWearables::editWearable(const LLUUID& item_id) return; } + if (!item->isFinished()) + { + LL_WARNS() << "Tried to edit wearable that isn't loaded" << LL_ENDL; + // Restart fetch or put item to the front + LLInventoryModelBackgroundFetch::instance().start(item->getUUID(), false); + return; + } + LLViewerWearable* wearable = gAgentWearables.getWearableFromItemID(item_id); if (!wearable) { @@ -2095,7 +2104,19 @@ void LLAgentWearables::editWearable(const LLUUID& item_id) return; } - const BOOL disable_camera_switch = LLWearableType::getInstanceFast()->getDisableCameraSwitch(wearable->getType()); + S32 shape_count = gAgentWearables.getWearableCount(LLWearableType::WT_SHAPE); + S32 hair_count = gAgentWearables.getWearableCount(LLWearableType::WT_HAIR); + S32 eye_count = gAgentWearables.getWearableCount(LLWearableType::WT_EYES); + S32 skin_count = gAgentWearables.getWearableCount(LLWearableType::WT_SKIN); + if (!shape_count || !hair_count || !eye_count || !skin_count) + { + // Don't let user edit wearables if avatar is cloud due to missing parts. + // Let user edit wearables if avatar is cloud due to missing textures. + LL_WARNS() << "Cannot modify wearable. Avatar is cloud and missing parts." << LL_ENDL; + return; + } + + const BOOL disable_camera_switch = LLWearableType::getInstance()->getDisableCameraSwitch(wearable->getType()); LLPanel* panel = LLFloaterSidePanelContainer::getPanel("appearance"); LLSidepanelAppearance::editWearable(wearable, panel, disable_camera_switch); } diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 8e9b0e33aef598b4724d42e0a4518d67ecfbab47..68ec54b495ba43429b25ba044f5884ebe37c24f8 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -147,7 +147,7 @@ class LLAppearanceHandler : public LLCommandHandler { // support secondlife:///app/appearance/show, but for now we just // make all secondlife:///app/appearance SLapps behave this way - if (!LLUI::getInstanceFast()->mSettingGroups["config"]->getBOOL("EnableAppearance")) + if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnableAppearance")) { LLNotificationsUtil::add("NoAppearance", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit")); return true; @@ -1036,7 +1036,7 @@ void LLWearableHoldingPattern::recoverMissingWearable(LLWearableType::EType type // Try to recover by replacing missing wearable with a new one. LLNotificationsUtil::add("ReplacedMissingWearable"); - LL_DEBUGS("Avatar") << "Wearable of type '" << LLWearableType::getInstanceFast()->getTypeName(type) + LL_DEBUGS("Avatar") << "Wearable of type '" << LLWearableType::getInstance()->getTypeName(type) << "' could not be downloaded. Replaced inventory item with default wearable." << LL_ENDL; LLViewerWearable* wearable = LLWearableList::instance().createNewWearable(type, gAgentAvatarp); @@ -2138,7 +2138,7 @@ void LLAppearanceMgr::filterWearableItems( continue; // S32 start_index = llmax(0,size-max_per_type); // [SL:KB] - Patch: Appearance-Misc | Checked: 2010-05-11 (Catznip-2.0) - S32 start_index = llmax(0, size - ((LLWearableType::getInstanceFast()->getAllowMultiwear((LLWearableType::EType)i)) ? max_per_type : 1)); + S32 start_index = llmax(0, size - ((LLWearableType::getInstance()->getAllowMultiwear((LLWearableType::EType)i)) ? max_per_type : 1)); // [/SL:KB[ for (S32 j = start_index; j<size; j++) { @@ -4124,7 +4124,7 @@ void LLAppearanceMgr::serverAppearanceUpdateCoro(LLCoreHttpUtil::HttpCoroutineAd // through the UDP and be handled in LLVOAvatar::processAvatarAppearance // this should ensure that we receive a new canonical COF from the sim // host. Hopefully it will return before the timeout. - LLAvatarPropertiesProcessor::getInstanceFast()->sendAvatarTexturesRequest(gAgent.getID()); + LLAvatarPropertiesProcessor::getInstance()->sendAvatarTexturesRequest(gAgent.getID()); bRetry = true; // Wait for a 1/2 second before trying again. Just to keep from asking too quickly. @@ -4972,6 +4972,7 @@ class LLWearFolderHandler : public LLCommandHandler "Quick Appearance"); if ( gInventory.getCategory( folder_uuid ) != NULL ) { + // Assume this is coming from the predefined avatars web floater LLAppearanceMgr::getInstance()->wearInventoryCategory(category, true, false); // *TODOw: This may not be necessary if initial outfit is chosen already -- josh diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index c5371064fd4abc961349c06f1996ba344ad60cca..9bf3831089bdcfd2f710d350e43c8c712be02b86 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -93,7 +93,6 @@ #include "llsdutil_math.h" #include "lllocationhistory.h" #include "llfasttimerview.h" -#include "lltelemetry.h" #include "llvector4a.h" #include "llviewermenufile.h" #include "llvoicechannel.h" @@ -246,6 +245,8 @@ #include "llavatariconctrl.h" #include "llgroupiconctrl.h" #include "llviewerassetstats.h" +#include "workqueue.h" +using namespace LL; // Include for security api initialization #include "llsecapi.h" @@ -370,6 +371,10 @@ BOOL gLogoutInProgress = FALSE; BOOL gSimulateMemLeak = FALSE; +// We don't want anyone, especially threads working on the graphics pipeline, +// to have to block due to this WorkQueue being full. +WorkQueue gMainloopWork("mainloop", 1024*1024); + //////////////////////////////////////////////////////////// // Internal globals... that should be removed. static std::string gArgs; @@ -388,42 +393,6 @@ static std::string gLaunchFileOnQuit; // Used on Win32 for other apps to identify our window (eg, win_setup) const char* const VIEWER_WINDOW_CLASSNAME = "Alchemy"; -//-- LLDeferredTaskList ------------------------------------------------------ - -/** - * A list of deferred tasks. - * - * We sometimes need to defer execution of some code until the viewer gets idle, - * e.g. removing an inventory item from within notifyObservers() may not work out. - * - * Tasks added to this list will be executed in the next LLAppViewer::idle() iteration. - * All tasks are executed only once. - */ -class LLDeferredTaskList final : public LLSingleton<LLDeferredTaskList> -{ - LLSINGLETON_EMPTY_CTOR(LLDeferredTaskList); - LOG_CLASS(LLDeferredTaskList); - - friend class LLAppViewer; - typedef boost::signals2::signal<void()> signal_t; - - void addTask(const signal_t::slot_type& cb) - { - mSignal.connect(cb); - } - - void run() - { - if (!mSignal.empty()) - { - mSignal(); - mSignal.disconnect_all_slots(); - } - } - - signal_t mSignal; -}; - //---------------------------------------------------------------------------- // List of entries from strings.xml to always replace @@ -521,7 +490,7 @@ static void deferred_ui_audio_callback(const LLUUID& uuid) if (gAudiop) { SoundData soundData(uuid, gAgent.getID(), 1.0f, LLAudioEngine::AUDIO_TYPE_UI); - LLDeferredSounds::instanceFast().deferSound(soundData); + LLDeferredSounds::instance().deferSound(soundData); } } @@ -578,7 +547,7 @@ static void settings_to_globals() LLSurface::setTextureSize(gSavedSettings.getU32("RegionTextureSize")); - LLRender::sGLCoreProfile = gSavedSettings.getBOOL("RenderGLCoreProfile"); + LLRender::sGLCoreProfile = gSavedSettings.getBOOL("RenderGLContextCoreProfile"); LLRender::sNsightDebugSupport = gSavedSettings.getBOOL("RenderNsightDebugSupport"); LLRender::sAnisotropicFilteringLevel = static_cast<F32>(gSavedSettings.getU32("RenderAnisotropicLevel")); LLVertexBuffer::sUseVAO = gSavedSettings.getBOOL("RenderUseVAO"); @@ -603,7 +572,7 @@ static void settings_to_globals() gDebugWindowProc = gSavedSettings.getBOOL("DebugWindowProc"); gShowObjectUpdates = gSavedSettings.getBOOL("ShowObjectUpdates"); - LLWorldMapView::sMapScale = gSavedSettings.getF32("MapScale"); + LLWorldMapView::setScaleSetting(gSavedSettings.getF32("MapScale")); #if LL_DARWIN gHiDPISupport = gSavedSettings.getBOOL("RenderHiDPI"); @@ -612,17 +581,17 @@ static void settings_to_globals() static void settings_modify() { - LLPipeline::sRenderTransparentWater = gSavedSettings.getBOOL("RenderTransparentWater"); - LLPipeline::sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); - LLPipeline::sRenderDeferred = LLPipeline::sRenderTransparentWater && LLPipeline::sRenderBump && gSavedSettings.getBOOL("RenderDeferred"); -// LLRenderTarget::sUseFBO = (LLPipeline::sRenderDeferred && gSavedSettings.getBOOL("RenderAvatarVP")); + LLPipeline::sRenderTransparentWater = gSavedSettings.getBOOL("RenderTransparentWater"); + LLPipeline::sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); + LLPipeline::sRenderDeferred = LLPipeline::sRenderBump && gSavedSettings.getBOOL("RenderDeferred"); +// LLRenderTarget::sUseFBO = LLPipeline::sRenderDeferred; // [RLVa:KB] - @setsphere - LLRenderTarget::sUseFBO = (LLPipeline::sRenderDeferred && gSavedSettings.getBOOL("RenderAvatarVP")) || (gSavedSettings.getBOOL("WindLightUseAtmosShaders") && LLPipeline::sUseDepthTexture); + LLRenderTarget::sUseFBO = LLPipeline::sRenderDeferred || (gSavedSettings.getBOOL("WindLightUseAtmosShaders") && LLPipeline::sUseDepthTexture); // [/RLVa:KB] - LLVOSurfacePatch::sLODFactor = gSavedSettings.getF32("RenderTerrainLODFactor"); - LLVOSurfacePatch::sLODFactor *= LLVOSurfacePatch::sLODFactor; //square lod factor to get exponential range of [1,4] - gDebugGL = gSavedSettings.getBOOL("RenderDebugGL") || gDebugSession; - gDebugPipeline = gSavedSettings.getBOOL("RenderDebugPipeline"); + LLVOSurfacePatch::sLODFactor = gSavedSettings.getF32("RenderTerrainLODFactor"); + LLVOSurfacePatch::sLODFactor *= LLVOSurfacePatch::sLODFactor; // square lod factor to get exponential range of [1,4] + gDebugGL = gDebugGLSession || gDebugSession; + gDebugPipeline = gSavedSettings.getBOOL("RenderDebugPipeline"); } class LLFastTimerLogThread final : public LLThread @@ -686,6 +655,7 @@ LLAppViewer::LLAppViewer() mLogoutMarkerFile(), mReportedCrash(false), mNumSessions(0), + mGeneralThreadPool(nullptr), mPurgeCache(false), mPurgeCacheOnExit(false), mPurgeUserDataOnExit(false), @@ -703,8 +673,7 @@ LLAppViewer::LLAppViewer() mPeriodicSlowFrame(LLCachedControl<bool>(gSavedSettings,"Periodic Slow Frame", FALSE)), mFastTimerLogThread(NULL), mSettingsLocationList(NULL), - mIsFirstRun(false), - mMinMicroSecPerFrame(0.f) + mIsFirstRun(false) { if(NULL != sInstance) { @@ -865,8 +834,6 @@ bool LLAppViewer::init() LLNotifications::instance(); LL_INFOS("InitInfo") << "Notifications initialized." << LL_ENDL ; - writeSystemInfo(); - ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// @@ -973,6 +940,9 @@ bool LLAppViewer::init() } LL_INFOS("InitInfo") << "Cache initialization is done." << LL_ENDL ; + // Initialize event recorder + LLViewerEventRecorder::createInstance(); + // // Initialize the window // @@ -980,6 +950,9 @@ bool LLAppViewer::init() initWindow(); LL_INFOS("InitInfo") << "Window is initialized." << LL_ENDL ; + // writeSystemInfo can be called after window is initialized (gViewerWindow non-null) + writeSystemInfo(); + // initWindow also initializes the Feature List, so now we can initialize this global. LLCubeMap::sUseCubeMaps = LLFeatureManager::getInstance()->isFeatureAvailable("RenderCubeMap"); @@ -994,29 +967,10 @@ bool LLAppViewer::init() // If we don't have the right GL requirements, exit. if (!gGLManager.mHasRequirements) { - // can't use an alert here since we're exiting and - // all hell breaks lose. - LLUIString details = LLNotifications::instance().getGlobalString("UnsupportedGLRequirements"); - OSMessageBox( - details.getString(), - LLStringUtil::null, - OSMB_OK); + // already handled with a MBVideoDrvErr return 0; } - // If we don't have the right shader requirements. - if (!gGLManager.mHasShaderObjects - || !gGLManager.mHasVertexShader - || !gGLManager.mHasFragmentShader) - { - LLUIString details = LLNotifications::instance().getGlobalString("UnsupportedShaderRequirements"); - OSMessageBox( - details.getString(), - LLStringUtil::null, - OSMB_OK); - return 0; - } - // Without SSE2 support we will crash almost immediately, warn here. if (!gSysCPU.hasSSE2()) { @@ -1142,7 +1096,7 @@ bool LLAppViewer::init() { url = LLTrans::getString("NvidiaDriverPage"); } - else if (gGLManager.mIsATI) + else if (gGLManager.mIsAMD) { url = LLTrans::getString("AMDDriverPage"); } @@ -1181,7 +1135,8 @@ bool LLAppViewer::init() gGLActive = FALSE; #if LL_RELEASE_FOR_DOWNLOAD && !defined(LL_LINUX) - if (!gSavedSettings.getBOOL("CmdLineSkipUpdater")) + // Skip updater if this is a non-interactive instance + if (!gSavedSettings.getBOOL("CmdLineSkipUpdater") && !gNonInteractive) { LLProcess::Params updater; updater.desc = "updater process"; @@ -1325,13 +1280,16 @@ bool LLAppViewer::init() joystick = LLViewerJoystick::getInstance(); joystick->setNeedsReset(true); /*----------------------------------------------------------------------*/ - - gSavedSettings.getControl("FramePerSecondLimit")->getSignal()->connect(boost::bind(&LLAppViewer::onChangeFrameLimit, this, _2)); - onChangeFrameLimit(gSavedSettings.getLLSD("FramePerSecondLimit")); - // Load User's bindings loadKeyBindings(); + //LLSimpleton creations + LLEnvironment::createInstance(); + LLEnvironment::getInstance()->initSingleton(); + LLWorld::createInstance(); + LLSelectMgr::createInstance(); + LLViewerCamera::createInstance(); + #if LL_WINDOWS if (!mSecondInstance) { @@ -1357,14 +1315,18 @@ void LLAppViewer::initMaxHeapSize() //------------------------------------------------------------------------------------------ //currently SL is built under 32-bit setting, we set its max heap size no more than 1.6 GB. - //F32 max_heap_size_gb = llmin(1.6f, (F32)gSavedSettings.getF32("MaxHeapSize")) ; - F32Gigabytes max_heap_size_gb = (F32Gigabytes)gSavedSettings.getF32("MaxHeapSize") ; + #ifndef LL_X86_64 + F32Gigabytes max_heap_size_gb = (F32Gigabytes)gSavedSettings.getF32("MaxHeapSize") ; +#else + F32Gigabytes max_heap_size_gb = (F32Gigabytes)gSavedSettings.getF32("MaxHeapSize64"); +#endif - LLMemory::initMaxHeapSizeGB(max_heap_size_gb); + LLMemory::initMaxHeapSizeGB(max_heap_size_gb); } static LLTrace::BlockTimerStatHandle FTM_MESSAGES("System Messages"); -static LLTrace::BlockTimerStatHandle FTM_SLEEP("Sleep"); +static LLTrace::BlockTimerStatHandle FTM_SLEEP1("Sleep1"); +static LLTrace::BlockTimerStatHandle FTM_SLEEP2("Sleep2"); static LLTrace::BlockTimerStatHandle FTM_YIELD("Yield"); static LLTrace::BlockTimerStatHandle FTM_TEXTURE_CACHE("Texture Cache"); @@ -1425,13 +1387,26 @@ bool LLAppViewer::frame() bool LLAppViewer::doFrame() { + LL_RECORD_BLOCK_TIME(FTM_FRAME); + + if (!LLWorld::instanceExists()) + { + LLWorld::createInstance(); + } + LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop")); LLSD newFrame; - LL_ALWAYS_RECORD_BLOCK_TIME(FTM_FRAME); + { + LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df LLTrace"); + if (LLFloaterReg::instanceVisible("block_timers")) + { LLTrace::BlockTimer::processTimes(); + } + LLTrace::get_frame_recording().nextPeriod(); LLTrace::BlockTimer::logStats(); + } LLTrace::get_thread_recorder()->pullFromChildren(); @@ -1439,6 +1414,7 @@ bool LLAppViewer::doFrame() LL_CLEAR_CALLSTACKS(); { + LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df processMiscNativeEvents" ) pingMainloopTimeout("Main:MiscNativeWindowEvents"); if (gViewerWindow) @@ -1447,7 +1423,10 @@ bool LLAppViewer::doFrame() gViewerWindow->getWindow()->processMiscNativeEvents(); } + { + LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df gatherInput" ) pingMainloopTimeout("Main:GatherInput"); + } if (gViewerWindow) { @@ -1471,13 +1450,23 @@ bool LLAppViewer::doFrame() } } + { + LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df mainloop" ) // canonical per-frame event mainloop.post(newFrame); + } + + { + LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df suspend" ) // give listeners a chance to run llcoro::suspend(); + // if one of our coroutines threw an uncaught exception, rethrow it now + LLCoros::instance().rethrow(); + } if (!LLApp::isExiting()) { + LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df JoystickKeyboard" ) pingMainloopTimeout("Main:JoystickKeyboard"); // Scan keyboard for movement keys. Command keys and typing @@ -1500,12 +1489,20 @@ bool LLAppViewer::doFrame() // Update state based on messages, user input, object idle. { - pauseMainloopTimeout(); // *TODO: Remove. Messages shouldn't be stalling for 20+ seconds! + { + LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df pauseMainloopTimeout" ) + pauseMainloopTimeout(); // *TODO: Remove. Messages shouldn't be stalling for 20+ seconds! + } - LL_ALWAYS_RECORD_BLOCK_TIME(FTM_IDLE); - idle(); + { + LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df idle"); //LL_RECORD_BLOCK_TIME(FTM_IDLE); + idle(); + } - resumeMainloopTimeout(); + { + LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df resumeMainloopTimeout" ) + resumeMainloopTimeout(); + } } if (gDoDisconnect && (LLStartUp::getStartupState() == STATE_STARTED)) @@ -1526,49 +1523,51 @@ bool LLAppViewer::doFrame() // *TODO: Should we run display() even during gHeadlessClient? DK 2011-02-18 if (!LLApp::isExiting() && !gHeadlessClient && gViewerWindow) { + LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df Display" ) pingMainloopTimeout("Main:Display"); gGLActive = TRUE; display(); - static U64 last_call = 0; - if (!gTeleportDisplay) { - // Frame/draw throttling, controlled by FramePerSecondLimit - U64 elapsed_time = LLTimer::getTotalTime() - last_call; - if (elapsed_time < mMinMicroSecPerFrame) - { - LL_RECORD_BLOCK_TIME(FTM_SLEEP); - // llclamp for when time function gets funky - U64 sleep_time = llclamp(mMinMicroSecPerFrame - elapsed_time, (U64)1, (U64)1e6); - micro_sleep(sleep_time); - } - } - last_call = LLTimer::getTotalTime(); - + LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df Snapshot" ) pingMainloopTimeout("Main:Snapshot"); LLFloaterSnapshot::update(); // take snapshots LLFloaterOutfitSnapshot::update(); gGLActive = FALSE; } } + } + { + LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df pauseMainloopTimeout" ) pingMainloopTimeout("Main:Sleep"); pauseMainloopTimeout(); + } // Sleep and run background threads { - LL_ALWAYS_RECORD_BLOCK_TIME(FTM_SLEEP); + //LL_RECORD_BLOCK_TIME(SLEEP2); + LL_PROFILE_ZONE_WARN( "Sleep2" ) // yield some time to the os based on command line option static LLCachedControl<S32> yield_time(gSavedSettings, "YieldTime", -1); if(yield_time >= 0) { LL_RECORD_BLOCK_TIME(FTM_YIELD); + LL_PROFILE_ZONE_NUM( yield_time ) ms_sleep(yield_time); } + if (gNonInteractive) + { + S32 non_interactive_ms_sleep_time = 100; + LLAppViewer::getTextureCache()->pause(); + LLAppViewer::getImageDecodeThread()->pause(); + ms_sleep(non_interactive_ms_sleep_time); + } + // yield cooperatively when not running as foreground window // and when not quiting (causes trouble at mac's cleanup stage) if (!LLApp::isExiting() @@ -1576,8 +1575,8 @@ bool LLAppViewer::doFrame() || !gFocusMgr.getAppHasFocus())) { // Sleep if we're not rendering, or the window is minimized. - static LLCachedControl<S32> s_bacground_yeild_time(gSavedSettings, "BackgroundYieldTime", 40); - S32 milliseconds_to_sleep = llclamp((S32)s_bacground_yeild_time, 0, 1000); + static LLCachedControl<S32> s_background_yield_time(gSavedSettings, "BackgroundYieldTime", 40); + S32 milliseconds_to_sleep = llclamp((S32)s_background_yield_time, 0, 1000); // don't sleep when BackgroundYieldTime set to 0, since this will still yield to other threads // of equal priority on Windows if (milliseconds_to_sleep > 0) @@ -1624,22 +1623,29 @@ bool LLAppViewer::doFrame() total_io_pending += io_pending ; } + + { + LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df gMeshRepo" ) gMeshRepo.update() ; + } if(!total_work_pending) //pause texture fetching threads if nothing to process. { + LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df getTextureCache" ) LLAppViewer::getTextureCache()->pause(); LLAppViewer::getImageDecodeThread()->pause(); LLAppViewer::getTextureFetch()->pause(); } if(!total_io_pending) //pause file threads if nothing to process. { + LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df LLVFSThread" ) LLLFSThread::sLocal->pause(); } //texture fetching debugger if(LLTextureFetchDebugger::isEnabled()) { + LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df tex_fetch_debugger_instance" ) LLFloaterTextureFetchDebugger* tex_fetch_debugger_instance = LLFloaterReg::findTypedInstance<LLFloaterTextureFetchDebugger>("tex_fetch_debugger"); if(tex_fetch_debugger_instance) @@ -1648,8 +1654,10 @@ bool LLAppViewer::doFrame() } } + { + LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df resumeMainloopTimeout" ) resumeMainloopTimeout(); - + } pingMainloopTimeout("Main:End"); } } @@ -1675,7 +1683,7 @@ bool LLAppViewer::doFrame() LL_INFOS() << "Exiting main_loop" << LL_ENDL; } - LLPROFILE_UPDATE(); + LL_PROFILER_FRAME_END return ! LLApp::isRunning(); } @@ -1760,6 +1768,7 @@ bool LLAppViewer::cleanup() LLPluginProcessParent::shutdown(); disconnectViewer(); + LLViewerCamera::deleteSingleton(); LL_INFOS() << "Viewer disconnected" << LL_ENDL; @@ -1945,7 +1954,7 @@ bool LLAppViewer::cleanup() if (LLEnvironment::instanceExists()) { - //Store environment settings if nessesary + //Store environment settings if necessary LLEnvironment::getInstance()->saveToSettings(); } @@ -2052,6 +2061,10 @@ bool LLAppViewer::cleanup() sTextureCache->shutdown(); sImageDecodeThread->shutdown(); sPurgeDiskCacheThread->shutdown(); + if (mGeneralThreadPool) + { + mGeneralThreadPool->close(); + } sTextureFetch->shutDownTextureCacheThread() ; sTextureFetch->shutDownImageDecodeThread() ; @@ -2076,6 +2089,8 @@ bool LLAppViewer::cleanup() mFastTimerLogThread = NULL; delete sPurgeDiskCacheThread; sPurgeDiskCacheThread = NULL; + delete mGeneralThreadPool; + mGeneralThreadPool = NULL; if (LLFastTimerView::sAnalyzePerformance) { @@ -2141,6 +2156,11 @@ bool LLAppViewer::cleanup() LLError::LLCallStacks::cleanup(); + LLEnvironment::deleteSingleton(); + LLSelectMgr::deleteSingleton(); + LLViewerEventRecorder::deleteSingleton(); + LLWorld::deleteSingleton(); + // It's not at first obvious where, in this long sequence, a generic cleanup // call OUGHT to go. So let's say this: as we migrate cleanup from // explicit hand-placed calls into the generic mechanism, eventually @@ -2160,6 +2180,24 @@ bool LLAppViewer::cleanup() return true; } +void LLAppViewer::initGeneralThread() +{ + if (mGeneralThreadPool) + { + return; + } + + LLSD poolSizes{ gSavedSettings.getLLSD("ThreadPoolSizes") }; + LLSD sizeSpec{ poolSizes["General"] }; + LLSD::Integer poolSize{ sizeSpec.isInteger() ? sizeSpec.asInteger() : 3 }; + LL_DEBUGS("ThreadPool") << "Instantiating General pool with " + << poolSize << " threads" << LL_ENDL; + // We don't want anyone, especially the main thread, to have to block + // due to this ThreadPool being full. + mGeneralThreadPool = new LL::ThreadPool("General", poolSize, 1024 * 1024); + mGeneralThreadPool->start(); +} + bool LLAppViewer::initThreads() { static const bool enable_threads = true; @@ -2179,6 +2217,7 @@ bool LLAppViewer::initThreads() if (LLTrace::BlockTimer::sLog || LLTrace::BlockTimer::sMetricLog) { + LLTrace::BlockTimer::setLogLock(new LLMutex()); mFastTimerLogThread = new LLFastTimerLogThread(LLTrace::BlockTimer::sLogName); mFastTimerLogThread->start(); } @@ -2330,7 +2369,7 @@ bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key, LL_INFOS("Settings") << "Attempting to load settings for the group " << file.name() << " - from location " << location_key << LL_ENDL; - LLControlGroup* settings_group = LLControlGroup::getInstance(file.name); + auto settings_group = LLControlGroup::getInstance(file.name); if(!settings_group) { LL_WARNS("Settings") << "No matching settings group for name " << file.name() << LL_ENDL; @@ -2425,15 +2464,61 @@ namespace } } // anonymous namespace +// Set a named control temporarily for this session, as when set via the command line --set option. +// Name can be specified as "<control_group>.<control_name>", with default group being Global. +bool tempSetControl(const std::string& name, const std::string& value) +{ + std::string name_part; + std::string group_part; + LLControlVariable* control = NULL; + + // Name can be further split into ControlGroup.Name, with the default control group being Global + size_t pos = name.find('.'); + if (pos != std::string::npos) + { + group_part = name.substr(0, pos); + name_part = name.substr(pos+1); + LL_INFOS() << "Setting " << group_part << "." << name_part << " to " << value << LL_ENDL; + auto g = LLControlGroup::getInstance(group_part); + if (g) control = g->getControl(name_part); + } + else + { + LL_INFOS() << "Setting Global." << name << " to " << value << LL_ENDL; + control = gSavedSettings.getControl(name); + } + + if (control) + { + control->setValue(value, false); + return true; + } + return false; +} + bool LLAppViewer::initConfiguration() { //Load settings files list std::string settings_file_list = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "settings_files.xml"); LLXMLNodePtr root; - BOOL success = LLXMLNode::parseFile(settings_file_list, root, NULL); + BOOL success = LLXMLNode::parseFile(settings_file_list, root, NULL); if (!success) { - LL_ERRS() << "Cannot load default configuration file " << settings_file_list << LL_ENDL; + LL_WARNS() << "Cannot load default configuration file " << settings_file_list << LL_ENDL; + if (gDirUtilp->fileExists(settings_file_list)) + { + LL_ERRS() << "Cannot load default configuration file settings_files.xml. " + << "Please reinstall viewer from https://secondlife.com/support/downloads/ " + << "and contact https://support.secondlife.com if issue persists after reinstall." + << LL_ENDL; + } + else + { + LL_ERRS() << "Default configuration file settings_files.xml not found. " + << "Please reinstall viewer from https://secondlife.com/support/downloads/ " + << "and contact https://support.secondlife.com if issue persists after reinstall." + << LL_ENDL; + } } mSettingsLocationList = new SettingsFiles(); @@ -2475,12 +2560,7 @@ bool LLAppViewer::initConfiguration() #ifndef LL_RELEASE_FOR_DOWNLOAD // provide developer build only overrides for these control variables that are not // persisted to settings.xml - LLControlVariable* c = gSavedSettings.getControl("ShowConsoleWindow"); - if (c) - { - c->setValue(true, false); - } - c = gSavedSettings.getControl("AllowMultipleViewers"); + LLControlVariable* c = gSavedSettings.getControl("AllowMultipleViewers"); if (c) { c->setValue(true, false); @@ -2586,9 +2666,10 @@ bool LLAppViewer::initConfiguration() disableCrashlogger(); } + gNonInteractive = gSavedSettings.getBOOL("NonInteractive"); // Handle initialization from settings. // Start up the debugging console before handling other options. - if (gSavedSettings.getBOOL("ShowConsoleWindow")) + if (gSavedSettings.getBOOL("ShowConsoleWindow") && !gNonInteractive) { initConsole(); } @@ -2621,31 +2702,7 @@ bool LLAppViewer::initConfiguration() { const std::string& name = *itr; const std::string& value = *(++itr); - std::string name_part; - std::string group_part; - LLControlVariable* control = NULL; - - // Name can be further split into ControlGroup.Name, with the default control group being Global - size_t pos = name.find('.'); - if (pos != std::string::npos) - { - group_part = name.substr(0, pos); - name_part = name.substr(pos+1); - LL_INFOS() << "Setting " << group_part << "." << name_part << " to " << value << LL_ENDL; - LLControlGroup* g = LLControlGroup::getInstance(group_part); - if (g) control = g->getControl(name_part); - } - else - { - LL_INFOS() << "Setting Global." << name << " to " << value << LL_ENDL; - control = gSavedSettings.getControl(name); - } - - if (control) - { - control->setValue(value, false); - } - else + if (!tempSetControl(name,value)) { LL_WARNS() << "Failed --set " << name << ": setting name unknown." << LL_ENDL; } @@ -2686,19 +2743,14 @@ bool LLAppViewer::initConfiguration() if (clp.hasOption("graphicslevel")) { - // User explicitly requested --graphicslevel on the command line. We - // expect this switch has already set RenderQualityPerformance. Check - // that value for validity. - U32 graphicslevel = gSavedSettings.getU32("RenderQualityPerformance"); - if (LLFeatureManager::instance().isValidGraphicsLevel(graphicslevel)) - { - // graphicslevel is valid: save it and engage it later. Capture - // the requested value separately from the settings variable - // because, if this is the first run, LLViewerWindow's constructor - // will call LLFeatureManager::applyRecommendedSettings(), which - // overwrites this settings variable! - mForceGraphicsLevel = graphicslevel; - } + // User explicitly requested --graphicslevel on the command line. We + // expect this switch has already set RenderQualityPerformance. Check + // that value for validity later. + // Capture the requested value separately from the settings variable + // because, if this is the first run, LLViewerWindow's constructor + // will call LLFeatureManager::applyRecommendedSettings(), which + // overwrites this settings variable! + mForceGraphicsLevel = gSavedSettings.getU32("RenderQualityPerformance"); } LLFastTimerView::sAnalyzePerformance = gSavedSettings.getBOOL("AnalyzePerformance"); @@ -2712,6 +2764,15 @@ bool LLAppViewer::initConfiguration() ll_init_fail_log(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "test_failures.log")); } + if (gSavedSettings.getBOOL("RenderDebugGLSession")) + { + gDebugGLSession = TRUE; + gDebugGL = TRUE; + // gDebugGL can cause excessive logging + // so it's limited to a single session + gSavedSettings.setBOOL("RenderDebugGLSession", FALSE); + } + const LLControlVariable* skinfolder = gSavedSettings.getControl("SkinCurrent"); if(skinfolder && LLStringUtil::null != skinfolder->getValue().asString()) { @@ -2735,6 +2796,19 @@ bool LLAppViewer::initConfiguration() } } + if (gNonInteractive) + { + tempSetControl("AllowMultipleViewers", "TRUE"); + tempSetControl("SLURLPassToOtherInstance", "FALSE"); + tempSetControl("RenderWater", "FALSE"); + tempSetControl("FlyingAtExit", "FALSE"); + tempSetControl("WindowWidth", "1024"); + tempSetControl("WindowHeight", "200"); + LLError::setEnabledLogTypesMask(0); + llassert_always(!gSavedSettings.getBOOL("SLURLPassToOtherInstance")); + } + + // Handle slurl use. NOTE: Don't let SL-55321 reappear. // This initial-SLURL logic, up through the call to // sendURLToOtherInstance(), must precede LLSplashScreen::show() -- @@ -3034,7 +3108,7 @@ bool LLAppViewer::initWindow() // Initialize GL stuff // - if (mForceGraphicsLevel) + if (mForceGraphicsLevel && (LLFeatureManager::instance().isValidGraphicsLevel(*mForceGraphicsLevel))) { LLFeatureManager::getInstance()->setGraphicsLevel(*mForceGraphicsLevel, false); gSavedSettings.setU32("RenderQualityPerformance", *mForceGraphicsLevel); @@ -3080,6 +3154,11 @@ bool LLAppViewer::isUpdaterMissing() return mUpdaterNotFound; } +bool LLAppViewer::waitForUpdater() +{ + return !gSavedSettings.getBOOL("CmdLineSkipUpdater") && !mUpdaterNotFound && !gNonInteractive; +} + void LLAppViewer::writeDebugInfo(bool isStatic) { #if LL_WINDOWS && LL_BUGSPLAT @@ -3187,7 +3266,28 @@ LLSD LLAppViewer::getViewerInfo() const info["GRAPHICS_CARD"] = ll_safe_string((const char*)(glGetString(GL_RENDERER))); #if LL_WINDOWS - std::string drvinfo = gDXHardware.getDriverVersionWMI(); + std::string drvinfo; + + if (gGLManager.mIsIntel) + { + drvinfo = gDXHardware.getDriverVersionWMI(LLDXHardware::GPU_INTEL); + } + else if (gGLManager.mIsNVIDIA) + { + drvinfo = gDXHardware.getDriverVersionWMI(LLDXHardware::GPU_NVIDIA); + } + else if (gGLManager.mIsAMD) + { + drvinfo = gDXHardware.getDriverVersionWMI(LLDXHardware::GPU_AMD); + } + + if (drvinfo.empty()) + { + // Generic/substitute windows driver? Unknown vendor? + LL_WARNS("DriverVersion") << "Vendor based driver search failed, searching for any driver" << LL_ENDL; + drvinfo = gDXHardware.getDriverVersionWMI(LLDXHardware::GPU_ANY); + } + if (!drvinfo.empty()) { info["GRAPHICS_DRIVER_VERSION"] = drvinfo; @@ -3233,9 +3333,18 @@ LLSD LLAppViewer::getViewerInfo() const info["AUDIO_DRIVER_VERSION"] = gAudiop ? LLSD(gAudiop->getDriverName(want_fullname)) : "Undefined"; if(LLVoiceClient::getInstance()->voiceEnabled()) { - LLVoiceVersionInfo version = LLVoiceClient::getInstance()->getVersion(); + LLVoiceVersionInfo version = LLVoiceClient::getInstance()->getVersion(); + const std::string build_version = version.mBuildVersion; std::ostringstream version_string; - version_string << version.serverType << " " << version.serverVersion << std::endl; + if (std::equal(build_version.begin(), build_version.begin() + version.serverVersion.size(), + version.serverVersion.begin())) + { // Normal case: Show type and build version. + version_string << version.serverType << " " << build_version << std::endl; + } + else + { // Mismatch: Show both versions. + version_string << version.serverVersion << "/" << build_version << std::endl; + } info["VOICE_VERSION"] = version_string.str(); } else @@ -3433,7 +3542,7 @@ void LLAppViewer::cleanupSavedSettings() } } - gSavedSettings.setF32("MapScale", LLWorldMapView::sMapScale ); + gSavedSettings.setF32("MapScale", LLWorldMapView::getScaleSetting()); // Some things are cached in LLAgent. if (gAgent.isInitialized()) @@ -4176,6 +4285,15 @@ U32 LLAppViewer::getTextureCacheVersion() return TEXTURE_CACHE_VERSION ; } +//static +U32 LLAppViewer::getDiskCacheVersion() +{ + // Viewer disk cache version intorduced in Simple Cache Viewer, change if the cache format changes. + const U32 DISK_CACHE_VERSION = 1; + + return DISK_CACHE_VERSION ; +} + //static U32 LLAppViewer::getObjectCacheVersion() { @@ -4203,12 +4321,16 @@ bool LLAppViewer::initCache() const uintmax_t disk_cache_bytes = disk_cache_mb * 1024 * 1024; bool texture_cache_mismatch = false; + bool remove_vfs_files = false; if (gSavedSettings.getS32("LocalCacheVersion") != LLAppViewer::getTextureCacheVersion()) { texture_cache_mismatch = true; if(!read_only) { gSavedSettings.setS32("LocalCacheVersion", LLAppViewer::getTextureCacheVersion()); + + //texture cache version was bumped up in Simple Cache Viewer, and at this point old vfs files are not needed + remove_vfs_files = true; } } @@ -4255,14 +4377,26 @@ bool LLAppViewer::initCache() if (!read_only) { - if (mPurgeCache) + if (gSavedSettings.getS32("DiskCacheVersion") != LLAppViewer::getDiskCacheVersion()) + { + LLDiskCache::getInstance()->clearCache(); + remove_vfs_files = true; + gSavedSettings.setS32("DiskCacheVersion", LLAppViewer::getDiskCacheVersion()); + } + + if (remove_vfs_files) + { + LLDiskCache::getInstance()->removeOldVFSFiles(); + } + + if (mPurgeCache) { - LLSplashScreen::update(LLTrans::getString("StartupClearingCache")); - purgeCache(); + LLSplashScreen::update(LLTrans::getString("StartupClearingCache")); + purgeCache(); // clear the new C++ file system based cache LLDiskCache::getInstance()->clearCache(); - } + } else { // purge excessive files from the new file system based cache @@ -4274,7 +4408,6 @@ bool LLAppViewer::initCache() LLSplashScreen::update(LLTrans::getString("StartupInitializingTextureCache")); // Init the texture cache - // Allocate 80% of the cache size for textures const S32 MB = 1024 * 1024; const S64 MIN_CACHE_SIZE = 512 * MB; const S64 MAX_CACHE_SIZE = 9984ll * MB; @@ -4289,7 +4422,7 @@ bool LLAppViewer::initCache() void LLAppViewer::addOnIdleCallback(const boost::function<void()>& cb) { - LLDeferredTaskList::instance().addTask(cb); + gMainloopWork.post(cb); } void LLAppViewer::loadKeyBindings() @@ -4561,6 +4694,7 @@ static LLTrace::BlockTimerStatHandle FTM_HUD_EFFECTS("HUD Effects"); /////////////////////////////////////////////////////// void LLAppViewer::idle() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_APP; pingMainloopTimeout("Main:Idle"); // Update frame timers @@ -4579,6 +4713,20 @@ void LLAppViewer::idle() LLDirPickerThread::clearDead(); F32 dt_raw = idle_timer.getElapsedTimeAndResetF32(); + // Service the WorkQueue we use for replies from worker threads. + // Use function statics for the timeslice setting so we only have to fetch + // and convert MainWorkTime once. + static F32 MainWorkTimeRaw = gSavedSettings.getF32("MainWorkTime"); + static F32Milliseconds MainWorkTimeMs(MainWorkTimeRaw); + // MainWorkTime is specified in fractional milliseconds, but std::chrono + // uses integer representations. What if we want less than a microsecond? + // Use nanoseconds. We're very sure we will never need to specify a + // MainWorkTime that would be larger than we could express in + // std::chrono::nanoseconds. + static std::chrono::nanoseconds MainWorkTimeNanoSec{ + std::chrono::nanoseconds::rep(MainWorkTimeMs.value() * 1000000)}; + gMainloopWork.runFor(MainWorkTimeNanoSec); + // Cap out-of-control frame times // Too low because in menus, swapping, debugger, etc. // Too high because idle called with no objects in view, etc. @@ -4627,13 +4775,13 @@ void LLAppViewer::idle() gGLActive = FALSE; } - auto& worldInst = LLWorld::instanceFast(); + auto& worldInst = LLWorld::instance(); F32 yaw = 0.f; // radians if (!gDisconnected) { - LL_RECORD_BLOCK_TIME(FTM_NETWORK); + LL_PROFILE_ZONE_NAMED_CATEGORY_NETWORK("network"); //LL_RECORD_BLOCK_TIME(FTM_NETWORK); // Update spaceserver timeinfo worldInst.setSpaceTimeUSec(worldInst.getSpaceTimeUSec() + LLUnits::Seconds::fromValue(dt_raw)); @@ -4666,7 +4814,7 @@ void LLAppViewer::idle() || (agent_force_update_time > (1.0f / (F32) AGENT_FORCE_UPDATES_PER_SECOND)); if (force_update || (agent_update_time > (1.0f / (F32) AGENT_UPDATES_PER_SECOND))) { - LL_RECORD_BLOCK_TIME(FTM_AGENT_UPDATE); + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; //LL_RECORD_BLOCK_TIME(FTM_AGENT_UPDATE); // Send avatar and camera info mLastAgentControlFlags = gAgent.getControlFlags(); mLastAgentForceUpdate = force_update ? 0 : agent_force_update_time; @@ -4770,13 +4918,18 @@ void LLAppViewer::idle() } } + + // Update layonts, handle mouse events, tooltips, e t c + // updateUI() needs to be called even in case viewer disconected + // since related notification still needs handling and allows + // opening chat. + gViewerWindow->updateUI(); + if (gDisconnected) { return; } - gViewerWindow->updateUI(); - if (gTeleportDisplay) { return; @@ -4790,7 +4943,7 @@ void LLAppViewer::idle() { // After agent and camera moved, figure out if we need to // deselect objects. - LLSelectMgr::getInstanceFast()->deselectAllIfTooFar(); + LLSelectMgr::getInstance()->deselectAllIfTooFar(); } @@ -4844,7 +4997,7 @@ void LLAppViewer::idle() { LL_RECORD_BLOCK_TIME(FTM_HUD_EFFECTS); - LLSelectMgr::getInstanceFast()->updateEffects(); + LLSelectMgr::getInstance()->updateEffects(); LLHUDManager::getInstance()->cleanupEffects(); LLHUDManager::getInstance()->sendEffects(); } @@ -4903,8 +5056,10 @@ void LLAppViewer::idle() // Here, particles are updated and drawables are moved. // - LL_RECORD_BLOCK_TIME(FTM_WORLD_UPDATE); - gPipeline.updateMove(); + { + LL_PROFILE_ZONE_NAMED_CATEGORY_APP("world update"); //LL_RECORD_BLOCK_TIME(FTM_WORLD_UPDATE); + gPipeline.updateMove(); + } worldInst.updateParticles(); @@ -4912,22 +5067,22 @@ void LLAppViewer::idle() { gAgentPilot.moveCamera(); } - else if (LLViewerJoystick::getInstanceFast()->getOverrideCamera()) + else if (LLViewerJoystick::getInstance()->getOverrideCamera()) { - LLViewerJoystick::getInstanceFast()->moveFlycam(); + LLViewerJoystick::getInstance()->moveFlycam(); } else { - if (LLToolMgr::getInstanceFast()->inBuildMode()) + if (LLToolMgr::getInstance()->inBuildMode()) { - LLViewerJoystick::getInstanceFast()->moveObjects(); + LLViewerJoystick::getInstance()->moveObjects(); } gAgentCamera.updateCamera(); } // update media focus - LLViewerMediaFocus::getInstanceFast()->update(); + LLViewerMediaFocus::getInstance()->update(); // Update marketplace LLMarketplaceInventoryImporter::update(); @@ -4943,7 +5098,7 @@ void LLAppViewer::idle() LLAvatarRenderInfoAccountant::getInstance()->idle(); { - LL_RECORD_BLOCK_TIME(FTM_AUDIO_UPDATE); + LL_PROFILE_ZONE_NAMED_CATEGORY_APP("audio update"); //LL_RECORD_BLOCK_TIME(FTM_AUDIO_UPDATE); if (gAudiop) { @@ -4952,14 +5107,10 @@ void LLAppViewer::idle() audio_update_wind(false); // this line actually commits the changes we've made to source positions, etc. - const F32 max_audio_decode_time = 0.002f; // 2 ms decode time - gAudiop->idle(max_audio_decode_time); + gAudiop->idle(); } } - // Execute deferred tasks. - LLDeferredTaskList::instance().run(); - // Handle shutdown process, for example, // wait for floaters to close, send quit message, // forcibly quit if it has taken too long @@ -5187,6 +5338,7 @@ static LLTrace::BlockTimerStatHandle FTM_CHECK_REGION_CIRCUIT("Check Region Circ void LLAppViewer::idleNetwork() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; pingMainloopTimeout("idleNetwork"); gObjectList.mNumNewObjects = 0; @@ -5195,7 +5347,7 @@ void LLAppViewer::idleNetwork() static const LLCachedControl<bool> speedTest(gSavedSettings, "SpeedTest"); if (!speedTest) { - LL_RECORD_BLOCK_TIME(FTM_IDLE_NETWORK); // decode + LL_PROFILE_ZONE_NAMED_CATEGORY_NETWORK("idle network"); //LL_RECORD_BLOCK_TIME(FTM_IDLE_NETWORK); // decode LLTimer check_message_timer; // Read all available packets from network @@ -5366,7 +5518,7 @@ void LLAppViewer::disconnectViewer() // Now we just ask the LLWorld singleton to cleanly shut down. if(LLWorld::instanceExists()) { - LLWorld::getInstance()->destroyClass(); + LLWorld::getInstance()->resetClass(); } LLVOCache::deleteSingleton(); @@ -5381,19 +5533,6 @@ void LLAppViewer::disconnectViewer() LLUrlEntryParcel::setDisconnected(gDisconnected); } -bool LLAppViewer::onChangeFrameLimit(LLSD const & evt) -{ - if (evt.asInteger() > 0) - { - mMinMicroSecPerFrame = (U64)(1000000.0f / F32(evt.asInteger())); - } - else - { - mMinMicroSecPerFrame = 0; - } - return false; -} - void LLAppViewer::forceErrorLLError() { LL_ERRS() << "This is a deliberate llerror" << LL_ENDL; @@ -5566,7 +5705,7 @@ void LLAppViewer::handleLoginComplete() { setCrashUserMetadata(gAgent.getID(), gAgentAvatarp->getFullname()); gWindowTitle.append(" - ").append(gAgentAvatarp->getFullname()); - gViewerWindow->setWindowTitle(gWindowTitle); + gViewerWindow->getWindow()->setTitle(gWindowTitle); } mOnLoginCompleted(); diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index 43dd79e84a2ceb37cf8f4fdd94cdd934c8b2efe6..735e7b88722af3efb8d00ffcf5a175ea43eb7ead 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -49,6 +49,8 @@ #include "lltimer.h" #include "llappcorehttp.h" +#include <boost/signals2.hpp> + class LLCommandLineParser; class LLFrameTimer; class LLPumpIO; @@ -60,6 +62,11 @@ class LLViewerJoystick; class LLPurgeDiskCacheThread; class LLViewerRegion; +namespace LL +{ + class ThreadPool; +} + extern LLTrace::BlockTimerStatHandle FTM_FRAME; class LLAppViewer : public LLApp @@ -68,13 +75,13 @@ class LLAppViewer : public LLApp LLAppViewer(); virtual ~LLAppViewer(); - /** - * @brief Access to the LLAppViewer singleton. - * - * The LLAppViewer singleton is created in main()/WinMain(). - * So don't use it in pre-entry (static initialization) code. - */ - static LLAppViewer* instance() {return sInstance; } + /** + * @brief Access to the LLAppViewer singleton. + * + * The LLAppViewer singleton is created in main()/WinMain(). + * So don't use it in pre-entry (static initialization) code. + */ + static LLAppViewer* instance() {return sInstance; } // // Main application logic @@ -92,12 +99,13 @@ class LLAppViewer : public LLApp void earlyExit(const std::string& name, const LLSD& substitutions = LLSD()); // Display an error dialog and forcibly quit. void earlyExitNoNotify(); // Do not display error dialog then forcibly quit. - void abortQuit(); // Called to abort a quit request. + void abortQuit(); // Called to abort a quit request. - bool quitRequested() { return mQuitRequested; } - bool logoutRequestSent() { return mLogoutRequestSent; } + bool quitRequested() { return mQuitRequested; } + bool logoutRequestSent() { return mLogoutRequestSent; } bool isSecondInstance() { return mSecondInstance; } bool isUpdaterMissing(); // In use by tests + bool waitForUpdater(); void writeDebugInfo(bool isStatic=true); @@ -112,7 +120,7 @@ class LLAppViewer : public LLApp // return false if the error trap needed restoration. virtual void initCrashReporting(bool reportFreeze = false) = 0; // What to do with crash report? static void handleViewerCrash(); // Hey! The viewer crashed. Do this, soon. - void checkForCrash(); + void checkForCrash(); // Thread accessors static LLTextureCache* getTextureCache() { return sTextureCache; } @@ -122,28 +130,29 @@ class LLAppViewer : public LLApp static U32 getTextureCacheVersion() ; static U32 getObjectCacheVersion() ; + static U32 getDiskCacheVersion() ; const std::string& getSerialNumber() { return mSerialNumber; } - + bool getPurgeCache() const { return mPurgeCache; } - + std::string getSecondLifeTitle() const; // The Second Life title. std::string getWindowTitle() const; // The window display name. - void forceDisconnect(const std::string& msg); // Force disconnection, with a message to the user. - void badNetworkHandler(); // Cause a crash state due to bad network packet. + void forceDisconnect(const std::string& msg); // Force disconnection, with a message to the user. + void badNetworkHandler(); // Cause a crash state due to bad network packet. bool hasSavedFinalSnapshot() { return mSavedFinalSnapshot; } void saveFinalSnapshot(); - void loadNameCache(); - void saveNameCache(); + void loadNameCache(); + void saveNameCache(); void loadExperienceCache(); void saveExperienceCache(); void removeMarkerFiles(); - + void removeDumpDir(); // LLAppViewer testing helpers. // *NOTE: These will potentially crash the viewer. Only for debugging. @@ -190,17 +199,21 @@ class LLAppViewer : public LLApp // On LoginCompleted callback typedef boost::signals2::signal<void (void)> login_completed_signal_t; login_completed_signal_t mOnLoginCompleted; - boost::signals2::connection setOnLoginCompletedCallback( const login_completed_signal_t::slot_type& cb ) { return mOnLoginCompleted.connect(cb); } + boost::signals2::connection setOnLoginCompletedCallback( const login_completed_signal_t::slot_type& cb ) + { + return mOnLoginCompleted.connect(cb); + } void addOnIdleCallback(const boost::function<void()>& cb); // add a callback to fire (once) when idle + void initGeneralThread(); void purgeUserDataOnExit() { mPurgeUserDataOnExit = true; } void purgeCache(); // Clear the local cache. void purgeCacheImmediate(); //clear local cache immediately. S32 updateTextureThreads(F32 max_time); void loadKeyBindings(); - + // mute/unmute the system's master audio virtual void setMasterSystemAudioMute(bool mute); virtual bool getMasterSystemAudioMute(); @@ -212,7 +225,7 @@ class LLAppViewer : public LLApp // llcorehttp init/shutdown/config information. LLAppCoreHttp & getAppCoreHttp() { return mAppCoreHttp; } - void updateNameLookupUrl(const LLViewerRegion* regionp); + void updateNameLookupUrl(const LLViewerRegion* regionp); protected: virtual bool initWindow(); // Initialize the viewer's window. @@ -223,7 +236,7 @@ class LLAppViewer : public LLApp virtual bool sendURLToOtherInstance(const std::string& url); virtual bool initParseCommandLine(LLCommandLineParser& clp) - { return true; } // Allow platforms to specify the command line args. + { return true; } // Allow platforms to specify the command line args. virtual std::string generateSerialNumber() = 0; // Platforms specific classes generate this. @@ -249,24 +262,21 @@ class LLAppViewer : public LLApp void processMarkerFiles(); static void recordMarkerVersion(LLAPRFile& marker_file); bool markerIsSameVersion(const std::string& marker_name) const; - - void idle(); - void idleShutdown(); + + void idle(); + void idleShutdown(); // update avatar SLID and display name caches - void idleExperienceCache(); void idleNameCache(); - void idleNetwork(); - - void sendLogoutRequest(); - void disconnectViewer(); + void idleNetwork(); - bool onChangeFrameLimit(LLSD const & evt); + void sendLogoutRequest(); + void disconnectViewer(); // *FIX: the app viewer class should be some sort of singleton, no? // Perhaps its child class is the singleton and this should be an abstract base. static LLAppViewer* sInstance; - bool mSecondInstance; // Is this a second instance of the app? + bool mSecondInstance; // Is this a second instance of the app? bool mUpdaterNotFound; // True when attempt to start updater failed std::string mMarkerFileName; @@ -284,6 +294,7 @@ class LLAppViewer : public LLApp static LLImageDecodeThread* sImageDecodeThread; static LLTextureFetch* sTextureFetch; static LLPurgeDiskCacheThread* sPurgeDiskCacheThread; + LL::ThreadPool* mGeneralThreadPool; S32 mNumSessions; @@ -298,8 +309,8 @@ class LLAppViewer : public LLApp boost::optional<U32> mForceGraphicsLevel; - bool mQuitRequested; // User wants to quit, may have modified documents open. - bool mLogoutRequestSent; // Disconnect message sent to simulator, no longer safe to send messages to the sim. + bool mQuitRequested; // User wants to quit, may have modified documents open. + bool mLogoutRequestSent; // Disconnect message sent to simulator, no longer safe to send messages to the sim. U32 mLastAgentControlFlags; F32 mLastAgentForceUpdate; struct SettingsFiles* mSettingsLocationList; @@ -316,10 +327,7 @@ class LLAppViewer : public LLApp // llcorehttp library init/shutdown helper LLAppCoreHttp mAppCoreHttp; - bool mIsFirstRun; - U64 mMinMicroSecPerFrame; // frame throttling - - + bool mIsFirstRun; }; // consts from viewer.h diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index 88ab4263e8e20b62d9476ee3fcc05c4c7b3f7e23..c97256441127b61fb9716af38d712d2896acce58 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -316,6 +316,11 @@ int APIENTRY WINMAIN(HINSTANCE hInstance, PWSTR pCmdLine, int nCmdShow) { + // Call Tracy first thing to have it allocate memory + // https://github.com/wolfpld/tracy/issues/196 + LL_PROFILER_FRAME_END; + LL_PROFILER_SET_THREAD_NAME("App"); + const S32 MAX_HEAPS = 255; DWORD heap_enable_lfh_error[MAX_HEAPS]; S32 num_heaps = 0; diff --git a/indra/newview/llaudiosourcevo.cpp b/indra/newview/llaudiosourcevo.cpp index 74ee159cd8a4a217b3f60b0c624a7fa2181facbc..cbd3f6af2cc627adf98cf206f4f2612e5a89d7a1 100644 --- a/indra/newview/llaudiosourcevo.cpp +++ b/indra/newview/llaudiosourcevo.cpp @@ -34,6 +34,7 @@ #include "llmutelist.h" #include "llviewercontrol.h" #include "llviewerparcelmgr.h" +#include "llvoavatarself.h" LLAudioSourceVO::LLAudioSourceVO(const LLUUID &sound_id, const LLUUID& owner_id, const F32 gain, LLViewerObject *objectp) : LLAudioSource(sound_id, owner_id, gain, LLAudioEngine::AUDIO_TYPE_SFX), @@ -141,15 +142,40 @@ void LLAudioSourceVO::updateMute() LLVector3d pos_global = getPosGlobal(); F32 cutoff = mObjectp->getSoundCutOffRadius(); - if ((cutoff > 0.1f && !isInCutOffRadius(pos_global, cutoff)) // consider cutoff below 0.1m as off - || !LLViewerParcelMgr::getInstanceFast()->canHearSound(pos_global)) - { - mute = true; - } + // Object can specify radius at which it turns off + // consider cutoff below 0.1m as 'cutoff off' + if (cutoff > 0.1f && !isInCutOffRadius(pos_global, cutoff)) + { + mute = true; + } + // check if parcel allows sounds to pass border + else if (!LLViewerParcelMgr::getInstance()->canHearSound(pos_global)) + { + if (isAgentAvatarValid() && gAgentAvatarp->getParent()) + { + // Check if agent is riding this object + // Agent can ride something out of region border and canHearSound + // will treat object as not being part of agent's parcel. + LLViewerObject *sound_root = (LLViewerObject*)mObjectp->getRoot(); + LLViewerObject *agent_root = (LLViewerObject*)gAgentAvatarp->getRoot(); + if (sound_root != agent_root) + { + mute = true; + } + else + { + LL_INFOS() << "roots identical" << LL_ENDL; + } + } + else + { + mute = true; + } + } if (!mute) { - auto& mute_list = LLMuteList::instanceFast(); + auto& mute_list = LLMuteList::instance(); if (mute_list.isMuted(mObjectp->getID())) { mute = true; diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index 4b41b91562a68e244e706c636da530291674aa39..668ee321c1c5b2f7d80a5b219169bf554463bd71 100644 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -63,12 +63,14 @@ #include "llnotificationsutil.h" // for LLNotificationsUtil #include "llpaneloutfitedit.h" #include "llpanelprofile.h" +#include "llparcel.h" #include "llrecentpeople.h" #include "lltrans.h" #include "llviewercontrol.h" #include "llviewerobjectlist.h" #include "llviewermessage.h" // for handle_lure #include "llviewernetwork.h" //LLGridManager +#include "llviewerparcelmgr.h" #include "llviewerregion.h" #include "lltrans.h" #include "llcallingcard.h" @@ -117,10 +119,10 @@ void LLAvatarActions::requestFriendshipDialog(const LLUUID& id, const std::strin payload["id"] = id; payload["name"] = name; - LLNotificationsUtil::add("AddFriendWithMessage", args, payload, &callbackAddFriendWithMessage); + LLNotificationsUtil::add("AddFriendWithMessage", args, payload, &callbackAddFriendWithMessage); // add friend to recent people list - LLRecentPeople::instanceFast().add(id); + LLRecentPeople::instance().add(id); } static void on_avatar_name_friendship(const LLUUID& id, const LLAvatarName av_name) @@ -411,6 +413,34 @@ void LLAvatarActions::showPick(const LLUUID& avatar_id, const LLUUID& pick_id) } } +// static +void LLAvatarActions::createPick() +{ + LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", gAgent.getID()))); + LLViewerRegion* region = gAgent.getRegion(); + if (profilefloater && region) + { + LLPickData data; + data.pos_global = gAgent.getPositionGlobal(); + data.sim_name = region->getName(); + + LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); + if (parcel) + { + data.name = parcel->getName(); + data.desc = parcel->getDesc(); + data.snapshot_id = parcel->getSnapshotID(); + data.parcel_id = parcel->getID(); + } + else + { + data.name = region->getName(); + } + + profilefloater->createPick(data); + } +} + // static bool LLAvatarActions::isPickTabSelected(const LLUUID& avatar_id) { @@ -451,6 +481,16 @@ void LLAvatarActions::showClassified(const LLUUID& avatar_id, const LLUUID& clas } } +// static +void LLAvatarActions::createClassified() +{ + LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", gAgent.getID()))); + if (profilefloater) + { + profilefloater->createClassified(); + } +} + //static bool LLAvatarActions::profileVisible(const LLUUID& avatar_id) { @@ -1165,14 +1205,14 @@ bool LLAvatarActions::toggleBlock(const LLUUID& id) LLMute mute(id, av_name.getUserName(), LLMute::AGENT); - if (LLMuteList::getInstanceFast()->isMuted(mute.mID, mute.mName)) + if (LLMuteList::getInstance()->isMuted(mute.mID, mute.mName)) { - LLMuteList::getInstanceFast()->remove(mute); + LLMuteList::getInstance()->remove(mute); return false; } else { - LLMuteList::getInstanceFast()->add(mute); + LLMuteList::getInstance()->add(mute); return true; } } @@ -1183,7 +1223,7 @@ void LLAvatarActions::toggleMute(const LLUUID& id, U32 flags) LLAvatarName av_name; LLAvatarNameCache::get(id, &av_name); - LLMuteList* mute_list = LLMuteList::getInstanceFast(); + LLMuteList* mute_list = LLMuteList::getInstance(); bool is_muted = mute_list->isMuted(id, flags); LLMute mute(id, av_name.getUserName(), LLMute::AGENT); @@ -1510,13 +1550,13 @@ bool LLAvatarActions::isBlocked(const LLUUID& id) { LLAvatarName av_name; LLAvatarNameCache::get(id, &av_name); - return LLMuteList::getInstanceFast()->isMuted(id, av_name.getUserName()); + return LLMuteList::getInstance()->isMuted(id, av_name.getUserName()); } // static bool LLAvatarActions::isVoiceMuted(const LLUUID& id) { - return LLMuteList::getInstanceFast()->isMuted(id, LLMute::flagVoiceChat); + return LLMuteList::getInstance()->isMuted(id, LLMute::flagVoiceChat); } // static diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h index 366ec9eb27dea1ff0e2de71e29d2e067881ae695..fea27c06e8d7497b6f2da05a91f2c139c1b3f6ec 100644 --- a/indra/newview/llavataractions.h +++ b/indra/newview/llavataractions.h @@ -99,8 +99,10 @@ class LLAvatarActions static void showProfile(const LLUUID& avatar_id); static void showPicks(const LLUUID& avatar_id); static void showPick(const LLUUID& avatar_id, const LLUUID& pick_id); + static void createPick(); static void showClassifieds(const LLUUID& avatar_id); static void showClassified(const LLUUID& avatar_id, const LLUUID& classified_id, bool edit = false); + static void createClassified(); static void hideProfile(const LLUUID& avatar_id); static bool profileVisible(const LLUUID& avatar_id); static bool isPickTabSelected(const LLUUID& avatar_id); diff --git a/indra/newview/llavatariconctrl.cpp b/indra/newview/llavatariconctrl.cpp index ca98600a84ac63a69cace76265507bdcdd249c75..2735e66132e41cdca24d43cc7911f1a2b347e849 100644 --- a/indra/newview/llavatariconctrl.cpp +++ b/indra/newview/llavatariconctrl.cpp @@ -204,7 +204,7 @@ LLAvatarIconCtrl::~LLAvatarIconCtrl() { if (mAvatarId.notNull()) { - LLAvatarPropertiesProcessor::getInstanceFast()->removeObserver(mAvatarId, this); + LLAvatarPropertiesProcessor::getInstance()->removeObserver(mAvatarId, this); // Name callbacks will be automatically disconnected since LLUICtrl is trackable } @@ -220,7 +220,7 @@ void LLAvatarIconCtrl::setValue(const LLSD& value) if (value.isUUID()) { LLAvatarPropertiesProcessor* app = - LLAvatarPropertiesProcessor::getInstanceFast(); + LLAvatarPropertiesProcessor::getInstance(); if (mAvatarId.notNull()) { app->removeObserver(mAvatarId, this); diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp index 5add8e5ba3e0048db721c67399f7d6ac6510e0c1..7b65cfd07e7b01d4f595a2dc509ac753511fae3e 100644 --- a/indra/newview/llavatarlist.cpp +++ b/indra/newview/llavatarlist.cpp @@ -462,7 +462,7 @@ void LLAvatarList::addNewItem(const LLUUID& id, const std::string& name, BOOL is BOOL LLAvatarList::handleRightMouseDown(S32 x, S32 y, MASK mask) { BOOL handled = LLUICtrl::handleRightMouseDown(x, y, mask); - if (mContextMenu) + if ( mContextMenu) { uuid_vec_t selected_uuids; getSelectedUUIDs(selected_uuids); @@ -478,7 +478,7 @@ BOOL LLAvatarList::handleMouseDown(S32 x, S32 y, MASK mask) S32 screen_x; S32 screen_y; localPointToScreen(x, y, &screen_x, &screen_y); - LLToolDragAndDrop::getInstanceFast()->setDragStart(screen_x, screen_y); + LLToolDragAndDrop::getInstance()->setDragStart(screen_x, screen_y); return LLFlatListViewEx::handleMouseDown(x, y, mask); } @@ -502,7 +502,7 @@ BOOL LLAvatarList::handleHover(S32 x, S32 y, MASK mask) S32 screen_y; localPointToScreen(x, y, &screen_x, &screen_y); - if(LLToolDragAndDrop::getInstanceFast()->isOverThreshold(screen_x, screen_y)) + if(LLToolDragAndDrop::getInstance()->isOverThreshold(screen_x, screen_y)) { // First, create the global drag and drop object std::vector<EDragAndDropType> types; @@ -510,7 +510,7 @@ BOOL LLAvatarList::handleHover(S32 x, S32 y, MASK mask) getSelectedUUIDs(cargo_ids); types.resize(cargo_ids.size(), DAD_PERSON); LLToolDragAndDrop::ESource src = LLToolDragAndDrop::SOURCE_PEOPLE; - LLToolDragAndDrop::getInstanceFast()->beginMultiDrag(types, cargo_ids, src); + LLToolDragAndDrop::getInstance()->beginMultiDrag(types, cargo_ids, src); } } @@ -561,7 +561,7 @@ void LLAvatarList::updateLastInteractionTimes() { // *TODO: error handling LLAvatarListItem* item = static_cast<LLAvatarListItem*>(*it); - S32 secs_since = now - (S32) LLRecentPeople::instanceFast().getDate(item->getAvatarId()).secondsSinceEpoch(); + S32 secs_since = now - (S32) LLRecentPeople::instance().getDate(item->getAvatarId()).secondsSinceEpoch(); if (secs_since >= 0) item->setTextFieldSeconds(secs_since); } @@ -574,7 +574,7 @@ void LLAvatarList::updateDistances() static LLCachedControl<F32> near_me_range(gSavedSettings, "NearMeRange"); LLWorld::pos_map_t positions; - LLWorld::getInstanceFast()->getAvatars(&positions, gAgent.getPositionGlobal(), near_me_range); + LLWorld::getInstance()->getAvatars(&positions, gAgent.getPositionGlobal(), near_me_range); for (auto itemp : items) { diff --git a/indra/newview/llavatarpropertiesprocessor.cpp b/indra/newview/llavatarpropertiesprocessor.cpp index 0ae1fcba91bc2eaed71087a7d30c88f462c05751..af5296691fe2f2539617bc05e33f463693fbeb69 100644 --- a/indra/newview/llavatarpropertiesprocessor.cpp +++ b/indra/newview/llavatarpropertiesprocessor.cpp @@ -36,6 +36,7 @@ #include "llstartup.h" // Linden library includes +#include "llavataractions.h" // for getProfileUrl #include "lldate.h" #include "lltrans.h" #include "llui.h" // LLUI::getLanguage() @@ -94,54 +95,98 @@ void LLAvatarPropertiesProcessor::removeObserver(const LLUUID& avatar_id, LLAvat } } - -void LLAvatarPropertiesProcessor::sendGenericRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string& method) +void LLAvatarPropertiesProcessor::sendRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string &method) { + // this is the startup state when send_complete_agent_movement() message is sent. + // Before this messages won't work so don't bother trying + if (LLStartUp::getStartupState() <= STATE_AGENT_SEND) + { + return; + } + + if (avatar_id.isNull()) + { + return; + } + // Suppress duplicate requests while waiting for a response from the network if (isPendingRequest(avatar_id, type)) { // waiting for a response, don't re-request return; } - // indicate we're going to make a request - addPendingRequest(avatar_id, type); - std::vector<std::string> strings; - strings.push_back( avatar_id.asString() ); - send_generic_message(method, strings); + std::string cap; + + switch (type) + { + case APT_PROPERTIES: + // indicate we're going to make a request + sendAvatarPropertiesRequestMessage(avatar_id); + // can use getRegionCapability("AgentProfile"), but it is heavy + // initAgentProfileCapRequest(avatar_id, cap); + break; + case APT_PICKS: + case APT_GROUPS: + case APT_NOTES: + if (cap.empty()) + { + // indicate we're going to make a request + sendGenericRequest(avatar_id, type, method); + } + else + { + initAgentProfileCapRequest(avatar_id, cap); + } + break; + default: + sendGenericRequest(avatar_id, type, method); + break; + } } -void LLAvatarPropertiesProcessor::sendAvatarPropertiesRequest(const LLUUID& avatar_id) +void LLAvatarPropertiesProcessor::sendGenericRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string &method) { - // this is the startup state when send_complete_agent_movement() message is sent. - // Before this, the AvatarPropertiesRequest message - // won't work so don't bother trying - if (LLStartUp::getStartupState() <= STATE_AGENT_SEND) - { - return; - } + // indicate we're going to make a request + addPendingRequest(avatar_id, type); - if (isPendingRequest(avatar_id, APT_PROPERTIES)) - { - // waiting for a response, don't re-request - return; - } - // indicate we're going to make a request - addPendingRequest(avatar_id, APT_PROPERTIES); + std::vector<std::string> strings; + strings.push_back(avatar_id.asString()); + send_generic_message(method, strings); +} - LLMessageSystem *msg = gMessageSystem; +void LLAvatarPropertiesProcessor::sendAvatarPropertiesRequestMessage(const LLUUID& avatar_id) +{ + addPendingRequest(avatar_id, APT_PROPERTIES); - msg->newMessageFast(_PREHASH_AvatarPropertiesRequest); - msg->nextBlockFast( _PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->addUUIDFast(_PREHASH_AvatarID, avatar_id); - gAgent.sendReliableMessage(); + LLMessageSystem *msg = gMessageSystem; + + msg->newMessageFast(_PREHASH_AvatarPropertiesRequest); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast( _PREHASH_AgentID, gAgent.getID() ); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addUUIDFast( _PREHASH_AvatarID, avatar_id); + gAgent.sendReliableMessage(); +} + +void LLAvatarPropertiesProcessor::initAgentProfileCapRequest(const LLUUID& avatar_id, const std::string& cap_url) +{ + addPendingRequest(avatar_id, APT_PROPERTIES); + addPendingRequest(avatar_id, APT_PICKS); + addPendingRequest(avatar_id, APT_GROUPS); + addPendingRequest(avatar_id, APT_NOTES); + LLCoros::instance().launch("requestAgentUserInfoCoro", + boost::bind(requestAvatarPropertiesCoro, cap_url, avatar_id)); +} + +void LLAvatarPropertiesProcessor::sendAvatarPropertiesRequest(const LLUUID& avatar_id) +{ + sendRequest(avatar_id, APT_PROPERTIES, "AvatarPropertiesRequest"); } void LLAvatarPropertiesProcessor::sendAvatarPicksRequest(const LLUUID& avatar_id) { - sendGenericRequest(avatar_id, APT_PICKS, "avatarpicksrequest"); + sendGenericRequest(avatar_id, APT_PICKS, "avatarpicksrequest"); } void LLAvatarPropertiesProcessor::sendAvatarNotesRequest(const LLUUID& avatar_id) @@ -174,7 +219,7 @@ void LLAvatarPropertiesProcessor::sendAvatarPropertiesUpdate(const LLAvatarData* return; } - LL_INFOS() << "Sending avatarinfo update" << LL_ENDL; + LL_WARNS() << "Sending avatarinfo update. This trims profile descriptions!!!" << LL_ENDL; // This value is required by sendAvatarPropertiesUpdate method. //A profile should never be mature. (From the original code) @@ -267,6 +312,113 @@ bool LLAvatarPropertiesProcessor::hasPaymentInfoOnFile(const LLAvatarData* avata return ((avatar_data->flags & AVATAR_TRANSACTED) || (avatar_data->flags & AVATAR_IDENTIFIED)); } +// static +void LLAvatarPropertiesProcessor::requestAvatarPropertiesCoro(std::string cap_url, LLUUID agent_id) +{ + LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); + LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t + httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("requestAvatarPropertiesCoro", httpPolicy)); + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + LLCore::HttpHeaders::ptr_t httpHeaders; + + LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); + httpOpts->setFollowRedirects(true); + + std::string finalUrl = cap_url + "/" + agent_id.asString(); + + LLSD result = httpAdapter->getAndSuspend(httpRequest, finalUrl, httpOpts, httpHeaders); + + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + if (!status + || !result.has("id") + || agent_id != result["id"].asUUID()) + { + LL_WARNS("AvatarProperties") << "Failed to get agent information for id " << agent_id << LL_ENDL; + LLAvatarPropertiesProcessor* self = getInstance(); + self->removePendingRequest(agent_id, APT_PROPERTIES); + self->removePendingRequest(agent_id, APT_PICKS); + self->removePendingRequest(agent_id, APT_GROUPS); + self->removePendingRequest(agent_id, APT_NOTES); + return; + } + + // Avatar Data + + LLAvatarData avatar_data; + std::string birth_date; + + avatar_data.agent_id = agent_id; + avatar_data.avatar_id = agent_id; + avatar_data.image_id = result["sl_image_id"].asUUID(); + avatar_data.fl_image_id = result["fl_image_id"].asUUID(); + avatar_data.partner_id = result["partner_id"].asUUID(); + avatar_data.about_text = result["sl_about_text"].asString(); + avatar_data.fl_about_text = result["fl_about_text"].asString(); + avatar_data.born_on = result["member_since"].asDate(); + avatar_data.profile_url = getProfileURL(agent_id.asString()); + + avatar_data.flags = 0; + avatar_data.caption_index = 0; + + LLAvatarPropertiesProcessor* self = getInstance(); + // Request processed, no longer pending + self->removePendingRequest(agent_id, APT_PROPERTIES); + self->notifyObservers(agent_id, &avatar_data, APT_PROPERTIES); + + // Picks + + LLSD picks_array = result["picks"]; + LLAvatarPicks avatar_picks; + avatar_picks.agent_id = agent_id; // Not in use? + avatar_picks.target_id = agent_id; + + for (LLSD::array_const_iterator it = picks_array.beginArray(); it != picks_array.endArray(); ++it) + { + const LLSD& pick_data = *it; + avatar_picks.picks_list.emplace_back(pick_data["id"].asUUID(), pick_data["name"].asString()); + } + + // Request processed, no longer pending + self->removePendingRequest(agent_id, APT_PICKS); + self->notifyObservers(agent_id, &avatar_picks, APT_PICKS); + + // Groups + + LLSD groups_array = result["groups"]; + LLAvatarGroups avatar_groups; + avatar_groups.agent_id = agent_id; // Not in use? + avatar_groups.avatar_id = agent_id; // target_id + + for (LLSD::array_const_iterator it = groups_array.beginArray(); it != groups_array.endArray(); ++it) + { + const LLSD& group_info = *it; + LLAvatarGroups::LLGroupData group_data; + group_data.group_powers = 0; // Not in use? + group_data.group_title = group_info["name"].asString(); // Missing data, not in use? + group_data.group_id = group_info["id"].asUUID(); + group_data.group_name = group_info["name"].asString(); + group_data.group_insignia_id = group_info["image_id"].asUUID(); + + avatar_groups.group_list.push_back(group_data); + } + + self->removePendingRequest(agent_id, APT_GROUPS); + self->notifyObservers(agent_id, &avatar_groups, APT_GROUPS); + + // Notes + LLAvatarNotes avatar_notes; + + avatar_notes.agent_id = agent_id; + avatar_notes.target_id = agent_id; + avatar_notes.notes = result["notes"].asString(); + + // Request processed, no longer pending + self->removePendingRequest(agent_id, APT_NOTES); + self->notifyObservers(agent_id, &avatar_notes, APT_NOTES); +} + void LLAvatarPropertiesProcessor::processAvatarPropertiesReply(LLMessageSystem* msg, void**) { LLAvatarData avatar_data; @@ -297,7 +449,7 @@ void LLAvatarPropertiesProcessor::processAvatarPropertiesReply(LLMessageSystem* { msg->getStringFast(_PREHASH_PropertiesData, _PREHASH_CharterMember, avatar_data.caption_text); } - LLAvatarPropertiesProcessor* self = getInstanceFast(); + LLAvatarPropertiesProcessor* self = getInstance(); // Request processed, no longer pending self->removePendingRequest(avatar_data.avatar_id, APT_PROPERTIES); self->notifyObservers(avatar_data.avatar_id,&avatar_data,APT_PROPERTIES); @@ -340,7 +492,7 @@ void LLAvatarPropertiesProcessor::processAvatarClassifiedsReply(LLMessageSystem* classifieds.classifieds_list.push_back(data); } - LLAvatarPropertiesProcessor* self = getInstanceFast(); + LLAvatarPropertiesProcessor* self = getInstance(); // Request processed, no longer pending self->removePendingRequest(classifieds.target_id, APT_CLASSIFIEDS); self->notifyObservers(classifieds.target_id,&classifieds,APT_CLASSIFIEDS); @@ -368,7 +520,7 @@ void LLAvatarPropertiesProcessor::processClassifiedInfoReply(LLMessageSystem* ms msg->getU8Fast(_PREHASH_Data, _PREHASH_ClassifiedFlags, c_info.flags); msg->getS32Fast(_PREHASH_Data, _PREHASH_PriceForListing, c_info.price_for_listing); - LLAvatarPropertiesProcessor* self = getInstanceFast(); + LLAvatarPropertiesProcessor* self = getInstance(); // Request processed, no longer pending self->removePendingRequest(c_info.creator_id, APT_CLASSIFIED_INFO); self->notifyObservers(c_info.creator_id, &c_info, APT_CLASSIFIED_INFO); @@ -383,7 +535,7 @@ void LLAvatarPropertiesProcessor::processAvatarNotesReply(LLMessageSystem* msg, msg->getUUIDFast(_PREHASH_Data, _PREHASH_TargetID, avatar_notes.target_id); msg->getStringFast(_PREHASH_Data, _PREHASH_Notes, avatar_notes.notes); - LLAvatarPropertiesProcessor* self = getInstanceFast(); + LLAvatarPropertiesProcessor* self = getInstance(); // Request processed, no longer pending self->removePendingRequest(avatar_notes.target_id, APT_NOTES); self->notifyObservers(avatar_notes.target_id,&avatar_notes,APT_NOTES); @@ -392,7 +544,7 @@ void LLAvatarPropertiesProcessor::processAvatarNotesReply(LLMessageSystem* msg, void LLAvatarPropertiesProcessor::processAvatarPicksReply(LLMessageSystem* msg, void**) { LLAvatarPicks avatar_picks; - msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, avatar_picks.target_id); + msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, avatar_picks.agent_id); msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_TargetID, avatar_picks.target_id); S32 block_count = msg->getNumberOfBlocksFast(_PREHASH_Data); @@ -406,7 +558,7 @@ void LLAvatarPropertiesProcessor::processAvatarPicksReply(LLMessageSystem* msg, avatar_picks.picks_list.push_back(std::make_pair(pick_id,pick_name)); } - LLAvatarPropertiesProcessor* self = getInstanceFast(); + LLAvatarPropertiesProcessor* self = getInstance(); // Request processed, no longer pending self->removePendingRequest(avatar_picks.target_id, APT_PICKS); self->notifyObservers(avatar_picks.target_id,&avatar_picks,APT_PICKS); @@ -437,7 +589,7 @@ void LLAvatarPropertiesProcessor::processPickInfoReply(LLMessageSystem* msg, voi msg->getS32Fast(_PREHASH_Data, _PREHASH_SortOrder, pick_data.sort_order); msg->getBOOLFast(_PREHASH_Data, _PREHASH_Enabled, pick_data.enabled); - LLAvatarPropertiesProcessor* self = getInstanceFast(); + LLAvatarPropertiesProcessor* self = getInstance(); // don't need to remove pending request as we don't track pick info self->notifyObservers(pick_data.creator_id, &pick_data, APT_PICK_INFO); } @@ -462,7 +614,7 @@ void LLAvatarPropertiesProcessor::processAvatarGroupsReply(LLMessageSystem* msg, avatar_groups.group_list.push_back(group_data); } - LLAvatarPropertiesProcessor* self = getInstanceFast(); + LLAvatarPropertiesProcessor* self = getInstance(); self->removePendingRequest(avatar_groups.avatar_id, APT_GROUPS); self->notifyObservers(avatar_groups.avatar_id,&avatar_groups,APT_GROUPS); } @@ -538,8 +690,8 @@ void LLAvatarPropertiesProcessor::sendPickDelete( const LLUUID& pick_id ) msg->addUUIDFast(_PREHASH_PickID, pick_id); gAgent.sendReliableMessage(); - LLAgentPicksInfo::getInstanceFast()->requestNumberOfPicks(); - LLAgentPicksInfo::getInstanceFast()->decrementNumberOfPicks(); + LLAgentPicksInfo::getInstance()->requestNumberOfPicks(); + LLAgentPicksInfo::getInstance()->decrementNumberOfPicks(); } void LLAvatarPropertiesProcessor::sendClassifiedDelete(const LLUUID& classified_id) @@ -589,7 +741,7 @@ void LLAvatarPropertiesProcessor::sendPickInfoUpdate(const LLPickData* new_pick) msg->addBOOLFast(_PREHASH_Enabled, new_pick->enabled); gAgent.sendReliableMessage(); - LLAgentPicksInfo::getInstanceFast()->requestNumberOfPicks(); + LLAgentPicksInfo::getInstance()->requestNumberOfPicks(); } void LLAvatarPropertiesProcessor::sendClassifiedInfoUpdate(const LLAvatarClassifiedInfo* c_data) diff --git a/indra/newview/llavatarpropertiesprocessor.h b/indra/newview/llavatarpropertiesprocessor.h index 78261fd49f93e6479d6266c1f62e7b7b8da03097..a6de5e333dc3c892373125c50940aea45b963ebb 100644 --- a/indra/newview/llavatarpropertiesprocessor.h +++ b/indra/newview/llavatarpropertiesprocessor.h @@ -248,6 +248,8 @@ class LLAvatarPropertiesProcessor final static bool hasPaymentInfoOnFile(const LLAvatarData* avatar_data); + static void requestAvatarPropertiesCoro(std::string cap_url, LLUUID agent_id); + static void processAvatarPropertiesReply(LLMessageSystem* msg, void**); static void processAvatarInterestsReply(LLMessageSystem* msg, void**); @@ -266,7 +268,10 @@ class LLAvatarPropertiesProcessor final protected: - void sendGenericRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string& method); + void sendRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string &method); + void sendGenericRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string &method); + void sendAvatarPropertiesRequestMessage(const LLUUID& avatar_id); + void initAgentProfileCapRequest(const LLUUID& avatar_id, const std::string& cap_url); void notifyObservers(const LLUUID& id,void* data, EAvatarProcessorType type); diff --git a/indra/newview/llavatarrenderinfoaccountant.cpp b/indra/newview/llavatarrenderinfoaccountant.cpp index fd0fcc29e4cce0b765bcb3e9a47c362283661b9b..34dd1e870f3f1ae4fef0103c3004997600babea2 100644 --- a/indra/newview/llavatarrenderinfoaccountant.cpp +++ b/indra/newview/llavatarrenderinfoaccountant.cpp @@ -82,7 +82,15 @@ void LLAvatarRenderInfoAccountant::avatarRenderInfoGetCoro(std::string url, U64 LLSD result = httpAdapter->getAndSuspend(httpRequest, url); - LLViewerRegion * regionp = LLWorld::getInstanceFast()->getRegionFromHandle(regionHandle); + LLWorld *world_inst = LLWorld::getInstance(); + if (!world_inst) + { + LL_WARNS("AvatarRenderInfoAccountant") << "Avatar render weight info received but world no longer exists " + << regionHandle << LL_ENDL; + return; + } + + LLViewerRegion * regionp = world_inst->getRegionFromHandle(regionHandle); if (!regionp) { LL_WARNS("AvatarRenderInfoAccountant") << "Avatar render weight info received but region not found for " @@ -183,7 +191,15 @@ void LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro(std::string url, U httpAdapter(std::make_shared<LLCoreHttpUtil::HttpCoroutineAdapter>("AvatarRenderInfoAccountant", httpPolicy)); LLCore::HttpRequest::ptr_t httpRequest(std::make_shared<LLCore::HttpRequest>()); - LLViewerRegion * regionp = LLWorld::getInstanceFast()->getRegionFromHandle(regionHandle); + LLWorld *world_inst = LLWorld::getInstance(); + if (!world_inst) + { + LL_WARNS("AvatarRenderInfoAccountant") << "Avatar render weight calculation but world no longer exists " + << regionHandle << LL_ENDL; + return; + } + + LLViewerRegion * regionp = world_inst->getRegionFromHandle(regionHandle); if (!regionp) { LL_WARNS("AvatarRenderInfoAccountant") << "Avatar render weight calculation but region not found for " @@ -239,9 +255,18 @@ void LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro(std::string url, U report[KEY_AGENTS] = agents; regionp = NULL; + world_inst = NULL; LLSD result = httpAdapter->postAndSuspend(httpRequest, url, report); - regionp = LLWorld::getInstanceFast()->getRegionFromHandle(regionHandle); + world_inst = LLWorld::getInstance(); + if (!world_inst) + { + LL_WARNS("AvatarRenderInfoAccountant") << "Avatar render weight POST result but world no longer exists " + << regionHandle << LL_ENDL; + return; + } + + regionp = world_inst->getRegionFromHandle(regionHandle); if (!regionp) { LL_INFOS("AvatarRenderInfoAccountant") << "Avatar render weight POST result received but region not found for " @@ -295,9 +320,16 @@ void LLAvatarRenderInfoAccountant::sendRenderInfoToRegion(LLViewerRegion * regio // make sure we won't re-report, coro will update timer with correct time later regionp->getRenderInfoReportTimer().resetWithExpiry(SECS_BETWEEN_REGION_REPORTS); - std::string coroname = - LLCoros::instance().launch("LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro", - boost::bind(&LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro, url, regionp->getHandle())); + try + { + std::string coroname = + LLCoros::instance().launch("LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro", + boost::bind(&LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro, url, regionp->getHandle())); + } + catch (std::bad_alloc&) + { + LL_ERRS() << "LLCoros::launch() allocation failure" << LL_ENDL; + } } } @@ -318,10 +350,17 @@ void LLAvatarRenderInfoAccountant::getRenderInfoFromRegion(LLViewerRegion * regi // make sure we won't re-request, coro will update timer with correct time later regionp->getRenderInfoRequestTimer().resetWithExpiry(SECS_BETWEEN_REGION_REQUEST); - // First send a request to get the latest data - std::string coroname = - LLCoros::instance().launch("LLAvatarRenderInfoAccountant::avatarRenderInfoGetCoro", - boost::bind(&LLAvatarRenderInfoAccountant::avatarRenderInfoGetCoro, url, regionp->getHandle())); + try + { + // First send a request to get the latest data + std::string coroname = + LLCoros::instance().launch("LLAvatarRenderInfoAccountant::avatarRenderInfoGetCoro", + boost::bind(&LLAvatarRenderInfoAccountant::avatarRenderInfoGetCoro, url, regionp->getHandle())); + } + catch (std::bad_alloc&) + { + LL_ERRS() << "LLCoros::launch() allocation failure" << LL_ENDL; + } } } @@ -335,7 +374,7 @@ void LLAvatarRenderInfoAccountant::idle() << LL_ENDL; // Check all regions - for (LLViewerRegion* regionp : LLWorld::getInstanceFast()->getRegionList()) + for (LLViewerRegion* regionp : LLWorld::getInstance()->getRegionList()) { if ( regionp && regionp->isAlive() @@ -370,7 +409,7 @@ void LLAvatarRenderInfoAccountant::scanNewRegion(const LLUUID& region_id) // Reset the global timer so it will scan regions on the next call to ::idle LLAvatarRenderInfoAccountant::getInstance()->resetRenderInfoScanTimer(); - LLViewerRegion* regionp = LLWorld::instanceFast().getRegionFromID(region_id); + LLViewerRegion* regionp = LLWorld::instance().getRegionFromID(region_id); if (regionp) { // Reset the region's timers so we will: // * request render info from it immediately diff --git a/indra/newview/llblocklist.cpp b/indra/newview/llblocklist.cpp index 05e71d75bbf6953e6b7243f2ee0a7376668e63bf..1eab2d8e232c67b8de0b6aa2206960ffb9729b7c 100644 --- a/indra/newview/llblocklist.cpp +++ b/indra/newview/llblocklist.cpp @@ -80,7 +80,7 @@ LLBlockList::~LLBlockList() void LLBlockList::createList() { - std::vector<LLMute> mutes = LLMuteList::instanceFast().getMutes(); + std::vector<LLMute> mutes = LLMuteList::instance().getMutes(); std::vector<LLMute>::const_iterator mute_it = mutes.begin(); for (; mute_it != mutes.end(); ++mute_it) diff --git a/indra/newview/llbrowsernotification.cpp b/indra/newview/llbrowsernotification.cpp index 7614624306bca3ddd3a10f3b53a09147e5be607c..036215a845bfb16b86ed2b63a8fb8488c7587084 100644 --- a/indra/newview/llbrowsernotification.cpp +++ b/indra/newview/llbrowsernotification.cpp @@ -43,14 +43,14 @@ LLBrowserNotification::LLBrowserNotification() bool LLBrowserNotification::processNotification(const LLNotificationPtr& notification, bool should_log) { LLUUID media_id = notification->getPayload()["media_id"].asUUID(); - LLMediaCtrl* media_instance = LLMediaCtrl::getInstance(media_id); + auto media_instance = LLMediaCtrl::getInstance(media_id); if (media_instance) { media_instance->showNotification(notification); } else if (LLViewerMediaFocus::instance().getControlsMediaID() == media_id) { - LLViewerMediaImpl* impl = LLViewerMedia::getInstance()->getMediaImplFromTextureID(media_id); + auto impl = LLViewerMedia::getInstance()->getMediaImplFromTextureID(media_id); if (impl) { impl->showNotification(notification); diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp index 05f17e6e3710c7817a356befbd7d432576915426..da8c1a863a041f5ffb36513731cf1f164b22d0d2 100644 --- a/indra/newview/llcallingcard.cpp +++ b/indra/newview/llcallingcard.cpp @@ -292,6 +292,7 @@ void LLAvatarTracker::copyBuddyList(buddy_map_t& buddies) const void LLAvatarTracker::terminateBuddy(const LLUUID& id) { LL_DEBUGS() << "LLAvatarTracker::terminateBuddy()" << LL_ENDL; + LLRelationship* buddy = get_ptr_in_map(mBuddyInfo, id); if(!buddy) return; mBuddyInfo.erase(id); @@ -491,6 +492,7 @@ void LLAvatarTracker::notifyObservers() // new masks and ids will be processed later from idle. return; } + LL_PROFILE_ZONE_SCOPED mIsNotifyObservers = TRUE; observer_list_t observers(mObservers); @@ -679,6 +681,7 @@ void LLAvatarTracker::processChangeUserRights(LLMessageSystem* msg, void**) void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online) { + LL_PROFILE_ZONE_SCOPED S32 count = msg->getNumberOfBlocksFast(_PREHASH_AgentBlock); BOOL chat_notify = gSavedSettings.getBOOL("ChatOnlineNotification"); @@ -713,8 +716,6 @@ void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online) // we were tracking someone who went offline deleteTrackingData(); } - // *TODO: get actual inventory id - gInventory.addChangedMask(LLInventoryObserver::CALLING_CARD, LLUUID::null); } if(chat_notify) { diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index 01153e14fe1ba0229e343cf07296b6ba45ff8279..44912dc7f21ec11002f2b80fe353e09e826d4ba2 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -49,6 +49,7 @@ #include "llspeakers.h" //for LLIMSpeakerMgr #include "lltrans.h" #include "llfloaterreg.h" +#include "llfloaterreporter.h" #include "llfloatersidepanelcontainer.h" #include "llmutelist.h" #include "llstylemap.h" @@ -134,6 +135,7 @@ class LLChatHistoryHeader: public LLPanel mSourceType(CHAT_SOURCE_UNKNOWN), mFrom(), mSessionID(), + mCreationTime(time_corrected()), mMinUserNameWidth(0), mUserNameFont(NULL), mUserNameTextBox(NULL), @@ -433,6 +435,48 @@ class LLChatHistoryHeader: public LLPanel { LLAvatarActions::pay(getAvatarId()); } + else if (level == "report_abuse") + { + std::string time_string; + if (mTime > 0) // have frame time + { + time_t current_time = time_corrected(); + time_t message_time = current_time - LLFrameTimer::getElapsedSeconds() + mTime; + + time_string = "[" + LLTrans::getString("TimeMonth") + "]/[" + + LLTrans::getString("TimeDay") + "]/[" + + LLTrans::getString("TimeYear") + "] [" + + LLTrans::getString("TimeHour") + "]:[" + + LLTrans::getString("TimeMin") + "]"; + + LLSD substitution; + + substitution["datetime"] = (S32)message_time; + LLStringUtil::format(time_string, substitution); + } + else + { + // From history. This might be empty or not full. + // See LLChatLogParser::parse + time_string = getChild<LLTextBox>("time_box")->getValue().asString(); + + // Just add current date if not full. + // Should be fine since both times are supposed to be stl + if (!time_string.empty() && time_string.size() < 7) + { + time_string = "[" + LLTrans::getString("TimeMonth") + "]/[" + + LLTrans::getString("TimeDay") + "]/[" + + LLTrans::getString("TimeYear") + "] " + time_string; + + LLSD substitution; + // To avoid adding today's date to yesterday's timestamp, + // use creation time instead of current time + substitution["datetime"] = (S32)mCreationTime; + LLStringUtil::format(time_string, substitution); + } + } + LLFloaterReporter::showFromChat(mAvatarID, mFrom, time_string, mText); + } else if(level == "block_unblock") { LLAvatarActions::toggleMute(getAvatarId(), LLMute::flagVoiceChat); @@ -441,10 +485,6 @@ class LLChatHistoryHeader: public LLPanel { LLAvatarActions::toggleMute(getAvatarId(), LLMute::flagTextChat); } - else if (level == "report_abuse") - { - ALAvatarActions::reportAbuse(getAvatarId()); - } else if(level == "toggle_allow_text_chat") { LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID); @@ -511,6 +551,10 @@ class LLChatHistoryHeader: public LLPanel { return canModerate(userdata); } + else if (level == "report_abuse") + { + return gAgentID != mAvatarID; + } // [RLVa:KB] - @pay else if (level == "can_pay") { @@ -599,10 +643,16 @@ class LLChatHistoryHeader: public LLPanel mUserNameTextBox = getChild<LLTextBox>("user_name"); mTimeBoxTextBox = getChild<LLTextBox>("time_box"); - mInfoCtrl = LLUICtrlFactory::getInstanceFast()->createFromFile<LLUICtrl>("inspector_info_ctrl.xml", this, LLPanel::child_registry_t::instanceFast()); - llassert(mInfoCtrl != NULL); - mInfoCtrl->setCommitCallback(boost::bind(&LLChatHistoryHeader::onClickInfoCtrl, mInfoCtrl)); - mInfoCtrl->setVisible(FALSE); + mInfoCtrl = LLUICtrlFactory::getInstance()->createFromFile<LLUICtrl>("inspector_info_ctrl.xml", this, LLPanel::child_registry_t::instance()); + if (mInfoCtrl) + { + mInfoCtrl->setCommitCallback(boost::bind(&LLChatHistoryHeader::onClickInfoCtrl, mInfoCtrl)); + mInfoCtrl->setVisible(FALSE); + } + else + { + LL_ERRS() << "Failed to create an interface element due to missing or corrupted file inspector_info_ctrl.xml" << LL_ENDL; + } return LLPanel::postBuild(); } @@ -674,6 +724,12 @@ class LLChatHistoryHeader: public LLPanel mSessionID = chat.mSessionID; mSourceType = chat.mSourceType; + // To be able to report a message, we need a copy of it's text + // and it's easier to store text directly than trying to get + // it from a lltextsegment or chat's mEditor + mText = chat.mText; + mTime = chat.mTime; + //*TODO overly defensive thing, source type should be maintained out there if((chat.mFromID.isNull() && chat.mFromName.empty()) || (chat.mFromName == SYSTEM_FROM && chat.mFromID.isNull())) { @@ -822,9 +878,9 @@ class LLChatHistoryHeader: public LLPanel if ( chat.mSourceType == CHAT_SOURCE_OBJECT) { std::string slurl = args["slurl"].asString(); - if (slurl.empty()) + if (slurl.empty() && LLWorld::instanceExists()) { - LLViewerRegion *region = LLWorld::getInstanceFast()->getRegionFromPosAgent(chat.mPosAgent); + LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosAgent(chat.mPosAgent); if(region) { LLSLURL region_slurl(region->getName(), chat.mPosAgent); @@ -1100,6 +1156,9 @@ class LLChatHistoryHeader: public LLPanel EChatSourceType mSourceType; std::string mFrom; LLUUID mSessionID; + std::string mText; + F64 mTime; // IM's frame time + time_t mCreationTime; // Views's time // [RLVa:KB] - Checked: 2010-04-22 (RLVa-1.2.2a) | Added: RLVa-1.2.0f bool mShowContextMenu; bool mShowInfoCtrl; diff --git a/indra/newview/llcofwearables.cpp b/indra/newview/llcofwearables.cpp index 26f973f61536337bc49cac1ee589ab5fa7469f38..aa2ba752b76f756458c4d00e89aaa739d2aaee3a 100644 --- a/indra/newview/llcofwearables.cpp +++ b/indra/newview/llcofwearables.cpp @@ -74,7 +74,7 @@ class CofContextMenu : public LLListContextMenu } // Set proper label for the "Create new <WEARABLE_TYPE>" menu item. - std::string new_label = LLTrans::getString("create_new_" + LLWearableType::getInstanceFast()->getTypeName(w_type)); + std::string new_label = LLTrans::getString("create_new_" + LLWearableType::getInstance()->getTypeName(w_type)); menu_item->setLabel(new_label); } diff --git a/indra/newview/llcolorswatch.cpp b/indra/newview/llcolorswatch.cpp index 80d810d1591a027b68d483afe7cc6e354a0523b2..036ff170743d90125f4eeca6f8b2cd4c0b842c09 100644 --- a/indra/newview/llcolorswatch.cpp +++ b/indra/newview/llcolorswatch.cpp @@ -290,9 +290,14 @@ void LLColorSwatchCtrl::onColorChanged ( void* data, EColorPickOp pick_op ) pickerp->getCurG (), pickerp->getCurB (), subject->mColor.mV[VALPHA] ); // keep current alpha - subject->mColor = updatedColor; - subject->setControlValue(updatedColor.getValue()); - pickerp->setRevertOnCancel(TRUE); + + bool color_changed = subject->mColor != updatedColor; + if (color_changed) + { + subject->mColor = updatedColor; + subject->setControlValue(updatedColor.getValue()); + } + if (pick_op == COLOR_CANCEL && subject->mOnCancelCallback) { subject->mOnCancelCallback( subject, LLSD()); @@ -306,6 +311,13 @@ void LLColorSwatchCtrl::onColorChanged ( void* data, EColorPickOp pick_op ) // just commit change subject->onCommit (); } + + if (pick_op == COLOR_CANCEL || pick_op == COLOR_SELECT) + { + // both select and cancel close LLFloaterColorPicker + // but COLOR_CHANGE does not + subject->setFocus(TRUE); + } } } } diff --git a/indra/newview/llcontrolavatar.cpp b/indra/newview/llcontrolavatar.cpp index 47416414190213206a24875e9bdec22e2b64f87b..f04b487d120d593256dfcb759b402ff36408b436 100644 --- a/indra/newview/llcontrolavatar.cpp +++ b/indra/newview/llcontrolavatar.cpp @@ -241,9 +241,7 @@ void LLControlAvatar::matchVolumeTransform() #ifdef SHOW_DEBUG LL_DEBUGS("BindShape") << getFullname() << " bind shape " << skin_info->mBindShapeMatrix << LL_ENDL; #endif - alignas(16) LLMatrix4 mat(LLMatrix4::kUninitialized); - skin_info->mBindShapeMatrix.store4a((F32*)mat.mMatrix); - bind_rot = LLSkinningUtil::getUnscaledQuaternion(mat); + bind_rot = LLSkinningUtil::getUnscaledQuaternion(LLMatrix4(skin_info->mBindShapeMatrix)); } #endif setRotation(bind_rot*obj_rot); @@ -300,14 +298,12 @@ void LLControlAvatar::updateVolumeGeom() mRootVolp->mDrawable->makeActive(); gPipeline.markMoved(mRootVolp->mDrawable); gPipeline.markTextured(mRootVolp->mDrawable); // face may need to change draw pool to/from POOL_HUD - mRootVolp->mDrawable->setState(LLDrawable::USE_BACKLIGHT); const LLViewerObject::const_child_list_t& child_list = mRootVolp->getChildren(); for (LLViewerObject* childp : child_list) { if (childp && childp->mDrawable.notNull()) { - childp->mDrawable->setState(LLDrawable::USE_BACKLIGHT); gPipeline.markTextured(childp->mDrawable); // face may need to change draw pool to/from POOL_HUD gPipeline.markMoved(childp->mDrawable); } @@ -567,7 +563,7 @@ void LLControlAvatar::updateAnimations() getAnimatedVolumes(volumes); // Rebuild mSignaledAnimations from the associated volumes. - auto& signaled_anim_map = LLObjectSignaledAnimationMap::instanceFast().getMap(); + auto& signaled_anim_map = LLObjectSignaledAnimationMap::instance().getMap(); std::map<LLUUID, S32> anims; for (LLVOVolume* volp : volumes) diff --git a/indra/newview/llconversationloglist.cpp b/indra/newview/llconversationloglist.cpp index 8f395d3f7f6405e52d928eaf89d0100ee8893de0..9f2f3a05074806fb45b7d1f318ec699ea149709c 100644 --- a/indra/newview/llconversationloglist.cpp +++ b/indra/newview/llconversationloglist.cpp @@ -401,7 +401,8 @@ bool LLConversationLogList::isActionEnabled(const LLSD& userdata) "can_invite_to_group" == command_name || "can_share" == command_name || "can_block" == command_name || - "can_pay" == command_name) + "can_pay" == command_name || + "report_abuse" == command_name) { return is_p2p; } diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp index 10cafa760a540ba2b5b111fcd7b502a1a53ee891..7b89d22c98cb2235b9d7e5a3fa6ba087cfbf6aa6 100644 --- a/indra/newview/llconversationmodel.cpp +++ b/indra/newview/llconversationmodel.cpp @@ -182,6 +182,7 @@ void LLConversationItem::buildParticipantMenuOptions(menuentry_vec_t& items, U32 items.push_back(std::string("map")); items.push_back(std::string("share")); items.push_back(std::string("pay")); + items.push_back(std::string("report_abuse")); items.push_back(std::string("block_unblock")); items.push_back(std::string("MuteText")); items.push_back(std::string("report_abuse")); @@ -650,7 +651,7 @@ void LLConversationItemParticipant::setDisplayModeratorRole(bool displayRole) bool LLConversationItemParticipant::isVoiceMuted() { - return mIsModeratorMuted || LLMuteList::getInstanceFast()->isMuted(mUUID, LLMute::flagVoiceChat); + return mIsModeratorMuted || LLMuteList::getInstance()->isMuted(mUUID, LLMute::flagVoiceChat); } // diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp index e17fc0f22f2c6661f8852cbbbf48bb907bcd20ab..a56d3f8ac27dcc7b6b37839f629ed9b92948aabf 100644 --- a/indra/newview/llconversationview.cpp +++ b/indra/newview/llconversationview.cpp @@ -272,9 +272,9 @@ BOOL LLConversationViewSession::postBuild() default: break; } - } - refresh(); + refresh(); // requires vmi + } return TRUE; } @@ -486,17 +486,20 @@ void LLConversationViewSession::refresh() { // Refresh the session view from its model data LLConversationItem* vmi = dynamic_cast<LLConversationItem*>(getViewModelItem()); - vmi->resetRefresh(); + if (vmi) + { + vmi->resetRefresh(); - if (mSessionTitle) - { - if (!highlightFriendTitle(vmi)) - { - LLStyle::Params title_style; - title_style.color = LLUIColorTable::instance().getColor("LabelTextColor"); - mSessionTitle->setText(vmi->getDisplayName(), title_style); - } - } + if (mSessionTitle) + { + if (!highlightFriendTitle(vmi)) + { + LLStyle::Params title_style; + title_style.color = LLUIColorTable::instance().getColor("LabelTextColor"); + mSessionTitle->setText(vmi->getDisplayName(), title_style); + } + } + } // Update all speaking indicators LLSpeakingIndicatorManager::updateSpeakingIndicators(); @@ -520,8 +523,11 @@ void LLConversationViewSession::refresh() } requestArrange(); - // Do the regular upstream refresh - LLFolderViewFolder::refresh(); + if (vmi) + { + // Do the regular upstream refresh + LLFolderViewFolder::refresh(); + } } void LLConversationViewSession::onCurrentVoiceSessionChanged(const LLUUID& session_id) @@ -623,8 +629,11 @@ BOOL LLConversationViewParticipant::postBuild() } updateChildren(); - LLFolderViewItem::postBuild(); - refresh(); + if (getViewModelItem()) + { + LLFolderViewItem::postBuild(); + refresh(); + } return TRUE; } @@ -708,10 +717,10 @@ void LLConversationViewParticipant::refresh() // *TODO: We should also do something with vmi->isModerator() to echo that state in the UI somewhat mSpeakingIndicator->setIsModeratorMuted(participant_model->isModeratorMuted()); + + // Do the regular upstream refresh + LLFolderViewItem::refresh(); } - - // Do the regular upstream refresh - LLFolderViewItem::refresh(); } void LLConversationViewParticipant::addToFolder(LLFolderViewFolder* folder) diff --git a/indra/newview/lldirpicker.cpp b/indra/newview/lldirpicker.cpp index 6e6778e7e6798b85a731325fbbe8409e558deb80..d3dd633a1f64dfe7d3990d3c06da71a622047aae 100644 --- a/indra/newview/lldirpicker.cpp +++ b/indra/newview/lldirpicker.cpp @@ -277,7 +277,7 @@ std::string LLDirPicker::getDirName() #endif -LLMutex LLDirPickerThread::sMutex(LLMutex::E_CONST_INIT); +LLMutex* LLDirPickerThread::sMutex = NULL; std::queue<LLDirPickerThread*> LLDirPickerThread::sDeadQ; void LLDirPickerThread::getFile() @@ -306,7 +306,7 @@ void LLDirPickerThread::run() } { - LLMutexLock lock(&sMutex); + LLMutexLock lock(sMutex); sDeadQ.push(this); } @@ -315,12 +315,16 @@ void LLDirPickerThread::run() //static void LLDirPickerThread::initClass() { + sMutex = new LLMutex(); } //static void LLDirPickerThread::cleanupClass() { clearDead(); + + delete sMutex; + sMutex = NULL; } //static @@ -328,7 +332,7 @@ void LLDirPickerThread::clearDead() { if (!sDeadQ.empty()) { - LLMutexLock lock(&sMutex); + LLMutexLock lock(sMutex); while (!sDeadQ.empty()) { LLDirPickerThread* thread = sDeadQ.front(); diff --git a/indra/newview/lldirpicker.h b/indra/newview/lldirpicker.h index b1dd3339f9640ee8d897e8d558098f61f65511bd..f300c9c43d049d58a2f08bca9888ea7e97b91ab2 100644 --- a/indra/newview/lldirpicker.h +++ b/indra/newview/lldirpicker.h @@ -104,7 +104,7 @@ class LLDirPickerThread final : public LLThread public: static std::queue<LLDirPickerThread*> sDeadQ; - static LLMutex sMutex; + static LLMutex* sMutex; static void initClass(); static void cleanupClass(); diff --git a/indra/newview/lldonotdisturbnotificationstorage.cpp b/indra/newview/lldonotdisturbnotificationstorage.cpp index cb5f9c8a2c98cb0ce48e1212c4130db8dc7cc8f7..4d9ef99319fbd09448ab69216241879d68ad9888 100644 --- a/indra/newview/lldonotdisturbnotificationstorage.cpp +++ b/indra/newview/lldonotdisturbnotificationstorage.cpp @@ -80,9 +80,14 @@ LLDoNotDisturbNotificationStorage::~LLDoNotDisturbNotificationStorage() { } +void LLDoNotDisturbNotificationStorage::reset() +{ + setFileName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "dnd_notifications.xml")); +} + void LLDoNotDisturbNotificationStorage::initialize() { - setFileName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "dnd_notifications.xml")); + reset(); getCommunicationChannel()->connectFailedFilter(boost::bind(&LLDoNotDisturbNotificationStorage::onChannelChanged, this, _1)); } @@ -96,11 +101,9 @@ void LLDoNotDisturbNotificationStorage::resetDirty() mDirty = false; } -static LLTrace::BlockTimerStatHandle FTM_SAVE_DND_NOTIFICATIONS("Save DND Notifications"); - void LLDoNotDisturbNotificationStorage::saveNotifications() { - LL_RECORD_BLOCK_TIME(FTM_SAVE_DND_NOTIFICATIONS); + LL_PROFILE_ZONE_SCOPED; LLNotificationChannelPtr channelPtr = getCommunicationChannel(); const LLCommunicationChannel *commChannel = dynamic_cast<LLCommunicationChannel*>(channelPtr.get()); diff --git a/indra/newview/lldonotdisturbnotificationstorage.h b/indra/newview/lldonotdisturbnotificationstorage.h index 42563181707724f623129cfc9edb33dcc1fc3d7f..12423b122438e1ce632aed0e435bc39d83a3e158 100644 --- a/indra/newview/lldonotdisturbnotificationstorage.h +++ b/indra/newview/lldonotdisturbnotificationstorage.h @@ -61,6 +61,7 @@ class LLDoNotDisturbNotificationStorage final : public LLParamSingleton<LLDoNotD void loadNotifications(); void updateNotifications(); void removeNotification(const char * name, const LLUUID& id); + void reset(); protected: diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 0923cac6a1944926e1cb39a8765a37bf41b25b16..8547462899eb5460e5e1995e1ac7ea9f44d0dd81 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -58,8 +58,6 @@ const F32 MIN_INTERPOLATE_DISTANCE_SQUARED = 0.001f * 0.001f; const F32 MAX_INTERPOLATE_DISTANCE_SQUARED = 10.f * 10.f; const F32 OBJECT_DAMPING_TIME_CONSTANT = 0.06f; -static LLTrace::BlockTimerStatHandle FTM_CULL_REBOUND("Cull Rebound"); - extern bool gShiftFrame; @@ -88,12 +86,11 @@ std::vector<LLPointer<LLDrawable> > LLDrawable::sDeadList; void LLDrawable::incrementVisible() { LLViewerOctreeEntryData::incrementVisible(); - sCurPixelAngle = (F32) gViewerWindow->getWindowHeightRaw()/LLViewerCamera::getInstanceFast()->getView(); + sCurPixelAngle = (F32) gViewerWindow->getWindowHeightRaw()/LLViewerCamera::getInstance()->getView(); } LLDrawable::LLDrawable(LLViewerObject *vobj, bool new_entry) : LLViewerOctreeEntryData(LLViewerOctreeEntry::LLDRAWABLE), - LLTrace::MemTrackable<LLDrawable, 16>("LLDrawable"), mVObjp(vobj) { init(new_entry); @@ -101,6 +98,8 @@ LLDrawable::LLDrawable(LLViewerObject *vobj, bool new_entry) void LLDrawable::init(bool new_entry) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE + // mXform mParent = NULL; mRenderType = 0; @@ -150,21 +149,6 @@ void LLDrawable::unload() { LLVOVolume *pVVol = getVOVolume(); pVVol->setNoLOD(); - - for (S32 i = 0; i < getNumFaces(); i++) - { - LLFace* facep = getFace(i); - if (facep->isState(LLFace::RIGGED)) - { - LLDrawPoolAvatar* pool = (LLDrawPoolAvatar*)facep->getPool(); - if (pool) { - pool->removeRiggedFace(facep); - } - facep->setVertexBuffer(NULL); - } - facep->clearState(LLFace::RIGGED); - } - pVVol->markForUpdate(TRUE); } @@ -261,19 +245,13 @@ BOOL LLDrawable::isLight() const } } -static LLTrace::BlockTimerStatHandle FTM_CLEANUP_DRAWABLE("Cleanup Drawable"); -static LLTrace::BlockTimerStatHandle FTM_DEREF_DRAWABLE("Deref"); -static LLTrace::BlockTimerStatHandle FTM_DELETE_FACES("Faces"); - void LLDrawable::cleanupReferences() { - LL_RECORD_BLOCK_TIME(FTM_CLEANUP_DRAWABLE); + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE; - { - LL_RECORD_BLOCK_TIME(FTM_DELETE_FACES); - std::for_each(mFaces.begin(), mFaces.end(), DeletePointer()); - mFaces.clear(); - } + + std::for_each(mFaces.begin(), mFaces.end(), DeletePointer()); + mFaces.clear(); gObjectList.removeDrawable(this); @@ -281,12 +259,9 @@ void LLDrawable::cleanupReferences() removeFromOctree(); - { - LL_RECORD_BLOCK_TIME(FTM_DEREF_DRAWABLE); - // Cleanup references to other objects - mVObjp = NULL; - mParent = NULL; - } + // Cleanup references to other objects + mVObjp = NULL; + mParent = NULL; } void LLDrawable::removeFromOctree() @@ -331,14 +306,12 @@ S32 LLDrawable::findReferences(LLDrawable *drawablep) return count; } -static LLTrace::BlockTimerStatHandle FTM_ALLOCATE_FACE("Allocate Face"); - LLFace* LLDrawable::addFace(LLFacePool *poolp, LLViewerTexture *texturep) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE LLFace *face; { - LL_RECORD_BLOCK_TIME(FTM_ALLOCATE_FACE); face = new LLFace(this, mVObjp); } @@ -363,13 +336,12 @@ LLFace* LLDrawable::addFace(LLFacePool *poolp, LLViewerTexture *texturep) LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep) { - LLFace *face; + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE - { - LL_RECORD_BLOCK_TIME(FTM_ALLOCATE_FACE); - face = new LLFace(this, mVObjp); - } + LLFace *face; + face = new LLFace(this, mVObjp); + face->setTEOffset(mFaces.size()); face->setTexture(texturep); face->setPoolType(gPipeline.getPoolTypeFromTE(te, texturep)); @@ -387,6 +359,8 @@ LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep) LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep, LLViewerTexture *normalp) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE + LLFace *face; face = new LLFace(this, mVObjp); @@ -408,6 +382,8 @@ LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep, LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep, LLViewerTexture *normalp, LLViewerTexture *specularp) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE + LLFace *face; face = new LLFace(this, mVObjp); @@ -430,6 +406,8 @@ LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep, void LLDrawable::setNumFaces(const S32 newFaces, LLFacePool *poolp, LLViewerTexture *texturep) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE + if (newFaces == (S32)mFaces.size()) { return; @@ -453,6 +431,8 @@ void LLDrawable::setNumFaces(const S32 newFaces, LLFacePool *poolp, LLViewerText void LLDrawable::setNumFacesFast(const S32 newFaces, LLFacePool *poolp, LLViewerTexture *texturep) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE + if (newFaces <= (S32)mFaces.size() && newFaces >= (S32)mFaces.size()/2) { return; @@ -476,6 +456,8 @@ void LLDrawable::setNumFacesFast(const S32 newFaces, LLFacePool *poolp, LLViewer void LLDrawable::mergeFaces(LLDrawable* src) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE + U32 face_count = mFaces.size() + src->mFaces.size(); mFaces.reserve(face_count); @@ -509,6 +491,8 @@ void LLDrawable::updateMaterial() void LLDrawable::makeActive() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE + #if !LL_RELEASE_FOR_DOWNLOAD if (mVObjp.notNull()) { @@ -570,6 +554,8 @@ void LLDrawable::makeActive() void LLDrawable::makeStatic(BOOL warning_enabled) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE + if (isState(ACTIVE) && !isState(ACTIVE_CHILD) && !mVObjp->isAttachment() && @@ -616,6 +602,8 @@ void LLDrawable::makeStatic(BOOL warning_enabled) // Returns "distance" between target destination and resulting xfrom F32 LLDrawable::updateXform(BOOL undamped) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE + BOOL damped = !undamped; // Position @@ -767,6 +755,8 @@ void LLDrawable::moveUpdatePipeline(BOOL moved) void LLDrawable::movePartition() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE + LLSpatialPartition* part = getSpatialPartition(); if (part) { @@ -811,6 +801,8 @@ BOOL LLDrawable::updateMoveUndamped() void LLDrawable::updatePartition() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE + if (!getVOVolume()) { movePartition(); @@ -828,6 +820,8 @@ void LLDrawable::updatePartition() BOOL LLDrawable::updateMoveDamped() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE + F32 dist_squared = updateXform(FALSE); mGeneration++; @@ -851,6 +845,8 @@ BOOL LLDrawable::updateMoveDamped() void LLDrawable::updateDistance(LLCamera& camera, bool force_update) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE + if (LLViewerCamera::sCurCameraID != LLViewerCamera::CAMERA_WORLD) { LL_WARNS() << "Attempted to update distance for non-world camera." << LL_ENDL; @@ -911,7 +907,7 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update) if (avatarp) { const LLVector3* av_box = avatarp->getLastAnimExtents(); - LLVector3 cam_pos_from_agent = LLViewerCamera::getInstanceFast()->getOrigin(); + LLVector3 cam_pos_from_agent = LLViewerCamera::getInstance()->getOrigin(); LLVector3 cam_to_box_offset = point_to_box_offset(cam_pos_from_agent, av_box); mDistanceWRTCamera = llmax(0.01f, ll_round(cam_to_box_offset.magVec(), 0.01f)); #ifdef SHOW_DEBUG @@ -958,6 +954,8 @@ void LLDrawable::updateTexture() BOOL LLDrawable::updateGeometry(BOOL priority) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE + llassert(mVObjp.notNull()); BOOL res = mVObjp && mVObjp->updateGeometry(this); return res; @@ -1035,6 +1033,8 @@ const LLVector3& LLDrawable::getBounds(LLVector3& min, LLVector3& max) const void LLDrawable::updateSpatialExtents() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE + if (mVObjp) { const LLVector4a* exts = getSpatialExtents(); @@ -1163,19 +1163,26 @@ void LLDrawable::setGroup(LLViewerOctreeGroup *groupp) LLViewerOctreeEntryData::setGroup(groupp); } +/* +* Get the SpatialPartition this Drawable should use. +* Checks current SpatialPartition assignment and corrects if it is invalid. +*/ LLSpatialPartition* LLDrawable::getSpatialPartition() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE + LLSpatialPartition* retval = NULL; - + if (!mVObjp || !getVOVolume() || isStatic()) { - retval = gPipeline.getSpatialPartition((LLViewerObject*) mVObjp); + retval = gPipeline.getSpatialPartition((LLViewerObject*)mVObjp); } else if (isRoot()) { - if (mSpatialBridge) + // determine if the spatial bridge has changed + if (mSpatialBridge) { U32 partition_type = mSpatialBridge->asPartition()->mPartitionType; bool is_hud = mVObjp->isHUDAttachment(); @@ -1192,14 +1199,14 @@ LLSpatialPartition* LLDrawable::getSpatialPartition() { // Was/became part of animesh // remove obsolete bridge - mSpatialBridge->markDead(); + mSpatialBridge->markDead(); setSpatialBridge(NULL); } else if ((partition_type == LLViewerRegion::PARTITION_AVATAR) != is_attachment) { // Was/became part of avatar // remove obsolete bridge - mSpatialBridge->markDead(); + mSpatialBridge->markDead(); setSpatialBridge(NULL); } } @@ -1210,17 +1217,20 @@ LLSpatialPartition* LLDrawable::getSpatialPartition() { setSpatialBridge(new LLHUDBridge(this, getRegion())); } - else if (mVObjp->isAnimatedObject() && mVObjp->getControlAvatar()) - { - setSpatialBridge(new LLControlAVBridge(this, getRegion())); - } + else if (mVObjp->isAnimatedObject() && mVObjp->getControlAvatar()) + { + setSpatialBridge(new LLControlAVBridge(this, getRegion())); + } // check HUD first, because HUD is also attachment else if (mVObjp->isAttachment()) { + // Attachment + // Use AvatarBridge of root object in attachment linkset setSpatialBridge(new LLAvatarBridge(this, getRegion())); } else { + // Moving linkset, use VolumeBridge of root object in linkset setSpatialBridge(new LLVolumeBridge(this, getRegion())); } } @@ -1248,6 +1258,8 @@ LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 dat LLDrawable(root->getVObj(), true), LLSpatialPartition(data_mask, render_by_group, GL_STREAM_DRAW, regionp) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE + mBridge = this; mDrawable = root; root->setSpatialBridge(this); @@ -1293,12 +1305,11 @@ void LLSpatialBridge::destroyTree() void LLSpatialBridge::updateSpatialExtents() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE + LLSpatialGroup* root = (LLSpatialGroup*) mOctree->getListener(0); - { - LL_RECORD_BLOCK_TIME(FTM_CULL_REBOUND); - root->rebound(); - } + root->rebound(); const LLVector4a* root_bounds = root->getBounds(); LLVector4a offset; @@ -1399,10 +1410,18 @@ LLCamera LLSpatialBridge::transformCamera(LLCamera& camera) ret.setOrigin(LLVector3(delta.getF32ptr())); ret.setAxes(LLVector3(lookAt.getF32ptr()), LLVector3(left_axis.getF32ptr()), LLVector3(up_axis.getF32ptr())); - + return ret; } +void LLSpatialBridge::transformExtents(const LLVector4a* src, LLVector4a* dst) +{ + LLMatrix4a mat = mDrawable->getXform()->getWorldMatrix(); + mat.invert(); + mat.mulBoundBox(src,dst); +} + + void LLDrawable::setVisible(LLCamera& camera, std::vector<LLDrawable*>* results, BOOL for_select) { LLViewerOctreeEntryData::setVisible(); @@ -1462,6 +1481,8 @@ class LLOctreeMarkNotCulled: public OctreeTraveler void LLSpatialBridge::setVisible(LLCamera& camera_in, std::vector<LLDrawable*>* results, BOOL for_select) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE + if (!gPipeline.hasRenderType(mDrawableType)) { return; @@ -1559,6 +1580,8 @@ void LLSpatialBridge::setVisible(LLCamera& camera_in, std::vector<LLDrawable*>* void LLSpatialBridge::updateDistance(LLCamera& camera_in, bool force_update) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE + if (mDrawable == NULL) { markDead(); @@ -1733,6 +1756,17 @@ void LLDrawable::updateFaceSize(S32 idx) } } +LLDrawable* LLDrawable::getRoot() +{ + LLDrawable* ret = this; + while (!ret->isRoot()) + { + ret = ret->getParent(); + } + + return ret; +} + LLBridgePartition::LLBridgePartition(LLViewerRegion* regionp) : LLSpatialPartition(0, FALSE, 0, regionp) { diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h index 289a80b9ec1f94d1d191eb3eb7e6a9386dd69cfc..ed1d29cdef414283d974383a8c51ce8032b4dd1c 100644 --- a/indra/newview/lldrawable.h +++ b/indra/newview/lldrawable.h @@ -59,11 +59,13 @@ const U32 SILHOUETTE_HIGHLIGHT = 0; // All data for new renderer goes into this class. LL_ALIGN_PREFIX(16) -class LLDrawable -: public LLViewerOctreeEntryData, - public LLTrace::MemTrackable<LLDrawable, 16> +class LLDrawable + : public LLViewerOctreeEntryData { + LL_ALIGN_NEW; public: + typedef std::vector<LLFace*> face_list_t; + LLDrawable(const LLDrawable& rhs) = delete; LLDrawable& operator=(const LLDrawable& rhs) = delete; @@ -110,6 +112,7 @@ class LLDrawable BOOL isAvatar() const { return mVObjp.notNull() && mVObjp->isAvatar(); } BOOL isRoot() const { return !mParent || mParent->isAvatar(); } + LLDrawable* getRoot(); BOOL isSpatialRoot() const { return !mParent || mParent->isAvatar(); } virtual BOOL isSpatialBridge() const { return FALSE; } virtual LLSpatialPartition* asPartition() { return NULL; } @@ -120,6 +123,8 @@ class LLDrawable inline LLFace* getFace(const S32 i) const; inline S32 getNumFaces() const; + face_list_t& getFaces() { return mFaces; } + const face_list_t& getFaces() const { return mFaces; } //void removeFace(const S32 i); // SJB: Avoid using this, it's slow LLFace* addFace(LLFacePool *poolp, LLViewerTexture *texturep); @@ -243,38 +248,34 @@ class LLDrawable { IN_REBUILD_Q1 = 0x00000001, IN_REBUILD_Q2 = 0x00000002, - IN_LIGHT_Q = 0x00000004, - EARLY_MOVE = 0x00000008, - MOVE_UNDAMPED = 0x00000010, - ON_MOVE_LIST = 0x00000020, - USE_BACKLIGHT = 0x00000040, - UV = 0x00000080, - UNLIT = 0x00000100, - LIGHT = 0x00000200, - LIGHTING_BUILT = 0x00000400, - REBUILD_VOLUME = 0x00000800, //volume changed LOD or parameters, or vertex buffer changed - REBUILD_TCOORD = 0x00001000, //texture coordinates changed - REBUILD_COLOR = 0x00002000, //color changed - REBUILD_POSITION= 0x00004000, //vertex positions/normals changed + EARLY_MOVE = 0x00000004, + MOVE_UNDAMPED = 0x00000008, + ON_MOVE_LIST = 0x00000010, + UV = 0x00000020, + UNLIT = 0x00000040, + LIGHT = 0x00000080, + REBUILD_VOLUME = 0x00000100, //volume changed LOD or parameters, or vertex buffer changed + REBUILD_TCOORD = 0x00000200, //texture coordinates changed + REBUILD_COLOR = 0x00000400, //color changed + REBUILD_POSITION= 0x00000800, //vertex positions/normals changed REBUILD_GEOMETRY= REBUILD_POSITION|REBUILD_TCOORD|REBUILD_COLOR, REBUILD_MATERIAL= REBUILD_TCOORD|REBUILD_COLOR, REBUILD_ALL = REBUILD_GEOMETRY|REBUILD_VOLUME, - REBUILD_RIGGED = 0x00008000, - ON_SHIFT_LIST = 0x00010000, - BLOCKER = 0x00020000, - ACTIVE = 0x00040000, - DEAD = 0x00080000, - INVISIBLE = 0x00100000, // stay invisible until flag is cleared - NEARBY_LIGHT = 0x00200000, // In gPipeline.mNearbyLightSet - BUILT = 0x00400000, - FORCE_INVISIBLE = 0x00800000, // stay invis until CLEAR_INVISIBLE is set (set of orphaned) - REBUILD_SHADOW = 0x02000000, - HAS_ALPHA = 0x04000000, - RIGGED = 0x08000000, - PARTITION_MOVE = 0x10000000, - ANIMATED_CHILD = 0x20000000, - ACTIVE_CHILD = 0x40000000, - FOR_UNLOAD = 0x80000000, //should be unload from memory + REBUILD_RIGGED = 0x00001000, + ON_SHIFT_LIST = 0x00002000, + ACTIVE = 0x00004000, + DEAD = 0x00008000, + INVISIBLE = 0x00010000, // stay invisible until flag is cleared + NEARBY_LIGHT = 0x00020000, // In gPipeline.mNearbyLightSet + BUILT = 0x00040000, + FORCE_INVISIBLE = 0x00080000, // stay invis until CLEAR_INVISIBLE is set (set of orphaned) + HAS_ALPHA = 0x00100000, + RIGGED = 0x00200000, //has a rigged face + RIGGED_CHILD = 0x00400000, //has a child with a rigged face + PARTITION_MOVE = 0x00800000, + ANIMATED_CHILD = 0x01000000, + ACTIVE_CHILD = 0x02000000, + FOR_UNLOAD = 0x04000000, //should be unload from memory } EDrawableFlags; public: @@ -288,8 +289,6 @@ class LLDrawable static F32 sCurPixelAngle; //current pixels per radian private: - typedef std::vector<LLFace*> face_list_t; - U32 mState; S32 mRenderType; LLPointer<LLViewerObject> mVObjp; diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index 4b937c7f1bd0cfdcddf0420d21f02e58f6a5ff30..2303479e764ac88ca049590b1f8ecf3541d9f9b1 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -50,6 +50,9 @@ #include "lldrawpoolwlsky.h" #include "llglslshader.h" #include "llglcommonfunc.h" +#include "llvoavatar.h" +#include "llviewershadermgr.h" + S32 LLDrawPool::sNumDrawPools = 0; @@ -385,24 +388,47 @@ LLRenderPass::~LLRenderPass() } void LLRenderPass::renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture) -{ +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[type]; for (LLDrawInfo* pparams : draw_info) { - if (pparams) { + if (pparams) + { pushBatch(*pparams, mask, texture); } } } -void LLRenderPass::renderTexture(U32 type, U32 mask, BOOL batch_textures) +void LLRenderPass::renderRiggedGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture) { - pushBatches(type, mask, true, batch_textures); + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; + LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[type]; + LLVOAvatar* lastAvatar = nullptr; + U64 lastMeshId = 0; + mask |= LLVertexBuffer::MAP_WEIGHT4; + + for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k) + { + LLDrawInfo* pparams = *k; + if (pparams) + { + if (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash) + { + uploadMatrixPalette(*pparams); + lastAvatar = pparams->mAvatar; + lastMeshId = pparams->mSkinInfo->mHash; + } + + pushBatch(*pparams, mask, texture); + } + } } void LLRenderPass::pushBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type), end = gPipeline.endRenderMap(type); i != end; ++i) { LLDrawInfo* pparams = *i; @@ -413,27 +439,74 @@ void LLRenderPass::pushBatches(U32 type, U32 mask, BOOL texture, BOOL batch_text } } +void LLRenderPass::pushRiggedBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; + LLVOAvatar* lastAvatar = nullptr; + U64 lastMeshId = 0; + mask |= LLVertexBuffer::MAP_WEIGHT4; + for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i) + { + LLDrawInfo* pparams = *i; + if (pparams) + { + if (pparams->mAvatar.notNull() && (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash)) + { + uploadMatrixPalette(*pparams); + lastAvatar = pparams->mAvatar; + lastMeshId = pparams->mSkinInfo->mHash; + } + + pushBatch(*pparams, mask, texture, batch_textures); + } + } +} + void LLRenderPass::pushMaskBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures) { - for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type), end = gPipeline.endRenderMap(type); i != end; ++i) + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; + for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i) { LLDrawInfo* pparams = *i; if (pparams) { - if (LLGLSLShader::sCurBoundShaderPtr) - { - LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(pparams->mAlphaMaskCutoff); - } - else - { - gGL.setAlphaRejectSettings(LLRender::CF_GREATER, pparams->mAlphaMaskCutoff); - } - + LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(pparams->mAlphaMaskCutoff); pushBatch(*pparams, mask, texture, batch_textures); } } } +void LLRenderPass::pushRiggedMaskBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; + LLVOAvatar* lastAvatar = nullptr; + U64 lastMeshId = 0; + for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i) + { + LLDrawInfo* pparams = *i; + if (pparams) + { + if (LLGLSLShader::sCurBoundShaderPtr) + { + LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(pparams->mAlphaMaskCutoff); + } + else + { + gGL.flush(); + } + + if (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash) + { + uploadMatrixPalette(*pparams); + lastAvatar = pparams->mAvatar; + lastMeshId = pparams->mSkinInfo->mHash; + } + + pushBatch(*pparams, mask | LLVertexBuffer::MAP_WEIGHT4, texture, batch_textures); + } + } +} + void LLRenderPass::applyModelMatrix(const LLDrawInfo& params) { if (params.mModelMatrix != gGLLastMatrix) @@ -451,6 +524,7 @@ void LLRenderPass::applyModelMatrix(const LLDrawInfo& params) void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; if (!params.mCount) { return; @@ -470,7 +544,7 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL ba LLViewerTexture* texture = params.mTextureList[i]; if (texture) { - gGL.getTexUnit(i)->bind(texture, TRUE); + gGL.getTexUnit(i)->bindFast(texture); } } } @@ -478,8 +552,7 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL ba { //not batching textures or batch has only 1 texture -- might need a texture matrix if (params.mTexture.notNull()) { - params.mTexture->addTextureStats(params.mVSize); - gGL.getTexUnit(0)->bind(params.mTexture, TRUE) ; + gGL.getTexUnit(0)->bindFast(params.mTexture); if (params.mTextureMatrix) { tex_setup = true; @@ -491,23 +564,20 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL ba } else { - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(0)->unbindFast(LLTexUnit::TT_TEXTURE); } } } - if (params.mVertexBuffer.notNull()) - { - if (params.mGroup) - { - params.mGroup->rebuildMesh(); - } + if (params.mGroup) + { + params.mGroup->rebuildMesh(); + } - LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test); - - params.mVertexBuffer->setBuffer(mask); - params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); - } + LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test); + + params.mVertexBuffer->setBufferFast(mask); + params.mVertexBuffer->drawRangeFast(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); if (tex_setup) { @@ -517,7 +587,34 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL ba } } -void LLRenderPass::renderGroups(U32 type, U32 mask, BOOL texture) +// static +bool LLRenderPass::uploadMatrixPalette(LLDrawInfo& params) +{ + // upload matrix palette to shader + return uploadMatrixPalette(params.mAvatar, params.mSkinInfo); +} + +//static +bool LLRenderPass::uploadMatrixPalette(LLVOAvatar* avatar, LLMeshSkinInfo* skinInfo) { - gPipeline.renderGroups(this, type, mask, texture); + if (!avatar) + { + return false; + } + const LLVOAvatar::MatrixPaletteCache& mpc = avatar->updateSkinInfoMatrixPalette(skinInfo); + U32 count = mpc.mMatrixPalette.size(); + + if (count == 0) + { + //skin info not loaded yet, don't render + return false; + } + + LLGLSLShader::sCurBoundShaderPtr->uniformMatrix3x4fv(LLViewerShaderMgr::AVATAR_MATRIX, + count, + FALSE, + (GLfloat*)&(mpc.mGLMp[0])); + + return true; } + diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h index ecd9bd034ff85b84b0e825b185106b4af10c2651..fd1b022e5bf3d7b513de8f35c1b5b85a149098e0 100644 --- a/indra/newview/lldrawpool.h +++ b/indra/newview/lldrawpool.h @@ -37,6 +37,8 @@ class LLViewerTexture; class LLViewerFetchedTexture; class LLSpatialGroup; class LLDrawInfo; +class LLVOAvatar; +class LLMeshSkinInfo; class LLDrawPool { @@ -125,38 +127,69 @@ class LLDrawPool class LLRenderPass : public LLDrawPool { public: + // list of possible LLRenderPass types to assign a render batch to + // NOTE: "rigged" variant MUST be non-rigged variant + 1 enum { PASS_SIMPLE = NUM_POOL_TYPES, + PASS_SIMPLE_RIGGED, PASS_GRASS, PASS_FULLBRIGHT, + PASS_FULLBRIGHT_RIGGED, PASS_INVISIBLE, - PASS_INVISI_SHINY, + PASS_INVISIBLE_RIGGED, + PASS_INVISI_SHINY, + PASS_INVISI_SHINY_RIGGED, PASS_FULLBRIGHT_SHINY, + PASS_FULLBRIGHT_SHINY_RIGGED, PASS_SHINY, + PASS_SHINY_RIGGED, PASS_BUMP, + PASS_BUMP_RIGGED, PASS_POST_BUMP, + PASS_POST_BUMP_RIGGED, PASS_MATERIAL, + PASS_MATERIAL_RIGGED, PASS_MATERIAL_ALPHA, + PASS_MATERIAL_ALPHA_RIGGED, PASS_MATERIAL_ALPHA_MASK, // Diffuse texture used as alpha mask + PASS_MATERIAL_ALPHA_MASK_RIGGED, PASS_MATERIAL_ALPHA_EMISSIVE, + PASS_MATERIAL_ALPHA_EMISSIVE_RIGGED, PASS_SPECMAP, + PASS_SPECMAP_RIGGED, PASS_SPECMAP_BLEND, + PASS_SPECMAP_BLEND_RIGGED, PASS_SPECMAP_MASK, // Diffuse texture used as alpha mask and specular texture(map) + PASS_SPECMAP_MASK_RIGGED, PASS_SPECMAP_EMISSIVE, + PASS_SPECMAP_EMISSIVE_RIGGED, PASS_NORMMAP, + PASS_NORMMAP_RIGGED, PASS_NORMMAP_BLEND, + PASS_NORMMAP_BLEND_RIGGED, PASS_NORMMAP_MASK, // Diffuse texture used as alpha mask and normal map + PASS_NORMMAP_MASK_RIGGED, PASS_NORMMAP_EMISSIVE, + PASS_NORMMAP_EMISSIVE_RIGGED, PASS_NORMSPEC, - PASS_NORMSPEC_BLEND, + PASS_NORMSPEC_RIGGED, + PASS_NORMSPEC_BLEND, + PASS_NORMSPEC_BLEND_RIGGED, PASS_NORMSPEC_MASK, // Diffuse texture used as alpha mask with normal and specular map + PASS_NORMSPEC_MASK_RIGGED, PASS_NORMSPEC_EMISSIVE, + PASS_NORMSPEC_EMISSIVE_RIGGED, PASS_GLOW, + PASS_GLOW_RIGGED, PASS_ALPHA, + PASS_ALPHA_RIGGED, PASS_ALPHA_MASK, + PASS_ALPHA_MASK_RIGGED, PASS_FULLBRIGHT_ALPHA_MASK, // Diffuse texture used as alpha mask and fullbright + PASS_FULLBRIGHT_ALPHA_MASK_RIGGED, PASS_ALPHA_INVISIBLE, + PASS_ALPHA_INVISIBLE_RIGGED, NUM_RENDER_TYPES, }; @@ -169,12 +202,14 @@ class LLRenderPass : public LLDrawPool static void applyModelMatrix(const LLDrawInfo& params); virtual void pushBatches(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_textures = FALSE); + virtual void pushRiggedBatches(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_textures = FALSE); virtual void pushMaskBatches(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_textures = FALSE); + virtual void pushRiggedMaskBatches(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_textures = FALSE); virtual void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures = FALSE); + static bool uploadMatrixPalette(LLDrawInfo& params); + static bool uploadMatrixPalette(LLVOAvatar* avatar, LLMeshSkinInfo* skinInfo); virtual void renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture = TRUE); - virtual void renderGroups(U32 type, U32 mask, BOOL texture = TRUE); - virtual void renderTexture(U32 type, U32 mask, BOOL batch_textures = TRUE); - + virtual void renderRiggedGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture = TRUE); }; class LLFacePool : public LLDrawPool diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 74de938dcd8d249761c73719ea6e183d581acdeb..cc8a9d9dbc65d9b3a1bb2069bbad15569dff9a4d 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -48,34 +48,26 @@ #include "lldrawpoolwater.h" #include "llspatialpartition.h" #include "llglcommonfunc.h" +#include "llvoavatar.h" BOOL LLDrawPoolAlpha::sShowDebugAlpha = FALSE; +#define current_shader (LLGLSLShader::sCurBoundShaderPtr) + static BOOL deferred_render = FALSE; -static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_SETUP("Alpha Setup"); -static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_GROUP_LOOP("Alpha Group"); -static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_PUSH("Alpha Push Verts"); -static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_DEFERRED("Alpha Deferred"); -static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_SETBUFFER("Alpha SetBuffer"); -static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_DRAW("Alpha Draw"); -static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_TEX_BINDS("Alpha Tex Binds"); -static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_MATS("Alpha Mat Tex Binds"); -static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_GLOW("Alpha Glow Binds"); -static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_SHADER_BINDS("Alpha Shader Binds"); -static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_DEFERRED_SHADER_BINDS("Alpha Def Binds"); -static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_DEFERRED_TEX_BINDS("Alpha Def Tex Binds"); -static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_MESH_REBUILD("Alpha Mesh Rebuild"); -static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_EMISSIVE("Alpha Emissive"); -static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_LIGHT_SETUP("Alpha Light Setup"); +// minimum alpha before discarding a fragment +static const F32 MINIMUM_ALPHA = 0.004f; // ~ 1/255 + +// minimum alpha before discarding a fragment when rendering impostors +static const F32 MINIMUM_IMPOSTOR_ALPHA = 0.1f; LLDrawPoolAlpha::LLDrawPoolAlpha(U32 type) : - LLRenderPass(type), current_shader(NULL), target_shader(NULL), - simple_shader(NULL), fullbright_shader(NULL), emissive_shader(NULL), + LLRenderPass(type), target_shader(NULL), mColorSFactor(LLRender::BF_UNDEF), mColorDFactor(LLRender::BF_UNDEF), mAlphaSFactor(LLRender::BF_UNDEF), mAlphaDFactor(LLRender::BF_UNDEF) { - + } LLDrawPoolAlpha::~LLDrawPoolAlpha() @@ -86,226 +78,213 @@ LLDrawPoolAlpha::~LLDrawPoolAlpha() void LLDrawPoolAlpha::prerender() { mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT); + + // TODO: is this even necessay? These are probably set to never discard + LLViewerFetchedTexture::sFlatNormalImagep->addTextureStats(1024.f*1024.f); + LLViewerFetchedTexture::sWhiteImagep->addTextureStats(1024.f * 1024.f); } S32 LLDrawPoolAlpha::getNumPostDeferredPasses() { - if (LLPipeline::sImpostorRender) - { //skip depth buffer filling pass when rendering impostors - return 1; - } - else if (LLPipeline::RenderDepthOfField) - { - return 2; - } - else - { - return 1; - } + return 1; } -void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass) +// set some common parameters on the given shader to prepare for alpha rendering +static void prepare_alpha_shader(LLGLSLShader* shader, bool textureGamma, bool deferredEnvironment) +{ + //static LLCachedControl<F32> displayGamma(gSavedSettings, "RenderDeferredDisplayGamma"); + //F32 gamma = displayGamma; + + // Does this deferred shader need environment uniforms set such as sun_dir, etc. ? + // NOTE: We don't actually need a gbuffer since we are doing forward rendering (for transparency) post deferred rendering + // TODO: bindDeferredShader() probably should have the updating of the environment uniforms factored out into updateShaderEnvironmentUniforms() + // i.e. shaders\class1\deferred\alphaF.glsl + if (deferredEnvironment) + { + gPipeline.bindDeferredShader( *shader ); + } + else + { + shader->bind(); + } + shader->uniform1i(LLShaderMgr::NO_ATMO, (LLPipeline::sRenderingHUDs) ? 1 : 0); + //shader->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f / 2.2f)); + + if (LLPipeline::sImpostorRender) + { + shader->setMinimumAlpha(MINIMUM_IMPOSTOR_ALPHA); + } + else + { + shader->setMinimumAlpha(MINIMUM_ALPHA); + } + if (textureGamma) + { + shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f); + } + + //also prepare rigged variant + if (shader->mRiggedVariant && shader->mRiggedVariant != shader) + { + prepare_alpha_shader(shader->mRiggedVariant, textureGamma, deferredEnvironment); + } +} + +void LLDrawPoolAlpha::renderPostDeferred(S32 pass) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DEFERRED); + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; + deferred_render = TRUE; + // prepare shaders emissive_shader = (LLPipeline::sRenderDeferred) ? &gDeferredEmissiveProgram : (LLPipeline::sUnderWaterRender) ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram; + prepare_alpha_shader(emissive_shader, true, false); - emissive_shader->bind(); - emissive_shader->uniform1i(LLShaderMgr::NO_ATMO, (LLPipeline::sRenderingHUDs) ? 1 : 0); - emissive_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f); + fullbright_shader = (LLPipeline::sImpostorRender) ? &gDeferredFullbrightAlphaMaskProgram : + (LLPipeline::sUnderWaterRender) ? &gDeferredFullbrightWaterProgram : &gDeferredFullbrightAlphaMaskProgram; + prepare_alpha_shader(fullbright_shader, true, false); - if (pass == 0) - { - fullbright_shader = (LLPipeline::sImpostorRender) ? &gDeferredFullbrightProgram : - (LLPipeline::sUnderWaterRender) ? &gDeferredFullbrightWaterProgram : &gDeferredFullbrightProgram; + simple_shader = (LLPipeline::sImpostorRender) ? &gDeferredAlphaImpostorProgram : + (LLPipeline::sUnderWaterRender) ? &gDeferredAlphaWaterProgram : &gDeferredAlphaProgram; + prepare_alpha_shader(simple_shader, false, true); //prime simple shader (loads shadow relevant uniforms) - fullbright_shader->bind(); - fullbright_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f); - fullbright_shader->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0); - fullbright_shader->unbind(); + for (int i = 0; i < LLMaterial::SHADER_COUNT; ++i) + { + prepare_alpha_shader(LLPipeline::sUnderWaterRender ? &gDeferredMaterialWaterProgram[i] : &gDeferredMaterialProgram[i], false, false); // note: bindDeferredShader will get called during render loop for materials + } - simple_shader = (LLPipeline::sImpostorRender) ? &gDeferredAlphaImpostorProgram : - (LLPipeline::sUnderWaterRender) ? &gDeferredAlphaWaterProgram : &gDeferredAlphaProgram; + // first pass, render rigged objects only and render to depth buffer + forwardRender(true); - //prime simple shader (loads shadow relevant uniforms) - gPipeline.bindDeferredShader(*simple_shader); + // second pass, regular forward alpha rendering + forwardRender(); - simple_shader->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0); - } - else if (!LLPipeline::sImpostorRender) - { - //update depth buffer sampler - gPipeline.mScreen.flush(); - gPipeline.mDeferredDepth.copyContents(gPipeline.mDeferredScreen, 0, 0, gPipeline.mDeferredScreen.getWidth(), gPipeline.mDeferredScreen.getHeight(), - 0, 0, gPipeline.mDeferredDepth.getWidth(), gPipeline.mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST); - gPipeline.mDeferredDepth.bindTarget(); - simple_shader = fullbright_shader = &gObjectFullbrightAlphaMaskProgram; - gObjectFullbrightAlphaMaskProgram.bind(); - gObjectFullbrightAlphaMaskProgram.setMinimumAlpha(0.33f); - } + // final pass, render to depth for depth of field effects + if (!LLPipeline::sImpostorRender && LLPipeline::RenderDepthOfField) + { + //update depth buffer sampler + gPipeline.mScreen.flush(); + gPipeline.mDeferredDepth.copyContents(gPipeline.mDeferredScreen, 0, 0, gPipeline.mDeferredScreen.getWidth(), gPipeline.mDeferredScreen.getHeight(), + 0, 0, gPipeline.mDeferredDepth.getWidth(), gPipeline.mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST); + gPipeline.mDeferredDepth.bindTarget(); + simple_shader = fullbright_shader = &gObjectFullbrightAlphaMaskProgram; - deferred_render = TRUE; - if (mShaderLevel > 0) - { - // Start out with no shaders. - current_shader = target_shader = NULL; - } - gPipeline.enableLightsDynamic(); -} + simple_shader->bind(); + simple_shader->setMinimumAlpha(0.33f); -void LLDrawPoolAlpha::endPostDeferredPass(S32 pass) -{ - LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DEFERRED); + // mask off color buffer writes as we're only writing to depth buffer + gGL.setColorMask(false, false); - if (pass == 1 && !LLPipeline::sImpostorRender) - { - gPipeline.mDeferredDepth.flush(); - gObjectFullbrightAlphaMaskProgram.unbind(); - } + // If the face is more than 90% transparent, then don't update the Depth buffer for Dof + // We don't want the nearly invisible objects to cause of DoF effects + renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2, + true); // <--- discard mostly transparent faces - deferred_render = FALSE; - endRenderPass(pass); + gPipeline.mDeferredDepth.flush(); + gPipeline.mScreen.bindTarget(); + gGL.setColorMask(true, false); + } + + deferred_render = FALSE; } -void LLDrawPoolAlpha::renderPostDeferred(S32 pass) -{ - LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DEFERRED); - render(pass); +//set some generic parameters for forward (non-deferred) rendering +static void prepare_forward_shader(LLGLSLShader* shader, F32 minimum_alpha) +{ + shader->bind(); + shader->setMinimumAlpha(minimum_alpha); + shader->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0); + + //also prepare rigged variant + if (shader->mRiggedVariant && shader->mRiggedVariant != shader) + { + prepare_forward_shader(shader->mRiggedVariant, minimum_alpha); + } } -void LLDrawPoolAlpha::beginRenderPass(S32 pass) +void LLDrawPoolAlpha::render(S32 pass) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_SETUP); - - simple_shader = (LLPipeline::sImpostorRender) ? &gObjectSimpleImpostorProgram : - (LLPipeline::sUnderWaterRender) ? &gObjectSimpleWaterProgram : &gObjectSimpleProgram; + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; - fullbright_shader = (LLPipeline::sImpostorRender) ? &gObjectFullbrightProgram : - (LLPipeline::sUnderWaterRender) ? &gObjectFullbrightWaterProgram : &gObjectFullbrightProgram; + simple_shader = (LLPipeline::sImpostorRender) ? &gObjectSimpleImpostorProgram : + (LLPipeline::sUnderWaterRender) ? &gObjectSimpleWaterProgram : &gObjectSimpleAlphaMaskProgram; - emissive_shader = (LLPipeline::sImpostorRender) ? &gObjectEmissiveProgram : - (LLPipeline::sUnderWaterRender) ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram; + fullbright_shader = (LLPipeline::sImpostorRender) ? &gObjectFullbrightAlphaMaskProgram : + (LLPipeline::sUnderWaterRender) ? &gObjectFullbrightWaterProgram : &gObjectFullbrightAlphaMaskProgram; + emissive_shader = (LLPipeline::sImpostorRender) ? &gObjectEmissiveProgram : + (LLPipeline::sUnderWaterRender) ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram; + + F32 minimum_alpha = MINIMUM_ALPHA; if (LLPipeline::sImpostorRender) - { - if (mShaderLevel > 0) - { - fullbright_shader->bind(); - fullbright_shader->setMinimumAlpha(0.5f); - fullbright_shader->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0); - simple_shader->bind(); - simple_shader->setMinimumAlpha(0.5f); - simple_shader->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0); - } - else - { - gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); //OK - } - } - else - { - if (mShaderLevel > 0) - { - fullbright_shader->bind(); - fullbright_shader->setMinimumAlpha(0.f); - fullbright_shader->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0); - simple_shader->bind(); - simple_shader->setMinimumAlpha(0.f); - simple_shader->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0); - } - else - { - gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); //OK - } + { + minimum_alpha = MINIMUM_IMPOSTOR_ALPHA; } - gPipeline.enableLightsDynamic(); - LLGLSLShader::bindNoShader(); - current_shader = NULL; -} + prepare_forward_shader(fullbright_shader, minimum_alpha); + prepare_forward_shader(simple_shader, minimum_alpha); -void LLDrawPoolAlpha::endRenderPass( S32 pass ) -{ - LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_SETUP); - LLRenderPass::endRenderPass(pass); + for (int i = 0; i < LLMaterial::SHADER_COUNT; ++i) + { + prepare_forward_shader(LLPipeline::sUnderWaterRender ? &gDeferredMaterialWaterProgram[i] : &gDeferredMaterialProgram[i], minimum_alpha); + } - if(gPipeline.canUseWindLightShaders()) - { - LLGLSLShader::bindNoShader(); - } + //first pass -- rigged only and drawn to depth buffer + forwardRender(true); + + //second pass -- non-rigged, no depth buffer writes + forwardRender(); } -void LLDrawPoolAlpha::render(S32 pass) +void LLDrawPoolAlpha::forwardRender(bool rigged) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA); + gPipeline.enableLightsDynamic(); - LLGLSPipelineAlpha gls_pipeline_alpha; + LLGLSPipelineAlpha gls_pipeline_alpha; - if (deferred_render && pass == 1) - { //depth only - gGL.setColorMask(false, false); - } - else - { - gGL.setColorMask(true, true); - } - - bool write_depth = LLDrawPoolWater::sSkipScreenCopy - || (deferred_render && pass == 1) - // we want depth written so that rendered alpha will - // contribute to the alpha mask used for impostors - || LLPipeline::sImpostorRenderAlphaDepthPass; + //enable writing to alpha for emissive effects + gGL.setColorMask(true, true); - LLGLDepthTest depth(GL_TRUE, write_depth ? GL_TRUE : GL_FALSE); + bool write_depth = rigged || + LLDrawPoolWater::sSkipScreenCopy + // we want depth written so that rendered alpha will + // contribute to the alpha mask used for impostors + || LLPipeline::sImpostorRenderAlphaDepthPass; - if (deferred_render && pass == 1) - { - gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, LLRender::BF_ONE_MINUS_SOURCE_ALPHA); - } - else - { - mColorSFactor = LLRender::BF_SOURCE_ALPHA; // } regular alpha blend - mColorDFactor = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; // } - mAlphaSFactor = LLRender::BF_ZERO; // } glow suppression - mAlphaDFactor = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; // } - gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor); - } + LLGLDepthTest depth(GL_TRUE, write_depth ? GL_TRUE : GL_FALSE); - if (mShaderLevel > 0) - { - renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2, pass); - } - else - { - renderAlpha(getVertexDataMask(), pass); - } + mColorSFactor = LLRender::BF_SOURCE_ALPHA; // } regular alpha blend + mColorDFactor = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; // } + mAlphaSFactor = LLRender::BF_ZERO; // } glow suppression + mAlphaDFactor = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; // } + gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor); - gGL.setColorMask(true, false); + // If the face is more than 90% transparent, then don't update the Depth buffer for Dof + // We don't want the nearly invisible objects to cause of DoF effects + renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2, false, rigged); - if (deferred_render && pass == 1) - { - gGL.setSceneBlendType(LLRender::BT_ALPHA); - } + gGL.setColorMask(true, false); + if (!rigged) + { //render "highlight alpha" on final non-rigged pass + // NOTE -- hacky call here protected by !rigged instead of alongside "forwardRender" + // so renderDebugAlpha is executed while gls_pipeline_alpha and depth GL state + // variables above are still in scope + renderDebugAlpha(); + } +} + +void LLDrawPoolAlpha::renderDebugAlpha() +{ if (sShowDebugAlpha) { - BOOL shaders = gPipeline.canUseVertexShaders(); - if(shaders) - { - gHighlightProgram.bind(); - } - else - { - gPipeline.enableLightsFullbright(); - } + gHighlightProgram.bind(); + gGL.diffuseColor4f(1, 0, 0, 1); + LLViewerFetchedTexture::sSmokeImagep->addTextureStats(1024.f * 1024.f); + gGL.getTexUnit(0)->bindFast(LLViewerFetchedTexture::sSmokeImagep); - gGL.diffuseColor4f(1,0,0,1); - - LLViewerFetchedTexture::sSmokeImagep->addTextureStats(1024.f*1024.f); - gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sSmokeImagep, TRUE) ; - renderAlphaHighlight(LLVertexBuffer::MAP_VERTEX | - LLVertexBuffer::MAP_TEXCOORD0); + renderAlphaHighlight(LLVertexBuffer::MAP_VERTEX | + LLVertexBuffer::MAP_TEXCOORD0); pushBatches(LLRenderPass::PASS_ALPHA_MASK, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE); pushBatches(LLRenderPass::PASS_ALPHA_INVISIBLE, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE); @@ -321,42 +300,85 @@ void LLDrawPoolAlpha::render(S32 pass) gGL.diffuseColor4f(0, 1, 0, 1); pushBatches(LLRenderPass::PASS_INVISIBLE, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE); - if(shaders) - { - gHighlightProgram.unbind(); - } + gHighlightProgram.mRiggedVariant->bind(); + gGL.diffuseColor4f(1, 0, 0, 1); + + pushRiggedBatches(LLRenderPass::PASS_ALPHA_MASK_RIGGED, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE); + pushRiggedBatches(LLRenderPass::PASS_ALPHA_INVISIBLE_RIGGED, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE); + + // Material alpha mask + gGL.diffuseColor4f(0, 0, 1, 1); + pushRiggedBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK_RIGGED, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE); + pushRiggedBatches(LLRenderPass::PASS_NORMMAP_MASK_RIGGED, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE); + pushRiggedBatches(LLRenderPass::PASS_SPECMAP_MASK_RIGGED, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE); + pushRiggedBatches(LLRenderPass::PASS_NORMSPEC_MASK_RIGGED, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE); + pushRiggedBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK_RIGGED, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE); + + gGL.diffuseColor4f(0, 1, 0, 1); + pushRiggedBatches(LLRenderPass::PASS_INVISIBLE_RIGGED, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE); + LLGLSLShader::sCurBoundShaderPtr->unbind(); } } void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask) { - for (LLCullResult::sg_iterator i = gPipeline.beginAlphaGroups(), i_end = gPipeline.endAlphaGroups(); i != i_end; ++i) - { - LLSpatialGroup* group = *i; - if (group->getSpatialPartition()->mRenderByGroup && - !group->isDead()) - { - LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA]; + for (int pass = 0; pass < 2; ++pass) + { //two passes, one rigged and one not + LLVOAvatar* lastAvatar = nullptr; + U64 lastMeshId = 0; - for (LLDrawInfo* paramsp : draw_info) - { - LLDrawInfo& params = *paramsp; - - if (params.mParticle) - { - continue; - } + LLCullResult::sg_iterator begin = pass == 0 ? gPipeline.beginAlphaGroups() : gPipeline.beginRiggedAlphaGroups(); + LLCullResult::sg_iterator end = pass == 0 ? gPipeline.endAlphaGroups() : gPipeline.endRiggedAlphaGroups(); - LLRenderPass::applyModelMatrix(params); - if (params.mGroup) - { - params.mGroup->rebuildMesh(); - } - params.mVertexBuffer->setBuffer(mask); - params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); - } - } - } + for (LLCullResult::sg_iterator i = begin; i != end; ++i) + { + LLSpatialGroup* group = *i; + if (group->getSpatialPartition()->mRenderByGroup && + !group->isDead()) + { + LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA+pass]; // <-- hacky + pass to use PASS_ALPHA_RIGGED on second pass + + for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k) + { + LLDrawInfo& params = **k; + + if (params.mParticle) + { + continue; + } + + bool rigged = (params.mAvatar != nullptr); + gHighlightProgram.bind(rigged); + gGL.diffuseColor4f(1, 0, 0, 1); + + if (rigged) + { + if (lastAvatar != params.mAvatar || + lastMeshId != params.mSkinInfo->mHash) + { + if (!uploadMatrixPalette(params)) + { + continue; + } + lastAvatar = params.mAvatar; + lastMeshId = params.mSkinInfo->mHash; + } + } + + LLRenderPass::applyModelMatrix(params); + if (params.mGroup) + { + params.mGroup->rebuildMesh(); + } + params.mVertexBuffer->setBufferFast(rigged ? mask | LLVertexBuffer::MAP_WEIGHT4 : mask); + params.mVertexBuffer->drawRangeFast(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); + } + } + } + } + + // make sure static version of highlight shader is bound before returning + gHighlightProgram.bind(); } inline bool IsFullbright(LLDrawInfo& params) @@ -376,46 +398,41 @@ inline bool IsEmissive(LLDrawInfo& params) inline void Draw(LLDrawInfo* draw, U32 mask) { - draw->mVertexBuffer->setBuffer(mask); + draw->mVertexBuffer->setBufferFast(mask); LLRenderPass::applyModelMatrix(*draw); - draw->mVertexBuffer->drawRange(draw->mDrawMode, draw->mStart, draw->mEnd, draw->mCount, draw->mOffset); + draw->mVertexBuffer->drawRangeFast(draw->mDrawMode, draw->mStart, draw->mEnd, draw->mCount, draw->mOffset); } -bool LLDrawPoolAlpha::TexSetup(LLDrawInfo* draw, bool use_shaders, bool use_material, LLGLSLShader* current_shader) +bool LLDrawPoolAlpha::TexSetup(LLDrawInfo* draw, bool use_material) { - //LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_TEX_BINDS); - bool tex_setup = false; if (deferred_render && use_material && current_shader) { - //LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DEFERRED_TEX_BINDS); if (draw->mNormalMap) - { + { draw->mNormalMap->addTextureStats(draw->mVSize); current_shader->bindTexture(LLShaderMgr::BUMP_MAP, draw->mNormalMap); } - + if (draw->mSpecularMap) { draw->mSpecularMap->addTextureStats(draw->mVSize); current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, draw->mSpecularMap); } } - else if (current_shader == simple_shader) + else if (current_shader == simple_shader || current_shader == simple_shader->mRiggedVariant) { - LLViewerFetchedTexture::sFlatNormalImagep->addTextureStats(draw->mVSize); - LLViewerFetchedTexture::sWhiteImagep->addTextureStats(draw->mVSize); - current_shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep); + current_shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep); current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep); } - if (use_shaders && draw->mTextureList.size() > 1) + if (draw->mTextureList.size() > 1) { for (U32 i = 0; i < draw->mTextureList.size(); ++i) { if (draw->mTextureList[i].notNull()) { - gGL.getTexUnit(i)->bind(draw->mTextureList[i], TRUE); + gGL.getTexUnit(i)->bindFast(draw->mTextureList[i]); } } } @@ -423,16 +440,15 @@ bool LLDrawPoolAlpha::TexSetup(LLDrawInfo* draw, bool use_shaders, bool use_mate { //not batching textures or batch has only 1 texture -- might need a texture matrix if (draw->mTexture.notNull()) { - draw->mTexture->addTextureStats(draw->mVSize); - if (use_shaders && use_material) + if (use_material) { current_shader->bindTexture(LLShaderMgr::DIFFUSE_MAP, draw->mTexture); } else { - gGL.getTexUnit(0)->bind(draw->mTexture, TRUE) ; + gGL.getTexUnit(0)->bindFast(draw->mTexture); } - + if (draw->mTextureMatrix) { tex_setup = true; @@ -444,7 +460,7 @@ bool LLDrawPoolAlpha::TexSetup(LLDrawInfo* draw, bool use_shaders, bool use_mate } else { - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(0)->unbindFast(LLTexUnit::TT_TEXTURE); } } @@ -462,161 +478,83 @@ void LLDrawPoolAlpha::RestoreTexSetup(bool tex_setup) } } -void LLDrawPoolAlpha::renderSimples(U32 mask, std::vector<LLDrawInfo*>& simples) +void LLDrawPoolAlpha::drawEmissive(U32 mask, LLDrawInfo* draw) { - gPipeline.enableLightsDynamic(); - simple_shader->bind(); - simple_shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep); - simple_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep); - simple_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, 1.0f, 1.0f, 1.0f, 1.0f); - simple_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, 0.0f); - simple_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 0.0f); - bool use_shaders = gPipeline.canUseVertexShaders(); - for (LLDrawInfo* draw : simples) - { - bool tex_setup = TexSetup(draw, use_shaders, false, simple_shader); - LLGLEnableFunc stencil_test(GL_STENCIL_TEST, draw->mSelected, &LLGLCommonFunc::selected_stencil_test); - gGL.blendFunc((LLRender::eBlendFactor) draw->mBlendFuncSrc, (LLRender::eBlendFactor) draw->mBlendFuncDst, mAlphaSFactor, mAlphaDFactor); - - Draw(draw, mask); - RestoreTexSetup(tex_setup); - } - simple_shader->unbind(); + LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 1.f); + draw->mVertexBuffer->setBufferFast((mask & ~LLVertexBuffer::MAP_COLOR) | LLVertexBuffer::MAP_EMISSIVE); + draw->mVertexBuffer->drawRangeFast(draw->mDrawMode, draw->mStart, draw->mEnd, draw->mCount, draw->mOffset); } -void LLDrawPoolAlpha::renderFullbrights(U32 mask, std::vector<LLDrawInfo*>& fullbrights) -{ - gPipeline.enableLightsFullbright(); - fullbright_shader->bind(); - fullbright_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 1.0f); - bool use_shaders = gPipeline.canUseVertexShaders(); - for (LLDrawInfo* draw : fullbrights) - { - bool tex_setup = TexSetup(draw, use_shaders, false, fullbright_shader); - LLGLEnableFunc stencil_test(GL_STENCIL_TEST, draw->mSelected, &LLGLCommonFunc::selected_stencil_test); - gGL.blendFunc((LLRender::eBlendFactor) draw->mBlendFuncSrc, (LLRender::eBlendFactor) draw->mBlendFuncDst, mAlphaSFactor, mAlphaDFactor); +void LLDrawPoolAlpha::renderEmissives(U32 mask, std::vector<LLDrawInfo*>& emissives) +{ + emissive_shader->bind(); + emissive_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 1.f); - Draw(draw, mask & ~(LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2)); + for (LLDrawInfo* draw : emissives) + { + bool tex_setup = TexSetup(draw, false); + drawEmissive(mask, draw); RestoreTexSetup(tex_setup); } - fullbright_shader->unbind(); } -void LLDrawPoolAlpha::renderMaterials(U32 mask, std::vector<LLDrawInfo*>& materials) +void LLDrawPoolAlpha::renderRiggedEmissives(U32 mask, std::vector<LLDrawInfo*>& emissives) { - LLGLSLShader::bindNoShader(); - current_shader = NULL; + LLGLDepthTest depth(GL_TRUE, GL_FALSE); //disable depth writes since "emissive" is additive so sorting doesn't matter + LLGLSLShader* shader = emissive_shader->mRiggedVariant; + shader->bind(); + shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 1.f); - gPipeline.enableLightsDynamic(); - bool use_shaders = gPipeline.canUseVertexShaders(); - for (LLDrawInfo* draw : materials) - { - U32 mask = draw->mShaderMask; + LLVOAvatar* lastAvatar = nullptr; + U64 lastMeshId = 0; - llassert(mask < LLMaterial::SHADER_COUNT); - target_shader = (LLPipeline::sUnderWaterRender) ? &(gDeferredMaterialWaterProgram[mask]) : &(gDeferredMaterialProgram[mask]); - - if (current_shader != target_shader) - { - //LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DEFERRED_SHADER_BINDS); - if (current_shader) - { - gPipeline.unbindDeferredShader(*current_shader); - } - gPipeline.bindDeferredShader(*target_shader); - current_shader = target_shader; - } - - bool tex_setup = TexSetup(draw, use_shaders, true, current_shader); - - current_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, draw->mSpecColor.mV[0], draw->mSpecColor.mV[1], draw->mSpecColor.mV[2], draw->mSpecColor.mV[3]); - current_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, draw->mEnvIntensity); - current_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, draw->mFullbright ? 1.f : 0.f); + mask |= LLVertexBuffer::MAP_WEIGHT4; + for (LLDrawInfo* draw : emissives) + { + bool tex_setup = TexSetup(draw, false); + if (lastAvatar != draw->mAvatar || lastMeshId != draw->mSkinInfo->mHash) { - //LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DEFERRED_TEX_BINDS); - if (draw->mNormalMap) - { - draw->mNormalMap->addTextureStats(draw->mVSize); - current_shader->bindTexture(LLShaderMgr::BUMP_MAP, draw->mNormalMap); - } - - if (draw->mSpecularMap) - { - draw->mSpecularMap->addTextureStats(draw->mVSize); - current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, draw->mSpecularMap); - } + if (!uploadMatrixPalette(*draw)) + { // failed to upload matrix palette, skip rendering + continue; + } + lastAvatar = draw->mAvatar; + lastMeshId = draw->mSkinInfo->mHash; } - - LLGLEnableFunc stencil_test(GL_STENCIL_TEST, draw->mSelected, &LLGLCommonFunc::selected_stencil_test); - gGL.blendFunc((LLRender::eBlendFactor) draw->mBlendFuncSrc, (LLRender::eBlendFactor) draw->mBlendFuncDst, mAlphaSFactor, mAlphaDFactor); - - Draw(draw, mask); + drawEmissive(mask, draw); RestoreTexSetup(tex_setup); } } -void LLDrawPoolAlpha::drawEmissive(U32 mask, LLDrawInfo* draw) +void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged) { - draw->mVertexBuffer->setBuffer((mask & ~LLVertexBuffer::MAP_COLOR) | LLVertexBuffer::MAP_EMISSIVE); - draw->mVertexBuffer->drawRange(draw->mDrawMode, draw->mStart, draw->mEnd, draw->mCount, draw->mOffset); -} - -void LLDrawPoolAlpha::drawEmissiveInline(U32 mask, LLDrawInfo* draw) -{ - // install glow-accumulating blend mode - gGL.blendFunc( - LLRender::BF_ZERO, LLRender::BF_ONE, // don't touch color - LLRender::BF_ONE, LLRender::BF_ONE); // add to alpha (glow) - - emissive_shader->bind(); - - drawEmissive(mask, draw); + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; + BOOL initialized_lighting = FALSE; + BOOL light_enabled = TRUE; - // restore our alpha blend mode - gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor); + LLVOAvatar* lastAvatar = nullptr; + U64 lastMeshId = 0; + LLGLSLShader* lastAvatarShader = nullptr; - current_shader->bind(); -} - -void LLDrawPoolAlpha::renderEmissives(U32 mask, std::vector<LLDrawInfo*>& emissives) -{ - emissive_shader->bind(); - emissive_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 1.f); - - gPipeline.enableLightsDynamic(); + LLCullResult::sg_iterator begin; + LLCullResult::sg_iterator end; - // install glow-accumulating blend mode - // don't touch color, add to alpha (glow) - gGL.blendFunc(LLRender::BF_ZERO, LLRender::BF_ONE, LLRender::BF_ONE, LLRender::BF_ONE); - bool use_shaders = gPipeline.canUseVertexShaders(); - for (LLDrawInfo* draw : emissives) + if (rigged) { - bool tex_setup = TexSetup(draw, use_shaders, false, emissive_shader); - drawEmissive(mask, draw); - RestoreTexSetup(tex_setup); + begin = gPipeline.beginRiggedAlphaGroups(); + end = gPipeline.endRiggedAlphaGroups(); + } + else + { + begin = gPipeline.beginAlphaGroups(); + end = gPipeline.endAlphaGroups(); } - // restore our alpha blend mode - gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor); - - emissive_shader->unbind(); -} - -void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) -{ - static const LLCachedControl<bool> batch_fullbrights(gSavedSettings, "RenderAlphaBatchFullbrights"); - static const LLCachedControl<bool> batch_emissives(gSavedSettings, "RenderAlphaBatchEmissives"); - bool initialized_lighting = FALSE; - bool light_enabled = TRUE; - - bool use_shaders = gPipeline.canUseVertexShaders(); - - LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_GROUP_LOOP); - - for (LLCullResult::sg_iterator i = gPipeline.beginAlphaGroups(), i_end = gPipeline.endAlphaGroups(); i != i_end; ++i) + for (LLCullResult::sg_iterator i = begin; i != end; ++i) { + LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("renderAlpha - group"); LLSpatialGroup* group = *i; llassert(group); llassert(group->getSpatialPartition()); @@ -625,56 +563,54 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) !group->isDead()) { static std::vector<LLDrawInfo*> emissives; - static std::vector<LLDrawInfo*> fullbrights; + static std::vector<LLDrawInfo*> rigged_emissives; + emissives.resize(0); + rigged_emissives.resize(0); bool is_particle_or_hud_particle = group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_PARTICLE || group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_HUD_PARTICLE; bool draw_glow_for_this_partition = mShaderLevel > 0; // no shaders = no glow. - - - bool disable_cull = is_particle_or_hud_particle; LLGLDisable cull(disable_cull ? GL_CULL_FACE : 0); - LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA]; + LLSpatialGroup::drawmap_elem_t& draw_info = rigged ? group->mDrawMap[LLRenderPass::PASS_ALPHA_RIGGED] : group->mDrawMap[LLRenderPass::PASS_ALPHA]; - for (LLDrawInfo* k : draw_info) + for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k) { - LLDrawInfo& params = *k; + LLDrawInfo& params = **k; + if ((bool)params.mAvatar != rigged) + { + continue; + } + + LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("ra - push batch") + U32 have_mask = params.mVertexBuffer->getTypeMask() & mask; if (have_mask != mask) { //FIXME! - //LL_WARNS_ONCE() << "Missing required components, expected mask: " << mask - // << " present: " << have_mask - // << ". Skipping render batch." << LL_ENDL; + LL_WARNS_ONCE() << "Missing required components, expected mask: " << mask + << " present: " << have_mask + << ". Skipping render batch." << LL_ENDL; continue; } - // Fix for bug - NORSPEC-271 - // If the face is more than 90% transparent, then don't update the Depth buffer for Dof - // We don't want the nearly invisible objects to cause of DoF effects - if(pass == 1 && !LLPipeline::sImpostorRender) + if(depth_only) { + // when updating depth buffer, discard faces that are more than 90% transparent LLFace* face = params.mFace; if(face) { const LLTextureEntry* tep = face->getTextureEntry(); if(tep) - { - if(tep->getColor().mV[3] < 0.1f) + { // don't render faces that are more than 90% transparent + if(tep->getColor().mV[3] < MINIMUM_IMPOSTOR_ALPHA) continue; } } } - if (params.mFullbright && batch_fullbrights) - { - fullbrights.push_back(¶ms); - continue; - } - LLRenderPass::applyModelMatrix(params); LLMaterial* mat = NULL; @@ -689,34 +625,17 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) // Turn off lighting if it hasn't already been so. if (light_enabled || !initialized_lighting) { - //LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_LIGHT_SETUP); - initialized_lighting = TRUE; - if (use_shaders) - { - target_shader = fullbright_shader; - } - else - { - gPipeline.enableLightsFullbright(); - } + target_shader = fullbright_shader; + light_enabled = FALSE; } } // Turn on lighting if it isn't already. else if (!light_enabled || !initialized_lighting) { - //LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_LIGHT_SETUP); - initialized_lighting = TRUE; - if (use_shaders) - { - target_shader = simple_shader; - } - else - { - gPipeline.enableLightsDynamic(); - } + target_shader = simple_shader; light_enabled = TRUE; } @@ -732,11 +651,15 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) target_shader = &(gDeferredMaterialWaterProgram[mask]); } + if (params.mAvatar != nullptr) + { + llassert(target_shader->mRiggedVariant != nullptr); + target_shader = target_shader->mRiggedVariant; + } + if (current_shader != target_shader) { - //LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DEFERRED_SHADER_BINDS); gPipeline.bindDeferredShader(*target_shader); - current_shader = target_shader; } } else if (!params.mFullbright) @@ -748,25 +671,23 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) target_shader = fullbright_shader; } - if(use_shaders && (current_shader != target_shader)) - {// If we need shaders, and we're not ALREADY using the proper shader, then bind it - // (this way we won't rebind shaders unnecessarily). - //LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_SHADER_BINDS); - current_shader = target_shader; - current_shader->bind(); - } - else if (!use_shaders && current_shader != NULL) - { - LLGLSLShader::bindNoShader(); - current_shader = NULL; - } + if (params.mAvatar != nullptr) + { + target_shader = target_shader->mRiggedVariant; + } + + if (current_shader != target_shader) + {// If we need shaders, and we're not ALREADY using the proper shader, then bind it + // (this way we won't rebind shaders unnecessarily). + target_shader->bind(); + } LLVector4 spec_color(1, 1, 1, 1); F32 env_intensity = 0.0f; F32 brightness = 1.0f; // We have a material. Supply the appropriate data here. - if (use_shaders && mat && deferred_render) + if (mat && deferred_render) { spec_color = params.mSpecColor; env_intensity = params.mEnvIntensity; @@ -775,7 +696,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) if (current_shader) { - current_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, spec_color.mV[0], spec_color.mV[1], spec_color.mV[2], spec_color.mV[3]); + current_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, spec_color.mV[0], spec_color.mV[1], spec_color.mV[2], spec_color.mV[3]); current_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, env_intensity); current_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, brightness); } @@ -785,38 +706,70 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) params.mGroup->rebuildMesh(); } - bool tex_setup = TexSetup(¶ms, use_shaders, use_shaders && (mat != nullptr), current_shader); + if (params.mAvatar != nullptr) + { + if (lastAvatar != params.mAvatar || + lastMeshId != params.mSkinInfo->mHash || + lastAvatarShader != LLGLSLShader::sCurBoundShaderPtr) + { + if (!uploadMatrixPalette(params)) + { + continue; + } + lastAvatar = params.mAvatar; + lastMeshId = params.mSkinInfo->mHash; + lastAvatarShader = LLGLSLShader::sCurBoundShaderPtr; + } + } - { - //LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_PUSH); + bool tex_setup = TexSetup(¶ms, (mat != nullptr)); + { LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test); gGL.blendFunc((LLRender::eBlendFactor) params.mBlendFuncSrc, (LLRender::eBlendFactor) params.mBlendFuncDst, mAlphaSFactor, mAlphaDFactor); - params.mVertexBuffer->setBuffer(mask & ~(params.mFullbright ? (LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2) : 0)); + bool reset_minimum_alpha = false; + if (!LLPipeline::sImpostorRender && + params.mBlendFuncDst != LLRender::BF_SOURCE_ALPHA && + params.mBlendFuncSrc != LLRender::BF_SOURCE_ALPHA) + { // this draw call has a custom blend function that may require rendering of "invisible" fragments + current_shader->setMinimumAlpha(0.f); + reset_minimum_alpha = true; + } + + U32 drawMask = mask; + if (params.mFullbright) + { + drawMask &= ~(LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2); + } + if (params.mAvatar != nullptr) + { + drawMask |= LLVertexBuffer::MAP_WEIGHT4; + } + + params.mVertexBuffer->setBufferFast(drawMask); + params.mVertexBuffer->drawRangeFast(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); + + if (reset_minimum_alpha) { - //LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DRAW); - params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); + current_shader->setMinimumAlpha(MINIMUM_ALPHA); } } // If this alpha mesh has glow, then draw it a second time to add the destination-alpha (=glow). Interleaving these state-changing calls is expensive, but glow must be drawn Z-sorted with alpha. - if (current_shader && - draw_glow_for_this_partition && + if (draw_glow_for_this_partition && (!is_particle_or_hud_particle || params.mHasGlow) && params.mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_EMISSIVE)) { - //LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_EMISSIVE); - - if (batch_emissives) + if (params.mAvatar != nullptr) { - emissives.push_back(¶ms); + rigged_emissives.push_back(¶ms); } else { - drawEmissiveInline(mask, ¶ms); - } + emissives.push_back(¶ms); + } } if (tex_setup) @@ -828,34 +781,71 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) } } - if (batch_fullbrights) + // render emissive faces into alpha channel for bloom effects + if (!depth_only) { - light_enabled = false; - renderFullbrights(mask, fullbrights); - } + gPipeline.enableLightsDynamic(); - if (batch_emissives) - { - light_enabled = true; - renderEmissives(mask, emissives); - } + // install glow-accumulating blend mode + // don't touch color, add to alpha (glow) + gGL.blendFunc(LLRender::BF_ZERO, LLRender::BF_ONE, LLRender::BF_ONE, LLRender::BF_ONE); - if (current_shader) - { - current_shader->bind(); - } + bool rebind = false; + LLGLSLShader* lastShader = current_shader; + if (!emissives.empty()) + { + light_enabled = true; + renderEmissives(mask, emissives); + rebind = true; + } + + if (!rigged_emissives.empty()) + { + light_enabled = true; + renderRiggedEmissives(mask, rigged_emissives); + rebind = true; + } + + // restore our alpha blend mode + gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor); - emissives.clear(); - fullbrights.clear(); - } + if (lastShader && rebind) + { + lastShader->bind(); + } + } + } } gGL.setSceneBlendType(LLRender::BT_ALPHA); - LLVertexBuffer::unbind(); - + LLVertexBuffer::unbind(); + if (!light_enabled) { gPipeline.enableLightsDynamic(); } } + +bool LLDrawPoolAlpha::uploadMatrixPalette(const LLDrawInfo& params) +{ + if (params.mAvatar.isNull()) + { + return false; + } + const LLVOAvatar::MatrixPaletteCache& mpc = params.mAvatar.get()->updateSkinInfoMatrixPalette(params.mSkinInfo); + U32 count = mpc.mMatrixPalette.size(); + + if (count == 0) + { + //skin info not loaded yet, don't render + return false; + } + + LLGLSLShader::sCurBoundShaderPtr->uniformMatrix3x4fv(LLViewerShaderMgr::AVATAR_MATRIX, + count, + FALSE, + (GLfloat*)&(mpc.mGLMp[0])); + + return true; +} diff --git a/indra/newview/lldrawpoolalpha.h b/indra/newview/lldrawpoolalpha.h index 9f110ea68f88635f591f88946d459976b269a844..521e038b1775b25970a56355989ea3a5651a4ccd 100644 --- a/indra/newview/lldrawpoolalpha.h +++ b/indra/newview/lldrawpoolalpha.h @@ -51,39 +51,34 @@ class LLDrawPoolAlpha final : public LLRenderPass /*virtual*/ ~LLDrawPoolAlpha(); /*virtual*/ S32 getNumPostDeferredPasses(); - /*virtual*/ void beginPostDeferredPass(S32 pass); - /*virtual*/ void endPostDeferredPass(S32 pass); /*virtual*/ void renderPostDeferred(S32 pass); - - /*virtual*/ void beginRenderPass(S32 pass = 0); - /*virtual*/ void endRenderPass( S32 pass ); /*virtual*/ S32 getNumPasses() { return 1; } virtual void render(S32 pass = 0); + void forwardRender(bool write_depth = false); /*virtual*/ void prerender(); + void renderDebugAlpha(); + void renderGroupAlpha(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture = TRUE); - void renderAlpha(U32 mask, S32 pass); + void renderAlpha(U32 mask, bool depth_only = false, bool rigged = false); void renderAlphaHighlight(U32 mask); - + bool uploadMatrixPalette(const LLDrawInfo& params); + static BOOL sShowDebugAlpha; private: - LLGLSLShader* current_shader; LLGLSLShader* target_shader; - LLGLSLShader* simple_shader; - LLGLSLShader* fullbright_shader; - LLGLSLShader* emissive_shader; - void renderSimples(U32 mask, std::vector<LLDrawInfo*>& simples); - void renderFullbrights(U32 mask, std::vector<LLDrawInfo*>& fullbrights); - void renderMaterials(U32 mask, std::vector<LLDrawInfo*>& fullbrights); - void renderEmissives(U32 mask, std::vector<LLDrawInfo*>& emissives); + // setup by beginFooPass, [0] is static variant, [1] is rigged variant + LLGLSLShader* simple_shader = nullptr; + LLGLSLShader* fullbright_shader = nullptr; + LLGLSLShader* emissive_shader = nullptr; void drawEmissive(U32 mask, LLDrawInfo* draw); - void drawEmissiveInline(U32 mask, LLDrawInfo* draw); - - bool TexSetup(LLDrawInfo* draw, bool use_shaders, bool use_material, LLGLSLShader* current_shader); + void renderEmissives(U32 mask, std::vector<LLDrawInfo*>& emissives); + void renderRiggedEmissives(U32 mask, std::vector<LLDrawInfo*>& emissives); + bool TexSetup(LLDrawInfo* draw, bool use_material); void RestoreTexSetup(bool tex_setup); // our 'normal' alpha blend function for this pass @@ -91,6 +86,9 @@ class LLDrawPoolAlpha final : public LLRenderPass LLRender::eBlendFactor mColorDFactor; LLRender::eBlendFactor mAlphaSFactor; LLRender::eBlendFactor mAlphaDFactor; + + // if true, we're executing a rigged render pass + bool mRigged = false; }; #endif // LL_LLDRAWPOOLALPHA_H diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 9936c77ff38d280c16d1658b1af67e4122acef41..5e68dee4dbdfb4e6125c9937354d4b39577a5de6 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -102,8 +102,6 @@ S32 normal_channel = -1; S32 specular_channel = -1; S32 cube_channel = -1; -static LLTrace::BlockTimerStatHandle FTM_SHADOW_AVATAR("Avatar Shadow"); - LLDrawPoolAvatar::LLDrawPoolAvatar(U32 type) : LLFacePool(type) { @@ -120,28 +118,27 @@ LLDrawPoolAvatar::~LLDrawPoolAvatar() // virtual BOOL LLDrawPoolAvatar::isDead() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR + if (!LLFacePool::isDead()) { return FALSE; } - for (U32 i = 0; i < NUM_RIGGED_PASSES; ++i) - { - if (mRiggedFace[i].size() > 0) - { - return FALSE; - } - } return TRUE; } S32 LLDrawPoolAvatar::getShaderLevel() const { + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR + return (S32) LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR); } void LLDrawPoolAvatar::prerender() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR + mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR); sShaderLevel = mShaderLevel; @@ -154,20 +151,12 @@ void LLDrawPoolAvatar::prerender() { sBufferUsage = GL_STREAM_DRAW; } - - if (!mDrawFace.empty()) - { - const LLFace *facep = mDrawFace[0]; - if (facep && facep->getDrawable()) - { - LLVOAvatar* avatarp = (LLVOAvatar *)facep->getDrawable()->getVObj().get(); - updateRiggedVertexBuffers(avatarp); - } - } } LLMatrix4a& LLDrawPoolAvatar::getModelView() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR + static LLMatrix4a ret; ret = gGLModelView; @@ -183,7 +172,7 @@ LLMatrix4a& LLDrawPoolAvatar::getModelView() void LLDrawPoolAvatar::beginDeferredPass(S32 pass) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_CHARACTERS); + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; sSkipTransparent = TRUE; is_deferred_render = true; @@ -204,21 +193,12 @@ void LLDrawPoolAvatar::beginDeferredPass(S32 pass) case 2: beginDeferredSkinned(); break; - case 3: - beginDeferredRiggedSimple(); - break; - case 4: - beginDeferredRiggedBump(); - break; - default: - beginDeferredRiggedMaterial(pass-5); - break; } } void LLDrawPoolAvatar::endDeferredPass(S32 pass) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_CHARACTERS); + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; sSkipTransparent = FALSE; is_deferred_render = false; @@ -239,65 +219,32 @@ void LLDrawPoolAvatar::endDeferredPass(S32 pass) case 2: endDeferredSkinned(); break; - case 3: - endDeferredRiggedSimple(); - break; - case 4: - endDeferredRiggedBump(); - break; - default: - endDeferredRiggedMaterial(pass-5); - break; } } void LLDrawPoolAvatar::renderDeferred(S32 pass) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR + render(pass); } S32 LLDrawPoolAvatar::getNumPostDeferredPasses() { - return 10; + return 1; } void LLDrawPoolAvatar::beginPostDeferredPass(S32 pass) { - switch (pass) - { - case 0: - beginPostDeferredAlpha(); - break; - case 1: - beginRiggedFullbright(); - break; - case 2: - beginRiggedFullbrightShiny(); - break; - case 3: - beginDeferredRiggedAlpha(); - break; - case 4: - beginRiggedFullbrightAlpha(); - break; - case 9: - beginRiggedGlow(); - break; - default: - beginDeferredRiggedMaterialAlpha(pass-5); - break; - } -} + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR -void LLDrawPoolAvatar::beginPostDeferredAlpha() -{ sSkipOpaque = TRUE; sShaderLevel = mShaderLevel; - if (LLPipeline::sUnderWaterRender) - { - sVertexProgram = &gDeferredAvatarAlphaWaterProgram; - } - else + //if (LLPipeline::sUnderWaterRender) + //{ + // sVertexProgram = &gDeferredAvatarAlphaWaterProgram; + //} + //else { sVertexProgram = &gDeferredAvatarAlphaProgram; } @@ -311,88 +258,9 @@ void LLDrawPoolAvatar::beginPostDeferredAlpha() sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); } -void LLDrawPoolAvatar::beginDeferredRiggedAlpha() -{ - if (LLPipeline::sUnderWaterRender) - { - sVertexProgram = &gDeferredSkinnedAlphaWaterProgram; - } - else - { - sVertexProgram = &gDeferredSkinnedAlphaProgram; - } - - gPipeline.bindDeferredShader(*sVertexProgram); - sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); - gPipeline.enableLightsDynamic(); -} - -void LLDrawPoolAvatar::beginDeferredRiggedMaterialAlpha(S32 pass) -{ - switch (pass) - { - case 0: pass = 1; break; - case 1: pass = 5; break; - case 2: pass = 9; break; - default: pass = 13; break; - } - - pass += LLMaterial::SHADER_COUNT; - - sVertexProgram = &gDeferredMaterialProgram[pass]; - - if (LLPipeline::sUnderWaterRender) - { - sVertexProgram = &(gDeferredMaterialWaterProgram[pass]); - } - - gPipeline.bindDeferredShader(*sVertexProgram); - sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); - normal_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::BUMP_MAP); - specular_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::SPECULAR_MAP); - gPipeline.enableLightsDynamic(); -} - -void LLDrawPoolAvatar::endDeferredRiggedAlpha() -{ - LLVertexBuffer::unbind(); - gPipeline.unbindDeferredShader(*sVertexProgram); - sDiffuseChannel = 0; - normal_channel = -1; - specular_channel = -1; - sVertexProgram = NULL; -} - void LLDrawPoolAvatar::endPostDeferredPass(S32 pass) { - switch (pass) - { - case 0: - endPostDeferredAlpha(); - break; - case 1: - endRiggedFullbright(); - break; - case 2: - endRiggedFullbrightShiny(); - break; - case 3: - endDeferredRiggedAlpha(); - break; - case 4: - endRiggedFullbrightAlpha(); - break; - case 5: - endRiggedGlow(); - break; - default: - endDeferredRiggedAlpha(); - break; - } -} - -void LLDrawPoolAvatar::endPostDeferredAlpha() -{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR // if we're in software-blending, remember to set the fence _after_ we draw so we wait till this rendering is done sRenderingSkinned = FALSE; sSkipOpaque = FALSE; @@ -404,29 +272,17 @@ void LLDrawPoolAvatar::endPostDeferredAlpha() void LLDrawPoolAvatar::renderPostDeferred(S32 pass) { - static const S32 actual_pass[] = - { //map post deferred pass numbers to what render() expects - 2, //skinned - 4, // rigged fullbright - 6, //rigged fullbright shiny - 7, //rigged alpha - 8, //rigged fullbright alpha - 9, //rigged material alpha 1 - 10,//rigged material alpha 2 - 11,//rigged material alpha 3 - 12,//rigged material alpha 4 - 13, //rigged glow - }; - - S32 p = actual_pass[pass]; + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR + is_post_deferred_render = true; if (LLPipeline::sImpostorRender) { //HACK for impostors so actual pass ends up being proper pass - p -= 2; + render(0); + } + else + { + render(2); } - - is_post_deferred_render = true; - render(p); is_post_deferred_render = false; } @@ -439,7 +295,7 @@ S32 LLDrawPoolAvatar::getNumShadowPasses() void LLDrawPoolAvatar::beginShadowPass(S32 pass) { - LL_RECORD_BLOCK_TIME(FTM_SHADOW_AVATAR); + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; if (pass == SHADOW_PASS_AVATAR_OPAQUE) { @@ -451,7 +307,7 @@ void LLDrawPoolAvatar::beginShadowPass(S32 pass) sVertexProgram->bind(); } - gGL.diffuseColor4f(1,1,1,1); + gGL.diffuseColor4f(1, 1, 1, 1); } else if (pass == SHADOW_PASS_AVATAR_ALPHA_BLEND) { @@ -471,7 +327,7 @@ void LLDrawPoolAvatar::beginShadowPass(S32 pass) sVertexProgram->bind(); } - gGL.diffuseColor4f(1,1,1,1); + gGL.diffuseColor4f(1, 1, 1, 1); } else if (pass == SHADOW_PASS_AVATAR_ALPHA_MASK) { @@ -491,69 +347,13 @@ void LLDrawPoolAvatar::beginShadowPass(S32 pass) sVertexProgram->bind(); } - gGL.diffuseColor4f(1,1,1,1); - } - else if (pass == SHADOW_PASS_ATTACHMENT_ALPHA_BLEND) - { - sVertexProgram = &gDeferredAttachmentAlphaShadowProgram; - - // bind diffuse tex so we can reference the alpha channel... - S32 loc = sVertexProgram->getUniformLocation(LLViewerShaderMgr::DIFFUSE_MAP); - sDiffuseChannel = 0; - if (loc != -1) - { - sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); - } - - if ((sShaderLevel > 0)) // for hardware blending - { - sRenderingSkinned = TRUE; - sVertexProgram->bind(); - } - - gGL.diffuseColor4f(1,1,1,1); - } - else if (pass == SHADOW_PASS_ATTACHMENT_ALPHA_MASK) - { - sVertexProgram = &gDeferredAttachmentAlphaMaskShadowProgram; - - // bind diffuse tex so we can reference the alpha channel... - S32 loc = sVertexProgram->getUniformLocation(LLViewerShaderMgr::DIFFUSE_MAP); - sDiffuseChannel = 0; - if (loc != -1) - { - sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); - } - - if ((sShaderLevel > 0)) // for hardware blending - { - sRenderingSkinned = TRUE; - sVertexProgram->bind(); - } - - gGL.diffuseColor4f(1,1,1,1); - } - else // SHADOW_PASS_ATTACHMENT_OPAQUE - { - sVertexProgram = &gDeferredAttachmentShadowProgram; - S32 loc = sVertexProgram->getUniformLocation(LLViewerShaderMgr::DIFFUSE_MAP); - sDiffuseChannel = 0; - if (loc != -1) - { - sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); - } - sVertexProgram->bind(); + gGL.diffuseColor4f(1, 1, 1, 1); } } void LLDrawPoolAvatar::endShadowPass(S32 pass) { - LL_RECORD_BLOCK_TIME(FTM_SHADOW_AVATAR); - - if (pass == SHADOW_PASS_ATTACHMENT_OPAQUE) - { - LLVertexBuffer::unbind(); - } + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; if (sShaderLevel > 0) { @@ -566,7 +366,7 @@ void LLDrawPoolAvatar::endShadowPass(S32 pass) void LLDrawPoolAvatar::renderShadow(S32 pass) { - LL_RECORD_BLOCK_TIME(FTM_SHADOW_AVATAR); + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; if (mDrawFace.empty()) { @@ -586,9 +386,9 @@ void LLDrawPoolAvatar::renderShadow(S32 pass) } LLVOAvatar::AvatarOverallAppearance oa = avatarp->getOverallAppearance(); BOOL impostor = !LLPipeline::sImpostorRender && avatarp->isImpostor(); - if (impostor || (oa == LLVOAvatar::AOA_INVISIBLE)) + if (impostor || (oa == LLVOAvatar::AOA_INVISIBLE)) { - // No shadows for impostored (including jellydolled) or invisible avs. + // No shadows for impostored (including jellydolled) or invisible avs. return; } @@ -612,79 +412,23 @@ void LLDrawPoolAvatar::renderShadow(S32 pass) avatarp->renderSkinned(); LLDrawPoolAvatar::sSkipOpaque = false; } - else if (pass == SHADOW_PASS_ATTACHMENT_ALPHA_BLEND) // rigged alpha - { - LLDrawPoolAvatar::sSkipOpaque = true; - renderRigged(avatarp, RIGGED_MATERIAL_ALPHA); - renderRigged(avatarp, RIGGED_MATERIAL_ALPHA_EMISSIVE); - renderRigged(avatarp, RIGGED_ALPHA); - renderRigged(avatarp, RIGGED_FULLBRIGHT_ALPHA); - renderRigged(avatarp, RIGGED_GLOW); - renderRigged(avatarp, RIGGED_SPECMAP_BLEND); - renderRigged(avatarp, RIGGED_NORMMAP_BLEND); - renderRigged(avatarp, RIGGED_NORMSPEC_BLEND); - LLDrawPoolAvatar::sSkipOpaque = false; - } - else if (pass == SHADOW_PASS_ATTACHMENT_ALPHA_MASK) // rigged alpha mask - { - LLDrawPoolAvatar::sSkipOpaque = true; - renderRigged(avatarp, RIGGED_MATERIAL_ALPHA_MASK); - renderRigged(avatarp, RIGGED_NORMMAP_MASK); - renderRigged(avatarp, RIGGED_SPECMAP_MASK); - renderRigged(avatarp, RIGGED_NORMSPEC_MASK); - renderRigged(avatarp, RIGGED_GLOW); - LLDrawPoolAvatar::sSkipOpaque = false; - } - else // rigged opaque (SHADOW_PASS_ATTACHMENT_OPAQUE - { - LLDrawPoolAvatar::sSkipTransparent = true; - renderRigged(avatarp, RIGGED_MATERIAL); - renderRigged(avatarp, RIGGED_SPECMAP); - renderRigged(avatarp, RIGGED_SPECMAP_EMISSIVE); - renderRigged(avatarp, RIGGED_NORMMAP); - renderRigged(avatarp, RIGGED_NORMMAP_EMISSIVE); - renderRigged(avatarp, RIGGED_NORMSPEC); - renderRigged(avatarp, RIGGED_NORMSPEC_EMISSIVE); - renderRigged(avatarp, RIGGED_SIMPLE); - renderRigged(avatarp, RIGGED_FULLBRIGHT); - renderRigged(avatarp, RIGGED_SHINY); - renderRigged(avatarp, RIGGED_FULLBRIGHT_SHINY); - renderRigged(avatarp, RIGGED_GLOW); - renderRigged(avatarp, RIGGED_DEFERRED_BUMP); - renderRigged(avatarp, RIGGED_DEFERRED_SIMPLE); - LLDrawPoolAvatar::sSkipTransparent = false; - } } S32 LLDrawPoolAvatar::getNumPasses() { - if (LLPipeline::sImpostorRender) - { - return 8; - } - else - { - return 10; - } + return 3; } S32 LLDrawPoolAvatar::getNumDeferredPasses() { - if (LLPipeline::sImpostorRender) - { - return 19; - } - else - { - return 21; - } + return 3; } void LLDrawPoolAvatar::render(S32 pass) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_CHARACTERS); + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; if (LLPipeline::sImpostorRender) { renderAvatars(NULL, pass+2); @@ -696,7 +440,7 @@ void LLDrawPoolAvatar::render(S32 pass) void LLDrawPoolAvatar::beginRenderPass(S32 pass) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_CHARACTERS); + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; //reset vertex buffer mappings LLVertexBuffer::unbind(); @@ -716,27 +460,6 @@ void LLDrawPoolAvatar::beginRenderPass(S32 pass) case 2: beginSkinned(); break; - case 3: - beginRiggedSimple(); - break; - case 4: - beginRiggedFullbright(); - break; - case 5: - beginRiggedShinySimple(); - break; - case 6: - beginRiggedFullbrightShiny(); - break; - case 7: - beginRiggedAlpha(); - break; - case 8: - beginRiggedFullbrightAlpha(); - break; - case 9: - beginRiggedGlow(); - break; } if (pass == 0) @@ -747,7 +470,7 @@ void LLDrawPoolAvatar::beginRenderPass(S32 pass) void LLDrawPoolAvatar::endRenderPass(S32 pass) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_CHARACTERS); + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; if (LLPipeline::sImpostorRender) { @@ -765,43 +488,21 @@ void LLDrawPoolAvatar::endRenderPass(S32 pass) case 2: endSkinned(); break; - case 3: - endRiggedSimple(); - break; - case 4: - endRiggedFullbright(); - break; - case 5: - endRiggedShinySimple(); - break; - case 6: - endRiggedFullbrightShiny(); - break; - case 7: - endRiggedAlpha(); - break; - case 8: - endRiggedFullbrightAlpha(); - break; - case 9: - endRiggedGlow(); - break; } } void LLDrawPoolAvatar::beginImpostor() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR + if (!LLPipeline::sReflectionRender) { LLVOAvatar::sRenderDistance = llclamp(LLVOAvatar::sRenderDistance, 16.f, 256.f); LLVOAvatar::sNumVisibleAvatars = 0; } - if (LLGLSLShader::sNoFixedFunction) - { gImpostorProgram.bind(); gImpostorProgram.setMinimumAlpha(0.01f); - } gPipeline.enableLightsFullbright(); sDiffuseChannel = 0; @@ -809,16 +510,17 @@ void LLDrawPoolAvatar::beginImpostor() void LLDrawPoolAvatar::endImpostor() { - if (LLGLSLShader::sNoFixedFunction) - { + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR + gImpostorProgram.unbind(); - } gPipeline.enableLightsDynamic(); } void LLDrawPoolAvatar::beginRigid() { - if (gPipeline.canUseVertexShaders()) + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR + + if (gPipeline.shadersLoaded()) { if (LLPipeline::sUnderWaterRender) { @@ -851,6 +553,8 @@ void LLDrawPoolAvatar::beginRigid() void LLDrawPoolAvatar::endRigid() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR + sShaderLevel = mShaderLevel; if (sVertexProgram != NULL) { @@ -860,6 +564,8 @@ void LLDrawPoolAvatar::endRigid() void LLDrawPoolAvatar::beginDeferredImpostor() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR + if (!LLPipeline::sReflectionRender) { LLVOAvatar::sRenderDistance = llclamp(LLVOAvatar::sRenderDistance, 16.f, 256.f); @@ -876,6 +582,8 @@ void LLDrawPoolAvatar::beginDeferredImpostor() void LLDrawPoolAvatar::endDeferredImpostor() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR + sShaderLevel = mShaderLevel; sVertexProgram->disableTexture(LLViewerShaderMgr::DEFERRED_NORMAL); sVertexProgram->disableTexture(LLViewerShaderMgr::SPECULAR_MAP); @@ -887,6 +595,8 @@ void LLDrawPoolAvatar::endDeferredImpostor() void LLDrawPoolAvatar::beginDeferredRigid() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR + sVertexProgram = &gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram; sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); sVertexProgram->bind(); @@ -903,6 +613,8 @@ void LLDrawPoolAvatar::beginDeferredRigid() void LLDrawPoolAvatar::endDeferredRigid() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR + sShaderLevel = mShaderLevel; sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP); sVertexProgram->unbind(); @@ -912,6 +624,8 @@ void LLDrawPoolAvatar::endDeferredRigid() void LLDrawPoolAvatar::beginSkinned() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR + if (sShaderLevel > 0) { if (LLPipeline::sUnderWaterRender) @@ -954,7 +668,7 @@ void LLDrawPoolAvatar::beginSkinned() } else { - if(gPipeline.canUseVertexShaders()) + if(gPipeline.shadersLoaded()) { // software skinning, use a basic shader for windlight. // TODO: find a better fallback method for software skinning. @@ -970,14 +684,13 @@ void LLDrawPoolAvatar::beginSkinned() } } - if (LLGLSLShader::sNoFixedFunction) - { sVertexProgram->setMinimumAlpha(LLDrawPoolAvatar::sMinimumAlpha); - } } void LLDrawPoolAvatar::endSkinned() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR + // if we're in software-blending, remember to set the fence _after_ we draw so we wait till this rendering is done if (sShaderLevel > 0) { @@ -989,7 +702,7 @@ void LLDrawPoolAvatar::endSkinned() } else { - if(gPipeline.canUseVertexShaders()) + if(gPipeline.shadersLoaded()) { // software skinning, use a basic shader for windlight. // TODO: find a better fallback method for software skinning. @@ -1000,1384 +713,207 @@ void LLDrawPoolAvatar::endSkinned() gGL.getTexUnit(0)->activate(); } -void LLDrawPoolAvatar::beginRiggedSimple() +void LLDrawPoolAvatar::beginDeferredSkinned() { - if (sShaderLevel > 0) + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR + + sShaderLevel = mShaderLevel; + sVertexProgram = &gDeferredAvatarProgram; + sRenderingSkinned = TRUE; + + sVertexProgram->bind(); + sVertexProgram->setMinimumAlpha(LLDrawPoolAvatar::sMinimumAlpha); + if (LLPipeline::sRenderingHUDs) { - if (LLPipeline::sUnderWaterRender) - { - sVertexProgram = &gSkinnedObjectSimpleWaterProgram; - } - else - { - sVertexProgram = &gSkinnedObjectSimpleProgram; - } + sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1); } else { - if (LLPipeline::sUnderWaterRender) - { - sVertexProgram = &gObjectSimpleNonIndexedWaterProgram; - } - else - { - sVertexProgram = &gObjectSimpleNonIndexedProgram; - } + sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0); } - if (sShaderLevel > 0 || gPipeline.canUseVertexShaders()) - { - sDiffuseChannel = 0; - sVertexProgram->bind(); - if (LLPipeline::sRenderingHUDs) - { - sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1); - } - else - { - sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0); - } - } + sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); + gGL.getTexUnit(0)->activate(); } -void LLDrawPoolAvatar::endRiggedSimple() +void LLDrawPoolAvatar::endDeferredSkinned() { - LLVertexBuffer::unbind(); - if (sShaderLevel > 0 || gPipeline.canUseVertexShaders()) - { - sVertexProgram->unbind(); - sVertexProgram = NULL; - } -} + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR -void LLDrawPoolAvatar::beginRiggedAlpha() -{ - beginRiggedSimple(); -} + // if we're in software-blending, remember to set the fence _after_ we draw so we wait till this rendering is done + sRenderingSkinned = FALSE; + sVertexProgram->unbind(); -void LLDrawPoolAvatar::endRiggedAlpha() -{ - endRiggedSimple(); -} + sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP); + sShaderLevel = mShaderLevel; -void LLDrawPoolAvatar::beginRiggedFullbrightAlpha() -{ - beginRiggedFullbright(); + gGL.getTexUnit(0)->activate(); } -void LLDrawPoolAvatar::endRiggedFullbrightAlpha() +void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) { - endRiggedFullbright(); -} + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; //LL_RECORD_BLOCK_TIME(FTM_RENDER_CHARACTERS); -void LLDrawPoolAvatar::beginRiggedGlow() -{ - if (sShaderLevel > 0) - { - if (LLPipeline::sUnderWaterRender) - { - sVertexProgram = &gSkinnedObjectEmissiveWaterProgram; - } - else - { - sVertexProgram = &gSkinnedObjectEmissiveProgram; - } - } - else - { - if (LLPipeline::sUnderWaterRender) - { - sVertexProgram = &gObjectEmissiveNonIndexedWaterProgram; - } - else - { - sVertexProgram = &gObjectEmissiveNonIndexedProgram; - } - } - - if (sShaderLevel > 0 || gPipeline.canUseVertexShaders()) - { - sDiffuseChannel = 0; - sVertexProgram->bind(); - - sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, LLPipeline::sRenderDeferred ? 2.2f : 1.1f); - - if (LLPipeline::sRenderingHUDs) - { - sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1); - } - else - { - sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0); - } - } -} - -void LLDrawPoolAvatar::endRiggedGlow() -{ - endRiggedFullbright(); -} - -void LLDrawPoolAvatar::beginRiggedFullbright() -{ - if (sShaderLevel > 0) - { - if (LLPipeline::sUnderWaterRender) - { - sVertexProgram = &gSkinnedObjectFullbrightWaterProgram; - } - else - { - if (LLPipeline::sRenderDeferred) - { - sVertexProgram = &gDeferredSkinnedFullbrightProgram; - } - else - { - sVertexProgram = &gSkinnedObjectFullbrightProgram; - } - } - } - else - { - if (LLPipeline::sUnderWaterRender) - { - sVertexProgram = &gObjectFullbrightNonIndexedWaterProgram; - } - else - { - sVertexProgram = &gObjectFullbrightNonIndexedProgram; - } - } - - if (sShaderLevel > 0 || gPipeline.canUseVertexShaders()) - { - sDiffuseChannel = 0; - sVertexProgram->bind(); - - if (LLPipeline::sRenderingHUDs) - { - sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f); - sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1); - } - else if (LLPipeline::sRenderDeferred) - { - sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f); - sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0); - } - else - { - sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f); - sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0); - } - } -} - -void LLDrawPoolAvatar::endRiggedFullbright() -{ - LLVertexBuffer::unbind(); - if (sShaderLevel > 0 || gPipeline.canUseVertexShaders()) - { - sVertexProgram->unbind(); - sVertexProgram = NULL; - } -} - -void LLDrawPoolAvatar::beginRiggedShinySimple() -{ - if (sShaderLevel > 0) - { - if (LLPipeline::sUnderWaterRender) - { - sVertexProgram = &gSkinnedObjectShinySimpleWaterProgram; - } - else - { - sVertexProgram = &gSkinnedObjectShinySimpleProgram; - } - } - else - { - if (LLPipeline::sUnderWaterRender) - { - sVertexProgram = &gObjectShinyNonIndexedWaterProgram; - } - else - { - sVertexProgram = &gObjectShinyNonIndexedProgram; - } - } - - if (sShaderLevel > 0 || gPipeline.canUseVertexShaders()) - { - sVertexProgram->bind(); - if (LLPipeline::sRenderingHUDs) - { - sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1); - } - else - { - sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0); - } - LLDrawPoolBump::bindCubeMap(sVertexProgram, 2, sDiffuseChannel, cube_channel, false); - } -} - -void LLDrawPoolAvatar::endRiggedShinySimple() -{ - LLVertexBuffer::unbind(); - if (sShaderLevel > 0 || gPipeline.canUseVertexShaders()) - { - LLDrawPoolBump::unbindCubeMap(sVertexProgram, 2, sDiffuseChannel, cube_channel, false); - sVertexProgram->unbind(); - sVertexProgram = NULL; - } -} - -void LLDrawPoolAvatar::beginRiggedFullbrightShiny() -{ - if (sShaderLevel > 0) - { - if (LLPipeline::sUnderWaterRender) - { - sVertexProgram = &gSkinnedObjectFullbrightShinyWaterProgram; - } - else - { - if (LLPipeline::sRenderDeferred) - { - sVertexProgram = &gDeferredSkinnedFullbrightShinyProgram; - } - else - { - sVertexProgram = &gSkinnedObjectFullbrightShinyProgram; - } - } - } - else - { - if (LLPipeline::sUnderWaterRender) - { - sVertexProgram = &gObjectFullbrightShinyNonIndexedWaterProgram; - } - else - { - sVertexProgram = &gObjectFullbrightShinyNonIndexedProgram; - } - } - - if (sShaderLevel > 0 || gPipeline.canUseVertexShaders()) - { - sVertexProgram->bind(); - if (LLPipeline::sRenderingHUDs) - { - sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1); - } - else - { - sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0); - } - LLDrawPoolBump::bindCubeMap(sVertexProgram, 2, sDiffuseChannel, cube_channel, false); - - if (LLPipeline::sRenderingHUDs) - { - sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f); - sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1); - } - else if (LLPipeline::sRenderDeferred) - { - sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f); - sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0); - } - else - { - sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f); - sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0); - } - } -} - -void LLDrawPoolAvatar::endRiggedFullbrightShiny() -{ - LLVertexBuffer::unbind(); - if (sShaderLevel > 0 || gPipeline.canUseVertexShaders()) - { - LLDrawPoolBump::unbindCubeMap(sVertexProgram, 2, sDiffuseChannel, cube_channel, false); - sVertexProgram->unbind(); - sVertexProgram = NULL; - } -} - - -void LLDrawPoolAvatar::beginDeferredRiggedSimple() -{ - sVertexProgram = &gDeferredSkinnedDiffuseProgram; - sDiffuseChannel = 0; - sVertexProgram->bind(); - if (LLPipeline::sRenderingHUDs) - { - sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1); - } - else - { - sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0); - } -} - -void LLDrawPoolAvatar::endDeferredRiggedSimple() -{ - LLVertexBuffer::unbind(); - sVertexProgram->unbind(); - sVertexProgram = NULL; -} - -void LLDrawPoolAvatar::beginDeferredRiggedBump() -{ - sVertexProgram = &gDeferredSkinnedBumpProgram; - sVertexProgram->bind(); - if (LLPipeline::sRenderingHUDs) - { - sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1); - } - else - { - sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0); - } - normal_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::BUMP_MAP); - sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); -} - -void LLDrawPoolAvatar::endDeferredRiggedBump() -{ - LLVertexBuffer::unbind(); - sVertexProgram->disableTexture(LLViewerShaderMgr::BUMP_MAP); - sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP); - sVertexProgram->unbind(); - normal_channel = -1; - sDiffuseChannel = 0; - sVertexProgram = NULL; -} - -void LLDrawPoolAvatar::beginDeferredRiggedMaterial(S32 pass) -{ - if (pass == 1 || - pass == 5 || - pass == 9 || - pass == 13) - { //skip alpha passes - return; - } - sVertexProgram = &gDeferredMaterialProgram[pass+LLMaterial::SHADER_COUNT]; - - if (LLPipeline::sUnderWaterRender) - { - sVertexProgram = &(gDeferredMaterialWaterProgram[pass+LLMaterial::SHADER_COUNT]); - } - - sVertexProgram->bind(); - if (LLPipeline::sRenderingHUDs) - { - sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1); - } - else - { - sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0); - } - normal_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::BUMP_MAP); - specular_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::SPECULAR_MAP); - sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); -} - -void LLDrawPoolAvatar::endDeferredRiggedMaterial(S32 pass) -{ - if (pass == 1 || - pass == 5 || - pass == 9 || - pass == 13) - { - return; - } - - LLVertexBuffer::unbind(); - sVertexProgram->disableTexture(LLViewerShaderMgr::BUMP_MAP); - sVertexProgram->disableTexture(LLViewerShaderMgr::SPECULAR_MAP); - sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP); - sVertexProgram->unbind(); - normal_channel = -1; - sDiffuseChannel = 0; - sVertexProgram = NULL; -} - -void LLDrawPoolAvatar::beginDeferredSkinned() -{ - sShaderLevel = mShaderLevel; - sVertexProgram = &gDeferredAvatarProgram; - sRenderingSkinned = TRUE; - - sVertexProgram->bind(); - sVertexProgram->setMinimumAlpha(LLDrawPoolAvatar::sMinimumAlpha); - if (LLPipeline::sRenderingHUDs) - { - sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1); - } - else - { - sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0); - } - - sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); - gGL.getTexUnit(0)->activate(); -} - -void LLDrawPoolAvatar::endDeferredSkinned() -{ - // if we're in software-blending, remember to set the fence _after_ we draw so we wait till this rendering is done - sRenderingSkinned = FALSE; - sVertexProgram->unbind(); - - sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP); - - sShaderLevel = mShaderLevel; - - gGL.getTexUnit(0)->activate(); -} - -static LLTrace::BlockTimerStatHandle FTM_RENDER_AVATARS("renderAvatars"); - - -void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) -{ - LL_RECORD_BLOCK_TIME(FTM_RENDER_AVATARS); - - if (pass == -1) + if (pass == -1) { for (S32 i = 1; i < getNumPasses(); i++) { //skip foot shadows prerender(); beginRenderPass(i); - renderAvatars(single_avatar, i); - endRenderPass(i); - } - - return; - } - - if (mDrawFace.empty() && !single_avatar) - { - return; - } - - LLVOAvatar *avatarp = NULL; - - if (single_avatar) - { - avatarp = single_avatar; - } - else - { - const LLFace *facep = mDrawFace[0]; - if (!facep->getDrawable()) - { - return; - } - avatarp = (LLVOAvatar *)facep->getDrawable()->getVObj().get(); - } - - if (avatarp->isDead() || avatarp->mDrawable.isNull()) - { - return; - } - - if (!single_avatar && !avatarp->isFullyLoaded() ) - { - if (pass==0 && (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES) || LLViewerPartSim::getMaxPartCount() <= 0)) - { - // debug code to draw a sphere in place of avatar - gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep); - gGL.setColorMask(true, true); - LLVector3 pos = avatarp->getPositionAgent(); - gGL.color4f(1.0f, 1.0f, 1.0f, 0.7f); - - gGL.pushMatrix(); - gGL.translatef((F32)(pos.mV[VX]), - (F32)(pos.mV[VY]), - (F32)(pos.mV[VZ])); - gGL.scalef(0.15f, 0.15f, 0.3f); - - gSphere.renderGGL(); - - gGL.popMatrix(); - gGL.setColorMask(true, false); - } - // don't render please - return; - } - - BOOL impostor = !LLPipeline::sImpostorRender && avatarp->isImpostor() && !single_avatar; - - if (( avatarp->isInMuteList() - || impostor - || (LLVOAvatar::AOA_NORMAL != avatarp->getOverallAppearance() && !avatarp->needsImpostorUpdate()) ) && pass != 0) -// || (LLVOAvatar::AV_DO_NOT_RENDER == avatarp->getVisualMuteSettings() && !avatarp->needsImpostorUpdate()) ) && pass != 0) - { //don't draw anything but the impostor for impostored avatars - return; - } - - if (pass == 0 && !impostor && LLPipeline::sUnderWaterRender) - { //don't draw foot shadows under water - return; - } - - LLVOAvatar *attached_av = avatarp->getAttachedAvatar(); - if (attached_av && (LLVOAvatar::AOA_NORMAL != attached_av->getOverallAppearance() || !gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_AVATAR))) - { - // Animesh attachment of a jellydolled or invisible parent - don't show - return; - } - - if (pass == 0) - { - if (!LLPipeline::sReflectionRender) - { - LLVOAvatar::sNumVisibleAvatars++; - } - -// if (impostor || (LLVOAvatar::AV_DO_NOT_RENDER == avatarp->getVisualMuteSettings() && !avatarp->needsImpostorUpdate())) - if (impostor || (LLVOAvatar::AOA_NORMAL != avatarp->getOverallAppearance() && !avatarp->needsImpostorUpdate())) - { - if (LLPipeline::sRenderDeferred && !LLPipeline::sReflectionRender && avatarp->mImpostor.isComplete()) - { - if (normal_channel > -1) - { - avatarp->mImpostor.bindTexture(2, normal_channel); - } - if (specular_channel > -1) - { - avatarp->mImpostor.bindTexture(1, specular_channel); - } - } - avatarp->renderImpostor(avatarp->getMutedAVColor(), sDiffuseChannel); - } - return; - } - - if (pass == 1) - { - // render rigid meshes (eyeballs) first - avatarp->renderRigid(); - return; - } - - if (pass == 3) - { - if (is_deferred_render) - { - renderDeferredRiggedSimple(avatarp); - } - else - { - renderRiggedSimple(avatarp); - - if (LLPipeline::sRenderDeferred) - { //render "simple" materials - renderRigged(avatarp, RIGGED_MATERIAL); - renderRigged(avatarp, RIGGED_MATERIAL_ALPHA_MASK); - renderRigged(avatarp, RIGGED_MATERIAL_ALPHA_EMISSIVE); - renderRigged(avatarp, RIGGED_NORMMAP); - renderRigged(avatarp, RIGGED_NORMMAP_MASK); - renderRigged(avatarp, RIGGED_NORMMAP_EMISSIVE); - renderRigged(avatarp, RIGGED_SPECMAP); - renderRigged(avatarp, RIGGED_SPECMAP_MASK); - renderRigged(avatarp, RIGGED_SPECMAP_EMISSIVE); - renderRigged(avatarp, RIGGED_NORMSPEC); - renderRigged(avatarp, RIGGED_NORMSPEC_MASK); - renderRigged(avatarp, RIGGED_NORMSPEC_EMISSIVE); - } - } - return; - } - - if (pass == 4) - { - if (is_deferred_render) - { - renderDeferredRiggedBump(avatarp); - } - else - { - renderRiggedFullbright(avatarp); - } - - return; - } - - if (is_deferred_render && pass >= 5 && pass <= 21) - { - S32 p = pass-5; - - if (p != 1 && - p != 5 && - p != 9 && - p != 13) - { - renderDeferredRiggedMaterial(avatarp, p); - } - return; - } - - - - - if (pass == 5) - { - renderRiggedShinySimple(avatarp); - - return; - } - - if (pass == 6) - { - renderRiggedFullbrightShiny(avatarp); - return; - } - - if (pass >= 7 && pass < 13) - { - if (pass == 7) - { - renderRiggedAlpha(avatarp); - - if (LLPipeline::sRenderDeferred && !is_post_deferred_render) - { //render transparent materials under water - LLGLEnable blend(GL_BLEND); - - gGL.setColorMask(true, true); - gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, - LLRender::BF_ONE_MINUS_SOURCE_ALPHA, - LLRender::BF_ZERO, - LLRender::BF_ONE_MINUS_SOURCE_ALPHA); - - renderRigged(avatarp, RIGGED_MATERIAL_ALPHA); - renderRigged(avatarp, RIGGED_SPECMAP_BLEND); - renderRigged(avatarp, RIGGED_NORMMAP_BLEND); - renderRigged(avatarp, RIGGED_NORMSPEC_BLEND); - - gGL.setSceneBlendType(LLRender::BT_ALPHA); - gGL.setColorMask(true, false); - } - return; - } - - if (pass == 8) - { - renderRiggedFullbrightAlpha(avatarp); - return; - } - - if (LLPipeline::sRenderDeferred && is_post_deferred_render) - { - S32 p = 0; - switch (pass) - { - case 9: p = 1; break; - case 10: p = 5; break; - case 11: p = 9; break; - case 12: p = 13; break; - } - - { - LLGLEnable blend(GL_BLEND); - renderDeferredRiggedMaterial(avatarp, p); - } - return; - } - else if (pass == 9) - { - renderRiggedGlow(avatarp); - return; - } - } - - if (pass == 13) - { - renderRiggedGlow(avatarp); - - return; - } - - if ((sShaderLevel >= SHADER_LEVEL_CLOTH)) - { - LLMatrix4 rot_mat; - LLViewerCamera::getInstanceFast()->getMatrixToLocal(rot_mat); - LLMatrix4 cfr(OGL_TO_CFR_ROTATION); - rot_mat *= cfr; - - LLVector4 wind; - wind.setVec(avatarp->mWindVec); - wind.mV[VW] = 0; - wind = wind * rot_mat; - wind.mV[VW] = avatarp->mWindVec.mV[VW]; - - sVertexProgram->uniform4fv(LLViewerShaderMgr::AVATAR_WIND, 1, wind.mV); - F32 phase = -1.f * (avatarp->mRipplePhase); - - F32 freq = 7.f + (noise1(avatarp->mRipplePhase) * 2.f); - LLVector4 sin_params(freq, freq, freq, phase); - sVertexProgram->uniform4fv(LLViewerShaderMgr::AVATAR_SINWAVE, 1, sin_params.mV); - - LLVector4 gravity(0.f, 0.f, -CLOTHING_GRAVITY_EFFECT, 0.f); - gravity = gravity * rot_mat; - sVertexProgram->uniform4fv(LLViewerShaderMgr::AVATAR_GRAVITY, 1, gravity.mV); - } - - if( !single_avatar || (avatarp == single_avatar) ) - { - avatarp->renderSkinned(); - } -} - -void LLDrawPoolAvatar::getRiggedGeometry( - LLFace* face, - LLPointer<LLVertexBuffer>& buffer, - U32 data_mask, - const LLMeshSkinInfo* skin, - LLVolume* volume, - const LLVolumeFace& vol_face) -{ - face->setGeomIndex(0); - face->setIndicesIndex(0); - - if (face->getTextureIndex() != FACE_DO_NOT_BATCH_TEXTURES) - { - face->setDrawInfo(NULL); - } - - //rigged faces do not batch textures - face->setTextureIndex(FACE_DO_NOT_BATCH_TEXTURES); - - if (buffer.isNull() || buffer->getTypeMask() != data_mask || !buffer->isWriteable()) - { - // make a new buffer - if (sShaderLevel > 0) - { - buffer = new LLVertexBuffer(data_mask, GL_DYNAMIC_DRAW); - } - else - { - buffer = new LLVertexBuffer(data_mask, GL_STREAM_DRAW); - } - - if (!buffer->allocateBuffer(vol_face.mNumVertices, vol_face.mNumIndices, true)) - { - LL_WARNS("LLDrawPoolAvatar") << "Failed to allocate Vertex Buffer to " - << vol_face.mNumVertices << " vertices and " - << vol_face.mNumIndices << " indices" << LL_ENDL; - // allocate dummy triangle - buffer->allocateBuffer(1, 3, true); - memset((U8*)buffer->getMappedData(), 0, buffer->getSize()); - memset((U8*)buffer->getMappedIndices(), 0, buffer->getIndicesSize()); - } - } - else - { - //resize existing buffer - if(!buffer->resizeBuffer(vol_face.mNumVertices, vol_face.mNumIndices)) - { - LL_WARNS("LLDrawPoolAvatar") << "Failed to resize Vertex Buffer to " - << vol_face.mNumVertices << " vertices and " - << vol_face.mNumIndices << " indices" << LL_ENDL; - // allocate dummy triangle - buffer->resizeBuffer(1, 3); - memset((U8*)buffer->getMappedData(), 0, buffer->getSize()); - memset((U8*)buffer->getMappedIndices(), 0, buffer->getIndicesSize()); - } - } - - face->setSize(buffer->getNumVerts(), buffer->getNumIndices()); - face->setVertexBuffer(buffer); - - U16 offset = 0; - - //let getGeometryVolume know if alpha should override shiny - U32 type = gPipeline.getPoolTypeFromTE(face->getTextureEntry(), face->getTexture()); - - if (type == LLDrawPool::POOL_ALPHA) - { - face->setPoolType(LLDrawPool::POOL_ALPHA); - } - else - { - face->setPoolType(mType); // either POOL_AVATAR or POOL_CONTROL_AV - } - - //LL_INFOS() << "Rebuilt face " << face->getTEOffset() << " of " << face->getDrawable() << " at " << gFrameTimeSeconds << LL_ENDL; - - // Let getGeometryVolume know if a texture matrix is in play - if (face->mTextureMatrix) - { - face->setState(LLFace::TEXTURE_ANIM); - } - else - { - face->clearState(LLFace::TEXTURE_ANIM); - } - - const LLMatrix4a& mat_vert = skin->mBindShapeMatrix; - LLMatrix4a mat_normal = skin->mBindShapeMatrix; - mat_normal.invert(); - mat_normal.transpose(); - - face->getGeometryVolume(*volume, face->getTEOffset(), mat_vert, mat_normal, offset, true); - - buffer->flush(); -} + renderAvatars(single_avatar, i); + endRenderPass(i); + } -void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( - LLVOAvatar* avatar, - LLFace* face, - const LLMeshSkinInfo* skin, - LLVolume* volume, - LLVolumeFace& vol_face) -{ - LLVector4a* weights = vol_face.mWeights; - if (!weights) - { return; } - LLPointer<LLVertexBuffer> buffer = face->getVertexBuffer(); - LLDrawable* drawable = face->getDrawable(); - - LLVOVolume* vobj = drawable->getVOVolume(); - if (vobj && vobj->isNoLOD()) + if (mDrawFace.empty() && !single_avatar) { return; } - // FIXME ugly const cast - LLSkinningUtil::scrubInvalidJoints(avatar, const_cast<LLMeshSkinInfo*>(skin)); - - U32 data_mask = face->getRiggedVertexBufferDataMask(); + LLVOAvatar *avatarp = NULL; - if (!vol_face.mWeightsScrubbed) - { - LLSkinningUtil::scrubSkinWeights(weights, vol_face.mNumVertices, skin); - vol_face.mWeightsScrubbed = TRUE; - } - - if (buffer.isNull() || - buffer->getTypeMask() != data_mask || - buffer->getNumVerts() != vol_face.mNumVertices || - buffer->getNumIndices() != vol_face.mNumIndices || - (drawable && drawable->isState(LLDrawable::REBUILD_ALL))) + if (single_avatar) { - if (drawable && drawable->isState(LLDrawable::REBUILD_ALL)) - { - //rebuild EVERY face in the drawable, not just this one, to avoid missing drawable wide rebuild issues - for (S32 i = 0, i_end = drawable->getNumFaces(); i < i_end; ++i) - { - LLFace* facep = drawable->getFace(i); - U32 face_data_mask = facep->getRiggedVertexBufferDataMask(); - if (face_data_mask) - { - LLPointer<LLVertexBuffer> cur_buffer = facep->getVertexBuffer(); - const LLVolumeFace& cur_vol_face = volume->getVolumeFace(i); - getRiggedGeometry(facep, cur_buffer, face_data_mask, skin, volume, cur_vol_face); - } - } - drawable->clearState(LLDrawable::REBUILD_ALL); - - buffer = face->getVertexBuffer(); - } - else + avatarp = single_avatar; + } + else + { + const LLFace *facep = mDrawFace[0]; + if (!facep->getDrawable()) { - //just rebuild this face - getRiggedGeometry(face, buffer, data_mask, skin, volume, vol_face); + return; } + avatarp = (LLVOAvatar *)facep->getDrawable()->getVObj().get(); } - if (buffer.isNull() || - buffer->getNumVerts() != vol_face.mNumVertices || - buffer->getNumIndices() != vol_face.mNumIndices) + if (avatarp->isDead() || avatarp->mDrawable.isNull()) { - // Allocation failed return; } - if (!buffer.isNull() && - sShaderLevel <= 0 && - face->mLastSkinTime < avatar->getLastSkinTime()) + if (!single_avatar && !avatarp->isFullyLoaded() ) { - //perform software vertex skinning for this face - LLStrider<LLVector3> position; - LLStrider<LLVector3> normal; - - bool has_normal = buffer->hasDataType(LLVertexBuffer::TYPE_NORMAL); - buffer->getVertexStrider(position); - - if (has_normal) + if (pass==0 && (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES) || LLViewerPartSim::getMaxPartCount() <= 0)) { - buffer->getNormalStrider(normal); - } - - LLVector4a* pos = (LLVector4a*) position.get(); - - LLVector4a* norm = has_normal ? (LLVector4a*) normal.get() : NULL; - - //build matrix palette -// LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT]; -// U32 count = LLSkinningUtil::getMeshJointCount(skin); -// LLSkinningUtil::initSkinningMatrixPalette(mat, count, skin, avatar); - - U32 count = 0; - auto mat_pair = vobj->getCachedSkinRenderMatrix(count, avatar, skin); - if (!mat_pair.has_value()) - return; - - LLMatrix4a* mat = mat_pair.value().first; + // debug code to draw a sphere in place of avatar + gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep); + gGL.setColorMask(true, true); + LLVector3 pos = avatarp->getPositionAgent(); + gGL.color4f(1.0f, 1.0f, 1.0f, 0.7f); + + gGL.pushMatrix(); + gGL.translatef((F32)(pos.mV[VX]), + (F32)(pos.mV[VY]), + (F32)(pos.mV[VZ])); + gGL.scalef(0.15f, 0.15f, 0.3f); - LLSkinningUtil::checkSkinWeights(weights, buffer->getNumVerts(), skin); + gSphere.renderGGL(); + + gGL.popMatrix(); + gGL.setColorMask(true, false); + } + // don't render please + return; + } - LLMatrix4a bind_shape_matrix = skin->mBindShapeMatrix; + BOOL impostor = !LLPipeline::sImpostorRender && avatarp->isImpostor() && !single_avatar; - { - for (S32 j = 0, j_end = buffer->getNumVerts(); j < j_end; ++j) - { - LLMatrix4a final_mat; - LLSkinningUtil::getPerVertexSkinMatrixUnchecked(weights[j], mat, final_mat); - - LLVector4a& v = vol_face.mPositions[j]; - LLVector4a t; - LLVector4a dst; - bind_shape_matrix.affineTransform(v, t); - final_mat.affineTransform(t, dst); - pos[j] = dst; - - if (norm) - { - LLVector4a& n = vol_face.mNormals[j]; - bind_shape_matrix.rotate(n, t); - final_mat.rotate(t, dst); - //dst.normalize3fast(); - norm[j] = dst; - } - } - } + if (( avatarp->isInMuteList() + || impostor + || (LLVOAvatar::AOA_NORMAL != avatarp->getOverallAppearance() && !avatarp->needsImpostorUpdate()) ) && pass != 0) +// || (LLVOAvatar::AV_DO_NOT_RENDER == avatarp->getVisualMuteSettings() && !avatarp->needsImpostorUpdate()) ) && pass != 0) + { //don't draw anything but the impostor for impostored avatars + return; + } + + if (pass == 0 && !impostor && LLPipeline::sUnderWaterRender) + { //don't draw foot shadows under water + return; } -} -void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) -{ - if (!avatar->shouldRenderRigged()) + LLVOAvatar *attached_av = avatarp->getAttachedAvatar(); + if (attached_av && (LLVOAvatar::AOA_NORMAL != attached_av->getOverallAppearance() || !gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_AVATAR))) { + // Animesh attachment of a jellydolled or invisible parent - don't show return; } - stop_glerror(); - - const U32 data_mask_type = LLFace::getRiggedDataMask(type); - - for (LLFace* face : mRiggedFace[type]) + if (pass == 0) { - const S32 offset = face->getIndicesStart(); - const U32 count = face->getIndicesCount(); - - const U16 start = face->getGeomStart(); - const U16 end = start + face->getGeomCount()-1; - - LLDrawable* drawable = face->getDrawable(); - if (!drawable) - { - continue; - } - - LLVOVolume* vobj = drawable->getVObj()->asVolume(); - if (!vobj) + if (!LLPipeline::sReflectionRender) { - continue; + LLVOAvatar::sNumVisibleAvatars++; } - const LLMeshSkinInfo* skin = vobj->getSkinInfo(); - if (!skin) +// if (impostor || (LLVOAvatar::AV_DO_NOT_RENDER == avatarp->getVisualMuteSettings() && !avatarp->needsImpostorUpdate())) + if (impostor || (LLVOAvatar::AOA_NORMAL != avatarp->getOverallAppearance() && !avatarp->needsImpostorUpdate())) { - continue; - } - - U32 data_mask = data_mask_type; - - const LLTextureEntry* tex_entry = face->getTextureEntry(); - - //stop_glerror(); - - //const LLVolumeFace& vol_face = volume->getVolumeFace(te); - //updateRiggedFaceVertexBuffer(avatar, face, skin, volume, vol_face); - - //stop_glerror(); - - LLVertexBuffer* buff = face->getVertexBuffer(); - - LLMaterial* mat = tex_entry ? tex_entry->getMaterialParams().get() : nullptr; - - if (LLDrawPoolAvatar::sShadowPass >= 0) - { - bool is_alpha_blend = false; - bool is_alpha_mask = false; - - LLViewerTexture* tex = face->getTexture(LLRender::DIFFUSE_MAP); - if (tex) - { - if (tex->getIsAlphaMask(-1.f, -1.f)) - { - is_alpha_mask = true; - } - } - - if (tex) - { - LLGLenum image_format = tex->getPrimaryFormat(); - if (!is_alpha_mask && (image_format == GL_RGBA || image_format == GL_ALPHA)) - { - is_alpha_blend = true; - } - } - - if (tex_entry) - { - if (tex_entry->getAlpha() <= 0.99f) - { - is_alpha_blend = true; - } - } - - if (mat) - { - switch (LLMaterial::eDiffuseAlphaMode(mat->getDiffuseAlphaMode())) - { - case LLMaterial::DIFFUSE_ALPHA_MODE_MASK: - { - is_alpha_mask = true; - is_alpha_blend = false; - } - break; - - case LLMaterial::DIFFUSE_ALPHA_MODE_BLEND: - { - is_alpha_blend = true; - is_alpha_mask = false; - } - break; - - case LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE: - case LLMaterial::DIFFUSE_ALPHA_MODE_DEFAULT: - case LLMaterial::DIFFUSE_ALPHA_MODE_NONE: - default: - is_alpha_blend = false; - is_alpha_mask = false; - break; - } - } - - // if this is alpha mask content and we're doing opaques or a non-alpha-mask shadow pass... - if (is_alpha_mask && (LLDrawPoolAvatar::sSkipTransparent || LLDrawPoolAvatar::sShadowPass != SHADOW_PASS_ATTACHMENT_ALPHA_MASK)) - { - continue; - } - - // if this is alpha blend content and we're doing opaques or a non-alpha-blend shadow pass... - if (is_alpha_blend && (LLDrawPoolAvatar::sSkipTransparent || LLDrawPoolAvatar::sShadowPass != SHADOW_PASS_ATTACHMENT_ALPHA_BLEND)) - { - continue; - } - - // if this is opaque content and we're skipping opaques... - if (!is_alpha_mask && !is_alpha_blend && LLDrawPoolAvatar::sSkipOpaque) - { - continue; - } - } - - if (buff) - { - if (sShaderLevel > 0) - { - U32 count = 0; - auto mat_pair = vobj->getCachedSkinRenderMatrix(count, avatar, skin); - if (!mat_pair.has_value()) - continue; - - F32* mp = mat_pair.value().second; - - LLDrawPoolAvatar::sVertexProgram->uniformMatrix3x4fv(LLViewerShaderMgr::AVATAR_MATRIX, - count, - FALSE, - (GLfloat*)mp); - - stop_glerror(); - } - else - { - data_mask &= ~LLVertexBuffer::MAP_WEIGHT4; - } - - /*if (glow) - { - gGL.diffuseColor4f(0,0,0,face->getTextureEntry()->getGlow()); - }*/ - - if (mat) + if (LLPipeline::sRenderDeferred && !LLPipeline::sReflectionRender && avatarp->mImpostor.isComplete()) { - //order is important here LLRender::DIFFUSE_MAP should be last, becouse it change - //(gGL).mCurrTextureUnitIndex - LLViewerTexture* specular = NULL; - if (LLPipeline::sImpostorRender) - { - specular = LLViewerTextureManager::findFetchedTexture(gBlackSquareID, TEX_LIST_STANDARD); - llassert(NULL != specular); - } - else - { - specular = face->getTexture(LLRender::SPECULAR_MAP); - } - if (specular && specular_channel > -1) - { - gGL.getTexUnit(specular_channel)->bind(specular); - } - if (normal_channel > -1) { - gGL.getTexUnit(normal_channel)->bind(face->getTexture(LLRender::NORMAL_MAP)); - } - gGL.getTexUnit(sDiffuseChannel)->bind(face->getTexture(LLRender::DIFFUSE_MAP), false, true); - - LLColor4 col; - F32 spec; - F32 env; - if (mat->getSpecularID().isNull()) - { - env = tex_entry->getShiny()*0.25f; - col.set(env,env,env,0); - spec = env; - } - else - { - col = mat->getSpecularLightColor(); - spec = mat->getSpecularLightExponent() / 255.f; - env = mat->getEnvironmentIntensity() / 255.f; - } - - BOOL fullbright = tex_entry->getFullbright(); - - sVertexProgram->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, fullbright ? 1.f : 0.f); - sVertexProgram->uniform4f(LLShaderMgr::SPECULAR_COLOR, col.mV[0], col.mV[1], col.mV[2], spec); - sVertexProgram->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, env); - - if (mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) - { - F32 cutoff = mat->getAlphaMaskCutoff()/255.f; - sVertexProgram->setMinimumAlpha(cutoff); - } - else - { - sVertexProgram->setMinimumAlpha(0.f); - } - - for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i) - { - LLViewerTexture* tex = face->getTexture(i); - if (tex) - { - tex->addTextureStats(avatar->getPixelArea()); - } + avatarp->mImpostor.bindTexture(2, normal_channel); } - } - else - { - gGL.getTexUnit(sDiffuseChannel)->bind(face->getTexture()); - sVertexProgram->setMinimumAlpha(0.f); - if (normal_channel > -1) + if (specular_channel > -1) { - LLDrawPoolBump::bindBumpMap(face, normal_channel); + avatarp->mImpostor.bindTexture(1, specular_channel); } } - - if (face->mTextureMatrix && vobj->mTexAnimMode) - { - U32 tex_index = gGL.getCurrentTexUnitIndex(); - - if (tex_index <= 1) - { - gGL.matrixMode(LLRender::eMatrixMode(LLRender::MM_TEXTURE0 + tex_index)); - gGL.pushMatrix(); - gGL.loadMatrix(*face->mTextureMatrix); - } - - buff->setBuffer(data_mask); - buff->drawRange(LLRender::TRIANGLES, start, end, count, offset); - - if (tex_index <= 1) - { - gGL.matrixMode(LLRender::eMatrixMode(LLRender::MM_TEXTURE0 + tex_index)); - gGL.popMatrix(); - gGL.matrixMode(LLRender::MM_MODELVIEW); - } - } - else - { - buff->setBuffer(data_mask); - buff->drawRange(LLRender::TRIANGLES, start, end, count, offset); - } + avatarp->renderImpostor(avatarp->getMutedAVColor(), sDiffuseChannel); } + return; } -} - -void LLDrawPoolAvatar::renderDeferredRiggedSimple(LLVOAvatar* avatar) -{ - renderRigged(avatar, RIGGED_DEFERRED_SIMPLE); -} - -void LLDrawPoolAvatar::renderDeferredRiggedBump(LLVOAvatar* avatar) -{ - renderRigged(avatar, RIGGED_DEFERRED_BUMP); -} - -void LLDrawPoolAvatar::renderDeferredRiggedMaterial(LLVOAvatar* avatar, S32 pass) -{ - renderRigged(avatar, pass); -} - -static LLTrace::BlockTimerStatHandle FTM_RIGGED_VBO("Rigged VBO"); - -void LLDrawPoolAvatar::updateRiggedVertexBuffers(LLVOAvatar* avatar) -{ - LL_RECORD_BLOCK_TIME(FTM_RIGGED_VBO); - //update rigged vertex buffers - for (U32 type = 0; type < NUM_RIGGED_PASSES; ++type) + if (pass == 1) { - for (LLFace* face : mRiggedFace[type]) - { - LLDrawable* drawable = face->getDrawable(); - if (!drawable) - { - continue; - } - - LLVOVolume* vobj = drawable->getVOVolume(); - - if (!vobj || vobj->isNoLOD()) - { - continue; - } - - LLVolume* volume = vobj->getVolume(); - S32 te = face->getTEOffset(); - - if (!volume || volume->getNumVolumeFaces() <= te) - { - continue; - } - - const LLMeshSkinInfo* skin = vobj->getSkinInfo(); - if (!skin) - { - continue; - } - - stop_glerror(); - - LLVolumeFace& vol_face = volume->getVolumeFace(te); - updateRiggedFaceVertexBuffer(avatar, face, skin, volume, vol_face); - } + // render rigid meshes (eyeballs) first + avatarp->renderRigid(); + return; } -} - -void LLDrawPoolAvatar::renderRiggedSimple(LLVOAvatar* avatar) -{ - renderRigged(avatar, RIGGED_SIMPLE); -} - -void LLDrawPoolAvatar::renderRiggedFullbright(LLVOAvatar* avatar) -{ - renderRigged(avatar, RIGGED_FULLBRIGHT); -} - - -void LLDrawPoolAvatar::renderRiggedShinySimple(LLVOAvatar* avatar) -{ - renderRigged(avatar, RIGGED_SHINY); -} -void LLDrawPoolAvatar::renderRiggedFullbrightShiny(LLVOAvatar* avatar) -{ - renderRigged(avatar, RIGGED_FULLBRIGHT_SHINY); -} - -void LLDrawPoolAvatar::renderRiggedAlpha(LLVOAvatar* avatar) -{ - if (!mRiggedFace[RIGGED_ALPHA].empty()) + if ((sShaderLevel >= SHADER_LEVEL_CLOTH)) { - LLGLEnable blend(GL_BLEND); - - gGL.setColorMask(true, true); - gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, - LLRender::BF_ONE_MINUS_SOURCE_ALPHA, - LLRender::BF_ZERO, - LLRender::BF_ONE_MINUS_SOURCE_ALPHA); - - renderRigged(avatar, RIGGED_ALPHA); - gGL.setSceneBlendType(LLRender::BT_ALPHA); - gGL.setColorMask(true, false); - } -} + LLMatrix4 rot_mat; + LLViewerCamera::getInstance()->getMatrixToLocal(rot_mat); + LLMatrix4 cfr(OGL_TO_CFR_ROTATION); + rot_mat *= cfr; + + LLVector4 wind; + wind.setVec(avatarp->mWindVec); + wind.mV[VW] = 0; + wind = wind * rot_mat; + wind.mV[VW] = avatarp->mWindVec.mV[VW]; -void LLDrawPoolAvatar::renderRiggedFullbrightAlpha(LLVOAvatar* avatar) -{ - if (!mRiggedFace[RIGGED_FULLBRIGHT_ALPHA].empty()) - { - LLGLEnable blend(GL_BLEND); + sVertexProgram->uniform4fv(LLViewerShaderMgr::AVATAR_WIND, 1, wind.mV); + F32 phase = -1.f * (avatarp->mRipplePhase); - gGL.setColorMask(true, true); - gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, - LLRender::BF_ONE_MINUS_SOURCE_ALPHA, - LLRender::BF_ZERO, - LLRender::BF_ONE_MINUS_SOURCE_ALPHA); + F32 freq = 7.f + (noise1(avatarp->mRipplePhase) * 2.f); + LLVector4 sin_params(freq, freq, freq, phase); + sVertexProgram->uniform4fv(LLViewerShaderMgr::AVATAR_SINWAVE, 1, sin_params.mV); - renderRigged(avatar, RIGGED_FULLBRIGHT_ALPHA); - gGL.setSceneBlendType(LLRender::BT_ALPHA); - gGL.setColorMask(true, false); + LLVector4 gravity(0.f, 0.f, -CLOTHING_GRAVITY_EFFECT, 0.f); + gravity = gravity * rot_mat; + sVertexProgram->uniform4fv(LLViewerShaderMgr::AVATAR_GRAVITY, 1, gravity.mV); } -} -void LLDrawPoolAvatar::renderRiggedGlow(LLVOAvatar* avatar) -{ - if (!mRiggedFace[RIGGED_GLOW].empty()) + if( !single_avatar || (avatarp == single_avatar) ) { - LLGLEnable blend(GL_BLEND); - LLGLDisable test(GL_ALPHA_TEST); - gGL.flush(); - - LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL); - glPolygonOffset(-1.0f, -1.0f); - gGL.setSceneBlendType(LLRender::BT_ADD); - - LLGLDepthTest depth(GL_TRUE, GL_FALSE); - gGL.setColorMask(false, true); - - renderRigged(avatar, RIGGED_GLOW, true); - - gGL.setColorMask(true, false); - gGL.setSceneBlendType(LLRender::BT_ALPHA); + avatarp->renderSkinned(); } } - +static LLTrace::BlockTimerStatHandle FTM_RIGGED_VBO("Rigged VBO"); //----------------------------------------------------------------------------- // getDebugTexture() //----------------------------------------------------------------------------- LLViewerTexture *LLDrawPoolAvatar::getDebugTexture() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR + if (mReferences.empty()) { return NULL; @@ -2398,73 +934,3 @@ LLColor3 LLDrawPoolAvatar::getDebugColor() const { return LLColor3(0.f, 1.f, 0.f); } - -void LLDrawPoolAvatar::addRiggedFace(LLFace* facep, U32 type) -{ - LLVolume* volume = facep->getViewerObject()->getVolume(); - if (!volume || volume->getNumVolumeFaces() <= facep->getTEOffset()) - { - return; - } - - const LLTextureEntry* tex_entry = facep->getTextureEntry(); - // Don't render invisible faces even when they are in a linkset except if there's glow. - if (tex_entry && tex_entry->getColor().mV[VW] <= 0.001f && tex_entry->getGlow() <= 0.f) - { - return; - } - - llassert (facep->isState(LLFace::RIGGED)); - llassert(getType() == LLDrawPool::POOL_AVATAR || getType() == LLDrawPool::POOL_CONTROL_AV); - if (facep->getPool() && facep->getPool() != this) - { - LL_ERRS() << "adding rigged face that's already in another pool" << LL_ENDL; - } - if (type >= NUM_RIGGED_PASSES) - { - LL_ERRS() << "Invalid rigged face type." << LL_ENDL; - } - if (facep->getRiggedIndex(type) != -1) - { - LL_ERRS() << "Tried to add a rigged face that's referenced elsewhere." << LL_ENDL; - } - - facep->setRiggedIndex(type, mRiggedFace[type].size()); - facep->setPool(this); - mRiggedFace[type].push_back(facep); -} - -void LLDrawPoolAvatar::removeRiggedFace(LLFace* facep) -{ - llassert (facep->isState(LLFace::RIGGED)); - llassert(getType() == LLDrawPool::POOL_AVATAR || getType() == LLDrawPool::POOL_CONTROL_AV); - if (facep->getPool() != this) - { - LL_ERRS() << "Tried to remove a rigged face from the wrong pool" << LL_ENDL; - } - facep->setPool(NULL); - - for (U32 i = 0; i < NUM_RIGGED_PASSES; ++i) - { - S32 index = facep->getRiggedIndex(i); - - if (index > -1) - { - if (mRiggedFace[i].size() > index && mRiggedFace[i][index] == facep) - { - facep->setRiggedIndex(i,-1); - mRiggedFace[i].erase(mRiggedFace[i].begin()+index); - for (U32 j = index; j < mRiggedFace[i].size(); ++j) - { //bump indexes down for faces referenced after erased face - mRiggedFace[i][j]->setRiggedIndex(i, j); - } - } - else - { - LL_ERRS() << "Face reference data corrupt for rigged type " << i - << ((mRiggedFace[i].size() <= index) ? "; wrong index (out of bounds)" : (mRiggedFace[i][index] != facep) ? "; wrong face pointer" : "") - << LL_ENDL; - } - } - } -} diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h index cf7861c485a2e8f1898985df292c49f997d65385..0548d407f3769b022365484469931a7da595fbd6 100644 --- a/indra/newview/lldrawpoolavatar.h +++ b/indra/newview/lldrawpoolavatar.h @@ -28,14 +28,18 @@ #define LL_LLDRAWPOOLAVATAR_H #include "lldrawpool.h" +#include "llmodel.h" + +#include <unordered_map> class LLVOAvatar; +class LLVOVolume; class LLGLSLShader; class LLFace; -class LLMeshSkinInfo; class LLVolume; class LLVolumeFace; +extern U32 gFrameCount; class LLDrawPoolAvatar final : public LLFacePool { @@ -58,119 +62,11 @@ class LLDrawPoolAvatar final : public LLFacePool ~LLDrawPoolAvatar(); /*virtual*/ BOOL isDead(); - typedef enum - { - RIGGED_MATERIAL=0, - RIGGED_MATERIAL_ALPHA, - RIGGED_MATERIAL_ALPHA_MASK, - RIGGED_MATERIAL_ALPHA_EMISSIVE, - RIGGED_SPECMAP, - RIGGED_SPECMAP_BLEND, - RIGGED_SPECMAP_MASK, - RIGGED_SPECMAP_EMISSIVE, - RIGGED_NORMMAP, - RIGGED_NORMMAP_BLEND, - RIGGED_NORMMAP_MASK, - RIGGED_NORMMAP_EMISSIVE, - RIGGED_NORMSPEC, - RIGGED_NORMSPEC_BLEND, - RIGGED_NORMSPEC_MASK, - RIGGED_NORMSPEC_EMISSIVE, - RIGGED_SIMPLE, - RIGGED_FULLBRIGHT, - RIGGED_SHINY, - RIGGED_FULLBRIGHT_SHINY, - RIGGED_GLOW, - RIGGED_ALPHA, - RIGGED_FULLBRIGHT_ALPHA, - RIGGED_DEFERRED_BUMP, - RIGGED_DEFERRED_SIMPLE, - NUM_RIGGED_PASSES, - RIGGED_UNKNOWN, - } eRiggedPass; - - typedef enum - { - RIGGED_MATERIAL_MASK = - LLVertexBuffer::MAP_VERTEX | - LLVertexBuffer::MAP_NORMAL | - LLVertexBuffer::MAP_TEXCOORD0 | - LLVertexBuffer::MAP_COLOR | - LLVertexBuffer::MAP_WEIGHT4, - RIGGED_MATERIAL_ALPHA_VMASK = RIGGED_MATERIAL_MASK, - RIGGED_MATERIAL_ALPHA_MASK_MASK = RIGGED_MATERIAL_MASK, - RIGGED_MATERIAL_ALPHA_EMISSIVE_MASK = RIGGED_MATERIAL_MASK, - RIGGED_SPECMAP_VMASK = - LLVertexBuffer::MAP_VERTEX | - LLVertexBuffer::MAP_NORMAL | - LLVertexBuffer::MAP_TEXCOORD0 | - LLVertexBuffer::MAP_TEXCOORD2 | - LLVertexBuffer::MAP_COLOR | - LLVertexBuffer::MAP_WEIGHT4, - RIGGED_SPECMAP_BLEND_MASK = RIGGED_SPECMAP_VMASK, - RIGGED_SPECMAP_MASK_MASK = RIGGED_SPECMAP_VMASK, - RIGGED_SPECMAP_EMISSIVE_MASK = RIGGED_SPECMAP_VMASK, - RIGGED_NORMMAP_VMASK = - LLVertexBuffer::MAP_VERTEX | - LLVertexBuffer::MAP_NORMAL | - LLVertexBuffer::MAP_TANGENT | - LLVertexBuffer::MAP_TEXCOORD0 | - LLVertexBuffer::MAP_TEXCOORD1 | - LLVertexBuffer::MAP_COLOR | - LLVertexBuffer::MAP_WEIGHT4, - RIGGED_NORMMAP_BLEND_MASK = RIGGED_NORMMAP_VMASK, - RIGGED_NORMMAP_MASK_MASK = RIGGED_NORMMAP_VMASK, - RIGGED_NORMMAP_EMISSIVE_MASK = RIGGED_NORMMAP_VMASK, - RIGGED_NORMSPEC_VMASK = - LLVertexBuffer::MAP_VERTEX | - LLVertexBuffer::MAP_NORMAL | - LLVertexBuffer::MAP_TANGENT | - LLVertexBuffer::MAP_TEXCOORD0 | - LLVertexBuffer::MAP_TEXCOORD1 | - LLVertexBuffer::MAP_TEXCOORD2 | - LLVertexBuffer::MAP_COLOR | - LLVertexBuffer::MAP_WEIGHT4, - RIGGED_NORMSPEC_BLEND_MASK = RIGGED_NORMSPEC_VMASK, - RIGGED_NORMSPEC_MASK_MASK = RIGGED_NORMSPEC_VMASK, - RIGGED_NORMSPEC_EMISSIVE_MASK = RIGGED_NORMSPEC_VMASK, - RIGGED_SIMPLE_MASK = LLVertexBuffer::MAP_VERTEX | - LLVertexBuffer::MAP_NORMAL | - LLVertexBuffer::MAP_TEXCOORD0 | - LLVertexBuffer::MAP_COLOR | - LLVertexBuffer::MAP_WEIGHT4, - RIGGED_FULLBRIGHT_MASK = LLVertexBuffer::MAP_VERTEX | - LLVertexBuffer::MAP_TEXCOORD0 | - LLVertexBuffer::MAP_COLOR | - LLVertexBuffer::MAP_WEIGHT4, - RIGGED_SHINY_MASK = RIGGED_SIMPLE_MASK, - RIGGED_FULLBRIGHT_SHINY_MASK = RIGGED_SIMPLE_MASK, - RIGGED_GLOW_MASK = LLVertexBuffer::MAP_VERTEX | - LLVertexBuffer::MAP_TEXCOORD0 | - LLVertexBuffer::MAP_EMISSIVE | - LLVertexBuffer::MAP_WEIGHT4, - RIGGED_ALPHA_MASK = RIGGED_SIMPLE_MASK, - RIGGED_FULLBRIGHT_ALPHA_MASK = RIGGED_FULLBRIGHT_MASK, - RIGGED_DEFERRED_BUMP_MASK = LLVertexBuffer::MAP_VERTEX | - LLVertexBuffer::MAP_NORMAL | - LLVertexBuffer::MAP_TEXCOORD0 | - LLVertexBuffer::MAP_TANGENT | - LLVertexBuffer::MAP_COLOR | - LLVertexBuffer::MAP_WEIGHT4, - RIGGED_DEFERRED_SIMPLE_MASK = LLVertexBuffer::MAP_VERTEX | - LLVertexBuffer::MAP_NORMAL | - LLVertexBuffer::MAP_TEXCOORD0 | - LLVertexBuffer::MAP_COLOR | - LLVertexBuffer::MAP_WEIGHT4, - } eRiggedDataMask; - typedef enum { SHADOW_PASS_AVATAR_OPAQUE, SHADOW_PASS_AVATAR_ALPHA_BLEND, SHADOW_PASS_AVATAR_ALPHA_MASK, - SHADOW_PASS_ATTACHMENT_ALPHA_BLEND, - SHADOW_PASS_ATTACHMENT_ALPHA_MASK, - SHADOW_PASS_ATTACHMENT_OPAQUE, NUM_SHADOW_PASSES } eShadowPass; @@ -211,78 +107,19 @@ typedef enum void endImpostor(); void endSkinned(); - void beginDeferredImpostor(); - void beginDeferredRigid(); - void beginDeferredSkinned(); - - void endDeferredImpostor(); - void endDeferredRigid(); - void endDeferredSkinned(); - - void beginPostDeferredAlpha(); - void endPostDeferredAlpha(); - - void beginRiggedSimple(); - void beginRiggedFullbright(); - void beginRiggedFullbrightShiny(); - void beginRiggedShinySimple(); - void beginRiggedAlpha(); - void beginRiggedFullbrightAlpha(); - void beginRiggedGlow(); - void beginDeferredRiggedAlpha(); - void beginDeferredRiggedMaterial(S32 pass); - void beginDeferredRiggedMaterialAlpha(S32 pass); + void beginDeferredRigid(); + void beginDeferredImpostor(); + void beginDeferredSkinned(); - void endRiggedSimple(); - void endRiggedFullbright(); - void endRiggedFullbrightShiny(); - void endRiggedShinySimple(); - void endRiggedAlpha(); - void endRiggedFullbrightAlpha(); - void endRiggedGlow(); - void endDeferredRiggedAlpha(); - void endDeferredRiggedMaterial(S32 pass); - void endDeferredRiggedMaterialAlpha(S32 pass); - - void beginDeferredRiggedSimple(); - void beginDeferredRiggedBump(); - - void endDeferredRiggedSimple(); - void endDeferredRiggedBump(); - - void getRiggedGeometry(LLFace* face, LLPointer<LLVertexBuffer>& buffer, U32 data_mask, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face); - void updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, - LLFace* facep, - const LLMeshSkinInfo* skin, - LLVolume* volume, - LLVolumeFace& vol_face); - void updateRiggedVertexBuffers(LLVOAvatar* avatar); - - void renderRigged(LLVOAvatar* avatar, U32 type, bool glow = false); - void renderRiggedSimple(LLVOAvatar* avatar); - void renderRiggedAlpha(LLVOAvatar* avatar); - void renderRiggedFullbrightAlpha(LLVOAvatar* avatar); - void renderRiggedFullbright(LLVOAvatar* avatar); - void renderRiggedShinySimple(LLVOAvatar* avatar); - void renderRiggedFullbrightShiny(LLVOAvatar* avatar); - void renderRiggedGlow(LLVOAvatar* avatar); - void renderDeferredRiggedSimple(LLVOAvatar* avatar); - void renderDeferredRiggedBump(LLVOAvatar* avatar); - void renderDeferredRiggedMaterial(LLVOAvatar* avatar, S32 pass); - - - - void addRiggedFace(LLFace* facep, U32 type); - void removeRiggedFace(LLFace* facep); - - std::vector<LLFace*> mRiggedFace[NUM_RIGGED_PASSES]; + void endDeferredRigid(); + void endDeferredImpostor(); + void endDeferredSkinned(); /*virtual*/ LLViewerTexture *getDebugTexture(); /*virtual*/ LLColor3 getDebugColor() const; // For AGP debug display void renderAvatars(LLVOAvatar *single_avatar, S32 pass = -1); // renders only one avatar if single_avatar is not null. - static BOOL sSkipOpaque; static BOOL sSkipTransparent; static S32 sShadowPass; diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index 0701a62fb508e52da1079edd9d4fa3caee9af1a5..13d9ed6b4e77ad6b65e9b1e4edfd74b4e1b2bde9 100644 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -47,12 +47,16 @@ #include "pipeline.h" #include "llspatialpartition.h" #include "llviewershadermgr.h" +#include "llmodel.h" //#include "llimagebmp.h" //#include "../tools/imdebug/imdebug.h" // static LLStandardBumpmap gStandardBumpmapList[TEM_BUMPMAP_COUNT]; +LL::WorkQueue::weak_t LLBumpImageList::sMainQueue; +LL::WorkQueue::weak_t LLBumpImageList::sTexUpdateQueue; +LLRenderTarget LLBumpImageList::sRenderTarget; // static U32 LLStandardBumpmap::sStandardBumpmapCount = 0; @@ -73,6 +77,8 @@ static S32 cube_channel = -1; static S32 diffuse_channel = -1; static S32 bump_channel = -1; +#define LL_BUMPLIST_MULTITHREADED 1 // TODO -- figure out why this doesn't work + // static void LLStandardBumpmap::init() { @@ -202,32 +208,7 @@ void LLDrawPoolBump::prerender() // static S32 LLDrawPoolBump::numBumpPasses() { - if (LLPipeline::sRenderBump) - { - if (mShaderLevel > 1) - { - if (LLPipeline::sImpostorRender) - { - return 2; - } - else - { - return 3; - } - } - else if (LLPipeline::sImpostorRender) - { - return 1; - } - else - { - return 2; - } - } - else - { - return 0; - } + return 1; } S32 LLDrawPoolBump::getNumPasses() @@ -235,140 +216,79 @@ S32 LLDrawPoolBump::getNumPasses() return numBumpPasses(); } -void LLDrawPoolBump::beginRenderPass(S32 pass) -{ - LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP); - switch( pass ) - { - case 0: - beginShiny(); - break; - case 1: - if (mShaderLevel > 1) - { - beginFullbrightShiny(); - } - else - { - beginBump(); - } - break; - case 2: - beginBump(); - break; - default: - llassert(0); - break; - } -} - void LLDrawPoolBump::render(S32 pass) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP); - + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP); + if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_BUMP)) - { - return; - } - - switch( pass ) - { - case 0: - renderShiny(); - break; - case 1: - if (mShaderLevel > 1) - { - renderFullbrightShiny(); - } - else - { - renderBump(); - } - break; - case 2: - renderBump(); - break; - default: - llassert(0); - break; - } -} + { + return; + } -void LLDrawPoolBump::endRenderPass(S32 pass) -{ - LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP); - switch( pass ) - { - case 0: - endShiny(); - break; - case 1: - if (mShaderLevel > 1) - { - endFullbrightShiny(); - } - else - { - endBump(); - } - break; - case 2: - endBump(); - break; - default: - llassert(0); - break; - } + for (int i = 0; i < 2; ++i) + { + mRigged = i == 1; + + // first pass -- shiny + beginShiny(); + renderShiny(); + endShiny(); - //to cleanup texture channels - LLRenderPass::endRenderPass(pass); + //second pass -- fullbright shiny + if (mShaderLevel > 1) + { + beginFullbrightShiny(); + renderFullbrightShiny(); + endFullbrightShiny(); + } + + //third pass -- bump + beginBump(); + renderBump(LLRenderPass::PASS_BUMP); + endBump(); + } } + //static -void LLDrawPoolBump::beginShiny(bool invisible) +void LLDrawPoolBump::beginShiny() { - LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY); - if ((!invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_SHINY))|| - (invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY))) - { - return; - } - + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY); + mShiny = TRUE; sVertexMask = VERTEX_MASK_SHINY; // Second pass: environment map - if (!invisible && mShaderLevel > 1) + if (mShaderLevel > 1) { sVertexMask = VERTEX_MASK_SHINY | LLVertexBuffer::MAP_TEXCOORD0; } - if (getShaderLevel() > 0) + if (LLPipeline::sUnderWaterRender) { - if (LLPipeline::sUnderWaterRender) - { - shader = &gObjectShinyWaterProgram; - } - else - { - shader = &gObjectShinyProgram; - } - shader->bind(); - if (LLPipeline::sRenderingHUDs) - { - shader->uniform1i(LLShaderMgr::NO_ATMO, 1); - } - else - { - shader->uniform1i(LLShaderMgr::NO_ATMO, 0); - } + shader = &gObjectShinyWaterProgram; } else { - shader = NULL; + shader = &gObjectShinyProgram; } - bindCubeMap(shader, mShaderLevel, diffuse_channel, cube_channel, invisible); + if (mRigged) + { + llassert(shader->mRiggedVariant); + shader = shader->mRiggedVariant; + } + + shader->bind(); + if (LLPipeline::sRenderingHUDs) + { + shader->uniform1i(LLShaderMgr::NO_ATMO, 1); + } + else + { + shader->uniform1i(LLShaderMgr::NO_ATMO, 0); + } + + bindCubeMap(shader, mShaderLevel, diffuse_channel, cube_channel); if (mShaderLevel > 1) { //indexed texture rendering, channel 0 is always diffuse @@ -377,28 +297,27 @@ void LLDrawPoolBump::beginShiny(bool invisible) } //static -void LLDrawPoolBump::bindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel, bool invisible) +void LLDrawPoolBump::bindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel) { LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL; if( cube_map ) { - if (!invisible && shader ) + if (shader ) { if (shader_level > 1) { - cube_map->setMatrix(1); + cube_map->setMatrix(1); // Make sure that texture coord generation happens for tex unit 1, as that's the one we use for // the cube map in the one pass shiny shaders cube_channel = shader->enableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); cube_map->enableTexture(cube_channel); - cube_map->enableTextureCoords(1); diffuse_channel = shader->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); } else { + cube_map->setMatrix(0); cube_channel = shader->enableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); diffuse_channel = -1; - cube_map->setMatrix(0); cube_map->enable(cube_channel); } gGL.getTexUnit(cube_channel)->bind(cube_map); @@ -410,49 +329,51 @@ void LLDrawPoolBump::bindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& di diffuse_channel = -1; gGL.getTexUnit(0)->disable(); cube_map->enable(0); - cube_map->setMatrix(0); + cube_map->setMatrix(0); gGL.getTexUnit(0)->bind(cube_map); - - gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_COLOR); - gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_VERT_ALPHA); } } } -void LLDrawPoolBump::renderShiny(bool invisible) +void LLDrawPoolBump::renderShiny() { - LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY); - if ((!invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_SHINY))|| - (invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY))) - { - return; - } - + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY); + if( gSky.mVOSkyp->getCubeMap() ) { LLGLEnable blend_enable(GL_BLEND); - if (!invisible && mShaderLevel > 1) + if (mShaderLevel > 1) { - LLRenderPass::pushBatches(LLRenderPass::PASS_SHINY, sVertexMask | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + if (mRigged) + { + LLRenderPass::pushRiggedBatches(LLRenderPass::PASS_SHINY_RIGGED, sVertexMask | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + } + else + { + LLRenderPass::pushBatches(LLRenderPass::PASS_SHINY, sVertexMask | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + } } - else if (!invisible) + else { - renderGroups(LLRenderPass::PASS_SHINY, sVertexMask); + if (mRigged) + { + gPipeline.renderRiggedGroups(this, LLRenderPass::PASS_SHINY_RIGGED, sVertexMask, TRUE); + } + else + { + gPipeline.renderGroups(this, LLRenderPass::PASS_SHINY, sVertexMask, TRUE); + } } - //else // invisible (deprecated) - //{ - //renderGroups(LLRenderPass::PASS_INVISI_SHINY, sVertexMask); - //} } } //static -void LLDrawPoolBump::unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel, bool invisible) +void LLDrawPoolBump::unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel) { LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL; if( cube_map ) { - if (!invisible && shader_level > 1) + if (shader_level > 1) { shader->disableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); @@ -467,29 +388,15 @@ void LLDrawPoolBump::unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& // Moved below shader->disableTexture call to avoid false alarms from auto-re-enable of textures on stage 0 // MAINT-755 cube_map->disable(); - cube_map->restoreMatrix(); - } - - if (!LLGLSLShader::sNoFixedFunction) - { - gGL.getTexUnit(diffuse_channel)->disable(); - gGL.getTexUnit(cube_channel)->disable(); - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); + cube_map->restoreMatrix(); } } -void LLDrawPoolBump::endShiny(bool invisible) +void LLDrawPoolBump::endShiny() { - LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY); - if ((!invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_SHINY))|| - (invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY))) - { - return; - } + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY); - unbindCubeMap(shader, mShaderLevel, diffuse_channel, cube_channel, invisible); + unbindCubeMap(shader, mShaderLevel, diffuse_channel, cube_channel); if (shader) { shader->unbind(); @@ -502,12 +409,8 @@ void LLDrawPoolBump::endShiny(bool invisible) void LLDrawPoolBump::beginFullbrightShiny() { - LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY); - if (!gPipeline.hasRenderBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY)) - { - return; - } - + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY); + sVertexMask = VERTEX_MASK_SHINY | LLVertexBuffer::MAP_TEXCOORD0; // Second pass: environment map @@ -528,6 +431,12 @@ void LLDrawPoolBump::beginFullbrightShiny() } } + if (mRigged) + { + llassert(shader->mRiggedVariant); + shader = shader->mRiggedVariant; + } + LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL; if( cube_map ) { @@ -541,13 +450,12 @@ void LLDrawPoolBump::beginFullbrightShiny() shader->uniform1i(LLShaderMgr::NO_ATMO, 0); } - cube_map->setMatrix(1); + cube_map->setMatrix(1); // Make sure that texture coord generation happens for tex unit 1, as that's the one we use for // the cube map in the one pass shiny shaders gGL.getTexUnit(1)->disable(); cube_channel = shader->enableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); cube_map->enableTexture(cube_channel); - cube_map->enableTextureCoords(1); diffuse_channel = shader->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); gGL.getTexUnit(cube_channel)->bind(cube_map); @@ -564,11 +472,7 @@ void LLDrawPoolBump::beginFullbrightShiny() void LLDrawPoolBump::renderFullbrightShiny() { - LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY); - if (!gPipeline.hasRenderBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY)) - { - return; - } + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY); if( gSky.mVOSkyp->getCubeMap() ) { @@ -576,43 +480,41 @@ void LLDrawPoolBump::renderFullbrightShiny() if (mShaderLevel > 1) { - LLRenderPass::pushBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY, sVertexMask | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + if (mRigged) + { + LLRenderPass::pushRiggedBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY_RIGGED, sVertexMask | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + } + else + { + LLRenderPass::pushBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY, sVertexMask | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + } } else { - LLRenderPass::renderTexture(LLRenderPass::PASS_FULLBRIGHT_SHINY, sVertexMask); + if (mRigged) + { + LLRenderPass::pushRiggedBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY_RIGGED, sVertexMask); + } + else + { + LLRenderPass::pushBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY, sVertexMask); + } } } } void LLDrawPoolBump::endFullbrightShiny() { - LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY); - if (!gPipeline.hasRenderBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY)) - { - return; - } + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY); LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL; if( cube_map ) { cube_map->disable(); - cube_map->restoreMatrix(); - - /*if (diffuse_channel != 0) - { - shader->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP); - } - gGL.getTexUnit(0)->activate(); - gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);*/ - + cube_map->restoreMatrix(); shader->unbind(); - //gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); } - //gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - //gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); - diffuse_channel = -1; cube_channel = 0; mShiny = FALSE; @@ -662,6 +564,7 @@ BOOL LLDrawPoolBump::bindBumpMap(LLFace* face, S32 channel) //static BOOL LLDrawPoolBump::bindBumpMap(U8 bump_code, LLViewerTexture* texture, F32 vsize, S32 channel) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //Note: texture atlas does not support bump texture now. LLViewerFetchedTexture* tex = LLViewerTextureManager::staticCastToFetchedTexture(texture) ; if(!tex) @@ -678,7 +581,7 @@ BOOL LLDrawPoolBump::bindBumpMap(U8 bump_code, LLViewerTexture* texture, F32 vsi break; case BE_BRIGHTNESS: case BE_DARKNESS: - bump = gBumpImageList.getBrightnessDarknessImage( tex, bump_code ); + bump = gBumpImageList.getBrightnessDarknessImage( tex, bump_code ); break; default: @@ -694,12 +597,13 @@ BOOL LLDrawPoolBump::bindBumpMap(U8 bump_code, LLViewerTexture* texture, F32 vsi { if (channel == -2) { - gGL.getTexUnit(1)->bind(bump); - gGL.getTexUnit(0)->bind(bump); + gGL.getTexUnit(1)->bindFast(bump); + gGL.getTexUnit(0)->bindFast(bump); } else { - gGL.getTexUnit(channel)->bind(bump); + // NOTE: do not use bindFast here (see SL-16222) + gGL.getTexUnit(channel)->bind(bump); } return TRUE; @@ -709,53 +613,22 @@ BOOL LLDrawPoolBump::bindBumpMap(U8 bump_code, LLViewerTexture* texture, F32 vsi } //static -void LLDrawPoolBump::beginBump(U32 pass) -{ - if (!gPipeline.hasRenderBatches(pass)) - { - return; - } - +void LLDrawPoolBump::beginBump() +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP); sVertexMask = VERTEX_MASK_BUMP; - LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP); // Optional second pass: emboss bump map stop_glerror(); - if (LLGLSLShader::sNoFixedFunction) - { - gObjectBumpProgram.bind(); - } - else - { - // TEXTURE UNIT 0 - // Output.rgb = texture at texture coord 0 - gGL.getTexUnit(0)->activate(); - - gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_ALPHA); - gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_ALPHA); + shader = &gObjectBumpProgram; - // TEXTURE UNIT 1 - gGL.getTexUnit(1)->activate(); - - gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE); + if (mRigged) + { + llassert(shader->mRiggedVariant); + shader = shader->mRiggedVariant; + } - gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_ADD_SIGNED, LLTexUnit::TBS_PREV_COLOR, LLTexUnit::TBS_ONE_MINUS_TEX_ALPHA); - gGL.getTexUnit(1)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_ALPHA); - - // src = tex0 + (1 - tex1) - 0.5 - // = (bump0/2 + 0.5) + (1 - (bump1/2 + 0.5)) - 0.5 - // = (1 + bump0 - bump1) / 2 - - - // Blend: src * dst + dst * src - // = 2 * src * dst - // = 2 * ((1 + bump0 - bump1) / 2) * dst [0 - 2 * dst] - // = (1 + bump0 - bump1) * dst.rgb - // = dst.rgb + dst.rgb * (bump0 - bump1) - - gGL.getTexUnit(0)->activate(); - gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE); - } + shader->bind(); gGL.setSceneBlendType(LLRender::BT_MULT_X2); stop_glerror(); @@ -764,12 +637,7 @@ void LLDrawPoolBump::beginBump(U32 pass) //static void LLDrawPoolBump::renderBump(U32 pass) { - if (!gPipeline.hasRenderBatches(pass)) - { - return; - } - - LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP); + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP); LLGLDisable fog(GL_FOG); LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_LEQUAL); LLGLEnable blend(GL_BLEND); @@ -783,28 +651,9 @@ void LLDrawPoolBump::renderBump(U32 pass) //static void LLDrawPoolBump::endBump(U32 pass) { - if (!gPipeline.hasRenderBatches(pass)) - { - return; - } + gObjectBumpProgram.unbind(); - if (LLGLSLShader::sNoFixedFunction) - { - gObjectBumpProgram.unbind(); - } - else - { - // Disable texture blending on unit 1 - gGL.getTexUnit(1)->activate(); - gGL.getTexUnit(1)->disable(); - gGL.getTexUnit(1)->setTextureBlendType(LLTexUnit::TB_MULT); - - // Disable texture blending on unit 0 - gGL.getTexUnit(0)->activate(); - gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); - } - - gGL.setSceneBlendType(LLRender::BT_ALPHA); + gGL.setSceneBlendType(LLRender::BT_ALPHA); } S32 LLDrawPoolBump::getNumDeferredPasses() @@ -819,101 +668,81 @@ S32 LLDrawPoolBump::getNumDeferredPasses() } } -void LLDrawPoolBump::beginDeferredPass(S32 pass) -{ - if (!gPipeline.hasRenderBatches(LLRenderPass::PASS_BUMP)) - { - return; - } - LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP); - mShiny = TRUE; - gDeferredBumpProgram.bind(); - diffuse_channel = gDeferredBumpProgram.enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); - bump_channel = gDeferredBumpProgram.enableTexture(LLViewerShaderMgr::BUMP_MAP); - gGL.getTexUnit(diffuse_channel)->unbind(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(bump_channel)->unbind(LLTexUnit::TT_TEXTURE); -} - -void LLDrawPoolBump::endDeferredPass(S32 pass) -{ - if (!gPipeline.hasRenderBatches(LLRenderPass::PASS_BUMP)) - { - return; - } - LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP); - mShiny = FALSE; - gDeferredBumpProgram.disableTexture(LLViewerShaderMgr::DIFFUSE_MAP); - gDeferredBumpProgram.disableTexture(LLViewerShaderMgr::BUMP_MAP); - gDeferredBumpProgram.unbind(); - gGL.getTexUnit(0)->activate(); -} - void LLDrawPoolBump::renderDeferred(S32 pass) { - if (!gPipeline.hasRenderBatches(LLRenderPass::PASS_BUMP)) - { - return; - } - LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP); + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP); - U32 type = LLRenderPass::PASS_BUMP; - LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type); - LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type); + mShiny = TRUE; + for (int i = 0; i < 2; ++i) + { + bool rigged = i == 1; + gDeferredBumpProgram.bind(rigged); + diffuse_channel = LLGLSLShader::sCurBoundShaderPtr->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); + bump_channel = LLGLSLShader::sCurBoundShaderPtr->enableTexture(LLViewerShaderMgr::BUMP_MAP); + gGL.getTexUnit(diffuse_channel)->unbind(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(bump_channel)->unbind(LLTexUnit::TT_TEXTURE); - U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_COLOR; - - for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i) - { - LLDrawInfo& params = **i; + U32 type = rigged ? LLRenderPass::PASS_BUMP_RIGGED : LLRenderPass::PASS_BUMP; + LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type); + LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type); - gDeferredBumpProgram.setMinimumAlpha(params.mAlphaMaskCutoff); - LLDrawPoolBump::bindBumpMap(params, bump_channel); - pushBatch(params, mask, TRUE); - } -} + U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_COLOR; -void LLDrawPoolBump::beginPostDeferredPass(S32 pass) -{ - switch (pass) - { - case 0: - beginFullbrightShiny(); - break; - case 1: - beginBump(LLRenderPass::PASS_POST_BUMP); - break; - } -} + LLVOAvatar* avatar = nullptr; + U64 skin = 0; -void LLDrawPoolBump::endPostDeferredPass(S32 pass) -{ - switch (pass) - { - case 0: - endFullbrightShiny(); - break; - case 1: - endBump(LLRenderPass::PASS_POST_BUMP); - break; - } + for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i) + { + LLDrawInfo& params = **i; + + LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(params.mAlphaMaskCutoff); + LLDrawPoolBump::bindBumpMap(params, bump_channel); + + if (rigged) + { + if (avatar != params.mAvatar || skin != params.mSkinInfo->mHash) + { + uploadMatrixPalette(params); + avatar = params.mAvatar; + skin = params.mSkinInfo->mHash; + } + pushBatch(params, mask | LLVertexBuffer::MAP_WEIGHT4, TRUE, FALSE); + } + else + { + pushBatch(params, mask, TRUE, FALSE); + } + } + + LLGLSLShader::sCurBoundShaderPtr->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP); + LLGLSLShader::sCurBoundShaderPtr->disableTexture(LLViewerShaderMgr::BUMP_MAP); + LLGLSLShader::sCurBoundShaderPtr->unbind(); + gGL.getTexUnit(0)->activate(); + } - //to disable texture channels - LLRenderPass::endRenderPass(pass); + mShiny = FALSE; } + void LLDrawPoolBump::renderPostDeferred(S32 pass) { - switch (pass) - { - case 0: - renderFullbrightShiny(); - break; - case 1: - renderBump(LLRenderPass::PASS_POST_BUMP); - break; - } + for (int i = 0; i < 2; ++i) + { // two passes -- static and rigged + mRigged = (i == 1); + + // render shiny + beginFullbrightShiny(); + renderFullbrightShiny(); + endFullbrightShiny(); + + //render bump + beginBump(); + renderBump(LLRenderPass::PASS_POST_BUMP); + endBump(); + } } + //////////////////////////////////////////////////////////////// // List of bump-maps created from other textures. @@ -928,6 +757,8 @@ void LLBumpImageList::init() LLStandardBumpmap::init(); LLStandardBumpmap::restoreGL(); + sMainQueue = LL::WorkQueue::getInstance("mainloop"); + sTexUpdateQueue = LL::WorkQueue::getInstance("LLImageGL"); // Share work queue with tex loader. } void LLBumpImageList::clear() @@ -937,6 +768,8 @@ void LLBumpImageList::clear() mBrightnessEntries.clear(); mDarknessEntries.clear(); + sRenderTarget.release(); + LLStandardBumpmap::clear(); } @@ -1046,6 +879,7 @@ void LLBumpImageList::updateImages() // Note: the caller SHOULD NOT keep the pointer that this function returns. It may be updated as more data arrives. LLViewerTexture* LLBumpImageList::getBrightnessDarknessImage(LLViewerFetchedTexture* src_image, U8 bump_code ) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; llassert( (bump_code == BE_BRIGHTNESS) || (bump_code == BE_DARKNESS) ); LLViewerTexture* bump = NULL; @@ -1075,10 +909,7 @@ LLViewerTexture* LLBumpImageList::getBrightnessDarknessImage(LLViewerFetchedText } else { - LLPointer<LLImageRaw> raw = new LLImageRaw(1,1,1); - raw->clear(0x77, 0x77, 0xFF, 0xFF); - - (*entries_list)[src_image->getID()] = LLViewerTextureManager::getLocalTexture( raw.get(), TRUE); + (*entries_list)[src_image->getID()] = LLViewerTextureManager::getLocalTexture( TRUE ); bump = (*entries_list)[src_image->getID()]; // In case callback was called immediately and replaced the image } @@ -1098,11 +929,10 @@ LLViewerTexture* LLBumpImageList::getBrightnessDarknessImage(LLViewerFetchedText } -static LLTrace::BlockTimerStatHandle FTM_BUMP_SOURCE_STANDARD_LOADED("Bump Standard Callback"); - // static void LLBumpImageList::onSourceBrightnessLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; LLUUID* source_asset_id = (LLUUID*)userdata; LLBumpImageList::onSourceLoaded( success, src_vi, src, *source_asset_id, BE_BRIGHTNESS ); if( final ) @@ -1122,22 +952,17 @@ void LLBumpImageList::onSourceDarknessLoaded( BOOL success, LLViewerFetchedTextu } } -static LLTrace::BlockTimerStatHandle FTM_BUMP_GEN_NORMAL("Generate Normal Map"); -static LLTrace::BlockTimerStatHandle FTM_BUMP_CREATE_TEXTURE("Create GL Normal Map"); - void LLBumpImageList::onSourceStandardLoaded( BOOL success, LLViewerFetchedTexture* src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata) { if (success && LLPipeline::sRenderDeferred) { - LL_RECORD_BLOCK_TIME(FTM_BUMP_SOURCE_STANDARD_LOADED); + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; LLPointer<LLImageRaw> nrm_image = new LLImageRaw(src->getWidth(), src->getHeight(), 4); { - LL_RECORD_BLOCK_TIME(FTM_BUMP_GEN_NORMAL); generateNormalMapFromAlpha(src, nrm_image); } src_vi->setExplicitFormat(GL_RGBA, GL_RGBA); { - LL_RECORD_BLOCK_TIME(FTM_BUMP_CREATE_TEXTURE); src_vi->createGLTexture(src_vi->getDiscardLevel(), nrm_image); } } @@ -1198,43 +1023,32 @@ void LLBumpImageList::generateNormalMapFromAlpha(LLImageRaw* src, LLImageRaw* nr } } - -static LLTrace::BlockTimerStatHandle FTM_BUMP_SOURCE_LOADED("Bump Source Loaded"); -static LLTrace::BlockTimerStatHandle FTM_BUMP_SOURCE_ENTRIES_UPDATE("Entries Update"); -static LLTrace::BlockTimerStatHandle FTM_BUMP_SOURCE_MIN_MAX("Min/Max"); -static LLTrace::BlockTimerStatHandle FTM_BUMP_SOURCE_RGB2LUM("RGB to Luminance"); -static LLTrace::BlockTimerStatHandle FTM_BUMP_SOURCE_RESCALE("Rescale"); -static LLTrace::BlockTimerStatHandle FTM_BUMP_SOURCE_GEN_NORMAL("Generate Normal"); -static LLTrace::BlockTimerStatHandle FTM_BUMP_SOURCE_CREATE("Bump Source Create"); - // static void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLImageRaw* src, LLUUID& source_asset_id, EBumpEffect bump_code ) { + LL_PROFILE_ZONE_SCOPED; + if( success ) { - LL_RECORD_BLOCK_TIME(FTM_BUMP_SOURCE_LOADED); + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; bump_image_map_t& entries_list(bump_code == BE_BRIGHTNESS ? gBumpImageList.mBrightnessEntries : gBumpImageList.mDarknessEntries ); bump_image_map_t::iterator iter = entries_list.find(source_asset_id); { - LL_RECORD_BLOCK_TIME(FTM_BUMP_SOURCE_ENTRIES_UPDATE); if (iter == entries_list.end() || iter->second.isNull() || iter->second->getWidth() != src->getWidth() || iter->second->getHeight() != src->getHeight()) // bump not cached yet or has changed resolution { //make sure an entry exists for this image - LLPointer<LLImageRaw> raw = new LLImageRaw(1,1,1); - raw->clear(0x77, 0x77, 0xFF, 0xFF); - - entries_list[src_vi->getID()] = LLViewerTextureManager::getLocalTexture( raw.get(), TRUE); + entries_list[src_vi->getID()] = LLViewerTextureManager::getLocalTexture(TRUE); iter = entries_list.find(src_vi->getID()); } } - //if (iter->second->getWidth() != src->getWidth() || - // iter->second->getHeight() != src->getHeight()) // bump not cached yet or has changed resolution + if (iter->second->getWidth() != src->getWidth() || + iter->second->getHeight() != src->getHeight()) // bump not cached yet or has changed resolution { LLPointer<LLImageRaw> dst_image = new LLImageRaw(src->getWidth(), src->getHeight(), 1); U8* dst_data = dst_image->getData(); @@ -1262,7 +1076,6 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI case 1: case 2: { - LL_RECORD_BLOCK_TIME(FTM_BUMP_SOURCE_MIN_MAX); if( src_data_size == dst_data_size * src_components ) { for( S32 i = 0, j=0; i < dst_data_size; i++, j+= src_components ) @@ -1288,7 +1101,6 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI case 3: case 4: { - LL_RECORD_BLOCK_TIME(FTM_BUMP_SOURCE_RGB2LUM); if( src_data_size == dst_data_size * src_components ) { for( S32 i = 0, j=0; i < dst_data_size; i++, j+= src_components ) @@ -1321,7 +1133,6 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI if( maximum > minimum ) { - LL_RECORD_BLOCK_TIME(FTM_BUMP_SOURCE_RESCALE); U8 bias_and_scale_lut[256]; F32 twice_one_over_range = 2.f / (maximum - minimum); S32 i; @@ -1351,113 +1162,146 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI } //--------------------------------------------------- - // immediately assign bump to a global smart pointer in case some local smart pointer + // immediately assign bump to a smart pointer in case some local smart pointer // accidentally releases it. - LLPointer<LLViewerTexture> bump = LLViewerTextureManager::getLocalTexture( TRUE ); + LLPointer<LLViewerTexture> bump = iter->second; if (!LLPipeline::sRenderDeferred) { - LL_RECORD_BLOCK_TIME(FTM_BUMP_SOURCE_CREATE); bump->setExplicitFormat(GL_ALPHA8, GL_ALPHA); - bump->createGLTexture(0, dst_image); + +#if LL_BUMPLIST_MULTITHREADED + auto tex_queue = LLImageGLThread::sEnabled ? sTexUpdateQueue.lock() : nullptr; + + if (tex_queue) + { //dispatch creation to background thread + LLImageRaw* dst_ptr = dst_image; + LLViewerTexture* bump_ptr = bump; + dst_ptr->ref(); + bump_ptr->ref(); + tex_queue->post( + [=]() + { + LL_PROFILE_ZONE_NAMED("bil - create texture"); + bump_ptr->createGLTexture(0, dst_ptr); + bump_ptr->unref(); + dst_ptr->unref(); + }); + + } + else +#endif + { + bump->createGLTexture(0, dst_image); + } } else { //convert to normal map - - //disable compression on normal maps to prevent errors below - bump->getGLTexture()->setAllowCompression(false); - - { - LL_RECORD_BLOCK_TIME(FTM_BUMP_SOURCE_CREATE); - bump->setExplicitFormat(GL_RGBA8, GL_ALPHA); - bump->createGLTexture(0, dst_image); - } - - { - LL_RECORD_BLOCK_TIME(FTM_BUMP_SOURCE_GEN_NORMAL); - gPipeline.mScreen.bindTarget(); - - LLGLDepthTest depth(GL_FALSE); - LLGLDisable cull(GL_CULL_FACE); - LLGLDisable blend(GL_BLEND); - gGL.setColorMask(TRUE, TRUE); - gNormalMapGenProgram.bind(); - - static LLStaticHashedString sNormScale("norm_scale"); - static LLStaticHashedString sStepX("stepX"); - static LLStaticHashedString sStepY("stepY"); - - gNormalMapGenProgram.uniform1f(sNormScale, LLPipeline::RenderNormalMapScale); - gNormalMapGenProgram.uniform1f(sStepX, 1.f/bump->getWidth()); - gNormalMapGenProgram.uniform1f(sStepY, 1.f/bump->getHeight()); - - LLVector2 v((F32) bump->getWidth()/gPipeline.mScreen.getWidth(), - (F32) bump->getHeight()/gPipeline.mScreen.getHeight()); - - gGL.getTexUnit(0)->bind(bump); - - S32 width = bump->getWidth(); - S32 height = bump->getHeight(); - - S32 screen_width = gPipeline.mScreen.getWidth(); - S32 screen_height = gPipeline.mScreen.getHeight(); - - glViewport(0, 0, screen_width, screen_height); - - for (S32 left = 0; left < width; left += screen_width) - { - S32 right = left + screen_width; - right = llmin(right, width); - - F32 left_tc = (F32) left/ width; - F32 right_tc = (F32) right/width; - - for (S32 bottom = 0; bottom < height; bottom += screen_height) - { - S32 top = bottom+screen_height; - top = llmin(top, height); - - F32 bottom_tc = (F32) bottom/height; - F32 top_tc = (F32)(bottom+screen_height)/height; - top_tc = llmin(top_tc, 1.f); - - F32 screen_right = (F32) (right-left)/screen_width; - F32 screen_top = (F32) (top-bottom)/screen_height; - - gGL.begin(LLRender::TRIANGLE_STRIP); - gGL.texCoord2f(left_tc, bottom_tc); - gGL.vertex2f(0, 0); - - gGL.texCoord2f(left_tc, top_tc); - gGL.vertex2f(0, screen_top); - - gGL.texCoord2f(right_tc, bottom_tc); - gGL.vertex2f(screen_right, 0); - - gGL.texCoord2f(right_tc, top_tc); - gGL.vertex2f(screen_right, screen_top); - - gGL.end(); - - gGL.flush(); - - S32 w = right-left; - S32 h = top-bottom; - - glCopyTexSubImage2D(GL_TEXTURE_2D, 0, left, bottom, 0, 0, w, h); - } - } - - glGenerateMipmap(GL_TEXTURE_2D); + LL_PROFILE_ZONE_NAMED("bil - create normal map"); + LLImageGL* img = bump->getGLTexture(); + LLImageRaw* dst_ptr = dst_image.get(); + LLGLTexture* bump_ptr = bump.get(); + + dst_ptr->ref(); + img->ref(); + bump_ptr->ref(); + auto create_func = [=]() + { + img->setUseMipMaps(TRUE); + // upload dst_image to GPU (greyscale in red channel) + img->setExplicitFormat(GL_RED, GL_RED); + + bump_ptr->createGLTexture(0, dst_ptr); + dst_ptr->unref(); + }; + + auto generate_func = [=]() + { + // Allocate an empty RGBA texture at "tex_name" the same size as bump + // Note: bump will still point at GPU copy of dst_image + bump_ptr->setExplicitFormat(GL_RGBA, GL_RGBA); + LLGLuint tex_name; + img->createGLTexture(0, nullptr, 0, 0, true, &tex_name); + + // point render target at empty buffer + sRenderTarget.setColorAttachment(img, tex_name); + + // generate normal map in empty texture + { + sRenderTarget.bindTarget(); + + LLGLDepthTest depth(GL_FALSE); + LLGLDisable cull(GL_CULL_FACE); + LLGLDisable blend(GL_BLEND); + gGL.setColorMask(TRUE, TRUE); + + gNormalMapGenProgram.bind(); + + static LLStaticHashedString sNormScale("norm_scale"); + static LLStaticHashedString sStepX("stepX"); + static LLStaticHashedString sStepY("stepY"); + + gNormalMapGenProgram.uniform1f(sNormScale, gSavedSettings.getF32("RenderNormalMapScale")); + gNormalMapGenProgram.uniform1f(sStepX, 1.f / bump_ptr->getWidth()); + gNormalMapGenProgram.uniform1f(sStepY, 1.f / bump_ptr->getHeight()); + + gGL.getTexUnit(0)->bind(bump_ptr); + + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.texCoord2f(0, 0); + gGL.vertex2f(0, 0); + + gGL.texCoord2f(0, 1); + gGL.vertex2f(0, 1); + + gGL.texCoord2f(1, 0); + gGL.vertex2f(1, 0); + + gGL.texCoord2f(1, 1); + gGL.vertex2f(1, 1); + + gGL.end(); + + gGL.flush(); + + gNormalMapGenProgram.unbind(); + + sRenderTarget.flush(); + sRenderTarget.releaseColorAttachment(); + } + + // point bump at normal map and free gpu copy of dst_image + img->syncTexName(tex_name); + + // generate mipmap + gGL.getTexUnit(0)->bind(img); + glGenerateMipmap(GL_TEXTURE_2D); + gGL.getTexUnit(0)->disable(); + + bump_ptr->unref(); + img->unref(); + }; + +#if LL_BUMPLIST_MULTITHREADED + auto main_queue = LLImageGLThread::sEnabled ? sMainQueue.lock() : nullptr; + + if (main_queue) + { //dispatch texture upload to background thread, issue GPU commands to generate normal map on main thread + main_queue->postTo( + sTexUpdateQueue, + create_func, + generate_func); + } + else +#endif + { // immediate upload texture and generate normal map + create_func(); + generate_func(); + } - gPipeline.mScreen.flush(); - gNormalMapGenProgram.unbind(); - - //generateNormalMapFromAlpha(dst_image, nrm_image); - } } - + iter->second = bump; // derefs (and deletes) old image //--------------------------------------------------- } @@ -1466,8 +1310,17 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI void LLDrawPoolBump::renderBump(U32 type, U32 mask) { - LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type); - LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type); + LLVOAvatar* avatar = nullptr; + U64 skin = 0; + + if (mRigged) + { // nudge type enum and include skinweights for rigged pass + type += 1; + mask |= LLVertexBuffer::MAP_WEIGHT4; + } + + LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type); + LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type); for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i) { @@ -1475,6 +1328,21 @@ void LLDrawPoolBump::renderBump(U32 type, U32 mask) if (LLDrawPoolBump::bindBumpMap(params)) { + if (mRigged) + { + if (avatar != params.mAvatar || skin != params.mSkinInfo->mHash) + { + if (uploadMatrixPalette(params)) + { + avatar = params.mAvatar; + skin = params.mSkinInfo->mHash; + } + else + { + continue; + } + } + } pushBatch(params, mask, FALSE); } } @@ -1482,6 +1350,7 @@ void LLDrawPoolBump::renderBump(U32 type, U32 mask) void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; applyModelMatrix(params); bool tex_setup = false; @@ -1494,7 +1363,7 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL LLViewerTexture* texturep = params.mTextureList[i]; if (texturep) { - gGL.getTexUnit(i)->bind(texturep, TRUE); + gGL.getTexUnit(i)->bindFast(texturep); } } } @@ -1509,13 +1378,6 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL } else { - if (!LLGLSLShader::sNoFixedFunction) - { - gGL.getTexUnit(1)->activate(); - gGL.matrixMode(LLRender::MM_TEXTURE); - gGL.loadMatrix(*params.mTextureMatrix); - } - gGL.getTexUnit(0)->activate(); gGL.matrixMode(LLRender::MM_TEXTURE); gGL.loadMatrix(*params.mTextureMatrix); @@ -1532,8 +1394,7 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL { if (params.mTexture.notNull()) { - gGL.getTexUnit(diffuse_channel)->bind(params.mTexture); - params.mTexture->addTextureStats(params.mVSize); + gGL.getTexUnit(diffuse_channel)->bindFast(params.mTexture); } else { @@ -1546,10 +1407,10 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL { params.mGroup->rebuildMesh(); } - params.mVertexBuffer->setBuffer(mask); - params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); + params.mVertexBuffer->setBufferFast(mask); + params.mVertexBuffer->drawRangeFast(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); - if (tex_setup) + if (tex_setup) { if (mShiny) { @@ -1557,12 +1418,6 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL } else { - if (!LLGLSLShader::sNoFixedFunction) - { - gGL.getTexUnit(1)->activate(); - gGL.matrixMode(LLRender::MM_TEXTURE); - gGL.loadIdentity(); - } gGL.getTexUnit(0)->activate(); gGL.matrixMode(LLRender::MM_TEXTURE); } @@ -1573,9 +1428,9 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL void LLDrawPoolInvisible::render(S32 pass) { //render invisiprims - LL_RECORD_BLOCK_TIME(FTM_RENDER_INVISIBLE); + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_INVISIBLE); - if (gPipeline.canUseVertexShaders()) + if (gPipeline.shadersLoaded()) { gOcclusionProgram.bind(); } @@ -1587,48 +1442,8 @@ void LLDrawPoolInvisible::render(S32 pass) gGL.setColorMask(true, false); glStencilMask(0xFFFFFFFF); - if (gPipeline.canUseVertexShaders()) + if (gPipeline.shadersLoaded()) { gOcclusionProgram.unbind(); } - - if (gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY)) - { - beginShiny(true); - renderShiny(true); - endShiny(true); - } -} - -void LLDrawPoolInvisible::beginDeferredPass(S32 pass) -{ - beginRenderPass(pass); -} - -void LLDrawPoolInvisible::endDeferredPass( S32 pass ) -{ - endRenderPass(pass); -} - -void LLDrawPoolInvisible::renderDeferred( S32 pass ) -{ //render invisiprims; this doesn't work becaue it also blocks all the post-deferred stuff -#if 0 - LL_RECORD_BLOCK_TIME(FTM_RENDER_INVISIBLE); - - U32 invisi_mask = LLVertexBuffer::MAP_VERTEX; - glStencilMask(0); - glStencilOp(GL_ZERO, GL_KEEP, GL_REPLACE); - gGL.setColorMask(false, false); - pushBatches(LLRenderPass::PASS_INVISIBLE, invisi_mask, FALSE); - gGL.setColorMask(true, true); - glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); - glStencilMask(0xFFFFFFFF); - - if (gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY)) - { - beginShiny(true); - renderShiny(true); - endShiny(true); - } -#endif } diff --git a/indra/newview/lldrawpoolbump.h b/indra/newview/lldrawpoolbump.h index 4ad648c28f3bebc77156a7f35e31b7e879d384f9..e8a027967bcca922e44c560f2471874a1c22bed1 100644 --- a/indra/newview/lldrawpoolbump.h +++ b/indra/newview/lldrawpoolbump.h @@ -32,6 +32,8 @@ #include "lltextureentry.h" #include "lluuid.h" +#include <unordered_map> + class LLImageRaw; class LLSpatialGroup; class LLDrawInfo; @@ -46,52 +48,47 @@ protected : static U32 sVertexMask; BOOL mShiny; - virtual U32 getVertexDataMask() { return sVertexMask; } + virtual U32 getVertexDataMask() override { return sVertexMask; } LLDrawPoolBump(); - virtual void render(S32 pass = 0); - virtual void beginRenderPass( S32 pass ); - virtual void endRenderPass( S32 pass ); - virtual S32 getNumPasses(); - /*virtual*/ void prerender(); - /*virtual*/ void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures = FALSE); + virtual void render(S32 pass = 0) override; + virtual S32 getNumPasses() override; + /*virtual*/ void prerender() override; + void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures = FALSE) override; void renderBump(U32 type, U32 mask); - void renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture); + void renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture) override; S32 numBumpPasses(); - void beginShiny(bool invisible = false); - void renderShiny(bool invisible = false); - void endShiny(bool invisible = false); + void beginShiny(); + void renderShiny(); + void endShiny(); void beginFullbrightShiny(); void renderFullbrightShiny(); void endFullbrightShiny(); - void beginBump(U32 pass = LLRenderPass::PASS_BUMP); + void beginBump(); void renderBump(U32 pass = LLRenderPass::PASS_BUMP); void endBump(U32 pass = LLRenderPass::PASS_BUMP); - static void bindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel, bool invisible); - static void unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel, bool invisible); + static void bindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel); + static void unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel); - virtual S32 getNumDeferredPasses(); - /*virtual*/ void beginDeferredPass(S32 pass); - /*virtual*/ void endDeferredPass(S32 pass); - /*virtual*/ void renderDeferred(S32 pass); + virtual S32 getNumDeferredPasses() override; + /*virtual*/ void renderDeferred(S32 pass) override; - virtual S32 getNumPostDeferredPasses() { return 2; } - /*virtual*/ void beginPostDeferredPass(S32 pass); - /*virtual*/ void endPostDeferredPass(S32 pass); - /*virtual*/ void renderPostDeferred(S32 pass); + virtual S32 getNumPostDeferredPasses() override { return 1; } + /*virtual*/ void renderPostDeferred(S32 pass) override; static BOOL bindBumpMap(LLDrawInfo& params, S32 channel = -2); static BOOL bindBumpMap(LLFace* face, S32 channel = -2); private: static BOOL bindBumpMap(U8 bump_code, LLViewerTexture* tex, F32 vsize, S32 channel); + bool mRigged = false; // if true, doing a rigged pass }; @@ -161,17 +158,20 @@ class LLBumpImageList static void onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLImageRaw* src, LLUUID& source_asset_id, EBumpEffect bump ); private: - typedef absl::flat_hash_map<LLUUID, LLPointer<LLViewerTexture> > bump_image_map_t; + typedef std::unordered_map<LLUUID, LLPointer<LLViewerTexture> > bump_image_map_t; bump_image_map_t mBrightnessEntries; bump_image_map_t mDarknessEntries; + static LL::WorkQueue::weak_t sMainQueue; + static LL::WorkQueue::weak_t sTexUpdateQueue; + static LLRenderTarget sRenderTarget; }; extern LLBumpImageList gBumpImageList; -class LLDrawPoolInvisible final : public LLDrawPoolBump +class LLDrawPoolInvisible : public LLRenderPass { public: - LLDrawPoolInvisible() : LLDrawPoolBump(LLDrawPool::POOL_INVISIBLE) { } + LLDrawPoolInvisible() : LLRenderPass(LLDrawPool::POOL_INVISIBLE) { } enum { @@ -186,11 +186,6 @@ class LLDrawPoolInvisible final : public LLDrawPoolBump virtual void beginRenderPass( S32 pass ) { } virtual void endRenderPass( S32 pass ) { } virtual S32 getNumPasses() {return 1;} - - virtual S32 getNumDeferredPasses() { return 1; } - /*virtual*/ void beginDeferredPass(S32 pass); - /*virtual*/ void endDeferredPass(S32 pass); - /*virtual*/ void renderDeferred(S32 pass); }; diff --git a/indra/newview/lldrawpoolground.cpp b/indra/newview/lldrawpoolground.cpp index 535a7f92ca2d764bd7839413e777c91348c882a7..5b74264dab4cb2ddca721316f733de27ebe174fb 100644 --- a/indra/newview/lldrawpoolground.cpp +++ b/indra/newview/lldrawpoolground.cpp @@ -63,7 +63,7 @@ void LLDrawPoolGround::render(S32 pass) F32 water_height = gAgent.getRegion()->getWaterHeight(); gGL.pushMatrix(); - LLVector3 origin = LLViewerCamera::getInstanceFast()->getOrigin(); + LLVector3 origin = LLViewerCamera::getInstance()->getOrigin(); gGL.translatef(origin.mV[0], origin.mV[1], llmax(origin.mV[2], water_height)); LLFace *facep = mDrawFace[0]; diff --git a/indra/newview/lldrawpoolmaterials.cpp b/indra/newview/lldrawpoolmaterials.cpp index 29bc0f10a5f953cbcfd6aef270acf5f94b7f0243..67cbb30144794e695db6ebe6d9374dd9b263e731 100644 --- a/indra/newview/lldrawpoolmaterials.cpp +++ b/indra/newview/lldrawpoolmaterials.cpp @@ -31,6 +31,7 @@ #include "llviewershadermgr.h" #include "pipeline.h" #include "llglcommonfunc.h" +#include "llvoavatar.h" S32 diffuse_channel = -1; @@ -47,11 +48,20 @@ void LLDrawPoolMaterials::prerender() S32 LLDrawPoolMaterials::getNumDeferredPasses() { - return 12; + // 12 render passes times 2 (one for each rigged and non rigged) + return 12*2; } void LLDrawPoolMaterials::beginDeferredPass(S32 pass) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_MATERIAL; + + bool rigged = false; + if (pass >= 12) + { + rigged = true; + pass -= 12; + } U32 shader_idx[] = { 0, //LLRenderPass::PASS_MATERIAL, @@ -72,13 +82,22 @@ void LLDrawPoolMaterials::beginDeferredPass(S32 pass) 15, //LLRenderPass::PASS_NORMSPEC_GLOW, }; - mShader = &(gDeferredMaterialProgram[shader_idx[pass]]); - - if (LLPipeline::sUnderWaterRender) - { - mShader = &(gDeferredMaterialWaterProgram[shader_idx[pass]]); - } - + U32 idx = shader_idx[pass]; + + if (LLPipeline::sUnderWaterRender) + { + mShader = &(gDeferredMaterialWaterProgram[idx]); + } + else + { + mShader = &(gDeferredMaterialProgram[idx]); + } + + if (rigged) + { + llassert(mShader->mRiggedVariant != nullptr); + mShader = mShader->mRiggedVariant; + } mShader->bind(); if (LLPipeline::sRenderingHUDs) @@ -91,13 +110,11 @@ void LLDrawPoolMaterials::beginDeferredPass(S32 pass) } diffuse_channel = mShader->enableTexture(LLShaderMgr::DIFFUSE_MAP); - - LL_RECORD_BLOCK_TIME(FTM_RENDER_MATERIALS); } void LLDrawPoolMaterials::endDeferredPass(S32 pass) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_MATERIALS); + LL_PROFILE_ZONE_SCOPED_CATEGORY_MATERIAL; mShader->unbind(); @@ -106,6 +123,7 @@ void LLDrawPoolMaterials::endDeferredPass(S32 pass) void LLDrawPoolMaterials::renderDeferred(S32 pass) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_MATERIAL; static const U32 type_list[] = { LLRenderPass::PASS_MATERIAL, @@ -126,9 +144,20 @@ void LLDrawPoolMaterials::renderDeferred(S32 pass) LLRenderPass::PASS_NORMSPEC_EMISSIVE, }; + bool rigged = false; + if (pass >= 12) + { + rigged = true; + pass -= 12; + } + llassert(pass < sizeof(type_list)/sizeof(U32)); U32 type = type_list[pass]; + if (rigged) + { + type += 1; + } U32 mask = mShader->mAttributeMask; @@ -157,7 +186,10 @@ void LLDrawPoolMaterials::renderDeferred(S32 pass) mShader->setMinimumAlpha(params.mAlphaMaskCutoff); mShader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, params.mFullbright ? 1.f : 0.f); - pushBatch(params, mask, TRUE); + { + LL_PROFILE_ZONE_SCOPED_CATEGORY_MATERIAL; + pushMaterialsBatch(params, mask, rigged); + } } } @@ -171,51 +203,37 @@ void LLDrawPoolMaterials::bindNormalMap(LLViewerTexture* tex) mShader->bindTexture(LLShaderMgr::BUMP_MAP, tex); } -void LLDrawPoolMaterials::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures) +void LLDrawPoolMaterials::pushMaterialsBatch(LLDrawInfo& params, U32 mask, bool rigged) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_MATERIAL; applyModelMatrix(params); bool tex_setup = false; - const U32 tex_list_size = params.mTextureList.size(); - if (batch_textures && tex_list_size > 1) + //not batching textures or batch has only 1 texture -- might need a texture matrix + if (params.mTextureMatrix) { - for (U32 i = 0; i < tex_list_size; ++i) + //if (mShiny) { - LLViewerTexture* texturep = params.mTextureList[i]; - if (texturep) - { - gGL.getTexUnit(i)->bind(texturep, TRUE); - } + gGL.getTexUnit(0)->activate(); + gGL.matrixMode(LLRender::MM_TEXTURE); } - } - else - { //not batching textures or batch has only 1 texture -- might need a texture matrix - if (params.mTextureMatrix) - { - //if (mShiny) - { - gGL.getTexUnit(0)->activate(); - gGL.matrixMode(LLRender::MM_TEXTURE); - } - gGL.loadMatrix(*params.mTextureMatrix); - gPipeline.mTextureMatrixOps++; + gGL.loadMatrix(*params.mTextureMatrix); + gPipeline.mTextureMatrixOps++; - tex_setup = true; - } + tex_setup = true; + } - if (mShaderLevel > 1 && texture) + if (mShaderLevel > 1) + { + if (params.mTexture.notNull()) { - if (params.mTexture.notNull()) - { - gGL.getTexUnit(diffuse_channel)->bind(params.mTexture); - params.mTexture->addTextureStats(params.mVSize); - } - else - { - gGL.getTexUnit(diffuse_channel)->unbind(LLTexUnit::TT_TEXTURE); - } + gGL.getTexUnit(diffuse_channel)->bindFast(params.mTexture); + } + else + { + gGL.getTexUnit(diffuse_channel)->unbindFast(LLTexUnit::TT_TEXTURE); } } @@ -224,10 +242,28 @@ void LLDrawPoolMaterials::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, params.mGroup->rebuildMesh(); } + // upload matrix palette to shader + if (rigged && params.mAvatar.notNull()) + { + const LLVOAvatar::MatrixPaletteCache& mpc = params.mAvatar->updateSkinInfoMatrixPalette(params.mSkinInfo); + U32 count = mpc.mMatrixPalette.size(); + + if (count == 0) + { + //skin info not loaded yet, don't render + return; + } + + mShader->uniformMatrix3x4fv(LLViewerShaderMgr::AVATAR_MATRIX, + count, + FALSE, + (GLfloat*)&(mpc.mGLMp[0])); + } + LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test); - params.mVertexBuffer->setBuffer(mask); - params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); + params.mVertexBuffer->setBufferFast(mask); + params.mVertexBuffer->drawRangeFast(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); if (tex_setup) { diff --git a/indra/newview/lldrawpoolmaterials.h b/indra/newview/lldrawpoolmaterials.h index b25919c434fe712696ac989e4d4e3d90bd797911..dc99a204c125c1237f0e50ad6f2de97d5bd76577 100644 --- a/indra/newview/lldrawpoolmaterials.h +++ b/indra/newview/lldrawpoolmaterials.h @@ -55,21 +55,21 @@ class LLDrawPoolMaterials final : public LLRenderPass LLVertexBuffer::MAP_TANGENT }; - /*virtual*/ U32 getVertexDataMask() { return VERTEX_DATA_MASK; } + U32 getVertexDataMask() override { return VERTEX_DATA_MASK; } - /*virtual*/ void render(S32 pass = 0) { } - /*virtual*/ S32 getNumPasses() {return 0;} - /*virtual*/ void prerender(); + void render(S32 pass = 0) override { } + S32 getNumPasses() override {return 0;} + void prerender() override; - /*virtual*/ S32 getNumDeferredPasses(); - /*virtual*/ void beginDeferredPass(S32 pass); - /*virtual*/ void endDeferredPass(S32 pass); - /*virtual*/ void renderDeferred(S32 pass); + S32 getNumDeferredPasses() override; + void beginDeferredPass(S32 pass) override; + void endDeferredPass(S32 pass) override; + void renderDeferred(S32 pass) override; void bindSpecularMap(LLViewerTexture* tex); void bindNormalMap(LLViewerTexture* tex); - /*virtual*/ void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures = FALSE); + void pushMaterialsBatch(LLDrawInfo& params, U32 mask, bool rigged); }; #endif //LL_LLDRAWPOOLMATERIALS_H diff --git a/indra/newview/lldrawpoolsimple.cpp b/indra/newview/lldrawpoolsimple.cpp index 119b5dc5f86e57109924c1bf908568406af664e1..e324a663f4cddcae707721e86af35590c51d5d2b 100644 --- a/indra/newview/lldrawpoolsimple.cpp +++ b/indra/newview/lldrawpoolsimple.cpp @@ -38,30 +38,54 @@ #include "llrender.h" static LLGLSLShader* simple_shader = NULL; -static LLGLSLShader* fullbright_shader = NULL; static LLTrace::BlockTimerStatHandle FTM_RENDER_SIMPLE_DEFERRED("Deferred Simple"); static LLTrace::BlockTimerStatHandle FTM_RENDER_GRASS_DEFERRED("Deferred Grass"); -void LLDrawPoolGlow::beginPostDeferredPass(S32 pass) + +static void setup_simple_shader(LLGLSLShader* shader) { - gDeferredEmissiveProgram.bind(); - gDeferredEmissiveProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f); + shader->bind(); + if (LLPipeline::sRenderingHUDs) - { - gDeferredEmissiveProgram.uniform1i(LLShaderMgr::NO_ATMO, 1); - } - else - { - gDeferredEmissiveProgram.uniform1i(LLShaderMgr::NO_ATMO, 0); - } + { + shader->uniform1i(LLShaderMgr::NO_ATMO, 1); + } + else + { + shader->uniform1i(LLShaderMgr::NO_ATMO, 0); + } +} + +static void setup_glow_shader(LLGLSLShader* shader) +{ + setup_simple_shader(shader); + if (LLPipeline::sRenderDeferred && !LLPipeline::sRenderingHUDs) + { + shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f); + } + else + { + shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.f); + } +} + +static void setup_fullbright_shader(LLGLSLShader* shader) +{ + setup_glow_shader(shader); + shader->uniform1f(LLViewerShaderMgr::FULLBRIGHT, 1.f); } -static LLTrace::BlockTimerStatHandle FTM_RENDER_GLOW_PUSH("Glow Push"); void LLDrawPoolGlow::renderPostDeferred(S32 pass) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_GLOW); + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_GLOW); + render(&gDeferredEmissiveProgram); +} + +void LLDrawPoolGlow::render(LLGLSLShader* shader) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_GLOW); LLGLEnable blend(GL_BLEND); LLGLDisable test(GL_ALPHA_TEST); gGL.flush(); @@ -73,81 +97,29 @@ void LLDrawPoolGlow::renderPostDeferred(S32 pass) LLGLDepthTest depth(GL_TRUE, GL_FALSE); gGL.setColorMask(false, true); - { - LL_RECORD_BLOCK_TIME(FTM_RENDER_GLOW_PUSH); - pushBatches(LLRenderPass::PASS_GLOW, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); - } - - gGL.setColorMask(true, false); - gGL.setSceneBlendType(LLRender::BT_ALPHA); -} - -void LLDrawPoolGlow::endPostDeferredPass(S32 pass) -{ - gDeferredEmissiveProgram.unbind(); - LLRenderPass::endRenderPass(pass); + //first pass -- static objects + setup_glow_shader(shader); + pushBatches(LLRenderPass::PASS_GLOW, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + + // second pass -- rigged objects + shader = shader->mRiggedVariant; + setup_glow_shader(shader); + pushRiggedBatches(LLRenderPass::PASS_GLOW_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + + gGL.setColorMask(true, false); + gGL.setSceneBlendType(LLRender::BT_ALPHA); } S32 LLDrawPoolGlow::getNumPasses() { - if (LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 0) - { - return 1; - } - else - { - return 0; - } + return 1; } void LLDrawPoolGlow::render(S32 pass) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_GLOW); - LLGLEnable blend(GL_BLEND); - LLGLDisable test(GL_ALPHA_TEST); - gGL.flush(); - /// Get rid of z-fighting with non-glow pass. - LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL); - glPolygonOffset(-1.0f, -1.0f); - gGL.setSceneBlendType(LLRender::BT_ADD); - - U32 shader_level = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT); - - //should never get here without basic shaders enabled - llassert(shader_level > 0); - - LLGLSLShader* shader = LLPipeline::sUnderWaterRender ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram; - shader->bind(); - if (LLPipeline::sRenderDeferred) - { - shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f); - } - else - { - shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.f); - } - - if (LLPipeline::sRenderingHUDs) - { - shader->uniform1i(LLShaderMgr::NO_ATMO, 1); - } - else - { - shader->uniform1i(LLShaderMgr::NO_ATMO, 0); - } - - LLGLDepthTest depth(GL_TRUE, GL_FALSE); - gGL.setColorMask(false, true); - - pushBatches(LLRenderPass::PASS_GLOW, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); - - gGL.setColorMask(true, false); - gGL.setSceneBlendType(LLRender::BT_ALPHA); - - if (shader_level > 0 && fullbright_shader) - { - shader->unbind(); - } + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; + LLGLSLShader* shader = LLPipeline::sUnderWaterRender ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram; + render(shader); } LLDrawPoolSimple::LLDrawPoolSimple() : @@ -160,100 +132,73 @@ void LLDrawPoolSimple::prerender() mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT); } -void LLDrawPoolSimple::beginRenderPass(S32 pass) +S32 LLDrawPoolSimple::getNumPasses() { - LL_RECORD_BLOCK_TIME(FTM_RENDER_SIMPLE); - - if (LLPipeline::sImpostorRender) - { - simple_shader = &gObjectSimpleImpostorProgram; - } - else if (LLPipeline::sUnderWaterRender) - { - simple_shader = &gObjectSimpleWaterProgram; - } - else - { - simple_shader = &gObjectSimpleProgram; - } - - if (mShaderLevel > 0) - { - simple_shader->bind(); - - if (LLPipeline::sRenderingHUDs) - { - simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 1); - } - else - { - simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 0); - } - } - else - { - // don't use shaders! - if (gGLManager.mHasShaderObjects) - { - LLGLSLShader::bindNoShader(); - } - } -} - -void LLDrawPoolSimple::endRenderPass(S32 pass) -{ - LL_RECORD_BLOCK_TIME(FTM_RENDER_SIMPLE); - stop_glerror(); - LLRenderPass::endRenderPass(pass); - stop_glerror(); - if (mShaderLevel > 0) - { - simple_shader->unbind(); - } + return 1; } void LLDrawPoolSimple::render(S32 pass) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_SIMPLE); + LLGLDisable blend(GL_BLEND); + LLGLSLShader* shader = nullptr; + if (LLPipeline::sImpostorRender) + { + shader = &gObjectSimpleImpostorProgram; + } + else if (LLPipeline::sUnderWaterRender) + { + shader = &gObjectSimpleWaterProgram; + } + else + { + shader = &gObjectSimpleProgram; + } + { //render simple - LL_RECORD_BLOCK_TIME(FTM_RENDER_SIMPLE); + gPipeline.enableLightsDynamic(); - if (mShaderLevel > 0) - { - U32 mask = getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX; - - pushBatches(LLRenderPass::PASS_SIMPLE, mask, TRUE, TRUE); - - if (LLPipeline::sRenderDeferred) - { //if deferred rendering is enabled, bump faces aren't registered as simple - //render bump faces here as simple so bump faces will appear under water - pushBatches(LLRenderPass::PASS_BUMP, mask, TRUE, TRUE); - pushBatches(LLRenderPass::PASS_MATERIAL, mask, TRUE, TRUE); - pushBatches(LLRenderPass::PASS_SPECMAP, mask, TRUE, TRUE); - pushBatches(LLRenderPass::PASS_NORMMAP, mask, TRUE, TRUE); - pushBatches(LLRenderPass::PASS_NORMSPEC, mask, TRUE, TRUE); - } - } - else - { - LLGLDisable alpha_test(GL_ALPHA_TEST); - renderTexture(LLRenderPass::PASS_SIMPLE, getVertexDataMask()); - } - + U32 mask = getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX; + + // first pass -- static objects + { + setup_simple_shader(shader); + pushBatches(LLRenderPass::PASS_SIMPLE, mask, TRUE, TRUE); + + if (LLPipeline::sRenderDeferred) + { //if deferred rendering is enabled, bump faces aren't registered as simple + //render bump faces here as simple so bump faces will appear under water + pushBatches(LLRenderPass::PASS_BUMP, mask, TRUE, TRUE); + pushBatches(LLRenderPass::PASS_MATERIAL, mask, TRUE, TRUE); + pushBatches(LLRenderPass::PASS_SPECMAP, mask, TRUE, TRUE); + pushBatches(LLRenderPass::PASS_NORMMAP, mask, TRUE, TRUE); + pushBatches(LLRenderPass::PASS_NORMSPEC, mask, TRUE, TRUE); + } + } + + //second pass, rigged + { + shader = shader->mRiggedVariant; + setup_simple_shader(shader); + pushRiggedBatches(LLRenderPass::PASS_SIMPLE_RIGGED, mask, TRUE, TRUE); + + if (LLPipeline::sRenderDeferred) + { //if deferred rendering is enabled, bump faces aren't registered as simple + //render bump faces here as simple so bump faces will appear under water + pushRiggedBatches(LLRenderPass::PASS_BUMP_RIGGED, mask, TRUE, TRUE); + pushRiggedBatches(LLRenderPass::PASS_MATERIAL_RIGGED, mask, TRUE, TRUE); + pushRiggedBatches(LLRenderPass::PASS_SPECMAP_RIGGED, mask, TRUE, TRUE); + pushRiggedBatches(LLRenderPass::PASS_NORMMAP_RIGGED, mask, TRUE, TRUE); + pushRiggedBatches(LLRenderPass::PASS_NORMSPEC_RIGGED, mask, TRUE, TRUE); + } + } } } - - - - - - - - static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_MASK("Alpha Mask"); LLDrawPoolAlphaMask::LLDrawPoolAlphaMask() : @@ -266,85 +211,36 @@ void LLDrawPoolAlphaMask::prerender() mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT); } -void LLDrawPoolAlphaMask::beginRenderPass(S32 pass) -{ - LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_MASK); - - if (LLPipeline::sUnderWaterRender) - { - simple_shader = &gObjectSimpleWaterAlphaMaskProgram; - } - else - { - simple_shader = &gObjectSimpleAlphaMaskProgram; - } - - if (mShaderLevel > 0) - { - simple_shader->bind(); - - if (LLPipeline::sRenderingHUDs) - { - simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 1); - } - else - { - simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 0); - } - } - else - { - // don't use shaders! - if (gGLManager.mHasShaderObjects) - { - LLGLSLShader::bindNoShader(); - } - } -} - -void LLDrawPoolAlphaMask::endRenderPass(S32 pass) -{ - LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_MASK); - stop_glerror(); - LLRenderPass::endRenderPass(pass); - stop_glerror(); - if (mShaderLevel > 0) - { - simple_shader->unbind(); - } -} - void LLDrawPoolAlphaMask::render(S32 pass) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; LLGLDisable blend(GL_BLEND); - LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_MASK); - if (mShaderLevel > 0) - { - simple_shader->bind(); - simple_shader->setMinimumAlpha(0.33f); + LLGLSLShader* shader = nullptr; + if (LLPipeline::sUnderWaterRender) + { + shader = &gObjectSimpleWaterAlphaMaskProgram; + } + else + { + shader = &gObjectSimpleAlphaMaskProgram; + } - if (LLPipeline::sRenderingHUDs) - { - simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 1); - } - else - { - simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 0); - } + // render static + setup_simple_shader(shader); + pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + pushMaskBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + pushMaskBatches(LLRenderPass::PASS_SPECMAP_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + pushMaskBatches(LLRenderPass::PASS_NORMMAP_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + pushMaskBatches(LLRenderPass::PASS_NORMSPEC_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); - pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); - pushMaskBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); - pushMaskBatches(LLRenderPass::PASS_SPECMAP_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); - pushMaskBatches(LLRenderPass::PASS_NORMMAP_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); - pushMaskBatches(LLRenderPass::PASS_NORMSPEC_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); - } - else - { - LLGLEnable test(GL_ALPHA_TEST); - pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask(), TRUE, FALSE); - gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); //OK - } + // render rigged + setup_simple_shader(shader->mRiggedVariant); + pushRiggedMaskBatches(LLRenderPass::PASS_ALPHA_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + pushRiggedMaskBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + pushRiggedMaskBatches(LLRenderPass::PASS_SPECMAP_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + pushRiggedMaskBatches(LLRenderPass::PASS_NORMMAP_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + pushRiggedMaskBatches(LLRenderPass::PASS_NORMSPEC_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); } LLDrawPoolFullbrightAlphaMask::LLDrawPoolFullbrightAlphaMask() : @@ -357,166 +253,70 @@ void LLDrawPoolFullbrightAlphaMask::prerender() mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT); } -void LLDrawPoolFullbrightAlphaMask::beginRenderPass(S32 pass) +void LLDrawPoolFullbrightAlphaMask::render(S32 pass) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_MASK); - - if (LLPipeline::sUnderWaterRender) - { - simple_shader = &gObjectFullbrightWaterAlphaMaskProgram; - } - else - { - simple_shader = &gObjectFullbrightAlphaMaskProgram; - } - - if (mShaderLevel > 0) - { - simple_shader->bind(); - - if (LLPipeline::sRenderingHUDs) - { - simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 1); - } - else - { - simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 0); - } - } - else - { - // don't use shaders! - if (gGLManager.mHasShaderObjects) - { - LLGLSLShader::bindNoShader(); - } - } -} + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_MASK); -void LLDrawPoolFullbrightAlphaMask::endRenderPass(S32 pass) -{ - LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_MASK); - stop_glerror(); - LLRenderPass::endRenderPass(pass); - stop_glerror(); - if (mShaderLevel > 0) - { - simple_shader->unbind(); - } -} + LLGLSLShader* shader = nullptr; + if (LLPipeline::sUnderWaterRender) + { + shader = &gObjectFullbrightWaterAlphaMaskProgram; + } + else + { + shader = &gObjectFullbrightAlphaMaskProgram; + } -void LLDrawPoolFullbrightAlphaMask::render(S32 pass) -{ - LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_MASK); + // render static + setup_fullbright_shader(shader); + pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); - if (mShaderLevel > 0) - { - if (simple_shader) - { - simple_shader->bind(); - simple_shader->setMinimumAlpha(0.33f); - - if (LLPipeline::sRenderingHUDs) - { - simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 1); - simple_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f); - } - else - { - simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 0); - if (LLPipeline::sRenderDeferred) - { - simple_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f); - } - else - { - simple_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f); - } - } - } - pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); - //LLGLSLShader::bindNoShader(); - } - else - { - LLGLEnable test(GL_ALPHA_TEST); - gPipeline.enableLightsFullbright(); - pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask(), TRUE, FALSE); - gPipeline.enableLightsDynamic(); - gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); //OK - } + // render rigged + setup_fullbright_shader(shader->mRiggedVariant); + pushRiggedMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); } //=============================== //DEFERRED IMPLEMENTATION //=============================== -void LLDrawPoolSimple::beginDeferredPass(S32 pass) -{ - LL_RECORD_BLOCK_TIME(FTM_RENDER_SIMPLE_DEFERRED); - gDeferredDiffuseProgram.bind(); - - if (LLPipeline::sRenderingHUDs) - { - gDeferredDiffuseProgram.uniform1i(LLShaderMgr::NO_ATMO, 1); - } - else - { - gDeferredDiffuseProgram.uniform1i(LLShaderMgr::NO_ATMO, 0); - } -} - -void LLDrawPoolSimple::endDeferredPass(S32 pass) +S32 LLDrawPoolSimple::getNumDeferredPasses() { - LL_RECORD_BLOCK_TIME(FTM_RENDER_SIMPLE_DEFERRED); - LLRenderPass::endRenderPass(pass); - - gDeferredDiffuseProgram.unbind(); + return 1; } void LLDrawPoolSimple::renderDeferred(S32 pass) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_SIMPLE_DEFERRED); LLGLDisable blend(GL_BLEND); LLGLDisable alpha_test(GL_ALPHA_TEST); - { //render simple - LL_RECORD_BLOCK_TIME(FTM_RENDER_SIMPLE_DEFERRED); - pushBatches(LLRenderPass::PASS_SIMPLE, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); - } + //render static + setup_simple_shader(&gDeferredDiffuseProgram); + pushBatches(LLRenderPass::PASS_SIMPLE, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + + //render rigged + setup_simple_shader(gDeferredDiffuseProgram.mRiggedVariant); + pushRiggedBatches(LLRenderPass::PASS_SIMPLE_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); } static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_MASK_DEFERRED("Deferred Alpha Mask"); -void LLDrawPoolAlphaMask::beginDeferredPass(S32 pass) -{ - -} - -void LLDrawPoolAlphaMask::endDeferredPass(S32 pass) -{ - -} void LLDrawPoolAlphaMask::renderDeferred(S32 pass) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_MASK_DEFERRED); - gDeferredDiffuseAlphaMaskProgram.bind(); - gDeferredDiffuseAlphaMaskProgram.setMinimumAlpha(0.33f); + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_MASK_DEFERRED); + LLGLSLShader* shader = &gDeferredDiffuseAlphaMaskProgram; - if (LLPipeline::sRenderingHUDs) - { - gDeferredDiffuseAlphaMaskProgram.uniform1i(LLShaderMgr::NO_ATMO, 1); - } - else - { - gDeferredDiffuseAlphaMaskProgram.uniform1i(LLShaderMgr::NO_ATMO, 0); - } + //render static + setup_simple_shader(shader); + pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); - pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); - gDeferredDiffuseAlphaMaskProgram.unbind(); + //render rigged + setup_simple_shader(shader->mRiggedVariant); + pushRiggedMaskBatches(LLRenderPass::PASS_ALPHA_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); } - // grass drawpool LLDrawPoolGrass::LLDrawPoolGrass() : LLRenderPass(POOL_GRASS) @@ -532,7 +332,7 @@ void LLDrawPoolGrass::prerender() void LLDrawPoolGrass::beginRenderPass(S32 pass) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_GRASS); + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_GRASS); stop_glerror(); if (LLPipeline::sUnderWaterRender) @@ -559,18 +359,14 @@ void LLDrawPoolGrass::beginRenderPass(S32 pass) } else { - gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); - // don't use shaders! - if (gGLManager.mHasShaderObjects) - { - LLGLSLShader::bindNoShader(); - } + gGL.flush(); + LLGLSLShader::bindNoShader(); } } void LLDrawPoolGrass::endRenderPass(S32 pass) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_GRASS); + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_GRASS); LLRenderPass::endRenderPass(pass); if (mShaderLevel > 0) @@ -579,20 +375,21 @@ void LLDrawPoolGrass::endRenderPass(S32 pass) } else { - gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); + gGL.flush(); } } void LLDrawPoolGrass::render(S32 pass) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; LLGLDisable blend(GL_BLEND); { - LL_RECORD_BLOCK_TIME(FTM_RENDER_GRASS); + //LL_RECORD_BLOCK_TIME(FTM_RENDER_GRASS); LLGLEnable test(GL_ALPHA_TEST); gGL.setSceneBlendType(LLRender::BT_ALPHA); //render grass - LLRenderPass::renderTexture(LLRenderPass::PASS_GRASS, getVertexDataMask()); + LLRenderPass::pushBatches(LLRenderPass::PASS_GRASS, getVertexDataMask()); } } @@ -608,8 +405,9 @@ void LLDrawPoolGrass::endDeferredPass(S32 pass) void LLDrawPoolGrass::renderDeferred(S32 pass) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; { - LL_RECORD_BLOCK_TIME(FTM_RENDER_GRASS_DEFERRED); + //LL_RECORD_BLOCK_TIME(FTM_RENDER_GRASS_DEFERRED); gDeferredNonIndexedDiffuseAlphaMaskProgram.bind(); gDeferredNonIndexedDiffuseAlphaMaskProgram.setMinimumAlpha(0.5f); @@ -623,7 +421,7 @@ void LLDrawPoolGrass::renderDeferred(S32 pass) } //render grass - LLRenderPass::renderTexture(LLRenderPass::PASS_GRASS, getVertexDataMask()); + LLRenderPass::pushBatches(LLRenderPass::PASS_GRASS, getVertexDataMask()); } } @@ -639,120 +437,67 @@ void LLDrawPoolFullbright::prerender() mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT); } -void LLDrawPoolFullbright::beginPostDeferredPass(S32 pass) -{ - if (LLPipeline::sUnderWaterRender) - { - gDeferredFullbrightWaterProgram.bind(); - } - else - { - gDeferredFullbrightProgram.bind(); - - if (LLPipeline::sRenderingHUDs) - { - gDeferredFullbrightProgram.uniform1i(LLShaderMgr::NO_ATMO, 1); - } - else - { - gDeferredFullbrightProgram.uniform1i(LLShaderMgr::NO_ATMO, 0); - } - } - -} void LLDrawPoolFullbright::renderPostDeferred(S32 pass) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_FULLBRIGHT); - - gGL.setSceneBlendType(LLRender::BT_ALPHA); - U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX; - pushBatches(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask, TRUE, TRUE); -} - -void LLDrawPoolFullbright::endPostDeferredPass(S32 pass) -{ - if (LLPipeline::sUnderWaterRender) - { - gDeferredFullbrightWaterProgram.unbind(); - } - else - { - gDeferredFullbrightProgram.unbind(); - } - LLRenderPass::endRenderPass(pass); -} - -void LLDrawPoolFullbright::beginRenderPass(S32 pass) -{ - LL_RECORD_BLOCK_TIME(FTM_RENDER_FULLBRIGHT); - - if (LLPipeline::sUnderWaterRender) - { - fullbright_shader = &gObjectFullbrightWaterProgram; - } - else - { - fullbright_shader = &gObjectFullbrightProgram; - } -} - -void LLDrawPoolFullbright::endRenderPass(S32 pass) -{ - LL_RECORD_BLOCK_TIME(FTM_RENDER_FULLBRIGHT); - LLRenderPass::endRenderPass(pass); + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_FULLBRIGHT); - stop_glerror(); - - if (mShaderLevel > 0) - { - fullbright_shader->unbind(); - } + LLGLSLShader* shader = nullptr; + if (LLPipeline::sUnderWaterRender) + { + shader = &gDeferredFullbrightWaterProgram; + } + else + { + shader = &gDeferredFullbrightProgram; + } - stop_glerror(); + gGL.setSceneBlendType(LLRender::BT_ALPHA); + U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX; + + // render static + setup_fullbright_shader(shader); + pushBatches(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask, TRUE, TRUE); + + // render rigged + setup_fullbright_shader(shader->mRiggedVariant); + pushRiggedBatches(LLRenderPass::PASS_FULLBRIGHT_RIGGED, fullbright_mask, TRUE, TRUE); } void LLDrawPoolFullbright::render(S32 pass) { //render fullbright - LL_RECORD_BLOCK_TIME(FTM_RENDER_FULLBRIGHT); + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_FULLBRIGHT); gGL.setSceneBlendType(LLRender::BT_ALPHA); stop_glerror(); + LLGLSLShader* shader = nullptr; + if (LLPipeline::sUnderWaterRender) + { + shader = &gObjectFullbrightWaterProgram; + } + else + { + shader = &gObjectFullbrightProgram; + } - if (mShaderLevel > 0) - { - fullbright_shader->bind(); - fullbright_shader->uniform1f(LLViewerShaderMgr::FULLBRIGHT, 1.f); - fullbright_shader->uniform1f(LLViewerShaderMgr::TEXTURE_GAMMA, 1.f); - - if (LLPipeline::sRenderingHUDs) - { - fullbright_shader->uniform1i(LLShaderMgr::NO_ATMO, 1); - } - else - { - fullbright_shader->uniform1i(LLShaderMgr::NO_ATMO, 0); - } - U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX; - pushBatches(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask, TRUE, TRUE); - pushBatches(LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, fullbright_mask, TRUE, TRUE); - pushBatches(LLRenderPass::PASS_SPECMAP_EMISSIVE, fullbright_mask, TRUE, TRUE); - pushBatches(LLRenderPass::PASS_NORMMAP_EMISSIVE, fullbright_mask, TRUE, TRUE); - pushBatches(LLRenderPass::PASS_NORMSPEC_EMISSIVE, fullbright_mask, TRUE, TRUE); - } - else - { - gPipeline.enableLightsFullbright(); - U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR; - renderTexture(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask); - pushBatches(LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, fullbright_mask); - pushBatches(LLRenderPass::PASS_SPECMAP_EMISSIVE, fullbright_mask); - pushBatches(LLRenderPass::PASS_NORMMAP_EMISSIVE, fullbright_mask); - pushBatches(LLRenderPass::PASS_NORMSPEC_EMISSIVE, fullbright_mask); - } + U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX; - stop_glerror(); + // render static + setup_fullbright_shader(shader); + pushBatches(LLRenderPass::PASS_FULLBRIGHT, mask, TRUE, TRUE); + pushBatches(LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, mask, TRUE, TRUE); + pushBatches(LLRenderPass::PASS_SPECMAP_EMISSIVE, mask, TRUE, TRUE); + pushBatches(LLRenderPass::PASS_NORMMAP_EMISSIVE, mask, TRUE, TRUE); + pushBatches(LLRenderPass::PASS_NORMSPEC_EMISSIVE, mask, TRUE, TRUE); + + // render rigged + setup_fullbright_shader(shader->mRiggedVariant); + pushRiggedBatches(LLRenderPass::PASS_FULLBRIGHT_RIGGED, mask, TRUE, TRUE); + pushRiggedBatches(LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE_RIGGED, mask, TRUE, TRUE); + pushRiggedBatches(LLRenderPass::PASS_SPECMAP_EMISSIVE_RIGGED, mask, TRUE, TRUE); + pushRiggedBatches(LLRenderPass::PASS_NORMMAP_EMISSIVE_RIGGED, mask, TRUE, TRUE); + pushRiggedBatches(LLRenderPass::PASS_NORMSPEC_EMISSIVE_RIGGED, mask, TRUE, TRUE); } S32 LLDrawPoolFullbright::getNumPasses() @@ -760,65 +505,40 @@ S32 LLDrawPoolFullbright::getNumPasses() return 1; } - -void LLDrawPoolFullbrightAlphaMask::beginPostDeferredPass(S32 pass) +void LLDrawPoolFullbrightAlphaMask::renderPostDeferred(S32 pass) { - + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_FULLBRIGHT); + + LLGLSLShader* shader = nullptr; if (LLPipeline::sRenderingHUDs) { - gObjectFullbrightAlphaMaskProgram.bind(); - gObjectFullbrightAlphaMaskProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f); - gObjectFullbrightAlphaMaskProgram.uniform1i(LLShaderMgr::NO_ATMO, 1); + shader = &gObjectFullbrightAlphaMaskProgram; } - else if (LLPipeline::sRenderDeferred) - { + else if (LLPipeline::sRenderDeferred) + { if (LLPipeline::sUnderWaterRender) - { - gDeferredFullbrightAlphaMaskWaterProgram.bind(); - gDeferredFullbrightAlphaMaskWaterProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f); - gDeferredFullbrightAlphaMaskWaterProgram.uniform1i(LLShaderMgr::NO_ATMO, 1); - } - else - { - gDeferredFullbrightAlphaMaskProgram.bind(); - gDeferredFullbrightAlphaMaskProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f); - gDeferredFullbrightAlphaMaskProgram.uniform1i(LLShaderMgr::NO_ATMO, 0); - } + { + shader = &gDeferredFullbrightAlphaMaskWaterProgram; + } + else + { + shader = &gDeferredFullbrightAlphaMaskProgram; + } } else { - gObjectFullbrightAlphaMaskProgram.bind(); - gObjectFullbrightAlphaMaskProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f); - gObjectFullbrightAlphaMaskProgram.uniform1i(LLShaderMgr::NO_ATMO, 0); - } -} + shader = &gObjectFullbrightAlphaMaskProgram; + } -void LLDrawPoolFullbrightAlphaMask::renderPostDeferred(S32 pass) -{ - LL_RECORD_BLOCK_TIME(FTM_RENDER_FULLBRIGHT); LLGLDisable blend(GL_BLEND); U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX; - pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, fullbright_mask, TRUE, TRUE); + + // render static + setup_fullbright_shader(shader); + pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, fullbright_mask, TRUE, TRUE); + + // render rigged + setup_fullbright_shader(shader->mRiggedVariant); + pushRiggedMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK_RIGGED, fullbright_mask, TRUE, TRUE); } -void LLDrawPoolFullbrightAlphaMask::endPostDeferredPass(S32 pass) -{ - if (LLPipeline::sRenderingHUDs || !LLPipeline::sRenderDeferred) - { - gObjectFullbrightAlphaMaskProgram.unbind(); - } - else - { - if (LLPipeline::sUnderWaterRender) - { - gDeferredFullbrightAlphaMaskWaterProgram.unbind(); - } - else - { - gDeferredFullbrightAlphaMaskProgram.unbind(); - } - } - LLRenderPass::endRenderPass(pass); -} - - diff --git a/indra/newview/lldrawpoolsimple.h b/indra/newview/lldrawpoolsimple.h index ad1d626cf26361ddcdc65db7cc3ae38fb2e97105..ae0be95f47c48f68c6badaa6bd98a419406d0b3d 100644 --- a/indra/newview/lldrawpoolsimple.h +++ b/indra/newview/lldrawpoolsimple.h @@ -29,6 +29,8 @@ #include "lldrawpool.h" +class LLGLSLShader; + class LLDrawPoolSimple final : public LLRenderPass { public: @@ -39,22 +41,17 @@ class LLDrawPoolSimple final : public LLRenderPass LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR }; - virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; } + virtual U32 getVertexDataMask() override { return VERTEX_DATA_MASK; } LLDrawPoolSimple(); - /*virtual*/ S32 getNumDeferredPasses() { return 1; } - /*virtual*/ void beginDeferredPass(S32 pass); - /*virtual*/ void endDeferredPass(S32 pass); - /*virtual*/ void renderDeferred(S32 pass); + S32 getNumDeferredPasses() override; + void renderDeferred(S32 pass) override; - /*virtual*/ void beginRenderPass(S32 pass); - /*virtual*/ void endRenderPass(S32 pass); /// We need two passes so we can handle emissive materials separately. - /*virtual*/ S32 getNumPasses() { return 1; } - /*virtual*/ void render(S32 pass = 0); - /*virtual*/ void prerender(); - + S32 getNumPasses() override; + void render(S32 pass = 0) override; + void prerender() override; }; class LLDrawPoolGrass final : public LLRenderPass @@ -99,13 +96,9 @@ class LLDrawPoolAlphaMask final : public LLRenderPass LLDrawPoolAlphaMask(); /*virtual*/ S32 getNumDeferredPasses() { return 1; } - /*virtual*/ void beginDeferredPass(S32 pass); - /*virtual*/ void endDeferredPass(S32 pass); /*virtual*/ void renderDeferred(S32 pass); /*virtual*/ S32 getNumPasses() { return 1; } - /*virtual*/ void beginRenderPass(S32 pass); - /*virtual*/ void endRenderPass(S32 pass); /*virtual*/ void render(S32 pass = 0); /*virtual*/ void prerender(); @@ -125,13 +118,9 @@ class LLDrawPoolFullbrightAlphaMask final : public LLRenderPass LLDrawPoolFullbrightAlphaMask(); /*virtual*/ S32 getNumPostDeferredPasses() { return 1; } - /*virtual*/ void beginPostDeferredPass(S32 pass); - /*virtual*/ void endPostDeferredPass(S32 pass); /*virtual*/ void renderPostDeferred(S32 pass); /*virtual*/ S32 getNumPasses() { return 1; } - /*virtual*/ void beginRenderPass(S32 pass); - /*virtual*/ void endRenderPass(S32 pass); /*virtual*/ void render(S32 pass = 0); /*virtual*/ void prerender(); }; @@ -151,12 +140,8 @@ class LLDrawPoolFullbright final : public LLRenderPass LLDrawPoolFullbright(); /*virtual*/ S32 getNumPostDeferredPasses() { return 1; } - /*virtual*/ void beginPostDeferredPass(S32 pass); - /*virtual*/ void endPostDeferredPass(S32 pass); /*virtual*/ void renderPostDeferred(S32 pass); - /*virtual*/ void beginRenderPass(S32 pass); - /*virtual*/ void endRenderPass(S32 pass); /*virtual*/ S32 getNumPasses(); /*virtual*/ void render(S32 pass = 0); /*virtual*/ void prerender(); @@ -180,10 +165,10 @@ class LLDrawPoolGlow final : public LLRenderPass virtual void prerender() { } /*virtual*/ S32 getNumPostDeferredPasses() { return 1; } - /*virtual*/ void beginPostDeferredPass(S32 pass); - /*virtual*/ void endPostDeferredPass(S32 pass); /*virtual*/ void renderPostDeferred(S32 pass); + void render(LLGLSLShader* shader); + /*virtual*/ S32 getNumPasses(); void render(S32 pass = 0); diff --git a/indra/newview/lldrawpoolsky.cpp b/indra/newview/lldrawpoolsky.cpp index 3fd3e78e3bcf932b725d0e7b9d26928c34ebcd63..3a1efec91b712bc3292af056b0253f28d87fc6c6 100644 --- a/indra/newview/lldrawpoolsky.cpp +++ b/indra/newview/lldrawpoolsky.cpp @@ -76,29 +76,15 @@ void LLDrawPoolSky::render(S32 pass) } - if (LLGLSLShader::sNoFixedFunction) - { //just use the UI shader (generic single texture no lighting) - gOneTextureNoColorProgram.bind(); - } - else - { - // don't use shaders! - if (gGLManager.mHasShaderObjects) - { - // Ironically, we must support shader objects to be - // able to use this call. - LLGLSLShader::bindNoShader(); - } - mShader = NULL; - } - + //just use the UI shader (generic single texture no lighting) + gOneTextureNoColorProgram.bind(); LLGLSPipelineDepthTestSkyBox gls_skybox(true, false); - LLGLEnable fog_enable( (mShaderLevel < 1 && LLViewerCamera::getInstanceFast()->cameraUnderWater()) ? GL_FOG : 0); + LLGLEnable fog_enable( (mShaderLevel < 1 && LLViewerCamera::getInstance()->cameraUnderWater()) ? GL_FOG : 0); gGL.pushMatrix(); - LLVector3 origin = LLViewerCamera::getInstanceFast()->getOrigin(); + LLVector3 origin = LLViewerCamera::getInstance()->getOrigin(); gGL.translatef(origin.mV[0], origin.mV[1], origin.mV[2]); S32 face_count = (S32)mDrawFace.size(); diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index b522587c658a1148dd108d623bc714e167624d3c..ba0c6767a0cf71f9836977adb40c8a5d419f85b8 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -108,7 +108,7 @@ void LLDrawPoolTerrain::prerender() void LLDrawPoolTerrain::beginRenderPass( S32 pass ) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_TERRAIN); + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_TERRAIN); LLFacePool::beginRenderPass(pass); sShader = LLPipeline::sUnderWaterRender ? @@ -123,7 +123,7 @@ void LLDrawPoolTerrain::beginRenderPass( S32 pass ) void LLDrawPoolTerrain::endRenderPass( S32 pass ) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_TERRAIN); + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_TERRAIN); //LLFacePool::endRenderPass(pass); if (mShaderLevel > 1 && sShader->mShaderLevel > 0) { @@ -151,7 +151,7 @@ void LLDrawPoolTerrain::boostTerrainDetailTextures() void LLDrawPoolTerrain::render(S32 pass) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_TERRAIN); + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_TERRAIN); if (mDrawFace.empty()) { @@ -194,7 +194,7 @@ void LLDrawPoolTerrain::render(S32 pass) void LLDrawPoolTerrain::beginDeferredPass(S32 pass) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_TERRAIN); + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_TERRAIN); LLFacePool::beginRenderPass(pass); sShader = LLPipeline::sUnderWaterRender ? &gDeferredTerrainWaterProgram : &gDeferredTerrainProgram; @@ -204,14 +204,14 @@ void LLDrawPoolTerrain::beginDeferredPass(S32 pass) void LLDrawPoolTerrain::endDeferredPass(S32 pass) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_TERRAIN); + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_TERRAIN); LLFacePool::endRenderPass(pass); sShader->unbind(); } void LLDrawPoolTerrain::renderDeferred(S32 pass) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_TERRAIN); + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_TERRAIN); if (mDrawFace.empty()) { return; @@ -232,25 +232,25 @@ void LLDrawPoolTerrain::renderDeferred(S32 pass) void LLDrawPoolTerrain::beginShadowPass(S32 pass) { - LL_RECORD_BLOCK_TIME(FTM_SHADOW_TERRAIN); + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_SHADOW_TERRAIN); LLFacePool::beginRenderPass(pass); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); gDeferredShadowProgram.bind(); - LLEnvironment& environment = LLEnvironment::instanceFast(); + LLEnvironment& environment = LLEnvironment::instance(); gDeferredShadowProgram.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0); } void LLDrawPoolTerrain::endShadowPass(S32 pass) { - LL_RECORD_BLOCK_TIME(FTM_SHADOW_TERRAIN); + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_SHADOW_TERRAIN); LLFacePool::endRenderPass(pass); gDeferredShadowProgram.unbind(); } void LLDrawPoolTerrain::renderShadow(S32 pass) { - LL_RECORD_BLOCK_TIME(FTM_SHADOW_TERRAIN); + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_SHADOW_TERRAIN); if (mDrawFace.empty()) { return; @@ -332,10 +332,6 @@ void LLDrawPoolTerrain::renderFullShader() shader->uniform4fv(LLShaderMgr::OBJECT_PLANE_S, 1, tp0.mV); shader->uniform4fv(LLShaderMgr::OBJECT_PLANE_T, 1, tp1.mV); - const LLSettingsWater::ptr_t& pwater = LLEnvironment::getInstanceFast()->getCurrentWater(); - - ((LLSettingsVOWater*)pwater.get())->updateShader(shader); - // TERRAIN TEXTURE COORDS 0: gGL.matrixMode(LLRender::MM_TEXTURE); gGL.loadIdentity(); @@ -477,22 +473,8 @@ void LLDrawPoolTerrain::renderSimple() tp0.setVec(tscale, 0.f, 0.0f, -1.f*(origin_agent.mV[0]/256.f)); tp1.setVec(0.f, tscale, 0.0f, -1.f*(origin_agent.mV[1]/256.f)); - if (LLGLSLShader::sNoFixedFunction) - { - sShader->uniform4fv(LLShaderMgr::OBJECT_PLANE_S, 1, tp0.mV); - sShader->uniform4fv(LLShaderMgr::OBJECT_PLANE_T, 1, tp1.mV); - } - else - { - glEnable(GL_TEXTURE_GEN_S); - glEnable(GL_TEXTURE_GEN_T); - glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); - glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); - glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV); - glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV); - } - - gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_VERT_COLOR); + sShader->uniform4fv(LLShaderMgr::OBJECT_PLANE_S, 1, tp0.mV); + sShader->uniform4fv(LLShaderMgr::OBJECT_PLANE_T, 1, tp1.mV); drawLoop(); @@ -501,15 +483,9 @@ void LLDrawPoolTerrain::renderSimple() gGL.getTexUnit(0)->activate(); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - if (!LLGLSLShader::sNoFixedFunction) - { - glDisable(GL_TEXTURE_GEN_S); - glDisable(GL_TEXTURE_GEN_T); - } gGL.matrixMode(LLRender::MM_TEXTURE); gGL.loadIdentity(); gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); } //============================================================================ @@ -558,6 +534,7 @@ void LLDrawPoolTerrain::renderOwnership() void LLDrawPoolTerrain::dirtyTextures(const std::set<LLViewerFetchedTexture*>& textures) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; LLViewerFetchedTexture* tex = LLViewerTextureManager::staticCastToFetchedTexture(mTexturep) ; if (tex && textures.find(tex) != textures.end()) { diff --git a/indra/newview/lldrawpooltree.cpp b/indra/newview/lldrawpooltree.cpp index 3662197c5eb59e33fe04155623c142498af36d62..60a9b5fdc7daffecdea3ad9b322d1a03ce485867 100644 --- a/indra/newview/lldrawpooltree.cpp +++ b/indra/newview/lldrawpooltree.cpp @@ -42,7 +42,6 @@ S32 LLDrawPoolTree::sDiffTex = 0; static LLGLSLShader* shader = NULL; -static LLTrace::BlockTimerStatHandle FTM_SHADOW_TREE("Tree Shadow"); LLDrawPoolTree::LLDrawPoolTree(LLViewerTexture *texturep) : LLFacePool(POOL_TREE), @@ -69,7 +68,7 @@ void LLDrawPoolTree::beginRenderPass(S32 pass) shader = &gTreeProgram; } - if (gPipeline.canUseVertexShaders()) + if (gPipeline.shadersLoaded()) { shader->bind(); shader->setMinimumAlpha(0.5f); @@ -78,27 +77,28 @@ void LLDrawPoolTree::beginRenderPass(S32 pass) else { gPipeline.enableLightsDynamic(); - gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); + gGL.flush(); } } void LLDrawPoolTree::render(S32 pass) { - LL_RECORD_BLOCK_TIME(LLPipeline::sShadowRender ? FTM_SHADOW_TREE : FTM_RENDER_TREES); + LL_PROFILE_ZONE_SCOPED; if (mDrawFace.empty()) { return; } - LLGLState test(GL_ALPHA_TEST, LLGLSLShader::sNoFixedFunction ? 0 : 1); + LLGLState test(GL_ALPHA_TEST, 0); // [SL:KB] - Patch: Render-TextureToggle (Catznip-4.0) LLViewerTexture* pTexture = (LLPipeline::sRenderTextures) ? mTexturep.get() : LLViewerFetchedTexture::sDefaultDiffuseImagep.get(); - gGL.getTexUnit(sDiffTex)->bind(pTexture); + gGL.getTexUnit(sDiffTex)->bindFast(pTexture); // [/SL:KB] -// gGL.getTexUnit(sDiffTex)->bind(mTexturep); - +// gGL.getTexUnit(sDiffTex)->bindFast(mTexturep); + gPipeline.touchTexture(mTexturep, 1024.f * 1024.f); // <=== keep Linden tree textures at full res + for (LLFace* face : mDrawFace) { if (!face || !face->getDrawable() || !face->getDrawable()->getRegion()) @@ -125,8 +125,8 @@ void LLDrawPoolTree::render(S32 pass) gPipeline.mMatrixOpCount++; } - buff->setBuffer(LLDrawPoolTree::VERTEX_DATA_MASK); - buff->drawRange(LLRender::TRIANGLES, 0, buff->getNumVerts()-1, buff->getNumIndices(), 0); + buff->setBufferFast(LLDrawPoolTree::VERTEX_DATA_MASK); + buff->drawRangeFast(LLRender::TRIANGLES, 0, buff->getNumVerts()-1, buff->getNumIndices(), 0); } } } @@ -142,7 +142,7 @@ void LLDrawPoolTree::endRenderPass(S32 pass) if (mShaderLevel <= 0) { - gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); + gGL.flush(); } } @@ -160,6 +160,7 @@ void LLDrawPoolTree::beginDeferredPass(S32 pass) void LLDrawPoolTree::renderDeferred(S32 pass) { + LL_PROFILE_ZONE_SCOPED; render(pass); } @@ -175,12 +176,12 @@ void LLDrawPoolTree::endDeferredPass(S32 pass) //============================================ void LLDrawPoolTree::beginShadowPass(S32 pass) { - LL_RECORD_BLOCK_TIME(FTM_SHADOW_TREE); + LL_PROFILE_ZONE_SCOPED; glPolygonOffset(gSavedSettings.getF32("RenderDeferredTreeShadowOffset"), gSavedSettings.getF32("RenderDeferredTreeShadowBias")); - LLEnvironment& environment = LLEnvironment::instanceFast(); + LLEnvironment& environment = LLEnvironment::instance(); gDeferredTreeShadowProgram.bind(); gDeferredTreeShadowProgram.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0); @@ -194,7 +195,7 @@ void LLDrawPoolTree::renderShadow(S32 pass) void LLDrawPoolTree::endShadowPass(S32 pass) { - LL_RECORD_BLOCK_TIME(FTM_SHADOW_TREE); + LL_PROFILE_ZONE_SCOPED; glPolygonOffset(gSavedSettings.getF32("RenderDeferredSpotShadowOffset"), gSavedSettings.getF32("RenderDeferredSpotShadowBias")); diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp index 7e8dddb69c964565ea2021b627d804564c07b246..28d9f13ec5c86861f742130cea30ae21fc5f47ca 100644 --- a/indra/newview/lldrawpoolwater.cpp +++ b/indra/newview/lldrawpoolwater.cpp @@ -50,8 +50,6 @@ #include "llsettingssky.h" #include "llsettingswater.h" -static float sTime; - BOOL deferred_render = FALSE; BOOL LLDrawPoolWater::sSkipScreenCopy = FALSE; @@ -69,7 +67,7 @@ LLDrawPoolWater::~LLDrawPoolWater() void LLDrawPoolWater::setTransparentTextures(const LLUUID& transparentTextureId, const LLUUID& nextTransparentTextureId) { - const LLSettingsWater::ptr_t& pwater = LLEnvironment::instanceFast().getCurrentWater(); + const LLSettingsWater::ptr_t& pwater = LLEnvironment::instance().getCurrentWater(); mWaterImagep[0] = LLViewerTextureManager::getFetchedTexture(!transparentTextureId.isNull() ? transparentTextureId : pwater->GetDefaultTransparentTextureAssetId()); mWaterImagep[1] = LLViewerTextureManager::getFetchedTexture(!nextTransparentTextureId.isNull() ? nextTransparentTextureId : (!transparentTextureId.isNull() ? transparentTextureId : pwater->GetDefaultTransparentTextureAssetId())); mWaterImagep[0]->addTextureStats(1024.f*1024.f); @@ -84,7 +82,7 @@ void LLDrawPoolWater::setOpaqueTexture(const LLUUID& opaqueTextureId) void LLDrawPoolWater::setNormalMaps(const LLUUID& normalMapId, const LLUUID& nextNormalMapId) { - const LLSettingsWater::ptr_t& pwater = LLEnvironment::instanceFast().getCurrentWater(); + const LLSettingsWater::ptr_t& pwater = LLEnvironment::instance().getCurrentWater(); mWaterNormp[0] = LLViewerTextureManager::getFetchedTexture(!normalMapId.isNull() ? normalMapId : pwater->GetDefaultWaterNormalAssetId()); mWaterNormp[1] = LLViewerTextureManager::getFetchedTexture(!nextNormalMapId.isNull() ? nextNormalMapId : (!normalMapId.isNull() ? normalMapId : pwater->GetDefaultWaterNormalAssetId())); mWaterNormp[0]->addTextureStats(1024.f*1024.f); @@ -110,7 +108,7 @@ void LLDrawPoolWater::prerender() S32 LLDrawPoolWater::getNumPasses() { - if (LLViewerCamera::getInstanceFast()->getOrigin().mV[2] < 1024.f) + if (LLViewerCamera::getInstance()->getOrigin().mV[2] < 1024.f) { return 1; } @@ -135,9 +133,17 @@ void LLDrawPoolWater::endPostDeferredPass(S32 pass) //=============================== void LLDrawPoolWater::renderDeferred(S32 pass) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_WATER); + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_WATER); + + if (!LLPipeline::sRenderTransparentWater) + { + // Will render opaque water without use of ALM + render(pass); + return; + } + deferred_render = TRUE; - shade(); + renderWater(); deferred_render = FALSE; } @@ -145,7 +151,7 @@ void LLDrawPoolWater::renderDeferred(S32 pass) void LLDrawPoolWater::render(S32 pass) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_WATER); + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_WATER); if (mDrawFace.empty() || LLDrawable::getCurrentFrame() <= 1) { return; @@ -171,7 +177,7 @@ void LLDrawPoolWater::render(S32 pass) if ((mShaderLevel > 0) && !sSkipScreenCopy) { - shade(); + renderWater(); return; } @@ -202,11 +208,11 @@ void LLDrawPoolWater::render(S32 pass) gGL.getTexUnit(2)->enable(LLTexUnit::TT_TEXTURE); gGL.getTexUnit(2)->bind(mWaterImagep[1]) ; - LLVector3 camera_up = LLViewerCamera::getInstanceFast()->getUpAxis(); + LLVector3 camera_up = LLViewerCamera::getInstance()->getUpAxis(); F32 up_dot = camera_up * LLVector3::z_axis; LLColor4 water_color; - if (LLViewerCamera::getInstanceFast()->cameraUnderWater()) + if (LLViewerCamera::getInstance()->cameraUnderWater()) { water_color.setVec(1.f, 1.f, 1.f, 0.4f); } @@ -230,9 +236,6 @@ void LLDrawPoolWater::render(S32 pass) glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0); glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1); - gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR); - gGL.getTexUnit(1)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_ALPHA); - gGL.getTexUnit(0)->activate(); glClearStencil(1); @@ -279,7 +282,7 @@ void LLDrawPoolWater::render(S32 pass) gGL.matrixMode(LLRender::MM_TEXTURE); gGL.loadIdentity(); - LLMatrix4a camera_rot = LLViewerCamera::getInstanceFast()->getModelview(); + LLMatrix4a camera_rot = LLViewerCamera::getInstance()->getModelview(); camera_rot.extractRotation_affine(); camera_rot.invert(); @@ -288,8 +291,6 @@ void LLDrawPoolWater::render(S32 pass) gGL.matrixMode(LLRender::MM_MODELVIEW); LLOverrideFaceColor overrid(this, 1.f, 1.f, 1.f, 0.5f*up_dot); - gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); - for (LLFace* face : mDrawFace) { if (voskyp->isReflFace(face)) @@ -304,8 +305,6 @@ void LLDrawPoolWater::render(S32 pass) } } - gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); - gSky.mVOSkyp->getCubeMap()->disable(); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); @@ -323,30 +322,31 @@ void LLDrawPoolWater::render(S32 pass) glStencilFunc(GL_NOTEQUAL, 0, 0xFFFFFFFF); renderReflection(refl_face); } - - gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); } // for low end hardware void LLDrawPoolWater::renderOpaqueLegacyWater() { - LLVOSky *voskyp = gSky.mVOSkyp; + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; + LLVOSky *voskyp = gSky.mVOSkyp; + + if (voskyp == NULL) + { + return; + } LLGLSLShader* shader = NULL; - if (LLGLSLShader::sNoFixedFunction) + if (LLPipeline::sUnderWaterRender) { - if (LLPipeline::sUnderWaterRender) - { - shader = &gObjectSimpleNonIndexedTexGenWaterProgram; - } - else - { - shader = &gObjectSimpleNonIndexedTexGenProgram; - } - - shader->bind(); + shader = &gObjectSimpleNonIndexedTexGenWaterProgram; + } + else + { + shader = &gObjectSimpleNonIndexedTexGenProgram; } + shader->bind(); + stop_glerror(); // Depth sorting and write to depth buffer @@ -429,12 +429,12 @@ void LLDrawPoolWater::renderOpaqueLegacyWater() } gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); } void LLDrawPoolWater::renderReflection(LLFace* face) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; LLVOSky *voskyp = gSky.mVOSkyp; if (!voskyp) @@ -461,307 +461,239 @@ void LLDrawPoolWater::renderReflection(LLFace* face) face->renderIndexed(); } -void LLDrawPoolWater::shade2(bool edge, LLGLSLShader* shader, const LLColor3& light_diffuse, const LLVector3& light_dir, F32 light_exp) +void LLDrawPoolWater::renderWater() { - LLEnvironment& environment = LLEnvironment::instanceFast(); - LLViewerCamera& viewerCamera = LLViewerCamera::instanceFast(); + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; + if (!deferred_render) + { + gGL.setColorMask(true, true); + } + + LLGLDisable blend(GL_BLEND); - F32 water_height = environment.getWaterHeight(); - F32 camera_height = viewerCamera.getOrigin().mV[2]; - F32 eyedepth = camera_height - water_height; - bool underwater = eyedepth <= 0.0f; + LLColor3 light_diffuse(0, 0, 0); + F32 light_exp = 0.0f; + LLEnvironment& environment = LLEnvironment::instance(); + LLViewerCamera& viewerCamera = LLViewerCamera::instance(); const LLSettingsWater::ptr_t& pwater = environment.getCurrentWater(); const LLSettingsSky::ptr_t& psky = environment.getCurrentSky(); + LLVector3 light_dir = environment.getLightDirection(); + bool sun_up = environment.getIsSunUp(); + bool moon_up = environment.getIsMoonUp(); + bool has_normal_mips = gSavedSettings.getBOOL("RenderWaterMipNormal"); + bool underwater = viewerCamera.cameraUnderWater(); - shader->bind(); - -// bind textures for water rendering - if (deferred_render) - { - if (shader->getUniformLocation(LLShaderMgr::DEFERRED_NORM_MATRIX) >= 0) - { - LLMatrix4a norm_mat = get_current_modelview(); - norm_mat.invert(); - norm_mat.transpose(); - shader->uniformMatrix4fv(LLShaderMgr::DEFERRED_NORM_MATRIX, 1, FALSE, norm_mat.getF32ptr()); - } - } - - LLColor4 specular(psky->getIsSunUp() ? psky->getSunlightColor() : psky->getMoonlightColor()); - shader->uniform4fv(LLShaderMgr::SPECULAR_COLOR, 1, specular.mV); - - sTime = (F32)LLFrameTimer::getElapsedSeconds() * 0.5f; - - S32 reftex = shader->enableTexture(LLShaderMgr::WATER_REFTEX); - - if (reftex > -1) - { - gGL.getTexUnit(reftex)->activate(); - gGL.getTexUnit(reftex)->bind(&gPipeline.mWaterRef); - gGL.getTexUnit(0)->activate(); - } - - //bind normal map - S32 bumpTex = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP); - S32 bumpTex2 = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP2); - - LLViewerTexture* tex_a = mWaterNormp[0]; - LLViewerTexture* tex_b = mWaterNormp[1]; - - F32 blend_factor = pwater->getBlendFactor(); - - gGL.getTexUnit(bumpTex)->unbind(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(bumpTex2)->unbind(LLTexUnit::TT_TEXTURE); - - if (tex_a && (!tex_b || (tex_a == tex_b))) + if (sun_up) { - gGL.getTexUnit(bumpTex)->bind(tex_a); - blend_factor = 0; // only one tex provided, no blending + light_diffuse += psky->getSunlightColor(); } - else if (tex_b && !tex_a) + // moonlight is several orders of magnitude less bright than sunlight, + // so only use this color when the moon alone is showing + else if (moon_up) { - gGL.getTexUnit(bumpTex)->bind(tex_b); - blend_factor = 0; // only one tex provided, no blending + light_diffuse += psky->getMoonlightColor(); } - else if (tex_b != tex_a) + + // Apply magic numbers translating light direction into intensities + light_dir.normalize(); + F32 ground_proj_sq = light_dir.mV[0] * light_dir.mV[0] + light_dir.mV[1] * light_dir.mV[1]; + light_exp = llmax(32.f, 256.f * powf(ground_proj_sq, 16.0f)); + if (0.f < light_diffuse.normalize()) // Normalizing a color? Puzzling... { - gGL.getTexUnit(bumpTex)->bind(tex_a); - gGL.getTexUnit(bumpTex2)->bind(tex_b); + light_diffuse *= (1.5f + (6.f * ground_proj_sq)); } - - // bind reflection texture from RenderTarget - S32 screentex = shader->enableTexture(LLShaderMgr::WATER_SCREENTEX); - F32 screenRes[] = - { - 1.f/gGLViewport[2], - 1.f/gGLViewport[3] - }; - - S32 diffTex = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP); - stop_glerror(); - -// set uniforms for water rendering - shader->uniform2fv(LLShaderMgr::DEFERRED_SCREEN_RES, 1, screenRes); - shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor); - - LLColor4 fog_color(pwater->getWaterFogColor(), 0.0f); - F32 fog_density = pwater->getModifiedWaterFogDensity(underwater); - if (screentex > -1) - { - shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY, fog_density); - gGL.getTexUnit(screentex)->bind(&gPipeline.mWaterDis); - } - - if (mShaderLevel == 1) + // set up normal maps filtering + for (auto norm_map : mWaterNormp) { - //F32 fog_density_slider_value = param_mgr->mDensitySliderValue; - //sWaterFogColor.mV[3] = fog_density_slider_value; - fog_color.mV[VW] = log(fog_density) / log(2); - } + if (norm_map) norm_map->setFilteringOption(has_normal_mips ? LLTexUnit::TFO_ANISOTROPIC : LLTexUnit::TFO_POINT); + } - shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, fog_color.mV); + LLColor4 specular(sun_up ? psky->getSunlightColor() : psky->getMoonlightColor()); + F32 phase_time = (F32) LLFrameTimer::getElapsedSeconds() * 0.5f; + LLGLSLShader *shader = nullptr; - shader->uniform1f(LLShaderMgr::WATER_WATERHEIGHT, eyedepth); - shader->uniform1f(LLShaderMgr::WATER_TIME, sTime); - shader->uniform3fv(LLShaderMgr::WATER_EYEVEC, 1, viewerCamera.getOrigin().mV); - shader->uniform3fv(LLShaderMgr::WATER_SPECULAR, 1, light_diffuse.mV); - if (environment.isCloudScrollPaused()) + // two passes, first with standard water shader bound, second with edge water shader bound + for( int edge = 0 ; edge < 2; edge++ ) { - shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, LLVector2::zero.mV); - shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, LLVector2::zero.mV); - } - else - { - shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, pwater->getWave1Dir().mV); - shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, pwater->getWave2Dir().mV); - } - shader->uniform3fv(LLShaderMgr::WATER_LIGHT_DIR, 1, light_dir.mV); + // select shader + if (underwater && LLPipeline::sWaterReflections) + { + shader = deferred_render ? &gDeferredUnderWaterProgram : &gUnderWaterProgram; + } + else + { + if (edge && !deferred_render) + { + shader = &gWaterEdgeProgram; + } + else + { + shader = deferred_render ? &gDeferredWaterProgram : &gWaterProgram; + } + } + shader->bind(); - shader->uniform3fv(LLShaderMgr::WATER_NORM_SCALE, 1, pwater->getNormalScale().mV); - shader->uniform1f(LLShaderMgr::WATER_FRESNEL_SCALE, pwater->getFresnelScale()); - shader->uniform1f(LLShaderMgr::WATER_FRESNEL_OFFSET, pwater->getFresnelOffset()); - shader->uniform1f(LLShaderMgr::WATER_BLUR_MULTIPLIER, pwater->getBlurMultiplier()); + // bind textures for water rendering + S32 reftex = shader->enableTexture(LLShaderMgr::WATER_REFTEX); + if (reftex > -1) + { + gGL.getTexUnit(reftex)->activate(); + gGL.getTexUnit(reftex)->bind(&gPipeline.mWaterRef); + gGL.getTexUnit(0)->activate(); + } - F32 sunAngle = llmax(0.f, light_dir.mV[1]); + // bind normal map + S32 bumpTex = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP); + S32 bumpTex2 = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP2); - shader->uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0); - shader->uniform1f(LLShaderMgr::WATER_SUN_ANGLE, 0.1f + 0.2f * sunAngle); + LLViewerTexture *tex_a = mWaterNormp[0]; + LLViewerTexture *tex_b = mWaterNormp[1]; - LLVector4 rotated_light_direction = environment.getClampedLightNorm(); - shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, rotated_light_direction.mV); - shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, 1, viewerCamera.getOrigin().mV); + F32 blend_factor = pwater->getBlendFactor(); - if (viewerCamera.cameraUnderWater()) - { - shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleBelow()); - } - else - { - shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleAbove()); - } + gGL.getTexUnit(bumpTex)->unbind(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(bumpTex2)->unbind(LLTexUnit::TT_TEXTURE); - { - LLGLEnable depth_clamp(gGLManager.mHasDepthClamp ? GL_DEPTH_CLAMP : 0); - LLGLDisable cullface(GL_CULL_FACE); - for (LLFace* face : mDrawFace) - { - if (gSky.mVOSkyp->isReflFace(face)) - { - continue; - } + if (tex_a && (!tex_b || (tex_a == tex_b))) + { + gGL.getTexUnit(bumpTex)->bind(tex_a); + blend_factor = 0; // only one tex provided, no blending + } + else if (tex_b && !tex_a) + { + gGL.getTexUnit(bumpTex)->bind(tex_b); + blend_factor = 0; // only one tex provided, no blending + } + else if (tex_b != tex_a) + { + gGL.getTexUnit(bumpTex)->bind(tex_a); + gGL.getTexUnit(bumpTex2)->bind(tex_b); + } - LLVOWater* water = (LLVOWater*)face->getViewerObject(); - if (diffTex > -1) - { - gGL.getTexUnit(diffTex)->bind(face->getTexture()); - } + // bind reflection texture from RenderTarget + S32 screentex = shader->enableTexture(LLShaderMgr::WATER_SCREENTEX); + F32 screenRes[] = {1.f / gGLViewport[2], 1.f / gGLViewport[3]}; - if (!water->getIsEdgePatch()) - { - sNeedsReflectionUpdate = TRUE; - sNeedsDistortionUpdate = TRUE; - } + S32 diffTex = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP); - if (water->getUseTexture() || !water->getIsEdgePatch() || gGLManager.mHasDepthClamp || deferred_render) - { - face->renderIndexed(); - } - else + // set uniforms for shader + if (deferred_render) + { + if (shader->getUniformLocation(LLShaderMgr::DEFERRED_NORM_MATRIX) >= 0) { - LLGLSquashToFarClip far_clip(get_current_projection()); - face->renderIndexed(); + LLMatrix4a norm_mat = get_current_modelview(); + norm_mat.invert(); + norm_mat.transpose(); + shader->uniformMatrix4fv(LLShaderMgr::DEFERRED_NORM_MATRIX, 1, FALSE, norm_mat.getF32ptr()); } - } - } - - gGL.getTexUnit(bumpTex)->unbind(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(bumpTex2)->unbind(LLTexUnit::TT_TEXTURE); - - shader->disableTexture(LLShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); - shader->disableTexture(LLShaderMgr::WATER_SCREENTEX); - shader->disableTexture(LLShaderMgr::BUMP_MAP); - shader->disableTexture(LLShaderMgr::DIFFUSE_MAP); - shader->disableTexture(LLShaderMgr::WATER_REFTEX); + } - shader->unbind(); -} + shader->uniform2fv(LLShaderMgr::DEFERRED_SCREEN_RES, 1, screenRes); + shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor); -void LLDrawPoolWater::shade() -{ - if (!deferred_render) - { - gGL.setColorMask(true, true); - } + LLColor4 fog_color(pwater->getWaterFogColor(), 0.0f); + F32 fog_density = pwater->getModifiedWaterFogDensity(underwater); - LLVOSky *voskyp = gSky.mVOSkyp; + if (screentex > -1) + { + shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY, fog_density); + gGL.getTexUnit(screentex)->bind(&gPipeline.mWaterDis); + } - if(voskyp == NULL) - { - return; - } + if (mShaderLevel == 1) + { + fog_color.mV[VW] = log(fog_density) / log(2); + } - LLGLDisable blend(GL_BLEND); + F32 water_height = environment.getWaterHeight(); + F32 camera_height = LLViewerCamera::getInstance()->getOrigin().mV[2]; + shader->uniform1f(LLShaderMgr::WATER_WATERHEIGHT, camera_height - water_height); + shader->uniform1f(LLShaderMgr::WATER_TIME, phase_time); + shader->uniform3fv(LLShaderMgr::WATER_EYEVEC, 1, viewerCamera.getOrigin().mV); - LLColor3 light_diffuse(0,0,0); - F32 light_exp = 0.0f; - LLVector3 light_dir; + shader->uniform4fv(LLShaderMgr::SPECULAR_COLOR, 1, specular.mV); + shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, fog_color.mV); - LLEnvironment& environment = LLEnvironment::instanceFast(); - const LLSettingsSky::ptr_t& psky = environment.getCurrentSky(); + shader->uniform3fv(LLShaderMgr::WATER_SPECULAR, 1, light_diffuse.mV); + //shader->uniform1f(LLShaderMgr::WATER_SPECULAR_EXP, light_exp); - light_dir = environment.getLightDirection(); - light_dir.normalize(); + shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, pwater->getWave1Dir().mV); + shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, pwater->getWave2Dir().mV); - bool sun_up = environment.getIsSunUp(); - bool moon_up = environment.getIsMoonUp(); + shader->uniform3fv(LLShaderMgr::WATER_LIGHT_DIR, 1, light_dir.mV); - if (sun_up) - { - light_diffuse += voskyp->getSun().getColorCached(); - } - // moonlight is several orders of magnitude less bright than sunlight, - // so only use this color when the moon alone is showing - else if (moon_up) - { - light_diffuse += psky->getMoonDiffuse(); - } + shader->uniform3fv(LLShaderMgr::WATER_NORM_SCALE, 1, pwater->getNormalScale().mV); + shader->uniform1f(LLShaderMgr::WATER_FRESNEL_SCALE, pwater->getFresnelScale()); + shader->uniform1f(LLShaderMgr::WATER_FRESNEL_OFFSET, pwater->getFresnelOffset()); + shader->uniform1f(LLShaderMgr::WATER_BLUR_MULTIPLIER, pwater->getBlurMultiplier()); - light_exp = light_dir * LLVector3(light_dir.mV[0], light_dir.mV[1], 0.f); + F32 sunAngle = llmax(0.f, light_dir.mV[1]); + //F32 scaledAngle = 1.f - sunAngle; - light_diffuse.normalize(); - light_diffuse *= (light_exp + 0.25f); + shader->uniform1i(LLShaderMgr::SUN_UP_FACTOR, sun_up ? 1 : 0); + shader->uniform1f(LLShaderMgr::WATER_SUN_ANGLE, sunAngle); + //shader->uniform1f(LLShaderMgr::WATER_SCALED_ANGLE, scaledAngle); + //shader->uniform1f(LLShaderMgr::WATER_SUN_ANGLE2, 0.1f + 0.2f * sunAngle); + shader->uniform1i(LLShaderMgr::WATER_EDGE_FACTOR, edge ? 1 : 0); - light_exp *= light_exp; - light_exp *= light_exp; - light_exp *= light_exp; - light_exp *= light_exp; - light_exp *= 256.f; - light_exp = light_exp > 32.f ? light_exp : 32.f; + LLVector4 rotated_light_direction = environment.getRotatedLightNorm(); + shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, rotated_light_direction.mV); + shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, 1, viewerCamera.getOrigin().mV); - light_diffuse *= 6.f; + if (viewerCamera.cameraUnderWater()) + { + shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleBelow()); + } + else + { + shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleAbove()); + } - LLGLSLShader* shader = nullptr; + LLGLDisable cullface(GL_CULL_FACE); - F32 eyedepth = LLViewerCamera::getInstanceFast()->getOrigin().mV[2] - environment.getWaterHeight(); - - if (eyedepth < 0.f && LLPipeline::sWaterReflections) - { - if (deferred_render) - { - shader = &gDeferredUnderWaterProgram; - } - else + LLVOWater *water = nullptr; + for (LLFace *const &face : mDrawFace) { - shader = &gUnderWaterProgram; + if (!face) continue; + water = static_cast<LLVOWater *>(face->getViewerObject()); + if (!water) continue; + + gGL.getTexUnit(diffTex)->bind(face->getTexture()); + + if ((bool)edge == (bool) water->getIsEdgePatch()) + { + face->renderIndexed(); + + // Note non-void water being drawn, updates required + if (!edge) // SL-16461 remove !LLPipeline::sUseOcclusion check + { + sNeedsReflectionUpdate = TRUE; + sNeedsDistortionUpdate = TRUE; + } + } } - } - else if (deferred_render) - { - shader = &gDeferredWaterProgram; - } - else - { - shader = &gWaterProgram; - } - - static const LLCachedControl<bool> render_water_mip_normal(gSavedSettings, "RenderWaterMipNormal"); - if (mWaterNormp[0]) - { - if (render_water_mip_normal) - { - mWaterNormp[0]->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC); - } - else - { - mWaterNormp[0]->setFilteringOption(LLTexUnit::TFO_POINT); - } - } + shader->disableTexture(LLShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); + shader->disableTexture(LLShaderMgr::WATER_SCREENTEX); + shader->disableTexture(LLShaderMgr::BUMP_MAP); + shader->disableTexture(LLShaderMgr::DIFFUSE_MAP); + shader->disableTexture(LLShaderMgr::WATER_REFTEX); + //shader->disableTexture(LLShaderMgr::WATER_SCREENDEPTH); + + // clean up + shader->unbind(); + gGL.getTexUnit(bumpTex)->unbind(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(bumpTex2)->unbind(LLTexUnit::TT_TEXTURE); + } - if (mWaterNormp[1]) + gGL.getTexUnit(0)->activate(); + gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); + if (!deferred_render) { - if (render_water_mip_normal) - { - mWaterNormp[1]->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC); - } - else - { - mWaterNormp[1]->setFilteringOption(LLTexUnit::TFO_POINT); - } - } - - shade2(false, shader, light_diffuse, light_dir, light_exp); - //shade2(true, edge_shader ? edge_shader : shader, light_diffuse, light_dir, light_exp); - - gGL.getTexUnit(0)->activate(); - gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); - if (!deferred_render) - { - gGL.setColorMask(true, false); - } - + gGL.setColorMask(true, false); + } } LLViewerTexture *LLDrawPoolWater::getDebugTexture() diff --git a/indra/newview/lldrawpoolwater.h b/indra/newview/lldrawpoolwater.h index e0f6548ac5772d2b9386678dbcae7e814789bff4..cfc4b9db22cd0d759bc4f52cc835d1a80e8ec281 100644 --- a/indra/newview/lldrawpoolwater.h +++ b/indra/newview/lldrawpoolwater.h @@ -78,8 +78,7 @@ class LLDrawPoolWater final : public LLFacePool /*virtual*/ LLColor3 getDebugColor() const; // For AGP debug display void renderReflection(LLFace* face); - void shade(); - void shade2(bool edge, LLGLSLShader* shader, const LLColor3& light_diffuse, const LLVector3& light_dir, F32 light_exp); + void renderWater(); void setTransparentTextures(const LLUUID& transparentTextureId, const LLUUID& nextTransparentTextureId); void setOpaqueTexture(const LLUUID& opaqueTextureId); diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp index f730af60aef7d59d912120ea482d58c83fd6651a..cd583e85268bccec3c253783a0ad7aacb8c6accb 100644 --- a/indra/newview/lldrawpoolwlsky.cpp +++ b/indra/newview/lldrawpoolwlsky.cpp @@ -95,9 +95,9 @@ void LLDrawPoolWLSky::beginRenderPass( S32 pass ) &gObjectFullbrightNoColorWaterProgram : &gCustomAlphaProgram; - auto& environment = LLEnvironment::instanceFast(); + auto& environment = LLEnvironment::instance(); mCamHeightLocal = environment.getCamHeight(); - mCameraOrigin = LLViewerCamera::getInstanceFast()->getOrigin(); + mCameraOrigin = LLViewerCamera::getInstance()->getOrigin(); mCurrentSky = environment.getCurrentSky(); } @@ -131,9 +131,9 @@ void LLDrawPoolWLSky::beginDeferredPass(S32 pass) &gObjectFullbrightNoColorWaterProgram : &gDeferredStarProgram; - auto& environment = LLEnvironment::instanceFast(); + auto& environment = LLEnvironment::instance(); mCamHeightLocal = environment.getCamHeight(); - mCameraOrigin = LLViewerCamera::getInstanceFast()->getOrigin(); + mCameraOrigin = LLViewerCamera::getInstance()->getOrigin(); mCurrentSky = environment.getCurrentSky(); } @@ -200,11 +200,9 @@ void LLDrawPoolWLSky::renderSkyHaze() const sky_shader->bindTexture(LLShaderMgr::HALO_MAP, halo_tex); LLSettingsVOSky* voskysetp = ((LLSettingsVOSky*)mCurrentSky.get()); - voskysetp->updateShader(sky_shader); - - F32 moisture_level = (float)voskysetp->getSkyMoistureLevelFast(); - F32 droplet_radius = (float)voskysetp->getSkyDropletRadiusFast(); - F32 ice_level = (float)voskysetp->getSkyIceLevelFast(); + F32 moisture_level = (float)voskysetp->getSkyMoistureLevel(); + F32 droplet_radius = (float)voskysetp->getSkyDropletRadius(); + F32 ice_level = (float)voskysetp->getSkyIceLevel(); // hobble halos and rainbows when there's no light source to generate them if (!voskysetp->getIsSunUp() && !voskysetp->getIsMoonUp()) @@ -216,6 +214,8 @@ void LLDrawPoolWLSky::renderSkyHaze() const sky_shader->uniform1f(LLShaderMgr::MOISTURE_LEVEL, moisture_level); sky_shader->uniform1f(LLShaderMgr::DROPLET_RADIUS, droplet_radius); sky_shader->uniform1f(LLShaderMgr::ICE_LEVEL, ice_level); + sky_shader->uniform1f(LLShaderMgr::SUN_MOON_GLOW_FACTOR, mCurrentSky->getSunMoonGlowFactor()); + sky_shader->uniform1i(LLShaderMgr::SUN_UP_FACTOR, mCurrentSky->getIsSunUp() ? 1 : 0); } else { @@ -274,33 +274,14 @@ void LLDrawPoolWLSky::renderStars() const gGL.translatef(mCameraOrigin.mV[0], mCameraOrigin.mV[1], mCameraOrigin.mV[2]); gGL.rotatef(gFrameTimeSeconds * 0.01f, 0.f, 0.f, 1.f); - if (LLGLSLShader::sNoFixedFunction) - { - star_shader->bind(); - star_shader->uniform1f(sCustomAlpha, star_alpha.mV[3]); - } - else - { - gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_VERT_COLOR); - gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_MULT_X2, LLTexUnit::TBS_CONST_ALPHA, LLTexUnit::TBS_TEX_ALPHA); - glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, star_alpha.mV); - } + star_shader->bind(); + star_shader->uniform1f(sCustomAlpha, star_alpha.mV[3]); gSky.mVOWLSkyp->drawStars(); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.popMatrix(); - - if (LLGLSLShader::sNoFixedFunction) - { - star_shader->unbind(); - } - else - { - // and disable the combiner states - gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); - } + star_shader->unbind(); } void LLDrawPoolWLSky::renderStarsDeferred() const @@ -311,7 +292,7 @@ void LLDrawPoolWLSky::renderStarsDeferred() const LLSettingsVOSky* voskysetp = ((LLSettingsVOSky*)mCurrentSky.get()); - F32 star_alpha = voskysetp->getStarBrightnessFast() / 500.0f; + F32 star_alpha = voskysetp->getStarBrightness() / 500.0f; // If start_brightness is not set, exit if(star_alpha < 0.001f) @@ -387,7 +368,7 @@ void LLDrawPoolWLSky::renderSkyClouds() const LLSettingsVOSky* voskysetp = ((LLSettingsVOSky*)mCurrentSky.get()); - F32 cloud_variance = voskysetp->getCloudVarianceFast(); + F32 cloud_variance = voskysetp->getCloudVariance(); F32 blend_factor = voskysetp->getBlendFactor(); // if we even have sun disc textures to work with... @@ -413,8 +394,7 @@ void LLDrawPoolWLSky::renderSkyClouds() const cloud_shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor); cloud_shader->uniform1f(LLShaderMgr::CLOUD_VARIANCE, cloud_variance); - - voskysetp->updateShader(cloud_shader); + cloud_shader->uniform1f(LLShaderMgr::SUN_MOON_GLOW_FACTOR, voskysetp->getSunMoonGlowFactor()); /// Render the skydome renderDome(cloud_shader); @@ -436,7 +416,7 @@ void LLDrawPoolWLSky::renderHeavenlyBodies() LLFace * face = gSky.mVOSkyp->mFace[LLVOSky::FACE_SUN]; F32 blend_factor = mCurrentSky->getBlendFactor(); - bool can_use_vertex_shaders = gPipeline.canUseVertexShaders(); + bool can_use_vertex_shaders = gPipeline.shadersLoaded(); bool can_use_windlight_shaders = gPipeline.canUseWindLightShaders(); @@ -522,7 +502,7 @@ void LLDrawPoolWLSky::renderHeavenlyBodies() LLSettingsVOSky* voskysetp = ((LLSettingsVOSky*)mCurrentSky.get()); - F32 moon_brightness = (float)voskysetp->getMoonBrightnessFast(); + F32 moon_brightness = (float)voskysetp->getMoonBrightness(); LLColor4 moon_color(gSky.mVOSkyp->getMoon().getColor()); moon_shader->uniform1f(LLShaderMgr::MOON_BRIGHTNESS, moon_brightness); @@ -545,11 +525,11 @@ void LLDrawPoolWLSky::renderHeavenlyBodies() void LLDrawPoolWLSky::renderDeferred(S32 pass) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_WL_SKY); if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY)) { return; } - LL_RECORD_BLOCK_TIME(FTM_RENDER_WL_SKY); gGL.setColorMask(true, false); @@ -565,11 +545,11 @@ void LLDrawPoolWLSky::renderDeferred(S32 pass) void LLDrawPoolWLSky::render(S32 pass) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_WL_SKY); if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY)) { return; } - LL_RECORD_BLOCK_TIME(FTM_RENDER_WL_SKY); renderSkyHaze(); renderStars(); diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp index 3465522abf6023f6f661d512df91cccbbc3a80e9..05b60718b6fcdf63d79bda8666b4994ea65ac491 100644 --- a/indra/newview/lldynamictexture.cpp +++ b/indra/newview/lldynamictexture.cpp @@ -119,10 +119,13 @@ BOOL LLViewerDynamicTexture::render() void LLViewerDynamicTexture::preRender(BOOL clear_depth) { gPipeline.allocatePhysicsBuffer(); - llassert(mFullWidth <= static_cast<S32>(gPipeline.mBake.getWidth())); - llassert(mFullHeight <= static_cast<S32>(gPipeline.mBake.getHeight())); + if (!gNonInteractive) + { + llassert(mFullWidth <= static_cast<S32>(gPipeline.mBake.getWidth())); + llassert(mFullHeight <= static_cast<S32>(gPipeline.mBake.getHeight())); + } - if (gGLManager.mHasFramebufferObject && gPipeline.mBake.isComplete()) + if (gPipeline.mBake.isComplete()) { //using offscreen render target, just use the bottom left corner mOrigin.set(0, 0); } @@ -145,7 +148,7 @@ void LLViewerDynamicTexture::preRender(BOOL clear_depth) gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); // Set up camera - LLViewerCamera* camera = LLViewerCamera::getInstanceFast(); + LLViewerCamera* camera = LLViewerCamera::getInstance(); mCamera.setOrigin(*camera); mCamera.setAxes(*camera); mCamera.setAspect(camera->getAspect()); @@ -188,7 +191,7 @@ void LLViewerDynamicTexture::postRender(BOOL success) gViewerWindow->setup2DViewport(); // restore camera - LLViewerCamera* camera = LLViewerCamera::getInstanceFast(); + LLViewerCamera* camera = LLViewerCamera::getInstance(); camera->setOrigin(mCamera); camera->setAxes(mCamera); camera->setAspect(mCamera.getAspect()); @@ -209,7 +212,7 @@ BOOL LLViewerDynamicTexture::updateAllInstances() return TRUE; } - bool use_fbo = gGLManager.mHasFramebufferObject && gPipeline.mBake.isComplete(); + bool use_fbo = gPipeline.mBake.isComplete(); if (use_fbo) { diff --git a/indra/newview/lldynamictexture.h b/indra/newview/lldynamictexture.h index 4bd74a84252ece10ee9e4ae884a83fcb9264be8b..caedf928c3b21fa596feaf8822e8ec067fcd0e64 100644 --- a/indra/newview/lldynamictexture.h +++ b/indra/newview/lldynamictexture.h @@ -35,16 +35,8 @@ class LLViewerDynamicTexture : public LLViewerTexture { + LL_ALIGN_NEW public: - void* operator new(size_t size) - { - return LLTrace::MemTrackable<LLTexture>::aligned_new<16>(size); - } - - void operator delete(void* ptr, size_t size) - { - LLTrace::MemTrackable<LLTexture>::aligned_delete<16>(ptr, size); - } enum { diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp index ae80e05569694f2ef213a8b346e8ac5c1b5d5060..6002e66552987888cc4c022e4c0a5b4455b6831d 100644 --- a/indra/newview/llenvironment.cpp +++ b/indra/newview/llenvironment.cpp @@ -108,7 +108,6 @@ namespace //--------------------------------------------------------------------- LLTrace::BlockTimerStatHandle FTM_ENVIRONMENT_UPDATE("Update Environment Tick"); - LLTrace::BlockTimerStatHandle FTM_SHADER_PARAM_UPDATE("Update Shader Parameters"); LLSettingsBase::Seconds DEFAULT_UPDATE_THRESHOLD(10.0); const LLSettingsBase::Seconds MINIMUM_SPANLENGTH(0.01f); @@ -615,6 +614,7 @@ namespace specialSet.insert(SETTING_CLOUD_TEXTUREID); specialSet.insert(SETTING_MOON_TEXTUREID); specialSet.insert(SETTING_SUN_TEXTUREID); + specialSet.insert(SETTING_CLOUD_SHADOW); // due to being part of skips } return specialSet; } @@ -655,6 +655,7 @@ namespace template<> void LLSettingsInjected<LLSettingsVOSky>::updateSpecial(const typename LLSettingsInjected<LLSettingsVOSky>::Injection::ptr_t &injection, typename LLSettingsBase::BlendFactor mix) { + bool is_texture = true; if (injection->mKeyName == SETTING_SUN_TEXTUREID) { mNextSunTextureId = injection->mValue.asUUID(); @@ -679,9 +680,29 @@ namespace { mNextHaloTextureId = injection->mValue.asUUID(); } + else if (injection->mKeyName == LLSettingsSky::SETTING_CLOUD_SHADOW) + { + // Special case due to being texture dependent and part of skips + is_texture = false; + 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()) + { + value = 0; // there was no texture so start from zero coverage + } + // Ideally we need to check for texture in injection, but + // in this case user is setting value explicitly, potentially + // with different transitions, don't ignore it + F64 result = ll_lerp(value, injection->mValue.asReal(), mix); + injection->mLastValue = LLSD::Real(result); + this->mSettings[injection->mKeyName] = injection->mLastValue; + } // Unfortunately I don't have a per texture blend factor. We'll just pick the one that is furthest along. - if (getBlendFactor() < mix) + if (is_texture && getBlendFactor() < mix) { setBlendFactor(mix); } @@ -828,7 +849,6 @@ std::string env_selection_to_string(LLEnvironment::EnvSelection_t sel) #undef RTNENUM } - //------------------------------------------------------------------------- LLEnvironment::LLEnvironment(): mCloudScrollDelta(), @@ -880,6 +900,11 @@ void LLEnvironment::cleanupSingleton() LLEventPumps::instance().obtain(PUMP_EXPERIENCE).stopListening(LISTENER_NAME); } +LLEnvironment::~LLEnvironment() +{ + cleanupSingleton(); +} + bool LLEnvironment::canEdit() const { return true; @@ -923,7 +948,7 @@ const LLSettingsWater::ptr_t& LLEnvironment::getCurrentWater() const bool LLEnvironment::canAgentUpdateParcelEnvironment() const { - LLParcel *parcel(LLViewerParcelMgr::instanceFast().getAgentOrSelectedParcel()); + LLParcel *parcel(LLViewerParcelMgr::instance().getAgentOrSelectedParcel()); return canAgentUpdateParcelEnvironment(parcel); } @@ -989,7 +1014,7 @@ void LLEnvironment::onRegionChange() void LLEnvironment::onParcelChange() { S32 parcel_id(INVALID_PARCEL_ID); - LLParcel* parcel = LLViewerParcelMgr::instanceFast().getAgentParcel(); + LLParcel* parcel = LLViewerParcelMgr::instance().getAgentParcel(); if (parcel) { @@ -1092,6 +1117,10 @@ void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, const LLSe mSignalEnvChanged(env, env_version); } +void LLEnvironment::setCurrentEnvironmentSelection(LLEnvironment::EnvSelection_t env) +{ + mCurrentEnvironment->setEnvironmentSelection(env); +} void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, LLEnvironment::fixedEnvironment_t fixed, S32 env_version) { @@ -1429,6 +1458,7 @@ LLEnvironment::DayInstance::ptr_t LLEnvironment::getSharedEnvironmentInstance() void LLEnvironment::updateEnvironment(LLSettingsBase::Seconds transition, bool forced) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_ENVIRONMENT; DayInstance::ptr_t pinstance = getSelectedEnvironmentInstance(); if ((mCurrentEnvironment != pinstance) || forced) @@ -1446,6 +1476,8 @@ void LLEnvironment::updateEnvironment(LLSettingsBase::Seconds transition, bool f { mCurrentEnvironment = pinstance; } + + updateSettingsUniforms(); } } @@ -1552,7 +1584,7 @@ LLVector4 LLEnvironment::getRotatedLightNorm() const //------------------------------------------------------------------------- void LLEnvironment::update(const LLViewerCamera * cam) { - LL_RECORD_BLOCK_TIME(FTM_ENVIRONMENT_UPDATE); + LL_PROFILE_ZONE_SCOPED_CATEGORY_ENVIRONMENT; //LL_RECORD_BLOCK_TIME(FTM_ENVIRONMENT_UPDATE); //F32Seconds now(LLDate::now().secondsSinceEpoch()); static LLFrameTimer timer; @@ -1572,6 +1604,8 @@ void LLEnvironment::update(const LLViewerCamera * cam) stop_glerror(); + updateSettingsUniforms(); + // *TODO: potential optimization - this block may only need to be // executed some of the time. For example for water shaders only. { @@ -1579,16 +1613,10 @@ void LLEnvironment::update(const LLViewerCamera * cam) end_shaders = LLViewerShaderMgr::instance()->endShaders(); for (shaders_iter = LLViewerShaderMgr::instance()->beginShaders(); shaders_iter != end_shaders; ++shaders_iter) { - if ((shaders_iter->mProgramObject != 0) && - (shaders_iter->mFeatures.atmosphericHelpers - || shaders_iter->mFeatures.calculatesAtmospherics - || shaders_iter->mFeatures.hasAtmospherics - || shaders_iter->mFeatures.hasGamma - || shaders_iter->mFeatures.hasTransport - || shaders_iter->mFeatures.hasWaterFog) && - (gPipeline.canUseWindLightShaders() - || shaders_iter->mShaderGroup == LLGLSLShader::SG_WATER)) - { + if ((shaders_iter->mProgramObject != 0) + && (gPipeline.canUseWindLightShaders() + || shaders_iter->mShaderGroup == LLGLSLShader::SG_WATER)) + { shaders_iter->mUniformsDirty = TRUE; } } @@ -1612,10 +1640,16 @@ void LLEnvironment::updateCloudScroll() } // static -void LLEnvironment::updateGLVariablesForSettings(LLGLSLShader *shader, const LLSettingsBase::ptr_t &psetting) +void LLEnvironment::updateGLVariablesForSettings(LLShaderUniforms* uniforms, const LLSettingsBase::ptr_t &psetting) { - LL_RECORD_BLOCK_TIME(FTM_SHADER_PARAM_UPDATE); + LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER; + + for (int i = 0; i < LLGLSLShader::SG_COUNT; ++i) + { + uniforms[i].clear(); + } + LLShaderUniforms* shader = &uniforms[LLGLSLShader::SG_ANY]; //_WARNS("RIDER") << "----------------------------------------------------------------" << LL_ENDL; const LLSettingsBase::parammapping_t& params = psetting->getParameterMap(); const auto& settings_map = psetting->mSettings.map(); @@ -1671,7 +1705,7 @@ void LLEnvironment::updateGLVariablesForSettings(LLGLSLShader *shader, const LLS { LLVector4 vect4(value); //_WARNS("RIDER") << "pushing '" << (*it).first << "' as " << vect4 << LL_ENDL; - shader->uniform4fv(it.second.getShaderKey(), 1, vect4.mV); + shader->uniform4fv(it.second.getShaderKey(), vect4 ); break; } @@ -1684,17 +1718,44 @@ void LLEnvironment::updateGLVariablesForSettings(LLGLSLShader *shader, const LLS default: break; } - stop_glerror(); } //_WARNS("RIDER") << "----------------------------------------------------------------" << LL_ENDL; - psetting->applySpecial(shader); + psetting->applySpecial(uniforms); +} + +void LLEnvironment::updateShaderUniforms(LLGLSLShader* shader) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER; + + // apply uniforms that should be applied to all shaders + mSkyUniforms[LLGLSLShader::SG_ANY].apply(shader); + mWaterUniforms[LLGLSLShader::SG_ANY].apply(shader); + + // apply uniforms specific to the given shader's shader group + auto group = shader->mShaderGroup; + mSkyUniforms[group].apply(shader); + mWaterUniforms[group].apply(shader); } -void LLEnvironment::updateShaderUniforms(LLGLSLShader *shader) +void LLEnvironment::updateSettingsUniforms() { - updateGLVariablesForSettings(shader, mCurrentEnvironment->getWater()); - updateGLVariablesForSettings(shader, mCurrentEnvironment->getSky()); + if (mCurrentEnvironment->getWater()) + { + updateGLVariablesForSettings(mWaterUniforms, mCurrentEnvironment->getWater()); + } + else + { + LL_WARNS("ENVIRONMENT") << "Failed to update GL variable for water settings, environment is not properly set" << LL_ENDL; + } + if (mCurrentEnvironment->getSky()) + { + updateGLVariablesForSettings(mSkyUniforms, mCurrentEnvironment->getSky()); + } + else + { + LL_WARNS("ENVIRONMENT") << "Failed to update GL variable for sky settings, environment is not properly set" << LL_ENDL; + } } void LLEnvironment::recordEnvironment(S32 parcel_id, LLEnvironment::EnvironmentInfo::ptr_t envinfo, LLSettingsBase::Seconds transition) @@ -1836,7 +1897,7 @@ void LLEnvironment::requestParcel(S32 parcel_id, environment_apply_fn cb) { if (!cb) { - LLSettingsBase::Seconds transition = LLViewerParcelMgr::getInstanceFast()->getTeleportInProgress() ? TRANSITION_FAST : TRANSITION_DEFAULT; + LLSettingsBase::Seconds transition = LLViewerParcelMgr::getInstance()->getTeleportInProgress() ? TRANSITION_FAST : TRANSITION_DEFAULT; cb = [this, transition](S32 pid, EnvironmentInfo::ptr_t envinfo) { clearEnvironment(ENV_PARCEL); @@ -1853,7 +1914,7 @@ void LLEnvironment::requestParcel(S32 parcel_id, environment_apply_fn cb) if (!cb) { - LLSettingsBase::Seconds transition = LLViewerParcelMgr::getInstanceFast()->getTeleportInProgress() ? TRANSITION_FAST : TRANSITION_DEFAULT; + LLSettingsBase::Seconds transition = LLViewerParcelMgr::getInstance()->getTeleportInProgress() ? TRANSITION_FAST : TRANSITION_DEFAULT; cb = [this, transition](S32 pid, EnvironmentInfo::ptr_t envinfo) { recordEnvironment(pid, envinfo, transition); }; } @@ -2556,7 +2617,7 @@ void LLEnvironment::setExperienceEnvironment(LLUUID experience_id, LLSD data, F3 if (!water.isUndefined()) { - environment->injectWaterSettings(sky, experience_id, LLSettingsBase::Seconds(transition_time)); + environment->injectWaterSettings(water, experience_id, LLSettingsBase::Seconds(transition_time)); } if (updateenvironment) @@ -2612,6 +2673,7 @@ LLEnvironment::DayInstance::ptr_t LLEnvironment::DayInstance::clone() const bool LLEnvironment::DayInstance::applyTimeDelta(const LLSettingsBase::Seconds& delta) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_ENVIRONMENT; ptr_t keeper(shared_from_this()); // makes sure that this does not go away while it is being worked on. bool changed(false); @@ -3356,7 +3418,7 @@ namespace } { - LLParcel* parcel = LLViewerParcelMgr::instanceFast().getAgentParcel(); + LLParcel* parcel = LLViewerParcelMgr::instance().getAgentParcel(); if (!parcel) return; @@ -3475,7 +3537,7 @@ namespace void DayInjection::onParcelChange() { S32 parcel_id(INVALID_PARCEL_ID); - LLParcel* parcel = LLViewerParcelMgr::instanceFast().getAgentParcel(); + LLParcel* parcel = LLViewerParcelMgr::instance().getAgentParcel(); if (!parcel) return; diff --git a/indra/newview/llenvironment.h b/indra/newview/llenvironment.h index 18cd43be4d28ab524a6dafeda4c4bca12cf60cc2..e688bfec0545fde37c3d7d024184180416a9e3f4 100644 --- a/indra/newview/llenvironment.h +++ b/indra/newview/llenvironment.h @@ -36,20 +36,21 @@ #include "llsettingswater.h" #include "llsettingsdaycycle.h" +#include "llglslshader.h" + #include <boost/signals2.hpp> //------------------------------------------------------------------------- class LLViewerCamera; -class LLGLSLShader; class LLParcel; //------------------------------------------------------------------------- -class LLEnvironment final : public LLSingleton<LLEnvironment> +class LLEnvironment final : public LLSimpleton<LLEnvironment> { - LLSINGLETON(LLEnvironment); LOG_CLASS(LLEnvironment); - public: + LLEnvironment(); + static const F64Seconds TRANSITION_INSTANT; static const F64Seconds TRANSITION_FAST; static const F64Seconds TRANSITION_DEFAULT; @@ -112,7 +113,7 @@ class LLEnvironment final : public LLSingleton<LLEnvironment> typedef std::array<F32, 4> altitude_list_t; typedef std::vector<F32> altitudes_vect_t; - virtual ~LLEnvironment() = default; + ~LLEnvironment(); bool canEdit() const; bool isExtendedEnvironmentEnabled() const; @@ -127,9 +128,14 @@ class LLEnvironment final : public LLSingleton<LLEnvironment> void update(const LLViewerCamera * cam); - static void updateGLVariablesForSettings(LLGLSLShader *shader, const LLSettingsBase::ptr_t &psetting); + static void updateGLVariablesForSettings(LLShaderUniforms* uniforms, const LLSettingsBase::ptr_t &psetting); + + // apply current sky settings to given shader void updateShaderUniforms(LLGLSLShader *shader); + // prepare settings to be applied to shaders (call whenever settings are updated) + void updateSettingsUniforms(); + void setSelectedEnvironment(EnvSelection_t env, LLSettingsBase::Seconds transition = TRANSITION_DEFAULT, bool forced = false); EnvSelection_t getSelectedEnvironment() const { return mSelectedEnvironment; } @@ -148,6 +154,8 @@ class LLEnvironment final : public LLSingleton<LLEnvironment> static void logEnvironment(EnvSelection_t env, const LLSettingsBase::ptr_t &settings, S32 env_version = NO_VERSION); + void setCurrentEnvironmentSelection(LLEnvironment::EnvSelection_t env); + LLSettingsDay::ptr_t getEnvironmentDay(EnvSelection_t env); LLSettingsDay::Seconds getEnvironmentDayLength(EnvSelection_t env); @@ -228,6 +236,11 @@ class LLEnvironment final : public LLSingleton<LLEnvironment> void handleEnvironmentPush(LLSD &message); + //cached uniform values from LLSD values + LLShaderUniforms mWaterUniforms[LLGLSLShader::SG_COUNT]; + LLShaderUniforms mSkyUniforms[LLGLSLShader::SG_COUNT]; + // ======================================================================================= + class DayInstance: public std::enable_shared_from_this<DayInstance> { public: @@ -285,6 +298,7 @@ class LLEnvironment final : public LLSingleton<LLEnvironment> LLSettingsDay::ptr_t mDayCycle; LLSettingsSky::ptr_t mSky; LLSettingsWater::ptr_t mWater; + S32 mSkyTrack; bool mInitialized; @@ -328,9 +342,10 @@ class LLEnvironment final : public LLSingleton<LLEnvironment> // [/RLVa:KB] DayInstance::ptr_t getSharedEnvironmentInstance(); + void initSingleton(); + protected: - virtual void initSingleton() override; - virtual void cleanupSingleton() override; + void cleanupSingleton(); private: diff --git a/indra/newview/llexperiencelog.cpp b/indra/newview/llexperiencelog.cpp index 809b3385715e36e7aec62c2c76dd05adc42a8852..09b61616f2fd0b44898f39a48aab7e9dddc3c77a 100644 --- a/indra/newview/llexperiencelog.cpp +++ b/indra/newview/llexperiencelog.cpp @@ -149,13 +149,6 @@ std::string LLExperienceLog::getPermissionString( const LLSD& message, const std { buf.str(entry); } - else - { -// [SL:KB] - Patch: Viewer-Build | Checked: Catznip-6.5 - buf.str(""); -// [/SL:KB] -// buf.str(); - } } if(buf.str().empty()) diff --git a/indra/newview/llexternaleditor.cpp b/indra/newview/llexternaleditor.cpp index dae307755c23c32ec8d816758f450318ba86a8d0..b0d88159c1579ac3f59a11f753ce1df876e58fbe 100644 --- a/indra/newview/llexternaleditor.cpp +++ b/indra/newview/llexternaleditor.cpp @@ -183,9 +183,9 @@ std::string LLExternalEditor::findCommand( cmd = override; LL_INFOS() << "Using override" << LL_ENDL; } - else if (!LLUI::getInstanceFast()->mSettingGroups["config"]->getString(sSetting).empty()) + else if (!LLUI::getInstance()->mSettingGroups["config"]->getString(sSetting).empty()) { - cmd = LLUI::getInstanceFast()->mSettingGroups["config"]->getString(sSetting); + cmd = LLUI::getInstance()->mSettingGroups["config"]->getString(sSetting); LL_INFOS() << "Using setting" << LL_ENDL; } else // otherwise use the path specified by the environment variable diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 609724b9d9b640406dad0ccf1e23cba036d0449d..3f026cd8378ce7e1c23628b71603d97d03d9ef48 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -56,6 +56,7 @@ #include "llviewertexture.h" #include "llvoavatar.h" #include "llsculptidsize.h" +#include "llmeshrepository.h" // [RLVa:KB] - Checked: RLVa-2.0.0 #include "rlvhandler.h" // [/RLVa:KB] @@ -67,7 +68,6 @@ #pragma GCC diagnostic ignored "-Wuninitialized" #endif -extern BOOL gGLDebugLoggingEnabled; #define LL_MAX_INDICES_COUNT 1000000 static LLStaticHashedString sTextureIndexIn("texture_index_in"); @@ -75,6 +75,7 @@ static LLStaticHashedString sColorIn("color_in"); BOOL LLFace::sSafeRenderSelect = TRUE; // FALSE + #define DOTVEC(a,b) (a.mV[0]*b.mV[0] + a.mV[1]*b.mV[1] + a.mV[2]*b.mV[2]) /* @@ -131,6 +132,7 @@ void planarProjection(LLVector2 &tc, const LLVector4a& normal, void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE; mLastUpdateTime = gFrameTimeSeconds; mLastMoveTime = 0.f; mLastSkinTime = gFrameTimeSeconds; @@ -204,14 +206,7 @@ void LLFace::destroy() if (mDrawPoolp) { - if (this->isState(LLFace::RIGGED) && (mDrawPoolp->getType() == LLDrawPool::POOL_CONTROL_AV || mDrawPoolp->getType() == LLDrawPool::POOL_AVATAR)) - { - ((LLDrawPoolAvatar*) mDrawPoolp)->removeRiggedFace(this); - } - else - { - mDrawPoolp->removeFace(this); - } + mDrawPoolp->removeFace(this); mDrawPoolp = NULL; } @@ -249,6 +244,8 @@ void LLFace::setPool(LLFacePool* pool) void LLFace::setPool(LLFacePool* new_pool, LLViewerTexture *texturep) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE + if (!new_pool) { LL_ERRS() << "Setting pool to null!" << LL_ENDL; @@ -337,6 +334,8 @@ void LLFace::setSpecularMap(LLViewerTexture* tex) void LLFace::dirtyTexture() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE + LLDrawable* drawablep = getDrawable(); if (mVObjp.notNull() && mVObjp->getVolume()) @@ -560,6 +559,8 @@ void LLFace::updateCenterAgent() void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE + if (mDrawablep == NULL || mDrawablep->getSpatialGroup() == NULL) { return; @@ -608,7 +609,7 @@ void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color) glPolygonOffset(-1.f, -1.f); gGL.multMatrix(volume->getRelativeXform()); const LLVolumeFace& vol_face = rigged->getVolumeFace(getTEOffset()); - LLVertexBuffer::drawElements(LLRender::TRIANGLES,vol_face.mNumVertices, vol_face.mPositions, vol_face.mTexCoords, vol_face.mNumIndices, vol_face.mIndices); + LLVertexBuffer::drawElements(LLRender::TRIANGLES,vol_face.mPositions, vol_face.mTexCoords, vol_face.mNumIndices, vol_face.mIndices); } } } @@ -627,6 +628,8 @@ void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color) void renderFace(LLDrawable* drawable, LLFace *face) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE + LLVOVolume* vobj = drawable->getVOVolume(); if (vobj) { @@ -644,7 +647,7 @@ void renderFace(LLDrawable* drawable, LLFace *face) if (volume) { const LLVolumeFace& vol_face = volume->getVolumeFace(face->getTEOffset()); - LLVertexBuffer::drawElements(LLRender::TRIANGLES, vol_face.mNumVertices, vol_face.mPositions, NULL, vol_face.mNumIndices, vol_face.mIndices); + LLVertexBuffer::drawElements(LLRender::TRIANGLES, vol_face.mPositions, NULL, vol_face.mNumIndices, vol_face.mIndices); } } } @@ -662,17 +665,7 @@ void LLFace::renderOneWireframe(const LLColor4 &color, F32 fogCfx, bool wirefram } else { - if (!LLGLSLShader::sNoFixedFunction) - { - LLGLEnable fog(GL_FOG); - glFogi(GL_FOG_MODE, GL_LINEAR); - float d = (LLViewerCamera::getInstanceFast()->getPointOfInterest() - LLViewerCamera::getInstanceFast()->getOrigin()).magVec(); - LLColor4 fogCol = color * fogCfx; - glFogf(GL_FOG_START, d); - glFogf(GL_FOG_END, d * (1 + (LLViewerCamera::getInstanceFast()->getView() / LLViewerCamera::getInstanceFast()->getDefaultFOV()))); - glFogfv(GL_FOG_COLOR, fogCol.mV); - } - gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); + gGL.flush(); { gGL.diffuseColor4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.4f); renderFace(mDrawablep, this); @@ -912,6 +905,8 @@ bool less_than_max_mag(const LLVector4a& vec) BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f, const LLMatrix4a& mat_vert, BOOL global_volume) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE + //get bounding box if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION | LLDrawable::REBUILD_RIGGED)) { @@ -1200,6 +1195,11 @@ bool LLFace::canRenderAsMask() return true; } + if (isState(LLFace::RIGGED)) + { // never auto alpha-mask rigged faces + return false; + } + const LLTextureEntry* te = getTextureEntry(); if( !te || !getViewerObject() || !getTexture() ) { @@ -1240,33 +1240,13 @@ bool LLFace::canRenderAsMask() } -static LLTrace::BlockTimerStatHandle FTM_FACE_GET_GEOM("Face Geom"); -static LLTrace::BlockTimerStatHandle FTM_FACE_GEOM_POSITION("Position"); -static LLTrace::BlockTimerStatHandle FTM_FACE_GEOM_NORMAL("Normal"); -static LLTrace::BlockTimerStatHandle FTM_FACE_GEOM_TEXTURE("Texture"); -static LLTrace::BlockTimerStatHandle FTM_FACE_GEOM_COLOR("Color"); -static LLTrace::BlockTimerStatHandle FTM_FACE_GEOM_EMISSIVE("Emissive"); -static LLTrace::BlockTimerStatHandle FTM_FACE_GEOM_WEIGHTS("Weights"); -static LLTrace::BlockTimerStatHandle FTM_FACE_GEOM_TANGENT("Binormal"); - -static LLTrace::BlockTimerStatHandle FTM_FACE_GEOM_INDEX("Index"); -static LLTrace::BlockTimerStatHandle FTM_FACE_GEOM_INDEX_TAIL("Tail"); -static LLTrace::BlockTimerStatHandle FTM_FACE_POSITION_STORE("Pos"); -static LLTrace::BlockTimerStatHandle FTM_FACE_TEXTURE_INDEX_STORE("TexIdx"); -static LLTrace::BlockTimerStatHandle FTM_FACE_POSITION_PAD("Pad"); -static LLTrace::BlockTimerStatHandle FTM_FACE_TEX_DEFAULT("Default"); -static LLTrace::BlockTimerStatHandle FTM_FACE_TEX_QUICK("Quick"); -static LLTrace::BlockTimerStatHandle FTM_FACE_TEX_QUICK_NO_XFORM("No Xform"); -static LLTrace::BlockTimerStatHandle FTM_FACE_TEX_QUICK_XFORM("Xform"); -static LLTrace::BlockTimerStatHandle FTM_FACE_TEX_QUICK_PLANAR("Quick Planar"); - BOOL LLFace::getGeometryVolume(const LLVolume& volume, const S32 &f, - const LLMatrix4a& mat_vert, const LLMatrix4a& mat_normal, + const LLMatrix4a& mat_vert_in, const LLMatrix4a& mat_norm_in, const U16 &index_offset, bool force_rebuild) { - LL_RECORD_BLOCK_TIME(FTM_FACE_GET_GEOM); + LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE; llassert(verify()); if (volume.getNumVolumeFaces() <= f) { @@ -1274,7 +1254,9 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, return FALSE; } - const LLVolumeFace &vf = volume.getVolumeFace(f); + bool rigged = isState(RIGGED); + + const LLVolumeFace &vf = volume.getVolumeFace(f); S32 num_vertices = (S32)vf.mNumVertices; S32 num_indices = (S32) vf.mNumIndices; @@ -1414,7 +1396,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, // INDICES if (full_rebuild) { - LL_RECORD_BLOCK_TIME(FTM_FACE_GEOM_INDEX); + LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - indices"); mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex, mIndicesCount, map_range); volatile __m128i* dst = (__m128i*) indicesp.get(); @@ -1430,7 +1412,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, } { - LL_RECORD_BLOCK_TIME(FTM_FACE_GEOM_INDEX_TAIL); + LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - indices tail"); U16* idx = (U16*) dst; for (S32 i = end*8; i < num_indices; ++i) @@ -1478,6 +1460,45 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, do_xform = false; } } + const LLMeshSkinInfo* skin = nullptr; + LLMatrix4a mat_vert; + LLMatrix4a mat_normal; + + // prepare mat_vert + if (rebuild_pos) + { + if (rigged) + { //override with bind shape matrix if rigged + skin = mSkinInfo; + mat_vert = skin->mBindShapeMatrix; + } + else + { + mat_vert = mat_vert_in; + } + } + + if (rebuild_normal || rebuild_tangent) + { //override mat_normal with inverse of skin->mBindShapeMatrix + LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - norm mat override"); + if (rigged) + { + if (skin == nullptr) + { + skin = mSkinInfo; + } + + //TODO -- cache this (check profile marker above)? + mat_normal = skin->mBindShapeMatrix; + mat_normal.invert(); + mat_normal.transpose(); + } + else + { + mat_normal = mat_norm_in; + } + } + { //if it's not fullbright and has no normals, bake sunlight based on face normal @@ -1486,7 +1507,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, if (rebuild_tcoord) { - LL_RECORD_BLOCK_TIME(FTM_FACE_GEOM_TEXTURE); + LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - tcoord"); //bump setup LLVector4a binormal_dir( -sin_ang, cos_ang, 0.f ); @@ -1585,7 +1606,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, do_xform = false; } - if (getVirtualSize() >= MIN_TEX_ANIM_SIZE || isState(LLFace::RIGGED)) + if (getVirtualSize() >= MIN_TEX_ANIM_SIZE) // || isState(LLFace::RIGGED)) { //don't override texture transform during tc bake tex_mode = 0; } @@ -1612,18 +1633,18 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, if (texgen != LLTextureEntry::TEX_GEN_PLANAR) { - LL_RECORD_BLOCK_TIME(FTM_FACE_TEX_QUICK); + LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - texgen"); if (!do_tex_mat) { if (!do_xform) { - LL_RECORD_BLOCK_TIME(FTM_FACE_TEX_QUICK_NO_XFORM); + LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("ggv - texgen 1"); S32 tc_size = (num_vertices*2*sizeof(F32)+0xF) & ~0xF; LLVector4a::memcpyNonAliased16((F32*) tex_coords0.get(), (F32*) vf.mTexCoords, tc_size); } else { - LL_RECORD_BLOCK_TIME(FTM_FACE_TEX_QUICK_XFORM); + LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("ggv - texgen 2"); F32* dst = (F32*) tex_coords0.get(); LLVector4a* src = (LLVector4a*) vf.mTexCoords; @@ -1662,8 +1683,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, { //do tex mat, no texgen, no bump for (S32 i = 0; i < num_vertices; i++) { - //LLVector4a& norm = vf.mNormals[i]; - //LLVector4a& center = *(vf.mCenter); LLVector4a tc(vf.mTexCoords[i].mV[VX],vf.mTexCoords[i].mV[VY],0.f); mTextureMatrix->affineTransform(tc,tc); (tex_coords0++)->set(tc.getF32ptr()); @@ -1672,7 +1691,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, } else { //no bump, tex gen planar - LL_RECORD_BLOCK_TIME(FTM_FACE_TEX_QUICK_PLANAR); + LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - texgen planar"); if (do_tex_mat) { for (S32 i = 0; i < num_vertices; i++) @@ -1714,7 +1733,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, } else { //bump mapped or has material, just do the whole expensive loop - LL_RECORD_BLOCK_TIME(FTM_FACE_TEX_DEFAULT); + LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - texgen default"); std::vector<LLVector2> bump_tc; if (!LLPipeline::sRenderDeferred && !mat && do_bump) @@ -1876,11 +1895,11 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, LLVector4a* end = src+num_vertices; //LLVector4a* end_64 = end-4; - //LL_RECORD_TIME_BLOCK(FTM_FACE_GEOM_POSITION); llassert(num_vertices > 0); mVertexBuffer->getVertexStrider(vert, mGeomIndex, mGeomCount, map_range); + F32* dst = (F32*) vert.get(); F32* end_f32 = dst+mGeomCount*4; @@ -1910,53 +1929,19 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, LLVector4a tmp; - { - //LL_RECORD_TIME_BLOCK(FTM_FACE_POSITION_STORE); - - /*if (num_vertices > 4) - { //more than 64 bytes - while (src < end_64) - { - _mm_prefetch((char*)src + 64, _MM_HINT_T0); - _mm_prefetch((char*)dst + 64, _MM_HINT_T0); - - mat_vert.affineTransform(*src, res0); - tmp.setSelectWithMask(mask, texIdx, res0); - tmp.store4a((F32*) dst); - - mat_vert.affineTransform(*(src+1), res1); - tmp.setSelectWithMask(mask, texIdx, res1); - tmp.store4a((F32*) dst+4); - - mat_vert.affineTransform(*(src+2), res2); - tmp.setSelectWithMask(mask, texIdx, res2); - tmp.store4a((F32*) dst+8); - - mat_vert.affineTransform(*(src+3), res3); - tmp.setSelectWithMask(mask, texIdx, res3); - tmp.store4a((F32*) dst+12); - - dst += 16; - src += 4; - } - }*/ - - while (src < end) - { - mat_vert.affineTransform(*src++, res0); - tmp.setSelectWithMask(mask, texIdx, res0); - tmp.store4a((F32*) dst); - dst += 4; - } + + while (src < end) + { + mat_vert.affineTransform(*src++, res0); + tmp.setSelectWithMask(mask, texIdx, res0); + tmp.store4a((F32*) dst); + dst += 4; } - + + while (dst < end_f32) { - //LL_RECORD_TIME_BLOCK(FTM_FACE_POSITION_PAD); - while (dst < end_f32) - { - res0.store4a((F32*) dst); - dst += 4; - } + res0.store4a((F32*) dst); + dst += 4; } if (map_range) @@ -1965,10 +1950,10 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, } } - if (rebuild_normal) { - //LL_RECORD_TIME_BLOCK(FTM_FACE_GEOM_NORMAL); + LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - normal"); + mVertexBuffer->getNormalStrider(norm, mGeomIndex, mGeomCount, map_range); F32* normals = (F32*) norm.get(); LLVector4a* src = vf.mNormals; @@ -1990,7 +1975,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, if (rebuild_tangent) { - LL_RECORD_BLOCK_TIME(FTM_FACE_GEOM_TANGENT); + LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - tangent"); mVertexBuffer->getTangentStrider(tangent, mGeomIndex, mGeomCount, map_range); F32* tangents = (F32*) tangent.get(); @@ -2028,7 +2013,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, if (rebuild_weights && vf.mWeights) { - LL_RECORD_BLOCK_TIME(FTM_FACE_GEOM_WEIGHTS); + LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - weight"); mVertexBuffer->getWeight4Strider(wght, mGeomIndex, mGeomCount, map_range); wght.copyArray(0, vf.mWeights, num_vertices); if (map_range) @@ -2039,7 +2024,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, if (rebuild_color && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_COLOR) ) { - LL_RECORD_BLOCK_TIME(FTM_FACE_GEOM_COLOR); + LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - color"); mVertexBuffer->getColorStrider(colors, mGeomIndex, mGeomCount, map_range); LLVector4a src; @@ -2070,7 +2055,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, if (rebuild_emissive) { - LL_RECORD_BLOCK_TIME(FTM_FACE_GEOM_EMISSIVE); + LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - emissive"); LLStrider<LLColor4U> emissive; mVertexBuffer->getEmissiveStrider(emissive, mGeomIndex, mGeomCount, map_range); @@ -2201,15 +2186,38 @@ F32 LLFace::getTextureVirtualSize() BOOL LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE; + //VECTORIZE THIS //get area of circle around face - LLVector4a center; - center.load3(getPositionAgent().mV); - LLVector4a size; - size.setSub(mExtents[1], mExtents[0]); + + LLVector4a center; + LLVector4a size; + + + if (isState(LLFace::RIGGED)) + { + //override with avatar bounding box + LLVOAvatar* avatar = mVObjp->getAvatar(); + if (avatar && avatar->mDrawable) + { + center.load3(avatar->getPositionAgent().mV); + const LLVector4a* exts = avatar->mDrawable->getSpatialExtents(); + size.setSub(exts[1], exts[0]); + } + else + { + return false; + } + } + else + { + center.load3(getPositionAgent().mV); + size.setSub(mExtents[1], mExtents[0]); + } size.mul(0.5f); - LLViewerCamera* camera = LLViewerCamera::getInstanceFast(); + LLViewerCamera* camera = LLViewerCamera::getInstance(); F32 size_squared = size.dot3(size).getF32(); LLVector4a lookAt; @@ -2314,7 +2322,7 @@ F32 LLFace::calcImportanceToCamera(F32 cos_angle_to_view_dir, F32 dist) { F32 importance = 0.f ; - LLViewerCamera& camera = LLViewerCamera::instanceFast(); + LLViewerCamera& camera = LLViewerCamera::instance(); if(cos_angle_to_view_dir > camera.getCosHalfFov() && dist < FACE_IMPORTANCE_TO_CAMERA_OVER_DISTANCE[FACE_IMPORTANCE_LEVEL - 1][0]) @@ -2480,6 +2488,8 @@ const LLMatrix4a& LLFace::getRenderMatrix() const S32 LLFace::renderElements(const U16 *index_array) const { + LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE + S32 ret = 0; if (isState(GLOBAL)) @@ -2499,6 +2509,8 @@ S32 LLFace::renderElements(const U16 *index_array) const S32 LLFace::renderIndexed() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE + if(mDrawablep == NULL || mDrawPoolp == NULL) { return 0; @@ -2509,6 +2521,8 @@ S32 LLFace::renderIndexed() S32 LLFace::renderIndexed(U32 mask) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE + if (mVertexBuffer.isNull()) { return 0; @@ -2647,56 +2661,6 @@ void LLFace::clearVertexBuffer() mVertexBuffer = NULL; } -//static -U32 LLFace::getRiggedDataMask(U32 type) -{ - static const U32 rigged_data_mask[] = { - LLDrawPoolAvatar::RIGGED_MATERIAL_MASK, - LLDrawPoolAvatar::RIGGED_MATERIAL_ALPHA_VMASK, - LLDrawPoolAvatar::RIGGED_MATERIAL_ALPHA_MASK_MASK, - LLDrawPoolAvatar::RIGGED_MATERIAL_ALPHA_EMISSIVE_MASK, - LLDrawPoolAvatar::RIGGED_SPECMAP_VMASK, - LLDrawPoolAvatar::RIGGED_SPECMAP_BLEND_MASK, - LLDrawPoolAvatar::RIGGED_SPECMAP_MASK_MASK, - LLDrawPoolAvatar::RIGGED_SPECMAP_EMISSIVE_MASK, - LLDrawPoolAvatar::RIGGED_NORMMAP_VMASK, - LLDrawPoolAvatar::RIGGED_NORMMAP_BLEND_MASK, - LLDrawPoolAvatar::RIGGED_NORMMAP_MASK_MASK, - LLDrawPoolAvatar::RIGGED_NORMMAP_EMISSIVE_MASK, - LLDrawPoolAvatar::RIGGED_NORMSPEC_VMASK, - LLDrawPoolAvatar::RIGGED_NORMSPEC_BLEND_MASK, - LLDrawPoolAvatar::RIGGED_NORMSPEC_MASK_MASK, - LLDrawPoolAvatar::RIGGED_NORMSPEC_EMISSIVE_MASK, - LLDrawPoolAvatar::RIGGED_SIMPLE_MASK, - LLDrawPoolAvatar::RIGGED_FULLBRIGHT_MASK, - LLDrawPoolAvatar::RIGGED_SHINY_MASK, - LLDrawPoolAvatar::RIGGED_FULLBRIGHT_SHINY_MASK, - LLDrawPoolAvatar::RIGGED_GLOW_MASK, - LLDrawPoolAvatar::RIGGED_ALPHA_MASK, - LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA_MASK, - LLDrawPoolAvatar::RIGGED_DEFERRED_BUMP_MASK, - LLDrawPoolAvatar::RIGGED_DEFERRED_SIMPLE_MASK, - }; - - llassert(type < sizeof(rigged_data_mask)/sizeof(U32)); - - return rigged_data_mask[type]; -} - -U32 LLFace::getRiggedVertexBufferDataMask() const -{ - U32 data_mask = 0; - for (U32 i = 0; i < mRiggedIndex.size(); ++i) - { - if (mRiggedIndex[i] > -1) - { - data_mask |= LLFace::getRiggedDataMask(i); - } - } - - return data_mask; -} - S32 LLFace::getRiggedIndex(U32 type) const { if (mRiggedIndex.empty()) @@ -2709,19 +2673,7 @@ S32 LLFace::getRiggedIndex(U32 type) const return mRiggedIndex[type]; } -void LLFace::setRiggedIndex(U32 type, S32 index) +U64 LLFace::getSkinHash() { - if (mRiggedIndex.empty()) - { - mRiggedIndex.resize(LLDrawPoolAvatar::NUM_RIGGED_PASSES); - for (U32 i = 0; i < mRiggedIndex.size(); ++i) - { - mRiggedIndex[i] = -1; - } - } - - llassert(type < mRiggedIndex.size()); - - mRiggedIndex[type] = index; + return mSkinInfo ? mSkinInfo->mHash : 0; } - diff --git a/indra/newview/llface.h b/indra/newview/llface.h index cfe1b2a233dfd85117387746293d5309437bfff7..c4290694305575d00e8861a17d03e4ad42061b4a 100644 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -47,15 +47,16 @@ class LLTextureEntry; class LLVertexProgram; class LLViewerTexture; class LLGeometryManager; -class LLTextureAtlasSlot; class LLDrawInfo; +class LLMeshSkinInfo; const F32 MIN_ALPHA_SIZE = 1024.f; const F32 MIN_TEX_ANIM_SIZE = 512.f; const U8 FACE_DO_NOT_BATCH_TEXTURES = 255; -class LLFace : public LLTrace::MemTrackableNonVirtual<LLFace, 16> +class alignas(16) LLFace { + LL_ALIGN_NEW public: LLFace(const LLFace& rhs) = delete; LLFace& operator=(const LLFace& rhs) = delete; @@ -74,8 +75,8 @@ class LLFace : public LLTrace::MemTrackableNonVirtual<LLFace, 16> public: LLFace(LLDrawable* drawablep, LLViewerObject* objp) - : LLTrace::MemTrackableNonVirtual<LLFace, 16>("LLFace") { + LL_PROFILE_ZONE_SCOPED; init(drawablep, objp); } ~LLFace() { destroy(); } @@ -132,7 +133,7 @@ class LLFace : public LLTrace::MemTrackableNonVirtual<LLFace, 16> LLViewerObject* getViewerObject() const { return mVObjp; } S32 getLOD() const { return mVObjp.notNull() ? mVObjp->getLOD() : 0; } void setPoolType(U32 type) { mPoolType = type; } - S32 getTEOffset() { return mTEOffset; } + S32 getTEOffset() const { return mTEOffset; } LLViewerTexture* getTexture(U32 ch = LLRender::DIFFUSE_MAP) const; void setViewerObject(LLViewerObject* object); @@ -222,15 +223,17 @@ class LLFace : public LLTrace::MemTrackableNonVirtual<LLFace, 16> void setVertexBuffer(LLVertexBuffer* buffer); void clearVertexBuffer(); //sets mVertexBuffer to NULL LLVertexBuffer* getVertexBuffer() const { return mVertexBuffer; } - U32 getRiggedVertexBufferDataMask() const; S32 getRiggedIndex(U32 type) const; - void setRiggedIndex(U32 type, S32 index); - - static U32 getRiggedDataMask(U32 type); void notifyAboutCreatingTexture(LLViewerTexture *texture); void notifyAboutMissingAsset(LLViewerTexture *texture); + // used to preserve draw order of faces that are batched together. + // Allows content creators to manipulate linked sets and face ordering + // for consistent alpha sorting results, particularly for rigged attachments + void setDrawOrderIndex(U32 index) { mDrawOrderIndex = index; } + U32 getDrawOrderIndex() const { return mDrawOrderIndex; } + public: //aligned members LLVector4a mExtents[2]; @@ -252,7 +255,12 @@ class LLFace : public LLTrace::MemTrackableNonVirtual<LLFace, 16> F32 mLastSkinTime; F32 mLastMoveTime; LLMatrix4a* mTextureMatrix; - LLDrawInfo* mDrawInfo; + LLDrawInfo* mDrawInfo = nullptr; + LLVOAvatar* mAvatar = nullptr; + LLMeshSkinInfo* mSkinInfo = nullptr; + + // return mSkinInfo->mHash or 0 if mSkinInfo is null + U64 getSkinHash(); private: LLPointer<LLVertexBuffer> mVertexBuffer; @@ -263,10 +271,10 @@ class LLFace : public LLTrace::MemTrackableNonVirtual<LLFace, 16> LLColor4 mFaceColor; // overrides material color if state |= USE_FACE_COLOR U16 mGeomCount; // vertex count for this face - U16 mGeomIndex; // index into draw pool + U16 mGeomIndex; // starting index into mVertexBuffer's vertex array U8 mTextureIndex; // index of texture channel to use for pseudo-atlasing U32 mIndicesCount; - U32 mIndicesIndex; // index into draw pool for indices (yeah, I know!) + U32 mIndicesIndex; // index into mVertexBuffer's index array S32 mIndexInTex[LLRender::NUM_TEXTURE_CHANNELS]; LLXformMatrix* mXform; @@ -296,6 +304,8 @@ class LLFace : public LLTrace::MemTrackableNonVirtual<LLFace, 16> bool mHasMedia ; bool mIsMediaAllowed; + U32 mDrawOrderIndex = 0; // see setDrawOrderIndex + // [SL:KB] - Patch: Render-TextureToggle (Catznip-4.0) mutable bool mShowDiffTexture; mutable LLPointer<LLViewerTexture> mOrigDiffTexture; diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp index f45c38f0e829eadf29c3321396be56da8c81af58..ede8e3e0fbf2e49e9f1c8bc7a53ae241b0d4b3da 100644 --- a/indra/newview/llfasttimerview.cpp +++ b/indra/newview/llfasttimerview.cpp @@ -302,7 +302,7 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask) // could be that existing tooltip is for a parent and is thus // covering region for this new timer, go ahead and unblock // so we can create a new tooltip - LLToolTipMgr::instanceFast().unblockToolTips(); + LLToolTipMgr::instance().unblockToolTips(); mHoverTimer = mHoverID; mToolTipRect.set(mBarRect.mLeft + (hover_bar->mSelfStart / mTotalTimeDisplay) * mBarRect.getWidth(), row.mTop, @@ -351,7 +351,7 @@ BOOL LLFastTimerView::handleToolTip(S32 x, S32 y, MASK mask) std::string tooltip = get_tooltip(*mHoverTimer, mHoverBarIndex > 0 ? mScrollIndex + mHoverBarIndex : 0, mRecording); - LLToolTipMgr::instanceFast().show(LLToolTip::Params() + LLToolTipMgr::instance().show(LLToolTip::Params() .message(tooltip) .sticky_rect(screen_rect) .delay_time(0.f)); @@ -367,7 +367,7 @@ BOOL LLFastTimerView::handleToolTip(S32 x, S32 y, MASK mask) BlockTimerStatHandle* idp = getLegendID(y); if (idp) { - LLToolTipMgr::instanceFast().show(get_tooltip(*idp, 0, mRecording)); + LLToolTipMgr::instance().show(get_tooltip(*idp, 0, mRecording)); return TRUE; } @@ -521,20 +521,6 @@ void LLFastTimerView::exportCharts(const std::string& base, const std::string& t is.close(); } - //get time domain - LLSD::Real cur_total_time = 0.0; - - for (U32 i = 0; i < cur_data.size(); ++i) - { - cur_total_time += cur_data[i]["Total"]["Time"].asReal(); - } - - LLSD::Real base_total_time = 0.0; - for (U32 i = 0; i < base_data.size(); ++i) - { - base_total_time += base_data[i]["Total"]["Time"].asReal(); - } - //allocate raw scratch space LLPointer<LLImageRaw> scratch = new LLImageRaw(1024, 512, 3); @@ -733,7 +719,6 @@ void LLFastTimerView::exportCharts(const std::string& base, const std::string& t //====================================== buffer.clear(); - gGL.color3fv(base_col.mV); U32 count = 0; U32 total_count = base_execution.size(); @@ -1036,11 +1021,9 @@ void LLFastTimerView::printLineStats() } } -static LLTrace::BlockTimerStatHandle FTM_DRAW_LINE_GRAPH("Draw line graph"); - void LLFastTimerView::drawLineGraph() { - LL_RECORD_BLOCK_TIME(FTM_DRAW_LINE_GRAPH); + LL_PROFILE_ZONE_SCOPED; //draw line graph history gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); LLLocalClipRect clip(mGraphRect); @@ -1079,6 +1062,7 @@ void LLFastTimerView::drawLineGraph() F32Seconds cur_max(0); U32 cur_max_calls = 0; + for(block_timer_tree_df_iterator_t it = LLTrace::begin_block_timer_tree_df(FTM_FRAME); it != LLTrace::end_block_timer_tree_df(); ++it) @@ -1112,6 +1096,7 @@ void LLFastTimerView::drawLineGraph() F32 call_scale_factor = (F32)mGraphRect.getHeight() / (F32)max_calls; F32 time_scale_factor = (F32)mGraphRect.getHeight() / max_time.value(); F32 hz_scale_factor = (F32) mGraphRect.getHeight() / (1.f / max_time.value()); + for (U32 j = mRecording.getNumRecordedPeriods(); j > 0; j--) @@ -1119,7 +1104,7 @@ void LLFastTimerView::drawLineGraph() LLTrace::Recording& recording = mRecording.getPrevRecording(j); F32Seconds time = llmax(recording.getSum(*idp), F64Seconds(0.000001)); U32 calls = recording.getSum(idp->callCount()); - + if (is_hover_timer) { //normalize to highlighted timer @@ -1465,6 +1450,7 @@ void LLFastTimerView::updateTotalTime() void LLFastTimerView::drawBars() { + LL_PROFILE_ZONE_SCOPED; LLLocalClipRect clip(mBarRect); S32 bar_height = mBarRect.getHeight() / (MAX_VISIBLE_HISTORY + 2); @@ -1544,11 +1530,9 @@ void LLFastTimerView::drawBars() gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); } -//static LLTrace::BlockTimerStatHandle FTM_UPDATE_TIMER_BAR_WIDTHS("Update timer bar widths"); - F32Seconds LLFastTimerView::updateTimerBarWidths(LLTrace::BlockTimerStatHandle* time_block, TimerBarRow& row, S32 history_index, U32& bar_index) { -// LL_RECORD_BLOCK_TIME(FTM_UPDATE_TIMER_BAR_WIDTHS); + LL_PROFILE_ZONE_SCOPED; const F32Seconds self_time = history_index == -1 ? mRecording.getPeriodMean(time_block->selfTime(), RUNNING_AVERAGE_WIDTH) : mRecording.getPrevRecording(history_index).getSum(time_block->selfTime()); @@ -1572,11 +1556,9 @@ F32Seconds LLFastTimerView::updateTimerBarWidths(LLTrace::BlockTimerStatHandle* return full_time; } -//static LLTrace::BlockTimerStatHandle FTM_UPDATE_TIMER_BAR_FRACTIONS("Update timer bar fractions"); - S32 LLFastTimerView::updateTimerBarOffsets(LLTrace::BlockTimerStatHandle* time_block, TimerBarRow& row, S32 timer_bar_index) { -// LL_RECORD_BLOCK_TIME(FTM_UPDATE_TIMER_BAR_FRACTIONS); + LL_PROFILE_ZONE_SCOPED; TimerBar& timer_bar = row.mBars[timer_bar_index]; const F32Seconds bar_time = timer_bar.mTotalTime - timer_bar.mSelfTime; @@ -1637,6 +1619,7 @@ S32 LLFastTimerView::updateTimerBarOffsets(LLTrace::BlockTimerStatHandle* time_b S32 LLFastTimerView::drawBar(LLRect bar_rect, TimerBarRow& row, S32 image_width, S32 image_height, bool hovered, bool visible, S32 bar_index) { + LL_PROFILE_ZONE_SCOPED; TimerBar& timer_bar = row.mBars[bar_index]; LLTrace::BlockTimerStatHandle* time_block = timer_bar.mTimeBlock; diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp index 34f60bec062ce80889cfaa7fc999522926d37433..815db449cf9fa31ae0ece17611ebdcc543bd89a6 100644 --- a/indra/newview/llfavoritesbar.cpp +++ b/indra/newview/llfavoritesbar.cpp @@ -174,7 +174,7 @@ class LLFavoriteLandmarkButton : public LLButton params.max_width = 1000; params.sticky_rect = calcScreenRect(); - LLToolTipMgr::instanceFast().show(params); + LLToolTipMgr::instance().show(params); } return TRUE; } @@ -196,7 +196,7 @@ class LLFavoriteLandmarkButton : public LLButton void onMouseEnter(S32 x, S32 y, MASK mask) { - if (LLToolDragAndDrop::getInstanceFast()->hasMouseCapture()) + if (LLToolDragAndDrop::getInstance()->hasMouseCapture()) { LLUICtrl::onMouseEnter(x, y, mask); } @@ -232,7 +232,7 @@ class LLFavoriteLandmarkMenuItem : public LLMenuItemCallGL LLToolTip::Params params; params.message = llformat("%s\n%s (%d, %d)", getLabel().c_str(), region_name.c_str(), mLandmarkInfoGetter.getPosX(), mLandmarkInfoGetter.getPosY()); params.sticky_rect = calcScreenRect(); - LLToolTipMgr::instanceFast().show(params); + LLToolTipMgr::instance().show(params); } return TRUE; } @@ -471,7 +471,25 @@ BOOL LLFavoritesBarCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, } // check if we are dragging an existing item from the favorites bar - if (item && mDragItemId == item->getUUID()) + bool existing_drop = false; + if (item && mDragItemId == item->getUUID()) + { + // There is a chance of mDragItemId being obsolete + // ex: can happen if something interrupts viewer, which + // results in viewer not geting a 'mouse up' signal + for (LLInventoryModel::item_array_t::iterator i = mItems.begin(); i != mItems.end(); ++i) + { + LLViewerInventoryItem* currItem = *i; + + if (currItem->getUUID() == mDragItemId) + { + existing_drop = true; + break; + } + } + } + + if (existing_drop) { *accept = ACCEPT_YES_SINGLE; @@ -500,6 +518,7 @@ BOOL LLFavoritesBarCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, if (mItems.empty()) { setLandingTab(NULL); + mLastTab = NULL; } handleNewFavoriteDragAndDrop(item, favorites_id, x, y); } @@ -515,6 +534,12 @@ BOOL LLFavoritesBarCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, void LLFavoritesBarCtrl::handleExistingFavoriteDragAndDrop(S32 x, S32 y) { + if (mItems.empty()) + { + // Isn't supposed to be empty + return; + } + // Identify the button hovered and the side to drop LLFavoriteLandmarkButton* dest = dynamic_cast<LLFavoriteLandmarkButton*>(mLandingTab); bool insert_before = true; @@ -718,14 +743,14 @@ void LLFavoritesBarCtrl::draw() { if (mItemsChangedTimer.getElapsedTimeF32() > 1.f) { - LLFavoritesOrderStorage::instanceFast().saveFavoritesRecord(); + LLFavoritesOrderStorage::instance().saveFavoritesRecord(); mItemsChangedTimer.stop(); } } - if(!mItemsChangedTimer.getStarted() && LLFavoritesOrderStorage::instanceFast().mUpdateRequired) + if(!mItemsChangedTimer.getStarted() && LLFavoritesOrderStorage::instance().mUpdateRequired) { - LLFavoritesOrderStorage::instanceFast().mUpdateRequired = false; + LLFavoritesOrderStorage::instance().mUpdateRequired = false; mItemsChangedTimer.start(); } @@ -772,6 +797,14 @@ void LLFavoritesBarCtrl::updateButtons(bool force_update) } LLFavoritesOrderStorage::instance().mPrevFavorites = mItems; mGetPrevItems = false; + + if (LLFavoritesOrderStorage::instance().isStorageUpdateNeeded()) + { + if (!mItemsChangedTimer.getStarted()) + { + mItemsChangedTimer.start(); + } + } } const LLButton::Params& button_params = getButtonParams(); @@ -779,6 +812,7 @@ void LLFavoritesBarCtrl::updateButtons(bool force_update) if(mItems.empty()) { mBarLabel->setVisible(TRUE); + mLastTab = NULL; } else { @@ -825,6 +859,10 @@ void LLFavoritesBarCtrl::updateButtons(bool force_update) dynamic_cast<LLFavoriteLandmarkButton*> (*cur_it); if (button) { + if (mLastTab == button) + { + mLastTab = NULL; + } removeChild(button); delete button; } @@ -861,6 +899,17 @@ void LLFavoritesBarCtrl::updateButtons(bool force_update) mLastTab = last_new_button; } + if (!mLastTab && mItems.size() > 0) + { + // mMoreTextBox was removed, so LLFavoriteLandmarkButtons + // should be the only ones in the list + LLFavoriteLandmarkButton* button = dynamic_cast<LLFavoriteLandmarkButton*> (childs->back()); + if (button) + { + mLastTab = button; + } + } + mFirstDropDownItem = j; // Chevron button if (mFirstDropDownItem < mItems.size()) @@ -1607,7 +1656,7 @@ void LLFavoritesOrderStorage::destroyClass() file.close(); LLFile::remove(filename); } - if(mSaveOnExit) + if(mSaveOnExit || gSavedSettings.getBOOL("UpdateRememberPasswordSetting")) { LLFavoritesOrderStorage::instance().saveFavoritesRecord(true); } @@ -1651,7 +1700,6 @@ void LLFavoritesOrderStorage::load() llifstream in_file; in_file.open(filename.c_str()); LLSD fav_llsd; - LLSD user_llsd; if (in_file.is_open()) { LLSDSerialize::fromXML(fav_llsd, in_file); @@ -1661,12 +1709,12 @@ void LLFavoritesOrderStorage::load() in_file.close(); if (fav_llsd.isMap() && fav_llsd.has(gAgentUsername)) { - user_llsd = fav_llsd[gAgentUsername]; + mStorageFavorites = fav_llsd[gAgentUsername]; S32 index = 0; bool needs_validation = gSavedPerAccountSettings.getBOOL("ShowFavoritesOnLogin"); - for (LLSD::array_iterator iter = user_llsd.beginArray(); - iter != user_llsd.endArray(); ++iter) + for (LLSD::array_iterator iter = mStorageFavorites.beginArray(); + iter != mStorageFavorites.endArray(); ++iter) { // Validation LLUUID fv_id = iter->get("id").asUUID(); @@ -1972,7 +2020,7 @@ BOOL LLFavoritesOrderStorage::saveFavoritesRecord(bool pref_changed) } } - if((items != mPrevFavorites) || name_changed || pref_changed) + if((items != mPrevFavorites) || name_changed || pref_changed || gSavedSettings.getBOOL("UpdateRememberPasswordSetting")) { std::string filename = getStoredFavoritesFilename(); if (!filename.empty()) @@ -1993,6 +2041,12 @@ BOOL LLFavoritesOrderStorage::saveFavoritesRecord(bool pref_changed) LLSD user_llsd; S32 fav_iter = 0; mMissingSLURLs.clear(); + + LLSD save_pass; + save_pass["save_password"] = gSavedSettings.getBOOL("RememberPassword"); + user_llsd[fav_iter] = save_pass; + fav_iter++; + for (LLInventoryModel::item_array_t::iterator it = items.begin(); it != items.end(); it++) { LLSD value; @@ -2063,6 +2117,23 @@ void LLFavoritesOrderStorage::showFavoritesOnLoginChanged(BOOL show) } } +bool LLFavoritesOrderStorage::isStorageUpdateNeeded() +{ + if (!mRecreateFavoriteStorage) + { + for (LLSD::array_iterator iter = mStorageFavorites.beginArray(); + iter != mStorageFavorites.endArray(); ++iter) + { + if (mFavoriteNames[iter->get("id").asUUID()] != iter->get("name").asString()) + { + mRecreateFavoriteStorage = true; + return true; + } + } + } + return false; +} + void AddFavoriteLandmarkCallback::fire(const LLUUID& inv_item_id) { if (mTargetLandmarkId.isNull()) return; diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h index 2ccb39c1bff608633d6e2289580718ae6eb060be..2fb9f8411ca329dec650b6a421cdcc00ce98166d 100644 --- a/indra/newview/llfavoritesbar.h +++ b/indra/newview/llfavoritesbar.h @@ -226,8 +226,11 @@ class LLFavoritesOrderStorage final : public LLSingleton<LLFavoritesOrderStorage BOOL saveFavoritesRecord(bool pref_changed = false); void showFavoritesOnLoginChanged(BOOL show); - LLInventoryModel::item_array_t mPrevFavorites; + bool isStorageUpdateNeeded(); + LLInventoryModel::item_array_t mPrevFavorites; + LLSD mStorageFavorites; + bool mRecreateFavoriteStorage; const static S32 NO_INDEX; static bool mSaveOnExit; @@ -254,7 +257,6 @@ class LLFavoritesOrderStorage final : public LLSingleton<LLFavoritesOrderStorage slurls_map_t mSLURLs; std::set<LLUUID> mMissingSLURLs; bool mIsDirty; - bool mRecreateFavoriteStorage; struct IsNotInFavorites { diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp index 41b3a60b9cac81bd7a2e7d0fc08adae4774f3e20..b3da3b1acbb7b84bdbe4138fb1a8326259e8293d 100644 --- a/indra/newview/llfeaturemanager.cpp +++ b/indra/newview/llfeaturemanager.cpp @@ -380,7 +380,10 @@ F32 gpu_benchmark(); F32 logExceptionBenchmark() { - // Todo: make a wrapper/class for SEH exceptions + // FIXME: gpu_benchmark uses many C++ classes on the stack to control state. + // SEH exceptions with our current exception handling options do not call + // destructors for these classes, resulting in an undefined state should + // this handler be invoked. F32 gbps = -1; __try { @@ -388,6 +391,9 @@ F32 logExceptionBenchmark() } __except (msc_exception_filter(GetExceptionCode(), GetExceptionInformation())) { + // HACK - ensure that profiling is disabled + LLGLSLShader::finishProfile(false); + // convert to C++ styled exception char integer_string[32]; snprintf(integer_string, 32, "SEH, code: %lu\n", GetExceptionCode()); @@ -519,7 +525,6 @@ void LLFeatureManager::initSingleton() void LLFeatureManager::applyRecommendedSettings() { - loadGPUClass(); // apply saved settings // cap the level at 2 (high) U32 level = llmax(GPU_CLASS_0, llmin(mGPUClass, GPU_CLASS_5)); @@ -606,22 +611,6 @@ void LLFeatureManager::setGraphicsLevel(U32 level, bool skipFeatures) // if we're passed an invalid level, default to "Low" std::string features(isValidGraphicsLevel(level)? getNameForGraphicsLevel(level) : "Low"); - if (features == "Low") - { -#if LL_DARWIN - // This Mac-specific change is to insure that we force 'Basic Shaders' for all Mac - // systems which support them instead of falling back to fixed-function unnecessarily - // MAINT-2157 - if (gGLManager.mGLVersion < 2.1f) -#else - // only use fixed function by default if GL version < 3.0 or this is an intel graphics chip - if (gGLManager.mGLVersion < 3.f || gGLManager.mIsIntel) -#endif - { - // same as Low, but with "Basic Shaders" disabled - features = "LowFixedFunction"; - } - } maskFeatures(features); @@ -669,46 +658,18 @@ void LLFeatureManager::applyBaseMasks() } // now all those wacky ones - if (!gGLManager.mHasFragmentShader) - { - maskFeatures("NoPixelShaders"); - } - if (!gGLManager.mHasVertexShader || !mGPUSupported) - { - maskFeatures("NoVertexShaders"); - } if (gGLManager.mIsNVIDIA) { maskFeatures("NVIDIA"); } - if (gGLManager.mIsGF2or4MX) - { - maskFeatures("GeForce2"); - } - if (gGLManager.mIsATI) - { - maskFeatures("ATI"); - } - if (gGLManager.mHasATIMemInfo && gGLManager.mVRAM < 256) + if (gGLManager.mIsAMD) { - maskFeatures("ATIVramLT256"); - } - if (gGLManager.mATIOldDriver) - { - maskFeatures("ATIOldDriver"); - } - if (gGLManager.mIsGFFX) - { - maskFeatures("GeForceFX"); + maskFeatures("AMD"); } if (gGLManager.mIsIntel) { maskFeatures("Intel"); } - if (gGLManager.mGLVersion < 1.5f) - { - maskFeatures("OpenGLPre15"); - } if (gGLManager.mGLVersion < 3.f) { maskFeatures("OpenGLPre30"); @@ -744,17 +705,6 @@ void LLFeatureManager::applyBaseMasks() //LL_INFOS() << "Masking features from gpu table match: " << gpustr << LL_ENDL; maskFeatures(gpustr); - // now mask cpu type ones - if (gSysMemory.getPhysicalMemoryKB() <= U32Megabytes(256)) - { - maskFeatures("RAM256MB"); - } - - if (gSysCPU.getMHz() < 1100) - { - maskFeatures("CPUSlow"); - } - if (isSafe()) { maskFeatures("safe"); @@ -769,11 +719,9 @@ LLSD LLFeatureManager::getRecommendedSettingsMap() LLSD map(LLSD::emptyMap()); - loadGPUClass(); U32 level = llmax(GPU_CLASS_0, llmin(mGPUClass, GPU_CLASS_5)); LL_INFOS("RenderInit") << "Getting the map of recommended settings for level " << level << LL_ENDL; - applyBaseMasks(); std::string features(isValidGraphicsLevel(level) ? getNameForGraphicsLevel(level) : "Low"); maskFeatures(features); diff --git a/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp index 1cc1adf014a92504ee88f828b157a1d4e1cc38c1..dcc4af3f041f63a992289c92f264d10d9e91c9bf 100644 --- a/indra/newview/llflexibleobject.cpp +++ b/indra/newview/llflexibleobject.cpp @@ -47,9 +47,6 @@ static const F32 SEC_PER_FLEXI_FRAME = 1.f / 60.f; // 60 flexi updates per secon /*static*/ F32 LLVolumeImplFlexible::sUpdateFactor = 1.0f; std::vector<LLVolumeImplFlexible*> LLVolumeImplFlexible::sInstanceList; -static LLTrace::BlockTimerStatHandle FTM_FLEXIBLE_REBUILD("Rebuild"); -static LLTrace::BlockTimerStatHandle FTM_DO_FLEXIBLE_UPDATE("Flexible Update"); - // LLFlexibleObjectData::pack/unpack now in llprimitive.cpp //----------------------------------------------- @@ -95,7 +92,7 @@ LLVolumeImplFlexible::~LLVolumeImplFlexible() //static void LLVolumeImplFlexible::updateClass() { - LL_RECORD_BLOCK_TIME(FTM_DO_FLEXIBLE_UPDATE); + LL_PROFILE_ZONE_SCOPED; U64 virtual_frame_num = LLTimer::getElapsedSeconds() / SEC_PER_FLEXI_FRAME; for (std::vector<LLVolumeImplFlexible*>::iterator iter = sInstanceList.begin(); @@ -312,7 +309,7 @@ void LLVolumeImplFlexible::updateRenderRes() F32 app_angle = ll_round((F32) atan2( mVO->getScale().mV[2]*2.f, drawablep->mDistanceWRTCamera) * RAD_TO_DEG, 0.01f); // Rendering sections increases with visible angle on the screen - mRenderRes = (S32)(FLEXIBLE_OBJECT_MAX_SECTIONS*4*app_angle*DEG_TO_RAD/LLViewerCamera::getInstanceFast()->getView()); + mRenderRes = (S32)(FLEXIBLE_OBJECT_MAX_SECTIONS*4*app_angle*DEG_TO_RAD/LLViewerCamera::getInstance()->getView()); #endif mRenderRes = llclamp(mRenderRes, new_res-1, (S32) FLEXIBLE_OBJECT_MAX_SECTIONS); @@ -360,7 +357,7 @@ void LLVolumeImplFlexible::doIdleUpdate() // Note: Flexies afar will be rarely updated, closer ones will be updated more frequently. // But frequency differences are extremely noticeable, so consider modifying update factor, // or at least clamping value a bit more from both sides. - U32 update_period = (U32) (llmax((S32) (LLViewerCamera::getInstanceFast()->getScreenPixelArea()*0.01f/(pixel_area*(sUpdateFactor+1.f))),0)+1); + U32 update_period = (U32) (llmax((S32) (LLViewerCamera::getInstance()->getScreenPixelArea()*0.01f/(pixel_area*(sUpdateFactor+1.f))),0)+1); // MAINT-1890 Clamp the update period to ensure that the update_period is no greater than 32 frames update_period = llclamp(update_period, 1U, 32U); @@ -389,7 +386,8 @@ void LLVolumeImplFlexible::doIdleUpdate() U64 throttling_delay = (virtual_frame_num + id) % update_period; if ((throttling_delay == 0 && mLastFrameNum < virtual_frame_num) //one or more virtual frames per frame - || (mLastFrameNum + update_period < virtual_frame_num)) // missed virtual frame + || (mLastFrameNum + update_period < virtual_frame_num) // missed virtual frame + || mLastFrameNum > virtual_frame_num) // overflow { // We need mLastFrameNum to compensate for 'unreliable time' and to filter 'duplicate' frames // If happened too late, subtract throttling_delay (it is zero otherwise) @@ -429,7 +427,7 @@ inline S32 log2(S32 x) void LLVolumeImplFlexible::doFlexibleUpdate() { - LL_RECORD_BLOCK_TIME(FTM_DO_FLEXIBLE_UPDATE); + LL_PROFILE_ZONE_SCOPED; LLVolume* volume = mVO->getVolume(); LLPath *path = &volume->getPath(); if ((mSimulateRes == 0 || !mInitialized) && mVO->mDrawable->isVisible()) @@ -720,13 +718,12 @@ void LLVolumeImplFlexible::doFlexibleUpdate() mLastSegmentRotation = parentSegmentRotation; } -static LLTrace::BlockTimerStatHandle FTM_FLEXI_PREBUILD("Flexi Prebuild"); void LLVolumeImplFlexible::preRebuild() { if (!mUpdated) { - LL_RECORD_BLOCK_TIME(FTM_FLEXI_PREBUILD); + LL_PROFILE_ZONE_SCOPED; doFlexibleRebuild(false); } } @@ -755,6 +752,7 @@ void LLVolumeImplFlexible::onSetScale(const LLVector3& scale, BOOL damped) BOOL LLVolumeImplFlexible::doUpdateGeometry(LLDrawable *drawable) { + LL_PROFILE_ZONE_SCOPED; LLVOVolume *volume = (LLVOVolume*)mVO; if (mVO->isAttachment()) @@ -790,11 +788,7 @@ BOOL LLVolumeImplFlexible::doUpdateGeometry(LLDrawable *drawable) volume->updateRelativeXform(); - if (mRenderRes > -1) - { - LL_RECORD_BLOCK_TIME(FTM_DO_FLEXIBLE_UPDATE); - doFlexibleUpdate(); - } + doFlexibleUpdate(); // Object may have been rotated, which means it needs a rebuild. See SL-47220 BOOL rotated = FALSE; @@ -812,7 +806,6 @@ BOOL LLVolumeImplFlexible::doUpdateGeometry(LLDrawable *drawable) volume->mDrawable->setState(LLDrawable::REBUILD_VOLUME); volume->dirtySpatialGroup(); { - LL_RECORD_BLOCK_TIME(FTM_FLEXIBLE_REBUILD); doFlexibleRebuild(volume->mVolumeChanged); } volume->genBBoxes(isVolumeGlobal()); diff --git a/indra/newview/llfloater360capture.cpp b/indra/newview/llfloater360capture.cpp index a489531fe2f5b4c2e99d25885e81c2096cbfbd6b..4e9a36e67de64900d5afd2dfbde4e90edc7c6e6d 100644 --- a/indra/newview/llfloater360capture.cpp +++ b/indra/newview/llfloater360capture.cpp @@ -114,6 +114,11 @@ BOOL LLFloater360Capture::postBuild() // by default each time vs restoring the last value mQualityRadioGroup->setSelectedIndex(0); + return true; +} + +void LLFloater360Capture::onOpen(const LLSD& key) +{ // Construct a URL pointing to the first page to load. Although // we do not use this page for anything (after some significant // design changes), we retain the code to load the start page @@ -154,8 +159,6 @@ BOOL LLFloater360Capture::postBuild() // We do an initial capture when the floater is opened, albeit at a 'preview' // quality level (really low resolution, but really fast) onCapture360ImagesBtn(); - - return true; } // called when the user choose a quality level using diff --git a/indra/newview/llfloater360capture.h b/indra/newview/llfloater360capture.h index 6da7ee074a399e4fa25f76af36aac1d0b18ab718..8f765c0b1be16019fd22089cacf0891c56017788 100644 --- a/indra/newview/llfloater360capture.h +++ b/indra/newview/llfloater360capture.h @@ -47,6 +47,7 @@ class LLFloater360Capture: ~LLFloater360Capture(); BOOL postBuild() override; + void onOpen(const LLSD& key) override; void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) override; void changeInterestListMode(bool send_everything); diff --git a/indra/newview/llfloaterauction.cpp b/indra/newview/llfloaterauction.cpp index bda4e3748199890d5eb5035973ea48082aa5e5b1..5b90137940d2dd38d0a9a02960807c9b5d33a550 100644 --- a/indra/newview/llfloaterauction.cpp +++ b/indra/newview/llfloaterauction.cpp @@ -102,8 +102,8 @@ void LLFloaterAuction::initialize() { mParcelUpdateCapUrl.clear(); - mParcelp = LLViewerParcelMgr::getInstanceFast()->getParcelSelection(); - LLViewerRegion* region = LLViewerParcelMgr::getInstanceFast()->getSelectionRegion(); + mParcelp = LLViewerParcelMgr::getInstance()->getParcelSelection(); + LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion(); LLParcel* parcelp = mParcelp->getParcel(); if(parcelp && region && !parcelp->getForSale()) { @@ -482,7 +482,7 @@ bool LLFloaterAuction::onSellToAnyoneConfirmed(const LLSD& notification, const L void LLFloaterAuction::doSellToAnyone() { LLParcel* parcelp = mParcelp->getParcel(); - LLViewerRegion* region = LLViewerParcelMgr::getInstanceFast()->getSelectionRegion(); + LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion(); if (parcelp && region diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp index 195dd783ccf6834fcc221013f1266ff51b8dfeb1..0cb22c8cd5a6dc0328b4c75ccec168b835c1a1a5 100644 --- a/indra/newview/llfloateravatarpicker.cpp +++ b/indra/newview/llfloateravatarpicker.cpp @@ -109,6 +109,7 @@ LLFloaterAvatarPicker::LLFloaterAvatarPicker(const LLSD& key) mNumResultsReturned(0), mNearMeListComplete(FALSE), mCloseOnSelect(FALSE), + mExcludeAgentFromSearchResults(FALSE), mContextConeOpacity (0.f), mContextConeInAlpha(0.f), mContextConeOutAlpha(0.f), @@ -315,11 +316,11 @@ void LLFloaterAvatarPicker::populateNearMe() near_me_scroller->deleteAllItems(); uuid_vec_t avatar_ids; - LLWorld::getInstanceFast()->getAvatars(&avatar_ids, NULL, gAgent.getPositionGlobal(), ALControlCache::NearMeRange); + LLWorld::getInstance()->getAvatars(&avatar_ids, NULL, gAgent.getPositionGlobal(), ALControlCache::NearMeRange); for(U32 i=0; i<avatar_ids.size(); i++) { LLUUID& av = avatar_ids[i]; - if(av == gAgent.getID()) continue; + if(mExcludeAgentFromSearchResults && (av == gAgent.getID())) continue; LLSD element; element["id"] = av; // value LLAvatarName av_name; diff --git a/indra/newview/llfloaterbuildoptions.cpp b/indra/newview/llfloaterbuildoptions.cpp index 75e0c872a7b5e94d7d9b547dd917355557be2a52..1b65d8d68384956703570225742e62a38a955437 100644 --- a/indra/newview/llfloaterbuildoptions.cpp +++ b/indra/newview/llfloaterbuildoptions.cpp @@ -57,7 +57,7 @@ BOOL LLFloaterBuildOptions::postBuild() // virtual void LLFloaterBuildOptions::onOpen(const LLSD& key) { - mObjectSelection = LLSelectMgr::getInstanceFast()->getEditSelection(); + mObjectSelection = LLSelectMgr::getInstance()->getEditSelection(); } // virtual diff --git a/indra/newview/llfloaterbulkpermission.cpp b/indra/newview/llfloaterbulkpermission.cpp index cbd32fa716c936b069da6c1a068df996dd3cc0e4..a1a06706bc6da7a57dcfb851e049c9ae1f36eea2 100644 --- a/indra/newview/llfloaterbulkpermission.cpp +++ b/indra/newview/llfloaterbulkpermission.cpp @@ -111,7 +111,7 @@ void LLFloaterBulkPermission::doApply() LLScrollListCtrl* list = getChild<LLScrollListCtrl>("queue output"); list->deleteAllItems(); ModifiableGatherer gatherer(mObjectIDs); - LLSelectMgr::getInstanceFast()->getSelection()->applyToNodes(&gatherer); + LLSelectMgr::getInstance()->getSelection()->applyToNodes(&gatherer); if(mObjectIDs.empty()) { list->setCommentText(getString("nothing_to_modify_text")); diff --git a/indra/newview/llfloaterbuy.cpp b/indra/newview/llfloaterbuy.cpp index a8ee4645f19e3857aa1728eb4f6e11ed3846d5f9..8ca1a7f0295f512fac5c912288dd14a5d878b353 100644 --- a/indra/newview/llfloaterbuy.cpp +++ b/indra/newview/llfloaterbuy.cpp @@ -90,7 +90,7 @@ void LLFloaterBuy::reset() // static void LLFloaterBuy::show(const LLSaleInfo& sale_info) { - LLObjectSelectionHandle selection = LLSelectMgr::getInstanceFast()->getSelection(); + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); if (selection->getRootObjectCount() != 1) { @@ -106,9 +106,9 @@ void LLFloaterBuy::show(const LLSaleInfo& sale_info) floater->reset(); floater->mSaleInfo = sale_info; // [RLVa:KB] - Checked: RLVa-2.0.0 - floater->mObjectSelection = LLSelectMgr::getInstanceFast()->getSelection(); + floater->mObjectSelection = LLSelectMgr::getInstance()->getSelection(); // [/RLVa:KB] -// floater->mObjectSelection = LLSelectMgr::getInstanceFast()->getEditSelection(); +// floater->mObjectSelection = LLSelectMgr::getInstance()->getEditSelection(); LLSelectNode* node = selection->getFirstRootNode(); if (!node) @@ -131,7 +131,7 @@ void LLFloaterBuy::show(const LLSaleInfo& sale_info) LLUUID owner_id; std::string owner_name; - BOOL owners_identical = LLSelectMgr::getInstanceFast()->selectGetOwner(owner_id, owner_name); + BOOL owners_identical = LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name); if (!owners_identical) { LLNotificationsUtil::add("BuyObjectOneOwner"); @@ -194,7 +194,7 @@ void LLFloaterBuy::show(const LLSaleInfo& sale_info) if (!floater->mSelectionUpdateSlot.connected()) { - floater->mSelectionUpdateSlot = LLSelectMgr::getInstanceFast()->mUpdateSignal.connect(boost::bind(&LLFloaterBuy::onSelectionChanged, floater)); + floater->mSelectionUpdateSlot = LLSelectMgr::getInstance()->mUpdateSignal.connect(boost::bind(&LLFloaterBuy::onSelectionChanged, floater)); } } @@ -294,12 +294,12 @@ void LLFloaterBuy::inventoryChanged(LLViewerObject* obj, void LLFloaterBuy::onSelectionChanged() { - if (LLSelectMgr::getInstanceFast()->getEditSelection()->getRootObjectCount() == 0) + if (LLSelectMgr::getInstance()->getEditSelection()->getRootObjectCount() == 0) { removeVOInventoryListener(); closeFloater(); } - else if (LLSelectMgr::getInstanceFast()->getEditSelection()->getRootObjectCount() > 1) + else if (LLSelectMgr::getInstance()->getEditSelection()->getRootObjectCount() > 1) { removeVOInventoryListener(); showViews(false); @@ -324,7 +324,7 @@ void LLFloaterBuy::onClickBuy() // *NOTE: doesn't work for multiple object buy, which UI does not // currently support sale info is used for verification only, if // it doesn't match region info then sale is canceled. - LLSelectMgr::getInstanceFast()->sendBuy(gAgent.getID(), category_id, mSaleInfo ); + LLSelectMgr::getInstance()->sendBuy(gAgent.getID(), category_id, mSaleInfo ); closeFloater(); } diff --git a/indra/newview/llfloaterbuycontents.cpp b/indra/newview/llfloaterbuycontents.cpp index 1c24d33810f9875c7b582c7fe3ea63ca02a3a5a4..a06371a603fed8509a2d3ba62e06fb23d0313b7a 100644 --- a/indra/newview/llfloaterbuycontents.cpp +++ b/indra/newview/llfloaterbuycontents.cpp @@ -87,7 +87,7 @@ LLFloaterBuyContents::~LLFloaterBuyContents() // static void LLFloaterBuyContents::show(const LLSaleInfo& sale_info) { - LLObjectSelectionHandle selection = LLSelectMgr::getInstanceFast()->getSelection(); + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); if (selection->getRootObjectCount() != 1) { @@ -104,13 +104,13 @@ void LLFloaterBuyContents::show(const LLSaleInfo& sale_info) list->deleteAllItems(); // [RLVa:KB] - Checked: RLVa-2.0.0 - floater->mObjectSelection = LLSelectMgr::getInstanceFast()->getSelection(); + floater->mObjectSelection = LLSelectMgr::getInstance()->getSelection(); // [/RLVa:KB] -// floater->mObjectSelection = LLSelectMgr::getInstanceFast()->getEditSelection(); +// floater->mObjectSelection = LLSelectMgr::getInstance()->getEditSelection(); LLUUID owner_id; std::string owner_name; - BOOL owners_identical = LLSelectMgr::getInstanceFast()->selectGetOwner(owner_id, owner_name); + BOOL owners_identical = LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name); if (!owners_identical) { LLNotificationsUtil::add("BuyContentsOneOwner"); @@ -289,7 +289,7 @@ void LLFloaterBuyContents::onClickBuy() // *NOTE: doesn't work for multiple object buy, which UI does not // currently support sale info is used for verification only, if // it doesn't match region info then sale is canceled. - LLSelectMgr::getInstanceFast()->sendBuy(gAgent.getID(), category_id, mSaleInfo); + LLSelectMgr::getInstance()->sendBuy(gAgent.getID(), category_id, mSaleInfo); // NOTE: do this here instead of on receipt of object, since contents are transfered // via a generic BulkUpdateInventory message with no way of distinguishing it from diff --git a/indra/newview/llfloaterbvhpreview.cpp b/indra/newview/llfloaterbvhpreview.cpp index 7a26b865b0b47cfb971f31639a2c383bfeb9978d..fa344d63f054d0fc4bcf686c4a7e82f3837e68e4 100644 --- a/indra/newview/llfloaterbvhpreview.cpp +++ b/indra/newview/llfloaterbvhpreview.cpp @@ -259,7 +259,7 @@ BOOL LLFloaterBvhPreview::postBuild() loaderp->serialize(dp); dp.reset(); LL_INFOS("BVH") << "Deserializing motionp" << LL_ENDL; - BOOL success = motionp && motionp->deserialize(dp, mMotionID); + BOOL success = motionp && motionp->deserialize(dp, mMotionID, false); LL_INFOS("BVH") << "Done" << LL_ENDL; delete []buffer; @@ -279,7 +279,7 @@ BOOL LLFloaterBvhPreview::postBuild() //temp.mV[VZ] = 0.f; F32 pelvis_max_displacement = pelvis_offset + (temp.magVec() * 0.5f) + 1.f; - F32 camera_zoom = LLViewerCamera::getInstanceFast()->getDefaultFOV() / (2.f * atan(pelvis_max_displacement / PREVIEW_CAMERA_DISTANCE)); + F32 camera_zoom = LLViewerCamera::getInstance()->getDefaultFOV() / (2.f * atan(pelvis_max_displacement / PREVIEW_CAMERA_DISTANCE)); mAnimPreview->setZoom(camera_zoom); @@ -1014,7 +1014,12 @@ LLPreviewAnimation::LLPreviewAnimation(S32 width, S32 height) : LLViewerDynamicT mDummyAvatar = (LLVOAvatar*)gObjectList.createObjectViewer(LL_PCODE_LEGACY_AVATAR, gAgent.getRegion(), LLViewerObject::CO_FLAG_UI_AVATAR); mDummyAvatar->mSpecialRenderMode = 1; mDummyAvatar->startMotion(ANIM_AGENT_STAND, BASE_ANIM_TIME_OFFSET); - mDummyAvatar->hideSkirt(); + + // on idle overall apperance update will set skirt to visible, so either + // call early or account for mSpecialRenderMode in updateMeshVisibility + mDummyAvatar->updateOverallAppearance(); + mDummyAvatar->hideHair(); + mDummyAvatar->hideSkirt(); // stop extraneous animations mDummyAvatar->stopMotion( ANIM_AGENT_HEAD_ROT, TRUE ); @@ -1054,10 +1059,7 @@ BOOL LLPreviewAnimation::render() gGL.pushMatrix(); gGL.loadIdentity(); - if (LLGLSLShader::sNoFixedFunction) - { - gUIProgram.bind(); - } + gUIProgram.bind(); LLGLSUIDefault def; gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); @@ -1079,15 +1081,15 @@ BOOL LLPreviewAnimation::render() LLQuaternion(mCameraYaw, LLVector3::z_axis); LLQuaternion av_rot = avatarp->mRoot->getWorldRotation() * camera_rot; - LLViewerCamera::getInstanceFast()->setOriginAndLookAt( + LLViewerCamera::getInstance()->setOriginAndLookAt( target_pos + ((LLVector3(mCameraDistance, 0.f, 0.f) + mCameraOffset) * av_rot), // camera LLVector3::z_axis, // up target_pos + (mCameraOffset * av_rot) ); // point of interest - LLViewerCamera::getInstanceFast()->setView(LLViewerCamera::getInstanceFast()->getDefaultFOV() / mCameraZoom); - LLViewerCamera::getInstanceFast()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, FALSE); + LLViewerCamera::getInstance()->setView(LLViewerCamera::getInstance()->getDefaultFOV() / mCameraZoom); + LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, FALSE); - mCameraRelPos = LLViewerCamera::getInstanceFast()->getOrigin() - avatarp->mHeadp->getWorldPosition(); + mCameraRelPos = LLViewerCamera::getInstance()->getOrigin() - avatarp->mHeadp->getWorldPosition(); //avatarp->setAnimationData("LookAtPoint", (void *)&mCameraRelPos); @@ -1105,6 +1107,7 @@ BOOL LLPreviewAnimation::render() { LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)face->getPool(); avatarp->dirtyMesh(); + gPipeline.enableLightsPreview(); avatarPoolp->renderAvatars(avatarp); // renders only one avatar } } diff --git a/indra/newview/llfloatercamera.cpp b/indra/newview/llfloatercamera.cpp index a262d1f039a342cfe84a9d638fb7aa0d2587fe6b..4377c2ebb60a7d5e76f93040b9e9e180031b778e 100644 --- a/indra/newview/llfloatercamera.cpp +++ b/indra/newview/llfloatercamera.cpp @@ -240,7 +240,7 @@ void LLPanelCameraZoom::onSliderValueChanged() void activate_camera_tool() { - LLToolMgr::getInstanceFast()->setTransientTool(LLToolCamera::getInstanceFast()); + LLToolMgr::getInstance()->setTransientTool(LLToolCamera::getInstance()); }; // @@ -417,8 +417,8 @@ ECameraControlMode LLFloaterCamera::determineMode() return CAMERA_CTRL_MODE_PAN; } - LLTool* curr_tool = LLToolMgr::getInstanceFast()->getCurrentTool(); - if (curr_tool == LLToolCamera::getInstanceFast()) + LLTool* curr_tool = LLToolMgr::getInstance()->getCurrentTool(); + if (curr_tool == LLToolCamera::getInstance()) { return CAMERA_CTRL_MODE_FREE_CAMERA; } @@ -434,9 +434,9 @@ ECameraControlMode LLFloaterCamera::determineMode() void clear_camera_tool() { - LLToolMgr* tool_mgr = LLToolMgr::getInstanceFast(); + LLToolMgr* tool_mgr = LLToolMgr::getInstance(); if (tool_mgr->usingTransientTool() && - tool_mgr->getCurrentTool() == LLToolCamera::getInstanceFast()) + tool_mgr->getCurrentTool() == LLToolCamera::getInstance()) { tool_mgr->clearTransientTool(); } diff --git a/indra/newview/llfloaterclassified.cpp b/indra/newview/llfloaterclassified.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3520b0f67aad50ef064618955e5129bfd7b11d69 --- /dev/null +++ b/indra/newview/llfloaterclassified.cpp @@ -0,0 +1,71 @@ +/** + * @file llfloaterclassified.cpp + * @brief LLFloaterClassified for displaying classifieds. + * + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Second Life Viewer Source Code + * 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 + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfloaterclassified.h" + +LLFloaterClassified::LLFloaterClassified(const LLSD& key) + : LLFloater(key) +{ +} + +LLFloaterClassified::~LLFloaterClassified() +{ +} + +void LLFloaterClassified::onOpen(const LLSD& key) +{ + LLPanel* panel = findChild<LLPanel>("main_panel", true); + if (panel) + { + panel->onOpen(key); + } + if (key.has("classified_name")) + { + setTitle(key["classified_name"].asString()); + } + LLFloater::onOpen(key); +} + +BOOL LLFloaterClassified::postBuild() +{ + return TRUE; +} + + +bool LLFloaterClassified::matchesKey(const LLSD& key) +{ + bool is_mkey_valid = mKey.has("classified_id"); + bool is_key_valid = key.has("classified_id"); + if (is_mkey_valid && is_key_valid) + { + return key["classified_id"].asUUID() == mKey["classified_id"].asUUID(); + } + return is_mkey_valid == is_key_valid; +} + +// eof diff --git a/indra/newview/llfloaterclassified.h b/indra/newview/llfloaterclassified.h new file mode 100644 index 0000000000000000000000000000000000000000..2c95d82b2c389dc7ab6284d6638585001b41fe6a --- /dev/null +++ b/indra/newview/llfloaterclassified.h @@ -0,0 +1,45 @@ +/** + * @file llfloaterclassified.h + * @brief LLFloaterClassified for displaying classifieds. + * + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Second Life Viewer Source Code + * 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 + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLFLOATERCLASSIFIED_H +#define LL_LLFLOATERCLASSIFIED_H + +#include "llfloater.h" + +class LLFloaterClassified : public LLFloater +{ + LOG_CLASS(LLFloaterClassified); +public: + LLFloaterClassified(const LLSD& key); + virtual ~LLFloaterClassified(); + + void onOpen(const LLSD& key) override; + BOOL postBuild() override; + + bool matchesKey(const LLSD& key) override; +}; + +#endif // LL_LLFLOATERCLASSIFIED_H diff --git a/indra/newview/llfloatercolorpicker.cpp b/indra/newview/llfloatercolorpicker.cpp index 3ed8774cae20d54da70368700958645e86277bf9..373ef57fa5e89fd6aae8e4a31b43989ea4db6ab9 100644 --- a/indra/newview/llfloatercolorpicker.cpp +++ b/indra/newview/llfloatercolorpicker.cpp @@ -167,7 +167,6 @@ void LLFloaterColorPicker::showUI () openFloater(getKey()); setVisible ( TRUE ); setFocus ( TRUE ); - setRevertOnCancel(FALSE); // HACK: if system color picker is required - close the SL one we made and use default system dialog if ( gSavedSettings.getBOOL ( "UseDefaultColorPicker" ) ) @@ -179,15 +178,23 @@ void LLFloaterColorPicker::showUI () // code that will get switched in for default system color picker if ( swatch ) { + // Todo: this needs to be threaded for viewer not to timeout LLColor4 curCol = swatch->get (); send_agent_pause(); - getWindow()->dialogColorPicker( &curCol [ 0 ], &curCol [ 1 ], &curCol [ 2 ] ); + bool commit = getWindow()->dialogColorPicker( &curCol [ 0 ], &curCol [ 1 ], &curCol [ 2 ] ); send_agent_resume(); - setOrigRgb ( curCol [ 0 ], curCol [ 1 ], curCol [ 2 ] ); - setCurRgb( curCol [ 0 ], curCol [ 1 ], curCol [ 2 ] ); - - LLColorSwatchCtrl::onColorChanged ( swatch, LLColorSwatchCtrl::COLOR_CHANGE ); + if (commit) + { + setOrigRgb(curCol[0], curCol[1], curCol[2]); + setCurRgb(curCol[0], curCol[1], curCol[2]); + + LLColorSwatchCtrl::onColorChanged(swatch, LLColorSwatchCtrl::COLOR_SELECT); + } + else + { + LLColorSwatchCtrl::onColorChanged(swatch, LLColorSwatchCtrl::COLOR_CANCEL); + } } closeFloater(); @@ -391,10 +398,7 @@ void LLFloaterColorPicker::onClickCancel ( void* data ) if ( self ) { - if(self->getRevertOnCancel()) - { - self->cancelSelection (); - } + self->cancelSelection(); self->closeFloater(); } } @@ -423,11 +427,11 @@ void LLFloaterColorPicker::onClickPipette( ) pipette_active = !pipette_active; if (pipette_active) { - LLToolMgr::getInstanceFast()->setTransientTool(LLToolPipette::getInstance()); + LLToolMgr::getInstance()->setTransientTool(LLToolPipette::getInstance()); } else { - LLToolMgr::getInstanceFast()->clearTransientTool(); + LLToolMgr::getInstance()->clearTransientTool(); } } @@ -488,7 +492,7 @@ void LLFloaterColorPicker::draw() static LLCachedControl<F32> max_opacity(gSavedSettings, "PickerContextOpacity", 0.4f); drawConeToOwner(mContextConeOpacity, max_opacity, mSwatch, mContextConeFadeTime, mContextConeInAlpha, mContextConeOutAlpha); - mPipetteBtn->setToggleState(LLToolMgr::getInstanceFast()->getCurrentTool() == LLToolPipette::getInstance()); + mPipetteBtn->setToggleState(LLToolMgr::getInstance()->getCurrentTool() == LLToolPipette::getInstance()); mApplyImmediateCheck->setEnabled(mActive && mCanApplyImmediately); mSelectBtn->setEnabled(mActive); @@ -1081,8 +1085,8 @@ void LLFloaterColorPicker::setActive(BOOL active) void LLFloaterColorPicker::stopUsingPipette() { - if (LLToolMgr::getInstanceFast()->getCurrentTool() == LLToolPipette::getInstanceFast()) + if (LLToolMgr::getInstance()->getCurrentTool() == LLToolPipette::getInstance()) { - LLToolMgr::getInstanceFast()->clearTransientTool(); + LLToolMgr::getInstance()->clearTransientTool(); } } diff --git a/indra/newview/llfloatercolorpicker.h b/indra/newview/llfloatercolorpicker.h index 816d501f900749e5e8932faff773b6d6425f8b0e..9d845a96090c199aaf80de5106bd5994ab93310a 100644 --- a/indra/newview/llfloatercolorpicker.h +++ b/indra/newview/llfloatercolorpicker.h @@ -104,9 +104,6 @@ class LLFloaterColorPicker final void setMouseDownInSwatch (BOOL mouse_down_in_swatch); BOOL getMouseDownInSwatch () { return mMouseDownInSwatch; } - void setRevertOnCancel (BOOL revertOnCancel) { mRevertOnCancel = revertOnCancel; }; - BOOL getRevertOnCancel () { return mRevertOnCancel; } - BOOL isColorChanged (); // called when text entries (RGB/HSL etc.) are changed by user @@ -149,8 +146,6 @@ class LLFloaterColorPicker final BOOL mMouseDownInHueRegion; BOOL mMouseDownInSwatch; - BOOL mRevertOnCancel; - const S32 mRGBViewerImageLeft; const S32 mRGBViewerImageTop; const S32 mRGBViewerImageWidth; diff --git a/indra/newview/llfloatercreatelandmark.cpp b/indra/newview/llfloatercreatelandmark.cpp index e2222bb82631567bb8e38e80d453f3f1689b70dc..68f5ab143b2e18adba14ba210bf6a44ba7e14a3e 100644 --- a/indra/newview/llfloatercreatelandmark.cpp +++ b/indra/newview/llfloatercreatelandmark.cpp @@ -46,19 +46,60 @@ typedef std::pair<LLUUID, std::string> folder_pair_t; -class LLLandmarksInventoryObserver : public LLInventoryAddedObserver +class LLLandmarksInventoryObserver : public LLInventoryObserver { public: LLLandmarksInventoryObserver(LLFloaterCreateLandmark* create_landmark_floater) : mFloater(create_landmark_floater) {} + void changed(U32 mask) override + { + if (mFloater->getItem()) + { + checkChanged(mask); + } + else + { + checkCreated(mask); + } + } + protected: - /*virtual*/ void done() + void checkCreated(U32 mask) { + if (gInventory.getAddedIDs().empty()) + { + return; + } + + if (!(mask & LLInventoryObserver::ADD) || + !(mask & LLInventoryObserver::CREATE) || + !(mask & LLInventoryObserver::UPDATE_CREATE)) + { + return; + } + mFloater->setItem(gInventory.getAddedIDs()); } + void checkChanged(U32 mask) + { + if (gInventory.getChangedIDs().empty()) + { + return; + } + + if ((mask & LLInventoryObserver::LABEL) || + (mask & LLInventoryObserver::INTERNAL) || + (mask & LLInventoryObserver::REMOVE) || + (mask & LLInventoryObserver::STRUCTURE) || + (mask & LLInventoryObserver::REBUILD)) + { + mFloater->updateItem(gInventory.getChangedIDs(), mask); + } + } + private: LLFloaterCreateLandmark* mFloater; }; @@ -90,6 +131,9 @@ BOOL LLFloaterCreateLandmark::postBuild() getChild<LLButton>("ok_btn")->setClickedCallback(boost::bind(&LLFloaterCreateLandmark::onSaveClicked, this)); getChild<LLButton>("cancel_btn")->setClickedCallback(boost::bind(&LLFloaterCreateLandmark::onCancelClicked, this)); + mLandmarkTitleEditor->setCommitCallback([this](LLUICtrl* ctrl, const LLSD& param) { onCommitTextChanges(); }); + mNotesEditor->setCommitCallback([this](LLUICtrl* ctrl, const LLSD& param) { onCommitTextChanges(); }); + mLandmarksID = gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK); return TRUE; @@ -219,6 +263,33 @@ void LLFloaterCreateLandmark::populateFoldersList(const LLUUID &folder_id) } } +void LLFloaterCreateLandmark::onCommitTextChanges() +{ + if (mItem.isNull()) + { + return; + } + std::string current_title_value = mLandmarkTitleEditor->getText(); + std::string item_title_value = mItem->getName(); + std::string current_notes_value = mNotesEditor->getText(); + std::string item_notes_value = mItem->getDescription(); + + LLStringUtil::trim(current_title_value); + LLStringUtil::trim(current_notes_value); + + if (!current_title_value.empty() && + (item_title_value != current_title_value || item_notes_value != current_notes_value)) + { + LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(mItem); + new_item->rename(current_title_value); + new_item->setDescription(current_notes_value); + LLPointer<LLInventoryCallback> cb; + LLInventoryModel::LLCategoryUpdate up(mItem->getParentUUID(), 0); + gInventory.accountForUpdate(up); + update_inventory_item(new_item, cb); + } +} + void LLFloaterCreateLandmark::onCreateFolderClicked() { LLNotificationsUtil::add("CreateLandmarkFolder", LLSD(), LLSD(), @@ -292,6 +363,8 @@ void LLFloaterCreateLandmark::onSaveClicked() new_item->updateParentOnServer(FALSE); } + removeObserver(); + gInventory.updateItem(new_item); gInventory.notifyObservers(); @@ -302,6 +375,7 @@ void LLFloaterCreateLandmark::onSaveClicked() void LLFloaterCreateLandmark::onCancelClicked() { + removeObserver(); if (!mItem.isNull()) { LLUUID item_id = mItem->getUUID(); @@ -331,10 +405,59 @@ void LLFloaterCreateLandmark::setItem(const uuid_set_t& items) { if(!getItem()) { - removeObserver(); mItem = item; + mAssetID = mItem->getAssetUUID(); + setVisibleAndFrontmost(true); break; } } } } + +void LLFloaterCreateLandmark::updateItem(const uuid_set_t& items, U32 mask) +{ + if (!getItem()) + { + return; + } + + LLUUID landmark_id = getItem()->getUUID(); + + for (uuid_set_t::const_iterator item_iter = items.begin(); + item_iter != items.end(); + ++item_iter) + { + const LLUUID& item_id = (*item_iter); + if (landmark_id == item_id) + { + if (getItem() != gInventory.getItem(item_id)) + { + // item is obsolete or removed + closeFloater(); + } + + LLUUID folder_id = mFolderCombo->getValue().asUUID(); + if (folder_id != mItem->getParentUUID()) + { + // user moved landmark in inventory, + // assume that we are done all other changes should already be commited + closeFloater(); + } + + if ((mask & LLInventoryObserver::INTERNAL) && mAssetID != mItem->getAssetUUID()) + { + closeFloater(); + } + + if (mask & LLInventoryObserver::LABEL) + { + mLandmarkTitleEditor->setText(mItem->getName()); + } + + if (mask & LLInventoryObserver::INTERNAL) + { + mNotesEditor->setText(mItem->getDescription()); + } + } + } +} diff --git a/indra/newview/llfloatercreatelandmark.h b/indra/newview/llfloatercreatelandmark.h index 64d8fb250e99f0533c69124c21e2a38996990418..7896ad9e65d91057abc663221fb00c1edeb80943 100644 --- a/indra/newview/llfloatercreatelandmark.h +++ b/indra/newview/llfloatercreatelandmark.h @@ -50,6 +50,7 @@ class LLFloaterCreateLandmark final : void onClose(bool app_quitting) override; void setItem(const uuid_set_t& items); + void updateItem(const uuid_set_t& items, U32 mask); LLInventoryItem* getItem() { return mItem; } @@ -57,6 +58,7 @@ class LLFloaterCreateLandmark final : void setLandmarkInfo(const LLUUID &folder_id); void removeObserver(); void populateFoldersList(const LLUUID &folder_id = LLUUID::null); + void onCommitTextChanges(); void onCreateFolderClicked(); void onSaveClicked(); void onCancelClicked(); @@ -67,6 +69,7 @@ class LLFloaterCreateLandmark final : LLLineEditor* mLandmarkTitleEditor; LLTextEditor* mNotesEditor; LLUUID mLandmarksID; + LLUUID mAssetID; LLLandmarksInventoryObserver* mInventoryObserver; LLPointer<LLInventoryItem> mItem; diff --git a/indra/newview/llfloaterdisplayname.cpp b/indra/newview/llfloaterdisplayname.cpp index 9bbb4a8a2053b972ad8cdf40d3ee884d391ff4af..bddaba18d64fce00f355826b8feb1cb65e560cca 100644 --- a/indra/newview/llfloaterdisplayname.cpp +++ b/indra/newview/llfloaterdisplayname.cpp @@ -47,7 +47,6 @@ class LLFloaterDisplayName final : public LLFloater virtual ~LLFloaterDisplayName() { } /*virtual*/ BOOL postBuild(); void onSave(); - void onReset(); void onCancel(); /*virtual*/ void onOpen(const LLSD& key); @@ -102,7 +101,6 @@ 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)); @@ -158,21 +156,6 @@ void LLFloaterDisplayName::onCancel() setVisible(false); } -void LLFloaterDisplayName::onReset() -{ - if (LLAvatarNameCache::getInstance()->hasNameLookupURL()) - { - LLViewerDisplayName::set("",boost::bind(&LLFloaterDisplayName::onCacheSetName, this, _1, _2, _3)); - } - else - { - LLNotificationsUtil::add("SetDisplayNameFailedGeneric"); - } - - setVisible(false); -} - - void LLFloaterDisplayName::onSave() { std::string display_name_utf8 = getChild<LLUICtrl>("display_name_editor")->getValue().asString(); diff --git a/indra/newview/llfloatereditextdaycycle.cpp b/indra/newview/llfloatereditextdaycycle.cpp index 24673d5a7c70796500c968c3a57aeb8c5c4a7982..297ad243595697e0b0902bc6baa59a39079b05ea 100644 --- a/indra/newview/llfloatereditextdaycycle.cpp +++ b/indra/newview/llfloatereditextdaycycle.cpp @@ -665,6 +665,7 @@ void LLFloaterEditExtDayCycle::onButtonApply(LLUICtrl *ctrl, const LLSD &data) if (ctrl_action == ACTION_SAVE) { doApplyUpdateInventory(dayclone); + clearDirtyFlag(); } else if (ctrl_action == ACTION_SAVEAS) { diff --git a/indra/newview/llfloaterfixedenvironment.cpp b/indra/newview/llfloaterfixedenvironment.cpp index 4f2c36f45b6217ae609cd8ef2b3dc5f190191add..aa9a2c164a2b897a0d7f720f0685bcd432cf3ccb 100644 --- a/indra/newview/llfloaterfixedenvironment.cpp +++ b/indra/newview/llfloaterfixedenvironment.cpp @@ -137,6 +137,7 @@ void LLFloaterFixedEnvironment::onClose(bool app_quitting) doCloseInventoryFloater(app_quitting); LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL); + LLEnvironment::instance().setCurrentEnvironmentSelection(LLEnvironment::ENV_LOCAL); LLEnvironment::instance().clearEnvironment(LLEnvironment::ENV_EDIT); mSettings.reset(); @@ -295,6 +296,7 @@ void LLFloaterFixedEnvironment::onButtonApply(LLUICtrl *ctrl, const LLSD &data) if (ctrl_action == ACTION_SAVE) { doApplyUpdateInventory(setting_clone); + clearDirtyFlag(); } else if (ctrl_action == ACTION_SAVEAS) { diff --git a/indra/newview/llfloatergesture.cpp b/indra/newview/llfloatergesture.cpp index da00e92e63f401a852eab8e18ddcf02904e96ad0..f71a4511d65b2613d94fd8eeabe660651fcb735d 100644 --- a/indra/newview/llfloatergesture.cpp +++ b/indra/newview/llfloatergesture.cpp @@ -122,7 +122,7 @@ LLFloaterGesture::LLFloaterGesture(const LLSD& key) mObserver = new LLFloaterGestureObserver(this); LLGestureMgr::instance().addObserver(mObserver); - mCommitCallbackRegistrar.add("Gesture.Action.ToogleActiveState", boost::bind(&LLFloaterGesture::onActivateBtnClick, this)); + mCommitCallbackRegistrar.add("Gesture.Action.ToggleActiveState", boost::bind(&LLFloaterGesture::onActivateBtnClick, this)); mCommitCallbackRegistrar.add("Gesture.Action.ShowPreview", boost::bind(&LLFloaterGesture::onClickEdit, this)); mCommitCallbackRegistrar.add("Gesture.Action.CopyPaste", boost::bind(&LLFloaterGesture::onCopyPasteAction, this, _2)); mCommitCallbackRegistrar.add("Gesture.Action.SaveToCOF", boost::bind(&LLFloaterGesture::addToCurrentOutFit, this)); diff --git a/indra/newview/llfloatergodtools.cpp b/indra/newview/llfloatergodtools.cpp index b3237101ceaed6639662a577c597cfea14ce9359..5e461bbbfa74c0e96926cd8d30a4a829c3bd66e8 100644 --- a/indra/newview/llfloatergodtools.cpp +++ b/indra/newview/llfloatergodtools.cpp @@ -274,7 +274,7 @@ void LLFloaterGodTools::processRegionInfo(LLMessageSystem* msg) { // Update is for a different region than the one we're in. // Just check for a waterheight change. - LLWorld::getInstanceFast()->waterHeightRegionInfo(sim_name, water_height); + LLWorld::getInstance()->waterHeightRegionInfo(sim_name, water_height); return; } @@ -815,7 +815,7 @@ void LLPanelRegionTools::onSelectRegion() { LL_INFOS() << "LLPanelRegionTools::onSelectRegion" << LL_ENDL; - LLViewerRegion *regionp = LLWorld::getInstanceFast()->getRegionFromPosGlobal(gAgent.getPositionGlobal()); + LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(gAgent.getPositionGlobal()); if (!regionp) { return; @@ -1167,12 +1167,12 @@ void LLPanelObjectTools::onClickSetBySelection(void* data) if (!panelp) return; const BOOL non_root_ok = TRUE; - LLSelectNode* node = LLSelectMgr::getInstanceFast()->getSelection()->getFirstRootNode(NULL, non_root_ok); + LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(NULL, non_root_ok); if (!node) return; std::string owner_name; LLUUID owner_id; - LLSelectMgr::getInstanceFast()->selectGetOwner(owner_id, owner_name); + LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name); panelp->mTargetAvatar = owner_id; LLStringUtil::format_map_t args; @@ -1250,7 +1250,7 @@ void LLPanelRequestTools::refresh() list->selectItemRange(2,last_item); list->operateOnSelection(LLCtrlListInterface::OP_DELETE); } - for (LLViewerRegion* regionp : LLWorld::getInstanceFast()->getRegionList()) + for (LLViewerRegion* regionp : LLWorld::getInstance()->getRegionList()) { std::string name = regionp->getName(); if (!name.empty()) @@ -1298,7 +1298,7 @@ void LLPanelRequestTools::onClickRequest() std::string req =getChild<LLUICtrl>("request")->getValue(); req = req.substr(0, req.find_first_of(" ")); std::string param = getChild<LLUICtrl>("parameter")->getValue(); - LLSelectMgr::getInstanceFast()->sendGodlikeRequest(req, param); + LLSelectMgr::getInstance()->sendGodlikeRequest(req, param); } else if(dest == AGENT_REGION) { @@ -1307,7 +1307,7 @@ void LLPanelRequestTools::onClickRequest() else { // find region by name - for (LLViewerRegion* regionp : LLWorld::getInstanceFast()->getRegionList()) + for (LLViewerRegion* regionp : LLWorld::getInstance()->getRegionList()) { if(dest == regionp->getName()) { diff --git a/indra/newview/llfloaterhoverheight.cpp b/indra/newview/llfloaterhoverheight.cpp index 42c5e40761660311cb129f1072293d1db5b90894..a00fc4aa84889fa36d99c685b634bac57be0eb36 100644 --- a/indra/newview/llfloaterhoverheight.cpp +++ b/indra/newview/llfloaterhoverheight.cpp @@ -100,11 +100,14 @@ void LLFloaterHoverHeight::onClose(bool app_quitting) // static void LLFloaterHoverHeight::onSliderMoved(LLUICtrl* ctrl, void* userData) { - LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl); - F32 value = sldrCtrl->getValueF32(); - LLVector3 offset(0.0, 0.0, llclamp(value,MIN_HOVER_Z,MAX_HOVER_Z)); - LL_INFOS("Avatar") << "setting hover from slider moved" << offset[2] << LL_ENDL; - gAgentAvatarp->setHoverOffset(offset, false); + if (isAgentAvatarValid()) + { + LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl); + F32 value = sldrCtrl->getValueF32(); + LLVector3 offset(0.0, 0.0, llclamp(value, MIN_HOVER_Z, MAX_HOVER_Z)); + LL_INFOS("Avatar") << "setting hover from slider moved" << offset[2] << LL_ENDL; + gAgentAvatarp->setHoverOffset(offset, false); + } } // Do send-to-the-server work when slider drag completes, or new diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp index 6b2926cfcc0df8660ae749a69d41ad4ba521c385..1ec28a94f48418ed76b39bca82d57305322886e8 100644 --- a/indra/newview/llfloaterimagepreview.cpp +++ b/indra/newview/llfloaterimagepreview.cpp @@ -664,10 +664,7 @@ BOOL LLImagePreviewAvatar::render() LLGLSUIDefault def; gGL.color4f(0.15f, 0.2f, 0.3f, 1.f); - if (LLGLSLShader::sNoFixedFunction) - { - gUIProgram.bind(); - } + gUIProgram.bind(); gl_rect_2d_simple( mFullWidth, mFullHeight ); @@ -684,16 +681,16 @@ BOOL LLImagePreviewAvatar::render() LLQuaternion(mCameraYaw, LLVector3::z_axis); LLQuaternion av_rot = avatarp->mPelvisp->getWorldRotation() * camera_rot; - LLViewerCamera::getInstanceFast()->setOriginAndLookAt( + LLViewerCamera::getInstance()->setOriginAndLookAt( target_pos + ((LLVector3(mCameraDistance, 0.f, 0.f) + mCameraOffset) * av_rot), // camera LLVector3::z_axis, // up target_pos + (mCameraOffset * av_rot) ); // point of interest stop_glerror(); - LLViewerCamera::getInstanceFast()->setAspect((F32)mFullWidth / mFullHeight); - LLViewerCamera::getInstanceFast()->setView(LLViewerCamera::getInstanceFast()->getDefaultFOV() / mCameraZoom); - LLViewerCamera::getInstanceFast()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, FALSE); + LLViewerCamera::getInstance()->setAspect((F32)mFullWidth / mFullHeight); + LLViewerCamera::getInstance()->setView(LLViewerCamera::getInstance()->getDefaultFOV() / mCameraZoom); + LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, FALSE); LLVertexBuffer::unbind(); avatarp->updateLOD(); @@ -866,10 +863,7 @@ BOOL LLImagePreviewSculpted::render() gGL.color4f(0.15f, 0.2f, 0.3f, 1.f); - if (LLGLSLShader::sNoFixedFunction) - { - gUIProgram.bind(); - } + gUIProgram.bind(); gl_rect_2d_simple( mFullWidth, mFullHeight ); @@ -887,26 +881,23 @@ BOOL LLImagePreviewSculpted::render() LLQuaternion(mCameraYaw, LLVector3::z_axis); LLQuaternion av_rot = camera_rot; - LLViewerCamera::getInstanceFast()->setOriginAndLookAt( + LLViewerCamera::getInstance()->setOriginAndLookAt( target_pos + ((LLVector3(mCameraDistance, 0.f, 0.f) + mCameraOffset) * av_rot), // camera LLVector3::z_axis, // up target_pos + (mCameraOffset * av_rot) ); // point of interest stop_glerror(); - LLViewerCamera::getInstanceFast()->setAspect((F32) mFullWidth / mFullHeight); - LLViewerCamera::getInstanceFast()->setView(LLViewerCamera::getInstanceFast()->getDefaultFOV() / mCameraZoom); - LLViewerCamera::getInstanceFast()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, FALSE); + LLViewerCamera::getInstance()->setAspect((F32) mFullWidth / mFullHeight); + LLViewerCamera::getInstance()->setView(LLViewerCamera::getInstance()->getDefaultFOV() / mCameraZoom); + LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, FALSE); const LLVolumeFace &vf = mVolume->getVolumeFace(0); U32 num_indices = vf.mNumIndices; gPipeline.enableLightsAvatar(); - if (LLGLSLShader::sNoFixedFunction) - { - gObjectPreviewProgram.bind(); - } + gObjectPreviewProgram.bind(); gPipeline.enableLightsPreview(); gGL.pushMatrix(); @@ -920,10 +911,7 @@ BOOL LLImagePreviewSculpted::render() gGL.popMatrix(); - if (LLGLSLShader::sNoFixedFunction) - { - gObjectPreviewProgram.unbind(); - } + gObjectPreviewProgram.unbind(); return TRUE; } diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp index 552cf540f383ad9d5119006021017a86d3fd59da..cdda3eb96d156218bcf40458c3730db91a5f8f1f 100644 --- a/indra/newview/llfloaterimcontainer.cpp +++ b/indra/newview/llfloaterimcontainer.cpp @@ -46,6 +46,7 @@ #include "llflashtimer.h" #include "llfloateravatarpicker.h" #include "llfloaterpreference.h" +#include "llfloaterreporter.h" #include "llimview.h" #include "llnotificationsutil.h" #include "lltoolbarview.h" @@ -727,7 +728,8 @@ void LLFloaterIMContainer::setMinimized(BOOL b) } void LLFloaterIMContainer::setVisible(BOOL visible) -{ LLFloaterIMNearbyChat* nearby_chat; +{ + LLFloaterIMNearbyChat* nearby_chat; if (visible) { // Make sure we have the Nearby Chat present when showing the conversation container @@ -762,22 +764,25 @@ void LLFloaterIMContainer::setVisible(BOOL visible) LLFloaterIMSessionTab::addToHost(LLUUID()); } - // We need to show/hide all the associated conversations that have been torn off - // (and therefore, are not longer managed by the multifloater), - // so that they show/hide with the conversations manager. - conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin(); - for (;widget_it != mConversationsWidgets.end(); ++widget_it) - { - LLConversationViewSession* widget = dynamic_cast<LLConversationViewSession*>(widget_it->second); - if (widget) - { - LLFloater* session_floater = widget->getSessionFloater(); - if (session_floater != nearby_chat) - { - widget->setVisibleIfDetached(visible); - } - } - } + if (!LLFloater::isQuitRequested()) + { + // We need to show/hide all the associated conversations that have been torn off + // (and therefore, are not longer managed by the multifloater), + // so that they show/hide with the conversations manager. + conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin(); + for (; widget_it != mConversationsWidgets.end(); ++widget_it) + { + LLConversationViewSession* widget = dynamic_cast<LLConversationViewSession*>(widget_it->second); + if (widget) + { + LLFloater* session_floater = widget->getSessionFloater(); + if (session_floater != nearby_chat) + { + widget->setVisibleIfDetached(visible); + } + } + } + } // Now, do the normal multifloater show/hide LLMultiFloater::setVisible(visible); @@ -1242,6 +1247,18 @@ void LLFloaterIMContainer::doToParticipants(const std::string& command, uuid_vec { LLAvatarActions::pay(userID); } + else if ("report_abuse" == command) + { + LLAvatarName av_name; + if (LLAvatarNameCache::get(userID, &av_name)) + { + LLFloaterReporter::showFromAvatar(userID, av_name.getCompleteName()); + } + else + { + LLFloaterReporter::showFromAvatar(userID, "not avaliable"); + } + } else if ("block_unblock" == command) { LLAvatarActions::toggleMute(userID, LLMute::flagVoiceChat); @@ -1551,10 +1568,13 @@ bool LLFloaterIMContainer::enableContextMenuItem(const std::string& item, uuid_v } // Handle all other options -// if (("can_invite" == item) || ("can_chat_history" == item) || ("can_share" == item) || ("can_pay" == item)) + if (("can_invite" == item) + || ("can_chat_history" == item) + || ("can_share" == item) // [RLVa:KB] - @pay - if (("can_invite" == item) || ("can_chat_history" == item) || ("can_share" == item)) +// || ("can_pay" == item) // [/RLVa:KB] + || ("report_abuse" == item)) { // Those menu items are enable only if a single avatar is selected return is_single_select; @@ -1639,11 +1659,11 @@ bool LLFloaterIMContainer::checkContextMenuItem(const std::string& item, uuid_ve { if ("is_blocked" == item) { - return LLMuteList::getInstanceFast()->isMuted(uuids.front(), LLMute::flagVoiceChat); + return LLMuteList::getInstance()->isMuted(uuids.front(), LLMute::flagVoiceChat); } else if (item == "is_muted") { - return LLMuteList::getInstanceFast()->isMuted(uuids.front(), LLMute::flagTextChat); + return LLMuteList::getInstance()->isMuted(uuids.front(), LLMute::flagTextChat); } else if ("is_allowed_text_chat" == item) { @@ -1802,7 +1822,7 @@ void LLFloaterIMContainer::setNearbyDistances() // Get the positions of the nearby avatars and their ids std::vector<LLVector3d> positions; uuid_vec_t avatar_ids; - LLWorld::getInstanceFast()->getAvatars(&avatar_ids, &positions, gAgent.getPositionGlobal(), ALControlCache::NearMeRange); + LLWorld::getInstance()->getAvatars(&avatar_ids, &positions, gAgent.getPositionGlobal(), ALControlCache::NearMeRange); // Get the position of the agent const LLVector3d& me_pos = gAgent.getPositionGlobal(); // For each nearby avatar, compute and update the distance @@ -2285,7 +2305,7 @@ void LLFloaterIMContainer::reSelectConversation() void LLFloaterIMContainer::updateSpeakBtnState() { - mSpeakBtn->setToggleState(LLVoiceClient::getInstanceFast()->getUserPTTState()); + mSpeakBtn->setToggleState(LLVoiceClient::getInstance()->getUserPTTState()); mSpeakBtn->setEnabled(LLAgent::isActionAllowed("speak")); } diff --git a/indra/newview/llfloaterimnearbychathandler.cpp b/indra/newview/llfloaterimnearbychathandler.cpp index fe18ef5a16e51e330a2942ba1a6e37e13428d284..38aaa1e83640ba93e458dd5607acd50a20afa34b 100644 --- a/indra/newview/llfloaterimnearbychathandler.cpp +++ b/indra/newview/llfloaterimnearbychathandler.cpp @@ -589,7 +589,7 @@ void LLFloaterIMNearbyChatHandler::processChat(const LLChat& chat_msg, LLSD userdata; userdata["date"] = LLDate::now(); userdata["nearby"] = true; - LLRecentPeople::instanceFast().add(chat_msg.mFromID, userdata); + LLRecentPeople::instance().add(chat_msg.mFromID, userdata); } // [/RLVa:KB] } diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index 305c4acb0a8b827d4a3d7761f697ba41d0d24df4..d514d46ae8006761f032ca676c02311d8b14730c 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -553,7 +553,7 @@ void LLFloaterIMSessionTab::removeConversationViewParticipant(const LLUUID& part void LLFloaterIMSessionTab::updateConversationViewParticipant(const LLUUID& participant_id) { LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,participant_id); - if (widget) + if (widget && widget->getViewModelItem()) { widget->refresh(); } @@ -578,8 +578,11 @@ void LLFloaterIMSessionTab::refreshConversation() { participants_uuids.push_back(widget_it->first); } - widget_it->second->refresh(); - widget_it->second->setVisible(TRUE); + if (widget_it->second->getViewModelItem()) + { + widget_it->second->refresh(); + widget_it->second->setVisible(TRUE); + } ++widget_it; } if (is_ad_hoc || mIsP2PChat) @@ -1149,7 +1152,10 @@ void LLFloaterIMSessionTab::getSelectedUUIDs(uuid_vec_t& selected_uuids) for (; it != it_end; ++it) { LLConversationItem* conversation_item = static_cast<LLConversationItem *>((*it)->getViewModelItem()); - selected_uuids.push_back(conversation_item->getUUID()); + if (conversation_item) + { + selected_uuids.push_back(conversation_item->getUUID()); + } } } diff --git a/indra/newview/llfloaterinspect.cpp b/indra/newview/llfloaterinspect.cpp index 39c27a241da02fc68acd3b2eb541e23611d29ffe..296351014ee4c844f6966ac7a6061d074ae19b63 100644 --- a/indra/newview/llfloaterinspect.cpp +++ b/indra/newview/llfloaterinspect.cpp @@ -85,12 +85,12 @@ LLFloaterInspect::~LLFloaterInspect(void) } if(!LLFloaterReg::instanceVisible("build")) { - if(LLToolMgr::getInstanceFast()->getBaseTool() == LLToolCompInspect::getInstanceFast()) + if(LLToolMgr::getInstance()->getBaseTool() == LLToolCompInspect::getInstance()) { - LLToolMgr::getInstanceFast()->clearTransientTool(); + LLToolMgr::getInstance()->clearTransientTool(); } // Switch back to basic toolset - LLToolMgr::getInstanceFast()->setCurrentToolset(gBasicToolset); + LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset); } else { @@ -100,10 +100,10 @@ LLFloaterInspect::~LLFloaterInspect(void) void LLFloaterInspect::onOpen(const LLSD& key) { - BOOL forcesel = LLSelectMgr::getInstanceFast()->setForceSelection(TRUE); - LLToolMgr::getInstanceFast()->setTransientTool(LLToolCompInspect::getInstance()); - LLSelectMgr::getInstanceFast()->setForceSelection(forcesel); // restore previouis value - mObjectSelection = LLSelectMgr::getInstanceFast()->getSelection(); + BOOL forcesel = LLSelectMgr::getInstance()->setForceSelection(TRUE); + LLToolMgr::getInstance()->setTransientTool(LLToolCompInspect::getInstance()); + LLSelectMgr::getInstance()->setForceSelection(forcesel); // restore previouis value + mObjectSelection = LLSelectMgr::getInstance()->getSelection(); refresh(); } @@ -418,7 +418,7 @@ void LLFloaterInspect::refresh() void LLFloaterInspect::onFocusReceived() { - LLToolMgr::getInstanceFast()->setTransientTool(LLToolCompInspect::getInstance()); + LLToolMgr::getInstance()->setTransientTool(LLToolCompInspect::getInstance()); LLFloater::onFocusReceived(); } diff --git a/indra/newview/llfloaterjoystick.cpp b/indra/newview/llfloaterjoystick.cpp index 4dedc6259724b47b29ccbf45f9acf938351bcd62..829d6d20ec93e7193052fe44cf11cc576d094134 100644 --- a/indra/newview/llfloaterjoystick.cpp +++ b/indra/newview/llfloaterjoystick.cpp @@ -292,7 +292,7 @@ void LLFloaterJoystick::refreshListOfDevices() std::string desc = LLViewerJoystick::getInstance()->getDescription(); if (!desc.empty()) { - LLSD value = LLSD::Integer(1); + LLSD value = LLSD::Integer(1); // value for selection addDevice(desc, value); mHasDeviceList = true; } @@ -392,6 +392,9 @@ void LLFloaterJoystick::onCommitJoystickEnabled(LLUICtrl*, void *joy_panel) LLSD value = self->mJoysticksCombo->getValue(); bool joystick_enabled = true; + // value is 0 for no device, + // 1 for a device on Mac (single device, no list support yet) + // binary packed guid for a device on windows (can have multiple devices) if (value.isInteger()) { // ndof already has a device selected, we are just setting it enabled or disabled @@ -400,7 +403,7 @@ void LLFloaterJoystick::onCommitJoystickEnabled(LLUICtrl*, void *joy_panel) else { LLViewerJoystick::getInstance()->initDevice(value); - // else joystick is enabled, because combobox holds id of device + // else joystick is enabled, because combobox holds id of the device joystick_enabled = true; } gSavedSettings.setBOOL("JoystickEnabled", joystick_enabled); diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index 796692439d4466480762e0a5420212476d7cdb9f..e9f4450708c2bd93d88f1762d4952331aa9c655d 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -192,7 +192,7 @@ void send_parcel_select_objects(S32 parcel_local_id, U32 return_type, // Since new highlight will be coming in, drop any highlights // that exist right now. - LLSelectMgr::getInstanceFast()->unhighlightAll(); + LLSelectMgr::getInstance()->unhighlightAll(); msg->newMessageFast(_PREHASH_ParcelSelectObjects); msg->nextBlockFast(_PREHASH_AgentData); @@ -293,7 +293,7 @@ void LLFloaterLand::onVisibilityChanged(const LLSD& visible) if (!visible.asBoolean()) { // Might have been showing owned objects - LLSelectMgr::getInstanceFast()->unhighlightAll(); + LLSelectMgr::getInstance()->unhighlightAll(); // Save which panel we had open sLastTab = mTabLand->getCurrentPanelIndex(); @@ -452,7 +452,8 @@ BOOL LLPanelLandGeneral::postBuild() mEditDesc = getChild<LLTextEditor>("Description"); mEditDesc->setCommitOnFocusLost(TRUE); - mEditDesc->setCommitCallback(onCommitAny, this); + mEditDesc->setCommitCallback(onCommitAny, this); + mEditDesc->setContentTrusted(false); // No prevalidate function - historically the prevalidate function was broken, // allowing residents to put in characters like U+2661 WHITE HEART SUIT, so // preserve that ability. @@ -749,6 +750,7 @@ void LLPanelLandGeneral::refresh() BOOL can_edit_identity = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_CHANGE_IDENTITY); mEditName->setEnabled(can_edit_identity); mEditDesc->setEnabled(can_edit_identity); + mEditDesc->setParseURLs(!can_edit_identity); BOOL can_edit_agent_only = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_NO_POWERS); mBtnSetGroup->setEnabled(can_edit_agent_only && !parcel->getIsGroupOwned()); @@ -1484,7 +1486,7 @@ bool LLPanelLandObjects::callbackReturnOwnerObjects(const LLSD& notification, co } } - LLSelectMgr::getInstanceFast()->unhighlightAll(); + LLSelectMgr::getInstance()->unhighlightAll(); LLViewerParcelMgr::getInstance()->sendParcelPropertiesUpdate( parcel ); refresh(); return false; @@ -1506,7 +1508,7 @@ bool LLPanelLandObjects::callbackReturnGroupObjects(const LLSD& notification, co send_return_objects_message(parcel->getLocalID(), RT_GROUP); } } - LLSelectMgr::getInstanceFast()->unhighlightAll(); + LLSelectMgr::getInstance()->unhighlightAll(); LLViewerParcelMgr::getInstance()->sendParcelPropertiesUpdate( parcel ); refresh(); return false; @@ -1524,7 +1526,7 @@ bool LLPanelLandObjects::callbackReturnOtherObjects(const LLSD& notification, co send_return_objects_message(parcel->getLocalID(), RT_OTHER); } } - LLSelectMgr::getInstanceFast()->unhighlightAll(); + LLSelectMgr::getInstance()->unhighlightAll(); LLViewerParcelMgr::getInstance()->sendParcelPropertiesUpdate( parcel ); refresh(); return false; @@ -1558,7 +1560,7 @@ bool LLPanelLandObjects::callbackReturnOwnerList(const LLSD& notification, const } } } - LLSelectMgr::getInstanceFast()->unhighlightAll(); + LLSelectMgr::getInstance()->unhighlightAll(); LLViewerParcelMgr::getInstance()->sendParcelPropertiesUpdate( parcel ); refresh(); return false; @@ -3064,7 +3066,8 @@ BOOL LLPanelLandCovenant::postBuild() { mLastRegionID = LLUUID::null; mNextUpdateTime = 0; - + mTextEstateOwner = getChild<LLTextBox>("estate_owner_text"); + mTextEstateOwner->setIsFriendCallback(LLAvatarActions::isFriend); return TRUE; } @@ -3172,8 +3175,7 @@ void LLPanelLandCovenant::updateEstateOwnerName(const std::string& name) LLPanelLandCovenant* self = LLFloaterLand::getCurrentPanelLandCovenant(); if (self) { - LLTextBox* editor = self->getChild<LLTextBox>("estate_owner_text"); - if (editor) editor->setText(name); + self->mTextEstateOwner->setText(name); } } diff --git a/indra/newview/llfloaterland.h b/indra/newview/llfloaterland.h index 65a22aa3fdcd5b4d9a845d281f67af9505296868..54eced4bc614835ce29eabaa04646d9598c41657 100644 --- a/indra/newview/llfloaterland.h +++ b/indra/newview/llfloaterland.h @@ -414,6 +414,7 @@ class LLPanelLandCovenant private: LLUUID mLastRegionID; F64 mNextUpdateTime; //seconds since client start + LLTextBox* mTextEstateOwner; }; #endif diff --git a/indra/newview/llfloaterlinkreplace.cpp b/indra/newview/llfloaterlinkreplace.cpp index 65d032c910664bb8b4e58a5cd4e245be594df6a5..8ee7a72055e3fabee739830e47287d43d130eee4 100644 --- a/indra/newview/llfloaterlinkreplace.cpp +++ b/indra/newview/llfloaterlinkreplace.cpp @@ -162,7 +162,7 @@ void LLFloaterLinkReplace::onStartClicked() else { LLSD args; - args["TYPE"] = LLWearableType::getInstanceFast()->getTypeName(source_item->getWearableType()); + args["TYPE"] = LLWearableType::getInstance()->getTypeName(source_item->getWearableType()); params.substitutions(args); LLNotifications::instance().add(params); } diff --git a/indra/newview/llfloatermap.cpp b/indra/newview/llfloatermap.cpp index 5304c6b4260694b3cfa74d185cdb440cee665537..37d0d430975073a320af5e974c091500f1ab78ae 100644 --- a/indra/newview/llfloatermap.cpp +++ b/indra/newview/llfloatermap.cpp @@ -51,7 +51,7 @@ // The minor cardinal direction labels are hidden if their height is more // than this proportion of the map. -const F32 MAP_MINOR_DIR_THRESHOLD = 0.07f; +const F32 MAP_MINOR_DIR_THRESHOLD = 0.035f; const S32 MAP_PADDING_LEFT = 0; const S32 MAP_PADDING_TOP = 2; const S32 MAP_PADDING_RIGHT = 2; @@ -81,38 +81,47 @@ LLFloaterMap::~LLFloaterMap() BOOL LLFloaterMap::postBuild() { - mMap = getChild<LLNetMap>("Net Map"); - if (gSavedSettings.getBOOL("DoubleClickTeleport")) - { - mMap->setToolTipMsg(getString("AltToolTipMsg")); - } - else if (gSavedSettings.getBOOL("DoubleClickShowWorldMap")) - { - mMap->setToolTipMsg(getString("ToolTipMsg")); - } - sendChildToBack(mMap); - - mTextBoxNorth = getChild<LLTextBox> ("floater_map_north"); - mTextBoxEast = getChild<LLTextBox> ("floater_map_east"); - mTextBoxWest = getChild<LLTextBox> ("floater_map_west"); - mTextBoxSouth = getChild<LLTextBox> ("floater_map_south"); - mTextBoxSouthEast = getChild<LLTextBox> ("floater_map_southeast"); - mTextBoxNorthEast = getChild<LLTextBox> ("floater_map_northeast"); - mTextBoxSouthWest = getChild<LLTextBox> ("floater_map_southwest"); - mTextBoxNorthWest = getChild<LLTextBox> ("floater_map_northwest"); + mMap = getChild<LLNetMap>("Net Map"); + mMap->setToolTipMsg(getString("ToolTipMsg")); + mMap->setParcelNameMsg(getString("ParcelNameMsg")); + mMap->setParcelSalePriceMsg(getString("ParcelSalePriceMsg")); + mMap->setParcelSaleAreaMsg(getString("ParcelSaleAreaMsg")); + mMap->setParcelOwnerMsg(getString("ParcelOwnerMsg")); + mMap->setRegionNameMsg(getString("RegionNameMsg")); + mMap->setToolTipHintMsg(getString("ToolTipHintMsg")); + mMap->setAltToolTipHintMsg(getString("AltToolTipHintMsg")); + sendChildToBack(mMap); + + mTextBoxNorth = getChild<LLTextBox>("floater_map_north"); + mTextBoxEast = getChild<LLTextBox>("floater_map_east"); + mTextBoxWest = getChild<LLTextBox>("floater_map_west"); + mTextBoxSouth = getChild<LLTextBox>("floater_map_south"); + mTextBoxSouthEast = getChild<LLTextBox>("floater_map_southeast"); + mTextBoxNorthEast = getChild<LLTextBox>("floater_map_northeast"); + mTextBoxSouthWest = getChild<LLTextBox>("floater_map_southwest"); + mTextBoxNorthWest = getChild<LLTextBox>("floater_map_northwest"); stretchMiniMap(getRect().getWidth() - MAP_PADDING_LEFT - MAP_PADDING_RIGHT ,getRect().getHeight() - MAP_PADDING_TOP - MAP_PADDING_BOTTOM); - updateMinorDirections(); + mTextBoxNorth->reshapeToFitText(); + mTextBoxEast->reshapeToFitText(); + mTextBoxWest->reshapeToFitText(); + mTextBoxSouth->reshapeToFitText(); + mTextBoxSouthEast->reshapeToFitText(); + mTextBoxNorthEast->reshapeToFitText(); + mTextBoxSouthWest->reshapeToFitText(); + mTextBoxNorthWest->reshapeToFitText(); - // Get the drag handle all the way in back - sendChildToBack(getDragHandle()); + updateMinorDirections(); - // keep onscreen - gFloaterView->adjustToFitScreen(this, FALSE); + // Get the drag handle all the way in back + sendChildToBack(getDragHandle()); - return TRUE; + // keep onscreen + gFloaterView->adjustToFitScreen(this, false); + + return true; } BOOL LLFloaterMap::handleDoubleClick(S32 x, S32 y, MASK mask) @@ -145,23 +154,44 @@ BOOL LLFloaterMap::handleDoubleClick(S32 x, S32 y, MASK mask) return TRUE; } -void LLFloaterMap::setDirectionPos( LLTextBox* text_box, F32 rotation ) +void LLFloaterMap::setDirectionPos(LLTextBox *text_box, F32 rotation) { - // Rotation is in radians. - // Rotation of 0 means x = 1, y = 0 on the unit circle. - - F32 map_half_height = (F32)(getRect().getHeight() / 2) - getHeaderHeight()/2; - F32 map_half_width = (F32)(getRect().getWidth() / 2) ; - F32 text_half_height = (F32)(text_box->getRect().getHeight() / 2); - F32 text_half_width = (F32)(text_box->getRect().getWidth() / 2); - F32 radius = llmin( map_half_height - text_half_height, map_half_width - text_half_width ); - - // Inset by a little to account for position display. - radius -= 8.f; - - text_box->setOrigin( - ll_round(map_half_width - text_half_width + radius * cos( rotation )), - ll_round(map_half_height - text_half_height + radius * sin( rotation )) ); + // Rotation is in radians. + // Rotation of 0 means x = 1, y = 0 on the unit circle. + + F32 map_half_height = (F32) (getRect().getHeight() / 2) - (getHeaderHeight() / 2); + F32 map_half_width = (F32) (getRect().getWidth() / 2); + F32 text_half_height = (F32) (text_box->getRect().getHeight() / 2); + F32 text_half_width = (F32) (text_box->getRect().getWidth() / 2); + F32 extra_padding = (F32) (mTextBoxNorth->getRect().getWidth() / 2); + F32 pos_half_height = map_half_height - text_half_height - extra_padding; + F32 pos_half_width = map_half_width - text_half_width - extra_padding; + + F32 corner_angle = atan2(pos_half_height, pos_half_width); + F32 rotation_mirrored_into_top = abs(fmodf(rotation, F_PI)); + if (rotation < 0) + { + rotation_mirrored_into_top = F_PI - rotation_mirrored_into_top; + } + F32 rotation_mirrored_into_top_right = (F_PI_BY_TWO - abs(rotation_mirrored_into_top - F_PI_BY_TWO)); + bool at_left_right_edge = rotation_mirrored_into_top_right < corner_angle; + + F32 part_x = cos(rotation); + F32 part_y = sin(rotation); + F32 y; + F32 x; + if (at_left_right_edge) + { + x = std::copysign(pos_half_width, part_x); + y = x * part_y / part_x; + } + else + { + y = std::copysign(pos_half_height, part_y); + x = y * part_x / part_y; + } + + text_box->setOrigin(ll_round(map_half_width + x - text_half_width), ll_round(map_half_height + y - text_half_height)); } void LLFloaterMap::updateMinorDirections() @@ -190,7 +220,7 @@ void LLFloaterMap::draw() if( rotate_map ) { // rotate subsequent draws to agent rotation - rotation = atan2( LLViewerCamera::getInstanceFast()->getAtAxis().mV[VX], LLViewerCamera::getInstanceFast()->getAtAxis().mV[VY] ); + rotation = atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ); } setDirectionPos( mTextBoxEast, rotation ); @@ -241,32 +271,6 @@ void LLFloaterMap::reshape(S32 width, S32 height, BOOL called_from_parent) updateMinorDirections(); } -void LLFloaterMap::handleZoom(const LLSD& userdata) -{ - std::string level = userdata.asString(); - - F32 scale = 0.0f; - if (level == std::string("default")) - { - LLControlVariable *pvar = gSavedSettings.getControl("MiniMapScale"); - if(pvar) - { - pvar->resetToDefault(); - scale = gSavedSettings.getF32("MiniMapScale"); - } - } - else if (level == std::string("close")) - scale = LLNetMap::MAP_SCALE_MAX; - else if (level == std::string("medium")) - scale = LLNetMap::MAP_SCALE_MID; - else if (level == std::string("far")) - scale = LLNetMap::MAP_SCALE_MIN; - if (scale != 0.0f) - { - mMap->setScale(scale); - } -} - void LLFloaterMap::setMinimized(BOOL b) { LLFloater::setMinimized(b); diff --git a/indra/newview/llfloatermap.h b/indra/newview/llfloatermap.h index c9776226d4368a1de173824915b5d4cf7dab6cc4..3e3bebf3b4a04e35f24d4c19a1460b8428c1cb43 100644 --- a/indra/newview/llfloatermap.h +++ b/indra/newview/llfloatermap.h @@ -49,7 +49,6 @@ class LLFloaterMap final : public LLFloater /*virtual*/ void setMinimized(BOOL b) override; private: - void handleZoom(const LLSD& userdata); void setDirectionPos( LLTextBox* text_box, F32 rotation ); void updateMinorDirections(); diff --git a/indra/newview/llfloatermarketplacelistings.cpp b/indra/newview/llfloatermarketplacelistings.cpp index 171c39bf317143f27399780099cc5a04777b1d60..e755e9924c067a01a6c0f0cd717e7c49352e81da 100644 --- a/indra/newview/llfloatermarketplacelistings.cpp +++ b/indra/newview/llfloatermarketplacelistings.cpp @@ -180,7 +180,7 @@ void LLPanelMarketplaceListings::draw() // Get the audit button enabled only after the whole inventory is fetched if (!mAuditBtn->getEnabled()) { - mAuditBtn->setEnabled(LLInventoryModelBackgroundFetch::instanceFast().isEverythingFetched()); + mAuditBtn->setEnabled(LLInventoryModelBackgroundFetch::instance().isEverythingFetched()); } LLPanel::draw(); @@ -431,7 +431,7 @@ void LLFloaterMarketplaceListings::fetchContents() { LLMarketplaceData::instance().setDataFetchedSignal(boost::bind(&LLFloaterMarketplaceListings::updateView, this)); LLMarketplaceData::instance().setSLMDataFetched(MarketplaceFetchCodes::MARKET_FETCH_LOADING); - LLInventoryModelBackgroundFetch::instanceFast().start(mRootFolderId); + LLInventoryModelBackgroundFetch::instance().start(mRootFolderId); LLMarketplaceData::instance().getSLMListings(); } } @@ -579,7 +579,25 @@ void LLFloaterMarketplaceListings::updateView() // Update the top message or flip to the tabs and folders view // *TODO : check those messages and create better appropriate ones in strings.xml - if (mRootFolderId.notNull()) + if (mkt_status == MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE) + { + std::string reason = LLMarketplaceData::instance().getSLMConnectionfailureReason(); + if (reason.empty()) + { + text = LLTrans::getString("InventoryMarketplaceConnectionError"); + } + else + { + LLSD args; + args["[REASON]"] = reason; + text = LLTrans::getString("InventoryMarketplaceConnectionErrorReason", args); + } + + title = LLTrans::getString("InventoryOutboxErrorTitle"); + tooltip = LLTrans::getString("InventoryOutboxErrorTooltip"); + LL_WARNS() << "Marketplace status code: " << mkt_status << LL_ENDL; + } + else if (mRootFolderId.notNull()) { // "Marketplace listings is empty!" message strings text = LLTrans::getString("InventoryMarketplaceListingsNoItems", subs); diff --git a/indra/newview/llfloatermediasettings.cpp b/indra/newview/llfloatermediasettings.cpp index 9cd114e30e4f3c39f79574110e1ef238489a9e58..b34961e8a2a67d30fe3f7aac2b4abc9609232137 100644 --- a/indra/newview/llfloatermediasettings.cpp +++ b/indra/newview/llfloatermediasettings.cpp @@ -148,7 +148,7 @@ void LLFloaterMediaSettings::apply() sInstance->mPanelMediaSettingsPermissions->preApply(); sInstance->mPanelMediaSettingsPermissions->getValues( settings, false ); - LLSelectMgr::getInstanceFast()->selectionSetMedia( LLTextureEntry::MF_HAS_MEDIA, settings ); + LLSelectMgr::getInstance()->selectionSetMedia( LLTextureEntry::MF_HAS_MEDIA, settings ); sInstance->mPanelMediaSettingsGeneral->postApply(); sInstance->mPanelMediaSettingsSecurity->postApply(); @@ -156,6 +156,18 @@ void LLFloaterMediaSettings::apply() } } +//////////////////////////////////////////////////////////////////////////////// +void LLFloaterMediaSettings::onOpen(const LLSD& key) +{ + if (mPanelMediaSettingsGeneral) + { + // media is expensive, so only load it when nessesary. + // If we need to preload it, set volume to 0 and any pause + // if applicable, then unpause here + mPanelMediaSettingsGeneral->updateMediaPreview(); + } +} + //////////////////////////////////////////////////////////////////////////////// void LLFloaterMediaSettings::onClose(bool app_quitting) { diff --git a/indra/newview/llfloatermediasettings.h b/indra/newview/llfloatermediasettings.h index 0796a401f1f74bbb6fd51a282273eb7e9c9768b7..ef2f021de31466878ecb81670041c3c5dc451363 100644 --- a/indra/newview/llfloatermediasettings.h +++ b/indra/newview/llfloatermediasettings.h @@ -42,6 +42,7 @@ class LLFloaterMediaSettings final : ~LLFloaterMediaSettings(); /*virtual*/ BOOL postBuild(); + /*virtual*/ void onOpen(const LLSD& key); /*virtual*/ void onClose(bool app_quitting); static LLFloaterMediaSettings* getInstance(); diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 70db5575f53e36002349fae2aa30df5002ad0857..eba8c735ce222cf2aa85573f2567f67ac22423f8 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -466,22 +466,25 @@ void LLFloaterModelPreview::loadHighLodModel() loadModel(3); } -void LLFloaterModelPreview::loadModel(S32 lod) +void LLFloaterModelPreview::prepareToLoadModel(S32 lod) { mModelPreview->mLoading = true; if (lod == LLModel::LOD_PHYSICS) { // loading physics from file mModelPreview->mPhysicsSearchLOD = lod; + mModelPreview->mWarnOfUnmatchedPhyicsMeshes = false; } - +} +void LLFloaterModelPreview::loadModel(S32 lod) +{ + prepareToLoadModel(lod); (new LLMeshFilePicker(mModelPreview, lod))->getFile(); } void LLFloaterModelPreview::loadModel(S32 lod, const std::string& file_name, bool force_disable_slm) { - mModelPreview->mLoading = true; - + prepareToLoadModel(lod); mModelPreview->loadModel(file_name, lod, force_disable_slm); } @@ -506,6 +509,15 @@ void LLFloaterModelPreview::onClickCalculateBtn() toggleCalculateButton(false); mUploadBtn->setEnabled(false); + + //disable "simplification" UI + LLPanel* simplification_panel = getChild<LLPanel>("physics simplification"); + LLView* child = simplification_panel->getFirstChild(); + while (child) + { + child->setEnabled(false); + child = simplification_panel->findNextSibling(child); + } } // Modified cell_params, make sure to clear values if you have to reuse cell_params outside of this function @@ -740,7 +752,7 @@ void LLFloaterModelPreview::onLODParamCommit(S32 lod, bool enforce_tri_limit) { case LLModelPreview::MESH_OPTIMIZER_AUTO: case LLModelPreview::MESH_OPTIMIZER_SLOPPY: - case LLModelPreview::MESH_OPTIMIZER_COMBINE: + case LLModelPreview::MESH_OPTIMIZER_PRECISE: mModelPreview->onLODMeshOptimizerParamCommit(lod, enforce_tri_limit, mode); break; default: @@ -1066,11 +1078,18 @@ void LLFloaterModelPreview::onPhysicsUseLOD(LLUICtrl* ctrl, void* userdata) } S32 file_mode = iface->getItemCount() - 1; - if (which_mode < file_mode) + S32 cube_mode = file_mode - 1; + if (which_mode < cube_mode) { S32 which_lod = num_lods - which_mode; sInstance->mModelPreview->setPhysicsFromLOD(which_lod); } + else if (which_mode == cube_mode) + { + std::string path = gDirUtilp->getAppRODataDir(); + gDirUtilp->append(path, "cube.dae"); + sInstance->loadModel(LLModel::LOD_PHYSICS, path); + } LLModelPreview *model_preview = sInstance->mModelPreview; if (model_preview) @@ -1382,31 +1401,31 @@ void LLFloaterModelPreview::clearAvatarTab() } void LLFloaterModelPreview::updateAvatarTab(bool highlight_overrides) - { +{ S32 display_lod = mModelPreview->mPreviewLOD; if (mModelPreview->mModel[display_lod].empty()) - { + { mSelectedJointName.clear(); return; - } + } // Joints will be listed as long as they are listed in mAlternateBindMatrix // even if they are for some reason identical to defaults. // Todo: Are overrides always identical for all lods? They normally are, but there might be situations where they aren't. if (mJointOverrides[display_lod].empty()) - { + { // populate map for (LLModelLoader::scene::iterator iter = mModelPreview->mScene[display_lod].begin(); iter != mModelPreview->mScene[display_lod].end(); ++iter) - { + { for (LLModelLoader::model_instance_list::iterator model_iter = iter->second.begin(); model_iter != iter->second.end(); ++model_iter) - { + { LLModelInstance& instance = *model_iter; LLModel* model = instance.mModel; const LLMeshSkinInfo *skin = &model->mSkinInfo; U32 joint_count = LLSkinningUtil::getMeshJointCount(skin); U32 bind_count = highlight_overrides ? skin->mAlternateBindMatrix.size() : 0; // simply do not include overrides if data is not needed if (bind_count > 0 && bind_count != joint_count) - { + { std::ostringstream out; out << "Invalid joint overrides for model " << model->getName(); out << ". Amount of joints " << joint_count; @@ -1415,68 +1434,68 @@ void LLFloaterModelPreview::updateAvatarTab(bool highlight_overrides) addStringToLog(out.str(), true); // Disable overrides for this model bind_count = 0; - } + } if (bind_count > 0) - { + { for (U32 j = 0; j < joint_count; ++j) - { - const LLVector3& joint_pos = skin->mAlternateBindMatrix[j].getTranslation(); + { + const LLVector3& joint_pos = LLVector3(skin->mAlternateBindMatrix[j].getTranslation()); LLJointOverrideData &data = mJointOverrides[display_lod][skin->mJointNames[j]]; LLJoint* pJoint = LLModelPreview::lookupJointByName(skin->mJointNames[j], mModelPreview); if (pJoint) - { + { // see how voavatar uses aboveJointPosThreshold if (pJoint->aboveJointPosThreshold(joint_pos)) - { + { // valid override if (data.mPosOverrides.size() > 0 && (data.mPosOverrides.begin()->second - joint_pos).lengthSquared() > (LL_JOINT_TRESHOLD_POS_OFFSET * LL_JOINT_TRESHOLD_POS_OFFSET)) - { + { // File contains multiple meshes with conflicting joint offsets // preview may be incorrect, upload result might wary (depends onto // mesh_id that hasn't been generated yet). data.mHasConflicts = true; - } + } data.mPosOverrides[model->getName()] = joint_pos; - } - else - { + } + else + { // default value, it won't be accounted for by avatar data.mModelsNoOverrides.insert(model->getName()); - } - } - } - } - else - { + } + } + } + } + else + { for (U32 j = 0; j < joint_count; ++j) - { + { LLJointOverrideData &data = mJointOverrides[display_lod][skin->mJointNames[j]]; data.mModelsNoOverrides.insert(model->getName()); } } - } - } - } + } + } + } LLPanel *panel = mTabContainer->getPanelByName("rigging_panel"); LLScrollListCtrl *joints_list = panel->getChild<LLScrollListCtrl>("joints_list"); if (joints_list->isEmpty()) - { + { // Populate table - std::map<std::string, std::string> joint_alias_map; + std::map<std::string, std::string> joint_alias_map; mModelPreview->getJointAliases(joint_alias_map); - + S32 conflicts = 0; joint_override_data_map_t::iterator joint_iter = mJointOverrides[display_lod].begin(); joint_override_data_map_t::iterator joint_end = mJointOverrides[display_lod].end(); while (joint_iter != joint_end) - { + { const std::string& listName = joint_iter->first; - + LLScrollListItem::Params item_params; item_params.value(listName); @@ -1484,38 +1503,38 @@ void LLFloaterModelPreview::updateAvatarTab(bool highlight_overrides) cell_params.font = LLFontGL::getFontSansSerif(); cell_params.value = listName; if (joint_alias_map.find(listName) == joint_alias_map.end()) - { + { // Missing names cell_params.color = LLColor4::red; - } + } if (joint_iter->second.mHasConflicts) - { + { // Conflicts cell_params.color = LLColor4::orange; conflicts++; - } + } if (highlight_overrides && joint_iter->second.mPosOverrides.size() > 0) - { + { cell_params.font.style = "BOLD"; - } + } item_params.columns.add(cell_params); joints_list->addRow(item_params, ADD_BOTTOM); joint_iter++; - } + } joints_list->selectFirstItem(); LLScrollListItem *selected = joints_list->getFirstSelected(); if (selected) -{ + { mSelectedJointName = selected->getValue().asString(); - } + } LLTextBox *joint_conf_descr = panel->getChild<LLTextBox>("conflicts_description"); joint_conf_descr->setTextArg("[CONFLICTS]", llformat("%d", conflicts)); joint_conf_descr->setTextArg("[JOINTS_COUNT]", llformat("%d", mJointOverrides[display_lod].size())); - } - } + } +} //----------------------------------------------------------------------------- // addStringToLogTab() @@ -1665,15 +1684,15 @@ LLFloaterModelPreview::DecompRequest::DecompRequest(const std::string& stage, LL void LLFloaterModelPreview::setCtrlLoadFromFile(S32 lod) { if (lod == LLModel::LOD_PHYSICS) - { + { LLComboBox* lod_combo = findChild<LLComboBox>("physics_lod_combo"); if (lod_combo) { - lod_combo->setCurrentByIndex(5); + lod_combo->setCurrentByIndex(lod_combo->getItemCount() - 1); } } else -{ + { LLComboBox* lod_combo = findChild<LLComboBox>("lod_source_" + lod_name[lod]); if (lod_combo) { @@ -1748,7 +1767,7 @@ void LLFloaterModelPreview::onLoDSourceCommit(S32 lod) S32 index = lod_source_combo->getCurrentIndex(); if (index == LLModelPreview::MESH_OPTIMIZER_AUTO || index == LLModelPreview::MESH_OPTIMIZER_SLOPPY - || index == LLModelPreview::MESH_OPTIMIZER_COMBINE) + || index == LLModelPreview::MESH_OPTIMIZER_PRECISE) { //rebuild LoD to update triangle counts onLODParamCommit(lod, true); } diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h index 8b3304f94660b8a233ea2831d7d613abfdec6aed..cd09adbf438f0adc6806cb6933d255a8f18c66dc 100644 --- a/indra/newview/llfloatermodelpreview.h +++ b/indra/newview/llfloatermodelpreview.h @@ -221,6 +221,7 @@ class LLFloaterModelPreview final : public LLFloaterModelUploadBase void resetUploadOptions(); void clearLogTab(); + void prepareToLoadModel(S32 lod); void createSmoothComboBox(LLComboBox* combo_box, float min, float max); diff --git a/indra/newview/llfloaterobjectweights.cpp b/indra/newview/llfloaterobjectweights.cpp index e10c47a78776d19a4698ec64c8b91c68a25a5c9a..bdca3e49f075b30a40f33d0913a8cfe373c0a092 100644 --- a/indra/newview/llfloaterobjectweights.cpp +++ b/indra/newview/llfloaterobjectweights.cpp @@ -116,7 +116,7 @@ void LLFloaterObjectWeights::onWeightsUpdate(const SelectionCost& selection_cost mSelectedPhysicsWeight->setText(llformat("%.1f", selection_cost.mPhysicsCost)); mSelectedServerWeight->setText(llformat("%.1f", selection_cost.mSimulationCost)); - S32 render_cost = LLSelectMgr::getInstanceFast()->getSelection()->getSelectedObjectRenderCost(); + S32 render_cost = LLSelectMgr::getInstance()->getSelection()->getSelectedObjectRenderCost(); mSelectedDisplayWeight->setText(llformat("%d", render_cost)); toggleWeightsLoadingIndicators(false); @@ -137,7 +137,7 @@ void LLFloaterObjectWeights::setErrorStatus(S32 status, const std::string& reaso void LLFloaterObjectWeights::updateLandImpacts(const LLParcel* parcel) { - if (!parcel || LLSelectMgr::getInstanceFast()->getSelection()->isEmpty()) + if (!parcel || LLSelectMgr::getInstance()->getSelection()->isEmpty()) { updateIfNothingSelected(); } @@ -164,7 +164,7 @@ void LLFloaterObjectWeights::updateLandImpacts(const LLParcel* parcel) void LLFloaterObjectWeights::refresh() { - LLSelectMgr* sel_mgr = LLSelectMgr::getInstanceFast(); + LLSelectMgr* sel_mgr = LLSelectMgr::getInstance(); if (sel_mgr->getSelection()->isEmpty()) { diff --git a/indra/newview/llfloateropenobject.cpp b/indra/newview/llfloateropenobject.cpp index 30a49e4e410b16414a79283247383aaadd855077..c2d0261edb140b0dcf7b6252371dde37183bafa3 100644 --- a/indra/newview/llfloateropenobject.cpp +++ b/indra/newview/llfloateropenobject.cpp @@ -80,7 +80,7 @@ BOOL LLFloaterOpenObject::postBuild() void LLFloaterOpenObject::onOpen(const LLSD& key) { - LLObjectSelectionHandle object_selection = LLSelectMgr::getInstanceFast()->getSelection(); + LLObjectSelectionHandle object_selection = LLSelectMgr::getInstance()->getSelection(); if (object_selection->getRootObjectCount() != 1) { LLNotificationsUtil::add("UnableToViewContentsMoreThanOne"); @@ -92,7 +92,7 @@ void LLFloaterOpenObject::onOpen(const LLSD& key) closeFloater(); return; } - mObjectSelection = LLSelectMgr::getInstanceFast()->getEditSelection(); + mObjectSelection = LLSelectMgr::getInstance()->getEditSelection(); refresh(); } diff --git a/indra/newview/llfloaterpathfindingconsole.cpp b/indra/newview/llfloaterpathfindingconsole.cpp index b31acf0095394ad8b09010ce4f33b108094eb92a..ccf3e723fd221cb336862701050449d8c4fe64f3 100644 --- a/indra/newview/llfloaterpathfindingconsole.cpp +++ b/indra/newview/llfloaterpathfindingconsole.cpp @@ -950,7 +950,7 @@ void LLFloaterPathfindingConsole::switchIntoTestPathMode() if (LLPathingLib::getInstance() != NULL) { llassert(mPathfindingToolset != NULL); - LLToolMgr *toolMgrInstance = LLToolMgr::getInstanceFast(); + LLToolMgr *toolMgrInstance = LLToolMgr::getInstance(); if (toolMgrInstance->getCurrentToolset() != mPathfindingToolset) { mSavedToolset = toolMgrInstance->getCurrentToolset(); @@ -964,7 +964,7 @@ void LLFloaterPathfindingConsole::switchOutOfTestPathMode() if (LLPathingLib::getInstance() != NULL) { llassert(mPathfindingToolset != NULL); - LLToolMgr *toolMgrInstance = LLToolMgr::getInstanceFast(); + LLToolMgr *toolMgrInstance = LLToolMgr::getInstance(); if (toolMgrInstance->getCurrentToolset() == mPathfindingToolset) { toolMgrInstance->setCurrentToolset(mSavedToolset); diff --git a/indra/newview/llfloaterpathfindingobjects.cpp b/indra/newview/llfloaterpathfindingobjects.cpp index 3f58a01559ba06b24803666f9b45969835c974fd..294c3d815948074d55ece002042ed5070a2e6483 100644 --- a/indra/newview/llfloaterpathfindingobjects.cpp +++ b/indra/newview/llfloaterpathfindingobjects.cpp @@ -79,7 +79,7 @@ void LLFloaterPathfindingObjects::onOpen(const LLSD &pKey) if (!mSelectionUpdateSlot.connected()) { - mSelectionUpdateSlot = LLSelectMgr::getInstanceFast()->mUpdateSignal.connect(boost::bind(&LLFloaterPathfindingObjects::onInWorldSelectionListChanged, this)); + mSelectionUpdateSlot = LLSelectMgr::getInstance()->mUpdateSignal.connect(boost::bind(&LLFloaterPathfindingObjects::onInWorldSelectionListChanged, this)); } if (!mRegionBoundaryCrossingSlot.connected()) @@ -467,7 +467,7 @@ void LLFloaterPathfindingObjects::showFloaterWithSelectionObjects() { mObjectsToBeSelected.clear(); - LLObjectSelectionHandle selectedObjectsHandle = LLSelectMgr::getInstanceFast()->getSelection(); + LLObjectSelectionHandle selectedObjectsHandle = LLSelectMgr::getInstance()->getSelection(); if (selectedObjectsHandle.notNull()) { LLObjectSelection *selectedObjects = selectedObjectsHandle.get(); @@ -830,7 +830,7 @@ void LLFloaterPathfindingObjects::updateStateOnActionControls() void LLFloaterPathfindingObjects::selectScrollListItemsInWorld() { mObjectsSelection.clear(); - LLSelectMgr::getInstanceFast()->deselectAll(); + LLSelectMgr::getInstance()->deselectAll(); std::vector<LLScrollListItem *> selectedItems = mObjectsScrollList->getAllSelected(); if (!selectedItems.empty()) @@ -854,7 +854,7 @@ void LLFloaterPathfindingObjects::selectScrollListItemsInWorld() if (!viewerObjects.empty()) { - mObjectsSelection = LLSelectMgr::getInstanceFast()->selectObjectAndFamily(viewerObjects); + mObjectsSelection = LLSelectMgr::getInstance()->selectObjectAndFamily(viewerObjects); } } } diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 471ee8249b9945a7e39474d7079ad5844321c664..669d222c825584b1d8ad4de045021bda27cb9986 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -374,60 +374,59 @@ void LLFloaterPreference::processProperties( void* pData, EAvatarProcessorType t const LLAvatarData* pAvatarData = static_cast<const LLAvatarData*>( pData ); if (pAvatarData && (gAgent.getID() == pAvatarData->avatar_id) && (pAvatarData->avatar_id.notNull())) { - storeAvatarProperties( pAvatarData ); - processProfileProperties( pAvatarData ); + mAllowPublish = (bool)(pAvatarData->flags & AVATAR_ALLOW_PUBLISH); + mAvatarDataInitialized = true; + getChild<LLUICtrl>("online_searchresults")->setValue(mAllowPublish); } } } -void LLFloaterPreference::storeAvatarProperties( const LLAvatarData* pAvatarData ) +void LLFloaterPreference::saveAvatarProperties( void ) { - if (LLStartUp::getStartupState() == STATE_STARTED) - { - mAvatarProperties.avatar_id = pAvatarData->avatar_id; - mAvatarProperties.image_id = pAvatarData->image_id; - mAvatarProperties.fl_image_id = pAvatarData->fl_image_id; - mAvatarProperties.about_text = pAvatarData->about_text; - mAvatarProperties.fl_about_text = pAvatarData->fl_about_text; - mAvatarProperties.profile_url = pAvatarData->profile_url; - mAvatarProperties.flags = pAvatarData->flags; - mAvatarProperties.allow_publish = pAvatarData->flags & AVATAR_ALLOW_PUBLISH; + const bool allowPublish = getChild<LLUICtrl>("online_searchresults")->getValue(); - mAvatarDataInitialized = true; - } -} + if ((LLStartUp::getStartupState() == STATE_STARTED) + && mAvatarDataInitialized + && (allowPublish != mAllowPublish)) + { + std::string cap_url = gAgent.getRegionCapability("AgentProfile"); + if (!cap_url.empty()) + { + mAllowPublish = allowPublish; -void LLFloaterPreference::processProfileProperties(const LLAvatarData* pAvatarData ) -{ - getChild<LLUICtrl>("online_searchresults")->setValue( (bool)(pAvatarData->flags & AVATAR_ALLOW_PUBLISH) ); + LLCoros::instance().launch("requestAgentUserInfoCoro", + boost::bind(saveAvatarPropertiesCoro, cap_url, allowPublish)); + } + } } -void LLFloaterPreference::saveAvatarProperties( void ) +void LLFloaterPreference::saveAvatarPropertiesCoro(const std::string cap_url, bool allow_publish) { - const BOOL allowPublish = getChild<LLUICtrl>("online_searchresults")->getValue(); + LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); + LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t + httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("put_avatar_properties_coro", httpPolicy)); + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + LLCore::HttpHeaders::ptr_t httpHeaders; - if (allowPublish) - { - mAvatarProperties.flags |= AVATAR_ALLOW_PUBLISH; - } + LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); + httpOpts->setFollowRedirects(true); - // - // NOTE: We really don't want to send the avatar properties unless we absolutely - // need to so we can avoid the accidental profile reset bug, so, if we're - // logged in, the avatar data has been initialized and we have a state change - // for the "allow publish" flag, then set the flag to its new value and send - // the properties update. - // - // NOTE: The only reason we can not remove this update altogether is because of the - // "allow publish" flag, the last remaining profile setting in the viewer - // that doesn't exist in the web profile. - // - if ((LLStartUp::getStartupState() == STATE_STARTED) && mAvatarDataInitialized && (allowPublish != mAvatarProperties.allow_publish)) - { - mAvatarProperties.allow_publish = allowPublish; + std::string finalUrl = cap_url + "/" + gAgentID.asString(); + LLSD data; + data["allow_publish"] = allow_publish; - LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesUpdate( &mAvatarProperties ); - } + LLSD result = httpAdapter->putAndSuspend(httpRequest, finalUrl, data, httpOpts, httpHeaders); + + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + if (!status) + { + LL_WARNS("Preferences") << "Failed to put agent information " << data << " for id " << gAgentID << LL_ENDL; + return; + } + + LL_DEBUGS("Preferences") << "Agent id: " << gAgentID << " Data: " << data << " Result: " << httpResults << LL_ENDL; } BOOL LLFloaterPreference::postBuild() @@ -1337,7 +1336,7 @@ void LLFloaterPreference::onBtnOK(const LLSD& userdata) else { // Show beep, pop up dialog, etc. - LL_INFOS() << "Can't close preferences!" << LL_ENDL; + LL_INFOS("Preferences") << "Can't close preferences!" << LL_ENDL; } LLPanelLogin::updateLocationSelectorsVisibility(); @@ -1527,7 +1526,7 @@ void LLFloaterPreference::buildPopupLists() { if (ignore == LLNotificationForm::IGNORE_WITH_LAST_RESPONSE) { - LLSD last_response = LLUI::getInstanceFast()->mSettingGroups["config"]->getLLSD("Default" + templatep->mName); + LLSD last_response = LLUI::getInstance()->mSettingGroups["config"]->getLLSD("Default" + templatep->mName); if (!last_response.isUndefined()) { for (LLSD::map_const_iterator it = last_response.beginMap(); @@ -1580,14 +1579,10 @@ void LLFloaterPreference::refreshEnabledState() //Deferred/SSAO/Shadows BOOL bumpshiny = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump") && gSavedSettings.getBOOL("RenderObjectBump"); - BOOL transparent_water = LLFeatureManager::getInstance()->isFeatureAvailable("RenderTransparentWater") && gSavedSettings.getBOOL("RenderTransparentWater"); BOOL shaders = gSavedSettings.getBOOL("WindLightUseAtmosShaders"); BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") && bumpshiny && - transparent_water && shaders && - gGLManager.mHasFramebufferObject && - gSavedSettings.getBOOL("RenderAvatarVP") && (ctrl_wind_light->get()) ? TRUE : FALSE; ctrl_deferred->setEnabled(enabled); @@ -1617,37 +1612,14 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState() ctrl_reflections->setEnabled(reflections); reflections_text->setEnabled(reflections); - // Transparent Water - LLCheckBoxCtrl* transparent_water_ctrl = getChild<LLCheckBoxCtrl>("TransparentWater"); - // Bump & Shiny LLCheckBoxCtrl* bumpshiny_ctrl = getChild<LLCheckBoxCtrl>("BumpShiny"); bool bumpshiny = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump"); bumpshiny_ctrl->setEnabled(bumpshiny ? TRUE : FALSE); // Avatar Mode - // Enable Avatar Shaders - LLCheckBoxCtrl* ctrl_avatar_vp = getChild<LLCheckBoxCtrl>("AvatarVertexProgram"); // Avatar Render Mode - LLCheckBoxCtrl* ctrl_avatar_cloth = getChild<LLCheckBoxCtrl>("AvatarCloth"); - - bool avatar_vp_enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderAvatarVP"); - if (LLViewerShaderMgr::sInitialized) - { - S32 max_avatar_shader = LLViewerShaderMgr::instance()->mMaxAvatarShaderLevel; - avatar_vp_enabled = (max_avatar_shader > 0) ? TRUE : FALSE; - } - - ctrl_avatar_vp->setEnabled(avatar_vp_enabled); - - if (gSavedSettings.getBOOL("RenderAvatarVP") == FALSE) - { - ctrl_avatar_cloth->setEnabled(FALSE); - } - else - { - ctrl_avatar_cloth->setEnabled(TRUE); - } + getChild<LLCheckBoxCtrl>("AvatarCloth")->setEnabled(TRUE); // Vertex Shaders, Global Shader Enable // SL-12594 Basic shaders are always enabled. DJH TODO clean up now-orphaned state handling code @@ -1674,9 +1646,6 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState() BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") && ((bumpshiny_ctrl && bumpshiny_ctrl->get()) ? TRUE : FALSE) && - ((transparent_water_ctrl && transparent_water_ctrl->get()) ? TRUE : FALSE) && - gGLManager.mHasFramebufferObject && - gSavedSettings.getBOOL("RenderAvatarVP") && (ctrl_wind_light->get()) ? TRUE : FALSE; ctrl_deferred->setEnabled(enabled); @@ -1795,7 +1764,6 @@ void LLFloaterPreferenceGraphicsAdvanced::disableUnavailableSettings() LLTextBox* reflections_text = getChild<LLTextBox>("ReflectionsText"); LLComboBox* ctrl_reflections_quality = getChild<LLComboBox>("ReflectionsQuality"); LLTextBox* reflections_quality_text = getChild<LLTextBox>("ReflectionsQualityText"); - LLCheckBoxCtrl* ctrl_avatar_vp = getChild<LLCheckBoxCtrl>("AvatarVertexProgram"); LLCheckBoxCtrl* ctrl_avatar_cloth = getChild<LLCheckBoxCtrl>("AvatarCloth"); LLCheckBoxCtrl* ctrl_wind_light = getChild<LLCheckBoxCtrl>("WindLightUseAtmosShaders"); LLCheckBoxCtrl* ctrl_deferred = getChild<LLCheckBoxCtrl>("UseLightShaders"); @@ -1832,8 +1800,7 @@ void LLFloaterPreferenceGraphicsAdvanced::disableUnavailableSettings() } // disabled deferred - if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") || - !gGLManager.mHasFramebufferObject) + if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred")) { ctrl_shadows->setEnabled(FALSE); ctrl_shadows->setValue(0); @@ -1880,30 +1847,6 @@ void LLFloaterPreferenceGraphicsAdvanced::disableUnavailableSettings() reflections_quality_text->setEnabled(FALSE); } - // disabled av - if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderAvatarVP")) - { - ctrl_avatar_vp->setEnabled(FALSE); - ctrl_avatar_vp->setValue(FALSE); - - ctrl_avatar_cloth->setEnabled(FALSE); - ctrl_avatar_cloth->setValue(FALSE); - - //deferred needs AvatarVP, disable deferred - ctrl_shadows->setEnabled(FALSE); - ctrl_shadows->setValue(0); - shadows_text->setEnabled(FALSE); - - ctrl_ssao->setEnabled(FALSE); - ctrl_ssao->setValue(FALSE); - - ctrl_dof->setEnabled(FALSE); - ctrl_dof->setValue(FALSE); - - ctrl_deferred->setEnabled(FALSE); - ctrl_deferred->setValue(FALSE); - } - // disabled cloth if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderAvatarCloth")) { @@ -1989,7 +1932,7 @@ void LLFloaterPreference::onClickEnablePopup() LLNotificationTemplatePtr templatep = LLNotifications::instance().getTemplate(*(std::string*)((*itor)->getUserdata())); //gSavedSettings.setWarning(templatep->mName, TRUE); std::string notification_name = templatep->mName; - LLUI::getInstanceFast()->mSettingGroups["ignores"]->setBOOL(notification_name, TRUE); + LLUI::getInstance()->mSettingGroups["ignores"]->setBOOL(notification_name, TRUE); } buildPopupLists(); @@ -2309,13 +2252,13 @@ bool LLFloaterPreference::loadFromFilename(const std::string& filename, std::map if (!LLXMLNode::parseFile(filename, root, NULL)) { - LL_WARNS() << "Unable to parse file " << filename << LL_ENDL; + LL_WARNS("Preferences") << "Unable to parse file " << filename << LL_ENDL; return false; } if (!root->hasName("labels")) { - LL_WARNS() << filename << " is not a valid definition file" << LL_ENDL; + LL_WARNS("Preferences") << filename << " is not a valid definition file" << LL_ENDL; return false; } @@ -2335,7 +2278,7 @@ bool LLFloaterPreference::loadFromFilename(const std::string& filename, std::map } else { - LL_WARNS() << filename << " failed to load" << LL_ENDL; + LL_WARNS("Preferences") << filename << " failed to load" << LL_ENDL; return false; } @@ -3230,7 +3173,7 @@ bool LLPanelPreferenceControls::addControlTableColumns(const std::string &filena LLScrollListCtrl::Contents contents; if (!LLUICtrlFactory::getLayeredXMLNode(filename, xmlNode)) { - LL_WARNS() << "Failed to load " << filename << LL_ENDL; + LL_WARNS("Preferences") << "Failed to load " << filename << LL_ENDL; return false; } LLXUIParser parser; @@ -3257,7 +3200,7 @@ bool LLPanelPreferenceControls::addControlTableRows(const std::string &filename) LLScrollListCtrl::Contents contents; if (!LLUICtrlFactory::getLayeredXMLNode(filename, xmlNode)) { - LL_WARNS() << "Failed to load " << filename << LL_ENDL; + LL_WARNS("Preferences") << "Failed to load " << filename << LL_ENDL; return false; } LLXUIParser parser; @@ -3363,7 +3306,7 @@ void LLPanelPreferenceControls::populateControlTable() { // Either unknown mode or MODE_SAVED_SETTINGS // It doesn't have UI or actual settings yet - LL_WARNS() << "Unimplemented mode" << LL_ENDL; + LL_WARNS("Preferences") << "Unimplemented mode" << LL_ENDL; // Searchable columns were removed, mark searchables for an update LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences"); @@ -3403,7 +3346,7 @@ void LLPanelPreferenceControls::populateControlTable() } else { - LL_WARNS() << "Unimplemented mode" << LL_ENDL; + LL_WARNS("Preferences") << "Unimplemented mode" << LL_ENDL; } // explicit update to make sure table is ready for llsearchableui @@ -3458,14 +3401,14 @@ void LLPanelPreferenceControls::cancel() if (mConflictHandler[i].hasUnsavedChanges()) { mConflictHandler[i].clear(); - if (mEditingMode == i) - { - // cancel() can be called either when preferences floater closes - // or when child floater closes (like advanced graphical settings) - // in which case we need to clear and repopulate table - regenerateControls(); - } - } + if (mEditingMode == i) + { + // cancel() can be called either when preferences floater closes + // or when child floater closes (like advanced graphical settings) + // in which case we need to clear and repopulate table + regenerateControls(); + } + } } } diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h index b4e44876aacc8ef23a199b06197e6b7331fa1e88..643d5375600b3fec2893fbbfcb8e6a252431c045 100644 --- a/indra/newview/llfloaterpreference.h +++ b/indra/newview/llfloaterpreference.h @@ -101,9 +101,8 @@ class LLFloaterPreference final : public LLFloater, public LLAvatarPropertiesObs static void updateShowFavoritesCheckbox(bool val); void processProperties( void* pData, EAvatarProcessorType type ); - void processProfileProperties(const LLAvatarData* pAvatarData ); - void storeAvatarProperties( const LLAvatarData* pAvatarData ); void saveAvatarProperties( void ); + static void saveAvatarPropertiesCoro(const std::string url, bool allow_publish); void selectPrivacyPanel(); void selectChatPanel(); void getControlNames(std::vector<std::string>& names); @@ -232,7 +231,7 @@ class LLFloaterPreference final : public LLFloater, public LLAvatarPropertiesObs bool mOriginalHideOnlineStatus; std::string mDirectoryVisibility; - LLAvatarData mAvatarProperties; + bool mAllowPublish; // Allow showing agent in search std::string mSavedCameraPreset; std::string mSavedGraphicsPreset; diff --git a/indra/newview/llfloaterprofile.cpp b/indra/newview/llfloaterprofile.cpp index f2863e1e27ebec2901aa9ee8007fdc45c66d241e..6ccdace6c5d9ad49770b97a5cd5d7bd5e056a679 100644 --- a/indra/newview/llfloaterprofile.cpp +++ b/indra/newview/llfloaterprofile.cpp @@ -2,9 +2,9 @@ * @file llfloaterprofile.cpp * @brief Avatar profile floater. * - * $LicenseInfo:firstyear=2009&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 @@ -28,9 +28,10 @@ #include "llfloaterprofile.h" +#include "llagent.h" //gAgent +#include "llnotificationsutil.h" #include "llpanelavatar.h" #include "llpanelprofile.h" -#include "llagent.h" //gAgent static const std::string PANEL_PROFILE_VIEW = "panel_profile_view"; @@ -62,12 +63,70 @@ BOOL LLFloaterProfile::postBuild() { mPanelProfile = findChild<LLPanelProfile>(PANEL_PROFILE_VIEW); - childSetAction("ok_btn", boost::bind(&LLFloaterProfile::onOKBtn, this)); - childSetAction("cancel_btn", boost::bind(&LLFloaterProfile::onCancelBtn, this)); - return TRUE; } +void LLFloaterProfile::onClickCloseBtn(bool app_quitting) +{ + if (!app_quitting) + { + if (mPanelProfile->hasUnpublishedClassifieds()) + { + LLNotificationsUtil::add("ProfileUnpublishedClassified", LLSD(), LLSD(), + boost::bind(&LLFloaterProfile::onUnsavedChangesCallback, this, _1, _2, false)); + } + else if (mPanelProfile->hasUnsavedChanges()) + { + LLNotificationsUtil::add("ProfileUnsavedChanges", LLSD(), LLSD(), + boost::bind(&LLFloaterProfile::onUnsavedChangesCallback, this, _1, _2, true)); + } + else + { + closeFloater(); + } + } + else + { + closeFloater(); + } +} + +void LLFloaterProfile::onUnsavedChangesCallback(const LLSD& notification, const LLSD& response, bool can_save) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (can_save) + { + // savable content + + if (option == 0) // Save + { + mPanelProfile->commitUnsavedChanges(); + closeFloater(); + } + if (option == 1) // Discard + { + closeFloater(); + } + // else cancel + } + else + { + // classifieds + + if (option == 0) // Ok + { + closeFloater(); + } + // else cancel + } + +} + +void LLFloaterProfile::createPick(const LLPickData &data) +{ + mPanelProfile->createPick(data); +} + void LLFloaterProfile::showPick(const LLUUID& pick_id) { mPanelProfile->showPick(pick_id); @@ -78,20 +137,28 @@ bool LLFloaterProfile::isPickTabSelected() return mPanelProfile->isPickTabSelected(); } -void LLFloaterProfile::showClassified(const LLUUID& classified_id, bool edit) +void LLFloaterProfile::refreshName() { - mPanelProfile->showClassified(classified_id, edit); + if (!mNameCallbackConnection.connected()) + { + mNameCallbackConnection = LLAvatarNameCache::get(mAvatarId, boost::bind(&LLFloaterProfile::onAvatarNameCache, this, _1, _2)); + } + + LLPanelProfileSecondLife *panel = findChild<LLPanelProfileSecondLife>("panel_profile_secondlife"); + if (panel) + { + panel->refreshName(); + } } -void LLFloaterProfile::onOKBtn() +void LLFloaterProfile::showClassified(const LLUUID& classified_id, bool edit) { - mPanelProfile->apply(); - closeFloater(); + mPanelProfile->showClassified(classified_id, edit); } -void LLFloaterProfile::onCancelBtn() +void LLFloaterProfile::createClassified() { - closeFloater(); + mPanelProfile->createClassified(); } void LLFloaterProfile::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name) diff --git a/indra/newview/llfloaterprofile.h b/indra/newview/llfloaterprofile.h index 259a752fbf2929269063e282e1ffea65d952487e..dea59610150b7fa0cb6f0706f2e16e26cfabf830 100644 --- a/indra/newview/llfloaterprofile.h +++ b/indra/newview/llfloaterprofile.h @@ -2,9 +2,9 @@ * @file llfloaterprofile.h * @brief Avatar profile floater. * - * $LicenseInfo:firstyear=2009&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 @@ -28,6 +28,7 @@ #define LL_LLFLOATERPROFILE_H #include "llavatarnamecache.h" +#include "llavatarpropertiesprocessor.h" #include "llfloater.h" class LLPanelProfile; @@ -39,17 +40,19 @@ class LLFloaterProfile final : public LLFloater LLFloaterProfile(const LLSD& key); virtual ~LLFloaterProfile(); - /*virtual*/ void onOpen(const LLSD& key); - /*virtual*/ BOOL postBuild(); + BOOL postBuild() override; + void onOpen(const LLSD& key) override; + void onClickCloseBtn(bool app_quitting = false) override; + void onUnsavedChangesCallback(const LLSD& notification, const LLSD& response, bool can_save); + + void createPick(const LLPickData &data); void showPick(const LLUUID& pick_id = LLUUID::null); bool isPickTabSelected(); + void refreshName(); void showClassified(const LLUUID& classified_id = LLUUID::null, bool edit = false); - -protected: - void onOKBtn(); - void onCancelBtn(); + void createClassified(); private: LLAvatarNameCache::callback_connection_t mNameCallbackConnection; diff --git a/indra/newview/llfloaterprofiletexture.cpp b/indra/newview/llfloaterprofiletexture.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bf1f56a6d1c686fd057003d73ee022e28339de86 --- /dev/null +++ b/indra/newview/llfloaterprofiletexture.cpp @@ -0,0 +1,223 @@ +/** + * @file llfloaterprofiletexture.cpp + * @brief LLFloaterProfileTexture class implementation + * + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Second Life Viewer Source Code + * 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 + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfloaterprofiletexture.h" + +#include "llbutton.h" +#include "llfloaterreg.h" +#include "llpreview.h" // fors constants +#include "lltrans.h" +#include "llviewercontrol.h" +#include "lltextureview.h" +#include "llviewertexture.h" +#include "llviewertexturelist.h" + + + +LLFloaterProfileTexture::LLFloaterProfileTexture(LLView* owner) + : LLFloater(LLSD()) + , mUpdateDimensions(TRUE) + , mLastHeight(0) + , mLastWidth(0) + , mImage(NULL) + , mImageOldBoostLevel(LLGLTexture::BOOST_NONE) + , mOwnerHandle(owner->getHandle()) +{ + buildFromFile("floater_profile_texture.xml"); +} + +LLFloaterProfileTexture::~LLFloaterProfileTexture() +{ + if (mImage.notNull()) + { + mImage->setBoostLevel(mImageOldBoostLevel); + mImage = NULL; + } +} + +// virtual +BOOL LLFloaterProfileTexture::postBuild() +{ + mProfileIcon = getChild<LLIconCtrl>("profile_pic"); + + mCloseButton = getChild<LLButton>("close_btn"); + mCloseButton->setCommitCallback([this](LLUICtrl*, void*) { closeFloater(); }, nullptr); + + return TRUE; +} + +// virtual +void LLFloaterProfileTexture::reshape(S32 width, S32 height, BOOL called_from_parent) +{ + LLFloater::reshape(width, height, called_from_parent); +} + +// It takes a while until we get height and width information. +// When we receive it, reshape the window accordingly. +void LLFloaterProfileTexture::updateDimensions() +{ + if (mImage.isNull()) + { + return; + } + if ((mImage->getFullWidth() * mImage->getFullHeight()) == 0) + { + return; + } + + S32 img_width = mImage->getFullWidth(); + S32 img_height = mImage->getFullHeight(); + + if (mAssetStatus != LLPreview::PREVIEW_ASSET_LOADED + || mLastWidth != img_width + || mLastHeight != img_height) + { + mAssetStatus = LLPreview::PREVIEW_ASSET_LOADED; + // Asset has been fully loaded + mUpdateDimensions = TRUE; + } + + mLastHeight = img_height; + mLastWidth = img_width; + + // Reshape the floater only when required + if (mUpdateDimensions) + { + mUpdateDimensions = FALSE; + + LLRect old_floater_rect = getRect(); + LLRect old_image_rect = mProfileIcon->getRect(); + S32 width = old_floater_rect.getWidth() - old_image_rect.getWidth() + mLastWidth; + S32 height = old_floater_rect.getHeight() - old_image_rect.getHeight() + mLastHeight; + + const F32 MAX_DIMENTIONS = 512; // most profiles are supposed to be 256x256 + + S32 biggest_dim = llmax(width, height); + if (biggest_dim > MAX_DIMENTIONS) + { + F32 scale_down = MAX_DIMENTIONS / (F32)biggest_dim; + width *= scale_down; + height *= scale_down; + } + + //reshape floater + reshape(width, height); + + gFloaterView->adjustToFitScreen(this, FALSE); + } +} + +void LLFloaterProfileTexture::draw() +{ + // drawFrustum + LLView *owner = mOwnerHandle.get(); + static LLCachedControl<F32> max_opacity(gSavedSettings, "PickerContextOpacity", 0.4f); + drawConeToOwner(mContextConeOpacity, max_opacity, owner); + + LLFloater::draw(); +} + +void LLFloaterProfileTexture::onOpen(const LLSD& key) +{ + mCloseButton->setFocus(true); +} + +void LLFloaterProfileTexture::resetAsset() +{ + mProfileIcon->setValue("Generic_Person_Large"); + mImageID = LLUUID::null; + if (mImage.notNull()) + { + mImage->setBoostLevel(mImageOldBoostLevel); + mImage = NULL; + } +} +void LLFloaterProfileTexture::loadAsset(const LLUUID &image_id) +{ + if (mImageID != image_id) + { + if (mImage.notNull()) + { + mImage->setBoostLevel(mImageOldBoostLevel); + mImage = NULL; + } + } + else + { + return; + } + + mProfileIcon->setValue(image_id); + mImageID = image_id; + mImage = LLViewerTextureManager::getFetchedTexture(mImageID, FTT_DEFAULT, MIPMAP_TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + mImageOldBoostLevel = mImage->getBoostLevel(); + + if ((mImage->getFullWidth() * mImage->getFullHeight()) == 0) + { + mImage->setLoadedCallback(LLFloaterProfileTexture::onTextureLoaded, + 0, TRUE, FALSE, new LLHandle<LLFloater>(getHandle()), &mCallbackTextureList); + + mImage->setBoostLevel(LLGLTexture::BOOST_PREVIEW); + mAssetStatus = LLPreview::PREVIEW_ASSET_LOADING; + } + else + { + mAssetStatus = LLPreview::PREVIEW_ASSET_LOADED; + } + + mUpdateDimensions = TRUE; + updateDimensions(); +} + +// static +void LLFloaterProfileTexture::onTextureLoaded( + BOOL success, + LLViewerFetchedTexture *src_vi, + LLImageRaw* src, + LLImageRaw* aux_src, + S32 discard_level, + BOOL final, + void* userdata) +{ + LLHandle<LLFloater>* handle = (LLHandle<LLFloater>*)userdata; + + if (!handle->isDead()) + { + LLFloaterProfileTexture* floater = static_cast<LLFloaterProfileTexture*>(handle->get()); + if (floater && success) + { + floater->mUpdateDimensions = TRUE; + floater->updateDimensions(); + } + } + + if (final || !success) + { + delete handle; + } +} diff --git a/indra/newview/llfloaterprofiletexture.h b/indra/newview/llfloaterprofiletexture.h new file mode 100644 index 0000000000000000000000000000000000000000..66a61213ddafc7baa4aa94bc597226476ed44c4b --- /dev/null +++ b/indra/newview/llfloaterprofiletexture.h @@ -0,0 +1,81 @@ +/** + * @file llfloaterprofiletexture.h + * @brief LLFloaterProfileTexture class definition + * + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Second Life Viewer Source Code + * 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 + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLFLOATERPROFILETEXTURE_H +#define LL_LLFLOATERPROFILETEXTURE_H + +#include "llfloater.h" +#include "llviewertexture.h" + +class LLButton; +class LLImageRaw; +class LLIconCtrl; + +class LLFloaterProfileTexture : public LLFloater +{ +public: + LLFloaterProfileTexture(LLView* owner); + ~LLFloaterProfileTexture(); + + void draw() override; + void onOpen(const LLSD& key) override; + + void resetAsset(); + void loadAsset(const LLUUID &image_id); + + + static void onTextureLoaded( + BOOL success, + LLViewerFetchedTexture *src_vi, + LLImageRaw* src, + LLImageRaw* aux_src, + S32 discard_level, + BOOL final, + void* userdata); + + void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE) override; +protected: + BOOL postBuild() override; + +private: + void updateDimensions(); + + LLUUID mImageID; + LLPointer<LLViewerFetchedTexture> mImage; + S32 mImageOldBoostLevel; + S32 mAssetStatus; + F32 mContextConeOpacity; + S32 mLastHeight; + S32 mLastWidth; + BOOL mUpdateDimensions; + + LLHandle<LLView> mOwnerHandle; + LLIconCtrl* mProfileIcon; + LLButton* mCloseButton; + + LLLoadedCallbackEntry::source_callback_list_t mCallbackTextureList; +}; +#endif // LL_LLFLOATERPROFILETEXTURE_H diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index a11770cd3be3db852afea8ae7ce693a54cf0f861..4fca6c085fbba3ba63afc4d256a5a3d24d5cdb49 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -47,6 +47,7 @@ #include "llagent.h" #include "llappviewer.h" +#include "llavataractions.h" #include "llavatarname.h" #include "llfloateravatarpicker.h" #include "llbutton.h" @@ -1322,6 +1323,7 @@ void LLPanelRegionDebugInfo::onClickDebugConsole(void* data) BOOL LLPanelRegionTerrainInfo::validateTextureSizes() { + static const S32 MAX_TERRAIN_TEXTURE_SIZE = 1024; for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) { std::string buffer; @@ -1343,20 +1345,19 @@ BOOL LLPanelRegionTerrainInfo::validateTextureSizes() LLSD args; args["TEXTURE_NUM"] = i+1; args["TEXTURE_BIT_DEPTH"] = llformat("%d",components * 8); + args["MAX_SIZE"] = MAX_TERRAIN_TEXTURE_SIZE; LLNotificationsUtil::add("InvalidTerrainBitDepth", args); return FALSE; } -// if (width > 512 || height > 512) -// [AL:SE] - Patch: Estate-LargeTerrain - if (width > 1024 || height > 1024) -// [/AL:SE] + if (width > MAX_TERRAIN_TEXTURE_SIZE || height > MAX_TERRAIN_TEXTURE_SIZE) { LLSD args; args["TEXTURE_NUM"] = i+1; args["TEXTURE_SIZE_X"] = width; args["TEXTURE_SIZE_Y"] = height; + args["MAX_SIZE"] = MAX_TERRAIN_TEXTURE_SIZE; LLNotificationsUtil::add("InvalidTerrainSize", args); return FALSE; @@ -1829,7 +1830,7 @@ void LLPanelEstateInfo::updateControls(LLViewerRegion* region) setCtrlsEnabled(god || owner || manager); getChildView("apply_btn")->setEnabled(FALSE); - + getChildView("estate_owner")->setEnabled(TRUE); getChildView("message_estate_btn")->setEnabled(god || owner || manager); getChildView("kick_user_from_estate_btn")->setEnabled(god || owner || manager); @@ -1891,6 +1892,8 @@ BOOL LLPanelEstateInfo::postBuild() getChild<LLUICtrl>("externally_visible_radio")->setFocus(TRUE); + getChild<LLTextBox>("estate_owner")->setIsFriendCallback(LLAvatarActions::isFriend); + return LLPanelRegionInfo::postBuild(); } @@ -2111,6 +2114,8 @@ bool LLPanelEstateCovenant::refreshFromRegion(LLViewerRegion* region) LLTextBox* region_landtype = getChild<LLTextBox>("region_landtype_text"); region_landtype->setText(region->getLocalizedSimProductName()); + + getChild<LLButton>("reset_covenant")->setEnabled(gAgent.isGodlike() || (region && region->canManageEstate())); // let the parent class handle the general data collection. bool rv = LLPanelRegionInfo::refreshFromRegion(region); @@ -2135,6 +2140,7 @@ BOOL LLPanelEstateCovenant::postBuild() { mEstateNameText = getChild<LLTextBox>("estate_name_text"); mEstateOwnerText = getChild<LLTextBox>("estate_owner_text"); + mEstateOwnerText->setIsFriendCallback(LLAvatarActions::isFriend); mLastModifiedText = getChild<LLTextBox>("covenant_timestamp_text"); mEditor = getChild<LLViewerTextEditor>("covenant_editor"); LLButton* reset_button = getChild<LLButton>("reset_covenant"); @@ -3688,7 +3694,7 @@ void LLPanelEstateAccess::searchAgent(LLNameListCtrl* listCtrl, const std::strin if (!search_string.empty()) { listCtrl->setSearchColumn(0); // name column - listCtrl->selectItemByPrefix(search_string, FALSE); + listCtrl->searchItems(search_string, false, true); } else { diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp index 6136a1c9b7b7c1ac7e5be7122f8127f22f90307c..fbc9f5885b3d045986a2a72ee2252d768299a98e 100644 --- a/indra/newview/llfloaterreporter.cpp +++ b/indra/newview/llfloaterreporter.cpp @@ -54,6 +54,7 @@ #include "llbutton.h" #include "llfloaterreg.h" #include "lltexturectrl.h" +#include "lltexteditor.h" #include "llscrolllistctrl.h" #include "lldispatcher.h" #include "llviewerobject.h" @@ -250,9 +251,6 @@ LLFloaterReporter::~LLFloaterReporter() mPosition.setVec(0.0f, 0.0f, 0.0f); - std::for_each(mMCDList.begin(), mMCDList.end(), DeletePointer() ); - mMCDList.clear(); - delete mResourceDatap; } @@ -567,8 +565,8 @@ void LLFloaterReporter::onClickCancel(void *userdata) void LLFloaterReporter::onClickObjPicker(void *userdata) { LLFloaterReporter *self = (LLFloaterReporter *)userdata; - LLToolObjPicker::getInstanceFast()->setExitCallback(LLFloaterReporter::closePickTool, self); - LLToolMgr::getInstanceFast()->setTransientTool(LLToolObjPicker::getInstanceFast()); + LLToolObjPicker::getInstance()->setExitCallback(LLFloaterReporter::closePickTool, self); + LLToolMgr::getInstance()->setTransientTool(LLToolObjPicker::getInstance()); self->mPicking = TRUE; self->getChild<LLUICtrl>("object_name")->setValue(LLStringUtil::null); self->getChild<LLUICtrl>("owner_name")->setValue(LLStringUtil::null); @@ -583,10 +581,10 @@ void LLFloaterReporter::closePickTool(void *userdata) { LLFloaterReporter *self = (LLFloaterReporter *)userdata; - LLUUID object_id = LLToolObjPicker::getInstanceFast()->getObjectID(); + LLUUID object_id = LLToolObjPicker::getInstance()->getObjectID(); self->getObjectInfo(object_id); - LLToolMgr::getInstanceFast()->clearTransientTool(); + LLToolMgr::getInstance()->clearTransientTool(); self->mPicking = FALSE; LLButton* pick_btn = self->getChild<LLButton>("pick_btn"); if (pick_btn) pick_btn->setToggleState(FALSE); @@ -669,6 +667,23 @@ void LLFloaterReporter::showFromAvatar(const LLUUID& avatar_id, const std::strin show(avatar_id, avatar_name); } +// static +void LLFloaterReporter::showFromChat(const LLUUID& avatar_id, const std::string& avatar_name, const std::string& time, const std::string& description) +{ + show(avatar_id, avatar_name); + + LLStringUtil::format_map_t args; + args["[MSG_TIME]"] = time; + args["[MSG_DESCRIPTION]"] = description; + + LLFloaterReporter *self = LLFloaterReg::findTypedInstance<LLFloaterReporter>("reporter"); + if (self) + { + std::string description = self->getString("chat_report_format", args); + self->getChild<LLUICtrl>("details_edit")->setValue(description); + } +} + void LLFloaterReporter::setPickedObjectProperties(const std::string& object_name, const std::string& owner_name, const LLUUID owner_id) { getChild<LLUICtrl>("object_name")->setValue(object_name); @@ -1040,37 +1055,3 @@ void LLFloaterReporter::onClose(bool app_quitting) mSnapshotTimer.stop(); gSavedPerAccountSettings.setBOOL("PreviousScreenshotForReport", app_quitting); } - - -// void LLFloaterReporter::setDescription(const std::string& description, LLMeanCollisionData *mcd) -// { -// LLFloaterReporter *self = LLFloaterReg::findTypedInstance<LLFloaterReporter>("reporter"); -// if (self) -// { -// self->getChild<LLUICtrl>("details_edit")->setValue(description); - -// for_each(self->mMCDList.begin(), self->mMCDList.end(), DeletePointer()); -// self->mMCDList.clear(); -// if (mcd) -// { -// self->mMCDList.push_back(new LLMeanCollisionData(mcd)); -// } -// } -// } - -// void LLFloaterReporter::addDescription(const std::string& description, LLMeanCollisionData *mcd) -// { -// LLFloaterReporter *self = LLFloaterReg::findTypedInstance<LLFloaterReporter>("reporter"); -// if (self) -// { -// LLTextEditor* text = self->getChild<LLTextEditor>("details_edit"); -// if (text) -// { -// text->insertText(description); -// } -// if (mcd) -// { -// self->mMCDList.push_back(new LLMeanCollisionData(mcd)); -// } -// } -// } diff --git a/indra/newview/llfloaterreporter.h b/indra/newview/llfloaterreporter.h index 63ad22beb682ade05dec1d0f89cc06b850f68311..4baed32a42e65a6b001435dcee89da34b8184684 100644 --- a/indra/newview/llfloaterreporter.h +++ b/indra/newview/llfloaterreporter.h @@ -93,6 +93,7 @@ class LLFloaterReporter final static void showFromObject(const LLUUID& object_id, const LLUUID& experience_id = LLUUID::null); static void showFromAvatar(const LLUUID& avatar_id, const std::string avatar_name); + static void showFromChat(const LLUUID& avatar_id, const std::string& avatar_name, const std::string& time, const std::string& description); static void showFromExperience(const LLUUID& experience_id); static void onClickSend (void *userdata); @@ -101,8 +102,6 @@ class LLFloaterReporter final void onClickSelectAbuser (); static void closePickTool (void *userdata); static void uploadDoneCallback(const LLUUID &uuid, void* user_data, S32 result, LLExtStat ext_status); - static void addDescription(const std::string& description, LLMeanCollisionData *mcd = NULL); - static void setDescription(const std::string& description, LLMeanCollisionData *mcd = NULL); void setPickedObjectProperties(const std::string& object_name, const std::string& owner_name, const LLUUID owner_id); @@ -114,10 +113,8 @@ class LLFloaterReporter final static void show(const LLUUID& object_id, const std::string& avatar_name = LLStringUtil::null, const LLUUID& experience_id = LLUUID::null); void takeScreenshot(bool use_prev_screenshot = false); - void sendReportViaCaps(std::string url); void uploadImage(); bool validateReport(); - void setReporterID(); LLSD gatherReport(); void sendReportViaLegacy(const LLSD & report); void sendReportViaCaps(std::string url, std::string sshot_url, const LLSD & report); @@ -144,7 +141,6 @@ class LLFloaterReporter final BOOL mPicking; LLVector3 mPosition; BOOL mCopyrightWarningSeen; - std::list<LLMeanCollisionData*> mMCDList; std::string mDefaultSummary; LLResourceData* mResourceDatap; boost::signals2::connection mAvatarNameCacheConnection; diff --git a/indra/newview/llfloatersearch.cpp b/indra/newview/llfloatersearch.cpp index 3dcc53deda730f2902685dd5e3aaba4226e70ec3..d1ef509543b4f87cc180b58e9f6f3906c425380d 100644 --- a/indra/newview/llfloatersearch.cpp +++ b/indra/newview/llfloatersearch.cpp @@ -50,7 +50,7 @@ class LLSearchHandler : public LLCommandHandler LLSearchHandler() : LLCommandHandler("search", UNTRUSTED_THROTTLE) { } bool handle(const LLSD& tokens, const LLSD& query_map, LLMediaCtrl* web) { - if (!LLUI::getInstanceFast()->mSettingGroups["config"]->getBOOL("EnableSearch")) + if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnableSearch")) { LLNotificationsUtil::add("NoSearch", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit")); return true; @@ -59,10 +59,10 @@ class LLSearchHandler : public LLCommandHandler const size_t parts = tokens.size(); // get the (optional) category for the search - std::string category; + std::string collection; if (parts > 0) { - category = tokens[0].asString(); + collection = tokens[0].asString(); } // get the (optional) search string @@ -74,7 +74,7 @@ class LLSearchHandler : public LLCommandHandler // create the LLSD arguments for the search floater LLFloaterSearch::Params p; - p.search.category = category; + p.search.collection = collection; p.search.query = LLURI::unescape(search_text); // open the search floater and perform the requested search @@ -85,8 +85,9 @@ class LLSearchHandler : public LLCommandHandler LLSearchHandler gSearchHandler; LLFloaterSearch::SearchQuery::SearchQuery() -: category("category", ""), - query("query") +: category("category", ""), + collection("collection", ""), + query("query") {} LLFloaterSearch::LLFloaterSearch(const Params& key) : @@ -95,16 +96,16 @@ LLFloaterSearch::LLFloaterSearch(const Params& key) : { // declare a map that transforms a category name into // the URL suffix that is used to search that category - mCategoryPaths = LLSD::emptyMap(); - mCategoryPaths["all"] = "search"; - mCategoryPaths["people"] = "search/people"; - mCategoryPaths["places"] = "search/places"; - mCategoryPaths["events"] = "search/events"; - mCategoryPaths["groups"] = "search/groups"; - mCategoryPaths["wiki"] = "search/wiki"; - mCategoryPaths["land"] = "land"; - mCategoryPaths["destinations"] = "destinations"; - mCategoryPaths["classifieds"] = "classifieds"; + + mSearchType.insert("standard"); + mSearchType.insert("land"); + mSearchType.insert("classified"); + + mCollectionType.insert("events"); + mCollectionType.insert("destinations"); + mCollectionType.insert("places"); + mCollectionType.insert("groups"); + mCollectionType.insert("people"); } BOOL LLFloaterSearch::postBuild() @@ -159,31 +160,49 @@ void LLFloaterSearch::search(const SearchQuery &p) // work out the subdir to use based on the requested category LLSD subs; - if (mCategoryPaths.has(p.category.getValue())) + if (mSearchType.find(p.category.getValue()) != mSearchType.end()) { - subs["CATEGORY"] = mCategoryPaths[p.category.getValue()].asString(); + subs["TYPE"] = p.category.getValue(); } else { - subs["CATEGORY"] = mCategoryPaths["all"].asString(); + subs["TYPE"] = "standard"; } // add the search query string subs["QUERY"] = LLURI::escape(p.query); + subs["COLLECTION"] = ""; + if (subs["TYPE"] == "standard") + { + if (mCollectionType.find(p.collection) != mCollectionType.end()) + { + subs["COLLECTION"] = "&collection_chosen=" + std::string(p.collection); + } + else + { + std::string collection_args(""); + for (std::set<std::string>::iterator it = mCollectionType.begin(); it != mCollectionType.end(); ++it) + { + collection_args += "&collection_chosen=" + std::string(*it); + } + subs["COLLECTION"] = collection_args; + } + } + // add the user's preferred maturity (can be changed via prefs) std::string maturity; if (gAgent.prefersAdult()) { - maturity = "42"; // PG,Mature,Adult + maturity = "gma"; // PG,Mature,Adult } else if (gAgent.prefersMature()) { - maturity = "21"; // PG,Mature + maturity = "gm"; // PG,Mature } else { - maturity = "13"; // PG + maturity = "g"; // PG } subs["MATURITY"] = maturity; diff --git a/indra/newview/llfloatersearch.h b/indra/newview/llfloatersearch.h index 0f9bf2f54d038a3bf53bc981f8b809f5c40c4af4..f4dd7b86d2f2a193958b7a3600491c227a8e4c73 100644 --- a/indra/newview/llfloatersearch.h +++ b/indra/newview/llfloatersearch.h @@ -49,6 +49,7 @@ class LLFloaterSearch final : struct SearchQuery : public LLInitParam::Block<SearchQuery> { Optional<std::string> category; + Optional<std::string> collection; Optional<std::string> query; SearchQuery(); @@ -84,7 +85,8 @@ class LLFloaterSearch final : private: /*virtual*/ BOOL postBuild(); - LLSD mCategoryPaths; + std::set<std::string> mSearchType; + std::set<std::string> mCollectionType; U8 mSearchGodLevel; }; diff --git a/indra/newview/llfloatersellland.cpp b/indra/newview/llfloatersellland.cpp index bae1ff2f9be6d9641f86711261384c03563acc2b..6c08f9969cc275e807f923bf9561d315095cc072 100644 --- a/indra/newview/llfloatersellland.cpp +++ b/indra/newview/llfloatersellland.cpp @@ -446,7 +446,7 @@ static LLNotificationFunctorRegistration tr("TransferObjectsHighlighted", &LLFlo // static bool LLFloaterSellLandUI::callbackHighlightTransferable(const LLSD& notification, const LLSD& data) { - LLSelectMgr::getInstanceFast()->unhighlightAll(); + LLSelectMgr::getInstance()->unhighlightAll(); return false; } diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp index 448e081a1cd26a880ca1490adc7eb8c9671207fe..e486f18148dd66bbfae99b865a8635546e3b4527 100644 --- a/indra/newview/llfloatersnapshot.cpp +++ b/indra/newview/llfloatersnapshot.cpp @@ -221,10 +221,10 @@ void LLFloaterSnapshotBase::ImplBase::updateLayout(LLFloaterSnapshotBase* floate // freeze everything else gSavedSettings.setBOOL("FreezeTime", TRUE); - if (LLToolMgr::getInstanceFast()->getCurrentToolset() != gCameraToolset) + if (LLToolMgr::getInstance()->getCurrentToolset() != gCameraToolset) { - floaterp->impl->mLastToolset = LLToolMgr::getInstanceFast()->getCurrentToolset(); - LLToolMgr::getInstanceFast()->setCurrentToolset(gCameraToolset); + floaterp->impl->mLastToolset = LLToolMgr::getInstance()->getCurrentToolset(); + LLToolMgr::getInstance()->setCurrentToolset(gCameraToolset); } } else // turning off freeze frame mode @@ -247,7 +247,7 @@ void LLFloaterSnapshotBase::ImplBase::updateLayout(LLFloaterSnapshotBase* floate // restore last tool (e.g. pie menu, etc) if (floaterp->impl->mLastToolset) { - LLToolMgr::getInstanceFast()->setCurrentToolset(floaterp->impl->mLastToolset); + LLToolMgr::getInstance()->setCurrentToolset(floaterp->impl->mLastToolset); } } } @@ -948,7 +948,7 @@ LLFloaterSnapshotBase::~LLFloaterSnapshotBase() if (impl->mLastToolset) { - LLToolMgr::getInstanceFast()->setCurrentToolset(impl->mLastToolset); + LLToolMgr::getInstance()->setCurrentToolset(impl->mLastToolset); } delete impl; @@ -1154,7 +1154,7 @@ void LLFloaterSnapshotBase::onClose(bool app_quitting) if (impl->mLastToolset) { - LLToolMgr::getInstanceFast()->setCurrentToolset(impl->mLastToolset); + LLToolMgr::getInstance()->setCurrentToolset(impl->mLastToolset); } } @@ -1441,7 +1441,7 @@ BOOL LLSnapshotFloaterView::handleMouseDown(S32 x, S32 y, MASK mask) // give floater a change to handle mouse, else camera tool if (childrenHandleMouseDown(x, y, mask) == NULL) { - LLToolMgr::getInstanceFast()->getCurrentTool()->handleMouseDown( x, y, mask ); + LLToolMgr::getInstance()->getCurrentTool()->handleMouseDown( x, y, mask ); } return TRUE; } @@ -1457,7 +1457,7 @@ BOOL LLSnapshotFloaterView::handleMouseUp(S32 x, S32 y, MASK mask) // give floater a change to handle mouse, else camera tool if (childrenHandleMouseUp(x, y, mask) == NULL) { - LLToolMgr::getInstanceFast()->getCurrentTool()->handleMouseUp( x, y, mask ); + LLToolMgr::getInstance()->getCurrentTool()->handleMouseUp( x, y, mask ); } return TRUE; } @@ -1473,7 +1473,7 @@ BOOL LLSnapshotFloaterView::handleHover(S32 x, S32 y, MASK mask) // give floater a change to handle mouse, else camera tool if (childrenHandleHover(x, y, mask) == NULL) { - LLToolMgr::getInstanceFast()->getCurrentTool()->handleHover( x, y, mask ); + LLToolMgr::getInstance()->getCurrentTool()->handleHover( x, y, mask ); } return TRUE; } diff --git a/indra/newview/llfloatertelehub.cpp b/indra/newview/llfloatertelehub.cpp index e5e2a6ff84178185918510a4ebcf4e76a181f4e2..05bda7006a92af5db553a2055e901beb967c10ea 100644 --- a/indra/newview/llfloatertelehub.cpp +++ b/indra/newview/llfloatertelehub.cpp @@ -74,12 +74,12 @@ BOOL LLFloaterTelehub::postBuild() void LLFloaterTelehub::onOpen(const LLSD& key) { // Show tools floater by selecting translate (select) tool - LLToolMgr::getInstanceFast()->setCurrentToolset(gBasicToolset); - LLToolMgr::getInstanceFast()->getCurrentToolset()->selectTool( LLToolCompTranslate::getInstance() ); + LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset); + LLToolMgr::getInstance()->getCurrentToolset()->selectTool( LLToolCompTranslate::getInstance() ); sendTelehubInfoRequest(); - mObjectSelection = LLSelectMgr::getInstanceFast()->getEditSelection(); + mObjectSelection = LLSelectMgr::getInstance()->getEditSelection(); } LLFloaterTelehub::~LLFloaterTelehub() @@ -104,7 +104,7 @@ void LLFloaterTelehub::refresh() LLViewerObject* object = mObjectSelection->getFirstRootObject(children_ok); BOOL have_selection = (object != NULL); - BOOL all_volume = LLSelectMgr::getInstanceFast()->selectionAllPCode( LL_PCODE_VOLUME ); + BOOL all_volume = LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME ); getChildView("connect_btn")->setEnabled(have_selection && all_volume); BOOL have_telehub = mTelehubObjectID.notNull(); @@ -163,23 +163,23 @@ void LLFloaterTelehub::addBeacons() void LLFloaterTelehub::sendTelehubInfoRequest() { - LLSelectMgr::getInstanceFast()->sendGodlikeRequest("telehub", "info ui"); + LLSelectMgr::getInstance()->sendGodlikeRequest("telehub", "info ui"); } void LLFloaterTelehub::onClickConnect() { - LLSelectMgr::getInstanceFast()->sendGodlikeRequest("telehub", "connect"); + LLSelectMgr::getInstance()->sendGodlikeRequest("telehub", "connect"); } void LLFloaterTelehub::onClickDisconnect() { - LLSelectMgr::getInstanceFast()->sendGodlikeRequest("telehub", "delete"); + LLSelectMgr::getInstance()->sendGodlikeRequest("telehub", "delete"); } void LLFloaterTelehub::onClickAddSpawnPoint() { - LLSelectMgr::getInstanceFast()->sendGodlikeRequest("telehub", "spawnpoint add"); - LLSelectMgr::getInstanceFast()->deselectAll(); + LLSelectMgr::getInstance()->sendGodlikeRequest("telehub", "spawnpoint add"); + LLSelectMgr::getInstance()->deselectAll(); } void LLFloaterTelehub::onClickRemoveSpawnPoint() diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp index 866502fb23f5318ddda24de310d90f1f22e6b0e0..7bcdc05b039365e70d01feb74ab139b5bd75cc4d 100644 --- a/indra/newview/llfloatertools.cpp +++ b/indra/newview/llfloatertools.cpp @@ -47,7 +47,6 @@ #include "llfloaterreg.h" #include "llfocusmgr.h" #include "llmediaentry.h" -#include "llmediactrl.h" #include "llmenugl.h" #include "llnotificationsutil.h" #include "llpanelcontents.h" @@ -243,7 +242,6 @@ BOOL LLFloaterTools::postBuild() mRadioGroupMove = getChild<LLRadioGroup>("move_radio_group"); mRadioGroupEdit = getChild<LLRadioGroup>("edit_radio_group"); mBtnGridOptions = getChild<LLButton>("Options..."); - mTitleMedia = getChild<LLMediaCtrl>("title_media"); mBtnLink = getChild<LLButton>("link_btn"); mBtnUnlink = getChild<LLButton>("unlink_btn"); mBtnPrevPart = getChild<LLButton>("prev_part_btn"); @@ -337,7 +335,6 @@ LLFloaterTools::LLFloaterTools(const LLSD& key) mCheckSnapToGrid(NULL), mBtnGridOptions(NULL), - mTitleMedia(NULL), mComboGridMode(NULL), mCheckStretchUniform(NULL), mCheckStretchTexture(NULL), @@ -381,8 +378,7 @@ LLFloaterTools::LLFloaterTools(const LLSD& key) mLandImpactsObserver(NULL), mDirty(TRUE), - mHasSelection(TRUE), - mNeedMediaTitle(TRUE) + mHasSelection(TRUE) { gFloaterTools = this; @@ -406,12 +402,9 @@ LLFloaterTools::LLFloaterTools(const LLSD& key) mCommitCallbackRegistrar.add("BuildTool.applyToSelection", boost::bind(&click_apply_to_selection, this)); mCommitCallbackRegistrar.add("BuildTool.commitRadioLand", boost::bind(&commit_radio_group_land,_1)); mCommitCallbackRegistrar.add("BuildTool.LandBrushForce", boost::bind(&commit_slider_dozer_force,_1)); - mCommitCallbackRegistrar.add("BuildTool.AddMedia", boost::bind(&LLFloaterTools::onClickBtnAddMedia,this)); - mCommitCallbackRegistrar.add("BuildTool.DeleteMedia", boost::bind(&LLFloaterTools::onClickBtnDeleteMedia,this)); - mCommitCallbackRegistrar.add("BuildTool.EditMedia", boost::bind(&LLFloaterTools::onClickBtnEditMedia,this)); - mCommitCallbackRegistrar.add("BuildTool.LinkObjects", boost::bind(&LLSelectMgr::linkObjects, LLSelectMgr::getInstanceFast())); - mCommitCallbackRegistrar.add("BuildTool.UnlinkObjects", boost::bind(&LLSelectMgr::unlinkObjects, LLSelectMgr::getInstanceFast())); + mCommitCallbackRegistrar.add("BuildTool.LinkObjects", boost::bind(&LLSelectMgr::linkObjects, LLSelectMgr::getInstance())); + mCommitCallbackRegistrar.add("BuildTool.UnlinkObjects", boost::bind(&LLSelectMgr::unlinkObjects, LLSelectMgr::getInstance())); mCommitCallbackRegistrar.add("BuildTool.TreeGrass", boost::bind(&LLFloaterTools::onSelectTreeGrassCombo, this)); @@ -446,7 +439,7 @@ void LLFloaterTools::refresh() const S32 INFO_WIDTH = getRect().getWidth(); const S32 INFO_HEIGHT = 384; LLRect object_info_rect(0, 0, INFO_WIDTH, -INFO_HEIGHT); - BOOL all_volume = LLSelectMgr::getInstanceFast()->selectionAllPCode( LL_PCODE_VOLUME ); + BOOL all_volume = LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME ); S32 idx_features = mTab->getPanelIndexByTitle(PANEL_NAMES[PANEL_FEATURES]); S32 idx_face = mTab->getPanelIndexByTitle(PANEL_NAMES[PANEL_FACE]); @@ -471,9 +464,9 @@ void LLFloaterTools::refresh() std::string num_string; bool enable_link_count = true; - LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstanceFast()->getSelection(); + LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection(); S32 prim_count = selected_objects->getObjectCount(); - if (prim_count == 1 && LLToolMgr::getInstanceFast()->getCurrentTool() == LLToolFace::getInstanceFast()) + if (prim_count == 1 && LLToolMgr::getInstance()->getCurrentTool() == LLToolFace::getInstance()) { desc_string = getString("selected_faces"); @@ -537,59 +530,90 @@ void LLFloaterTools::refresh() if (!gMeshRepo.meshRezEnabled()) { std::string obj_count_string; - LLResMgr::getIntegerString(obj_count_string, LLSelectMgr::getInstanceFast()->getSelection()->getRootObjectCount()); + LLResMgr::getIntegerString(obj_count_string, LLSelectMgr::getInstance()->getSelection()->getRootObjectCount()); getChild<LLUICtrl>("selection_count")->setTextArg("[OBJ_COUNT]", obj_count_string); std::string prim_count_string; - LLResMgr::getIntegerString(prim_count_string, LLSelectMgr::getInstanceFast()->getSelection()->getObjectCount()); + LLResMgr::getIntegerString(prim_count_string, LLSelectMgr::getInstance()->getSelection()->getObjectCount()); getChild<LLUICtrl>("selection_count")->setTextArg("[PRIM_COUNT]", prim_count_string); // calculate selection rendering cost if (sShowObjectCost) { std::string prim_cost_string; - S32 render_cost = LLSelectMgr::getInstanceFast()->getSelection()->getSelectedObjectRenderCost(); + S32 render_cost = LLSelectMgr::getInstance()->getSelection()->getSelectedObjectRenderCost(); LLResMgr::getIntegerString(prim_cost_string, render_cost); } // disable the object and prim counts if nothing selected - bool have_selection = ! LLSelectMgr::getInstanceFast()->getSelection()->isEmpty(); + bool have_selection = ! LLSelectMgr::getInstance()->getSelection()->isEmpty(); getChildView("link_num_obj_count")->setEnabled(have_selection); } else #endif { - F32 link_cost = selected_objects->getSelectedLinksetCost(); - S32 link_count = selected_objects->getRootObjectCount(); + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); + F32 link_cost = selection->getSelectedLinksetCost(); + S32 link_count = selection->getRootObjectCount(); + S32 object_count = selection->getObjectCount(); - LLCrossParcelFunctor func; - if (selected_objects->applyToRootObjects(&func, true)) - { - // Selection crosses parcel bounds. - // We don't display remaining land capacity in this case. - const LLStringExplicit empty_str(""); - childSetTextArg("remaining_capacity", "[CAPACITY_STRING]", empty_str); - } - else - { - LLViewerObject* selected_object = mObjectSelection->getFirstObject(); - if (selected_object) - { - // Select a parcel at the currently selected object's position. + LLCrossParcelFunctor func; + if (!LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func, true)) + { + // Unless multiple parcels selected, higlight parcel object is at. + LLViewerObject* selected_object = mObjectSelection->getFirstObject(); + if (selected_object) + { + // Select a parcel at the currently selected object's position. if (!selected_object->isAttachment()) { - LLViewerParcelMgr::getInstanceFast()->selectParcelAt(selected_object->getPositionGlobal()); + LLViewerParcelMgr::getInstance()->selectParcelAt(selected_object->getPositionGlobal()); } else { const LLStringExplicit empty_str(""); childSetTextArg("remaining_capacity", "[CAPACITY_STRING]", empty_str); } - } - else - { - LL_WARNS() << "Failed to get selected object" << LL_ENDL; - } - } + } + else + { + LL_WARNS() << "Failed to get selected object" << LL_ENDL; + } + } + + //if (object_count == 1) + //{ + // // "selection_faces" shouldn't be visible if not LLToolFace::getInstance() + // // But still need to be populated in case user switches + + // std::string faces_str = ""; + + // for (LLObjectSelection::iterator iter = selection->begin(); iter != selection->end();) + // { + // LLObjectSelection::iterator nextiter = iter++; // not strictly needed, we have only one object + // LLSelectNode* node = *nextiter; + // LLViewerObject* object = (*nextiter)->getObject(); + // if (!object) + // continue; + // S32 num_tes = llmin((S32)object->getNumTEs(), (S32)object->getNumFaces()); + // for (S32 te = 0; te < num_tes; ++te) + // { + // if (node->isTESelected(te)) + // { + // if (!faces_str.empty()) + // { + // faces_str += ", "; + // } + // faces_str += llformat("%d", te); + // } + // } + // } + + // childSetTextArg("selection_faces", "[FACES_STRING]", faces_str); + //} + + //bool show_faces = (object_count == 1) + // && LLToolFace::getInstance() == LLToolMgr::getInstance()->getCurrentTool(); + //getChildView("selection_faces")->setVisible(show_faces); LLStringUtil::format_map_t selection_args; selection_args["OBJ_COUNT"] = llformat("%.1d", link_count); @@ -611,7 +635,7 @@ void LLFloaterTools::refresh() mPanelObject->refresh(); mPanelVolume->refresh(); mPanelFace->refresh(); - refreshMedia(); + mPanelFace->refreshMedia(); mPanelContents->refresh(); mPanelLandInfo->refresh(); @@ -625,7 +649,7 @@ void LLFloaterTools::refresh() void LLFloaterTools::draw() { - BOOL has_selection = !LLSelectMgr::getInstanceFast()->getSelection()->isEmpty(); + BOOL has_selection = !LLSelectMgr::getInstance()->getSelection()->isEmpty(); if(!has_selection && (mHasSelection != has_selection)) { mDirty = TRUE; @@ -638,9 +662,6 @@ void LLFloaterTools::draw() mDirty = FALSE; } - // grab media name/title and update the UI widget - updateMediaTitle(); - // mCheckSelectIndividual->set(gSavedSettings.getBOOL("EditLinkedParts")); LLFloater::draw(); } @@ -666,7 +687,7 @@ void LLFloaterTools::resetToolState() void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask) { - LLTool *tool = LLToolMgr::getInstanceFast()->getCurrentTool(); + LLTool *tool = LLToolMgr::getInstance()->getCurrentTool(); // HACK to allow seeing the buttons when you have the app in a window. // Keep the visibility the same as it @@ -681,7 +702,7 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask) } // Focus buttons - BOOL focus_visible = ( tool == LLToolCamera::getInstanceFast() ); + BOOL focus_visible = ( tool == LLToolCamera::getInstance() ); mBtnFocus ->setToggleState( focus_visible ); @@ -715,7 +736,7 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask) getChild<LLUICtrl>("slider zoom")->setValue(gAgentCamera.getCameraZoomFraction() * 0.5f); // Move buttons - BOOL move_visible = (tool == LLToolGrab::getInstanceFast()); + BOOL move_visible = (tool == LLToolGrab::getInstance()); if (mBtnMove) mBtnMove ->setToggleState( move_visible ); @@ -740,13 +761,13 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask) } // Edit buttons - BOOL edit_visible = tool == LLToolCompTranslate::getInstanceFast() || - tool == LLToolCompRotate::getInstanceFast() || - tool == LLToolCompScale::getInstanceFast() || - tool == LLToolFace::getInstanceFast() || - tool == LLToolIndividual::getInstanceFast() || - tool == ALToolAlign::getInstanceFast() || - tool == LLToolPipette::getInstanceFast(); + BOOL edit_visible = tool == LLToolCompTranslate::getInstance() || + tool == LLToolCompRotate::getInstance() || + tool == LLToolCompScale::getInstance() || + tool == LLToolFace::getInstance() || + tool == LLToolIndividual::getInstance() || + tool == ALToolAlign::getInstance() || + tool == LLToolPipette::getInstance(); mBtnEdit ->setToggleState( edit_visible ); mRadioGroupEdit->setVisible( edit_visible ); @@ -756,14 +777,14 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask) mBtnLink->setVisible(edit_visible); mBtnUnlink->setVisible(edit_visible); - mBtnLink->setEnabled(LLSelectMgr::instanceFast().enableLinkObjects()); - mBtnUnlink->setEnabled(LLSelectMgr::instanceFast().enableUnlinkObjects()); + mBtnLink->setEnabled(LLSelectMgr::instance().enableLinkObjects()); + mBtnUnlink->setEnabled(LLSelectMgr::instance().enableUnlinkObjects()); mBtnPrevPart->setVisible(edit_visible); mBtnNextPart->setVisible(edit_visible); - bool select_btn_enabled = (!LLSelectMgr::getInstanceFast()->getSelection()->isEmpty() - && (ALControlCache::EditLinkedParts || LLToolFace::getInstanceFast() == LLToolMgr::getInstanceFast()->getCurrentTool())); + bool select_btn_enabled = (!LLSelectMgr::getInstance()->getSelection()->isEmpty() + && (ALControlCache::EditLinkedParts || LLToolFace::getInstance() == LLToolMgr::getInstance()->getCurrentTool())); mBtnPrevPart->setEnabled(select_btn_enabled); mBtnNextPart->setEnabled(select_btn_enabled); @@ -773,23 +794,23 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask) //mCheckSelectIndividual->set(gSavedSettings.getBOOL("EditLinkedParts")); } - if ( tool == LLToolCompTranslate::getInstanceFast() ) + if ( tool == LLToolCompTranslate::getInstance() ) { mRadioGroupEdit->setValue("radio position"); } - else if ( tool == LLToolCompRotate::getInstanceFast() ) + else if ( tool == LLToolCompRotate::getInstance() ) { mRadioGroupEdit->setValue("radio rotate"); } - else if ( tool == LLToolCompScale::getInstanceFast() ) + else if ( tool == LLToolCompScale::getInstance() ) { mRadioGroupEdit->setValue("radio stretch"); } - else if ( tool == LLToolFace::getInstanceFast() ) + else if ( tool == LLToolFace::getInstance() ) { mRadioGroupEdit->setValue("radio select face"); } - else if ( tool == ALToolAlign::getInstanceFast() ) + else if ( tool == ALToolAlign::getInstance() ) { mRadioGroupEdit->setValue("radio align"); } @@ -821,8 +842,8 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask) } // Snap to grid disabled for grab tool - very confusing - if (mCheckSnapToGrid) mCheckSnapToGrid->setVisible( edit_visible /* || tool == LLToolGrab::getInstanceFast() */ ); - if (mBtnGridOptions) mBtnGridOptions->setVisible( edit_visible /* || tool == LLToolGrab::getInstanceFast() */ ); + if (mCheckSnapToGrid) mCheckSnapToGrid->setVisible( edit_visible /* || tool == LLToolGrab::getInstance() */ ); + if (mBtnGridOptions) mBtnGridOptions->setVisible( edit_visible /* || tool == LLToolGrab::getInstance() */ ); //mCheckSelectLinked ->setVisible( edit_visible ); if (mCheckStretchUniform) mCheckStretchUniform->setVisible( edit_visible ); @@ -831,13 +852,13 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask) if (mCheckActualRoot) mCheckActualRoot->setVisible( edit_visible ); // Create buttons - BOOL create_visible = (tool == LLToolCompCreate::getInstanceFast()); + BOOL create_visible = (tool == LLToolCompCreate::getInstance()); // Tree/grass picker mTreeGrassCombo->setVisible(create_visible); if (create_visible) buildTreeGrassCombo(); - mBtnCreate ->setToggleState( tool == LLToolCompCreate::getInstanceFast() ); + mBtnCreate ->setToggleState( tool == LLToolCompCreate::getInstance() ); if (mCheckCopySelection && mCheckCopySelection->get()) @@ -871,18 +892,18 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask) if (mCheckCopyRotates && mCheckCopySelection) mCheckCopyRotates->setEnabled( mCheckCopySelection->get() ); // Land buttons - BOOL land_visible = (tool == LLToolBrushLand::getInstanceFast() || tool == LLToolSelectLand::getInstanceFast() ); + BOOL land_visible = (tool == LLToolBrushLand::getInstance() || tool == LLToolSelectLand::getInstance() ); mCostTextBorder->setVisible(!land_visible); if (mBtnLand) mBtnLand ->setToggleState( land_visible ); mRadioGroupLand->setVisible( land_visible ); - if ( tool == LLToolSelectLand::getInstanceFast() ) + if ( tool == LLToolSelectLand::getInstance() ) { mRadioGroupLand->setValue("radio select land"); } - else if ( tool == LLToolBrushLand::getInstanceFast() ) + else if ( tool == LLToolBrushLand::getInstance() ) { S32 dozer_mode = gSavedSettings.getS32("RadioLandBrushAction"); switch(dozer_mode) @@ -913,7 +934,7 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask) if (mBtnApplyToSelection) { mBtnApplyToSelection->setVisible( land_visible ); - mBtnApplyToSelection->setEnabled( land_visible && !LLViewerParcelMgr::getInstanceFast()->selectionEmpty() && tool != LLToolSelectLand::getInstanceFast()); + mBtnApplyToSelection->setEnabled( land_visible && !LLViewerParcelMgr::getInstance()->selectionEmpty() && tool != LLToolSelectLand::getInstance()); } if (mSliderDozerSize) { @@ -927,10 +948,12 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask) getChildView("Strength:")->setVisible( land_visible); } - bool have_selection = !LLSelectMgr::getInstanceFast()->getSelection()->isEmpty(); + bool have_selection = !LLSelectMgr::getInstance()->getSelection()->isEmpty(); getChildView("selection_count")->setVisible(!land_visible && have_selection); getChildView("remaining_capacity")->setVisible(!land_visible && have_selection); + //getChildView("selection_faces")->setVisible(LLToolFace::getInstance() == LLToolMgr::getInstance()->getCurrentTool() + // && LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1); getChildView("selection_empty")->setVisible(!land_visible && !have_selection); mTab->setVisible(!land_visible); @@ -948,8 +971,8 @@ BOOL LLFloaterTools::canClose() // virtual void LLFloaterTools::onOpen(const LLSD& key) { - mParcelSelection = LLViewerParcelMgr::getInstanceFast()->getFloatingParcelSelection(); - mObjectSelection = LLSelectMgr::getInstanceFast()->getEditSelection(); + mParcelSelection = LLViewerParcelMgr::getInstance()->getFloatingParcelSelection(); + mObjectSelection = LLSelectMgr::getInstance()->getEditSelection(); std::string panel = key.asString(); if (!panel.empty()) @@ -957,9 +980,9 @@ void LLFloaterTools::onOpen(const LLSD& key) mTab->selectTabByName(panel); } - LLTool* tool = LLToolMgr::getInstanceFast()->getCurrentTool(); - if (tool == LLToolCompInspect::getInstanceFast() - || tool == LLToolDragAndDrop::getInstanceFast()) + LLTool* tool = LLToolMgr::getInstance()->getCurrentTool(); + if (tool == LLToolCompInspect::getInstance() + || tool == LLToolDragAndDrop::getInstance()) { // Something called floater up while it was supressed (during drag n drop, inspect), // so it won't be getting any layout or visibility updates, update once @@ -977,18 +1000,17 @@ void LLFloaterTools::onClose(bool app_quitting) { mTab->setVisible(FALSE); - LLViewerJoystick::getInstanceFast()->moveAvatar(false); + LLViewerJoystick::getInstance()->moveAvatar(false); // destroy media source used to grab media title - if( mTitleMedia ) - mTitleMedia->unloadMediaSource(); + mPanelFace->unloadMedia(); // Different from handle_reset_view in that it doesn't actually // move the camera if EditCameraMovement is not set. gAgentCamera.resetView(gSavedSettings.getBOOL("EditCameraMovement")); // exit component selection mode - LLSelectMgr::getInstanceFast()->promoteSelectionToRoot(); + LLSelectMgr::getInstance()->promoteSelectionToRoot(); gSavedSettings.setBOOL("EditLinkedParts", FALSE); gViewerWindow->showCursor(); @@ -999,10 +1021,10 @@ void LLFloaterTools::onClose(bool app_quitting) mObjectSelection = NULL; // Switch back to basic toolset - LLToolMgr::getInstanceFast()->setCurrentToolset(gBasicToolset); + LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset); // we were already in basic toolset, using build tools // so manually reset tool to default (pie menu tool) - LLToolMgr::getInstanceFast()->getCurrentToolset()->selectFirstTool(); + LLToolMgr::getInstance()->getCurrentToolset()->selectFirstTool(); //gMenuBarView->setItemVisible("BuildTools", FALSE); LLFloaterReg::hideInstance("media_settings"); @@ -1090,7 +1112,7 @@ void commit_slider_dozer_force(LLUICtrl *ctrl) void click_apply_to_selection(void*) { - LLToolBrushLand::getInstanceFast()->modifyLandInSelectionGlobal(); + LLToolBrushLand::getInstance()->modifyLandInSelectionGlobal(); } void commit_radio_group_edit(LLUICtrl *ctrl) @@ -1101,23 +1123,23 @@ void commit_radio_group_edit(LLUICtrl *ctrl) std::string selected = group->getValue().asString(); if (selected == "radio position") { - LLFloaterTools::setEditTool( LLToolCompTranslate::getInstanceFast() ); + LLFloaterTools::setEditTool( LLToolCompTranslate::getInstance() ); } else if (selected == "radio rotate") { - LLFloaterTools::setEditTool( LLToolCompRotate::getInstanceFast() ); + LLFloaterTools::setEditTool( LLToolCompRotate::getInstance() ); } else if (selected == "radio stretch") { - LLFloaterTools::setEditTool( LLToolCompScale::getInstanceFast() ); + LLFloaterTools::setEditTool( LLToolCompScale::getInstance() ); } else if (selected == "radio select face") { - LLFloaterTools::setEditTool( LLToolFace::getInstanceFast() ); + LLFloaterTools::setEditTool( LLToolFace::getInstance() ); } else if (selected == "radio align") { - LLFloaterTools::setEditTool( ALToolAlign::getInstanceFast() ); + LLFloaterTools::setEditTool( ALToolAlign::getInstance() ); } gSavedSettings.setBOOL("ShowParcelOwners", show_owners); } @@ -1128,11 +1150,11 @@ void commit_radio_group_land(LLUICtrl* ctrl) std::string selected = group->getValue().asString(); if (selected == "radio select land") { - LLFloaterTools::setEditTool( LLToolSelectLand::getInstanceFast() ); + LLFloaterTools::setEditTool( LLToolSelectLand::getInstance() ); } else { - LLFloaterTools::setEditTool( LLToolBrushLand::getInstanceFast() ); + LLFloaterTools::setEditTool( LLToolBrushLand::getInstance() ); S32 dozer_mode = gSavedSettings.getS32("RadioLandBrushAction"); if (selected == "radio flatten") dozer_mode = 0; @@ -1166,11 +1188,11 @@ void commit_select_component(void *data) if (select_individuals) { - LLSelectMgr::getInstanceFast()->demoteSelectionToIndividuals(); + LLSelectMgr::getInstance()->demoteSelectionToIndividuals(); } else { - LLSelectMgr::getInstanceFast()->promoteSelectionToRoot(); + LLSelectMgr::getInstance()->promoteSelectionToRoot(); } } @@ -1187,7 +1209,7 @@ void commit_grid_mode(LLUICtrl *ctrl) { LLComboBox* combo = (LLComboBox*)ctrl; - LLSelectMgr::getInstanceFast()->setGridMode((EGridMode)combo->getCurrentIndex()); + LLSelectMgr::getInstance()->setGridMode((EGridMode)combo->getCurrentIndex()); } // static @@ -1206,84 +1228,39 @@ void LLFloaterTools::onClickGridOptions() { LLFloater* floaterp = LLFloaterReg::showInstance("build_options"); // position floater next to build tools, not over - floaterp->setRect(gFloaterView->findNeighboringPosition(this, floaterp)); + floaterp->setShape(gFloaterView->findNeighboringPosition(this, floaterp), true); } // static void LLFloaterTools::setEditTool(void* tool_pointer) { LLTool *tool = (LLTool *)tool_pointer; - LLToolMgr::getInstanceFast()->getCurrentToolset()->selectTool( tool ); + LLToolMgr::getInstance()->getCurrentToolset()->selectTool( tool ); } void LLFloaterTools::setTool(const LLSD& user_data) { std::string control_name = user_data.asString(); if(control_name == "Focus") - LLToolMgr::getInstanceFast()->getCurrentToolset()->selectTool((LLTool *) LLToolCamera::getInstanceFast() ); + LLToolMgr::getInstance()->getCurrentToolset()->selectTool((LLTool *) LLToolCamera::getInstance() ); else if (control_name == "Move" ) - LLToolMgr::getInstanceFast()->getCurrentToolset()->selectTool( (LLTool *)LLToolGrab::getInstanceFast() ); + LLToolMgr::getInstance()->getCurrentToolset()->selectTool( (LLTool *)LLToolGrab::getInstance() ); else if (control_name == "Edit" ) - LLToolMgr::getInstanceFast()->getCurrentToolset()->selectTool( (LLTool *) LLToolCompTranslate::getInstanceFast()); + LLToolMgr::getInstance()->getCurrentToolset()->selectTool( (LLTool *) LLToolCompTranslate::getInstance()); else if (control_name == "Create" ) - LLToolMgr::getInstanceFast()->getCurrentToolset()->selectTool( (LLTool *) LLToolCompCreate::getInstanceFast()); + LLToolMgr::getInstance()->getCurrentToolset()->selectTool( (LLTool *) LLToolCompCreate::getInstance()); else if (control_name == "Land" ) - LLToolMgr::getInstanceFast()->getCurrentToolset()->selectTool( (LLTool *) LLToolSelectLand::getInstanceFast()); + LLToolMgr::getInstance()->getCurrentToolset()->selectTool( (LLTool *) LLToolSelectLand::getInstance()); else LL_WARNS()<<" no parameter name "<<control_name<<" found!! No Tool selected!!"<< LL_ENDL; } void LLFloaterTools::onFocusReceived() { - LLToolMgr::getInstanceFast()->setCurrentToolset(gBasicToolset); + LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset); LLFloater::onFocusReceived(); } -// Media stuff -void LLFloaterTools::refreshMedia() -{ - getMediaState(); -} - -bool LLFloaterTools::selectedMediaEditable() -{ - U32 owner_mask_on; - U32 owner_mask_off; - U32 valid_owner_perms = LLSelectMgr::getInstanceFast()->selectGetPerm( PERM_OWNER, - &owner_mask_on, &owner_mask_off ); - U32 group_mask_on; - U32 group_mask_off; - U32 valid_group_perms = LLSelectMgr::getInstanceFast()->selectGetPerm( PERM_GROUP, - &group_mask_on, &group_mask_off ); - U32 everyone_mask_on; - U32 everyone_mask_off; - S32 valid_everyone_perms = LLSelectMgr::getInstanceFast()->selectGetPerm( PERM_EVERYONE, - &everyone_mask_on, &everyone_mask_off ); - - bool selected_Media_editable = false; - - // if perms we got back are valid - if ( valid_owner_perms && - valid_group_perms && - valid_everyone_perms ) - { - - if ( ( owner_mask_on & PERM_MODIFY ) || - ( group_mask_on & PERM_MODIFY ) || - (everyone_mask_on & PERM_MODIFY ) ) - { - selected_Media_editable = true; - } - else - // user is NOT allowed to press the RESET button - { - selected_Media_editable = false; - }; - }; - - return selected_Media_editable; -} - void LLFloaterTools::updateLandImpacts() { LLParcel *parcel = mParcelSelection->getParcel(); @@ -1294,7 +1271,7 @@ void LLFloaterTools::updateLandImpacts() S32 rezzed_prims = parcel->getSimWidePrimCount(); S32 total_capacity = parcel->getSimWideMaxPrimCapacity(); - LLViewerRegion* region = LLViewerParcelMgr::getInstanceFast()->getSelectionRegion(); + LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion(); if (region) { S32 max_tasks_per_region = (S32)region->getMaxTasks(); @@ -1320,787 +1297,6 @@ void LLFloaterTools::updateLandImpacts() } } -void LLFloaterTools::getMediaState() -{ - LLObjectSelectionHandle selected_objects =LLSelectMgr::getInstanceFast()->getSelection(); - LLViewerObject* first_object = selected_objects->getFirstObject(); - LLTextBox* media_info = getChild<LLTextBox>("media_info"); - - if( !(first_object - && first_object->getPCode() == LL_PCODE_VOLUME - &&first_object->permModify() - )) - { - getChildView("add_media")->setEnabled(FALSE); - media_info->clear(); - clearMediaSettings(); - return; - } - - std::string url = first_object->getRegion()->getCapability("ObjectMedia"); - bool has_media_capability = (!url.empty()); - - if(!has_media_capability) - { - getChildView("add_media")->setEnabled(FALSE); - LL_WARNS("LLFloaterToolsMedia") << "Media not enabled (no capability) in this region!" << LL_ENDL; - clearMediaSettings(); - return; - } - - BOOL is_nonpermanent_enforced = (LLSelectMgr::getInstanceFast()->getSelection()->getFirstRootNode() - && LLSelectMgr::getInstanceFast()->selectGetRootsNonPermanentEnforced()) - || LLSelectMgr::getInstanceFast()->selectGetNonPermanentEnforced(); - bool editable = is_nonpermanent_enforced && (first_object->permModify() || selectedMediaEditable()); - - // Check modify permissions and whether any selected objects are in - // the process of being fetched. If they are, then we're not editable - if (editable) - { - LLObjectSelection::iterator iter = selected_objects->begin(); - LLObjectSelection::iterator end = selected_objects->end(); - for ( ; iter != end; ++iter) - { - LLSelectNode* node = *iter; - LLVOVolume* object = node ? node->getObject()->asVolume() : nullptr; - if (nullptr != object) - { - if (!object->permModify()) - { - LL_INFOS("LLFloaterToolsMedia") - << "Selection not editable due to lack of modify permissions on object id " - << object->getID() << LL_ENDL; - - editable = false; - break; - } - // XXX DISABLE this for now, because when the fetch finally - // does come in, the state of this floater doesn't properly - // update. Re-selecting fixes the problem, but there is - // contention as to whether this is a sufficient solution. -// if (object->isMediaDataBeingFetched()) -// { -// LL_INFOS("LLFloaterToolsMedia") -// << "Selection not editable due to media data being fetched for object id " -// << object->getID() << LL_ENDL; -// -// editable = false; -// break; -// } - } - } - } - - // Media settings - bool bool_has_media = false; - struct media_functor : public LLSelectedTEGetFunctor<bool> - { - bool get(LLViewerObject* object, S32 face) - { - LLTextureEntry *te = object->getTE(face); - if (te) - { - return te->hasMedia(); - } - return false; - } - } func; - - - // check if all faces have media(or, all dont have media) - LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo = selected_objects->getSelectedTEValue( &func, bool_has_media ); - - const LLMediaEntry default_media_data; - - struct functor_getter_media_data : public LLSelectedTEGetFunctor< LLMediaEntry> - { - functor_getter_media_data(const LLMediaEntry& entry): mMediaEntry(entry) {} - - LLMediaEntry get( LLViewerObject* object, S32 face ) - { - if ( object ) - if ( object->getTE(face) ) - if ( object->getTE(face)->getMediaData() ) - return *(object->getTE(face)->getMediaData()); - return mMediaEntry; - }; - - const LLMediaEntry& mMediaEntry; - - } func_media_data(default_media_data); - - LLMediaEntry media_data_get; - LLFloaterMediaSettings::getInstance()->mMultipleMedia = !(selected_objects->getSelectedTEValue( &func_media_data, media_data_get )); - - std::string multi_media_info_str = LLTrans::getString("Multiple Media"); - std::string media_title = ""; - // update UI depending on whether "object" (prim or face) has media - // and whether or not you are allowed to edit it. - - getChildView("add_media")->setEnabled(editable); - // IF all the faces have media (or all dont have media) - if ( LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo ) - { - // TODO: get media title and set it. - media_info->clear(); - // if identical is set, all faces are same (whether all empty or has the same media) - if(!(LLFloaterMediaSettings::getInstance()->mMultipleMedia) ) - { - // Media data is valid - if(media_data_get!=default_media_data) - { - // initial media title is the media URL (until we get the name) - media_title = media_data_get.getHomeURL(); - } - // else all faces might be empty. - } - else // there' re Different Medias' been set on on the faces. - { - media_title = multi_media_info_str; - } - - getChildView("delete_media")->setEnabled(bool_has_media && editable ); - // TODO: display a list of all media on the face - use 'identical' flag - } - else // not all face has media but at least one does. - { - // seleted faces have not identical value - LLFloaterMediaSettings::getInstance()->mMultipleValidMedia = selected_objects->isMultipleTEValue(&func_media_data, default_media_data ); - - if(LLFloaterMediaSettings::getInstance()->mMultipleValidMedia) - { - media_title = multi_media_info_str; - } - else - { - // Media data is valid - if(media_data_get!=default_media_data) - { - // initial media title is the media URL (until we get the name) - media_title = media_data_get.getHomeURL(); - } - } - - getChildView("delete_media")->setEnabled(TRUE); - } - - navigateToTitleMedia(media_title); - media_info->setText(media_title); - - // load values for media settings - updateMediaSettings(); - - LLFloaterMediaSettings::initValues(mMediaSettings, editable ); -} - - -////////////////////////////////////////////////////////////////////////////// -// called when a user wants to add media to a prim or prim face -void LLFloaterTools::onClickBtnAddMedia() -{ - // check if multiple faces are selected - if(LLSelectMgr::getInstanceFast()->getSelection()->isMultipleTESelected()) - { - LLNotificationsUtil::add("MultipleFacesSelected", LLSD(), LLSD(), multipleFacesSelectedConfirm); - } - else - { - onClickBtnEditMedia(); - } -} - -// static -bool LLFloaterTools::multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - switch( option ) - { - case 0: // "Yes" - gFloaterTools->onClickBtnEditMedia(); - break; - case 1: // "No" - default: - break; - } - return false; -} - -////////////////////////////////////////////////////////////////////////////// -// called when a user wants to edit existing media settings on a prim or prim face -// TODO: test if there is media on the item and only allow editing if present -void LLFloaterTools::onClickBtnEditMedia() -{ - refreshMedia(); - LLFloaterReg::showInstance("media_settings"); -} - -////////////////////////////////////////////////////////////////////////////// -// called when a user wants to delete media from a prim or prim face -void LLFloaterTools::onClickBtnDeleteMedia() -{ - LLNotificationsUtil::add("DeleteMedia", LLSD(), LLSD(), deleteMediaConfirm); -} - - -// static -bool LLFloaterTools::deleteMediaConfirm(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - switch( option ) - { - case 0: // "Yes" - LLSelectMgr::getInstanceFast()->selectionSetMedia( 0, LLSD() ); - if(LLFloaterReg::instanceVisible("media_settings")) - { - LLFloaterReg::hideInstance("media_settings"); - } - break; - - case 1: // "No" - default: - break; - } - return false; -} - -////////////////////////////////////////////////////////////////////////////// -// -void LLFloaterTools::clearMediaSettings() -{ - LLFloaterMediaSettings::clearValues(false); -} - -////////////////////////////////////////////////////////////////////////////// -// -void LLFloaterTools::navigateToTitleMedia( const std::string url ) -{ - std::string multi_media_info_str = LLTrans::getString("Multiple Media"); - if (url.empty() || multi_media_info_str == url) - { - // nothing to show - mNeedMediaTitle = false; - } - else if (mTitleMedia) - { - LLPluginClassMedia* media_plugin = mTitleMedia->getMediaPlugin(); - - if ( media_plugin ) // Shouldn't this be after navigateTo creates plugin? - { - // if it's a movie, we don't want to hear it - media_plugin->setVolume( 0 ); - }; - - // check if url changed or if we need a new media source - if (mTitleMedia->getCurrentNavUrl() != url || media_plugin == NULL) - { - mTitleMedia->navigateTo( url ); - } - - // flag that we need to update the title (even if no request were made) - mNeedMediaTitle = true; - } -} - -////////////////////////////////////////////////////////////////////////////// -// -void LLFloaterTools::updateMediaTitle() -{ - // only get the media name if we need it - if ( ! mNeedMediaTitle ) - return; - - // get plugin impl - LLPluginClassMedia* media_plugin = mTitleMedia->getMediaPlugin(); - if ( media_plugin ) - { - // get the media name (asynchronous - must call repeatedly) - std::string media_title = media_plugin->getMediaName(); - - // only replace the title if what we get contains something - if ( ! media_title.empty() ) - { - // update the UI widget - LLTextBox* media_title_field = getChild<LLTextBox>("media_info"); - if ( media_title_field ) - { - media_title_field->setText( media_title ); - - // stop looking for a title when we get one - // FIXME: check this is the right approach - mNeedMediaTitle = false; - }; - }; - }; -} - -////////////////////////////////////////////////////////////////////////////// -// -void LLFloaterTools::updateMediaSettings() -{ - bool identical( false ); - std::string base_key( "" ); - std::string value_str( "" ); - int value_int = 0; - bool value_bool = false; - LLObjectSelectionHandle selected_objects =LLSelectMgr::getInstanceFast()->getSelection(); - // TODO: (CP) refactor this using something clever or boost or both !! - - const LLMediaEntry default_media_data; - - // controls - U8 value_u8 = default_media_data.getControls(); - struct functor_getter_controls : public LLSelectedTEGetFunctor< U8 > - { - functor_getter_controls(const LLMediaEntry &entry) : mMediaEntry(entry) {} - - U8 get( LLViewerObject* object, S32 face ) - { - if ( object ) - if ( object->getTE(face) ) - if ( object->getTE(face)->getMediaData() ) - return object->getTE(face)->getMediaData()->getControls(); - return mMediaEntry.getControls(); - }; - - const LLMediaEntry &mMediaEntry; - - } func_controls(default_media_data); - identical = selected_objects->getSelectedTEValue( &func_controls, value_u8 ); - base_key = std::string( LLMediaEntry::CONTROLS_KEY ); - mMediaSettings[ base_key ] = value_u8; - mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; - - // First click (formerly left click) - value_bool = default_media_data.getFirstClickInteract(); - struct functor_getter_first_click : public LLSelectedTEGetFunctor< bool > - { - functor_getter_first_click(const LLMediaEntry& entry): mMediaEntry(entry) {} - - bool get( LLViewerObject* object, S32 face ) - { - if ( object ) - if ( object->getTE(face) ) - if ( object->getTE(face)->getMediaData() ) - return object->getTE(face)->getMediaData()->getFirstClickInteract(); - return mMediaEntry.getFirstClickInteract(); - }; - - const LLMediaEntry &mMediaEntry; - - } func_first_click(default_media_data); - identical = selected_objects->getSelectedTEValue( &func_first_click, value_bool ); - base_key = std::string( LLMediaEntry::FIRST_CLICK_INTERACT_KEY ); - mMediaSettings[ base_key ] = value_bool; - mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; - - // Home URL - value_str = default_media_data.getHomeURL(); - struct functor_getter_home_url : public LLSelectedTEGetFunctor< std::string > - { - functor_getter_home_url(const LLMediaEntry& entry): mMediaEntry(entry) {} - - std::string get( LLViewerObject* object, S32 face ) - { - if ( object ) - if ( object->getTE(face) ) - if ( object->getTE(face)->getMediaData() ) - return object->getTE(face)->getMediaData()->getHomeURL(); - return mMediaEntry.getHomeURL(); - }; - - const LLMediaEntry &mMediaEntry; - - } func_home_url(default_media_data); - identical = selected_objects->getSelectedTEValue( &func_home_url, value_str ); - base_key = std::string( LLMediaEntry::HOME_URL_KEY ); - mMediaSettings[ base_key ] = value_str; - mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; - - // Current URL - value_str = default_media_data.getCurrentURL(); - struct functor_getter_current_url : public LLSelectedTEGetFunctor< std::string > - { - functor_getter_current_url(const LLMediaEntry& entry): mMediaEntry(entry) {} - - std::string get( LLViewerObject* object, S32 face ) - { - if ( object ) - if ( object->getTE(face) ) - if ( object->getTE(face)->getMediaData() ) - return object->getTE(face)->getMediaData()->getCurrentURL(); - return mMediaEntry.getCurrentURL(); - }; - - const LLMediaEntry &mMediaEntry; - - } func_current_url(default_media_data); - identical = selected_objects->getSelectedTEValue( &func_current_url, value_str ); - base_key = std::string( LLMediaEntry::CURRENT_URL_KEY ); - mMediaSettings[ base_key ] = value_str; - mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; - - // Auto zoom - value_bool = default_media_data.getAutoZoom(); - struct functor_getter_auto_zoom : public LLSelectedTEGetFunctor< bool > - { - - functor_getter_auto_zoom(const LLMediaEntry& entry) : mMediaEntry(entry) {} - - bool get( LLViewerObject* object, S32 face ) - { - if ( object ) - if ( object->getTE(face) ) - if ( object->getTE(face)->getMediaData() ) - return object->getTE(face)->getMediaData()->getAutoZoom(); - return mMediaEntry.getAutoZoom(); - }; - - const LLMediaEntry &mMediaEntry; - - } func_auto_zoom(default_media_data); - identical = selected_objects->getSelectedTEValue( &func_auto_zoom, value_bool ); - base_key = std::string( LLMediaEntry::AUTO_ZOOM_KEY ); - mMediaSettings[ base_key ] = value_bool; - mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; - - // Auto play - //value_bool = default_media_data.getAutoPlay(); - // set default to auto play TRUE -- angela EXT-5172 - value_bool = true; - struct functor_getter_auto_play : public LLSelectedTEGetFunctor< bool > - { - functor_getter_auto_play(const LLMediaEntry& entry) : mMediaEntry(entry) {} - - bool get( LLViewerObject* object, S32 face ) - { - if ( object ) - if ( object->getTE(face) ) - if ( object->getTE(face)->getMediaData() ) - return object->getTE(face)->getMediaData()->getAutoPlay(); - //return mMediaEntry.getAutoPlay(); set default to auto play TRUE -- angela EXT-5172 - return true; - }; - - const LLMediaEntry &mMediaEntry; - - } func_auto_play(default_media_data); - identical = selected_objects->getSelectedTEValue( &func_auto_play, value_bool ); - base_key = std::string( LLMediaEntry::AUTO_PLAY_KEY ); - mMediaSettings[ base_key ] = value_bool; - mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; - - - // Auto scale - // set default to auto scale TRUE -- angela EXT-5172 - //value_bool = default_media_data.getAutoScale(); - value_bool = true; - struct functor_getter_auto_scale : public LLSelectedTEGetFunctor< bool > - { - functor_getter_auto_scale(const LLMediaEntry& entry): mMediaEntry(entry) {} - - bool get( LLViewerObject* object, S32 face ) - { - if ( object ) - if ( object->getTE(face) ) - if ( object->getTE(face)->getMediaData() ) - return object->getTE(face)->getMediaData()->getAutoScale(); - // return mMediaEntry.getAutoScale(); set default to auto scale TRUE -- angela EXT-5172 - return true; - }; - - const LLMediaEntry &mMediaEntry; - - } func_auto_scale(default_media_data); - identical = selected_objects->getSelectedTEValue( &func_auto_scale, value_bool ); - base_key = std::string( LLMediaEntry::AUTO_SCALE_KEY ); - mMediaSettings[ base_key ] = value_bool; - mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; - - // Auto loop - value_bool = default_media_data.getAutoLoop(); - struct functor_getter_auto_loop : public LLSelectedTEGetFunctor< bool > - { - functor_getter_auto_loop(const LLMediaEntry& entry) : mMediaEntry(entry) {} - - bool get( LLViewerObject* object, S32 face ) - { - if ( object ) - if ( object->getTE(face) ) - if ( object->getTE(face)->getMediaData() ) - return object->getTE(face)->getMediaData()->getAutoLoop(); - return mMediaEntry.getAutoLoop(); - }; - - const LLMediaEntry &mMediaEntry; - - } func_auto_loop(default_media_data); - identical = selected_objects->getSelectedTEValue( &func_auto_loop, value_bool ); - base_key = std::string( LLMediaEntry::AUTO_LOOP_KEY ); - mMediaSettings[ base_key ] = value_bool; - mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; - - // width pixels (if not auto scaled) - value_int = default_media_data.getWidthPixels(); - struct functor_getter_width_pixels : public LLSelectedTEGetFunctor< int > - { - functor_getter_width_pixels(const LLMediaEntry& entry): mMediaEntry(entry) {} - - int get( LLViewerObject* object, S32 face ) - { - if ( object ) - if ( object->getTE(face) ) - if ( object->getTE(face)->getMediaData() ) - return object->getTE(face)->getMediaData()->getWidthPixels(); - return mMediaEntry.getWidthPixels(); - }; - - const LLMediaEntry &mMediaEntry; - - } func_width_pixels(default_media_data); - identical = selected_objects->getSelectedTEValue( &func_width_pixels, value_int ); - base_key = std::string( LLMediaEntry::WIDTH_PIXELS_KEY ); - mMediaSettings[ base_key ] = value_int; - mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; - - // height pixels (if not auto scaled) - value_int = default_media_data.getHeightPixels(); - struct functor_getter_height_pixels : public LLSelectedTEGetFunctor< int > - { - functor_getter_height_pixels(const LLMediaEntry& entry) : mMediaEntry(entry) {} - - int get( LLViewerObject* object, S32 face ) - { - if ( object ) - if ( object->getTE(face) ) - if ( object->getTE(face)->getMediaData() ) - return object->getTE(face)->getMediaData()->getHeightPixels(); - return mMediaEntry.getHeightPixels(); - }; - - const LLMediaEntry &mMediaEntry; - - } func_height_pixels(default_media_data); - identical = selected_objects->getSelectedTEValue( &func_height_pixels, value_int ); - base_key = std::string( LLMediaEntry::HEIGHT_PIXELS_KEY ); - mMediaSettings[ base_key ] = value_int; - mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; - - // Enable Alt image - value_bool = default_media_data.getAltImageEnable(); - struct functor_getter_enable_alt_image : public LLSelectedTEGetFunctor< bool > - { - functor_getter_enable_alt_image(const LLMediaEntry& entry): mMediaEntry(entry) {} - - bool get( LLViewerObject* object, S32 face ) - { - if ( object ) - if ( object->getTE(face) ) - if ( object->getTE(face)->getMediaData() ) - return object->getTE(face)->getMediaData()->getAltImageEnable(); - return mMediaEntry.getAltImageEnable(); - }; - - const LLMediaEntry &mMediaEntry; - - } func_enable_alt_image(default_media_data); - identical = selected_objects->getSelectedTEValue( &func_enable_alt_image, value_bool ); - base_key = std::string( LLMediaEntry::ALT_IMAGE_ENABLE_KEY ); - mMediaSettings[ base_key ] = value_bool; - mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; - - // Perms - owner interact - value_bool = 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_OWNER ); - struct functor_getter_perms_owner_interact : public LLSelectedTEGetFunctor< bool > - { - functor_getter_perms_owner_interact(const LLMediaEntry& entry): mMediaEntry(entry) {} - - bool get( LLViewerObject* object, S32 face ) - { - if ( object ) - if ( object->getTE(face) ) - if ( object->getTE(face)->getMediaData() ) - return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_OWNER)); - return 0 != ( mMediaEntry.getPermsInteract() & LLMediaEntry::PERM_OWNER ); - }; - - const LLMediaEntry &mMediaEntry; - - } func_perms_owner_interact(default_media_data); - identical = selected_objects->getSelectedTEValue( &func_perms_owner_interact, value_bool ); - base_key = std::string( LLPanelContents::PERMS_OWNER_INTERACT_KEY ); - mMediaSettings[ base_key ] = value_bool; - mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; - - // Perms - owner control - value_bool = 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_OWNER ); - struct functor_getter_perms_owner_control : public LLSelectedTEGetFunctor< bool > - { - functor_getter_perms_owner_control(const LLMediaEntry& entry) : mMediaEntry(entry) {} - - bool get( LLViewerObject* object, S32 face ) - { - if ( object ) - if ( object->getTE(face) ) - if ( object->getTE(face)->getMediaData() ) - return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_OWNER)); - return 0 != ( mMediaEntry.getPermsControl() & LLMediaEntry::PERM_OWNER ); - }; - - const LLMediaEntry &mMediaEntry; - - } func_perms_owner_control(default_media_data); - identical = selected_objects ->getSelectedTEValue( &func_perms_owner_control, value_bool ); - base_key = std::string( LLPanelContents::PERMS_OWNER_CONTROL_KEY ); - mMediaSettings[ base_key ] = value_bool; - mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; - - // Perms - group interact - value_bool = 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_GROUP ); - struct functor_getter_perms_group_interact : public LLSelectedTEGetFunctor< bool > - { - functor_getter_perms_group_interact(const LLMediaEntry& entry): mMediaEntry(entry) {} - - bool get( LLViewerObject* object, S32 face ) - { - if ( object ) - if ( object->getTE(face) ) - if ( object->getTE(face)->getMediaData() ) - return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_GROUP)); - return 0 != ( mMediaEntry.getPermsInteract() & LLMediaEntry::PERM_GROUP ); - }; - - const LLMediaEntry &mMediaEntry; - - } func_perms_group_interact(default_media_data); - identical = selected_objects->getSelectedTEValue( &func_perms_group_interact, value_bool ); - base_key = std::string( LLPanelContents::PERMS_GROUP_INTERACT_KEY ); - mMediaSettings[ base_key ] = value_bool; - mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; - - // Perms - group control - value_bool = 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_GROUP ); - struct functor_getter_perms_group_control : public LLSelectedTEGetFunctor< bool > - { - functor_getter_perms_group_control(const LLMediaEntry& entry): mMediaEntry(entry) {} - - bool get( LLViewerObject* object, S32 face ) - { - if ( object ) - if ( object->getTE(face) ) - if ( object->getTE(face)->getMediaData() ) - return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_GROUP)); - return 0 != ( mMediaEntry.getPermsControl() & LLMediaEntry::PERM_GROUP ); - }; - - const LLMediaEntry &mMediaEntry; - - } func_perms_group_control(default_media_data); - identical = selected_objects->getSelectedTEValue( &func_perms_group_control, value_bool ); - base_key = std::string( LLPanelContents::PERMS_GROUP_CONTROL_KEY ); - mMediaSettings[ base_key ] = value_bool; - mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; - - // Perms - anyone interact - value_bool = 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_ANYONE ); - struct functor_getter_perms_anyone_interact : public LLSelectedTEGetFunctor< bool > - { - functor_getter_perms_anyone_interact(const LLMediaEntry& entry): mMediaEntry(entry) {} - - bool get( LLViewerObject* object, S32 face ) - { - if ( object ) - if ( object->getTE(face) ) - if ( object->getTE(face)->getMediaData() ) - return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_ANYONE)); - return 0 != ( mMediaEntry.getPermsInteract() & LLMediaEntry::PERM_ANYONE ); - }; - - const LLMediaEntry &mMediaEntry; - - } func_perms_anyone_interact(default_media_data); - identical = LLSelectMgr::getInstanceFast()->getSelection()->getSelectedTEValue( &func_perms_anyone_interact, value_bool ); - base_key = std::string( LLPanelContents::PERMS_ANYONE_INTERACT_KEY ); - mMediaSettings[ base_key ] = value_bool; - mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; - - // Perms - anyone control - value_bool = 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_ANYONE ); - struct functor_getter_perms_anyone_control : public LLSelectedTEGetFunctor< bool > - { - functor_getter_perms_anyone_control(const LLMediaEntry& entry) : mMediaEntry(entry) {} - - bool get( LLViewerObject* object, S32 face ) - { - if ( object ) - if ( object->getTE(face) ) - if ( object->getTE(face)->getMediaData() ) - return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_ANYONE)); - return 0 != ( mMediaEntry.getPermsControl() & LLMediaEntry::PERM_ANYONE ); - }; - - const LLMediaEntry &mMediaEntry; - - } func_perms_anyone_control(default_media_data); - identical = selected_objects->getSelectedTEValue( &func_perms_anyone_control, value_bool ); - base_key = std::string( LLPanelContents::PERMS_ANYONE_CONTROL_KEY ); - mMediaSettings[ base_key ] = value_bool; - mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; - - // security - whitelist enable - value_bool = default_media_data.getWhiteListEnable(); - struct functor_getter_whitelist_enable : public LLSelectedTEGetFunctor< bool > - { - functor_getter_whitelist_enable(const LLMediaEntry& entry) : mMediaEntry(entry) {} - - bool get( LLViewerObject* object, S32 face ) - { - if ( object ) - if ( object->getTE(face) ) - if ( object->getTE(face)->getMediaData() ) - return object->getTE(face)->getMediaData()->getWhiteListEnable(); - return mMediaEntry.getWhiteListEnable(); - }; - - const LLMediaEntry &mMediaEntry; - - } func_whitelist_enable(default_media_data); - identical = selected_objects->getSelectedTEValue( &func_whitelist_enable, value_bool ); - base_key = std::string( LLMediaEntry::WHITELIST_ENABLE_KEY ); - mMediaSettings[ base_key ] = value_bool; - mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; - - // security - whitelist URLs - std::vector<std::string> value_vector_str = default_media_data.getWhiteList(); - struct functor_getter_whitelist_urls : public LLSelectedTEGetFunctor< std::vector<std::string> > - { - functor_getter_whitelist_urls(const LLMediaEntry& entry): mMediaEntry(entry) {} - - std::vector<std::string> get( LLViewerObject* object, S32 face ) - { - if ( object ) - if ( object->getTE(face) ) - if ( object->getTE(face)->getMediaData() ) - return object->getTE(face)->getMediaData()->getWhiteList(); - return mMediaEntry.getWhiteList(); - }; - - const LLMediaEntry &mMediaEntry; - - } func_whitelist_urls(default_media_data); - identical = selected_objects->getSelectedTEValue( &func_whitelist_urls, value_vector_str ); - base_key = std::string( LLMediaEntry::WHITELIST_KEY ); - mMediaSettings[ base_key ].clear(); - std::vector< std::string >::iterator iter = value_vector_str.begin(); - while( iter != value_vector_str.end() ) - { - std::string white_list_url = *iter; - mMediaSettings[ base_key ].append( white_list_url ); - ++iter; - }; - - mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; -} - template<class P> void build_plant_combo(const std::map<U32, P*>& list, LLComboBox* combo) { diff --git a/indra/newview/llfloatertools.h b/indra/newview/llfloatertools.h index 6cb910176d1f31a881ff44fbb1dc008283e848b8..69498456e2f486c97c94b85b9e8fb112ea6b8211 100644 --- a/indra/newview/llfloatertools.h +++ b/indra/newview/llfloatertools.h @@ -44,7 +44,6 @@ class LLRadioGroup; class LLSlider; class LLTabContainer; class LLTextBox; -class LLMediaCtrl; class LLTool; class LLParcelSelection; class LLObjectSelection; @@ -98,11 +97,6 @@ class LLFloaterTools final static void setEditTool(void* data); void setTool(const LLSD& user_data); void saveLastTool(); - void onClickBtnDeleteMedia(); - void onClickBtnAddMedia(); - void onClickBtnEditMedia(); - void clearMediaSettings(); - bool selectedMediaEditable(); void updateLandImpacts(); static void setGridMode(S32 mode); @@ -111,13 +105,6 @@ class LLFloaterTools final private: void refresh(); - void refreshMedia(); - void getMediaState(); - void updateMediaSettings(); - void navigateToTitleMedia( const std::string url ); // navigate if changed - void updateMediaTitle(); - static bool deleteMediaConfirm(const LLSD& notification, const LLSD& response); - static bool multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response); static void setObjectType( LLPCode pcode ); void onClickGridOptions(); @@ -202,19 +189,12 @@ class LLFloaterTools final LLParcelSelectionHandle mParcelSelection; LLObjectSelectionHandle mObjectSelection; - LLMediaCtrl *mTitleMedia; - bool mNeedMediaTitle; - private: BOOL mDirty; BOOL mHasSelection; std::map<std::string, std::string> mStatusText; - -protected: - LLSD mMediaSettings; - public: static bool sShowObjectCost; static bool sPreviousFocusOnAvatar; diff --git a/indra/newview/llfloaterurlentry.cpp b/indra/newview/llfloaterurlentry.cpp index 6bf4b90f073eea75d0be27673deb940413c07567..b012c740e367140a7361168025ee84acf9148f31 100644 --- a/indra/newview/llfloaterurlentry.cpp +++ b/indra/newview/llfloaterurlentry.cpp @@ -112,16 +112,6 @@ void LLFloaterURLEntry::headerFetchComplete(S32 status, const std::string& mime_ panel_media->setMediaType(mime_type); panel_media->setMediaURL(mMediaURLEdit->getValue().asString()); } - else - { - LLPanelFace* panel_face = dynamic_cast<LLPanelFace*>(mPanelLandMediaHandle.get()); - if(panel_face) - { - panel_face->setMediaType(mime_type); - panel_face->setMediaURL(mMediaURLEdit->getValue().asString()); - } - - } getChildView("loading_label")->setVisible( false); closeFloater(); diff --git a/indra/newview/llfloaterwebcontent.cpp b/indra/newview/llfloaterwebcontent.cpp index 4ef48f7bf8e2202eb0b8c48b4cf784c8fe6daeaa..cc1a20720e4ae2722d79f6bbcc21633ba0e911d8 100644 --- a/indra/newview/llfloaterwebcontent.cpp +++ b/indra/newview/llfloaterwebcontent.cpp @@ -159,7 +159,7 @@ LLFloater* LLFloaterWebContent::create( Params p) //static void LLFloaterWebContent::closeRequest(const std::string &uuid) { - LLFloaterWebContent* floaterp = instance_tracker_t::getInstance(uuid); + auto floaterp = instance_tracker_t::getInstance(uuid); if (floaterp) { floaterp->closeFloater(false); @@ -169,7 +169,7 @@ void LLFloaterWebContent::closeRequest(const std::string &uuid) //static void LLFloaterWebContent::geometryChanged(const std::string &uuid, S32 x, S32 y, S32 width, S32 height) { - LLFloaterWebContent* floaterp = instance_tracker_t::getInstance(uuid); + auto floaterp = instance_tracker_t::getInstance(uuid); if (floaterp) { floaterp->geometryChanged(x, y, width, height); diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp index f6ec7c62281fff018f9b5d324c9d4bba9070bb18..8cc14a66fa9709a4d8136ef499a52633893186b1 100644 --- a/indra/newview/llfloaterworldmap.cpp +++ b/indra/newview/llfloaterworldmap.cpp @@ -46,6 +46,7 @@ //#include "llfirstuse.h" #include "llfloaterreg.h" // getTypedInstance() #include "llfocusmgr.h" +#include "lliconctrl.h" #include "llinventoryfunctions.h" #include "llinventorymodel.h" #include "llinventorymodelbackgroundfetch.h" @@ -86,7 +87,6 @@ //--------------------------------------------------------------------------- // Constants //--------------------------------------------------------------------------- -static const F32 MAP_ZOOM_TIME = 0.2f; // Merov: we switched from using the "world size" (which varies depending where the user went) to a fixed // width of 512 regions max visible at a time. This makes the zoom slider works in a consistent way across @@ -291,7 +291,7 @@ void* LLFloaterWorldMap::createWorldMapView(void* data) BOOL LLFloaterWorldMap::postBuild() { - mPanel = getChild<LLPanel>("objects_mapview"); + mMapView = dynamic_cast<LLWorldMapView*>(getChild<LLPanel>("objects_mapview")); mTrackRegionButton = getChild<LLButton>("track_region"); LLComboBox *avatar_combo = getChild<LLComboBox>("friend combo"); @@ -313,13 +313,13 @@ BOOL LLFloaterWorldMap::postBuild() landmark_combo->setTextChangedCallback( boost::bind(&LLFloaterWorldMap::onComboTextEntry, this) ); mListLandmarkCombo = dynamic_cast<LLCtrlListInterface *>(landmark_combo); - mCurZoomVal = log(LLWorldMapView::sMapScale/256.f)/log(2.f); - getChild<LLUICtrl>("zoom slider")->setValue(mCurZoomVal); + F32 slider_zoom = mMapView->getZoom(); + getChild<LLUICtrl>("zoom slider")->setValue(slider_zoom); + + //getChild<LLPanel>("expand_btn_panel")->setMouseDownCallback(boost::bind(&LLFloaterWorldMap::onExpandCollapseBtn, this)); setDefaultBtn(NULL); - mZoomTimer.stop(); - onChangeMaturity(); return TRUE; @@ -329,7 +329,7 @@ BOOL LLFloaterWorldMap::postBuild() LLFloaterWorldMap::~LLFloaterWorldMap() { // All cleaned up by LLView destructor - mPanel = NULL; + mMapView = NULL; // Inventory deletes all observers on shutdown mInventory = NULL; @@ -353,7 +353,7 @@ LLFloaterWorldMap* LLFloaterWorldMap::getInstance() void LLFloaterWorldMap::onClose(bool app_quitting) { // While we're not visible, discard the overlay images we're using - LLWorldMap::getInstanceFast()->clearImageRefs(); + LLWorldMap::getInstance()->clearImageRefs(); mTeleportFinishConnection.disconnect(); } @@ -367,20 +367,18 @@ void LLFloaterWorldMap::onOpen(const LLSD& key) mIsClosing = FALSE; - LLWorldMapView* map_panel; - map_panel = (LLWorldMapView*)gFloaterWorldMap->mPanel; - map_panel->clearLastClick(); + mMapView->clearLastClick(); { // reset pan on show, so it centers on you again if (!center_on_target) { - LLWorldMapView::setPan(0, 0, TRUE); + mMapView->setPan(0, 0, true); } - map_panel->updateVisibleBlocks(); + mMapView->updateVisibleBlocks(); // Reload items as they may have changed - LLWorldMap::getInstanceFast()->reloadItems(); + LLWorldMap::getInstance()->reloadItems(); // We may already have a bounding box for the regions of the world, // so use that to adjust the view. @@ -391,7 +389,7 @@ void LLFloaterWorldMap::onOpen(const LLSD& key) // Start speculative download of landmarks const LLUUID landmark_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK); - LLInventoryModelBackgroundFetch::instanceFast().start(landmark_folder_id); + LLInventoryModelBackgroundFetch::instance().start(landmark_folder_id); getChild<LLUICtrl>("location")->setFocus( TRUE); gFocusMgr.triggerFocusFlash(); @@ -412,7 +410,7 @@ void LLFloaterWorldMap::onOpen(const LLSD& key) // static void LLFloaterWorldMap::reloadIcons(void*) { - LLWorldMap::getInstanceFast()->reloadItems(); + LLWorldMap::getInstance()->reloadItems(); } // virtual @@ -425,18 +423,21 @@ BOOL LLFloaterWorldMap::handleHover(S32 x, S32 y, MASK mask) BOOL LLFloaterWorldMap::handleScrollWheel(S32 x, S32 y, S32 clicks) { - if (!isMinimized() && isFrontmost()) - { - if(mPanel->pointInView(x, y)) - { - F32 slider_value = (F32)getChild<LLUICtrl>("zoom slider")->getValue().asReal(); - slider_value += ((F32)clicks * -0.3333f); - getChild<LLUICtrl>("zoom slider")->setValue(LLSD(slider_value)); - return TRUE; - } - } - - return LLFloater::handleScrollWheel(x, y, clicks); + if (!isMinimized() && isFrontmost()) + { + S32 map_x = x - mMapView->getRect().mLeft; + S32 map_y = y - mMapView->getRect().mBottom; + if (mMapView->pointInView(map_x, map_y)) + { + F32 old_slider_zoom = (F32) getChild<LLUICtrl>("zoom slider")->getValue().asReal(); + F32 slider_zoom = old_slider_zoom + ((F32) clicks * -0.3333f); + getChild<LLUICtrl>("zoom slider")->setValue(LLSD(slider_zoom)); + mMapView->zoomWithPivot(slider_zoom, map_x, map_y); + return true; + } + } + + return LLFloater::handleScrollWheel(x, y, clicks); } @@ -510,9 +511,9 @@ void LLFloaterWorldMap::draw() getChildView("Teleport")->setEnabled((BOOL)tracking_status); // getChildView("Clear")->setEnabled((BOOL)tracking_status); - getChildView("Show Destination")->setEnabled((BOOL)tracking_status || LLWorldMap::getInstanceFast()->isTracking()); + getChildView("Show Destination")->setEnabled((BOOL)tracking_status || LLWorldMap::getInstance()->isTracking()); getChildView("copy_slurl")->setEnabled((mSLURL.isValid()) ); - mTrackRegionButton->setEnabled((BOOL) tracking_status || LLWorldMap::getInstanceFast()->isTracking()); + mTrackRegionButton->setEnabled((BOOL) tracking_status || LLWorldMap::getInstance()->isTracking()); // [RLVa:KB] - Checked: 2010-08-22 (RLVa-1.2.1a) | Added: RLVa-1.2.1a childSetEnabled("Go Home", (!rlv_handler_t::isEnabled()) || !(gRlvHandler.hasBehaviour(RLV_BHVR_TPLM) && gRlvHandler.hasBehaviour(RLV_BHVR_TPLOC))); @@ -520,26 +521,13 @@ void LLFloaterWorldMap::draw() setMouseOpaque(TRUE); getDragHandle()->setMouseOpaque(TRUE); - - //RN: snaps to zoom value because interpolation caused jitter in the text rendering - if (!mZoomTimer.getStarted() && mCurZoomVal != (F32)getChild<LLUICtrl>("zoom slider")->getValue().asReal()) - { - mZoomTimer.start(); - } - F32 interp = mZoomTimer.getElapsedTimeF32() / MAP_ZOOM_TIME; - if (interp > 1.f) - { - interp = 1.f; - mZoomTimer.stop(); - } - mCurZoomVal = ll_lerp(mCurZoomVal, (F32)getChild<LLUICtrl>("zoom slider")->getValue().asReal(), interp); - F32 map_scale = 256.f*pow(2.f, mCurZoomVal); - LLWorldMapView::setScale( map_scale ); + + mMapView->zoom((F32)getChild<LLUICtrl>("zoom slider")->getValue().asReal()); // Enable/disable checkboxes depending on the zoom level // If above threshold level (i.e. low res) -> Disable all checkboxes // If under threshold level (i.e. high res) -> Enable all checkboxes - bool enable = LLWorldMapView::showRegionInfo(); + bool enable = mMapView->showRegionInfo(); getChildView("people_chk")->setEnabled(enable); getChildView("infohub_chk")->setEnabled(enable); getChildView("telehub_chk")->setEnabled(enable); @@ -648,15 +636,15 @@ void LLFloaterWorldMap::trackGenericItem(const LLItemInfo &item) void LLFloaterWorldMap::trackLocation(const LLVector3d& pos_global) { - LLSimInfo* sim_info = LLWorldMap::getInstanceFast()->simInfoFromPosGlobal(pos_global); + LLSimInfo* sim_info = LLWorldMap::getInstance()->simInfoFromPosGlobal(pos_global); if (!sim_info) { // We haven't found a region for that point yet, leave the tracking to the world map LLTracker::stopTracking(false); - LLWorldMap::getInstanceFast()->setTracking(pos_global); + LLWorldMap::getInstance()->setTracking(pos_global); S32 world_x = S32(pos_global.mdV[0] / 256); S32 world_y = S32(pos_global.mdV[1] / 256); - LLWorldMapMessage::getInstanceFast()->sendMapBlockRequest(world_x, world_y, world_x, world_y, true); + LLWorldMapMessage::getInstance()->sendMapBlockRequest(world_x, world_y, world_x, world_y, true); setDefaultBtn(""); // clicked on a non-region - turn off coord display @@ -669,8 +657,8 @@ void LLFloaterWorldMap::trackLocation(const LLVector3d& pos_global) // Down region. Show the blue circle of death! // i.e. let the world map that this and tell it it's invalid LLTracker::stopTracking(false); - LLWorldMap::getInstanceFast()->setTracking(pos_global); - LLWorldMap::getInstanceFast()->setTrackingInvalid(); + LLWorldMap::getInstance()->setTracking(pos_global); + LLWorldMap::getInstance()->setTrackingInvalid(); setDefaultBtn(""); // clicked on a down region - turn off coord display @@ -692,7 +680,7 @@ void LLFloaterWorldMap::trackLocation(const LLVector3d& pos_global) std::string tooltip(""); mTrackedStatus = LLTracker::TRACKING_LOCATION; - LLWorldMap::getInstanceFast()->cancelTracking(); // The floater is taking over the tracking + LLWorldMap::getInstance()->cancelTracking(); // The floater is taking over the tracking // [RLVa:KB] - Checked: 2012-02-08 (RLVa-1.4.5) | Added: RLVa-1.4.5 LLTracker::trackLocation(pos_global, (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ? full_name : RlvStrings::getString(RlvStringKeys::Hidden::Generic).c_str(), tooltip); // [/RLVa:KB] @@ -741,7 +729,7 @@ void LLFloaterWorldMap::updateTeleportCoordsDisplay( const LLVector3d& pos ) F32 region_local_x; F32 region_local_y; F32 region_local_z; - LLSimInfo* sim_info = LLWorldMap::getInstanceFast()->simInfoFromPosGlobal(pos); + LLSimInfo* sim_info = LLWorldMap::getInstance()->simInfoFromPosGlobal(pos); if (sim_info) { U32 locX, locY; @@ -781,7 +769,7 @@ void LLFloaterWorldMap::updateLocation() { // Make sure we know where we are before setting the current user position std::string agent_sim_name; - gotSimName = LLWorldMap::getInstanceFast()->simNameFromPosGlobal( agentPos, agent_sim_name ); + gotSimName = LLWorldMap::getInstance()->simNameFromPosGlobal( agentPos, agent_sim_name ); // [RLVa:KB] - Checked: 2012-02-08 (RLVa-1.4.5) | Added: RLVa-1.4.5 if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) { @@ -866,7 +854,7 @@ void LLFloaterWorldMap::updateLocation() void LLFloaterWorldMap::trackURL(const std::string& region_name, S32 x_coord, S32 y_coord, S32 z_coord) { - LLSimInfo* sim_info = LLWorldMap::getInstanceFast()->simInfoFromName(region_name); + LLSimInfo* sim_info = LLWorldMap::getInstance()->simInfoFromName(region_name); z_coord = llclamp(z_coord, 0, 4096); if (sim_info) { @@ -890,9 +878,9 @@ void LLFloaterWorldMap::trackURL(const std::string& region_name, S32 x_coord, S3 // pass sim name to combo box gFloaterWorldMap->mCompletingRegionName = region_name; - LLWorldMapMessage::getInstanceFast()->sendNamedRegionRequest(region_name); + LLWorldMapMessage::getInstance()->sendNamedRegionRequest(region_name); LLStringUtil::toLower(gFloaterWorldMap->mCompletingRegionName); - LLWorldMap::getInstanceFast()->setTrackingCommit(); + LLWorldMap::getInstance()->setTrackingCommit(); } } @@ -1056,7 +1044,7 @@ void LLFloaterWorldMap::clearLocationSelection(BOOL clear_ui, BOOL dest_reached) { list->operateOnAll(LLCtrlListInterface::OP_DELETE); } - LLWorldMap::getInstanceFast()->cancelTracking(); + LLWorldMap::getInstance()->cancelTracking(); mCompletingRegionName = ""; } @@ -1080,7 +1068,7 @@ void LLFloaterWorldMap::clearAvatarSelection(BOOL clear_ui) { mTrackedStatus = LLTracker::TRACKING_NOTHING; LLCtrlListInterface *list = mListFriendCombo; - if (list) + if (list && list->getSelectedValue().asString() != "None") { list->selectByValue( "None" ); } @@ -1100,9 +1088,7 @@ void LLFloaterWorldMap::adjustZoomSliderBounds() S32 world_height_regions = MAX_VISIBLE_REGIONS; // Find how much space we have to display the world - LLWorldMapView* map_panel; - map_panel = (LLWorldMapView*)mPanel; - LLRect view_rect = map_panel->getRect(); + LLRect view_rect = mMapView->getRect(); // View size in pixels S32 view_width = view_rect.getWidth(); @@ -1326,15 +1312,15 @@ void LLFloaterWorldMap::onLocationCommit() LLStringUtil::toLower(str); mCompletingRegionName = str; - LLWorldMap::getInstanceFast()->setTrackingCommit(); + LLWorldMap::getInstance()->setTrackingCommit(); if (str.length() >= 3) { - LLWorldMapMessage::getInstanceFast()->sendNamedRegionRequest(str); + LLWorldMapMessage::getInstance()->sendNamedRegionRequest(str); } else { str += "#"; - LLWorldMapMessage::getInstanceFast()->sendNamedRegionRequest(str); + LLWorldMapMessage::getInstance()->sendNamedRegionRequest(str); } } @@ -1358,7 +1344,7 @@ void LLFloaterWorldMap::onClearBtn() { mTrackedStatus = LLTracker::TRACKING_NOTHING; LLTracker::stopTracking(true); - LLWorldMap::getInstanceFast()->cancelTracking(); + LLWorldMap::getInstance()->cancelTracking(); mSLURL = LLSLURL(); // Clear the SLURL since it's invalid mSetToUserPosition = TRUE; // Revert back to the current user position } @@ -1370,9 +1356,9 @@ void LLFloaterWorldMap::onShowTargetBtn() void LLFloaterWorldMap::onShowAgentBtn() { - LLWorldMapView::setPan( 0, 0, FALSE); // FALSE == animate - // Set flag so user's location will be displayed if not tracking anything else - mSetToUserPosition = TRUE; + mMapView->setPanWithInterpTime(0, 0, false, 0.1f); // false == animate + // Set flag so user's location will be displayed if not tracking anything else + mSetToUserPosition = true; } void LLFloaterWorldMap::onClickTeleportBtn() @@ -1390,6 +1376,22 @@ void LLFloaterWorldMap::onCopySLURL() LLNotificationsUtil::add("CopySLURL", args); } +//void LLFloaterWorldMap::onExpandCollapseBtn() +//{ +// LLLayoutStack* floater_stack = getChild<LLLayoutStack>("floater_map_stack"); +// LLLayoutPanel* controls_panel = getChild<LLLayoutPanel>("controls_lp"); +// +// bool toggle_collapse = !controls_panel->isCollapsed(); +// floater_stack->collapsePanel(controls_panel, toggle_collapse); +// floater_stack->updateLayout(); +// +// std::string image_name = getString(toggle_collapse ? "expand_icon" : "collapse_icon"); +// std::string tooltip = getString(toggle_collapse ? "expand_tooltip" : "collapse_tooltip"); +// getChild<LLIconCtrl>("expand_collapse_icon")->setImage(LLUI::getUIImage(image_name)); +// getChild<LLIconCtrl>("expand_collapse_icon")->setToolTip(tooltip); +// getChild<LLPanel>("expand_btn_panel")->setToolTip(tooltip); +//} + void LLFloaterWorldMap::onTrackRegion() { ALFloaterRegionTracker* floaterp = LLFloaterReg::showTypedInstance<ALFloaterRegionTracker>("region_tracker"); @@ -1398,7 +1400,7 @@ void LLFloaterWorldMap::onTrackRegion() if (LLTracker::getTrackingStatus() != LLTracker::TRACKING_NOTHING) { std::string sim_name; - if (LLWorldMap::getInstanceFast()->simNameFromPosGlobal(LLTracker::getTrackedPositionGlobal(), sim_name)) + if (LLWorldMap::getInstance()->simNameFromPosGlobal(LLTracker::getTrackedPositionGlobal(), sim_name)) { const std::string& temp_label = floaterp->getRegionLabelIfExists(sim_name); LLSD args, payload; @@ -1432,9 +1434,9 @@ void LLFloaterWorldMap::centerOnTarget(BOOL animate) pos_global = LLTracker::getTrackedPositionGlobal() - gAgentCamera.getCameraPositionGlobal(); } } - else if(LLWorldMap::getInstanceFast()->isTracking()) + else if(LLWorldMap::getInstance()->isTracking()) { - pos_global = LLWorldMap::getInstanceFast()->getTrackedPositionGlobal() - gAgentCamera.getCameraPositionGlobal();; + pos_global = LLWorldMap::getInstance()->getTrackedPositionGlobal() - gAgentCamera.getCameraPositionGlobal();; @@ -1445,9 +1447,10 @@ void LLFloaterWorldMap::centerOnTarget(BOOL animate) pos_global.clearVec(); } - LLWorldMapView::setPan( -llfloor((F32)(pos_global.mdV[VX] * (F64)LLWorldMapView::sMapScale / REGION_WIDTH_METERS)), - -llfloor((F32)(pos_global.mdV[VY] * (F64)LLWorldMapView::sMapScale / REGION_WIDTH_METERS)), - !animate); + F64 map_scale = (F64)mMapView->getScale(); + mMapView->setPanWithInterpTime(-llfloor((F32)(pos_global.mdV[VX] * map_scale / REGION_WIDTH_METERS)), + -llfloor((F32)(pos_global.mdV[VY] * map_scale / REGION_WIDTH_METERS)), + !animate, 0.1f); mWaitingForTracker = FALSE; } @@ -1618,7 +1621,7 @@ void LLFloaterWorldMap::updateSims(bool found_null_sim) S32 num_results = 0; - const auto& region_map = LLWorldMap::getInstanceFast()->getRegionMap(); + const auto& region_map = LLWorldMap::getInstance()->getRegionMap(); std::vector<std::pair <U64, LLSimInfo*> > sim_info_vec; sim_info_vec.reserve(region_map.size()); @@ -1682,7 +1685,7 @@ void LLFloaterWorldMap::onTeleportFinished() { if(isInVisibleChain()) { - LLWorldMapView::setPan(0, 0, TRUE); + mMapView->setPan(0, 0, TRUE); } } @@ -1699,7 +1702,7 @@ void LLFloaterWorldMap::onCommitSearchResult() } LLStringUtil::toLower(sim_name); - for (const auto& sim_info_pair : LLWorldMap::getInstanceFast()->getRegionMap()) + for (const auto& sim_info_pair : LLWorldMap::getInstance()->getRegionMap()) { LLSimInfo* info = sim_info_pair.second.get(); @@ -1756,9 +1759,8 @@ void LLFloaterWorldMap::onChangeMaturity() void LLFloaterWorldMap::onFocusLost() { - gViewerWindow->showCursor(); - LLWorldMapView* map_panel = (LLWorldMapView*)gFloaterWorldMap->mPanel; - map_panel->mPanning = FALSE; + gViewerWindow->showCursor(); + mMapView->mPanning = false; } LLPanelHideBeacon::LLPanelHideBeacon() : diff --git a/indra/newview/llfloaterworldmap.h b/indra/newview/llfloaterworldmap.h index bb980ff1e7d5c37ccaa748c687f93b40d844acbf..b640dc5eec764e1f2fbb5fe293740cfc745edc5c 100644 --- a/indra/newview/llfloaterworldmap.h +++ b/indra/newview/llfloaterworldmap.h @@ -44,6 +44,7 @@ class LLInventoryObserver; class LLItemInfo; class LLLineEditor; class LLTabContainer; +class LLWorldMapView; class LLFloaterWorldMap final : public LLFloater { @@ -131,6 +132,8 @@ class LLFloaterWorldMap final : public LLFloater void onCopySLURL(); void onTrackRegion(); + //void onExpandCollapseBtn(); + void centerOnTarget(BOOL animate); void updateLocation(); @@ -155,11 +158,7 @@ class LLFloaterWorldMap final : public LLFloater void onTeleportFinished(); private: - LLPanel* mPanel; // Panel displaying the map - - // Ties to LLWorldMapView::sMapScale, in pixels per region - F32 mCurZoomVal; - LLFrameTimer mZoomTimer; + LLWorldMapView* mMapView; // Panel displaying the map // update display of teleport destination coordinates - pos is in global coordinates void updateTeleportCoordsDisplay( const LLVector3d& pos ); diff --git a/indra/newview/llfolderviewmodelinventory.cpp b/indra/newview/llfolderviewmodelinventory.cpp index 22b672d1c5867d107e620b386ce69d3f4d9d586f..fb06cc2be9d79177f7b810a499d4f101e568a1d9 100644 --- a/indra/newview/llfolderviewmodelinventory.cpp +++ b/indra/newview/llfolderviewmodelinventory.cpp @@ -107,7 +107,7 @@ void LLFolderViewModelInventory::sort( LLFolderViewFolder* folder ) bool LLFolderViewModelInventory::contentsReady() { - return !LLInventoryModelBackgroundFetch::instanceFast().folderFetchActive(); + return !LLInventoryModelBackgroundFetch::instance().folderFetchActive(); } bool LLFolderViewModelInventory::isFolderComplete(LLFolderViewFolder* folder) diff --git a/indra/newview/llfriendcard.cpp b/indra/newview/llfriendcard.cpp index 46b34666783841b416c8db00bc0d865c8aa1f751..0ba283f5f401cf660425900dd5697b58dbb1167d 100644 --- a/indra/newview/llfriendcard.cpp +++ b/indra/newview/llfriendcard.cpp @@ -327,22 +327,63 @@ void LLFriendCardsManager::syncFriendCardsFolders() /************************************************************************/ /* Private Methods */ /************************************************************************/ -const LLUUID& LLFriendCardsManager::findFriendFolderUUIDImpl() const +const LLUUID& LLFriendCardsManager::findFirstCallingCardSubfolder(const LLUUID &parent_id) const { - const LLUUID callingCardsFolderID = gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD); + if (parent_id.isNull()) + { + return LLUUID::null; + } - std::string friendFolderName = get_friend_folder_name(); + LLInventoryModel::cat_array_t* cats; + LLInventoryModel::item_array_t* items; + gInventory.getDirectDescendentsOf(parent_id, cats, items); - return findChildFolderUUID(callingCardsFolderID, friendFolderName); + if (!cats || !items || cats->size() == 0) + { + // call failed + return LLUUID::null; + } + + if (cats->size() > 1) + { + const LLViewerInventoryCategory* friendFolder = gInventory.getCategory(parent_id); + if (friendFolder) + { + LL_WARNS_ONCE() << friendFolder->getName() << " folder contains more than one folder" << LL_ENDL; + } + } + + for (LLInventoryModel::cat_array_t::const_iterator iter = cats->begin(); + iter != cats->end(); + ++iter) + { + const LLInventoryCategory* category = (*iter); + if (category->getPreferredType() == LLFolderType::FT_CALLINGCARD) + { + return category->getUUID(); + } + } + + return LLUUID::null; } -const LLUUID& LLFriendCardsManager::findFriendAllSubfolderUUIDImpl() const +// Inventorry -> +// Calling Cards - > +// Friends - > (the only expected folder) +// All (the only expected folder) + +const LLUUID& LLFriendCardsManager::findFriendFolderUUIDImpl() const { - LLUUID friendFolderUUID = findFriendFolderUUIDImpl(); + const LLUUID callingCardsFolderID = gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD); + + return findFirstCallingCardSubfolder(callingCardsFolderID); +} - std::string friendAllSubfolderName = get_friend_all_subfolder_name(); +const LLUUID& LLFriendCardsManager::findFriendAllSubfolderUUIDImpl() const +{ + LLUUID friendFolderUUID = findFriendFolderUUIDImpl(); - return findChildFolderUUID(friendFolderUUID, friendAllSubfolderName); + return findFirstCallingCardSubfolder(friendFolderUUID); } const LLUUID& LLFriendCardsManager::findChildFolderUUID(const LLUUID& parentFolderUUID, const std::string& nonLocalizedName) const diff --git a/indra/newview/llfriendcard.h b/indra/newview/llfriendcard.h index 84e7377a43e2759a198a5c467a34aaa20c578f36..cbfb1d544c7182511680ef265cc80e51c21f03d8 100644 --- a/indra/newview/llfriendcard.h +++ b/indra/newview/llfriendcard.h @@ -114,6 +114,7 @@ class LLFriendCardsManager final } const LLUUID& findChildFolderUUID(const LLUUID& parentFolderUUID, const std::string& nonLocalizedName) const; + const LLUUID& findFirstCallingCardSubfolder(const LLUUID &parent_id) const; const LLUUID& findFriendFolderUUIDImpl() const; const LLUUID& findFriendAllSubfolderUUIDImpl() const; const LLUUID& findFriendCardInventoryUUIDImpl(const LLUUID& avatarID); diff --git a/indra/newview/llgiveinventory.cpp b/indra/newview/llgiveinventory.cpp index cbc4b59bde48acf0ee7e7fbde0b1488d5095faa5..38e99bab0775b719aa8cbda8520ba1e428f264aa 100644 --- a/indra/newview/llgiveinventory.cpp +++ b/indra/newview/llgiveinventory.cpp @@ -474,7 +474,7 @@ bool LLGiveInventory::commitGiveInventoryItem(const LLUUID& to_agent, if ( (!RlvActions::isRlvEnabled()) || (RlvActions::canShowName(RlvActions::SNC_DEFAULT, to_agent)) || (im_session_id.notNull()) || (!RlvUtil::isNearbyAgent(to_agent)) || (RlvUIEnabler::hasOpenProfile(to_agent)) ) { - LLRecentPeople::instanceFast().add(to_agent); + LLRecentPeople::instance().add(to_agent); } return true; // [/RLVa:KB] @@ -564,7 +564,7 @@ bool LLGiveInventory::commitGiveInventoryCategory(const LLUUID& to_agent, if ( (!RlvActions::isRlvEnabled()) || (RlvActions::canShowName(RlvActions::SNC_DEFAULT, to_agent)) || (im_session_id.notNull()) || (!RlvUtil::isNearbyAgent(to_agent)) || (RlvUIEnabler::hasOpenProfile(to_agent)) ) { - LLRecentPeople::instanceFast().add(to_agent); + LLRecentPeople::instance().add(to_agent); } // [/RLVa:KB] diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp index c0554cbe254faefd9bca115bd20f4c7352372766..d204d5d65e775fbc6c02e847f392a4774c9d8b66 100644 --- a/indra/newview/llglsandbox.cpp +++ b/indra/newview/llglsandbox.cpp @@ -103,7 +103,7 @@ void LLToolSelectRect::handleRectangleSelection(S32 x, S32 y, MASK mask) top = ll_round((F32) top * LLUI::getScaleFactor().mV[VY]); bottom = ll_round((F32) bottom * LLUI::getScaleFactor().mV[VY]); - LLViewerCamera* viewer_cam = LLViewerCamera::getInstanceFast(); + LLViewerCamera* viewer_cam = LLViewerCamera::getInstance(); F32 old_far_plane = viewer_cam->getFar(); F32 old_near_plane = viewer_cam->getNear(); @@ -192,17 +192,17 @@ void LLToolSelectRect::handleRectangleSelection(S32 x, S32 y, MASK mask) { return true; } - S32 result = LLViewerCamera::getInstanceFast()->sphereInFrustum(drawable->getPositionAgent(), drawable->getRadius()); + S32 result = LLViewerCamera::getInstance()->sphereInFrustum(drawable->getPositionAgent(), drawable->getRadius()); switch (result) { case 0: - LLSelectMgr::getInstanceFast()->unhighlightObjectOnly(vobjp); + LLSelectMgr::getInstance()->unhighlightObjectOnly(vobjp); break; case 1: // check vertices - if (!LLViewerCamera::getInstanceFast()->areVertsVisible(vobjp, LLSelectMgr::sRectSelectInclusive)) + if (!LLViewerCamera::getInstance()->areVertsVisible(vobjp, LLSelectMgr::sRectSelectInclusive)) { - LLSelectMgr::getInstanceFast()->unhighlightObjectOnly(vobjp); + LLSelectMgr::getInstance()->unhighlightObjectOnly(vobjp); } break; default: @@ -211,14 +211,14 @@ void LLToolSelectRect::handleRectangleSelection(S32 x, S32 y, MASK mask) return true; } } func; - LLSelectMgr::getInstanceFast()->getHighlightedObjects()->applyToObjects(&func); + LLSelectMgr::getInstance()->getHighlightedObjects()->applyToObjects(&func); } if (grow_selection) { std::vector<LLDrawable*> potentials; - for (LLViewerRegion* region : LLWorld::getInstanceFast()->getRegionList()) + for (LLViewerRegion* region : LLWorld::getInstance()->getRegionList()) { for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) { @@ -265,11 +265,11 @@ void LLToolSelectRect::handleRectangleSelection(S32 x, S32 y, MASK mask) // check vertices if (viewer_cam->areVertsVisible(vobjp, LLSelectMgr::sRectSelectInclusive)) { - LLSelectMgr::getInstanceFast()->highlightObjectOnly(vobjp); + LLSelectMgr::getInstance()->highlightObjectOnly(vobjp); } break; case 2: - LLSelectMgr::getInstanceFast()->highlightObjectOnly(vobjp); + LLSelectMgr::getInstance()->highlightObjectOnly(vobjp); break; default: break; @@ -284,8 +284,8 @@ void LLToolSelectRect::handleRectangleSelection(S32 x, S32 y, MASK mask) gGL.matrixMode(LLRender::MM_MODELVIEW); // restore camera - LLViewerCamera::getInstanceFast()->setFar(old_far_plane); - LLViewerCamera::getInstanceFast()->setNear(old_near_plane); + LLViewerCamera::getInstance()->setFar(old_far_plane); + LLViewerCamera::getInstance()->setNear(old_near_plane); gViewerWindow->setup3DRender(); } @@ -352,7 +352,7 @@ void LLViewerParcelMgr::renderRect(const LLVector3d &west_south_bottom_global, // resolves correctly so we can get a height value. const F32 FUDGE = 0.01f; - auto& worldInst = LLWorld::instanceFast(); + auto& worldInst = LLWorld::instance(); F32 sw_bottom = worldInst.resolveLandHeightAgent( LLVector3( west, south, 0.f ) ); F32 se_bottom = worldInst.resolveLandHeightAgent( LLVector3( east-FUDGE, south, 0.f ) ); @@ -833,10 +833,7 @@ void LLViewerObjectList::renderObjectBeacons() LLGLSUIDefault gls_ui; - if (LLGLSLShader::sNoFixedFunction) - { - gUIProgram.bind(); - } + gUIProgram.bind(); { gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); @@ -924,10 +921,7 @@ void LLViewerObjectList::renderObjectBeacons() void LLSky::renderSunMoonBeacons(const LLVector3& pos_agent, const LLVector3& direction, LLColor4 color) { LLGLSUIDefault gls_ui; - if (LLGLSLShader::sNoFixedFunction) - { - gUIProgram.bind(); - } + gUIProgram.bind(); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); LLVector3 pos_end; @@ -1060,9 +1054,8 @@ class VAOHolder //----------------------------------------------------------------------------- F32 gpu_benchmark() { - if (!gGLManager.mHasShaderObjects || !gGLManager.mHasTimerQuery) - { // don't bother benchmarking the fixed function - // or venerable drivers which don't support accurate timing anyway + if (!gGLManager.mHasTimerQuery) + { // don't bother benchmarking venerable drivers which don't support accurate timing anyway // and are likely to be correctly identified by the GPU table already. return -1.f; } @@ -1165,7 +1158,7 @@ F32 gpu_benchmark() delete [] pixels; //make a dummy triangle to draw with - LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, GL_STREAM_DRAW); + LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX, GL_STREAM_DRAW); if (!buff->allocateBuffer(3, 0, true)) { @@ -1175,7 +1168,6 @@ F32 gpu_benchmark() } LLStrider<LLVector3> v; - LLStrider<LLVector2> tc; if (! buff->getVertexStrider(v)) { @@ -1197,6 +1189,16 @@ F32 gpu_benchmark() // ensure matched pair of bind() and unbind() calls ShaderBinder binder(gBenchmarkProgram); +#ifdef GL_ARB_vertex_array_object + U32 glarray = 0; + + if (LLRender::sGLCoreProfile) + { + glGenVertexArrays(1, &glarray); + glBindVertexArray(glarray); + } +#endif + buff->setBuffer(LLVertexBuffer::MAP_VERTEX); glFinish(); @@ -1229,6 +1231,15 @@ F32 gpu_benchmark() } } +#ifdef GL_ARB_vertex_array_object + if (LLRender::sGLCoreProfile) + { + glBindVertexArray(0); + glDeleteVertexArrays(1, &glarray); + } +#endif + + std::sort(results.begin(), results.end()); F32 gbps = results[results.size()/2]; diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp index 06b8f3bee2b696405d18b5095ecf9c3bbe925a44..659607ae80167805ad4eccf08abdb36c02bcec87 100644 --- a/indra/newview/llgrouplist.cpp +++ b/indra/newview/llgrouplist.cpp @@ -48,7 +48,6 @@ // [/RLVa:KB] static LLDefaultChildRegistry::Register<LLGroupList> r("group_list"); -S32 LLGroupListItem::sIconWidth = 0; class LLGroupComparator : public LLFlatListView::ItemComparator { @@ -68,7 +67,35 @@ class LLGroupComparator : public LLFlatListView::ItemComparator } }; +class LLSharedGroupComparator : public LLFlatListView::ItemComparator +{ +public: + LLSharedGroupComparator() {}; + + /*virtual*/ bool compare(const LLPanel* item1, const LLPanel* item2) const + { + const LLGroupListItem* group_item1 = static_cast<const LLGroupListItem*>(item1); + std::string name1 = group_item1->getGroupName(); + bool item1_shared = gAgent.isInGroup(group_item1->getGroupID(), true); + + const LLGroupListItem* group_item2 = static_cast<const LLGroupListItem*>(item2); + std::string name2 = group_item2->getGroupName(); + bool item2_shared = gAgent.isInGroup(group_item2->getGroupID(), true); + + if (item2_shared != item1_shared) + { + return item1_shared; + } + + LLStringUtil::toUpper(name1); + LLStringUtil::toUpper(name2); + + return name1 < name2; + } +}; + static LLGroupComparator GROUP_COMPARATOR; +static LLSharedGroupComparator SHARED_GROUP_COMPARATOR; LLGroupList::Params::Params() : for_agent("for_agent", true) @@ -85,7 +112,15 @@ LLGroupList::LLGroupList(const Params& p) setCommitOnSelectionChange(true); // Set default sort order. - setComparator(&GROUP_COMPARATOR); + if (mForAgent) + { + setComparator(&GROUP_COMPARATOR); + } + else + { + // shared groups first + setComparator(&SHARED_GROUP_COMPARATOR); + } if (mForAgent) { @@ -263,7 +298,7 @@ void LLGroupList::setGroups(const std::map< std::string,LLUUID> group_list) void LLGroupList::addNewItem(const LLUUID& id, const std::string& name, const LLUUID& icon_id, EAddPosition pos, bool visible_in_profile) { - LLGroupListItem* item = new LLGroupListItem(mForAgent && mShowIcons); + LLGroupListItem* item = new LLGroupListItem(mForAgent, mShowIcons); item->setGroupID(id); item->setName(name, mNameFilter); @@ -272,7 +307,10 @@ void LLGroupList::addNewItem(const LLUUID& id, const std::string& name, const LL item->getChildView("info_btn")->setVisible( false); item->getChildView("profile_btn")->setVisible( false); item->setGroupIconVisible(mShowIcons); - item->setVisibleInProfile(visible_in_profile); + if (!mShowIcons) + { + item->setVisibleInProfile(visible_in_profile); + } addItem(item, id, pos); // setCommentVisible(false); @@ -368,14 +406,18 @@ bool LLGroupList::onContextMenuItemEnable(const LLSD& userdata) /* LLGroupListItem implementation */ /************************************************************************/ -LLGroupListItem::LLGroupListItem(bool for_agent) +LLGroupListItem::LLGroupListItem(bool for_agent, bool show_icons) : LLPanel(), mGroupIcon(NULL), mGroupNameBox(NULL), mInfoBtn(NULL), -mGroupID(LLUUID::null) +mProfileBtn(NULL), +mVisibilityHideBtn(NULL), +mVisibilityShowBtn(NULL), +mGroupID(LLUUID::null), +mForAgent(for_agent) { - if (for_agent) + if (show_icons) { buildFromFile( "panel_group_list_item.xml"); } @@ -383,13 +425,6 @@ mGroupID(LLUUID::null) { buildFromFile( "panel_group_list_item_short.xml"); } - - // Remember group icon width including its padding from the name text box, - // so that we can hide and show the icon again later. - if (!sIconWidth && mGroupNameBox) - { - sIconWidth = mGroupNameBox->getRect().mLeft - mGroupIcon->getRect().mLeft; - } } LLGroupListItem::~LLGroupListItem() @@ -406,7 +441,25 @@ BOOL LLGroupListItem::postBuild() mInfoBtn = getChild<LLButton>("info_btn"); mInfoBtn->setClickedCallback(boost::bind(&LLGroupListItem::onInfoBtnClick, this)); - childSetAction("profile_btn", boost::bind(&LLGroupListItem::onProfileBtnClick, this)); + mProfileBtn = getChild<LLButton>("profile_btn"); + mProfileBtn->setClickedCallback([this](LLUICtrl *, const LLSD &) { onProfileBtnClick(); }); + + mVisibilityHideBtn = findChild<LLButton>("visibility_hide_btn"); + if (mVisibilityHideBtn) + { + mVisibilityHideBtn->setClickedCallback([this](LLUICtrl *, const LLSD &) { onVisibilityBtnClick(false); }); + } + mVisibilityShowBtn = findChild<LLButton>("visibility_show_btn"); + if (mVisibilityShowBtn) + { + mVisibilityShowBtn->setClickedCallback([this](LLUICtrl *, const LLSD &) { onVisibilityBtnClick(true); }); + } + + // Remember group icon width including its padding from the name text box, + // so that we can hide and show the icon again later. + // Also note that panel_group_list_item and panel_group_list_item_short + // have icons of different sizes so we need to figure it per file. + mIconWidth = mGroupNameBox->getRect().mLeft - mGroupIcon->getRect().mLeft; return TRUE; } @@ -425,7 +478,16 @@ void LLGroupListItem::onMouseEnter(S32 x, S32 y, MASK mask) if (mGroupID.notNull()) // don't show the info button for the "none" group { mInfoBtn->setVisible(true); - getChildView("profile_btn")->setVisible( true); + mProfileBtn->setVisible(true); + if (mForAgent && mVisibilityHideBtn) + { + LLGroupData agent_gdatap; + if (gAgent.getGroupData(mGroupID, agent_gdatap)) + { + mVisibilityHideBtn->setVisible(agent_gdatap.mListInProfile); + mVisibilityShowBtn->setVisible(!agent_gdatap.mListInProfile); + } + } } LLPanel::onMouseEnter(x, y, mask); @@ -435,7 +497,12 @@ void LLGroupListItem::onMouseLeave(S32 x, S32 y, MASK mask) { getChildView("hovered_icon")->setVisible( false); mInfoBtn->setVisible(false); - getChildView("profile_btn")->setVisible( false); + mProfileBtn->setVisible(false); + if (mVisibilityHideBtn) + { + mVisibilityHideBtn->setVisible(false); + mVisibilityShowBtn->setVisible(false); + } LLPanel::onMouseLeave(x, y, mask); } @@ -453,7 +520,17 @@ void LLGroupListItem::setGroupID(const LLUUID& group_id) mID = group_id; mGroupID = group_id; - setActive(group_id == gAgent.getGroupID()); + + if (mForAgent) + { + // Active group should be bold. + setBold(group_id == gAgent.getGroupID()); + } + else + { + // Groups shared with the agent should be bold + setBold(gAgent.isInGroup(group_id, true)); + } LLGroupMgr::getInstance()->addObserver(this); } @@ -474,7 +551,7 @@ void LLGroupListItem::setGroupIconVisible(bool visible) // Move the group name horizontally by icon size + its distance from the group name. LLRect name_rect = mGroupNameBox->getRect(); - name_rect.mLeft += visible ? sIconWidth : -sIconWidth; + name_rect.mLeft += visible ? mIconWidth : -mIconWidth; mGroupNameBox->setRect(name_rect); } @@ -486,17 +563,16 @@ void LLGroupListItem::setVisibleInProfile(bool visible) ////////////////////////////////////////////////////////////////////////// // Private Section ////////////////////////////////////////////////////////////////////////// -void LLGroupListItem::setActive(bool active) +void LLGroupListItem::setBold(bool bold) { // *BUG: setName() overrides the style params. - // Active group should be bold. LLFontDescriptor new_desc(mGroupNameBox->getFont()->getFontDesc()); // *NOTE dzaporozhan // On Windows LLFontGL::NORMAL will not remove LLFontGL::BOLD if font // is predefined as bold (SansSerifSmallBold, for example) - new_desc.setStyle(active ? LLFontGL::BOLD : LLFontGL::NORMAL); + new_desc.setStyle(bold ? LLFontGL::BOLD : LLFontGL::NORMAL); LLFontGL* new_font = LLFontGL::getFont(new_desc); mGroupNameStyle.font = new_font; @@ -516,6 +592,18 @@ void LLGroupListItem::onProfileBtnClick() LLGroupActions::show(mGroupID); } +void LLGroupListItem::onVisibilityBtnClick(bool new_visibility) +{ + LLGroupData agent_gdatap; + if (gAgent.getGroupData(mGroupID, agent_gdatap)) + { + gAgent.setUserGroupFlags(mGroupID, agent_gdatap.mAcceptNotices, new_visibility); + setVisibleInProfile(new_visibility); + mVisibilityHideBtn->setVisible(new_visibility); + mVisibilityShowBtn->setVisible(!new_visibility); + } +} + void LLGroupListItem::changed(LLGroupChange gc) { LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(mID); diff --git a/indra/newview/llgrouplist.h b/indra/newview/llgrouplist.h index ce7e74c29444801332fdecfafa8c1ad1d6acad65..cb08ae5417743735a28bc5adc8669608ac978057 100644 --- a/indra/newview/llgrouplist.h +++ b/indra/newview/llgrouplist.h @@ -101,7 +101,7 @@ class LLGroupListItem : public LLPanel , public LLGroupMgrObserver { public: - LLGroupListItem(bool for_agent); + LLGroupListItem(bool for_agent, bool show_icons); ~LLGroupListItem(); /*virtual*/ BOOL postBuild(); /*virtual*/ void setValue(const LLSD& value); @@ -120,18 +120,23 @@ class LLGroupListItem : public LLPanel void setVisibleInProfile(bool visible); private: - void setActive(bool active); + void setBold(bool bold); void onInfoBtnClick(); void onProfileBtnClick(); + void onVisibilityBtnClick(bool new_visibility); LLTextBox* mGroupNameBox; LLUUID mGroupID; LLGroupIconCtrl* mGroupIcon; - LLButton* mInfoBtn; + LLButton* mInfoBtn; + LLButton* mProfileBtn; + LLButton* mVisibilityHideBtn; + LLButton* mVisibilityShowBtn; std::string mGroupName; + bool mForAgent; LLStyle::Params mGroupNameStyle; - static S32 sIconWidth; // icon width + padding + S32 mIconWidth; }; #endif // LL_LLGROUPLIST_H diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp index 7ef665f73b4b1528ef7cc24c8fe5d604c990b922..f95d37ddb8e8cbf2f6af80097bba1b226520156d 100644 --- a/indra/newview/llgroupmgr.cpp +++ b/indra/newview/llgroupmgr.cpp @@ -925,12 +925,10 @@ static void formatDateString(std::string &date_string) } } -static LLTrace::BlockTimerStatHandle FTM_PROCESS_GROUP_MEMBERS_REPLY("Process Group Members"); - // static void LLGroupMgr::processGroupMembersReply(LLMessageSystem* msg, void** data) { - LL_RECORD_BLOCK_TIME(FTM_PROCESS_GROUP_MEMBERS_REPLY); + LL_PROFILE_ZONE_SCOPED; LL_DEBUGS("GrpMgr") << "LLGroupMgr::processGroupMembersReply" << LL_ENDL; LLUUID agent_id; @@ -1035,12 +1033,10 @@ void LLGroupMgr::processGroupMembersReply(LLMessageSystem* msg, void** data) LLGroupMgr::getInstance()->notifyObservers(GC_MEMBER_DATA); } -static LLTrace::BlockTimerStatHandle FTM_PROCESS_GROUP_PROPERTIES_REPLY("Process Group Properties"); - //static void LLGroupMgr::processGroupPropertiesReply(LLMessageSystem* msg, void** data) { - LL_RECORD_BLOCK_TIME(FTM_PROCESS_GROUP_PROPERTIES_REPLY); + LL_PROFILE_ZONE_SCOPED; LL_DEBUGS("GrpMgr") << "LLGroupMgr::processGroupPropertiesReply" << LL_ENDL; if (!msg) @@ -1121,11 +1117,10 @@ void LLGroupMgr::processGroupPropertiesReply(LLMessageSystem* msg, void** data) LLGroupMgr::getInstance()->notifyObservers(GC_PROPERTIES); } -static LLTrace::BlockTimerStatHandle FTM_PROCESS_GROUP_ROLE_DATA_REPLY("Process Group Role Data"); // static void LLGroupMgr::processGroupRoleDataReply(LLMessageSystem* msg, void** data) { - LL_RECORD_BLOCK_TIME(FTM_PROCESS_GROUP_ROLE_DATA_REPLY); + LL_PROFILE_ZONE_SCOPED; LL_DEBUGS("GrpMgr") << "LLGroupMgr::processGroupRoleDataReply" << LL_ENDL; LLUUID agent_id; @@ -1209,11 +1204,10 @@ void LLGroupMgr::processGroupRoleDataReply(LLMessageSystem* msg, void** data) LLGroupMgr::getInstance()->notifyObservers(GC_ROLE_DATA); } -static LLTrace::BlockTimerStatHandle FTM_PROCESS_GROUP_ROLE_MEMBERS_REPLY("Process Group Role Members"); // static void LLGroupMgr::processGroupRoleMembersReply(LLMessageSystem* msg, void** data) { - LL_RECORD_BLOCK_TIME(FTM_PROCESS_GROUP_ROLE_MEMBERS_REPLY); + LL_PROFILE_ZONE_SCOPED; LL_DEBUGS("GrpMgr") << "LLGroupMgr::processGroupRoleMembersReply" << LL_ENDL; LLUUID agent_id; diff --git a/indra/newview/llhexeditor.cpp b/indra/newview/llhexeditor.cpp index ec8b3d50eeb6689ead905a13a46bb21620c71eb5..d1e497b2080e94a49aff6c66efec9a90b722e9bd 100644 --- a/indra/newview/llhexeditor.cpp +++ b/indra/newview/llhexeditor.cpp @@ -274,7 +274,7 @@ U32 LLHexEditor::getProperSelectionEnd() const return (mSelectionStart < mSelectionEnd) ? mSelectionEnd : mSelectionStart; } -BOOL LLHexEditor::handleScrollWheel(S32 x, S32 y, S32 clicks) const +BOOL LLHexEditor::handleScrollWheel(S32 x, S32 y, S32 clicks) { return mScrollbar->handleScrollWheel( 0, 0, clicks ); } diff --git a/indra/newview/llhexeditor.h b/indra/newview/llhexeditor.h index 9ff06d1e61417220282b9187b9af2629125c1de3..63d513336bcedafd42acc7b8915472deb9bb81e8 100644 --- a/indra/newview/llhexeditor.h +++ b/indra/newview/llhexeditor.h @@ -42,7 +42,7 @@ class LLHexEditor : public LLUICtrl, public LLEditMenuHandler void reshape(S32 width, S32 height, BOOL called_from_parent); void setFocus(BOOL b); - BOOL handleScrollWheel(S32 x, S32 y, S32 clicks) const; + BOOL handleScrollWheel(S32 x, S32 y, S32 clicks) override; BOOL handleMouseDown(S32 x, S32 y, MASK mask); BOOL handleHover(S32 x, S32 y, MASK mask); BOOL handleMouseUp(S32 x, S32 y, MASK mask); diff --git a/indra/newview/llhudeffectblob.cpp b/indra/newview/llhudeffectblob.cpp index 0e1395865dc4ba72dfc70ed8486059f1fc6b2a84..087abf24eff1364154d7dadb38f8728d4823ab00 100644 --- a/indra/newview/llhudeffectblob.cpp +++ b/indra/newview/llhudeffectblob.cpp @@ -64,7 +64,7 @@ void LLHUDEffectBlob::render() LLVector3 pixel_up, pixel_right; - LLViewerCamera::instanceFast().getPixelVectors(pos_agent, pixel_up, pixel_right); + LLViewerCamera::instance().getPixelVectors(pos_agent, pixel_up, pixel_right); LLGLSPipelineAlpha gls_pipeline_alpha; gGL.getTexUnit(0)->bind(mImage->getImage()); diff --git a/indra/newview/llhudicon.cpp b/indra/newview/llhudicon.cpp index 3c33fee1dca4782bd569590d0da39f970ea20706..ef20f577ab864c60d2cf79f2ffbccadd09d64c9d 100644 --- a/indra/newview/llhudicon.cpp +++ b/indra/newview/llhudicon.cpp @@ -99,7 +99,7 @@ void LLHUDIcon::renderIcon(BOOL for_select) // put icon above object, and in front // RN: don't use drawable radius, it's fricking HUGE - LLViewerCamera* camera = LLViewerCamera::getInstanceFast(); + LLViewerCamera* camera = LLViewerCamera::getInstance(); LLVector3 icon_relative_pos = (camera->getUpAxis() * ~mSourceObject->getRenderRotation()); icon_relative_pos.abs(); @@ -218,7 +218,7 @@ BOOL LLHUDIcon::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& // put icon above object, and in front // RN: don't use drawable radius, it's fricking HUGE - LLViewerCamera* camera = LLViewerCamera::getInstanceFast(); + LLViewerCamera* camera = LLViewerCamera::getInstance(); LLVector3 icon_relative_pos = (camera->getUpAxis() * ~mSourceObject->getRenderRotation()); icon_relative_pos.abs(); diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp index 09d9e66f1cf6d660aaf96ed3ba0353bf4925feed..dd20b7caa9c768d5f968efcca013a78cb3d37167 100644 --- a/indra/newview/llhudnametag.cpp +++ b/indra/newview/llhudnametag.cpp @@ -147,7 +147,7 @@ BOOL LLHUDNameTag::lineSegmentIntersect(const LLVector4a& start, const LLVector4 LLVector3 position = mPositionAgent; - auto& viewerCamera = LLViewerCamera::instanceFast(); + auto& viewerCamera = LLViewerCamera::instance(); if (mSourceObject) { //get intersection of eye through mPositionAgent to plane of source object @@ -226,6 +226,7 @@ BOOL LLHUDNameTag::lineSegmentIntersect(const LLVector4a& start, const LLVector4 void LLHUDNameTag::render() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; if (sDisplayText) { LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); @@ -291,7 +292,7 @@ void LLHUDNameTag::renderText(BOOL for_select) LLVector3 x_pixel_vec; LLVector3 y_pixel_vec; - LLViewerCamera::getInstanceFast()->getPixelVectors(mPositionAgent, y_pixel_vec, x_pixel_vec); + LLViewerCamera::getInstance()->getPixelVectors(mPositionAgent, y_pixel_vec, x_pixel_vec); LLVector3 width_vec = mWidth * x_pixel_vec; LLVector3 height_vec = mHeight * y_pixel_vec; @@ -299,7 +300,7 @@ void LLHUDNameTag::renderText(BOOL for_select) mRadius = (width_vec + height_vec).magVec() * 0.5f; LLCoordGL screen_pos; - LLViewerCamera::getInstanceFast()->projectPosAgentToScreen(mPositionAgent, screen_pos, FALSE); + LLViewerCamera::getInstance()->projectPosAgentToScreen(mPositionAgent, screen_pos, FALSE); LLVector2 screen_offset = updateScreenPos(mPositionOffset); @@ -326,8 +327,6 @@ void LLHUDNameTag::renderText(BOOL for_select) // Render label { - //gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); - for(std::vector<LLHUDTextSegment>::iterator segment_iter = mLabelSegments.begin(); segment_iter != mLabelSegments.end(); ++segment_iter ) { @@ -585,7 +584,7 @@ void LLHUDNameTag::updateVisibility() return; } - auto& viewerCamera = LLViewerCamera::instanceFast(); + auto& viewerCamera = LLViewerCamera::instance(); // push text towards camera by radius of object, but not past camera LLVector3 vec_from_camera = mPositionAgent - viewerCamera.getOrigin(); @@ -648,7 +647,7 @@ LLVector2 LLHUDNameTag::updateScreenPos(LLVector2 &offset) LLVector2 screen_pos_vec; LLVector3 x_pixel_vec; LLVector3 y_pixel_vec; - auto& viewerCamera = LLViewerCamera::instanceFast(); + auto& viewerCamera = LLViewerCamera::instance(); viewerCamera.getPixelVectors(mPositionAgent, y_pixel_vec, x_pixel_vec); LLVector3 world_pos = mPositionAgent + (offset.mV[VX] * x_pixel_vec) + (offset.mV[VY] * y_pixel_vec); @@ -739,6 +738,7 @@ void LLHUDNameTag::updateSize() void LLHUDNameTag::updateAll() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; // iterate over all text objects, calculate their restoration forces, // and add them to the visible set if they are on screen and close enough sVisibleTextObjects.clear(); diff --git a/indra/newview/llhudrender.cpp b/indra/newview/llhudrender.cpp index 9a9d98ed63a7914793e5e95f88eb5e48a1419ebe..151bd6cd0616a0264d739075b00d4ddda1cf447b 100644 --- a/indra/newview/llhudrender.cpp +++ b/indra/newview/llhudrender.cpp @@ -59,7 +59,7 @@ void hud_render_text(const LLWString &wstr, const LLVector3 &pos_agent, const LLColor4& color, const BOOL orthographic) { - LLViewerCamera* camera = LLViewerCamera::getInstanceFast(); + LLViewerCamera* camera = LLViewerCamera::getInstance(); // Do cheap plane culling LLVector3 dir_vec = pos_agent - camera->getOrigin(); dir_vec /= dir_vec.magVec(); diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp index 70f0a026c3552f0a6bb36bb0eccac21151e39534..7624a421755ce02436bd4fe9e24109b961fdd033 100644 --- a/indra/newview/llhudtext.cpp +++ b/indra/newview/llhudtext.cpp @@ -156,7 +156,7 @@ void LLHUDText::renderText() } else { - LLViewerCamera::getInstanceFast()->getPixelVectors(mPositionAgent, y_pixel_vec, x_pixel_vec); + LLViewerCamera::getInstance()->getPixelVectors(mPositionAgent, y_pixel_vec, x_pixel_vec); } LLVector3 width_vec = mWidth * x_pixel_vec; @@ -174,9 +174,6 @@ void LLHUDText::renderText() F32 y_offset = (F32)mOffsetY; // Render label - { - gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); - } // Render text { @@ -349,7 +346,7 @@ void LLHUDText::updateVisibility() #if 0 if (!mSourceObject) { - LL_WARNS() << "HUD text: mSourceObject is NULL, mOnHUDAttachment: " << mOnHUDAttachment << LL_ENDL; + // Beacons mVisible = TRUE; if (mOnHUDAttachment) { @@ -380,7 +377,7 @@ void LLHUDText::updateVisibility() } // push text towards camera by radius of object, but not past camera - auto& viewerCamera = LLViewerCamera::instanceFast(); + auto& viewerCamera = LLViewerCamera::instance(); LLVector3 vec_from_camera = mPositionAgent - viewerCamera.getOrigin(); LLVector3 dir_from_camera = vec_from_camera; dir_from_camera.normVec(); @@ -464,7 +461,7 @@ LLVector2 LLHUDText::updateScreenPos(const LLVector2 &offset) LLVector2 screen_pos_vec; // LLVector3 x_pixel_vec; // LLVector3 y_pixel_vec; -// LLViewerCamera::getInstanceFast()->getPixelVectors(mPositionAgent, y_pixel_vec, x_pixel_vec); +// LLViewerCamera::getInstance()->getPixelVectors(mPositionAgent, y_pixel_vec, x_pixel_vec); // LLVector3 world_pos = mPositionAgent + (offset.mV[VX] * x_pixel_vec) + (offset.mV[VY] * y_pixel_vec); // if (!LLViewerCamera::getInstance()->projectPosAgentToScreen(world_pos, screen_pos, FALSE) && mVisibleOffScreen) // { @@ -592,7 +589,6 @@ void LLHUDText::renderAllHUD() { LLGLState::checkStates(); LLGLState::checkTextureChannels(); - LLGLState::checkClientArrays(); { LLGLEnable color_mat(GL_COLOR_MATERIAL); @@ -610,7 +606,6 @@ void LLHUDText::renderAllHUD() LLGLState::checkStates(); LLGLState::checkTextureChannels(); - LLGLState::checkClientArrays(); } void LLHUDText::shiftAll(const LLVector3& offset) diff --git a/indra/newview/llimprocessing.cpp b/indra/newview/llimprocessing.cpp index 7538ad7b8d1f46f7a2d8fb29374edd1297f3bec3..9c8d5f38a44e7683096f6e5df90d7c2accc1bad6 100644 --- a/indra/newview/llimprocessing.cpp +++ b/indra/newview/llimprocessing.cpp @@ -184,8 +184,8 @@ void inventory_offer_handler(LLOfferInfo* info) // If muted, don't even go through the messaging stuff. Just curtail the offer here. // Passing in a null UUID handles the case of where you have muted one of your own objects by_name. // The solution for STORM-1297 seems to handle the cases where the object is owned by someone else. - if (LLMuteList::getInstanceFast()->isMuted(info->mFromID, info->mFromName) || - LLMuteList::getInstanceFast()->isMuted(LLUUID::null, info->mFromName)) + if (LLMuteList::getInstance()->isMuted(info->mFromID, info->mFromName) || + LLMuteList::getInstance()->isMuted(LLUUID::null, info->mFromName)) { info->forceResponse(IOR_MUTE); return; @@ -494,9 +494,9 @@ void LLIMProcessing::processNewMessage(LLUUID from_id, name = clean_name_from_im(name, dialog); BOOL is_do_not_disturb = gAgent.isDoNotDisturb(); - BOOL is_muted = LLMuteList::getInstanceFast()->isMuted(from_id, name, LLMute::flagTextChat) + BOOL is_muted = LLMuteList::getInstance()->isMuted(from_id, name, LLMute::flagTextChat) // object IMs contain sender object id in session_id (STORM-1209) - || (dialog == IM_FROM_TASK && LLMuteList::getInstanceFast()->isMuted(session_id)); + || (dialog == IM_FROM_TASK && LLMuteList::getInstance()->isMuted(session_id)); BOOL is_owned_by_me = FALSE; BOOL is_friend = (LLAvatarTracker::instance().getBuddyInfo(from_id) == NULL) ? false : true; BOOL accept_im_from_only_friend = gSavedPerAccountSettings.getBOOL("VoiceCallsFriendsOnly"); @@ -805,7 +805,7 @@ void LLIMProcessing::processNewMessage(LLUUID from_id, } } - if (agent_id.notNull() && LLMuteList::getInstanceFast()->isMuted(agent_id)) + if (agent_id.notNull() && LLMuteList::getInstance()->isMuted(agent_id)) { break; } @@ -887,7 +887,7 @@ void LLIMProcessing::processNewMessage(LLUUID from_id, // group is not blocked, but we still need to check agent that sent the invitation // and we have no agent's id // Note: server sends username "first.last". - is_muted |= LLMuteList::getInstanceFast()->isMuted(name); + is_muted |= LLMuteList::getInstance()->isMuted(name); } if (is_do_not_disturb || is_muted) { @@ -1676,7 +1676,7 @@ void LLIMProcessing::requestOfflineMessages() if (!requested && gMessageSystem && !gDisconnected - && LLMuteList::getInstanceFast()->isLoaded() + && LLMuteList::getInstance()->isLoaded() && isAgentAvatarValid() && gAgent.getRegion() && gAgent.getRegion()->capabilitiesReceived()) diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 3ec60ea148bd5ba9f51ee3d15065b1c4f5424339..c03c8658654e20cd204d2f54e557995505a1de41 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -314,7 +314,7 @@ void notify_of_message(const LLSD& msg, bool is_dnd_msg) || NOT_ON_TOP == conversations_floater_status)) || is_dnd_msg) { - if(!LLMuteList::getInstanceFast()->isMuted(participant_id)) + if(!LLMuteList::getInstance()->isMuted(participant_id)) { if(gAgent.isDoNotDisturb()) { @@ -343,7 +343,7 @@ void notify_of_message(const LLSD& msg, bool is_dnd_msg) && !is_session_focused && !is_dnd_msg) //prevent flashing FUI button because the conversation floater will have already opened { - if(!LLMuteList::getInstanceFast()->isMuted(participant_id)) + if(!LLMuteList::getInstance()->isMuted(participant_id)) { if(!gAgent.isDoNotDisturb()) { @@ -1203,7 +1203,7 @@ bool LLIMModel::addMessage(const LLUUID& session_id, const std::string& from, co //other places may be called from message history. if( !from_id.isNull() && ( session->isP2PSessionType() || session->isAdHocSessionType() ) ) - LLRecentPeople::instanceFast().add(from_id); + LLRecentPeople::instance().add(from_id); // notify listeners LLSD arg; @@ -1227,7 +1227,6 @@ LLIMModel::LLIMSession* LLIMModel::addMessageSilently(const LLUUID& session_id, if (!session) { - LL_WARNS() << "session " << session_id << "does not exist " << LL_ENDL; return NULL; } @@ -1497,7 +1496,7 @@ void LLIMModel::sendMessage(const std::string& utf8_text, case IM_LURE_USER: case IM_GODLIKE_LURE_USER: case IM_FRIENDSHIP_OFFERED: - LLMuteList::getInstanceFast()->autoRemove(other_participant_id, LLMuteList::AR_IM); + LLMuteList::getInstance()->autoRemove(other_participant_id, LLMuteList::AR_IM); break; default: ; // do nothing } @@ -1532,7 +1531,7 @@ void LLIMModel::sendMessage(const std::string& utf8_text, { if( session == 0)//??? shouldn't really happen { - LLRecentPeople::instanceFast().add(other_participant_id); + LLRecentPeople::instance().add(other_participant_id); return; } // IM_SESSION_INVITE means that this is an Ad-hoc incoming chat @@ -1552,7 +1551,7 @@ void LLIMModel::sendMessage(const std::string& utf8_text, // Add the recepient of the session. if (!session->mInitialTargetIDs.empty()) { - LLRecentPeople::instanceFast().add(*(session->mInitialTargetIDs.begin())); + LLRecentPeople::instance().add(*(session->mInitialTargetIDs.begin())); } } } @@ -1569,7 +1568,7 @@ void LLIMModel::addSpeakersToRecent(const LLUUID& im_session_id) for(LLSpeakerMgr::speaker_list_t::iterator it = speaker_list.begin(); it != speaker_list.end(); it++) { const LLPointer<LLSpeaker>& speakerp = *it; - LLRecentPeople::instanceFast().add(speakerp->mID); + LLRecentPeople::instance().add(speakerp->mID); } } @@ -2085,8 +2084,8 @@ void LLCallDialog::setIcon(const LLSD& session_id, const LLSD& participant_id) } else { - LL_WARNS() << "Participant neither avatar nor group" << LL_ENDL; - group_icon->setValue(session_id); + LL_WARNS() << "Participant neither avatar nor group" << LL_ENDL; + group_icon->setValue(session_id); } } @@ -2359,7 +2358,7 @@ BOOL LLIncomingCallDialog::postBuild() call_type = getString(notify_box_type); } - if (caller_name == "anonymous") // obsolete? Likely was part of avaline support + if (caller_name == "anonymous") // obsolete? Likely was part of avaline support { caller_name = getString("anonymous"); setCallerName(caller_name, caller_name, call_type); @@ -2809,7 +2808,7 @@ void LLIMMgr::addMessage( // if (!LLMuteList::getInstance()->isMuted(other_participant_id, LLMute::flagTextChat) && !skip_message) // [SL:KB] - Patch: Chat-Misc | Checked: 2014-05-01 (Catznip-3.6) - if (!LLMuteList::getInstanceFast()->isMuted(other_participant_id, LLMute::flagTextChat)) + if (!LLMuteList::getInstance()->isMuted(other_participant_id, LLMute::flagTextChat)) // [/SL:KB] { LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, msg, bonus); @@ -3152,14 +3151,14 @@ void LLIMMgr::inviteToSession( //ignore invites from muted residents if (!is_linden) { - if (LLMuteList::getInstanceFast()->isMuted(caller_id, LLMute::flagVoiceChat) + if (LLMuteList::getInstance()->isMuted(caller_id, LLMute::flagVoiceChat) && voice_invite && "VoiceInviteQuestionDefault" == question_type) { LL_INFOS("IMVIEW") << "Rejecting voice call from initiating muted resident " << caller_name << LL_ENDL; LLIncomingCallDialog::processCallResponse(1, payload); return; } - else if (LLMuteList::getInstanceFast()->isMuted(caller_id, LLMute::flagAll & ~LLMute::flagVoiceChat) && !voice_invite) + else if (LLMuteList::getInstance()->isMuted(caller_id, LLMute::flagAll & ~LLMute::flagVoiceChat) && !voice_invite) { LL_INFOS("IMVIEW") << "Rejecting session invite from initiating muted resident " << caller_name << LL_ENDL; return; @@ -3237,7 +3236,7 @@ void LLIMMgr::inviteToSession( // the call, the caller should be added to the recent list // anyway. STORM-507. if(type == IM_SESSION_P2P_INVITE) - LLRecentPeople::instanceFast().add(caller_id); + LLRecentPeople::instance().add(caller_id); mPendingInvitations[session_id.asString()] = LLSD(); } @@ -3567,7 +3566,7 @@ void LLIMMgr::noteMutedUsers(const LLUUID& session_id, const std::vector<LLUUID>& ids) { // Don't do this if we don't have a mute list. - LLMuteList *ml = LLMuteList::getInstanceFast(); + LLMuteList *ml = LLMuteList::getInstance(); if( !ml ) { return; @@ -3790,7 +3789,7 @@ class LLViewerChatterBoxInvitation : public LLHTTPNode BOOL is_do_not_disturb = gAgent.isDoNotDisturb(); // [SL:KB] - Patch: Chat-GroupOptions | Checked: 2012-06-21 (Catznip-3.3) - BOOL is_muted = LLMuteList::getInstanceFast()->isMuted(from_id, LLMute::flagTextChat); + BOOL is_muted = LLMuteList::getInstance()->isMuted(from_id, LLMute::flagTextChat); BOOL is_group = gAgent.isInGroup(session_id); // Just return if the user is currently marked DnD or if the group session was started by someone on the mute list (we'll get another invitation later) @@ -3888,7 +3887,7 @@ class LLViewerChatterBoxInvitation : public LLHTTPNode ll_vector3_from_sd(message_params["position"]), true); - if (LLMuteList::getInstanceFast()->isMuted(from_id, name, LLMute::flagTextChat)) + if (LLMuteList::getInstance()->isMuted(from_id, name, LLMute::flagTextChat)) { return; } diff --git a/indra/newview/llinspect.cpp b/indra/newview/llinspect.cpp index 28fee7d65fae18a38a1752a70dff24e4a4a89f11..43d95f4dea550b2580d16e240744da39a94a6e59 100644 --- a/indra/newview/llinspect.cpp +++ b/indra/newview/llinspect.cpp @@ -114,8 +114,8 @@ BOOL LLInspect::handleToolTip(S32 x, S32 y, MASK mask) params.message = child_handler->getToolTip(); //set up delay if there is no visible tooltip at this moment static LLUICachedControl<F32> tool_tip_delay("ToolTipDelay", 0.69999f); - params.delay_time = LLToolTipMgr::instanceFast().toolTipVisible() ? 0.f : tool_tip_delay; - LLToolTipMgr::instanceFast().show(params); + params.delay_time = LLToolTipMgr::instance().toolTipVisible() ? 0.f : tool_tip_delay; + LLToolTipMgr::instance().show(params); handled = TRUE; } return handled; diff --git a/indra/newview/llinspectavatar.cpp b/indra/newview/llinspectavatar.cpp index c702326dfd84388642c6d31a1b6105c529b68b4e..b11c440015061cdf946380e59e06be034a54b26e 100644 --- a/indra/newview/llinspectavatar.cpp +++ b/indra/newview/llinspectavatar.cpp @@ -119,7 +119,7 @@ class LLFetchAvatarData : public LLAvatarPropertiesObserver mInspector(inspector) { LLAvatarPropertiesProcessor* processor = - LLAvatarPropertiesProcessor::getInstanceFast(); + LLAvatarPropertiesProcessor::getInstance(); // register ourselves as an observer processor->addObserver(mAvatarID, this); // send a request (duplicates will be suppressed inside the avatar @@ -130,7 +130,7 @@ class LLFetchAvatarData : public LLAvatarPropertiesObserver ~LLFetchAvatarData() { // remove ourselves as an observer - LLAvatarPropertiesProcessor::getInstanceFast()-> + LLAvatarPropertiesProcessor::getInstance()-> removeObserver(mAvatarID, this); } @@ -337,7 +337,7 @@ void LLInspectAvatar::onClickMuteVolume() LLMuteList* mute_list = LLMuteList::getInstance(); bool is_muted = mute_list->isMuted(mAvatarID, LLMute::flagVoiceChat); - LLMute mute(mAvatarID, mAvatarName.getDisplayName(), LLMute::AGENT); + LLMute mute(mAvatarID, mAvatarName.getUserName(), LLMute::AGENT); if (!is_muted) { mute_list->add(mute, LLMute::flagVoiceChat); diff --git a/indra/newview/llinspectobject.cpp b/indra/newview/llinspectobject.cpp index 95c670222869318476070da67b06568c4002f5f6..aa818c6488228d60859f7b3a328fe69f462001cb 100644 --- a/indra/newview/llinspectobject.cpp +++ b/indra/newview/llinspectobject.cpp @@ -28,16 +28,17 @@ #include "llinspectobject.h" // Viewer +#include "llagent.h" // To standup #include "llfloatersidepanelcontainer.h" #include "llinspect.h" #include "llmediaentry.h" -#include "llnotificationsutil.h" // *TODO: Eliminate, add LLNotificationsUtil wrapper #include "llselectmgr.h" #include "llslurl.h" #include "llviewermenu.h" // handle_object_touch(), handle_buy() #include "llviewermedia.h" #include "llviewermediafocus.h" #include "llviewerobjectlist.h" // to select the requested object +#include "llvoavatarself.h" // [RLVa:KB] - Checked: 2010-02-27 (RLVa-1.2.0c) #include "rlvactions.h" #include "rlvcommon.h" @@ -180,7 +181,7 @@ BOOL LLInspectObject::postBuild(void) boost::bind(&LLInspectObject::onClickMoreInfo, this)); // Watch for updates to selection properties off the network - LLSelectMgr::getInstanceFast()->mUpdateSignal.connect( + LLSelectMgr::getInstance()->mUpdateSignal.connect( boost::bind(&LLInspectObject::update, this) ); return TRUE; @@ -213,8 +214,8 @@ void LLInspectObject::onOpen(const LLSD& data) // Make sure any media is unfocused before changing the selection here. LLViewerMediaFocus::getInstance()->clearFocus(); - LLSelectMgr::instanceFast().deselectAll(); - mObjectSelection = LLSelectMgr::instanceFast().selectObjectAndFamily(obj,FALSE,TRUE); + LLSelectMgr::instance().deselectAll(); + mObjectSelection = LLSelectMgr::instance().selectObjectAndFamily(obj,FALSE,TRUE); // Mark this as a transient selection struct SetTransient : public LLSelectedNodeFunctor @@ -236,7 +237,7 @@ void LLInspectObject::onOpen(const LLSD& data) if(!mMediaEntry) return; - mMediaImpl = LLViewerMedia::getInstanceFast()->getMediaImplFromTextureID(mMediaEntry->getMediaID()); + mMediaImpl = LLViewerMedia::getInstance()->getMediaImplFromTextureID(mMediaEntry->getMediaID()); } } @@ -257,7 +258,7 @@ void LLInspectObject::update() // but we're never destroyed. if (!getVisible()) return; - LLObjectSelection* selection = LLSelectMgr::getInstanceFast()->getSelection(); + LLObjectSelection* selection = LLSelectMgr::getInstance()->getSelection(); if (!selection) return; LLSelectNode* nodep = selection->getFirstRootNode(); @@ -295,7 +296,7 @@ void LLInspectObject::update() if(!mMediaEntry) return; - mMediaImpl = LLViewerMedia::getInstanceFast()->getMediaImplFromTextureID(mMediaEntry->getMediaID()); + mMediaImpl = LLViewerMedia::getInstance()->getMediaImplFromTextureID(mMediaEntry->getMediaID()); updateMediaCurrentURL(); updateSecureBrowsing(); @@ -623,7 +624,7 @@ void LLInspectObject::onClickPay() void LLInspectObject::onClickTakeFreeCopy() { - LLObjectSelection* selection = LLSelectMgr::getInstanceFast()->getSelection(); + LLObjectSelection* selection = LLSelectMgr::getInstance()->getSelection(); if (!selection) return; LLSelectNode* nodep = selection->getFirstRootNode(); @@ -652,7 +653,31 @@ void LLInspectObject::onClickTouch() void LLInspectObject::onClickSit() { - handle_object_sit_or_stand(); + bool is_sitting = false; + if (mObjectSelection) + { + LLSelectNode* node = mObjectSelection->getFirstRootNode(); + if (node && node->mValid) + { + LLViewerObject* root_object = node->getObject(); + if (root_object + && isAgentAvatarValid() + && gAgentAvatarp->isSitting() + && gAgentAvatarp->getRoot() == root_object) + { + is_sitting = true; + } + } + } + + if (is_sitting) + { + gAgent.standUp(); + } + else + { + handle_object_sit(mObjectID); + } closeFloater(); } diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index dc3d4b0c92c72ab11eea5aefc5bf5d13ad9fb32f..de9ee65cfd1b877bd01dbbb229bdd296252df4ba 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -849,6 +849,19 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, // disabled_items.push_back(std::string("Copy")); // } + if (isAgentInventory()) + { + items.push_back(std::string("New folder from selected")); + items.push_back(std::string("Subfolder Separator")); + std::set<LLUUID> selected_uuid_set = LLAvatarActions::getInventorySelectedUUIDs(); + uuid_vec_t ids; + std::copy(selected_uuid_set.begin(), selected_uuid_set.end(), std::back_inserter(ids)); + if (!is_only_items_selected(ids) && !is_only_cats_selected(ids)) + { + disabled_items.push_back(std::string("New folder from selected")); + } + } + if (obj->getIsLinkType()) { items.push_back(std::string("Find Original")); @@ -1211,7 +1224,10 @@ void LLInvFVBridge::addMarketplaceContextMenuOptions(U32 flags, LLInventoryModel::cat_array_t categories; LLInventoryModel::item_array_t items; gInventory.collectDescendents(local_version_folder_id, categories, items, FALSE); - if (categories.size() >= gSavedSettings.getU32("InventoryOutboxMaxFolderCount")) + LLCachedControl<U32> max_depth(gSavedSettings, "InventoryOutboxMaxFolderDepth", 4); + LLCachedControl<U32> max_count(gSavedSettings, "InventoryOutboxMaxFolderCount", 20); + if (categories.size() >= max_count + || depth > (max_depth + 1)) { disabled_items.push_back(std::string("New Folder")); } @@ -4010,7 +4026,20 @@ void LLFolderBridge::perform_pasteFromClipboard() { if (item && can_move_to_landmarks(item)) { - dropToFavorites(item); + if (LLClipboard::instance().isCutMode()) + { + LLViewerInventoryItem* viitem = dynamic_cast<LLViewerInventoryItem*>(item); + llassert(viitem); + if (viitem) + { + //changeItemParent() implicity calls dirtyFilter + changeItemParent(model, viitem, parent_id, FALSE); + } + } + else + { + dropToFavorites(item); + } } } else if (LLClipboard::instance().isCutMode()) @@ -4485,7 +4514,16 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags, menuentry_vec_t& items.push_back(std::string("Conference Chat Folder")); items.push_back(std::string("IM All Contacts In Folder")); } + + if (((flags & ITEM_IN_MULTI_SELECTION) == 0) && hasChildren()) + { + items.push_back(std::string("Ungroup folder items")); + } } + else + { + disabled_items.push_back(std::string("New folder from selected")); + } #ifndef LL_RELEASE_FOR_DOWNLOAD if (LLFolderType::lookupIsProtectedType(type) && is_agent_inventory) @@ -6032,14 +6070,14 @@ class LLCallingCardObserver : public LLFriendObserver public: LLCallingCardObserver(LLCallingCardBridge* bridge) : mBridgep(bridge) {} virtual ~LLCallingCardObserver() { mBridgep = NULL; } - virtual void changed(U32 mask) - { - mBridgep->refreshFolderViewItem(); - if (mask & LLFriendObserver::ONLINE) - { - mBridgep->checkSearchBySuffixChanges(); - } - } + virtual void changed(U32 mask) + { + if (mask & LLFriendObserver::ONLINE) + { + mBridgep->refreshFolderViewItem(); + mBridgep->checkSearchBySuffixChanges(); + } + } protected: LLCallingCardBridge* mBridgep; }; @@ -6053,14 +6091,16 @@ LLCallingCardBridge::LLCallingCardBridge(LLInventoryPanel* inventory, const LLUUID& uuid ) : LLItemBridge(inventory, root, uuid) { - mObserver = new LLCallingCardObserver(this); - LLAvatarTracker::instance().addObserver(mObserver); + mObserver = new LLCallingCardObserver(this); + mCreatorUUID = getItem()->getCreatorUUID(); + LLAvatarTracker::instance().addParticularFriendObserver(mCreatorUUID, mObserver); } LLCallingCardBridge::~LLCallingCardBridge() { - LLAvatarTracker::instance().removeObserver(mObserver); - delete mObserver; + LLAvatarTracker::instance().removeParticularFriendObserver(mCreatorUUID, mObserver); + + delete mObserver; } void LLCallingCardBridge::refreshFolderViewItem() @@ -7044,10 +7084,10 @@ BOOL LLObjectBridge::renameItem(const std::string& new_name) LLViewerObject* obj = gAgentAvatarp->getWornAttachment( item->getUUID() ); if(obj) { - LLSelectMgr::getInstanceFast()->deselectAll(); - LLSelectMgr::getInstanceFast()->addAsIndividual( obj, SELECT_ALL_TES, FALSE ); - LLSelectMgr::getInstanceFast()->selectionSetObjectName( new_name ); - LLSelectMgr::getInstanceFast()->deselectAll(); + LLSelectMgr::getInstance()->deselectAll(); + LLSelectMgr::getInstance()->addAsIndividual( obj, SELECT_ALL_TES, FALSE ); + LLSelectMgr::getInstance()->selectionSetObjectName( new_name ); + LLSelectMgr::getInstance()->deselectAll(); } } } @@ -7256,7 +7296,7 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags) // [/RLVa:KB] } - if (LLWearableType::getInstanceFast()->getAllowMultiwear(mWearableType)) + if (LLWearableType::getInstance()->getAllowMultiwear(mWearableType)) { items.push_back(std::string("Wearable Add")); // if (!gAgentWearables.canAddWearable(mWearableType)) diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index 17614137995c69e08940a74f391473a80f6cd759..21c12cfee388442e235b5324aac9376b3017c42c 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -468,6 +468,7 @@ class LLCallingCardBridge : public LLItemBridge void checkSearchBySuffixChanges(); protected: LLCallingCardObserver* mObserver; + LLUUID mCreatorUUID; }; class LLNotecardBridge : public LLItemBridge diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp index 8dbd7f6d7d01a495790e8f81cb3b33436b0247c0..1c759868cc29deb5703698764e12801455bc82aa 100644 --- a/indra/newview/llinventoryfilter.cpp +++ b/indra/newview/llinventoryfilter.cpp @@ -49,8 +49,6 @@ #include "llclipboard.h" #include "lltrans.h" -LLTrace::BlockTimerStatHandle FT_FILTER_CLIPBOARD("Filter Clipboard"); - LLInventoryFilter::FilterOps::FilterOps(const Params& p) : mFilterObjectTypes(p.object_types), mFilterCategoryTypes(p.category_types), @@ -513,7 +511,7 @@ bool LLInventoryFilter::checkAgainstClipboard(const LLUUID& object_id) const { if (LLClipboard::instance().isCutMode()) { - LL_RECORD_BLOCK_TIME(FT_FILTER_CLIPBOARD); + LL_PROFILE_ZONE_SCOPED; LLUUID current_id = object_id; LLInventoryObject *current_object = gInventory.getObject(object_id); while (current_id.notNull() && current_object) @@ -1415,7 +1413,7 @@ const std::string& LLInventoryFilter::getFilterText() filtered_by_all_types = FALSE; } - if (!LLInventoryModelBackgroundFetch::instanceFast().folderFetchActive() + if (!LLInventoryModelBackgroundFetch::instance().folderFetchActive() && filtered_by_type && !filtered_by_all_types) { diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 9b23e76e0753dc2bea2b9693e92956e2d3eb6919..ce1048f2c266993008d8a168bef7867b144acd25 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1930,6 +1930,86 @@ void change_item_parent(const LLUUID& item_id, const LLUUID& new_parent_id) } } +void move_items_to_folder(const LLUUID& new_cat_uuid, const uuid_vec_t& selected_uuids) +{ + for (uuid_vec_t::const_iterator it = selected_uuids.begin(); it != selected_uuids.end(); ++it) + { + LLInventoryItem* inv_item = gInventory.getItem(*it); + if (inv_item) + { + change_item_parent(*it, new_cat_uuid); + } + else + { + LLInventoryCategory* inv_cat = gInventory.getCategory(*it); + if (inv_cat && !LLFolderType::lookupIsProtectedType(inv_cat->getPreferredType())) + { + gInventory.changeCategoryParent((LLViewerInventoryCategory*)inv_cat, new_cat_uuid, false); + } + } + } + + LLFloater* floater_inventory = LLFloaterReg::getInstance("inventory"); + if (!floater_inventory) + { + LL_WARNS() << "Could not find My Inventory floater" << LL_ENDL; + return; + } + LLSidepanelInventory *sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory"); + if (sidepanel_inventory) + { + if (sidepanel_inventory->getActivePanel()) + { + sidepanel_inventory->getActivePanel()->setSelection(new_cat_uuid, TAKE_FOCUS_YES); + LLFolderViewItem* fv_folder = sidepanel_inventory->getActivePanel()->getItemByID(new_cat_uuid); + if (fv_folder) + { + fv_folder->setOpen(TRUE); + } + } + } +} + +bool is_only_cats_selected(const uuid_vec_t& selected_uuids) +{ + for (uuid_vec_t::const_iterator it = selected_uuids.begin(); it != selected_uuids.end(); ++it) + { + LLInventoryCategory* inv_cat = gInventory.getCategory(*it); + if (!inv_cat) + { + return false; + } + } + return true; +} + +bool is_only_items_selected(const uuid_vec_t& selected_uuids) +{ + for (uuid_vec_t::const_iterator it = selected_uuids.begin(); it != selected_uuids.end(); ++it) + { + LLViewerInventoryItem* inv_item = gInventory.getItem(*it); + if (!inv_item) + { + return false; + } + } + return true; +} + + +void move_items_to_new_subfolder(const uuid_vec_t& selected_uuids, const std::string& folder_name) +{ + LLInventoryObject* first_item = gInventory.getObject(*selected_uuids.begin()); + if (!first_item) + { + return; + } + + inventory_func_type func = boost::bind(&move_items_to_folder, _1, selected_uuids); + gInventory.createNewCategory(first_item->getParentUUID(), LLFolderType::FT_NONE, folder_name, func); + +} + ///---------------------------------------------------------------------------- /// LLInventoryCollectFunctor implementations ///---------------------------------------------------------------------------- @@ -2584,6 +2664,81 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root { (new LLDirPickerThread(boost::bind(&LLInventoryAction::saveMultipleTextures, _1, selected_items, model), std::string()))->getFile(); } + else if ("new_folder_from_selected" == action) + { + + LLInventoryObject* first_item = gInventory.getObject(*ids.begin()); + if (!first_item) + { + return; + } + const LLUUID& parent_uuid = first_item->getParentUUID(); + for (uuid_vec_t::const_iterator it = ids.begin(); it != ids.end(); ++it) + { + LLInventoryObject *item = gInventory.getObject(*it); + if (!item || item->getParentUUID() != parent_uuid) + { + LLNotificationsUtil::add("SameFolderRequired"); + return; + } + } + + LLSD args; + args["DESC"] = LLTrans::getString("New Folder"); + + LLNotificationsUtil::add("CreateSubfolder", args, LLSD(), + [ids](const LLSD& notification, const LLSD& response) + { + S32 opt = LLNotificationsUtil::getSelectedOption(notification, response); + if (opt == 0) + { + std::string settings_name = response["message"].asString(); + + LLInventoryObject::correctInventoryName(settings_name); + if (settings_name.empty()) + { + settings_name = LLTrans::getString("New Folder"); + } + move_items_to_new_subfolder(ids, settings_name); + } + }); + } + else if ("ungroup_folder_items" == action) + { + if (selected_uuid_set.size() == 1) + { + LLInventoryCategory* inv_cat = gInventory.getCategory(*ids.begin()); + if (!inv_cat || LLFolderType::lookupIsProtectedType(inv_cat->getPreferredType())) + { + return; + } + const LLUUID &new_cat_uuid = inv_cat->getParentUUID(); + LLInventoryModel::cat_array_t* cat_array; + LLInventoryModel::item_array_t* item_array; + gInventory.getDirectDescendentsOf(inv_cat->getUUID(), cat_array, item_array); + LLInventoryModel::cat_array_t cats = *cat_array; + LLInventoryModel::item_array_t items = *item_array; + + for (LLInventoryModel::cat_array_t::const_iterator cat_iter = cats.begin(); cat_iter != cats.end(); ++cat_iter) + { + LLViewerInventoryCategory* cat = *cat_iter; + if (cat) + { + gInventory.changeCategoryParent(cat, new_cat_uuid, false); + } + } + for (LLInventoryModel::item_array_t::const_iterator item_iter = items.begin(); item_iter != items.end(); ++item_iter) + { + LLViewerInventoryItem* item = *item_iter; + if(item) + { + gInventory.changeItemParent(item, new_cat_uuid, false); + } + } + gInventory.removeCategory(inv_cat->getUUID()); + gInventory.notifyObservers(); + } + } else { std::set<LLFolderViewItem*>::iterator set_iter; diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h index fe8412f67e63d95d79447e0e32473e7e0041f70f..354276a16e967b941b206bad60be9ce76e91ffa1 100644 --- a/indra/newview/llinventoryfunctions.h +++ b/indra/newview/llinventoryfunctions.h @@ -103,6 +103,10 @@ LLUUID nested_parent_id(LLUUID cur_uuid, S32 depth); S32 compute_stock_count(LLUUID cat_uuid, bool force_count = false); void change_item_parent(const LLUUID& item_id, const LLUUID& new_parent_id); +void move_items_to_new_subfolder(const uuid_vec_t& selected_uuids, const std::string& folder_name); +void move_items_to_folder(const LLUUID& new_cat_uuid, const uuid_vec_t& selected_uuids); +bool is_only_cats_selected(const uuid_vec_t& selected_uuids); +bool is_only_items_selected(const uuid_vec_t& selected_uuids); /** Miscellaneous global functions ** ** diff --git a/indra/newview/llinventoryicon.cpp b/indra/newview/llinventoryicon.cpp index 2042fa728b728142506e8622a82791076bc3b363..df7dca0737fad6ff11873dabfc03d48b4c38fc24 100644 --- a/indra/newview/llinventoryicon.cpp +++ b/indra/newview/llinventoryicon.cpp @@ -190,14 +190,14 @@ const std::string& LLInventoryIcon::getIconName(LLAssetType::EType asset_type, const std::string& LLInventoryIcon::getIconName(LLInventoryType::EIconName idx) { - const IconEntry *entry = LLIconDictionary::instanceFast().lookup(idx); + const IconEntry *entry = LLIconDictionary::instance().lookup(idx); return entry->mName; } LLInventoryType::EIconName LLInventoryIcon::assignWearableIcon(U32 misc_flag) { const LLWearableType::EType wearable_type = LLWearableType::inventoryFlagsToWearableType(misc_flag); - return LLWearableType::getInstanceFast()->getIconName(wearable_type); + return LLWearableType::getInstance()->getIconName(wearable_type); } LLInventoryType::EIconName LLInventoryIcon::assignSettingsIcon(U32 misc_flag) diff --git a/indra/newview/llinventoryitemslist.cpp b/indra/newview/llinventoryitemslist.cpp index 1dc1aa395e0de7e9da2ca75b7deb50373ce716ed..23129f7d441e1a38abe4e0ed076e64d71de63d16 100644 --- a/indra/newview/llinventoryitemslist.cpp +++ b/indra/newview/llinventoryitemslist.cpp @@ -133,11 +133,9 @@ void LLInventoryItemsList::idle(void* user_data) } } -LLTrace::BlockTimerStatHandle FTM_INVENTORY_ITEMS_REFRESH("Inventory List Refresh"); - void LLInventoryItemsList::refresh() { - LL_RECORD_BLOCK_TIME(FTM_INVENTORY_ITEMS_REFRESH); + LL_PROFILE_ZONE_SCOPED; switch (mRefreshState) { diff --git a/indra/newview/llinventorylistitem.cpp b/indra/newview/llinventorylistitem.cpp index 12bb609df8c5cc4c1776ffd5861407415419912f..de6a850b5705ad221a8ec77c9db95e42c71075e2 100644 --- a/indra/newview/llinventorylistitem.cpp +++ b/indra/newview/llinventorylistitem.cpp @@ -298,31 +298,41 @@ LLPanelInventoryListItemBase::LLPanelInventoryListItemBase(LLViewerInventoryItem applyXUILayout(icon_params, this); mIconCtrl = LLUICtrlFactory::create<LLIconCtrl>(icon_params); - if (mIconCtrl) - { - addChild(mIconCtrl); - } - else + if (!mIconCtrl) { LLIconCtrl::Params icon_params; icon_params.name = "item_icon"; mIconCtrl = LLUICtrlFactory::create<LLIconCtrl>(icon_params); } + if (mIconCtrl) + { + addChild(mIconCtrl); + } + else + { + LL_ERRS() << "Failed to create mIconCtrl" << LL_ENDL; + } + LLTextBox::Params text_params(params.item_name); applyXUILayout(text_params, this); mTitleCtrl = LLUICtrlFactory::create<LLTextBox>(text_params); - if (mTitleCtrl) + if (!mTitleCtrl) { - addChild(mTitleCtrl); - } - else - { - LLTextBox::Params text_aprams; + LLTextBox::Params text_params; text_params.name = "item_title"; mTitleCtrl = LLUICtrlFactory::create<LLTextBox>(text_params); } + + if (mTitleCtrl) + { + addChild(mTitleCtrl); + } + else + { + LL_ERRS() << "Failed to create mTitleCtrl" << LL_ENDL; + } } class WidgetVisibilityChanger diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index d2039136c6e64dce3aa14c3628d7cbbac5d8a5fb..4976cd5b39768ed2c4a2317b972591bb49f70280 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -139,15 +139,7 @@ bool LLCanCache::operator()(LLInventoryCategory* cat, LLInventoryItem* item) ///---------------------------------------------------------------------------- /// Class LLInventoryValidationInfo ///---------------------------------------------------------------------------- -LLInventoryValidationInfo::LLInventoryValidationInfo(): - mFatalErrorCount(0), - mWarningCount(0), - mLoopCount(0), - mOrphanedCount(0), - mInitialized(false), - mFatalNoRootFolder(false), - mFatalNoLibraryRootFolder(false), - mFatalQADebugMode(false) +LLInventoryValidationInfo::LLInventoryValidationInfo() { } @@ -169,7 +161,6 @@ std::ostream& operator<<(std::ostream& os, const LLInventoryValidationInfo& v) void LLInventoryValidationInfo::asLLSD(LLSD& sd) const { sd["fatal_error_count"] = mFatalErrorCount; - sd["warning_count"] = mWarningCount; sd["loop_count"] = mLoopCount; sd["orphaned_count"] = mOrphanedCount; sd["initialized"] = mInitialized; @@ -177,6 +168,20 @@ void LLInventoryValidationInfo::asLLSD(LLSD& sd) const sd["fatal_no_root_folder"] = mFatalNoRootFolder; sd["fatal_no_library_root_folder"] = mFatalNoLibraryRootFolder; sd["fatal_qa_debug_mode"] = mFatalQADebugMode; + + sd["warning_count"] = mWarningCount; + if (mWarningCount>0) + { + sd["warnings"] = LLSD::emptyArray(); + for (auto const& it : mWarnings) + { + S32 val =LLSD::Integer(it.second); + if (val>0) + { + sd["warnings"][it.first] = val; + } + } + } if (mMissingRequiredSystemFolders.size()>0) { sd["missing_system_folders"] = LLSD::emptyArray(); @@ -367,13 +372,13 @@ const LLViewerInventoryCategory* LLInventoryModel::getFirstDescendantOf(const LL return NULL; } -LLInventoryModel::EAnscestorResult LLInventoryModel::getObjectTopmostAncestor(const LLUUID& object_id, LLUUID& result) const +LLInventoryModel::EAncestorResult LLInventoryModel::getObjectTopmostAncestor(const LLUUID& object_id, LLUUID& result) const { LLInventoryObject *object = getObject(object_id); if (!object) { LL_WARNS(LOG_INV) << "Unable to trace topmost ancestor, initial object " << object_id << " does not exist" << LL_ENDL; - return ANSCESTOR_MISSING; + return ANCESTOR_MISSING; } std::set<LLUUID> object_ids{ object_id }; // loop protection @@ -383,19 +388,19 @@ LLInventoryModel::EAnscestorResult LLInventoryModel::getObjectTopmostAncestor(co if (object_ids.find(parent_id) != object_ids.end()) { LL_WARNS(LOG_INV) << "Detected a loop on an object " << parent_id << " when searching for ancestor of " << object_id << LL_ENDL; - return ANSCESTOR_LOOP; + return ANCESTOR_LOOP; } object_ids.insert(parent_id); LLInventoryObject *parent_object = getObject(parent_id); if (!parent_object) { LL_WARNS(LOG_INV) << "unable to trace topmost ancestor of " << object_id << ", missing item for uuid " << parent_id << LL_ENDL; - return ANSCESTOR_MISSING; + return ANCESTOR_MISSING; } object = parent_object; } result = object->getUUID(); - return ANSCESTOR_OK; + return ANCESTOR_OK; } // Get the object by id. Returns NULL if not found. @@ -564,9 +569,18 @@ void LLInventoryModel::consolidateForType(const LLUUID& main_id, LLFolderType::E LLViewerInventoryCategory* cat = getCategory(*it); changeCategoryParent(cat, main_id, TRUE); } - + // Purge the emptied folder - removeCategory(folder_id); + // Note that this might be a system folder, don't validate removability + LLViewerInventoryCategory* cat = getCategory(folder_id); + if (cat) + { + const LLUUID trash_id = findCategoryUUIDForType(LLFolderType::FT_TRASH); + if (trash_id.notNull()) + { + changeCategoryParent(cat, trash_id, TRUE); + } + } remove_inventory_category(folder_id, NULL); } } @@ -3285,7 +3299,6 @@ bool LLInventoryModel::messageUpdateCore(LLMessageSystem* msg, bool account, U32 gInventory.accountForUpdate(update); } - U32 changes = 0x0; if (account) { mask |= LLInventoryObserver::CREATE; @@ -3293,7 +3306,7 @@ bool LLInventoryModel::messageUpdateCore(LLMessageSystem* msg, bool account, U32 //as above, this loop never seems to loop more than once per call for (item_array_t::iterator it = items.begin(); it != items.end(); ++it) { - changes |= gInventory.updateItem(*it, mask); + gInventory.updateItem(*it, mask); } gInventory.notifyObservers(); gViewerWindow->getWindow()->decBusyCount(); @@ -4168,9 +4181,9 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const { LLPointer<LLInventoryValidationInfo> validation_info = new LLInventoryValidationInfo; S32 fatal_errs = 0; - S32 warnings = 0; - S32 loops = 0; - S32 orphaned = 0; + S32 warning_count= 0; + S32 loop_count = 0; + S32 orphaned_count = 0; if (getRootFolderID().isNull()) { @@ -4191,7 +4204,9 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const // ParentChild should be one larger because of the special entry for null uuid. LL_INFOS("Inventory") << "unexpected sizes: cat map size " << mCategoryMap.size() << " parent/child " << mParentChildCategoryTree.size() << LL_ENDL; - warnings++; + + validation_info->mWarnings["category_map_size"]++; + warning_count++; } S32 cat_lock = 0; S32 item_lock = 0; @@ -4210,32 +4225,35 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const if (!cat) { LL_WARNS("Inventory") << "null cat" << LL_ENDL; - warnings++; + validation_info->mWarnings["null_cat"]++; + warning_count++; continue; } LLUUID topmost_ancestor_id; // Will leave as null uuid on failure - EAnscestorResult res = getObjectTopmostAncestor(cat_id, topmost_ancestor_id); + EAncestorResult res = getObjectTopmostAncestor(cat_id, topmost_ancestor_id); switch (res) { - case ANSCESTOR_MISSING: - orphaned++; + case ANCESTOR_MISSING: + orphaned_count++; break; - case ANSCESTOR_LOOP: - loops++; + case ANCESTOR_LOOP: + loop_count++; break; - case ANSCESTOR_OK: + case ANCESTOR_OK: break; default: LL_WARNS("Inventory") << "Unknown ancestor error for " << cat_id << LL_ENDL; - warnings++; + validation_info->mWarnings["unknown_ancestor_status"]++; + warning_count++; break; } if (cat_id != cat->getUUID()) { LL_WARNS("Inventory") << "cat id/index mismatch " << cat_id << " " << cat->getUUID() << LL_ENDL; - warnings++; + validation_info->mWarnings["cat_id_index_mismatch"]++; + warning_count++; } if (cat->getParentUUID().isNull()) @@ -4245,7 +4263,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const LL_WARNS("Inventory") << "cat " << cat_id << " has no parent, but is not root (" << getRootFolderID() << ") or library root (" << getLibraryRootFolderID() << ")" << LL_ENDL; - warnings++; + validation_info->mWarnings["null_parent"]++; + warning_count++; } } cat_array_t* cats; @@ -4254,7 +4273,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const if (!cats || !items) { LL_WARNS("Inventory") << "invalid direct descendents for " << cat_id << LL_ENDL; - warnings++; + validation_info->mWarnings["direct_descendents"]++; + warning_count++; continue; } if (cat->getDescendentCount() == LLViewerInventoryCategory::DESCENDENT_COUNT_UNKNOWN) @@ -4272,7 +4292,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const << " cached " << cat->getDescendentCount() << " expected " << cats->size() << "+" << items->size() << "=" << cats->size() +items->size() << LL_ENDL; - warnings++; + validation_info->mWarnings["invalid_descendent_count"]++; + warning_count++; } } if (cat->getVersion() == LLViewerInventoryCategory::VERSION_UNKNOWN) @@ -4296,7 +4317,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const if (!item) { LL_WARNS("Inventory") << "null item at index " << i << " for cat " << cat_id << LL_ENDL; - warnings++; + validation_info->mWarnings["null_item_at_index"]++; + warning_count++; continue; } @@ -4307,7 +4329,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const LL_WARNS("Inventory") << "wrong parent for " << item_id << " found " << item->getParentUUID() << " expected " << cat_id << LL_ENDL; - warnings++; + validation_info->mWarnings["wrong_parent_for_item"]++; + warning_count++; } @@ -4317,7 +4340,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const { LL_WARNS("Inventory") << "item " << item_id << " found as child of " << cat_id << " but not in top level mItemMap" << LL_ENDL; - warnings++; + validation_info->mWarnings["item_not_in_top_map"]++; + warning_count++; } else { @@ -4331,11 +4355,12 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const // Topmost ancestor should be root or library. LLUUID topmost_ancestor_id; - EAnscestorResult found = getObjectTopmostAncestor(item_id, topmost_ancestor_id); - if (found != ANSCESTOR_OK) + EAncestorResult found = getObjectTopmostAncestor(item_id, topmost_ancestor_id); + if (found != ANCESTOR_OK) { LL_WARNS("Inventory") << "unable to find topmost ancestor for " << item_id << LL_ENDL; - warnings++; + validation_info->mWarnings["topmost_ancestor_not_found"]++; + warning_count++; } else { @@ -4346,7 +4371,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const << " got " << topmost_ancestor_id << " expected " << getRootFolderID() << " or " << getLibraryRootFolderID() << LL_ENDL; - warnings++; + validation_info->mWarnings["topmost_ancestor_not_recognized"]++; + warning_count++; } } } @@ -4362,7 +4388,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const { LL_WARNS("Inventory") << "cat " << cat_id << " name [" << cat->getName() << "] orphaned - no child cat array for alleged parent " << parent_id << LL_ENDL; - orphaned++; + orphaned_count++; } else { @@ -4380,7 +4406,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const { LL_WARNS("Inventory") << "cat " << cat_id << " name [" << cat->getName() << "] orphaned - not found in child cat array of alleged parent " << parent_id << LL_ENDL; - orphaned++; + orphaned_count++; } } } @@ -4389,7 +4415,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const LLFolderType::EType folder_type = cat->getPreferredType(); bool cat_is_in_library = false; LLUUID topmost_id; - if (getObjectTopmostAncestor(cat->getUUID(),topmost_id) == ANSCESTOR_OK && topmost_id == getLibraryRootFolderID()) + if (getObjectTopmostAncestor(cat->getUUID(),topmost_id) == ANCESTOR_OK && topmost_id == getLibraryRootFolderID()) { cat_is_in_library = true; } @@ -4422,14 +4448,15 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const if (item->getUUID() != item_id) { LL_WARNS("Inventory") << "item_id " << item_id << " does not match " << item->getUUID() << LL_ENDL; - warnings++; + validation_info->mWarnings["item_id_mismatch"]++; + warning_count++; } const LLUUID& parent_id = item->getParentUUID(); if (parent_id.isNull()) { LL_WARNS("Inventory") << "item " << item_id << " name [" << item->getName() << "] has null parent id!" << LL_ENDL; - orphaned++; + orphaned_count++; } else { @@ -4440,7 +4467,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const { LL_WARNS("Inventory") << "item " << item_id << " name [" << item->getName() << "] orphaned - alleged parent has no child items list " << parent_id << LL_ENDL; - orphaned++; + orphaned_count++; } else { @@ -4457,7 +4484,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const { LL_WARNS("Inventory") << "item " << item_id << " name [" << item->getName() << "] orphaned - not found as child of alleged parent " << parent_id << LL_ENDL; - orphaned++; + orphaned_count++; } } @@ -4475,18 +4502,18 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const LL_WARNS("Inventory") << "link " << item->getUUID() << " type " << item->getActualType() << " missing backlink info at target_id " << target_id << LL_ENDL; - orphaned++; + orphaned_count++; } // Links should have referents. if (item->getActualType() == LLAssetType::AT_LINK && !target_item) { LL_WARNS("Inventory") << "broken item link " << item->getName() << " id " << item->getUUID() << LL_ENDL; - orphaned++; + orphaned_count++; } else if (item->getActualType() == LLAssetType::AT_LINK_FOLDER && !target_cat) { LL_WARNS("Inventory") << "broken folder link " << item->getName() << " id " << item->getUUID() << LL_ENDL; - orphaned++; + orphaned_count++; } if (target_item && target_item->getIsLinkType()) { @@ -4558,13 +4585,15 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const if (is_automatic) { LL_WARNS("Inventory") << "Fatal inventory corruption: cannot create system folder of type " << ft << LL_ENDL; - fatal_errs++; validation_info->mMissingRequiredSystemFolders.insert(folder_type); + fatal_errs++; } else { // Can create, and will when needed. - warnings++; + // (Not sure this is really a warning, but worth logging) + validation_info->mWarnings["missing_system_folder_can_create"]++; + warning_count++; } } else if (count_under_root > 1) @@ -4575,6 +4604,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const { // It is a fatal problem or can lead to fatal problems for COF, // outfits, trash and other non-automatic folders. + validation_info->mFatalSystemDuplicate++; fatal_errs++; } else @@ -4582,13 +4612,15 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const // For automatic folders it's not a fatal issue and shouldn't // break inventory or other functionality further // Exception: FT_SETTINGS is not automatic, but only deserves a warning. - warnings++; + validation_info->mWarnings["non_fatal_system_duplicate_under_root"]++; + warning_count++; } } if (count_elsewhere > 0) { LL_WARNS("Inventory") << "Found " << count_elsewhere << " extra folders of type " << ft << " outside of root" << LL_ENDL; - warnings++; + validation_info->mWarnings["non_fatal_system_duplicate_elsewhere"]++; + warning_count++; } } } @@ -4610,12 +4642,12 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const // FIXME need to fail login and tell user to retry, contact support if problem persists. bool valid = (fatal_errs == 0); - LL_INFOS("Inventory") << "Validate done, fatal errors: " << fatal_errs << ", warnings: " << warnings << ", valid: " << valid << LL_ENDL; + LL_INFOS("Inventory") << "Validate done, fatal errors: " << fatal_errs << ", warnings: " << warning_count << ", valid: " << valid << LL_ENDL; validation_info->mFatalErrorCount = fatal_errs; - validation_info->mWarningCount = warnings; - validation_info->mLoopCount = loops; - validation_info->mOrphanedCount = orphaned; + validation_info->mWarningCount = warning_count; + validation_info->mLoopCount = loop_count; + validation_info->mOrphanedCount = orphaned_count; return validation_info; } @@ -4819,12 +4851,10 @@ void LLInventoryModel::FetchItemHttpHandler::processData(LLSD & content, LLCore: } // as above, this loop never seems to loop more than once per call - U32 changes(0U); for (LLInventoryModel::item_array_t::iterator it = items.begin(); it != items.end(); ++it) { - changes |= gInventory.updateItem(*it); + gInventory.updateItem(*it); } - // *HUH: Have computed 'changes', nothing uses it. gInventory.notifyObservers(); gViewerWindow->getWindow()->decBusyCount(); diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index f8c9905ca617397026e16c76ed57b3727e609907..62cef2e60b8a778dcd4adb37dcac245434008484 100644 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -68,15 +68,19 @@ class LLInventoryValidationInfo: public LLRefCount void toOstream(std::ostream& os) const; void asLLSD(LLSD& sd) const; + bool mInitialized{false}; + S32 mWarningCount{0}; + std::map<std::string,U32> mWarnings; + + S32 mLoopCount{0}; // Presence of folders whose ancestors loop onto themselves + S32 mOrphanedCount{0}; // Missing or orphaned items, links and folders + + S32 mFatalErrorCount{0}; + bool mFatalNoRootFolder{false}; + S32 mFatalSystemDuplicate{0}; + bool mFatalNoLibraryRootFolder{false}; + bool mFatalQADebugMode{false}; - S32 mFatalErrorCount; - S32 mWarningCount; - S32 mLoopCount; // Presence of folders whose ansestors loop onto themselves - S32 mOrphanedCount; // Missing or orphaned items, links and folders - bool mInitialized; - bool mFatalNoRootFolder; - bool mFatalNoLibraryRootFolder; - bool mFatalQADebugMode; std::set<LLFolderType::EType> mMissingRequiredSystemFolders; std::set<LLFolderType::EType> mDuplicateRequiredSystemFolders; }; @@ -297,13 +301,13 @@ class LLInventoryModel // Check if one object has a parent chain up to the category specified by UUID. BOOL isObjectDescendentOf(const LLUUID& obj_id, const LLUUID& cat_id, const bool break_on_recursion = false) const; - enum EAnscestorResult{ - ANSCESTOR_OK = 0, - ANSCESTOR_MISSING = 1, - ANSCESTOR_LOOP = 2, + enum EAncestorResult{ + ANCESTOR_OK = 0, + ANCESTOR_MISSING = 1, + ANCESTOR_LOOP = 2, }; // Follow parent chain to the top. - EAnscestorResult getObjectTopmostAncestor(const LLUUID& object_id, LLUUID& result) const; + EAncestorResult getObjectTopmostAncestor(const LLUUID& object_id, LLUUID& result) const; //-------------------------------------------------------------------- // Find diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index 29929c86c6042940d3a18ef8b197d39a397c7166..87496dab42db42f1673bd9d037096ab87c6a9631 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -115,12 +115,12 @@ class BGItemHttpHandler : public LLInventoryModel::FetchItemHttpHandler BGItemHttpHandler(const LLSD & request_sd) : LLInventoryModel::FetchItemHttpHandler(request_sd) { - LLInventoryModelBackgroundFetch::instanceFast().incrFetchCount(1); + LLInventoryModelBackgroundFetch::instance().incrFetchCount(1); } virtual ~BGItemHttpHandler() { - LLInventoryModelBackgroundFetch::instanceFast().incrFetchCount(-1); + LLInventoryModelBackgroundFetch::instance().incrFetchCount(-1); } protected: @@ -148,12 +148,12 @@ class BGFolderHttpHandler : public LLCore::HttpHandler mRequestSD(request_sd), mRecursiveCatUUIDs(recursive_cats) { - LLInventoryModelBackgroundFetch::instanceFast().incrFetchCount(1); + LLInventoryModelBackgroundFetch::instance().incrFetchCount(1); } virtual ~BGFolderHttpHandler() { - LLInventoryModelBackgroundFetch::instanceFast().incrFetchCount(-1); + LLInventoryModelBackgroundFetch::instance().incrFetchCount(-1); } protected: @@ -339,7 +339,7 @@ void LLInventoryModelBackgroundFetch::setAllFoldersFetched() void LLInventoryModelBackgroundFetch::backgroundFetchCB(void *) { - LLInventoryModelBackgroundFetch::instanceFast().backgroundFetch(); + LLInventoryModelBackgroundFetch::instance().backgroundFetch(); } void LLInventoryModelBackgroundFetch::backgroundFetch() @@ -347,7 +347,7 @@ void LLInventoryModelBackgroundFetch::backgroundFetch() if (mBackgroundFetchActive && gAgent.getRegion() && gAgent.getRegion()->capabilitiesReceived()) { // If we'll be using the capability, we'll be sending batches and the background thing isn't as important. - if (LLGridManager::instanceFast().isInSecondlife() || gSavedSettings.getBOOL("UseHTTPInventory")) + if (LLGridManager::instance().isInSecondlife() || gSavedSettings.getBOOL("UseHTTPInventory")) { bulkFetch(); return; @@ -556,7 +556,7 @@ void LLInventoryModelBackgroundFetch::bulkFetch() // OnIdle it will be called anyway due to Add flag for processed item. // It seems like in some cases we are updaiting on fail (no flag), // but is there anything to update? - if (LLGridManager::getInstanceFast()->isInSecondlife()) + if (LLGridManager::getInstance()->isInSecondlife()) { gInventory.notifyObservers(); } @@ -822,7 +822,7 @@ void BGFolderHttpHandler::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRes void BGFolderHttpHandler::processData(LLSD & content, LLCore::HttpResponse * response) { - LLInventoryModelBackgroundFetch * fetcher(LLInventoryModelBackgroundFetch::getInstanceFast()); + LLInventoryModelBackgroundFetch * fetcher(LLInventoryModelBackgroundFetch::getInstance()); // API V2 and earlier should probably be testing for "error" map // in response as an application-level error. @@ -870,7 +870,7 @@ void BGFolderHttpHandler::processData(LLSD & content, LLCore::HttpResponse * res titem->setParent(lost_uuid); titem->updateParentOnServer(FALSE); gInventory.updateItem(titem); - if (!LLGridManager::getInstanceFast()->isInSecondlife()) + if (!LLGridManager::getInstance()->isInSecondlife()) { gInventory.notifyObservers(); } @@ -947,7 +947,7 @@ void BGFolderHttpHandler::processData(LLSD & content, LLCore::HttpResponse * res fetcher->setAllFoldersFetched(); } - if (!LLGridManager::getInstanceFast()->isInSecondlife()) + if (!LLGridManager::getInstance()->isInSecondlife()) { gInventory.notifyObservers(); } @@ -972,7 +972,7 @@ void BGFolderHttpHandler::processFailure(LLCore::HttpStatus status, LLCore::Http // cause of the retry. The new http library should be doing // adquately on retries but I want to keep the structure of a // retry for reference. - LLInventoryModelBackgroundFetch *fetcher = LLInventoryModelBackgroundFetch::getInstanceFast(); + LLInventoryModelBackgroundFetch *fetcher = LLInventoryModelBackgroundFetch::getInstance(); if (false) { // timed out or curl failure @@ -991,7 +991,7 @@ void BGFolderHttpHandler::processFailure(LLCore::HttpStatus status, LLCore::Http } } - if (!LLGridManager::getInstanceFast()->isInSecondlife()) + if (!LLGridManager::getInstance()->isInSecondlife()) { gInventory.notifyObservers(); } @@ -1012,7 +1012,7 @@ void BGFolderHttpHandler::processFailure(const char * const reason, LLCore::Http // the same but be aware that this may be a source of problems. // Philosophy is that inventory folders are so essential to // operation that this is a reasonable action. - LLInventoryModelBackgroundFetch *fetcher = LLInventoryModelBackgroundFetch::getInstanceFast(); + LLInventoryModelBackgroundFetch *fetcher = LLInventoryModelBackgroundFetch::getInstance(); if (true) { for (const auto& folder_sd : mRequestSD["folders"].array()) @@ -1030,7 +1030,7 @@ void BGFolderHttpHandler::processFailure(const char * const reason, LLCore::Http } } - if (!LLGridManager::getInstanceFast()->isInSecondlife()) + if (!LLGridManager::getInstance()->isInSecondlife()) { gInventory.notifyObservers(); } diff --git a/indra/newview/llinventoryobserver.cpp b/indra/newview/llinventoryobserver.cpp index 77b1af116112e7183d7e5a2f174db3c8134f9ed6..33b2855dc9fc78e81f79f131ba19982bb9bd876a 100644 --- a/indra/newview/llinventoryobserver.cpp +++ b/indra/newview/llinventoryobserver.cpp @@ -243,7 +243,7 @@ void fetch_items_from_llsd(const LLSD& items_llsd) gInventory.requestPost(true, url, body[i], handler, (i ? "Library Item" : "Inventory Item")); continue; } - else if (!LLGridManager::instanceFast().isInSecondlife()) + else if (!LLGridManager::instance().isInSecondlife()) { LLMessageSystem* msg = gMessageSystem; BOOL start_new_message = TRUE; diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index b2c33a0daa60c2c4c3e6cc6861651ed27ec9c724..e1b8a3194161c5f08d2b5da8566dce261ee01fe2 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -697,10 +697,9 @@ void LLInventoryPanel::itemChanged(const LLUUID& item_id, U32 mask, const LLInve } // Called when something changed in the global model (new item, item coming through the wire, rename, move, etc...) (CHUI-849) -static LLTrace::BlockTimerStatHandle FTM_REFRESH("Inventory Refresh"); void LLInventoryPanel::modelChanged(U32 mask) { - LL_RECORD_BLOCK_TIME(FTM_REFRESH); + LL_PROFILE_ZONE_SCOPED; if (mViewsInitialized != VIEWS_INITIALIZED) return; @@ -794,9 +793,9 @@ void LLInventoryPanel::idle(void* user_data) { LLInventoryPanel* panel = (LLInventoryPanel*)user_data; // Nudge the filter if the clipboard state changed - if (panel->mClipboardState != LLClipboard::instanceFast().getGeneration()) + if (panel->mClipboardState != LLClipboard::instance().getGeneration()) { - panel->mClipboardState = LLClipboard::instanceFast().getGeneration(); + panel->mClipboardState = LLClipboard::instance().getGeneration(); const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); LLFolderViewFolder* trash_folder = panel->getFolderByID(trash_id); if (trash_folder) @@ -855,9 +854,9 @@ void LLInventoryPanel::idle(void* user_data) { panel->mFolderRoot.get()->update(); // while dragging, update selection rendering to reflect single/multi drag status - if (LLToolDragAndDrop::getInstanceFast()->hasMouseCapture()) + if (LLToolDragAndDrop::getInstance()->hasMouseCapture()) { - EAcceptance last_accept = LLToolDragAndDrop::getInstanceFast()->getLastAccept(); + EAcceptance last_accept = LLToolDragAndDrop::getInstance()->getLastAccept(); if (last_accept == ACCEPT_YES_SINGLE || last_accept == ACCEPT_YES_COPY_SINGLE) { panel->mFolderRoot.get()->setShowSingleSelection(TRUE); @@ -1275,7 +1274,7 @@ BOOL LLInventoryPanel::handleHover(S32 x, S32 y, MASK mask) if(handled) { ECursorType cursor = getWindow()->getCursor(); - if (LLInventoryModelBackgroundFetch::instanceFast().folderFetchActive() && cursor == UI_CURSOR_ARROW) + if (LLInventoryModelBackgroundFetch::instance().folderFetchActive() && cursor == UI_CURSOR_ARROW) { // replace arrow cursor with arrow and hourglass cursor getWindow()->setCursor(UI_CURSOR_WORKING); @@ -1883,10 +1882,9 @@ void LLInventoryPanel::removeItemID(const LLUUID& id) } } -LLTrace::BlockTimerStatHandle FTM_GET_ITEM_BY_ID("Get FolderViewItem by ID"); LLFolderViewItem* LLInventoryPanel::getItemByID(const LLUUID& id) { - LL_RECORD_BLOCK_TIME(FTM_GET_ITEM_BY_ID); + LL_PROFILE_ZONE_SCOPED; auto map_it = mItemMap.find(id); if (map_it != mItemMap.end()) diff --git a/indra/newview/lllegacyatmospherics.cpp b/indra/newview/lllegacyatmospherics.cpp index e18df511d4047d7ce530839698c57f015ccc1f00..f2bb983bc43668d71af5dc2f809a62f689b14d5f 100644 --- a/indra/newview/lllegacyatmospherics.cpp +++ b/indra/newview/lllegacyatmospherics.cpp @@ -202,19 +202,11 @@ void LLAtmospherics::init() mInitialized = true; } -LLColor4 LLAtmospherics::calcSkyColorInDir(AtmosphericsVars& vars, const LLVector3 &dir, bool isShiny) -{ - const LLSettingsSky::ptr_t& psky = LLEnvironment::instanceFast().getCurrentSky(); - return calcSkyColorInDir(psky, vars, dir, isShiny); -} - // This cubemap is used as "environmentMap" in indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl -LLColor4 LLAtmospherics::calcSkyColorInDir(const LLSettingsSky::ptr_t &psky, AtmosphericsVars& vars, const LLVector3 &dir, bool isShiny) +LLColor4 LLAtmospherics::calcSkyColorInDir(const LLSettingsSky::ptr_t &psky, AtmosphericsVars& vars, const LLVector3 &dir, bool isShiny, bool low_end) { - F32 sky_saturation = 0.25f; - F32 land_saturation = 0.1f; - - bool low_end = !gPipeline.canUseWindLightShaders(); + const F32 sky_saturation = 0.25f; + const F32 land_saturation = 0.1f; if (isShiny && dir.mV[VZ] < -0.02f) { @@ -271,11 +263,12 @@ LLColor4 LLAtmospherics::calcSkyColorInDir(const LLSettingsSky::ptr_t &psky, Atm // indra\newview\lllegacyatmospherics.cpp void LLAtmospherics::calcSkyColorWLVert(const LLSettingsSky::ptr_t &psky, LLVector3 & Pn, AtmosphericsVars& vars) { - LLColor3 blue_density = vars.blue_density; - LLColor3 blue_horizon = vars.blue_horizon; - F32 haze_horizon = vars.haze_horizon; - F32 haze_density = vars.haze_density; - F32 density_multiplier = vars.density_multiplier; + const LLColor3 blue_density = vars.blue_density; + const LLColor3 blue_horizon = vars.blue_horizon; + const F32 haze_horizon = vars.haze_horizon; + const F32 haze_density = vars.haze_density; + const F32 density_multiplier = vars.density_multiplier; + F32 max_y = vars.max_y; LLVector4 sun_norm = vars.sun_norm; @@ -315,6 +308,7 @@ void LLAtmospherics::calcSkyColorWLVert(const LLSettingsSky::ptr_t &psky, LLVect // this is used later for sunlight modulation at various altitudes LLColor3 light_atten = vars.light_atten; LLColor3 light_transmittance = psky->getLightTransmittanceFast(vars.total_density, vars.density_multiplier, Plen); + (void)light_transmittance; // silence Clang warn-error // Calculate relative weights LLColor3 temp2(0.f, 0.f, 0.f); @@ -389,23 +383,16 @@ void LLAtmospherics::updateFog(const F32 distance, const LLVector3& tosun_in) if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FOG)) { - if (!LLGLSLShader::sNoFixedFunction) - { - glFogf(GL_FOG_DENSITY, 0); - glFogfv(GL_FOG_COLOR, (F32 *) &LLColor4::white.mV); - glFogf(GL_FOG_END, 1000000.f); - } return; } - const BOOL hide_clip_plane = TRUE; LLColor4 target_fog(0.f, 0.2f, 0.5f, 0.f); const F32 water_height = gAgent.getRegion() ? gAgent.getRegion()->getWaterHeight() : 0.f; // LLWorld::getInstance()->getWaterHeight(); F32 camera_height = gAgentCamera.getCameraPositionAgent().mV[2]; - F32 near_clip_height = LLViewerCamera::getInstanceFast()->getAtAxis().mV[VZ] * LLViewerCamera::getInstanceFast()->getNear(); + F32 near_clip_height = LLViewerCamera::getInstance()->getAtAxis().mV[VZ] * LLViewerCamera::getInstance()->getNear(); camera_height += near_clip_height; F32 fog_distance = 0.f; @@ -434,16 +421,19 @@ void LLAtmospherics::updateFog(const F32 distance, const LLVector3& tosun_in) // Sky colors, just slightly above the horizon in the direction of the sun, perpendicular to the sun, and at a 45 degree angle to the sun. AtmosphericsVars vars; - LLEnvironment& env = LLEnvironment::instanceFast(); - + LLEnvironment& env = LLEnvironment::instance(); const LLSettingsSky::ptr_t& psky = env.getCurrentSky(); + // NOTE: This is very similar to LLVOSky::cacheEnvironment() + // Differences: + // vars.sun_norm + // vars.sunlight // invariants across whole sky tex process... - vars.blue_density = psky->getBlueDensity(); + vars.blue_density = psky->getBlueDensity(); vars.blue_horizon = psky->getBlueHorizon(); vars.haze_density = psky->getHazeDensity(); vars.haze_horizon = psky->getHazeHorizon(); - vars.density_multiplier = psky->getDensityMultiplier(); + vars.density_multiplier = psky->getDensityMultiplier(); vars.distance_multiplier = psky->getDistanceMultiplier(); vars.max_y = psky->getMaxY(); vars.sun_norm = env.getSunDirectionCFR(); @@ -458,9 +448,9 @@ void LLAtmospherics::updateFog(const F32 distance, const LLVector3& tosun_in) vars.light_transmittance = psky->getLightTransmittanceFast(vars.total_density, vars.density_multiplier, vars.max_y); vars.gamma = psky->getGamma(); - res_color[0] = calcSkyColorInDir(psky, vars, tosun); - res_color[1] = calcSkyColorInDir(psky, vars, perp_tosun); - res_color[2] = calcSkyColorInDir(psky, vars, tosun_45); + res_color[0] = calcSkyColorInDir(psky, vars, tosun); + res_color[1] = calcSkyColorInDir(psky, vars, perp_tosun); + res_color[2] = calcSkyColorInDir(psky, vars, tosun_45); sky_fog_color = color_norm(res_color[0] + res_color[1] + res_color[2]); @@ -482,45 +472,17 @@ void LLAtmospherics::updateFog(const F32 distance, const LLVector3& tosun_in) render_fog_color = sky_fog_color; - F32 fog_density = 0.f; fog_distance = mFogRatio * distance; if (camera_height > water_height) { LLColor4 fog(render_fog_color); - if (!LLGLSLShader::sNoFixedFunction) - { - glFogfv(GL_FOG_COLOR, fog.mV); - } mGLFogCol = fog; - - if (hide_clip_plane) - { - // For now, set the density to extend to the cull distance. - const F32 f_log = 2.14596602628934723963618357029f; // sqrt(fabs(log(0.01f))) - fog_density = f_log/fog_distance; - if (!LLGLSLShader::sNoFixedFunction) - { - glFogi(GL_FOG_MODE, GL_EXP2); - } - } - else - { - const F32 f_log = 4.6051701859880913680359829093687f; // fabs(log(0.01f)) - fog_density = (f_log)/fog_distance; - if (!LLGLSLShader::sNoFixedFunction) - { - glFogi(GL_FOG_MODE, GL_EXP); - } - } } else { const LLSettingsWater::ptr_t& pwater = env.getCurrentWater(); F32 depth = water_height - camera_height; - - // get the water param manager variables - float water_fog_density = pwater->getModifiedWaterFogDensity(depth <= 0.0f); LLColor4 water_fog_color(pwater->getWaterFogColor()); @@ -534,15 +496,6 @@ void LLAtmospherics::updateFog(const F32 distance, const LLVector3& tosun_in) // set the gl fog color mGLFogCol = fogCol; - - // set the density based on what the shaders use - fog_density = water_fog_density * gSavedSettings.getF32("WaterGLFogDensityScale"); - - if (!LLGLSLShader::sNoFixedFunction) - { - glFogfv(GL_FOG_COLOR, (F32 *) &fogCol.mV); - glFogi(GL_FOG_MODE, GL_EXP2); - } } mFogColor = sky_fog_color; @@ -550,13 +503,6 @@ void LLAtmospherics::updateFog(const F32 distance, const LLVector3& tosun_in) LLDrawPoolWater::sWaterFogEnd = fog_distance*2.2f; - if (!LLGLSLShader::sNoFixedFunction) - { - LLGLSFog gls_fog; - glFogf(GL_FOG_END, fog_distance*2.2f); - glFogf(GL_FOG_DENSITY, fog_density); - glHint(GL_FOG_HINT, GL_NICEST); - } stop_glerror(); } diff --git a/indra/newview/lllegacyatmospherics.h b/indra/newview/lllegacyatmospherics.h index ebe111b6dce3f6d6f76ad10aa6da6e0eb39932e2..aa009d15cfe6cc517513957750d5cdd70c6ba297 100644 --- a/indra/newview/lllegacyatmospherics.h +++ b/indra/newview/lllegacyatmospherics.h @@ -257,13 +257,11 @@ class LLAtmospherics void setCloudDensity(F32 cloud_density) { mCloudDensity = cloud_density; } void setWind ( const LLVector3& wind ) { mWind = wind.length(); } - LLColor4 calcSkyColorInDir(AtmosphericsVars& vars, const LLVector3& dir, bool isShiny = false); - LLColor4 calcSkyColorInDir(const LLSettingsSky::ptr_t &psky, AtmosphericsVars& vars, const LLVector3& dir, bool isShiny = false); + LLColor4 calcSkyColorInDir(const LLSettingsSky::ptr_t &psky, AtmosphericsVars& vars, const LLVector3& dir, bool isShiny = false, const bool low_end = false); -protected: +protected: void calcSkyColorWLVert(const LLSettingsSky::ptr_t &psky, LLVector3 & Pn, AtmosphericsVars& vars); - LLColor3 getHazeColor(LLSettingsSky::ptr_t psky, AtmosphericsVars& vars, F32 costheta, F32 cloud_shadow); LLHaze mHaze; F32 mHazeConcentration; diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp index aac4fb7282493d8ecfd97453e5d25e4490a9aff6..a100553e6b847b43eb3757a8fa1521eb20520550 100644 --- a/indra/newview/lllocalbitmaps.cpp +++ b/indra/newview/lllocalbitmaps.cpp @@ -941,6 +941,36 @@ LLLocalBitmapMgr::~LLLocalBitmapMgr() mBitmapList.clear(); } +LLUUID LLLocalBitmapMgr::addUnit(const std::string &filename) +{ + if (!checkTextureDimensions(filename)) + { + return LLUUID::null; + } + + LLLocalBitmap* unit = new LLLocalBitmap(filename); + + if (unit->getValid()) + { + mBitmapList.push_back(unit); + return unit->getTrackingID(); + } + else + { + LL_WARNS() << "Attempted to add invalid or unreadable image file, attempt cancelled.\n" + << "Filename: " << filename << LL_ENDL; + + LLSD notif_args; + notif_args["FNAME"] = filename; + LLNotificationsUtil::add("LocalBitmapsVerifyFail", notif_args); + + delete unit; + unit = NULL; + } + + return LLUUID::null; +} + bool LLLocalBitmapMgr::addUnit() { bool add_successful = false; @@ -953,32 +983,10 @@ bool LLLocalBitmapMgr::addUnit() std::string filename = picker.getFirstFile(); while(!filename.empty()) { - if(!checkTextureDimensions(filename)) - { - filename = picker.getNextFile(); - continue; - } - - LLLocalBitmap* unit = new LLLocalBitmap(filename); - - if (unit->getValid()) - { - mBitmapList.push_back(unit); - add_successful = true; - } - else - { - LL_WARNS() << "Attempted to add invalid or unreadable image file, attempt cancelled.\n" - << "Filename: " << filename << LL_ENDL; - - LLSD notif_args; - notif_args["FNAME"] = filename; - LLNotificationsUtil::add("LocalBitmapsVerifyFail", notif_args); - - delete unit; - unit = NULL; - } - + if (addUnit(filename).notNull()) + { + add_successful = true; + } filename = picker.getNextFile(); } diff --git a/indra/newview/lllocalbitmaps.h b/indra/newview/lllocalbitmaps.h index 94aad1471a134d00b5ae03a31378fb374f04ed8e..89f9c5cd779f09b48ad9c27e678bd82bbd9de861 100644 --- a/indra/newview/lllocalbitmaps.h +++ b/indra/newview/lllocalbitmaps.h @@ -117,13 +117,14 @@ class LLLocalBitmapMgr final : public LLSingleton<LLLocalBitmapMgr> ~LLLocalBitmapMgr(); public: bool addUnit(); + LLUUID addUnit(const std::string &filename); void delUnit(LLUUID tracking_id); bool checkTextureDimensions(std::string filename); LLUUID getWorldID(LLUUID tracking_id); bool isLocal(LLUUID world_id); std::string getFilename(LLUUID tracking_id); - + void feedScrollList(LLScrollListCtrl* ctrl); void doUpdates(); void setNeedsRebake(); diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp index bb936aed8fbaf764baaf0d18a53062af72c8bb24..b432cfaaf23230acf938cf255283bbb8516b4096 100644 --- a/indra/newview/lllocationinputctrl.cpp +++ b/indra/newview/lllocationinputctrl.cpp @@ -496,7 +496,7 @@ BOOL LLLocationInputCtrl::handleToolTip(S32 x, S32 y, MASK mask) LLSD value = item->getValue(); if (value.has("tooltip")) { - LLToolTipMgr::instanceFast().show(value["tooltip"]); + LLToolTipMgr::instance().show(value["tooltip"]); } } } @@ -846,7 +846,7 @@ void LLLocationInputCtrl::refreshParcelIcons() // Our "cursor" moving right to left S32 x = mAddLandmarkBtn->getRect().mLeft; - LLViewerParcelMgr* vpm = LLViewerParcelMgr::getInstanceFast(); + LLViewerParcelMgr* vpm = LLViewerParcelMgr::getInstance(); LLViewerRegion* agent_region = gAgent.getRegion(); LLParcel* agent_parcel = vpm->getAgentParcel(); diff --git a/indra/newview/lllocationinputctrl.h b/indra/newview/lllocationinputctrl.h index 82929a97d13a236d1b1a5af623d58344c64dc829..ef42718288fbfad5b0821f52ca47704d62478b94 100644 --- a/indra/newview/lllocationinputctrl.h +++ b/indra/newview/lllocationinputctrl.h @@ -109,6 +109,8 @@ class LLLocationInputCtrl LLLineEditor* getTextEntry() const { return mTextEntry; } void handleLoginComplete(); + bool isNavMeshDirty() { return mIsNavMeshDirty; } + // [RLVa:KB] - Checked: 2014-03-23 (RLVa-1.4.10) void refresh(); // [/RLVa:KB] diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp index bb339305cec290bc030fac4d2896d17e38641226..1a46fde2692ce398ba44521db06bacdd7c43123a 100644 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -291,7 +291,7 @@ void LLLoginInstance::constructAuthParams(LLPointer<LLCredential> user_credentia mRequestData["options"] = requested_options; mRequestData["http_params"] = http_params; #if LL_RELEASE_FOR_DOWNLOAD - mRequestData["wait_for_updater"] = !gSavedSettings.getBOOL("CmdLineSkipUpdater") && !LLAppViewer::instance()->isUpdaterMissing(); + mRequestData["wait_for_updater"] = LLAppViewer::instance()->waitForUpdater(); #else mRequestData["wait_for_updater"] = false; #endif @@ -462,26 +462,8 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event) LLSD args(llsd::map( "MESSAGE", LLTrans::getString(response["message_id"].asString()) )); LLSD payload; - LLNotificationsUtil::add("PromptMFAToken", args, payload, [=](LLSD const & notif, LLSD const & response) { - bool continue_clicked = response["continue"].asBoolean(); - std::string token = response["token"].asString(); - LL_DEBUGS("LLLogin") << "PromptMFAToken: response: " << response << " continue_clicked" << continue_clicked << LL_ENDL; - - // strip out whitespace - SL-17034/BUG-231938 - token = boost::regex_replace(token, boost::regex("\\s"), ""); - - if (continue_clicked && !token.empty()) - { - LL_INFOS("LLLogin") << "PromptMFAToken: token submitted" << LL_ENDL; - - // Set the request data to true and retry login. - mRequestData["params"]["token"] = token; - reconnect(); - } else { - LL_INFOS("LLLogin") << "PromptMFAToken: no token, attemptComplete" << LL_ENDL; - attemptComplete(); - } - }); + LLNotificationsUtil::add("PromptMFAToken", args, payload, + boost::bind(&LLLoginInstance::handleMFAChallenge, this, _1, _2)); } else if( reason_response == "key" || reason_response == "presence" @@ -558,23 +540,59 @@ void LLLoginInstance::handleIndeterminate(const LLSD& event) bool LLLoginInstance::handleTOSResponse(bool accepted, const std::string& key) { - if(accepted) - { - LL_INFOS("LLLogin") << "LLLoginInstance::handleTOSResponse: accepted" << LL_ENDL; + if(accepted) + { + LL_INFOS("LLLogin") << "LLLoginInstance::handleTOSResponse: accepted " << LL_ENDL; - // Set the request data to true and retry login. - mRequestData["params"][key] = true; - reconnect(); - } - else - { - LL_INFOS("LLLogin") << "LLLoginInstance::handleTOSResponse: attemptComplete" << LL_ENDL; + // Set the request data to true and retry login. + mRequestData["params"][key] = true; - attemptComplete(); - } + if (!mRequestData["params"]["token"].asString().empty()) + { + // SL-18511 this TOS failure happened while we are in the middle of an MFA challenge/response. + // the previously entered token is very likely expired, so prompt again + LLSD args(llsd::map( "MESSAGE", LLTrans::getString("LoginFailedAuthenticationMFARequired") )); + LLSD payload; + LLNotificationsUtil::add("PromptMFAToken", args, payload, + boost::bind(&LLLoginInstance::handleMFAChallenge, this, _1, _2)); + } + else + { + reconnect(); + } + } + else + { + LL_INFOS("LLLogin") << "LLLoginInstance::handleTOSResponse: attemptComplete" << LL_ENDL; + + attemptComplete(); + } + + LLEventPumps::instance().obtain(TOS_REPLY_PUMP).stopListening(TOS_LISTENER_NAME); + return true; +} - LLEventPumps::instance().obtain(TOS_REPLY_PUMP).stopListening(TOS_LISTENER_NAME); - return true; +bool LLLoginInstance::handleMFAChallenge(LLSD const & notif, LLSD const & response) +{ + bool continue_clicked = response["continue"].asBoolean(); + std::string token = response["token"].asString(); + LL_DEBUGS("LLLogin") << "PromptMFAToken: response: " << response << " continue_clicked" << continue_clicked << LL_ENDL; + + // strip out whitespace - SL-17034/BUG-231938 + token = boost::regex_replace(token, boost::regex("\\s"), ""); + + if (continue_clicked && !token.empty()) + { + LL_INFOS("LLLogin") << "PromptMFAToken: token submitted" << LL_ENDL; + + // Set the request data to true and retry login. + mRequestData["params"]["token"] = token; + reconnect(); + } else { + LL_INFOS("LLLogin") << "PromptMFAToken: no token, attemptComplete" << LL_ENDL; + attemptComplete(); + } + return true; } void LLLoginInstance::attemptComplete() diff --git a/indra/newview/lllogininstance.h b/indra/newview/lllogininstance.h index f6104d8a9bacb2c2f57b62cd31458c833d9ab683..48d75544ee28381be2de59b90b38d58e7ba19b68 100644 --- a/indra/newview/lllogininstance.h +++ b/indra/newview/lllogininstance.h @@ -84,6 +84,7 @@ class LLLoginInstance final : public LLSingleton<LLLoginInstance> void syncWithUpdater(ResponsePtr resp, const LLSD& notification, const LLSD& response); bool handleTOSResponse(bool v, const std::string& key); + bool handleMFAChallenge(LLSD const & notif, LLSD const & response); void attemptComplete(); diff --git a/indra/newview/llmanip.cpp b/indra/newview/llmanip.cpp index 233e74206cdf499eec621645b8082af36eee9bf7..83b0392d64f6cca024aefca75b739f5fcabfb802 100644 --- a/indra/newview/llmanip.cpp +++ b/indra/newview/llmanip.cpp @@ -112,14 +112,14 @@ void LLManip::getManipNormal(LLViewerObject* object, EManipPart manip, LLVector3 LLVector3 grid_scale; LLQuaternion grid_rotation; - LLSelectMgr::getInstanceFast()->getGrid(grid_origin, grid_rotation, grid_scale); + LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale); if (manip >= LL_X_ARROW && manip <= LL_Z_ARROW) { LLVector3 arrow_axis; getManipAxis(object, manip, arrow_axis); - LLVector3 cross = arrow_axis % LLViewerCamera::getInstanceFast()->getAtAxis(); + LLVector3 cross = arrow_axis % LLViewerCamera::getInstance()->getAtAxis(); normal = cross % arrow_axis; normal.normVec(); } @@ -154,7 +154,7 @@ BOOL LLManip::getManipAxis(LLViewerObject* object, EManipPart manip, LLVector3 & LLVector3 grid_scale; LLQuaternion grid_rotation; - LLSelectMgr::getInstanceFast()->getGrid(grid_origin, grid_rotation, grid_scale); + LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale); if (manip == LL_X_ARROW) { @@ -187,12 +187,12 @@ F32 LLManip::getSubdivisionLevel(const LLVector3 &reference_point, const LLVecto } else { - cam_to_reference = reference_point - LLViewerCamera::getInstanceFast()->getOrigin(); + cam_to_reference = reference_point - LLViewerCamera::getInstance()->getOrigin(); } F32 current_range = cam_to_reference.normVec(); F32 projected_translation_axis_length = (translate_axis % cam_to_reference).magVec(); - F32 subdivisions = llmax(projected_translation_axis_length * grid_scale / (current_range / LLViewerCamera::getInstanceFast()->getPixelMeterRatio() * min_pixel_spacing), 0.f); + F32 subdivisions = llmax(projected_translation_axis_length * grid_scale / (current_range / LLViewerCamera::getInstance()->getPixelMeterRatio() * min_pixel_spacing), 0.f); // figure out nearest power of 2 that subdivides grid_scale with result > min_pixel_spacing subdivisions = llclamp((F32)pow(2.f, llfloor(log(subdivisions) / log(2.f))), min_subdivisions, max_subdivisions); @@ -201,7 +201,7 @@ F32 LLManip::getSubdivisionLevel(const LLVector3 &reference_point, const LLVecto void LLManip::handleSelect() { - mObjectSelection = LLSelectMgr::getInstanceFast()->getEditSelection(); + mObjectSelection = LLSelectMgr::getInstance()->getEditSelection(); } void LLManip::handleDeselect() @@ -273,7 +273,7 @@ BOOL LLManip::getMousePointOnPlaneGlobal(LLVector3d& point, S32 x, S32 y, LLVect if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) { BOOL result = FALSE; - F32 mouse_x = ((F32)x / gViewerWindow->getWorldViewWidthScaled() - 0.5f) * LLViewerCamera::getInstanceFast()->getAspect() / gAgentCamera.mHUDCurZoom; + F32 mouse_x = ((F32)x / gViewerWindow->getWorldViewWidthScaled() - 0.5f) * LLViewerCamera::getInstance()->getAspect() / gAgentCamera.mHUDCurZoom; F32 mouse_y = ((F32)y / gViewerWindow->getWorldViewHeightScaled() - 0.5f) / gAgentCamera.mHUDCurZoom; LLVector3 origin_agent = gAgent.getPosAgentFromGlobal(origin); @@ -312,7 +312,7 @@ BOOL LLManip::nearestPointOnLineFromMouse( S32 x, S32 y, const LLVector3& b1, co if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) { - F32 mouse_x = (((F32)x / gViewerWindow->getWindowWidthScaled()) - 0.5f) * LLViewerCamera::getInstanceFast()->getAspect() / gAgentCamera.mHUDCurZoom; + F32 mouse_x = (((F32)x / gViewerWindow->getWindowWidthScaled()) - 0.5f) * LLViewerCamera::getInstance()->getAspect() / gAgentCamera.mHUDCurZoom; F32 mouse_y = (((F32)y / gViewerWindow->getWindowHeightScaled()) - 0.5f) / gAgentCamera.mHUDCurZoom; a1 = LLVector3(llmin(b1.mV[VX] - 0.1f, b2.mV[VX] - 0.1f, 0.f), -mouse_x, mouse_y); a2 = a1 + LLVector3(1.f, 0.f, 0.f); @@ -355,7 +355,7 @@ BOOL LLManip::nearestPointOnLineFromMouse( S32 x, S32 y, const LLVector3& b1, co LLVector3 LLManip::getSavedPivotPoint() const { - return LLSelectMgr::getInstanceFast()->getSavedBBoxOfSelection().getCenterAgent(); + return LLSelectMgr::getInstance()->getSavedBBoxOfSelection().getCenterAgent(); } LLVector3 LLManip::getPivotPoint() @@ -366,7 +366,7 @@ LLVector3 LLManip::getPivotPoint() { return vobjp->getPivotPositionAgent(); } - return LLSelectMgr::getInstanceFast()->getBBoxOfSelection().getCenterAgent(); + return LLSelectMgr::getInstance()->getBBoxOfSelection().getCenterAgent(); } @@ -375,7 +375,7 @@ void LLManip::renderGuidelines(BOOL draw_x, BOOL draw_y, BOOL draw_z) LLVector3 grid_origin; LLQuaternion grid_rot; LLVector3 grid_scale; - LLSelectMgr::getInstanceFast()->getGrid(grid_origin, grid_rot, grid_scale); + LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rot, grid_scale); const BOOL children_ok = TRUE; LLViewerObject* object = mObjectSelection->getFirstRootObject(children_ok); @@ -384,7 +384,7 @@ void LLManip::renderGuidelines(BOOL draw_x, BOOL draw_y, BOOL draw_z) return; } - //LLVector3 center_agent = LLSelectMgr::getInstanceFast()->getBBoxOfSelection().getCenterAgent(); + //LLVector3 center_agent = LLSelectMgr::getInstance()->getBBoxOfSelection().getCenterAgent(); LLVector3 center_agent = getPivotPoint(); gGL.pushMatrix(); diff --git a/indra/newview/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp index eea9e3d1a1739effaf607a392929a2ef48de0e8c..c51e925453a38d996e536bcdda7c75ea27b168a0 100644 --- a/indra/newview/llmaniprotate.cpp +++ b/indra/newview/llmaniprotate.cpp @@ -105,7 +105,7 @@ LLManipRotate::LLManipRotate( LLToolComposite* composite ) void LLManipRotate::handleSelect() { // *FIX: put this in mouseDown? - LLSelectMgr::getInstanceFast()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK); + LLSelectMgr::getInstance()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK); if (gFloaterTools) { gFloaterTools->setStatusText("rotate"); @@ -158,10 +158,7 @@ void LLManipRotate::render() } else { - if (LLGLSLShader::sNoFixedFunction) - { - gDebugProgram.bind(); - } + gDebugProgram.bind(); LLGLEnable cull_face(GL_CULL_FACE); LLGLDepthTest gls_depth(GL_FALSE); @@ -215,10 +212,7 @@ void LLManipRotate::render() } gGL.popMatrix(); - if (LLGLSLShader::sNoFixedFunction) - { - gUIProgram.bind(); - } + gUIProgram.bind(); } gGL.translatef( center.mV[VX], center.mV[VY], center.mV[VZ] ); @@ -230,16 +224,13 @@ void LLManipRotate::render() LLVector3 grid_scale; LLQuaternion grid_rotation; - LLSelectMgr::getInstanceFast()->getGrid(grid_origin, grid_rotation, grid_scale); + LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale); grid_rotation.getAngleAxis(&angle_radians, &x, &y, &z); gGL.rotatef(angle_radians * RAD_TO_DEG, x, y, z); - if (LLGLSLShader::sNoFixedFunction) - { - gDebugProgram.bind(); - } + gDebugProgram.bind(); if (mManipPart == LL_ROT_Z) { @@ -361,11 +352,7 @@ void LLManipRotate::render() } - if (LLGLSLShader::sNoFixedFunction) - { - gUIProgram.bind(); - } - + gUIProgram.bind(); } gGL.popMatrix(); gGL.popMatrix(); @@ -410,10 +397,10 @@ BOOL LLManipRotate::handleMouseDownOnPart( S32 x, S32 y, MASK mask ) highlightManipulators(x, y); S32 hit_part = mHighlightedPart; // we just started a drag, so save initial object positions - LLSelectMgr::getInstanceFast()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_ROTATE); + LLSelectMgr::getInstance()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_ROTATE); // save selection center - mRotationCenter = gAgent.getPosGlobalFromAgent( getPivotPoint() ); //LLSelectMgr::getInstanceFast()->getSelectionCenterGlobal(); + mRotationCenter = gAgent.getPosGlobalFromAgent( getPivotPoint() ); //LLSelectMgr::getInstance()->getSelectionCenterGlobal(); mManipPart = (EManipPart)hit_part; LLVector3 center = gAgent.getPosAgentFromGlobal( mRotationCenter ); @@ -460,7 +447,7 @@ BOOL LLManipRotate::handleMouseDownOnPart( S32 x, S32 y, MASK mask ) // Route future Mouse messages here preemptively. (Release on mouse up.) setMouseCapture( TRUE ); - LLSelectMgr::getInstanceFast()->enableSilhouette(FALSE); + LLSelectMgr::getInstance()->enableSilhouette(FALSE); mHelpTextTimer.reset(); sNumTimesHelpTextShown++; @@ -505,12 +492,12 @@ BOOL LLManipRotate::handleMouseUp(S32 x, S32 y, MASK mask) mManipPart = LL_NO_PART; // Might have missed last update due to timing. - LLSelectMgr::getInstanceFast()->sendMultipleUpdate( UPD_ROTATION | UPD_POSITION ); - LLSelectMgr::getInstanceFast()->enableSilhouette(TRUE); + LLSelectMgr::getInstance()->sendMultipleUpdate( UPD_ROTATION | UPD_POSITION ); + LLSelectMgr::getInstance()->enableSilhouette(TRUE); //gAgent.setObjectTracking(gSavedSettings.getBOOL("TrackFocusObject")); - LLSelectMgr::getInstanceFast()->updateSelectionCenter(); - LLSelectMgr::getInstanceFast()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK); + LLSelectMgr::getInstance()->updateSelectionCenter(); + LLSelectMgr::getInstance()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK); } return LLManip::handleMouseUp(x, y, mask); @@ -626,7 +613,7 @@ void LLManipRotate::drag( S32 x, S32 y ) object->setRotation(new_rot, damped); LLVOAvatar* avatar = object->asAvatar(); if (avatar && avatar->isSelf() - && LLSelectMgr::getInstanceFast()->mAllowSelectAvatar + && LLSelectMgr::getInstance()->mAllowSelectAvatar && !object->getParent()) { // Normal avatars use object's orienttion, but self uses @@ -694,7 +681,7 @@ void LLManipRotate::drag( S32 x, S32 y ) if (object->isRootEdit() && !object->isAttachment()) { LLVector3d new_pos_global = gAgent.getPosGlobalFromAgent(new_position); - new_pos_global = LLWorld::getInstanceFast()->clipToVisibleRegions(selectNode->mSavedPositionGlobal, new_pos_global); + new_pos_global = LLWorld::getInstance()->clipToVisibleRegions(selectNode->mSavedPositionGlobal, new_pos_global); new_position = gAgent.getPosAgentFromGlobal(new_pos_global); } @@ -743,20 +730,20 @@ void LLManipRotate::drag( S32 x, S32 y ) } // store changes to override updates - for (LLSelectNode* selectNode : LLSelectMgr::getInstanceFast()->getSelection()->begin_end()) + for (LLSelectNode* selectNode : LLSelectMgr::getInstance()->getSelection()->begin_end()) { LLViewerObject*cur = selectNode->getObject(); LLViewerObject *root_object = (cur == NULL) ? NULL : cur->getRootEdit(); if( cur->permModify() && cur->permMove() && !cur->isPermanentEnforced() && ((root_object == NULL) || !root_object->isPermanentEnforced()) && - (!cur->isAvatar() || LLSelectMgr::getInstanceFast()->mAllowSelectAvatar)) + (!cur->isAvatar() || LLSelectMgr::getInstance()->mAllowSelectAvatar)) { selectNode->mLastRotation = cur->getRotation(); selectNode->mLastPositionLocal = cur->getPosition(); } } - LLSelectMgr::getInstanceFast()->updateSelectionCenter(); + LLSelectMgr::getInstance()->updateSelectionCenter(); // RN: just clear focus so camera doesn't follow spurious object updates gAgentCamera.clearFocusObject(); @@ -788,7 +775,7 @@ void LLManipRotate::renderSnapGuides() LLVector3 grid_scale; LLQuaternion grid_rotation; - LLSelectMgr::getInstanceFast()->getGrid(grid_origin, grid_rotation, grid_scale, true); + LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale, true); LLVector3 constraint_axis = getConstraintAxis(); @@ -812,7 +799,7 @@ void LLManipRotate::renderSnapGuides() { test_axis = test_axis * ~grid_rotation; } - else if (LLSelectMgr::getInstanceFast()->getGridMode() == GRID_MODE_REF_OBJECT) + else if (LLSelectMgr::getInstance()->getGridMode() == GRID_MODE_REF_OBJECT) { test_axis = test_axis * ~grid_rotation; constrain_to_ref_object = TRUE; @@ -1166,9 +1153,9 @@ void LLManipRotate::renderSnapGuides() { if (mHelpTextTimer.getElapsedTimeF32() < sHelpTextVisibleTime + sHelpTextFadeTime && sNumTimesHelpTextShown < sMaxTimesShowHelpText) { - LLVector3 selection_center_start = LLSelectMgr::getInstanceFast()->getSavedBBoxOfSelection().getCenterAgent(); + LLVector3 selection_center_start = LLSelectMgr::getInstance()->getSavedBBoxOfSelection().getCenterAgent(); - LLVector3 offset_dir = LLViewerCamera::getInstanceFast()->getUpAxis(); + LLVector3 offset_dir = LLViewerCamera::getInstance()->getUpAxis(); F32 line_alpha = ALControlCache::GridOpacity; @@ -1197,7 +1184,7 @@ BOOL LLManipRotate::updateVisiblity() // JC - 03.26.2002 if (!hasMouseCapture()) { - mRotationCenter = gAgent.getPosGlobalFromAgent( getPivotPoint() );//LLSelectMgr::getInstanceFast()->getSelectionCenterGlobal(); + mRotationCenter = gAgent.getPosGlobalFromAgent( getPivotPoint() );//LLSelectMgr::getInstance()->getSelectionCenterGlobal(); } BOOL visible = FALSE; @@ -1212,7 +1199,7 @@ BOOL LLManipRotate::updateVisiblity() mCenterToCamNorm = mCenterToCam; mCenterToCamMag = mCenterToCamNorm.normVec(); - mRadiusMeters = RADIUS_PIXELS / (F32) LLViewerCamera::getInstanceFast()->getViewHeightInPixels(); + mRadiusMeters = RADIUS_PIXELS / (F32) LLViewerCamera::getInstance()->getViewHeightInPixels(); mRadiusMeters /= gAgentCamera.mHUDCurZoom; mRadiusMeters *= ui_scale_factor; @@ -1228,13 +1215,13 @@ BOOL LLManipRotate::updateVisiblity() } else { - visible = LLViewerCamera::getInstanceFast()->projectPosAgentToScreen(center, mCenterScreen ); + visible = LLViewerCamera::getInstance()->projectPosAgentToScreen(center, mCenterScreen ); if( visible ) { mCenterToCam = gAgentCamera.getCameraPositionAgent() - center; mCenterToCamNorm = mCenterToCam; mCenterToCamMag = mCenterToCamNorm.normVec(); - LLVector3 cameraAtAxis = LLViewerCamera::getInstanceFast()->getAtAxis(); + LLVector3 cameraAtAxis = LLViewerCamera::getInstance()->getAtAxis(); cameraAtAxis.normVec(); F32 z_dist = -1.f * (mCenterToCam * cameraAtAxis); @@ -1251,8 +1238,8 @@ BOOL LLManipRotate::updateVisiblity() if (mCenterToCamMag > 0.001f) { - F32 fraction_of_fov = RADIUS_PIXELS / (F32) LLViewerCamera::getInstanceFast()->getViewHeightInPixels(); - F32 apparent_angle = fraction_of_fov * LLViewerCamera::getInstanceFast()->getView(); // radians + F32 fraction_of_fov = RADIUS_PIXELS / (F32) LLViewerCamera::getInstance()->getViewHeightInPixels(); + F32 apparent_angle = fraction_of_fov * LLViewerCamera::getInstance()->getView(); // radians mRadiusMeters = z_dist * tan(apparent_angle); mRadiusMeters *= ui_scale_factor; @@ -1361,7 +1348,7 @@ LLVector3 LLManipRotate::getConstraintAxis() LLVector3 grid_scale; LLQuaternion grid_rotation; - LLSelectMgr::getInstanceFast()->getGrid(grid_origin, grid_rotation, grid_scale); + LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale); LLSelectNode* first_node = mObjectSelection->getFirstMoveableNode(TRUE); if (first_node) @@ -1388,7 +1375,7 @@ LLQuaternion LLManipRotate::dragConstrained( S32 x, S32 y ) LLVector3 grid_scale; LLQuaternion grid_rotation; - LLSelectMgr::getInstanceFast()->getGrid(grid_origin, grid_rotation, grid_scale); + LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale); LLVector3 axis1; LLVector3 axis2; @@ -1398,7 +1385,7 @@ LLQuaternion LLManipRotate::dragConstrained( S32 x, S32 y ) { test_axis = test_axis * ~grid_rotation; } - else if (LLSelectMgr::getInstanceFast()->getGridMode() == GRID_MODE_REF_OBJECT) + else if (LLSelectMgr::getInstance()->getGridMode() == GRID_MODE_REF_OBJECT) { test_axis = test_axis * ~grid_rotation; } @@ -1422,7 +1409,7 @@ LLQuaternion LLManipRotate::dragConstrained( S32 x, S32 y ) { axis1 = axis1 * grid_rotation; } - else if (LLSelectMgr::getInstanceFast()->getGridMode() == GRID_MODE_REF_OBJECT) + else if (LLSelectMgr::getInstance()->getGridMode() == GRID_MODE_REF_OBJECT) { axis1 = axis1 * grid_rotation; } @@ -1751,7 +1738,7 @@ LLVector3 LLManipRotate::intersectRayWithSphere( const LLVector3& ray_pt, const //static void LLManipRotate::mouseToRay( S32 x, S32 y, LLVector3* ray_pt, LLVector3* ray_dir ) { - if (LLSelectMgr::getInstanceFast()->getSelection()->getSelectType() == SELECT_TYPE_HUD) + if (LLSelectMgr::getInstance()->getSelection()->getSelectType() == SELECT_TYPE_HUD) { F32 mouse_x = (((F32)x / gViewerWindow->getWorldViewRectScaled().getWidth()) - 0.5f) / gAgentCamera.mHUDCurZoom; F32 mouse_y = ((((F32)y) / gViewerWindow->getWorldViewRectScaled().getHeight()) - 0.5f) / gAgentCamera.mHUDCurZoom; @@ -1762,7 +1749,7 @@ void LLManipRotate::mouseToRay( S32 x, S32 y, LLVector3* ray_pt, LLVector3* ray_ else { *ray_pt = gAgentCamera.getCameraPositionAgent(); - LLViewerCamera::getInstanceFast()->projectScreenToPosAgent(x, y, ray_dir); + LLViewerCamera::getInstance()->projectScreenToPosAgent(x, y, ray_dir); *ray_dir -= *ray_pt; ray_dir->normVec(); } @@ -1772,7 +1759,7 @@ void LLManipRotate::highlightManipulators( S32 x, S32 y ) { mHighlightedPart = LL_NO_PART; - //LLBBox bbox = LLSelectMgr::getInstanceFast()->getBBoxOfSelection(); + //LLBBox bbox = LLSelectMgr::getInstance()->getBBoxOfSelection(); LLViewerObject *first_object = mObjectSelection->getFirstMoveableObject(TRUE); if (!first_object) @@ -1790,7 +1777,7 @@ void LLManipRotate::highlightManipulators( S32 x, S32 y ) LLVector3 grid_scale; LLQuaternion grid_rotation; - LLSelectMgr::getInstanceFast()->getGrid(grid_origin, grid_rotation, grid_scale); + LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale); LLVector3 rot_x_axis = LLVector3::x_axis * grid_rotation; LLVector3 rot_y_axis = LLVector3::y_axis * grid_rotation; diff --git a/indra/newview/llmanipscale.cpp b/indra/newview/llmanipscale.cpp index b65f3ae7089110f1e2dd03199c9321da0ccda8a5..a8f5637274a7a883963f60af20a6457a3478fbf5 100644 --- a/indra/newview/llmanipscale.cpp +++ b/indra/newview/llmanipscale.cpp @@ -170,9 +170,9 @@ inline void LLManipScale::conditionalHighlight( U32 part, const LLColor4* highli void LLManipScale::handleSelect() { - LLBBox bbox = LLSelectMgr::getInstanceFast()->getBBoxOfSelection(); + LLBBox bbox = LLSelectMgr::getInstance()->getBBoxOfSelection(); updateSnapGuides(bbox); - LLSelectMgr::getInstanceFast()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK); + LLSelectMgr::getInstance()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK); if (gFloaterTools) { gFloaterTools->setStatusText("scale"); @@ -216,7 +216,7 @@ void LLManipScale::render() LLGLDepthTest gls_depth(GL_TRUE); LLGLEnable gl_blend(GL_BLEND); LLGLEnable gls_alpha_test(GL_ALPHA_TEST); - LLBBox bbox = LLSelectMgr::getInstanceFast()->getBBoxOfSelection(); + LLBBox bbox = LLSelectMgr::getInstance()->getBBoxOfSelection(); if( canAffectSelection() ) { @@ -241,7 +241,7 @@ void LLManipScale::render() { for (S32 i = 0; i < NUM_MANIPULATORS; i++) { - mBoxHandleSize[i] = BOX_HANDLE_BASE_SIZE * BOX_HANDLE_BASE_FACTOR / (F32) LLViewerCamera::getInstanceFast()->getViewHeightInPixels(); + mBoxHandleSize[i] = BOX_HANDLE_BASE_SIZE * BOX_HANDLE_BASE_FACTOR / (F32) LLViewerCamera::getInstance()->getViewHeightInPixels(); mBoxHandleSize[i] /= gAgentCamera.mHUDCurZoom; mBoxHandleSize[i] *= ui_scale_factor; } @@ -267,8 +267,8 @@ void LLManipScale::render() if (range_squared > 0.001f * 0.001f) { // range != zero - F32 fraction_of_fov = BOX_HANDLE_BASE_SIZE / (F32) LLViewerCamera::getInstanceFast()->getViewHeightInPixels(); - F32 apparent_angle = fraction_of_fov * LLViewerCamera::getInstanceFast()->getView(); // radians + F32 fraction_of_fov = BOX_HANDLE_BASE_SIZE / (F32) LLViewerCamera::getInstance()->getViewHeightInPixels(); + F32 apparent_angle = fraction_of_fov * LLViewerCamera::getInstance()->getView(); // radians mBoxHandleSize[i] = (F32) sqrtf(range_squared) * tan(apparent_angle) * BOX_HANDLE_BASE_FACTOR; } else @@ -347,10 +347,10 @@ BOOL LLManipScale::handleMouseDownOnPart( S32 x, S32 y, MASK mask ) highlightManipulators(x, y); S32 hit_part = mHighlightedPart; - LLSelectMgr::getInstanceFast()->enableSilhouette(FALSE); + LLSelectMgr::getInstance()->enableSilhouette(FALSE); mManipPart = (EManipPart)hit_part; - LLBBox bbox = LLSelectMgr::getInstanceFast()->getBBoxOfSelection(); + LLBBox bbox = LLSelectMgr::getInstance()->getBBoxOfSelection(); LLVector3 box_center_agent = bbox.getCenterAgent(); LLVector3 box_corner_agent = bbox.localToAgent( unitVectorToLocalBBoxExtent( partToUnitVector( mManipPart ), bbox ) ); @@ -367,7 +367,7 @@ BOOL LLManipScale::handleMouseDownOnPart( S32 x, S32 y, MASK mask ) mDragPointGlobal = mDragStartPointGlobal; // we just started a drag, so save initial object positions, orientations, and scales - LLSelectMgr::getInstanceFast()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_SCALE); + LLSelectMgr::getInstance()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_SCALE); // Route future Mouse messages here preemptively. (Release on mouse up.) setMouseCapture( TRUE ); @@ -397,7 +397,7 @@ BOOL LLManipScale::handleMouseUp(S32 x, S32 y, MASK mask) } //send texture update - auto& select_mgr = LLSelectMgr::instanceFast(); + auto& select_mgr = LLSelectMgr::instance(); select_mgr.adjustTexturesByScale(TRUE, getStretchTextures()); select_mgr.enableSilhouette(TRUE); @@ -446,7 +446,7 @@ BOOL LLManipScale::handleHover(S32 x, S32 y, MASK mask) } // Patch up textures, if possible. - LLSelectMgr::getInstanceFast()->adjustTexturesByScale(FALSE, getStretchTextures()); + LLSelectMgr::getInstance()->adjustTexturesByScale(FALSE, getStretchTextures()); gViewerWindow->setCursor(UI_CURSOR_TOOLSCALE); return TRUE; @@ -458,7 +458,7 @@ void LLManipScale::highlightManipulators(S32 x, S32 y) // If we have something selected, try to hit its manipulator handles. // Don't do this with nothing selected, as it kills the framerate. - LLBBox bbox = LLSelectMgr::getInstanceFast()->getBBoxOfSelection(); + LLBBox bbox = LLSelectMgr::getInstance()->getBBoxOfSelection(); if( canAffectSelection() ) { @@ -471,15 +471,15 @@ void LLManipScale::highlightManipulators(S32 x, S32 y) transform *= cfr; LLMatrix4 window_scale; F32 zoom_level = 2.f * gAgentCamera.mHUDCurZoom; - window_scale.initAll(LLVector3(zoom_level / LLViewerCamera::getInstanceFast()->getAspect(), zoom_level, 0.f), + window_scale.initAll(LLVector3(zoom_level / LLViewerCamera::getInstance()->getAspect(), zoom_level, 0.f), LLQuaternion::DEFAULT, LLVector3::zero); transform *= window_scale; } else { - LLMatrix4 projMatrix(LLViewerCamera::getInstanceFast()->getProjection().getF32ptr()); - LLMatrix4 modelView(LLViewerCamera::getInstanceFast()->getModelview().getF32ptr()); + LLMatrix4 projMatrix(LLViewerCamera::getInstance()->getProjection().getF32ptr()); + LLMatrix4 modelView(LLViewerCamera::getInstance()->getModelview().getF32ptr()); transform.initAll(LLVector3(1.f, 1.f, 1.f), bbox.getRotation(), bbox.getPositionAgent()); transform *= modelView; @@ -833,7 +833,7 @@ void LLManipScale::drag( S32 x, S32 y ) } // store changes to override updates - auto& select_mgr = LLSelectMgr::instanceFast(); + auto& select_mgr = LLSelectMgr::instance(); for (LLSelectNode* selectNode : select_mgr.getSelection()->begin_end()) { LLViewerObject*cur = selectNode->getObject(); @@ -881,7 +881,7 @@ void LLManipScale::dragCorner( S32 x, S32 y ) } mDragPointGlobal = lerp(mDragStartCenterGlobal, mDragStartPointGlobal, t); - LLBBox bbox = LLSelectMgr::getInstanceFast()->getBBoxOfSelection(); + LLBBox bbox = LLSelectMgr::getInstance()->getBBoxOfSelection(); F32 scale_factor = 1.f; F32 max_scale = partToMaxScale(mManipPart, bbox); F32 min_scale = partToMinScale(mManipPart, bbox); @@ -946,7 +946,7 @@ void LLManipScale::dragCorner( S32 x, S32 y ) } } - LLWorld* world_inst = LLWorld::getInstanceFast(); + LLWorld* world_inst = LLWorld::getInstance(); F32 max_scale_factor = LLWorld::getInstance()->getRegionMaxPrimScale() / LLWorld::getInstance()->getRegionMinPrimScale(); F32 min_scale_factor = LLWorld::getInstance()->getRegionMinPrimScale() / LLWorld::getInstance()->getRegionMaxPrimScale(); @@ -1076,7 +1076,7 @@ void LLManipScale::dragFace( S32 x, S32 y ) LLVector3 drag_start_dir_f; drag_start_dir_f.set(drag_start_dir_d); - LLBBox bbox = LLSelectMgr::getInstanceFast()->getBBoxOfSelection(); + LLBBox bbox = LLSelectMgr::getInstance()->getBBoxOfSelection(); F32 s = 0; F32 t = 0; @@ -1214,7 +1214,7 @@ void LLManipScale::sendUpdates( BOOL send_position_update, BOOL send_scale_updat // enforce minimum update delay and don't stream updates on sub-object selections if( elapsed_time > UPDATE_DELAY && !ALControlCache::EditLinkedParts ) { - LLSelectMgr::getInstanceFast()->sendMultipleUpdate( update_flags ); + LLSelectMgr::getInstance()->sendMultipleUpdate( update_flags ); update_timer.reset(); mSendUpdateOnMouseUp = FALSE; } @@ -1281,7 +1281,7 @@ void LLManipScale::stretchFace( const LLVector3& drag_start_agent, const LLVecto if (cur->isRootEdit() && !cur->isAttachment()) { - LLVector3d new_pos_global = LLWorld::getInstanceFast()->clipToVisibleRegions(selectNode->mSavedPositionGlobal, selectNode->mSavedPositionGlobal + delta_pos_global); + LLVector3d new_pos_global = LLWorld::getInstance()->clipToVisibleRegions(selectNode->mSavedPositionGlobal, selectNode->mSavedPositionGlobal + delta_pos_global); cur->setPositionGlobal( new_pos_global ); } else @@ -1333,7 +1333,7 @@ void LLManipScale::renderGuidelinesPart( const LLBBox& bbox ) guideline_end -= guideline_start; guideline_end.normalize(); - guideline_end *= gAgent.getRegion() ? gAgent.getRegion()->getWidth() : LLWorld::getInstanceFast()->getRegionWidthInMeters(); + guideline_end *= gAgent.getRegion() ? gAgent.getRegion()->getWidth() : LLWorld::getInstance()->getRegionWidthInMeters(); guideline_end += guideline_start; { @@ -1351,7 +1351,7 @@ void LLManipScale::updateSnapGuides(const LLBBox& bbox) LLVector3 grid_origin; LLVector3 grid_scale; LLQuaternion grid_rotation; - LLSelectMgr::getInstanceFast()->getGrid(grid_origin, grid_rotation, grid_scale); + LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale); bool uniform = LLManipScale::getUniform(); @@ -1366,8 +1366,8 @@ void LLManipScale::updateSnapGuides(const LLBBox& bbox) } else { - F32 object_distance = dist_vec(box_corner_agent, LLViewerCamera::getInstanceFast()->getOrigin()); - mSnapRegimeOffset = (SNAP_GUIDE_SCREEN_OFFSET * gViewerWindow->getWorldViewWidthRaw() * object_distance) / LLViewerCamera::getInstanceFast()->getPixelMeterRatio(); + F32 object_distance = dist_vec(box_corner_agent, LLViewerCamera::getInstance()->getOrigin()); + mSnapRegimeOffset = (SNAP_GUIDE_SCREEN_OFFSET * gViewerWindow->getWorldViewWidthRaw() * object_distance) / LLViewerCamera::getInstance()->getPixelMeterRatio(); } LLVector3 cam_at_axis; F32 snap_guide_length; @@ -1378,9 +1378,9 @@ void LLManipScale::updateSnapGuides(const LLBBox& bbox) } else { - cam_at_axis = LLViewerCamera::getInstanceFast()->getAtAxis(); - F32 manipulator_distance = dist_vec(box_corner_agent, LLViewerCamera::getInstanceFast()->getOrigin()); - snap_guide_length = (SNAP_GUIDE_SCREEN_LENGTH * gViewerWindow->getWorldViewWidthRaw() * manipulator_distance) / LLViewerCamera::getInstanceFast()->getPixelMeterRatio(); + cam_at_axis = LLViewerCamera::getInstance()->getAtAxis(); + F32 manipulator_distance = dist_vec(box_corner_agent, LLViewerCamera::getInstance()->getOrigin()); + snap_guide_length = (SNAP_GUIDE_SCREEN_LENGTH * gViewerWindow->getWorldViewWidthRaw() * manipulator_distance) / LLViewerCamera::getInstance()->getPixelMeterRatio(); } mSnapGuideLength = snap_guide_length / llmax(0.1f, (llmin(mSnapGuideDir1 * cam_at_axis, mSnapGuideDir2 * cam_at_axis))); @@ -1408,7 +1408,7 @@ void LLManipScale::updateSnapGuides(const LLBBox& bbox) LLVector3 scale_snap = grid_scale; mScaleSnapUnit1 = scale_snap.scaleVec(partToUnitVector( mManipPart )).length(); mScaleSnapUnit2 = mScaleSnapUnit1; - mSnapGuideDir1 *= mSnapGuideDir1 * LLViewerCamera::getInstanceFast()->getUpAxis() > 0.f ? 1.f : -1.f; + mSnapGuideDir1 *= mSnapGuideDir1 * LLViewerCamera::getInstance()->getUpAxis() > 0.f ? 1.f : -1.f; mSnapGuideDir2 = mSnapGuideDir1 * -1.f; mSnapDir1 = mScaleDir; mSnapDir2 = mScaleDir; @@ -1422,7 +1422,7 @@ void LLManipScale::updateSnapGuides(const LLBBox& bbox) } else { - local_camera_dir = (LLViewerCamera::getInstanceFast()->getOrigin() - box_corner_agent) * ~bbox.getRotation(); + local_camera_dir = (LLViewerCamera::getInstance()->getOrigin() - box_corner_agent) * ~bbox.getRotation(); local_camera_dir.normalize(); } @@ -1688,7 +1688,7 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox) gGL.end(); } - LLVector2 screen_translate_axis(llabs(mScaleDir * LLViewerCamera::getInstanceFast()->getLeftAxis()), llabs(mScaleDir * LLViewerCamera::getInstanceFast()->getUpAxis())); + LLVector2 screen_translate_axis(llabs(mScaleDir * LLViewerCamera::getInstance()->getLeftAxis()), llabs(mScaleDir * LLViewerCamera::getInstance()->getUpAxis())); screen_translate_axis.normalize(); S32 tick_label_spacing = ll_round(screen_translate_axis * sTickLabelSpacing); @@ -1793,7 +1793,7 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox) { LLVector3 text_origin = tick_pos + (mSnapGuideDir1 * mSnapRegimeOffset * (1.f + tick_scale)); - EGridMode grid_mode = LLSelectMgr::getInstanceFast()->getGridMode(); + EGridMode grid_mode = LLSelectMgr::getInstance()->getGridMode(); F32 tick_value; if (grid_mode == GRID_MODE_WORLD) { @@ -1840,7 +1840,7 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox) { LLVector3 text_origin = tick_pos + (mSnapGuideDir2 * mSnapRegimeOffset * (1.f + tick_scale)); - EGridMode grid_mode = LLSelectMgr::getInstanceFast()->getGridMode(); + EGridMode grid_mode = LLSelectMgr::getInstance()->getGridMode(); F32 tick_value; if (grid_mode == GRID_MODE_WORLD) { @@ -1869,10 +1869,10 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox) { if (mHelpTextTimer.getElapsedTimeF32() < sHelpTextVisibleTime + sHelpTextFadeTime && sNumTimesHelpTextShown < sMaxTimesShowHelpText) { - LLVector3 selection_center_start = LLSelectMgr::getInstanceFast()->getSavedBBoxOfSelection().getCenterAgent(); + LLVector3 selection_center_start = LLSelectMgr::getInstance()->getSavedBBoxOfSelection().getCenterAgent(); LLVector3 offset_dir; - if (mSnapGuideDir1 * LLViewerCamera::getInstanceFast()->getAtAxis() > mSnapGuideDir2 * LLViewerCamera::getInstanceFast()->getAtAxis()) + if (mSnapGuideDir1 * LLViewerCamera::getInstance()->getAtAxis() > mSnapGuideDir2 * LLViewerCamera::getInstance()->getAtAxis()) { offset_dir = mSnapGuideDir2; } @@ -1889,7 +1889,7 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox) help_text_color.mV[VALPHA] = clamp_rescale(mHelpTextTimer.getElapsedTimeF32(), sHelpTextVisibleTime, sHelpTextVisibleTime + sHelpTextFadeTime, grid_alpha, 0.f); hud_render_text(scale_help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(scale_help_text.c_str()), 3.f, help_text_color, false); static const LLWString scale_help_text2 = utf8str_to_wstring(LLTrans::getString("manip_hint2")); - help_text_pos -= LLViewerCamera::getInstanceFast()->getUpAxis() * mSnapRegimeOffset * 0.4f; + help_text_pos -= LLViewerCamera::getInstance()->getUpAxis() * mSnapRegimeOffset * 0.4f; hud_render_text(scale_help_text2, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(scale_help_text2.c_str()), 3.f, help_text_color, false); } } diff --git a/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp index f0f4e01748d562efc38d2a506d6be967b4a2b268..2e1284fa161f7e23352ce8938d062812ae325246 100644 --- a/indra/newview/llmaniptranslate.cpp +++ b/indra/newview/llmaniptranslate.cpp @@ -289,7 +289,7 @@ LLManipTranslate::~LLManipTranslate() void LLManipTranslate::handleSelect() { - LLSelectMgr::getInstanceFast()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK); + LLSelectMgr::getInstance()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK); if (gFloaterTools) { gFloaterTools->setStatusText("move"); @@ -340,12 +340,12 @@ BOOL LLManipTranslate::handleMouseDownOnPart( S32 x, S32 y, MASK mask ) mHelpTextTimer.reset(); sNumTimesHelpTextShown++; - LLSelectMgr::getInstanceFast()->getGrid(mGridOrigin, mGridRotation, mGridScale); + LLSelectMgr::getInstance()->getGrid(mGridOrigin, mGridRotation, mGridScale); - LLSelectMgr::getInstanceFast()->enableSilhouette(FALSE); + LLSelectMgr::getInstance()->enableSilhouette(FALSE); // we just started a drag, so save initial object positions - LLSelectMgr::getInstanceFast()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_MOVE); + LLSelectMgr::getInstance()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_MOVE); mManipPart = (EManipPart)hit_part; mMouseDownX = x; @@ -376,7 +376,7 @@ BOOL LLManipTranslate::handleMouseDownOnPart( S32 x, S32 y, MASK mask ) BOOL axis_exists = getManipAxis(selected_object, mManipPart, axis); getManipNormal(selected_object, mManipPart, mManipNormal); - //LLVector3 select_center_agent = gAgent.getPosAgentFromGlobal(LLSelectMgr::getInstanceFast()->getSelectionCenterGlobal()); + //LLVector3 select_center_agent = gAgent.getPosAgentFromGlobal(LLSelectMgr::getInstance()->getSelectionCenterGlobal()); // TomY: The above should (?) be identical to the below LLVector3 select_center_agent = getPivotPoint(); mSubdivisions = getSubdivisionLevel(select_center_agent, axis_exists ? axis : LLVector3::z_axis, getMinGridScale()); @@ -385,7 +385,7 @@ BOOL LLManipTranslate::handleMouseDownOnPart( S32 x, S32 y, MASK mask ) if (mManipPart >= LL_YZ_PLANE && mManipPart <= LL_XY_PLANE) { LLCoordGL mouse_pos; - if (!LLViewerCamera::getInstanceFast()->projectPosAgentToScreen(select_center_agent, mouse_pos)) + if (!LLViewerCamera::getInstance()->projectPosAgentToScreen(select_center_agent, mouse_pos)) { // mouse_pos may be nonsense LL_WARNS() << "Failed to project object center to screen" << LL_ENDL; @@ -398,7 +398,7 @@ BOOL LLManipTranslate::handleMouseDownOnPart( S32 x, S32 y, MASK mask ) } } - LLSelectMgr::getInstanceFast()->updateSelectionCenter(); + LLSelectMgr::getInstance()->updateSelectionCenter(); LLVector3d object_start_global = gAgent.getPosGlobalFromAgent(getPivotPoint()); getMousePointOnPlaneGlobal(mDragCursorStartGlobal, x, y, object_start_global, mManipNormal); mDragSelectionStartGlobal = object_start_global; @@ -483,7 +483,7 @@ BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask) if (mask == MASK_COPY) { // ...we're trying to make a copy - LLSelectMgr::getInstanceFast()->selectDuplicate(LLVector3::zero, FALSE); + LLSelectMgr::getInstance()->selectDuplicate(LLVector3::zero, FALSE); mCopyMadeThisDrag = TRUE; // When we make the copy, we don't want to do any other processing. @@ -526,7 +526,7 @@ BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask) axis_d.setVec(axis_f); - LLSelectMgr::getInstanceFast()->updateSelectionCenter(); + LLSelectMgr::getInstance()->updateSelectionCenter(); LLVector3d current_pos_global = gAgent.getPosGlobalFromAgent(getPivotPoint()); mSubdivisions = getSubdivisionLevel(getPivotPoint(), axis_f, getMinGridScale()); @@ -592,7 +592,7 @@ BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask) // snap to planar grid LLVector3 cursor_point_agent = gAgent.getPosAgentFromGlobal(cursor_point_global); - LLVector3 camera_plane_projection = LLViewerCamera::getInstanceFast()->getAtAxis(); + LLVector3 camera_plane_projection = LLViewerCamera::getInstance()->getAtAxis(); camera_plane_projection -= projected_vec(camera_plane_projection, mManipNormal); camera_plane_projection.normVec(); LLVector3 camera_projected_dir = camera_plane_projection; @@ -728,7 +728,7 @@ BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask) LLVector3d new_position_global = selectNode->mSavedPositionGlobal + clamped_relative_move; // Don't let object centers go too far underground - LLWorld* world_inst = LLWorld::getInstanceFast(); + LLWorld* world_inst = LLWorld::getInstance(); F64 min_height = world_inst->getMinAllowedZ(object, object->getPositionGlobal()); if (new_position_global.mdV[VZ] < min_height) { @@ -736,9 +736,9 @@ BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask) } // For safety, cap heights where objects can be dragged - if (new_position_global.mdV[VZ] > LLWorld::getInstanceFast()->getRegionMaxHeight()) + if (new_position_global.mdV[VZ] > LLWorld::getInstance()->getRegionMaxHeight()) { - new_position_global.mdV[VZ] = LLWorld::getInstanceFast()->getRegionMaxHeight(); + new_position_global.mdV[VZ] = LLWorld::getInstance()->getRegionMaxHeight(); } // Grass is always drawn on the ground, so clamp its position to the ground @@ -780,7 +780,7 @@ BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask) } } - LLSelectMgr::getInstanceFast()->updateSelectionCenter(); + LLSelectMgr::getInstance()->updateSelectionCenter(); gAgentCamera.clearFocusObject(); dialog_refresh_all(); // ??? is this necessary? @@ -800,9 +800,9 @@ void LLManipTranslate::highlightManipulators(S32 x, S32 y) return; } - //LLBBox bbox = LLSelectMgr::getInstanceFast()->getBBoxOfSelection(); - LLMatrix4 projMatrix( LLViewerCamera::getInstanceFast()->getProjection().getF32ptr() ); - LLMatrix4 modelView( LLViewerCamera::getInstanceFast()->getModelview().getF32ptr() ); + //LLBBox bbox = LLSelectMgr::getInstance()->getBBoxOfSelection(); + LLMatrix4 projMatrix( LLViewerCamera::getInstance()->getProjection().getF32ptr() ); + LLMatrix4 modelView( LLViewerCamera::getInstance()->getModelview().getF32ptr() ); LLVector3 object_position = getPivotPoint(); @@ -810,7 +810,7 @@ void LLManipTranslate::highlightManipulators(S32 x, S32 y) LLVector3 grid_scale; LLQuaternion grid_rotation; - LLSelectMgr::getInstanceFast()->getGrid(grid_origin, grid_rotation, grid_scale); + LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale); LLVector3 relative_camera_dir; @@ -825,14 +825,14 @@ void LLManipTranslate::highlightManipulators(S32 x, S32 y) transform *= cfr; LLMatrix4 window_scale; F32 zoom_level = 2.f * gAgentCamera.mHUDCurZoom; - window_scale.initAll(LLVector3(zoom_level / LLViewerCamera::getInstanceFast()->getAspect(), zoom_level, 0.f), + window_scale.initAll(LLVector3(zoom_level / LLViewerCamera::getInstance()->getAspect(), zoom_level, 0.f), LLQuaternion::DEFAULT, LLVector3::zero); transform *= window_scale; } else { - relative_camera_dir = (object_position - LLViewerCamera::getInstanceFast()->getOrigin()) * ~grid_rotation; + relative_camera_dir = (object_position - LLViewerCamera::getInstance()->getOrigin()) * ~grid_rotation; relative_camera_dir.normVec(); transform.initRotTrans(grid_rotation, LLVector4(object_position)); @@ -1049,13 +1049,13 @@ BOOL LLManipTranslate::handleMouseUp(S32 x, S32 y, MASK mask) { // make sure arrow colors go back to normal mManipPart = LL_NO_PART; - LLSelectMgr::getInstanceFast()->enableSilhouette(TRUE); + LLSelectMgr::getInstance()->enableSilhouette(TRUE); // Might have missed last update due to UPDATE_DELAY timing. - LLSelectMgr::getInstanceFast()->sendMultipleUpdate( UPD_POSITION ); + LLSelectMgr::getInstance()->sendMultipleUpdate( UPD_POSITION ); mInSnapRegime = FALSE; - LLSelectMgr::getInstanceFast()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK); + LLSelectMgr::getInstance()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK); //gAgent.setObjectTracking(gSavedSettings.getBOOL("TrackFocusObject")); } @@ -1119,8 +1119,8 @@ void LLManipTranslate::renderSnapGuides() LLVector3 grid_scale; LLQuaternion grid_rotation; - LLSelectMgr::getInstanceFast()->getGrid(grid_origin, grid_rotation, grid_scale); - LLVector3 saved_selection_center = getSavedPivotPoint(); //LLSelectMgr::getInstanceFast()->getSavedBBoxOfSelection().getCenterAgent(); + LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale); + LLVector3 saved_selection_center = getSavedPivotPoint(); //LLSelectMgr::getInstance()->getSavedBBoxOfSelection().getCenterAgent(); LLVector3 selection_center = getPivotPoint(); LLViewerObject *first_object = first_node->getObject(); @@ -1163,7 +1163,7 @@ void LLManipTranslate::renderSnapGuides() } else { - at_axis_abs = saved_selection_center - LLViewerCamera::getInstanceFast()->getOrigin(); + at_axis_abs = saved_selection_center - LLViewerCamera::getInstance()->getOrigin(); at_axis_abs.normVec(); at_axis_abs = at_axis_abs * ~grid_rotation; @@ -1239,14 +1239,14 @@ void LLManipTranslate::renderSnapGuides() } else { - LLVector3 cam_to_selection = getPivotPoint() - LLViewerCamera::getInstanceFast()->getOrigin(); + LLVector3 cam_to_selection = getPivotPoint() - LLViewerCamera::getInstance()->getOrigin(); F32 current_range = cam_to_selection.normVec(); - guide_size_meters = SNAP_GUIDE_SCREEN_SIZE * gViewerWindow->getWorldViewHeightRaw() * current_range / LLViewerCamera::getInstanceFast()->getPixelMeterRatio(); + guide_size_meters = SNAP_GUIDE_SCREEN_SIZE * gViewerWindow->getWorldViewHeightRaw() * current_range / LLViewerCamera::getInstance()->getPixelMeterRatio(); - F32 fraction_of_fov = mAxisArrowLength / (F32) LLViewerCamera::getInstanceFast()->getViewHeightInPixels(); - F32 apparent_angle = fraction_of_fov * LLViewerCamera::getInstanceFast()->getView(); // radians + F32 fraction_of_fov = mAxisArrowLength / (F32) LLViewerCamera::getInstance()->getViewHeightInPixels(); + F32 apparent_angle = fraction_of_fov * LLViewerCamera::getInstance()->getView(); // radians F32 offset_at_camera = tan(apparent_angle) * 1.5f; - F32 range = dist_vec(gAgent.getPosAgentFromGlobal(first_node->mSavedPositionGlobal), LLViewerCamera::getInstanceFast()->getOrigin()); + F32 range = dist_vec(gAgent.getPosAgentFromGlobal(first_node->mSavedPositionGlobal), LLViewerCamera::getInstance()->getOrigin()); mSnapOffsetMeters = range * offset_at_camera; } @@ -1375,7 +1375,7 @@ void LLManipTranslate::renderSnapGuides() sub_div_offset = ll_round(fmod(dist_grid_axis - offset_nearest_grid_unit, getMinGridScale() * 32.f) / smallest_grid_unit_scale); - LLVector2 screen_translate_axis(llabs(translate_axis * LLViewerCamera::getInstanceFast()->getLeftAxis()), llabs(translate_axis * LLViewerCamera::getInstanceFast()->getUpAxis())); + LLVector2 screen_translate_axis(llabs(translate_axis * LLViewerCamera::getInstance()->getLeftAxis()), llabs(translate_axis * LLViewerCamera::getInstance()->getUpAxis())); screen_translate_axis.normVec(); S32 tick_label_spacing = ll_round(screen_translate_axis * sTickLabelSpacing); @@ -1400,7 +1400,7 @@ void LLManipTranslate::renderSnapGuides() { F32 snap_offset_meters; - if (mSnapOffsetAxis * LLViewerCamera::getInstanceFast()->getUpAxis() > 0.f) + if (mSnapOffsetAxis * LLViewerCamera::getInstance()->getUpAxis() > 0.f) { snap_offset_meters = mSnapOffsetMeters; } @@ -1414,7 +1414,7 @@ void LLManipTranslate::renderSnapGuides() LLVector3 tick_offset = (tick_pos - mGridOrigin) * ~mGridRotation; F32 offset_val = 0.5f * tick_offset.mV[ARROW_TO_AXIS[mManipPart]] / getMinGridScale(); - EGridMode grid_mode = LLSelectMgr::getInstanceFast()->getGridMode(); + EGridMode grid_mode = LLSelectMgr::getInstance()->getGridMode(); F32 text_highlight = 0.8f; if(i - ll_round(offset_nearest_grid_unit / smallest_grid_unit_scale) == 0 && mInSnapRegime) { @@ -1439,7 +1439,7 @@ void LLManipTranslate::renderSnapGuides() if (mHelpTextTimer.getElapsedTimeF32() < sHelpTextVisibleTime + sHelpTextFadeTime && sNumTimesHelpTextShown < sMaxTimesShowHelpText) { F32 snap_offset_meters_up; - if (mSnapOffsetAxis * LLViewerCamera::getInstanceFast()->getUpAxis() > 0.f) + if (mSnapOffsetAxis * LLViewerCamera::getInstance()->getUpAxis() > 0.f) { snap_offset_meters_up = mSnapOffsetMeters; } @@ -1448,7 +1448,7 @@ void LLManipTranslate::renderSnapGuides() snap_offset_meters_up = -mSnapOffsetMeters; } - LLVector3 selection_center_start = getSavedPivotPoint();//LLSelectMgr::getInstanceFast()->getSavedBBoxOfSelection().getCenterAgent(); + LLVector3 selection_center_start = getSavedPivotPoint();//LLSelectMgr::getInstance()->getSavedBBoxOfSelection().getCenterAgent(); LLVector3 help_text_pos = selection_center_start + (snap_offset_meters_up * 3.f * mSnapOffsetAxis); const LLFontGL* big_fontp = LLFontGL::getFontSansSerif(); @@ -1458,7 +1458,7 @@ void LLManipTranslate::renderSnapGuides() help_text_color.mV[VALPHA] = clamp_rescale(mHelpTextTimer.getElapsedTimeF32(), sHelpTextVisibleTime, sHelpTextVisibleTime + sHelpTextFadeTime, line_alpha, 0.f); hud_render_text(translate_help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(translate_help_text.c_str()), 3.f, help_text_color, false); static const LLWString translate_help_text2 = utf8str_to_wstring(LLTrans::getString("manip_hint2")); - help_text_pos -= LLViewerCamera::getInstanceFast()->getUpAxis() * mSnapOffsetMeters * 0.2f; + help_text_pos -= LLViewerCamera::getInstance()->getUpAxis() * mSnapOffsetMeters * 0.2f; hud_render_text(translate_help_text2, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(translate_help_text2.c_str()), 3.f, help_text_color, false); } } @@ -1579,11 +1579,6 @@ void LLManipTranslate::renderSnapGuides() LLGLEnable stipple(GL_LINE_STIPPLE); gGL.flush(); - if (!LLGLSLShader::sNoFixedFunction) - { - glLineStipple(1, 0x3333); - } - switch (mManipPart) { case LL_YZ_PLANE: @@ -1647,7 +1642,7 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal, LLQuaternion grid_rotation, LLColor4 inner_color) { - if (!gSavedSettings.getBOOL("GridCrossSections") || !LLGLSLShader::sNoFixedFunction) + if (!gSavedSettings.getBOOL("GridCrossSections")) { return; } @@ -1684,7 +1679,7 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal, //setup clip plane normal = normal * grid_rotation; - if (normal * (LLViewerCamera::getInstanceFast()->getOrigin()-selection_center) < 0) + if (normal * (LLViewerCamera::getInstance()->getOrigin()-selection_center) < 0) { normal = -normal; } @@ -1796,7 +1791,7 @@ void LLManipTranslate::renderTranslationHandles() LLQuaternion grid_rotation; LLGLDepthTest gls_depth(GL_FALSE); - LLSelectMgr::getInstanceFast()->getGrid(grid_origin, grid_rotation, grid_scale); + LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale); LLVector3 at_axis; if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) { @@ -1804,7 +1799,7 @@ void LLManipTranslate::renderTranslationHandles() } else { - at_axis = LLViewerCamera::getInstanceFast()->getAtAxis() * ~grid_rotation; + at_axis = LLViewerCamera::getInstance()->getAtAxis() * ~grid_rotation; } if (at_axis.mV[VX] > 0.f) @@ -1863,8 +1858,8 @@ void LLManipTranslate::renderTranslationHandles() if (range > 0.001f) { // range != zero - F32 fraction_of_fov = mAxisArrowLength / (F32) LLViewerCamera::getInstanceFast()->getViewHeightInPixels(); - F32 apparent_angle = fraction_of_fov * LLViewerCamera::getInstanceFast()->getView(); // radians + F32 fraction_of_fov = mAxisArrowLength / (F32) LLViewerCamera::getInstance()->getViewHeightInPixels(); + F32 apparent_angle = fraction_of_fov * LLViewerCamera::getInstance()->getView(); // radians mArrowLengthMeters = range * tan(apparent_angle); } else @@ -1902,7 +1897,7 @@ void LLManipTranslate::renderTranslationHandles() } else { - relative_camera_dir = (selection_center - LLViewerCamera::getInstanceFast()->getOrigin()) * invRotation; + relative_camera_dir = (selection_center - LLViewerCamera::getInstance()->getOrigin()) * invRotation; } relative_camera_dir.normVec(); diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp index b3df9d9ac7bd353e6ab5be5388935ea3332ccd51..6899618d7f3d58223cfbfd830c573381bf5c0ea2 100644 --- a/indra/newview/llmarketplacefunctions.cpp +++ b/indra/newview/llmarketplacefunctions.cpp @@ -217,7 +217,7 @@ namespace LLMarketplaceImport httpHeaders->append(HTTP_OUT_HEADER_CONNECTION, "Keep-Alive"); httpHeaders->append(HTTP_OUT_HEADER_COOKIE, sMarketplaceCookie); httpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_XML); - httpHeaders->append(HTTP_OUT_HEADER_USER_AGENT, LLViewerMedia::getInstanceFast()->getCurrentUserAgent()); + httpHeaders->append(HTTP_OUT_HEADER_USER_AGENT, LLViewerMedia::getInstance()->getCurrentUserAgent()); LLSD result = httpAdapter->postAndSuspend(httpRequest, url, LLSD(), httpOpts, httpHeaders); @@ -281,11 +281,11 @@ namespace LLMarketplaceImport httpHeaders->append(HTTP_OUT_HEADER_ACCEPT, "*/*"); httpHeaders->append(HTTP_OUT_HEADER_COOKIE, sMarketplaceCookie); httpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_LLSD_XML); - httpHeaders->append(HTTP_OUT_HEADER_USER_AGENT, LLViewerMedia::getInstanceFast()->getCurrentUserAgent()); + httpHeaders->append(HTTP_OUT_HEADER_USER_AGENT, LLViewerMedia::getInstance()->getCurrentUserAgent()); } else { - httpHeaders = LLViewerMedia::getInstanceFast()->getHttpHeaders(); + httpHeaders = LLViewerMedia::getInstance()->getHttpHeaders(); } LLSD result = httpAdapter->getAndSuspend(httpRequest, url, httpOpts, httpHeaders); @@ -756,7 +756,14 @@ void LLMarketplaceData::initializeSLM(const status_updated_signal_t::slot_type& if (mMarketPlaceStatus != MarketplaceStatusCodes::MARKET_PLACE_NOT_INITIALIZED) { // If already initialized, just confirm the status so the callback gets called - setSLMStatus(mMarketPlaceStatus); + if (mMarketPlaceFailureReason.empty()) + { + setSLMStatus(mMarketPlaceStatus); + } + else + { + setSLMConnectionFailure(mMarketPlaceFailureReason); + } } else { @@ -797,28 +804,27 @@ void LLMarketplaceData::getMerchantStatusCoro() if (httpCode == HTTP_NOT_FOUND) { log_SLM_infos("Get /merchant", httpCode, std::string("User is not a merchant")); - setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_MERCHANT); + LLMarketplaceData::instance().setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_MERCHANT); } else if (httpCode == HTTP_SERVICE_UNAVAILABLE) { log_SLM_infos("Get /merchant", httpCode, std::string("Merchant is not migrated")); - setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_MIGRATED_MERCHANT); + LLMarketplaceData::instance().setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_MIGRATED_MERCHANT); } - else if (httpCode == HTTP_INTERNAL_ERROR) + else { - // 499 includes timeout and ssl error - marketplace is down or having issues, we do not show it in this request according to MAINT-5938 LL_WARNS("SLM") << "SLM Merchant Request failed with status: " << httpCode << ", reason : " << status.toString() << ", code : " << result["error_code"].asString() << ", description : " << result["error_description"].asString() << LL_ENDL; - LLMarketplaceData::instance().setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE); - } - else - { - std::string err_code = result["error_code"].asString(); - //std::string err_description = result["error_description"].asString(); - log_SLM_warning("Get /merchant", httpCode, status.toString(), err_code, result["error_description"]); - setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE); + std::string reason = status.toString(); + if (reason.empty()) + { + reason = result["error_code"].asString(); + } + // Since user might not even have a marketplace, there is no reason to report the error + // to the user, instead write it down into listings' floater + LLMarketplaceData::instance().setSLMConnectionFailure(reason); } return; } @@ -1278,6 +1284,17 @@ std::string LLMarketplaceData::getSLMConnectURL(const std::string& route) void LLMarketplaceData::setSLMStatus(U32 status) { mMarketPlaceStatus = status; + mMarketPlaceFailureReason.clear(); + if (mStatusUpdatedSignal) + { + (*mStatusUpdatedSignal)(); + } +} + +void LLMarketplaceData::setSLMConnectionFailure(const std::string& reason) +{ + mMarketPlaceStatus = MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE; + mMarketPlaceFailureReason = reason; if (mStatusUpdatedSignal) { (*mStatusUpdatedSignal)(); diff --git a/indra/newview/llmarketplacefunctions.h b/indra/newview/llmarketplacefunctions.h index c6a69def5795499b35bbb1a29eede3e49038412a..4d41e6c1e666e559cba04f095eb10c6c5295a4e3 100644 --- a/indra/newview/llmarketplacefunctions.h +++ b/indra/newview/llmarketplacefunctions.h @@ -198,7 +198,9 @@ class LLMarketplaceData final typedef boost::signals2::signal<void ()> status_updated_signal_t; void initializeSLM(const status_updated_signal_t::slot_type& cb); U32 getSLMStatus() const { return mMarketPlaceStatus; } + std::string getSLMConnectionfailureReason() { return mMarketPlaceFailureReason; } void setSLMStatus(U32 status); + void setSLMConnectionFailure(const std::string& reason); void getSLMListings(); bool isEmpty() { return (mMarketplaceItems.size() == 0); } void setDataFetchedSignal(const status_updated_signal_t::slot_type& cb); @@ -272,6 +274,7 @@ class LLMarketplaceData final // Handling Marketplace connection and inventory connection U32 mMarketPlaceStatus; + std::string mMarketPlaceFailureReason; status_updated_signal_t* mStatusUpdatedSignal; LLInventoryObserver* mInventoryObserver; bool mDirtyCount; // If true, stock count value need to be updated at the next check diff --git a/indra/newview/llmaterialmgr.cpp b/indra/newview/llmaterialmgr.cpp index 38bdd0b183a8ebc0b4262033c674f20053921995..2a7184a7929a376749d88f4fc8dedc0f34963390 100644 --- a/indra/newview/llmaterialmgr.cpp +++ b/indra/newview/llmaterialmgr.cpp @@ -587,13 +587,11 @@ void LLMaterialMgr::onPutResponse(bool success, const LLSD& content) } } -static LLTrace::BlockTimerStatHandle FTM_MATERIALS_IDLE("Idle Materials"); - void LLMaterialMgr::onIdle(void*) { - LL_RECORD_BLOCK_TIME(FTM_MATERIALS_IDLE); + LL_PROFILE_ZONE_SCOPED; - LLMaterialMgr* instancep = LLMaterialMgr::getInstanceFast(); + LLMaterialMgr* instancep = LLMaterialMgr::getInstance(); if (!instancep->mGetQueue.empty()) { @@ -624,7 +622,7 @@ void LLMaterialMgr::CapsRecvForRegion(const LLUUID& regionId, LLUUID regionTest, void LLMaterialMgr::processGetQueue() { - auto& worldInst = LLWorld::instanceFast(); + auto& worldInst = LLWorld::instance(); get_queue_t::iterator loopRegionQueue = mGetQueue.begin(); while (mGetQueue.end() != loopRegionQueue) { @@ -839,7 +837,7 @@ void LLMaterialMgr::processGetAllQueue() void LLMaterialMgr::processGetAllQueueCoro(LLUUID regionId) { - auto& worldInst = LLWorld::instanceFast(); + auto& worldInst = LLWorld::instance(); LLViewerRegion* regionp = worldInst.getRegionFromID(regionId); if (regionp == NULL) { diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp index 42c71483e5bf28ccae543ebd7d80766bec4ec041..d53548587274515f9d360b769f6aa12872937064 100644 --- a/indra/newview/llmediactrl.cpp +++ b/indra/newview/llmediactrl.cpp @@ -743,7 +743,7 @@ bool LLMediaCtrl::ensureMediaSourceExists() if(mMediaSource.isNull()) { // If we don't already have a media source, try to create one. - mMediaSource = LLViewerMedia::getInstanceFast()->newMediaImpl(mMediaTextureID, mTextureWidth, mTextureHeight); + mMediaSource = LLViewerMedia::getInstance()->newMediaImpl(mMediaTextureID, mTextureWidth, mTextureHeight); if ( mMediaSource ) { mMediaSource->setUsedInUI(true); diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index b43138141bdfb552f45cba39208b91627bc1ce9c..b80649c0b1a40e118eeaeb6e0d4bd72d041344c1 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -387,6 +387,9 @@ U32 LLMeshRepository::sLODPending = 0; U32 LLMeshRepository::sCacheBytesRead = 0; U32 LLMeshRepository::sCacheBytesWritten = 0; +U32 LLMeshRepository::sCacheBytesHeaders = 0; +U32 LLMeshRepository::sCacheBytesSkins = 0; +U32 LLMeshRepository::sCacheBytesDecomps = 0; U32 LLMeshRepository::sCacheReads = 0; U32 LLMeshRepository::sCacheWrites = 0; U32 LLMeshRepository::sMaxLockHoldoffs = 0; @@ -1900,6 +1903,7 @@ EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mes { LLMutexLock lock(mHeaderMutex); mMeshHeader[mesh_id] = { header_size, header }; + LLMeshRepository::sCacheBytesHeaders += header_size; } @@ -1989,7 +1993,7 @@ bool LLMeshRepoThread::skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 dat return false; } - // LL_DEBUGS(LOG_MESH) << "info pelvis offset" << info.mPelvisOffset << LL_ENDL; + // LL_DEBUGS(LOG_MESH) << "info pelvis offset" << info.mPelvisOffset << LL_ENDL; { LLMutexLock lock(mMutex); mSkinInfoQ.emplace_back(skin_info); @@ -3647,7 +3651,7 @@ void LLMeshRepository::unregisterMesh(LLVOVolume* vobj) S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_params, S32 detail, S32 last_lod) { - LL_RECORD_BLOCK_TIME(FTM_MESH_FETCH); + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; //LL_LL_RECORD_BLOCK_TIME(FTM_MESH_FETCH); // Manage time-to-load metrics for mesh download operations. metricsProgress(1); @@ -3733,7 +3737,7 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para void LLMeshRepository::notifyLoadedMeshes() { //called from main thread - LL_RECORD_BLOCK_TIME(FTM_MESH_FETCH); + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; //LL_RECORD_BLOCK_TIME(FTM_MESH_FETCH); // GetMesh2 operation with keepalives, etc. With pipelining, // we'll increase this. See llappcorehttp and llcorehttp for @@ -4007,6 +4011,8 @@ void LLMeshRepository::notifyLoadedMeshes() void LLMeshRepository::notifySkinInfoReceived(LLMeshSkinInfo* info) { auto pair = mSkinMap.emplace(info->mMeshID, info); // Cache into LLPointer + // Alternative: We can get skin size from header + sCacheBytesSkins += info->sizeBytes(); skin_load_map::iterator iter = mLoadingSkins.find(info->mMeshID); if (iter != mLoadingSkins.end()) @@ -4045,10 +4051,14 @@ void LLMeshRepository::notifyDecompositionReceived(LLModel::Decomposition* decom { //just insert decomp into map mDecompositionMap[decomp->mMeshID] = decomp; mLoadingDecompositions.erase(decomp->mMeshID); + sCacheBytesDecomps += decomp->sizeBytes(); } else { //merge decomp with existing entry + sCacheBytesDecomps -= iter->second->sizeBytes(); iter->second->merge(decomp); + sCacheBytesDecomps += iter->second->sizeBytes(); + mLoadingDecompositions.erase(decomp->mMeshID); delete decomp; } @@ -4133,11 +4143,10 @@ S32 LLMeshRepository::getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lo LLPointer<LLMeshSkinInfo> LLMeshRepository::getSkinInfo(const LLUUID& mesh_id, LLVOVolume* requesting_obj) { - LL_RECORD_BLOCK_TIME(FTM_MESH_FETCH); - - if (mesh_id.notNull()) - { - skin_map::iterator iter = mSkinMap.find(mesh_id); + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; + if (mesh_id.notNull()) + { + skin_map::iterator iter = mSkinMap.find(mesh_id); if (iter != mSkinMap.end()) { return iter->second; @@ -4169,7 +4178,7 @@ LLPointer<LLMeshSkinInfo> LLMeshRepository::getSkinInfo(const LLUUID& mesh_id, L void LLMeshRepository::fetchPhysicsShape(const LLUUID& mesh_id) { - LL_RECORD_BLOCK_TIME(FTM_MESH_FETCH); + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; //LL_RECORD_BLOCK_TIME(FTM_MESH_FETCH); if (mesh_id.notNull()) { @@ -4198,7 +4207,7 @@ void LLMeshRepository::fetchPhysicsShape(const LLUUID& mesh_id) LLModel::Decomposition* LLMeshRepository::getDecomposition(const LLUUID& mesh_id) { - LL_RECORD_BLOCK_TIME(FTM_MESH_FETCH); + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; //LL_RECORD_BLOCK_TIME(FTM_MESH_FETCH); LLModel::Decomposition* ret = NULL; @@ -4447,7 +4456,7 @@ F32 LLMeshRepository::getStreamingCostLegacy(LLSD& header, F32 radius, S32* byte { if (header.has("404") || !header.has("lowest_lod") - || ((header.has("version") || !LLGridManager::instanceFast().isInSecondlife()) && header["version"].asInteger() > MAX_MESH_VERSION)) + || ((header.has("version") || !LLGridManager::instance().isInSecondlife()) && header["version"].asInteger() > MAX_MESH_VERSION)) { return 0.f; } diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index cfd05cfac0eafda9be9b1116b7bb9d7daf68a69d..e8015100ba92fbd898a1e9223613f2f339ab886e 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -27,6 +27,7 @@ #ifndef LL_MESH_REPOSITORY_H #define LL_MESH_REPOSITORY_H +#include <unordered_map> #include "llassettype.h" #include "llmodel.h" #include "lluuid.h" @@ -570,6 +571,9 @@ class LLMeshRepository static U32 sLODProcessing; static U32 sCacheBytesRead; static U32 sCacheBytesWritten; + static U32 sCacheBytesHeaders; + static U32 sCacheBytesSkins; + static U32 sCacheBytesDecomps; static U32 sCacheReads; static U32 sCacheWrites; static U32 sMaxLockHoldoffs; // Maximum sequential locking failures @@ -603,7 +607,7 @@ class LLMeshRepository S32 getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod); static S32 getActualMeshLOD(LLSD& header, S32 lod); - LLPointer<LLMeshSkinInfo> getSkinInfo(const LLUUID& mesh_id, LLVOVolume* requesting_obj); + LLPointer<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); @@ -661,7 +665,7 @@ class LLMeshRepository std::queue<LLUUID> mPendingPhysicsShapeRequests; U32 mMeshThreadCount; - + LLMeshRepoThread* mThread; std::vector<LLMeshUploadThread*> mUploads; std::vector<LLMeshUploadThread*> mUploadWaitList; diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index 8d1c029dab2c0fa5774ec8c4de60f6ef86c0f50a..1c015a2c3de3cc025dbdc32389b23c09ace071e7 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -41,6 +41,7 @@ #include "lliconctrl.h" #include "llmatrix4a.h" #include "llmeshrepository.h" +#include "llmeshoptimizer.h" #include "llrender.h" #include "llsdutil_math.h" #include "llskinningutil.h" @@ -67,7 +68,6 @@ #include "lltabcontainer.h" #include "lltextbox.h" -#include <meshoptimizer.h> #include <boost/algorithm/string.hpp> bool LLModelPreview::sIgnoreLoadedCallback = false; @@ -87,9 +87,9 @@ static const LLColor4 PREVIEW_DEG_FILL_COL(1.f, 0.f, 0.f, 0.5f); static const F32 PREVIEW_DEG_EDGE_WIDTH(3.f); static const F32 PREVIEW_DEG_POINT_SIZE(8.f); static const F32 PREVIEW_ZOOM_LIMIT(10.f); +static const std::string DEFAULT_PHYSICS_MESH_NAME = "default_physics_shape"; const F32 SKIN_WEIGHT_CAMERA_DISTANCE = 16.f; - LLViewerFetchedTexture* bindMaterialDiffuseTexture(const LLImportMaterial& material) { LLViewerFetchedTexture *texture = LLViewerTextureManager::getFetchedTexture(material.getDiffuseMap(), FTT_DEFAULT, TRUE, LLGLTexture::BOOST_PREVIEW); @@ -433,6 +433,20 @@ void LLModelPreview::rebuildUploadData() LLFloaterModelPreview::addStringToLog(out, false); } } + if (mWarnOfUnmatchedPhyicsMeshes && !lod_model && (i == LLModel::LOD_PHYSICS)) + { + // Despite the various strategies above, if we don't now have a physics model, we're going to end up with decomposition. + // That's ok, but might not what they wanted. Use default_physics_shape if found. + std::ostringstream out; + out << "No physics model specified for " << instance.mLabel; + if (mDefaultPhysicsShapeP) + { + out << " - using: " << DEFAULT_PHYSICS_MESH_NAME; + lod_model = mDefaultPhysicsShapeP; + } + LL_WARNS() << out.str() << LL_ENDL; + LLFloaterModelPreview::addStringToLog(out, !mDefaultPhysicsShapeP); // Flash log tab if no default. + } if (lod_model) { @@ -495,9 +509,7 @@ void LLModelPreview::rebuildUploadData() bool upload_skinweights = fmp && fmp->childGetValue("upload_skin").asBoolean(); if (upload_skinweights && high_lod_model->mSkinInfo.mJointNames.size() > 0) { - alignas(16) LLMatrix4 bind_mat(LLMatrix4::kUninitialized); - high_lod_model->mSkinInfo.mBindShapeMatrix.store4a((F32*)bind_mat.mMatrix); - LLQuaternion bind_rot = LLSkinningUtil::getUnscaledQuaternion(bind_mat); + LLQuaternion bind_rot = LLSkinningUtil::getUnscaledQuaternion(LLMatrix4(high_lod_model->mSkinInfo.mBindShapeMatrix)); LLQuaternion identity; if (!bind_rot.isEqualEps(identity, 0.01f)) { @@ -819,8 +831,10 @@ void LLModelPreview::clearIncompatible(S32 lod) // at this point we don't care about sub-models, // different amount of sub-models means face count mismatch, not incompatibility U32 lod_size = countRootModels(mModel[lod]); + bool replaced_base_model = (lod == LLModel::LOD_HIGH); for (U32 i = 0; i <= LLModel::LOD_HIGH; i++) - { //clear out any entries that aren't compatible with this model + { + // Clear out any entries that aren't compatible with this model if (i != lod) { if (countRootModels(mModel[i]) != lod_size) @@ -834,9 +848,47 @@ void LLModelPreview::clearIncompatible(S32 lod) mBaseModel = mModel[lod]; mBaseScene = mScene[lod]; mVertexBuffer[5].clear(); + replaced_base_model = true; + } + } + } + } + + if (replaced_base_model && !mGenLOD) + { + // In case base was replaced, we might need to restart generation + + // Check if already started + bool subscribe_for_generation = mLodsQuery.empty(); + + // Remove previously scheduled work + mLodsQuery.clear(); + + LLFloaterModelPreview* fmp = LLFloaterModelPreview::sInstance; + if (!fmp) return; + + // Schedule new work + for (S32 i = LLModel::LOD_HIGH; i >= 0; --i) + { + if (mModel[i].empty()) + { + // Base model was replaced, regenerate this lod if applicable + LLComboBox* lod_combo = mFMP->findChild<LLComboBox>("lod_source_" + lod_name[i]); + if (!lod_combo) return; + + S32 lod_mode = lod_combo->getCurrentIndex(); + if (lod_mode != LOD_FROM_FILE) + { + mLodsQuery.push_back(i); } } } + + // Subscribe if we have pending work and not subscribed yet + if (!mLodsQuery.empty() && subscribe_for_generation) + { + doOnIdleRepeating(lodQueryCallback); + } } } @@ -999,6 +1051,13 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod) } else { + if (loaded_lod == LLModel::LOD_PHYSICS) + { // Explicitly loading physics. See if there is a default mesh. + LLMatrix4 ignored_transform; // Each mesh that uses this will supply their own. + mDefaultPhysicsShapeP = nullptr; + FindModel(mScene[loaded_lod], DEFAULT_PHYSICS_MESH_NAME + getLodSuffix(loaded_lod), mDefaultPhysicsShapeP, ignored_transform); + mWarnOfUnmatchedPhyicsMeshes = true; + } BOOL legacyMatching = gSavedSettings.getBOOL("ImporterLegacyMatching"); if (!legacyMatching) { @@ -1069,7 +1128,6 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod) LL_WARNS() << out.str() << LL_ENDL; LLFloaterModelPreview::addStringToLog(out, false); } - mModel[loaded_lod][idx]->mLabel = name; } } @@ -1226,8 +1284,9 @@ void LLModelPreview::restoreNormals() // Runs per object, but likely it is a better way to run per model+submodels // returns a ratio of base model indices to resulting indices // returns -1 in case of failure -F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *target_model, F32 indices_decimator, F32 error_threshold, bool sloppy) +F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *target_model, F32 indices_decimator, F32 error_threshold, eSimplificationMode simplification_mode) { + // I. Weld faces together // Figure out buffer size S32 size_indices = 0; S32 size_vertices = 0; @@ -1262,20 +1321,21 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe { const LLVolumeFace &face = base_model->getVolumeFace(face_idx); - // vertices + // Vertices S32 copy_bytes = face.mNumVertices * sizeof(LLVector4a); LLVector4a::memcpyNonAliased16((F32*)(combined_positions + combined_positions_shift), (F32*)face.mPositions, copy_bytes); - // normals + // Normals LLVector4a::memcpyNonAliased16((F32*)(combined_normals + combined_positions_shift), (F32*)face.mNormals, copy_bytes); - // tex coords + // Tex coords copy_bytes = face.mNumVertices * sizeof(LLVector2); memcpy((void*)(combined_tex_coords + combined_positions_shift), (void*)face.mTexCoords, copy_bytes); combined_positions_shift += face.mNumVertices; - // indices, sadly can't do dumb memcpy for indices, need to adjust each value + // Indices + // Sadly can't do dumb memcpy for indices, need to adjust each value for (S32 i = 0; i < face.mNumIndices; ++i) { U16 idx = face.mIndices[i]; @@ -1286,10 +1346,42 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe indices_idx_shift += face.mNumVertices; } - // Now that we have buffers, optimize + // II. Generate a shadow buffer if nessesary. + // Welds together vertices if possible + + U32* shadow_indices = NULL; + // if MESH_OPTIMIZER_FULL, just leave as is, since generateShadowIndexBufferU32 + // won't do anything new, model was remaped on a per face basis. + // Similar for MESH_OPTIMIZER_NO_TOPOLOGY, it's pointless + // since 'simplifySloppy' ignores all topology, including normals and uvs. + // Note: simplifySloppy can affect UVs significantly. + if (simplification_mode == MESH_OPTIMIZER_NO_NORMALS) + { + // strip normals, reflections should restore relatively correctly + shadow_indices = (U32*)ll_aligned_malloc_32(size_indices * sizeof(U32)); + LLMeshOptimizer::generateShadowIndexBufferU32(shadow_indices, combined_indices, size_indices, combined_positions, NULL, combined_tex_coords, size_vertices); + } + if (simplification_mode == MESH_OPTIMIZER_NO_UVS) + { + // strip uvs, can heavily affect textures + shadow_indices = (U32*)ll_aligned_malloc_32(size_indices * sizeof(U32)); + LLMeshOptimizer::generateShadowIndexBufferU32(shadow_indices, combined_indices, size_indices, combined_positions, NULL, NULL, size_vertices); + } + + U32* source_indices = NULL; + if (shadow_indices) + { + source_indices = shadow_indices; + } + else + { + source_indices = combined_indices; + } + + // III. Simplify S32 target_indices = 0; F32 result_error = 0; // how far from original the model is, 1 == 100% - S32 new_indices = 0; + S32 size_new_indices = 0; if (indices_decimator > 0) { @@ -1299,54 +1391,43 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe { target_indices = 3; } - if (sloppy) - { - new_indices = meshopt_simplifySloppy( - output_indices, - combined_indices, - size_indices, - (const float*)combined_positions, - size_vertices, - LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_VERTEX], - target_indices, - error_threshold, - &result_error - ); - } - else - { - new_indices = meshopt_simplify( - output_indices, - combined_indices, - size_indices, - (const float*)combined_positions, - size_vertices, - LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_VERTEX], - target_indices, - error_threshold, - &result_error - ); - } + + size_new_indices = LLMeshOptimizer::simplifyU32( + output_indices, + source_indices, + size_indices, + combined_positions, + size_vertices, + LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_VERTEX], + target_indices, + error_threshold, + simplification_mode == MESH_OPTIMIZER_NO_TOPOLOGY, + &result_error); if (result_error < 0) { LL_WARNS() << "Negative result error from meshoptimizer for model " << target_model->mLabel << " target Indices: " << target_indices - << " new Indices: " << new_indices + << " new Indices: " << size_new_indices << " original count: " << size_indices << LL_ENDL; } - if (new_indices < 3) + // free unused buffers + ll_aligned_free_32(combined_indices); + ll_aligned_free_32(shadow_indices); + combined_indices = NULL; + shadow_indices = NULL; + + if (size_new_indices < 3) { // Model should have at least one visible triangle ll_aligned_free<64>(combined_positions); ll_aligned_free_32(output_indices); - ll_aligned_free_32(combined_indices); return -1; } - // repack back into individual faces + // IV. Repack back into individual faces LLVector4a* buffer_positions = (LLVector4a*)ll_aligned_malloc<64>(sizeof(LLVector4a) * 2 * size_vertices + tc_bytes_size); LLVector4a* buffer_normals = buffer_positions + size_vertices; @@ -1377,7 +1458,7 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe } // Copy relevant indices and vertices - for (S32 i = 0; i < new_indices; ++i) + for (S32 i = 0; i < size_new_indices; ++i) { U32 idx = output_indices[i]; @@ -1400,19 +1481,19 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe LL_WARNS() << "Over triangle limit. Failed to optimize in 'per object' mode, falling back to per face variant for" << " model " << target_model->mLabel << " target Indices: " << target_indices - << " new Indices: " << new_indices + << " new Indices: " << size_new_indices << " original count: " << size_indices << " error treshold: " << error_threshold << LL_ENDL; // U16 vertices overflow shouldn't happen, but just in case - new_indices = 0; + size_new_indices = 0; valid_faces = 0; for (U32 face_idx = 0; face_idx < base_model->getNumVolumeFaces(); ++face_idx) { - genMeshOptimizerPerFace(base_model, target_model, face_idx, indices_decimator, error_threshold, false); + genMeshOptimizerPerFace(base_model, target_model, face_idx, indices_decimator, error_threshold, simplification_mode); const LLVolumeFace &face = target_model->getVolumeFace(face_idx); - new_indices += face.mNumIndices; + size_new_indices += face.mNumIndices; if (face.mNumIndices >= 3) { valid_faces++; @@ -1420,7 +1501,7 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe } if (valid_faces) { - return (F32)size_indices / (F32)new_indices; + return (F32)size_indices / (F32)size_new_indices; } else { @@ -1490,18 +1571,17 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe ll_aligned_free<64>(buffer_positions); ll_aligned_free_32(output_indices); ll_aligned_free_16(buffer_indices); - ll_aligned_free_32(combined_indices); - if (new_indices < 3 || valid_faces == 0) + if (size_new_indices < 3 || valid_faces == 0) { // Model should have at least one visible triangle return -1; } - return (F32)size_indices / (F32)new_indices; + return (F32)size_indices / (F32)size_new_indices; } -F32 LLModelPreview::genMeshOptimizerPerFace(LLModel *base_model, LLModel *target_model, U32 face_idx, F32 indices_decimator, F32 error_threshold, bool sloppy) +F32 LLModelPreview::genMeshOptimizerPerFace(LLModel *base_model, LLModel *target_model, U32 face_idx, F32 indices_decimator, F32 error_threshold, eSimplificationMode simplification_mode) { const LLVolumeFace &face = base_model->getVolumeFace(face_idx); S32 size_indices = face.mNumIndices; @@ -1509,14 +1589,40 @@ F32 LLModelPreview::genMeshOptimizerPerFace(LLModel *base_model, LLModel *target { return -1; } - // todo: do not allocate per each face, add one large buffer somewhere - // faces have limited amount of indices + S32 size = (size_indices * sizeof(U16) + 0xF) & ~0xF; - U16* output = (U16*)ll_aligned_malloc_16(size); + U16* output_indices = (U16*)ll_aligned_malloc_16(size); + + U16* shadow_indices = NULL; + // if MESH_OPTIMIZER_FULL, just leave as is, since generateShadowIndexBufferU32 + // won't do anything new, model was remaped on a per face basis. + // Similar for MESH_OPTIMIZER_NO_TOPOLOGY, it's pointless + // since 'simplifySloppy' ignores all topology, including normals and uvs. + if (simplification_mode == MESH_OPTIMIZER_NO_NORMALS) + { + U16* shadow_indices = (U16*)ll_aligned_malloc_16(size); + LLMeshOptimizer::generateShadowIndexBufferU16(shadow_indices, face.mIndices, size_indices, face.mPositions, NULL, face.mTexCoords, face.mNumVertices); + } + if (simplification_mode == MESH_OPTIMIZER_NO_UVS) + { + U16* shadow_indices = (U16*)ll_aligned_malloc_16(size); + LLMeshOptimizer::generateShadowIndexBufferU16(shadow_indices, face.mIndices, size_indices, face.mPositions, NULL, NULL, face.mNumVertices); + } + // Don't run ShadowIndexBuffer for MESH_OPTIMIZER_NO_TOPOLOGY, it's pointless + + U16* source_indices = NULL; + if (shadow_indices) + { + source_indices = shadow_indices; + } + else + { + source_indices = face.mIndices; + } S32 target_indices = 0; F32 result_error = 0; // how far from original the model is, 1 == 100% - S32 new_indices = 0; + S32 size_new_indices = 0; if (indices_decimator > 0) { @@ -1526,40 +1632,25 @@ F32 LLModelPreview::genMeshOptimizerPerFace(LLModel *base_model, LLModel *target { target_indices = 3; } - if (sloppy) - { - new_indices = meshopt_simplifySloppy( - output, - face.mIndices, - size_indices, - (const float*)face.mPositions, - face.mNumVertices, - LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_VERTEX], - target_indices, - error_threshold, - &result_error); - } - else - { - new_indices = meshopt_simplify( - output, - face.mIndices, - size_indices, - (const float*)face.mPositions, - face.mNumVertices, - LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_VERTEX], - target_indices, - error_threshold, - &result_error); - } + size_new_indices = LLMeshOptimizer::simplify( + output_indices, + source_indices, + size_indices, + face.mPositions, + face.mNumVertices, + LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_VERTEX], + target_indices, + error_threshold, + simplification_mode == MESH_OPTIMIZER_NO_TOPOLOGY, + &result_error); if (result_error < 0) { LL_WARNS() << "Negative result error from meshoptimizer for face " << face_idx << " of model " << target_model->mLabel << " target Indices: " << target_indices - << " new Indices: " << new_indices + << " new Indices: " << size_new_indices << " original count: " << size_indices << " error treshold: " << error_threshold << LL_ENDL; @@ -1570,10 +1661,9 @@ F32 LLModelPreview::genMeshOptimizerPerFace(LLModel *base_model, LLModel *target // Copy old values new_face = face; - - if (new_indices < 3) + if (size_new_indices < 3) { - if (!sloppy) + if (simplification_mode != MESH_OPTIMIZER_NO_TOPOLOGY) { // meshopt_optimizeSloppy() can optimize triangles away even if target_indices is > 2, // but optimize() isn't supposed to @@ -1597,23 +1687,24 @@ F32 LLModelPreview::genMeshOptimizerPerFace(LLModel *base_model, LLModel *target else { // Assign new values - new_face.resizeIndices(new_indices); // will wipe out mIndices, so new_face can't substitute output - S32 idx_size = (new_indices * sizeof(U16) + 0xF) & ~0xF; - LLVector4a::memcpyNonAliased16((F32*)new_face.mIndices, (F32*)output, idx_size); + new_face.resizeIndices(size_new_indices); // will wipe out mIndices, so new_face can't substitute output + S32 idx_size = (size_new_indices * sizeof(U16) + 0xF) & ~0xF; + LLVector4a::memcpyNonAliased16((F32*)new_face.mIndices, (F32*)output_indices, idx_size); - // clear unused values + // Clear unused values new_face.optimize(); } - ll_aligned_free_16(output); + ll_aligned_free_16(output_indices); + ll_aligned_free_16(shadow_indices); - if (new_indices < 3) + if (size_new_indices < 3) { // At least one triangle is needed return -1; } - return (F32)size_indices / (F32)new_indices; + return (F32)size_indices / (F32)size_new_indices; } void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 decimation, bool enforce_tri_limit) @@ -1626,7 +1717,7 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d out << "Invalid level of detail: " << which_lod; LL_WARNS() << out.str() << LL_ENDL; LLFloaterModelPreview::addStringToLog(out, false); - llassert(which_lod >= -1 && which_lod < LLModel::NUM_LODS); + assert(lod >= -1 && lod < LLModel::NUM_LODS); return; } @@ -1747,16 +1838,19 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d // Ideally this should run not per model, // but combine all submodels with origin model as well - if (model_meshopt_mode == MESH_OPTIMIZER_COMBINE) + if (model_meshopt_mode == MESH_OPTIMIZER_PRECISE) { - // Run meshoptimizer for each model/object, up to 8 faces in one model. - - // Ideally this should run not per model, - // but combine all submodels with origin model as well - F32 res = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, false); - if (res < 0) + // Run meshoptimizer for each face + for (U32 face_idx = 0; face_idx < base->getNumVolumeFaces(); ++face_idx) { - target_model->copyVolumeFaces(base); + F32 res = genMeshOptimizerPerFace(base, target_model, face_idx, indices_decimator, lod_error_threshold, MESH_OPTIMIZER_FULL); + if (res < 0) + { + // Mesh optimizer failed and returned an invalid model + const LLVolumeFace &face = base->getVolumeFace(face_idx); + LLVolumeFace &new_face = target_model->getVolumeFace(face_idx); + new_face = face; + } } } @@ -1765,19 +1859,29 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d // Run meshoptimizer for each face for (U32 face_idx = 0; face_idx < base->getNumVolumeFaces(); ++face_idx) { - if (genMeshOptimizerPerFace(base, target_model, face_idx, indices_decimator, lod_error_threshold, true) < 0) + if (genMeshOptimizerPerFace(base, target_model, face_idx, indices_decimator, lod_error_threshold, MESH_OPTIMIZER_NO_TOPOLOGY) < 0) { // Sloppy failed and returned an invalid model - genMeshOptimizerPerFace(base, target_model, face_idx, indices_decimator, lod_error_threshold, false); + genMeshOptimizerPerFace(base, target_model, face_idx, indices_decimator, lod_error_threshold, MESH_OPTIMIZER_FULL); } } } if (model_meshopt_mode == MESH_OPTIMIZER_AUTO) { - // Switches between 'combine' method and 'sloppy' based on combine's result. - F32 allowed_ratio_drift = 2.f; - F32 precise_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, false); + // Remove progressively more data if we can't reach the target. + F32 allowed_ratio_drift = 1.8f; + F32 precise_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, MESH_OPTIMIZER_FULL); + + if (precise_ratio < 0 || (precise_ratio * allowed_ratio_drift < indices_decimator)) + { + precise_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, MESH_OPTIMIZER_NO_NORMALS); + } + + if (precise_ratio < 0 || (precise_ratio * allowed_ratio_drift < indices_decimator)) + { + precise_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, MESH_OPTIMIZER_NO_UVS); + } if (precise_ratio < 0 || (precise_ratio * allowed_ratio_drift < indices_decimator)) { @@ -1785,10 +1889,11 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d // Sloppy variant can fail entirely and has issues with precision, // so code needs to do multiple attempts with different decimators. // Todo: this is a bit of a mess, needs to be refined and improved + F32 last_working_decimator = 0.f; F32 last_working_ratio = F32_MAX; - F32 sloppy_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, true); + F32 sloppy_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, MESH_OPTIMIZER_NO_TOPOLOGY); if (sloppy_ratio > 0) { @@ -1811,13 +1916,13 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d // side due to overal lack of precision, and we don't need an ideal result, which // likely does not exist, just a better one, so a partial correction is enough. F32 sloppy_decimator = indices_decimator * (indices_decimator / sloppy_ratio + 1) / 2; - sloppy_ratio = genMeshOptimizerPerModel(base, target_model, sloppy_decimator, lod_error_threshold, true); + sloppy_ratio = genMeshOptimizerPerModel(base, target_model, sloppy_decimator, lod_error_threshold, MESH_OPTIMIZER_NO_TOPOLOGY); } if (last_working_decimator > 0 && sloppy_ratio < last_working_ratio) { // Compensation didn't work, return back to previous decimator - sloppy_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, true); + sloppy_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, MESH_OPTIMIZER_NO_TOPOLOGY); } if (sloppy_ratio < 0) @@ -1850,7 +1955,7 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d && sloppy_decimator > precise_ratio && sloppy_decimator > 1)// precise_ratio isn't supposed to be below 1, but check just in case { - sloppy_ratio = genMeshOptimizerPerModel(base, target_model, sloppy_decimator, lod_error_threshold, true); + sloppy_ratio = genMeshOptimizerPerModel(base, target_model, sloppy_decimator, lod_error_threshold, MESH_OPTIMIZER_NO_TOPOLOGY); sloppy_decimator = sloppy_decimator / sloppy_decimation_step; } } @@ -1870,7 +1975,7 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d else { // Fallback to normal method - precise_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, false); + precise_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, MESH_OPTIMIZER_FULL); } LL_INFOS() << "Model " << target_model->getName() @@ -2598,8 +2703,6 @@ void LLModelPreview::clearBuffers() void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights) { - U32 tri_count = 0; - U32 vertex_count = 0; U32 mesh_count = 0; @@ -2632,7 +2735,6 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights) continue; } - LLModel* base_mdl = *base_iter; base_iter++; S32 num_faces = mdl->getNumVolumeFaces(); @@ -2707,7 +2809,7 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights) //find closest weight to vf.mVertices[i].mPosition LLVector3 pos(vf.mPositions[i].getF32ptr()); - const LLModel::weight_list& weight_list = base_mdl->getJointInfluences(pos); + const LLModel::weight_list& weight_list = mdl->getJointInfluences(pos); llassert(weight_list.size()>0 && weight_list.size() <= 4); // LLModel::loadModel() should guarantee this LLVector4 w(0, 0, 0, 0); @@ -2735,10 +2837,7 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights) mVertexBuffer[lod][mdl].push_back(vb); - vertex_count += num_vertices; - tri_count += num_indices / 3; ++mesh_count; - } } } @@ -2834,6 +2933,20 @@ void LLModelPreview::loadedCallback( { pPreview->lookupLODModelFiles(lod); } + + const LLVOAvatar* avatarp = pPreview->getPreviewAvatar(); + if (avatarp) { // set up ground plane for possible rendering + const LLVector3 root_pos = avatarp->mRoot->getPosition(); + const LLVector4a* ext = avatarp->mDrawable->getSpatialExtents(); + const LLVector4a min = ext[0], max = ext[1]; + const F32 center = (max[2] - min[2]) * 0.5f; + const F32 ground = root_pos[2] - center; + auto plane = pPreview->mGroundPlane; + plane[0] = {min[0], min[1], ground}; + plane[1] = {max[0], min[1], ground}; + plane[2] = {max[0], max[1], ground}; + plane[3] = {min[0], max[1], ground}; + } } } @@ -3041,6 +3154,9 @@ BOOL LLModelPreview::render() // (note: all these UI updates need to be somewhere that is not render) fmp->childSetValue("upload_skin", true); mFirstSkinUpdate = false; + upload_skin = true; + skin_weight = true; + mViewOption["show_skin_weight"] = true; } fmp->enableViewOption("show_skin_weight"); @@ -3127,9 +3243,9 @@ BOOL LLModelPreview::render() F32 aspect = (F32)preview_rect.getWidth() / preview_rect.getHeight(); - LLViewerCamera::getInstanceFast()->setAspect(aspect); + LLViewerCamera::getInstance()->setAspect(aspect); - LLViewerCamera::getInstanceFast()->setView(LLViewerCamera::getInstanceFast()->getDefaultFOV() / mCameraZoom); + LLViewerCamera::getInstance()->setView(LLViewerCamera::getInstance()->getDefaultFOV() / mCameraZoom); LLVector3 offset = mCameraOffset; LLVector3 target_pos = mPreviewTarget + offset; @@ -3157,7 +3273,7 @@ BOOL LLModelPreview::render() LLQuaternion av_rot = camera_rot; F32 camera_distance = skin_weight ? SKIN_WEIGHT_CAMERA_DISTANCE : mCameraDistance; - LLViewerCamera::getInstanceFast()->setOriginAndLookAt( + LLViewerCamera::getInstance()->setOriginAndLookAt( target_pos + ((LLVector3(camera_distance, 0.f, 0.f) + offset) * av_rot), // camera LLVector3::z_axis, // up target_pos); // point of interest @@ -3165,7 +3281,7 @@ BOOL LLModelPreview::render() z_near = llclamp(z_far * 0.001f, 0.001f, 0.1f); - LLViewerCamera::getInstanceFast()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, width, height, FALSE, z_near, z_far); + LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, width, height, FALSE, z_near, z_far); stop_glerror(); @@ -3334,6 +3450,14 @@ BOOL LLModelPreview::render() if (!physics.mMesh.empty()) { //render hull instead of mesh + // SL-16993 physics.mMesh[i].mNormals were being used to light the exploded + // analyzed physics shape but the drawArrays() interface changed + // causing normal data <0,0,0> to be passed to the shader. + // The Phyics Preview shader uses plain vertex coloring so the physics hull is full lit. + // We could also use interface/ui shaders. + gObjectPreviewProgram.unbind(); + gPhysicsPreviewProgram.bind(); + for (U32 i = 0; i < physics.mMesh.size(); ++i) { if (explode > 0.f) @@ -3354,13 +3478,16 @@ BOOL LLModelPreview::render() } gGL.diffuseColor4ubv(hull_colors[i].mV); - LLVertexBuffer::drawArrays(LLRender::TRIANGLES, physics.mMesh[i].mPositions, physics.mMesh[i].mNormals); + LLVertexBuffer::drawArrays(LLRender::TRIANGLES, physics.mMesh[i].mPositions); if (explode > 0.f) { gGL.popMatrix(); } } + + gPhysicsPreviewProgram.unbind(); + gObjectPreviewProgram.bind(); } } } @@ -3483,7 +3610,7 @@ BOOL LLModelPreview::render() getPreviewAvatar()->addPelvisFixup(mPelvisZOffset, fake_mesh_id); bool pelvis_recalc = false; - LLViewerCamera::getInstanceFast()->setOriginAndLookAt( + LLViewerCamera::getInstance()->setOriginAndLookAt( target_pos + ((LLVector3(camera_distance, 0.f, 0.f) + offset) * av_rot), // camera LLVector3::z_axis, // up target_pos); // point of interest @@ -3520,7 +3647,7 @@ BOOL LLModelPreview::render() LLJoint *joint = getPreviewAvatar()->getJoint(skin->mJointNums[j]); if (joint) { - const LLVector3& jointPos = skin->mAlternateBindMatrix[j].getTranslation(); + const LLVector3& jointPos = LLVector3(skin->mAlternateBindMatrix[j].getTranslation()); if (joint->aboveJointPosThreshold(jointPos)) { bool override_changed; @@ -3565,7 +3692,7 @@ BOOL LLModelPreview::render() LLSkinningUtil::initSkinningMatrixPalette(mat, joint_count, skin, getPreviewAvatar()); - LLMatrix4a bind_shape_matrix = skin->mBindShapeMatrix; + const LLMatrix4a& bind_shape_matrix = skin->mBindShapeMatrix; for (U32 j = 0; j < buffer->getNumVerts(); ++j) { LLMatrix4a final_mat; @@ -3632,6 +3759,7 @@ BOOL LLModelPreview::render() { getPreviewAvatar()->renderBones(); } + renderGroundPlane(mPelvisZOffset); if (shader) { shader->bind(); @@ -3653,6 +3781,28 @@ BOOL LLModelPreview::render() return TRUE; } +void LLModelPreview::renderGroundPlane(float z_offset) +{ // Not necesarilly general - beware - but it seems to meet the needs of LLModelPreview::render + + gGL.diffuseColor3f( 1.0f, 0.0f, 1.0f ); + + gGL.begin(LLRender::LINES); + gGL.vertex3fv(mGroundPlane[0].mV); + gGL.vertex3fv(mGroundPlane[1].mV); + + gGL.vertex3fv(mGroundPlane[1].mV); + gGL.vertex3fv(mGroundPlane[2].mV); + + gGL.vertex3fv(mGroundPlane[2].mV); + gGL.vertex3fv(mGroundPlane[3].mV); + + gGL.vertex3fv(mGroundPlane[3].mV); + gGL.vertex3fv(mGroundPlane[0].mV); + + gGL.end(); +} + + //----------------------------------------------------------------------------- // refresh() //----------------------------------------------------------------------------- @@ -3768,7 +3918,7 @@ bool LLModelPreview::lodQueryCallback() } // return false to continue cycle - return false; + return preview->mLodsQuery.empty(); } } // nothing to process diff --git a/indra/newview/llmodelpreview.h b/indra/newview/llmodelpreview.h index 149e077837fe7fae177920519753d4bf7d73366c..ed49a48bc2e0c4c1e75db8bfe14b872d82a997ea 100644 --- a/indra/newview/llmodelpreview.h +++ b/indra/newview/llmodelpreview.h @@ -125,7 +125,7 @@ class LLModelPreview final : public LLViewerDynamicTexture, public LLMutex { LOD_FROM_FILE = 0, MESH_OPTIMIZER_AUTO, // automatically selects method based on model or face - MESH_OPTIMIZER_COMBINE, // combines faces into a single model, simplifies, then splits back into faces + MESH_OPTIMIZER_PRECISE, // combines faces into a single model, simplifies, then splits back into faces MESH_OPTIMIZER_SLOPPY, // uses sloppy method, works per face USE_LOD_ABOVE, } eLoDMode; @@ -224,14 +224,39 @@ class LLModelPreview final : public LLViewerDynamicTexture, public LLMutex LLVOAvatar* getPreviewAvatar(void) { return mPreviewAvatar; } // Count amount of original models, excluding sub-models static U32 countRootModels(LLModelLoader::model_list models); + LLVector3 mGroundPlane[4]; + void renderGroundPlane(float z_offset = 0.0f); + /// Indicates whether we should warn of high-lod meshes that do not have a corresponding physics mesh. + /// Reset when resetting the modelpreview (i.e., when the uploader dialog is created or reset), and when + /// about to process a physics file. Set to true immediately after the file is loaded (before rebuildUploadData()). + /// + /// (The rules for mapping the correspondence of high-lod meshes to physics meshes are complex. When + /// lod rendering meshes are used, there is never an unmatched mesh. Nor is there a mismatch when + /// the high-lod file and physics file have ony one mesh each. In these cases, this value is moot. + /// When there are multiple meshes in each file, they are matched by name or order, and some meshes + /// are broken up by limitations into multiple objects, and thus there can be mismatches.) + bool mWarnOfUnmatchedPhyicsMeshes{false}; + /// A mesh to use as the default physics shape in only those cases where the physics shape is not otherwise specified. + /// It is set only when the user chooses a physics shape file that contains a mesh with a name that matches DEFAULT_PHYSICS_MESH_NAME. + /// It is reset when such a name is not found, and when resetting the modelpreview. + /// Not read unless mWarnOfUnmatchedPhyicsMeshes is true. + LLModel* mDefaultPhysicsShapeP{}; + + typedef enum + { + MESH_OPTIMIZER_FULL, + MESH_OPTIMIZER_NO_NORMALS, + MESH_OPTIMIZER_NO_UVS, + MESH_OPTIMIZER_NO_TOPOLOGY, + } eSimplificationMode; // Merges faces into single mesh, simplifies using mesh optimizer, // then splits back into faces. // Returns reached simplification ratio. -1 in case of a failure. - F32 genMeshOptimizerPerModel(LLModel *base_model, LLModel *target_model, F32 indices_ratio, F32 error_threshold, bool sloppy); + F32 genMeshOptimizerPerModel(LLModel *base_model, LLModel *target_model, F32 indices_ratio, F32 error_threshold, eSimplificationMode simplification_mode); // Simplifies specified face using mesh optimizer. // Returns reached simplification ratio. -1 in case of a failure. - F32 genMeshOptimizerPerFace(LLModel *base_model, LLModel *target_model, U32 face_idx, F32 indices_ratio, F32 error_threshold, bool sloppy); + F32 genMeshOptimizerPerFace(LLModel *base_model, LLModel *target_model, U32 face_idx, F32 indices_ratio, F32 error_threshold, eSimplificationMode simplification_mode); protected: friend class LLModelLoader; diff --git a/indra/newview/llmorphview.cpp b/indra/newview/llmorphview.cpp index ceb11e7ef3c887d78f6eabf815b2b0627a87daf5..d1cd72f4b5eb1897c138dedc5880f6b904c06dd3 100644 --- a/indra/newview/llmorphview.cpp +++ b/indra/newview/llmorphview.cpp @@ -81,8 +81,8 @@ void LLMorphView::initialize() gAgentAvatarp->mSpecialRenderMode = 3; // set up camera for close look at avatar - mOldCameraNearClip = LLViewerCamera::getInstanceFast()->getNear(); - LLViewerCamera::getInstanceFast()->setNear(MORPH_NEAR_CLIP); + mOldCameraNearClip = LLViewerCamera::getInstance()->getNear(); + LLViewerCamera::getInstance()->setNear(MORPH_NEAR_CLIP); } //----------------------------------------------------------------------------- @@ -95,7 +95,7 @@ void LLMorphView::shutdown() gAgentAvatarp->startMotion( ANIM_AGENT_BODY_NOISE ); gAgentAvatarp->mSpecialRenderMode = 0; // reset camera - LLViewerCamera::getInstanceFast()->setNear(mOldCameraNearClip); + LLViewerCamera::getInstance()->setNear(mOldCameraNearClip); } } diff --git a/indra/newview/llmoveview.cpp b/indra/newview/llmoveview.cpp index a2cd854bd2de80d07f97b941c6724c63678d1181..f7e9edeeb409970d29dfd982c138609a15862895 100644 --- a/indra/newview/llmoveview.cpp +++ b/indra/newview/llmoveview.cpp @@ -716,7 +716,7 @@ void LLPanelStandStopFlying::onStandButtonClick() { LLFirstUse::sit(false); - LLSelectMgr::getInstanceFast()->deselectAllForStandingUp(); + LLSelectMgr::getInstance()->deselectAllForStandingUp(); gAgent.setControlFlags(AGENT_CONTROL_STAND_UP); } // [/RLVa:KB] diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp index c6102a9d722db0d9578c58d4a81062900c7c28bd..c20ed3127f02924d337deca443d153f68e2013c0 100644 --- a/indra/newview/llmutelist.cpp +++ b/indra/newview/llmutelist.cpp @@ -377,7 +377,7 @@ BOOL LLMuteList::add(const LLMute& mute, U32 flags) void LLMuteList::updateAdd(const LLMute& mute) { - // External mutes (e.g. Avaline callers) are local only, don't send them to the server. + // External mutes are local only, don't send them to the server. if (mute.mType == LLMute::EXTERNAL) { return; diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp index 58d3bba6cdbbc3219c4967d5d95a87553c2c682e..aa533e5b5a2fd1775a34d5375201baafe1004e53 100644 --- a/indra/newview/llnamelistctrl.cpp +++ b/indra/newview/llnamelistctrl.cpp @@ -271,6 +271,25 @@ BOOL LLNameListCtrl::handleToolTip(S32 x, S32 y, MASK mask) return handled; } +// virtual +BOOL LLNameListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask) +{ + LLNameListItem* hit_item = dynamic_cast<LLNameListItem*>(hitItem(x, y)); + LLFloater* floater = gFloaterView->getParentFloater(this); + if (floater && floater->isFrontmost() && hit_item) + { + if(hit_item->isGroup()) + { + ContextMenuType prev_menu = getContextMenuType(); + setContextMenu(MENU_GROUP); + BOOL handled = LLScrollListCtrl::handleRightMouseDown(x, y, mask); + setContextMenu(prev_menu); + return handled; + } + } + return LLScrollListCtrl::handleRightMouseDown(x, y, mask); +} + // public void LLNameListCtrl::addGroupNameItem(const LLUUID& group_id, EAddPosition pos, BOOL enabled) diff --git a/indra/newview/llnamelistctrl.h b/indra/newview/llnamelistctrl.h index ef0be135e618e1c2b9473553700332eead2ef1d7..5dd5da5892ade23c01e7851e0fd8a3d3b6a1b3a3 100644 --- a/indra/newview/llnamelistctrl.h +++ b/indra/newview/llnamelistctrl.h @@ -170,6 +170,7 @@ class LLNameListCtrl /*virtual*/ void updateColumns(bool force_update); /*virtual*/ void mouseOverHighlightNthItem( S32 index ); + /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); private: void showInspector(const LLUUID& avatar_id, bool is_group, bool is_experience = false); void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name, std::string suffix, std::string prefix, LLHandle<LLNameListItem> item); diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp index f3b891e397cfd4f5cd1d6eaa21ef34825d609772..97845ddc46ef7ef80c0dbc06c2ff54c1e29e2cac 100644 --- a/indra/newview/llnavigationbar.cpp +++ b/indra/newview/llnavigationbar.cpp @@ -454,9 +454,9 @@ void LLNavigationBar::onLocationSelection() if(value.has("AssetUUID")) { - gAgent.teleportViaLandmark( LLUUID(value["AssetUUID"].asString())); - mSaveToLocationHistory = true; + // user teleported by manually inputting inventory landmark's name + mSaveToLocationHistory = false; return; } else @@ -783,7 +783,7 @@ void LLNavigationBar::refreshLocationCtrl() void LLNavigationBar::invokeSearch(std::string search_text) { - LLFloaterReg::showInstance("search", LLSD().with("category", "all").with("query", LLSD(search_text))); + LLFloaterReg::showInstance("search", LLSD().with("category", "standard").with("query", LLSD(search_text))); } void LLNavigationBar::clearHistoryCache() @@ -803,3 +803,8 @@ int LLNavigationBar::getDefFavBarHeight() { return mDefaultFpRect.getHeight(); } + +bool LLNavigationBar::isRebakeNavMeshAvailable() +{ + return mCmbLocation->isNavMeshDirty(); +} diff --git a/indra/newview/llnavigationbar.h b/indra/newview/llnavigationbar.h index 9cb52ef755973a7d609bd00a501f5b31b5abd2bc..4b1a6ec720ec2d0895133bcc5732a98f3a58df6f 100755 --- a/indra/newview/llnavigationbar.h +++ b/indra/newview/llnavigationbar.h @@ -102,6 +102,8 @@ class LLNavigationBar final int getDefNavBarHeight(); int getDefFavBarHeight(); + + bool isRebakeNavMeshAvailable(); // [RLVa:KB] - Checked: 2014-03-23 (RLVa-1.4.10) void refreshLocationCtrl(); diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index aa395ffd334a6aa07a2d03b4e41927168320cb60..a7774871d9311cf78bd9b8be67ae94cefee0469d 100644 --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -37,6 +37,7 @@ #include "llfocusmgr.h" #include "lllocalcliprect.h" #include "llrender.h" +#include "llresmgr.h" #include "llui.h" #include "lltooltip.h" @@ -47,12 +48,16 @@ #include "llagentcamera.h" #include "llappviewer.h" // for gDisconnected #include "llcallingcard.h" // LLAvatarTracker +#include "llfloaterland.h" #include "llfloaterworldmap.h" #include "llparcel.h" #include "lltracker.h" #include "llsurface.h" +#include "llurlmatch.h" +#include "llurlregistry.h" #include "llviewercamera.h" #include "llviewercontrol.h" +#include "llviewerparcelmgr.h" #include "llviewertexture.h" #include "llviewertexturelist.h" #include "llviewermenu.h" @@ -70,9 +75,12 @@ static LLDefaultChildRegistry::Register<LLNetMap> r1("net_map"); -const F32 LLNetMap::MAP_SCALE_MIN = 32.f; -const F32 LLNetMap::MAP_SCALE_MID = 1024.f; -const F32 LLNetMap::MAP_SCALE_MAX = 4096.f; +const F32 LLNetMap::MAP_SCALE_MIN = 32; +const F32 LLNetMap::MAP_SCALE_FAR = 32; +const F32 LLNetMap::MAP_SCALE_MEDIUM = 128; +const F32 LLNetMap::MAP_SCALE_CLOSE = 256; +const F32 LLNetMap::MAP_SCALE_VERY_CLOSE = 1024; +const F32 LLNetMap::MAP_SCALE_MAX = 4096; const F32 MAP_SCALE_ZOOM_FACTOR = 1.04f; // Zoom in factor per click of scroll wheel (4%) const F32 MIN_DOT_RADIUS = 3.5f; @@ -87,14 +95,14 @@ LLNetMap::LLNetMap (const Params & p) mUpdateObjectImage(false), mUpdateParcelImage(false), mBackgroundColor (p.bg_color()), - mScale( MAP_SCALE_MID ), - mPixelsPerMeter( MAP_SCALE_MID / REGION_WIDTH_METERS ), + mScale( MAP_SCALE_MEDIUM ), + mPixelsPerMeter( MAP_SCALE_MEDIUM / REGION_WIDTH_METERS ), mObjectMapTPM(0.f), mObjectMapPixels(0.f), mPanning(false), - mTargetPan(0.f, 0.f), mCurPan(0.f, 0.f), mStartPan(0.f, 0.f), + mPopupWorldPos(0.f, 0.f, 0.f), mMouseDown(0, 0), mObjectImageCenterGlobal( gAgentCamera.getCameraPositionGlobal() ), mObjectRawImagep(), @@ -108,6 +116,13 @@ LLNetMap::LLNetMap (const Params & p) mPopupMenuHandle() { setScale(gSavedSettings.getF32("MiniMapScale")); + if (gAgent.isFirstLogin()) + { + // *HACK: On first run, set this to false for new users, otherwise the + // default is true to maintain consistent experience for existing + // users. + gSavedSettings.setBOOL("MiniMapRotate", false); + } } LLNetMap::~LLNetMap() @@ -132,18 +147,25 @@ LLNetMap::~LLNetMap() BOOL LLNetMap::postBuild() { - LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; - - registrar.add("Minimap.Zoom", boost::bind(&LLNetMap::handleZoom, this, _2)); - registrar.add("Minimap.Tracker", boost::bind(&LLNetMap::handleStopTracking, this, _2)); + LLUICtrl::CommitCallbackRegistry::ScopedRegistrar commitRegistrar; + LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enableRegistrar; + + enableRegistrar.add("Minimap.Zoom.Check", boost::bind(&LLNetMap::isZoomChecked, this, _2)); + commitRegistrar.add("Minimap.Zoom.Set", boost::bind(&LLNetMap::setZoom, this, _2)); + commitRegistrar.add("Minimap.Tracker", boost::bind(&LLNetMap::handleStopTracking, this, _2)); + commitRegistrar.add("Minimap.Center.Activate", boost::bind(&LLNetMap::activateCenterMap, this, _2)); + enableRegistrar.add("Minimap.MapOrientation.Check", boost::bind(&LLNetMap::isMapOrientationChecked, this, _2)); + commitRegistrar.add("Minimap.MapOrientation.Set", boost::bind(&LLNetMap::setMapOrientation, this, _2)); + commitRegistrar.add("Minimap.AboutLand", boost::bind(&LLNetMap::popupShowAboutLand, this, _2)); LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_mini_map.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + menu->setItemEnabled("Re-center map", false); mPopupMenuHandle = menu->getHandle(); mParcelMgrConn = LLViewerParcelMgr::instance().setCollisionUpdateCallback(boost::bind(&LLNetMap::refreshParcelOverlay, this)); mParcelOverlayConn = LLViewerParcelOverlay::setUpdateCallback(boost::bind(&LLNetMap::refreshParcelOverlay, this)); - return TRUE; + return true; } void LLNetMap::setScale( F32 scale ) @@ -176,6 +198,10 @@ void LLNetMap::setScale( F32 scale ) void LLNetMap::draw() { + if (!LLWorld::instanceExists()) + { + return; + } LLViewerRegion* curregionp = gAgent.getRegion(); if (!curregionp) return; @@ -187,8 +213,9 @@ void LLNetMap::draw() static LLUIColor map_chat_ring_color = LLUIColorTable::instance().getColor("MapChatRingColor", LLColor4::white); static LLUIColor map_shout_ring_color = LLUIColorTable::instance().getColor("MapShoutRingColor", LLColor4::white); //static LLUIColor map_track_disabled_color = LLUIColorTable::instance().getColor("MapTrackDisabledColor", LLColor4::white); - static LLUIColor map_frustum_color = LLUIColorTable::instance().getColor("MapFrustumColor", LLColor4::white); - static LLUIColor map_frustum_rotating_color = LLUIColorTable::instance().getColor("MapFrustumRotatingColor", LLColor4::white); + static LLUIColor map_frustum_color = LLUIColorTable::instance().getColor("MapFrustumRotatingColor", LLColor4::white); + static LLUIColor map_frustum_rotating_color = LLUIColorTable::instance().getColor("MapFrustumColor", LLColor4::white); + static LLUIColor map_parcel_outline_color = LLUIColorTable::instance().getColor("MapParcelOutlineColor", LLColor4(LLColor3(LLColor4::yellow), 0.5f)); static LLUIColor map_line_color = LLUIColorTable::instance().getColor("MapLineColor", LLColor4::red); static LLUIColor map_parcel_line_color = LLUIColorTable::instance().getColor("MapParcelBoundryLine", LLColor4::white); @@ -196,7 +223,7 @@ void LLNetMap::draw() static LLCachedControl<bool> enable_object_render(gSavedSettings, "AlchemyMinimapRenderObjects", true); static LLCachedControl<bool> render_guide_line(gSavedSettings, "AlchemyMinimapGuideLine", false); static LLCachedControl<bool> map_chat_ring(gSavedSettings, "AlchemyMinimapChatRings", false); - static LLCachedControl<bool> minimap_parcel_boundries(gSavedSettings, "AlchemyMinimapParcelBoundries", false); + static LLCachedControl<bool> minimap_parcel_boundries(gSavedSettings, "MiniMapShowPropertyLines", false); if (mObjectImagep.isNull()) { @@ -207,18 +234,34 @@ void LLNetMap::draw() createParcelImage(); } - static LLUICachedControl<bool> auto_center("MiniMapAutoCenter", true); - if (auto_center) + static LLUICachedControl<bool> auto_center("MiniMapAutoCenter", true); + bool auto_centering = auto_center && !mPanning; + mCentering = mCentering && !mPanning; + + if (auto_centering || mCentering) { - mCurPan = lerp(mCurPan, mTargetPan, LLSmoothInterpolation::getInterpolant(0.1f)); + mCurPan = lerp(mCurPan, LLVector2(0.0f, 0.0f) , LLSmoothInterpolation::getInterpolant(0.1f)); } + bool centered = abs(mCurPan.mV[VX]) < 0.5f && abs(mCurPan.mV[VY]) < 0.5f; + if (centered) + { + mCurPan.mV[0] = 0.0f; + mCurPan.mV[1] = 0.0f; + mCentering = false; + } + + bool can_recenter_map = !(centered || mCentering || auto_centering); + auto menu = (LLMenuGL*)mPopupMenuHandle.get(); + if(menu) menu->setItemEnabled("Re-center map", can_recenter_map); + + updateAboutLandPopupButton(); // Prepare a scissor region F32 rotation = 0.f; gGL.pushUIMatrix(); - auto& viewer_camera = LLViewerCamera::instanceFast(); + auto& viewer_camera = LLViewerCamera::instance(); { LLLocalClipRect clip(getLocalRect()); { @@ -246,18 +289,19 @@ void LLNetMap::draw() gGL.rotateUI(rot); } - auto& worldInst = LLWorld::instanceFast(); + auto& worldInst = LLWorld::instance(); // figure out where agent is S32 region_width = REGION_WIDTH_UNITS; + const F32 scale_pixels_per_meter = mScale / region_width; for (LLViewerRegion* regionp : worldInst.getRegionList()) { // Find x and y position relative to camera's center. LLVector3 origin_agent = regionp->getOriginAgent(); LLVector3 rel_region_pos = origin_agent - gAgentCamera.getCameraPositionAgent(); - F32 relative_x = (rel_region_pos.mV[0] / region_width) * mScale; - F32 relative_y = (rel_region_pos.mV[1] / region_width) * mScale; + F32 relative_x = rel_region_pos.mV[0] * scale_pixels_per_meter; + F32 relative_y = rel_region_pos.mV[1] * scale_pixels_per_meter; const F32 real_width(regionp->getWidth()); // background region rectangle @@ -330,7 +374,7 @@ void LLNetMap::draw() gGL.end(); // Draw water - gGL.setAlphaRejectSettings(LLRender::CF_GREATER, ABOVE_WATERLINE_ALPHA / 255.f); + gGL.flush(); { if (regionp->getLand().getWaterTexture()) { @@ -347,7 +391,7 @@ void LLNetMap::draw() gGL.end(); } } - gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); + gGL.flush(); } } @@ -391,8 +435,8 @@ void LLNetMap::draw() LLVector3 map_center_agent = gAgent.getPosAgentFromGlobal(mObjectImageCenterGlobal); map_center_agent -= camera_position; - map_center_agent.mV[VX] *= mScale / region_width; - map_center_agent.mV[VY] *= mScale / region_width; + map_center_agent.mV[VX] *= scale_pixels_per_meter; + map_center_agent.mV[VY] *= scale_pixels_per_meter; gGL.getTexUnit(0)->bind(mObjectImagep); @@ -578,15 +622,17 @@ void LLNetMap::draw() F32 horiz_fov = viewer_camera.getView() * viewer_camera.getAspect(); F32 far_clip_meters = viewer_camera.getFar(); F32 far_clip_pixels = far_clip_meters * meters_to_pixels; - - F32 half_width_meters = far_clip_meters * tan( horiz_fov / 2 ); - F32 half_width_pixels = half_width_meters * meters_to_pixels; - F32 ctr_x = (F32)center_sw_left; - F32 ctr_y = (F32)center_sw_bottom; + F32 ctr_x = (F32)center_sw_left; + F32 ctr_y = (F32)center_sw_bottom; + const F32 steps_per_circle = 40.0f; + const F32 steps_per_radian = steps_per_circle / F_TWO_PI; + const F32 arc_start = -(horiz_fov / 2.0f) + F_PI_BY_TWO; + const F32 arc_end = (horiz_fov / 2.0f) + F_PI_BY_TWO; + const S32 steps = llmax(1, (S32)((horiz_fov * steps_per_radian) + 0.5f)); - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); LLColor4 frust_col = rotate_map ? map_frustum_color() : map_frustum_rotating_color(); @@ -613,14 +659,8 @@ void LLNetMap::draw() gGL.rotateUI(rot); } - gGL.begin( LLRender::TRIANGLES ); - gGL.color4fv(frust_col.mV); - gGL.vertex2f( 0.f, 0.f ); - frust_col.mV[VW] *= .1f; - gGL.color4fv(frust_col.mV); - gGL.vertex2f( half_width_pixels, far_clip_pixels ); - gGL.vertex2f( -half_width_pixels, far_clip_pixels ); - gGL.end(); + gl_washer_segment_2d(far_clip_pixels, 0, arc_start, arc_end, steps, map_frustum_color(), map_frustum_color()); + if (render_guide_line) { gGL.begin(LLRender::LINES); @@ -661,7 +701,7 @@ LLVector3 LLNetMap::globalPosToView(const LLVector3d& global_pos) static LLUICachedControl<bool> rotate_map("MiniMapRotate", true); if( rotate_map ) { - F32 radians = atan2( LLViewerCamera::getInstanceFast()->getAtAxis().mV[VX], LLViewerCamera::getInstanceFast()->getAtAxis().mV[VY] ); + F32 radians = atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ); LLQuaternion rot(radians, LLVector3(0.f, 0.f, 1.f)); pos_local.rotVec( rot ); } @@ -698,6 +738,67 @@ void LLNetMap::drawTracking(const LLVector3d& pos_global, const LLColor4& color, } } +bool LLNetMap::isMouseOnPopupMenu() +{ + auto menu = (LLMenuGL*)mPopupMenuHandle.get(); + if (!menu || !menu->isOpen()) + { + return false; + } + + S32 popup_x; + S32 popup_y; + LLUI::getInstance()->getMousePositionLocal(mPopupMenuHandle.get(), &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; + // Test tolerance from all four corners, as the popup menu can appear from a different direction if there's not enough space. + // Assume the size of the popup menu is much larger than the provided tolerance. + // In practice, this is a [tolerance]px margin around the popup menu. + for (S32 sign_x = -1; sign_x <= 1; sign_x += 2) + { + for (S32 sign_y = -1; sign_y <= 1; sign_y += 2) + { + if (menu->pointInView(popup_x + (sign_x * tolerance), popup_y + (sign_y * tolerance))) + { + return true; + } + } + } + return false; +} + +void LLNetMap::updateAboutLandPopupButton() +{ + auto menu = (LLMenuGL*)mPopupMenuHandle.get(); + if (!menu || !menu->isOpen()) + { + return; + } + + LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosGlobal(mPopupWorldPos); + if (!region) + { + menu->setItemEnabled("About Land", false); + } + else + { + // Check if the mouse is in the bounds of the popup. If so, it's safe to assume no other hover function will be called, so the hover + // parcel can be used to check if location-sensitive tooltip options are available. + if (isMouseOnPopupMenu()) + { + LLViewerParcelMgr::getInstance()->setHoverParcel(mPopupWorldPos); + LLParcel *hover_parcel = LLViewerParcelMgr::getInstance()->getHoverParcel(); + bool valid_parcel = false; + if (hover_parcel) + { + valid_parcel = hover_parcel->getOwnerID().notNull(); + } + menu->setItemEnabled("About Land", valid_parcel); + } + } +} + LLVector3d LLNetMap::viewPosToGlobal( S32 x, S32 y ) { x -= ll_round(getRect().getWidth() / 2 + mCurPan.mV[VX]); @@ -705,7 +806,7 @@ LLVector3d LLNetMap::viewPosToGlobal( S32 x, S32 y ) LLVector3 pos_local( (F32)x, (F32)y, 0 ); - F32 radians = - atan2( LLViewerCamera::getInstanceFast()->getAtAxis().mV[VX], LLViewerCamera::getInstanceFast()->getAtAxis().mV[VY] ); + F32 radians = - atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ); static LLUICachedControl<bool> rotate_map("MiniMapRotate", true); if( rotate_map ) @@ -725,78 +826,164 @@ LLVector3d LLNetMap::viewPosToGlobal( S32 x, S32 y ) BOOL LLNetMap::handleScrollWheel(S32 x, S32 y, S32 clicks) { - // note that clicks are reversed from what you'd think: i.e. > 0 means zoom out, < 0 means zoom in - F32 new_scale = mScale * pow(MAP_SCALE_ZOOM_FACTOR, -clicks); + // note that clicks are reversed from what you'd think: i.e. > 0 means zoom out, < 0 means zoom in + F32 new_scale = mScale * pow(MAP_SCALE_ZOOM_FACTOR, -clicks); F32 old_scale = mScale; - setScale(new_scale); + setScale(new_scale); - static LLUICachedControl<bool> auto_center("MiniMapAutoCenter", true); - if (!auto_center) - { - // Adjust pan to center the zoom on the mouse pointer - LLVector2 zoom_offset; - zoom_offset.mV[VX] = x - getRect().getWidth() / 2; - zoom_offset.mV[VY] = y - getRect().getHeight() / 2; - mCurPan -= zoom_offset * mScale / old_scale - zoom_offset; - } + static LLUICachedControl<bool> auto_center("MiniMapAutoCenter", true); + if (!auto_center) + { + // Adjust pan to center the zoom on the mouse pointer + LLVector2 zoom_offset; + zoom_offset.mV[VX] = x - getRect().getWidth() / 2; + zoom_offset.mV[VY] = y - getRect().getHeight() / 2; + mCurPan -= zoom_offset * mScale / old_scale - zoom_offset; + } - return TRUE; + return true; } -BOOL LLNetMap::handleToolTip( S32 x, S32 y, MASK mask ) +BOOL LLNetMap::handleToolTip(S32 x, S32 y, MASK mask) { - if (gDisconnected) - { - return FALSE; - } + if (gDisconnected) + { + return false; + } - // If the cursor is near an avatar on the minimap, a mini-inspector will be - // shown for the avatar, instead of the normal map tooltip. + // If the cursor is near an avatar on the minimap, a mini-inspector will be + // shown for the avatar, instead of the normal map tooltip. // if (handleToolTipAgent(mClosestAgentToCursor)) // [RLVa:KB] - Checked: RLVa-1.2.2 bool fRlvCanShowName = (mClosestAgentToCursor.notNull()) && (RlvActions::canShowName(RlvActions::SNC_DEFAULT, mClosestAgentToCursor)); if ( (fRlvCanShowName) && (handleToolTipAgent(mClosestAgentToCursor)) ) // [/RLVa:KB] - { - return TRUE; - } + { + return true; + } // [RLVa:KB] - Checked: RLVa-1.2.2 LLStringUtil::format_map_t args; LLAvatarName avName; args["[AGENT]"] = ( (!fRlvCanShowName) && (mClosestAgentToCursor.notNull()) && (LLAvatarNameCache::get(mClosestAgentToCursor, &avName)) ) ? RlvStrings::getAnonym(avName) + "\n" : ""; // [/RLVa:KB] - LLRect sticky_rect; - std::string region_name; - LLViewerRegion* region = LLWorld::getInstanceFast()->getRegionFromPosGlobal( viewPosToGlobal( x, y ) ); - if(region) - { - // set sticky_rect - S32 SLOP = 4; - localPointToScreen(x - SLOP, y - SLOP, &(sticky_rect.mLeft), &(sticky_rect.mBottom)); - sticky_rect.mRight = sticky_rect.mLeft + 2 * SLOP; - sticky_rect.mTop = sticky_rect.mBottom + 2 * SLOP; - -// region_name = region->getName(); + // The popup menu uses the hover parcel when it is open and the mouse is on + // top of it, with some additional tolerance. Returning early here prevents + // fighting over that hover parcel when getting tooltip info in the + // tolerance region. + if (isMouseOnPopupMenu()) + { + return false; + } + + LLRect sticky_rect; + S32 SLOP = 4; + localPointToScreen(x - SLOP, y - SLOP, &(sticky_rect.mLeft), &(sticky_rect.mBottom)); + sticky_rect.mRight = sticky_rect.mLeft + 2 * SLOP; + sticky_rect.mTop = sticky_rect.mBottom + 2 * SLOP; + + std::string parcel_name_msg; + std::string parcel_sale_price_msg; + std::string parcel_sale_area_msg; + std::string parcel_owner_msg; + std::string region_name_msg; + + LLVector3d posGlobal = viewPosToGlobal(x, y); + LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosGlobal(posGlobal); + if (region) + { +// std::string region_name = region->getName(); // [RLVa:KB] - Checked: RLVa-1.2.2 - region_name = (RlvActions::canShowLocation()) ? region->getName() : RlvStrings::getString(RlvStringKeys::Hidden::Region); + std::string region_name = (RlvActions::canShowLocation()) ? region->getName() : RlvStrings::getString(RlvStringKeys::Hidden::Region); // [/RLVa:KB] - if (!region_name.empty()) - { - region_name += "\n"; - } - } + if (!region_name.empty()) + { + region_name_msg = mRegionNameMsg; + LLStringUtil::format(region_name_msg, {{"[REGION_NAME]", region_name}}); + } -// LLStringUtil::format_map_t args; - args["[REGION]"] = region_name; - std::string msg = mToolTipMsg; - LLStringUtil::format(msg, args); - LLToolTipMgr::instance().show(LLToolTip::Params() - .message(msg) - .sticky_rect(sticky_rect)); - - return TRUE; + // Only show parcel information in the tooltip if property lines are visible. Otherwise, the parcel the tooltip is referring to is + // ambiguous. + if (gSavedSettings.getBOOL("MiniMapShowPropertyLines")) + { + LLViewerParcelMgr::getInstance()->setHoverParcel(posGlobal); + LLParcel *hover_parcel = LLViewerParcelMgr::getInstance()->getHoverParcel(); + if (hover_parcel) + { + std::string parcel_name = hover_parcel->getName(); + if (!parcel_name.empty()) + { + parcel_name_msg = mParcelNameMsg; + LLStringUtil::format(parcel_name_msg, {{"[PARCEL_NAME]", parcel_name}}); + } + + const LLUUID parcel_owner = hover_parcel->getOwnerID(); + std::string parcel_owner_name_url = LLSLURL("agent", parcel_owner, "inspect").getSLURLString(); + static LLUrlMatch parcel_owner_name_url_match; + LLUrlRegistry::getInstance()->findUrl(parcel_owner_name_url, parcel_owner_name_url_match); + if (!parcel_owner_name_url_match.empty()) + { + parcel_owner_msg = mParcelOwnerMsg; + std::string parcel_owner_name = parcel_owner_name_url_match.getLabel(); + LLStringUtil::format(parcel_owner_msg, {{"[PARCEL_OWNER]", parcel_owner_name}}); + } + + if (hover_parcel->getForSale()) + { + const LLUUID auth_buyer_id = hover_parcel->getAuthorizedBuyerID(); + const LLUUID agent_id = gAgent.getID(); + bool show_for_sale = auth_buyer_id.isNull() || auth_buyer_id == agent_id || parcel_owner == agent_id; + if (show_for_sale) + { + S32 price = hover_parcel->getSalePrice(); + S32 area = hover_parcel->getArea(); + F32 cost_per_sqm = 0.0f; + if (area > 0) + { + cost_per_sqm = F32(price) / area; + } + std::string formatted_price = LLResMgr::getInstance()->getMonetaryString(price); + std::string formatted_cost_per_meter = llformat("%.1f", cost_per_sqm); + parcel_sale_price_msg = mParcelSalePriceMsg; + LLStringUtil::format(parcel_sale_price_msg, + {{"[PRICE]", formatted_price}, {"[PRICE_PER_SQM]", formatted_cost_per_meter}}); + std::string formatted_area = llformat("%d", area); + parcel_sale_area_msg = mParcelSaleAreaMsg; + LLStringUtil::format(parcel_sale_area_msg, {{"[AREA]", formatted_area}}); + } + } + } + } + } + + std::string tool_tip_hint_msg; + if (gSavedSettings.getBOOL("DoubleClickTeleport")) + { + tool_tip_hint_msg = mAltToolTipHintMsg; + } + else if (gSavedSettings.getBOOL("DoubleClickShowWorldMap")) + { + tool_tip_hint_msg = mToolTipHintMsg; + } + + // LLStringUtil::format_map_t args; + args["[PARCEL_NAME_MSG]"] = parcel_name_msg.empty() ? "" : parcel_name_msg + '\n'; + args["[PARCEL_SALE_PRICE_MSG]"] = parcel_sale_price_msg.empty() ? "" : parcel_sale_price_msg + '\n'; + args["[PARCEL_SALE_AREA_MSG]"] = parcel_sale_area_msg.empty() ? "" : parcel_sale_area_msg + '\n'; + args["[PARCEL_OWNER_MSG]"] = parcel_owner_msg.empty() ? "" : parcel_owner_msg + '\n'; + args["[REGION_NAME_MSG]"] = region_name_msg.empty() ? "" : region_name_msg + '\n'; + args["[TOOL_TIP_HINT_MSG]"] = tool_tip_hint_msg.empty() ? "" : tool_tip_hint_msg + '\n'; + + std::string msg = mToolTipMsg; + LLStringUtil::format(msg, args); + if (msg.back() == '\n') + { + msg.resize(msg.size() - 1); + } + LLToolTipMgr::instance().show(LLToolTip::Params().message(msg).sticky_rect(sticky_rect)); + + return true; } BOOL LLNetMap::handleToolTipAgent(const LLUUID& avatar_id) @@ -978,7 +1165,7 @@ void LLNetMap::renderPropertyLinesForRegion(const LLViewerRegion* region, const const S32 GRIDS_PER_EDGE = real_width / GRID_STEP; const U8* ownership = region->getParcelOverlay()->getOwnership(); - const U8* collision = (region->getHandle() == LLViewerParcelMgr::instanceFast().getCollisionRegionHandle()) ? LLViewerParcelMgr::instanceFast().getCollisionBitmap() : NULL; + const U8* collision = (region->getHandle() == LLViewerParcelMgr::instance().getCollisionRegionHandle()) ? LLViewerParcelMgr::instance().getCollisionBitmap() : NULL; for (S32 idxRow = 0; idxRow < GRIDS_PER_EDGE; idxRow++) { for (S32 idxCol = 0; idxCol < GRIDS_PER_EDGE; idxCol++) @@ -1088,50 +1275,50 @@ void LLNetMap::createParcelImage() mUpdateParcelImage = true; } -BOOL LLNetMap::handleMouseDown( S32 x, S32 y, MASK mask ) +BOOL LLNetMap::handleMouseDown(S32 x, S32 y, MASK mask) { if (!(mask & MASK_SHIFT)) return FALSE; - // Start panning - gFocusMgr.setMouseCapture(this); + // Start panning + gFocusMgr.setMouseCapture(this); - mStartPan = mCurPan; - mMouseDown.mX = x; - mMouseDown.mY = y; - return TRUE; + mStartPan = mCurPan; + mMouseDown.mX = x; + mMouseDown.mY = y; + return true; } -BOOL LLNetMap::handleMouseUp( S32 x, S32 y, MASK mask ) +BOOL LLNetMap::handleMouseUp(S32 x, S32 y, MASK mask) { - if(abs(mMouseDown.mX-x)<3 && abs(mMouseDown.mY-y)<3) - handleClick(x,y,mask); - - if (hasMouseCapture()) - { - if (mPanning) - { - // restore mouse cursor - S32 local_x, local_y; - local_x = mMouseDown.mX + llfloor(mCurPan.mV[VX] - mStartPan.mV[VX]); - local_y = mMouseDown.mY + llfloor(mCurPan.mV[VY] - mStartPan.mV[VY]); - LLRect clip_rect = getRect(); - clip_rect.stretch(-8); - clip_rect.clipPointToRect(mMouseDown.mX, mMouseDown.mY, local_x, local_y); + if (abs(mMouseDown.mX - x) < 3 && abs(mMouseDown.mY - y) < 3) + { + handleClick(x, y, mask); + } + + if (hasMouseCapture()) + { + if (mPanning) + { + // restore mouse cursor + S32 local_x, local_y; + local_x = mMouseDown.mX + llfloor(mCurPan.mV[VX] - mStartPan.mV[VX]); + local_y = mMouseDown.mY + llfloor(mCurPan.mV[VY] - mStartPan.mV[VY]); + LLRect clip_rect = getRect(); + clip_rect.stretch(-8); + clip_rect.clipPointToRect(mMouseDown.mX, mMouseDown.mY, local_x, local_y); LLUI::setMousePositionLocal(this, local_x, local_y); - // finish the pan - mPanning = false; + // finish the pan + mPanning = false; - mMouseDown.set(0, 0); + mMouseDown.set(0, 0); + } + gViewerWindow->showCursor(); + gFocusMgr.setMouseCapture(NULL); + return true; + } - // auto centre - mTargetPan.setZero(); - } - gViewerWindow->showCursor(); - gFocusMgr.setMouseCapture(NULL); - return TRUE; - } - return FALSE; + return false; } BOOL LLNetMap::handleRightMouseDown(S32 x, S32 y, MASK mask) @@ -1139,9 +1326,10 @@ BOOL LLNetMap::handleRightMouseDown(S32 x, S32 y, MASK mask) auto menu = static_cast<LLMenuGL*>(mPopupMenuHandle.get()); if (menu) { + mPopupWorldPos = viewPosToGlobal(x, y); menu->buildDrawLabels(); menu->updateParent(LLMenuGL::sMenuContainer); - menu->setItemEnabled("Stop Tracking", LLTracker::isTracking(0)); + menu->setItemEnabled("Stop tracking", LLTracker::isTracking(0)); LLMenuGL::showPopup(this, menu, x, y); } return TRUE; @@ -1189,6 +1377,27 @@ BOOL LLNetMap::handleDoubleClick(S32 x, S32 y, MASK mask) return TRUE; } +F32 LLNetMap::getScaleForName(std::string scale_name) +{ + if (scale_name == "very close") + { + return LLNetMap::MAP_SCALE_VERY_CLOSE; + } + else if (scale_name == "close") + { + return LLNetMap::MAP_SCALE_CLOSE; + } + else if (scale_name == "medium") + { + return LLNetMap::MAP_SCALE_MEDIUM; + } + else if (scale_name == "far") + { + return LLNetMap::MAP_SCALE_FAR; + } + return 0.0f; +} + // static bool LLNetMap::outsideSlop( S32 x, S32 y, S32 start_x, S32 start_y, S32 slop ) { @@ -1206,7 +1415,7 @@ BOOL LLNetMap::handleHover( S32 x, S32 y, MASK mask ) { if (!mPanning) { - // just started panning, so hide cursor + // Just started panning. Hide cursor. mPanning = true; gViewerWindow->hideCursor(); } @@ -1216,13 +1425,9 @@ BOOL LLNetMap::handleHover( S32 x, S32 y, MASK mask ) // Set pan to value at start of drag + offset mCurPan += delta; - mTargetPan = mCurPan; gViewerWindow->moveCursorToCenter(); } - - // Doesn't really matter, cursor should be hidden - gViewerWindow->setCursor( UI_CURSOR_TOOLPAN ); } else { @@ -1240,30 +1445,21 @@ BOOL LLNetMap::handleHover( S32 x, S32 y, MASK mask ) return TRUE; } -void LLNetMap::handleZoom(const LLSD& userdata) +bool LLNetMap::isZoomChecked(const LLSD &userdata) { - std::string level = userdata.asString(); - - F32 scale = 0.0f; - if (level == std::string("default")) - { - LLControlVariable *pvar = gSavedSettings.getControl("MiniMapScale"); - if(pvar) - { - pvar->resetToDefault(); - scale = gSavedSettings.getF32("MiniMapScale"); - } - } - else if (level == std::string("close")) - scale = LLNetMap::MAP_SCALE_MAX; - else if (level == std::string("medium")) - scale = LLNetMap::MAP_SCALE_MID; - else if (level == std::string("far")) - scale = LLNetMap::MAP_SCALE_MIN; - if (scale != 0.0f) - { - setScale(scale); - } + std::string level = userdata.asString(); + F32 scale = getScaleForName(level); + return scale == mScale; +} + +void LLNetMap::setZoom(const LLSD &userdata) +{ + std::string level = userdata.asString(); + F32 scale = getScaleForName(level); + if (scale != 0.0f) + { + setScale(scale); + } } void LLNetMap::handleStopTracking (const LLSD& userdata) @@ -1271,7 +1467,49 @@ void LLNetMap::handleStopTracking (const LLSD& userdata) auto menu = static_cast<LLMenuGL*>(mPopupMenuHandle.get()); if (menu) { - menu->setItemEnabled ("Stop Tracking", false); + menu->setItemEnabled ("Stop tracking", false); LLTracker::stopTracking (LLTracker::isTracking(NULL)); } } + +void LLNetMap::activateCenterMap(const LLSD &userdata) { mCentering = true; } + +bool LLNetMap::isMapOrientationChecked(const LLSD &userdata) +{ + const std::string command_name = userdata.asString(); + const bool rotate_map = gSavedSettings.getBOOL("MiniMapRotate"); + if (command_name == "north_at_top") + { + return !rotate_map; + } + + if (command_name == "camera_at_top") + { + return rotate_map; + } + + return false; +} + +void LLNetMap::setMapOrientation(const LLSD &userdata) +{ + const std::string command_name = userdata.asString(); + if (command_name == "north_at_top") + { + gSavedSettings.setBOOL("MiniMapRotate", false); + } + else if (command_name == "camera_at_top") + { + gSavedSettings.setBOOL("MiniMapRotate", true); + } +} + +void LLNetMap::popupShowAboutLand(const LLSD &userdata) +{ + // Update parcel selection. It's important to deselect land first so the "About Land" floater doesn't refresh with the old selection. + LLViewerParcelMgr::getInstance()->deselectLand(); + LLParcelSelectionHandle selection = LLViewerParcelMgr::getInstance()->selectParcelAt(mPopupWorldPos); + gMenuHolder->setParcelSelection(selection); + + LLFloaterReg::showInstance("about_land", LLSD(), false); +} diff --git a/indra/newview/llnetmap.h b/indra/newview/llnetmap.h index bef77b2ab0e083223f0807033aa32f580012444b..76e9e1ca0bc516f175738cd279859af70407aa09 100644 --- a/indra/newview/llnetmap.h +++ b/indra/newview/llnetmap.h @@ -63,9 +63,12 @@ class LLNetMap final : public LLUICtrl public: virtual ~LLNetMap(); - static const F32 MAP_SCALE_MIN; - static const F32 MAP_SCALE_MID; - static const F32 MAP_SCALE_MAX; + static const F32 MAP_SCALE_MIN; + static const F32 MAP_SCALE_FAR; + static const F32 MAP_SCALE_MEDIUM; + static const F32 MAP_SCALE_CLOSE; + static const F32 MAP_SCALE_VERY_CLOSE; + static const F32 MAP_SCALE_MAX; /*virtual*/ void draw() override; /*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks) override; @@ -82,8 +85,17 @@ class LLNetMap final : public LLUICtrl void refreshParcelOverlay() { mUpdateParcelImage = true; } - void setScale( F32 scale ); - void setToolTipMsg(const std::string& msg) { mToolTipMsg = msg; } + void setScale(F32 scale); + + void setToolTipMsg(const std::string& msg) { mToolTipMsg = msg; } + void setParcelNameMsg(const std::string& msg) { mParcelNameMsg = msg; } + void setParcelSalePriceMsg(const std::string& msg) { mParcelSalePriceMsg = msg; } + void setParcelSaleAreaMsg(const std::string& msg) { mParcelSaleAreaMsg = msg; } + void setParcelOwnerMsg(const std::string& msg) { mParcelOwnerMsg = msg; } + void setRegionNameMsg(const std::string& msg) { mRegionNameMsg = msg; } + void setToolTipHintMsg(const std::string& msg) { mToolTipHintMsg = msg; } + void setAltToolTipHintMsg(const std::string& msg) { mAltToolTipHintMsg = msg; } + void renderScaledPointGlobal( const LLVector3d& pos, const LLColor4U &color, F32 radius ); private: @@ -97,6 +109,8 @@ class LLNetMap final : public LLUICtrl void drawTracking( const LLVector3d& pos_global, const LLColor4& color, BOOL draw_arrow = TRUE); + bool isMouseOnPopupMenu(); + void updateAboutLandPopupButton(); BOOL handleToolTipAgent(const LLUUID& avatar_id); static void showAvatarInspector(const LLUUID& avatar_id); @@ -105,6 +119,7 @@ class LLNetMap final : public LLUICtrl void createParcelImage(); void renderPropertyLinesForRegion(const LLViewerRegion* pRegion, const LLColor4U& clrOverlay); + F32 getScaleForName(std::string scale_name); static bool outsideSlop(S32 x, S32 y, S32 start_x, S32 start_y, S32 slop); private: @@ -119,11 +134,12 @@ class LLNetMap final : public LLUICtrl F32 mObjectMapPixels; // Width of object map in pixels F32 mDotRadius; // Size of avatar markers - bool mPanning; // map is being dragged - LLVector2 mTargetPan; - LLVector2 mCurPan; - LLVector2 mStartPan; // pan offset at start of drag - LLCoordGL mMouseDown; // pointer position at start of drag + bool mPanning; // map is being dragged + bool mCentering; // map is being re-centered around the agent + LLVector2 mCurPan; + LLVector2 mStartPan; // pan offset at start of drag + LLVector3d mPopupWorldPos; // world position picked under mouse when context menu is opened + LLCoordGL mMouseDown; // pointer position at start of drag LLVector3d mObjectImageCenterGlobal; LLPointer<LLImageRaw> mObjectRawImagep; @@ -139,14 +155,26 @@ class LLNetMap final : public LLUICtrl LLUUID mClosestAgentToCursor; LLUUID mClosestAgentAtLastRightClick; - std::string mToolTipMsg; + std::string mToolTipMsg; + std::string mParcelNameMsg; + std::string mParcelSalePriceMsg; + std::string mParcelSaleAreaMsg; + std::string mParcelOwnerMsg; + std::string mRegionNameMsg; + std::string mToolTipHintMsg; + std::string mAltToolTipHintMsg; public: void setSelected(uuid_vec_t uuids) { gmSelected=uuids; }; private: - void handleZoom(const LLSD& userdata); - void handleStopTracking (const LLSD& userdata); + bool isZoomChecked(const LLSD& userdata); + void setZoom(const LLSD& userdata); + void handleStopTracking(const LLSD& userdata); + void activateCenterMap(const LLSD& userdata); + bool isMapOrientationChecked(const LLSD& userdata); + void setMapOrientation(const LLSD& userdata); + void popupShowAboutLand(const LLSD& userdata); LLHandle<LLView> mPopupMenuHandle; uuid_vec_t gmSelected; diff --git a/indra/newview/llnotificationofferhandler.cpp b/indra/newview/llnotificationofferhandler.cpp index 16e6615166f535c4793e203a99484f3084802760..ec3253089edfe934f54c833df5f2bdbc92001e07 100644 --- a/indra/newview/llnotificationofferhandler.cpp +++ b/indra/newview/llnotificationofferhandler.cpp @@ -180,14 +180,14 @@ bool LLOfferHandler::processNotification(const LLNotificationPtr& notification, /*virtual*/ void LLOfferHandler::onChange(LLNotificationPtr p) { - LLToastNotifyPanel* panelp = LLToastNotifyPanel::getInstance(p->getID()); + auto panelp = LLToastNotifyPanel::getInstance(p->getID()); if (panelp) { // // HACK: if we're dealing with a notification embedded in IM, update it // otherwise remove its toast // - if (dynamic_cast<LLIMToastNotifyPanel*>(panelp)) + if (dynamic_cast<LLIMToastNotifyPanel*>(panelp.get())) { panelp->updateNotification(); } diff --git a/indra/newview/llnotificationscripthandler.cpp b/indra/newview/llnotificationscripthandler.cpp index 01d20ac6fb81b029b3c28a68672b8fe421ed3578..68efc85822c0604d540069945fe0347f323b29c7 100644 --- a/indra/newview/llnotificationscripthandler.cpp +++ b/indra/newview/llnotificationscripthandler.cpp @@ -73,7 +73,8 @@ void LLScriptHandler::initChannel() //-------------------------------------------------------------------------- void LLScriptHandler::addToastWithNotification(const LLNotificationPtr& notification) { - LLToastPanel* notify_box = LLToastPanel::buidPanelFromNotification(notification); + LL_PROFILE_ZONE_SCOPED + LLToastPanel* notify_box = LLToastPanel::buidPanelFromNotification(notification); LLToast::Params p; p.notif_id = notification->getID(); diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp index 3344c6c5c3fd87b1eced7b39fd1299b2cef474eb..10f0dbb4e98177ffad98c05c3b88d2961529dfba 100644 --- a/indra/newview/lloutfitgallery.cpp +++ b/indra/newview/lloutfitgallery.cpp @@ -908,7 +908,7 @@ void LLOutfitGalleryContextMenu::onOutfitsRemovalConfirmation(const LLSD& notifi void LLOutfitGalleryContextMenu::onCreate(const LLSD& data) { - LLWearableType::EType type = LLWearableType::getInstanceFast()->typeNameToType(data.asString()); + LLWearableType::EType type = LLWearableType::getInstance()->typeNameToType(data.asString()); if (type == LLWearableType::WT_NONE) { LL_WARNS() << "Invalid wearable type" << LL_ENDL; @@ -1390,6 +1390,7 @@ void LLOutfitGallery::onSelectPhoto(LLUUID selected_outfit_id) texture_floaterp->setOnFloaterCommitCallback(boost::bind(&LLOutfitGallery::onTexturePickerCommit, this, _1, _2)); texture_floaterp->setOnUpdateImageStatsCallback(boost::bind(&LLOutfitGallery::onTexturePickerUpdateImageStats, this, _1)); texture_floaterp->setLocalTextureEnabled(FALSE); + texture_floaterp->setBakeTextureEnabled(FALSE); texture_floaterp->setCanApply(false, true); } diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index 37b2cc8093f1041a84cb8c0fdd366f90d70f4afe..132495c9392dd1bf8baca446cdc2c187066b47aa 100644 --- a/indra/newview/lloutfitslist.cpp +++ b/indra/newview/lloutfitslist.cpp @@ -1207,7 +1207,7 @@ void LLOutfitListGearMenuBase::onRename() void LLOutfitListGearMenuBase::onCreate(const LLSD& data) { - LLWearableType::EType type = LLWearableType::getInstanceFast()->typeNameToType(data.asString()); + LLWearableType::EType type = LLWearableType::getInstance()->typeNameToType(data.asString()); if (type == LLWearableType::WT_NONE) { LL_WARNS() << "Invalid wearable type" << LL_ENDL; diff --git a/indra/newview/lloutputmonitorctrl.cpp b/indra/newview/lloutputmonitorctrl.cpp index 08d0f548f071cfcf40d98a8a6fadeddfd819f243..7129641c20aa0b409cec71a5ace7fd538b9f1b31 100644 --- a/indra/newview/lloutputmonitorctrl.cpp +++ b/indra/newview/lloutputmonitorctrl.cpp @@ -128,14 +128,14 @@ void LLOutputMonitorCtrl::draw() if (getVisible() && mAutoUpdate && !getIsMuted() && mSpeakerId.notNull()) { - setPower(LLVoiceClient::getInstanceFast()->getCurrentPower(mSpeakerId)); + setPower(LLVoiceClient::getInstance()->getCurrentPower(mSpeakerId)); if(mIsAgentControl) { - setIsTalking(LLVoiceClient::getInstanceFast()->getUserPTTState()); + setIsTalking(LLVoiceClient::getInstance()->getUserPTTState()); } else { - setIsTalking(LLVoiceClient::getInstanceFast()->getIsSpeaking(mSpeakerId)); + setIsTalking(LLVoiceClient::getInstance()->getIsSpeaking(mSpeakerId)); } } @@ -306,8 +306,8 @@ void LLOutputMonitorCtrl::setSpeakerId(const LLUUID& speaker_id, const LLUUID& s else { // check only blocking on voice. EXT-3542 - mIsMuted = LLMuteList::getInstanceFast()->isMuted(mSpeakerId, LLMute::flagVoiceChat); - LLMuteList::getInstanceFast()->addObserver(this); + mIsMuted = LLMuteList::getInstance()->isMuted(mSpeakerId, LLMute::flagVoiceChat); + LLMuteList::getInstance()->addObserver(this); } } } diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp index 1b3994dc7bd674624f45032530ec08751eead1b0..4c097bb0451d005e1f0e94024ab9535b72cb59bb 100644 --- a/indra/newview/llpanelavatar.cpp +++ b/indra/newview/llpanelavatar.cpp @@ -70,32 +70,20 @@ static LLDefaultChildRegistry::Register<LLProfileDropTarget> r("profile_drop_tar LLPanelProfileTab::LLPanelProfileTab() : LLPanel() , mAvatarId(LLUUID::null) -, mLoading(false) -, mLoaded(false) -, mEmbedded(false) +, mLoadingState(PROFILE_INIT) , mSelfProfile(false) { } LLPanelProfileTab::~LLPanelProfileTab() { - if(getAvatarId().notNull()) - { - LLAvatarPropertiesProcessor::getInstanceFast()->removeObserver(getAvatarId(),this); - } } void LLPanelProfileTab::setAvatarId(const LLUUID& avatar_id) { if (avatar_id.notNull()) { - if (getAvatarId().notNull()) - { - LLAvatarPropertiesProcessor::getInstanceFast()->removeObserver(mAvatarId, this); - } mAvatarId = avatar_id; - LLAvatarPropertiesProcessor::getInstanceFast()->addObserver(getAvatarId(), this); - mSelfProfile = (getAvatarId() == gAgentID); } } @@ -108,11 +96,11 @@ void LLPanelProfileTab::onOpen(const LLSD& key) setApplyProgress(true); } -void LLPanelProfileTab::updateButtons() +void LLPanelProfileTab::setLoaded() { setApplyProgress(false); - mLoaded = true; + mLoadingState = PROFILE_LOADED; } void LLPanelProfileTab::setApplyProgress(bool started) @@ -132,4 +120,36 @@ void LLPanelProfileTab::setApplyProgress(bool started) indicator->stop(); } } + + LLView* panel = findChild<LLView>("indicator_stack"); + if (panel) + { + panel->setVisible(started); + } +} + +LLPanelProfilePropertiesProcessorTab::LLPanelProfilePropertiesProcessorTab() + : LLPanelProfileTab() +{ +} + +LLPanelProfilePropertiesProcessorTab::~LLPanelProfilePropertiesProcessorTab() +{ + if (getAvatarId().notNull()) + { + LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this); + } +} + +void LLPanelProfilePropertiesProcessorTab::setAvatarId(const LLUUID & avatar_id) +{ + if (avatar_id.notNull()) + { + if (getAvatarId().notNull()) + { + LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this); + } + LLPanelProfileTab::setAvatarId(avatar_id); + LLAvatarPropertiesProcessor::getInstance()->addObserver(getAvatarId(), this); + } } diff --git a/indra/newview/llpanelavatar.h b/indra/newview/llpanelavatar.h index f73ea0643dbeb19aab368c85c96c5572c8653577..f182660c8ea68cbe09626c5d2f4e042e9f317695 100644 --- a/indra/newview/llpanelavatar.h +++ b/indra/newview/llpanelavatar.h @@ -81,7 +81,6 @@ class LLProfileDropTarget : public LLView */ class LLPanelProfileTab : public LLPanel - , public LLAvatarPropertiesObserver { public: @@ -105,11 +104,6 @@ class LLPanelProfileTab */ virtual void onOpen(const LLSD& key); - /** - * Processes data received from server. - */ - virtual void processProperties(void* data, EAvatarProcessorType type) = 0; - /** * Clears all data received from server. */ @@ -117,37 +111,59 @@ class LLPanelProfileTab /*virtual*/ ~LLPanelProfileTab(); - void setEmbedded(bool embedded) { mEmbedded = embedded; } - protected: LLPanelProfileTab(); + enum ELoadingState + { + PROFILE_INIT, + PROFILE_LOADING, + PROFILE_LOADED, + }; + // mLoading: false: Initial state, can request // true: Data requested, skip duplicate requests (happens due to LLUI's habit of repeated callbacks) // mLoaded: false: Initial state, show loading indicator // true: Data recieved, which comes in a single message, hide indicator - bool getIsLoading() { return mLoading; } - void setIsLoading() { mLoading = true; } - bool getIsLoaded() { return mLoaded; } - void resetLoading() { mLoading = false; mLoaded = false; } - - const bool getEmbedded() const { return mEmbedded; } + ELoadingState getLoadingState() { return mLoadingState; } + virtual void setLoaded(); + void setApplyProgress(bool started); const bool getSelfProfile() const { return mSelfProfile; } - void setApplyProgress(bool started); +public: + void setIsLoading() { mLoadingState = PROFILE_LOADING; } + void resetLoading() { mLoadingState = PROFILE_INIT; } + + bool getStarted() { return mLoadingState != PROFILE_INIT; } + bool getIsLoaded() { return mLoadingState == PROFILE_LOADED; } - virtual void updateButtons(); + virtual bool hasUnsavedChanges() { return false; } + virtual void commitUnsavedChanges() {} private: LLUUID mAvatarId; - bool mLoading; - bool mLoaded; - bool mEmbedded; + ELoadingState mLoadingState; bool mSelfProfile; }; +class LLPanelProfilePropertiesProcessorTab + : public LLPanelProfileTab + , public LLAvatarPropertiesObserver +{ +public: + LLPanelProfilePropertiesProcessorTab(); + ~LLPanelProfilePropertiesProcessorTab(); + + /*virtual*/ void setAvatarId(const LLUUID& avatar_id); + + /** + * Processes data received from server via LLAvatarPropertiesObserver. + */ + virtual void processProperties(void* data, EAvatarProcessorType type) = 0; +}; + #endif // LL_LLPANELAVATAR_H diff --git a/indra/newview/llpanelblockedlist.cpp b/indra/newview/llpanelblockedlist.cpp index 3322e8a3df435c58e87c5e076aa9cf06643a7e05..3a4fc613b7b08037d4ccaba0a37bc39c9f90ffce 100644 --- a/indra/newview/llpanelblockedlist.cpp +++ b/indra/newview/llpanelblockedlist.cpp @@ -232,7 +232,7 @@ void LLPanelBlockedList::onFilterEdit(const std::string& search_string) void LLPanelBlockedList::callbackBlockPicked(const uuid_vec_t& ids, const std::vector<LLAvatarName> names) { if (names.empty() || ids.empty()) return; - LLMute mute(ids[0], names[0].getAccountName(), LLMute::AGENT); + LLMute mute(ids[0], names[0].getUserName(), LLMute::AGENT); LLMuteList::getInstance()->add(mute); showPanelAndSelect(mute.mID); } diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp index c4f81b6dca91347803f9caef13bcf54b923e2885..b0a26cf9be864a7ee2c4ad3281b60df93b3cdd2b 100644 --- a/indra/newview/llpanelclassified.cpp +++ b/indra/newview/llpanelclassified.cpp @@ -156,7 +156,7 @@ void LLPanelClassifiedInfo::onOpen(const LLSD& key) if(getAvatarId().notNull()) { - LLAvatarPropertiesProcessor::getInstanceFast()->removeObserver(getAvatarId(), this); + LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this); } setAvatarId(avatar_id); @@ -173,8 +173,8 @@ void LLPanelClassifiedInfo::onOpen(const LLSD& key) LL_INFOS() << "Opening classified [" << getClassifiedName() << "] (" << getClassifiedId() << ")" << LL_ENDL; - LLAvatarPropertiesProcessor::getInstanceFast()->addObserver(getAvatarId(), this); - LLAvatarPropertiesProcessor::getInstanceFast()->sendClassifiedInfoRequest(getClassifiedId()); + LLAvatarPropertiesProcessor::getInstance()->addObserver(getAvatarId(), this); + LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(getClassifiedId()); gGenericDispatcher.addHandler("classifiedclickthrough", &sClassifiedClickThrough); if (gAgent.getRegion()) @@ -256,7 +256,7 @@ void LLPanelClassifiedInfo::processProperties(void* data, EAvatarProcessorType t setInfoLoaded(true); - LLAvatarPropertiesProcessor::getInstanceFast()->removeObserver(getAvatarId(), this); + LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this); } } } diff --git a/indra/newview/llpanelcontents.cpp b/indra/newview/llpanelcontents.cpp index 582a206cfb864a0d25f8388eab9cdf2b0ec964d7..e6f9c8d3db1f4acafa7bb71fb135b256f97b1425 100644 --- a/indra/newview/llpanelcontents.cpp +++ b/indra/newview/llpanelcontents.cpp @@ -114,13 +114,13 @@ void LLPanelContents::getState(LLViewerObject *objectp ) } LLUUID group_id; // used for SL-23488 - LLSelectMgr::getInstanceFast()->selectGetGroup(group_id); // sets group_id as a side effect SL-23488 + LLSelectMgr::getInstance()->selectGetGroup(group_id); // sets group_id as a side effect SL-23488 // BUG? Check for all objects being editable? bool editable = gAgent.isGodlike() || (objectp->permModify() && !objectp->isPermanentEnforced() && ( objectp->permYouOwner() || ( !group_id.isNull() && gAgent.isInGroup(group_id) ))); // solves SL-23488 - BOOL all_volume = LLSelectMgr::getInstanceFast()->selectionAllPCode( LL_PCODE_VOLUME ); + BOOL all_volume = LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME ); // [RLVa:KB] - Checked: 2010-04-01 (RLVa-1.2.0c) | Modified: RLVa-1.0.5a if ( (rlv_handler_t::isEnabled()) && (editable) ) @@ -133,7 +133,7 @@ void LLPanelContents::getState(LLViewerObject *objectp ) if ( (editable) && ((gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) || (gRlvHandler.hasBehaviour(RLV_BHVR_SITTP))) ) { // Only check the first (non-)root object because nothing else would result in enabling the button (see below) - LLViewerObject* pObj = LLSelectMgr::getInstanceFast()->getSelection()->getFirstRootObject(TRUE); + LLViewerObject* pObj = LLSelectMgr::getInstance()->getSelection()->getFirstRootObject(TRUE); editable = (pObj) && (isAgentAvatarValid()) && ((!gAgentAvatarp->isSitting()) || (gAgentAvatarp->getRoot() != pObj->getRootEdit())); @@ -145,8 +145,8 @@ void LLPanelContents::getState(LLViewerObject *objectp ) getChildView("button new script")->setEnabled( editable && all_volume && - ((LLSelectMgr::getInstanceFast()->getSelection()->getRootObjectCount() == 1) - || (LLSelectMgr::getInstanceFast()->getSelection()->getObjectCount() == 1))); + ((LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() == 1) + || (LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1))); getChildView("button permissions")->setEnabled(!objectp->isPermanentEnforced()); mPanelInventoryObject->setEnabled(!objectp->isPermanentEnforced()); @@ -155,7 +155,7 @@ void LLPanelContents::getState(LLViewerObject *objectp ) void LLPanelContents::refresh() { const BOOL children_ok = TRUE; - LLViewerObject* object = LLSelectMgr::getInstanceFast()->getSelection()->getFirstRootObject(children_ok); + LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getFirstRootObject(children_ok); getState(object); if (mPanelInventoryObject) @@ -181,7 +181,7 @@ void LLPanelContents::clearContents() void LLPanelContents::onClickNewScript(void *userdata) { const BOOL children_ok = TRUE; - LLViewerObject* object = LLSelectMgr::getInstanceFast()->getSelection()->getFirstRootObject(children_ok); + LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getFirstRootObject(children_ok); if(object) { // [RLVa:KB] - Checked: 2010-03-31 (RLVa-1.2.0c) | Modified: RLVa-1.0.5a diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp index 0555eb8730acf12b5d993ae45c7fc36c969a9330..3d080006eca030b1f0e5331d00bbb9a3d9936833 100644 --- a/indra/newview/llpaneleditwearable.cpp +++ b/indra/newview/llpaneleditwearable.cpp @@ -1280,7 +1280,7 @@ void LLPanelEditWearable::changeCamera(U8 subpart) { // Don't change the camera if this type doesn't have a camera switch. // Useful for wearables like physics that don't have an associated physical body part. - if (LLWearableType::getInstanceFast()->getDisableCameraSwitch(mWearablePtr->getType())) + if (LLWearableType::getInstance()->getDisableCameraSwitch(mWearablePtr->getType())) { return; } @@ -1312,7 +1312,9 @@ void LLPanelEditWearable::changeCamera(U8 subpart) gMorphView->setCameraOffset( subpart_entry->mCameraOffset ); if (gSavedSettings.getBOOL("AppearanceCameraMovement")) { - gMorphView->updateCamera(); + // Unlock focus from avatar but don't stop animation to not interrupt ANIM_AGENT_CUSTOMIZE + gAgentCamera.setFocusOnAvatar(FALSE, gAgentCamera.getCameraAnimating()); + gMorphView->updateCamera(); } } diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 4b173196cb37eaa494812edcad8add8ead624308..7e223396d86193e29f9f680da7c0c8a871779b77 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -38,6 +38,7 @@ #include "llfontgl.h" // project includes +#include "llagent.h" #include "llagentdata.h" #include "llbutton.h" #include "llcheckboxctrl.h" @@ -45,10 +46,18 @@ #include "llcombobox.h" #include "lldrawpoolbump.h" #include "llface.h" +#include "llinventoryfunctions.h" +#include "llinventorymodel.h" // gInventory +#include "llinventorymodelbackgroundfetch.h" +#include "llfloatermediasettings.h" +#include "llfloaterreg.h" #include "lllineeditor.h" #include "llmaterialmgr.h" +#include "llmediactrl.h" #include "llmediaentry.h" +#include "llmenubutton.h" #include "llnotificationsutil.h" +#include "llpanelcontents.h" #include "llradiogroup.h" #include "llresmgr.h" #include "llselectmgr.h" @@ -57,6 +66,8 @@ #include "lltexturectrl.h" #include "lltextureentry.h" #include "lltooldraganddrop.h" +#include "lltoolface.h" +#include "lltoolmgr.h" #include "lltrans.h" #include "llui.h" #include "llviewercontrol.h" @@ -163,6 +174,8 @@ BOOL LLPanelFace::postBuild() mSpinMaskCutoff = getChild<LLSpinCtrl>("maskcutoff"); mSpinMaskCutoff->setCommitCallback(std::bind(onCommitMaterialMaskCutoff, std::placeholders::_1, this)); + childSetCommitCallback("add_media", &LLPanelFace::onClickBtnAddMedia, this); + childSetCommitCallback("delete_media", &LLPanelFace::onClickBtnDeleteMedia, this); childSetAction("button align",&LLPanelFace::onClickAutoFix,this); childSetAction("button align textures", &LLPanelFace::onAlignTexture, this); @@ -279,7 +292,13 @@ BOOL LLPanelFace::postBuild() { mCtrlGlow->setCommitCallback(LLPanelFace::onCommitGlow, this); } - + + mMenuClipboardColor = getChild<LLMenuButton>("clipboard_color_params_btn"); + mMenuClipboardTexture = getChild<LLMenuButton>("clipboard_texture_params_btn"); + + mTitleMedia = getChild<LLMediaCtrl>("title_media"); + mTitleMediaText = getChild<LLTextBox>("media_info"); + clearCtrls(); return TRUE; @@ -287,17 +306,33 @@ BOOL LLPanelFace::postBuild() LLPanelFace::LLPanelFace() : LLPanel(), - mIsAlpha(false) + mIsAlpha(false), + mComboMatMedia(NULL), + mTitleMedia(NULL), + mTitleMediaText(NULL), + mNeedMediaTitle(true) { - USE_TEXTURE = LLTrans::getString("use_texture"); + USE_TEXTURE = LLTrans::getString("use_texture"); + mCommitCallbackRegistrar.add("PanelFace.menuDoToSelected", boost::bind(&LLPanelFace::menuDoToSelected, this, _2)); + mEnableCallbackRegistrar.add("PanelFace.menuEnable", boost::bind(&LLPanelFace::menuEnableItem, this, _2)); } - LLPanelFace::~LLPanelFace() { - // Children all cleaned up by default view destructor. + unloadMedia(); } +void LLPanelFace::draw() +{ + updateCopyTexButton(); + + // grab media name/title and update the UI widget + // Todo: move it, it's preferable not to update + // labels inside draw + updateMediaTitle(); + + LLPanel::draw(); +} void LLPanelFace::sendTexture() { @@ -310,7 +345,7 @@ void LLPanelFace::sendTexture() { id = mTextureCtrl->getImageAssetID(); } - LLSelectMgr::getInstanceFast()->selectionSetImage(id); + LLSelectMgr::getInstance()->selectionSetImage(id); } } @@ -338,13 +373,13 @@ void LLPanelFace::sendBump(U32 bumpiness) // LLSelectedTEMaterial::setNormalID(this, current_normal_map); - LLSelectMgr::getInstanceFast()->selectionSetBumpmap( bump, mBumpyTextureCtrl->getImageItemID() ); + LLSelectMgr::getInstance()->selectionSetBumpmap( bump, mBumpyTextureCtrl->getImageItemID() ); } void LLPanelFace::sendTexGen() { U8 tex_gen = (U8) mComboTexGen->getCurrentIndex() << TEM_TEX_GEN_SHIFT; - LLSelectMgr::getInstanceFast()->selectionSetTexGen( tex_gen ); + LLSelectMgr::getInstance()->selectionSetTexGen( tex_gen ); } void LLPanelFace::sendShiny(U32 shininess) @@ -363,7 +398,7 @@ void LLPanelFace::sendShiny(U32 shininess) LLSelectedTEMaterial::setSpecularID(this, specmap); - LLSelectMgr::getInstanceFast()->selectionSetShiny( shiny, mShinyTextureCtrl->getImageItemID() ); + LLSelectMgr::getInstance()->selectionSetShiny( shiny, mShinyTextureCtrl->getImageItemID() ); updateShinyControls(!specmap.isNull(), true); @@ -372,20 +407,20 @@ void LLPanelFace::sendShiny(U32 shininess) void LLPanelFace::sendFullbright() { U8 fullbright = mCheckFullbright->get() ? TEM_FULLBRIGHT_MASK : 0; - LLSelectMgr::getInstanceFast()->selectionSetFullbright( fullbright ); + LLSelectMgr::getInstance()->selectionSetFullbright( fullbright ); } void LLPanelFace::sendColor() { const LLColor4& color = mColorSwatch->get(); - LLSelectMgr::getInstanceFast()->selectionSetColorOnly( color ); + LLSelectMgr::getInstance()->selectionSetColorOnly( color ); } void LLPanelFace::sendAlpha() { F32 alpha = (100.f - mCtrlColorTransp->get()) / 100.f; - LLSelectMgr::getInstanceFast()->selectionSetAlphaOnly( alpha ); + LLSelectMgr::getInstance()->selectionSetAlphaOnly( alpha ); } @@ -394,7 +429,7 @@ void LLPanelFace::sendGlow() if (mCtrlGlow) { F32 glow = mCtrlGlow->get(); - LLSelectMgr::getInstanceFast()->selectionSetGlow( glow ); + LLSelectMgr::getInstance()->selectionSetGlow( glow ); } } @@ -725,16 +760,16 @@ void LLPanelFace::sendTextureInfo() bool identical_face =false; LLSelectedTE::getFace(last_face, identical_face); LLPanelFaceSetAlignedTEFunctor setfunc(this, last_face); - LLSelectMgr::getInstanceFast()->getSelection()->applyToTEs(&setfunc); + LLSelectMgr::getInstance()->getSelection()->applyToTEs(&setfunc); } else { LLPanelFaceSetTEFunctor setfunc(this); - LLSelectMgr::getInstanceFast()->getSelection()->applyToTEs(&setfunc); + LLSelectMgr::getInstance()->getSelection()->applyToTEs(&setfunc); } LLPanelFaceSendFunctor sendfunc; - LLSelectMgr::getInstanceFast()->getSelection()->applyToObjects(&sendfunc); + LLSelectMgr::getInstance()->getSelection()->applyToObjects(&sendfunc); } void LLPanelFace::alignTestureLayer() @@ -744,7 +779,7 @@ void LLPanelFace::alignTestureLayer() LLSelectedTE::getFace(last_face, identical_face); LLPanelFaceSetAlignedConcreteTEFunctor setfunc(this, last_face, static_cast<LLRender::eTexIndex>(mRadioMatType->getSelectedIndex())); - LLSelectMgr::getInstanceFast()->getSelection()->applyToTEs(&setfunc); + LLSelectMgr::getInstance()->getSelection()->applyToTEs(&setfunc); } void LLPanelFace::getState() @@ -754,7 +789,7 @@ void LLPanelFace::getState() void LLPanelFace::updateUI(bool force_set_values /*false*/) { //set state of UI to match state of texture entry(ies) (calls setEnabled, setValue, etc, but NOT setVisible) - LLViewerObject* objectp = LLSelectMgr::getInstanceFast()->getSelection()->getFirstObject(); + LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); if( objectp && objectp->getPCode() == LL_PCODE_VOLUME @@ -763,7 +798,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) BOOL editable = objectp->permModify() && !objectp->isPermanentEnforced(); // only turn on auto-adjust button if there is a media renderer and the media is loaded - getChildView("button align")->setEnabled(editable); + childSetEnabled("button align", editable); if (mComboMatMedia->getCurrentIndex() < MATMEDIA_MATERIAL) { @@ -912,7 +947,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) break; } - if(LLViewerMedia::getInstanceFast()->textureHasMedia(id)) + if(LLViewerMedia::getInstance()->textureHasMedia(id)) { getChildView("button align")->setEnabled(editable); } @@ -1011,7 +1046,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) childSetValue("checkbox planar align", align_planar && enabled); childSetVisible("checkbox planar align", enabled); childSetEnabled("checkbox planar align", enabled); - childSetEnabled("button align textures", enabled && LLSelectMgr::getInstanceFast()->getSelection()->getObjectCount() > 1); + childSetEnabled("button align textures", enabled && LLSelectMgr::getInstance()->getSelection()->getObjectCount() > 1); if (align_planar && enabled) { @@ -1021,7 +1056,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) LLPanelFaceGetIsAlignedTEFunctor get_is_aligend_func(last_face); // this will determine if the texture param controls are tentative: - identical_planar_aligned = LLSelectMgr::getInstanceFast()->getSelection()->applyToTEs(&get_is_aligend_func); + identical_planar_aligned = LLSelectMgr::getInstance()->getSelection()->applyToTEs(&get_is_aligend_func); } } @@ -1272,7 +1307,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) F32 repeats = 1.0f; U32 material_type = (mComboMatMedia->getCurrentIndex() == MATMEDIA_MATERIAL) ? mRadioMatType->getSelectedIndex() : MATTYPE_DIFFUSE; - LLSelectMgr::getInstanceFast()->setTextureChannel(LLRender::eTexIndex(material_type)); + LLSelectMgr::getInstance()->setTextureChannel(LLRender::eTexIndex(material_type)); switch (material_type) { @@ -1419,6 +1454,9 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) } } } + S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount(); + BOOL single_volume = (selected_count == 1); + mMenuClipboardColor->setEnabled(editable && single_volume); // Set variable values for numeric expressions LLCalc* calcp = LLCalc::getInstance(); @@ -1473,12 +1511,772 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) } +void LLPanelFace::updateCopyTexButton() +{ + LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); + mMenuClipboardTexture->setEnabled(objectp && objectp->getPCode() == LL_PCODE_VOLUME && objectp->permModify() + && !objectp->isPermanentEnforced() && !objectp->isInventoryPending() + && (LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1)); + std::string tooltip = (objectp && objectp->isInventoryPending()) ? LLTrans::getString("LoadingContents") : getString("paste_options"); + mMenuClipboardTexture->setToolTip(tooltip); + +} + void LLPanelFace::refresh() { LL_DEBUGS("Materials") << LL_ENDL; getState(); } +void LLPanelFace::refreshMedia() +{ + LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection(); + LLViewerObject* first_object = selected_objects->getFirstObject(); + + if (!(first_object + && first_object->getPCode() == LL_PCODE_VOLUME + && first_object->permModify() + )) + { + getChildView("add_media")->setEnabled(FALSE); + mTitleMediaText->clear(); + clearMediaSettings(); + return; + } + + std::string url = first_object->getRegion()->getCapability("ObjectMedia"); + bool has_media_capability = (!url.empty()); + + if (!has_media_capability) + { + getChildView("add_media")->setEnabled(FALSE); + LL_WARNS("LLFloaterToolsMedia") << "Media not enabled (no capability) in this region!" << LL_ENDL; + clearMediaSettings(); + return; + } + + BOOL is_nonpermanent_enforced = (LLSelectMgr::getInstance()->getSelection()->getFirstRootNode() + && LLSelectMgr::getInstance()->selectGetRootsNonPermanentEnforced()) + || LLSelectMgr::getInstance()->selectGetNonPermanentEnforced(); + bool editable = is_nonpermanent_enforced && (first_object->permModify() || selectedMediaEditable()); + + // Check modify permissions and whether any selected objects are in + // the process of being fetched. If they are, then we're not editable + if (editable) + { + LLObjectSelection::iterator iter = selected_objects->begin(); + LLObjectSelection::iterator end = selected_objects->end(); + for (; iter != end; ++iter) + { + LLSelectNode* node = *iter; + LLVOVolume* object = dynamic_cast<LLVOVolume*>(node->getObject()); + if (NULL != object) + { + if (!object->permModify()) + { + LL_INFOS("LLFloaterToolsMedia") + << "Selection not editable due to lack of modify permissions on object id " + << object->getID() << LL_ENDL; + + editable = false; + break; + } + } + } + } + + // Media settings + bool bool_has_media = false; + struct media_functor : public LLSelectedTEGetFunctor<bool> + { + bool get(LLViewerObject* object, S32 face) + { + LLTextureEntry *te = object->getTE(face); + if (te) + { + return te->hasMedia(); + } + return false; + } + } func; + + + // check if all faces have media(or, all dont have media) + LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo = selected_objects->getSelectedTEValue(&func, bool_has_media); + + const LLMediaEntry default_media_data; + + struct functor_getter_media_data : public LLSelectedTEGetFunctor< LLMediaEntry> + { + functor_getter_media_data(const LLMediaEntry& entry) : mMediaEntry(entry) {} + + LLMediaEntry get(LLViewerObject* object, S32 face) + { + if (object) + if (object->getTE(face)) + if (object->getTE(face)->getMediaData()) + return *(object->getTE(face)->getMediaData()); + return mMediaEntry; + }; + + const LLMediaEntry& mMediaEntry; + + } func_media_data(default_media_data); + + LLMediaEntry media_data_get; + LLFloaterMediaSettings::getInstance()->mMultipleMedia = !(selected_objects->getSelectedTEValue(&func_media_data, media_data_get)); + + std::string multi_media_info_str = LLTrans::getString("Multiple Media"); + std::string media_title = ""; + // update UI depending on whether "object" (prim or face) has media + // and whether or not you are allowed to edit it. + + getChildView("add_media")->setEnabled(editable); + // IF all the faces have media (or all dont have media) + if (LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo) + { + // TODO: get media title and set it. + mTitleMediaText->clear(); + // if identical is set, all faces are same (whether all empty or has the same media) + if (!(LLFloaterMediaSettings::getInstance()->mMultipleMedia)) + { + // Media data is valid + if (media_data_get != default_media_data) + { + // initial media title is the media URL (until we get the name) + media_title = media_data_get.getHomeURL(); + } + // else all faces might be empty. + } + else // there' re Different Medias' been set on on the faces. + { + media_title = multi_media_info_str; + } + + getChildView("delete_media")->setEnabled(bool_has_media && editable); + // TODO: display a list of all media on the face - use 'identical' flag + } + else // not all face has media but at least one does. + { + // seleted faces have not identical value + LLFloaterMediaSettings::getInstance()->mMultipleValidMedia = selected_objects->isMultipleTEValue(&func_media_data, default_media_data); + + if (LLFloaterMediaSettings::getInstance()->mMultipleValidMedia) + { + media_title = multi_media_info_str; + } + else + { + // Media data is valid + if (media_data_get != default_media_data) + { + // initial media title is the media URL (until we get the name) + media_title = media_data_get.getHomeURL(); + } + } + + getChildView("delete_media")->setEnabled(TRUE); + } + + U32 materials_media = mComboMatMedia->getCurrentIndex(); + if (materials_media == MATMEDIA_MEDIA) + { + // currently displaying media info, navigateTo and update title + navigateToTitleMedia(media_title); + } + else + { + // Media can be heavy, don't keep it around + // MAC specific: MAC doesn't support setVolume(0) so if not + // unloaded, it might keep playing audio until user closes editor + unloadMedia(); + mNeedMediaTitle = false; + } + + mTitleMediaText->setText(media_title); + + // load values for media settings + updateMediaSettings(); + + LLFloaterMediaSettings::initValues(mMediaSettings, editable); +} + +void LLPanelFace::unloadMedia() +{ + // destroy media source used to grab media title + if (mTitleMedia) + mTitleMedia->unloadMediaSource(); +} + +////////////////////////////////////////////////////////////////////////////// +// +void LLPanelFace::navigateToTitleMedia( const std::string url ) +{ + std::string multi_media_info_str = LLTrans::getString("Multiple Media"); + if (url.empty() || multi_media_info_str == url) + { + // nothing to show + mNeedMediaTitle = false; + } + else if (mTitleMedia) + { + LLPluginClassMedia* media_plugin = mTitleMedia->getMediaPlugin(); + // check if url changed or if we need a new media source + if (mTitleMedia->getCurrentNavUrl() != url || media_plugin == NULL) + { + mTitleMedia->navigateTo( url ); + + LLViewerMediaImpl* impl = LLViewerMedia::getInstance()->getMediaImplFromTextureID(mTitleMedia->getTextureID()); + if (impl) + { + // if it's a page with a movie, we don't want to hear it + impl->setVolume(0); + }; + } + + // flag that we need to update the title (even if no request were made) + mNeedMediaTitle = true; + } +} + +bool LLPanelFace::selectedMediaEditable() +{ + U32 owner_mask_on; + U32 owner_mask_off; + U32 valid_owner_perms = LLSelectMgr::getInstance()->selectGetPerm(PERM_OWNER, + &owner_mask_on, &owner_mask_off); + U32 group_mask_on; + U32 group_mask_off; + U32 valid_group_perms = LLSelectMgr::getInstance()->selectGetPerm(PERM_GROUP, + &group_mask_on, &group_mask_off); + U32 everyone_mask_on; + U32 everyone_mask_off; + S32 valid_everyone_perms = LLSelectMgr::getInstance()->selectGetPerm(PERM_EVERYONE, + &everyone_mask_on, &everyone_mask_off); + + bool selected_Media_editable = false; + + // if perms we got back are valid + if (valid_owner_perms && + valid_group_perms && + valid_everyone_perms) + { + + if ((owner_mask_on & PERM_MODIFY) || + (group_mask_on & PERM_MODIFY) || + (everyone_mask_on & PERM_MODIFY)) + { + selected_Media_editable = true; + } + else + // user is NOT allowed to press the RESET button + { + selected_Media_editable = false; + }; + }; + + return selected_Media_editable; +} + +void LLPanelFace::clearMediaSettings() +{ + LLFloaterMediaSettings::clearValues(false); +} + +void LLPanelFace::updateMediaSettings() +{ + bool identical(false); + std::string base_key(""); + std::string value_str(""); + int value_int = 0; + bool value_bool = false; + LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection(); + // TODO: (CP) refactor this using something clever or boost or both !! + + const LLMediaEntry default_media_data; + + // controls + U8 value_u8 = default_media_data.getControls(); + struct functor_getter_controls : public LLSelectedTEGetFunctor< U8 > + { + functor_getter_controls(const LLMediaEntry &entry) : mMediaEntry(entry) {} + + U8 get(LLViewerObject* object, S32 face) + { + if (object) + if (object->getTE(face)) + if (object->getTE(face)->getMediaData()) + return object->getTE(face)->getMediaData()->getControls(); + return mMediaEntry.getControls(); + }; + + const LLMediaEntry &mMediaEntry; + + } func_controls(default_media_data); + identical = selected_objects->getSelectedTEValue(&func_controls, value_u8); + base_key = std::string(LLMediaEntry::CONTROLS_KEY); + mMediaSettings[base_key] = value_u8; + mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical; + + // First click (formerly left click) + value_bool = default_media_data.getFirstClickInteract(); + struct functor_getter_first_click : public LLSelectedTEGetFunctor< bool > + { + functor_getter_first_click(const LLMediaEntry& entry) : mMediaEntry(entry) {} + + bool get(LLViewerObject* object, S32 face) + { + if (object) + if (object->getTE(face)) + if (object->getTE(face)->getMediaData()) + return object->getTE(face)->getMediaData()->getFirstClickInteract(); + return mMediaEntry.getFirstClickInteract(); + }; + + const LLMediaEntry &mMediaEntry; + + } func_first_click(default_media_data); + identical = selected_objects->getSelectedTEValue(&func_first_click, value_bool); + base_key = std::string(LLMediaEntry::FIRST_CLICK_INTERACT_KEY); + mMediaSettings[base_key] = value_bool; + mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical; + + // Home URL + value_str = default_media_data.getHomeURL(); + struct functor_getter_home_url : public LLSelectedTEGetFunctor< std::string > + { + functor_getter_home_url(const LLMediaEntry& entry) : mMediaEntry(entry) {} + + std::string get(LLViewerObject* object, S32 face) + { + if (object) + if (object->getTE(face)) + if (object->getTE(face)->getMediaData()) + return object->getTE(face)->getMediaData()->getHomeURL(); + return mMediaEntry.getHomeURL(); + }; + + const LLMediaEntry &mMediaEntry; + + } func_home_url(default_media_data); + identical = selected_objects->getSelectedTEValue(&func_home_url, value_str); + base_key = std::string(LLMediaEntry::HOME_URL_KEY); + mMediaSettings[base_key] = value_str; + mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical; + + // Current URL + value_str = default_media_data.getCurrentURL(); + struct functor_getter_current_url : public LLSelectedTEGetFunctor< std::string > + { + functor_getter_current_url(const LLMediaEntry& entry) : mMediaEntry(entry) {} + + std::string get(LLViewerObject* object, S32 face) + { + if (object) + if (object->getTE(face)) + if (object->getTE(face)->getMediaData()) + return object->getTE(face)->getMediaData()->getCurrentURL(); + return mMediaEntry.getCurrentURL(); + }; + + const LLMediaEntry &mMediaEntry; + + } func_current_url(default_media_data); + identical = selected_objects->getSelectedTEValue(&func_current_url, value_str); + base_key = std::string(LLMediaEntry::CURRENT_URL_KEY); + mMediaSettings[base_key] = value_str; + mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical; + + // Auto zoom + value_bool = default_media_data.getAutoZoom(); + struct functor_getter_auto_zoom : public LLSelectedTEGetFunctor< bool > + { + + functor_getter_auto_zoom(const LLMediaEntry& entry) : mMediaEntry(entry) {} + + bool get(LLViewerObject* object, S32 face) + { + if (object) + if (object->getTE(face)) + if (object->getTE(face)->getMediaData()) + return object->getTE(face)->getMediaData()->getAutoZoom(); + return mMediaEntry.getAutoZoom(); + }; + + const LLMediaEntry &mMediaEntry; + + } func_auto_zoom(default_media_data); + identical = selected_objects->getSelectedTEValue(&func_auto_zoom, value_bool); + base_key = std::string(LLMediaEntry::AUTO_ZOOM_KEY); + mMediaSettings[base_key] = value_bool; + mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical; + + // Auto play + //value_bool = default_media_data.getAutoPlay(); + // set default to auto play TRUE -- angela EXT-5172 + value_bool = true; + struct functor_getter_auto_play : public LLSelectedTEGetFunctor< bool > + { + functor_getter_auto_play(const LLMediaEntry& entry) : mMediaEntry(entry) {} + + bool get(LLViewerObject* object, S32 face) + { + if (object) + if (object->getTE(face)) + if (object->getTE(face)->getMediaData()) + return object->getTE(face)->getMediaData()->getAutoPlay(); + //return mMediaEntry.getAutoPlay(); set default to auto play TRUE -- angela EXT-5172 + return true; + }; + + const LLMediaEntry &mMediaEntry; + + } func_auto_play(default_media_data); + identical = selected_objects->getSelectedTEValue(&func_auto_play, value_bool); + base_key = std::string(LLMediaEntry::AUTO_PLAY_KEY); + mMediaSettings[base_key] = value_bool; + mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical; + + + // Auto scale + // set default to auto scale TRUE -- angela EXT-5172 + //value_bool = default_media_data.getAutoScale(); + value_bool = true; + struct functor_getter_auto_scale : public LLSelectedTEGetFunctor< bool > + { + functor_getter_auto_scale(const LLMediaEntry& entry) : mMediaEntry(entry) {} + + bool get(LLViewerObject* object, S32 face) + { + if (object) + if (object->getTE(face)) + if (object->getTE(face)->getMediaData()) + return object->getTE(face)->getMediaData()->getAutoScale(); + // return mMediaEntry.getAutoScale(); set default to auto scale TRUE -- angela EXT-5172 + return true; + }; + + const LLMediaEntry &mMediaEntry; + + } func_auto_scale(default_media_data); + identical = selected_objects->getSelectedTEValue(&func_auto_scale, value_bool); + base_key = std::string(LLMediaEntry::AUTO_SCALE_KEY); + mMediaSettings[base_key] = value_bool; + mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical; + + // Auto loop + value_bool = default_media_data.getAutoLoop(); + struct functor_getter_auto_loop : public LLSelectedTEGetFunctor< bool > + { + functor_getter_auto_loop(const LLMediaEntry& entry) : mMediaEntry(entry) {} + + bool get(LLViewerObject* object, S32 face) + { + if (object) + if (object->getTE(face)) + if (object->getTE(face)->getMediaData()) + return object->getTE(face)->getMediaData()->getAutoLoop(); + return mMediaEntry.getAutoLoop(); + }; + + const LLMediaEntry &mMediaEntry; + + } func_auto_loop(default_media_data); + identical = selected_objects->getSelectedTEValue(&func_auto_loop, value_bool); + base_key = std::string(LLMediaEntry::AUTO_LOOP_KEY); + mMediaSettings[base_key] = value_bool; + mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical; + + // width pixels (if not auto scaled) + value_int = default_media_data.getWidthPixels(); + struct functor_getter_width_pixels : public LLSelectedTEGetFunctor< int > + { + functor_getter_width_pixels(const LLMediaEntry& entry) : mMediaEntry(entry) {} + + int get(LLViewerObject* object, S32 face) + { + if (object) + if (object->getTE(face)) + if (object->getTE(face)->getMediaData()) + return object->getTE(face)->getMediaData()->getWidthPixels(); + return mMediaEntry.getWidthPixels(); + }; + + const LLMediaEntry &mMediaEntry; + + } func_width_pixels(default_media_data); + identical = selected_objects->getSelectedTEValue(&func_width_pixels, value_int); + base_key = std::string(LLMediaEntry::WIDTH_PIXELS_KEY); + mMediaSettings[base_key] = value_int; + mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical; + + // height pixels (if not auto scaled) + value_int = default_media_data.getHeightPixels(); + struct functor_getter_height_pixels : public LLSelectedTEGetFunctor< int > + { + functor_getter_height_pixels(const LLMediaEntry& entry) : mMediaEntry(entry) {} + + int get(LLViewerObject* object, S32 face) + { + if (object) + if (object->getTE(face)) + if (object->getTE(face)->getMediaData()) + return object->getTE(face)->getMediaData()->getHeightPixels(); + return mMediaEntry.getHeightPixels(); + }; + + const LLMediaEntry &mMediaEntry; + + } func_height_pixels(default_media_data); + identical = selected_objects->getSelectedTEValue(&func_height_pixels, value_int); + base_key = std::string(LLMediaEntry::HEIGHT_PIXELS_KEY); + mMediaSettings[base_key] = value_int; + mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical; + + // Enable Alt image + value_bool = default_media_data.getAltImageEnable(); + struct functor_getter_enable_alt_image : public LLSelectedTEGetFunctor< bool > + { + functor_getter_enable_alt_image(const LLMediaEntry& entry) : mMediaEntry(entry) {} + + bool get(LLViewerObject* object, S32 face) + { + if (object) + if (object->getTE(face)) + if (object->getTE(face)->getMediaData()) + return object->getTE(face)->getMediaData()->getAltImageEnable(); + return mMediaEntry.getAltImageEnable(); + }; + + const LLMediaEntry &mMediaEntry; + + } func_enable_alt_image(default_media_data); + identical = selected_objects->getSelectedTEValue(&func_enable_alt_image, value_bool); + base_key = std::string(LLMediaEntry::ALT_IMAGE_ENABLE_KEY); + mMediaSettings[base_key] = value_bool; + mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical; + + // Perms - owner interact + value_bool = 0 != (default_media_data.getPermsInteract() & LLMediaEntry::PERM_OWNER); + struct functor_getter_perms_owner_interact : public LLSelectedTEGetFunctor< bool > + { + functor_getter_perms_owner_interact(const LLMediaEntry& entry) : mMediaEntry(entry) {} + + bool get(LLViewerObject* object, S32 face) + { + if (object) + if (object->getTE(face)) + if (object->getTE(face)->getMediaData()) + return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_OWNER)); + return 0 != (mMediaEntry.getPermsInteract() & LLMediaEntry::PERM_OWNER); + }; + + const LLMediaEntry &mMediaEntry; + + } func_perms_owner_interact(default_media_data); + identical = selected_objects->getSelectedTEValue(&func_perms_owner_interact, value_bool); + base_key = std::string(LLPanelContents::PERMS_OWNER_INTERACT_KEY); + mMediaSettings[base_key] = value_bool; + mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical; + + // Perms - owner control + value_bool = 0 != (default_media_data.getPermsControl() & LLMediaEntry::PERM_OWNER); + struct functor_getter_perms_owner_control : public LLSelectedTEGetFunctor< bool > + { + functor_getter_perms_owner_control(const LLMediaEntry& entry) : mMediaEntry(entry) {} + + bool get(LLViewerObject* object, S32 face) + { + if (object) + if (object->getTE(face)) + if (object->getTE(face)->getMediaData()) + return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_OWNER)); + return 0 != (mMediaEntry.getPermsControl() & LLMediaEntry::PERM_OWNER); + }; + + const LLMediaEntry &mMediaEntry; + + } func_perms_owner_control(default_media_data); + identical = selected_objects->getSelectedTEValue(&func_perms_owner_control, value_bool); + base_key = std::string(LLPanelContents::PERMS_OWNER_CONTROL_KEY); + mMediaSettings[base_key] = value_bool; + mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical; + + // Perms - group interact + value_bool = 0 != (default_media_data.getPermsInteract() & LLMediaEntry::PERM_GROUP); + struct functor_getter_perms_group_interact : public LLSelectedTEGetFunctor< bool > + { + functor_getter_perms_group_interact(const LLMediaEntry& entry) : mMediaEntry(entry) {} + + bool get(LLViewerObject* object, S32 face) + { + if (object) + if (object->getTE(face)) + if (object->getTE(face)->getMediaData()) + return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_GROUP)); + return 0 != (mMediaEntry.getPermsInteract() & LLMediaEntry::PERM_GROUP); + }; + + const LLMediaEntry &mMediaEntry; + + } func_perms_group_interact(default_media_data); + identical = selected_objects->getSelectedTEValue(&func_perms_group_interact, value_bool); + base_key = std::string(LLPanelContents::PERMS_GROUP_INTERACT_KEY); + mMediaSettings[base_key] = value_bool; + mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical; + + // Perms - group control + value_bool = 0 != (default_media_data.getPermsControl() & LLMediaEntry::PERM_GROUP); + struct functor_getter_perms_group_control : public LLSelectedTEGetFunctor< bool > + { + functor_getter_perms_group_control(const LLMediaEntry& entry) : mMediaEntry(entry) {} + + bool get(LLViewerObject* object, S32 face) + { + if (object) + if (object->getTE(face)) + if (object->getTE(face)->getMediaData()) + return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_GROUP)); + return 0 != (mMediaEntry.getPermsControl() & LLMediaEntry::PERM_GROUP); + }; + + const LLMediaEntry &mMediaEntry; + + } func_perms_group_control(default_media_data); + identical = selected_objects->getSelectedTEValue(&func_perms_group_control, value_bool); + base_key = std::string(LLPanelContents::PERMS_GROUP_CONTROL_KEY); + mMediaSettings[base_key] = value_bool; + mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical; + + // Perms - anyone interact + value_bool = 0 != (default_media_data.getPermsInteract() & LLMediaEntry::PERM_ANYONE); + struct functor_getter_perms_anyone_interact : public LLSelectedTEGetFunctor< bool > + { + functor_getter_perms_anyone_interact(const LLMediaEntry& entry) : mMediaEntry(entry) {} + + bool get(LLViewerObject* object, S32 face) + { + if (object) + if (object->getTE(face)) + if (object->getTE(face)->getMediaData()) + return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_ANYONE)); + return 0 != (mMediaEntry.getPermsInteract() & LLMediaEntry::PERM_ANYONE); + }; + + const LLMediaEntry &mMediaEntry; + + } func_perms_anyone_interact(default_media_data); + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&func_perms_anyone_interact, value_bool); + base_key = std::string(LLPanelContents::PERMS_ANYONE_INTERACT_KEY); + mMediaSettings[base_key] = value_bool; + mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical; + + // Perms - anyone control + value_bool = 0 != (default_media_data.getPermsControl() & LLMediaEntry::PERM_ANYONE); + struct functor_getter_perms_anyone_control : public LLSelectedTEGetFunctor< bool > + { + functor_getter_perms_anyone_control(const LLMediaEntry& entry) : mMediaEntry(entry) {} + + bool get(LLViewerObject* object, S32 face) + { + if (object) + if (object->getTE(face)) + if (object->getTE(face)->getMediaData()) + return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_ANYONE)); + return 0 != (mMediaEntry.getPermsControl() & LLMediaEntry::PERM_ANYONE); + }; + + const LLMediaEntry &mMediaEntry; + + } func_perms_anyone_control(default_media_data); + identical = selected_objects->getSelectedTEValue(&func_perms_anyone_control, value_bool); + base_key = std::string(LLPanelContents::PERMS_ANYONE_CONTROL_KEY); + mMediaSettings[base_key] = value_bool; + mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical; + + // security - whitelist enable + value_bool = default_media_data.getWhiteListEnable(); + struct functor_getter_whitelist_enable : public LLSelectedTEGetFunctor< bool > + { + functor_getter_whitelist_enable(const LLMediaEntry& entry) : mMediaEntry(entry) {} + + bool get(LLViewerObject* object, S32 face) + { + if (object) + if (object->getTE(face)) + if (object->getTE(face)->getMediaData()) + return object->getTE(face)->getMediaData()->getWhiteListEnable(); + return mMediaEntry.getWhiteListEnable(); + }; + + const LLMediaEntry &mMediaEntry; + + } func_whitelist_enable(default_media_data); + identical = selected_objects->getSelectedTEValue(&func_whitelist_enable, value_bool); + base_key = std::string(LLMediaEntry::WHITELIST_ENABLE_KEY); + mMediaSettings[base_key] = value_bool; + mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical; + + // security - whitelist URLs + std::vector<std::string> value_vector_str = default_media_data.getWhiteList(); + struct functor_getter_whitelist_urls : public LLSelectedTEGetFunctor< std::vector<std::string> > + { + functor_getter_whitelist_urls(const LLMediaEntry& entry) : mMediaEntry(entry) {} + + std::vector<std::string> get(LLViewerObject* object, S32 face) + { + if (object) + if (object->getTE(face)) + if (object->getTE(face)->getMediaData()) + return object->getTE(face)->getMediaData()->getWhiteList(); + return mMediaEntry.getWhiteList(); + }; + + const LLMediaEntry &mMediaEntry; + + } func_whitelist_urls(default_media_data); + identical = selected_objects->getSelectedTEValue(&func_whitelist_urls, value_vector_str); + base_key = std::string(LLMediaEntry::WHITELIST_KEY); + mMediaSettings[base_key].clear(); + std::vector< std::string >::iterator iter = value_vector_str.begin(); + while (iter != value_vector_str.end()) + { + std::string white_list_url = *iter; + mMediaSettings[base_key].append(white_list_url); + ++iter; + }; + + mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical; +} + +void LLPanelFace::updateMediaTitle() +{ + // only get the media name if we need it + if (!mNeedMediaTitle) + return; + + // get plugin impl + LLPluginClassMedia* media_plugin = mTitleMedia->getMediaPlugin(); + if (media_plugin && mTitleMedia->getCurrentNavUrl() == media_plugin->getNavigateURI()) + { + // get the media name (asynchronous - must call repeatedly) + std::string media_title = media_plugin->getMediaName(); + + // only replace the title if what we get contains something + if (!media_title.empty()) + { + // update the UI widget + if (mTitleMediaText) + { + mTitleMediaText->setText(media_title); + + // stop looking for a title when we get one + mNeedMediaTitle = false; + }; + }; + }; +} + // // Static functions // @@ -1507,24 +2305,24 @@ void LLPanelFace::onCommitAlpha(const LLSD& data) void LLPanelFace::onCancelColor(const LLSD& data) { - LLSelectMgr::getInstanceFast()->selectionRevertColors(); + LLSelectMgr::getInstance()->selectionRevertColors(); } void LLPanelFace::onCancelShinyColor(const LLSD& data) { - LLSelectMgr::getInstanceFast()->selectionRevertShinyColors(); + LLSelectMgr::getInstance()->selectionRevertShinyColors(); } void LLPanelFace::onSelectColor(const LLSD& data) { - LLSelectMgr::getInstanceFast()->saveSelectedObjectColors(); + LLSelectMgr::getInstance()->saveSelectedObjectColors(); sendColor(); } void LLPanelFace::onSelectShinyColor(const LLSD& data) { LLSelectedTEMaterial::setSpecularLightColor(this, mShinyColorSwatch->get()); - LLSelectMgr::getInstanceFast()->saveSelectedShinyColors(); + LLSelectMgr::getInstance()->saveSelectedShinyColors(); } // static @@ -1537,9 +2335,9 @@ void LLPanelFace::onCommitMaterialsMedia(LLUICtrl* ctrl, void* userdata) self->updateShinyControls(false,true); self->updateBumpyControls(false,true); self->updateUI(); + self->refreshMedia(); } -// static void LLPanelFace::updateVisibility() { U32 materials_media = mComboMatMedia->getCurrentIndex(); @@ -1551,7 +2349,7 @@ void LLPanelFace::updateVisibility() mRadioMatType->setVisible(!show_media); // Media controls - getChildView("media_info")->setVisible(show_media); + mTitleMediaText->setVisible(show_media); getChildView("add_media")->setVisible(show_media); getChildView("delete_media")->setVisible(show_media); getChildView("button align")->setVisible(show_media); @@ -1767,7 +2565,7 @@ void LLPanelFace::onCommitGlow(LLUICtrl* ctrl, void* userdata) BOOL LLPanelFace::onDragTexture(LLUICtrl*, LLInventoryItem* item) { BOOL accept = TRUE; - for (LLSelectNode* node : LLSelectMgr::getInstanceFast()->getSelection()->root_begin_end()) + for (LLSelectNode* node : LLSelectMgr::getInstance()->getSelection()->root_begin_end()) { LLViewerObject* obj = node->getObject(); if(!LLToolDragAndDrop::isInventoryDropAcceptable(obj, item)) @@ -1787,12 +2585,12 @@ void LLPanelFace::onCommitTexture( const LLSD& data ) void LLPanelFace::onCancelTexture(const LLSD& data) { - LLSelectMgr::getInstanceFast()->selectionRevertTextures(); + LLSelectMgr::getInstance()->selectionRevertTextures(); } void LLPanelFace::onSelectTexture(const LLSD& data) { - LLSelectMgr::getInstanceFast()->saveSelectedObjectTextures(); + LLSelectMgr::getInstance()->saveSelectedObjectTextures(); sendTexture(); LLGLenum image_format; @@ -1878,6 +2676,77 @@ void LLPanelFace::onSelectNormalTexture(const LLSD& data) sendBump(nmap_id.isNull() ? 0 : BUMPY_TEXTURE); } +////////////////////////////////////////////////////////////////////////////// +// called when a user wants to edit existing media settings on a prim or prim face +// TODO: test if there is media on the item and only allow editing if present +void LLPanelFace::onClickBtnEditMedia(LLUICtrl* ctrl, void* userdata) +{ + LLPanelFace* self = (LLPanelFace*)userdata; + self->refreshMedia(); + LLFloaterReg::showInstance("media_settings"); +} + +////////////////////////////////////////////////////////////////////////////// +// called when a user wants to delete media from a prim or prim face +void LLPanelFace::onClickBtnDeleteMedia(LLUICtrl* ctrl, void* userdata) +{ + LLNotificationsUtil::add("DeleteMedia", LLSD(), LLSD(), deleteMediaConfirm); +} + +////////////////////////////////////////////////////////////////////////////// +// called when a user wants to add media to a prim or prim face +void LLPanelFace::onClickBtnAddMedia(LLUICtrl* ctrl, void* userdata) +{ + // check if multiple faces are selected + if (LLSelectMgr::getInstance()->getSelection()->isMultipleTESelected()) + { + LLPanelFace* self = (LLPanelFace*)userdata; + self->refreshMedia(); + LLNotificationsUtil::add("MultipleFacesSelected", LLSD(), LLSD(), multipleFacesSelectedConfirm); + } + else + { + onClickBtnEditMedia(ctrl, userdata); + } +} + +// static +bool LLPanelFace::deleteMediaConfirm(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + switch (option) + { + case 0: // "Yes" + LLSelectMgr::getInstance()->selectionSetMedia(0, LLSD()); + if (LLFloaterReg::instanceVisible("media_settings")) + { + LLFloaterReg::hideInstance("media_settings"); + } + break; + + case 1: // "No" + default: + break; + } + return false; +} + +// static +bool LLPanelFace::multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + switch (option) + { + case 0: // "Yes" + LLFloaterReg::showInstance("media_settings"); + break; + case 1: // "No" + default: + break; + } + return false; +} + //static void LLPanelFace::syncOffsetX(LLPanelFace* self, F32 offsetU) { @@ -2093,7 +2962,7 @@ void LLPanelFace::onCommitMaterialBumpyRot(LLUICtrl* ctrl, void* userdata) bool identical_face = false; LLSelectedTE::getFace(last_face, identical_face); LLPanelFaceSetAlignedTEFunctor setfunc(self, last_face); - LLSelectMgr::getInstanceFast()->getSelection()->applyToTEs(&setfunc); + LLSelectMgr::getInstance()->getSelection()->applyToTEs(&setfunc); } else { @@ -2121,7 +2990,7 @@ void LLPanelFace::onCommitMaterialShinyRot(LLUICtrl* ctrl, void* userdata) bool identical_face = false; LLSelectedTE::getFace(last_face, identical_face); LLPanelFaceSetAlignedTEFunctor setfunc(self, last_face); - LLSelectMgr::getInstanceFast()->getSelection()->applyToTEs(&setfunc); + LLSelectMgr::getInstance()->getSelection()->applyToTEs(&setfunc); } else { @@ -2277,7 +3146,7 @@ void LLPanelFace::onCommitRepeatsPerMeter(LLUICtrl* ctrl, void* userdata) if (gSavedSettings.getBOOL("SyncMaterialSettings")) { - LLSelectMgr::getInstanceFast()->selectionTexScaleAutofit( repeats_per_meter ); + LLSelectMgr::getInstance()->selectionTexScaleAutofit( repeats_per_meter ); bumpy_scale_u->setValue(obj_scale_s * repeats_per_meter); bumpy_scale_v->setValue(obj_scale_t * repeats_per_meter); @@ -2297,7 +3166,7 @@ void LLPanelFace::onCommitRepeatsPerMeter(LLUICtrl* ctrl, void* userdata) { case MATTYPE_DIFFUSE: { - LLSelectMgr::getInstanceFast()->selectionTexScaleAutofit( repeats_per_meter ); + LLSelectMgr::getInstance()->selectionTexScaleAutofit( repeats_per_meter ); } break; @@ -2340,13 +3209,13 @@ struct LLPanelFaceSetMediaFunctor : public LLSelectedTEFunctor const LLMediaEntry* mep = tep->hasMedia() ? tep->getMediaData() : NULL; if ( mep ) { - pMediaImpl = LLViewerMedia::getInstanceFast()->getMediaImplFromTextureID(mep->getMediaID()); + pMediaImpl = LLViewerMedia::getInstance()->getMediaImplFromTextureID(mep->getMediaID()); } if ( pMediaImpl.isNull()) { // If we didn't find face media for this face, check whether this face is showing parcel media. - pMediaImpl = LLViewerMedia::getInstanceFast()->getMediaImplFromTextureID(tep->getID()); + pMediaImpl = LLViewerMedia::getInstance()->getMediaImplFromTextureID(tep->getID()); } if ( pMediaImpl.notNull()) @@ -2375,10 +3244,10 @@ struct LLPanelFaceSetMediaFunctor : public LLSelectedTEFunctor void LLPanelFace::onClickAutoFix(void* userdata) { LLPanelFaceSetMediaFunctor setfunc; - LLSelectMgr::getInstanceFast()->getSelection()->applyToTEs(&setfunc); + LLSelectMgr::getInstance()->getSelection()->applyToTEs(&setfunc); LLPanelFaceSendFunctor sendfunc; - LLSelectMgr::getInstanceFast()->getSelection()->applyToObjects(&sendfunc); + LLSelectMgr::getInstance()->getSelection()->applyToObjects(&sendfunc); } void LLPanelFace::onAlignTexture(void* userdata) @@ -2387,15 +3256,811 @@ void LLPanelFace::onAlignTexture(void* userdata) self->alignTestureLayer(); } +enum EPasteMode +{ + PASTE_COLOR, + PASTE_TEXTURE +}; + +struct LLPanelFacePasteTexFunctor : public LLSelectedTEFunctor +{ + LLPanelFacePasteTexFunctor(LLPanelFace* panel, EPasteMode mode) : + mPanelFace(panel), mMode(mode) {} + + virtual bool apply(LLViewerObject* objectp, S32 te) + { + switch (mMode) + { + case PASTE_COLOR: + mPanelFace->onPasteColor(objectp, te); + break; + case PASTE_TEXTURE: + mPanelFace->onPasteTexture(objectp, te); + break; + } + return true; + } +private: + LLPanelFace *mPanelFace; + EPasteMode mMode; +}; -// TODO: I don't know who put these in or what these are for??? -void LLPanelFace::setMediaURL(const std::string& url) +struct LLPanelFaceUpdateFunctor : public LLSelectedObjectFunctor { + LLPanelFaceUpdateFunctor(bool update_media) : mUpdateMedia(update_media) {} + virtual bool apply(LLViewerObject* object) + { + object->sendTEUpdate(); + if (mUpdateMedia) + { + LLVOVolume *vo = dynamic_cast<LLVOVolume*>(object); + if (vo && vo->hasMedia()) + { + vo->sendMediaDataUpdate(); + } + } + return true; + } +private: + bool mUpdateMedia; +}; + +struct LLPanelFaceNavigateHomeFunctor : public LLSelectedTEFunctor +{ + virtual bool apply(LLViewerObject* objectp, S32 te) + { + if (objectp && objectp->getTE(te)) + { + LLTextureEntry* tep = objectp->getTE(te); + const LLMediaEntry *media_data = tep->getMediaData(); + if (media_data) + { + if (media_data->getCurrentURL().empty() && media_data->getAutoPlay()) + { + viewer_media_t media_impl = + LLViewerMedia::getInstance()->getMediaImplFromTextureID(tep->getMediaData()->getMediaID()); + if (media_impl) + { + media_impl->navigateHome(); + } + } + } + } + return true; + } +}; + +void LLPanelFace::onCopyColor() +{ + LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); + LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode(); + S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount(); + if (!objectp || !node + || objectp->getPCode() != LL_PCODE_VOLUME + || !objectp->permModify() + || objectp->isPermanentEnforced() + || selected_count > 1) + { + return; + } + + if (mClipboardParams.has("color")) + { + mClipboardParams["color"].clear(); + } + else + { + mClipboardParams["color"] = LLSD::emptyArray(); + } + + std::map<LLUUID, LLUUID> asset_item_map; + + // a way to resolve situations where source and target have different amount of faces + S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); + mClipboardParams["color_all_tes"] = (num_tes != 1) || (LLToolFace::getInstance() == LLToolMgr::getInstance()->getCurrentTool()); + for (S32 te = 0; te < num_tes; ++te) + { + if (node->isTESelected(te)) + { + LLTextureEntry* tep = objectp->getTE(te); + if (tep) + { + LLSD te_data; + + // asLLSD() includes media + te_data["te"] = tep->asLLSD(); // Note: includes a lot more than just color/alpha/glow + + mClipboardParams["color"].append(te_data); + } + } + } +} + +void LLPanelFace::onPasteColor() +{ + if (!mClipboardParams.has("color")) + { + return; + } + + LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); + LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode(); + S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount(); + if (!objectp || !node + || objectp->getPCode() != LL_PCODE_VOLUME + || !objectp->permModify() + || objectp->isPermanentEnforced() + || selected_count > 1) + { + // not supposed to happen + LL_WARNS() << "Failed to paste color due to missing or wrong selection" << LL_ENDL; + return; + } + + bool face_selection_mode = LLToolFace::getInstance() == LLToolMgr::getInstance()->getCurrentTool(); + LLSD &clipboard = mClipboardParams["color"]; // array + S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); + S32 compare_tes = num_tes; + + if (face_selection_mode) + { + compare_tes = 0; + for (S32 te = 0; te < num_tes; ++te) + { + if (node->isTESelected(te)) + { + compare_tes++; + } + } + } + + // we can copy if single face was copied in edit face mode or if face count matches + if (!((clipboard.size() == 1) && mClipboardParams["color_all_tes"].asBoolean()) + && compare_tes != clipboard.size()) + { + LLSD notif_args; + if (face_selection_mode) + { + static std::string reason = getString("paste_error_face_selection_mismatch"); + notif_args["REASON"] = reason; + } + else + { + static std::string reason = getString("paste_error_object_face_count_mismatch"); + notif_args["REASON"] = reason; + } + LLNotificationsUtil::add("FacePasteFailed", notif_args); + return; + } + + LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection(); + + LLPanelFacePasteTexFunctor paste_func(this, PASTE_COLOR); + selected_objects->applyToTEs(&paste_func); + + LLPanelFaceUpdateFunctor sendfunc(false); + selected_objects->applyToObjects(&sendfunc); +} + +void LLPanelFace::onPasteColor(LLViewerObject* objectp, S32 te) +{ + LLSD te_data; + LLSD &clipboard = mClipboardParams["color"]; // array + if ((clipboard.size() == 1) && mClipboardParams["color_all_tes"].asBoolean()) + { + te_data = *(clipboard.beginArray()); + } + else if (clipboard[te]) + { + te_data = clipboard[te]; + } + else + { + return; + } + + LLTextureEntry* tep = objectp->getTE(te); + if (tep) + { + if (te_data.has("te")) + { + // Color / Alpha + if (te_data["te"].has("colors")) + { + LLColor4 color = tep->getColor(); + + LLColor4 clip_color; + clip_color.setValue(te_data["te"]["colors"]); + + // Color + color.mV[VRED] = clip_color.mV[VRED]; + color.mV[VGREEN] = clip_color.mV[VGREEN]; + color.mV[VBLUE] = clip_color.mV[VBLUE]; + + // Alpha + color.mV[VALPHA] = clip_color.mV[VALPHA]; + + objectp->setTEColor(te, color); + } + + // Color/fullbright + if (te_data["te"].has("fullbright")) + { + objectp->setTEFullbright(te, te_data["te"]["fullbright"].asInteger()); + } + + // Glow + if (te_data["te"].has("glow")) + { + objectp->setTEGlow(te, (F32)te_data["te"]["glow"].asReal()); + } + } + } } -void LLPanelFace::setMediaType(const std::string& mime_type) + +void LLPanelFace::onCopyTexture() { + LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); + LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode(); + S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount(); + if (!objectp || !node + || objectp->getPCode() != LL_PCODE_VOLUME + || !objectp->permModify() + || objectp->isPermanentEnforced() + || selected_count > 1) + { + return; + } + + if (mClipboardParams.has("texture")) + { + mClipboardParams["texture"].clear(); + } + else + { + mClipboardParams["texture"] = LLSD::emptyArray(); + } + + std::map<LLUUID, LLUUID> asset_item_map; + + // a way to resolve situations where source and target have different amount of faces + S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); + mClipboardParams["texture_all_tes"] = (num_tes != 1) || (LLToolFace::getInstance() == LLToolMgr::getInstance()->getCurrentTool()); + for (S32 te = 0; te < num_tes; ++te) + { + if (node->isTESelected(te)) + { + LLTextureEntry* tep = objectp->getTE(te); + if (tep) + { + LLSD te_data; + + // asLLSD() includes media + te_data["te"] = tep->asLLSD(); + te_data["te"]["shiny"] = tep->getShiny(); + te_data["te"]["bumpmap"] = tep->getBumpmap(); + te_data["te"]["bumpshiny"] = tep->getBumpShiny(); + te_data["te"]["bumpfullbright"] = tep->getBumpShinyFullbright(); + + if (te_data["te"].has("imageid")) + { + LLUUID item_id; + LLUUID id = te_data["te"]["imageid"].asUUID(); + bool from_library = get_is_predefined_texture(id); + bool full_perm = from_library; + + if (!full_perm + && objectp->permCopy() + && objectp->permTransfer() + && objectp->permModify()) + { + // If agent created this object and nothing is limiting permissions, mark as full perm + // If agent was granted permission to edit objects owned and created by somebody else, mark full perm + // This check is not perfect since we can't figure out whom textures belong to so this ended up restrictive + std::string creator_app_link; + LLUUID creator_id; + LLSelectMgr::getInstance()->selectGetCreator(creator_id, creator_app_link); + full_perm = objectp->mOwnerID == creator_id; + } + + if (id.notNull() && !full_perm) + { + std::map<LLUUID, LLUUID>::iterator iter = asset_item_map.find(id); + if (iter != asset_item_map.end()) + { + item_id = iter->second; + } + else + { + // What this does is simply searches inventory for item with same asset id, + // as result it is Hightly unreliable, leaves little control to user, borderline hack + // but there are little options to preserve permissions - multiple inventory + // items might reference same asset and inventory search is expensive. + bool no_transfer = false; + if (objectp->getInventoryItemByAsset(id)) + { + no_transfer = !objectp->getInventoryItemByAsset(id)->getIsFullPerm(); + } + item_id = get_copy_free_item_by_asset_id(id, no_transfer); + // record value to avoid repeating inventory search when possible + asset_item_map[id] = item_id; + } + } + + if (item_id.notNull() && gInventory.isObjectDescendentOf(item_id, gInventory.getLibraryRootFolderID())) + { + full_perm = true; + from_library = true; + } + + { + te_data["te"]["itemfullperm"] = full_perm; + te_data["te"]["fromlibrary"] = from_library; + + // If full permission object, texture is free to copy, + // but otherwise we need to check inventory and extract permissions + // + // Normally we care only about restrictions for current user and objects + // don't inherit any 'next owner' permissions from texture, so there is + // no need to record item id if full_perm==true + if (!full_perm && !from_library && item_id.notNull()) + { + LLViewerInventoryItem* itemp = gInventory.getItem(item_id); + if (itemp) + { + LLPermissions item_permissions = itemp->getPermissions(); + if (item_permissions.allowOperationBy(PERM_COPY, + gAgent.getID(), + gAgent.getGroupID())) + { + te_data["te"]["imageitemid"] = item_id; + te_data["te"]["itemfullperm"] = itemp->getIsFullPerm(); + if (!itemp->isFinished()) + { + // needed for dropTextureAllFaces + LLInventoryModelBackgroundFetch::instance().start(item_id, false); + } + } + } + } + } + } + + LLMaterialPtr material_ptr = tep->getMaterialParams(); + if (!material_ptr.isNull()) + { + LLSD mat_data; + + mat_data["NormMap"] = material_ptr->getNormalID(); + mat_data["SpecMap"] = material_ptr->getSpecularID(); + + mat_data["NormRepX"] = material_ptr->getNormalRepeatX(); + mat_data["NormRepY"] = material_ptr->getNormalRepeatY(); + mat_data["NormOffX"] = material_ptr->getNormalOffsetX(); + mat_data["NormOffY"] = material_ptr->getNormalOffsetY(); + mat_data["NormRot"] = material_ptr->getNormalRotation(); + + mat_data["SpecRepX"] = material_ptr->getSpecularRepeatX(); + mat_data["SpecRepY"] = material_ptr->getSpecularRepeatY(); + mat_data["SpecOffX"] = material_ptr->getSpecularOffsetX(); + mat_data["SpecOffY"] = material_ptr->getSpecularOffsetY(); + mat_data["SpecRot"] = material_ptr->getSpecularRotation(); + + mat_data["SpecColor"] = material_ptr->getSpecularLightColor().getValue(); + mat_data["SpecExp"] = material_ptr->getSpecularLightExponent(); + mat_data["EnvIntensity"] = material_ptr->getEnvironmentIntensity(); + mat_data["AlphaMaskCutoff"] = material_ptr->getAlphaMaskCutoff(); + mat_data["DiffuseAlphaMode"] = material_ptr->getDiffuseAlphaMode(); + + // Replace no-copy textures, destination texture will get used instead if available + if (mat_data.has("NormMap")) + { + LLUUID id = mat_data["NormMap"].asUUID(); + if (id.notNull() && !get_can_copy_texture(id)) + { + mat_data["NormMap"] = LLUUID(gSavedSettings.getString("DefaultObjectTexture")); + mat_data["NormMapNoCopy"] = true; + } + + } + if (mat_data.has("SpecMap")) + { + LLUUID id = mat_data["SpecMap"].asUUID(); + if (id.notNull() && !get_can_copy_texture(id)) + { + mat_data["SpecMap"] = LLUUID(gSavedSettings.getString("DefaultObjectTexture")); + mat_data["SpecMapNoCopy"] = true; + } + + } + + te_data["material"] = mat_data; + } + + mClipboardParams["texture"].append(te_data); + } + } + } } +void LLPanelFace::onPasteTexture() +{ + if (!mClipboardParams.has("texture")) + { + return; + } + + LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); + LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode(); + S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount(); + if (!objectp || !node + || objectp->getPCode() != LL_PCODE_VOLUME + || !objectp->permModify() + || objectp->isPermanentEnforced() + || selected_count > 1) + { + // not supposed to happen + LL_WARNS() << "Failed to paste texture due to missing or wrong selection" << LL_ENDL; + return; + } + + bool face_selection_mode = LLToolFace::getInstance() == LLToolMgr::getInstance()->getCurrentTool(); + LLSD &clipboard = mClipboardParams["texture"]; // array + S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); + S32 compare_tes = num_tes; + + if (face_selection_mode) + { + compare_tes = 0; + for (S32 te = 0; te < num_tes; ++te) + { + if (node->isTESelected(te)) + { + compare_tes++; + } + } + } + + // we can copy if single face was copied in edit face mode or if face count matches + if (!((clipboard.size() == 1) && mClipboardParams["texture_all_tes"].asBoolean()) + && compare_tes != clipboard.size()) + { + LLSD notif_args; + if (face_selection_mode) + { + static std::string reason = getString("paste_error_face_selection_mismatch"); + notif_args["REASON"] = reason; + } + else + { + static std::string reason = getString("paste_error_object_face_count_mismatch"); + notif_args["REASON"] = reason; + } + LLNotificationsUtil::add("FacePasteFailed", notif_args); + return; + } + + bool full_perm_object = true; + LLSD::array_const_iterator iter = clipboard.beginArray(); + LLSD::array_const_iterator end = clipboard.endArray(); + for (; iter != end; ++iter) + { + const LLSD& te_data = *iter; + if (te_data.has("te") && te_data["te"].has("imageid")) + { + bool full_perm = te_data["te"].has("itemfullperm") && te_data["te"]["itemfullperm"].asBoolean(); + full_perm_object &= full_perm; + if (!full_perm) + { + if (te_data["te"].has("imageitemid")) + { + LLUUID item_id = te_data["te"]["imageitemid"].asUUID(); + if (item_id.notNull()) + { + LLViewerInventoryItem* itemp = gInventory.getItem(item_id); + if (!itemp) + { + // image might be in object's inventory, but it can be not up to date + LLSD notif_args; + static std::string reason = getString("paste_error_inventory_not_found"); + notif_args["REASON"] = reason; + LLNotificationsUtil::add("FacePasteFailed", notif_args); + return; + } + } + } + else + { + // Item was not found on 'copy' stage + // Since this happened at copy, might be better to either show this + // at copy stage or to drop clipboard here + LLSD notif_args; + static std::string reason = getString("paste_error_inventory_not_found"); + notif_args["REASON"] = reason; + LLNotificationsUtil::add("FacePasteFailed", notif_args); + return; + } + } + } + } + + if (!full_perm_object) + { + LLNotificationsUtil::add("FacePasteTexturePermissions"); + } + + LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection(); + + LLPanelFacePasteTexFunctor paste_func(this, PASTE_TEXTURE); + selected_objects->applyToTEs(&paste_func); + + LLPanelFaceUpdateFunctor sendfunc(true); + selected_objects->applyToObjects(&sendfunc); + + LLPanelFaceNavigateHomeFunctor navigate_home_func; + selected_objects->applyToTEs(&navigate_home_func); +} + +void LLPanelFace::onPasteTexture(LLViewerObject* objectp, S32 te) +{ + LLSD te_data; + LLSD &clipboard = mClipboardParams["texture"]; // array + if ((clipboard.size() == 1) && mClipboardParams["texture_all_tes"].asBoolean()) + { + te_data = *(clipboard.beginArray()); + } + else if (clipboard[te]) + { + te_data = clipboard[te]; + } + else + { + return; + } + + LLTextureEntry* tep = objectp->getTE(te); + if (tep) + { + if (te_data.has("te")) + { + // Texture + bool full_perm = te_data["te"].has("itemfullperm") && te_data["te"]["itemfullperm"].asBoolean(); + bool from_library = te_data["te"].has("fromlibrary") && te_data["te"]["fromlibrary"].asBoolean(); + if (te_data["te"].has("imageid")) + { + const LLUUID& imageid = te_data["te"]["imageid"].asUUID(); //texture or asset id + LLViewerInventoryItem* itemp_res = NULL; + + if (te_data["te"].has("imageitemid")) + { + LLUUID item_id = te_data["te"]["imageitemid"].asUUID(); + if (item_id.notNull()) + { + LLViewerInventoryItem* itemp = gInventory.getItem(item_id); + if (itemp && itemp->isFinished()) + { + // dropTextureAllFaces will fail if incomplete + itemp_res = itemp; + } + else + { + // Theoretically shouldn't happend, but if it does happen, we + // might need to add a notification to user that paste will fail + // since inventory isn't fully loaded + LL_WARNS() << "Item " << item_id << " is incomplete, paste might fail silently." << LL_ENDL; + } + } + } + // for case when item got removed from inventory after we pressed 'copy' + // or texture got pasted into previous object + if (!itemp_res && !full_perm) + { + // Due to checks for imageitemid in LLPanelFace::onPasteTexture() this should no longer be reachable. + LL_INFOS() << "Item " << te_data["te"]["imageitemid"].asUUID() << " no longer in inventory." << LL_ENDL; + // Todo: fix this, we are often searching same texture multiple times (equal to number of faces) + // Perhaps just mPanelFace->onPasteTexture(objectp, te, &asset_to_item_id_map); ? Not pretty, but will work + LLViewerInventoryCategory::cat_array_t cats; + LLViewerInventoryItem::item_array_t items; + LLAssetIDMatches asset_id_matches(imageid); + gInventory.collectDescendentsIf(LLUUID::null, + cats, + items, + LLInventoryModel::INCLUDE_TRASH, + asset_id_matches); + + // Extremely unreliable and perfomance unfriendly. + // But we need this to check permissions and it is how texture control finds items + for (S32 i = 0; i < items.size(); i++) + { + LLViewerInventoryItem* itemp = items[i]; + if (itemp && itemp->isFinished()) + { + // dropTextureAllFaces will fail if incomplete + LLPermissions item_permissions = itemp->getPermissions(); + if (item_permissions.allowOperationBy(PERM_COPY, + gAgent.getID(), + gAgent.getGroupID())) + { + itemp_res = itemp; + break; // first match + } + } + } + } + + if (itemp_res) + { + if (te == -1) // all faces + { + LLToolDragAndDrop::dropTextureAllFaces(objectp, + itemp_res, + from_library ? LLToolDragAndDrop::SOURCE_LIBRARY : LLToolDragAndDrop::SOURCE_AGENT, + LLUUID::null); + } + else // one face + { + LLToolDragAndDrop::dropTextureOneFace(objectp, + te, + itemp_res, + from_library ? LLToolDragAndDrop::SOURCE_LIBRARY : LLToolDragAndDrop::SOURCE_AGENT, + LLUUID::null, + 0); + } + } + // not an inventory item or no complete items + else if (full_perm) + { + // Either library, local or existed as fullperm when user made a copy + LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(imageid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + objectp->setTEImage(U8(te), image); + } + } + + if (te_data["te"].has("bumpmap")) + { + objectp->setTEBumpmap(te, (U8)te_data["te"]["bumpmap"].asInteger()); + } + if (te_data["te"].has("bumpshiny")) + { + objectp->setTEBumpShiny(te, (U8)te_data["te"]["bumpshiny"].asInteger()); + } + if (te_data["te"].has("bumpfullbright")) + { + objectp->setTEBumpShinyFullbright(te, (U8)te_data["te"]["bumpfullbright"].asInteger()); + } + + // Texture map + if (te_data["te"].has("scales") && te_data["te"].has("scalet")) + { + objectp->setTEScale(te, (F32)te_data["te"]["scales"].asReal(), (F32)te_data["te"]["scalet"].asReal()); + } + if (te_data["te"].has("offsets") && te_data["te"].has("offsett")) + { + objectp->setTEOffset(te, (F32)te_data["te"]["offsets"].asReal(), (F32)te_data["te"]["offsett"].asReal()); + } + if (te_data["te"].has("imagerot")) + { + objectp->setTERotation(te, (F32)te_data["te"]["imagerot"].asReal()); + } + + // Media + if (te_data["te"].has("media_flags")) + { + U8 media_flags = te_data["te"]["media_flags"].asInteger(); + objectp->setTEMediaFlags(te, media_flags); + LLVOVolume *vo = dynamic_cast<LLVOVolume*>(objectp); + if (vo && te_data["te"].has(LLTextureEntry::TEXTURE_MEDIA_DATA_KEY)) + { + vo->syncMediaData(te, te_data["te"][LLTextureEntry::TEXTURE_MEDIA_DATA_KEY], true/*merge*/, true/*ignore_agent*/); + } + } + else + { + // Keep media flags on destination unchanged + } + } + + if (te_data.has("material")) + { + LLUUID object_id = objectp->getID(); + + LLSelectedTEMaterial::setAlphaMaskCutoff(this, (U8)te_data["material"]["SpecRot"].asInteger(), te, object_id); + + // Normal + // Replace placeholders with target's + if (te_data["material"].has("NormMapNoCopy")) + { + LLMaterialPtr material = tep->getMaterialParams(); + if (material.notNull()) + { + LLUUID id = material->getNormalID(); + if (id.notNull()) + { + te_data["material"]["NormMap"] = id; + } + } + } + LLSelectedTEMaterial::setNormalID(this, te_data["material"]["NormMap"].asUUID(), te, object_id); + LLSelectedTEMaterial::setNormalRepeatX(this, (F32)te_data["material"]["NormRepX"].asReal(), te, object_id); + LLSelectedTEMaterial::setNormalRepeatY(this, (F32)te_data["material"]["NormRepY"].asReal(), te, object_id); + LLSelectedTEMaterial::setNormalOffsetX(this, (F32)te_data["material"]["NormOffX"].asReal(), te, object_id); + LLSelectedTEMaterial::setNormalOffsetY(this, (F32)te_data["material"]["NormOffY"].asReal(), te, object_id); + LLSelectedTEMaterial::setNormalRotation(this, (F32)te_data["material"]["NormRot"].asReal(), te, object_id); + + // Specular + // Replace placeholders with target's + if (te_data["material"].has("SpecMapNoCopy")) + { + LLMaterialPtr material = tep->getMaterialParams(); + if (material.notNull()) + { + LLUUID id = material->getSpecularID(); + if (id.notNull()) + { + te_data["material"]["SpecMap"] = id; + } + } + } + LLSelectedTEMaterial::setSpecularID(this, te_data["material"]["SpecMap"].asUUID(), te, object_id); + LLSelectedTEMaterial::setSpecularRepeatX(this, (F32)te_data["material"]["SpecRepX"].asReal(), te, object_id); + LLSelectedTEMaterial::setSpecularRepeatY(this, (F32)te_data["material"]["SpecRepY"].asReal(), te, object_id); + LLSelectedTEMaterial::setSpecularOffsetX(this, (F32)te_data["material"]["SpecOffX"].asReal(), te, object_id); + LLSelectedTEMaterial::setSpecularOffsetY(this, (F32)te_data["material"]["SpecOffY"].asReal(), te, object_id); + LLSelectedTEMaterial::setSpecularRotation(this, (F32)te_data["material"]["SpecRot"].asReal(), te, object_id); + LLColor4 spec_color(te_data["material"]["SpecColor"]); + LLSelectedTEMaterial::setSpecularLightColor(this, spec_color, te); + LLSelectedTEMaterial::setSpecularLightExponent(this, (U8)te_data["material"]["SpecExp"].asInteger(), te, object_id); + LLSelectedTEMaterial::setEnvironmentIntensity(this, (U8)te_data["material"]["EnvIntensity"].asInteger(), te, object_id); + LLSelectedTEMaterial::setDiffuseAlphaMode(this, (U8)te_data["material"]["SpecRot"].asInteger(), te, object_id); + if (te_data.has("te") && te_data["te"].has("shiny")) + { + objectp->setTEShiny(te, (U8)te_data["te"]["shiny"].asInteger()); + } + } + } +} + +void LLPanelFace::menuDoToSelected(const LLSD& userdata) +{ + std::string command = userdata.asString(); + + // paste + if (command == "color_paste") + { + onPasteColor(); + } + else if (command == "texture_paste") + { + onPasteTexture(); + } + // copy + else if (command == "color_copy") + { + onCopyColor(); + } + else if (command == "texture_copy") + { + onCopyTexture(); + } +} + +bool LLPanelFace::menuEnableItem(const LLSD& userdata) +{ + std::string command = userdata.asString(); + + // paste options + if (command == "color_paste") + { + return mClipboardParams.has("color"); + } + else if (command == "texture_paste") + { + return mClipboardParams.has("texture"); + } + return false; +} + + // static void LLPanelFace::onCommitPlanarAlign(LLUICtrl* ctrl, void* userdata) { @@ -2430,10 +4095,10 @@ void LLPanelFace::onTextureSelectionChanged(LLInventoryItem* itemp) { LLUUID obj_owner_id; std::string obj_owner_name; - LLSelectMgr::instanceFast().selectGetOwner(obj_owner_id, obj_owner_name); + LLSelectMgr::instance().selectGetOwner(obj_owner_id, obj_owner_name); LLSaleInfo sale_info; - LLSelectMgr::instanceFast().selectGetSaleInfo(sale_info); + LLSelectMgr::instance().selectGetSaleInfo(sale_info); bool can_copy = itemp->getPermissions().allowCopyBy(gAgentID); // do we have perm to copy this texture? bool can_transfer = itemp->getPermissions().allowOperationBy(PERM_TRANSFER, gAgentID); // do we have perm to transfer this texture? @@ -2473,7 +4138,7 @@ void LLPanelFace::LLSelectedTE::getFace(LLFace*& face_to_return, bool& identical return (object->mDrawable) ? object->mDrawable->getFace(te): NULL; } } get_te_face_func; - identical_face = LLSelectMgr::getInstanceFast()->getSelection()->getSelectedTEValue(&get_te_face_func, face_to_return, false, (LLFace*)nullptr); + identical_face = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&get_te_face_func, face_to_return, false, (LLFace*)nullptr); } void LLPanelFace::LLSelectedTE::getImageFormat(LLGLenum& image_format_to_return, bool& identical_face) @@ -2487,7 +4152,7 @@ void LLPanelFace::LLSelectedTE::getImageFormat(LLGLenum& image_format_to_return, return image ? image->getPrimaryFormat() : GL_RGB; } } get_glenum; - identical_face = LLSelectMgr::getInstanceFast()->getSelection()->getSelectedTEValue(&get_glenum, image_format); + identical_face = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&get_glenum, image_format); image_format_to_return = image_format; } @@ -2514,7 +4179,7 @@ void LLPanelFace::LLSelectedTE::getTexId(LLUUID& id, bool& identical) id = image->getID(); } - if (!id.isNull() && LLViewerMedia::getInstanceFast()->textureHasMedia(id)) + if (!id.isNull() && LLViewerMedia::getInstance()->textureHasMedia(id)) { if (te) { @@ -2532,7 +4197,7 @@ void LLPanelFace::LLSelectedTE::getTexId(LLUUID& id, bool& identical) return id; } } func; - identical = LLSelectMgr::getInstanceFast()->getSelection()->getSelectedTEValue( &func, id ); + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, id ); } void LLPanelFace::LLSelectedTEMaterial::getCurrent(LLMaterialPtr& material_ptr, bool& identical_material) @@ -2544,7 +4209,7 @@ void LLPanelFace::LLSelectedTEMaterial::getCurrent(LLMaterialPtr& material_ptr, return object->getTE(te_index)->getMaterialParams(); } } func; - identical_material = LLSelectMgr::getInstanceFast()->getSelection()->getSelectedTEValue( &func, material_ptr); + identical_material = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, material_ptr); } void LLPanelFace::LLSelectedTEMaterial::getMaxSpecularRepeats(F32& repeats, bool& identical) @@ -2568,7 +4233,7 @@ void LLPanelFace::LLSelectedTEMaterial::getMaxSpecularRepeats(F32& repeats, bool } } max_spec_repeats_func; - identical = LLSelectMgr::getInstanceFast()->getSelection()->getSelectedTEValue( &max_spec_repeats_func, repeats); + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &max_spec_repeats_func, repeats); } void LLPanelFace::LLSelectedTEMaterial::getMaxNormalRepeats(F32& repeats, bool& identical) @@ -2592,7 +4257,7 @@ void LLPanelFace::LLSelectedTEMaterial::getMaxNormalRepeats(F32& repeats, bool& } } max_norm_repeats_func; - identical = LLSelectMgr::getInstanceFast()->getSelection()->getSelectedTEValue( &max_norm_repeats_func, repeats); + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &max_norm_repeats_func, repeats); } void LLPanelFace::LLSelectedTEMaterial::getCurrentDiffuseAlphaMode(U8& diffuse_alpha_mode, bool& identical, bool diffuse_texture_has_alpha) @@ -2621,7 +4286,7 @@ void LLPanelFace::LLSelectedTEMaterial::getCurrentDiffuseAlphaMode(U8& diffuse_a } bool _isAlpha; // whether or not the diffuse texture selected contains alpha information } get_diff_mode(diffuse_texture_has_alpha); - identical = LLSelectMgr::getInstanceFast()->getSelection()->getSelectedTEValue( &get_diff_mode, diffuse_alpha_mode); + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &get_diff_mode, diffuse_alpha_mode); } void LLPanelFace::LLSelectedTE::getObjectScaleS(F32& scale_s, bool& identical) @@ -2637,7 +4302,7 @@ void LLPanelFace::LLSelectedTE::getObjectScaleS(F32& scale_s, bool& identical) } } scale_s_func; - identical = LLSelectMgr::getInstanceFast()->getSelection()->getSelectedTEValue( &scale_s_func, scale_s ); + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &scale_s_func, scale_s ); } void LLPanelFace::LLSelectedTE::getObjectScaleT(F32& scale_t, bool& identical) @@ -2653,7 +4318,7 @@ void LLPanelFace::LLSelectedTE::getObjectScaleT(F32& scale_t, bool& identical) } } scale_t_func; - identical = LLSelectMgr::getInstanceFast()->getSelection()->getSelectedTEValue( &scale_t_func, scale_t ); + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &scale_t_func, scale_t ); } void LLPanelFace::LLSelectedTE::getMaxDiffuseRepeats(F32& repeats, bool& identical) @@ -2671,5 +4336,5 @@ void LLPanelFace::LLSelectedTE::getMaxDiffuseRepeats(F32& repeats, bool& identic } } max_diff_repeats_func; - identical = LLSelectMgr::getInstanceFast()->getSelection()->getSelectedTEValue( &max_diff_repeats_func, repeats ); + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &max_diff_repeats_func, repeats ); } diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h index 43cc115dd6759e112157c620cd110211c3d1b9f1..e83ce32d3dbbbd92599fcff537f8f8a4a55fdb11 100644 --- a/indra/newview/llpanelface.h +++ b/indra/newview/llpanelface.h @@ -47,6 +47,8 @@ class LLUICtrl; class LLViewerObject; class LLFloater; class LLMaterialID; +class LLMediaCtrl; +class LLMenuButton; class LLRadioGroup; // Represents an edit for use in replicating the op across one or more materials in the selection set. @@ -98,8 +100,10 @@ class LLPanelFace : public LLPanel virtual ~LLPanelFace(); void refresh(); - void setMediaURL(const std::string& url); - void setMediaType(const std::string& mime_type); + void refreshMedia(); + void unloadMedia(); + + /*virtual*/ void draw(); LLMaterialPtr createDefaultMaterial(LLMaterialPtr current_material) { @@ -115,6 +119,12 @@ class LLPanelFace : public LLPanel LLRender::eTexIndex getTextureChannelToEdit(); protected: + void navigateToTitleMedia(const std::string url); + bool selectedMediaEditable(); + void clearMediaSettings(); + void updateMediaSettings(); + void updateMediaTitle(); + void getState(); void sendTexture(); // applies and sends texture @@ -129,6 +139,8 @@ class LLPanelFace : public LLPanel void sendMedia(); void alignTestureLayer(); + void updateCopyTexButton(); + // this function is to return TRUE if the drag should succeed. static BOOL onDragTexture(LLUICtrl* ctrl, LLInventoryItem* item); @@ -151,6 +163,9 @@ class LLPanelFace : public LLPanel void onCloseTexturePicker(const LLSD& data); + static bool deleteMediaConfirm(const LLSD& notification, const LLSD& response); + static bool multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response); + // Make UI reflect state of currently selected material (refresh) // and UI mode (e.g. editing normal map v diffuse map) // @@ -195,6 +210,9 @@ class LLPanelFace : public LLPanel static void onCommitMaterialsMedia( LLUICtrl* ctrl, void* userdata); static void onCommitMaterialType( LLUICtrl* ctrl, void* userdata); + static void onClickBtnEditMedia(LLUICtrl* ctrl, void* userdata); + static void onClickBtnDeleteMedia(LLUICtrl* ctrl, void* userdata); + static void onClickBtnAddMedia(LLUICtrl* ctrl, void* userdata); static void onCommitBump( LLUICtrl* ctrl, void* userdata); static void onCommitTexGen( LLUICtrl* ctrl, void* userdata); static void onCommitShiny( LLUICtrl* ctrl, void* userdata); @@ -206,6 +224,18 @@ class LLPanelFace : public LLPanel static void onClickAutoFix(void*); static void onAlignTexture(void*); +public: // needs to be accessible to selection manager + void onCopyColor(); // records all selected faces + void onPasteColor(); // to specific face + void onPasteColor(LLViewerObject* objectp, S32 te); // to specific face + void onCopyTexture(); + void onPasteTexture(); + void onPasteTexture(LLViewerObject* objectp, S32 te); + +protected: + void menuDoToSelected(const LLSD& userdata); + bool menuEnableItem(const LLSD& userdata); + static F32 valueGlow(LLViewerObject* object, S32 face); public: @@ -216,7 +246,6 @@ class LLPanelFace : public LLPanel LLColorSwatchCtrl* mShinyColorSwatch = nullptr; LLComboBox* mComboTexGen = nullptr; - LLComboBox* mComboMatMedia = nullptr; LLComboBox* mComboBumpiness = nullptr; LLComboBox* mComboShininess = nullptr; LLComboBox* mComboAlphaMode = nullptr; @@ -259,6 +288,10 @@ class LLPanelFace : public LLPanel F32 getCurrentShinyOffsetU(); F32 getCurrentShinyOffsetV(); + LLComboBox *mComboMatMedia; + LLMediaCtrl *mTitleMedia; + LLTextBox *mTitleMediaText; + // Update visibility of controls to match current UI mode // (e.g. materials vs media editing) // @@ -266,10 +299,6 @@ class LLPanelFace : public LLPanel // void updateVisibility(); - // Make material(s) reflect current state of UI (apply edit) - // - void updateMaterial(); - // Hey look everyone, a type-safe alternative to copy and paste! :) // @@ -355,7 +384,7 @@ class LLPanelFace : public LLPanel LLPanelFace *_panel; const LLUUID & _only_for_object_id; } editor(p, &edit, only_for_object_id); - LLSelectMgr::getInstanceFast()->selectionSetMaterialParams(&editor, te); + LLSelectMgr::getInstance()->selectionSetMaterialParams(&editor, te); } template< @@ -387,7 +416,7 @@ class LLPanelFace : public LLPanel } DataType _default; } GetFunc(default_value); - identical = LLSelectMgr::getInstanceFast()->getSelection()->getSelectedTEValue( &GetFunc, data_value, has_tolerance, tolerance); + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &GetFunc, data_value, has_tolerance, tolerance); data_to_return = data_value; } @@ -409,7 +438,7 @@ class LLPanelFace : public LLPanel } DataType _default; } GetTEValFunc(default_value); - identical = LLSelectMgr::getInstanceFast()->getSelection()->getSelectedTEValue( &GetTEValFunc, data_value, has_tolerance, tolerance ); + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &GetTEValFunc, data_value, has_tolerance, tolerance ); data_to_return = data_value; } @@ -425,7 +454,10 @@ class LLPanelFace : public LLPanel * If agent selects texture which is not allowed to be applied for the currently selected object, * all controls of the floater texture picker which allow to apply the texture will be disabled. */ - void onTextureSelectionChanged(LLInventoryItem* itemp); + void onTextureSelectionChanged(LLInventoryItem* itemp); + + LLMenuButton* mMenuClipboardColor; + LLMenuButton* mMenuClipboardTexture; bool mIsAlpha; @@ -440,7 +472,12 @@ class LLPanelFace : public LLPanel * up-arrow on a spinner, and avoids running afoul of its throttle. */ bool mUpdateInFlight; - bool mUpdatePending; + bool mUpdatePending; + + LLSD mClipboardParams; + + LLSD mMediaSettings; + bool mNeedMediaTitle; public: #if defined(DEF_GET_MAT_STATE) diff --git a/indra/newview/llpanelgroupcreate.cpp b/indra/newview/llpanelgroupcreate.cpp index 06c9424160c2b64c0ad1a723318c049a00ceb1a4..2a262fc6efb52819dfc467db4cf0978812d609df 100644 --- a/indra/newview/llpanelgroupcreate.cpp +++ b/indra/newview/llpanelgroupcreate.cpp @@ -106,7 +106,7 @@ void LLPanelGroupCreate::onOpen(const LLSD& key) // populate list addMembershipRow("Base"); addMembershipRow("Premium"); - addMembershipRow("Premium Plus"); + addMembershipRow("Premium_Plus"); addMembershipRow("Internal");// Present only if you are already in one, needed for testing S32 cost = LLAgentBenefitsMgr::current().getCreateGroupCost(); diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp index 2272f4c1d8d260e95eeeb4b16f47700f35c603ed..696d28f8959177c9811c1cebc5bf74cefd00a9af 100644 --- a/indra/newview/llpanelgroupgeneral.cpp +++ b/indra/newview/llpanelgroupgeneral.cpp @@ -100,6 +100,7 @@ BOOL LLPanelGroupGeneral::postBuild() mEditCharter->setCommitCallback(onCommitAny, this); mEditCharter->setFocusReceivedCallback(boost::bind(onFocusEdit, _1, this)); mEditCharter->setFocusChangedCallback(boost::bind(onFocusEdit, _1, this)); + mEditCharter->setContentTrusted(false); } // Options @@ -648,7 +649,8 @@ void LLPanelGroupGeneral::update(LLGroupChange gc) if (mEditCharter) { - mEditCharter->setText(gdatap->mCharter); + mEditCharter->setParseURLs(!mAllowEdit || !can_change_ident); + mEditCharter->setText(gdatap->mCharter); } resetDirty(); diff --git a/indra/newview/llpanellandaudio.cpp b/indra/newview/llpanellandaudio.cpp index e7bdc51b4a56597068511cd89d1b66c4b93ed4a0..9e3fc544773ab2c27285b870b4f18072c8b14318 100644 --- a/indra/newview/llpanellandaudio.cpp +++ b/indra/newview/llpanellandaudio.cpp @@ -97,6 +97,9 @@ BOOL LLPanelLandAudio::postBuild() mCheckAVSoundGroup = getChild<LLCheckBoxCtrl>("group av sound check"); childSetCommitCallback("group av sound check", onCommitAny, this); + mCheckObscureMOAP = getChild<LLCheckBoxCtrl>("obscure_moap"); + childSetCommitCallback("obscure_moap", onCommitAny, this); + return TRUE; } @@ -157,6 +160,9 @@ void LLPanelLandAudio::refresh() mCheckAVSoundGroup->set(parcel->getAllowGroupAVSounds() || parcel->getAllowAnyAVSounds()); // On if "Everyone" is on mCheckAVSoundGroup->setEnabled(can_change_av_sounds && !parcel->getAllowAnyAVSounds()); // Enabled if "Everyone" is off + + mCheckObscureMOAP->set(parcel->getObscureMOAP()); + mCheckObscureMOAP->setEnabled(can_change_media); } } // static @@ -184,6 +190,8 @@ void LLPanelLandAudio::onCommitAny(LLUICtrl*, void *userdata) group_av_sound = self->mCheckAVSoundGroup->get(); } + bool obscure_moap = self->mCheckObscureMOAP->get(); + // Remove leading/trailing whitespace (common when copying/pasting) LLStringUtil::trim(music_url); @@ -194,6 +202,7 @@ void LLPanelLandAudio::onCommitAny(LLUICtrl*, void *userdata) parcel->setMusicURL(music_url); parcel->setAllowAnyAVSounds(any_av_sound); parcel->setAllowGroupAVSounds(group_av_sound); + parcel->setObscureMOAP(obscure_moap); // Send current parcel data upstream to server LLViewerParcelMgr::getInstance()->sendParcelPropertiesUpdate( parcel ); diff --git a/indra/newview/llpanellandaudio.h b/indra/newview/llpanellandaudio.h index 7e4fce80e412e38a86585abad2513e44742dde25..b54fe62179a9f294af384e0daa3c5a02e9926f07 100644 --- a/indra/newview/llpanellandaudio.h +++ b/indra/newview/llpanellandaudio.h @@ -53,6 +53,7 @@ class LLPanelLandAudio LLLineEditor* mMusicURLEdit; LLCheckBoxCtrl* mCheckAVSoundAny; LLCheckBoxCtrl* mCheckAVSoundGroup; + LLCheckBoxCtrl* mCheckObscureMOAP; LLSafeHandle<LLParcelSelection>& mParcel; }; diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp index d9b467941a108edb4837dd2576d9f30aa05f4fb1..23565345330251177902c4565b6f89c3eeb8bbed 100644 --- a/indra/newview/llpanellandmarks.cpp +++ b/indra/newview/llpanellandmarks.cpp @@ -29,6 +29,7 @@ #include "llpanellandmarks.h" #include "llbutton.h" +#include "llfloaterprofile.h" #include "llfloaterreg.h" #include "llnotificationsutil.h" #include "llsdutil.h" @@ -1027,17 +1028,6 @@ bool LLLandmarksPanel::canItemBeModified(const std::string& command_name, LLFold return can_be_modified; } -void LLLandmarksPanel::onPickPanelExit( LLPanelPickEdit* pick_panel, LLView* owner, const LLSD& params) -{ - pick_panel->setVisible(FALSE); - owner->removeChild(pick_panel); - //we need remove observer to avoid processParcelInfo in the future. - LLRemoteParcelInfoProcessor::getInstance()->removeObserver(params["parcel_id"].asUUID(), this); - - delete pick_panel; - pick_panel = NULL; -} - bool LLLandmarksPanel::handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, void* cargo_data , EAcceptance* accept) { *accept = ACCEPT_NO; @@ -1104,49 +1094,21 @@ void LLLandmarksPanel::doProcessParcelInfo(LLLandmark* landmark, LLInventoryItem* inv_item, const LLParcelData& parcel_data) { - LLPanelPickEdit* panel_pick = LLPanelPickEdit::create(); LLVector3d landmark_global_pos; landmark->getGlobalPos(landmark_global_pos); - // let's toggle pick panel into panel places - LLPanel* panel_places = NULL; - LLFloaterSidePanelContainer* floaterp = LLFloaterReg::getTypedInstance<LLFloaterSidePanelContainer>("places"); - if (floaterp) - { - panel_places = floaterp->findChild<LLPanel>("main_panel"); - } - - if (!panel_places) - { - llassert(NULL != panel_places); - return; - } - panel_places->addChild(panel_pick); - LLRect paren_rect(panel_places->getRect()); - panel_pick->reshape(paren_rect.getWidth(),paren_rect.getHeight(), TRUE); - panel_pick->setRect(paren_rect); - panel_pick->onOpen(LLSD()); - LLPickData data; data.pos_global = landmark_global_pos; data.name = inv_item->getName(); data.desc = inv_item->getDescription(); data.snapshot_id = parcel_data.snapshot_id; data.parcel_id = parcel_data.parcel_id; - panel_pick->setPickData(&data); - - LLSD params; - params["parcel_id"] = parcel_data.parcel_id; - /* set exit callback to get back onto panel places - in callback we will make cleaning up( delete pick_panel instance, - remove landmark panel from observer list - */ - panel_pick->setExitCallback(boost::bind(&LLLandmarksPanel::onPickPanelExit,this, - panel_pick, panel_places,params)); - panel_pick->setSaveCallback(boost::bind(&LLLandmarksPanel::onPickPanelExit,this, - panel_pick, panel_places,params)); - panel_pick->setCancelCallback(boost::bind(&LLLandmarksPanel::onPickPanelExit,this, - panel_pick, panel_places,params)); + + LLFloaterProfile* profile_floater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", gAgentID))); + if (profile_floater) + { + profile_floater->createPick(data); + } } void LLLandmarksPanel::doCreatePick(LLLandmark* landmark, const LLUUID &item_id) diff --git a/indra/newview/llpanellandmarks.h b/indra/newview/llpanellandmarks.h index d7408269b5dfb6728dfb928bbb058e26da9031e8..16f3a5dc243033796bcb59be60c2e4d93d40dd75 100644 --- a/indra/newview/llpanellandmarks.h +++ b/indra/newview/llpanellandmarks.h @@ -34,7 +34,6 @@ #include "llinventorymodel.h" #include "lllandmarklist.h" #include "llpanelplacestab.h" -#include "llpanelpick.h" #include "llremoteparcelrequest.h" class LLAccordionCtrlTab; @@ -136,7 +135,6 @@ class LLLandmarksPanel : public LLPanelPlacesTab, LLRemoteParcelInfoObserver * For now it checks cut/rename/delete/paste actions. */ bool canItemBeModified(const std::string& command_name, LLFolderViewItem* item) const; - void onPickPanelExit( LLPanelPickEdit* pick_panel, LLView* owner, const LLSD& params); /** * Landmark actions callbacks. Fire when a landmark is loaded from the list. diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index 9510dee6bf425c539a60021f8c014113591e4899..4a151edd05d1985cb0048e8e47a39c4a0c4f34b5 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -90,44 +90,6 @@ LLPointer<LLCredential> load_user_credentials(std::string &user_key) } } -// keys are lower case to be case insensitive so they are not always -// identical to names which retain user input, like: -// "AwEsOmE Resident" -> "awesome_resident" -std::string get_user_key_from_name(const std::string &username) -{ - std::string key = username; - LLStringUtil::trim(key); - LLStringUtil::toLower(key); - if (!LLGridManager::getInstance()->isInSecondlife()) - { - size_t separator_index = username.find_first_of(" "); - if (separator_index == username.npos) - { - // CRED_IDENTIFIER_TYPE_ACCOUNT - return key; - } - } - // CRED_IDENTIFIER_TYPE_AGENT - size_t separator_index = username.find_first_of(" ._"); - std::string first = username.substr(0, separator_index); - std::string last; - if (separator_index != username.npos) - { - last = username.substr(separator_index + 1, username.npos); - LLStringUtil::trim(last); - } - else - { - // ...on Linden grids, single username users as considered to have - // last name "Resident" - // *TODO: Make login.cgi support "account_name" like above - last = "resident"; - } - - key = first + "_" + last; - return key; -} - class LLLoginLocationAutoHandler : public LLCommandHandler { public: @@ -324,10 +286,10 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, username_combo->setReturnCallback(boost::bind(&LLPanelLogin::onClickConnect, this)); username_combo->setKeystrokeOnEsc(TRUE); - { - LLCheckBoxCtrl* remember_name = getChild<LLCheckBoxCtrl>("remember_name"); - remember_name->setCommitCallback(boost::bind(&LLPanelLogin::onRememberUserCheck, this)); - } + + LLCheckBoxCtrl* remember_name = getChild<LLCheckBoxCtrl>("remember_name"); + remember_name->setCommitCallback(boost::bind(&LLPanelLogin::onRememberUserCheck, this)); + getChild<LLCheckBoxCtrl>("remember_password")->setCommitCallback(boost::bind(&LLPanelLogin::onRememberPasswordCheck, this)); } void LLPanelLogin::addFavoritesToStartLocation() @@ -400,10 +362,22 @@ void LLPanelLogin::addFavoritesToStartLocation() combo->addSeparator(); LL_DEBUGS() << "Loading favorites for " << iter->first << LL_ENDL; LLSD user_llsd = iter->second; + bool update_password_setting = true; for (LLSD::array_const_iterator iter1 = user_llsd.beginArray(); iter1 != user_llsd.endArray(); ++iter1) { - std::string label = (*iter1)["name"].asString(); + if ((*iter1).has("save_password")) + { + bool save_password = (*iter1)["save_password"].asBoolean(); + gSavedSettings.setBOOL("RememberPassword", save_password); + if (!save_password) + { + getChild<LLButton>("connect_btn")->setEnabled(false); + } + update_password_setting = false; + } + + std::string label = (*iter1)["name"].asString(); std::string value = (*iter1)["slurl"].asString(); if(label != "" && value != "") { @@ -415,6 +389,10 @@ void LLPanelLogin::addFavoritesToStartLocation() } } } + if (update_password_setting) + { + gSavedSettings.setBOOL("UpdateRememberPasswordSetting", TRUE); + } break; } if (combo->getValue().asString().empty()) @@ -530,21 +508,12 @@ void LLPanelLogin::populateFields(LLPointer<LLCredential> credential, bool remem LL_WARNS() << "Attempted fillFields with no login view shown" << LL_ENDL; return; } - if (sInstance->mFirstLoginThisInstall) - { - LLUICtrl* remember_check = sInstance->getChild<LLUICtrl>("remember_check"); - remember_check->setValue(remember_psswrd); - // no list to populate - setFields(credential); - } - else - { - sInstance->getChild<LLUICtrl>("remember_name")->setValue(remember_user); - LLUICtrl* remember_password = sInstance->getChild<LLUICtrl>("remember_password"); - remember_password->setValue(remember_user && remember_psswrd); - remember_password->setEnabled(remember_user); - sInstance->populateUserList(credential); - } + + sInstance->getChild<LLUICtrl>("remember_name")->setValue(remember_user); + LLUICtrl* remember_password = sInstance->getChild<LLUICtrl>("remember_password"); + remember_password->setValue(remember_user && remember_psswrd); + remember_password->setEnabled(remember_user); + sInstance->populateUserList(credential); } //static @@ -655,39 +624,6 @@ void LLPanelLogin::getFields(LLPointer<LLCredential>& credential, LL_INFOS("Credentials", "Authentication") << "retrieving username:" << username << LL_ENDL; // determine if the username is a first/last form or not. size_t separator_index = username.find_first_of(' '); - if (separator_index == username.npos - && !LLGridManager::getInstance()->isInSecondlife()) - { - LL_INFOS("Credentials", "Authentication") << "account: " << username << LL_ENDL; - // single username, so this is a 'clear' identifier - identifier["type"] = CRED_IDENTIFIER_TYPE_ACCOUNT; - identifier["account_name"] = username; - - if (LLPanelLogin::sInstance->mPasswordModified) - { - // password is plaintext - authenticator["type"] = CRED_AUTHENTICATOR_TYPE_CLEAR; - authenticator["secret"] = password; - } - else - { - credential = load_user_credentials(username); - if (credential.notNull()) - { - authenticator = credential->getAuthenticator(); - if (authenticator.emptyMap()) - { - // Likely caused by user trying to log in to non-system grid - // with unsupported name format, just retry - LL_WARNS() << "Authenticator failed to load for: " << username << LL_ENDL; - // password is plaintext - authenticator["type"] = CRED_AUTHENTICATOR_TYPE_CLEAR; - authenticator["secret"] = password; - } - } - } - } - else { // Be lenient in terms of what separators we allow for two-word names // and allow legacy users to login with firstname.lastname @@ -738,16 +674,9 @@ void LLPanelLogin::getFields(LLPointer<LLCredential>& credential, } } credential = gSecAPIHandler->createCredential(LLGridManager::getInstance()->getGrid(), identifier, authenticator); - if (!sInstance->mFirstLoginThisInstall) - { - remember_psswrd = sInstance->getChild<LLUICtrl>("remember_password")->getValue(); - remember_user = sInstance->getChild<LLUICtrl>("remember_name")->getValue(); - } - else - { - remember_psswrd = sInstance->getChild<LLUICtrl>("remember_check")->getValue(); - remember_user = remember_psswrd; // on panel_login_first "remember_check" is named as 'remember me' - } + + remember_psswrd = sInstance->getChild<LLUICtrl>("remember_password")->getValue(); + remember_user = sInstance->getChild<LLUICtrl>("remember_name")->getValue(); } @@ -1133,17 +1062,18 @@ void LLPanelLogin::onUserListCommit(void*) } // static -// At the moment only happens if !mFirstLoginThisInstall void LLPanelLogin::onRememberUserCheck(void*) { - if (sInstance && !sInstance->mFirstLoginThisInstall) + if (sInstance) { LLCheckBoxCtrl* remember_name(sInstance->getChild<LLCheckBoxCtrl>("remember_name")); LLCheckBoxCtrl* remember_psswrd(sInstance->getChild<LLCheckBoxCtrl>("remember_password")); LLComboBox* user_combo(sInstance->getChild<LLComboBox>("username_combo")); bool remember = remember_name->getValue().asBoolean(); - if (user_combo->getCurrentIndex() != -1 && !remember) + if (!sInstance->mFirstLoginThisInstall + && user_combo->getCurrentIndex() != -1 + && !remember) { remember = true; remember_name->setValue(true); @@ -1157,6 +1087,14 @@ void LLPanelLogin::onRememberUserCheck(void*) } } +void LLPanelLogin::onRememberPasswordCheck(void*) +{ + if (sInstance) + { + gSavedSettings.setBOOL("UpdateRememberPasswordSetting", TRUE); + } +} + // static void LLPanelLogin::onPassKey(LLLineEditor* caller, void* user_data) { diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h index d4663e49f51e64dcd9854e5ff22aaddd3ea054fb..ef7d36e29f64581ac64b5afab089b6a585a5a2a6 100644 --- a/indra/newview/llpanellogin.h +++ b/indra/newview/llpanellogin.h @@ -105,6 +105,7 @@ class LLPanelLogin final : static void onUserNameTextEnty(void*); static void onUserListCommit(void*); static void onRememberUserCheck(void*); + static void onRememberPasswordCheck(void*); static void onPassKey(LLLineEditor* caller, void* user_data); static void connectCallback(const LLSD& notification, const LLSD& response); diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index e900deaefcdd2d8dbe98578812b00e394b1e34ba..9ebc636b7df5d4a1ded04ffb32bfd56c5c07c180 100644 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -750,13 +750,13 @@ void LLPanelMainInventory::updateItemcountText() std::string text = ""; - if (LLInventoryModelBackgroundFetch::instanceFast().folderFetchActive()) + if (LLInventoryModelBackgroundFetch::instance().folderFetchActive()) { static LLUIString itemcount_fetching_str = getString("ItemcountFetching"); itemcount_fetching_str.setArgList(string_args); text = itemcount_fetching_str.getString(); } - else if (LLInventoryModelBackgroundFetch::instanceFast().isEverythingFetched()) + else if (LLInventoryModelBackgroundFetch::instance().isEverythingFetched()) { static LLUIString itemcount_completed_str = getString("ItemcountCompleted"); itemcount_completed_str.setArgList(string_args); diff --git a/indra/newview/llpanelmediasettingsgeneral.cpp b/indra/newview/llpanelmediasettingsgeneral.cpp index db814416bf87f52f0e3c764f805c1026147244fb..e1818cc68b3933c3d775e694690c958f6e6e823f 100644 --- a/indra/newview/llpanelmediasettingsgeneral.cpp +++ b/indra/newview/llpanelmediasettingsgeneral.cpp @@ -98,9 +98,6 @@ BOOL LLPanelMediaSettingsGeneral::postBuild() childSetCommitCallback( LLMediaEntry::HOME_URL_KEY, onCommitHomeURL, this); childSetCommitCallback( "current_url_reset_btn",onBtnResetCurrentUrl, this); - // interrogates controls and updates widgets as required - updateMediaPreview(); - return true; } @@ -313,9 +310,6 @@ void LLPanelMediaSettingsGeneral::initValues( void* userdata, const LLSD& _media data_set[ i ].ctrl_ptr->setTentative( media_settings[ tentative_key ].asBoolean() ); }; }; - - // interrogates controls and updates widgets as required - self->updateMediaPreview(); } //////////////////////////////////////////////////////////////////////////////// @@ -457,7 +451,7 @@ bool LLPanelMediaSettingsGeneral::navigateHomeSelectedFace(bool only_if_current_ if (!only_if_current_is_empty || (media_data->getCurrentURL().empty() && media_data->getAutoPlay())) { viewer_media_t media_impl = - LLViewerMedia::getInstanceFast()->getMediaImplFromTextureID(object->getTE(face)->getMediaData()->getMediaID()); + LLViewerMedia::getInstance()->getMediaImplFromTextureID(object->getTE(face)->getMediaData()->getMediaID()); if(media_impl) { media_impl->navigateHome(); @@ -473,7 +467,7 @@ bool LLPanelMediaSettingsGeneral::navigateHomeSelectedFace(bool only_if_current_ } functor_navigate_media(only_if_current_is_empty); bool all_face_media_navigated = false; - LLObjectSelectionHandle selected_objects =LLSelectMgr::getInstanceFast()->getSelection(); + LLObjectSelectionHandle selected_objects =LLSelectMgr::getInstance()->getSelection(); selected_objects->getSelectedTEValue( &functor_navigate_media, all_face_media_navigated ); // Note: we don't update the 'current URL' field until the media data itself changes @@ -511,7 +505,7 @@ void LLPanelMediaSettingsGeneral::updateCurrentUrl() const LLMediaEntry & mMediaEntry; } func_current_url(default_media_data); - bool identical = LLSelectMgr::getInstanceFast()->getSelection()->getSelectedTEValue( &func_current_url, value_str ); + bool identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func_current_url, value_str ); mCurrentURL->setText(value_str); mCurrentURL->setTentative(identical); diff --git a/indra/newview/llpanelmediasettingspermissions.cpp b/indra/newview/llpanelmediasettingspermissions.cpp index 9c7243841bb59674d20a1dcfa655ee9809777767..cb0b7789ff6e193deb31f4b08c3ff7bda70b9923 100644 --- a/indra/newview/llpanelmediasettingspermissions.cpp +++ b/indra/newview/llpanelmediasettingspermissions.cpp @@ -95,7 +95,7 @@ void LLPanelMediaSettingsPermissions::draw() getChild<LLUICtrl>("perms_group_name")->setValue(LLStringUtil::null); LLUUID group_id; - BOOL groups_identical = LLSelectMgr::getInstanceFast()->selectGetGroup(group_id); + BOOL groups_identical = LLSelectMgr::getInstance()->selectGetGroup(group_id); if (groups_identical) { if(mPermsGroupName) diff --git a/indra/newview/llpanelnearbymedia.cpp b/indra/newview/llpanelnearbymedia.cpp index 2a6d8f520b7a81c5fa1b6844737441615e1ea395..e05ccefe0e9bc488298bc253093686d140eeb7cc 100644 --- a/indra/newview/llpanelnearbymedia.cpp +++ b/indra/newview/llpanelnearbymedia.cpp @@ -504,7 +504,7 @@ void LLPanelNearByMedia::refreshParcelItems() // Only show "special parcel items" if "All" or "Within" filter // (and if media is "enabled") bool should_include = (choice == MEDIA_CLASS_ALL || choice == MEDIA_CLASS_WITHIN_PARCEL); - LLViewerMedia* media_inst = LLViewerMedia::getInstanceFast(); + LLViewerMedia* media_inst = LLViewerMedia::getInstance(); // First Parcel Media: add or remove it as necessary if (gSavedSettings.getBOOL("AudioStreamingMedia") && should_include && media_inst->hasParcelMedia()) @@ -615,7 +615,7 @@ void LLPanelNearByMedia::refreshList() refreshParcelItems(); // Get the canonical list from LLViewerMedia - LLViewerMedia* media_inst = LLViewerMedia::getInstanceFast(); + LLViewerMedia* media_inst = LLViewerMedia::getInstance(); LLViewerMedia::impl_list impls = media_inst->getPriorityList(); LLViewerMedia::impl_list::iterator priority_iter; @@ -739,19 +739,19 @@ void LLPanelNearByMedia::updateColumns() void LLPanelNearByMedia::onClickEnableAll() { - LLViewerMedia::getInstanceFast()->setAllMediaEnabled(true); + LLViewerMedia::getInstance()->setAllMediaEnabled(true); } void LLPanelNearByMedia::onClickDisableAll() { - LLViewerMedia::getInstanceFast()->setAllMediaEnabled(false); + LLViewerMedia::getInstance()->setAllMediaEnabled(false); } void LLPanelNearByMedia::onClickEnableParcelMedia() { - if ( ! LLViewerMedia::getInstanceFast()->isParcelMediaPlaying() ) + if ( ! LLViewerMedia::getInstance()->isParcelMediaPlaying() ) { - LLViewerParcelMedia::getInstance()->play(LLViewerParcelMgr::getInstanceFast()->getAgentParcel()); + LLViewerParcelMedia::getInstance()->play(LLViewerParcelMgr::getInstance()->getAgentParcel()); } } @@ -795,7 +795,7 @@ bool LLPanelNearByMedia::setDisabled(const LLUUID &row_id, bool disabled) return true; } else { - LLViewerMediaImpl* impl = LLViewerMedia::getInstanceFast()->getMediaImplFromTextureID(row_id); + LLViewerMediaImpl* impl = LLViewerMedia::getInstance()->getMediaImplFromTextureID(row_id); if(impl) { impl->setDisabled(disabled, true); @@ -852,7 +852,7 @@ void LLPanelNearByMedia::onClickParcelAudioPlay() } else { - LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLViewerMedia::getInstanceFast()->getParcelAudioURL()); + LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLViewerMedia::getInstance()->getParcelAudioURL()); } } @@ -944,7 +944,7 @@ void LLPanelNearByMedia::onMoreLess() void LLPanelNearByMedia::updateControls() { LLUUID selected_media_id = mMediaList->getValue().asUUID(); - LLViewerMedia* media_inst = LLViewerMedia::getInstanceFast(); + LLViewerMedia* media_inst = LLViewerMedia::getInstance(); if (selected_media_id == PARCEL_AUDIO_LIST_ITEM_UUID) { @@ -1080,7 +1080,7 @@ void LLPanelNearByMedia::onClickSelectedMediaPlay() if (selected_media_id != PARCEL_AUDIO_LIST_ITEM_UUID) { LLViewerMediaImpl *impl = (selected_media_id == PARCEL_MEDIA_LIST_ITEM_UUID) ? - ((LLViewerMediaImpl*)LLViewerParcelMedia::getInstanceFast()->getParcelMedia()) : LLViewerMedia::getInstanceFast()->getMediaImplFromTextureID(selected_media_id); + ((LLViewerMediaImpl*)LLViewerParcelMedia::getInstance()->getParcelMedia()) : LLViewerMedia::getInstance()->getMediaImplFromTextureID(selected_media_id); if (NULL != impl) { if (impl->isMediaTimeBased() && impl->isMediaPaused()) @@ -1091,7 +1091,7 @@ void LLPanelNearByMedia::onClickSelectedMediaPlay() } else if (impl->isParcelMedia()) { - LLViewerParcelMedia::getInstanceFast()->play(LLViewerParcelMgr::getInstance()->getAgentParcel()); + LLViewerParcelMedia::getInstance()->play(LLViewerParcelMgr::getInstance()->getAgentParcel()); } } } @@ -1109,7 +1109,7 @@ void LLPanelNearByMedia::onClickSelectedMediaPause() onClickParcelMediaPause(); } else { - LLViewerMediaImpl* impl = LLViewerMedia::getInstanceFast()->getMediaImplFromTextureID(selected_media_id); + LLViewerMediaImpl* impl = LLViewerMedia::getInstance()->getMediaImplFromTextureID(selected_media_id); if (NULL != impl && impl->isMediaTimeBased() && impl->isMediaPlaying()) { impl->pause(); @@ -1126,7 +1126,7 @@ void LLPanelNearByMedia::onClickSelectedMediaMute() } else { LLViewerMediaImpl* impl = (selected_media_id == PARCEL_MEDIA_LIST_ITEM_UUID) ? - ((LLViewerMediaImpl*)LLViewerParcelMedia::getInstance()->getParcelMedia()) : LLViewerMedia::getInstanceFast()->getMediaImplFromTextureID(selected_media_id); + ((LLViewerMediaImpl*)LLViewerParcelMedia::getInstance()->getParcelMedia()) : LLViewerMedia::getInstance()->getMediaImplFromTextureID(selected_media_id); if (NULL != impl) { F32 volume = impl->getVolume(); @@ -1157,7 +1157,7 @@ void LLPanelNearByMedia::onCommitSelectedMediaVolume() } else { LLViewerMediaImpl* impl = (selected_media_id == PARCEL_MEDIA_LIST_ITEM_UUID) ? - ((LLViewerMediaImpl*)LLViewerParcelMedia::getInstance()->getParcelMedia()) : LLViewerMedia::getInstanceFast()->getMediaImplFromTextureID(selected_media_id); + ((LLViewerMediaImpl*)LLViewerParcelMedia::getInstance()->getParcelMedia()) : LLViewerMedia::getInstance()->getMediaImplFromTextureID(selected_media_id); if (NULL != impl) { impl->setVolume(mVolumeSlider->getValueF32()); diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp index 9455809163dd3682eba559346b57131b9b192d36..d9310d202d9c784f2fb7a8af5812ddabbeaf293b 100644 --- a/indra/newview/llpanelobject.cpp +++ b/indra/newview/llpanelobject.cpp @@ -46,6 +46,7 @@ #include "llcombobox.h" #include "llfocusmgr.h" #include "llmanipscale.h" +#include "llmenubutton.h" #include "llpreviewscript.h" #include "llresmgr.h" #include "llselectmgr.h" @@ -136,8 +137,9 @@ BOOL LLPanelObject::postBuild() // Phantom checkbox mCheckPhantom = getChild<LLCheckBoxCtrl>("Phantom Checkbox Ctrl"); childSetCommitCallback("Phantom Checkbox Ctrl",onCommitPhantom,this); - + // Position + mMenuClipboardPos = getChild<LLMenuButton>("clipboard_pos_btn"); mLabelPosition = getChild<LLTextBox>("label position"); mCtrlPosX = getChild<LLSpinCtrl>("Pos X"); childSetCommitCallback("Pos X",onCommitPosition,this); @@ -147,6 +149,7 @@ BOOL LLPanelObject::postBuild() childSetCommitCallback("Pos Z",onCommitPosition,this); // Scale + mMenuClipboardSize = getChild<LLMenuButton>("clipboard_size_btn"); mLabelSize = getChild<LLTextBox>("label size"); mCtrlScaleX = getChild<LLSpinCtrl>("Scale X"); childSetCommitCallback("Scale X",onCommitScale,this); @@ -160,6 +163,7 @@ BOOL LLPanelObject::postBuild() childSetCommitCallback("Scale Z",onCommitScale,this); // Rotation + mMenuClipboardRot = getChild<LLMenuButton>("clipboard_rot_btn"); mLabelRotation = getChild<LLTextBox>("label rotation"); mCtrlRotX = getChild<LLSpinCtrl>("Rot X"); childSetCommitCallback("Rot X",onCommitRotation,this); @@ -174,6 +178,8 @@ BOOL LLPanelObject::postBuild() mComboBaseType = getChild<LLComboBox>("comboBaseType"); childSetCommitCallback("comboBaseType",onCommitParametric,this); + mMenuClipboardParams = getChild<LLMenuButton>("clipboard_obj_params_btn"); + // Cut mLabelCut = getChild<LLTextBox>("text cut"); mSpinCutBegin = getChild<LLSpinCtrl>("cut begin"); @@ -266,7 +272,7 @@ BOOL LLPanelObject::postBuild() // Allow any texture to be used during non-immediate mode. mCtrlSculptTexture->setNonImmediateFilterPermMask(PERM_NONE); LLAggregatePermissions texture_perms; - if (LLSelectMgr::getInstanceFast()->selectGetAggregateTexturePermissions(texture_perms)) + if (LLSelectMgr::getInstance()->selectGetAggregateTexturePermissions(texture_perms)) { BOOL can_copy = texture_perms.getValue(PERM_COPY) == LLAggregatePermissions::AP_EMPTY || @@ -304,10 +310,15 @@ LLPanelObject::LLPanelObject() mSelectedType(MI_BOX), mSculptTextureRevert(LLUUID::null), mSculptTypeRevert(0), + mHasClipboardPos(false), + mHasClipboardSize(false), + mHasClipboardRot(false), mSizeChanged(FALSE), mRegionMaxHeight(256.f), mRegionMaxDepth(0.f) { + mCommitCallbackRegistrar.add("PanelObject.menuDoToSelected", boost::bind(&LLPanelObject::menuDoToSelected, this, _2)); + mEnableCallbackRegistrar.add("PanelObject.menuEnable", boost::bind(&LLPanelObject::menuEnableItem, this, _2)); } @@ -318,7 +329,7 @@ LLPanelObject::~LLPanelObject() void LLPanelObject::getState( ) { - LLSelectMgr* select_mgr = LLSelectMgr::getInstanceFast(); + LLSelectMgr* select_mgr = LLSelectMgr::getInstance(); LLViewerObject* objectp = select_mgr->getSelection()->getFirstRootObject(); LLViewerObject* root_objectp = objectp; if(!objectp) @@ -407,7 +418,7 @@ void LLPanelObject::getState( ) calcp->clearVar(LLCalc::Z_POS); } - + mMenuClipboardPos->setEnabled(enable_move); mLabelPosition->setEnabled( enable_move ); mCtrlPosX->setEnabled(enable_move); mCtrlPosY->setEnabled(enable_move); @@ -443,6 +454,7 @@ void LLPanelObject::getState( ) calcp->setVar(LLCalc::Z_SCALE, 0.f); } + mMenuClipboardSize->setEnabled(enable_scale); mLabelSize->setEnabled( enable_scale ); mCtrlScaleX->setEnabled( enable_scale ); mCtrlScaleY->setEnabled( enable_scale ); @@ -474,6 +486,7 @@ void LLPanelObject::getState( ) calcp->clearVar(LLCalc::Z_ROT); } + mMenuClipboardRot->setEnabled(enable_rotate); mLabelRotation->setEnabled( enable_rotate ); mCtrlRotX->setEnabled( enable_rotate ); mCtrlRotY->setEnabled( enable_rotate ); @@ -699,7 +712,7 @@ void LLPanelObject::getState( ) } else { - LL_INFOS() << "Unknown path " << (S32) path << " profile " << (S32) profile << " in getState" << LL_ENDL; + LL_INFOS("FloaterTools") << "Unknown path " << (S32) path << " profile " << (S32) profile << " in getState" << LL_ENDL; selected_item = MI_BOX; } @@ -1053,6 +1066,7 @@ void LLPanelObject::getState( ) // Update field enablement mComboBaseType ->setEnabled( enabled ); + mMenuClipboardParams->setEnabled(enabled); mLabelCut ->setEnabled( enabled ); mSpinCutBegin ->setEnabled( enabled ); @@ -1209,7 +1223,8 @@ void LLPanelObject::getState( ) } mComboBaseType->setEnabled(!isMesh); - + mMenuClipboardParams->setEnabled(!isMesh); + if (mCtrlSculptType) { if (sculpt_stitching == LL_SCULPT_TYPE_NONE) @@ -1270,14 +1285,14 @@ void LLPanelObject::sendIsPhysical() BOOL value = mCheckPhysics->get(); if( mIsPhysical != value ) { - LLSelectMgr::getInstanceFast()->selectionUpdatePhysics(value); + LLSelectMgr::getInstance()->selectionUpdatePhysics(value); mIsPhysical = value; - LL_INFOS() << "update physics sent" << LL_ENDL; + LL_INFOS("FloaterTools") << "update physics sent" << LL_ENDL; } else { - LL_INFOS() << "update physics not changed" << LL_ENDL; + LL_INFOS("FloaterTools") << "update physics not changed" << LL_ENDL; } } @@ -1286,14 +1301,14 @@ void LLPanelObject::sendIsTemporary() BOOL value = mCheckTemporary->get(); if( mIsTemporary != value ) { - LLSelectMgr::getInstanceFast()->selectionUpdateTemporary(value); + LLSelectMgr::getInstance()->selectionUpdateTemporary(value); mIsTemporary = value; - LL_INFOS() << "update temporary sent" << LL_ENDL; + LL_INFOS("FloaterTools") << "update temporary sent" << LL_ENDL; } else { - LL_INFOS() << "update temporary not changed" << LL_ENDL; + LL_INFOS("FloaterTools") << "update temporary not changed" << LL_ENDL; } } @@ -1303,14 +1318,14 @@ void LLPanelObject::sendIsPhantom() BOOL value = mCheckPhantom->get(); if( mIsPhantom != value ) { - LLSelectMgr::getInstanceFast()->selectionUpdatePhantom(value); + LLSelectMgr::getInstance()->selectionUpdatePhantom(value); mIsPhantom = value; - LL_INFOS() << "update phantom sent" << LL_ENDL; + LL_INFOS("FloaterTools") << "update phantom sent" << LL_ENDL; } else { - LL_INFOS() << "update phantom not changed" << LL_ENDL; + LL_INFOS("FloaterTools") << "update phantom not changed" << LL_ENDL; } } @@ -1490,7 +1505,7 @@ void LLPanelObject::getVolumeParams(LLVolumeParams& volume_params) break; default: - LL_WARNS() << "Unknown base type " << selected_type + LL_WARNS("FloaterTools") << "Unknown base type " << selected_type << " in getVolumeParams()" << LL_ENDL; // assume a box selected_type = MI_BOX; @@ -1783,7 +1798,7 @@ void LLPanelObject::sendRotation(BOOL btn_down) if(!btn_down) { child_positions.clear() ; - LLSelectMgr::getInstanceFast()->sendMultipleUpdate(UPD_ROTATION | UPD_POSITION); + LLSelectMgr::getInstance()->sendMultipleUpdate(UPD_ROTATION | UPD_POSITION); } } } @@ -1807,17 +1822,17 @@ void LLPanelObject::sendScale(BOOL btn_down) BOOL dont_stretch_textures = !LLManipScale::getStretchTextures(); if (dont_stretch_textures) { - LLSelectMgr::getInstanceFast()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_SCALE); + LLSelectMgr::getInstance()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_SCALE); } mObject->setScale(newscale, TRUE); if(!btn_down) { - LLSelectMgr::getInstanceFast()->sendMultipleUpdate(UPD_SCALE | UPD_POSITION); + LLSelectMgr::getInstance()->sendMultipleUpdate(UPD_SCALE | UPD_POSITION); } - LLSelectMgr::getInstanceFast()->adjustTexturesByScale(TRUE, !dont_stretch_textures); + LLSelectMgr::getInstance()->adjustTexturesByScale(TRUE, !dont_stretch_textures); // LL_INFOS() << "scale sent" << LL_ENDL; } else @@ -1841,7 +1856,7 @@ void LLPanelObject::sendPosition(BOOL btn_down) } else { - LLWorld* world_inst = LLWorld::getInstanceFast(); + LLWorld* world_inst = LLWorld::getInstance(); // Clamp the Z height const F32 height = newpos.mV[VZ]; @@ -1903,12 +1918,12 @@ void LLPanelObject::sendPosition(BOOL btn_down) if (!btn_down) { - LLSelectMgr::getInstanceFast()->sendMultipleUpdate(UPD_POSITION); + LLSelectMgr::getInstance()->sendMultipleUpdate(UPD_POSITION); } - LLSelectMgr::getInstanceFast()->updateSelectionCenter(); + LLSelectMgr::getInstance()->updateSelectionCenter(); } - else if ( LLWorld::getInstanceFast()->positionRegionValidGlobal(new_pos_global) ) + else if ( LLWorld::getInstance()->positionRegionValidGlobal(new_pos_global) ) { // send only if the position is changed, that is, the delta vector is not zero LLVector3d old_pos_global = mObject->getPositionGlobal(); @@ -1938,10 +1953,10 @@ void LLPanelObject::sendPosition(BOOL btn_down) if(!btn_down) { - LLSelectMgr::getInstanceFast()->sendMultipleUpdate(UPD_POSITION); + LLSelectMgr::getInstance()->sendMultipleUpdate(UPD_POSITION); } - LLSelectMgr::getInstanceFast()->updateSelectionCenter(); + LLSelectMgr::getInstance()->updateSelectionCenter(); } } else @@ -2004,7 +2019,7 @@ void LLPanelObject::refresh() mRootObject = NULL; } - LLWorld* worldp = LLWorld::getInstanceFast(); + LLWorld* worldp = LLWorld::getInstance(); if (mObject && mObject->getRegion()) { auto region = mObject->getRegion(); @@ -2013,7 +2028,7 @@ void LLPanelObject::refresh() mRegionMaxDepth = region->getMinRegionHeight(); mCtrlPosZ->setMaxValue(mRegionMaxHeight); mMinScale = region->getMinPrimScale(); - mMaxScale = LLGridManager::getInstanceFast()->isInOpenSim() ? region->getMaxPrimScale() : get_default_max_prim_scale(LLPickInfo::isFlora(mObject)); + mMaxScale = LLGridManager::getInstance()->isInOpenSim() ? region->getMaxPrimScale() : get_default_max_prim_scale(LLPickInfo::isFlora(mObject)); mCtrlScaleX->setMinValue(mMinScale); mCtrlScaleX->setMaxValue(mMaxScale); mCtrlScaleY->setMinValue(mMinScale); @@ -2024,7 +2039,7 @@ void LLPanelObject::refresh() else { mRegionMaxHeight = worldp->getRegionMaxHeight(); - mRegionMaxDepth = LLGridManager::getInstanceFast()->isInOpenSim() ? -256.f : 0.f; // OpenSim is derp + mRegionMaxDepth = LLGridManager::getInstance()->isInOpenSim() ? -256.f : 0.f; // OpenSim is derp mCtrlPosZ->setMaxValue(mRegionMaxHeight); mMinScale = worldp->getRegionMinPrimScale(); mMaxScale = get_default_max_prim_scale(LLPickInfo::isFlora(mObject)); @@ -2052,7 +2067,7 @@ void LLPanelObject::draw() static const LLColor4 blue( 0.f, 0.5f, 1.0f, 1); // Tune the colors of the labels - LLTool* tool = LLToolMgr::getInstanceFast()->getCurrentTool(); + LLTool* tool = LLToolMgr::getInstance()->getCurrentTool(); if (tool == LLToolCompTranslate::getInstance()) { @@ -2163,7 +2178,7 @@ void LLPanelObject::onCommitLock(LLUICtrl *ctrl, void *data) BOOL new_state = self->mCheckLock->get(); - LLSelectMgr::getInstanceFast()->selectionSetObjectPermissions(PERM_OWNER, !new_state, PERM_MOVE | PERM_MODIFY); + LLSelectMgr::getInstance()->selectionSetObjectPermissions(PERM_OWNER, !new_state, PERM_MOVE | PERM_MODIFY); } // static @@ -2257,3 +2272,291 @@ void LLPanelObject::onCommitSculptType(LLUICtrl *ctrl, void* userdata) self->sendSculpt(); } + +void LLPanelObject::menuDoToSelected(const LLSD& userdata) +{ + std::string command = userdata.asString(); + + // paste + if (command == "psr_paste") + { + onPastePos(); + onPasteSize(); + onPasteRot(); + } + else if (command == "pos_paste") + { + onPastePos(); + } + else if (command == "size_paste") + { + onPasteSize(); + } + else if (command == "rot_paste") + { + onPasteRot(); + } + else if (command == "params_paste") + { + onPasteParams(); + } + // copy + else if (command == "psr_copy") + { + onCopyPos(); + onCopySize(); + onCopyRot(); + } + else if (command == "pos_copy") + { + onCopyPos(); + } + else if (command == "size_copy") + { + onCopySize(); + } + else if (command == "rot_copy") + { + onCopyRot(); + } + else if (command == "params_copy") + { + onCopyParams(); + } +} + +bool LLPanelObject::menuEnableItem(const LLSD& userdata) +{ + std::string command = userdata.asString(); + + // paste options + if (command == "psr_paste") + { + S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount(); + BOOL single_volume = (LLSelectMgr::getInstance()->selectionAllPCode(LL_PCODE_VOLUME)) + && (selected_count == 1); + + if (!single_volume) + { + return false; + } + + bool enable_move; + bool enable_modify; + + LLSelectMgr::getInstance()->selectGetEditMoveLinksetPermissions(enable_move, enable_modify); + + return enable_move && enable_modify && mHasClipboardPos && mHasClipboardSize && mHasClipboardRot; + } + else if (command == "pos_paste") + { + // assumes that menu won't be active if there is no move permission + return mHasClipboardPos; + } + else if (command == "size_paste") + { + return mHasClipboardSize; + } + else if (command == "rot_paste") + { + return mHasClipboardRot; + } + else if (command == "params_paste") + { + return mClipboardParams.isMap() && !mClipboardParams.emptyMap(); + } + // copy options + else if (command == "psr_copy") + { + S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount(); + BOOL single_volume = (LLSelectMgr::getInstance()->selectionAllPCode(LL_PCODE_VOLUME)) + && (selected_count == 1); + + if (!single_volume) + { + return false; + } + + bool enable_move; + bool enable_modify; + + LLSelectMgr::getInstance()->selectGetEditMoveLinksetPermissions(enable_move, enable_modify); + + // since we forbid seeing values we also should forbid copying them + return enable_move && enable_modify; + } + return false; +} + +void LLPanelObject::onCopyPos() +{ + mClipboardPos = LLVector3(mCtrlPosX->get(), mCtrlPosY->get(), mCtrlPosZ->get()); + + std::string stringVec = llformat("<%g, %g, %g>", mClipboardPos.mV[VX], mClipboardPos.mV[VY], mClipboardPos.mV[VZ]); + LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(stringVec)); + + mHasClipboardPos = true; +} + +void LLPanelObject::onCopySize() +{ + mClipboardSize = LLVector3(mCtrlScaleX->get(), mCtrlScaleY->get(), mCtrlScaleZ->get()); + + std::string stringVec = llformat("<%g, %g, %g>", mClipboardSize.mV[VX], mClipboardSize.mV[VY], mClipboardSize.mV[VZ]); + LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(stringVec)); + + mHasClipboardSize = true; +} + +void LLPanelObject::onCopyRot() +{ + mClipboardRot = LLVector3(mCtrlRotX->get(), mCtrlRotY->get(), mCtrlRotZ->get()); + + std::string stringVec = llformat("<%g, %g, %g>", mClipboardRot.mV[VX], mClipboardRot.mV[VY], mClipboardRot.mV[VZ]); + LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(stringVec)); + + mHasClipboardRot = true; +} + +void LLPanelObject::onPastePos() +{ + if (!mHasClipboardPos) return; + if (mObject.isNull()) return; + + LLViewerRegion* regionp = mObject->getRegion(); + if (!regionp) return; + + + // Clamp pos on non-attachments, just keep the prims within the region + if (!mObject->isAttachment()) + { + F32 max_width = regionp->getWidth(); // meters + mClipboardPos.mV[VX] = llclamp(mClipboardPos.mV[VX], 0.f, max_width); + mClipboardPos.mV[VY] = llclamp(mClipboardPos.mV[VY], 0.f, max_width); + //height will get properly clamped by sendPosition + } + + mCtrlPosX->set( mClipboardPos.mV[VX] ); + mCtrlPosY->set( mClipboardPos.mV[VY] ); + mCtrlPosZ->set( mClipboardPos.mV[VZ] ); + + sendPosition(FALSE); +} + +void LLPanelObject::onPasteSize() +{ + if (!mHasClipboardSize) return; + + F32 min_scale = SL_MIN_PRIM_SCALE; + F32 max_scale = SL_DEFAULT_MAX_PRIM_SCALE; + if(gAgent.getRegion()) + { + min_scale = gAgent.getRegion()->getMinPrimScale(); + max_scale = gAgent.getRegion()->getMaxPrimScale(); + } + + mClipboardSize.mV[VX] = llclamp(mClipboardSize.mV[VX], min_scale, max_scale); + mClipboardSize.mV[VY] = llclamp(mClipboardSize.mV[VY], min_scale, max_scale); + mClipboardSize.mV[VZ] = llclamp(mClipboardSize.mV[VZ], min_scale, max_scale); + + mCtrlScaleX->set(mClipboardSize.mV[VX]); + mCtrlScaleY->set(mClipboardSize.mV[VY]); + mCtrlScaleZ->set(mClipboardSize.mV[VZ]); + + sendScale(FALSE); +} + +void LLPanelObject::onPasteRot() +{ + if (!mHasClipboardRot) return; + + mCtrlRotX->set(mClipboardRot.mV[VX]); + mCtrlRotY->set(mClipboardRot.mV[VY]); + mCtrlRotZ->set(mClipboardRot.mV[VZ]); + + sendRotation(FALSE); +} + +void LLPanelObject::onCopyParams() +{ + LLViewerObject* objectp = mObject; + if (!objectp || objectp->isMesh()) + { + return; + } + + mClipboardParams.clear(); + + // Parametrics + LLVolumeParams params; + getVolumeParams(params); + mClipboardParams["volume_params"] = params.asLLSD(); + + // Sculpted Prim + if (objectp->getSculptParams()) + { + LLSculptParams *sculpt_params = (LLSculptParams *)objectp->getSculptParams(); + + LLUUID texture_id = sculpt_params->getSculptTexture(); + if (get_can_copy_texture(texture_id)) + { + LL_DEBUGS("FloaterTools") << "Recording texture" << LL_ENDL; + mClipboardParams["sculpt"]["id"] = texture_id; + } + else + { + mClipboardParams["sculpt"]["id"] = LLUUID(SCULPT_DEFAULT_TEXTURE); + } + + mClipboardParams["sculpt"]["type"] = sculpt_params->getSculptType(); + } +} + +void LLPanelObject::onPasteParams() +{ + LLViewerObject* objectp = mObject; + if (!objectp) + { + return; + } + + // Sculpted Prim + if (mClipboardParams.has("sculpt")) + { + LLSculptParams sculpt_params; + LLUUID sculpt_id = mClipboardParams["sculpt"]["id"].asUUID(); + U8 sculpt_type = (U8)mClipboardParams["sculpt"]["type"].asInteger(); + sculpt_params.setSculptTexture(sculpt_id, sculpt_type); + objectp->setParameterEntry(LLNetworkData::PARAMS_SCULPT, sculpt_params, TRUE); + } + else + { + LLSculptParams *sculpt_params = (LLSculptParams *)objectp->getSculptParams(); + if (sculpt_params) + { + objectp->setParameterEntryInUse(LLNetworkData::PARAMS_SCULPT, FALSE, TRUE); + } + } + + // volume params + // make sure updateVolume() won't affect flexible + if (mClipboardParams.has("volume_params")) + { + LLVolumeParams params; + params.fromLLSD(mClipboardParams["volume_params"]); + LLVOVolume *volobjp = (LLVOVolume *)objectp; + if (volobjp->isFlexible()) + { + if (params.getPathParams().getCurveType() == LL_PCODE_PATH_LINE) + { + params.getPathParams().setCurveType(LL_PCODE_PATH_FLEXIBLE); + } + } + else if (params.getPathParams().getCurveType() == LL_PCODE_PATH_FLEXIBLE) + { + params.getPathParams().setCurveType(LL_PCODE_PATH_LINE); + } + + objectp->updateVolume(params); + } +} diff --git a/indra/newview/llpanelobject.h b/indra/newview/llpanelobject.h index b5f9d129464f3d052c9b7eb9b661afa8ca5ca9bf..fcfb9d1edeba382001ba5c58d6975e28ec5f7c4a 100644 --- a/indra/newview/llpanelobject.h +++ b/indra/newview/llpanelobject.h @@ -37,6 +37,7 @@ class LLCheckBoxCtrl; class LLTextBox; class LLUICtrl; class LLButton; +class LLMenuButton; class LLViewerObject; class LLComboBox; class LLColorSwatchCtrl; @@ -66,6 +67,14 @@ class LLPanelObject final : public LLPanel static void onCommitPhantom( LLUICtrl* ctrl, void* userdata); static void onCommitPhysics( LLUICtrl* ctrl, void* userdata); + void onCopyPos(); + void onPastePos(); + void onCopySize(); + void onPasteSize(); + void onCopyRot(); + void onPasteRot(); + void onCopyParams(); + void onPasteParams(); static void onCommitParametric(LLUICtrl* ctrl, void* userdata); @@ -75,6 +84,9 @@ class LLPanelObject final : public LLPanel BOOL onDropSculpt(LLInventoryItem* item); static void onCommitSculptType( LLUICtrl *ctrl, void* userdata); + void menuDoToSelected(const LLSD& userdata); + bool menuEnableItem(const LLSD& userdata); + protected: void getState(); @@ -92,6 +104,7 @@ class LLPanelObject final : public LLPanel protected: // Per-object options LLComboBox* mComboBaseType; + LLMenuButton* mMenuClipboardParams; LLTextBox* mLabelCut; LLSpinCtrl* mSpinCutBegin; @@ -131,17 +144,20 @@ class LLPanelObject final : public LLPanel LLTextBox* mLabelRevolutions; LLSpinCtrl* mSpinRevolutions; + LLMenuButton* mMenuClipboardPos; LLTextBox* mLabelPosition; LLSpinCtrl* mCtrlPosX; LLSpinCtrl* mCtrlPosY; LLSpinCtrl* mCtrlPosZ; + LLMenuButton* mMenuClipboardSize; LLTextBox* mLabelSize; LLSpinCtrl* mCtrlScaleX; LLSpinCtrl* mCtrlScaleY; LLSpinCtrl* mCtrlScaleZ; BOOL mSizeChanged; + LLMenuButton* mMenuClipboardRot; LLTextBox* mLabelRotation; LLSpinCtrl* mCtrlRotX; LLSpinCtrl* mCtrlRotY; @@ -157,7 +173,7 @@ class LLPanelObject final : public LLPanel LLComboBox *mCtrlSculptType; LLCheckBoxCtrl *mCtrlSculptMirror; LLCheckBoxCtrl *mCtrlSculptInvert; - + LLVector3 mCurEulerDegrees; // to avoid sending rotation when not changed BOOL mIsPhysical; // to avoid sending "physical" when not changed BOOL mIsTemporary; // to avoid sending "temporary" when not changed @@ -174,6 +190,15 @@ class LLPanelObject final : public LLPanel F32 mMaxHollowSize; F32 mMinHoleSize; + LLVector3 mClipboardPos; + LLVector3 mClipboardSize; + LLVector3 mClipboardRot; + LLSD mClipboardParams; + + bool mHasClipboardPos; + bool mHasClipboardSize; + bool mHasClipboardRot; + LLPointer<LLViewerObject> mObject; LLPointer<LLViewerObject> mRootObject; }; diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp index 2d12d39f569aaf855112b6dc56b6c8740fb09f00..b015aecf8493cd1590d41ce20952f93d00a9ad00 100644 --- a/indra/newview/llpanelobjectinventory.cpp +++ b/indra/newview/llpanelobjectinventory.cpp @@ -717,7 +717,18 @@ const std::string& LLTaskCategoryBridge::getDisplayName() const if (cat) { - mDisplayName.assign(cat->getName()); + std::string name = cat->getName(); + if (mChildren.size() > 0) + { + // Add item count + // Normally we would be using getLabelSuffix for this + // but object's inventory just uses displaynames + LLStringUtil::format_map_t args; + args["[ITEMS_COUNT]"] = llformat("%d", mChildren.size()); + + name.append(" " + LLTrans::getString("InventoryItemsCount", args)); + } + mDisplayName.assign(name); } return mDisplayName; @@ -1728,6 +1739,8 @@ void LLPanelObjectInventory::createFolderViews(LLInventoryObject* inventory_root { createViewsForCategory(&contents, inventory_root, new_folder); } + // Refresh for label to add item count + new_folder->refresh(); } } @@ -1803,7 +1816,7 @@ void LLPanelObjectInventory::refresh() //LL_INFOS() << "LLPanelObjectInventory::refresh()" << LL_ENDL; BOOL has_inventory = FALSE; const BOOL non_root_ok = TRUE; - LLObjectSelectionHandle selection = LLSelectMgr::getInstanceFast()->getSelection(); + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); LLSelectNode* node = selection->getFirstRootNode(NULL, non_root_ok); if(node && node->mValid) { @@ -1837,7 +1850,7 @@ void LLPanelObjectInventory::refresh() { // Server unsubsribes viewer (deselects object) from property // updates after "ObjectAttach" so we need to resubscribe - LLSelectMgr::getInstanceFast()->sendSelect(); + LLSelectMgr::getInstance()->sendSelect(); } } diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp index d31c414b1baf1d27886032a15ad1c8c2d2aed7e5..e1c7aaf3107e01d197d9c208fff067a542fc79da 100644 --- a/indra/newview/llpaneloutfitedit.cpp +++ b/indra/newview/llpaneloutfitedit.cpp @@ -102,7 +102,7 @@ std::string LLShopURLDispatcher::resolveURL(LLWearableType::EType wearable_type, { const std::string prefix = "MarketplaceURL"; const std::string sex_str = (sex == SEX_MALE) ? "Male" : "Female"; - const std::string type_str = LLWearableType::getInstanceFast()->getTypeName(wearable_type); + const std::string type_str = LLWearableType::getInstance()->getTypeName(wearable_type); std::string setting_name = prefix; @@ -178,7 +178,7 @@ class LLPanelOutfitEditGearMenu private: static void onCreate(const LLSD& param) { - LLWearableType::EType type = LLWearableType::getInstanceFast()->typeNameToType(param.asString()); + LLWearableType::EType type = LLWearableType::getInstance()->typeNameToType(param.asString()); if (type == LLWearableType::WT_NONE) { LL_WARNS() << "Invalid wearable type" << LL_ENDL; @@ -193,7 +193,7 @@ class LLPanelOutfitEditGearMenu { LLView* menu_clothes = gMenuHolder->getChildView("COF.Gear.New_Clothes", FALSE); LLView* menu_bp = gMenuHolder->getChildView("COF.Gear.New_Body_Parts", FALSE); - LLWearableType * wearable_type_inst = LLWearableType::getInstanceFast(); + LLWearableType * wearable_type_inst = LLWearableType::getInstance(); for (U8 i = LLWearableType::WT_SHAPE; i != (U8) LLWearableType::WT_COUNT; ++i) { diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index ed4e5a3e0f68149418a8ef8c9439253adac9be2e..1cc810b806b4016b81e1be8289fa137776727e21 100644 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -100,7 +100,7 @@ class LLAvatarItemRecentComparator : public LLAvatarItemComparator protected: virtual bool doCompare(const LLAvatarListItem* avatar_item1, const LLAvatarListItem* avatar_item2) const { - LLRecentPeople& people = LLRecentPeople::instanceFast(); + LLRecentPeople& people = LLRecentPeople::instance(); const LLDate& date1 = people.getDate(avatar_item1->getAvatarId()); const LLDate& date2 = people.getDate(avatar_item2->getAvatarId()); @@ -221,8 +221,8 @@ class LLAvatarItemRecentArrivalComparator : public LLAvatarItemNameComparator virtual bool doCompare(const LLAvatarListItem* item1, const LLAvatarListItem* item2) const { - F32 arr_time1 = LLRecentPeople::instanceFast().getArrivalTimeByID(item1->getAvatarId()); - F32 arr_time2 = LLRecentPeople::instanceFast().getArrivalTimeByID(item2->getAvatarId()); + F32 arr_time1 = LLRecentPeople::instance().getArrivalTimeByID(item1->getAvatarId()); + F32 arr_time2 = LLRecentPeople::instance().getArrivalTimeByID(item2->getAvatarId()); if (arr_time1 == arr_time2) { @@ -526,7 +526,7 @@ class LLRecentListUpdater : public LLAvatarListUpdater, public boost::signals2:: LLRecentListUpdater(callback_t cb) : LLAvatarListUpdater(cb, 0) { - LLRecentPeople::instanceFast().setChangedCallback(boost::bind(&LLRecentListUpdater::update, this)); + LLRecentPeople::instance().setChangedCallback(boost::bind(&LLRecentListUpdater::update, this)); } }; @@ -832,7 +832,7 @@ void LLPanelPeople::updateNearbyList() if (RlvActions::canShowNearbyAgents()) { // [/RLVa:KB] - LLWorld::getInstanceFast()->getAvatars(&mNearbyList->getIDs(), &positions, gAgent.getPositionGlobal(), ALControlCache::NearMeRange); + LLWorld::getInstance()->getAvatars(&mNearbyList->getIDs(), &positions, gAgent.getPositionGlobal(), ALControlCache::NearMeRange); // [RLVa:KB] - Checked: RLVa-2.0.3 } else @@ -851,7 +851,7 @@ void LLPanelPeople::updateRecentList() if (!mRecentList) return; - LLRecentPeople::instanceFast().get(mRecentList->getIDs()); + LLRecentPeople::instance().get(mRecentList->getIDs()); mRecentList->setDirty(); } @@ -1123,9 +1123,9 @@ void LLPanelPeople::onGroupLimitInfo() args["MAX_BASIC"] = max_basic; args["MAX_PREMIUM"] = max_premium; - if (LLAgentBenefitsMgr::has("Premium Plus")) + if (LLAgentBenefitsMgr::has("Premium_Plus")) { - S32 max_premium_plus = LLAgentBenefitsMgr::get("Premium Plus").getGroupMembershipLimit(); + S32 max_premium_plus = LLAgentBenefitsMgr::get("Premium_Plus").getGroupMembershipLimit(); args["MAX_PREMIUM_PLUS"] = max_premium_plus; LLNotificationsUtil::add("GroupLimitInfoPlus", args); } @@ -1635,8 +1635,8 @@ bool LLPanelPeople::updateNearbyArrivalTime() { std::vector<LLVector3d> positions; std::vector<LLUUID> uuids; - LLWorld::getInstanceFast()->getAvatars(&uuids, &positions, gAgent.getPositionGlobal(), ALControlCache::NearMeRange); - LLRecentPeople::instanceFast().updateAvatarsArrivalTime(uuids); + LLWorld::getInstance()->getAvatars(&uuids, &positions, gAgent.getPositionGlobal(), ALControlCache::NearMeRange); + LLRecentPeople::instance().updateAvatarsArrivalTime(uuids); return LLApp::isExiting(); } diff --git a/indra/newview/llpanelpermissions.cpp b/indra/newview/llpanelpermissions.cpp index 563c9d9e50d35f9242894051c0e542bf540d115a..0fb79e90007eb9a12e493098d7b177dc9dc528be 100644 --- a/indra/newview/llpanelpermissions.cpp +++ b/indra/newview/llpanelpermissions.cpp @@ -323,7 +323,7 @@ void LLPanelPermissions::disableAll() void LLPanelPermissions::refresh() { - LLSelectMgr* select_mgr = LLSelectMgr::getInstanceFast(); + LLSelectMgr* select_mgr = LLSelectMgr::getInstance(); LLButton* BtnDeedToGroup = getChild<LLButton>("button deed"); if(BtnDeedToGroup) @@ -1171,21 +1171,21 @@ void LLPanelPermissions::updateCreatorName(const LLUUID& creator_id, const LLAva void LLPanelPermissions::onClickClaim(void*) { // try to claim ownership - LLSelectMgr::getInstanceFast()->sendOwner(gAgent.getID(), gAgent.getGroupID()); + LLSelectMgr::getInstance()->sendOwner(gAgent.getID(), gAgent.getGroupID()); } // static void LLPanelPermissions::onClickRelease(void*) { // try to release ownership - LLSelectMgr::getInstanceFast()->sendOwner(LLUUID::null, LLUUID::null); + LLSelectMgr::getInstance()->sendOwner(LLUUID::null, LLUUID::null); } void LLPanelPermissions::onClickGroup() { LLUUID owner_id; std::string name; - BOOL owners_identical = LLSelectMgr::getInstanceFast()->selectGetOwner(owner_id, name); + BOOL owners_identical = LLSelectMgr::getInstance()->selectGetOwner(owner_id, name); LLFloater* parent_floater = gFloaterView->getParentFloater(this); if(owners_identical && (owner_id == gAgent.getID())) @@ -1211,7 +1211,7 @@ void LLPanelPermissions::cbGroupID(LLUUID group_id) { mLabelGroupName->setNameID(group_id, TRUE); } - LLSelectMgr::getInstanceFast()->sendGroup(group_id); + LLSelectMgr::getInstance()->sendGroup(group_id); } bool callback_deed_to_group(const LLSD& notification, const LLSD& response) @@ -1220,10 +1220,10 @@ bool callback_deed_to_group(const LLSD& notification, const LLSD& response) if (0 == option) { LLUUID group_id; - BOOL groups_identical = LLSelectMgr::getInstanceFast()->selectGetGroup(group_id); + BOOL groups_identical = LLSelectMgr::getInstance()->selectGetGroup(group_id); if(group_id.notNull() && groups_identical && (gAgent.hasPowerInGroup(group_id, GP_OBJECT_DEED))) { - LLSelectMgr::getInstanceFast()->sendOwner(LLUUID::null, group_id, FALSE); + LLSelectMgr::getInstance()->sendOwner(LLUUID::null, group_id, FALSE); } } return false; @@ -1241,7 +1241,7 @@ void LLPanelPermissions::onClickDeedToGroup(void* data) // static void LLPanelPermissions::onCommitPerm(LLUICtrl *ctrl, void *data, U8 field, U32 perm) { - LLViewerObject* object = LLSelectMgr::getInstanceFast()->getSelection()->getFirstRootObject(); + LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getFirstRootObject(); if(!object) return; // Checkbox will have toggled itself @@ -1249,7 +1249,7 @@ void LLPanelPermissions::onCommitPerm(LLUICtrl *ctrl, void *data, U8 field, U32 LLCheckBoxCtrl *check = (LLCheckBoxCtrl *)ctrl; BOOL new_state = check->get(); - LLSelectMgr::getInstanceFast()->selectionSetObjectPermissions(field, new_state, perm); + LLSelectMgr::getInstance()->selectionSetObjectPermissions(field, new_state, perm); } // static @@ -1308,8 +1308,8 @@ void LLPanelPermissions::onCommitName(LLUICtrl*, void* data) { return; } - LLSelectMgr::getInstanceFast()->selectionSetObjectName(tb->getText()); - LLObjectSelectionHandle selection = LLSelectMgr::getInstanceFast()->getSelection(); + LLSelectMgr::getInstance()->selectionSetObjectName(tb->getText()); + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); if (selection->isAttachment() && (selection->getNumNodes() == 1) && !tb->getText().empty()) { LLUUID object_id = selection->getFirstObject()->getAttachmentItemID(); @@ -1335,8 +1335,8 @@ void LLPanelPermissions::onCommitDesc(LLUICtrl*, void* data) { return; } - LLSelectMgr::getInstanceFast()->selectionSetObjectDescription(le->getText()); - LLObjectSelectionHandle selection = LLSelectMgr::getInstanceFast()->getSelection(); + LLSelectMgr::getInstance()->selectionSetObjectDescription(le->getText()); + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); if (selection->isAttachment() && (selection->getNumNodes() == 1)) { LLUUID object_id = selection->getFirstObject()->getAttachmentItemID(); @@ -1388,7 +1388,7 @@ void LLPanelPermissions::setAllSaleInfo() if (price < 0) sale_type = LLSaleInfo::FS_NOT; - LLSelectMgr* select_mgr = LLSelectMgr::getInstanceFast(); + LLSelectMgr* select_mgr = LLSelectMgr::getInstance(); LLSaleInfo old_sale_info; select_mgr->selectGetSaleInfo(old_sale_info); @@ -1449,14 +1449,14 @@ void LLPanelPermissions::onCommitClickAction(LLUICtrl* ctrl, void*) if (click_action == CLICK_ACTION_BUY) { LLSaleInfo sale_info; - LLSelectMgr::getInstanceFast()->selectGetSaleInfo(sale_info); + LLSelectMgr::getInstance()->selectGetSaleInfo(sale_info); if (!sale_info.isForSale()) { LLNotificationsUtil::add("CantSetBuyObject"); // Set click action back to its old value U8 click_action = 0; - LLSelectMgr::getInstanceFast()->selectionGetClickAction(&click_action); + LLSelectMgr::getInstance()->selectionGetClickAction(&click_action); std::string item_value = click_action_to_string_value(click_action); box->setValue(LLSD(item_value)); return; @@ -1466,14 +1466,14 @@ void LLPanelPermissions::onCommitClickAction(LLUICtrl* ctrl, void*) { // Verify object has script with money() handler LLSelectionPayable payable; - bool can_pay = LLSelectMgr::getInstanceFast()->getSelection()->applyToObjects(&payable); + bool can_pay = LLSelectMgr::getInstance()->getSelection()->applyToObjects(&payable); if (!can_pay) { // Warn, but do it anyway. LLNotificationsUtil::add("ClickActionNotPayable"); } } - LLSelectMgr::getInstanceFast()->selectionSetClickAction(click_action); + LLSelectMgr::getInstance()->selectionSetClickAction(click_action); } // static @@ -1482,7 +1482,7 @@ void LLPanelPermissions::onCommitIncludeInSearch(LLUICtrl* ctrl, void*) LLCheckBoxCtrl* box = (LLCheckBoxCtrl*)ctrl; llassert(box); - LLSelectMgr::getInstanceFast()->selectionSetIncludeInSearch(box->get()); + LLSelectMgr::getInstance()->selectionSetIncludeInSearch(box->get()); } diff --git a/indra/newview/llpanelpick.cpp b/indra/newview/llpanelpick.cpp deleted file mode 100644 index a813417846e14864896fd4116ba67fdd27ab3f76..0000000000000000000000000000000000000000 --- a/indra/newview/llpanelpick.cpp +++ /dev/null @@ -1,620 +0,0 @@ -/** - * @file llpanelpick.cpp - * @brief LLPanelPick class implementation - * - * $LicenseInfo:firstyear=2004&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$ - */ - -// Display of a "Top Pick" used both for the global top picks in the -// Find directory, and also for each individual user's picks in their -// profile. - -#include "llviewerprecompiledheaders.h" - -#include "llpanelpick.h" - -#include "message.h" - -#include "llparcel.h" - -#include "llbutton.h" -#include "llfloaterreg.h" -#include "lliconctrl.h" -#include "lllineeditor.h" -#include "llpanel.h" -#include "llscrollcontainer.h" -#include "lltexteditor.h" - -#include "llagent.h" -#include "llagentpicksinfo.h" -#include "llavatarpropertiesprocessor.h" -#include "llfloaterworldmap.h" -#include "lltexturectrl.h" -#include "lluiconstants.h" -#include "llviewerparcelmgr.h" -#include "llviewerregion.h" -#include "llworldmap.h" - - -#define XML_PANEL_EDIT_PICK "panel_edit_pick.xml" -#define XML_PANEL_PICK_INFO "panel_pick_info.xml" - -#define XML_NAME "pick_name" -#define XML_DESC "pick_desc" -#define XML_SNAPSHOT "pick_snapshot" -#define XML_LOCATION "pick_location" - -#define XML_BTN_ON_TXTR "edit_icon" -#define XML_BTN_SAVE "save_changes_btn" - -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// - -//static -LLPanelPickInfo* LLPanelPickInfo::create() -{ - LLPanelPickInfo* panel = new LLPanelPickInfo(); - panel->buildFromFile(XML_PANEL_PICK_INFO); - return panel; -} - -LLPanelPickInfo::LLPanelPickInfo() - : LLPanel() - , LLAvatarPropertiesObserver() - , LLRemoteParcelInfoObserver() - , mAvatarId(LLUUID::null) - , mSnapshotCtrl(NULL) - , mPickId(LLUUID::null) - , mParcelId(LLUUID::null) - , mRequestedId(LLUUID::null) - , mScrollingPanelMinHeight(0) - , mScrollingPanelWidth(0) - , mScrollingPanel(NULL) - , mScrollContainer(NULL) -{ -} - -LLPanelPickInfo::~LLPanelPickInfo() -{ - LLAvatarPropertiesProcessor::getInstanceFast()->removeObserver(getAvatarId(), this); - - if (mParcelId.notNull()) - { - LLRemoteParcelInfoProcessor::getInstanceFast()->removeObserver(mParcelId, this); - } -} - -void LLPanelPickInfo::onOpen(const LLSD& key) -{ - LLUUID avatar_id = key["avatar_id"]; - if(avatar_id.isNull()) - { - return; - } - - if(getAvatarId().notNull()) - { - LLAvatarPropertiesProcessor::getInstanceFast()->removeObserver( - getAvatarId(), this); - } - - setAvatarId(avatar_id); - - resetData(); - resetControls(); - - setPickId(key["pick_id"]); - setPickName(key["pick_name"]); - setPickDesc(key["pick_desc"]); - setSnapshotId(key["snapshot_id"]); - - LLAvatarPropertiesProcessor::getInstanceFast()->addObserver( - getAvatarId(), this); - LLAvatarPropertiesProcessor::getInstanceFast()->sendPickInfoRequest( - getAvatarId(), getPickId()); -} - -BOOL LLPanelPickInfo::postBuild() -{ - mSnapshotCtrl = getChild<LLTextureCtrl>(XML_SNAPSHOT); - - childSetAction("teleport_btn", boost::bind(&LLPanelPickInfo::onClickTeleport, this)); - childSetAction("show_on_map_btn", boost::bind(&LLPanelPickInfo::onClickMap, this)); - childSetAction("back_btn", boost::bind(&LLPanelPickInfo::onClickBack, this)); - - mScrollingPanel = getChild<LLPanel>("scroll_content_panel"); - mScrollContainer = getChild<LLScrollContainer>("profile_scroll"); - - mScrollingPanelMinHeight = mScrollContainer->getScrolledViewRect().getHeight(); - mScrollingPanelWidth = mScrollingPanel->getRect().getWidth(); - - LLTextEditor* text_desc = getChild<LLTextEditor>(XML_DESC); - text_desc->setContentTrusted(false); - - return TRUE; -} - -void LLPanelPickInfo::reshape(S32 width, S32 height, BOOL called_from_parent) -{ - LLPanel::reshape(width, height, called_from_parent); - - if (!mScrollContainer || !mScrollingPanel) - return; - - static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0); - - S32 scroll_height = mScrollContainer->getRect().getHeight(); - if (mScrollingPanelMinHeight >= scroll_height) - { - mScrollingPanel->reshape(mScrollingPanelWidth, mScrollingPanelMinHeight); - } - else - { - mScrollingPanel->reshape(mScrollingPanelWidth + scrollbar_size, scroll_height); - } -} - -void LLPanelPickInfo::processProperties(void* data, EAvatarProcessorType type) -{ - if(APT_PICK_INFO != type) - { - return; - } - LLPickData* pick_info = static_cast<LLPickData*>(data); - if(!pick_info - || pick_info->creator_id != getAvatarId() - || pick_info->pick_id != getPickId()) - { - return; - } - - mParcelId = pick_info->parcel_id; - setSnapshotId(pick_info->snapshot_id); - setPickName(pick_info->name); - setPickDesc(pick_info->desc); - setPosGlobal(pick_info->pos_global); - - // Send remote parcel info request to get parcel name and sim (region) name. - sendParcelInfoRequest(); - - // *NOTE dzaporozhan - // We want to keep listening to APT_PICK_INFO because user may - // edit the Pick and we have to update Pick info panel. - // revomeObserver is called from onClickBack -} - -void LLPanelPickInfo::sendParcelInfoRequest() -{ - if (mParcelId != mRequestedId) - { - LLRemoteParcelInfoProcessor::getInstance()->addObserver(mParcelId, this); - LLRemoteParcelInfoProcessor::getInstance()->sendParcelInfoRequest(mParcelId); - - mRequestedId = mParcelId; - } -} - -void LLPanelPickInfo::setExitCallback(const commit_callback_t& cb) -{ - getChild<LLButton>("back_btn")->setClickedCallback(cb); -} - -void LLPanelPickInfo::processParcelInfo(const LLParcelData& parcel_data) -{ - setPickLocation(createLocationText(LLStringUtil::null, parcel_data.name, - parcel_data.sim_name, getPosGlobal())); - - // We have received parcel info for the requested ID so clear it now. - mRequestedId.setNull(); - - if (mParcelId.notNull()) - { - LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelId, this); - } -} - -void LLPanelPickInfo::setEditPickCallback(const commit_callback_t& cb) -{ - getChild<LLButton>("edit_btn")->setClickedCallback(cb); -} - -// PROTECTED AREA - -void LLPanelPickInfo::resetControls() -{ - if(getAvatarId() == gAgent.getID()) - { - getChildView("edit_btn")->setEnabled(TRUE); - getChildView("edit_btn")->setVisible( TRUE); - } - else - { - getChildView("edit_btn")->setEnabled(FALSE); - getChildView("edit_btn")->setVisible( FALSE); - } -} - -void LLPanelPickInfo::resetData() -{ - setPickName(LLStringUtil::null); - setPickDesc(LLStringUtil::null); - setPickLocation(LLStringUtil::null); - setPickId(LLUUID::null); - setSnapshotId(LLUUID::null); - mPosGlobal.clearVec(); - mParcelId.setNull(); - mRequestedId.setNull(); -} - -// static -std::string LLPanelPickInfo::createLocationText(const std::string& owner_name, const std::string& original_name, const std::string& sim_name, const LLVector3d& pos_global) -{ - std::string location_text; - location_text.append(owner_name); - if (!original_name.empty()) - { - if (!location_text.empty()) location_text.append(", "); - location_text.append(original_name); - - } - if (!sim_name.empty()) - { - if (!location_text.empty()) location_text.append(", "); - location_text.append(sim_name); - } - - if (!location_text.empty()) location_text.append(" "); - - if (!pos_global.isNull()) - { - S32 region_x = ll_round((F32)pos_global.mdV[VX]) % REGION_WIDTH_UNITS; - S32 region_y = ll_round((F32)pos_global.mdV[VY]) % REGION_WIDTH_UNITS; - S32 region_z = ll_round((F32)pos_global.mdV[VZ]); - location_text.append(llformat(" (%d, %d, %d)", region_x, region_y, region_z)); - } - return location_text; -} - -void LLPanelPickInfo::setSnapshotId(const LLUUID& id) -{ - mSnapshotCtrl->setImageAssetID(id); - mSnapshotCtrl->setValid(TRUE); -} - -void LLPanelPickInfo::setPickName(const std::string& name) -{ - getChild<LLUICtrl>(XML_NAME)->setValue(name); -} - -void LLPanelPickInfo::setPickDesc(const std::string& desc) -{ - getChild<LLUICtrl>(XML_DESC)->setValue(desc); -} - -void LLPanelPickInfo::setPickLocation(const std::string& location) -{ - getChild<LLUICtrl>(XML_LOCATION)->setValue(location); -} - -void LLPanelPickInfo::onClickMap() -{ - LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal()); - LLFloaterReg::showInstance("world_map", "center"); -} - -void LLPanelPickInfo::onClickTeleport() -{ - if (!getPosGlobal().isExactlyZero()) - { - gAgent.teleportViaLocation(getPosGlobal()); - LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal()); - } -} - -void LLPanelPickInfo::onClickBack() -{ - LLAvatarPropertiesProcessor::getInstanceFast()->removeObserver(getAvatarId(), this); -} - -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// - -//static -LLPanelPickEdit* LLPanelPickEdit::create() -{ - LLPanelPickEdit* panel = new LLPanelPickEdit(); - panel->buildFromFile(XML_PANEL_EDIT_PICK); - return panel; -} - -LLPanelPickEdit::LLPanelPickEdit() - : LLPanelPickInfo() - , mLocationChanged(false) - , mNeedData(true) - , mNewPick(false) -{ -} - -LLPanelPickEdit::~LLPanelPickEdit() -{ -} - -void LLPanelPickEdit::onOpen(const LLSD& key) -{ - LLUUID pick_id = key["pick_id"]; - mNeedData = true; - - // creating new Pick - if(pick_id.isNull()) - { - mNewPick = true; - - setAvatarId(gAgent.getID()); - - resetData(); - resetControls(); - - setPosGlobal(gAgent.getPositionGlobal()); - - LLUUID parcel_id = LLUUID::null, snapshot_id = LLUUID::null; - std::string pick_name, pick_desc, region_name; - - LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); - if(parcel) - { - parcel_id = parcel->getID(); - pick_name = parcel->getName(); - pick_desc = parcel->getDesc(); - snapshot_id = parcel->getSnapshotID(); - } - - LLViewerRegion* region = gAgent.getRegion(); - if(region) - { - region_name = region->getName(); - } - - setParcelID(parcel_id); - getChild<LLUICtrl>("pick_name")->setValue(pick_name.empty() ? region_name : pick_name); - getChild<LLUICtrl>("pick_desc")->setValue(pick_desc); - setSnapshotId(snapshot_id); - setPickLocation(createLocationText(getLocationNotice(), pick_name, region_name, getPosGlobal())); - - enableSaveButton(true); - } - // editing existing pick - else - { - mNewPick = false; - LLPanelPickInfo::onOpen(key); - - enableSaveButton(false); - } - - resetDirty(); -} - -void LLPanelPickEdit::setPickData(const LLPickData* pick_data) -{ - if(!pick_data) - { - return; - } - - mNeedData = false; - - setParcelID(pick_data->parcel_id); - getChild<LLUICtrl>("pick_name")->setValue(pick_data->name); - getChild<LLUICtrl>("pick_desc")->setValue(pick_data->desc); - setSnapshotId(pick_data->snapshot_id); - setPosGlobal(pick_data->pos_global); - setPickLocation(createLocationText(LLStringUtil::null, pick_data->name, - pick_data->sim_name, pick_data->pos_global)); -} - -BOOL LLPanelPickEdit::postBuild() -{ - LLPanelPickInfo::postBuild(); - - mSnapshotCtrl->setCommitCallback(boost::bind(&LLPanelPickEdit::onSnapshotChanged, this)); - - LLLineEditor* line_edit = getChild<LLLineEditor>("pick_name"); - line_edit->setKeystrokeCallback(boost::bind(&LLPanelPickEdit::onPickChanged, this, _1), NULL); - - LLTextEditor* text_edit = getChild<LLTextEditor>("pick_desc"); - text_edit->setKeystrokeCallback(boost::bind(&LLPanelPickEdit::onPickChanged, this, _1)); - - childSetAction(XML_BTN_SAVE, boost::bind(&LLPanelPickEdit::onClickSave, this)); - childSetAction("set_to_curr_location_btn", boost::bind(&LLPanelPickEdit::onClickSetLocation, this)); - - initTexturePickerMouseEvents(); - - return TRUE; -} - -void LLPanelPickEdit::setSaveCallback(const commit_callback_t& cb) -{ - getChild<LLButton>("save_changes_btn")->setClickedCallback(cb); -} - -void LLPanelPickEdit::setCancelCallback(const commit_callback_t& cb) -{ - getChild<LLButton>("cancel_btn")->setClickedCallback(cb); -} - -void LLPanelPickEdit::resetDirty() -{ - LLPanelPickInfo::resetDirty(); - - getChild<LLLineEditor>("pick_name")->resetDirty(); - getChild<LLTextEditor>("pick_desc")->resetDirty(); - mSnapshotCtrl->resetDirty(); - mLocationChanged = false; -} - -BOOL LLPanelPickEdit::isDirty() const -{ - if( mNewPick - || LLPanelPickInfo::isDirty() - || mLocationChanged - || mSnapshotCtrl->isDirty() - || getChild<LLLineEditor>("pick_name")->isDirty() - || getChild<LLTextEditor>("pick_desc")->isDirty()) - { - return TRUE; - } - return FALSE; -} - -// PROTECTED AREA - -void LLPanelPickEdit::sendUpdate() -{ - LLPickData pick_data; - - // If we don't have a pick id yet, we'll need to generate one, - // otherwise we'll keep overwriting pick_id 00000 in the database. - if (getPickId().isNull()) - { - getPickId().generate(); - } - - pick_data.agent_id = gAgent.getID(); - pick_data.session_id = gAgent.getSessionID(); - pick_data.pick_id = getPickId(); - pick_data.creator_id = gAgent.getID();; - - //legacy var need to be deleted - pick_data.top_pick = FALSE; - pick_data.parcel_id = mParcelId; - pick_data.name = getChild<LLUICtrl>(XML_NAME)->getValue().asString(); - pick_data.desc = getChild<LLUICtrl>(XML_DESC)->getValue().asString(); - pick_data.snapshot_id = mSnapshotCtrl->getImageAssetID(); - pick_data.pos_global = getPosGlobal(); - pick_data.sort_order = 0; - pick_data.enabled = TRUE; - - LLAvatarPropertiesProcessor::instance().sendPickInfoUpdate(&pick_data); - - if(mNewPick) - { - // Assume a successful create pick operation, make new number of picks - // available immediately. Actual number of picks will be requested in - // LLAvatarPropertiesProcessor::sendPickInfoUpdate and updated upon server respond. - LLAgentPicksInfo::getInstance()->incrementNumberOfPicks(); - } -} - -void LLPanelPickEdit::onSnapshotChanged() -{ - enableSaveButton(true); -} - -void LLPanelPickEdit::onPickChanged(LLUICtrl* ctrl) -{ - enableSaveButton(isDirty()); -} - -void LLPanelPickEdit::resetData() -{ - LLPanelPickInfo::resetData(); - mLocationChanged = false; -} - -void LLPanelPickEdit::enableSaveButton(bool enable) -{ - getChildView(XML_BTN_SAVE)->setEnabled(enable); -} - -void LLPanelPickEdit::onClickSetLocation() -{ - // Save location for later use. - setPosGlobal(gAgent.getPositionGlobal()); - - std::string parcel_name, region_name; - - LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); - if (parcel) - { - mParcelId = parcel->getID(); - parcel_name = parcel->getName(); - } - - LLViewerRegion* region = gAgent.getRegion(); - if(region) - { - region_name = region->getName(); - } - - setPickLocation(createLocationText(getLocationNotice(), parcel_name, region_name, getPosGlobal())); - - mLocationChanged = true; - enableSaveButton(TRUE); -} - -void LLPanelPickEdit::onClickSave() -{ - sendUpdate(); - - mLocationChanged = false; - - LLSD params; - params["action"] = "save_new_pick"; - notifyParent(params); -} - -std::string LLPanelPickEdit::getLocationNotice() -{ - static std::string notice = getString("location_notice"); - return notice; -} - -void LLPanelPickEdit::processProperties(void* data, EAvatarProcessorType type) -{ - if(mNeedData) - { - LLPanelPickInfo::processProperties(data, type); - } -} - -// PRIVATE AREA - -void LLPanelPickEdit::initTexturePickerMouseEvents() -{ - text_icon = getChild<LLIconCtrl>(XML_BTN_ON_TXTR); - mSnapshotCtrl->setMouseEnterCallback(boost::bind(&LLPanelPickEdit::onTexturePickerMouseEnter, this, _1)); - mSnapshotCtrl->setMouseLeaveCallback(boost::bind(&LLPanelPickEdit::onTexturePickerMouseLeave, this, _1)); - - text_icon->setVisible(FALSE); -} - -void LLPanelPickEdit::onTexturePickerMouseEnter(LLUICtrl* ctrl) -{ - text_icon->setVisible(TRUE); -} - -void LLPanelPickEdit::onTexturePickerMouseLeave(LLUICtrl* ctrl) -{ - text_icon->setVisible(FALSE); -} diff --git a/indra/newview/llpanelpick.h b/indra/newview/llpanelpick.h deleted file mode 100644 index 7a8bd66fcfe2420a503b3be2b8a107339ed9a62e..0000000000000000000000000000000000000000 --- a/indra/newview/llpanelpick.h +++ /dev/null @@ -1,264 +0,0 @@ -/** - * @file llpanelpick.h - * @brief LLPanelPick class definition - * - * $LicenseInfo:firstyear=2004&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$ - */ - -// Display of a "Top Pick" used both for the global top picks in the -// Find directory, and also for each individual user's picks in their -// profile. - -#ifndef LL_LLPANELPICK_H -#define LL_LLPANELPICK_H - -#include "llpanel.h" -#include "llremoteparcelrequest.h" -#include "llavatarpropertiesprocessor.h" - -class LLIconCtrl; -class LLTextureCtrl; -class LLScrollContainer; -class LLMessageSystem; -class LLAvatarPropertiesObserver; - -/** - * Panel for displaying Pick Information - snapshot, name, description, etc. - */ -class LLPanelPickInfo : public LLPanel, public LLAvatarPropertiesObserver, LLRemoteParcelInfoObserver -{ - LOG_CLASS(LLPanelPickInfo); -public: - - // Creates new panel - static LLPanelPickInfo* create(); - - virtual ~LLPanelPickInfo(); - - /** - * Initializes panel properties - * - * By default Pick will be created for current Agent location. - * Use setPickData to change Pick properties. - */ - /*virtual*/ void onOpen(const LLSD& key); - - /*virtual*/ BOOL postBuild(); - - /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); - - /*virtual*/ void processProperties(void* data, EAvatarProcessorType type); - - /** - * Sends remote parcel info request to resolve parcel name from its ID. - */ - void sendParcelInfoRequest(); - - /** - * Sets "Back" button click callback - */ - virtual void setExitCallback(const commit_callback_t& cb); - - /** - * Sets "Edit" button click callback - */ - virtual void setEditPickCallback(const commit_callback_t& cb); - - //This stuff we got from LLRemoteParcelObserver, in the last one we intentionally do nothing - /*virtual*/ void processParcelInfo(const LLParcelData& parcel_data); - /*virtual*/ void setParcelID(const LLUUID& parcel_id) { mParcelId = parcel_id; } - /*virtual*/ void setErrorStatus(S32 status, const std::string& reason) {}; - -protected: - - LLPanelPickInfo(); - - /** - * Resets Pick information - */ - virtual void resetData(); - - /** - * Resets UI controls (visibility, values) - */ - virtual void resetControls(); - - /** - * "Location text" is actually the owner name, the original - * name that owner gave the parcel, and the location. - */ - static std::string createLocationText( - const std::string& owner_name, - const std::string& original_name, - const std::string& sim_name, - const LLVector3d& pos_global); - - virtual void setAvatarId(const LLUUID& avatar_id) { mAvatarId = avatar_id; } - virtual LLUUID& getAvatarId() { return mAvatarId; } - - /** - * Sets snapshot id. - * - * Will mark snapshot control as valid if id is not null. - * Will mark snapshot control as invalid if id is null. If null id is a valid value, - * you have to manually mark snapshot is valid. - */ - virtual void setSnapshotId(const LLUUID& id); - - virtual void setPickId(const LLUUID& id) { mPickId = id; } - virtual LLUUID& getPickId() { return mPickId; } - - virtual void setPickName(const std::string& name); - - virtual void setPickDesc(const std::string& desc); - - virtual void setPickLocation(const std::string& location); - - virtual void setPosGlobal(const LLVector3d& pos) { mPosGlobal = pos; } - virtual LLVector3d& getPosGlobal() { return mPosGlobal; } - - /** - * Callback for "Map" button, opens Map - */ - void onClickMap(); - - /** - * Callback for "Teleport" button, teleports user to Pick location. - */ - void onClickTeleport(); - - void onClickBack(); - -protected: - - S32 mScrollingPanelMinHeight; - S32 mScrollingPanelWidth; - LLScrollContainer* mScrollContainer; - LLPanel* mScrollingPanel; - LLTextureCtrl* mSnapshotCtrl; - - LLUUID mAvatarId; - LLVector3d mPosGlobal; - LLUUID mParcelId; - LLUUID mPickId; - LLUUID mRequestedId; -}; - -/** - * Panel for creating/editing Pick. - */ -class LLPanelPickEdit : public LLPanelPickInfo -{ - LOG_CLASS(LLPanelPickEdit); -public: - - /** - * Creates new panel - */ - static LLPanelPickEdit* create(); - - /*virtual*/ ~LLPanelPickEdit(); - - /*virtual*/ void onOpen(const LLSD& key); - - virtual void setPickData(const LLPickData* pick_data); - - /*virtual*/ BOOL postBuild(); - - /** - * Sets "Save" button click callback - */ - virtual void setSaveCallback(const commit_callback_t& cb); - - /** - * Sets "Cancel" button click callback - */ - virtual void setCancelCallback(const commit_callback_t& cb); - - /** - * Resets panel and all cantrols to unedited state - */ - /*virtual*/ void resetDirty(); - - /** - * Returns true if any of Pick properties was changed by user. - */ - /*virtual*/ BOOL isDirty() const; - - /*virtual*/ void processProperties(void* data, EAvatarProcessorType type); - -protected: - - LLPanelPickEdit(); - - /** - * Sends Pick properties to server. - */ - void sendUpdate(); - - /** - * Called when snapshot image changes. - */ - void onSnapshotChanged(); - - /** - * Callback for Pick snapshot, name and description changed event. - */ - void onPickChanged(LLUICtrl* ctrl); - - /*virtual*/ void resetData(); - - /** - * Enables/disables "Save" button - */ - void enableSaveButton(bool enable); - - /** - * Callback for "Set Location" button click - */ - void onClickSetLocation(); - - /** - * Callback for "Save" button click - */ - void onClickSave(); - - std::string getLocationNotice(); - -protected: - - bool mLocationChanged; - bool mNeedData; - bool mNewPick; - -private: - - void initTexturePickerMouseEvents(); - void onTexturePickerMouseEnter(LLUICtrl* ctrl); - void onTexturePickerMouseLeave(LLUICtrl* ctrl); - -private: - - LLIconCtrl* text_icon; -}; - -#endif // LL_LLPANELPICK_H diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp index f4ad490f0b684a9e328c8cc1073962928e3645f9..bbd0a4573ce4f39906f5cba4f3b305c469914f2d 100644 --- a/indra/newview/llpanelplaceinfo.cpp +++ b/indra/newview/llpanelplaceinfo.cpp @@ -27,6 +27,8 @@ #include "llviewerprecompiledheaders.h" #include "llpanelplaceinfo.h" +#include "llfloaterprofile.h" +#include "llfloaterreg.h" #include "llavatarname.h" #include "llsdutil.h" @@ -42,7 +44,6 @@ #include "llagent.h" #include "llexpandabletextbox.h" -#include "llpanelpick.h" #include "llslurl.h" #include "lltexturectrl.h" #include "llviewerregion.h" @@ -309,7 +310,7 @@ void LLPanelPlaceInfo::reshape(S32 width, S32 height, BOOL called_from_parent) } } -void LLPanelPlaceInfo::createPick(const LLVector3d& pos_global, LLPanelPickEdit* pick_panel) +void LLPanelPlaceInfo::createPick(const LLVector3d& pos_global) { LLPickData data; data.pos_global = pos_global; @@ -318,7 +319,12 @@ void LLPanelPlaceInfo::createPick(const LLVector3d& pos_global, LLPanelPickEdit* data.desc = mDescEditor->getText(); data.snapshot_id = mSnapshotCtrl->getImageAssetID(); data.parcel_id = mParcelID; - pick_panel->setPickData(&data); + + LLFloaterProfile* profile_floater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", gAgentID))); + if (profile_floater) + { + profile_floater->createPick(data); + } } // static diff --git a/indra/newview/llpanelplaceinfo.h b/indra/newview/llpanelplaceinfo.h index d4291a96f170aef398af9f8767eeacfde39ddbb5..669dba36bdce5a2409a080bf043beddab90918ee 100644 --- a/indra/newview/llpanelplaceinfo.h +++ b/indra/newview/llpanelplaceinfo.h @@ -38,7 +38,6 @@ class LLAvatarName; class LLExpandableTextBox; class LLIconCtrl; class LLInventoryItem; -class LLPanelPickEdit; class LLParcel; class LLScrollContainer; class LLTextBox; @@ -95,7 +94,7 @@ class LLPanelPlaceInfo : public LLPanel, LLRemoteParcelInfoObserver // Create a pick for the location specified // by global_pos. - void createPick(const LLVector3d& pos_global, LLPanelPickEdit* pick_panel); + void createPick(const LLVector3d& pos_global); protected: static void onNameCache(LLTextBox* text, const std::string& full_name); diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp index 34932e15daa1c6f41564334fff156434964da9c2..1ce91baa23b85499a7b336039499536e97fa462b 100644 --- a/indra/newview/llpanelplaces.cpp +++ b/indra/newview/llpanelplaces.cpp @@ -63,7 +63,6 @@ #include "lllayoutstack.h" #include "llpanellandmarkinfo.h" #include "llpanellandmarks.h" -#include "llpanelpick.h" #include "llpanelplaceprofile.h" #include "llpanelteleporthistory.h" #include "llremoteparcelrequest.h" @@ -238,7 +237,6 @@ LLPanelPlaces::LLPanelPlaces() mFilterEditor(NULL), mPlaceProfile(NULL), mLandmarkInfo(NULL), - mPickPanel(NULL), mItem(NULL), mPlaceMenu(NULL), mLandmarkMenu(NULL), @@ -953,28 +951,11 @@ void LLPanelPlaces::onOverflowMenuItemClicked(const LLSD& param) } else if (item == "pick") { - if (mPickPanel == NULL) - { - mPickPanel = LLPanelPickEdit::create(); - addChild(mPickPanel); - - mPickPanel->setExitCallback(boost::bind(&LLPanelPlaces::togglePickPanel, this, FALSE)); - mPickPanel->setCancelCallback(boost::bind(&LLPanelPlaces::togglePickPanel, this, FALSE)); - mPickPanel->setSaveCallback(boost::bind(&LLPanelPlaces::togglePickPanel, this, FALSE)); - } - - togglePickPanel(TRUE); - mPickPanel->onOpen(LLSD()); - LLPanelPlaceInfo* panel = getCurrentInfoPanel(); if (panel) { - panel->createPick(mPosGlobal, mPickPanel); + panel->createPick(mPosGlobal); } - - LLRect rect = getRect(); - mPickPanel->reshape(rect.getWidth(), rect.getHeight()); - mPickPanel->setRect(rect); } else if (item == "add_to_favbar") { @@ -1051,17 +1032,6 @@ bool LLPanelPlaces::handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_t return false; } -void LLPanelPlaces::togglePickPanel(BOOL visible) -{ - if (mPickPanel) - { - mPickPanel->setVisible(visible); - mPlaceProfile->setVisible(!visible); - updateVerbs(); - } - -} - void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible) { if (!mPlaceProfile || !mLandmarkInfo) @@ -1310,15 +1280,11 @@ void LLPanelPlaces::updateVerbs() bool is_agent_place_info_visible = mPlaceInfoType == AGENT_INFO_TYPE; bool is_create_landmark_visible = mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE; - bool is_pick_panel_visible = false; - if(mPickPanel) - { - is_pick_panel_visible = mPickPanel->isInVisibleChain(); - } + bool have_3d_pos = ! mPosGlobal.isExactlyZero(); - mTeleportBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn && !is_pick_panel_visible); - mShowOnMapBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn && !is_pick_panel_visible); + mTeleportBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn); + mShowOnMapBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn); mSaveBtn->setVisible(isLandmarkEditModeOn); mCancelBtn->setVisible(isLandmarkEditModeOn); mCloseBtn->setVisible(is_create_landmark_visible && !isLandmarkEditModeOn); diff --git a/indra/newview/llpanelplaces.h b/indra/newview/llpanelplaces.h index 3b87eb6cb9521ac15ecfa72d18e534eea1f3bfde..e554099343cd972caceaf38c619901897bfed3d5 100644 --- a/indra/newview/llpanelplaces.h +++ b/indra/newview/llpanelplaces.h @@ -38,7 +38,6 @@ class LLLandmark; class LLPanelLandmarkInfo; class LLPanelPlaceProfile; -class LLPanelPickEdit; class LLPanelPlaceInfo; class LLPanelPlacesTab; class LLParcelSelection; @@ -95,7 +94,6 @@ class LLPanelPlaces : public LLPanel void onOverflowButtonClicked(); void onOverflowMenuItemClicked(const LLSD& param); bool onOverflowMenuItemEnable(const LLSD& param); - void onCreateLandmarkButtonClicked(const LLUUID& folder_id); void onBackButtonClicked(); void onGearMenuClick(); void onSortingMenuClick(); @@ -103,9 +101,6 @@ class LLPanelPlaces : public LLPanel void onRemoveButtonClicked(); bool handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept); - - void toggleMediaPanel(); - void togglePickPanel(BOOL visible); void togglePlaceInfoPanel(BOOL visible); /*virtual*/ void onVisibilityChange(BOOL new_visibility); @@ -122,7 +117,6 @@ class LLPanelPlaces : public LLPanel LLPanelPlaceProfile* mPlaceProfile; LLPanelLandmarkInfo* mLandmarkInfo; - LLPanelPickEdit* mPickPanel; LLToggleableMenu* mPlaceMenu; LLToggleableMenu* mLandmarkMenu; diff --git a/indra/newview/llpanelprimmediacontrols.cpp b/indra/newview/llpanelprimmediacontrols.cpp index 598d3e67f24421175f6fb85b14a6cae996c97714..5503501a3eee6e3a9d7da3f1c9c112221b6dda90 100644 --- a/indra/newview/llpanelprimmediacontrols.cpp +++ b/indra/newview/llpanelprimmediacontrols.cpp @@ -268,7 +268,7 @@ void LLPanelPrimMediaControls::focusOnTarget() LLViewerMediaImpl* LLPanelPrimMediaControls::getTargetMediaImpl() { - return LLViewerMedia::getInstanceFast()->getMediaImplFromTextureID(mTargetImplID); + return LLViewerMedia::getInstance()->getMediaImplFromTextureID(mTargetImplID); } LLViewerObject* LLPanelPrimMediaControls::getTargetObject() diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 0f7825b6f6fc09b78ad0638adde5f61627795bae..a0752b9a698244e40c62a7008019a41d37f90406 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -2,9 +2,9 @@ * @file llpanelprofile.cpp * @brief Profile panel implementation * -* $LicenseInfo:firstyear=2009&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 @@ -29,6 +29,7 @@ // Common #include "llavatarnamecache.h" +#include "llsdutil.h" #include "llslurl.h" #include "lldateutil.h" //ageFromDate @@ -36,6 +37,7 @@ #include "llavatariconctrl.h" #include "llclipboard.h" #include "llcheckboxctrl.h" +#include "llcombobox.h" #include "lllineeditor.h" #include "llloadingindicator.h" #include "llmenubutton.h" @@ -45,6 +47,10 @@ #include "lltexturectrl.h" #include "lltoggleablemenu.h" #include "llgrouplist.h" +#include "llurlaction.h" + +// Image +#include "llimagej2c.h" // Newview #include "alavataractions.h" @@ -54,9 +60,13 @@ #include "llavatarpropertiesprocessor.h" #include "llcallingcard.h" #include "llcommandhandler.h" +#include "llfloaterprofiletexture.h" #include "llfloaterreg.h" +#include "llfloaterreporter.h" +#include "llfilepicker.h" #include "llfirstuse.h" #include "llgroupactions.h" +#include "lllogchat.h" #include "llmutelist.h" #include "llnotificationsutil.h" #include "llpanelblockedlist.h" @@ -65,6 +75,8 @@ #include "lltrans.h" #include "llviewercontrol.h" #include "llviewermenu.h" //is_agent_mappable +#include "llviewermenufile.h" +#include "llviewertexturelist.h" #include "llvoiceclient.h" #include "llweb.h" #include "rlvhandler.h" @@ -72,7 +84,6 @@ static LLPanelInjector<LLPanelProfileSecondLife> t_panel_profile_secondlife("panel_profile_secondlife"); static LLPanelInjector<LLPanelProfileWeb> t_panel_web("panel_profile_web"); -static LLPanelInjector<LLPanelProfileInterests> t_panel_interests("panel_profile_interests"); static LLPanelInjector<LLPanelProfilePicks> t_panel_picks("panel_profile_picks"); static LLPanelInjector<LLPanelProfileFirstLife> t_panel_firstlife("panel_profile_firstlife"); static LLPanelInjector<LLPanelProfileNotes> t_panel_notes("panel_profile_notes"); @@ -80,12 +91,367 @@ static LLPanelInjector<LLPanelProfile> t_panel_profile("panel_profile") static const std::string PANEL_SECONDLIFE = "panel_profile_secondlife"; static const std::string PANEL_WEB = "panel_profile_web"; -static const std::string PANEL_INTERESTS = "panel_profile_interests"; static const std::string PANEL_PICKS = "panel_profile_picks"; static const std::string PANEL_CLASSIFIEDS = "panel_profile_classifieds"; static const std::string PANEL_FIRSTLIFE = "panel_profile_firstlife"; static const std::string PANEL_NOTES = "panel_profile_notes"; +static const std::string PANEL_PROFILE_VIEW = "panel_profile_view"; + +static const std::string PROFILE_PROPERTIES_CAP = "AgentProfile"; +static const std::string PROFILE_IMAGE_UPLOAD_CAP = "UploadAgentProfileImage"; + + +////////////////////////////////////////////////////////////////////////// + +void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id) +{ + LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); + LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t + httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("request_avatar_properties_coro", httpPolicy)); + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + LLCore::HttpHeaders::ptr_t httpHeaders; + + LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); + httpOpts->setFollowRedirects(true); + + std::string finalUrl = cap_url + "/" + agent_id.asString(); + + LLSD result = httpAdapter->getAndSuspend(httpRequest, finalUrl, httpOpts, httpHeaders); + + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + LL_DEBUGS("AvatarProperties") << "Agent id: " << agent_id << " Result: " << httpResults << LL_ENDL; + + if (!status + || !result.has("id") + || agent_id != result["id"].asUUID()) + { + LL_WARNS("AvatarProperties") << "Failed to get agent information for id " << agent_id << LL_ENDL; + return; + } + + LLFloater* floater_profile = LLFloaterReg::findInstance("profile", LLSD().with("id", agent_id)); + if (!floater_profile) + { + // floater is dead, so panels are dead as well + return; + } + + LLPanel *panel = floater_profile->findChild<LLPanel>(PANEL_PROFILE_VIEW, TRUE); + LLPanelProfile *panel_profile = dynamic_cast<LLPanelProfile*>(panel); + if (!panel_profile) + { + LL_WARNS() << PANEL_PROFILE_VIEW << " not found" << LL_ENDL; + return; + } + + + // Avatar Data + + LLAvatarData *avatar_data = &panel_profile->mAvatarData; + std::string birth_date; + + avatar_data->agent_id = agent_id; + avatar_data->avatar_id = agent_id; + avatar_data->image_id = result["sl_image_id"].asUUID(); + avatar_data->fl_image_id = result["fl_image_id"].asUUID(); + avatar_data->partner_id = result["partner_id"].asUUID(); + avatar_data->about_text = result["sl_about_text"].asString(); + avatar_data->fl_about_text = result["fl_about_text"].asString(); + avatar_data->born_on = result["member_since"].asDate(); + avatar_data->profile_url = getProfileURL(agent_id.asString()); + + avatar_data->flags = 0; + + if (result["online"].asBoolean()) + { + avatar_data->flags |= AVATAR_ONLINE; + } + if (result["allow_publish"].asBoolean()) + { + avatar_data->flags |= AVATAR_ALLOW_PUBLISH; + } + if (result["identified"].asBoolean()) + { + avatar_data->flags |= AVATAR_IDENTIFIED; + } + if (result["transacted"].asBoolean()) + { + avatar_data->flags |= AVATAR_TRANSACTED; + } + + avatar_data->caption_index = 0; + if (result.has("charter_member")) // won't be present if "caption" is set + { + avatar_data->caption_index = result["charter_member"].asInteger(); + } + else if (result.has("caption")) + { + avatar_data->caption_text = result["caption"].asString(); + } + + panel = floater_profile->findChild<LLPanel>(PANEL_SECONDLIFE, TRUE); + LLPanelProfileSecondLife *panel_sl = dynamic_cast<LLPanelProfileSecondLife*>(panel); + if (panel_sl) + { + panel_sl->processProfileProperties(avatar_data); + } + + panel = floater_profile->findChild<LLPanel>(PANEL_WEB, TRUE); + LLPanelProfileWeb *panel_web = dynamic_cast<LLPanelProfileWeb*>(panel); + if (panel_web) + { + panel_web->setLoaded(); + } + + panel = floater_profile->findChild<LLPanel>(PANEL_FIRSTLIFE, TRUE); + LLPanelProfileFirstLife *panel_first = dynamic_cast<LLPanelProfileFirstLife*>(panel); + if (panel_first) + { + panel_first->processProperties(avatar_data); + } + + // Picks + + LLSD picks_array = result["picks"]; + LLAvatarPicks avatar_picks; + avatar_picks.agent_id = agent_id; // Not in use? + avatar_picks.target_id = agent_id; + + for (LLSD::array_const_iterator it = picks_array.beginArray(); it != picks_array.endArray(); ++it) + { + const LLSD& pick_data = *it; + avatar_picks.picks_list.emplace_back(pick_data["id"].asUUID(), pick_data["name"].asString()); + } + + panel = floater_profile->findChild<LLPanel>(PANEL_PICKS, TRUE); + LLPanelProfilePicks *panel_picks = dynamic_cast<LLPanelProfilePicks*>(panel); + if (panel_picks) + { + // Refresh pick limit before processing + LLAgentPicksInfo::getInstance()->onServerRespond(&avatar_picks); + panel_picks->processProperties(&avatar_picks); + } + + // Groups + + LLSD groups_array = result["groups"]; + LLAvatarGroups avatar_groups; + avatar_groups.agent_id = agent_id; // Not in use? + avatar_groups.avatar_id = agent_id; // target_id + + for (LLSD::array_const_iterator it = groups_array.beginArray(); it != groups_array.endArray(); ++it) + { + const LLSD& group_info = *it; + LLAvatarGroups::LLGroupData group_data; + group_data.group_powers = 0; // Not in use? + group_data.group_title = group_info["name"].asString(); // Missing data, not in use? + group_data.group_id = group_info["id"].asUUID(); + group_data.group_name = group_info["name"].asString(); + group_data.group_insignia_id = group_info["image_id"].asUUID(); + + avatar_groups.group_list.push_back(group_data); + } + + if (panel_sl) + { + panel_sl->processGroupProperties(&avatar_groups); + } + + // Notes + LLAvatarNotes avatar_notes; + + avatar_notes.agent_id = agent_id; + avatar_notes.target_id = agent_id; + avatar_notes.notes = result["notes"].asString(); + + panel = floater_profile->findChild<LLPanel>(PANEL_NOTES, TRUE); + LLPanelProfileNotes *panel_notes = dynamic_cast<LLPanelProfileNotes*>(panel); + if (panel_notes) + { + panel_notes->processProperties(&avatar_notes); + } +} + +//TODO: changes take two minutes to propagate! +// Add some storage that holds updated data for two minutes +// for new instances to reuse the data +// Profile data is only relevant to won avatar, but notes +// are for everybody +void put_avatar_properties_coro(std::string cap_url, LLUUID agent_id, LLSD data) +{ + LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); + LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t + httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("put_avatar_properties_coro", httpPolicy)); + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + LLCore::HttpHeaders::ptr_t httpHeaders; + + LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); + httpOpts->setFollowRedirects(true); + + std::string finalUrl = cap_url + "/" + agent_id.asString(); + + LLSD result = httpAdapter->putAndSuspend(httpRequest, finalUrl, data, httpOpts, httpHeaders); + + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + if (!status) + { + LL_WARNS("AvatarProperties") << "Failed to put agent information " << data << " for id " << agent_id << LL_ENDL; + return; + } + + LL_DEBUGS("AvatarProperties") << "Agent id: " << agent_id << " Data: " << data << " Result: " << httpResults << LL_ENDL; +} + +LLUUID post_profile_image(std::string cap_url, const LLSD &first_data, std::string path_to_image, LLHandle<LLPanel> *handle) +{ + LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); + LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t + httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("post_profile_image_coro", httpPolicy)); + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + LLCore::HttpHeaders::ptr_t httpHeaders; + + LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); + httpOpts->setFollowRedirects(true); + + LLSD result = httpAdapter->postAndSuspend(httpRequest, cap_url, first_data, httpOpts, httpHeaders); + + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + if (!status) + { + // todo: notification? + LL_WARNS("AvatarProperties") << "Failed to get uploader cap " << status.toString() << LL_ENDL; + return LLUUID::null; + } + if (!result.has("uploader")) + { + // todo: notification? + LL_WARNS("AvatarProperties") << "Failed to get uploader cap, response contains no data." << LL_ENDL; + return LLUUID::null; + } + std::string uploader_cap = result["uploader"].asString(); + if (uploader_cap.empty()) + { + LL_WARNS("AvatarProperties") << "Failed to get uploader cap, cap invalid." << LL_ENDL; + return LLUUID::null; + } + + // Upload the image + + LLCore::HttpRequest::ptr_t uploaderhttpRequest(new LLCore::HttpRequest); + LLCore::HttpHeaders::ptr_t uploaderhttpHeaders(new LLCore::HttpHeaders); + LLCore::HttpOptions::ptr_t uploaderhttpOpts(new LLCore::HttpOptions); + S64 length; + + { + llifstream instream(path_to_image.c_str(), std::iostream::binary | std::iostream::ate); + if (!instream.is_open()) + { + LL_WARNS("AvatarProperties") << "Failed to open file " << path_to_image << LL_ENDL; + return LLUUID::null; + } + length = instream.tellg(); + } + + uploaderhttpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, "application/jp2"); // optional + uploaderhttpHeaders->append(HTTP_OUT_HEADER_CONTENT_LENGTH, llformat("%d", length)); // required! + uploaderhttpOpts->setFollowRedirects(true); + + result = httpAdapter->postFileAndSuspend(uploaderhttpRequest, uploader_cap, path_to_image, uploaderhttpOpts, uploaderhttpHeaders); + + httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + LL_WARNS("AvatarProperties") << result << LL_ENDL; + + if (!status) + { + LL_WARNS("AvatarProperties") << "Failed to upload image " << status.toString() << LL_ENDL; + return LLUUID::null; + } + + if (result["state"].asString() != "complete") + { + if (result.has("message")) + { + LL_WARNS("AvatarProperties") << "Failed to upload image, state " << result["state"] << " message: " << result["message"] << LL_ENDL; + } + else + { + LL_WARNS("AvatarProperties") << "Failed to upload image " << result << LL_ENDL; + } + return LLUUID::null; + } + + return result["new_asset"].asUUID(); +} + +enum EProfileImageType +{ + PROFILE_IMAGE_SL, + PROFILE_IMAGE_FL, +}; + +void post_profile_image_coro(std::string cap_url, EProfileImageType type, std::string path_to_image, LLHandle<LLPanel> *handle) +{ + LLSD data; + switch (type) + { + case PROFILE_IMAGE_SL: + data["profile-image-asset"] = "sl_image_id"; + break; + case PROFILE_IMAGE_FL: + data["profile-image-asset"] = "fl_image_id"; + break; + } + + LLUUID result = post_profile_image(cap_url, data, path_to_image, handle); + + // reset loading indicator + if (!handle->isDead()) + { + switch (type) + { + case PROFILE_IMAGE_SL: + { + LLPanelProfileSecondLife* panel = static_cast<LLPanelProfileSecondLife*>(handle->get()); + if (result.notNull()) + { + panel->setProfileImageUploaded(result); + } + else + { + // failure, just stop progress indicator + panel->setProfileImageUploading(false); + } + break; + } + case PROFILE_IMAGE_FL: + { + LLPanelProfileFirstLife* panel = static_cast<LLPanelProfileFirstLife*>(handle->get()); + if (result.notNull()) + { + panel->setProfileImageUploaded(result); + } + else + { + // failure, just stop progress indicator + panel->setProfileImageUploading(false); + } + break; + } + } + } + // Cleanup + LLFile::remove(path_to_image); + delete handle; +} ////////////////////////////////////////////////////////////////////////// // LLProfileHandler @@ -151,7 +517,7 @@ class LLAgentHandler : public LLCommandHandler if (verb == "pay") { - if (!LLUI::getInstanceFast()->mSettingGroups["config"]->getBOOL("EnableAvatarPay")) + if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnableAvatarPay")) { LLNotificationsUtil::add("NoAvatarPay", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit")); return true; @@ -219,231 +585,471 @@ class LLAgentHandler : public LLCommandHandler } return true; } + + // reportAbuse is here due to convoluted avatar handling + // in LLScrollListCtrl and LLTextBase + if (verb == "reportAbuse" && web == NULL) + { + LLAvatarName av_name; + if (LLAvatarNameCache::get(avatar_id, &av_name)) + { + LLFloaterReporter::showFromAvatar(avatar_id, av_name.getCompleteName()); + } + else + { + LLFloaterReporter::showFromAvatar(avatar_id, "not avaliable"); + } + return true; + } return false; } }; LLAgentHandler gAgentHandler; +///---------------------------------------------------------------------------- +/// LLFloaterProfilePermissions +///---------------------------------------------------------------------------- -////////////////////////////////////////////////////////////////////////// -// LLPanelProfileSecondLife +class LLFloaterProfilePermissions + : public LLFloater + , public LLFriendObserver +{ +public: + LLFloaterProfilePermissions(LLView * owner, const LLUUID &avatar_id); + ~LLFloaterProfilePermissions(); + BOOL postBuild() override; + void onOpen(const LLSD& key) override; + void draw() override; + void changed(U32 mask) override; // LLFriendObserver + + void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name); + bool hasUnsavedChanges() { return mHasUnsavedPermChanges; } + + void onApplyRights(); + +private: + void fillRightsData(); + void rightsConfirmationCallback(const LLSD& notification, const LLSD& response); + void confirmModifyRights(bool grant); + void onCommitSeeOnlineRights(); + void onCommitEditRights(); + void onCancel(); + + LLTextBase* mDescription; + LLCheckBoxCtrl* mOnlineStatus; + LLCheckBoxCtrl* mMapRights; + LLCheckBoxCtrl* mEditObjectRights; + LLButton* mOkBtn; + LLButton* mCancelBtn; + + LLUUID mAvatarID; + F32 mContextConeOpacity; + bool mHasUnsavedPermChanges; + LLHandle<LLView> mOwnerHandle; + + boost::signals2::connection mAvatarNameCacheConnection; +}; -LLPanelProfileSecondLife::LLPanelProfileSecondLife() - : LLPanelProfileTab() - , mStatusText(NULL) - , mAvatarNameCacheConnection() +LLFloaterProfilePermissions::LLFloaterProfilePermissions(LLView * owner, const LLUUID &avatar_id) + : LLFloater(LLSD()) + , mAvatarID(avatar_id) + , mContextConeOpacity(0.0f) + , mHasUnsavedPermChanges(false) + , mOwnerHandle(owner->getHandle()) { + buildFromFile("floater_profile_permissions.xml"); } -LLPanelProfileSecondLife::~LLPanelProfileSecondLife() +LLFloaterProfilePermissions::~LLFloaterProfilePermissions() { - if (getAvatarId().notNull()) - { - LLAvatarTracker::instance().removeParticularFriendObserver(getAvatarId(), this); - } - - if (LLVoiceClient::instanceExists()) - { - LLVoiceClient::getInstance()->removeObserver((LLVoiceClientStatusObserver*)this); - } - - if (mAvatarNameCacheConnection.connected()) - { - mAvatarNameCacheConnection.disconnect(); - } - - if (mRlvBehaviorConn.connected()) + mAvatarNameCacheConnection.disconnect(); + if (mAvatarID.notNull()) { - mRlvBehaviorConn.disconnect(); + LLAvatarTracker::instance().removeParticularFriendObserver(mAvatarID, this); } } -BOOL LLPanelProfileSecondLife::postBuild() +BOOL LLFloaterProfilePermissions::postBuild() { - mStatusText = getChild<LLTextBox>("status"); - mGroupList = getChild<LLGroupList>("group_list"); - mShowInSearchCheckbox = getChild<LLCheckBoxCtrl>("show_in_search_checkbox"); - mSecondLifePic = getChild<LLTextureCtrl>("2nd_life_pic"); - mSecondLifePicLayout = getChild<LLPanel>("image_stack"); - mDescriptionEdit = getChild<LLTextBase>("sl_description_edit"); - mTeleportButton = getChild<LLButton>("teleport"); - mShowOnMapButton = getChild<LLButton>("show_on_map_btn"); - mBlockButton = getChild<LLButton>("block"); - mUnblockButton = getChild<LLButton>("unblock"); - mNameLabel = getChild<LLUICtrl>("name_label"); - mDisplayNameButton = getChild<LLButton>("set_name"); - mAddFriendButton = getChild<LLButton>("add_friend"); - mGroupInviteButton = getChild<LLButton>("group_invite"); - mPayButton = getChild<LLButton>("pay"); - mIMButton = getChild<LLButton>("im"); - mCopyMenuButton = getChild<LLMenuButton>("copy_btn"); - mGiveInvPanel = getChild<LLPanel>("give_stack"); - - mStatusText->setVisible(FALSE); - mCopyMenuButton->setVisible(FALSE); - - mAddFriendButton->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::onAddFriendButtonClick, this)); - mIMButton->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::onIMButtonClick, this)); - mTeleportButton->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::onTeleportButtonClick, this)); - mShowOnMapButton->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::onMapButtonClick, this)); - mPayButton->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::pay, this)); - mBlockButton->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::onClickToggleBlock, this)); - mUnblockButton->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::onClickToggleBlock, this)); - mGroupInviteButton->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::onGroupInvite,this)); - mDisplayNameButton->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::onClickSetName, this)); - mSecondLifePic->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::onCommitTexture, this)); - - LLUICtrl::CommitCallbackRegistry::ScopedRegistrar commit; - commit.add("Profile.CopyName", [this](LLUICtrl*, const LLSD& userdata) { ALAvatarActions::copyData(getAvatarId(), userdata); }); - - LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable; - enable.add("Profile.EnableCall", [this](LLUICtrl*, const LLSD&) { return mVoiceStatus; }); - enable.add("Profile.EnableGod", [](LLUICtrl*, const LLSD&) { return gAgent.isGodlike(); }); - - mGroupList->setDoubleClickCallback(boost::bind(&LLPanelProfileSecondLife::openGroupProfile, this)); - mGroupList->setReturnCallback(boost::bind(&LLPanelProfileSecondLife::openGroupProfile, this)); - - LLVoiceClient::getInstanceFast()->addObserver((LLVoiceClientStatusObserver*)this); - mCopyMenuButton->setMenu("menu_name_field.xml", LLMenuButton::MP_BOTTOM_RIGHT); + mDescription = getChild<LLTextBase>("perm_description"); + mOnlineStatus = getChild<LLCheckBoxCtrl>("online_check"); + mMapRights = getChild<LLCheckBoxCtrl>("map_check"); + mEditObjectRights = getChild<LLCheckBoxCtrl>("objects_check"); + mOkBtn = getChild<LLButton>("perms_btn_ok"); + mCancelBtn = getChild<LLButton>("perms_btn_cancel"); - mRlvBehaviorConn = gRlvHandler.setBehaviourToggleCallback([this](ERlvBehaviour eBhvr, ERlvParamType eParam) { if (eBhvr == RLV_BHVR_SHOWWORLDMAP) updateButtons(); }); + mOnlineStatus->setCommitCallback([this](LLUICtrl*, void*) { onCommitSeeOnlineRights(); }, nullptr); + mMapRights->setCommitCallback([this](LLUICtrl*, void*) { mHasUnsavedPermChanges = true; }, nullptr); + mEditObjectRights->setCommitCallback([this](LLUICtrl*, void*) { onCommitEditRights(); }, nullptr); + mOkBtn->setCommitCallback([this](LLUICtrl*, void*) { onApplyRights(); }, nullptr); + mCancelBtn->setCommitCallback([this](LLUICtrl*, void*) { onCancel(); }, nullptr); return TRUE; } -void LLPanelProfileSecondLife::onOpen(const LLSD& key) +void LLFloaterProfilePermissions::onOpen(const LLSD& key) { - LLPanelProfileTab::onOpen(key); - - resetData(); - - LLUUID avatar_id = getAvatarId(); - LLAvatarPropertiesProcessor::getInstanceFast()->addObserver(avatar_id, this); - - BOOL own_profile = getSelfProfile(); - - mGroupInviteButton->setVisible(!own_profile); - mShowOnMapButton->setVisible(!own_profile); - mPayButton->setVisible(!own_profile); - mTeleportButton->setVisible(!own_profile); - mIMButton->setVisible(!own_profile); - mAddFriendButton->setVisible(!own_profile); - mBlockButton->setVisible(!own_profile); - mUnblockButton->setVisible(!own_profile); - mGroupList->setShowNone(!own_profile); - mGiveInvPanel->setVisible(!own_profile); - - mSecondLifePic->setOpenTexPreview(!own_profile); - - if (own_profile && !getEmbedded()) + if (LLAvatarActions::isFriend(mAvatarID)) { - // Group list control cannot toggle ForAgent loading - // Less than ideal, but viewing own profile via search is edge case - mGroupList->enableForAgent(false); + LLAvatarTracker::instance().addParticularFriendObserver(mAvatarID, this); + fillRightsData(); } - if (own_profile && !getEmbedded() ) - { - mNameLabel->setVisible(FALSE); - mDisplayNameButton->setVisible(TRUE); - mDisplayNameButton->setEnabled(TRUE); - } + mCancelBtn->setFocus(true); - mDescriptionEdit->setParseHTML(!own_profile && !getEmbedded()); + mAvatarNameCacheConnection = LLAvatarNameCache::get(mAvatarID, boost::bind(&LLFloaterProfilePermissions::onAvatarNameCache, this, _1, _2)); +} - LLProfileDropTarget* drop_target = getChild<LLProfileDropTarget>("drop_target"); - drop_target->setVisible(!own_profile); - drop_target->setEnabled(!own_profile); +void LLFloaterProfilePermissions::draw() +{ + // drawFrustum + LLView *owner = mOwnerHandle.get(); + static LLCachedControl<F32> max_opacity(gSavedSettings, "PickerContextOpacity", 0.4f); + drawConeToOwner(mContextConeOpacity, max_opacity, owner); + LLFloater::draw(); +} - if (!own_profile) +void LLFloaterProfilePermissions::changed(U32 mask) +{ + if (mask != LLFriendObserver::ONLINE) { - mVoiceStatus = LLAvatarActions::canCall() && (LLAvatarActions::isFriend(avatar_id) ? LLAvatarTracker::instance().isBuddyOnline(avatar_id) : TRUE); - drop_target->setAgentID(avatar_id); - updateOnlineStatus(); + fillRightsData(); } +} - updateButtons(); +void LLFloaterProfilePermissions::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name) +{ + mAvatarNameCacheConnection.disconnect(); - mAvatarNameCacheConnection = LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileSecondLife::onAvatarNameCache, this, _1, _2)); + LLStringUtil::format_map_t args; + args["[AGENT_NAME]"] = av_name.getDisplayName(); + std::string descritpion = getString("description_string", args); + mDescription->setValue(descritpion); } -void LLPanelProfileSecondLife::apply(LLAvatarData* data) +void LLFloaterProfilePermissions::fillRightsData() { - if (getIsLoaded() && getSelfProfile()) + const LLRelationship* relation = LLAvatarTracker::instance().getBuddyInfo(mAvatarID); + // If true - we are viewing friend's profile, enable check boxes and set values. + if (relation) { - data->image_id = mSecondLifePic->getImageAssetID(); - data->about_text = mDescriptionEdit->getValue().asString(); - data->allow_publish = mShowInSearchCheckbox->getValue(); + S32 rights = relation->getRightsGrantedTo(); - LLAvatarPropertiesProcessor::getInstanceFast()->sendAvatarPropertiesUpdate(data); + BOOL see_online = LLRelationship::GRANT_ONLINE_STATUS & rights ? TRUE : FALSE; + mOnlineStatus->setValue(see_online); + mMapRights->setEnabled(see_online); + mMapRights->setValue(LLRelationship::GRANT_MAP_LOCATION & rights ? TRUE : FALSE); + mEditObjectRights->setValue(LLRelationship::GRANT_MODIFY_OBJECTS & rights ? TRUE : FALSE); + } + else + { + closeFloater(); + LL_INFOS("ProfilePermissions") << "Floater closing since agent is no longer a friend" << LL_ENDL; } } -void LLPanelProfileSecondLife::updateData() +void LLFloaterProfilePermissions::rightsConfirmationCallback(const LLSD& notification, + const LLSD& response) { - LLUUID avatar_id = getAvatarId(); - if (!getIsLoading() && avatar_id.notNull() && !(getSelfProfile() && !getEmbedded())) + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (option != 0) // canceled { - setIsLoading(); - LLAvatarPropertiesProcessor::getInstanceFast()->sendAvatarGroupsRequest(avatar_id); + mEditObjectRights->setValue(mEditObjectRights->getValue().asBoolean() ? FALSE : TRUE); + } + else + { + mHasUnsavedPermChanges = true; } } -void LLPanelProfileSecondLife::processProperties(void* data, EAvatarProcessorType type) +void LLFloaterProfilePermissions::confirmModifyRights(bool grant) { + LLSD args; + args["NAME"] = LLSLURL("agent", mAvatarID, "completename").getSLURLString(); + LLNotificationsUtil::add(grant ? "GrantModifyRights" : "RevokeModifyRights", args, LLSD(), + boost::bind(&LLFloaterProfilePermissions::rightsConfirmationCallback, this, _1, _2)); +} - if (APT_PROPERTIES == type) +void LLFloaterProfilePermissions::onCommitSeeOnlineRights() +{ + bool see_online = mOnlineStatus->getValue().asBoolean(); + mMapRights->setEnabled(see_online); + if (see_online) { - const LLAvatarData* avatar_data = static_cast<const LLAvatarData*>(data); - if(avatar_data && getAvatarId() == avatar_data->avatar_id) + const LLRelationship* relation = LLAvatarTracker::instance().getBuddyInfo(mAvatarID); + if (relation) { - processProfileProperties(avatar_data); - updateButtons(); + S32 rights = relation->getRightsGrantedTo(); + mMapRights->setValue(LLRelationship::GRANT_MAP_LOCATION & rights ? TRUE : FALSE); } - } - else if (APT_GROUPS == type) - { - LLAvatarGroups* avatar_groups = static_cast<LLAvatarGroups*>(data); - if(avatar_groups && getAvatarId() == avatar_groups->avatar_id) + else { - processGroupProperties(avatar_groups); + closeFloater(); + LL_INFOS("ProfilePermissions") << "Floater closing since agent is no longer a friend" << LL_ENDL; } } + else + { + mMapRights->setValue(FALSE); + } + mHasUnsavedPermChanges = true; } -void LLPanelProfileSecondLife::resetData() +void LLFloaterProfilePermissions::onCommitEditRights() { - resetLoading(); - getChild<LLUICtrl>("complete_name")->setValue(LLStringUtil::null); - getChild<LLUICtrl>("register_date")->setValue(LLStringUtil::null); - getChild<LLUICtrl>("acc_status_text")->setValue(LLStringUtil::null); - getChild<LLUICtrl>("partner_text")->setValue(LLStringUtil::null); + const LLRelationship* buddy_relationship = LLAvatarTracker::instance().getBuddyInfo(mAvatarID); - // Set default image and 1:1 dimensions for it - mSecondLifePic->setValue(mSecondLifePic->getDefaultImageAssetID()); - LLRect imageRect = mSecondLifePicLayout->getRect(); + if (!buddy_relationship) + { + LL_WARNS("ProfilePermissions") << "Trying to modify rights for non-friend avatar. Closing floater." << LL_ENDL; + closeFloater(); + return; + } + + bool allow_modify_objects = mEditObjectRights->getValue().asBoolean(); + + // if modify objects checkbox clicked + if (buddy_relationship->isRightGrantedTo( + LLRelationship::GRANT_MODIFY_OBJECTS) != allow_modify_objects) + { + confirmModifyRights(allow_modify_objects); + } +} + +void LLFloaterProfilePermissions::onApplyRights() +{ + const LLRelationship* buddy_relationship = LLAvatarTracker::instance().getBuddyInfo(mAvatarID); + + if (!buddy_relationship) + { + LL_WARNS("ProfilePermissions") << "Trying to modify rights for non-friend avatar. Skipped." << LL_ENDL; + return; + } + + S32 rights = 0; + + if (mOnlineStatus->getValue().asBoolean()) + { + rights |= LLRelationship::GRANT_ONLINE_STATUS; + } + if (mMapRights->getValue().asBoolean()) + { + rights |= LLRelationship::GRANT_MAP_LOCATION; + } + if (mEditObjectRights->getValue().asBoolean()) + { + rights |= LLRelationship::GRANT_MODIFY_OBJECTS; + } + + LLAvatarPropertiesProcessor::getInstance()->sendFriendRights(mAvatarID, rights); + + closeFloater(); +} + +void LLFloaterProfilePermissions::onCancel() +{ + closeFloater(); +} + +////////////////////////////////////////////////////////////////////////// +// LLPanelProfileSecondLife + +LLPanelProfileSecondLife::LLPanelProfileSecondLife() + : LLPanelProfileTab() + , mAvatarNameCacheConnection() + , mHasUnsavedDescriptionChanges(false) + , mWaitingForImageUpload(false) + , mAllowPublish(false) +{ +} + +LLPanelProfileSecondLife::~LLPanelProfileSecondLife() +{ + if (getAvatarId().notNull()) + { + LLAvatarTracker::instance().removeParticularFriendObserver(getAvatarId(), this); + } + + if (LLVoiceClient::instanceExists()) + { + LLVoiceClient::getInstance()->removeObserver((LLVoiceClientStatusObserver*)this); + } + + if (mAvatarNameCacheConnection.connected()) + { + mAvatarNameCacheConnection.disconnect(); + } + + if (mRlvBehaviorConn.connected()) + { + mRlvBehaviorConn.disconnect(); + } +} + +BOOL LLPanelProfileSecondLife::postBuild() +{ + mGroupList = getChild<LLGroupList>("group_list"); + mShowInSearchCombo = getChild<LLComboBox>("show_in_search"); + mSecondLifePic = getChild<LLIconCtrl>("2nd_life_pic"); + mSecondLifePicLayout = getChild<LLPanel>("image_panel"); + mDescriptionEdit = getChild<LLTextEditor>("sl_description_edit"); + mAgentActionMenuButton = getChild<LLMenuButton>("agent_actions_menu"); + mSaveDescriptionChanges = getChild<LLButton>("save_description_changes"); + mDiscardDescriptionChanges = getChild<LLButton>("discard_description_changes"); + mCanSeeOnlineIcon = getChild<LLIconCtrl>("can_see_online"); + mCantSeeOnlineIcon = getChild<LLIconCtrl>("cant_see_online"); + mCanSeeOnMapIcon = getChild<LLIconCtrl>("can_see_on_map"); + mCantSeeOnMapIcon = getChild<LLIconCtrl>("cant_see_on_map"); + mCanEditObjectsIcon = getChild<LLIconCtrl>("can_edit_objects"); + mCantEditObjectsIcon = getChild<LLIconCtrl>("cant_edit_objects"); + + mShowInSearchCombo->setCommitCallback([this](LLUICtrl*, void*) { onShowInSearchCallback(); }, nullptr); + mGroupList->setDoubleClickCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { LLPanelProfileSecondLife::openGroupProfile(); }); + mGroupList->setReturnCallback([this](LLUICtrl*, const LLSD&) { LLPanelProfileSecondLife::openGroupProfile(); }); + mSaveDescriptionChanges->setCommitCallback([this](LLUICtrl*, void*) { onSaveDescriptionChanges(); }, nullptr); + mDiscardDescriptionChanges->setCommitCallback([this](LLUICtrl*, void*) { onDiscardDescriptionChanges(); }, nullptr); + mDescriptionEdit->setKeystrokeCallback([this](LLTextEditor* caller) { onSetDescriptionDirty(); }); + + mCanSeeOnlineIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); }); + mCantSeeOnlineIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); }); + mCanSeeOnMapIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); }); + mCantSeeOnMapIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); }); + mCanEditObjectsIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); }); + mCantEditObjectsIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); }); + mSecondLifePic->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentProfileTexture(); }); + + //mRlvBehaviorConn = gRlvHandler.setBehaviourToggleCallback([this](ERlvBehaviour eBhvr, ERlvParamType eParam) { if (eBhvr == RLV_BHVR_SHOWWORLDMAP) updateButtons(); }); + + return TRUE; +} + +void LLPanelProfileSecondLife::onOpen(const LLSD& key) +{ + LLPanelProfileTab::onOpen(key); + + resetData(); + + LLUUID avatar_id = getAvatarId(); + + BOOL own_profile = getSelfProfile(); + + mGroupList->setShowNone(!own_profile); + + childSetVisible("notes_panel", !own_profile); + childSetVisible("settings_panel", own_profile); + childSetVisible("about_buttons_panel", own_profile); + + if (own_profile) + { + // Group list control cannot toggle ForAgent loading + // Less than ideal, but viewing own profile via search is edge case + mGroupList->enableForAgent(false); + } + + // Init menu, menu needs to be created in scope of a registar to work correctly. + LLUICtrl::CommitCallbackRegistry::ScopedRegistrar commit; + commit.add("Profile.Commit", [this](LLUICtrl*, const LLSD& userdata) { onCommitMenu(userdata); }); + + LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable; + enable.add("Profile.EnableItem", [this](LLUICtrl*, const LLSD& userdata) { return onEnableMenu(userdata); }); + enable.add("Profile.CheckItem", [this](LLUICtrl*, const LLSD& userdata) { return onCheckMenu(userdata); }); + + if (own_profile) + { + mAgentActionMenuButton->setMenu("menu_profile_self.xml", LLMenuButton::MP_BOTTOM_RIGHT); + } + else + { + // Todo: use PeopleContextMenu instead? + mAgentActionMenuButton->setMenu("menu_profile_other.xml", LLMenuButton::MP_BOTTOM_RIGHT); + } + + mDescriptionEdit->setParseHTML(!own_profile); + + if (!own_profile) + { + mVoiceStatus = LLAvatarActions::canCall() && (LLAvatarActions::isFriend(avatar_id) ? LLAvatarTracker::instance().isBuddyOnline(avatar_id) : TRUE); + updateOnlineStatus(); + fillRightsData(); + } + + mAvatarNameCacheConnection = LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileSecondLife::onAvatarNameCache, this, _1, _2)); +} + +void LLPanelProfileSecondLife::updateData() +{ + LLUUID avatar_id = getAvatarId(); + if (!getStarted() && avatar_id.notNull()) + { + setIsLoading(); + + std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); + if (!cap_url.empty()) + { + LLCoros::instance().launch("requestAgentUserInfoCoro", + boost::bind(request_avatar_properties_coro, cap_url, avatar_id)); + } + else + { + LL_WARNS() << "Failed to update profile data, no cap found" << LL_ENDL; + } + } +} + +void LLPanelProfileSecondLife::refreshName() +{ + if (!mAvatarNameCacheConnection.connected()) + { + mAvatarNameCacheConnection = LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileSecondLife::onAvatarNameCache, this, _1, _2)); + } +} + +void LLPanelProfileSecondLife::resetData() +{ + resetLoading(); + + // Set default image and 1:1 dimensions for it + mSecondLifePic->setValue("Generic_Person_Large"); + mImageId = LLUUID::null; + + LLRect imageRect = mSecondLifePicLayout->getRect(); mSecondLifePicLayout->reshape(imageRect.getHeight(), imageRect.getHeight()); - mDescriptionEdit->setValue(LLStringUtil::null); - mStatusText->setVisible(FALSE); - mCopyMenuButton->setVisible(FALSE); + setDescriptionText(LLStringUtil::null); mGroups.clear(); mGroupList->setGroups(mGroups); + + bool own_profile = getSelfProfile(); + mCanSeeOnlineIcon->setVisible(false); + mCantSeeOnlineIcon->setVisible(!own_profile); + mCanSeeOnMapIcon->setVisible(false); + mCantSeeOnMapIcon->setVisible(!own_profile); + mCanEditObjectsIcon->setVisible(false); + mCantEditObjectsIcon->setVisible(!own_profile); + + mCanSeeOnlineIcon->setEnabled(false); + mCantSeeOnlineIcon->setEnabled(false); + mCanSeeOnMapIcon->setEnabled(false); + mCantSeeOnMapIcon->setEnabled(false); + mCanEditObjectsIcon->setEnabled(false); + mCantEditObjectsIcon->setEnabled(false); + + childSetVisible("partner_layout", FALSE); } void LLPanelProfileSecondLife::processProfileProperties(const LLAvatarData* avatar_data) { LLUUID avatar_id = getAvatarId(); - if (!LLAvatarActions::isFriend(avatar_id) && !getSelfProfile()) + const LLRelationship* relationship = LLAvatarTracker::instance().getBuddyInfo(getAvatarId()); + if ((relationship != NULL || gAgent.isGodlike()) && !getSelfProfile()) { - // this is non-friend avatar. Status will be updated from LLAvatarPropertiesProcessor. - // in LLPanelProfileSecondLife::processOnlineStatus() - - // subscribe observer to get online status. Request will be sent by LLPanelProfileSecondLife itself. - // do not subscribe for friend avatar because online status can be wrong overridden - // via LLAvatarData::flags if Preferences: "Only Friends & Groups can see when I am online" is set. - processOnlineStatus(avatar_data->flags & AVATAR_ONLINE); + // Relies onto friend observer to get information about online status updates. + // Once SL-17506 gets implemented, condition might need to become: + // (gAgent.isGodlike() || isRightGrantedFrom || flags & AVATAR_ONLINE) + processOnlineStatus(relationship != NULL, + gAgent.isGodlike() || relationship->isRightGrantedFrom(LLRelationship::GRANT_ONLINE_STATUS), + (avatar_data->flags & AVATAR_ONLINE)); } fillCommonData(avatar_data); @@ -451,19 +1057,12 @@ void LLPanelProfileSecondLife::processProfileProperties(const LLAvatarData* avat fillPartnerData(avatar_data); fillAccountStatus(avatar_data); + + setLoaded(); } void LLPanelProfileSecondLife::processGroupProperties(const LLAvatarGroups* avatar_groups) { - //KC: the group_list ctrl can handle all this for us on our own profile - if (getSelfProfile() && !getEmbedded()) - { - return; - } - - // *NOTE dzaporozhan - // Group properties may arrive in two callbacks, we need to save them across - // different calls. We can't do that in textbox as textbox may change the text. LLAvatarGroups::group_list_t::const_iterator it = avatar_groups->group_list.begin(); const LLAvatarGroups::group_list_t::const_iterator it_end = avatar_groups->group_list.end(); @@ -486,330 +1085,882 @@ void LLPanelProfileSecondLife::openGroupProfile() void LLPanelProfileSecondLife::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name) { mAvatarNameCacheConnection.disconnect(); + getChild<LLUICtrl>("display_name")->setValue(av_name.getDisplayName()); + getChild<LLUICtrl>("user_name")->setValue(av_name.getAccountName()); +} + +void LLPanelProfileSecondLife::setProfileImageUploading(bool loading) +{ + LLLoadingIndicator* indicator = getChild<LLLoadingIndicator>("image_upload_indicator"); + indicator->setVisible(loading); + if (loading) + { + indicator->start(); + } + else + { + indicator->stop(); + } + mWaitingForImageUpload = loading; +} + +void LLPanelProfileSecondLife::setProfileImageUploaded(const LLUUID &image_asset_id) +{ + mSecondLifePic->setValue(image_asset_id); + mImageId = image_asset_id; + + LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTexture(image_asset_id); + if (imagep->getFullHeight()) + { + onImageLoaded(true, imagep); + } + else + { + imagep->setLoadedCallback(onImageLoaded, + MAX_DISCARD_LEVEL, + FALSE, + FALSE, + new LLHandle<LLPanel>(getHandle()), + NULL, + FALSE); + } + + LLFloater *floater = mFloaterProfileTextureHandle.get(); + if (floater) + { + LLFloaterProfileTexture * texture_view = dynamic_cast<LLFloaterProfileTexture*>(floater); + if (mImageId.notNull()) + { + texture_view->loadAsset(mImageId); + } + else + { + texture_view->resetAsset(); + } + } + + setProfileImageUploading(false); +} + +bool LLPanelProfileSecondLife::hasUnsavedChanges() +{ + LLFloater *floater = mFloaterPermissionsHandle.get(); + if (floater) + { + LLFloaterProfilePermissions* perm = dynamic_cast<LLFloaterProfilePermissions*>(floater); + if (perm && perm->hasUnsavedChanges()) + { + return true; + } + } + // if floater + return mHasUnsavedDescriptionChanges; +} + +void LLPanelProfileSecondLife::commitUnsavedChanges() +{ + LLFloater *floater = mFloaterPermissionsHandle.get(); + if (floater) + { + LLFloaterProfilePermissions* perm = dynamic_cast<LLFloaterProfilePermissions*>(floater); + if (perm && perm->hasUnsavedChanges()) + { + perm->onApplyRights(); + } + } + if (mHasUnsavedDescriptionChanges) + { + onSaveDescriptionChanges(); + } +} + +void LLPanelProfileSecondLife::fillCommonData(const LLAvatarData* avatar_data) +{ + // Refresh avatar id in cache with new info to prevent re-requests + // and to make sure icons in text will be up to date + LLAvatarIconIDCache::getInstance()->add(avatar_data->avatar_id, avatar_data->image_id); + + fillAgeData(avatar_data->born_on); + + setDescriptionText(avatar_data->about_text); + + if (avatar_data->image_id.notNull()) + { + mSecondLifePic->setValue(avatar_data->image_id); + mImageId = avatar_data->image_id; + } + else + { + mSecondLifePic->setValue("Generic_Person_Large"); + mImageId = LLUUID::null; + } + + // Will be loaded as a LLViewerFetchedTexture::BOOST_UI due to mSecondLifePic + LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTexture(avatar_data->image_id); + if (imagep->getFullHeight()) + { + onImageLoaded(true, imagep); + } + else + { + imagep->setLoadedCallback(onImageLoaded, + MAX_DISCARD_LEVEL, + FALSE, + FALSE, + new LLHandle<LLPanel>(getHandle()), + NULL, + FALSE); + } + + if (getSelfProfile()) + { + mAllowPublish = avatar_data->flags & AVATAR_ALLOW_PUBLISH; + mShowInSearchCombo->setValue((BOOL)mAllowPublish); + } +} - getChild<LLUICtrl>("complete_name")->setValue( av_name.getCompleteName() ); - mCopyMenuButton->setVisible(TRUE); +void LLPanelProfileSecondLife::fillPartnerData(const LLAvatarData* avatar_data) +{ + LLTextBox* partner_text_ctrl = getChild<LLTextBox>("partner_link"); + if (avatar_data->partner_id.notNull()) + { + childSetVisible("partner_layout", TRUE); + LLStringUtil::format_map_t args; + args["[LINK]"] = LLSLURL("agent", avatar_data->partner_id, "inspect").getSLURLString(); + std::string partner_text = getString("partner_text", args); + partner_text_ctrl->setText(partner_text); + } + else + { + childSetVisible("partner_layout", FALSE); + } +} + +void LLPanelProfileSecondLife::fillAccountStatus(const LLAvatarData* avatar_data) +{ + LLStringUtil::format_map_t args; + args["[ACCTTYPE]"] = LLAvatarPropertiesProcessor::accountType(avatar_data); + args["[PAYMENTINFO]"] = LLAvatarPropertiesProcessor::paymentInfo(avatar_data); + + std::string caption_text = getString("CaptionTextAcctInfo", args); + getChild<LLUICtrl>("account_info")->setValue(caption_text); +} + +void LLPanelProfileSecondLife::fillRightsData() +{ + if (getSelfProfile()) + { + return; + } + + const LLRelationship* relation = LLAvatarTracker::instance().getBuddyInfo(getAvatarId()); + // If true - we are viewing friend's profile, enable check boxes and set values. + if (relation) + { + S32 rights = relation->getRightsGrantedTo(); + bool can_see_online = LLRelationship::GRANT_ONLINE_STATUS & rights; + bool can_see_on_map = LLRelationship::GRANT_MAP_LOCATION & rights; + bool can_edit_objects = LLRelationship::GRANT_MODIFY_OBJECTS & rights; + + mCanSeeOnlineIcon->setVisible(can_see_online); + mCantSeeOnlineIcon->setVisible(!can_see_online); + mCanSeeOnMapIcon->setVisible(can_see_on_map); + mCantSeeOnMapIcon->setVisible(!can_see_on_map); + mCanEditObjectsIcon->setVisible(can_edit_objects); + mCantEditObjectsIcon->setVisible(!can_edit_objects); + + mCanSeeOnlineIcon->setEnabled(true); + mCantSeeOnlineIcon->setEnabled(true); + mCanSeeOnMapIcon->setEnabled(true); + mCantSeeOnMapIcon->setEnabled(true); + mCanEditObjectsIcon->setEnabled(true); + mCantEditObjectsIcon->setEnabled(true); + } + else + { + mCanSeeOnlineIcon->setVisible(false); + mCantSeeOnlineIcon->setVisible(false); + mCanSeeOnMapIcon->setVisible(false); + mCantSeeOnMapIcon->setVisible(false); + mCanEditObjectsIcon->setVisible(false); + mCantEditObjectsIcon->setVisible(false); + } +} + +void LLPanelProfileSecondLife::fillAgeData(const LLDate &born_on) +{ + std::string name_and_date = getString("date_format"); + LLSD args_name; + args_name["datetime"] = (S32)born_on.secondsSinceEpoch(); + LLStringUtil::format(name_and_date, args_name); + getChild<LLUICtrl>("sl_birth_date")->setValue(name_and_date); + + std::string register_date = getString("age_format"); + LLSD args_age; + args_age["[AGE]"] = LLDateUtil::ageFromDate(born_on, LLDate::now()); + LLStringUtil::format(register_date, args_age); + getChild<LLUICtrl>("user_age")->setValue(register_date); +} + +void LLPanelProfileSecondLife::onImageLoaded(BOOL success, LLViewerFetchedTexture *imagep) +{ + LLRect imageRect = mSecondLifePicLayout->getRect(); + if (!success || imagep->getFullWidth() == imagep->getFullHeight()) + { + mSecondLifePicLayout->reshape(imageRect.getWidth(), imageRect.getWidth()); + } + else + { + // assume 3:4, for sake of firestorm + mSecondLifePicLayout->reshape(imageRect.getWidth(), imageRect.getWidth() * 3 / 4); + } +} + +//static +void LLPanelProfileSecondLife::onImageLoaded(BOOL success, + LLViewerFetchedTexture *src_vi, + LLImageRaw* src, + LLImageRaw* aux_src, + S32 discard_level, + BOOL final, + void* userdata) +{ + if (!userdata) return; + + LLHandle<LLPanel>* handle = (LLHandle<LLPanel>*)userdata; + + if (!handle->isDead()) + { + LLPanelProfileSecondLife* panel = static_cast<LLPanelProfileSecondLife*>(handle->get()); + if (panel) + { + panel->onImageLoaded(success, src_vi); + } + } + + if (final || !success) + { + delete handle; + } +} + +// virtual, called by LLAvatarTracker +void LLPanelProfileSecondLife::changed(U32 mask) +{ + updateOnlineStatus(); + if (mask != LLFriendObserver::ONLINE) + { + fillRightsData(); + } +} + +// virtual, called by LLVoiceClient +void LLPanelProfileSecondLife::onChange(EStatusType status, const std::string &channelURI, bool proximal) +{ + if(status == STATUS_JOINING || status == STATUS_LEFT_CHANNEL) + { + return; + } + + mVoiceStatus = LLAvatarActions::canCall() && (LLAvatarActions::isFriend(getAvatarId()) ? LLAvatarTracker::instance().isBuddyOnline(getAvatarId()) : TRUE); +} + +void LLPanelProfileSecondLife::setAvatarId(const LLUUID& avatar_id) +{ + if (avatar_id.notNull()) + { + if (getAvatarId().notNull()) + { + LLAvatarTracker::instance().removeParticularFriendObserver(getAvatarId(), this); + } + + LLPanelProfileTab::setAvatarId(avatar_id); + + if (LLAvatarActions::isFriend(getAvatarId())) + { + LLAvatarTracker::instance().addParticularFriendObserver(getAvatarId(), this); + } + } +} + +// method was disabled according to EXT-2022. Re-enabled & improved according to EXT-3880 +void LLPanelProfileSecondLife::updateOnlineStatus() +{ + const LLRelationship* relationship = LLAvatarTracker::instance().getBuddyInfo(getAvatarId()); + if (relationship != NULL) + { + // For friend let check if he allowed me to see his status + bool online = relationship->isOnline(); + bool perm_granted = relationship->isRightGrantedFrom(LLRelationship::GRANT_ONLINE_STATUS); + processOnlineStatus(true, perm_granted, online); + } + else + { + childSetVisible("frind_layout", false); + childSetVisible("online_layout", false); + childSetVisible("offline_layout", false); + } +} + +void LLPanelProfileSecondLife::processOnlineStatus(bool is_friend, bool show_online, bool online) +{ + childSetVisible("frind_layout", is_friend); + childSetVisible("online_layout", online && show_online); + childSetVisible("offline_layout", !online && show_online); +} + +void LLPanelProfileSecondLife::setLoaded() +{ + LLPanelProfileTab::setLoaded(); + + if (getSelfProfile()) + { + mShowInSearchCombo->setEnabled(TRUE); + mDescriptionEdit->setEnabled(TRUE); + } +} + + + +class LLProfileImagePicker : public LLFilePickerThread +{ +public: + LLProfileImagePicker(EProfileImageType type, LLHandle<LLPanel> *handle); + ~LLProfileImagePicker(); + void notify(const std::vector<std::string>& filenames) override; + +private: + LLHandle<LLPanel> *mHandle; + EProfileImageType mType; +}; + +LLProfileImagePicker::LLProfileImagePicker(EProfileImageType type, LLHandle<LLPanel> *handle) + : LLFilePickerThread(LLFilePicker::FFLOAD_IMAGE), + mHandle(handle), + mType(type) +{ +} + +LLProfileImagePicker::~LLProfileImagePicker() +{ + delete mHandle; +} + +void LLProfileImagePicker::notify(const std::vector<std::string>& filenames) +{ + if (mHandle->isDead()) + { + return; + } + if (filenames.empty()) + { + return; + } + std::string file_path = filenames[0]; + if (file_path.empty()) + { + return; + } + + // generate a temp texture file for coroutine + std::string temp_file = gDirUtilp->getTempFilename(); + U32 codec = LLImageBase::getCodecFromExtension(gDirUtilp->getExtension(file_path)); + const S32 MAX_DIM = 256; + if (!LLViewerTextureList::createUploadFile(file_path, temp_file, codec, MAX_DIM)) + { + //todo: image not supported notification + LL_WARNS("AvatarProperties") << "Failed to upload profile image of type " << (S32)PROFILE_IMAGE_SL << ", failed to open image" << LL_ENDL; + return; + } + + std::string cap_url = gAgent.getRegionCapability(PROFILE_IMAGE_UPLOAD_CAP); + if (cap_url.empty()) + { + LL_WARNS("AvatarProperties") << "Failed to upload profile image of type " << (S32)PROFILE_IMAGE_SL << ", no cap found" << LL_ENDL; + return; + } + + switch (mType) + { + case PROFILE_IMAGE_SL: + { + LLPanelProfileSecondLife* panel = static_cast<LLPanelProfileSecondLife*>(mHandle->get()); + panel->setProfileImageUploading(true); + } + break; + case PROFILE_IMAGE_FL: + { + LLPanelProfileFirstLife* panel = static_cast<LLPanelProfileFirstLife*>(mHandle->get()); + panel->setProfileImageUploading(true); + } + break; + } + + LLCoros::instance().launch("postAgentUserImageCoro", + boost::bind(post_profile_image_coro, cap_url, mType, temp_file, mHandle)); + + mHandle = nullptr; // transferred to post_profile_image_coro +} + +void LLPanelProfileSecondLife::onCommitMenu(const LLSD& userdata) +{ + const std::string item_name = userdata.asString(); + const LLUUID agent_id = getAvatarId(); + // todo: consider moving this into LLAvatarActions::onCommit(name, id) + // and making all other flaoters, like people menu do the same + if (item_name == "im") + { + LLAvatarActions::startIM(agent_id); + } + else if (item_name == "offer_teleport") + { + LLAvatarActions::offerTeleport(agent_id); + } + else if (item_name == "request_teleport") + { + LLAvatarActions::teleportRequest(agent_id); + } + else if (item_name == "voice_call") + { + LLAvatarActions::startCall(agent_id); + } + else if (item_name == "chat_history") + { + LLAvatarActions::viewChatHistory(agent_id); + } + else if (item_name == "add_friend") + { + LLAvatarActions::requestFriendshipDialog(agent_id); + } + else if (item_name == "remove_friend") + { + LLAvatarActions::removeFriendDialog(agent_id); + } + else if (item_name == "invite_to_group") + { + LLAvatarActions::inviteToGroup(agent_id); + } + else if (item_name == "can_show_on_map") + { + LLAvatarActions::showOnMap(agent_id); + } + else if (item_name == "share") + { + LLAvatarActions::share(agent_id); + } + else if (item_name == "pay") + { + LLAvatarActions::pay(agent_id); + } + else if (item_name == "toggle_block_agent") + { + LLAvatarActions::toggleBlock(agent_id); + } + else if (item_name == "copy_user_id") + { + LLWString wstr = utf8str_to_wstring(getAvatarId().asString()); + LLClipboard::instance().copyToClipboard(wstr, 0, wstr.size()); + } + else if (item_name == "agent_permissions") + { + onShowAgentPermissionsDialog(); + } + else if (item_name == "copy_display_name" + || item_name == "copy_username") + { + LLAvatarName av_name; + if (!LLAvatarNameCache::get(getAvatarId(), &av_name)) + { + // shouldn't happen, option is supposed to be invisible while name is fetching + LL_WARNS() << "Failed to get agent data" << LL_ENDL; + return; + } + LLWString wstr; + if (item_name == "copy_display_name") + { + wstr = utf8str_to_wstring(av_name.getDisplayName(true)); + } + else if (item_name == "copy_username") + { + wstr = utf8str_to_wstring(av_name.getUserName()); + } + LLClipboard::instance().copyToClipboard(wstr, 0, wstr.size()); + } + else if (item_name == "edit_display_name") + { + LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileSecondLife::onAvatarNameCacheSetName, this, _1, _2)); + LLFirstUse::setDisplayName(false); + } + else if (item_name == "edit_partner") + { + std::string url = "https://[GRID]/my/account/partners.php"; + LLSD subs; + url = LLWeb::expandURLSubstitutions(url, subs); + LLUrlAction::openURL(url); + } + else if (item_name == "upload_photo") + { + (new LLProfileImagePicker(PROFILE_IMAGE_SL, new LLHandle<LLPanel>(getHandle())))->getFile(); + + LLFloater* floaterp = mFloaterTexturePickerHandle.get(); + if (floaterp) + { + floaterp->closeFloater(); + } + } + else if (item_name == "change_photo") + { + onShowTexturePicker(); + } + else if (item_name == "remove_photo") + { + onCommitProfileImage(LLUUID::null); + + LLFloater* floaterp = mFloaterTexturePickerHandle.get(); + if (floaterp) + { + floaterp->closeFloater(); + } + } } -void LLPanelProfileSecondLife::fillCommonData(const LLAvatarData* avatar_data) +bool LLPanelProfileSecondLife::onEnableMenu(const LLSD& userdata) { - // Refresh avatar id in cache with new info to prevent re-requests - // and to make sure icons in text will be up to date - LLAvatarIconIDCache::getInstanceFast()->add(avatar_data->avatar_id, avatar_data->image_id); - - LLStringUtil::format_map_t args; + const std::string item_name = userdata.asString(); + const LLUUID agent_id = getAvatarId(); + if (item_name == "offer_teleport" || item_name == "request_teleport") { - std::string birth_date = LLTrans::getString("AvatarBirthDateFormat"); - LLStringUtil::format(birth_date, LLSD().with("datetime", (S32) avatar_data->born_on.secondsSinceEpoch())); - args["[REG_DATE]"] = birth_date; + return LLAvatarActions::canOfferTeleport(agent_id); } - - args["[AGE]"] = LLDateUtil::ageFromDate( avatar_data->born_on, LLDate::now()); - std::string register_date = getString("RegisterDateFormat", args); - getChild<LLUICtrl>("register_date")->setValue(register_date ); - mDescriptionEdit->setValue(avatar_data->about_text); - mSecondLifePic->setValue(avatar_data->image_id); - - //Don't bother about boost level, picker will set it - LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTexture(avatar_data->image_id); - if (imagep->getFullHeight()) + else if (item_name == "voice_call") { - onImageLoaded(true, imagep); + return mVoiceStatus; } - else + else if (item_name == "chat_history") { - imagep->setLoadedCallback(onImageLoaded, - MAX_DISCARD_LEVEL, - FALSE, - FALSE, - new LLHandle<LLPanel>(getHandle()), - NULL, - FALSE); + return LLLogChat::isTranscriptExist(agent_id); } - - if (getSelfProfile()) + else if (item_name == "add_friend") { - mShowInSearchCheckbox->setValue((BOOL)(avatar_data->flags & AVATAR_ALLOW_PUBLISH)); + return !LLAvatarActions::isFriend(agent_id); } -} - -void LLPanelProfileSecondLife::fillPartnerData(const LLAvatarData* avatar_data) -{ - LLTextEditor* partner_text = getChild<LLTextEditor>("partner_text"); - if (avatar_data->partner_id.notNull()) + else if (item_name == "remove_friend") { - partner_text->setText(LLSLURL("agent", avatar_data->partner_id, "inspect").getSLURLString()); + return LLAvatarActions::isFriend(agent_id); } - else + else if (item_name == "can_show_on_map") { - partner_text->setText(getString("no_partner_text")); + return (LLAvatarTracker::instance().isBuddyOnline(agent_id) && LLAvatarActions::isAgentMappable(agent_id)) + || gAgent.isGodlike(); + } + else if (item_name == "toggle_block_agent") + { + return LLAvatarActions::canBlock(agent_id); + } + else if (item_name == "agent_permissions") + { + return LLAvatarActions::isFriend(agent_id); + } + else if (item_name == "copy_display_name" + || item_name == "copy_username") + { + return !mAvatarNameCacheConnection.connected(); + } + else if (item_name == "upload_photo" + || item_name == "change_photo") + { + std::string cap_url = gAgent.getRegionCapability(PROFILE_IMAGE_UPLOAD_CAP); + return !cap_url.empty() && !mWaitingForImageUpload && getIsLoaded(); + } + else if (item_name == "remove_photo") + { + std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); + return mImageId.notNull() && !cap_url.empty() && !mWaitingForImageUpload && getIsLoaded(); } -} - -void LLPanelProfileSecondLife::fillAccountStatus(const LLAvatarData* avatar_data) -{ - LLStringUtil::format_map_t args; - args["[ACCTTYPE]"] = LLAvatarPropertiesProcessor::accountType(avatar_data); - args["[PAYMENTINFO]"] = LLAvatarPropertiesProcessor::paymentInfo(avatar_data); - - std::string caption_text = getString("CaptionTextAcctInfo", args); - getChild<LLUICtrl>("acc_status_text")->setValue(caption_text); -} -void LLPanelProfileSecondLife::onMapButtonClick() -{ - LLAvatarActions::showOnMap(getAvatarId()); + return false; } -void LLPanelProfileSecondLife::pay() +bool LLPanelProfileSecondLife::onCheckMenu(const LLSD& userdata) { - LLAvatarActions::pay(getAvatarId()); + const std::string item_name = userdata.asString(); + const LLUUID agent_id = getAvatarId(); + if (item_name == "toggle_block_agent") + { + return LLAvatarActions::isBlocked(agent_id); + } + return false; } -void LLPanelProfileSecondLife::onClickToggleBlock() +void LLPanelProfileSecondLife::onAvatarNameCacheSetName(const LLUUID& agent_id, const LLAvatarName& av_name) { - bool blocked = LLAvatarActions::toggleBlock(getAvatarId()); - - updateButtons(); - // we are hiding one button and showing another, set focus - if (blocked) + if (av_name.getDisplayName().empty()) { - mUnblockButton->setFocus(true); + // something is wrong, tell user to try again later + LLNotificationsUtil::add("SetDisplayNameFailedGeneric"); + return; } - else + + LL_INFOS("LegacyProfile") << "name-change now " << LLDate::now() << " next_update " + << LLDate(av_name.mNextUpdate) << LL_ENDL; + F64 now_secs = LLDate::now().secondsSinceEpoch(); + + if (now_secs < av_name.mNextUpdate) { - mBlockButton->setFocus(true); + // if the update time is more than a year in the future, it means updates have been blocked + // show a more general message + static const S32 YEAR = 60*60*24*365; + if (now_secs + YEAR < av_name.mNextUpdate) + { + LLNotificationsUtil::add("SetDisplayNameBlocked"); + return; + } } -} -void LLPanelProfileSecondLife::onAddFriendButtonClick() -{ - LLAvatarActions::requestFriendshipDialog(getAvatarId()); + LLFloaterReg::showInstance("display_name"); } -void LLPanelProfileSecondLife::onIMButtonClick() +void LLPanelProfileSecondLife::setDescriptionText(const std::string &text) { - LLAvatarActions::startIM(getAvatarId()); -} + mSaveDescriptionChanges->setEnabled(FALSE); + mDiscardDescriptionChanges->setEnabled(FALSE); + mHasUnsavedDescriptionChanges = false; -void LLPanelProfileSecondLife::onTeleportButtonClick() -{ - LLAvatarActions::offerTeleport(getAvatarId()); + mDescriptionText = text; + mDescriptionEdit->setValue(mDescriptionText); } -void LLPanelProfileSecondLife::onGroupInvite() +void LLPanelProfileSecondLife::onSetDescriptionDirty() { - LLAvatarActions::inviteToGroup(getAvatarId()); + mSaveDescriptionChanges->setEnabled(TRUE); + mDiscardDescriptionChanges->setEnabled(TRUE); + mHasUnsavedDescriptionChanges = true; } -void LLPanelProfileSecondLife::onImageLoaded(BOOL success, LLViewerFetchedTexture *imagep) +void LLPanelProfileSecondLife::onShowInSearchCallback() { - LLRect imageRect = mSecondLifePicLayout->getRect(); - if (!success || imagep->getFullWidth() == imagep->getFullHeight()) + S32 value = mShowInSearchCombo->getValue().asInteger(); + if (mAllowPublish == (bool)value) + { + return; + } + std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); + if (!cap_url.empty()) { - mSecondLifePicLayout->reshape(imageRect.getHeight(), imageRect.getHeight()); + mAllowPublish = value; + LLSD data; + data["allow_publish"] = mAllowPublish; + LLCoros::instance().launch("putAgentUserInfoCoro", + boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), data)); } else { - // assume 3:4, for sake of firestorm - mSecondLifePicLayout->reshape(imageRect.getHeight() * 4 / 3, imageRect.getHeight()); + LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL; } } -//static -void LLPanelProfileSecondLife::onImageLoaded(BOOL success, - LLViewerFetchedTexture *src_vi, - LLImageRaw* src, - LLImageRaw* aux_src, - S32 discard_level, - BOOL final, - void* userdata) +void LLPanelProfileSecondLife::onSaveDescriptionChanges() { - if (!userdata) return; - - LLHandle<LLPanel>* handle = (LLHandle<LLPanel>*)userdata; - - if (!handle->isDead()) + mDescriptionText = mDescriptionEdit->getValue().asString(); + std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); + if (!cap_url.empty()) { - LLPanelProfileSecondLife* panel = static_cast<LLPanelProfileSecondLife*>(handle->get()); - if (panel) - { - panel->onImageLoaded(success, src_vi); - } + LLCoros::instance().launch("putAgentUserInfoCoro", + boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), LLSD().with("sl_about_text", mDescriptionText))); } - - if (final || !success) + else { - delete handle; + LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL; } -} -// virtual, called by LLAvatarTracker -void LLPanelProfileSecondLife::changed(U32 mask) -{ - updateOnlineStatus(); - updateButtons(); + mSaveDescriptionChanges->setEnabled(FALSE); + mDiscardDescriptionChanges->setEnabled(FALSE); + mHasUnsavedDescriptionChanges = false; } -// virtual, called by LLVoiceClient -void LLPanelProfileSecondLife::onChange(EStatusType status, const std::string &channelURI, bool proximal) +void LLPanelProfileSecondLife::onDiscardDescriptionChanges() { - if(status == STATUS_JOINING || status == STATUS_LEFT_CHANNEL) - { - return; - } - - mVoiceStatus = LLAvatarActions::canCall() && (LLAvatarActions::isFriend(getAvatarId()) ? LLAvatarTracker::instance().isBuddyOnline(getAvatarId()) : TRUE); + setDescriptionText(mDescriptionText); } -void LLPanelProfileSecondLife::setAvatarId(const LLUUID& avatar_id) +void LLPanelProfileSecondLife::onShowAgentPermissionsDialog() { - if (avatar_id.notNull()) + LLFloater *floater = mFloaterPermissionsHandle.get(); + if (!floater) { - if (getAvatarId().notNull()) + LLFloater* parent_floater = gFloaterView->getParentFloater(this); + if (parent_floater) { - LLAvatarTracker::instance().removeParticularFriendObserver(getAvatarId(), this); - } - - LLPanelProfileTab::setAvatarId(avatar_id); + LLFloaterProfilePermissions * perms = new LLFloaterProfilePermissions(parent_floater, getAvatarId()); + mFloaterPermissionsHandle = perms->getHandle(); + perms->openFloater(); + perms->setVisibleAndFrontmost(TRUE); - if (LLAvatarActions::isFriend(getAvatarId())) - { - LLAvatarTracker::instance().addParticularFriendObserver(getAvatarId(), this); + parent_floater->addDependentFloater(mFloaterPermissionsHandle); } } -} - -bool LLPanelProfileSecondLife::isGrantedToSeeOnlineStatus() -{ - // set text box visible to show online status for non-friends who has not set in Preferences - // "Only Friends & Groups can see when I am online" - if (!LLAvatarActions::isFriend(getAvatarId())) + else // already open { - return true; + floater->setMinimized(FALSE); + floater->setVisibleAndFrontmost(TRUE); } - - // *NOTE: GRANT_ONLINE_STATUS is always set to false while changing any other status. - // When avatar disallow me to see her online status processOfflineNotification Message is received by the viewer - // see comments for ChangeUserRights template message. EXT-453. - // If GRANT_ONLINE_STATUS flag is changed it will be applied when viewer restarts. EXT-3880 - const LLRelationship* relationship = LLAvatarTracker::instance().getBuddyInfo(getAvatarId()); - return relationship->isRightGrantedFrom(LLRelationship::GRANT_ONLINE_STATUS); -} - -// method was disabled according to EXT-2022. Re-enabled & improved according to EXT-3880 -void LLPanelProfileSecondLife::updateOnlineStatus() -{ - if (!LLAvatarActions::isFriend(getAvatarId())) return; - // For friend let check if he allowed me to see his status - const LLRelationship* relationship = LLAvatarTracker::instance().getBuddyInfo(getAvatarId()); - bool online = relationship->isOnline(); - processOnlineStatus(online); -} - -void LLPanelProfileSecondLife::processOnlineStatus(bool online) -{ - mStatusText->setVisible(isGrantedToSeeOnlineStatus()); - - std::string status = getString(online ? "status_online" : "status_offline"); - - mStatusText->setValue(status); - mStatusText->setColor(online ? - LLUIColorTable::instanceFast().getColor("StatusUserOnline") : - LLUIColorTable::instanceFast().getColor("StatusUserOffline")); } -void LLPanelProfileSecondLife::updateButtons() +void LLPanelProfileSecondLife::onShowAgentProfileTexture() { - LLPanelProfileTab::updateButtons(); - - if (getSelfProfile() && !getEmbedded()) + if (!getIsLoaded()) { - mShowInSearchCheckbox->setVisible(TRUE); - mShowInSearchCheckbox->setEnabled(TRUE); - mDescriptionEdit->setEnabled(TRUE); + return; } - if (!getSelfProfile()) + LLFloater *floater = mFloaterProfileTextureHandle.get(); + if (!floater) { - LLUUID av_id = getAvatarId(); - bool is_buddy_online = LLAvatarTracker::instance().isBuddyOnline(getAvatarId()); + LLFloater* parent_floater = gFloaterView->getParentFloater(this); + if (parent_floater) + { + LLFloaterProfileTexture * texture_view = new LLFloaterProfileTexture(parent_floater); + mFloaterProfileTextureHandle = texture_view->getHandle(); + if (mImageId.notNull()) + { + texture_view->loadAsset(mImageId); + } + else + { + texture_view->resetAsset(); + } + texture_view->openFloater(); + texture_view->setVisibleAndFrontmost(TRUE); - if (LLAvatarActions::isFriend(av_id)) + parent_floater->addDependentFloater(mFloaterProfileTextureHandle); + } + } + else // already open + { + LLFloaterProfileTexture * texture_view = dynamic_cast<LLFloaterProfileTexture*>(floater); + texture_view->setMinimized(FALSE); + texture_view->setVisibleAndFrontmost(TRUE); + if (mImageId.notNull()) { - mTeleportButton->setEnabled(is_buddy_online); - //Disable "Add Friend" button for friends. - mAddFriendButton->setEnabled(false); + texture_view->loadAsset(mImageId); } else { - mTeleportButton->setEnabled(true); - mAddFriendButton->setEnabled(true); + texture_view->resetAsset(); } - - bool enable_map_btn = ((is_buddy_online && LLAvatarActions::isAgentMappable(av_id)) || gAgent.isGodlike()) && !gRlvHandler.hasBehaviour(RLV_BHVR_SHOWWORLDMAP); - mShowOnMapButton->setEnabled(enable_map_btn); - - bool enable_block_btn = LLAvatarActions::canBlock(av_id) && !LLAvatarActions::isBlocked(av_id); - mBlockButton->setVisible(enable_block_btn); - - bool enable_unblock_btn = LLAvatarActions::isBlocked(av_id); - mUnblockButton->setVisible(enable_unblock_btn); } } -void LLPanelProfileSecondLife::onClickSetName() +void LLPanelProfileSecondLife::onShowTexturePicker() { - LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileSecondLife::onAvatarNameCacheSetName, this, _1, _2)); - - LLFirstUse::setDisplayName(false); -} + LLFloater* floaterp = mFloaterTexturePickerHandle.get(); -void LLPanelProfileSecondLife::onCommitTexture() -{ - LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTexture(mSecondLifePic->getImageAssetID()); - if (imagep->getFullHeight()) + // Show the dialog + if (!floaterp) { - onImageLoaded(true, imagep); + LLFloater* parent_floater = gFloaterView->getParentFloater(this); + if (parent_floater) + { + // because inventory construction is somewhat slow + getWindow()->setCursor(UI_CURSOR_WAIT); + LLFloaterTexturePicker* texture_floaterp = new LLFloaterTexturePicker( + this, + mImageId, + LLUUID::null, + LLUUID::null, + mImageId, + FALSE, + FALSE, + "SELECT PHOTO", + PERM_NONE, + PERM_NONE, + PERM_NONE, + FALSE, + NULL); + + mFloaterTexturePickerHandle = texture_floaterp->getHandle(); + + texture_floaterp->setOnFloaterCommitCallback([this](LLTextureCtrl::ETexturePickOp op, LLUUID id) + { + if (op == LLTextureCtrl::TEXTURE_SELECT) + { + LLUUID image_asset_id; + LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterTexturePickerHandle.get(); + if (floaterp) + { + if (id.notNull()) + { + image_asset_id = id; + } + else + { + image_asset_id = floaterp->getAssetID(); + } + } + + onCommitProfileImage(image_asset_id); + } + }); + texture_floaterp->setLocalTextureEnabled(FALSE); + texture_floaterp->setBakeTextureEnabled(FALSE); + texture_floaterp->setCanApply(false, true); + + parent_floater->addDependentFloater(mFloaterTexturePickerHandle); + + texture_floaterp->openFloater(); + texture_floaterp->setFocus(TRUE); + } } else { - imagep->setLoadedCallback(onImageLoaded, - MAX_DISCARD_LEVEL, - FALSE, - FALSE, - new LLHandle<LLPanel>(getHandle()), - NULL, - FALSE); + floaterp->setMinimized(FALSE); + floaterp->setVisibleAndFrontmost(TRUE); } } -void LLPanelProfileSecondLife::onAvatarNameCacheSetName(const LLUUID& agent_id, const LLAvatarName& av_name) +void LLPanelProfileSecondLife::onCommitProfileImage(const LLUUID& id) { - if (av_name.getDisplayName().empty()) + if (mImageId == id) { - // something is wrong, tell user to try again later - LLNotificationsUtil::add("SetDisplayNameFailedGeneric"); return; } - LL_INFOS("LegacyProfile") << "name-change now " << LLDate::now() << " next_update " - << LLDate(av_name.mNextUpdate) << LL_ENDL; - F64 now_secs = LLDate::now().secondsSinceEpoch(); - - if (now_secs < av_name.mNextUpdate) + std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); + if (!cap_url.empty()) { - // if the update time is more than a year in the future, it means updates have been blocked - // show a more general message - static const S32 YEAR = 60*60*24*365; - if (now_secs + YEAR < av_name.mNextUpdate) + LLSD params; + params["sl_image_id"] = id; + LLCoros::instance().launch("putAgentUserInfoCoro", + boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), params)); + + mImageId = id; + if (mImageId == LLUUID::null) { - LLNotificationsUtil::add("SetDisplayNameBlocked"); - return; + mSecondLifePic->setValue("Generic_Person_Large"); + } + else + { + mSecondLifePic->setValue(mImageId); } - } - LLFloaterReg::showInstance("display_name"); + LLFloater *floater = mFloaterProfileTextureHandle.get(); + if (floater) + { + LLFloaterProfileTexture * texture_view = dynamic_cast<LLFloaterProfileTexture*>(floater); + if (mImageId == LLUUID::null) + { + texture_view->resetAsset(); + } + else + { + texture_view->loadAsset(mImageId); + } + } + } + else + { + LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL; + } } ////////////////////////////////////////////////////////////////////////// @@ -848,32 +1999,15 @@ BOOL LLPanelProfileWeb::postBuild() return TRUE; } -void LLPanelProfileWeb::processProperties(void* data, EAvatarProcessorType type) -{ - if (APT_PROPERTIES == type) - { - const LLAvatarData* avatar_data = static_cast<const LLAvatarData*>(data); - if (avatar_data && getAvatarId() == avatar_data->avatar_id) - { - updateButtons(); - } - } -} - void LLPanelProfileWeb::resetData() { mWebBrowser->navigateHome(); } -void LLPanelProfileWeb::apply(LLAvatarData* data) -{ - -} - void LLPanelProfileWeb::updateData() { LLUUID avatar_id = getAvatarId(); - if (!getIsLoading() && avatar_id.notNull() && !mURLWebProfile.empty()) + if (!getStarted() && avatar_id.notNull() && !mURLWebProfile.empty()) { setIsLoading(); @@ -966,250 +2100,290 @@ void LLPanelProfileWeb::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent e } } -void LLPanelProfileWeb::updateButtons() -{ - LLPanelProfileTab::updateButtons(); -} ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// -static const S32 WANT_CHECKS = 8; -static const S32 SKILL_CHECKS = 6; - -LLPanelProfileInterests::LLPanelProfileInterests() +LLPanelProfileFirstLife::LLPanelProfileFirstLife() : LLPanelProfileTab() + , mHasUnsavedChanges(false) +{ +} + +LLPanelProfileFirstLife::~LLPanelProfileFirstLife() +{ +} + +BOOL LLPanelProfileFirstLife::postBuild() +{ + mDescriptionEdit = getChild<LLTextEditor>("fl_description_edit"); + mPicture = getChild<LLIconCtrl>("real_world_pic"); + + mUploadPhoto = getChild<LLButton>("fl_upload_image"); + mChangePhoto = getChild<LLButton>("fl_change_image"); + mRemovePhoto = getChild<LLButton>("fl_remove_image"); + mSaveChanges = getChild<LLButton>("fl_save_changes"); + mDiscardChanges = getChild<LLButton>("fl_discard_changes"); + + mUploadPhoto->setCommitCallback([this](LLUICtrl*, void*) { onUploadPhoto(); }, nullptr); + mChangePhoto->setCommitCallback([this](LLUICtrl*, void*) { onChangePhoto(); }, nullptr); + mRemovePhoto->setCommitCallback([this](LLUICtrl*, void*) { onRemovePhoto(); }, nullptr); + mSaveChanges->setCommitCallback([this](LLUICtrl*, void*) { onSaveDescriptionChanges(); }, nullptr); + mDiscardChanges->setCommitCallback([this](LLUICtrl*, void*) { onDiscardDescriptionChanges(); }, nullptr); + mDescriptionEdit->setKeystrokeCallback([this](LLTextEditor* caller) { onSetDescriptionDirty(); }); + + return TRUE; +} + +void LLPanelProfileFirstLife::onOpen(const LLSD& key) +{ + LLPanelProfileTab::onOpen(key); + + if (!getSelfProfile()) + { + // Otherwise as the only focusable element it will be selected + mDescriptionEdit->setTabStop(FALSE); + } + + resetData(); +} + +void LLPanelProfileFirstLife::setProfileImageUploading(bool loading) { + mUploadPhoto->setEnabled(!loading); + mChangePhoto->setEnabled(!loading); + mRemovePhoto->setEnabled(!loading && mImageId.notNull()); + + LLLoadingIndicator* indicator = getChild<LLLoadingIndicator>("image_upload_indicator"); + indicator->setVisible(loading); + if (loading) + { + indicator->start(); + } + else + { + indicator->stop(); + } } -LLPanelProfileInterests::~LLPanelProfileInterests() +void LLPanelProfileFirstLife::setProfileImageUploaded(const LLUUID &image_asset_id) { + mPicture->setValue(image_asset_id); + mImageId = image_asset_id; + setProfileImageUploading(false); } -void LLPanelProfileInterests::onOpen(const LLSD& key) +void LLPanelProfileFirstLife::commitUnsavedChanges() { - LLPanelProfileTab::onOpen(key); - - resetData(); + if (mHasUnsavedChanges) + { + onSaveDescriptionChanges(); + } } -BOOL LLPanelProfileInterests::postBuild() +void LLPanelProfileFirstLife::onUploadPhoto() { - mWantToEditor = getChild<LLLineEditor>("want_to_edit"); - mSkillsEditor = getChild<LLLineEditor>("skills_edit"); - mLanguagesEditor = getChild<LLLineEditor>("languages_edit"); - - for (S32 i = 0; i < WANT_CHECKS; ++i) - { - std::string check_name = llformat("chk%d", i); - mWantChecks[i] = getChild<LLCheckBoxCtrl>(check_name); - } + (new LLProfileImagePicker(PROFILE_IMAGE_FL, new LLHandle<LLPanel>(getHandle())))->getFile(); - for (S32 i = 0; i < SKILL_CHECKS; ++i) + LLFloater* floaterp = mFloaterTexturePickerHandle.get(); + if (floaterp) { - std::string check_name = llformat("schk%d", i); - mSkillChecks[i] = getChild<LLCheckBoxCtrl>(check_name); + floaterp->closeFloater(); } - - return TRUE; } - -void LLPanelProfileInterests::processProperties(void* data, EAvatarProcessorType type) +void LLPanelProfileFirstLife::onChangePhoto() { - if (APT_INTERESTS == type) + LLFloater* floaterp = mFloaterTexturePickerHandle.get(); + + // Show the dialog + if (!floaterp) { - const LLAvatarInterests* interests_data = static_cast<const LLAvatarInterests*>(data); - if (interests_data && getAvatarId() == interests_data->avatar_id) + LLFloater* parent_floater = gFloaterView->getParentFloater(this); + if (parent_floater) { - for (S32 i = 0; i < WANT_CHECKS; ++i) - { - if (interests_data->want_to_mask & (1<<i)) - { - mWantChecks[i]->setValue(TRUE); - } - else - { - mWantChecks[i]->setValue(FALSE); - } - } - - for (S32 i = 0; i < SKILL_CHECKS; ++i) + // because inventory construction is somewhat slow + getWindow()->setCursor(UI_CURSOR_WAIT); + LLFloaterTexturePicker* texture_floaterp = new LLFloaterTexturePicker( + this, + mImageId, + LLUUID::null, + LLUUID::null, + mImageId, + FALSE, + FALSE, + "SELECT PHOTO", + PERM_NONE, + PERM_NONE, + PERM_NONE, + FALSE, + NULL); + + mFloaterTexturePickerHandle = texture_floaterp->getHandle(); + + texture_floaterp->setOnFloaterCommitCallback([this](LLTextureCtrl::ETexturePickOp op, LLUUID id) { - if (interests_data->skills_mask & (1<<i)) - { - mSkillChecks[i]->setValue(TRUE); - } - else + if (op == LLTextureCtrl::TEXTURE_SELECT) { - mSkillChecks[i]->setValue(FALSE); + LLUUID image_asset_id; + LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterTexturePickerHandle.get(); + if (floaterp) + { + if (id.notNull()) + { + image_asset_id = id; + } + else + { + image_asset_id = floaterp->getAssetID(); + } + } + + onCommitPhoto(image_asset_id); } - } + }); + texture_floaterp->setLocalTextureEnabled(FALSE); + texture_floaterp->setCanApply(false, true); - mWantToEditor->setText(interests_data->want_to_text); - mSkillsEditor->setText(interests_data->skills_text); - mLanguagesEditor->setText(interests_data->languages_text); + parent_floater->addDependentFloater(mFloaterTexturePickerHandle); - updateButtons(); + texture_floaterp->openFloater(); + texture_floaterp->setFocus(TRUE); } } + else + { + floaterp->setMinimized(FALSE); + floaterp->setVisibleAndFrontmost(TRUE); + } } -void LLPanelProfileInterests::resetData() +void LLPanelProfileFirstLife::onRemovePhoto() { - mWantToEditor->setValue(LLStringUtil::null); - mSkillsEditor->setValue(LLStringUtil::null); - mLanguagesEditor->setValue(LLStringUtil::null); + onCommitPhoto(LLUUID::null); - for (S32 i = 0; i < WANT_CHECKS; ++i) + LLFloater* floaterp = mFloaterTexturePickerHandle.get(); + if (floaterp) { - mWantChecks[i]->setValue(FALSE); + floaterp->closeFloater(); } +} - for (S32 i = 0; i < SKILL_CHECKS; ++i) +void LLPanelProfileFirstLife::onCommitPhoto(const LLUUID& id) +{ + if (mImageId == id) { - mSkillChecks[i]->setValue(FALSE); + return; } -} -void LLPanelProfileInterests::apply() -{ - if (getIsLoaded() && getSelfProfile()) + std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); + if (!cap_url.empty()) { - LLAvatarInterests interests_data = LLAvatarInterests(); + LLSD params; + params["fl_image_id"] = id; + LLCoros::instance().launch("putAgentUserInfoCoro", + boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), params)); - interests_data.want_to_mask = 0; - for (S32 i = 0; i < WANT_CHECKS; ++i) + mImageId = id; + if (mImageId.notNull()) { - if (mWantChecks[i]->getValue().asBoolean()) - { - interests_data.want_to_mask |= (1 << i); - } + mPicture->setValue(mImageId); } - - interests_data.skills_mask = 0; - for (S32 i = 0; i < SKILL_CHECKS; ++i) + else { - if (mSkillChecks[i]->getValue().asBoolean()) - { - interests_data.skills_mask |= (1 << i); - } + mPicture->setValue("Generic_Person_Large"); } - interests_data.want_to_text = mWantToEditor->getText(); - interests_data.skills_text = mSkillsEditor->getText(); - interests_data.languages_text = mLanguagesEditor->getText(); - - LLAvatarPropertiesProcessor::getInstanceFast()->sendInterestsUpdate(&interests_data); + mRemovePhoto->setEnabled(mImageId.notNull()); } - -} - -void LLPanelProfileInterests::updateButtons() -{ - LLPanelProfileTab::updateButtons(); - - if (getSelfProfile() && !getEmbedded()) + else { - mWantToEditor->setEnabled(TRUE); - mSkillsEditor->setEnabled(TRUE); - mLanguagesEditor->setEnabled(TRUE); - - for (S32 i = 0; i < WANT_CHECKS; ++i) - { - mWantChecks[i]->setEnabled(TRUE); - } - - for (S32 i = 0; i < SKILL_CHECKS; ++i) - { - mSkillChecks[i]->setEnabled(TRUE); - } + LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL; } } -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// - - -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// - -LLPanelProfileFirstLife::LLPanelProfileFirstLife() - : LLPanelProfileTab(), - mIsEditing(false) +void LLPanelProfileFirstLife::setDescriptionText(const std::string &text) { + mSaveChanges->setEnabled(FALSE); + mDiscardChanges->setEnabled(FALSE); + mHasUnsavedChanges = false; + + mCurrentDescription = text; + mDescriptionEdit->setValue(mCurrentDescription); } -LLPanelProfileFirstLife::~LLPanelProfileFirstLife() +void LLPanelProfileFirstLife::onSetDescriptionDirty() { + mSaveChanges->setEnabled(TRUE); + mDiscardChanges->setEnabled(TRUE); + mHasUnsavedChanges = true; } -BOOL LLPanelProfileFirstLife::postBuild() +void LLPanelProfileFirstLife::onSaveDescriptionChanges() { - mDescriptionEdit = getChild<LLTextEditor>("fl_description_edit"); - mPicture = getChild<LLTextureCtrl>("real_world_pic"); - - mDescriptionEdit->setFocusReceivedCallback(boost::bind(&LLPanelProfileFirstLife::onDescriptionFocusReceived, this)); + mCurrentDescription = mDescriptionEdit->getValue().asString(); + std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); + if (!cap_url.empty()) + { + LLCoros::instance().launch("putAgentUserInfoCoro", + boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), LLSD().with("fl_about_text", mCurrentDescription))); + } + else + { + LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL; + } - return TRUE; + mSaveChanges->setEnabled(FALSE); + mDiscardChanges->setEnabled(FALSE); + mHasUnsavedChanges = false; } -void LLPanelProfileFirstLife::onOpen(const LLSD& key) +void LLPanelProfileFirstLife::onDiscardDescriptionChanges() { - LLPanelProfileTab::onOpen(key); - - resetData(); + setDescriptionText(mCurrentDescription); } - -void LLPanelProfileFirstLife::onDescriptionFocusReceived() +void LLPanelProfileFirstLife::processProperties(const LLAvatarData* avatar_data) { - if (!mIsEditing && getSelfProfile()) + setDescriptionText(avatar_data->fl_about_text); + + mImageId = avatar_data->fl_image_id; + + if (mImageId.notNull()) { - mIsEditing = true; - mDescriptionEdit->setParseHTML(false); - mDescriptionEdit->setText(mCurrentDescription); + mPicture->setValue(mImageId); } -} - -void LLPanelProfileFirstLife::processProperties(void* data, EAvatarProcessorType type) -{ - if (APT_PROPERTIES == type) + else { - const LLAvatarData* avatar_data = static_cast<const LLAvatarData*>(data); - if (avatar_data && getAvatarId() == avatar_data->avatar_id) - { - mCurrentDescription = avatar_data->fl_about_text; - mDescriptionEdit->setValue(mCurrentDescription); - mPicture->setValue(avatar_data->fl_image_id); - updateButtons(); - } + mPicture->setValue("Generic_Person_Large"); } + + setLoaded(); } void LLPanelProfileFirstLife::resetData() { - mDescriptionEdit->setValue(LLStringUtil::null); - mPicture->setValue(mPicture->getDefaultImageAssetID()); -} + setDescriptionText(std::string()); + mPicture->setValue("Generic_Person_Large"); + mImageId = LLUUID::null; -void LLPanelProfileFirstLife::apply(LLAvatarData* data) -{ - data->fl_image_id = mPicture->getImageAssetID(); - data->fl_about_text = mDescriptionEdit->getValue().asString(); + mUploadPhoto->setVisible(getSelfProfile()); + mChangePhoto->setVisible(getSelfProfile()); + mRemovePhoto->setVisible(getSelfProfile()); + mSaveChanges->setVisible(getSelfProfile()); + mDiscardChanges->setVisible(getSelfProfile()); } -void LLPanelProfileFirstLife::updateButtons() +void LLPanelProfileFirstLife::setLoaded() { - LLPanelProfileTab::updateButtons(); + LLPanelProfileTab::setLoaded(); - if (getSelfProfile() && !getEmbedded()) + if (getSelfProfile()) { mDescriptionEdit->setEnabled(TRUE); mPicture->setEnabled(TRUE); + mRemovePhoto->setEnabled(mImageId.notNull()); } } @@ -1219,45 +2393,48 @@ void LLPanelProfileFirstLife::updateButtons() LLPanelProfileNotes::LLPanelProfileNotes() : LLPanelProfileTab() -, mAvatarNameCacheConnection() + , mHasUnsavedChanges(false) { } LLPanelProfileNotes::~LLPanelProfileNotes() { - if (getAvatarId().notNull()) - { - LLAvatarTracker::instance().removeParticularFriendObserver(getAvatarId(), this); - } - - if (mAvatarNameCacheConnection.connected()) - { - mAvatarNameCacheConnection.disconnect(); - } } void LLPanelProfileNotes::updateData() { LLUUID avatar_id = getAvatarId(); - if (!getIsLoading() && avatar_id.notNull()) + if (!getStarted() && avatar_id.notNull()) { setIsLoading(); - LLAvatarPropertiesProcessor::getInstanceFast()->sendAvatarNotesRequest(avatar_id); + + std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); + if (!cap_url.empty()) + { + LLCoros::instance().launch("requestAgentUserInfoCoro", + boost::bind(request_avatar_properties_coro, cap_url, avatar_id)); + } + } +} + +void LLPanelProfileNotes::commitUnsavedChanges() +{ + if (mHasUnsavedChanges) + { + onSaveNotesChanges(); } } BOOL LLPanelProfileNotes::postBuild() { - mOnlineStatus = getChild<LLCheckBoxCtrl>("status_check"); - mMapRights = getChild<LLCheckBoxCtrl>("map_check"); - mEditObjectRights = getChild<LLCheckBoxCtrl>("objects_check"); mNotesEditor = getChild<LLTextEditor>("notes_edit"); - mCharacterLimitWarning = getChild<LLTextBox>("character_limit_warning"); + mSaveChanges = getChild<LLButton>("notes_save_changes"); + mDiscardChanges = getChild<LLButton>("notes_discard_changes"); - mEditObjectRights->setCommitCallback(boost::bind(&LLPanelProfileNotes::onCommitRights, this)); - - mNotesEditor->setCommitCallback(boost::bind(&LLPanelProfileNotes::onCommitNotes,this)); + mSaveChanges->setCommitCallback([this](LLUICtrl*, void*) { onSaveNotesChanges(); }, nullptr); + mDiscardChanges->setCommitCallback([this](LLUICtrl*, void*) { onDiscardNotesChanges(); }, nullptr); + mNotesEditor->setKeystrokeCallback([this](LLTextEditor* caller) { onSetNotesDirty(); }); return TRUE; } @@ -1267,222 +2444,67 @@ void LLPanelProfileNotes::onOpen(const LLSD& key) LLPanelProfileTab::onOpen(key); resetData(); - - fillRightsData(); - - mAvatarNameCacheConnection = LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileNotes::onAvatarNameCache, this, _1, _2)); -} - -void LLPanelProfileNotes::apply() -{ - onCommitNotes(); - applyRights(); -} - -void LLPanelProfileNotes::fillRightsData() -{ - mOnlineStatus->setValue(FALSE); - mMapRights->setValue(FALSE); - mEditObjectRights->setValue(FALSE); - - const LLRelationship* relation = LLAvatarTracker::instance().getBuddyInfo(getAvatarId()); - // If true - we are viewing friend's profile, enable check boxes and set values. - if(relation) - { - S32 rights = relation->getRightsGrantedTo(); - - mOnlineStatus->setValue(LLRelationship::GRANT_ONLINE_STATUS & rights ? TRUE : FALSE); - mMapRights->setValue(LLRelationship::GRANT_MAP_LOCATION & rights ? TRUE : FALSE); - mEditObjectRights->setValue(LLRelationship::GRANT_MODIFY_OBJECTS & rights ? TRUE : FALSE); - } - - enableCheckboxes(NULL != relation); -} - -void LLPanelProfileNotes::onCommitNotes() -{ - if (getIsLoaded()) - { - std::string notes = mNotesEditor->getValue().asString(); - LLAvatarPropertiesProcessor::getInstanceFast()->sendNotes(getAvatarId(),notes); - } -} - -void LLPanelProfileNotes::rightsConfirmationCallback(const LLSD& notification, - const LLSD& response) -{ - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if (option != 0) - { - mEditObjectRights->setValue(mEditObjectRights->getValue().asBoolean() ? FALSE : TRUE); - } } -void LLPanelProfileNotes::confirmModifyRights(bool grant) +void LLPanelProfileNotes::setNotesText(const std::string &text) { - LLSD args; - args["NAME"] = LLSLURL("agent", getAvatarId(), "completename").getSLURLString(); - - - LLNotificationsUtil::add(grant ? "GrantModifyRights" : "RevokeModifyRights", args, LLSD(), - boost::bind(&LLPanelProfileNotes::rightsConfirmationCallback, this, _1, _2)); + mSaveChanges->setEnabled(FALSE); + mDiscardChanges->setEnabled(FALSE); + mHasUnsavedChanges = false; + mCurrentNotes = text; + mNotesEditor->setValue(mCurrentNotes); } -void LLPanelProfileNotes::onCommitRights() +void LLPanelProfileNotes::onSetNotesDirty() { - const LLRelationship* buddy_relationship = LLAvatarTracker::instance().getBuddyInfo(getAvatarId()); - - if (!buddy_relationship) - { - LL_WARNS("LegacyProfile") << "Trying to modify rights for non-friend avatar. Skipped." << LL_ENDL; - return; - } - - bool allow_modify_objects = mEditObjectRights->getValue().asBoolean(); - - // if modify objects checkbox clicked - if (buddy_relationship->isRightGrantedTo( - LLRelationship::GRANT_MODIFY_OBJECTS) != allow_modify_objects) - { - confirmModifyRights(allow_modify_objects); - } + mSaveChanges->setEnabled(TRUE); + mDiscardChanges->setEnabled(TRUE); + mHasUnsavedChanges = true; } -void LLPanelProfileNotes::applyRights() +void LLPanelProfileNotes::onSaveNotesChanges() { - const LLRelationship* buddy_relationship = LLAvatarTracker::instance().getBuddyInfo(getAvatarId()); - - if (!buddy_relationship) - { - // Lets have a warning log message instead of having a crash. EXT-4947. - LL_WARNS("LegacyProfile") << "Trying to modify rights for non-friend avatar. Skipped." << LL_ENDL; - return; - } - - S32 rights = 0; - - if (mOnlineStatus->getValue().asBoolean()) - { - rights |= LLRelationship::GRANT_ONLINE_STATUS; - } - if (mMapRights->getValue().asBoolean()) + mCurrentNotes = mNotesEditor->getValue().asString(); + std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); + if (!cap_url.empty()) { - rights |= LLRelationship::GRANT_MAP_LOCATION; + LLCoros::instance().launch("putAgentUserInfoCoro", + boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), LLSD().with("notes", mCurrentNotes))); } - if (mEditObjectRights->getValue().asBoolean()) + else { - rights |= LLRelationship::GRANT_MODIFY_OBJECTS; + LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL; } - LLAvatarPropertiesProcessor::getInstanceFast()->sendFriendRights(getAvatarId(), rights); + mSaveChanges->setEnabled(FALSE); + mDiscardChanges->setEnabled(FALSE); + mHasUnsavedChanges = false; } -void LLPanelProfileNotes::updateWarning() +void LLPanelProfileNotes::onDiscardNotesChanges() { - mCharacterLimitWarning->setText(std::string()); - - std::string str = getString("header_symbol_limit"); - mCharacterLimitWarning->appendText(str, false, LLStyle::Params().color(LLColor4::yellow)); - mCharacterLimitWarning->appendText(" ", false, LLStyle::Params()); - - LLStringUtil::format_map_t args; - if (!mURLWebProfile.empty()) - { - args["[PROFILE_URL]"] = mURLWebProfile; - } - else - { - args["[PROFILE_URL]"] = getProfileURL(getAvatarId().asString()); - } - str = getString("body_symbol_limit", args); - mCharacterLimitWarning->appendText(str, false, LLStyle::Params()); + setNotesText(mCurrentNotes); } -void LLPanelProfileNotes::processProperties(void* data, EAvatarProcessorType type) +void LLPanelProfileNotes::processProperties(LLAvatarNotes* avatar_notes) { - if (APT_NOTES == type) - { - LLAvatarNotes* avatar_notes = static_cast<LLAvatarNotes*>(data); - if (avatar_notes && getAvatarId() == avatar_notes->target_id) - { - mNotesEditor->setValue(avatar_notes->notes); - mNotesEditor->setEnabled(TRUE); - updateButtons(); - - if (avatar_notes->notes.size() > 1000) - { - mCharacterLimitWarning->setVisible(TRUE); - updateWarning(); - } - else - { - mCharacterLimitWarning->setVisible(FALSE); - } - - LLAvatarPropertiesProcessor::getInstanceFast()->removeObserver(getAvatarId(),this); - } - } + setNotesText(avatar_notes->notes); + mNotesEditor->setEnabled(TRUE); + setLoaded(); } void LLPanelProfileNotes::resetData() { resetLoading(); - mNotesEditor->setValue(LLStringUtil::null); - mOnlineStatus->setValue(FALSE); - mMapRights->setValue(FALSE); - mEditObjectRights->setValue(FALSE); - mCharacterLimitWarning->setVisible(FALSE); - - mURLWebProfile.clear(); -} - -void LLPanelProfileNotes::enableCheckboxes(bool enable) -{ - mOnlineStatus->setEnabled(enable); - mMapRights->setEnabled(enable); - mEditObjectRights->setEnabled(enable); -} - -// virtual, called by LLAvatarTracker -void LLPanelProfileNotes::changed(U32 mask) -{ - // update rights to avoid have checkboxes enabled when friendship is terminated. EXT-4947. - fillRightsData(); + setNotesText(std::string()); } void LLPanelProfileNotes::setAvatarId(const LLUUID& avatar_id) { if (avatar_id.notNull()) { - if (getAvatarId().notNull()) - { - LLAvatarTracker::instance().removeParticularFriendObserver(getAvatarId(), this); - } LLPanelProfileTab::setAvatarId(avatar_id); - LLAvatarTracker::instance().addParticularFriendObserver(getAvatarId(), this); - } -} - -void LLPanelProfileNotes::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name) -{ - mAvatarNameCacheConnection.disconnect(); - - std::string username = av_name.getAccountName(); - if (username.empty()) - { - username = LLCacheName::buildUsername(av_name.getDisplayName()); - } - else - { - LLStringUtil::replaceChar(username, ' ', '.'); - } - - mURLWebProfile = getProfileURL(username, false); - - if (mCharacterLimitWarning->getVisible()) - { - updateWarning(); } } @@ -1504,15 +2526,6 @@ BOOL LLPanelProfile::postBuild() return TRUE; } -void LLPanelProfile::processProperties(void* data, EAvatarProcessorType type) -{ - //*TODO: figure out what this does - mTabContainer->setCommitCallback(boost::bind(&LLPanelProfile::onTabChange, this)); - - // Load data on currently opened tab as well - onTabChange(); -} - void LLPanelProfile::onTabChange() { LLPanelProfileTab* active_panel = dynamic_cast<LLPanelProfileTab*>(mTabContainer->getCurrentPanel()); @@ -1520,13 +2533,6 @@ void LLPanelProfile::onTabChange() { active_panel->updateData(); } - updateBtnsVisibility(); -} - -void LLPanelProfile::updateBtnsVisibility() -{ - getChild<LLUICtrl>("ok_btn")->setVisible(((getSelfProfile() && !getEmbedded()) || isNotesTabSelected())); - getChild<LLUICtrl>("cancel_btn")->setVisible(((getSelfProfile() && !getEmbedded()) || isNotesTabSelected())); } void LLPanelProfile::onOpen(const LLSD& key) @@ -1544,7 +2550,6 @@ void LLPanelProfile::onOpen(const LLSD& key) mTabContainer = getChild<LLTabContainer>("panel_profile_tabs"); mPanelSecondlife = findChild<LLPanelProfileSecondLife>(PANEL_SECONDLIFE); mPanelWeb = findChild<LLPanelProfileWeb>(PANEL_WEB); - mPanelInterests = findChild<LLPanelProfileInterests>(PANEL_INTERESTS); mPanelPicks = findChild<LLPanelProfilePicks>(PANEL_PICKS); mPanelClassifieds = findChild<LLPanelProfileClassifieds>(PANEL_CLASSIFIEDS); mPanelFirstlife = findChild<LLPanelProfileFirstLife>(PANEL_FIRSTLIFE); @@ -1552,64 +2557,51 @@ void LLPanelProfile::onOpen(const LLSD& key) mPanelSecondlife->onOpen(avatar_id); mPanelWeb->onOpen(avatar_id); - mPanelInterests->onOpen(avatar_id); mPanelPicks->onOpen(avatar_id); mPanelClassifieds->onOpen(avatar_id); mPanelFirstlife->onOpen(avatar_id); mPanelNotes->onOpen(avatar_id); - mPanelSecondlife->setEmbedded(getEmbedded()); - mPanelWeb->setEmbedded(getEmbedded()); - mPanelInterests->setEmbedded(getEmbedded()); - mPanelPicks->setEmbedded(getEmbedded()); - mPanelClassifieds->setEmbedded(getEmbedded()); - mPanelFirstlife->setEmbedded(getEmbedded()); - mPanelNotes->setEmbedded(getEmbedded()); - // Always request the base profile info resetLoading(); updateData(); - updateBtnsVisibility(); - - // KC - Not handling pick and classified opening thru onOpen - // because this would make unique profile floaters per slurl - // and result in multiple profile floaters for the same avatar + // Some tabs only request data when opened + mTabContainer->setCommitCallback(boost::bind(&LLPanelProfile::onTabChange, this)); } void LLPanelProfile::updateData() { LLUUID avatar_id = getAvatarId(); - if (!getIsLoading() && avatar_id.notNull()) + // Todo: getIsloading functionality needs to be expanded to + // include 'inited' or 'data_provided' state to not rerequest + if (!getStarted() && avatar_id.notNull()) { setIsLoading(); - LLAvatarPropertiesProcessor::getInstanceFast()->sendAvatarPropertiesRequest(avatar_id); + + mPanelSecondlife->setIsLoading(); + mPanelPicks->setIsLoading(); + mPanelFirstlife->setIsLoading(); + mPanelNotes->setIsLoading(); + + std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); + if (!cap_url.empty()) + { + LLCoros::instance().launch("requestAgentUserInfoCoro", + boost::bind(request_avatar_properties_coro, cap_url, avatar_id)); + } } } -void LLPanelProfile::apply() +void LLPanelProfile::refreshName() { - if (getSelfProfile()) - { - //KC - AvatarData is spread over 3 different panels - // collect data from the last 2 and give to the first to save - LLAvatarData data = LLAvatarData(); - data.avatar_id = gAgentID; - mPanelFirstlife->apply(&data); - mPanelWeb->apply(&data); - mPanelSecondlife->apply(&data); - - mPanelInterests->apply(); - mPanelPicks->apply(); - mPanelNotes->apply(); - mPanelClassifieds->apply(); + mPanelSecondlife->refreshName(); +} - //KC - Classifieds handles this itself - } - else - { - mPanelNotes->apply(); - } +void LLPanelProfile::createPick(const LLPickData &data) +{ + mTabContainer->selectTabPanel(mPanelPicks); + mPanelPicks->createPick(data); } void LLPanelProfile::showPick(const LLUUID& pick_id) @@ -1631,6 +2623,29 @@ bool LLPanelProfile::isNotesTabSelected() return (mTabContainer->getCurrentPanel() == mPanelNotes); } +bool LLPanelProfile::hasUnsavedChanges() +{ + return mPanelSecondlife->hasUnsavedChanges() + || mPanelPicks->hasUnsavedChanges() + || mPanelClassifieds->hasUnsavedChanges() + || mPanelFirstlife->hasUnsavedChanges() + || mPanelNotes->hasUnsavedChanges(); +} + +bool LLPanelProfile::hasUnpublishedClassifieds() +{ + return mPanelClassifieds->hasNewClassifieds(); +} + +void LLPanelProfile::commitUnsavedChanges() +{ + mPanelSecondlife->commitUnsavedChanges(); + mPanelPicks->commitUnsavedChanges(); + mPanelClassifieds->commitUnsavedChanges(); + mPanelFirstlife->commitUnsavedChanges(); + mPanelNotes->commitUnsavedChanges(); +} + void LLPanelProfile::showClassified(const LLUUID& classified_id, bool edit) { if (classified_id.notNull()) @@ -1640,5 +2655,9 @@ void LLPanelProfile::showClassified(const LLUUID& classified_id, bool edit) mTabContainer->selectTabPanel(mPanelClassifieds); } - +void LLPanelProfile::createClassified() +{ + mPanelClassifieds->createClassified(); + mTabContainer->selectTabPanel(mPanelClassifieds); +} diff --git a/indra/newview/llpanelprofile.h b/indra/newview/llpanelprofile.h index 66ba3e0fdb57b5b65781c49174d11a4952bc72ea..215594bc467a3a6470be2a78238498cdf24a8bf8 100644 --- a/indra/newview/llpanelprofile.h +++ b/indra/newview/llpanelprofile.h @@ -2,9 +2,9 @@ * @file llpanelprofile.h * @brief Profile panel * -* $LicenseInfo:firstyear=2009&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 @@ -40,13 +40,15 @@ // class LLPanelProfileSecondLife; // class LLPanelProfileWeb; -// class LLPanelProfileInterests; // class LLPanelProfilePicks; // class LLPanelProfileFirstLife; // class LLPanelProfileNotes; class LLAvatarName; +class LLButton; class LLCheckBoxCtrl; +class LLComboBox; +class LLIconCtrl; class LLTabContainer; class LLTextBox; class LLTextureCtrl; @@ -60,6 +62,7 @@ class LLPanelProfileClassifieds; class LLPanelProfilePicks; class LLViewerFetchedTexture; + /** * Panel for displaying Avatar's second life related info. */ @@ -72,81 +75,74 @@ class LLPanelProfileSecondLife LLPanelProfileSecondLife(); /*virtual*/ ~LLPanelProfileSecondLife(); - /*virtual*/ void onOpen(const LLSD& key); - - /** - * Saves changes. - */ - void apply(LLAvatarData* data); + void onOpen(const LLSD& key) override; /** * LLFriendObserver trigger */ - virtual void changed(U32 mask); + void changed(U32 mask) override; // Implements LLVoiceClientStatusObserver::onChange() to enable the call // button when voice is available - /*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal); - - /*virtual*/ void setAvatarId(const LLUUID& avatar_id); + void onChange(EStatusType status, const std::string &channelURI, bool proximal) override; - /*virtual*/ BOOL postBuild(); + void setAvatarId(const LLUUID& avatar_id) override; - /*virtual*/ void processProperties(void* data, EAvatarProcessorType type); + BOOL postBuild() override; - void resetData(); + void resetData() override; /** * Sends update data request to server. */ - /*virtual*/ void updateData(); + void updateData() override; + void refreshName(); void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name); + void setProfileImageUploading(bool loading); + void setProfileImageUploaded(const LLUUID &image_asset_id); + + bool hasUnsavedChanges() override; + void commitUnsavedChanges() override; + + friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id); + protected: /** * Process profile related data received from server. */ - virtual void processProfileProperties(const LLAvatarData* avatar_data); + void processProfileProperties(const LLAvatarData* avatar_data); /** * Processes group related data received from server. */ - virtual void processGroupProperties(const LLAvatarGroups* avatar_groups); + void processGroupProperties(const LLAvatarGroups* avatar_groups); /** * Fills common for Avatar profile and My Profile fields. */ - virtual void fillCommonData(const LLAvatarData* avatar_data); + void fillCommonData(const LLAvatarData* avatar_data); /** * Fills partner data. */ - virtual void fillPartnerData(const LLAvatarData* avatar_data); + void fillPartnerData(const LLAvatarData* avatar_data); /** * Fills account status. */ - virtual void fillAccountStatus(const LLAvatarData* avatar_data); + void fillAccountStatus(const LLAvatarData* avatar_data); - void onMapButtonClick(); - - /** - * Opens "Pay Resident" dialog. - */ - void pay(); - - /** - * Add/remove resident to/from your block list. - * Updates button focus - */ - void onClickToggleBlock(); - - void onAddFriendButtonClick(); - void onIMButtonClick(); - void onTeleportButtonClick(); + /** + * Sets permissions specific icon + */ + void fillRightsData(); - void onGroupInvite(); + /** + * Fills user name, display name, age. + */ + void fillAgeData(const LLDate &born_on); void onImageLoaded(BOOL success, LLViewerFetchedTexture *imagep); static void onImageLoaded(BOOL success, @@ -157,8 +153,6 @@ class LLPanelProfileSecondLife BOOL final, void* userdata); - bool isGrantedToSeeOnlineStatus(); - /** * Displays avatar's online status if possible. * @@ -172,39 +166,55 @@ class LLPanelProfileSecondLife * - Else: Offline */ void updateOnlineStatus(); - void processOnlineStatus(bool online); + void processOnlineStatus(bool is_friend, bool show_online, bool online); private: - /*virtual*/ void updateButtons(); - void onClickSetName(); - void onCommitTexture(); + void setLoaded() override; + void onCommitMenu(const LLSD& userdata); + bool onEnableMenu(const LLSD& userdata); + bool onCheckMenu(const LLSD& userdata); void onAvatarNameCacheSetName(const LLUUID& id, const LLAvatarName& av_name); + void setDescriptionText(const std::string &text); + void onSetDescriptionDirty(); + void onShowInSearchCallback(); + void onSaveDescriptionChanges(); + void onDiscardDescriptionChanges(); + void onShowAgentPermissionsDialog(); + void onShowAgentProfileTexture(); + void onShowTexturePicker(); + void onCommitProfileImage(const LLUUID& id); + private: typedef std::map<std::string, LLUUID> group_map_t; group_map_t mGroups; void openGroupProfile(); - LLTextBox* mStatusText; LLGroupList* mGroupList; - LLCheckBoxCtrl* mShowInSearchCheckbox; - LLTextureCtrl* mSecondLifePic; + LLComboBox* mShowInSearchCombo; + LLIconCtrl* mSecondLifePic; LLPanel* mSecondLifePicLayout; - LLTextBase* mDescriptionEdit; - LLButton* mTeleportButton; - LLButton* mShowOnMapButton; - LLButton* mBlockButton; - LLButton* mUnblockButton; - LLUICtrl* mNameLabel; - LLButton* mDisplayNameButton; - LLButton* mAddFriendButton; - LLButton* mGroupInviteButton; - LLButton* mPayButton; - LLButton* mIMButton; - LLMenuButton* mCopyMenuButton; - LLPanel* mGiveInvPanel; - + LLTextEditor* mDescriptionEdit; + LLMenuButton* mAgentActionMenuButton; + LLButton* mSaveDescriptionChanges; + LLButton* mDiscardDescriptionChanges; + LLIconCtrl* mCanSeeOnlineIcon; + LLIconCtrl* mCantSeeOnlineIcon; + LLIconCtrl* mCanSeeOnMapIcon; + LLIconCtrl* mCantSeeOnMapIcon; + LLIconCtrl* mCanEditObjectsIcon; + LLIconCtrl* mCantEditObjectsIcon; + + LLHandle<LLFloater> mFloaterPermissionsHandle; + LLHandle<LLFloater> mFloaterProfileTextureHandle; + LLHandle<LLFloater> mFloaterTexturePickerHandle; + + bool mHasUnsavedDescriptionChanges; bool mVoiceStatus; + bool mWaitingForImageUpload; + bool mAllowPublish; + std::string mDescriptionText; + LLUUID mImageId; boost::signals2::connection mAvatarNameCacheConnection; boost::signals2::connection mRlvBehaviorConn; @@ -222,30 +232,24 @@ class LLPanelProfileWeb LLPanelProfileWeb(); /*virtual*/ ~LLPanelProfileWeb(); - /*virtual*/ void onOpen(const LLSD& key); + void onOpen(const LLSD& key) override; - /*virtual*/ BOOL postBuild(); + BOOL postBuild() override; - /*virtual*/ void processProperties(void* data, EAvatarProcessorType type); - - void resetData(); - - /** - * Saves changes. - */ - void apply(LLAvatarData* data); + void resetData() override; /** * Loads web profile. */ - /*virtual*/ void updateData(); + void updateData() override; - /*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event); + void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) override; void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name); + friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id); + protected: - /*virtual*/ void updateButtons(); void onCommitLoad(LLUICtrl* ctrl); private: @@ -259,41 +263,6 @@ class LLPanelProfileWeb boost::signals2::connection mAvatarNameCacheConnection; }; -/** -* Panel for displaying Avatar's interests. -*/ -class LLPanelProfileInterests - : public LLPanelProfileTab -{ -public: - LLPanelProfileInterests(); - /*virtual*/ ~LLPanelProfileInterests(); - - /*virtual*/ void onOpen(const LLSD& key); - - /*virtual*/ BOOL postBuild(); - - /*virtual*/ void processProperties(void* data, EAvatarProcessorType type); - - void resetData(); - - /** - * Saves changes. - */ - virtual void apply(); - -protected: - /*virtual*/ void updateButtons(); - -private: - LLCheckBoxCtrl* mWantChecks[8]; - LLCheckBoxCtrl* mSkillChecks[6]; - LLLineEditor* mWantToEditor; - LLLineEditor* mSkillsEditor; - LLLineEditor* mLanguagesEditor; -}; - - /** * Panel for displaying Avatar's first life related info. */ @@ -304,28 +273,47 @@ class LLPanelProfileFirstLife LLPanelProfileFirstLife(); /*virtual*/ ~LLPanelProfileFirstLife(); - /*virtual*/ void onOpen(const LLSD& key); + void onOpen(const LLSD& key) override; - /*virtual*/ BOOL postBuild(); + BOOL postBuild() override; - /*virtual*/ void processProperties(void* data, EAvatarProcessorType type); + void processProperties(const LLAvatarData* avatar_data); - void resetData(); + void resetData() override; - /** - * Saves changes. - */ - void apply(LLAvatarData* data); + void setProfileImageUploading(bool loading); + void setProfileImageUploaded(const LLUUID &image_asset_id); + + bool hasUnsavedChanges() override { return mHasUnsavedChanges; } + void commitUnsavedChanges() override; + + friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id); protected: - /*virtual*/ void updateButtons(); - void onDescriptionFocusReceived(); + void setLoaded() override; - LLTextEditor* mDescriptionEdit; - LLTextureCtrl* mPicture; + void onUploadPhoto(); + void onChangePhoto(); + void onRemovePhoto(); + void onCommitPhoto(const LLUUID& id); + void setDescriptionText(const std::string &text); + void onSetDescriptionDirty(); + void onSaveDescriptionChanges(); + void onDiscardDescriptionChanges(); - bool mIsEditing; - std::string mCurrentDescription; + LLTextEditor* mDescriptionEdit; + LLIconCtrl* mPicture; + LLButton* mUploadPhoto; + LLButton* mChangePhoto; + LLButton* mRemovePhoto; + LLButton* mSaveChanges; + LLButton* mDiscardChanges; + + LLHandle<LLFloater> mFloaterTexturePickerHandle; + + std::string mCurrentDescription; + LLUUID mImageId; + bool mHasUnsavedChanges; }; /** @@ -333,60 +321,38 @@ class LLPanelProfileFirstLife */ class LLPanelProfileNotes : public LLPanelProfileTab - , public LLFriendObserver { public: LLPanelProfileNotes(); /*virtual*/ ~LLPanelProfileNotes(); - virtual void setAvatarId(const LLUUID& avatar_id); - - /** - * LLFriendObserver trigger - */ - virtual void changed(U32 mask); - - /*virtual*/ void onOpen(const LLSD& key); + void setAvatarId(const LLUUID& avatar_id) override; - /*virtual*/ BOOL postBuild(); + void onOpen(const LLSD& key) override; - /*virtual*/ void processProperties(void* data, EAvatarProcessorType type); + BOOL postBuild() override; - void resetData(); + void processProperties(LLAvatarNotes* avatar_notes); - /*virtual*/ void updateData(); + void resetData() override; - /** - * Saves changes. - */ - virtual void apply(); + void updateData() override; - void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name); + bool hasUnsavedChanges() override { return mHasUnsavedChanges; } + void commitUnsavedChanges() override; protected: - /** - * Fills rights data for friends. - */ - void fillRightsData(); - - void rightsConfirmationCallback(const LLSD& notification, const LLSD& response); - void confirmModifyRights(bool grant); - void onCommitRights(); - void onCommitNotes(); - void enableCheckboxes(bool enable); - - void applyRights(); - void updateWarning(); + void setNotesText(const std::string &text); + void onSetNotesDirty(); + void onSaveNotesChanges(); + void onDiscardNotesChanges(); - LLCheckBoxCtrl* mOnlineStatus; - LLCheckBoxCtrl* mMapRights; - LLCheckBoxCtrl* mEditObjectRights; LLTextEditor* mNotesEditor; - LLTextBox* mCharacterLimitWarning; + LLButton* mSaveChanges; + LLButton* mDiscardChanges; - std::string mURLWebProfile; - - boost::signals2::connection mAvatarNameCacheConnection; + std::string mCurrentNotes; + bool mHasUnsavedChanges; }; @@ -400,38 +366,45 @@ class LLPanelProfile LLPanelProfile(); /*virtual*/ ~LLPanelProfile(); - /*virtual*/ BOOL postBuild(); - - /*virtual*/ void updateData(); - - /*virtual*/ void processProperties(void* data, EAvatarProcessorType type); + BOOL postBuild() override; - /*virtual*/ void onOpen(const LLSD& key); + void updateData() override; + void refreshName(); - /** - * Saves changes. - */ - void apply(); + void onOpen(const LLSD& key) override; + void createPick(const LLPickData &data); void showPick(const LLUUID& pick_id = LLUUID::null); bool isPickTabSelected(); bool isNotesTabSelected(); - - void updateBtnsVisibility(); + bool hasUnsavedChanges() override; + bool hasUnpublishedClassifieds(); + void commitUnsavedChanges() override; void showClassified(const LLUUID& classified_id = LLUUID::null, bool edit = false); + void createClassified(); + + LLAvatarData getAvatarData() { return mAvatarData; }; + + friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id); private: void onTabChange(); LLPanelProfileSecondLife* mPanelSecondlife; LLPanelProfileWeb* mPanelWeb; - LLPanelProfileInterests* mPanelInterests; LLPanelProfilePicks* mPanelPicks; LLPanelProfileClassifieds* mPanelClassifieds; LLPanelProfileFirstLife* mPanelFirstlife; - LLPanelProfileNotes* mPanelNotes; + LLPanelProfileNotes* mPanelNotes; LLTabContainer* mTabContainer; + + // Todo: due to server taking minutes to update this needs a more long term storage + // to reuse recently saved values if user opens floater again + // Storage implementation depends onto how a cap will be implemented, if cap will be + // enought to fully update LLAvatarPropertiesProcessor, then this storage can be + // implemented there. + LLAvatarData mAvatarData; }; #endif //LL_LLPANELPROFILE_H diff --git a/indra/newview/llpanelprofileclassifieds.cpp b/indra/newview/llpanelprofileclassifieds.cpp index 7f0af75626342a44bb50fd4a0aee3b4410ccc4d6..8a13f0c236863e74fc26a5880272a64aa8faca46 100644 --- a/indra/newview/llpanelprofileclassifieds.cpp +++ b/indra/newview/llpanelprofileclassifieds.cpp @@ -2,9 +2,9 @@ * @file llpanelprofileclassifieds.cpp * @brief LLPanelProfileClassifieds and related class implementations * - * $LicenseInfo:firstyear=2009&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 @@ -36,6 +36,7 @@ #include "llcommandhandler.h" // for classified HTML detail page click tracking #include "llcorehttputil.h" #include "lldispatcher.h" +#include "llfloaterclassified.h" #include "llfloaterreg.h" #include "llfloatersidepanelcontainer.h" #include "llfloaterworldmap.h" @@ -90,7 +91,7 @@ class LLClassifiedHandler : public LLCommandHandler, public LLAvatarPropertiesOb return true; } - if (!LLUI::getInstanceFast()->mSettingGroups["config"]->getBOOL("EnableClassifieds")) + if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnableClassifieds")) { LLNotificationsUtil::add("NoClassifieds", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit")); return true; @@ -99,7 +100,7 @@ class LLClassifiedHandler : public LLCommandHandler, public LLAvatarPropertiesOb // handle app/classified/create urls first if (params.size() == 1 && params[0].asString() == "create") { - LLAvatarActions::showClassifieds(gAgent.getID()); + LLAvatarActions::createClassified(); return true; } @@ -123,8 +124,8 @@ class LLClassifiedHandler : public LLCommandHandler, public LLAvatarPropertiesOb { mRequestVerb = verb; mClassifiedIds.insert(classified_id); - LLAvatarPropertiesProcessor::getInstanceFast()->addObserver(LLUUID(), this); - LLAvatarPropertiesProcessor::getInstanceFast()->sendClassifiedInfoRequest(classified_id); + LLAvatarPropertiesProcessor::getInstance()->addObserver(LLUUID(), this); + LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(classified_id); return true; } else if (verb == "edit") @@ -148,15 +149,19 @@ class LLClassifiedHandler : public LLCommandHandler, public LLAvatarPropertiesOb { LLSD params; params["id"] = c_info->creator_id; - params["open_tab_name"] = "panel_picks"; - params["show_tab_panel"] = "classified_details"; params["classified_id"] = c_info->classified_id; params["classified_creator_id"] = c_info->creator_id; params["classified_snapshot_id"] = c_info->snapshot_id; params["classified_name"] = c_info->name; params["classified_desc"] = c_info->description; params["from_search"] = true; - LLFloaterSidePanelContainer::showPanel("picks", params); + + LLFloaterClassified* floaterp = LLFloaterReg::getTypedInstance<LLFloaterClassified>("classified", params); + if (floaterp) + { + floaterp->openFloater(params); + floaterp->setVisibleAndFrontmost(); + } } } } @@ -180,7 +185,7 @@ class LLClassifiedHandler : public LLCommandHandler, public LLAvatarPropertiesOb // remove our observer now that we're done mClassifiedIds.erase(c_info->classified_id); - LLAvatarPropertiesProcessor::getInstanceFast()->removeObserver(LLUUID(), this); + LLAvatarPropertiesProcessor::getInstance()->removeObserver(LLUUID(), this); } }; LLClassifiedHandler gClassifiedHandler; @@ -193,9 +198,10 @@ LLClassifiedHandler gClassifiedHandler; //----------------------------------------------------------------------------- LLPanelProfileClassifieds::LLPanelProfileClassifieds() - : LLPanelProfileTab() + : LLPanelProfilePropertiesProcessorTab() , mClassifiedToSelectOnLoad(LLUUID::null) , mClassifiedEditOnLoad(false) + , mSheduledClassifiedCreation(false) { } @@ -209,11 +215,12 @@ LLPanelProfileClassifieds::~LLPanelProfileClassifieds() void LLPanelProfileClassifieds::onOpen(const LLSD& key) { - LLPanelProfileTab::onOpen(key); + LLPanelProfilePropertiesProcessorTab::onOpen(key); resetData(); - if (getSelfProfile() && !getEmbedded()) + bool own_profile = getSelfProfile(); + if (own_profile) { mNewButton->setVisible(TRUE); mNewButton->setEnabled(FALSE); @@ -229,6 +236,9 @@ void LLPanelProfileClassifieds::onOpen(const LLSD& key) mDeleteButton->setVisible(FALSE); mDeleteButton->setEnabled(FALSE); } + + childSetVisible("buttons_header", own_profile); + } void LLPanelProfileClassifieds::selectClassified(const LLUUID& classified_id, bool edit) @@ -259,6 +269,26 @@ void LLPanelProfileClassifieds::selectClassified(const LLUUID& classified_id, bo } } +void LLPanelProfileClassifieds::createClassified() +{ + if (getIsLoaded()) + { + mNoItemsLabel->setVisible(FALSE); + LLPanelProfileClassified* classified_panel = LLPanelProfileClassified::create(); + classified_panel->onOpen(LLSD()); + mTabContainer->addTabPanel( + LLTabContainer::TabPanelParams(). + panel(classified_panel). + select_tab(true). + label(classified_panel->getClassifiedName())); + updateButtons(); + } + else + { + mSheduledClassifiedCreation = true; + } +} + BOOL LLPanelProfileClassifieds::postBuild() { mTabContainer = getChild<LLTabContainer>("tab_classifieds"); @@ -294,11 +324,11 @@ void LLPanelProfileClassifieds::onClickDelete() { LLUUID classified_id = classified_panel->getClassifiedId(); LLSD args; - args["PICK"] = classified_panel->getClassifiedName(); + args["CLASSIFIED"] = classified_panel->getClassifiedName(); LLSD payload; payload["classified_id"] = classified_id; payload["tab_idx"] = mTabContainer->getCurrentPanelIndex(); - LLNotificationsUtil::add("DeleteAvatarPick", args, payload, + LLNotificationsUtil::add("ProfileDeleteClassified", args, payload, boost::bind(&LLPanelProfileClassifieds::callbackDeleteClassified, this, _1, _2)); } } @@ -320,7 +350,7 @@ void LLPanelProfileClassifieds::callbackDeleteClassified(const LLSD& notificatio if (classified_id.notNull()) { - LLAvatarPropertiesProcessor::getInstanceFast()->sendClassifiedDelete(classified_id); + LLAvatarPropertiesProcessor::getInstance()->sendClassifiedDelete(classified_id); } updateButtons(); @@ -342,6 +372,7 @@ void LLPanelProfileClassifieds::processProperties(void* data, EAvatarProcessorTy // do not clear classified list in case we will receive two or more data packets. // list has been cleared in updateData(). (fix for EXT-6436) LLUUID selected_id = mClassifiedToSelectOnLoad; + bool has_selection = false; LLAvatarClassifieds::classifieds_list_t::const_iterator it = c_info->classifieds_list.begin(); for (; c_info->classifieds_list.end() != it; ++it) @@ -366,29 +397,46 @@ void LLPanelProfileClassifieds::processProperties(void* data, EAvatarProcessorTy if (selected_id == c_data.classified_id) { - mClassifiedToSelectOnLoad = LLUUID::null; - mClassifiedEditOnLoad = false; + has_selection = true; } } - BOOL no_data = !mTabContainer->getTabCount(); - mNoItemsLabel->setVisible(no_data); - if (no_data) + if (mSheduledClassifiedCreation) { - if(getSelfProfile()) - { - mNoItemsLabel->setValue(LLTrans::getString("NoClassifiedsText")); - } - else - { - mNoItemsLabel->setValue(LLTrans::getString("NoAvatarClassifiedsText")); - } + LLPanelProfileClassified* classified_panel = LLPanelProfileClassified::create(); + classified_panel->onOpen(LLSD()); + mTabContainer->addTabPanel( + LLTabContainer::TabPanelParams(). + panel(classified_panel). + select_tab(!has_selection). + label(classified_panel->getClassifiedName())); + has_selection = true; } - else if (selected_id.isNull()) + + // reset 'do on load' values + mClassifiedToSelectOnLoad = LLUUID::null; + mClassifiedEditOnLoad = false; + mSheduledClassifiedCreation = false; + + // set even if not visible, user might delete own + // calassified and this string will need to be shown + if (getSelfProfile()) + { + mNoItemsLabel->setValue(LLTrans::getString("NoClassifiedsText")); + } + else + { + mNoItemsLabel->setValue(LLTrans::getString("NoAvatarClassifiedsText")); + } + + bool has_data = mTabContainer->getTabCount() > 0; + mNoItemsLabel->setVisible(!has_data); + if (has_data && !has_selection) { mTabContainer->selectFirstTab(); } + setLoaded(); updateButtons(); } } @@ -402,9 +450,7 @@ void LLPanelProfileClassifieds::resetData() void LLPanelProfileClassifieds::updateButtons() { - LLPanelProfileTab::updateButtons(); - - if (getSelfProfile() && !getEmbedded()) + if (getSelfProfile()) { mNewButton->setEnabled(canAddNewClassified()); mDeleteButton->setEnabled(canDeleteClassified()); @@ -415,14 +461,40 @@ void LLPanelProfileClassifieds::updateData() { // Send picks request only once LLUUID avatar_id = getAvatarId(); - if (!getIsLoading() && avatar_id.notNull()) + if (!getStarted() && avatar_id.notNull()) { setIsLoading(); mNoItemsLabel->setValue(LLTrans::getString("PicksClassifiedsLoadingText")); mNoItemsLabel->setVisible(TRUE); - LLAvatarPropertiesProcessor::getInstanceFast()->sendAvatarClassifiedsRequest(avatar_id); + LLAvatarPropertiesProcessor::getInstance()->sendAvatarClassifiedsRequest(avatar_id); + } +} + +bool LLPanelProfileClassifieds::hasNewClassifieds() +{ + for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx) + { + LLPanelProfileClassified* classified_panel = dynamic_cast<LLPanelProfileClassified*>(mTabContainer->getPanelByIndex(tab_idx)); + if (classified_panel && classified_panel->isNew()) + { + return true; + } + } + return false; +} + +bool LLPanelProfileClassifieds::hasUnsavedChanges() +{ + for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx) + { + LLPanelProfileClassified* classified_panel = dynamic_cast<LLPanelProfileClassified*>(mTabContainer->getPanelByIndex(tab_idx)); + if (classified_panel && classified_panel->isDirty()) // includes 'new' + { + return true; + } } + return false; } bool LLPanelProfileClassifieds::canAddNewClassified() @@ -435,7 +507,7 @@ bool LLPanelProfileClassifieds::canDeleteClassified() return (mTabContainer->getTabCount() > 0); } -void LLPanelProfileClassifieds::apply() +void LLPanelProfileClassifieds::commitUnsavedChanges() { if (getIsLoaded()) { @@ -490,7 +562,7 @@ static const S32 CB_ITEM_MATURE = 0; static const S32 CB_ITEM_PG = 1; LLPanelProfileClassified::LLPanelProfileClassified() - : LLPanelProfileTab() + : LLPanelProfilePropertiesProcessorTab() , mInfoLoaded(false) , mTeleportClicksOld(0) , mMapClicksOld(0) @@ -561,9 +633,8 @@ BOOL LLPanelProfileClassified::postBuild() mSetLocationButton = getChild<LLButton>("set_to_curr_location_btn"); mCancelButton = getChild<LLButton>("cancel_btn"); - mTeleportBtnCnt = getChild<LLPanel>("teleport_btn_lp"); - mMapBtnCnt = getChild<LLPanel>("map_btn_lp"); - mEditBtnCnt = getChild<LLPanel>("edit_btn_lp"); + mUtilityBtnCnt = getChild<LLPanel>("util_buttons_lp"); + mPublishBtnsCnt = getChild<LLPanel>("publish_layout_panel"); mCancelBtnCnt = getChild<LLPanel>("cancel_btn_lp"); mSaveBtnCnt = getChild<LLPanel>("save_btn_lp"); @@ -609,13 +680,13 @@ void LLPanelProfileClassified::onOpen(const LLSD& key) if(is_new) { - LLPanelProfileTab::setAvatarId(gAgent.getID()); + LLPanelProfilePropertiesProcessorTab::setAvatarId(gAgent.getID()); setPosGlobal(gAgent.getPositionGlobal()); LLUUID snapshot_id = LLUUID::null; std::string desc; - LLParcel* parcel = LLViewerParcelMgr::getInstanceFast()->getAgentParcel(); + LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); if(parcel) { desc = parcel->getDesc(); @@ -651,7 +722,7 @@ void LLPanelProfileClassified::onOpen(const LLSD& key) { return; } - LLPanelProfileTab::setAvatarId(avatar_id); + LLPanelProfilePropertiesProcessorTab::setAvatarId(avatar_id); setClassifiedId(key["classified_id"]); setClassifiedName(key["classified_name"]); @@ -660,7 +731,7 @@ void LLPanelProfileClassified::onOpen(const LLSD& key) LL_INFOS() << "Opening classified [" << getClassifiedName() << "] (" << getClassifiedId() << ")" << LL_ENDL; - LLAvatarPropertiesProcessor::getInstanceFast()->sendClassifiedInfoRequest(getClassifiedId()); + LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(getClassifiedId()); gGenericDispatcher.addHandler("classifiedclickthrough", &sClassifiedClickThrough); @@ -708,7 +779,13 @@ void LLPanelProfileClassified::processProperties(void* data, EAvatarProcessorTyp if(c_info && getClassifiedId() == c_info->classified_id) { // see LLPanelProfileClassified::sendUpdate() for notes + if (mIsNewWithErrors) + { + // We just published it + setEditMode(FALSE); + } mIsNewWithErrors = false; + mIsNew = false; setClassifiedName(c_info->name); setDescription(c_info->description); @@ -748,6 +825,7 @@ void LLPanelProfileClassified::processProperties(void* data, EAvatarProcessorTyp // for just created classified - in case user opened edit panel before processProperties() callback mSaveButton->setLabelArg("[LABEL]", getString("save_label")); + setLoaded(); updateButtons(); if (mEditOnLoad) @@ -777,10 +855,12 @@ void LLPanelProfileClassified::setEditMode(BOOL edit_mode) void LLPanelProfileClassified::updateButtons() { bool edit_mode = getEditMode(); - mTeleportBtnCnt->setVisible(!edit_mode); - mMapBtnCnt->setVisible(!edit_mode); - mEditBtnCnt->setVisible(!edit_mode); - mCancelBtnCnt->setVisible(edit_mode); + mUtilityBtnCnt->setVisible(!edit_mode); + + // cancel button should either delete unpublished + // classified or not be there at all + mCancelBtnCnt->setVisible(edit_mode && !mIsNew); + mPublishBtnsCnt->setVisible(edit_mode); mSaveBtnCnt->setVisible(edit_mode); mEditButton->setVisible(!edit_mode && getSelfProfile()); } @@ -847,7 +927,7 @@ void LLPanelProfileClassified::onCancelClick() else { // Reload data to undo changes to forms - LLAvatarPropertiesProcessor::getInstanceFast()->sendClassifiedInfoRequest(getClassifiedId()); + LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(getClassifiedId()); } setInfoLoaded(false); @@ -1229,7 +1309,7 @@ void LLPanelProfileClassified::sendUpdate() c_data.flags = getFlags(); c_data.price_for_listing = getPriceForListing(); - LLAvatarPropertiesProcessor::getInstanceFast()->sendClassifiedInfoUpdate(&c_data); + LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoUpdate(&c_data); if(isNew()) { @@ -1269,7 +1349,7 @@ std::string LLPanelProfileClassified::makeClassifiedName() { std::string name; - LLParcel* parcel = LLViewerParcelMgr::getInstanceFast()->getAgentParcel(); + LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); if(parcel) { name = parcel->getName(); diff --git a/indra/newview/llpanelprofileclassifieds.h b/indra/newview/llpanelprofileclassifieds.h index 8ddef4d11122c1aab1447fd67473f8cfb5f13afb..188c16141d86894ff69dc3353ce34282ad09b28d 100644 --- a/indra/newview/llpanelprofileclassifieds.h +++ b/indra/newview/llpanelprofileclassifieds.h @@ -2,9 +2,9 @@ * @file llpanelprofileclassifieds.h * @brief LLPanelProfileClassifieds and related class implementations * - * $LicenseInfo:firstyear=2009&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 @@ -54,7 +54,7 @@ class LLPublishClassifiedFloater final : public LLFloater LLPublishClassifiedFloater(const LLSD& key); virtual ~LLPublishClassifiedFloater(); - /*virtual*/ BOOL postBuild(); + BOOL postBuild() override; void setPrice(S32 price); S32 getPrice(); @@ -68,27 +68,32 @@ class LLPublishClassifiedFloater final : public LLFloater * Panel for displaying Avatar's picks. */ class LLPanelProfileClassifieds - : public LLPanelProfileTab + : public LLPanelProfilePropertiesProcessorTab { public: LLPanelProfileClassifieds(); /*virtual*/ ~LLPanelProfileClassifieds(); - /*virtual*/ BOOL postBuild(); + BOOL postBuild() override; - /*virtual*/ void onOpen(const LLSD& key); + void onOpen(const LLSD& key) override; void selectClassified(const LLUUID& classified_id, bool edit); - /*virtual*/ void processProperties(void* data, EAvatarProcessorType type); + void createClassified(); - /*virtual*/ void resetData(); + void processProperties(void* data, EAvatarProcessorType type) override; - /*virtual*/ void updateButtons(); + void resetData() override; - /*virtual*/ void updateData(); + void updateButtons(); - /*virtual*/ void apply(); + void updateData() override; + + bool hasNewClassifieds(); + bool hasUnsavedChanges() override; + // commits changes to existing classifieds, but does not publish new classified! + void commitUnsavedChanges() override; private: void onClickNewBtn(); @@ -105,13 +110,13 @@ class LLPanelProfileClassifieds LLUUID mClassifiedToSelectOnLoad; bool mClassifiedEditOnLoad; - + bool mSheduledClassifiedCreation; boost::signals2::connection mRlvBehaviorConn; }; class LLPanelProfileClassified - : public LLPanelProfileTab + : public LLPanelProfilePropertiesProcessorTab { public: @@ -121,11 +126,11 @@ class LLPanelProfileClassified /*virtual*/ ~LLPanelProfileClassified(); - /*virtual*/ BOOL postBuild(); + BOOL postBuild() override; - void onOpen(const LLSD& key); + void onOpen(const LLSD& key) override; - /*virtual*/ void processProperties(void* data, EAvatarProcessorType type); + void processProperties(void* data, EAvatarProcessorType type) override; void setSnapshotId(const LLUUID& id); @@ -167,9 +172,9 @@ class LLPanelProfileClassified void setInfoLoaded(bool loaded) { mInfoLoaded = loaded; } - /*virtual*/ BOOL isDirty() const; + BOOL isDirty() const override; - /*virtual*/ void resetDirty(); + void resetDirty() override; bool isNew() { return mIsNew; } @@ -211,11 +216,11 @@ class LLPanelProfileClassified protected: - /*virtual*/ void resetData(); + void resetData() override; void resetControls(); - /*virtual*/ void updateButtons(); + void updateButtons(); void updateInfoRect(); static std::string createLocationText( @@ -261,46 +266,6 @@ class LLPanelProfileClassified void onTextureSelected(); - - - - /** - * Callback for "Map" button, opens Map - */ - void onClickMap(); - - /** - * Callback for "Teleport" button, teleports user to Pick location. - */ - void onClickTeleport(); - - /** - * Enables/disables "Save" button - */ - void enableSaveButton(BOOL enable); - - /** - * Called when snapshot image changes. - */ - void onSnapshotChanged(); - - /** - * Callback for Pick snapshot, name and description changed event. - */ - void onPickChanged(LLUICtrl* ctrl); - - /** - * Callback for "Set Location" button click - */ - void onClickSetLocation(); - - /** - * Callback for "Save" button click - */ - void onClickSave(); - - void onDescriptionFocusReceived(); - void updateTabLabel(const std::string& title); private: @@ -330,9 +295,8 @@ class LLPanelProfileClassified LLButton* mSetLocationButton; LLButton* mCancelButton; - LLPanel* mMapBtnCnt; - LLPanel* mTeleportBtnCnt; - LLPanel* mEditBtnCnt; + LLPanel* mUtilityBtnCnt; + LLPanel* mPublishBtnsCnt; LLPanel* mSaveBtnCnt; LLPanel* mCancelBtnCnt; diff --git a/indra/newview/llpanelprofilelegacy.cpp b/indra/newview/llpanelprofilelegacy.cpp index 58744a8b7aeaee7f0cd93a992097003549505068..01cd9d388aca97ba8cc754eaa0521a253ad82ec2 100644 --- a/indra/newview/llpanelprofilelegacy.cpp +++ b/indra/newview/llpanelprofilelegacy.cpp @@ -58,7 +58,6 @@ #include "llfloaterworldmap.h" #include "llgroupactions.h" #include "llpanelclassified.h" -#include "llpanelpick.h" #if WIP_PROFILES #include "llpanelpicks.h" #include "llpickitem.h" diff --git a/indra/newview/llpanelprofilepicks.cpp b/indra/newview/llpanelprofilepicks.cpp index 6f8acae5916b8ffdb2dd76164a59eef62a70b485..4f95a4e80586f62d997269717f90470abc62c015 100644 --- a/indra/newview/llpanelprofilepicks.cpp +++ b/indra/newview/llpanelprofilepicks.cpp @@ -74,16 +74,16 @@ class LLPickHandler : public LLCommandHandler return true; } - if (!LLUI::getInstanceFast()->mSettingGroups["config"]->getBOOL("EnablePicks")) + if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnablePicks")) { LLNotificationsUtil::add("NoPicks", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit")); return true; } - // handle app/classified/create urls first + // handle app/pick/create urls first if (params.size() == 1 && params[0].asString() == "create") { - LLAvatarActions::showPicks(gAgent.getID()); + LLAvatarActions::createPick(); return true; } @@ -123,7 +123,7 @@ LLPickHandler gPickHandler; //----------------------------------------------------------------------------- LLPanelProfilePicks::LLPanelProfilePicks() - : LLPanelProfileTab() + : LLPanelProfilePropertiesProcessorTab() , mPickToSelectOnLoad(LLUUID::null) { } @@ -138,11 +138,12 @@ LLPanelProfilePicks::~LLPanelProfilePicks() void LLPanelProfilePicks::onOpen(const LLSD& key) { - LLPanelProfileTab::onOpen(key); + LLPanelProfilePropertiesProcessorTab::onOpen(key); resetData(); - if (getSelfProfile() && !getEmbedded()) + bool own_profile = getSelfProfile(); + if (own_profile) { mNewButton->setVisible(TRUE); mNewButton->setEnabled(FALSE); @@ -150,6 +151,38 @@ void LLPanelProfilePicks::onOpen(const LLSD& key) mDeleteButton->setVisible(TRUE); mDeleteButton->setEnabled(FALSE); } + + childSetVisible("buttons_header", own_profile); +} + +void LLPanelProfilePicks::createPick(const LLPickData &data) +{ + if (getIsLoaded()) + { + if (canAddNewPick()) + { + mNoItemsLabel->setVisible(FALSE); + LLPanelProfilePick* pick_panel = LLPanelProfilePick::create(); + pick_panel->setAvatarId(getAvatarId()); + pick_panel->processProperties(&data); + mTabContainer->addTabPanel( + LLTabContainer::TabPanelParams(). + panel(pick_panel). + select_tab(true). + label(pick_panel->getPickName())); + updateButtons(); + } + else + { + // This means that something doesn't properly check limits + // before creating a pick + LL_WARNS() << "failed to add pick" << LL_ENDL; + } + } + else + { + mSheduledPickCreation.push_back(data); + } } void LLPanelProfilePicks::selectPick(const LLUUID& pick_id) @@ -214,7 +247,7 @@ void LLPanelProfilePicks::onClickDelete() LLSD payload; payload["pick_id"] = pick_id; payload["tab_idx"] = mTabContainer->getCurrentPanelIndex(); - LLNotificationsUtil::add("DeleteAvatarPick", args, payload, + LLNotificationsUtil::add("ProfileDeletePick", args, payload, boost::bind(&LLPanelProfilePicks::callbackDeletePick, this, _1, _2)); } } @@ -236,7 +269,7 @@ void LLPanelProfilePicks::callbackDeletePick(const LLSD& notification, const LLS if (pick_id.notNull()) { - LLAvatarPropertiesProcessor::getInstanceFast()->sendPickDelete(pick_id); + LLAvatarPropertiesProcessor::getInstance()->sendPickDelete(pick_id); } updateButtons(); @@ -250,66 +283,93 @@ void LLPanelProfilePicks::processProperties(void* data, EAvatarProcessorType typ LLAvatarPicks* avatar_picks = static_cast<LLAvatarPicks*>(data); if (avatar_picks && getAvatarId() == avatar_picks->target_id) { - LLUUID selected_id = mPickToSelectOnLoad; - if (mPickToSelectOnLoad.isNull()) + processProperties(avatar_picks); + } + } +} + +void LLPanelProfilePicks::processProperties(const LLAvatarPicks* avatar_picks) +{ + LLUUID selected_id = mPickToSelectOnLoad; + bool has_selection = false; + if (mPickToSelectOnLoad.isNull()) + { + if (mTabContainer->getTabCount() > 0) + { + LLPanelProfilePick* active_pick_panel = dynamic_cast<LLPanelProfilePick*>(mTabContainer->getCurrentPanel()); + if (active_pick_panel) { - if (mTabContainer->getTabCount() > 0) - { - LLPanelProfilePick* active_pick_panel = dynamic_cast<LLPanelProfilePick*>(mTabContainer->getCurrentPanel()); - if (active_pick_panel) - { - selected_id = active_pick_panel->getPickId(); - } - } + selected_id = active_pick_panel->getPickId(); } + } + } - mTabContainer->deleteAllTabs(); + mTabContainer->deleteAllTabs(); - LLAvatarPicks::picks_list_t::const_iterator it = avatar_picks->picks_list.begin(); - for (; avatar_picks->picks_list.end() != it; ++it) - { - LLUUID pick_id = it->first; - std::string pick_name = it->second; + LLAvatarPicks::picks_list_t::const_iterator it = avatar_picks->picks_list.begin(); + for (; avatar_picks->picks_list.end() != it; ++it) + { + LLUUID pick_id = it->first; + std::string pick_name = it->second; - LLPanelProfilePick* pick_panel = LLPanelProfilePick::create(); + LLPanelProfilePick* pick_panel = LLPanelProfilePick::create(); - pick_panel->setPickId(pick_id); - pick_panel->setPickName(pick_name); - pick_panel->setAvatarId(getAvatarId()); + pick_panel->setPickId(pick_id); + pick_panel->setPickName(pick_name); + pick_panel->setAvatarId(getAvatarId()); - mTabContainer->addTabPanel( - LLTabContainer::TabPanelParams(). - panel(pick_panel). - select_tab(selected_id == pick_id). - label(pick_name)); + mTabContainer->addTabPanel( + LLTabContainer::TabPanelParams(). + panel(pick_panel). + select_tab(selected_id == pick_id). + label(pick_name)); - if (selected_id == pick_id) - { - mPickToSelectOnLoad = LLUUID::null; - } - } + if (selected_id == pick_id) + { + has_selection = true; + } + } - BOOL no_data = !mTabContainer->getTabCount(); - mNoItemsLabel->setVisible(no_data); - if (no_data) - { - if(getSelfProfile()) - { - mNoItemsLabel->setValue(LLTrans::getString("NoPicksText")); - } - else - { - mNoItemsLabel->setValue(LLTrans::getString("NoAvatarPicksText")); - } - } - else if (selected_id.isNull()) - { - mTabContainer->selectFirstTab(); - } + while (!mSheduledPickCreation.empty() && canAddNewPick()) + { + const LLPickData data = + mSheduledPickCreation.back(); - updateButtons(); - } + LLPanelProfilePick* pick_panel = LLPanelProfilePick::create(); + pick_panel->setAvatarId(getAvatarId()); + pick_panel->processProperties(&data); + mTabContainer->addTabPanel( + LLTabContainer::TabPanelParams(). + panel(pick_panel). + select_tab(!has_selection). + label(pick_panel->getPickName())); + + mSheduledPickCreation.pop_back(); + has_selection = true; + } + + // reset 'do on load' values + mPickToSelectOnLoad = LLUUID::null; + mSheduledPickCreation.clear(); + + if (getSelfProfile()) + { + mNoItemsLabel->setValue(LLTrans::getString("NoPicksText")); + } + else + { + mNoItemsLabel->setValue(LLTrans::getString("NoAvatarPicksText")); + } + + bool has_data = mTabContainer->getTabCount() > 0; + mNoItemsLabel->setVisible(!has_data); + if (has_data && !has_selection) + { + mTabContainer->selectFirstTab(); } + + setLoaded(); + updateButtons(); } void LLPanelProfilePicks::resetData() @@ -320,9 +380,7 @@ void LLPanelProfilePicks::resetData() void LLPanelProfilePicks::updateButtons() { - LLPanelProfileTab::updateButtons(); - - if (getSelfProfile() && !getEmbedded()) + if (getSelfProfile()) { mNewButton->setEnabled(canAddNewPick()); mDeleteButton->setEnabled(canDeletePick()); @@ -348,19 +406,47 @@ void LLPanelProfilePicks::updateData() { // Send picks request only once LLUUID avatar_id = getAvatarId(); - if (!getIsLoading() && avatar_id.notNull()) + if (!getStarted() && avatar_id.notNull()) { setIsLoading(); + + LLAvatarPropertiesProcessor::getInstance()->sendAvatarPicksRequest(avatar_id); + } + if (!getIsLoaded()) + { mNoItemsLabel->setValue(LLTrans::getString("PicksClassifiedsLoadingText")); mNoItemsLabel->setVisible(TRUE); + } +} + +bool LLPanelProfilePicks::hasUnsavedChanges() +{ + for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx) + { + LLPanelProfilePick* pick_panel = dynamic_cast<LLPanelProfilePick*>(mTabContainer->getPanelByIndex(tab_idx)); + if (pick_panel && (pick_panel->isDirty() || pick_panel->isDirty())) + { + return true; + } + } + return false; +} - LLAvatarPropertiesProcessor::getInstanceFast()->sendAvatarPicksRequest(avatar_id); +void LLPanelProfilePicks::commitUnsavedChanges() +{ + for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx) + { + LLPanelProfilePick* pick_panel = dynamic_cast<LLPanelProfilePick*>(mTabContainer->getPanelByIndex(tab_idx)); + if (pick_panel) + { + pick_panel->apply(); + } } } bool LLPanelProfilePicks::canAddNewPick() { - return (!LLAgentPicksInfo::getInstanceFast()->isPickLimitReached() && + return (!LLAgentPicksInfo::getInstance()->isPickLimitReached() && mTabContainer->getTabCount() < LLAgentBenefitsMgr::current().getPicksLimit() && RlvActions::canShowLocation()); } @@ -376,7 +462,7 @@ bool LLPanelProfilePicks::canDeletePick() //----------------------------------------------------------------------------- LLPanelProfilePick::LLPanelProfilePick() - : LLPanelProfileTab() + : LLPanelProfilePropertiesProcessorTab() , LLRemoteParcelInfoObserver() , mSnapshotCtrl(NULL) , mPickId(LLUUID::null) @@ -384,7 +470,6 @@ LLPanelProfilePick::LLPanelProfilePick() , mRequestedId(LLUUID::null) , mLocationChanged(false) , mNewPick(false) - , mCurrentPickDescription("") , mIsEditing(false) { } @@ -401,7 +486,7 @@ LLPanelProfilePick::~LLPanelProfilePick() { if (mParcelId.notNull()) { - LLRemoteParcelInfoProcessor::getInstanceFast()->removeObserver(mParcelId, this); + LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelId, this); } } @@ -411,7 +496,7 @@ void LLPanelProfilePick::setAvatarId(const LLUUID& avatar_id) { return; } - LLPanelProfileTab::setAvatarId(avatar_id); + LLPanelProfilePropertiesProcessorTab::setAvatarId(avatar_id); // creating new Pick if (getPickId().isNull() && getSelfProfile()) @@ -423,7 +508,7 @@ void LLPanelProfilePick::setAvatarId(const LLUUID& avatar_id) LLUUID parcel_id = LLUUID::null, snapshot_id = LLUUID::null; std::string pick_name, pick_desc, region_name; - LLParcel* parcel = LLViewerParcelMgr::getInstanceFast()->getAgentParcel(); + LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); if (parcel) { parcel_id = parcel->getID(); @@ -448,14 +533,14 @@ void LLPanelProfilePick::setAvatarId(const LLUUID& avatar_id) } else { - LLAvatarPropertiesProcessor::getInstanceFast()->sendPickInfoRequest(getAvatarId(), getPickId()); + LLAvatarPropertiesProcessor::getInstance()->sendPickInfoRequest(getAvatarId(), getPickId()); enableSaveButton(FALSE); } resetDirty(); - if (getSelfProfile() && !getEmbedded()) + if (getSelfProfile()) { mPickName->setEnabled(TRUE); mPickDescription->setEnabled(TRUE); @@ -472,6 +557,8 @@ BOOL LLPanelProfilePick::postBuild() mPickName = getChild<LLLineEditor>("pick_name"); mPickDescription = getChild<LLTextEditor>("pick_desc"); mSaveButton = getChild<LLButton>("save_changes_btn"); + mCreateButton = getChild<LLButton>("create_changes_btn"); + mCancelButton = getChild<LLButton>("cancel_changes_btn"); mSetCurrentLocationButton = getChild<LLButton>("set_to_curr_location_btn"); mSnapshotCtrl = getChild<LLTextureCtrl>("pick_snapshot"); @@ -481,6 +568,8 @@ BOOL LLPanelProfilePick::postBuild() childSetAction("show_on_map_btn", boost::bind(&LLPanelProfilePick::onClickMap, this)); mSaveButton->setCommitCallback(boost::bind(&LLPanelProfilePick::onClickSave, this)); + mCreateButton->setCommitCallback(boost::bind(&LLPanelProfilePick::onClickSave, this)); + mCancelButton->setCommitCallback(boost::bind(&LLPanelProfilePick::onClickCancel, this)); mSetCurrentLocationButton->setCommitCallback(boost::bind(&LLPanelProfilePick::onClickSetLocation, this)); mPickName->setKeystrokeCallback(boost::bind(&LLPanelProfilePick::onPickChanged, this, _1), NULL); @@ -500,7 +589,6 @@ void LLPanelProfilePick::onDescriptionFocusReceived() { mIsEditing = true; mPickDescription->setParseHTML(false); - setPickDesc(mCurrentPickDescription); } } @@ -519,18 +607,22 @@ void LLPanelProfilePick::processProperties(void* data, EAvatarProcessorType type return; } + processProperties(pick_info); +} + +void LLPanelProfilePick::processProperties(const LLPickData* pick_info) +{ mIsEditing = false; mPickDescription->setParseHTML(true); mParcelId = pick_info->parcel_id; setSnapshotId(pick_info->snapshot_id); - if (!getSelfProfile() || getEmbedded()) + if (!getSelfProfile()) { mSnapshotCtrl->setEnabled(FALSE); } setPickName(pick_info->name); setPickDesc(pick_info->desc); setPosGlobal(pick_info->pos_global); - mCurrentPickDescription = pick_info->desc; // Send remote parcel info request to get parcel name and sim (region) name. sendParcelInfoRequest(); @@ -540,7 +632,7 @@ void LLPanelProfilePick::processProperties(void* data, EAvatarProcessorType type // edit the Pick and we have to update Pick info panel. // revomeObserver is called from onClickBack - updateButtons(); + setLoaded(); } void LLPanelProfilePick::apply() @@ -594,8 +686,11 @@ void LLPanelProfilePick::onClickTeleport() void LLPanelProfilePick::enableSaveButton(BOOL enable) { - mSaveButton->setEnabled(enable); - mSaveButton->setVisible(enable); + childSetVisible("save_changes_lp", enable); + + childSetVisible("save_btn_lp", enable && !mNewPick); + childSetVisible("create_btn_lp", enable && mNewPick); + childSetVisible("cancel_btn_lp", enable && !mNewPick); } void LLPanelProfilePick::onSnapshotChanged() @@ -644,7 +739,7 @@ void LLPanelProfilePick::onClickSetLocation() std::string parcel_name, region_name; - LLParcel* parcel = LLViewerParcelMgr::getInstanceFast()->getAgentParcel(); + LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); if (parcel) { mParcelId = parcel->getID(); @@ -670,6 +765,13 @@ void LLPanelProfilePick::onClickSave() mLocationChanged = false; } +void LLPanelProfilePick::onClickCancel() +{ + LLAvatarPropertiesProcessor::getInstance()->sendPickInfoRequest(getAvatarId(), getPickId()); + mLocationChanged = false; + enableSaveButton(FALSE); +} + std::string LLPanelProfilePick::getLocationNotice() { static const std::string notice = getString("location_notice"); @@ -682,10 +784,10 @@ void LLPanelProfilePick::sendParcelInfoRequest() { if (mRequestedId.notNull()) { - LLRemoteParcelInfoProcessor::getInstanceFast()->removeObserver(mRequestedId, this); + LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mRequestedId, this); } - LLRemoteParcelInfoProcessor::getInstanceFast()->addObserver(mParcelId, this); - LLRemoteParcelInfoProcessor::getInstanceFast()->sendParcelInfoRequest(mParcelId); + LLRemoteParcelInfoProcessor::getInstance()->addObserver(mParcelId, this); + LLRemoteParcelInfoProcessor::getInstance()->sendParcelInfoRequest(mParcelId); mRequestedId = mParcelId; } @@ -700,7 +802,7 @@ void LLPanelProfilePick::processParcelInfo(const LLParcelData& parcel_data) if (mParcelId.notNull()) { - LLRemoteParcelInfoProcessor::getInstanceFast()->removeObserver(mParcelId, this); + LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelId, this); } } @@ -730,14 +832,14 @@ void LLPanelProfilePick::sendUpdate() pick_data.sort_order = 0; pick_data.enabled = TRUE; - LLAvatarPropertiesProcessor::getInstanceFast()->sendPickInfoUpdate(&pick_data); + LLAvatarPropertiesProcessor::getInstance()->sendPickInfoUpdate(&pick_data); if(mNewPick) { // Assume a successful create pick operation, make new number of picks // available immediately. Actual number of picks will be requested in // LLAvatarPropertiesProcessor::sendPickInfoUpdate and updated upon server respond. - LLAgentPicksInfo::getInstanceFast()->incrementNumberOfPicks(); + LLAgentPicksInfo::getInstance()->incrementNumberOfPicks(); } } diff --git a/indra/newview/llpanelprofilepicks.h b/indra/newview/llpanelprofilepicks.h index 558956e809d7425d2d35a3cac0faa0e3c0d79be2..fa5155cb22e0c5ed3375213396ed86f43953515a 100644 --- a/indra/newview/llpanelprofilepicks.h +++ b/indra/newview/llpanelprofilepicks.h @@ -2,9 +2,9 @@ * @file llpanelprofilepicks.h * @brief LLPanelProfilePicks and related class definitions * - * $LicenseInfo:firstyear=2009&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 @@ -44,23 +44,25 @@ class LLTextEditor; * Panel for displaying Avatar's picks. */ class LLPanelProfilePicks - : public LLPanelProfileTab + : public LLPanelProfilePropertiesProcessorTab { public: LLPanelProfilePicks(); /*virtual*/ ~LLPanelProfilePicks(); - /*virtual*/ BOOL postBuild(); + BOOL postBuild() override; - /*virtual*/ void onOpen(const LLSD& key); + void onOpen(const LLSD& key) override; + void createPick(const LLPickData &data); void selectPick(const LLUUID& pick_id); - /*virtual*/ void processProperties(void* data, EAvatarProcessorType type); + void processProperties(void* data, EAvatarProcessorType type) override; + void processProperties(const LLAvatarPicks* avatar_picks); - /*virtual*/ void resetData(); + void resetData() override; - /*virtual*/ void updateButtons(); + void updateButtons(); /** * Saves changes. @@ -70,7 +72,12 @@ class LLPanelProfilePicks /** * Sends update data request to server. */ - /*virtual*/ void updateData(); + void updateData() override; + + bool hasUnsavedChanges() override; + void commitUnsavedChanges() override; + + friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id); private: void onClickNewBtn(); @@ -86,13 +93,13 @@ class LLPanelProfilePicks LLButton* mDeleteButton; LLUUID mPickToSelectOnLoad; - + std::list<LLPickData> mSheduledPickCreation; boost::signals2::connection mRlvBehaviorConn; }; class LLPanelProfilePick - : public LLPanelProfileTab + : public LLPanelProfilePropertiesProcessorTab , public LLRemoteParcelInfoObserver { public: @@ -104,9 +111,9 @@ class LLPanelProfilePick /*virtual*/ ~LLPanelProfilePick(); - /*virtual*/ BOOL postBuild(); + BOOL postBuild() override; - void setAvatarId(const LLUUID& avatar_id); + void setAvatarId(const LLUUID& avatar_id) override; void setPickId(const LLUUID& id) { mPickId = id; } virtual LLUUID& getPickId() { return mPickId; } @@ -114,7 +121,13 @@ class LLPanelProfilePick virtual void setPickName(const std::string& name); const std::string getPickName(); - /*virtual*/ void processProperties(void* data, EAvatarProcessorType type); + void processProperties(void* data, EAvatarProcessorType type) override; + void processProperties(const LLPickData* pick_data); + + /** + * Returns true if any of Pick properties was changed by user. + */ + BOOL isDirty() const override; /** * Saves changes. @@ -124,9 +137,9 @@ class LLPanelProfilePick void updateTabLabel(const std::string& title); //This stuff we got from LLRemoteParcelObserver, in the last one we intentionally do nothing - /*virtual*/ void processParcelInfo(const LLParcelData& parcel_data); - /*virtual*/ void setParcelID(const LLUUID& parcel_id) { mParcelId = parcel_id; } - /*virtual*/ void setErrorStatus(S32 status, const std::string& reason) {}; + void processParcelInfo(const LLParcelData& parcel_data) override; + void setParcelID(const LLUUID& parcel_id) override { mParcelId = parcel_id; } + void setErrorStatus(S32 status, const std::string& reason) override {}; protected: @@ -187,22 +200,22 @@ class LLPanelProfilePick /** * Resets panel and all cantrols to unedited state */ - /*virtual*/ void resetDirty(); + void resetDirty() override; /** - * Returns true if any of Pick properties was changed by user. + * Callback for "Set Location" button click */ - /*virtual*/ BOOL isDirty() const; + void onClickSetLocation(); /** - * Callback for "Set Location" button click + * Callback for "Save" and "Create" button click */ - void onClickSetLocation(); + void onClickSave(); /** * Callback for "Save" button click */ - void onClickSave(); + void onClickCancel(); std::string getLocationNotice(); @@ -218,6 +231,8 @@ class LLPanelProfilePick LLTextEditor* mPickDescription; LLButton* mSetCurrentLocationButton; LLButton* mSaveButton; + LLButton* mCreateButton; + LLButton* mCancelButton; LLVector3d mPosGlobal; LLUUID mParcelId; @@ -228,8 +243,6 @@ class LLPanelProfilePick bool mNewPick; bool mIsEditing; - std::string mCurrentPickDescription; - void onDescriptionFocusReceived(); }; diff --git a/indra/newview/llpaneltopinfobar.cpp b/indra/newview/llpaneltopinfobar.cpp index e47b439d598ebaf3685860e59242abfc2c3843b1..092196ff4f5ea0038b9a81d692c29a91049eddcc 100644 --- a/indra/newview/llpaneltopinfobar.cpp +++ b/indra/newview/llpaneltopinfobar.cpp @@ -281,7 +281,7 @@ void LLPanelTopInfoBar::updateParcelInfoText() void LLPanelTopInfoBar::updateParcelIcons() { - LLViewerParcelMgr* vpm = LLViewerParcelMgr::getInstanceFast(); + LLViewerParcelMgr* vpm = LLViewerParcelMgr::getInstance(); LLViewerRegion* agent_region = gAgent.getRegion(); LLParcel* agent_parcel = vpm->getAgentParcel(); diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp index 1b4fa15c3ac8cfab5d8a032d619e8688b8ec91ff..4e074b0f1f016f4b4e60a692bfc56b1d056ba26e 100644 --- a/indra/newview/llpanelvolume.cpp +++ b/indra/newview/llpanelvolume.cpp @@ -51,6 +51,7 @@ #include "llfocusmgr.h" #include "llmanipscale.h" #include "llinventorymodel.h" +#include "llmenubutton.h" #include "llpreviewscript.h" #include "llresmgr.h" #include "llselectmgr.h" @@ -199,6 +200,9 @@ BOOL LLPanelVolume::postBuild() mSpinPhysicsRestitution->setCommitCallback(boost::bind(&LLPanelVolume::sendPhysicsRestitution, this, _1, mSpinPhysicsRestitution)); } + mMenuClipboardFeatures = getChild<LLMenuButton>("clipboard_features_params_btn"); + mMenuClipboardLight = getChild<LLMenuButton>("clipboard_light_params_btn"); + std::map<std::string, std::string> material_name_map; material_name_map["Stone"]= LLTrans::getString("Stone"); material_name_map["Metal"]= LLTrans::getString("Metal"); @@ -239,6 +243,8 @@ LLPanelVolume::LLPanelVolume() { setMouseOpaque(FALSE); + mCommitCallbackRegistrar.add("PanelVolume.menuDoToSelected", boost::bind(&LLPanelVolume::menuDoToSelected, this, _2)); + mEnableCallbackRegistrar.add("PanelVolume.menuEnable", boost::bind(&LLPanelVolume::menuEnableItem, this, _2)); } @@ -249,11 +255,11 @@ LLPanelVolume::~LLPanelVolume() void LLPanelVolume::getState( ) { - LLViewerObject* objectp = LLSelectMgr::getInstanceFast()->getSelection()->getFirstRootObject(); + LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstRootObject(); LLViewerObject* root_objectp = objectp; if(!objectp) { - objectp = LLSelectMgr::getInstanceFast()->getSelection()->getFirstObject(); + objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); // *FIX: shouldn't we just keep the child? if (objectp) { @@ -297,14 +303,14 @@ void LLPanelVolume::getState( ) LLUUID owner_id; std::string owner_name; - LLSelectMgr::getInstanceFast()->selectGetOwner(owner_id, owner_name); + LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name); // BUG? Check for all objects being editable? BOOL editable = root_objectp->permModify() && !root_objectp->isPermanentEnforced(); - BOOL single_volume = LLSelectMgr::getInstanceFast()->selectionAllPCode( LL_PCODE_VOLUME ) - && LLSelectMgr::getInstanceFast()->getSelection()->getObjectCount() == 1; - BOOL single_root_volume = LLSelectMgr::getInstanceFast()->selectionAllPCode( LL_PCODE_VOLUME ) && - LLSelectMgr::getInstanceFast()->getSelection()->getRootObjectCount() == 1; + BOOL single_volume = LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME ) + && LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1; + BOOL single_root_volume = LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME ) && + LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() == 1; // Select Single Message if (single_volume) @@ -424,7 +430,6 @@ void LLPanelVolume::getState( ) gAgentAvatarp->updateMeshVisibility(); } } - // Flexible properties BOOL is_flexible = volobjp && volobjp->isFlexible(); @@ -501,7 +506,7 @@ void LLPanelVolume::getState( ) return object->getMaterial(); } } func; - bool material_same = LLSelectMgr::getInstanceFast()->getSelection()->getSelectedTEValue( &func, material_code ); + bool material_same = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, material_code ); std::string LEGACY_FULLBRIGHT_DESC = LLTrans::getString("Fullbright"); if (editable && single_volume && material_same) { @@ -579,6 +584,9 @@ void LLPanelVolume::getState( ) mObject = objectp; mRootObject = root_objectp; + + mMenuClipboardFeatures->setEnabled(editable && single_volume && volobjp); // Note: physics doesn't need to be limited by single volume + mMenuClipboardLight->setEnabled(editable && single_volume && volobjp); } // static @@ -602,13 +610,6 @@ void LLPanelVolume::refresh() mRootObject = NULL; } - BOOL visible = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 0 ? TRUE : FALSE; - - mLightFOV->setVisible(visible); - mLightFocus->setVisible(visible); - mLightAmbiance->setVisible(visible); - mLightTextureCtrl->setVisible( visible); - bool enable_mesh = false; LLSD sim_features; @@ -713,7 +714,7 @@ void LLPanelVolume::sendIsFlexible() if (objectp->getClickAction() == CLICK_ACTION_SIT) { - LLSelectMgr::getInstanceFast()->selectionSetClickAction(CLICK_ACTION_NONE); + LLSelectMgr::getInstance()->selectionSetClickAction(CLICK_ACTION_NONE); } } @@ -721,7 +722,7 @@ void LLPanelVolume::sendIsFlexible() if (volobjp->setIsFlexible(is_flexible)) { mObject->sendShapeUpdate(); - LLSelectMgr::getInstanceFast()->selectionUpdatePhantom(volobjp->flagPhantom()); + LLSelectMgr::getInstance()->selectionUpdatePhantom(volobjp->flagPhantom()); } LL_INFOS() << "update flexible sent" << LL_ENDL; @@ -730,7 +731,7 @@ void LLPanelVolume::sendIsFlexible() void LLPanelVolume::sendPhysicsShapeType(LLUICtrl* ctrl, void* userdata) { U8 type = ctrl->getValue().asInteger(); - LLSelectMgr::getInstanceFast()->selectionSetPhysicsType(type); + LLSelectMgr::getInstance()->selectionSetPhysicsType(type); refreshCost(); } @@ -738,30 +739,30 @@ void LLPanelVolume::sendPhysicsShapeType(LLUICtrl* ctrl, void* userdata) void LLPanelVolume::sendPhysicsGravity(LLUICtrl* ctrl, void* userdata) { F32 val = ctrl->getValue().asReal(); - LLSelectMgr::getInstanceFast()->selectionSetGravity(val); + LLSelectMgr::getInstance()->selectionSetGravity(val); } void LLPanelVolume::sendPhysicsFriction(LLUICtrl* ctrl, void* userdata) { F32 val = ctrl->getValue().asReal(); - LLSelectMgr::getInstanceFast()->selectionSetFriction(val); + LLSelectMgr::getInstance()->selectionSetFriction(val); } void LLPanelVolume::sendPhysicsRestitution(LLUICtrl* ctrl, void* userdata) { F32 val = ctrl->getValue().asReal(); - LLSelectMgr::getInstanceFast()->selectionSetRestitution(val); + LLSelectMgr::getInstance()->selectionSetRestitution(val); } void LLPanelVolume::sendPhysicsDensity(LLUICtrl* ctrl, void* userdata) { F32 val = ctrl->getValue().asReal(); - LLSelectMgr::getInstanceFast()->selectionSetDensity(val); + LLSelectMgr::getInstance()->selectionSetDensity(val); } void LLPanelVolume::refreshCost() { - LLViewerObject* obj = LLSelectMgr::getInstanceFast()->getSelection()->getFirstObject(); + LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); if (obj) { @@ -827,6 +828,290 @@ void LLPanelVolume::onLightSelectTexture(const LLSD& data) setLightTextureID(id, mLightTextureCtrl->getImageItemID(), volobjp); } +void LLPanelVolume::onCopyFeatures() +{ + LLViewerObject* objectp = mObject; + if (!objectp) + { + return; + } + + LLSD clipboard; + + LLVOVolume *volobjp = NULL; + if (objectp && (objectp->getPCode() == LL_PCODE_VOLUME)) + { + volobjp = (LLVOVolume *)objectp; + } + + // Flexi Prim + if (volobjp && volobjp->isFlexible()) + { + LLFlexibleObjectData *attributes = (LLFlexibleObjectData *)objectp->getFlexibleObjectData(); + if (attributes) + { + clipboard["flex"]["lod"] = attributes->getSimulateLOD(); + clipboard["flex"]["gav"] = attributes->getGravity(); + clipboard["flex"]["ten"] = attributes->getTension(); + clipboard["flex"]["fri"] = attributes->getAirFriction(); + clipboard["flex"]["sen"] = attributes->getWindSensitivity(); + LLVector3 force = attributes->getUserForce(); + clipboard["flex"]["forx"] = force.mV[0]; + clipboard["flex"]["fory"] = force.mV[1]; + clipboard["flex"]["forz"] = force.mV[2]; + } + } + + // Physics + { + clipboard["physics"]["shape"] = objectp->getPhysicsShapeType(); + clipboard["physics"]["gravity"] = objectp->getPhysicsGravity(); + clipboard["physics"]["friction"] = objectp->getPhysicsFriction(); + clipboard["physics"]["density"] = objectp->getPhysicsDensity(); + clipboard["physics"]["restitution"] = objectp->getPhysicsRestitution(); + + U8 material_code = 0; + struct f : public LLSelectedTEGetFunctor<U8> + { + U8 get(LLViewerObject* object, S32 te) + { + return object->getMaterial(); + } + } func; + bool material_same = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&func, material_code); + // This should always be true since material should be per object. + if (material_same) + { + clipboard["physics"]["material"] = material_code; + } + } + + mClipboardParams["features"] = clipboard; +} + +void LLPanelVolume::onPasteFeatures() +{ + LLViewerObject* objectp = mObject; + if (!objectp && mClipboardParams.has("features")) + { + return; + } + + LLSD &clipboard = mClipboardParams["features"]; + + LLVOVolume *volobjp = NULL; + if (objectp && (objectp->getPCode() == LL_PCODE_VOLUME)) + { + volobjp = (LLVOVolume *)objectp; + } + + // Physics + bool is_root = objectp->isRoot(); + + // Not sure if phantom should go under physics, but doesn't fit elsewhere + BOOL is_phantom = clipboard["is_phantom"].asBoolean() && is_root; + LLSelectMgr::getInstance()->selectionUpdatePhantom(is_phantom); + + BOOL is_physical = clipboard["is_physical"].asBoolean() && is_root; + LLSelectMgr::getInstance()->selectionUpdatePhysics(is_physical); + + if (clipboard.has("physics")) + { + objectp->setPhysicsShapeType((U8)clipboard["physics"]["shape"].asInteger()); + U8 cur_material = objectp->getMaterial(); + U8 material = (U8)clipboard["physics"]["material"].asInteger() | (cur_material & ~LL_MCODE_MASK); + + objectp->setMaterial(material); + objectp->sendMaterialUpdate(); + objectp->setPhysicsGravity(clipboard["physics"]["gravity"].asReal()); + objectp->setPhysicsFriction(clipboard["physics"]["friction"].asReal()); + objectp->setPhysicsDensity(clipboard["physics"]["density"].asReal()); + objectp->setPhysicsRestitution(clipboard["physics"]["restitution"].asReal()); + objectp->updateFlags(TRUE); + } + + // Flexible + bool is_flexible = clipboard.has("flex"); + if (is_flexible && volobjp->canBeFlexible()) + { + LLVOVolume *volobjp = (LLVOVolume *)objectp; + BOOL update_shape = FALSE; + + // do before setParameterEntry or it will think that it is already flexi + update_shape = volobjp->setIsFlexible(is_flexible); + + if (objectp->getClickAction() == CLICK_ACTION_SIT) + { + objectp->setClickAction(CLICK_ACTION_NONE); + } + + LLFlexibleObjectData *attributes = (LLFlexibleObjectData *)objectp->getFlexibleObjectData(); + if (attributes) + { + LLFlexibleObjectData new_attributes; + new_attributes = *attributes; + new_attributes.setSimulateLOD(clipboard["flex"]["lod"].asInteger()); + new_attributes.setGravity(clipboard["flex"]["gav"].asReal()); + new_attributes.setTension(clipboard["flex"]["ten"].asReal()); + new_attributes.setAirFriction(clipboard["flex"]["fri"].asReal()); + new_attributes.setWindSensitivity(clipboard["flex"]["sen"].asReal()); + F32 fx = (F32)clipboard["flex"]["forx"].asReal(); + F32 fy = (F32)clipboard["flex"]["fory"].asReal(); + F32 fz = (F32)clipboard["flex"]["forz"].asReal(); + LLVector3 force(fx, fy, fz); + new_attributes.setUserForce(force); + objectp->setParameterEntry(LLNetworkData::PARAMS_FLEXIBLE, new_attributes, true); + } + + if (update_shape) + { + mObject->sendShapeUpdate(); + LLSelectMgr::getInstance()->selectionUpdatePhantom(volobjp->flagPhantom()); + } + } + else + { + LLVOVolume *volobjp = (LLVOVolume *)objectp; + if (volobjp->setIsFlexible(false)) + { + mObject->sendShapeUpdate(); + LLSelectMgr::getInstance()->selectionUpdatePhantom(volobjp->flagPhantom()); + } + } +} + +void LLPanelVolume::onCopyLight() +{ + LLViewerObject* objectp = mObject; + if (!objectp) + { + return; + } + + LLSD clipboard; + + LLVOVolume *volobjp = NULL; + if (objectp && (objectp->getPCode() == LL_PCODE_VOLUME)) + { + volobjp = (LLVOVolume *)objectp; + } + + // Light Source + if (volobjp && volobjp->getIsLight()) + { + clipboard["light"]["intensity"] = volobjp->getLightIntensity(); + clipboard["light"]["radius"] = volobjp->getLightRadius(); + clipboard["light"]["falloff"] = volobjp->getLightFalloff(); + LLColor3 color = volobjp->getLightSRGBColor(); + clipboard["light"]["r"] = color.mV[0]; + clipboard["light"]["g"] = color.mV[1]; + clipboard["light"]["b"] = color.mV[2]; + + // Spotlight + if (volobjp->isLightSpotlight()) + { + LLUUID id = volobjp->getLightTextureID(); + if (id.notNull() && get_can_copy_texture(id)) + { + clipboard["spot"]["id"] = id; + LLVector3 spot_params = volobjp->getSpotLightParams(); + clipboard["spot"]["fov"] = spot_params.mV[0]; + clipboard["spot"]["focus"] = spot_params.mV[1]; + clipboard["spot"]["ambiance"] = spot_params.mV[2]; + } + } + } + + mClipboardParams["light"] = clipboard; +} + +void LLPanelVolume::onPasteLight() +{ + LLViewerObject* objectp = mObject; + if (!objectp && mClipboardParams.has("light")) + { + return; + } + + LLSD &clipboard = mClipboardParams["light"]; + + LLVOVolume *volobjp = NULL; + if (objectp && (objectp->getPCode() == LL_PCODE_VOLUME)) + { + volobjp = (LLVOVolume *)objectp; + } + + // Light Source + if (volobjp) + { + if (clipboard.has("light")) + { + volobjp->setIsLight(TRUE); + volobjp->setLightIntensity((F32)clipboard["light"]["intensity"].asReal()); + volobjp->setLightRadius((F32)clipboard["light"]["radius"].asReal()); + volobjp->setLightFalloff((F32)clipboard["light"]["falloff"].asReal()); + F32 r = (F32)clipboard["light"]["r"].asReal(); + F32 g = (F32)clipboard["light"]["g"].asReal(); + F32 b = (F32)clipboard["light"]["b"].asReal(); + volobjp->setLightSRGBColor(LLColor3(r, g, b)); + } + else + { + volobjp->setIsLight(FALSE); + } + + if (clipboard.has("spot")) + { + volobjp->setLightTextureID(clipboard["spot"]["id"].asUUID()); + LLVector3 spot_params; + spot_params.mV[0] = (F32)clipboard["spot"]["fov"].asReal(); + spot_params.mV[1] = (F32)clipboard["spot"]["focus"].asReal(); + spot_params.mV[2] = (F32)clipboard["spot"]["ambiance"].asReal(); + volobjp->setSpotLightParams(spot_params); + } + } +} + +void LLPanelVolume::menuDoToSelected(const LLSD& userdata) +{ + std::string command = userdata.asString(); + + // paste + if (command == "features_paste") + { + onPasteFeatures(); + } + else if (command == "light_paste") + { + onPasteLight(); + } + // copy + else if (command == "features_copy") + { + onCopyFeatures(); + } + else if (command == "light_copy") + { + onCopyLight(); + } +} + +bool LLPanelVolume::menuEnableItem(const LLSD& userdata) +{ + std::string command = userdata.asString(); + + // paste options + if (command == "features_paste") + { + return mClipboardParams.has("features"); + } + else if (command == "light_paste") + { + return mClipboardParams.has("light"); + } + return false; +} + // static void LLPanelVolume::onCommitMaterial( LLUICtrl* ctrl, void* userdata ) { @@ -854,7 +1139,7 @@ void LLPanelVolume::onCommitMaterial( LLUICtrl* ctrl, void* userdata ) objectp->setPhysicsRestitution(LLMaterialTable::basic.getRestitution(material_code)); } } - LLSelectMgr::getInstanceFast()->selectionSetMaterial(material_code); + LLSelectMgr::getInstance()->selectionSetMaterial(material_code); } } } diff --git a/indra/newview/llpanelvolume.h b/indra/newview/llpanelvolume.h index 77ea15f7f8418a3755cec2072626fe4b573b4b25..7cdd33aceb8041571bdbe2aead3fec82e31c0ecd 100644 --- a/indra/newview/llpanelvolume.h +++ b/indra/newview/llpanelvolume.h @@ -37,6 +37,7 @@ class LLCheckBoxCtrl; class LLTextBox; class LLUICtrl; class LLButton; +class LLMenuButton; class LLViewerObject; class LLComboBox; class LLColorSwatchCtrl; @@ -77,6 +78,13 @@ class LLPanelVolume final : public LLPanel static void setLightTextureID(const LLUUID &asset_id, const LLUUID &item_id, LLVOVolume* volobjp); + void onCopyFeatures(); + void onPasteFeatures(); + void onCopyLight(); + void onPasteLight(); + + void menuDoToSelected(const LLSD& userdata); + bool menuEnableItem(const LLSD& userdata); protected: void getState(); @@ -135,6 +143,11 @@ class LLPanelVolume final : public LLPanel LLSpinCtrl* mSpinPhysicsFriction = nullptr; LLSpinCtrl* mSpinPhysicsDensity = nullptr; LLSpinCtrl* mSpinPhysicsRestitution = nullptr; + + LLMenuButton* mMenuClipboardFeatures; + LLMenuButton* mMenuClipboardLight; + + LLSD mClipboardParams; }; #endif diff --git a/indra/newview/llpanelwearing.cpp b/indra/newview/llpanelwearing.cpp index 37cc6c236ec3fc1a74ab272816b0c70b68089c39..64bdc473bd9520c9415d896f811cff75ada3a38b 100644 --- a/indra/newview/llpanelwearing.cpp +++ b/indra/newview/llpanelwearing.cpp @@ -585,8 +585,8 @@ void LLPanelWearing::onEditAttachment() LLScrollListItem* item = mTempItemsList->getFirstSelected(); if (item) { - LLSelectMgr::getInstanceFast()->deselectAll(); - LLSelectMgr::getInstanceFast()->selectObjectAndFamily(mAttachmentsMap[item->getUUID()]); + LLSelectMgr::getInstance()->deselectAll(); + LLSelectMgr::getInstance()->selectObjectAndFamily(mAttachmentsMap[item->getUUID()]); handle_object_edit(); } } @@ -596,9 +596,9 @@ void LLPanelWearing::onRemoveAttachment() LLScrollListItem* item = mTempItemsList->getFirstSelected(); if (item && item->getUUID().notNull()) { - LLSelectMgr::getInstanceFast()->deselectAll(); - LLSelectMgr::getInstanceFast()->selectObjectAndFamily(mAttachmentsMap[item->getUUID()]); - LLSelectMgr::getInstanceFast()->sendDropAttachment(); + LLSelectMgr::getInstance()->deselectAll(); + LLSelectMgr::getInstance()->selectObjectAndFamily(mAttachmentsMap[item->getUUID()]); + LLSelectMgr::getInstance()->sendDropAttachment(); } } diff --git a/indra/newview/llpatchvertexarray.cpp b/indra/newview/llpatchvertexarray.cpp index 4b79458c07dfe5bfe9f0de0109fc9df34ac64559..86870787463fdac91d10071c64241f38082ed000 100644 --- a/indra/newview/llpatchvertexarray.cpp +++ b/indra/newview/llpatchvertexarray.cpp @@ -69,11 +69,9 @@ void LLPatchVertexArray::create(U32 surface_width, U32 patch_width, F32 meters_p // (The -1 is there because an LLSurface has a buffer of 1 on // its East and North edges). U32 power_of_two = 1; - U32 surface_order = 0; while (power_of_two < (surface_width-1)) { power_of_two *= 2; - surface_order += 1; } if (power_of_two != (surface_width-1)) diff --git a/indra/newview/llpathfindingmanager.cpp b/indra/newview/llpathfindingmanager.cpp index 99ecb337817d554b340f70b718b1d8cd6b60b87b..91b3bffc6a1fab1f4713118f19ec7e98a94f792d 100644 --- a/indra/newview/llpathfindingmanager.cpp +++ b/indra/newview/llpathfindingmanager.cpp @@ -457,7 +457,7 @@ void LLPathfindingManager::navMeshStatusRequestCoro(std::string url, U64 regionH httpAdapter(std::make_shared<LLCoreHttpUtil::HttpCoroutineAdapter>("NavMeshStatusRequest", httpPolicy)); LLCore::HttpRequest::ptr_t httpRequest(std::make_shared<LLCore::HttpRequest>()); - LLViewerRegion *region = LLWorld::getInstanceFast()->getRegionFromHandle(regionHandle); + LLViewerRegion *region = LLWorld::getInstance()->getRegionFromHandle(regionHandle); if (!region) { LL_WARNS("PathfindingManager") << "Attempting to retrieve navmesh status for region that has gone away." << LL_ENDL; @@ -468,7 +468,7 @@ void LLPathfindingManager::navMeshStatusRequestCoro(std::string url, U64 regionH region = NULL; LLSD result = httpAdapter->getAndSuspend(httpRequest, url); - region = LLWorld::getInstanceFast()->getRegionFromHandle(regionHandle); + region = LLWorld::getInstance()->getRegionFromHandle(regionHandle); LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); @@ -765,7 +765,7 @@ std::string LLPathfindingManager::getRetrieveObjectLinksetsURLForCurrentRegion() std::string LLPathfindingManager::getChangeObjectLinksetsURLForCurrentRegion() const { - return getCapabilityURLForCurrentRegion(CAP_SERVICE_SET_OBJECT_LINKSETS); + return getCapabilityURLForCurrentRegion(CAP_SERVICE_SET_OBJECT_LINKSETS); } std::string LLPathfindingManager::getTerrainLinksetsURLForCurrentRegion() const diff --git a/indra/newview/llpathfindingmanager.h b/indra/newview/llpathfindingmanager.h index 1e15f27026b1ae15c99ab19bf7e1d0653fa05354..6e00a127a95eda5b96ba1eddbfcc1829739699a0 100644 --- a/indra/newview/llpathfindingmanager.h +++ b/indra/newview/llpathfindingmanager.h @@ -123,7 +123,7 @@ class LLPathfindingManager final : public LLSingleton<LLPathfindingManager> std::string getNavMeshStatusURLForRegion(LLViewerRegion *pRegion) const; std::string getRetrieveNavMeshURLForRegion(LLViewerRegion *pRegion) const; std::string getRetrieveObjectLinksetsURLForCurrentRegion() const; - std::string getChangeObjectLinksetsURLForCurrentRegion() const; + std::string getChangeObjectLinksetsURLForCurrentRegion() const; std::string getTerrainLinksetsURLForCurrentRegion() const; std::string getCharactersURLForCurrentRegion() const; std::string getAgentStateURLForRegion(LLViewerRegion *pRegion) const; diff --git a/indra/newview/llpathfindingpathtool.cpp b/indra/newview/llpathfindingpathtool.cpp index 3707123f85d52282e4c40123a380085190dc8544..e846008cb8526a3dd8b698f87989a56f57ff4eb9 100644 --- a/indra/newview/llpathfindingpathtool.cpp +++ b/indra/newview/llpathfindingpathtool.cpp @@ -320,7 +320,7 @@ bool LLPathfindingPathTool::isCameraModKeys(MASK pMask) const void LLPathfindingPathTool::getRayPoints(S32 pX, S32 pY, LLVector3 &pRayStart, LLVector3 &pRayEnd) const { LLVector3 dv = gViewerWindow->mouseDirectionGlobal(pX, pY); - LLVector3 mousePos = LLViewerCamera::getInstanceFast()->getOrigin(); + LLVector3 mousePos = LLViewerCamera::getInstance()->getOrigin(); pRayStart = mousePos; pRayEnd = mousePos + dv * 150; } diff --git a/indra/newview/llpersistentnotificationstorage.cpp b/indra/newview/llpersistentnotificationstorage.cpp index 18888f2723d0e1af3e69976b5815c172913d7fd2..9bf771db8a702473c56d53aa0cd04a84cdbbf5c7 100644 --- a/indra/newview/llpersistentnotificationstorage.cpp +++ b/indra/newview/llpersistentnotificationstorage.cpp @@ -47,11 +47,9 @@ LLPersistentNotificationStorage::~LLPersistentNotificationStorage() { } -static LLTrace::BlockTimerStatHandle FTM_SAVE_NOTIFICATIONS("Save Notifications"); - void LLPersistentNotificationStorage::saveNotifications() { - LL_RECORD_BLOCK_TIME(FTM_SAVE_NOTIFICATIONS); + LL_PROFILE_ZONE_SCOPED; boost::intrusive_ptr<LLPersistentNotificationChannel> history_channel = boost::dynamic_pointer_cast<LLPersistentNotificationChannel>(LLNotifications::instance().getChannel("Persistent")); if (!history_channel) @@ -90,11 +88,9 @@ void LLPersistentNotificationStorage::saveNotifications() writeNotifications(output); } -static LLTrace::BlockTimerStatHandle FTM_LOAD_NOTIFICATIONS("Load Notifications"); - void LLPersistentNotificationStorage::loadNotifications() { - LL_RECORD_BLOCK_TIME(FTM_LOAD_NOTIFICATIONS); + LL_PROFILE_ZONE_SCOPED; LL_INFOS("LLPersistentNotificationStorage") << "start loading notifications" << LL_ENDL; @@ -167,12 +163,16 @@ void LLPersistentNotificationStorage::loadNotifications() LL_INFOS("LLPersistentNotificationStorage") << "finished loading notifications" << LL_ENDL; } -void LLPersistentNotificationStorage::initialize() +void LLPersistentNotificationStorage::reset() { - std::string file_name = "open_notifications_" + LLGridManager::getInstance()->getGrid() + ".xml"; - setFileName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, file_name)); - setOldFileName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "open_notifications.xml")); + std::string file_name = "open_notifications_" + LLGridManager::getInstance()->getGrid() + ".xml"; + setFileName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, file_name)); + setOldFileName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "open_notifications.xml")); +} +void LLPersistentNotificationStorage::initialize() +{ + reset(); LLNotifications::instance().getChannel("Persistent")-> connectChanged(boost::bind(&LLPersistentNotificationStorage::onPersistentChannelChanged, this, _1)); } diff --git a/indra/newview/llpersistentnotificationstorage.h b/indra/newview/llpersistentnotificationstorage.h index 7dabb691a604c68a9acbfeb059084c8330024466..d65a36faac8c2994d95989f46e4a2f931b5ec2d1 100644 --- a/indra/newview/llpersistentnotificationstorage.h +++ b/indra/newview/llpersistentnotificationstorage.h @@ -52,6 +52,7 @@ class LLPersistentNotificationStorage final : public LLParamSingleton<LLPersiste void saveNotifications(); void loadNotifications(); + void reset(); protected: diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp index dc9a7f6231b57d1bf4bf8ee0faccb631541a21c1..b474c3e498f30a5e23b082e68ea38418266fab70 100644 --- a/indra/newview/llphysicsmotion.cpp +++ b/indra/newview/llphysicsmotion.cpp @@ -453,6 +453,7 @@ F32 LLPhysicsMotion::calculateAcceleration_local(const F32 velocity_local, const BOOL LLPhysicsMotionController::onUpdate(F32 time, U8* joint_mask) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; // Skip if disabled globally. static const LLCachedControl<bool> av_physics(gSavedSettings, "AvatarPhysics"); if (!av_physics) diff --git a/indra/newview/llphysicsshapebuilderutil.cpp b/indra/newview/llphysicsshapebuilderutil.cpp index 5bfe5c9941c470443abd6bd3e96170040c240a4a..9603ee63295b0cc58dfff1fb5b3d16d8934b00df 100644 --- a/indra/newview/llphysicsshapebuilderutil.cpp +++ b/indra/newview/llphysicsshapebuilderutil.cpp @@ -29,7 +29,7 @@ #include "llphysicsshapebuilderutil.h" /* static */ -void LLPhysicsShapeBuilderUtil::determinePhysicsShape( const LLPhysicsVolumeParams& volume_params, const LLVector3& scale, PhysicsShapeSpecification& specOut ) +void LLPhysicsShapeBuilderUtil::determinePhysicsShape( const LLPhysicsVolumeParams& volume_params, const LLVector3& scale, PhysicsShapeSpecification& specOut) { const LLProfileParams& profile_params = volume_params.getProfileParams(); const LLPathParams& path_params = volume_params.getPathParams(); @@ -191,6 +191,7 @@ void LLPhysicsShapeBuilderUtil::determinePhysicsShape( const LLPhysicsVolumePara if ( volume_params.shouldForceConvex() ) { + // Server distinguishes between convex of a prim vs isSculpt, but we don't care. specOut.mType = PhysicsShapeSpecification::USER_CONVEX; } // Make a simpler convex shape if we can. @@ -199,6 +200,16 @@ void LLPhysicsShapeBuilderUtil::determinePhysicsShape( const LLPhysicsVolumePara { specOut.mType = PhysicsShapeSpecification::PRIM_CONVEX; } + else if (volume_params.isMeshSculpt() && + // Check overall dimensions, not individual triangles. + (scale.mV[0] < SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE || + scale.mV[1] < SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE || + scale.mV[2] < SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE + ) ) + { + // Server distinguishes between user-specified or default convex mesh, vs server's thin-triangle override, but we don't. + specOut.mType = PhysicsShapeSpecification::PRIM_CONVEX; + } else if ( volume_params.isSculpt() ) // Is a sculpt of any kind (mesh or legacy) { specOut.mType = volume_params.isMeshSculpt() ? PhysicsShapeSpecification::USER_MESH : PhysicsShapeSpecification::SCULPT; diff --git a/indra/newview/llphysicsshapebuilderutil.h b/indra/newview/llphysicsshapebuilderutil.h index bd5b7d799cc7994855649f12bb469bd1536782d9..b3b100296f48e7cfbd759a28c9ed75d2b16a5a78 100644 --- a/indra/newview/llphysicsshapebuilderutil.h +++ b/indra/newview/llphysicsshapebuilderutil.h @@ -47,6 +47,7 @@ const F32 SHAPE_BUILDER_ENTRY_SNAP_SCALE_BIN_SIZE = 0.15f; const F32 SHAPE_BUILDER_ENTRY_SNAP_PARAMETER_BIN_SIZE = 0.010f; const F32 SHAPE_BUILDER_CONVEXIFICATION_SIZE = 2.f * COLLISION_TOLERANCE; const F32 SHAPE_BUILDER_MIN_GEOMETRY_SIZE = 0.5f * COLLISION_TOLERANCE; +const F32 SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE = 0.5f; class LLPhysicsVolumeParams : public LLVolumeParams { diff --git a/indra/newview/llpreview.cpp b/indra/newview/llpreview.cpp index 2c9324b80b270f716633c8ee506dc6ec2a3d01c9..5cecf435467a3ba4113d87db7140a9b2b7dcbac8 100644 --- a/indra/newview/llpreview.cpp +++ b/indra/newview/llpreview.cpp @@ -216,11 +216,11 @@ void LLPreview::onCommit() LLViewerObject* obj = gAgentAvatarp->getWornAttachment( item->getUUID() ); if( obj ) { - LLSelectMgr::getInstanceFast()->deselectAll(); - LLSelectMgr::getInstanceFast()->addAsIndividual( obj, SELECT_ALL_TES, FALSE ); - LLSelectMgr::getInstanceFast()->selectionSetObjectDescription( getChild<LLUICtrl>("desc")->getValue().asString() ); + LLSelectMgr::getInstance()->deselectAll(); + LLSelectMgr::getInstance()->addAsIndividual( obj, SELECT_ALL_TES, FALSE ); + LLSelectMgr::getInstance()->selectionSetObjectDescription( getChild<LLUICtrl>("desc")->getValue().asString() ); - LLSelectMgr::getInstanceFast()->deselectAll(); + LLSelectMgr::getInstance()->deselectAll(); } } } diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp index 3071b0cde07083b13004172d26573595b9d5325a..8b89eef300539f449338dbb97a07163b9d24d75f 100644 --- a/indra/newview/llpreviewgesture.cpp +++ b/indra/newview/llpreviewgesture.cpp @@ -347,9 +347,6 @@ BOOL LLPreviewGesture::postBuild() LLTextBox* text; LLCheckBoxCtrl* check; - edit = getChild<LLLineEditor>("name"); - edit->setKeystrokeCallback(onKeystrokeCommit, this); - edit = getChild<LLLineEditor>("desc"); edit->setKeystrokeCallback(onKeystrokeCommit, this); @@ -482,9 +479,6 @@ BOOL LLPreviewGesture::postBuild() { getChild<LLUICtrl>("desc")->setValue(item->getDescription()); getChild<LLLineEditor>("desc")->setPrevalidate(&LLTextValidate::validateASCIIPrintableNoPipe); - - getChild<LLUICtrl>("name")->setValue(item->getName()); - getChild<LLLineEditor>("name")->setPrevalidate(&LLTextValidate::validateASCIIPrintableNoPipe); } return LLPreview::postBuild(); diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp index 6f522f90ce4a0bceaf472a41aac74ba029909e3b..fe0f0534f73528a3449646af575f19c6f54db054 100644 --- a/indra/newview/llpreviewnotecard.cpp +++ b/indra/newview/llpreviewnotecard.cpp @@ -972,7 +972,10 @@ bool LLPreviewNotecard::loadNotecardText(const std::string& filename) buffer[nread] = '\0'; fclose(file); - mEditor->setText(LLStringExplicit(buffer)); + std::string text = std::string(buffer); + LLStringUtil::replaceTabsWithSpaces(text, LLTextEditor::spacesPerTab()); + + mEditor->setText(text); delete[] buffer; return true; diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index c78f83b26af4af425118174196de14bed58ee542..37d94ef3503b677b9df1ac3f55a5614da7fe1c2e 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -628,7 +628,10 @@ bool LLScriptEdCore::loadScriptText(const std::string& filename) // buffer[nread] = '\0'; // fclose(file); // -// mEditor->setText(LLStringExplicit(buffer)); +// std::string text = std::string(buffer); +// LLStringUtil::replaceTabsWithSpaces(text, LLTextEditor::spacesPerTab()); +// +// mEditor->setText(text); // delete[] buffer; // // return true; diff --git a/indra/newview/llprogressview.cpp b/indra/newview/llprogressview.cpp index 14f8fe31f5144214fec1107bdeac41dfd8b93dfc..a1195964d10c28b7cf0b6eea7aa54e9421681e28 100644 --- a/indra/newview/llprogressview.cpp +++ b/indra/newview/llprogressview.cpp @@ -88,7 +88,7 @@ BOOL LLProgressView::postBuild() mMediaCtrl->setVisible( false ); // hidden initially mMediaCtrl->addObserver( this ); // watch events - LLViewerMedia::getInstanceFast()->setOnlyAudibleMediaTextureID(mMediaCtrl->getTextureID()); + LLViewerMedia::getInstance()->setOnlyAudibleMediaTextureID(mMediaCtrl->getTextureID()); mCancelBtn = getChild<LLButton>("cancel_btn"); mCancelBtn->setClickedCallback( LLProgressView::onCancelButtonClicked, NULL ); @@ -294,7 +294,7 @@ void LLProgressView::draw() { mFadeToWorldTimer.stop(); - LLViewerMedia::getInstanceFast()->setOnlyAudibleMediaTextureID(LLUUID::null); + LLViewerMedia::getInstance()->setOnlyAudibleMediaTextureID(LLUUID::null); // Fade is complete, release focus gFocusMgr.releaseFocusIfNeeded( this ); diff --git a/indra/newview/llrecentpeople.h b/indra/newview/llrecentpeople.h index 9a26205e49bcfcde0aa46f4eefecaa9fb7b822df..f68105cac41e6fc1f6e78c9f175976067df104bf 100644 --- a/indra/newview/llrecentpeople.h +++ b/indra/newview/llrecentpeople.h @@ -63,7 +63,7 @@ class LLRecentPeople final : public LLSingleton<LLRecentPeople>, public LLOldEve * @param id avatar to add. * * @param userdata additional information about last interaction party. - * For example a session id can be added. lol + * For example session id can be added. * * @return false if the avatar is in the list already, true otherwise */ diff --git a/indra/newview/llregionposition.cpp b/indra/newview/llregionposition.cpp index 654831c41184a53e2b67a42708b22b8575ec0d43..32c271b2b8625553c595e61295b3899e21518b5a 100644 --- a/indra/newview/llregionposition.cpp +++ b/indra/newview/llregionposition.cpp @@ -80,7 +80,7 @@ LLVector3d LLRegionPosition::getPositionGlobal() const void LLRegionPosition::setPositionGlobal(const LLVector3d& position_global ) { - mRegionp = LLWorld::getInstanceFast()->getRegionFromPosGlobal(position_global); + mRegionp = LLWorld::getInstance()->getRegionFromPosGlobal(position_global); if (mRegionp) { mPositionRegion = mRegionp->getPosRegionFromGlobal(position_global); diff --git a/indra/newview/llremoteparcelrequest.cpp b/indra/newview/llremoteparcelrequest.cpp index 331fe205ad13f27fe2223a28881be2f0a9dc75fe..e469326e8e50e5047c66d4e6f21e1dff96e8826c 100644 --- a/indra/newview/llremoteparcelrequest.cpp +++ b/indra/newview/llremoteparcelrequest.cpp @@ -213,7 +213,12 @@ void LLRemoteParcelInfoProcessor::regionParcelInfoCoro(std::string url, if (!status) { - observer->setErrorStatus(status.getStatus(), status.getMessage()); + std::string message = status.getMessage(); + if (message.empty()) + { + message = status.toString(); + } + observer->setErrorStatus(status.getStatus(), message); } else { diff --git a/indra/newview/llscenemonitor.cpp b/indra/newview/llscenemonitor.cpp index cd1ea809a19ea1ea0da39b7483ab8cbe141d62ec..67a513e3eecb3b141e05a032047b93c3aa6ee88c 100644 --- a/indra/newview/llscenemonitor.cpp +++ b/indra/newview/llscenemonitor.cpp @@ -271,7 +271,7 @@ void LLSceneMonitor::capture() static LLCachedControl<F32> scene_load_sample_time(gSavedSettings, "SceneLoadingMonitorSampleTime"); static bool force_capture = true; - bool enabled = LLGLSLShader::sNoFixedFunction && (monitor_enabled || mDebugViewerVisible); + bool enabled = monitor_enabled || mDebugViewerVisible; if(mEnabled != enabled) { if(mEnabled) @@ -332,9 +332,6 @@ bool LLSceneMonitor::needsUpdate() const return mDiffState == NEED_DIFF; } -static LLTrace::BlockTimerStatHandle FTM_GENERATE_SCENE_LOAD_DITHER_TEXTURE("Generate Scene Load Dither Texture"); -static LLTrace::BlockTimerStatHandle FTM_SCENE_LOAD_IMAGE_DIFF("Scene Load Image Diff"); - static LLStaticHashedString sDitherScale("dither_scale"); static LLStaticHashedString sDitherScaleS("dither_scale_s"); static LLStaticHashedString sDitherScaleT("dither_scale_t"); @@ -356,14 +353,12 @@ void LLSceneMonitor::compare() return; } - LL_RECORD_BLOCK_TIME(FTM_SCENE_LOAD_IMAGE_DIFF); mDiffState = EXECUTE_DIFF; S32 width = gViewerWindow->getWindowWidthRaw(); S32 height = gViewerWindow->getWindowHeightRaw(); if(!mDiff) { - LL_RECORD_BLOCK_TIME(FTM_GENERATE_SCENE_LOAD_DITHER_TEXTURE); mDiff = new LLRenderTarget(); mDiff->allocate(width, height, GL_RGBA, false, false, LLTexUnit::TT_TEXTURE, true); @@ -371,7 +366,6 @@ void LLSceneMonitor::compare() } else if(mDiff->getWidth() != width || mDiff->getHeight() != height) { - LL_RECORD_BLOCK_TIME(FTM_GENERATE_SCENE_LOAD_DITHER_TEXTURE); mDiff->resize(width, height); generateDitheringTexture(width, height); } @@ -427,8 +421,6 @@ void LLSceneMonitor::calcDiffAggregate() { #ifdef LL_WINDOWS - LL_RECORD_BLOCK_TIME(FTM_SCENE_LOAD_IMAGE_DIFF); - if(mDiffState != EXECUTE_DIFF && !mDebugViewerVisible) { return; @@ -481,8 +473,6 @@ void LLSceneMonitor::calcDiffAggregate() static LLTrace::EventStatHandle<> sFramePixelDiff("FramePixelDifference"); void LLSceneMonitor::fetchQueryResult() { - LL_RECORD_BLOCK_TIME(FTM_SCENE_LOAD_IMAGE_DIFF); - if(mDiffState == WAIT_ON_RESULT && !LLAppViewer::instance()->quitRequested()) { @@ -729,13 +719,6 @@ void LLSceneMonitorView::onTeleportFinished() void LLSceneMonitorView::onVisibilityChange(BOOL visible) { - if (!LLGLSLShader::sNoFixedFunction && visible) - { - visible = false; - // keep Scene monitor and its view in sycn - setVisible(false); - LL_WARNS("SceneMonitor") << "Incompatible graphical settings, Scene Monitor can't be turned on" << LL_ENDL; - } LLSceneMonitor::getInstance()->setDebugViewerVisible(visible); } diff --git a/indra/newview/llsceneview.cpp b/indra/newview/llsceneview.cpp index f7aa63e34d8a504696272cb98d0e37503d13f006..e250f9bc7a998730c056b98cc448ad670f229f06 100644 --- a/indra/newview/llsceneview.cpp +++ b/indra/newview/llsceneview.cpp @@ -266,14 +266,11 @@ void LLSceneView::draw() U32 count = triangles[idx].size(); - U32 total = 0; - gGL.begin(LLRender::LINE_STRIP); //plot triangles for (U32 i = 0; i < count; ++i) { U32 tri_count = triangles[idx][i]; - total += tri_count; F32 y = (F32) (tri_count-tri_domain[0])/triangle_range*tri_rect.getHeight()+tri_rect.mBottom; F32 x = (F32) i / count * tri_rect.getWidth() + tri_rect.mLeft; @@ -290,15 +287,8 @@ void LLSceneView::draw() gGL.end(); gGL.flush(); - U32 total_visible = 0; count = visible_triangles[idx].size(); - for (U32 i = 0; i < count; ++i) - { - U32 tri_count = visible_triangles[idx][i]; - total_visible += tri_count; - } - std::string label = llformat("%s Object Triangle Counts (Ktris) -- Visible: %.2f/%.2f (%.2f KB Visible)", category[idx], total_visible_triangles[idx]/1024.f, total_triangles[idx]/1024.f, total_visible_bytes[idx]/1024.f); diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp index 2a947d6c1a8fad4a7e29fd11b27c0cc3f99a0164..d466275ae17f010ead2633cc9a04f31d7c926fc4 100644 --- a/indra/newview/llscreenchannel.cpp +++ b/indra/newview/llscreenchannel.cpp @@ -49,10 +49,9 @@ using namespace LLNotificationsUI; bool LLScreenChannel::mWasStartUpToastShown = false; -LLTrace::BlockTimerStatHandle FTM_GET_CHANNEL_RECT("Calculate Notification Channel Region"); LLRect LLScreenChannelBase::getChannelRect() { - LL_RECORD_BLOCK_TIME(FTM_GET_CHANNEL_RECT); + LL_PROFILE_ZONE_SCOPED; if (mFloaterSnapRegion == NULL) { @@ -260,7 +259,8 @@ void LLScreenChannel::updatePositionAndSize(LLRect new_world_rect) //-------------------------------------------------------------------------- void LLScreenChannel::addToast(const LLToast::Params& p) { - bool store_toast = false, show_toast = false; + LL_PROFILE_ZONE_SCOPED + bool store_toast = false, show_toast = false; if (mDisplayToastsAlways) { diff --git a/indra/newview/llscripteditor.cpp b/indra/newview/llscripteditor.cpp index cd3a4dfd11a712d8094c3abfa485732b644b6948..c6bb2f19dd45a47b90394ae550ec79b0bcb3f3f7 100644 --- a/indra/newview/llscripteditor.cpp +++ b/indra/newview/llscripteditor.cpp @@ -138,11 +138,9 @@ void LLScriptEditor::initKeywords() mKeywords.initialize(LLSyntaxIdLSL::getInstance()->getKeywordsXML()); } -LLTrace::BlockTimerStatHandle FTM_SYNTAX_HIGHLIGHTING("Syntax Highlighting"); - void LLScriptEditor::loadKeywords() { - LL_RECORD_BLOCK_TIME(FTM_SYNTAX_HIGHLIGHTING); + LL_PROFILE_ZONE_SCOPED; mKeywords.processTokens(); segment_vec_t segment_list; @@ -160,7 +158,7 @@ void LLScriptEditor::updateSegments() { if (mReflowIndex < S32_MAX && mKeywords.isLoaded() && mParseOnTheFly) { - LL_RECORD_BLOCK_TIME(FTM_SYNTAX_HIGHLIGHTING); + LL_PROFILE_ZONE_SCOPED; // HACK: No non-ascii keywords for now segment_vec_t segment_list; mKeywords.findSegments(&segment_list, getWText(), mDefaultColor.get(), *this); diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index f7864cc877cb9f5ac839333be441388bee5dba5c..4050b9b796003408f68bd3d44431a307c6f43c40 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -164,7 +164,7 @@ struct LLDeRezInfo LLSelectionCallbackData::LLSelectionCallbackData() { - LLSelectMgr *instance = LLSelectMgr::getInstanceFast(); + LLSelectMgr *instance = LLSelectMgr::getInstance(); LLObjectSelectionHandle selection = instance->getSelection(); if (!selection->getNumNodes()) { @@ -215,8 +215,6 @@ void LLSelectMgr::cleanupGlobals() LLSelectMgr::getInstance()->clearSelections(); } -// Build time optimization, generate this function once here -template class LLSelectMgr* LLSingleton<class LLSelectMgr>::getInstance(); //----------------------------------------------------------------------------- // LLSelectMgr() //----------------------------------------------------------------------------- @@ -318,14 +316,29 @@ void LLSelectMgr::resetObjectOverrides(LLObjectSelectionHandle selected_handle) { struct f : public LLSelectedNodeFunctor { + f(bool a, LLSelectMgr* p) : mAvatarOverridesPersist(a), mManager(p) {} + bool mAvatarOverridesPersist; + LLSelectMgr* mManager; virtual bool apply(LLSelectNode* node) { + if (mAvatarOverridesPersist) + { + LLViewerObject* object = node->getObject(); + if (object && !object->getParent()) + { + LLVOAvatar* avatar = object->asAvatar(); + if (avatar) + { + mManager->mAvatarOverridesMap.emplace(avatar->getID(), AvatarPositionOverride(node->mLastPositionLocal, node->mLastRotation, object)); + } + } + } node->mLastPositionLocal.setVec(0, 0, 0); node->mLastRotation = LLQuaternion(); node->mLastScale.setVec(0, 0, 0); return true; } - } func; + } func(mAllowSelectAvatar, this); selected_handle->applyToNodes(&func); } @@ -359,6 +372,93 @@ void LLSelectMgr::overrideObjectUpdates() getSelection()->applyToNodes(&func); } +void LLSelectMgr::resetAvatarOverrides() +{ + mAvatarOverridesMap.clear(); +} + +void LLSelectMgr::overrideAvatarUpdates() +{ + if (mAvatarOverridesMap.size() == 0) + { + return; + } + + if (!mAllowSelectAvatar || !gFloaterTools) + { + resetAvatarOverrides(); + return; + } + + if (!gFloaterTools->getVisible() && getSelection()->isEmpty()) + { + // when user switches selection, floater is invisible and selection is empty + LLToolset *toolset = LLToolMgr::getInstance()->getCurrentToolset(); + if (toolset->isShowFloaterTools() + && toolset->isToolSelected(0)) // Pie tool + { + resetAvatarOverrides(); + return; + } + } + + // remove selected avatars from this list, + // but set object overrides to make sure avatar won't snap back + struct f : public LLSelectedNodeFunctor + { + f(LLSelectMgr* p) : mManager(p) {} + LLSelectMgr* mManager; + virtual bool apply(LLSelectNode* selectNode) + { + LLViewerObject* object = selectNode->getObject(); + if (object && !object->getParent()) + { + LLVOAvatar* avatar = object->asAvatar(); + if (avatar) + { + uuid_av_override_map_t::iterator iter = mManager->mAvatarOverridesMap.find(avatar->getID()); + if (iter != mManager->mAvatarOverridesMap.end()) + { + if (selectNode->mLastPositionLocal.isExactlyZero()) + { + selectNode->mLastPositionLocal = iter->second.mLastPositionLocal; + } + if (selectNode->mLastRotation == LLQuaternion()) + { + selectNode->mLastRotation = iter->second.mLastRotation; + } + mManager->mAvatarOverridesMap.erase(iter); + } + } + } + return true; + } + } func(this); + getSelection()->applyToNodes(&func); + + // Override avatar positions + uuid_av_override_map_t::iterator it = mAvatarOverridesMap.begin(); + while (it != mAvatarOverridesMap.end()) + { + if (it->second.mObject->isDead()) + { + it = mAvatarOverridesMap.erase(it); + } + else + { + if (!it->second.mLastPositionLocal.isExactlyZero()) + { + it->second.mObject->setPosition(it->second.mLastPositionLocal); + } + if (it->second.mLastRotation != LLQuaternion()) + { + it->second.mObject->setRotation(it->second.mLastRotation); + } + it++; + } + } +} + //----------------------------------------------------------------------------- // Select just the object, not any other group members. //----------------------------------------------------------------------------- @@ -581,7 +681,7 @@ BOOL LLSelectMgr::removeObjectFromSelections(const LLUUID &id) BOOL object_found = FALSE; LLTool *tool = NULL; - tool = LLToolMgr::getInstanceFast()->getCurrentTool(); + tool = LLToolMgr::getInstance()->getCurrentTool(); // It's possible that the tool is editing an object that is not selected LLViewerObject* tool_editing_object = tool->getEditingObject(); @@ -3701,27 +3801,27 @@ bool LLSelectMgr::confirmDelete(const LLSD& notification, const LLSD& response, const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); // attempt to derez into the trash. LLDeRezInfo info(DRD_TRASH, trash_id); - LLSelectMgr::getInstanceFast()->sendListToRegions("DeRezObject", + LLSelectMgr::getInstance()->sendListToRegions("DeRezObject", packDeRezHeader, packObjectLocalID, logNoOp, (void*) &info, SEND_ONLY_ROOTS); // VEFFECT: Delete Object - one effect for all deletes - if (!gSavedSettings.getBOOL("AlchemyDisableEffectSpiral") && (LLSelectMgr::getInstanceFast()->mSelectedObjects->mSelectType != SELECT_TYPE_HUD)) + if (!gSavedSettings.getBOOL("AlchemyDisableEffectSpiral") && (LLSelectMgr::getInstance()->mSelectedObjects->mSelectType != SELECT_TYPE_HUD)) { LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINT, TRUE); - effectp->setPositionGlobal( LLSelectMgr::getInstanceFast()->getSelectionCenterGlobal() ); + effectp->setPositionGlobal( LLSelectMgr::getInstance()->getSelectionCenterGlobal() ); effectp->setColor(LLColor4U(gAgent.getEffectColor())); F32 duration = 0.5f; - duration += LLSelectMgr::getInstanceFast()->mSelectedObjects->getObjectCount() / 64.f; + duration += LLSelectMgr::getInstance()->mSelectedObjects->getObjectCount() / 64.f; effectp->setDuration(duration); } gAgentCamera.setLookAt(LOOKAT_TARGET_CLEAR); // Keep track of how many objects have been deleted. - add(LLStatViewer::DELETE_OBJECT, LLSelectMgr::getInstanceFast()->mSelectedObjects->getObjectCount()); + add(LLStatViewer::DELETE_OBJECT, LLSelectMgr::getInstance()->mSelectedObjects->getObjectCount()); } break; case 1: @@ -4441,7 +4541,7 @@ void LLSelectMgr::deselectAllIfTooFar() // [RLVa:KB] - Checked: 2010-04-11 (RLVa-1.2.0e) | Modified: RLVa-0.2.0f static RlvCachedBehaviourModifier<float> s_nFartouchDist(RLV_MODIFIER_FARTOUCHDIST); - BOOL fRlvFartouch = gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH) && LLToolMgr::instanceFast().inEdit(); + BOOL fRlvFartouch = gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH) && LLToolMgr::instance().inEdit(); if ( (ALControlCache::LimitSelectDistance || (fRlvFartouch) ) // [/RLVa:KB] && (!mSelectedObjects->getPrimaryObject() || !mSelectedObjects->getPrimaryObject()->isAvatar()) @@ -4569,7 +4669,7 @@ void LLSelectMgr::sendAttach(LLObjectSelectionHandle selection_handle, U8 attach return; } - BOOL build_mode = LLToolMgr::getInstanceFast()->inEdit(); + BOOL build_mode = LLToolMgr::getInstance()->inEdit(); // Special case: Attach to default location for this object. if (0 == attachment_point || get_if_there(gAgentAvatarp->mAttachmentPoints, (S32)attachment_point, (LLViewerJointAttachment*)NULL)) @@ -5456,7 +5556,7 @@ void LLSelectMgr::processObjectProperties(LLMessageSystem* msg, void** user_data return (node->getObject() && node->getObject()->mID == mID); } } func(id); - LLSelectNode* node = LLSelectMgr::getInstanceFast()->getSelection()->getFirstNode(&func); + LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode(&func); if (!node) { @@ -5585,7 +5685,7 @@ void LLSelectMgr::processObjectPropertiesFamily(LLMessageSystem* msg, void** use else if (request_flags & OBJECT_PAY_REQUEST) { // check if the owner of the paid object is muted - LLMuteList::getInstanceFast()->autoRemove(owner_id, LLMuteList::AR_MONEY); + LLMuteList::getInstance()->autoRemove(owner_id, LLMuteList::AR_MONEY); } // Now look through all of the hovered nodes @@ -5598,7 +5698,7 @@ void LLSelectMgr::processObjectPropertiesFamily(LLMessageSystem* msg, void** use return (node->getObject() && node->getObject()->mID == mID); } } func(id); - LLSelectNode* node = LLSelectMgr::getInstanceFast()->mHoverObjects->getFirstNode(&func); + LLSelectNode* node = LLSelectMgr::getInstance()->mHoverObjects->getFirstNode(&func); if (node) { @@ -5624,7 +5724,7 @@ void LLSelectMgr::processForceObjectSelect(LLMessageSystem* msg, void**) if (reset_list) { - LLSelectMgr::getInstanceFast()->deselectAll(); + LLSelectMgr::getInstance()->deselectAll(); } LLUUID full_id; @@ -5650,7 +5750,7 @@ void LLSelectMgr::processForceObjectSelect(LLMessageSystem* msg, void**) } // Don't select, just highlight - LLSelectMgr::getInstanceFast()->highlightObjectAndFamily(objects); + LLSelectMgr::getInstance()->highlightObjectAndFamily(objects); } void LLSelectMgr::updateSilhouettes() @@ -5795,7 +5895,7 @@ void LLSelectMgr::updateSilhouettes() num_sils_genned = 0; // render silhouettes for highlighted objects - const auto& viewer_cam_origin = LLViewerCamera::instanceFast().getOrigin(); + const auto& viewer_cam_origin = LLViewerCamera::instance().getOrigin(); //BOOL subtracting_from_selection = (gKeyboard->currentMask(TRUE) == MASK_CONTROL); for (S32 pass = 0; pass < 2; pass++) { @@ -5858,8 +5958,6 @@ void LLSelectMgr::updateSilhouettes() // clear flags after traversing node list (as child objects need to refer to parent flags, etc) objectp->clearChanged(LLXform::MOVED | LLXform::SILHOUETTE); } - - //gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); } void LLSelectMgr::updateSelectionSilhouette(LLObjectSelectionHandle object_handle, S32& num_sils_genned, std::vector<LLViewerObject*>& changed_objects) @@ -5870,7 +5968,7 @@ void LLSelectMgr::updateSelectionSilhouette(LLObjectSelectionHandle object_handl //mSilhouetteImagep->bindTexture(); //glAlphaFunc(GL_GREATER, sHighlightAlphaTest); - const auto& viewer_cam_origin = LLViewerCamera::instanceFast().getOrigin(); + const auto& viewer_cam_origin = LLViewerCamera::instance().getOrigin(); for (S32 pass = 0; pass < 2; pass++) { for (LLSelectNode* node : object_handle->begin_end()) @@ -5933,7 +6031,7 @@ void LLSelectMgr::renderSilhouettes(BOOL for_hud) gGL.pushMatrix(); gGL.loadIdentity(); F32 depth = llmax(1.f, hud_bbox.getExtentLocal().mV[VX] * 1.1f); - auto& viewerCamera = LLViewerCamera::instanceFast(); + auto& viewerCamera = LLViewerCamera::instance(); gGL.ortho(-0.5f * viewerCamera.getAspect(), 0.5f * viewerCamera.getAspect(), -0.5f, 0.5f, 0.f, depth); gGL.matrixMode(LLRender::MM_MODELVIEW); @@ -6229,6 +6327,24 @@ LLSelectNode::LLSelectNode(const LLSelectNode& nodep) LLSelectNode::~LLSelectNode() { + LLSelectMgr *manager = LLSelectMgr::getInstance(); + if (manager->mAllowSelectAvatar + && (!mLastPositionLocal.isExactlyZero() + || mLastRotation != LLQuaternion())) + { + LLViewerObject* object = getObject(); //isDead() check + if (object && !object->getParent()) + { + LLVOAvatar* avatar = object->asAvatar(); + if (avatar) + { + // Avatar was moved and needs to stay that way + manager->mAvatarOverridesMap.emplace(avatar->getID(), LLSelectMgr::AvatarPositionOverride(mLastPositionLocal, mLastRotation, object)); + } + } + } + + delete mPermissions; mPermissions = NULL; } @@ -6533,7 +6649,7 @@ void LLSelectNode::renderOneSilhouette(const LLColor4 &color) LLVolume *volume = objectp->getVolume(); if (volume) { - auto& viewerCamera = LLViewerCamera::instanceFast(); + auto& viewerCamera = LLViewerCamera::instance(); F32 silhouette_thickness; if (isAgentAvatarValid() && is_hud_object) @@ -6555,22 +6671,9 @@ void LLSelectNode::renderOneSilhouette(const LLColor4 &color) { gGL.flush(); gGL.blendFunc(LLRender::BF_SOURCE_COLOR, LLRender::BF_ONE); - if (!LLGLSLShader::sNoFixedFunction) - { - LLGLEnable fog(GL_FOG); - glFogi(GL_FOG_MODE, GL_LINEAR); - float d = (viewerCamera.getPointOfInterest() - viewerCamera.getOrigin()).magVec(); - LLColor4 fogCol = color * (F32) llclamp((LLSelectMgr::getInstanceFast()->getSelectionCenterGlobal() - - gAgentCamera.getCameraPositionGlobal()).magVec() / - (LLSelectMgr::getInstanceFast()->getBBoxOfSelection().getExtentLocal().magVec() * 4), - 0.0, 1.0); - glFogf(GL_FOG_START, d); - glFogf(GL_FOG_END, d * (1 + (viewerCamera.getView() / viewerCamera.getDefaultFOV()))); - glFogfv(GL_FOG_COLOR, fogCol.mV); - } LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_GEQUAL); - gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); + gGL.flush(); gGL.begin(LLRender::LINES); { gGL.color4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.4f); @@ -6662,7 +6765,7 @@ void dialog_refresh_all() // make cleaning up the functions below easier. Also, sometimes entities // outside the selection manager change properties of selected objects // and call into this function. Yuck. - LLSelectMgr::getInstanceFast()->mUpdateSignal(); + LLSelectMgr::getInstance()->mUpdateSignal(); // *TODO: Eliminate all calls into outside classes below, make those // objects register with the update signal. @@ -6716,7 +6819,7 @@ S32 get_family_count(LLViewerObject *parent) } else { - if (LLSelectMgr::getInstanceFast()->canSelectObject(child)) + if (LLSelectMgr::getInstance()->canSelectObject(child)) { count += get_family_count( child ); } @@ -6736,6 +6839,10 @@ void LLSelectMgr::updateSelectionCenter() const F32 MOVE_SELECTION_THRESHOLD = 1.f; // Movement threshold in meters for updating selection // center (tractor beam) + // override any avatar updates received + // Works only if avatar was repositioned + // and edit floater is visible + overrideAvatarUpdates(); //override any object updates received //for selected objects overrideObjectUpdates(); @@ -6796,7 +6903,7 @@ void LLSelectMgr::updateSelectionCenter() if (gAgentID.notNull()) { - LLTool *tool = LLToolMgr::getInstanceFast()->getCurrentTool(); + LLTool *tool = LLToolMgr::getInstance()->getCurrentTool(); if (mShowSelection) { LLVector3d select_center_global; @@ -7053,9 +7160,9 @@ void LLSelectMgr::validateSelection() { virtual bool apply(LLViewerObject* object) { - if (!instanceFast().canSelectObject(object)) + if (!instance().canSelectObject(object)) { - instanceFast().deselectObjectOnly(object); + instance().deselectObjectOnly(object); } return true; } @@ -7912,7 +8019,7 @@ bool LLSelectMgr::selectionMove(const LLVector3& displ, // calculate the distance of the object closest to the camera origin F32 min_dist_squared = F32_MAX; // value will be overridden in the loop - const auto& origin = LLViewerCamera::getInstanceFast()->getOrigin(); + const auto& origin = LLViewerCamera::getInstance()->getOrigin(); LLVector3 obj_pos; for (LLSelectNode* nodep : selection->root_begin_end()) @@ -7934,16 +8041,16 @@ bool LLSelectMgr::selectionMove(const LLVector3& displ, displ.mV[2] * min_dist); // equates to: Displ_global = Displ * M_cam_axes_in_global_frame - displ_global = LLViewerCamera::getInstanceFast()->rotateToAbsolute(displ_global); + displ_global = LLViewerCamera::getInstance()->rotateToAbsolute(displ_global); } LLQuaternion new_rot; if (update_rotation) { // let's calculate the rotation around each camera axes - LLQuaternion qx(roll, LLViewerCamera::getInstanceFast()->getAtAxis()); - LLQuaternion qy(pitch, LLViewerCamera::getInstanceFast()->getLeftAxis()); - LLQuaternion qz(yaw, LLViewerCamera::getInstanceFast()->getUpAxis()); + LLQuaternion qx(roll, LLViewerCamera::getInstance()->getAtAxis()); + LLQuaternion qy(pitch, LLViewerCamera::getInstance()->getLeftAxis()); + LLQuaternion qz(yaw, LLViewerCamera::getInstance()->getUpAxis()); new_rot.setQuat(qx * qy * qz); } diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index a95f1e289decfce7e1f8275e8090e7f70dee43ce..e42f6a7fef17fd4825e9c8b4bd22110bae2951e3 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -420,11 +420,8 @@ class LLSelectionCallbackData LLObjectSelectionHandle mSelectedObjects; }; -class LLSelectMgr final : public LLEditMenuHandler, public LLSingleton<LLSelectMgr> +class LLSelectMgr final : public LLEditMenuHandler, public LLSimpleton<LLSelectMgr> { - LLSINGLETON(LLSelectMgr); - ~LLSelectMgr(); - public: static BOOL sRectSelectInclusive; // do we need to surround an object to pick it? static BOOL sRenderHiddenSelections; // do we show selection silhouettes that are occluded? @@ -450,6 +447,9 @@ class LLSelectMgr final : public LLEditMenuHandler, public LLSingleton<LLSelectM LLCachedControl<bool> mDebugSelectMgr; public: + LLSelectMgr(); + ~LLSelectMgr(); + static void cleanupGlobals(); // LLEditMenuHandler interface @@ -480,6 +480,30 @@ class LLSelectMgr final : public LLEditMenuHandler, public LLSingleton<LLSelectM void resetObjectOverrides(LLObjectSelectionHandle selected_handle); void overrideObjectUpdates(); + void resetAvatarOverrides(); + void overrideAvatarUpdates(); + + struct AvatarPositionOverride + { + AvatarPositionOverride(); + AvatarPositionOverride(LLVector3 &vec, LLQuaternion &quat, LLViewerObject *obj) : + mLastPositionLocal(vec), + mLastRotation(quat), + mObject(obj) + { + } + LLVector3 mLastPositionLocal; + LLQuaternion mLastRotation; + LLPointer<LLViewerObject> mObject; + }; + + // Avatar overrides should persist even after selection + // was removed as long as edit floater is up + typedef std::map<LLUUID, AvatarPositionOverride> uuid_av_override_map_t; + uuid_av_override_map_t mAvatarOverridesMap; +public: + + // Returns the previous value of mForceSelection BOOL setForceSelection(BOOL force); diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp index 404e01a18a1bac253b9abd98d4e86725444c6b61..6e64cc5660ecefa86c016459683ed0a368934679 100644 --- a/indra/newview/llsettingsvo.cpp +++ b/indra/newview/llsettingsvo.cpp @@ -655,6 +655,7 @@ LLSD LLSettingsVOSky::convertToLegacy(const LLSettingsSky::ptr_t &psky, bool isA //------------------------------------------------------------------------- void LLSettingsVOSky::updateSettings() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_ENVIRONMENT; LLSettingsSky::updateSettings(); LLVector3 sun_direction = getSunDirection(); LLVector3 moon_direction = getMoonDirection(); @@ -680,44 +681,26 @@ void LLSettingsVOSky::updateSettings() gSky.setSunScale(getSunScale()); gSky.setMoonScale(getMoonScale()); - - //Cache settings for fast access during render - // Legacy? SETTING_CLOUD_SCROLL_RATE("cloud_scroll_rate") - mCloudPosDensityCached = LLVector4(mSettings[SETTING_CLOUD_POS_DENSITY1]); - - mDensityMultiplierCached = getDensityMultiplier(); - mDistanceMultiplierCached = getDistanceMultiplier(); - mGammaCached = getGamma(); - mCloudVarianceCached = getCloudVariance(); - mMoonBrightnessCached = getMoonBrightness(); - mStarBrightnessCached = getStarBrightness(); - - mSkyMoistureCached = getSkyMoistureLevel(); - mSkyDropletRadius = getSkyDropletRadius(); - mSkyIceLevel = getSkyIceLevel(); - - mSunDiffuseCached = getSunlightColor(); - mMoonDiffuseCached = getMoonlightColor(); - mCloudColorCached = LLColor4(getCloudColor(), 1.0); } void LLSettingsVOSky::applySpecial(void *ptarget, bool force) { - LLGLSLShader *shader = (LLGLSLShader *) ptarget; - - if (shader->mShaderGroup == LLGLSLShader::SG_DEFAULT) - { - shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, LLEnvironment::getInstanceFast()->getClampedLightNorm().mV); - shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, 1, LLViewerCamera::getInstanceFast()->getOrigin().mV); - } - else if (shader->mShaderGroup == LLGLSLShader::SG_SKY) - { - auto& env = LLEnvironment::instanceFast(); - - shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, env.getClampedLightNorm().mV); + LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER; + LLVector4 light_direction = LLEnvironment::instance().getClampedLightNorm(); + + LLShaderUniforms* shader = &((LLShaderUniforms*)ptarget)[LLGLSLShader::SG_DEFAULT]; + { + shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, light_direction); + shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, LLViewerCamera::getInstance()->getOrigin()); + } + + shader = &((LLShaderUniforms*)ptarget)[LLGLSLShader::SG_SKY]; + { + shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, light_direction); - LLVector4 vect_c_p_d1(mCloudPosDensityCached); - LLVector4 cloud_scroll(env.getCloudScrollDelta()); + // Legacy? SETTING_CLOUD_SCROLL_RATE("cloud_scroll_rate") + LLVector4 vect_c_p_d1(mSettings[SETTING_CLOUD_POS_DENSITY1]); + LLVector4 cloud_scroll( LLEnvironment::instance().getCloudScrollDelta() ); // SL-13084 EEP added support for custom cloud textures -- flip them horizontally to match the preview of Clouds > Cloud Scroll // Keep in Sync! @@ -726,23 +709,36 @@ void LLSettingsVOSky::applySpecial(void *ptarget, bool force) // * indra\newview\app_settings\shaders\class1\deferred\cloudsV.glsl cloud_scroll[0] = -cloud_scroll[0]; vect_c_p_d1 += cloud_scroll; - shader->uniform4fv(LLShaderMgr::CLOUD_POS_DENSITY1, 1, vect_c_p_d1.mV); + shader->uniform4fv(LLShaderMgr::CLOUD_POS_DENSITY1, vect_c_p_d1); - shader->uniform4fv(LLShaderMgr::SUNLIGHT_COLOR, 1, mSunDiffuseCached.mV); - shader->uniform4fv(LLShaderMgr::MOONLIGHT_COLOR, 1, mMoonDiffuseCached.mV); - shader->uniform4fv(LLShaderMgr::CLOUD_COLOR, 1, mCloudColorCached.mV); - } + LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); + LLVector4 sunDiffuse = LLVector4(psky->getSunlightColor().mV); + LLVector4 moonDiffuse = LLVector4(psky->getMoonlightColor().mV); + + shader->uniform4fv(LLShaderMgr::SUNLIGHT_COLOR, sunDiffuse); + shader->uniform4fv(LLShaderMgr::MOONLIGHT_COLOR, moonDiffuse); + + LLVector4 cloud_color(LLVector3(psky->getCloudColor().mV), 1.0); + shader->uniform4fv(LLShaderMgr::CLOUD_COLOR, cloud_color); + } + + shader = &((LLShaderUniforms*)ptarget)[LLGLSLShader::SG_ANY]; shader->uniform1f(LLShaderMgr::SCENE_LIGHT_STRENGTH, mSceneLightStrength); - shader->uniform4fv(LLShaderMgr::AMBIENT, 1, getTotalAmbient().mV); + LLColor4 ambient(getTotalAmbient()); + shader->uniform4fv(LLShaderMgr::AMBIENT, LLVector4(ambient.mV)); shader->uniform1i(LLShaderMgr::SUN_UP_FACTOR, getIsSunUp() ? 1 : 0); shader->uniform1f(LLShaderMgr::SUN_MOON_GLOW_FACTOR, getSunMoonGlowFactor()); - shader->uniform1f(LLShaderMgr::DENSITY_MULTIPLIER, mDensityMultiplierCached); - shader->uniform1f(LLShaderMgr::DISTANCE_MULTIPLIER, mDistanceMultiplierCached); + shader->uniform1f(LLShaderMgr::DENSITY_MULTIPLIER, getDensityMultiplier()); + shader->uniform1f(LLShaderMgr::DISTANCE_MULTIPLIER, getDistanceMultiplier()); + + F32 g = getGamma(); + //F32 display_gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma"); - shader->uniform1f(LLShaderMgr::GAMMA, mGammaCached); + shader->uniform1f(LLShaderMgr::GAMMA, g); + //shader->uniform1f(LLShaderMgr::DISPLAY_GAMMA, display_gamma); } const LLSettingsSky::parammapping_t& LLSettingsVOSky::getParameterMap() const @@ -932,9 +928,13 @@ LLSD LLSettingsVOWater::convertToLegacy(const LLSettingsWater::ptr_t &pwater) //------------------------------------------------------------------------- void LLSettingsVOWater::applySpecial(void *ptarget, bool force) { - LLGLSLShader *shader = (LLGLSLShader *)ptarget; + LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER; + + LLEnvironment& env = LLEnvironment::instance(); - if (force || (shader->mShaderGroup == LLGLSLShader::SG_WATER)) + auto group = LLGLSLShader::SG_WATER; + LLShaderUniforms* shader = &((LLShaderUniforms*)ptarget)[group]; + { F32 water_height = gAgent.getRegion() ? gAgent.getRegion()->getWaterHeight() : DEFAULT_WATER_HEIGHT; @@ -955,32 +955,34 @@ void LLSettingsVOWater::applySpecial(void *ptarget, bool force) ep.negate(); enorm.copyComponent<3>(ep); - shader->uniform4fv(LLShaderMgr::WATER_WATERPLANE, 1, enorm.getF32ptr()); + shader->uniform4fv(LLShaderMgr::WATER_WATERPLANE, enorm.getF32ptr()); - LLVector4 light_direction = LLEnvironment::getInstanceFast()->getClampedLightNorm(); + LLVector4 light_direction = env.getClampedLightNorm(); F32 waterFogKS = 1.f / llmax(light_direction.mV[2], WATER_FOG_LIGHT_CLAMP); shader->uniform1f(LLShaderMgr::WATER_FOGKS, waterFogKS); - F32 eyedepth = LLViewerCamera::getInstanceFast()->getOrigin().mV[2] - water_height; + F32 eyedepth = LLViewerCamera::getInstance()->getOrigin().mV[2] - water_height; bool underwater = (eyedepth <= 0.0f); - F32 waterFogDensity = getModifiedWaterFogDensityFast(mCachedWaterFogDensity, mCachedFogMod, underwater); + F32 waterFogDensity = env.getCurrentWater()->getModifiedWaterFogDensity(underwater); shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY, waterFogDensity); - shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, mCachedWaterFogColor.mV); + LLColor4 fog_color(env.getCurrentWater()->getWaterFogColor(), 0.0f); + shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, fog_color.mV); - F32 blend_factor = getBlendFactor(); + F32 blend_factor = env.getCurrentWater()->getBlendFactor(); shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor); // update to normal lightnorm, water shader itself will use rotated lightnorm as necessary - shader->uniform4fv(LLShaderMgr::LIGHTNORM, 1, light_direction.mV); + shader->uniform4fv(LLShaderMgr::LIGHTNORM, light_direction.mV); } } void LLSettingsVOWater::updateSettings() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; // base class clears dirty flag so as to not trigger recursive update LLSettingsBase::updateSettings(); @@ -991,10 +993,6 @@ void LLSettingsVOWater::updateSettings() pwaterpool->setOpaqueTexture(GetDefaultOpaqueTextureAssetId()); pwaterpool->setNormalMaps(getNormalMapID(), getNextNormalMapID()); } - - mCachedWaterFogDensity= getWaterFogDensity(); - mCachedFogMod = getFogMod(); - mCachedWaterFogColor = LLColor4(getWaterFogColor(), 0.0f); } const LLSettingsWater::parammapping_t& LLSettingsVOWater::getParameterMap() const @@ -1044,12 +1042,39 @@ LLSettingsDay::ptr_t LLSettingsVODay::buildFromLegacyPreset(const std::string &n std::set<std::string> framenames; std::set<std::string> notfound; + // expected and correct folder sctructure is to have + // three folders in widnlight's root: days, water, skies std::string base_path(gDirUtilp->getDirName(path)); std::string water_path(base_path); std::string sky_path(base_path); + std::string day_path(base_path); gDirUtilp->append(water_path, "water"); gDirUtilp->append(sky_path, "skies"); + gDirUtilp->append(day_path, "days"); + + if (!gDirUtilp->fileExists(day_path)) + { + LL_WARNS("SETTINGS") << "File " << name << ".xml is not in \"days\" folder." << LL_ENDL; + } + + if (!gDirUtilp->fileExists(water_path)) + { + LL_WARNS("SETTINGS") << "Failed to find accompaniying water folder for file " << name + << ".xml. Falling back to using default folder" << LL_ENDL; + + water_path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight"); + gDirUtilp->append(water_path, "water"); + } + + if (!gDirUtilp->fileExists(sky_path)) + { + LL_WARNS("SETTINGS") << "Failed to find accompaniying skies folder for file " << name + << ".xml. Falling back to using default folder" << LL_ENDL; + + sky_path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight"); + gDirUtilp->append(sky_path, "skies"); + } newsettings[SETTING_NAME] = name; diff --git a/indra/newview/llsettingsvo.h b/indra/newview/llsettingsvo.h index 2e2f39093601de63212bc65c3836e46044fe7d04..e6bac012aa334a445f796d89701eab96b60fe0b1 100644 --- a/indra/newview/llsettingsvo.h +++ b/indra/newview/llsettingsvo.h @@ -101,15 +101,6 @@ class LLSettingsVOSky : public LLSettingsSky bool isAdvanced() const { return m_isAdvanced; } - void updateShader(LLGLSLShader* shader) { applySpecial(shader, true); } - - F32 getSkyMoistureLevelFast() const { return mSkyMoistureCached; } - F32 getSkyDropletRadiusFast() const { return mSkyDropletRadius; } - F32 getSkyIceLevelFast() const { return mSkyIceLevel; } - F32 getCloudVarianceFast() const { return mCloudVarianceCached;; } - F32 getMoonBrightnessFast() const { return mMoonBrightnessCached; } - F32 getStarBrightnessFast() const { return mStarBrightnessCached; } - protected: LLSettingsVOSky(); @@ -122,21 +113,8 @@ class LLSettingsVOSky : public LLSettingsSky const parammapping_t& getParameterMap() const final; - LLVector4 mCloudPosDensityCached; - LLColor4 mSunDiffuseCached; - LLColor4 mMoonDiffuseCached; - LLColor4 mCloudColorCached; - F32 mDensityMultiplierCached; - F32 mDistanceMultiplierCached; - F32 mGammaCached = 1.f; - F32 mCloudVarianceCached; - F32 mMoonBrightnessCached; - F32 mStarBrightnessCached; - F32 mSkyMoistureCached; - F32 mSkyDropletRadius; - F32 mSkyIceLevel; - F32 mSceneLightStrength = 3.0f; bool m_isAdvanced = false; + F32 mSceneLightStrength = 3.0f; }; //========================================================================= @@ -155,8 +133,6 @@ class LLSettingsVOWater : public LLSettingsWater static LLSD convertToLegacy(const ptr_t &); - void updateShader(LLGLSLShader* shader) { applySpecial(shader, true); } - protected: LLSettingsVOWater(); @@ -167,11 +143,8 @@ class LLSettingsVOWater : public LLSettingsWater private: - LLColor4 mCachedWaterFogColor; - F32 mCachedWaterFogDensity; - F32 mCachedFogMod; - static const F32 WATER_FOG_LIGHT_CLAMP; + }; //========================================================================= diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp index d5819902b7bdcd3cbf1fb318c813f178521adafa..7827d86d22117c1f90065a2f417e56dd9bac8bf7 100644 --- a/indra/newview/llsidepanelappearance.cpp +++ b/indra/newview/llsidepanelappearance.cpp @@ -211,7 +211,7 @@ void LLSidepanelAppearance::updateToVisibility(const LLSD &new_visibility) // when editing its physics. if (!gAgentCamera.cameraCustomizeAvatar()) { - LLVOAvatarSelf::onCustomizeStart(LLWearableType::getInstanceFast()->getDisableCameraSwitch(wearable_ptr->getType())); + LLVOAvatarSelf::onCustomizeStart(LLWearableType::getInstance()->getDisableCameraSwitch(wearable_ptr->getType())); } if (is_wearable_edit_visible) { diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp index cc3f6e0f41c1144a8a6d284052397e011538dbb8..a5dcdc41edebd1b971efe18bfe14799dfb202c1d 100644 --- a/indra/newview/llsidepanelinventory.cpp +++ b/indra/newview/llsidepanelinventory.cpp @@ -426,7 +426,7 @@ void LLSidepanelInventory::onOpen(const LLSD& key) if (key.has("task")) { if (mTaskPanel) - mTaskPanel->setObjectSelection(LLSelectMgr::getInstanceFast()->getSelection()); + mTaskPanel->setObjectSelection(LLSelectMgr::getInstance()->getSelection()); showTaskInfoPanel(); } } diff --git a/indra/newview/llsidepaneltaskinfo.cpp b/indra/newview/llsidepaneltaskinfo.cpp index 7c27a7f585e18df2b7acc3a13d83b6b583081ac8..9f575d106c8c68070870a19f805b3c5513b8febb 100644 --- a/indra/newview/llsidepaneltaskinfo.cpp +++ b/indra/newview/llsidepaneltaskinfo.cpp @@ -86,7 +86,7 @@ static LLPanelInjector<LLSidepanelTaskInfo> t_task_info("sidepanel_task_info"); LLSidepanelTaskInfo::LLSidepanelTaskInfo() { setMouseOpaque(FALSE); - LLSelectMgr::instanceFast().mUpdateSignal.connect(boost::bind(&LLSidepanelTaskInfo::refreshAll, this)); + LLSelectMgr::instance().mUpdateSignal.connect(boost::bind(&LLSidepanelTaskInfo::refreshAll, this)); } @@ -312,10 +312,10 @@ void LLSidepanelTaskInfo::refresh() const BOOL is_one_object = (object_count == 1); // BUG: fails if a root and non-root are both single-selected. - const BOOL is_perm_modify = (mObjectSelection->getFirstRootNode() && LLSelectMgr::getInstanceFast()->selectGetRootsModify()) || - LLSelectMgr::getInstanceFast()->selectGetModify(); - const BOOL is_nonpermanent_enforced = (mObjectSelection->getFirstRootNode() && LLSelectMgr::getInstanceFast()->selectGetRootsNonPermanentEnforced()) || - LLSelectMgr::getInstanceFast()->selectGetNonPermanentEnforced(); + const BOOL is_perm_modify = (mObjectSelection->getFirstRootNode() && LLSelectMgr::getInstance()->selectGetRootsModify()) || + LLSelectMgr::getInstance()->selectGetModify(); + const BOOL is_nonpermanent_enforced = (mObjectSelection->getFirstRootNode() && LLSelectMgr::getInstance()->selectGetRootsNonPermanentEnforced()) || + LLSelectMgr::getInstance()->selectGetNonPermanentEnforced(); S32 string_index = 0; std::string MODIFY_INFO_STRINGS[] = @@ -345,20 +345,20 @@ void LLSidepanelTaskInfo::refresh() std::string pfAttrName; if ((mObjectSelection->getFirstRootNode() - && LLSelectMgr::getInstanceFast()->selectGetRootsNonPathfinding()) - || LLSelectMgr::getInstanceFast()->selectGetNonPathfinding()) + && LLSelectMgr::getInstance()->selectGetRootsNonPathfinding()) + || LLSelectMgr::getInstance()->selectGetNonPathfinding()) { pfAttrName = "Pathfinding_Object_Attr_None"; } else if ((mObjectSelection->getFirstRootNode() - && LLSelectMgr::getInstanceFast()->selectGetRootsPermanent()) - || LLSelectMgr::getInstanceFast()->selectGetPermanent()) + && LLSelectMgr::getInstance()->selectGetRootsPermanent()) + || LLSelectMgr::getInstance()->selectGetPermanent()) { pfAttrName = "Pathfinding_Object_Attr_Permanent"; } else if ((mObjectSelection->getFirstRootNode() - && LLSelectMgr::getInstanceFast()->selectGetRootsCharacter()) - || LLSelectMgr::getInstanceFast()->selectGetCharacter()) + && LLSelectMgr::getInstance()->selectGetRootsCharacter()) + || LLSelectMgr::getInstance()->selectGetCharacter()) { pfAttrName = "Pathfinding_Object_Attr_Character"; } @@ -374,9 +374,9 @@ void LLSidepanelTaskInfo::refresh() getChildView("Creator:")->setEnabled(TRUE); std::string creator_name; // [RLVa:KB] - Checked: 2010-11-01 (RLVa-1.2.2a) | Modified: RLVa-1.2.2a - BOOL creators_identical = LLSelectMgr::getInstanceFast()->selectGetCreator(mCreatorID, creator_name); + BOOL creators_identical = LLSelectMgr::getInstance()->selectGetCreator(mCreatorID, creator_name); // [/RLVa:KB] -// LLSelectMgr::getInstanceFast()->selectGetCreator(creator_id, creator_name); +// LLSelectMgr::getInstance()->selectGetCreator(creator_id, creator_name); // if(creator_id != mCreatorID ) // { @@ -394,10 +394,10 @@ void LLSidepanelTaskInfo::refresh() getChildView("Owner:")->setEnabled(TRUE); std::string owner_name; - const BOOL owners_identical = LLSelectMgr::getInstanceFast()->selectGetOwner(mOwnerID, owner_name); + const BOOL owners_identical = LLSelectMgr::getInstance()->selectGetOwner(mOwnerID, owner_name); if (mOwnerID.isNull()) { - if (LLSelectMgr::getInstanceFast()->selectIsGroupOwned()) + if (LLSelectMgr::getInstance()->selectIsGroupOwned()) { // Group owned already displayed by selectGetOwner } @@ -405,7 +405,7 @@ void LLSidepanelTaskInfo::refresh() { // Display last owner if public std::string last_owner_name; - LLSelectMgr::getInstanceFast()->selectGetLastOwner(mLastOwnerID, last_owner_name); + LLSelectMgr::getInstance()->selectGetLastOwner(mLastOwnerID, last_owner_name); // It should never happen that the last owner is null and the owner // is null, but it seems to be a bug in the simulator right now. JC @@ -436,7 +436,7 @@ void LLSidepanelTaskInfo::refresh() creator_name = LLSLURL("agent", mCreatorID, "rlvanonym").getSLURLString(); // Only anonymize the owner name if all of the selection is owned by the same avie and isn't group owned - if ( (owners_identical) && (!LLSelectMgr::getInstanceFast()->selectIsGroupOwned()) && (mOwnerID != gAgent.getID()) ) + if ( (owners_identical) && (!LLSelectMgr::getInstance()->selectIsGroupOwned()) && (mOwnerID != gAgent.getID()) ) owner_name = LLSLURL("agent", mOwnerID, "rlvanonym").getSLURLString(); } @@ -451,7 +451,7 @@ void LLSidepanelTaskInfo::refresh() getChildView("Group:")->setEnabled(TRUE); getChild<LLUICtrl>("Group Name")->setValue(LLStringUtil::null); LLUUID group_id; - BOOL groups_identical = LLSelectMgr::getInstanceFast()->selectGetGroup(group_id); + BOOL groups_identical = LLSelectMgr::getInstance()->selectGetGroup(group_id); if (groups_identical) { if (mLabelGroupName) @@ -520,17 +520,17 @@ void LLSidepanelTaskInfo::refresh() BOOL is_for_sale_mixed = FALSE; BOOL is_sale_price_mixed = FALSE; U32 num_for_sale = FALSE; - LLSelectMgr::getInstanceFast()->selectGetAggregateSaleInfo(num_for_sale, + LLSelectMgr::getInstance()->selectGetAggregateSaleInfo(num_for_sale, is_for_sale_mixed, is_sale_price_mixed, total_sale_price, individual_sale_price); const BOOL self_owned = (gAgent.getID() == mOwnerID); - const BOOL group_owned = LLSelectMgr::getInstanceFast()->selectIsGroupOwned() ; - const BOOL public_owned = (mOwnerID.isNull() && !LLSelectMgr::getInstanceFast()->selectIsGroupOwned()); - const BOOL can_transfer = LLSelectMgr::getInstanceFast()->selectGetRootsTransfer(); - const BOOL can_copy = LLSelectMgr::getInstanceFast()->selectGetRootsCopy(); + const BOOL group_owned = LLSelectMgr::getInstance()->selectIsGroupOwned() ; + const BOOL public_owned = (mOwnerID.isNull() && !LLSelectMgr::getInstance()->selectIsGroupOwned()); + const BOOL can_transfer = LLSelectMgr::getInstance()->selectGetRootsTransfer(); + const BOOL can_copy = LLSelectMgr::getInstance()->selectGetRootsCopy(); if (!owners_identical) { @@ -619,22 +619,22 @@ void LLSidepanelTaskInfo::refresh() U32 next_owner_mask_on = 0; U32 next_owner_mask_off = 0; - BOOL valid_base_perms = LLSelectMgr::getInstanceFast()->selectGetPerm(PERM_BASE, + BOOL valid_base_perms = LLSelectMgr::getInstance()->selectGetPerm(PERM_BASE, &base_mask_on, &base_mask_off); //BOOL valid_owner_perms =// - LLSelectMgr::getInstanceFast()->selectGetPerm(PERM_OWNER, + LLSelectMgr::getInstance()->selectGetPerm(PERM_OWNER, &owner_mask_on, &owner_mask_off); - BOOL valid_group_perms = LLSelectMgr::getInstanceFast()->selectGetPerm(PERM_GROUP, + BOOL valid_group_perms = LLSelectMgr::getInstance()->selectGetPerm(PERM_GROUP, &group_mask_on, &group_mask_off); - BOOL valid_everyone_perms = LLSelectMgr::getInstanceFast()->selectGetPerm(PERM_EVERYONE, + BOOL valid_everyone_perms = LLSelectMgr::getInstance()->selectGetPerm(PERM_EVERYONE, &everyone_mask_on, &everyone_mask_off); - BOOL valid_next_perms = LLSelectMgr::getInstanceFast()->selectGetPerm(PERM_NEXT_OWNER, + BOOL valid_next_perms = LLSelectMgr::getInstance()->selectGetPerm(PERM_NEXT_OWNER, &next_owner_mask_on, &next_owner_mask_off); @@ -918,7 +918,7 @@ void LLSidepanelTaskInfo::refresh() // reflect sale information LLSaleInfo sale_info; - BOOL valid_sale_info = LLSelectMgr::getInstanceFast()->selectGetSaleInfo(sale_info); + BOOL valid_sale_info = LLSelectMgr::getInstance()->selectGetSaleInfo(sale_info); LLSaleInfo::EForSale sale_type = sale_info.getSaleType(); LLComboBox* combo_sale_type = getChild<LLComboBox>("sale type"); @@ -949,16 +949,16 @@ void LLSidepanelTaskInfo::refresh() } // Check search status of objects - const BOOL all_volume = LLSelectMgr::getInstanceFast()->selectionAllPCode( LL_PCODE_VOLUME ); + const BOOL all_volume = LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME ); bool include_in_search; - const BOOL all_include_in_search = LLSelectMgr::getInstanceFast()->selectionGetIncludeInSearch(&include_in_search); + const BOOL all_include_in_search = LLSelectMgr::getInstance()->selectionGetIncludeInSearch(&include_in_search); getChildView("search_check")->setEnabled(has_change_sale_ability && all_volume); getChild<LLUICtrl>("search_check")->setValue(include_in_search); getChild<LLUICtrl>("search_check")->setTentative( !all_include_in_search); // Click action (touch, sit, buy) U8 click_action = 0; - if (LLSelectMgr::getInstanceFast()->selectionGetClickAction(&click_action)) + if (LLSelectMgr::getInstance()->selectionGetClickAction(&click_action)) { LLComboBox* ComboClickAction = getChild<LLComboBox>("clickaction"); if (ComboClickAction) @@ -1005,21 +1005,21 @@ void LLSidepanelTaskInfo::refresh() void LLSidepanelTaskInfo::onClickClaim(void*) { // try to claim ownership - LLSelectMgr::getInstanceFast()->sendOwner(gAgent.getID(), gAgent.getGroupID()); + LLSelectMgr::getInstance()->sendOwner(gAgent.getID(), gAgent.getGroupID()); } // static void LLSidepanelTaskInfo::onClickRelease(void*) { // try to release ownership - LLSelectMgr::getInstanceFast()->sendOwner(LLUUID::null, LLUUID::null); + LLSelectMgr::getInstance()->sendOwner(LLUUID::null, LLUUID::null); } void LLSidepanelTaskInfo::onClickGroup() { LLUUID owner_id; std::string name; - BOOL owners_identical = LLSelectMgr::getInstanceFast()->selectGetOwner(owner_id, name); + BOOL owners_identical = LLSelectMgr::getInstance()->selectGetOwner(owner_id, name); LLFloater* parent_floater = gFloaterView->getParentFloater(this); if (owners_identical && (owner_id == gAgent.getID())) @@ -1044,7 +1044,7 @@ void LLSidepanelTaskInfo::cbGroupID(LLUUID group_id) { mLabelGroupName->setNameID(group_id, TRUE); } - LLSelectMgr::getInstanceFast()->sendGroup(group_id); + LLSelectMgr::getInstance()->sendGroup(group_id); } static bool callback_deed_to_group(const LLSD& notification, const LLSD& response) @@ -1053,10 +1053,10 @@ static bool callback_deed_to_group(const LLSD& notification, const LLSD& respons if (option == 0) { LLUUID group_id; - const BOOL groups_identical = LLSelectMgr::getInstanceFast()->selectGetGroup(group_id); + const BOOL groups_identical = LLSelectMgr::getInstance()->selectGetGroup(group_id); if (group_id.notNull() && groups_identical && (gAgent.hasPowerInGroup(group_id, GP_OBJECT_DEED))) { - LLSelectMgr::getInstanceFast()->sendOwner(LLUUID::null, group_id, FALSE); + LLSelectMgr::getInstance()->sendOwner(LLUUID::null, group_id, FALSE); } } return FALSE; @@ -1074,7 +1074,7 @@ void LLSidepanelTaskInfo::onClickDeedToGroup(void *data) // static void LLSidepanelTaskInfo::onCommitPerm(LLUICtrl *ctrl, void *data, U8 field, U32 perm) { - LLViewerObject* object = LLSelectMgr::getInstanceFast()->getSelection()->getFirstRootObject(); + LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getFirstRootObject(); if(!object) return; // Checkbox will have toggled itself @@ -1082,7 +1082,7 @@ void LLSidepanelTaskInfo::onCommitPerm(LLUICtrl *ctrl, void *data, U8 field, U32 LLCheckBoxCtrl *check = (LLCheckBoxCtrl *)ctrl; BOOL new_state = check->get(); - LLSelectMgr::getInstanceFast()->selectionSetObjectPermissions(field, new_state, perm); + LLSelectMgr::getInstance()->selectionSetObjectPermissions(field, new_state, perm); LLSidepanelTaskInfo* self = (LLSidepanelTaskInfo*)data; if (self) @@ -1144,8 +1144,8 @@ void LLSidepanelTaskInfo::onCommitName(LLUICtrl*, void* data) LLLineEditor* tb = self->getChild<LLLineEditor>("Object Name"); if(tb) { - LLSelectMgr::getInstanceFast()->selectionSetObjectName(tb->getText()); -// LLSelectMgr::getInstanceFast()->selectionSetObjectName(self->mLabelObjectName->getText()); + LLSelectMgr::getInstance()->selectionSetObjectName(tb->getText()); +// LLSelectMgr::getInstance()->selectionSetObjectName(self->mLabelObjectName->getText()); } } @@ -1158,7 +1158,7 @@ void LLSidepanelTaskInfo::onCommitDesc(LLUICtrl*, void* data) LLLineEditor* le = self->getChild<LLLineEditor>("Object Description"); if(le) { - LLSelectMgr::getInstanceFast()->selectionSetObjectDescription(le->getText()); + LLSelectMgr::getInstance()->selectionSetObjectDescription(le->getText()); } } @@ -1199,13 +1199,13 @@ void LLSidepanelTaskInfo::setAllSaleInfo() sale_type = LLSaleInfo::FS_NOT; LLSaleInfo old_sale_info; - LLSelectMgr::getInstanceFast()->selectGetSaleInfo(old_sale_info); + LLSelectMgr::getInstance()->selectGetSaleInfo(old_sale_info); LLSaleInfo new_sale_info(sale_type, price); - LLSelectMgr::getInstanceFast()->selectionSetObjectSaleInfo(new_sale_info); + LLSelectMgr::getInstance()->selectionSetObjectSaleInfo(new_sale_info); U8 old_click_action = 0; - LLSelectMgr::getInstanceFast()->selectionGetClickAction(&old_click_action); + LLSelectMgr::getInstance()->selectionGetClickAction(&old_click_action); if (old_sale_info.isForSale() && !new_sale_info.isForSale() @@ -1213,7 +1213,7 @@ void LLSidepanelTaskInfo::setAllSaleInfo() { // If turned off for-sale, make sure click-action buy is turned // off as well - LLSelectMgr::getInstanceFast()-> + LLSelectMgr::getInstance()-> selectionSetClickAction(CLICK_ACTION_TOUCH); } else if (new_sale_info.isForSale() @@ -1222,7 +1222,7 @@ void LLSidepanelTaskInfo::setAllSaleInfo() { // If just turning on for-sale, preemptively turn on one-click buy // unless user have a different click action set - LLSelectMgr::getInstanceFast()-> + LLSelectMgr::getInstance()-> selectionSetClickAction(CLICK_ACTION_BUY); } } @@ -1273,14 +1273,14 @@ void LLSidepanelTaskInfo::doClickAction(U8 click_action) if (click_action == CLICK_ACTION_BUY) { LLSaleInfo sale_info; - LLSelectMgr::getInstanceFast()->selectGetSaleInfo(sale_info); + LLSelectMgr::getInstance()->selectGetSaleInfo(sale_info); if (!sale_info.isForSale()) { LLNotificationsUtil::add("CantSetBuyObject"); // Set click action back to its old value U8 click_action = 0; - LLSelectMgr::getInstanceFast()->selectionGetClickAction(&click_action); + LLSelectMgr::getInstance()->selectionGetClickAction(&click_action); return; } } @@ -1288,7 +1288,7 @@ void LLSidepanelTaskInfo::doClickAction(U8 click_action) { // Verify object has script with money() handler LLSelectionPayable payable; - bool can_pay = LLSelectMgr::getInstanceFast()->getSelection()->applyToObjects(&payable); + bool can_pay = LLSelectMgr::getInstance()->getSelection()->applyToObjects(&payable); if (!can_pay) { // Warn, but do it anyway. @@ -1299,7 +1299,7 @@ void LLSidepanelTaskInfo::doClickAction(U8 click_action) handle_give_money_dialog(); } } - LLSelectMgr::getInstanceFast()->selectionSetClickAction(click_action); + LLSelectMgr::getInstance()->selectionSetClickAction(click_action); } // static @@ -1307,7 +1307,7 @@ void LLSidepanelTaskInfo::onCommitIncludeInSearch(LLUICtrl* ctrl, void* data) { LLCheckBoxCtrl* box = (LLCheckBoxCtrl*)ctrl; llassert(box); - LLSelectMgr::getInstanceFast()->selectionSetIncludeInSearch(box->get()); + LLSelectMgr::getInstance()->selectionSetIncludeInSearch(box->get()); } // virtual @@ -1323,7 +1323,7 @@ void LLSidepanelTaskInfo::updateVerbs() //mEditBtn->setEnabled(obj && obj->permModify()); */ - LLSafeHandle<LLObjectSelection> object_selection = LLSelectMgr::getInstanceFast()->getSelection(); + LLSafeHandle<LLObjectSelection> object_selection = LLSelectMgr::getInstance()->getSelection(); const BOOL any_selected = (object_selection->getNumNodes() > 0); mOpenBtn->setVisible(true); diff --git a/indra/newview/llskinningutil.cpp b/indra/newview/llskinningutil.cpp index 69707f72d1585c7c00a6e621187fdaa401efb486..130f344bbf9388c39dfa0905978ced0b6ab268f1 100644 --- a/indra/newview/llskinningutil.cpp +++ b/indra/newview/llskinningutil.cpp @@ -34,7 +34,7 @@ #include "llvolume.h" #include "llrigginginfo.h" -#define MAT_USE_SSE 1 +#define DEBUG_SKINNING LL_DEBUG void dump_avatar_and_skin_state(const std::string& reason, LLVOAvatar *avatar, const LLMeshSkinInfo *skin) { @@ -113,24 +113,20 @@ void LLSkinningUtil::scrubInvalidJoints(LLVOAvatar *avatar, LLMeshSkinInfo* skin skin->mInvalidJointsScrubbed = true; } -#define MAT_USE_SSE 1 - void LLSkinningUtil::initSkinningMatrixPalette( LLMatrix4a* mat, S32 count, const LLMeshSkinInfo* skin, LLVOAvatar *avatar) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; + initJointNums(const_cast<LLMeshSkinInfo*>(skin), avatar); for (U32 j = 0; j < count; ++j) { S32 joint_num = skin->mJointNums[j]; - LLJoint *joint = NULL; - if (joint_num >= 0 && joint_num < LL_CHARACTER_MAX_ANIMATED_JOINTS) - { - joint = avatar->getJoint(joint_num); - } - llassert(joint); + LLJoint *joint = avatar->getJoint(joint_num); + if (joint) { mat[j].setMul(joint->getWorldMatrix(), skin->mInvBindMatrix[j]); @@ -178,7 +174,7 @@ void LLSkinningUtil::checkSkinWeights(LLVector4a* weights, U32 num_vertices, con void LLSkinningUtil::getPerVertexSkinMatrix( F32* weights, - LLMatrix4a* mat, + const LLMatrix4a* mat, bool handle_bad_scale, LLMatrix4a& final_mat) { @@ -241,6 +237,7 @@ void LLSkinningUtil::initJointNums(LLMeshSkinInfo* skin, LLVOAvatar *avatar) { if (!skin->mJointNumsInitialized) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; for (U32 j = 0; j < skin->mJointNames.size(); ++j) { #if DEBUG_SKINNING @@ -295,7 +292,7 @@ void LLSkinningUtil::updateRiggingInfo(const LLMeshSkinInfo* skin, LLVOAvatar *a //S32 active_verts = 0; vol_face.mJointRiggingInfoTab.resize(LL_CHARACTER_MAX_ANIMATED_JOINTS); LLJointRiggingInfoTab &rig_info_tab = vol_face.mJointRiggingInfoTab; - LLMatrix4a bind_shape = skin->mBindShapeMatrix; + const LLMatrix4a& bind_shape = skin->mBindShapeMatrix; LLMatrix4a matrixPalette[LL_CHARACTER_MAX_ANIMATED_JOINTS]; for (U32 i = 0; i < llmin(skin->mInvBindMatrix.size(), (size_t)LL_CHARACTER_MAX_ANIMATED_JOINTS); ++i) { diff --git a/indra/newview/llskinningutil.h b/indra/newview/llskinningutil.h index 29e9950534997845cd0d201f79c3b0ebc5b9d842..e535ec054a92f0f32a07ab83ed851c5cac55a133 100644 --- a/indra/newview/llskinningutil.h +++ b/indra/newview/llskinningutil.h @@ -53,7 +53,7 @@ namespace LLSkinningUtil void initJointNums(LLMeshSkinInfo* skin, LLVOAvatar *avatar); void initSkinningMatrixPalette(LLMatrix4a* mat, S32 count, const LLMeshSkinInfo* skin, LLVOAvatar *avatar); void checkSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin); - void getPerVertexSkinMatrix(F32* weights, LLMatrix4a* mat, bool handle_bad_scale, LLMatrix4a& final_mat); + void getPerVertexSkinMatrix(F32* weights, const LLMatrix4a* mat, bool handle_bad_scale, LLMatrix4a& final_mat); void updateRiggingInfo(const LLMeshSkinInfo* skin, LLVOAvatar *avatar, LLVolumeFace& vol_face); diff --git a/indra/newview/llsky.cpp b/indra/newview/llsky.cpp index 9ac779d4a446775f1cc75989ecf555e216429128..c89de0bf39c295344d782808ac44e120124a9524 100644 --- a/indra/newview/llsky.cpp +++ b/indra/newview/llsky.cpp @@ -270,7 +270,7 @@ void LLSky::updateFog(const F32 distance) { if (mVOSkyp) { - LLEnvironment* environment = LLEnvironment::getInstanceFast(); + LLEnvironment* environment = LLEnvironment::getInstance(); mVOSkyp->updateFog(environment, environment->getCurrentSky(), distance); } } diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp index 0041a4b55750fd329148aaec6d54f548636ef1b6..0d64d642a56f014203fadc6f67c424fa121d4db7 100644 --- a/indra/newview/llsnapshotlivepreview.cpp +++ b/indra/newview/llsnapshotlivepreview.cpp @@ -676,8 +676,8 @@ BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview ) } // If we're in freeze-frame and/or auto update mode and camera has moved, update snapshot. - LLVector3 new_camera_pos = LLViewerCamera::getInstanceFast()->getOrigin(); - LLQuaternion new_camera_rot = LLViewerCamera::getInstanceFast()->getQuaternion(); + LLVector3 new_camera_pos = LLViewerCamera::getInstance()->getOrigin(); + LLQuaternion new_camera_rot = LLViewerCamera::getInstance()->getQuaternion(); if (previewp->mForceUpdateSnapshot || (((ALControlCache::AutoSnapshot && LLView::isAvailable(previewp->mViewContainer)) || (LLPipeline::FreezeTime && previewp->mAllowFullScreenPreview)) && diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 2d55fa91732c53597b98b03680d97934945010ea..e0d0e65be2c2001a08f81990aa9dfb74718d325b 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -51,13 +51,9 @@ #include "llphysicsshapebuilderutil.h" #include "llvoavatar.h" #include "llvolumemgr.h" -#include "lltextureatlas.h" #include "llviewershadermgr.h" #include "llcontrolavatar.h" -static LLTrace::BlockTimerStatHandle FTM_FRUSTUM_CULL("Frustum Culling"); -static LLTrace::BlockTimerStatHandle FTM_CULL_REBOUND("Cull Rebound Partition"); - extern bool gShiftFrame; static U32 sZombieGroups = 0; @@ -131,129 +127,6 @@ LLSpatialGroup::~LLSpatialGroup() sNodeCount--; clearDrawMap(); - clearAtlasList() ; -} - -BOOL LLSpatialGroup::hasAtlas(LLTextureAtlas* atlasp) -{ - S8 type = atlasp->getComponents() - 1 ; - for(std::list<LLTextureAtlas*>::iterator iter = mAtlasList[type].begin(); iter != mAtlasList[type].end() ; ++iter) - { - if(atlasp == *iter) - { - return TRUE ; - } - } - return FALSE ; -} - -void LLSpatialGroup::addAtlas(LLTextureAtlas* atlasp, S8 recursive_level) -{ - if(!hasAtlas(atlasp)) - { - mAtlasList[atlasp->getComponents() - 1].push_back(atlasp) ; - atlasp->addSpatialGroup(this) ; - } - - --recursive_level; - if(recursive_level)//levels propagating up. - { - LLSpatialGroup* parent = getParent() ; - if(parent) - { - parent->addAtlas(atlasp, recursive_level) ; - } - } -} - -void LLSpatialGroup::removeAtlas(LLTextureAtlas* atlasp, BOOL remove_group, S8 recursive_level) -{ - mAtlasList[atlasp->getComponents() - 1].remove(atlasp) ; - if(remove_group) - { - atlasp->removeSpatialGroup(this) ; - } - - --recursive_level; - if(recursive_level)//levels propagating up. - { - LLSpatialGroup* parent = getParent() ; - if(parent) - { - parent->removeAtlas(atlasp, recursive_level) ; - } - } -} - -void LLSpatialGroup::clearAtlasList() -{ - std::list<LLTextureAtlas*>::iterator iter ; - for(S8 i = 0 ; i < 4 ; i++) - { - if(mAtlasList[i].size() > 0) - { - for(iter = mAtlasList[i].begin(); iter != mAtlasList[i].end() ; ++iter) - { - ((LLTextureAtlas*)*iter)->removeSpatialGroup(this) ; - } - mAtlasList[i].clear() ; - } - } -} - -LLTextureAtlas* LLSpatialGroup::getAtlas(S8 ncomponents, S8 to_be_reserved, S8 recursive_level) -{ - S8 type = ncomponents - 1 ; - if(mAtlasList[type].size() > 0) - { - for(std::list<LLTextureAtlas*>::iterator iter = mAtlasList[type].begin(); iter != mAtlasList[type].end() ; ++iter) - { - if(!((LLTextureAtlas*)*iter)->isFull(to_be_reserved)) - { - return *iter ; - } - } - } - - --recursive_level; - if(recursive_level) - { - LLSpatialGroup* parent = getParent() ; - if(parent) - { - return parent->getAtlas(ncomponents, to_be_reserved, recursive_level) ; - } - } - return NULL ; -} - -void LLSpatialGroup::setCurUpdatingSlot(LLTextureAtlasSlot* slotp) -{ - mCurUpdatingSlotp = slotp; - - //if(!hasAtlas(mCurUpdatingSlotp->getAtlas())) - //{ - // addAtlas(mCurUpdatingSlotp->getAtlas()) ; - //} -} - -LLTextureAtlasSlot* LLSpatialGroup::getCurUpdatingSlot(LLViewerTexture* imagep, S8 recursive_level) -{ - if(gFrameCount && mCurUpdatingTime == gFrameCount && mCurUpdatingTexture == imagep) - { - return mCurUpdatingSlotp ; - } - - //--recursive_level ; - //if(recursive_level) - //{ - // LLSpatialGroup* parent = getParent() ; - // if(parent) - // { - // return parent->getCurUpdatingSlot(imagep, recursive_level) ; - // } - //} - return NULL ; } void LLSpatialGroup::clearDrawMap() @@ -345,6 +218,7 @@ void LLSpatialGroup::validateDrawMap() BOOL LLSpatialGroup::updateInGroup(LLDrawable *drawablep, BOOL immediate) { + LL_PROFILE_ZONE_SCOPED; drawablep->updateSpatialExtents(); OctreeNode* parent = mOctreeNode->getOctParent(); @@ -409,11 +283,6 @@ void LLSpatialGroup::rebuildMesh() } } -static LLTrace::BlockTimerStatHandle FTM_REBUILD_VBO("VBO Rebuilt"); -static LLTrace::BlockTimerStatHandle FTM_ADD_GEOMETRY_COUNT("Add Geometry"); -static LLTrace::BlockTimerStatHandle FTM_CREATE_VB("Create VB"); -static LLTrace::BlockTimerStatHandle FTM_GET_GEOMETRY("Get Geometry"); - void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group) { if (group->isDead() || !group->hasState(LLSpatialGroup::GEOM_DIRTY)) @@ -427,7 +296,7 @@ void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group) group->mLastUpdateViewAngle = group->mViewAngle; } - LL_RECORD_BLOCK_TIME(FTM_REBUILD_VBO); + LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL; group->clearDrawMap(); @@ -435,15 +304,12 @@ void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group) U32 index_count = 0; U32 vertex_count = 0; - { - LL_RECORD_BLOCK_TIME(FTM_ADD_GEOMETRY_COUNT); - addGeometryCount(group, vertex_count, index_count); - } - + addGeometryCount(group, vertex_count, index_count); + if (vertex_count > 0 && index_count > 0) { //create vertex buffer containing volume geometry for this node { - LL_RECORD_BLOCK_TIME(FTM_CREATE_VB); + group->mBuilt = 1.f; if (group->mVertexBuffer.isNull() || !group->mVertexBuffer->isWriteable() || @@ -458,7 +324,6 @@ void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group) group->mVertexBuffer = NULL; group->mBufferMap.clear(); } - stop_glerror(); } else { @@ -471,13 +336,11 @@ void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group) group->mVertexBuffer = NULL; group->mBufferMap.clear(); } - stop_glerror(); } } if (group->mVertexBuffer) { - LL_RECORD_BLOCK_TIME(FTM_GET_GEOMETRY); getGeometry(group); } } @@ -503,7 +366,9 @@ LLSpatialGroup* LLSpatialGroup::getParent() } BOOL LLSpatialGroup::removeObject(LLDrawable *drawablep, BOOL from_octree) - { +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL + if(!drawablep) { return FALSE; @@ -591,6 +456,8 @@ class LLSpatialSetStateDiff : public LLSpatialSetState void LLSpatialGroup::setState(U32 state, S32 mode) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL + llassert(state <= LLSpatialGroup::STATE_MASK); if (mode > STATE_MODE_SINGLE) @@ -638,6 +505,8 @@ class LLSpatialClearStateDiff : public LLSpatialClearState void LLSpatialGroup::clearState(U32 state, S32 mode) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL + llassert(state <= LLSpatialGroup::STATE_MASK); if (mode > STATE_MODE_SINGLE) @@ -673,11 +542,7 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : LLO mDistance(0.f), mDepth(0.f), mLastUpdateDistance(-1.f), - mLastUpdateTime(gFrameTimeSeconds), - mAtlasList(4), - mCurUpdatingTime(0), - mCurUpdatingSlotp(NULL), - mCurUpdatingTexture (NULL) + mLastUpdateTime(gFrameTimeSeconds) { ll_assert_aligned(this,16); @@ -724,6 +589,8 @@ void LLSpatialGroup::updateDistance(LLCamera &camera) F32 LLSpatialPartition::calcDistance(LLSpatialGroup* group, LLCamera& camera) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL + LLVector4a eye; LLVector4a origin; origin.load3(camera.getOrigin().mV); @@ -817,6 +684,8 @@ F32 LLSpatialGroup::getUpdateUrgency() const BOOL LLSpatialGroup::changeLOD() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL + if (hasState(ALPHA_DIRTY | OBJECT_DIRTY)) { //a rebuild is going to happen, update distance and LoD @@ -911,6 +780,8 @@ void LLSpatialGroup::handleDestruction(const TreeNode* node) void LLSpatialGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* child) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL + if (child->getListenerCount() == 0) { new LLSpatialGroup(child, getSpatialPartition()); @@ -983,10 +854,12 @@ LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 LLSpatialPartition::~LLSpatialPartition() { + cleanup(); } LLSpatialGroup *LLSpatialPartition::put(LLDrawable *drawablep, BOOL was_visible) { + LL_PROFILE_ZONE_SCOPED; drawablep->updateSpatialExtents(); //keep drawable from being garbage collected @@ -1012,6 +885,7 @@ LLSpatialGroup *LLSpatialPartition::put(LLDrawable *drawablep, BOOL was_visible) BOOL LLSpatialPartition::remove(LLDrawable *drawablep, LLSpatialGroup *curp) { + LL_PROFILE_ZONE_SCOPED; if (!curp->removeObject(drawablep)) { OCT_ERRS << "Failed to remove drawable from octree!" << LL_ENDL; @@ -1028,6 +902,7 @@ BOOL LLSpatialPartition::remove(LLDrawable *drawablep, LLSpatialGroup *curp) void LLSpatialPartition::move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL immediate) { + LL_PROFILE_ZONE_SCOPED; // sanity check submitted by open source user bushing Spatula // who was seeing crashing here. (See VWR-424 reported by Bunny Mayne) if (!drawablep) @@ -1485,12 +1360,12 @@ void LLSpatialPartition::resetVertexBuffers() BOOL LLSpatialPartition::getVisibleExtents(LLCamera& camera, LLVector3& visMin, LLVector3& visMax) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL; LLVector4a visMina, visMaxa; visMina.load3(visMin.mV); visMaxa.load3(visMax.mV); { - LL_RECORD_BLOCK_TIME(FTM_CULL_REBOUND); LLSpatialGroup* group = (LLSpatialGroup*) mOctree->getListener(0); group->rebound(); } @@ -1512,11 +1387,11 @@ BOOL LLSpatialPartition::visibleObjectsInFrustum(LLCamera& camera) S32 LLSpatialPartition::cull(LLCamera &camera, std::vector<LLDrawable *>* results, BOOL for_select) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL; #if LL_OCTREE_PARANOIA_CHECK ((LLSpatialGroup*)mOctree->getListener(0))->checkStates(); #endif { - LL_RECORD_BLOCK_TIME(FTM_CULL_REBOUND); LLSpatialGroup* group = (LLSpatialGroup*) mOctree->getListener(0); group->rebound(); } @@ -1533,37 +1408,32 @@ S32 LLSpatialPartition::cull(LLCamera &camera, std::vector<LLDrawable *>* result S32 LLSpatialPartition::cull(LLCamera &camera, bool do_occlusion) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL; #if LL_OCTREE_PARANOIA_CHECK ((LLSpatialGroup*)mOctree->getListener(0))->checkStates(); #endif - { - LL_RECORD_BLOCK_TIME(FTM_CULL_REBOUND); - LLSpatialGroup* group = (LLSpatialGroup*) mOctree->getListener(0); - group->rebound(); - } + LLSpatialGroup* group = (LLSpatialGroup*) mOctree->getListener(0); + group->rebound(); #if LL_OCTREE_PARANOIA_CHECK ((LLSpatialGroup*)mOctree->getListener(0))->validate(); #endif - if (LLPipeline::sShadowRender) - { - LL_RECORD_BLOCK_TIME(FTM_FRUSTUM_CULL); - LLOctreeCullShadow culler(&camera); - culler.traverse(mOctree); - } - else if (mInfiniteFarClip || !LLPipeline::sUseFarClip) - { - LL_RECORD_BLOCK_TIME(FTM_FRUSTUM_CULL); - LLOctreeCullNoFarClip culler(&camera); - culler.traverse(mOctree); - } - else - { - LL_RECORD_BLOCK_TIME(FTM_FRUSTUM_CULL); - LLOctreeCull culler(&camera); - culler.traverse(mOctree); - } + if (LLPipeline::sShadowRender) + { + LLOctreeCullShadow culler(&camera); + culler.traverse(mOctree); + } + else if (mInfiniteFarClip || !LLPipeline::sUseFarClip) + { + LLOctreeCullNoFarClip culler(&camera); + culler.traverse(mOctree); + } + else + { + LLOctreeCull culler(&camera); + culler.traverse(mOctree); + } return 0; } @@ -1624,7 +1494,7 @@ void pushVerts(LLVolume* volume) for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i) { const LLVolumeFace& face = volume->getVolumeFace(i); - LLVertexBuffer::drawElements(LLRender::TRIANGLES, face.mNumVertices, face.mPositions, NULL, face.mNumIndices, face.mIndices); + LLVertexBuffer::drawElements(LLRender::TRIANGLES, face.mPositions, NULL, face.mNumIndices, face.mIndices); } } @@ -1703,6 +1573,62 @@ void pushVertsColorCoded(LLSpatialGroup* group, U32 mask) } } +// return false if drawable is rigged and: +// - a linked rigged drawable has a different spatial group +// - a linked rigged drawable face has the wrong draw order index +bool check_rigged_group(LLDrawable* drawable) +{ + if (drawable->isState(LLDrawable::RIGGED)) + { + LLSpatialGroup* group = drawable->getSpatialGroup(); + LLDrawable* root = drawable->getRoot(); + + if (root->isState(LLDrawable::RIGGED) && root->getSpatialGroup() != group) + { + llassert(false); + return false; + } + + S32 last_draw_index = -1; + if (root->isState(LLDrawable::RIGGED)) + { + for (auto& face : root->getFaces()) + { + if ((S32) face->getDrawOrderIndex() <= last_draw_index) + { + llassert(false); + return false; + } + last_draw_index = face->getDrawOrderIndex(); + } + } + + for (auto& child : root->getVObj()->getChildren()) + { + if (child->mDrawable->isState(LLDrawable::RIGGED)) + { + for (auto& face : child->mDrawable->getFaces()) + { + if ((S32) face->getDrawOrderIndex() <= last_draw_index) + { + llassert(false); + return false; + } + last_draw_index = face->getDrawOrderIndex(); + } + } + + if (child->mDrawable->getSpatialGroup() != group) + { + llassert(false); + return false; + } + } + } + + return true; +} + void renderOctree(LLSpatialGroup* group) { //render solid object bounding box, color @@ -1736,13 +1662,20 @@ void renderOctree(LLSpatialGroup* group) gGL.flush(); gGL.setLineWidth(1.f); gGL.flush(); + + LLVOAvatar* lastAvatar = nullptr; + U64 lastMeshId = 0; + for (LLSpatialGroup::element_iter i = group->getDataBegin(), i_end = group->getDataEnd(); i != i_end; ++i) { LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); - if(!drawable) + if(!drawable || drawable->getNumFaces() == 0) { continue; } + + llassert(check_rigged_group(drawable)); + if (!group->getSpatialPartition()->isBridge()) { gGL.pushMatrix(); @@ -1750,6 +1683,27 @@ void renderOctree(LLSpatialGroup* group) gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]); } + LLFace* face = drawable->getFace(0); + bool rigged = face->isState(LLFace::RIGGED); + gDebugProgram.bind(rigged); + + gGL.diffuseColor4f(1, 0, 0, 1); + + if (rigged) + { + gGL.pushMatrix(); + gGL.loadMatrix(gGLModelView); + if (lastAvatar != face->mAvatar || + lastMeshId != face->mSkinInfo->mHash) + { + if (!LLRenderPass::uploadMatrixPalette(face->mAvatar, face->mSkinInfo)) + { + continue; + } + lastAvatar = face->mAvatar; + lastMeshId = face->mSkinInfo->mHash; + } + } for (S32 j = 0, j_end = drawable->getNumFaces(); j < j_end; ++j) { LLFace* face = drawable->getFace(j); @@ -1768,19 +1722,25 @@ void renderOctree(LLSpatialGroup* group) continue; } - face->getVertexBuffer()->setBuffer(LLVertexBuffer::MAP_VERTEX); + face->getVertexBuffer()->setBuffer(LLVertexBuffer::MAP_VERTEX | (rigged ? LLVertexBuffer::MAP_WEIGHT4 : 0)); //drawBox((face->mExtents[0] + face->mExtents[1])*0.5f, // (face->mExtents[1]-face->mExtents[0])*0.5f); face->getVertexBuffer()->draw(LLRender::TRIANGLES, face->getIndicesCount(), face->getIndicesStart()); } } + if (rigged) + { + gGL.popMatrix(); + } + if (!group->getSpatialPartition()->isBridge()) { gGL.popMatrix(); } } glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + gDebugProgram.bind(); // make sure non-rigged variant is bound gGL.diffuseColor4f(1,1,1,1); } } @@ -2383,7 +2343,12 @@ void renderMeshBaseHull(LLVOVolume* volume, U32 data_mask, LLColor4& color, LLCo if (!decomp->mBaseHullMesh.empty()) { gGL.diffuseColor4fv(color.mV); - LLVertexBuffer::drawArrays(LLRender::TRIANGLES, decomp->mBaseHullMesh.mPositions, decomp->mBaseHullMesh.mNormals); + LLVertexBuffer::drawArrays(LLRender::TRIANGLES, decomp->mBaseHullMesh.mPositions); + + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + gGL.diffuseColor4fv(line_color.mV); + LLVertexBuffer::drawArrays(LLRender::TRIANGLES, decomp->mBaseHullMesh.mPositions); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } else { @@ -2403,13 +2368,11 @@ void renderMeshBaseHull(LLVOVolume* volume, U32 data_mask, LLColor4& color, LLCo void render_hull(LLModel::PhysicsMesh& mesh, const LLColor4& color, const LLColor4& line_color) { gGL.diffuseColor4fv(color.mV); - LLVertexBuffer::drawArrays(LLRender::TRIANGLES, mesh.mPositions, mesh.mNormals); - LLGLEnable offset(GL_POLYGON_OFFSET_LINE); + LLVertexBuffer::drawArrays(LLRender::TRIANGLES, mesh.mPositions); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - glPolygonOffset(3.f, 3.f); gGL.setLineWidth(3.f); gGL.diffuseColor4fv(line_color.mV); - LLVertexBuffer::drawArrays(LLRender::TRIANGLES, mesh.mPositions, mesh.mNormals); + LLVertexBuffer::drawArrays(LLRender::TRIANGLES, mesh.mPositions); gGL.setLineWidth(1.f); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } @@ -2464,6 +2427,9 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume) gGL.pushMatrix(); gGL.multMatrix(volume->getRelativeXform()); + LLGLEnable(GL_POLYGON_OFFSET_LINE); + glPolygonOffset(3.f, 3.f); + if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::USER_MESH) { LLUUID mesh_id = volume->getVolume()->getParams().getSculptID(); @@ -2491,12 +2457,12 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume) { //decomp has physics mesh, render that mesh gGL.diffuseColor4fv(color.mV); - LLVertexBuffer::drawArrays(LLRender::TRIANGLES, decomp->mPhysicsShapeMesh.mPositions, decomp->mPhysicsShapeMesh.mNormals); + LLVertexBuffer::drawArrays(LLRender::TRIANGLES, decomp->mPhysicsShapeMesh.mPositions); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); gGL.diffuseColor4fv(line_color.mV); - LLVertexBuffer::drawArrays(LLRender::TRIANGLES, decomp->mPhysicsShapeMesh.mPositions, decomp->mPhysicsShapeMesh.mNormals); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + LLVertexBuffer::drawArrays(LLRender::TRIANGLES, decomp->mPhysicsShapeMesh.mPositions); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } else { //no mesh or decomposition, render base hull @@ -2622,13 +2588,13 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume) gGL.diffuseColor4fv(line_color.mV); LLVertexBuffer::unbind(); - llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShader != 0); - - LLVertexBuffer::drawElements(LLRender::TRIANGLES, phys_volume->mNumHullPoints, phys_volume->mHullPoints, NULL, phys_volume->mNumHullIndices, phys_volume->mHullIndices); + llassert(LLGLSLShader::sCurBoundShader != 0); + + LLVertexBuffer::drawElements(LLRender::TRIANGLES, phys_volume->mHullPoints, NULL, phys_volume->mNumHullIndices, phys_volume->mHullIndices); gGL.diffuseColor4fv(color.mV); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - LLVertexBuffer::drawElements(LLRender::TRIANGLES, phys_volume->mNumHullPoints, phys_volume->mHullPoints, NULL, phys_volume->mNumHullIndices, phys_volume->mHullIndices); + LLVertexBuffer::drawElements(LLRender::TRIANGLES, phys_volume->mHullPoints, NULL, phys_volume->mNumHullIndices, phys_volume->mHullIndices); } else @@ -2705,11 +2671,11 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume) { gGL.diffuseColor4fv(line_color.mV); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - LLVertexBuffer::drawElements(LLRender::TRIANGLES, phys_volume->mNumHullPoints, phys_volume->mHullPoints, NULL, phys_volume->mNumHullIndices, phys_volume->mHullIndices); + LLVertexBuffer::drawElements(LLRender::TRIANGLES, phys_volume->mHullPoints, NULL, phys_volume->mNumHullIndices, phys_volume->mHullIndices); gGL.diffuseColor4fv(color.mV); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - LLVertexBuffer::drawElements(LLRender::TRIANGLES, phys_volume->mNumHullPoints, phys_volume->mHullPoints, NULL, phys_volume->mNumHullIndices, phys_volume->mHullIndices); + LLVertexBuffer::drawElements(LLRender::TRIANGLES, phys_volume->mHullPoints, NULL, phys_volume->mNumHullIndices, phys_volume->mHullIndices); } else { @@ -2901,8 +2867,27 @@ void renderBatchSize(LLDrawInfo* params) { LLGLEnable offset(GL_POLYGON_OFFSET_FILL); glPolygonOffset(-1.f, 1.f); - gGL.diffuseColor4ubv((GLubyte*) &(params->mDebugColor)); - pushVerts(params, LLVertexBuffer::MAP_VERTEX); + LLGLSLShader* old_shader = LLGLSLShader::sCurBoundShaderPtr; + U32 mask = LLVertexBuffer::MAP_VERTEX; + bool bind = false; + if (params->mAvatar) + { + gGL.pushMatrix(); + gGL.loadMatrix(gGLModelView); + bind = true; + old_shader->mRiggedVariant->bind(); + LLRenderPass::uploadMatrixPalette(*params); + mask |= LLVertexBuffer::MAP_WEIGHT4; + } + + gGL.diffuseColor4ubv((GLubyte*)&(params->mDebugColor)); + pushVerts(params, mask); + + if (bind) + { + gGL.popMatrix(); + old_shader->bind(); + } } void renderShadowFrusta(LLDrawInfo* params) @@ -3099,7 +3084,7 @@ class LLRenderOctreeRaycast : public LLOctreeTriangleRayIntersect } - void visit(const LLOctreeNode<LLVolumeTriangle>* branch) + void visit(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* branch) { LLVolumeOctreeListener* vl = (LLVolumeOctreeListener*) branch->getListener(0); @@ -3141,7 +3126,7 @@ class LLRenderOctreeRaycast : public LLOctreeTriangleRayIntersect } gGL.begin(LLRender::TRIANGLES); - for (LLOctreeNode<LLVolumeTriangle>::const_element_iter iter = branch->getDataBegin(), end = branch->getDataEnd(); + for (LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>::const_element_iter iter = branch->getDataBegin(), end = branch->getDataEnd(); iter != end; ++iter) { @@ -3224,21 +3209,21 @@ void renderRaycast(LLDrawable* drawablep) { //render face positions gGL.diffuseColor4f(0.f, 1.f, 1.f, 0.5f); - LLVertexBuffer::drawElements(LLRender::TRIANGLES, face.mNumVertices, face.mPositions, NULL, face.mNumIndices, face.mIndices); + LLVertexBuffer::drawElements(LLRender::TRIANGLES, face.mPositions, NULL, face.mNumIndices, face.mIndices); } if (!volume->isUnique()) { F32 t = 1.f; - if (!face.mOctree) + if (!face.getOctree()) { ((LLVolumeFace*) &face)->createOctree(); } LLRenderOctreeRaycast render(start, dir, &t); - render.traverse(face.mOctree); + render.traverse(face.getOctree()); } gGL.popMatrix(); @@ -3739,7 +3724,7 @@ class LLOctreeStateCheck : public OctreeTraveler void LLSpatialPartition::renderPhysicsShapes() { LLSpatialBridge* bridge = asBridge(); - LLCamera* camera = LLViewerCamera::getInstanceFast(); + LLCamera* camera = LLViewerCamera::getInstance(); if (bridge) { @@ -3779,15 +3764,12 @@ void LLSpatialPartition::renderDebug() return; } - if (LLGLSLShader::sNoFixedFunction) - { - gDebugProgram.bind(); - } + gDebugProgram.bind(); if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY)) { //sLastMaxTexPriority = lerp(sLastMaxTexPriority, sCurMaxTexPriority, gFrameIntervalSeconds); - sLastMaxTexPriority = (F32) LLViewerCamera::getInstanceFast()->getScreenPixelArea(); + sLastMaxTexPriority = (F32) LLViewerCamera::getInstance()->getScreenPixelArea(); sCurMaxTexPriority = 0.f; } @@ -3798,7 +3780,7 @@ void LLSpatialPartition::renderDebug() gPipeline.disableLights(); LLSpatialBridge* bridge = asBridge(); - LLCamera* camera = LLViewerCamera::getInstanceFast(); + LLCamera* camera = LLViewerCamera::getInstance(); if (bridge) { @@ -3831,10 +3813,7 @@ void LLSpatialPartition::renderDebug() glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } } - if (LLGLSLShader::sNoFixedFunction) - { - gDebugProgram.unbind(); - } + gDebugProgram.unbind(); } void LLSpatialGroup::drawObjectBox(LLColor4 col) @@ -3854,7 +3833,7 @@ bool LLSpatialPartition::isHUDPartition() BOOL LLSpatialPartition::isVisible(const LLVector3& v) { - if (!LLViewerCamera::getInstanceFast()->sphereInFrustum(v, 4.0f)) + if (!LLViewerCamera::getInstance()->sphereInFrustum(v, 4.0f)) { return FALSE; } @@ -3863,7 +3842,7 @@ BOOL LLSpatialPartition::isVisible(const LLVector3& v) } LL_ALIGN_PREFIX(16) -class LLOctreeIntersect : public LLOctreeTraveler<LLViewerOctreeEntry> +class LLOctreeIntersect : public LLOctreeTraveler<LLViewerOctreeEntry, LLPointer<LLViewerOctreeEntry>> { public: LL_ALIGN_16(LLVector4a mStart); @@ -4025,8 +4004,7 @@ LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset, LLViewerTexture* texture, LLVertexBuffer* buffer, bool selected, BOOL fullbright, U8 bump, BOOL particle, F32 part_size) -: LLTrace::MemTrackableNonVirtual<LLDrawInfo, 16>("LLDrawInfo"), - mVertexBuffer(buffer), +: mVertexBuffer(buffer), mTexture(texture), mTextureMatrix(NULL), mModelMatrix(NULL), @@ -4056,7 +4034,8 @@ LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset, { mVertexBuffer->validateRange(mStart, mEnd, mCount, mOffset); - mDebugColor = ((U32)ll_rand() << 16) + ll_rand(); + mDebugColor = (rand() << 16) + rand(); + ((U8*)&mDebugColor)[3] = 200; } LLDrawInfo::~LLDrawInfo() @@ -4082,6 +4061,11 @@ void LLDrawInfo::validate() mVertexBuffer->validateRange(mStart, mEnd, mCount, mOffset); } +U64 LLDrawInfo::getSkinHash() +{ + return mSkinInfo ? mSkinInfo->mHash : 0; +} + LLVertexBuffer* LLGeometryManager::createVertexBuffer(U32 type_mask, U32 usage) { return new LLVertexBuffer(type_mask, usage); @@ -4091,6 +4075,7 @@ LLCullResult::LLCullResult() { mVisibleGroupsAllocated = 0; mAlphaGroupsAllocated = 0; + mRiggedAlphaGroupsAllocated = 0; mOcclusionGroupsAllocated = 0; mDrawableGroupsAllocated = 0; mVisibleListAllocated = 0; @@ -4102,6 +4087,9 @@ LLCullResult::LLCullResult() mAlphaGroups.clear(); mAlphaGroups.push_back(NULL); mAlphaGroupsEnd = &mAlphaGroups[0]; + mRiggedAlphaGroups.clear(); + mRiggedAlphaGroups.push_back(NULL); + mRiggedAlphaGroupsEnd = &mRiggedAlphaGroups[0]; mOcclusionGroups.clear(); mOcclusionGroups.push_back(NULL); mOcclusionGroupsEnd = &mOcclusionGroups[0]; @@ -4143,6 +4131,9 @@ void LLCullResult::clear() mAlphaGroupsSize = 0; mAlphaGroupsEnd = &mAlphaGroups[0]; + mRiggedAlphaGroupsSize = 0; + mRiggedAlphaGroupsEnd = &mRiggedAlphaGroups[0]; + mOcclusionGroupsSize = 0; mOcclusionGroupsEnd = &mOcclusionGroups[0]; @@ -4187,6 +4178,16 @@ LLCullResult::sg_iterator LLCullResult::endAlphaGroups() return mAlphaGroupsEnd; } +LLCullResult::sg_iterator LLCullResult::beginRiggedAlphaGroups() +{ + return &mRiggedAlphaGroups[0]; +} + +LLCullResult::sg_iterator LLCullResult::endRiggedAlphaGroups() +{ + return mRiggedAlphaGroupsEnd; +} + LLCullResult::sg_iterator LLCullResult::beginOcclusionGroups() { return &mOcclusionGroups[0]; @@ -4265,6 +4266,20 @@ void LLCullResult::pushAlphaGroup(LLSpatialGroup* group) mAlphaGroupsEnd = &mAlphaGroups[mAlphaGroupsSize]; } +void LLCullResult::pushRiggedAlphaGroup(LLSpatialGroup* group) +{ + if (mRiggedAlphaGroupsSize < mRiggedAlphaGroupsAllocated) + { + mRiggedAlphaGroups[mRiggedAlphaGroupsSize] = group; + } + else + { + pushBack(mRiggedAlphaGroups, mRiggedAlphaGroupsAllocated, group); + } + ++mRiggedAlphaGroupsSize; + mRiggedAlphaGroupsEnd = &mRiggedAlphaGroups[mRiggedAlphaGroupsSize]; +} + void LLCullResult::pushOcclusionGroup(LLSpatialGroup* group) { if (mOcclusionGroupsSize < mOcclusionGroupsAllocated) diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index 4b52506fb7abc9e645d71af35ba91bf65c7c0492..5544a99fac45e0eee3ed7aefaad3df8fad5834e0 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -40,7 +40,10 @@ #include "llface.h" #include "llviewercamera.h" #include "llvector4a.h" +#include "llvoavatar.h" + #include <queue> +#include <unordered_map> #define SG_STATE_INHERIT_MASK (OCCLUDED) #define SG_INITIAL_STATE_MASK (DIRTY | GEOM_DIRTY) @@ -49,14 +52,13 @@ class LLViewerOctreePartition; class LLSpatialPartition; class LLSpatialBridge; class LLSpatialGroup; -class LLTextureAtlas; -class LLTextureAtlasSlot; class LLViewerRegion; void pushVerts(LLFace* face, U32 mask); -class LLDrawInfo : public LLRefCount, public LLTrace::MemTrackableNonVirtual<LLDrawInfo, 16> +class LLDrawInfo : public LLRefCount { + LL_ALIGN_NEW; protected: ~LLDrawInfo(); @@ -72,12 +74,19 @@ class LLDrawInfo : public LLRefCount, public LLTrace::MemTrackableNonVirtual<LLD void validate(); + // return mSkinHash->mHash, or 0 if mSkinHash is null + U64 getSkinHash(); + LLVector4a mExtents[2]; LLPointer<LLVertexBuffer> mVertexBuffer; LLPointer<LLViewerTexture> mTexture; std::vector<LLPointer<LLViewerTexture> > mTextureList; + // virtual size of mTexture and mTextureList textures + // used to update the decode priority of textures in this DrawInfo + std::vector<F32> mTextureListVSize; + U32 mDebugColor; const LLMatrix4a* mTextureMatrix; const LLMatrix4a* mModelMatrix; @@ -108,6 +117,8 @@ class LLDrawInfo : public LLRefCount, public LLTrace::MemTrackableNonVirtual<LLD F32 mAlphaMaskCutoff; U8 mDiffuseAlphaMode; bool mSelected; + LLPointer<LLVOAvatar> mAvatar = nullptr; + LLMeshSkinInfo* mSkinInfo = nullptr; struct CompareTexture @@ -193,22 +204,22 @@ class LLSpatialGroup final : public LLOcclusionCullingGroup void* operator new(std::size_t size) { - return aligned_new<64>(size); + return ll_aligned_malloc<64>(size); } void operator delete(void* ptr, std::size_t size) { - aligned_delete<64>(ptr, size); + ll_aligned_free<64>(ptr); } void* operator new[](std::size_t size) { - return aligned_new<64>(size); + return ll_aligned_malloc<64>(size); } void operator delete[](void* ptr, std::size_t size) { - aligned_delete<64>(ptr, size); + ll_aligned_free<64>(ptr); } static U32 sNodeCount; @@ -217,10 +228,10 @@ class LLSpatialGroup final : public LLOcclusionCullingGroup typedef std::vector<LLPointer<LLSpatialGroup> > sg_vector_t; typedef std::vector<LLPointer<LLSpatialBridge> > bridge_list_t; typedef std::vector<LLPointer<LLDrawInfo> > drawmap_elem_t; - typedef std::map<U32, drawmap_elem_t > draw_map_t; + typedef std::unordered_map<U32, drawmap_elem_t > draw_map_t; typedef std::vector<LLPointer<LLVertexBuffer> > buffer_list_t; - typedef std::map<LLFace*, buffer_list_t> buffer_texture_map_t; - typedef std::map<U32, buffer_texture_map_t> buffer_map_t; + typedef std::unordered_map<LLFace*, buffer_list_t> buffer_texture_map_t; + typedef std::unordered_map<U32, buffer_texture_map_t> buffer_map_t; struct CompareDistanceGreater { @@ -246,6 +257,19 @@ class LLSpatialGroup final : public LLOcclusionCullingGroup } }; + struct CompareRenderOrder + { + bool operator()(const LLSpatialGroup* const& lhs, const LLSpatialGroup* const& rhs) + { + if (lhs->mAvatarp != rhs->mAvatarp) + { + return lhs->mAvatarp < rhs->mAvatarp; + } + + return lhs->mRenderOrder > rhs->mRenderOrder; + } + }; + typedef enum { GEOM_DIRTY = LLViewerOctreeGroup::INVALID_STATE, @@ -299,49 +323,15 @@ class LLSpatialGroup final : public LLOcclusionCullingGroup virtual void handleDestruction(const TreeNode* node); virtual void handleChildAddition(const OctreeNode* parent, OctreeNode* child); -//------------------- -//for atlas use -//------------------- - //atlas - void setCurUpdatingTime(U32 t) {mCurUpdatingTime = t ;} - U32 getCurUpdatingTime() const { return mCurUpdatingTime ;} - - void setCurUpdatingSlot(LLTextureAtlasSlot* slotp) ; - LLTextureAtlasSlot* getCurUpdatingSlot(LLViewerTexture* imagep, S8 recursive_level = 3) ; - - void setCurUpdatingTexture(LLViewerTexture* tex){ mCurUpdatingTexture = tex ;} - LLViewerTexture* getCurUpdatingTexture() const { return mCurUpdatingTexture ;} - - BOOL hasAtlas(LLTextureAtlas* atlasp) ; - LLTextureAtlas* getAtlas(S8 ncomponents, S8 to_be_reserved, S8 recursive_level = 3) ; - void addAtlas(LLTextureAtlas* atlasp, S8 recursive_level = 3) ; - void removeAtlas(LLTextureAtlas* atlasp, BOOL remove_group = TRUE, S8 recursive_level = 3) ; - void clearAtlasList() ; - public: - LL_ALIGN_16(LLVector4a mViewAngle); LL_ALIGN_16(LLVector4a mLastUpdateViewAngle); F32 mObjectBoxSize; //cached mObjectBounds[1].getLength3() - -private: - U32 mCurUpdatingTime ; - //do not make the below two to use LLPointer - //because mCurUpdatingTime invalidates them automatically. - LLTextureAtlasSlot* mCurUpdatingSlotp ; - LLViewerTexture* mCurUpdatingTexture ; - - std::vector< std::list<LLTextureAtlas*> > mAtlasList ; -//------------------- -//end for atlas use -//------------------- protected: virtual ~LLSpatialGroup(); - static S32 sLODSeed; - public: bridge_list_t mBridgeList; buffer_map_t mBufferMap; //used by volume buffers to attempt to reuse vertex buffers @@ -363,6 +353,10 @@ class LLSpatialGroup final : public LLOcclusionCullingGroup F32 mPixelArea; F32 mRadius; + + //used by LLVOAVatar to set render order in alpha draw pool to preserve legacy render order behavior + LLVOAvatar* mAvatarp = nullptr; + U32 mRenderOrder = 0; } LL_ALIGN_POSTFIX(64); class LLGeometryManager @@ -466,8 +460,11 @@ class LLSpatialBridge : public LLDrawable, public LLSpatialPartition void cleanupReferences() final; LLSpatialPartition* asPartition() final { return this; } + //transform agent space camera into this Spatial Bridge's coordinate frame LLCamera transformCamera(LLCamera& camera); - + + //transform agent space bounding box into this Spatial Bridge's coordinate frame + void transformExtents(const LLVector4a* src, LLVector4a* dst); LLDrawable* mDrawable; }; @@ -494,6 +491,9 @@ class LLCullResult sg_iterator beginAlphaGroups(); sg_iterator endAlphaGroups(); + sg_iterator beginRiggedAlphaGroups(); + sg_iterator endRiggedAlphaGroups(); + bool hasOcclusionGroups() { return mOcclusionGroupsSize > 0; } sg_iterator beginOcclusionGroups(); sg_iterator endOcclusionGroups(); @@ -512,6 +512,7 @@ class LLCullResult void pushVisibleGroup(LLSpatialGroup* group); void pushAlphaGroup(LLSpatialGroup* group); + void pushRiggedAlphaGroup(LLSpatialGroup* group); void pushOcclusionGroup(LLSpatialGroup* group); void pushDrawableGroup(LLSpatialGroup* group); void pushDrawable(LLDrawable* drawable); @@ -520,6 +521,7 @@ class LLCullResult U32 getVisibleGroupsSize() { return mVisibleGroupsSize; } U32 getAlphaGroupsSize() { return mAlphaGroupsSize; } + U32 getRiggedAlphaGroupsSize() { return mRiggedAlphaGroupsSize; } U32 getDrawableGroupsSize() { return mDrawableGroupsSize; } U32 getVisibleListSize() { return mVisibleListSize; } U32 getVisibleBridgeSize() { return mVisibleBridgeSize; } @@ -533,6 +535,7 @@ class LLCullResult U32 mVisibleGroupsSize; U32 mAlphaGroupsSize; + U32 mRiggedAlphaGroupsSize; U32 mOcclusionGroupsSize; U32 mDrawableGroupsSize; U32 mVisibleListSize; @@ -540,6 +543,7 @@ class LLCullResult U32 mVisibleGroupsAllocated; U32 mAlphaGroupsAllocated; + U32 mRiggedAlphaGroupsAllocated; U32 mOcclusionGroupsAllocated; U32 mDrawableGroupsAllocated; U32 mVisibleListAllocated; @@ -551,6 +555,8 @@ class LLCullResult sg_iterator mVisibleGroupsEnd; sg_list_t mAlphaGroups; sg_iterator mAlphaGroupsEnd; + sg_list_t mRiggedAlphaGroups; + sg_iterator mRiggedAlphaGroupsEnd; sg_list_t mOcclusionGroups; sg_iterator mOcclusionGroupsEnd; sg_list_t mDrawableGroups; @@ -647,7 +653,8 @@ class LLVolumeGeometryManager: public LLGeometryManager virtual void rebuildGeom(LLSpatialGroup* group); virtual void rebuildMesh(LLSpatialGroup* group); virtual void getGeometry(LLSpatialGroup* group); - U32 genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort = FALSE, BOOL batch_textures = FALSE, BOOL no_materials = FALSE); + virtual void addGeometryCount(LLSpatialGroup* group, U32& vertex_count, U32& index_count); + U32 genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort = FALSE, BOOL batch_textures = FALSE, BOOL rigged = FALSE); void registerFace(LLSpatialGroup* group, LLFace* facep, U32 type); private: @@ -655,13 +662,13 @@ class LLVolumeGeometryManager: public LLGeometryManager void freeFaces(); static int32_t sInstanceCount; - static LLFace** sFullbrightFaces; - static LLFace** sBumpFaces; - static LLFace** sSimpleFaces; - static LLFace** sNormFaces; - static LLFace** sSpecFaces; - static LLFace** sNormSpecFaces; - static LLFace** sAlphaFaces; + static LLFace** sFullbrightFaces[2]; + static LLFace** sBumpFaces[2]; + static LLFace** sSimpleFaces[2]; + static LLFace** sNormFaces[2]; + static LLFace** sSpecFaces[2]; + static LLFace** sNormSpecFaces[2]; + static LLFace** sAlphaFaces[2]; }; //spatial partition that uses volume geometry manager (implemented in LLVOVolume.cpp) diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp index 8eecdb73d5a55d03d48714930511fee4a43e6120..f78d3dccbe60b4cf156c20a7bf025625a4f5b843 100644 --- a/indra/newview/llspeakers.cpp +++ b/indra/newview/llspeakers.cpp @@ -364,7 +364,7 @@ void LLSpeakerMgr::update(BOOL resort_ok) return; } - auto& voice_client = LLVoiceClient::instanceFast(); + auto& voice_client = LLVoiceClient::instance(); static const LLUIColor speaking_color = LLUIColorTable::instance().getColor("SpeakingColor"); static const LLUIColor overdriven_color = LLUIColorTable::instance().getColor("OverdrivenColor"); @@ -475,7 +475,7 @@ void LLSpeakerMgr::update(BOOL resort_ok) void LLSpeakerMgr::updateSpeakerList() { // Are we bound to the currently active voice channel? - auto& voice_client = LLVoiceClient::instanceFast(); + auto& voice_client = LLVoiceClient::instance(); if ((!mVoiceChannel && voice_client.inProximalChannel()) || (mVoiceChannel && mVoiceChannel->isActive())) { std::set<LLUUID> participants; @@ -498,12 +498,12 @@ void LLSpeakerMgr::updateSpeakerList() // If the list is empty, we update it with whatever we have locally so that it doesn't stay empty too long. // *TODO: Fix the server side code that sometimes forgets to send back the list of participants after a chat started. // (IOW, fix why we get no ChatterBoxSessionAgentListUpdates message after the initial ChatterBoxSessionStartReply) - LLIMModel::LLIMSession* session = LLIMModel::getInstanceFast()->findIMSession(session_id); + LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(session_id); if (session->isGroupSessionType() && (mSpeakers.size() <= 1)) { // For groups, we need to hit the group manager. // Note: The session uuid and the group uuid are actually one and the same. If that was to change, this will fail. - LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstanceFast()->getGroupData(session_id); + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(session_id); if (gdatap && gdatap->isMemberDataComplete() && !gdatap->mMembers.empty()) { @@ -533,7 +533,7 @@ void LLSpeakerMgr::updateSpeakerList() } else if (mSpeakers.empty()) { - // For all other session type (ad-hoc, P2P, avaline), we use the initial participants targets list + // For all other session type (ad-hoc, P2P), we use the initial participants targets list for (uuid_vec_t::iterator it = session->mInitialTargetIDs.begin();it!=session->mInitialTargetIDs.end();++it) { // Add buddies if they are on line, add any other avatar. @@ -649,7 +649,7 @@ void LLSpeakerMgr::speakerChatted(const LLUUID& speaker_id) BOOL LLSpeakerMgr::isVoiceActive() { // mVoiceChannel = NULL means current voice channel, whatever it is - return LLVoiceClient::getInstanceFast()->voiceEnabled() && mVoiceChannel && mVoiceChannel->isActive(); + return LLVoiceClient::getInstance()->voiceEnabled() && mVoiceChannel && mVoiceChannel->isActive(); } @@ -1004,7 +1004,7 @@ void LLLocalSpeakerMgr::updateSpeakerList() // pick up non-voice speakers in chat range uuid_vec_t avatar_ids; std::vector<LLVector3d> positions; - LLWorld::getInstanceFast()->getAvatars(&avatar_ids, &positions, gAgent.getPositionGlobal(), CHAT_NORMAL_RADIUS); + LLWorld::getInstance()->getAvatars(&avatar_ids, &positions, gAgent.getPositionGlobal(), CHAT_NORMAL_RADIUS); for(U32 i=0; i<avatar_ids.size(); i++) { setSpeaker(avatar_ids[i]); diff --git a/indra/newview/llsprite.cpp b/indra/newview/llsprite.cpp index 56e4c49c6cf0cb1fc2a2eac12a3cbd9d3743f501..0cdad86a76db7b06daf6b5aeccf91aa31287366a 100644 --- a/indra/newview/llsprite.cpp +++ b/indra/newview/llsprite.cpp @@ -75,7 +75,7 @@ LLSprite::~LLSprite() void LLSprite::updateFace(LLFace &face) { - LLViewerCamera &camera = *LLViewerCamera::getInstanceFast(); + LLViewerCamera &camera = *LLViewerCamera::getInstance(); // First, figure out how many vertices/indices we need. U32 num_vertices, num_indices; diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index edad0e3e8e87b86e4f55b367641a953ad87d5c5d..6e4106eb036c09cbc444f13e78aa4d2b90373d0b 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -37,6 +37,7 @@ #else # include <sys/stat.h> // mkdir() #endif +#include <memory> // std::unique_ptr #include "llviewermedia_streamingaudio.h" #include "llaudioengine.h" @@ -127,7 +128,6 @@ #include "llpanellogin.h" #include "llmutelist.h" #include "llavatarpropertiesprocessor.h" -#include "llpanelpick.h" #include "llpanelgrouplandmoney.h" #include "llpanelgroupnotices.h" #include "llparcel.h" @@ -185,7 +185,6 @@ #include "pipeline.h" #include "llappviewer.h" #include "llfasttimerview.h" -#include "lltelemetry.h" #include "llfloaterdirectory.h" #include "llfloatermap.h" #include "llweb.h" @@ -200,6 +199,7 @@ #include "llavatariconctrl.h" #include "llvoicechannel.h" #include "llpathfindingmanager.h" +#include "llremoteparcelrequest.h" // [RLVa:KB] - Checked: RLVa-1.2.0 #include "rlvhandler.h" // [/RLVa:KB] @@ -215,6 +215,9 @@ #include "llstacktrace.h" +#include "threadpool.h" + + #if LL_WINDOWS #include "lldxhardware.h" #endif @@ -264,6 +267,7 @@ static bool mLoginStatePastUI = false; static bool mBenefitsSuccessfullyInit = false; const F32 STATE_AGENT_WAIT_TIMEOUT = 240; //seconds +const S32 MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN = 3; // Give region 3 chances std::unique_ptr<LLEventPump> LLStartUp::sStateWatcher(new LLEventStream("StartupState")); std::unique_ptr<LLStartupListener> LLStartUp::sListener(new LLStartupListener()); @@ -324,6 +328,12 @@ void update_texture_fetch() LLAppViewer::getImageDecodeThread()->update(1); // unpauses the image thread LLAppViewer::getTextureFetch()->update(1); // unpauses the texture fetch thread gTextureList.updateImages(0.10f); + + if (LLImageGLThread::sEnabled) + { + std::shared_ptr<LL::WorkQueue> main_queue = LL::WorkQueue::getInstance("mainloop"); + main_queue->runFor(std::chrono::milliseconds(1)); + } } void set_flags_and_update_appearance() @@ -557,8 +567,6 @@ bool idle_startup() } #if LL_WINDOWS - LLPROFILE_STARTUP(); - // On the windows dev builds, unpackaged, the message.xml file will // be located in indra/build-vc**/newview/<config>/app_settings. std::string message_path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"message.xml"); @@ -685,7 +693,7 @@ bool idle_startup() #else void* window_handle = NULL; #endif - bool init = gAudiop->init(kAUDIO_NUM_SOURCES, window_handle, LLAppViewer::instance()->getSecondLifeTitle()); + bool init = gAudiop->init(window_handle, LLAppViewer::instance()->getSecondLifeTitle()); if(init) { gAudiop->setMuted(TRUE); @@ -972,6 +980,12 @@ bool idle_startup() LLPersistentNotificationStorage::initParamSingleton(); LLDoNotDisturbNotificationStorage::initParamSingleton(); } + else + { + // reinitialize paths in case user switched grids or accounts + LLPersistentNotificationStorage::getInstance()->reset(); + LLDoNotDisturbNotificationStorage::getInstance()->reset(); + } // Set PerAccountSettingsFile to the default value. std::string settings_per_account = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, LLAppViewer::instance()->getSettingsFilename("Default", "PerAccount")); @@ -1122,6 +1136,7 @@ bool idle_startup() { // Generic failure message std::ostringstream emsg; + emsg << LLTrans::getString("LoginFailedHeader") << "\n"; if(LLLoginInstance::getInstance()->authFailure()) { LL_INFOS("LLStartup") << "Login failed, LLLoginInstance::getResponse(): " @@ -1134,11 +1149,37 @@ bool idle_startup() std::string message_id = response["message_id"]; std::string message; // actual string to show the user - if(!message_id.empty() && LLTrans::findString(message, message_id, response["message_args"])) - { - // message will be filled in with the template and arguments - } - else if(!message_response.empty()) + bool localized_by_id = false; + if(!message_id.empty()) + { + LLSD message_args = response["message_args"]; + if (message_args.has("TIME") + && (message_id == "LoginFailedAcountSuspended" + || message_id == "LoginFailedAccountMaintenance")) + { + LLDate date; + std::string time_string; + if (date.fromString(message_args["TIME"].asString())) + { + LLSD args; + args["datetime"] = (S32)date.secondsSinceEpoch(); + LLTrans::findString(time_string, "LocalTime", args); + } + else + { + time_string = message_args["TIME"].asString() + " " + LLTrans::getString("PacificTime"); + } + + message_args["TIME"] = time_string; + } + // message will be filled in with the template and arguments + if (LLTrans::findString(message, message_id, message_args)) + { + localized_by_id = true; + } + } + + if(!localized_by_id && !message_response.empty()) { // *HACK: "no_inventory_host" sent as the message itself. // Remove this clause when server is sending message_id as well. @@ -1421,10 +1462,21 @@ bool idle_startup() { LLStartUp::setStartupState( STATE_SEED_CAP_GRANTED ); } + else if (regionp->capabilitiesError()) + { + // Try to connect despite capabilities' error state + LLStartUp::setStartupState(STATE_SEED_CAP_GRANTED); + } else { U32 num_retries = regionp->getNumSeedCapRetries(); - if (num_retries > 0) + if (num_retries > MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN) + { + // Region will keep trying to get capabilities, + // but for now continue as if caps were granted + LLStartUp::setStartupState(STATE_SEED_CAP_GRANTED); + } + else if (num_retries > 0) { LLStringUtil::format_map_t args; args["[NUMBER]"] = llformat("%d", num_retries + 1); @@ -1555,6 +1607,9 @@ bool idle_startup() gAgentCamera.resetCamera(); display_startup(); + // start up the ThreadPool we'll use for textures et al. + LLAppViewer::instance()->initGeneralThread(); + // Initialize global class data needed for surfaces (i.e. textures) LL_DEBUGS("AppInit") << "Initializing sky..." << LL_ENDL; // Initialize all of the viewer object classes for the first time (doing things like texture fetches. @@ -1569,7 +1624,11 @@ bool idle_startup() display_startup(); LL_DEBUGS("AppInit") << "Decoding images..." << LL_ENDL; - // For all images pre-loaded into viewer cache, decode them. + // For all images pre-loaded into viewer cache, init + // priorities and fetching using decodeAllImages. + // Most of the fetching and decoding likely to be done + // by update_texture_fetch() later, while viewer waits. + // // Need to do this AFTER we init the sky const S32 DECODE_TIME_SEC = 2; for (int i = 0; i < DECODE_TIME_SEC; i++) @@ -2431,6 +2490,11 @@ void login_callback(S32 option, void *userdata) void show_release_notes_if_required() { static bool release_notes_shown = false; + // We happen to know that instantiating LLVersionInfo implicitly + // instantiates the LLEventMailDrop named "relnotes", which we (might) use + // below. If viewer release notes stop working, might be because that + // LLEventMailDrop got moved out of LLVersionInfo and hasn't yet been + // instantiated. if (!release_notes_shown && (LLVersionInfo::instance().getChannelAndVersion() != gLastRunVersion) && LLVersionInfo::instance().getViewerMaturity() != LLVersionInfo::TEST_VIEWER // don't show Release Notes for the test builds && gSavedSettings.getBOOL("UpdaterShowReleaseNotes") @@ -2952,7 +3016,7 @@ void reset_login() gAgentWearables.cleanup(); gAgentCamera.cleanup(); gAgent.cleanup(); - LLWorld::getInstance()->destroyClass(); + LLWorld::getInstance()->resetClass(); if ( gViewerWindow ) { // Hide menus and normal buttons @@ -3420,12 +3484,6 @@ bool init_benefits(LLSD& response) succ = false; } - // FIXME PREMIUM - for testing if login does not yet provide Premium Plus. Should be removed thereafter. - //if (succ && !LLAgentBenefitsMgr::has("Premium Plus")) - //{ - // LLAgentBenefitsMgr::init("Premium Plus", packages_sd["Premium"]["benefits"]); - // llassert(LLAgentBenefitsMgr::has("Premium Plus")); - //} return succ; } diff --git a/indra/newview/llstartup.h b/indra/newview/llstartup.h index f6825ad0e83d5839f5e3ef55518c6cc783a85e6d..8b627a4630a54079e3e84675c5617ca6eae857e5 100644 --- a/indra/newview/llstartup.h +++ b/indra/newview/llstartup.h @@ -27,6 +27,7 @@ #ifndef LL_LLSTARTUP_H #define LL_LLSTARTUP_H +#include <memory> // unique_ptr class LLViewerTexture ; class LLEventPump; class LLStartupListener; diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp index 844acf6bac5d47a70214776ef1d6ba84f25bbc0a..e0f335c6f6af679f94dd7a2fce8b34de5156501a 100644 --- a/indra/newview/llstatusbar.cpp +++ b/indra/newview/llstatusbar.cpp @@ -365,7 +365,7 @@ void LLStatusBar::refresh() bool mute_audio = LLAppViewer::instance()->getMasterSystemAudioMute(); mBtnVolume->setToggleState(mute_audio); - LLViewerMedia* media_inst = LLViewerMedia::getInstanceFast(); + LLViewerMedia* media_inst = LLViewerMedia::getInstance(); // Disable media toggle if there's no media, parcel media, and no parcel audio // (or if media is disabled) @@ -572,8 +572,8 @@ void LLStatusBar::onMouseEnterPresetsCamera() mPanelPresetsCameraPulldown->setShape(pulldown_rect); // show the master presets pull-down - LLUI::getInstanceFast()->clearPopups(); - LLUI::getInstanceFast()->addPopup(mPanelPresetsCameraPulldown); + LLUI::getInstance()->clearPopups(); + LLUI::getInstance()->addPopup(mPanelPresetsCameraPulldown); mPanelNearByMedia->setVisible(FALSE); mPanelVolumePulldown->setVisible(FALSE); mPanelPresetsPulldown->setVisible(FALSE); @@ -598,8 +598,8 @@ void LLStatusBar::onMouseEnterPresets() mPanelPresetsPulldown->setShape(pulldown_rect); // show the master presets pull-down - LLUI::getInstanceFast()->clearPopups(); - LLUI::getInstanceFast()->addPopup(mPanelPresetsPulldown); + LLUI::getInstance()->clearPopups(); + LLUI::getInstance()->addPopup(mPanelPresetsPulldown); mPanelPresetsCameraPulldown->setVisible(FALSE); mPanelNearByMedia->setVisible(FALSE); @@ -624,8 +624,8 @@ void LLStatusBar::onMouseEnterQuickSettings() // show the master volume pull-down mPanelQuickSettingsPulldown->setShape(qs_rect); - LLUI::getInstanceFast()->clearPopups(); - LLUI::getInstanceFast()->addPopup(mPanelQuickSettingsPulldown); + LLUI::getInstance()->clearPopups(); + LLUI::getInstance()->addPopup(mPanelQuickSettingsPulldown); mPanelPresetsCameraPulldown->setVisible(FALSE); mPanelPresetsPulldown->setVisible(FALSE); @@ -649,8 +649,8 @@ void LLStatusBar::onMouseEnterAO() qs_rect.translate(mPanelPopupHolder->getRect().getWidth() - qs_rect.mRight, 0); mPanelAOPulldown->setShape(qs_rect); - LLUI::getInstanceFast()->clearPopups(); - LLUI::getInstanceFast()->addPopup(mPanelAOPulldown); + LLUI::getInstance()->clearPopups(); + LLUI::getInstance()->addPopup(mPanelAOPulldown); mPanelPresetsCameraPulldown->setVisible(FALSE); mPanelPresetsPulldown->setVisible(FALSE); @@ -677,8 +677,8 @@ void LLStatusBar::onMouseEnterVolume() // show the master volume pull-down - LLUI::getInstanceFast()->clearPopups(); - LLUI::getInstanceFast()->addPopup(mPanelVolumePulldown); + LLUI::getInstance()->clearPopups(); + LLUI::getInstance()->addPopup(mPanelVolumePulldown); mPanelPresetsCameraPulldown->setVisible(FALSE); mPanelPresetsPulldown->setVisible(FALSE); mPanelNearByMedia->setVisible(FALSE); @@ -702,8 +702,8 @@ void LLStatusBar::onMouseEnterNearbyMedia() // show the master volume pull-down mPanelNearByMedia->setShape(nearby_media_rect); - LLUI::getInstanceFast()->clearPopups(); - LLUI::getInstanceFast()->addPopup(mPanelNearByMedia); + LLUI::getInstance()->clearPopups(); + LLUI::getInstance()->addPopup(mPanelNearByMedia); mPanelPresetsCameraPulldown->setVisible(FALSE); mPanelPresetsPulldown->setVisible(FALSE); @@ -742,7 +742,7 @@ void LLStatusBar::onClickMediaToggle(void* data) LLStatusBar *status_bar = (LLStatusBar*)data; // "Selected" means it was showing the "play" icon (so media was playing), and now it shows "pause", so turn off media bool pause = status_bar->mMediaToggle->getValue(); - LLViewerMedia::getInstanceFast()->setAllMediaPaused(pause); + LLViewerMedia::getInstance()->setAllMediaPaused(pause); } void LLStatusBar::onAOStateChanged() diff --git a/indra/newview/llsurface.cpp b/indra/newview/llsurface.cpp index a306569ca5ea84f2d64f50b409af1169f449550a..edebf92c175e74bcc660d389b6724a7e5bf5ea51 100644 --- a/indra/newview/llsurface.cpp +++ b/indra/newview/llsurface.cpp @@ -173,7 +173,7 @@ void LLSurface::create(const S32 grids_per_edge, mOriginGlobal.setVec(origin_global); - mPVArray.create(mGridsPerEdge, mGridsPerPatchEdge, LLWorld::getInstanceFast()->getRegionScale()); + mPVArray.create(mGridsPerEdge, mGridsPerPatchEdge, LLWorld::getInstance()->getRegionScale()); S32 number_of_grids = mGridsPerEdge * mGridsPerEdge; @@ -1251,7 +1251,7 @@ void LLSurface::setWaterHeight(F32 height) mWaterObjp->setPositionRegion(water_pos_region); if (changed) { - LLWorld::getInstanceFast()->updateWaterObjects(); + LLWorld::getInstance()->updateWaterObjects(); } } else @@ -1277,6 +1277,7 @@ F32 LLSurface::getWaterHeight() const BOOL LLSurface::generateWaterTexture(const F32 x, const F32 y, const F32 width, const F32 height) { + LL_PROFILE_ZONE_SCOPED if (!getWaterTexture()) { return FALSE; diff --git a/indra/newview/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp index 3e78656a7ad0c19563d04ab0631bd2a180db8ce9..81a41b08fc1061ac6e0f7d1584f2e799912e8565 100644 --- a/indra/newview/llsurfacepatch.cpp +++ b/indra/newview/llsurfacepatch.cpp @@ -761,6 +761,7 @@ BOOL LLSurfacePatch::updateTexture() void LLSurfacePatch::updateGL() { + LL_PROFILE_ZONE_SCOPED F32 meters_per_grid = getSurface()->getMetersPerGrid(); F32 grids_per_patch_edge = (F32)getSurface()->getGridsPerPatchEdge(); @@ -897,7 +898,7 @@ void LLSurfacePatch::updateVisibility() radius.splat(mRadius); // sphere in frustum on global coordinates - if (LLViewerCamera::getInstanceFast()->AABBInFrustumNoFarClip(center, radius)) + if (LLViewerCamera::getInstance()->AABBInFrustumNoFarClip(center, radius)) { // We now need to calculate the render stride based on patchp's distance // from LLCamera render_stride is governed by a relation something like this... diff --git a/indra/newview/lltelemetry.cpp b/indra/newview/lltelemetry.cpp deleted file mode 100644 index 0c63e2fede5d45b4b56949d9399d812a98c166f4..0000000000000000000000000000000000000000 --- a/indra/newview/lltelemetry.cpp +++ /dev/null @@ -1,145 +0,0 @@ - /** - * @file lltelemetry.cpp - * @brief Wrapper for Rad Game Tools Telemetry - * - * $LicenseInfo:firstyear=2020&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2020, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" - -#include "lltelemetry.h" - -#if LLPROFILE_USE_RAD_TELEMETRY_PROFILER - #if LL_WINDOWS - #include "llwin32headers.h" - - // build-vc120-64\packages\lib\release - // build-vc150-64\packages\lib\release - #ifdef _MSC_VER - #pragma comment(lib,"rad_tm_win64.lib") - #else - #pragma message "NOTE: Rad GameTools Telemetry requested but non-MSVC compiler not yet supported on Windows" - #endif - #endif // LL_WINDOWS - - #if LL_DARWIN - #pragma message "NOTE: Rad Game Tools Telemetry requested but not yet supported on Darwin" - #endif - - #if LL_LINUX - #pragma message "NOTE: Rad Game Tools Telemetry requested but not yet supported on Linux" - #endif - -// -// local consts -// -static const tm_int32 TELEMETRY_BUFFER_SIZE = 8 * 1024 * 1024; - -// -// local globals -// -static char *gTelemetryBufferPtr = NULL; // Telemetry - -static const char *tm_status[ TMERR_INIT_NETWORKING_FAILED + 1 ] = -{ - "Telemetry pass: connected" // TM_OK - , "Telemetry FAIL: disabled via #define NTELEMETRY" // TMERR_DISABLED - , "Telemetry FAIL: invalid paramater" // TMERR_INVALID_PARAM - , "Telemetry FAIL: DLL not found" // TMERR_NULL_API - , "Telemetry FAIL: out of resources" // TMERR_OUT_OF_RESOURCES - , "Telemetry FAIL: tmInitialize() not called" // TMERR_UNINITIALIZED - , "Telemetry FAIL: bad hostname" // TMERR_BAD_HOSTNAME - , "Telemetry FAIL: couldn't connect to server" // TMERR_COULD_NOT_CONNECT - , "Telemetry FAIL: unknown network error" // TMERR_UNKNOWN_NETWORK - , "Telemetry FAIL: tmShutdown() already called" // TMERR_ALREADY_SHUTDOWN - , "Telemetry FAIL: memory buffer too small" // TMERR_ARENA_TOO_SMALL - , "Telemetry FAIL: server handshake error" // TMERR_BAD_HANDSHAKE - , "Telemetry FAIL: unaligned parameters" // TMERR_UNALIGNED - , "Telemetry FAIL: network not initialized" // TMERR_NETWORK_NOT_INITIALIZED -- WSAStartup not called before tmOpen() - , "Telemetry FAIL: bad version" // TMERR_BAD_VERSION - , "Telemetry FAIL: timer too large" // TMERR_BAD_TIMER - , "Telemetry FAIL: tmOpen() already called" // TMERR_ALREADY_OPENED - , "Telemetry FAIL: tmInitialize() already called" // TMERR_ALREADY_INITIALIZED - , "Telemetry FAIL: could't open file" // TMERR_FILE_OPEN_FAILED - , "Telemetry FAIL: tmOpen() failed networking" // TMERR_INIT_NETWORKING_FAILED -}; - -// -// exported functionality -// - -void telemetry_shutdown() -{ - #if LL_WINDOWS - if (gTelemetryBufferPtr) - { - tmClose(0); - tmShutdown(); - - delete[] gTelemetryBufferPtr; - gTelemetryBufferPtr = NULL; - } - #endif -} - -void telemetry_startup() -{ - #if LL_WINDOWS - tmLoadLibrary(TM_RELEASE); // Loads .dll - - gTelemetryBufferPtr = new char[ TELEMETRY_BUFFER_SIZE ]; - tmInitialize(TELEMETRY_BUFFER_SIZE, gTelemetryBufferPtr); - - tm_error telemetry_status = tmOpen( - 0, // unused - "SecondLife", // app name - __DATE__ " " __TIME__, // build identifier - "localhost", // server name (or filename) - TMCT_TCP, // connection type (or TMCT_FILE) - 4719, // port - TMOF_INIT_NETWORKING, // open flags - 250 ); // timeout ms - - if (telemetry_status == TMERR_UNKNOWN) - { - LL_ERRS() << "Telemetry FAIL: unknown error" << LL_ENDL; - } - else if (telemetry_status && (telemetry_status <= TMERR_INIT_NETWORKING_FAILED)) - { - LL_INFOS() << tm_status[ telemetry_status ] << LL_ENDL; - free(gTelemetryBufferPtr); - gTelemetryBufferPtr = NULL; - } - #endif // LL_WINDOWS -} - -// Called after we render a frame -void telemetry_update() -{ - #if LL_WINDOWS - if (gTelemetryBufferPtr) - { - tmTick(0); - } - #endif -} -#endif // LLPROFILE_USE_RAD_TELEMETRY_PROFILER diff --git a/indra/newview/lltelemetry.h b/indra/newview/lltelemetry.h deleted file mode 100644 index a73e5fcfa27aef28cdd4ad71f6a273885bbba7b1..0000000000000000000000000000000000000000 --- a/indra/newview/lltelemetry.h +++ /dev/null @@ -1,81 +0,0 @@ -/** - * @file lltelemetry.h - * @brief Wrapper for Rad Game Tools Telemetry - * - * $LicenseInfo:firstyear=2020&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2020, 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$ - */ - -/* -To use: - -1. Uncomment #define LLPROFILE_USE_RAD_TELEMETRY_PROFILER below - -2. Include this header file - #include "lltelemetry.h" - -3. Add zones to the functions you wish to profile - void onFoo() - { - LLPROFILE_ZONE("Foo"); - } -*/ -//#define LLPROFILE_USE_RAD_TELEMETRY_PROFILER 1 - -// Default NO local telemetry profiling -#ifndef LLPROFILE_USE_RAD_TELEMETRY_PROFILER - #define LLPROFILE_USE_RAD_TELEMETRY_PROFILER 0 - #define LLPROFILE_SHUTDOWN( ...) {} - #define LLPROFILE_STARTUP( ...) {} - #define LLPROFILE_UPDATE( ...) {} - - #define LLPROFILE_AUTO_CPU_MARKER_COLOR(r, g, b) - #define LLPROFILE_ENTER(name) - #define LLPROFILE_ENTER_FORMAT(format, ...) - #define LLPROFILE_FUNCTION - #define LLPROFILE_LEAVE() - #define LLPROFILE_THREAD_NAME(name) - #define LLPROFILE_ZONE(name) - #define LLPROFILE_ZONE_FORMAT(format, ...) -#else - #include <rad_tm.h> - - #define LLPROFILE_SHUTDOWN telemetry_shutdown - #define LLPROFILE_STARTUP telemetry_startup - #define LLPROFILE_UPDATE telemetry_update - - #define LLPROFILE_AUTO_CPU_MARKER_COLOR(r, g, b) tmZoneColor(r, g, b) - #define LLPROFILE_ENTER(name) tmEnter(0, 0, name) - #define LLPROFILE_ENTER_FORMAT(format, ...) tmEnter(0, 0, format, __VA_ARGS__) - #define LLPROFILE_FUNCTION tmFunction(0, 0) - #define LLPROFILE_LEAVE() tmLeave(0) - #define LLPROFILE_THREAD_NAME(name) tmThreadName(0, 0, name) - #define LLPROFILE_ZONE(name) tmZone(0, 0, name) - #define LLPROFILE_ZONE_FORMAT(format, ...) tmZone(0, 0, format, __VA_ARGS__) -#endif // LLPROFILE_USE_RAD_TELEMETRY_PROFILER - -// -// exported functionality -// - -extern void telemetry_startup(); -extern void telemetry_shutdown(); -extern void telemetry_update(); // called after every frame update diff --git a/indra/newview/llteleporthistory.cpp b/indra/newview/llteleporthistory.cpp index e6931f26a627aad8a6222e84eeb5768bbfd05269..20a1656b5f55e2c0cae09fe3eae6627666252aa3 100644 --- a/indra/newview/llteleporthistory.cpp +++ b/indra/newview/llteleporthistory.cpp @@ -39,6 +39,11 @@ #include "llviewerregion.h" #include "llworldmap.h" #include "llagentui.h" +#include "llwindow.h" +#include "llviewerwindow.h" +#include "llavatarname.h" +#include "llavatarnamecache.h" + #include "llviewernetwork.h" #include "llworldmapmessage.h" // [RLVa:KB] - Checked: 2010-09-03 (RLVa-1.2.1b) @@ -160,6 +165,20 @@ void LLTeleportHistory::handleLoginComplete() updateCurrentLocation(gAgent.getPositionGlobal()); } +static void on_avatar_name_update_title(const LLAvatarName& av_name) +{ + if (gAgent.getRegion() && gViewerWindow && gViewerWindow->getWindow()) + { + std::string region = gAgent.getRegion()->getName(); + std::string username = av_name.getUserName(); + + // this first pass simply displays username and region name + // but could easily be extended to include other details like + // X/Y/Z location within a region etc. + std::string new_title = STRINGIZE(username << " @ " << region); + gViewerWindow->getWindow()->setTitle(new_title); + } +} void LLTeleportHistory::updateCurrentLocation(const LLVector3d& new_pos) { @@ -245,6 +264,14 @@ void LLTeleportHistory::updateCurrentLocation(const LLVector3d& new_pos) if (!mGotInitialUpdate) mGotInitialUpdate = true; + // update Viewer window title with username and region name + // if we are in "non-interactive mode" (SL-15999) or the debug + // setting to allow it is enabled (may be useful in other situations) + if (gNonInteractive || gSavedSettings.getBOOL("UpdateAppWindowTitleBar")) + { + LLAvatarNameCache::get(gAgent.getID(), boost::bind(&on_avatar_name_update_title, _2)); + } + // Signal the interesting party that we've changed. onHistoryChanged(); } diff --git a/indra/newview/lltextureatlas.cpp b/indra/newview/lltextureatlas.cpp deleted file mode 100644 index 1c8e4f796e0548226e420ebdf02b50542c781d43..0000000000000000000000000000000000000000 --- a/indra/newview/lltextureatlas.cpp +++ /dev/null @@ -1,416 +0,0 @@ -/** - * @file lltextureatlas.cpp - * @brief LLTextureAtlas class implementation. - * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ -#include "llviewerprecompiledheaders.h" -#include "linden_common.h" -#include "llerror.h" -#include "llimage.h" -#include "llmath.h" -#include "llgl.h" -#include "llrender.h" -#include "lltextureatlas.h" - -//------------------- -S16 LLTextureAtlas::sMaxSubTextureSize = 64 ; -S16 LLTextureAtlas::sSlotSize = 32 ; - -#ifndef DEBUG_ATLAS -#define DEBUG_ATLAS 0 -#endif - -#ifndef DEBUG_USAGE_BITS -#define DEBUG_USAGE_BITS 0 -#endif -//************************************************************************************************************** -LLTextureAtlas::LLTextureAtlas(U8 ncomponents, S16 atlas_dim) : - LLViewerTexture(atlas_dim * sSlotSize, atlas_dim * sSlotSize, ncomponents, TRUE), - mAtlasDim(atlas_dim), - mNumSlotsReserved(0), - mMaxSlotsInAtlas(atlas_dim * atlas_dim) -{ - generateEmptyUsageBits() ; - - //generate an empty texture - generateGLTexture() ; - LLPointer<LLImageRaw> image_raw = new LLImageRaw(mFullWidth, mFullHeight, mComponents); - createGLTexture(0, image_raw, 0); - image_raw = NULL; -} - -LLTextureAtlas::~LLTextureAtlas() -{ - if(mSpatialGroupList.size() > 0) - { - LL_ERRS() << "Not clean up the spatial groups!" << LL_ENDL ; - } - releaseUsageBits() ; -} - -//virtual -S8 LLTextureAtlas::getType() const -{ - return 0; //LLViewerTexture::ATLAS_TEXTURE ; -} - -void LLTextureAtlas::getTexCoordOffset(S16 col, S16 row, F32& xoffset, F32& yoffset) -{ - xoffset = (F32)col / mAtlasDim ; - yoffset = (F32)row / mAtlasDim ; -} - -void LLTextureAtlas::getTexCoordScale(S32 w, S32 h, F32& xscale, F32& yscale) -{ - xscale = (F32)w / (mAtlasDim * sSlotSize) ; - yscale = (F32)h / (mAtlasDim * sSlotSize) ; -} - -//insert a texture piece into the atlas -LLGLuint LLTextureAtlas::insertSubTexture(LLImageGL* source_gl_tex, S32 discard_level, const LLImageRaw* raw_image, S16 slot_col, S16 slot_row) -{ - if(!getTexName()) - { - return 0 ; - } - - S32 w = raw_image->getWidth() ; - S32 h = raw_image->getHeight() ; - if(w < 8 || w > sMaxSubTextureSize || h < 8 || h > sMaxSubTextureSize) - { - //size overflow - return 0 ; - } - - BOOL res = gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, getTexName()); - if (!res) - { - LL_ERRS() << "bindTexture failed" << LL_ENDL; - } - - GLint xoffset = sSlotSize * slot_col ; - GLint yoffset = sSlotSize * slot_row ; - - if(!source_gl_tex->preAddToAtlas(discard_level, raw_image)) - { - return 0 ; - } - - glTexSubImage2D(GL_TEXTURE_2D, 0, xoffset, yoffset, w, h, - mGLTexturep->getPrimaryFormat(), mGLTexturep->getFormatType(), raw_image->getData()); - - source_gl_tex->postAddToAtlas() ; - return getTexName(); -} - -//release a sub-texture slot from the atlas -void LLTextureAtlas::releaseSlot(S16 slot_col, S16 slot_row, S8 slot_width) -{ - unmarkUsageBits(slot_width, slot_col, slot_row) ; - mNumSlotsReserved -= slot_width * slot_width ; -} - -BOOL LLTextureAtlas::isEmpty() const -{ - return !mNumSlotsReserved ; -} - -BOOL LLTextureAtlas::isFull(S8 to_be_reserved) const -{ - return mNumSlotsReserved + to_be_reserved > mMaxSlotsInAtlas ; -} -F32 LLTextureAtlas::getFullness() const -{ - return (F32)mNumSlotsReserved / mMaxSlotsInAtlas ; -} - -void LLTextureAtlas::addSpatialGroup(LLSpatialGroup* groupp) -{ - if(groupp && !hasSpatialGroup(groupp)) - { - mSpatialGroupList.push_back(groupp); - } -} - -void LLTextureAtlas::removeSpatialGroup(LLSpatialGroup* groupp) -{ - if(groupp) - { - mSpatialGroupList.remove(groupp); - } -} - -void LLTextureAtlas::clearSpatialGroup() -{ - mSpatialGroupList.clear(); -} -void LLTextureAtlas::removeLastSpatialGroup() -{ - mSpatialGroupList.pop_back() ; -} - -LLSpatialGroup* LLTextureAtlas::getLastSpatialGroup() -{ - if(mSpatialGroupList.size() > 0) - { - return mSpatialGroupList.back() ; - } - return NULL ; -} - -BOOL LLTextureAtlas::hasSpatialGroup(LLSpatialGroup* groupp) -{ - for(std::list<LLSpatialGroup*>::iterator iter = mSpatialGroupList.begin(); iter != mSpatialGroupList.end() ; ++iter) - { - if(*iter == groupp) - { - return TRUE ; - } - } - return FALSE ; -} - -//-------------------------------------------------------------------------------------- -//private -void LLTextureAtlas::generateEmptyUsageBits() -{ - S32 col_len = (mAtlasDim + 7) >> 3 ; - mUsageBits = new U8*[mAtlasDim] ; - *mUsageBits = new U8[mAtlasDim * col_len] ; - - mUsageBits[0] = *mUsageBits ; - for(S32 i = 1 ; i < mAtlasDim ; i++) - { - mUsageBits[i] = mUsageBits[i-1] + col_len ; - - for(S32 j = 0 ; j < col_len ; j++) - { - //init by 0 for all bits. - mUsageBits[i][j] = 0 ; - } - } - - //do not forget mUsageBits[0]! - for(S32 j = 0 ; j < col_len ; j++) - { - //init by 0 for all bits. - mUsageBits[0][j] = 0 ; - } - - mTestBits = NULL ; -#if DEBUG_USAGE_BITS - //------------ - //test - mTestBits = new U8*[mAtlasDim] ; - *mTestBits = new U8[mAtlasDim * mAtlasDim] ; - mTestBits[0] = *mTestBits ; - for(S32 i = 1 ; i < mAtlasDim ; i++) - { - mTestBits[i] = mTestBits[i-1] + mAtlasDim ; - - for(S32 j = 0 ; j < mAtlasDim ; j++) - { - //init by 0 for all bits. - mTestBits[i][j] = 0 ; - } - } - - for(S32 j = 0 ; j < mAtlasDim ; j++) - { - //init by 0 for all bits. - mTestBits[0][j] = 0 ; - } -#endif -} - -void LLTextureAtlas::releaseUsageBits() -{ - if(mUsageBits) - { - delete[] *mUsageBits ; - delete[] mUsageBits ; - } - mUsageBits = NULL ; - - //test - if( mTestBits) - { - delete[] *mTestBits; - delete[] mTestBits; - } - mTestBits = NULL ; -} - -void LLTextureAtlas::markUsageBits(S8 bits_len, U8 mask, S16 col, S16 row) -{ - S16 x = col >> 3 ; - - for(S8 i = 0 ; i < bits_len ; i++) - { - mUsageBits[row + i][x] |= mask ; - } - -#if DEBUG_USAGE_BITS - //test - for(S8 i = row ; i < row + bits_len ; i++) - { - for(S8 j = col ; j < col + bits_len ; j++) - { - mTestBits[i][j] = 1 ; - } - } -#endif -} - -void LLTextureAtlas::unmarkUsageBits(S8 bits_len, S16 col, S16 row) -{ - S16 x = col >> 3 ; - U8 mask = 1 ; - for(S8 i = 1 ; i < bits_len ; i++) - { - mask |= (1 << i) ; - } - mask <<= (col & 7) ; - mask = ~mask ; - - for(S8 i = 0 ; i < bits_len ; i++) - { - mUsageBits[row + i][x] &= mask ; - } - -#if DEBUG_USAGE_BITS - //test - for(S8 i = row ; i < row + bits_len ; i++) - { - for(S8 j = col ; j < col + bits_len ; j++) - { - mTestBits[i][j] = 0 ; - } - } -#endif -} - -//return true if any of bits in the range marked. -BOOL LLTextureAtlas::areUsageBitsMarked(S8 bits_len, U8 mask, S16 col, S16 row) -{ - BOOL ret = FALSE ; - S16 x = col >> 3 ; - - for(S8 i = 0 ; i < bits_len ; i++) - { - if(mUsageBits[row + i][x] & mask) - { - ret = TRUE ; - break ; - //return TRUE ; - } - } - -#if DEBUG_USAGE_BITS - //test - BOOL ret2 = FALSE ; - for(S8 i = row ; i < row + bits_len ; i++) - { - for(S8 j = col ; j < col + bits_len ; j++) - { - if(mTestBits[i][j]) - { - ret2 = TRUE ; - } - } - } - - if(ret != ret2) - { - LL_ERRS() << "bits map corrupted." << LL_ENDL ; - } -#endif - return ret ;//FALSE ; -} - -//---------------------------------------------------------------------- -// -//index order: Z order, i.e.: -// |-----|-----|-----|-----| -// | 10 | 11 | 14 | 15 | -// |-----|-----|-----|-----| -// | 8 | 9 | 12 | 13 | -// |-----|-----|-----|-----| -// | 2 | 3 | 6 | 7 | -// |-----|-----|-----|-----| -// | 0 | 1 | 4 | 5 | -// |-----|-----|-----|-----| -void LLTextureAtlas::getPositionFromIndex(S16 index, S16& col, S16& row) -{ - col = 0 ; - row = 0 ; - - S16 index_copy = index ; - for(S16 i = 0 ; index_copy && i < 16 ; i += 2) - { - col |= ((index & (1 << i)) >> i) << (i >> 1) ; - row |= ((index & (1 << (i + 1))) >> (i + 1)) << (i >> 1) ; - index_copy >>= 2 ; - } -} -void LLTextureAtlas::getIndexFromPosition(S16 col, S16 row, S16& index) -{ - index = 0 ; - S16 col_copy = col ; - S16 row_copy = row ; - for(S16 i = 0 ; (col_copy || row_copy) && i < 16 ; i++) - { - index |= ((col & 1 << i) << i) | ((row & 1 << i) << ( i + 1)) ; - col_copy >>= 1 ; - row_copy >>= 1 ; - } -} -//---------------------------------------------------------------------- -//return TRUE if succeeds. -BOOL LLTextureAtlas::getNextAvailableSlot(S8 bits_len, S16& col, S16& row) -{ - S16 index_step = bits_len * bits_len ; - - U8 mask = 1 ; - for(S8 i = 1 ; i < bits_len ; i++) - { - mask |= (1 << i) ; - } - - U8 cur_mask ; - for(S16 index = 0 ; index < mMaxSlotsInAtlas ; index += index_step) - { - getPositionFromIndex(index, col, row) ; - - cur_mask = mask << (col & 7) ; - if(!areUsageBitsMarked(bits_len, cur_mask, col, row)) - { - markUsageBits(bits_len, cur_mask, col, row) ; - mNumSlotsReserved += bits_len * bits_len ; - - return TRUE ; - } - } - - return FALSE ; -} diff --git a/indra/newview/lltextureatlas.h b/indra/newview/lltextureatlas.h deleted file mode 100644 index 6b36eb7fe410742679ee6012b7ded1f3c6a1bad0..0000000000000000000000000000000000000000 --- a/indra/newview/lltextureatlas.h +++ /dev/null @@ -1,90 +0,0 @@ -/** - * @file lltextureatlas.h - * @brief LLTextureAtlas base class. - * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - - -#ifndef LL_TEXTUREATLAS_H -#define LL_TEXTUREATLAS_H - -#include "llviewertexture.h" -class LLSpatialGroup ; - -class LLTextureAtlas : public LLViewerTexture -{ -protected: - /*virtual*/ ~LLTextureAtlas() ; - -public: - LLTextureAtlas(U8 ncomponents, S16 atlas_dim = 16) ; - - /*virtual*/ S8 getType() const; - - LLGLuint insertSubTexture(LLImageGL* source_gl_tex, S32 discard_level, const LLImageRaw* raw_image, S16 slot_col, S16 slot_row) ; - void releaseSlot(S16 slot_col, S16 slot_row, S8 slot_width); - - BOOL getNextAvailableSlot(S8 bits_len, S16& col, S16& row) ; - void getTexCoordOffset(S16 col, S16 row, F32& xoffset, F32& yOffset) ; - void getTexCoordScale(S32 w, S32 h, F32& xscale, F32& yscale) ; - - BOOL isEmpty() const ; - BOOL isFull(S8 to_be_reserved = 1) const ; - F32 getFullness() const ; - - void addSpatialGroup(LLSpatialGroup* groupp) ; - void removeSpatialGroup(LLSpatialGroup* groupp) ; - LLSpatialGroup* getLastSpatialGroup() ; - void removeLastSpatialGroup() ; - BOOL hasSpatialGroup(LLSpatialGroup* groupp) ; - void clearSpatialGroup() ; - std::list<LLSpatialGroup*>* getSpatialGroupList() {return &mSpatialGroupList;} -private: - void generateEmptyUsageBits() ; - void releaseUsageBits() ; - - void markUsageBits(S8 bits_len, U8 mask, S16 col, S16 row) ; - void unmarkUsageBits(S8 bits_len, S16 col, S16 row) ; - - void getPositionFromIndex(S16 index, S16& col, S16& row) ; - void getIndexFromPosition(S16 col, S16 row, S16& index) ; - BOOL areUsageBitsMarked(S8 bits_len, U8 mask, S16 col, S16 row) ; - -private: - S16 mAtlasDim ; //number of slots per edge, i.e, there are "mAtlasDim * mAtlasDim" total slots in the atlas. - S16 mNumSlotsReserved ; - S16 mMaxSlotsInAtlas ; - U8 **mUsageBits ; - std::list<LLSpatialGroup*> mSpatialGroupList ; - -public: - //debug use only - U8 **mTestBits ; - -public: - static S16 sMaxSubTextureSize ; - static S16 sSlotSize ; -}; - -#endif - diff --git a/indra/newview/lltextureatlasmanager.cpp b/indra/newview/lltextureatlasmanager.cpp deleted file mode 100644 index ca9d6da4db1b17b0b6a8b06738755941acf8f9ca..0000000000000000000000000000000000000000 --- a/indra/newview/lltextureatlasmanager.cpp +++ /dev/null @@ -1,268 +0,0 @@ -/** - * @file lltextureatlasmanager.cpp - * @brief LLTextureAtlasManager class implementation. - * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ -#include "llviewerprecompiledheaders.h" -#include "linden_common.h" -#include "llerror.h" -#include "llmath.h" -#include "lltextureatlas.h" -#include "lltextureatlasmanager.h" -#include "llspatialpartition.h" - -const S8 MAX_NUM_EMPTY_ATLAS = 2 ; -const F32 MIN_ATLAS_FULLNESS = 0.6f ; - -//********************************************************************************************* -//implementation of class LLTextureAtlasInfo -//********************************************************************************************* -LLTextureAtlasSlot::LLTextureAtlasSlot(LLTextureAtlas* atlasp, LLSpatialGroup* groupp, S16 col, S16 row, F32 xoffset, F32 yoffset, S8 slot_width) : - mAtlasp(atlasp), - mGroupp(groupp), - mCol(col), - mRow(row), - mReservedSlotWidth(slot_width), - mValid(FALSE), - mUpdatedTime(0), - mTexCoordOffset(xoffset, yoffset), - mTexCoordScale(1.f, 1.f) -{ - llassert_always(mAtlasp || mGroupp || mReservedSlotWidth) ; -} - -LLTextureAtlasSlot::~LLTextureAtlasSlot() -{ - if(mAtlasp) - { - mAtlasp->releaseSlot(mCol, mRow, mReservedSlotWidth) ; - if(mAtlasp->isEmpty()) - { - LLTextureAtlasManager::getInstance()->releaseAtlas(mAtlasp) ; - } - mAtlasp = NULL ; - } -} - -//void LLTextureAtlasSlot::setAtlas(LLTextureAtlas* atlasp) -//{ -// mAtlasp = atlasp ; -//} -//void LLTextureAtlasSlot::setSlotPos(S16 col, S16 row) -//{ -// mCol = col ; -// mRow = row ; -//} -//void LLTextureAtlasSlot::setSlotWidth(S8 width) -//{ -// //slot is a square with each edge length a power-of-two number -// mReservedSlotWidth = width ; -//} -//void LLTextureAtlasSlot::setTexCoordOffset(F32 xoffset, F32 yoffset) -//{ -// mTexCoordOffset.mV[0] = xoffset ; -// mTexCoordOffset.mV[1] = yoffset ; -//} - -void LLTextureAtlasSlot::setSpatialGroup(LLSpatialGroup* groupp) -{ - mGroupp = groupp ; -} -void LLTextureAtlasSlot::setTexCoordScale(F32 xscale, F32 yscale) -{ - mTexCoordScale.mV[0] = xscale ; - mTexCoordScale.mV[1] = yscale ; -} -//********************************************************************************************* -//END of implementation of class LLTextureAtlasInfo -//********************************************************************************************* - -//********************************************************************************************* -//implementation of class LLTextureAtlasManager -//********************************************************************************************* -LLTextureAtlasManager::LLTextureAtlasManager() : - mAtlasMap(4), - mEmptyAtlasMap(4) -{ -} - -LLTextureAtlasManager::~LLTextureAtlasManager() -{ - for(S32 i = 0 ; i < 4 ; i++) - { - for(ll_texture_atlas_list_t::iterator j = mAtlasMap[i].begin() ; j != mAtlasMap[i].end() ; ++j) - { - *j = NULL ; - } - for(ll_texture_atlas_list_t::iterator j = mEmptyAtlasMap[i].begin() ; j != mEmptyAtlasMap[i].end() ; ++j) - { - *j = NULL ; - } - - mAtlasMap[i].clear() ; - mEmptyAtlasMap[i].clear() ; - } - mAtlasMap.clear() ; - mEmptyAtlasMap.clear() ; -} - -//return TRUE if qualified -BOOL LLTextureAtlasManager::canAddToAtlas(S32 w, S32 h, S8 ncomponents, LLGLenum target) -{ - if(ncomponents < 1 || ncomponents > 4) - { - return FALSE ; - } - //only support GL_TEXTURE_2D - if(GL_TEXTURE_2D != target) - { - return FALSE ; - } - //real image size overflows - if(w < 8 || w > LLTextureAtlas::sMaxSubTextureSize || h < 8 || h > LLTextureAtlas::sMaxSubTextureSize) - { - return FALSE ; - } - - //if non-power-of-two number - if((w & (w - 1)) || (h & (h - 1))) - { - return FALSE ; - } - - return TRUE ; -} - -void LLTextureAtlasManager::releaseAtlas(LLTextureAtlas* atlasp) -{ - LLSpatialGroup* groupp = atlasp->getLastSpatialGroup() ; - while(groupp) - { - groupp->removeAtlas(atlasp, FALSE) ; - atlasp->removeLastSpatialGroup() ; - - groupp = atlasp->getLastSpatialGroup() ; - } - - S8 type = atlasp->getComponents() - 1 ; - //insert to the empty list - if(mEmptyAtlasMap[type].size() < MAX_NUM_EMPTY_ATLAS) - { - mEmptyAtlasMap[type].push_back(atlasp) ; - } - - //delete the atlasp - mAtlasMap[type].remove(atlasp) ; -} - -// -//this function reserves an appropriate slot from atlas pool for an image. -//return non-NULL if succeeds. -//Note: -//1, this function does not check if the image this slot assigned for qualifies for atlas or not, -// call LLTextureAtlasManager::canAddToAtlas(...) to do the check before calling this function. -//2, this function also dose not check if the image is already in atlas. It always assigns a new slot anyway. -//3, this function tries to group sub-textures from same spatial group into ONE atlas to improve render batching. -// -LLPointer<LLTextureAtlasSlot> LLTextureAtlasManager::reserveAtlasSlot(S32 sub_texture_size, S8 ncomponents, - LLSpatialGroup* groupp, LLViewerTexture* imagep) -{ - if(!groupp) - { - //do not insert to atlas if does not have a group. - return NULL ; - } - - //bits_len must <= 8 and is a power of two number, i.e.: must be one of these numbers: 1, 2, 4, 8. - if(sub_texture_size > LLTextureAtlas::sMaxSubTextureSize) - { - sub_texture_size = LLTextureAtlas::sMaxSubTextureSize ; - } - S8 bits_len = sub_texture_size / LLTextureAtlas::sSlotSize ; - if(bits_len < 1) - { - bits_len = 1 ; - } - - S16 col = -1, row = -1; - S8 total_bits = bits_len * bits_len ; - - //insert to the atlas reserved by the same spatial group - LLPointer<LLTextureAtlas> atlasp = groupp->getAtlas(ncomponents, total_bits) ; - if(atlasp.notNull()) - { - if(!atlasp->getNextAvailableSlot(bits_len, col, row)) - { - //failed - atlasp = NULL ; - } - } - - //search an atlas to fit for 'size' - if(!atlasp) - { - S8 atlas_index = ncomponents - 1 ; - ll_texture_atlas_list_t::iterator iter = mAtlasMap[atlas_index].begin() ; - for(; iter != mAtlasMap[atlas_index].end(); ++iter) - { - LLTextureAtlas* cur = (LLTextureAtlas*)*iter ; - if(cur->getFullness() < MIN_ATLAS_FULLNESS)//this atlas is empty enough for this group to insert more sub-textures later if necessary. - { - if(cur->getNextAvailableSlot(bits_len, col, row)) - { - atlasp = cur ; - groupp->addAtlas(atlasp) ; - break ; - } - } - } - } - - //create a new atlas if necessary - if(!atlasp) - { - if(mEmptyAtlasMap[ncomponents - 1].size() > 0) - { - //there is an empty one - atlasp = mEmptyAtlasMap[ncomponents - 1].back() ; - mEmptyAtlasMap[ncomponents - 1].pop_back() ; - } - else - { - atlasp = new LLTextureAtlas(ncomponents, 16) ; - } - mAtlasMap[ncomponents - 1].push_back(atlasp) ; - atlasp->getNextAvailableSlot(bits_len, col, row) ; - groupp->addAtlas(atlasp) ; - } - - F32 xoffset, yoffset ; - atlasp->getTexCoordOffset(col, row, xoffset, yoffset) ; - LLPointer<LLTextureAtlasSlot> slot_infop = new LLTextureAtlasSlot(atlasp, groupp, col, row, xoffset, yoffset, bits_len) ; - - return slot_infop ; -} - -//********************************************************************************************* -//END of implementation of class LLTextureAtlasManager -//********************************************************************************************* diff --git a/indra/newview/lltextureatlasmanager.h b/indra/newview/lltextureatlasmanager.h deleted file mode 100644 index 772216676cd1c4aa33028e0a9b2c8981133f4d30..0000000000000000000000000000000000000000 --- a/indra/newview/lltextureatlasmanager.h +++ /dev/null @@ -1,105 +0,0 @@ -/** - * @file lltextureatlasmanager.h - * @brief LLTextureAtlasManager base class. - * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - - -#ifndef LL_TEXTUREATLASMANAGER_H -#define LL_TEXTUREATLASMANAGER_H - -#include "llmemory.h" - -class LLSpatialGroup ; -class LLViewerTexture ; - -//just use it as a structure. -class LLTextureAtlasSlot : public LLRefCount -{ -public: - LLTextureAtlasSlot(LLTextureAtlas* atlasp, LLSpatialGroup* groupp, S16 col, S16 row, F32 xoffset, F32 yoffset, S8 slot_width) ; - -protected: - virtual ~LLTextureAtlasSlot(); - -public: - - // - //do not allow to change those values - // - //void setAtlas(LLTextureAtlas* atlasp) ; - //void setSlotPos(S16 col, S16 row) ; - //void setSlotWidth(S8 width) ; - //void setTexCoordOffset(F32 xoffser, F32 yoffset) ; - // - - void setSpatialGroup(LLSpatialGroup* groupp) ; - void setTexCoordScale(F32 xscale, F32 yscale) ; - void setValid() {mValid = TRUE ;} - - LLTextureAtlas* getAtlas()const {return mAtlasp;} - LLSpatialGroup* getSpatialGroup() const {return mGroupp ;} - S16 getSlotCol()const {return mCol;} - S16 getSlotRow()const {return mRow;} - S8 getSlotWidth()const{return mReservedSlotWidth;} - BOOL isValid()const { return mValid;} - const LLVector2* getTexCoordOffset()const {return &mTexCoordOffset;} - const LLVector2* getTexCoordScale() const {return &mTexCoordScale;} - - void setUpdatedTime(U32 t) {mUpdatedTime = t;} - U32 getUpdatedTime()const {return mUpdatedTime;} - -private: - LLTextureAtlas* mAtlasp; - S16 mCol ;//col of the slot - S16 mRow ;//row of the slot - S8 mReservedSlotWidth ; //slot is a square with each edge length a power-of-two number - LLSpatialGroup* mGroupp ; - BOOL mValid ; - - LLVector2 mTexCoordOffset ; - LLVector2 mTexCoordScale ; - - U32 mUpdatedTime ; -} ; - -class LLTextureAtlasManager final : public LLSingleton<LLTextureAtlasManager> -{ - LLSINGLETON(LLTextureAtlasManager); - ~LLTextureAtlasManager(); - typedef std::list<LLPointer<LLTextureAtlas> > ll_texture_atlas_list_t ; - -public: - - LLPointer<LLTextureAtlasSlot> reserveAtlasSlot(S32 sub_texture_size, S8 ncomponents, - LLSpatialGroup* groupp, LLViewerTexture* imagep) ; - void releaseAtlas(LLTextureAtlas* atlasp); - - BOOL canAddToAtlas(S32 w, S32 h, S8 ncomponents, LLGLenum target) ; - -private: - std::vector<ll_texture_atlas_list_t> mAtlasMap ; - std::vector<ll_texture_atlas_list_t> mEmptyAtlasMap ; //delay some empty atlases deletion to avoid possible creation of new atlas immediately. -}; - -#endif diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index 1c90d01b5dc785bd2d721f2e6714be339e89de57..567d1f0bc85ecd05ca8096d88f4b5190470b9191 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -1048,7 +1048,8 @@ void LLTextureCache::setReadOnly(BOOL read_only) mReadOnly = read_only ; } -//called in the main thread. +// Called in the main thread. +// Returns the unused amount of max_size if any S64 LLTextureCache::initCache(ELLPath location, S64 max_size, BOOL texture_cache_mismatch) { llassert_always(getPending() == 0) ; //should not start accessing the texture cache before initialized. diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 6638ee0faed8990535d88b71179cb3ee8d91b6b3..6f9f4012bcf52e0414282a915ea4024ac38e4ded 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -81,6 +81,67 @@ static const S32 LOCAL_TRACKING_ID_COLUMN = 1; //static const char WHITE_IMAGE_NAME[] = "Blank Texture"; //static const char NO_IMAGE_NAME[] = "None"; + + +//static +bool get_is_predefined_texture(LLUUID asset_id) +{ + if (asset_id == LLUUID(gSavedSettings.getString("DefaultObjectTexture")) + || asset_id == LLUUID(gSavedSettings.getString("UIImgWhiteUUID")) + || asset_id == LLUUID(gSavedSettings.getString("UIImgInvisibleUUID")) + || asset_id == LLUUID(SCULPT_DEFAULT_TEXTURE)) + { + return true; + } + return false; +} + +LLUUID get_copy_free_item_by_asset_id(LLUUID asset_id, bool no_trans_perm) +{ + LLViewerInventoryCategory::cat_array_t cats; + LLViewerInventoryItem::item_array_t items; + LLAssetIDMatches asset_id_matches(asset_id); + gInventory.collectDescendentsIf(LLUUID::null, + cats, + items, + LLInventoryModel::INCLUDE_TRASH, + asset_id_matches); + + LLUUID res; + if (items.size()) + { + for (S32 i = 0; i < items.size(); i++) + { + LLViewerInventoryItem* itemp = items[i]; + if (itemp) + { + LLPermissions item_permissions = itemp->getPermissions(); + if (item_permissions.allowOperationBy(PERM_COPY, + gAgent.getID(), + gAgent.getGroupID())) + { + bool allow_trans = item_permissions.allowOperationBy(PERM_TRANSFER, gAgent.getID(), gAgent.getGroupID()); + if (allow_trans != no_trans_perm) + { + return itemp->getUUID(); + } + res = itemp->getUUID(); + } + } + } + } + return res; +} + +bool get_can_copy_texture(LLUUID asset_id) +{ + // User is allowed to copy a texture if: + // library asset or default texture, + // or copy perm asset exists in user's inventory + + return get_is_predefined_texture(asset_id) || get_copy_free_item_by_asset_id(asset_id).notNull(); +} + LLFloaterTexturePicker::LLFloaterTexturePicker( LLView* owner, LLUUID image_asset_id, @@ -205,9 +266,9 @@ void LLFloaterTexturePicker::setCanApplyImmediately(BOOL b) void LLFloaterTexturePicker::stopUsingPipette() { - if (LLToolMgr::getInstanceFast()->getCurrentTool() == LLToolPipette::getInstanceFast()) + if (LLToolMgr::getInstance()->getCurrentTool() == LLToolPipette::getInstance()) { - LLToolMgr::getInstanceFast()->clearTransientTool(); + LLToolMgr::getInstance()->clearTransientTool(); } } @@ -434,7 +495,7 @@ BOOL LLFloaterTexturePicker::postBuild() updateFilterPermMask(); mSavedFolderState.setApply(FALSE); - LLToolPipette::getInstanceFast()->setToolSelectCallback(boost::bind(&LLFloaterTexturePicker::onTextureSelect, this, _1)); + LLToolPipette::getInstance()->setToolSelectCallback(boost::bind(&LLFloaterTexturePicker::onTextureSelect, this, _1)); getChild<LLComboBox>("l_bake_use_texture_combo_box")->setCommitCallback(onBakeTextureSelect, this); getChild<LLCheckBoxCtrl>("hide_base_mesh_region")->setCommitCallback(onHideBaseMeshRegionCheck, this); @@ -455,7 +516,7 @@ void LLFloaterTexturePicker::draw() getChildView("show_folders_check")->setEnabled(mActive && mCanApplyImmediately && !mNoCopyTextureSelected); getChildView("Select")->setEnabled(mActive && mCanApply); getChildView("Pipette")->setEnabled(mActive); - getChild<LLUICtrl>("Pipette")->setValue(LLToolMgr::getInstanceFast()->getCurrentTool() == LLToolPipette::getInstanceFast()); + getChild<LLUICtrl>("Pipette")->setValue(LLToolMgr::getInstance()->getCurrentTool() == LLToolPipette::getInstance()); //BOOL allow_copy = FALSE; if( mOwner ) @@ -467,7 +528,7 @@ void LLFloaterTexturePicker::draw() if (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(mImageAssetID)) { - LLViewerObject* obj = LLSelectMgr::getInstanceFast()->getSelection()->getFirstObject(); + LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); if (obj) { LLViewerTexture* viewerTexture = obj->getBakedTextureForMagicId(mImageAssetID); @@ -723,11 +784,11 @@ void LLFloaterTexturePicker::onBtnPipette() pipette_active = !pipette_active; if (pipette_active) { - LLToolMgr::getInstanceFast()->setTransientTool(LLToolPipette::getInstance()); + LLToolMgr::getInstance()->setTransientTool(LLToolPipette::getInstance()); } else { - LLToolMgr::getInstanceFast()->clearTransientTool(); + LLToolMgr::getInstance()->clearTransientTool(); } } @@ -1650,7 +1711,7 @@ void LLTextureCtrl::draw() if (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(mImageAssetID)) { - LLViewerObject* obj = LLSelectMgr::getInstanceFast()->getSelection()->getFirstObject(); + LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); if (obj) { LLViewerTexture* viewerTexture = obj->getBakedTextureForMagicId(mImageAssetID); diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h index 1190fd04b2f232a0f61d0febf5ad12b0dfc4c32a..719fb953aa46be7c94911a681592b6544d3f4b80 100644 --- a/indra/newview/lltexturectrl.h +++ b/indra/newview/lltexturectrl.h @@ -52,6 +52,16 @@ class LLViewerFetchedTexture; typedef boost::function<BOOL (LLUICtrl*, LLInventoryItem*)> drag_n_drop_callback; typedef boost::function<void (LLInventoryItem*)> texture_selected_callback; +// Helper functions for UI that work with picker +bool get_is_predefined_texture(LLUUID asset_id); + +// texture picker works by asset ids since objects normaly do +// not retain inventory ids as result these functions are looking +// for textures in inventory by asset ids +// This search can be performance unfriendly and doesn't warranty +// that the texture is original source of asset +LLUUID get_copy_free_item_by_asset_id(LLUUID image_id, bool no_trans_perm = false); +bool get_can_copy_texture(LLUUID image_id); ////////////////////////////////////////////////////////////////////////////////////////// // LLTextureCtrl diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 4c67bb599e150eb23aa04bf502e2f1aff443ab5d..128568ea4b4049b18b95281695955775f570d769 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -318,6 +318,7 @@ class LLTextureFetchWorker : public LLWorkerClass, public LLCore::HttpHandler // Threads: Ttc virtual void completed(bool success) { + LL_PROFILE_ZONE_SCOPED; LLTextureFetchWorker* worker = mFetcher->getWorker(mID); if (worker) { @@ -342,6 +343,7 @@ class LLTextureFetchWorker : public LLWorkerClass, public LLCore::HttpHandler // Threads: Ttc virtual void completed(bool success) { + LL_PROFILE_ZONE_SCOPED; LLTextureFetchWorker* worker = mFetcher->getWorker(mID); if (worker) { @@ -366,6 +368,7 @@ class LLTextureFetchWorker : public LLWorkerClass, public LLCore::HttpHandler // Threads: Tid virtual void completed(bool success, LLImageRaw* raw, LLImageRaw* aux) { + LL_PROFILE_ZONE_SCOPED; LLTextureFetchWorker* worker = mFetcher->getWorker(mID); if (worker) { @@ -1153,6 +1156,11 @@ void LLTextureFetchWorker::startWork(S32 param) // Threads: Ttf bool LLTextureFetchWorker::doWork(S32 param) { + LL_PROFILE_ZONE_SCOPED; + if (gNonInteractive) + { + return true; + } static const LLCore::HttpStatus http_not_found(HTTP_NOT_FOUND); // 404 static const LLCore::HttpStatus http_service_unavail(HTTP_SERVICE_UNAVAILABLE); // 503 static const LLCore::HttpStatus http_not_sat(HTTP_REQUESTED_RANGE_NOT_SATISFIABLE); // 416; @@ -1391,7 +1399,7 @@ bool LLTextureFetchWorker::doWork(S32 param) if (mHost.isInvalid()) region = gAgent.getRegion(); else - region = LLWorld::getInstanceFast()->getRegion(mHost); + region = LLWorld::getInstance()->getRegion(mHost); if (region) { diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp index 751eb1d26d43b4311d08a350a81a81e708cc2d19..16a55dc85658db7d1acf8e5256ea670f4cb9ebb2 100644 --- a/indra/newview/lltextureview.cpp +++ b/indra/newview/lltextureview.cpp @@ -521,7 +521,7 @@ void LLGLTexMemBar::draw() F32Bytes total_texture_downloaded = gTotalTextureData; F32Bytes total_object_downloaded = gTotalObjectData; U32 total_http_requests = LLAppViewer::getTextureFetch()->getTotalNumHTTPRequests(); - U32 total_active_cached_objects = LLWorld::getInstanceFast()->getNumOfActiveCachedObjects(); + U32 total_active_cached_objects = LLWorld::getInstance()->getNumOfActiveCachedObjects(); U32 total_objects = gObjectList.getNumObjects(); F32 x_right = 0.0; @@ -558,9 +558,11 @@ void LLGLTexMemBar::draw() U32 texFetchLatMed = U32(recording.getMean(LLTextureFetch::sTexFetchLatency).value() * 1000.0f); U32 texFetchLatMax = U32(recording.getMax(LLTextureFetch::sTexFetchLatency).value() * 1000.0f); - text = llformat("GL Tot: %d/%d MB Bound: %4d/%4d MB FBO: %d MB Raw Tot: %d MB Bias: %.2f Cache: %.1f/%.1f MB", + text = llformat("GL Tot: %d/%d MB GL Free: %d Sys Free: %d MB Bound: %4d/%4d MB FBO: %d MB Raw Tot: %d MB Bias: %.2f Cache: %.1f/%.1f MB", total_mem.value(), max_total_mem.value(), + LLImageGLThread::getFreeVRAMMegabytes(), + LLMemory::getAvailableMemKB()/1024, bound_mem.value(), max_bound_mem.value(), LLRenderTarget::sBytesAllocated/(1024*1024), @@ -875,7 +877,7 @@ void LLTextureView::draw() if (!mOrderFetch) { - if (pri < HIGH_PRIORITY && LLSelectMgr::getInstanceFast()) + if (pri < HIGH_PRIORITY && LLSelectMgr::getInstance()) { struct f : public LLSelectedTEFunctor { @@ -887,7 +889,7 @@ void LLTextureView::draw() } } func(imagep); const bool firstonly = true; - bool match = LLSelectMgr::getInstanceFast()->getSelection()->applyToTEs(&func, firstonly); + bool match = LLSelectMgr::getInstance()->getSelection()->applyToTEs(&func, firstonly); if (match) { pri += 3*HIGH_PRIORITY; @@ -896,7 +898,7 @@ void LLTextureView::draw() if (pri < HIGH_PRIORITY && (cur_discard< 0 || desired_discard < cur_discard)) { - LLSelectNode* hover_node = LLSelectMgr::instanceFast().getHoverNode(); + LLSelectNode* hover_node = LLSelectMgr::instance().getHoverNode(); if (hover_node) { LLViewerObject *objectp = hover_node->getObject(); diff --git a/indra/newview/lltoastalertpanel.cpp b/indra/newview/lltoastalertpanel.cpp index 8baad30e8f09e0593a2e617cb34e283ab46e47a9..692e8d91a9c8d90c4cadc48447d4a4f1b52e78dc 100644 --- a/indra/newview/lltoastalertpanel.cpp +++ b/indra/newview/lltoastalertpanel.cpp @@ -291,7 +291,7 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal mLineEditor->setText(edit_text_contents); std::string notif_name = mNotification->getName(); - if (("SaveOutfitAs" == notif_name) || ("SaveSettingAs" == notif_name) || ("CreateLandmarkFolder" == notif_name)) + if (("SaveOutfitAs" == notif_name) || ("SaveSettingAs" == notif_name) || ("CreateLandmarkFolder" == notif_name) || ("CreateSubfolder" == notif_name)) { mLineEditor->setPrevalidate(&LLTextValidate::validateASCII); } diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp index f64fe05663183b2f3a61685aebf833634d5f01dd..024f25bc98a2a7f1c8d1f2d30311e5c9fae386c6 100644 --- a/indra/newview/lltoastnotifypanel.cpp +++ b/indra/newview/lltoastnotifypanel.cpp @@ -329,7 +329,7 @@ void LLToastNotifyPanel::init( LLRect rect, bool show_images ) mTextBox->setContentTrusted(is_content_trusted); mTextBox->setValue(mNotification->getMessage()); mTextBox->setIsFriendCallback(LLAvatarActions::isFriend); - mTextBox->setIsObjectBlockedCallback(boost::bind(&LLMuteList::isMuted, LLMuteList::getInstanceFast(), _1, _2, 0)); + mTextBox->setIsObjectBlockedCallback(boost::bind(&LLMuteList::isMuted, LLMuteList::getInstance(), _1, _2, 0)); // add buttons for a script notification if (mIsTip) diff --git a/indra/newview/lltoastpanel.cpp b/indra/newview/lltoastpanel.cpp index 908243508485bf31ad81df9297b237a8b40ba644..b35766e4e731c545f9f19b37ec78c61d184ec661 100644 --- a/indra/newview/lltoastpanel.cpp +++ b/indra/newview/lltoastpanel.cpp @@ -114,7 +114,8 @@ void LLToastPanel::snapToMessageHeight(LLTextBase* message, S32 maxLineCount) LLToastPanel* LLToastPanel::buidPanelFromNotification( const LLNotificationPtr& notification) { - LLToastPanel* res = NULL; + LL_PROFILE_ZONE_SCOPED + LLToastPanel* res = NULL; //process tip toast panels if ("notifytip" == notification->getType()) diff --git a/indra/newview/lltool.cpp b/indra/newview/lltool.cpp index 12630da2a01ec5c0ee5e5cc87d6e73a73790541d..9bf94868c18b641c52e10f68716472d890e2c5bb 100644 --- a/indra/newview/lltool.cpp +++ b/indra/newview/lltool.cpp @@ -195,7 +195,7 @@ BOOL LLTool::handleKey(KEY key, MASK mask) LLTool* LLTool::getOverrideTool(MASK mask) { // NOTE: if in flycam mode, ALT-ZOOM camera should be disabled - if (LLViewerJoystick::getInstanceFast()->getOverrideCamera()) + if (LLViewerJoystick::getInstance()->getOverrideCamera()) { return NULL; } @@ -205,7 +205,7 @@ LLTool* LLTool::getOverrideTool(MASK mask) { if (mask & MASK_ALT) { - return LLToolCamera::getInstanceFast(); + return LLToolCamera::getInstance(); } } return NULL; diff --git a/indra/newview/lltoolbarview.cpp b/indra/newview/lltoolbarview.cpp index 542169e45818a29865337b3da14b499561215a64..9d14a548f9338394606f38554752c31aa86fa5f4 100644 --- a/indra/newview/lltoolbarview.cpp +++ b/indra/newview/lltoolbarview.cpp @@ -51,7 +51,7 @@ static LLDefaultChildRegistry::Register<LLToolBarView> r("toolbar_view"); bool isToolDragged() { - return (LLToolDragAndDrop::getInstanceFast()->getSource() == LLToolDragAndDrop::SOURCE_VIEWER); + return (LLToolDragAndDrop::getInstance()->getSource() == LLToolDragAndDrop::SOURCE_VIEWER); } LLToolBarView::Toolbar::Toolbar() diff --git a/indra/newview/lltoolbrush.cpp b/indra/newview/lltoolbrush.cpp index c728081cec62b287797efca539fbbfe6a454430c..1ca27fce1bfe80944b43027ec9e32a16759dc442 100644 --- a/indra/newview/lltoolbrush.cpp +++ b/indra/newview/lltoolbrush.cpp @@ -193,12 +193,12 @@ void LLToolBrushLand::modifyLandAtPointGlobal(const LLVector3d &pos_global, void LLToolBrushLand::modifyLandInSelectionGlobal() { - if (LLViewerParcelMgr::getInstanceFast()->selectionEmpty()) + if (LLViewerParcelMgr::getInstance()->selectionEmpty()) { return; } - if (LLToolMgr::getInstanceFast()->getCurrentTool() == LLToolSelectLand::getInstanceFast()) + if (LLToolMgr::getInstance()->getCurrentTool() == LLToolSelectLand::getInstance()) { // selecting land, don't do anything return; @@ -588,7 +588,7 @@ void LLToolBrushLand::renderOverlay(LLSurface& land, const LLVector3& pos_region void LLToolBrushLand::determineAffectedRegions(region_list_t& regions, const LLVector3d& spot ) const { - auto& world_inst = LLWorld::instanceFast(); + auto& world_inst = LLWorld::instance(); LLVector3d corner(spot); corner.mdV[VX] -= (mBrushSize / 2); @@ -624,7 +624,7 @@ void LLToolBrushLand::onIdle( void* brush_tool ) { LLToolBrushLand* self = static_cast<LLToolBrushLand*>(brush_tool); - if( LLToolMgr::getInstanceFast()->getCurrentTool() == self ) + if( LLToolMgr::getInstance()->getCurrentTool() == self ) { self->brush(); } diff --git a/indra/newview/lltoolcomp.cpp b/indra/newview/lltoolcomp.cpp index 42dacaada0cbbfde51e9d1084b1f73be9474cfc4..6bb55d584f55940117445ee91782477b8f591549 100644 --- a/indra/newview/lltoolcomp.cpp +++ b/indra/newview/lltoolcomp.cpp @@ -114,7 +114,7 @@ void LLToolComposite::handleSelect() { if (!ALControlCache::EditLinkedParts) { - LLSelectMgr::getInstanceFast()->promoteSelectionToRoot(); + LLSelectMgr::getInstance()->promoteSelectionToRoot(); } mCur = mDefault; mCur->handleSelect(); @@ -151,7 +151,7 @@ BOOL LLToolCompInspect::handleMouseDown(S32 x, S32 y, MASK mask) { BOOL handled = FALSE; - if (mCur == LLToolCamera::getInstanceFast()) + if (mCur == LLToolCamera::getInstance()) { handled = mCur->handleMouseDown(x, y, mask); } @@ -168,14 +168,14 @@ BOOL LLToolCompInspect::handleMouseDown(S32 x, S32 y, MASK mask) BOOL LLToolCompInspect::handleMouseUp(S32 x, S32 y, MASK mask) { BOOL handled = LLToolComposite::handleMouseUp(x, y, mask); - mIsToolCameraActive = getCurrentTool() == LLToolCamera::getInstanceFast(); + mIsToolCameraActive = getCurrentTool() == LLToolCamera::getInstance(); return handled; } void LLToolCompInspect::pickCallback(const LLPickInfo& pick_info) { LLViewerObject* hit_obj = pick_info.getObject(); - LLToolCompInspect * tool_inspectp = LLToolCompInspect::getInstanceFast(); + LLToolCompInspect * tool_inspectp = LLToolCompInspect::getInstance(); if (!tool_inspectp->mMouseDown) { @@ -184,7 +184,7 @@ void LLToolCompInspect::pickCallback(const LLPickInfo& pick_info) return; } - LLSelectMgr * mgr_selectp = LLSelectMgr::getInstanceFast(); + LLSelectMgr * mgr_selectp = LLSelectMgr::getInstance(); if( hit_obj && mgr_selectp->getSelection()->getObjectCount()) { LLEditMenuHandler::gEditMenuHandler = mgr_selectp; } @@ -205,7 +205,7 @@ BOOL LLToolCompInspect::handleKey(KEY key, MASK mask) if(KEY_ALT == key) { - setCurrentTool(LLToolCamera::getInstanceFast()); + setCurrentTool(LLToolCamera::getInstance()); mIsToolCameraActive = TRUE; handled = TRUE; } @@ -225,7 +225,7 @@ void LLToolCompInspect::onMouseCaptureLost() void LLToolCompInspect::keyUp(KEY key, MASK mask) { - if (KEY_ALT == key && mCur == LLToolCamera::getInstanceFast()) + if (KEY_ALT == key && mCur == LLToolCamera::getInstance()) { setCurrentTool(mDefault); mIsToolCameraActive = FALSE; @@ -276,9 +276,9 @@ void LLToolCompTranslate::pickCallback(const LLPickInfo& pick_info) { LLViewerObject* hit_obj = pick_info.getObject(); - auto tool_comp_translate = LLToolCompTranslate::getInstanceFast(); + auto tool_comp_translate = LLToolCompTranslate::getInstance(); - LLToolCompTranslate::getInstanceFast()->mManip->highlightManipulators(pick_info.mMousePt.mX, pick_info.mMousePt.mY); + LLToolCompTranslate::getInstance()->mManip->highlightManipulators(pick_info.mMousePt.mX, pick_info.mMousePt.mY); if (!tool_comp_translate->mMouseDown) { // fast click on object, but mouse is already up...just do select @@ -290,7 +290,7 @@ void LLToolCompTranslate::pickCallback(const LLPickInfo& pick_info) { if (tool_comp_translate->mManip->getSelection()->getObjectCount()) { - LLEditMenuHandler::gEditMenuHandler = LLSelectMgr::getInstanceFast(); + LLEditMenuHandler::gEditMenuHandler = LLSelectMgr::getInstance(); } BOOL can_move = tool_comp_translate->mManip->canAffectSelection(); @@ -326,11 +326,11 @@ LLTool* LLToolCompTranslate::getOverrideTool(MASK mask) { if (mask == MASK_CONTROL) { - return LLToolCompRotate::getInstanceFast(); + return LLToolCompRotate::getInstance(); } else if (mask == (MASK_CONTROL | MASK_SHIFT)) { - return LLToolCompScale::getInstanceFast(); + return LLToolCompScale::getInstance(); } return LLToolComposite::getOverrideTool(mask); } @@ -404,7 +404,7 @@ void LLToolCompScale::pickCallback(const LLPickInfo& pick_info) { LLViewerObject* hit_obj = pick_info.getObject(); - auto tool_comp_scale = LLToolCompScale::getInstanceFast(); + auto tool_comp_scale = LLToolCompScale::getInstance(); tool_comp_scale->mManip->highlightManipulators(pick_info.mMousePt.mX, pick_info.mMousePt.mY); if (!tool_comp_scale->mMouseDown) @@ -419,7 +419,7 @@ void LLToolCompScale::pickCallback(const LLPickInfo& pick_info) { if (tool_comp_scale->mManip->getSelection()->getObjectCount()) { - LLEditMenuHandler::gEditMenuHandler = LLSelectMgr::getInstanceFast(); + LLEditMenuHandler::gEditMenuHandler = LLSelectMgr::getInstance(); } if( LLManip::LL_NO_PART != tool_comp_scale->mManip->getHighlightedPart() ) { @@ -449,7 +449,7 @@ LLTool* LLToolCompScale::getOverrideTool(MASK mask) { if (mask == MASK_CONTROL) { - return LLToolCompRotate::getInstanceFast(); + return LLToolCompRotate::getInstance(); } return LLToolComposite::getOverrideTool(mask); @@ -535,7 +535,7 @@ void LLToolCompCreate::pickCallback(const LLPickInfo& pick_info) MASK mask = (pick_info.mKeyMask & ~MASK_SHIFT); mask = (mask & ~MASK_CONTROL); - auto tool_comp_create = LLToolCompCreate::getInstanceFast(); + auto tool_comp_create = LLToolCompCreate::getInstance(); tool_comp_create->setCurrentTool(tool_comp_create->mSelectRect ); tool_comp_create->mSelectRect->handlePick( pick_info ); } @@ -607,7 +607,7 @@ void LLToolCompRotate::pickCallback(const LLPickInfo& pick_info) { LLViewerObject* hit_obj = pick_info.getObject(); - auto tool_comp_rotate = LLToolCompRotate::getInstanceFast(); + auto tool_comp_rotate = LLToolCompRotate::getInstance(); tool_comp_rotate->mManip->highlightManipulators(pick_info.mMousePt.mX, pick_info.mMousePt.mY); if (!tool_comp_rotate->mMouseDown) { @@ -620,7 +620,7 @@ void LLToolCompRotate::pickCallback(const LLPickInfo& pick_info) { if (tool_comp_rotate->mManip->getSelection()->getObjectCount()) { - LLEditMenuHandler::gEditMenuHandler = LLSelectMgr::getInstanceFast(); + LLEditMenuHandler::gEditMenuHandler = LLSelectMgr::getInstance(); } if( LLManip::LL_NO_PART != tool_comp_rotate->mManip->getHighlightedPart() ) { @@ -650,7 +650,7 @@ LLTool* LLToolCompRotate::getOverrideTool(MASK mask) { if (mask == (MASK_CONTROL | MASK_SHIFT)) { - return LLToolCompScale::getInstanceFast(); + return LLToolCompScale::getInstance(); } return LLToolComposite::getOverrideTool(mask); } @@ -701,7 +701,7 @@ LLToolCompGun::LLToolCompGun() mDefault = mGun; mTimerFOV.stop(); - mStartFOV = mOriginalFOV = mTargetFOV = LLViewerCamera::getInstanceFast()->getAndSaveDefaultFOV(); + mStartFOV = mOriginalFOV = mTargetFOV = LLViewerCamera::getInstance()->getAndSaveDefaultFOV(); } @@ -724,7 +724,7 @@ BOOL LLToolCompGun::handleHover(S32 x, S32 y, MASK mask) // item selected from context menu. if ( mCur == mNull && !gPopupMenuView->getVisible() ) { - LLSelectMgr::getInstanceFast()->deselectAll(); + LLSelectMgr::getInstance()->deselectAll(); setCurrentTool( (LLTool*) mGrab ); } @@ -765,9 +765,9 @@ BOOL LLToolCompGun::handleMouseDown(S32 x, S32 y, MASK mask) // On mousedown, start grabbing gGrabTransientTool = this; - LLToolMgr::getInstanceFast()->getCurrentToolset()->selectTool( (LLTool*) mGrab ); + LLToolMgr::getInstance()->getCurrentToolset()->selectTool( (LLTool*) mGrab ); - return LLToolGrab::getInstanceFast()->handleMouseDown(x, y, mask); + return LLToolGrab::getInstance()->handleMouseDown(x, y, mask); } @@ -782,9 +782,9 @@ BOOL LLToolCompGun::handleDoubleClick(S32 x, S32 y, MASK mask) // On mousedown, start grabbing gGrabTransientTool = this; - LLToolMgr::getInstanceFast()->getCurrentToolset()->selectTool( (LLTool*) mGrab ); + LLToolMgr::getInstance()->getCurrentToolset()->selectTool( (LLTool*) mGrab ); - return LLToolGrab::getInstanceFast()->handleDoubleClick(x, y, mask); + return LLToolGrab::getInstance()->handleDoubleClick(x, y, mask); } @@ -796,11 +796,11 @@ BOOL LLToolCompGun::handleRightMouseDown(S32 x, S32 y, MASK mask) if (!mTimerFOV.getStarted()) { - mStartFOV = LLViewerCamera::getInstanceFast()->getAndSaveDefaultFOV(); + mStartFOV = LLViewerCamera::getInstance()->getAndSaveDefaultFOV(); mOriginalFOV = mStartFOV; } else - mStartFOV = LLViewerCamera::getInstanceFast()->getDefaultFOV(); + mStartFOV = LLViewerCamera::getInstance()->getDefaultFOV(); mTargetFOV = gSavedPerAccountSettings.getF32("AlchemyMouselookAlternativeFOV"); mTimerFOV.start(); @@ -816,7 +816,7 @@ BOOL LLToolCompGun::handleRightMouseUp(S32 x, S32 y, MASK mask) { mRightMouseDown = false; - mStartFOV = LLViewerCamera::getInstanceFast()->getDefaultFOV(); + mStartFOV = LLViewerCamera::getInstance()->getDefaultFOV(); mTargetFOV = mOriginalFOV; mTimerFOV.start(); @@ -854,7 +854,7 @@ void LLToolCompGun::handleDeselect() LLToolComposite::handleDeselect(); if (mRightMouseDown || mTimerFOV.getStarted()) { - LLViewerCamera::getInstanceFast()->loadDefaultFOV(); + LLViewerCamera::getInstance()->loadDefaultFOV(); mRightMouseDown = false; mTimerFOV.stop(); } @@ -866,7 +866,7 @@ BOOL LLToolCompGun::handleScrollWheel(S32 x, S32 y, S32 clicks) { if(mRightMouseDown) { - mStartFOV = LLViewerCamera::getInstanceFast()->getDefaultFOV(); + mStartFOV = LLViewerCamera::getInstance()->getDefaultFOV(); gSavedPerAccountSettings.setF32( "AlchemyMouselookAlternativeFOV", @@ -888,7 +888,7 @@ void LLToolCompGun::draw() { if(mTimerFOV.getStarted()) { - if(!LLViewerCamera::getInstanceFast()->mSavedFOVLoaded && mStartFOV != mTargetFOV) + if(!LLViewerCamera::getInstance()->mSavedFOVLoaded && mStartFOV != mTargetFOV) { F32 timer = mTimerFOV.getElapsedTimeF32(); @@ -896,10 +896,10 @@ void LLToolCompGun::draw() static LLCachedControl<F32> ml_zoom_time(gSavedSettings, "AlchemyMouseLookZoomTime", 6.66f); if(timer > ml_zoom_timeout) { - LLViewerCamera::getInstanceFast()->setDefaultFOV(mTargetFOV); + LLViewerCamera::getInstance()->setDefaultFOV(mTargetFOV); mTimerFOV.stop(); } - else LLViewerCamera::getInstanceFast()->setDefaultFOV(ll_lerp(mStartFOV, mTargetFOV, timer * ml_zoom_time)); + else LLViewerCamera::getInstance()->setDefaultFOV(ll_lerp(mStartFOV, mTargetFOV, timer * ml_zoom_time)); } else mTimerFOV.stop(); } diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index 20b4fc2b4978c88cefb9d3f55dd5e3649d0ff1b2..8735517cfa6b623fcc98fcf069800011f0987190 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -330,7 +330,7 @@ void LLToolDragAndDrop::beginDrag(EDragAndDropType type, mObjectID = object_id; setMouseCapture( TRUE ); - LLToolMgr::getInstanceFast()->setTransientTool( this ); + LLToolMgr::getInstance()->setTransientTool( this ); mCursor = UI_CURSOR_NO; if ((mCargoTypes[0] == DAD_CATEGORY) && ((mSource == SOURCE_AGENT) || (mSource == SOURCE_LIBRARY))) @@ -400,7 +400,7 @@ void LLToolDragAndDrop::beginMultiDrag( mSourceID = source_id; setMouseCapture( TRUE ); - LLToolMgr::getInstanceFast()->setTransientTool( this ); + LLToolMgr::getInstance()->setTransientTool( this ); mCursor = UI_CURSOR_NO; if ((mSource == SOURCE_AGENT) || (mSource == SOURCE_LIBRARY)) { @@ -447,14 +447,14 @@ void LLToolDragAndDrop::beginMultiDrag( void LLToolDragAndDrop::endDrag() { mEndDragSignal(); - LLSelectMgr::getInstanceFast()->unhighlightAll(); + LLSelectMgr::getInstance()->unhighlightAll(); setMouseCapture(FALSE); } void LLToolDragAndDrop::onMouseCaptureLost() { // Called whenever the drag ends or if mouse capture is simply lost - LLToolMgr::getInstanceFast()->clearTransientTool(); + LLToolMgr::getInstance()->clearTransientTool(); mCargoTypes.clear(); mCargoIDs.clear(); mSource = SOURCE_AGENT; @@ -807,9 +807,9 @@ void LLToolDragAndDrop::dragOrDrop3D( S32 x, S32 y, MASK mask, BOOL drop, EAccep void LLToolDragAndDrop::pickCallback(const LLPickInfo& pick_info) { - if (getInstanceFast() != NULL) + if (getInstance() != NULL) { - getInstanceFast()->pick(pick_info); + getInstance()->pick(pick_info); } } @@ -819,7 +819,7 @@ void LLToolDragAndDrop::pick(const LLPickInfo& pick_info) S32 hit_face = -1; LLViewerObject* hit_obj = pick_info.getObject(); - LLSelectMgr::getInstanceFast()->unhighlightAll(); + LLSelectMgr::getInstance()->unhighlightAll(); bool highlight_object = false; // Treat attachments as part of the avatar they are attached to. if (hit_obj != NULL) @@ -915,7 +915,7 @@ void LLToolDragAndDrop::pick(const LLPickInfo& pick_info) { if (mCargoTypes[i] != DAD_OBJECT || (pick_info.mKeyMask & MASK_CONTROL)) { - LLSelectMgr::getInstanceFast()->highlightObjectAndFamily(hit_obj); + LLSelectMgr::getInstance()->highlightObjectAndFamily(hit_obj); break; } } @@ -1107,7 +1107,8 @@ void LLToolDragAndDrop::dropTextureOneFace(LLViewerObject* hit_obj, S32 hit_face, LLInventoryItem* item, LLToolDragAndDrop::ESource source, - const LLUUID& src_id) + const LLUUID& src_id, + S32 tex_channel) { if (hit_face == -1) return; if (!item) @@ -1131,7 +1132,8 @@ void LLToolDragAndDrop::dropTextureOneFace(LLViewerObject* hit_obj, if (gFloaterTools->getVisible() && panel_face) { - switch (LLSelectMgr::getInstanceFast()->getTextureChannel()) + tex_channel = (tex_channel > -1) ? tex_channel : LLSelectMgr::getInstance()->getTextureChannel(); + switch (tex_channel) { case 0: @@ -1240,7 +1242,7 @@ void LLToolDragAndDrop::dropObject(LLViewerObject* raycast_target, BOOL from_task_inventory, BOOL remove_from_inventory) { - LLViewerRegion* regionp = LLWorld::getInstanceFast()->getRegionFromPosGlobal(mLastHitPos); + LLViewerRegion* regionp = LLWorld::getInstance()->getRegionFromPosGlobal(mLastHitPos); if (!regionp) { LL_WARNS() << "Couldn't find region to rez object" << LL_ENDL; @@ -1303,7 +1305,7 @@ void LLToolDragAndDrop::dropObject(LLViewerObject* raycast_target, LLUUID source_id = from_task_inventory ? mSourceID : LLUUID::null; // Select the object only if we're editing. - BOOL rez_selected = LLToolMgr::getInstanceFast()->inEdit(); + BOOL rez_selected = LLToolMgr::getInstance()->inEdit(); LLVector3 ray_start = regionp->getPosRegionFromGlobal(mLastCameraPos); @@ -1382,7 +1384,7 @@ void LLToolDragAndDrop::dropObject(LLViewerObject* raycast_target, // selected object. if (rez_selected) { - LLSelectMgr::getInstanceFast()->deselectAll(); + LLSelectMgr::getInstance()->deselectAll(); gViewerWindow->getWindow()->incBusyCount(); } diff --git a/indra/newview/lltooldraganddrop.h b/indra/newview/lltooldraganddrop.h index 1a10e1f6a0da6f668abed9156089863690c5a990..86773f81819a6912600a3c448886ff799463d3de 100644 --- a/indra/newview/lltooldraganddrop.h +++ b/indra/newview/lltooldraganddrop.h @@ -244,7 +244,8 @@ class LLToolDragAndDrop final : public LLTool, public LLSingleton<LLToolDragAndD static void dropTextureOneFace(LLViewerObject* hit_obj, S32 hit_face, LLInventoryItem* item, ESource source, - const LLUUID& src_id); + const LLUUID& src_id, + S32 tex_channel = -1); static void dropTextureAllFaces(LLViewerObject* hit_obj, LLInventoryItem* item, ESource source, diff --git a/indra/newview/lltoolface.cpp b/indra/newview/lltoolface.cpp index 0bc4e18c0cc799c5ed43a59bcdea80e0df95a3f6..f380de18377f1439408206d3fd779ca23e3dd5aa 100644 --- a/indra/newview/lltoolface.cpp +++ b/indra/newview/lltoolface.cpp @@ -58,7 +58,7 @@ LLToolFace::~LLToolFace() BOOL LLToolFace::handleDoubleClick(S32 x, S32 y, MASK mask) { - if (!LLSelectMgr::getInstanceFast()->getSelection()->isEmpty()) + if (!LLSelectMgr::getInstance()->getSelection()->isEmpty()) { // You should already have an object selected from the mousedown. // If so, show its properties @@ -108,17 +108,17 @@ void LLToolFace::pickCallback(const LLPickInfo& pick_info) if ( !hit_obj->isSelected() ) { // object wasn't selected so add the object and face - LLSelectMgr::getInstanceFast()->selectObjectOnly(hit_obj, hit_face); + LLSelectMgr::getInstance()->selectObjectOnly(hit_obj, hit_face); } - else if (!LLSelectMgr::getInstanceFast()->getSelection()->contains(hit_obj, hit_face) ) + else if (!LLSelectMgr::getInstance()->getSelection()->contains(hit_obj, hit_face) ) { // object is selected, but not this face, so add it. - LLSelectMgr::getInstanceFast()->addAsIndividual(hit_obj, hit_face); + LLSelectMgr::getInstance()->addAsIndividual(hit_obj, hit_face); } else { // object is selected, as is this face, so remove the face. - LLSelectMgr::getInstanceFast()->remove(hit_obj, hit_face); + LLSelectMgr::getInstance()->remove(hit_obj, hit_face); // BUG: If you remove the last face, the simulator won't know about it. } @@ -127,15 +127,15 @@ void LLToolFace::pickCallback(const LLPickInfo& pick_info) { // clicked without modifiers, select only // this face - LLSelectMgr::getInstanceFast()->deselectAll(); - LLSelectMgr::getInstanceFast()->selectObjectOnly(hit_obj, hit_face); + LLSelectMgr::getInstance()->deselectAll(); + LLSelectMgr::getInstance()->selectObjectOnly(hit_obj, hit_face); } } else { if (!(pick_info.mKeyMask == MASK_SHIFT)) { - LLSelectMgr::getInstanceFast()->deselectAll(); + LLSelectMgr::getInstance()->deselectAll(); } } } @@ -144,14 +144,14 @@ void LLToolFace::pickCallback(const LLPickInfo& pick_info) void LLToolFace::handleSelect() { // From now on, draw faces - LLSelectMgr::getInstanceFast()->setTEMode(TRUE); + LLSelectMgr::getInstance()->setTEMode(TRUE); } void LLToolFace::handleDeselect() { // Stop drawing faces - LLSelectMgr::getInstanceFast()->setTEMode(FALSE); + LLSelectMgr::getInstance()->setTEMode(FALSE); } diff --git a/indra/newview/lltoolfocus.cpp b/indra/newview/lltoolfocus.cpp index 434dc77a850f1230b5a997f409ce0fc0aec244df..97e5ba0943ff50dfc515c7a4b4129896e996d17d 100644 --- a/indra/newview/lltoolfocus.cpp +++ b/indra/newview/lltoolfocus.cpp @@ -110,7 +110,7 @@ void LLToolCamera::handleDeselect() if (!mValidSelection && (override_mask != MASK_NONE || (gFloaterTools && gFloaterTools->getVisible()))) { LLMenuGL::sMenuContainer->hideMenus(); - LLSelectMgr::getInstanceFast()->validateSelection(); + LLSelectMgr::getInstance()->validateSelection(); } } @@ -168,7 +168,7 @@ void LLToolCamera::pickCallback(const LLPickInfo& pick_info) // check for hud attachments if (hit_obj && hit_obj->isHUDAttachment()) { - LLObjectSelectionHandle selection = LLSelectMgr::getInstanceFast()->getSelection(); + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); if (!selection->getObjectCount() || selection->getSelectType() != SELECT_TYPE_HUD) { LLToolCamera::getInstance()->mValidClickPoint = FALSE; @@ -206,7 +206,7 @@ void LLToolCamera::pickCallback(const LLPickInfo& pick_info) } //RN: check to see if this is mouse-driving as opposed to ALT-zoom or Focus tool else if (pick_info.mKeyMask & MASK_ALT || - (LLToolMgr::getInstanceFast()->getCurrentTool()->getName() == "Camera")) + (LLToolMgr::getInstance()->getCurrentTool()->getName() == "Camera")) { LLViewerObject* hit_obj = pick_info.getObject(); if (hit_obj) @@ -225,7 +225,7 @@ void LLToolCamera::pickCallback(const LLPickInfo& pick_info) gAgentCamera.setFocusGlobal(pick_info); } - BOOL zoom_tool = gCameraBtnZoom && (LLToolMgr::getInstanceFast()->getBaseTool() == LLToolCamera::getInstanceFast()); + BOOL zoom_tool = gCameraBtnZoom && (LLToolMgr::getInstance()->getBaseTool() == LLToolCamera::getInstance()); if (!(pick_info.mKeyMask & MASK_ALT) && !LLFloaterCamera::inFreeCameraMode() && !zoom_tool && @@ -235,12 +235,12 @@ void LLToolCamera::pickCallback(const LLPickInfo& pick_info) (hit_obj == gAgentAvatarp || (hit_obj && hit_obj->isAttachment() && LLVOAvatar::findAvatarFromAttachment(hit_obj)->isSelf()))) { - LLToolCamera::getInstanceFast()->mMouseSteering = TRUE; + LLToolCamera::getInstance()->mMouseSteering = TRUE; } } - LLToolCamera::getInstanceFast()->mValidClickPoint = TRUE; + LLToolCamera::getInstance()->mValidClickPoint = TRUE; if( CAMERA_MODE_CUSTOMIZE_AVATAR == gAgentCamera.getCameraMode() ) { @@ -268,7 +268,7 @@ void LLToolCamera::releaseMouse() //for the situation when left click was performed on the Agent if (!LLFloaterCamera::inFreeCameraMode()) { - LLToolMgr::getInstanceFast()->clearTransientTool(); + LLToolMgr::getInstance()->clearTransientTool(); } mMouseSteering = FALSE; @@ -293,7 +293,7 @@ BOOL LLToolCamera::handleMouseUp(S32 x, S32 y, MASK mask) { LLCoordGL mouse_pos; LLVector3 focus_pos = gAgent.getPosAgentFromGlobal(gAgentCamera.getFocusGlobal()); - BOOL success = LLViewerCamera::getInstanceFast()->projectPosAgentToScreen(focus_pos, mouse_pos); + BOOL success = LLViewerCamera::getInstance()->projectPosAgentToScreen(focus_pos, mouse_pos); if (success) { LLUI::setMousePositionScreen(mouse_pos.mX, mouse_pos.mY); diff --git a/indra/newview/lltoolgrab.cpp b/indra/newview/lltoolgrab.cpp index 88c04353c27f523f60c9541dbb19aa18af8246f6..d552448c56b2b0c6bfad7287bba9950e92e176d8 100644 --- a/indra/newview/lltoolgrab.cpp +++ b/indra/newview/lltoolgrab.cpp @@ -122,7 +122,7 @@ void LLToolGrabBase::handleDeselect() if (!mValidSelection && (override_mask != MASK_NONE || (gFloaterTools && gFloaterTools->getVisible()))) { LLMenuGL::sMenuContainer->hideMenus(); - LLSelectMgr::getInstanceFast()->validateSelection(); + LLSelectMgr::getInstance()->validateSelection(); } } @@ -171,19 +171,19 @@ BOOL LLToolGrabBase::handleMouseDown(S32 x, S32 y, MASK mask) void LLToolGrabBase::pickCallback(const LLPickInfo& pick_info) { - LLToolGrab::getInstanceFast()->mGrabPick = pick_info; + LLToolGrab::getInstance()->mGrabPick = pick_info; LLViewerObject *objectp = pick_info.getObject(); BOOL extend_select = (pick_info.mKeyMask & MASK_SHIFT); - if (!extend_select && !LLSelectMgr::getInstanceFast()->getSelection()->isEmpty()) + if (!extend_select && !LLSelectMgr::getInstance()->getSelection()->isEmpty()) { - LLSelectMgr::getInstanceFast()->deselectAll(); - LLToolGrab::getInstanceFast()->mDeselectedThisClick = TRUE; + LLSelectMgr::getInstance()->deselectAll(); + LLToolGrab::getInstance()->mDeselectedThisClick = TRUE; } else { - LLToolGrab::getInstanceFast()->mDeselectedThisClick = FALSE; + LLToolGrab::getInstance()->mDeselectedThisClick = FALSE; } // if not over object, do nothing @@ -193,13 +193,13 @@ void LLToolGrabBase::pickCallback(const LLPickInfo& pick_info) if ( (!objectp) || ((RlvActions::isRlvEnabled()) && (!RlvActions::canTouch(objectp, pick_info.mObjectOffset))) ) // [/RLVa:KB] { - LLToolGrab::getInstanceFast()->setMouseCapture(TRUE); - LLToolGrab::getInstanceFast()->mMode = GRAB_NOOBJECT; - LLToolGrab::getInstanceFast()->mGrabPick.mObjectID.setNull(); + LLToolGrab::getInstance()->setMouseCapture(TRUE); + LLToolGrab::getInstance()->mMode = GRAB_NOOBJECT; + LLToolGrab::getInstance()->mGrabPick.mObjectID.setNull(); } else { - LLToolGrab::getInstanceFast()->handleObjectHit(LLToolGrab::getInstanceFast()->mGrabPick); + LLToolGrab::getInstance()->handleObjectHit(LLToolGrab::getInstance()->mGrabPick); } } @@ -310,7 +310,7 @@ BOOL LLToolGrabBase::handleObjectHit(const LLPickInfo& info) startSpin(); } - LLSelectMgr::getInstanceFast()->updateSelectionCenter(); // update selection beam + LLSelectMgr::getInstance()->updateSelectionCenter(); // update selection beam // update point at LLViewerObject *edit_object = info.getObject(); @@ -564,8 +564,8 @@ void LLToolGrabBase::handleHoverActive(S32 x, S32 y, MASK mask) const F32 RADIANS_PER_PIXEL_X = 0.01f; const F32 RADIANS_PER_PIXEL_Y = 0.01f; - S32 dx = x - (gViewerWindow->getWorldViewWidthScaled() / 2); - S32 dy = y - (gViewerWindow->getWorldViewHeightScaled() / 2); + S32 dx = gViewerWindow->getCurrentMouseDX(); + S32 dy = gViewerWindow->getCurrentMouseDY(); if (dx != 0 || dy != 0) { @@ -591,7 +591,7 @@ void LLToolGrabBase::handleHoverActive(S32 x, S32 y, MASK mask) LLQuaternion rotation_around_vertical( dx*RADIANS_PER_PIXEL_X, up ); // y motion maps to rotation around left axis - const LLVector3 &agent_left = LLViewerCamera::getInstanceFast()->getLeftAxis(); + const LLVector3 &agent_left = LLViewerCamera::getInstance()->getLeftAxis(); LLQuaternion rotation_around_left( dy*RADIANS_PER_PIXEL_Y, agent_left ); // compose with current rotation @@ -616,14 +616,14 @@ void LLToolGrabBase::handleHoverActive(S32 x, S32 y, MASK mask) //------------------------------------------------------ LLVector3d x_part; - x_part.setVec(LLViewerCamera::getInstanceFast()->getLeftAxis()); + x_part.setVec(LLViewerCamera::getInstance()->getLeftAxis()); x_part.mdV[VZ] = 0.0; x_part.normVec(); LLVector3d y_part; if( mVerticalDragging ) { - y_part.setVec(LLViewerCamera::getInstanceFast()->getUpAxis()); + y_part.setVec(LLViewerCamera::getInstance()->getUpAxis()); // y_part.setVec(0.f, 0.f, 1.f); } else @@ -665,7 +665,7 @@ void LLToolGrabBase::handleHoverActive(S32 x, S32 y, MASK mask) */ // Don't let object centers go underground. - F32 land_height = LLWorld::getInstanceFast()->resolveLandHeightGlobal(grab_point_global); + F32 land_height = LLWorld::getInstance()->resolveLandHeightGlobal(grab_point_global); if (grab_point_global.mdV[VZ] < land_height) { @@ -673,12 +673,12 @@ void LLToolGrabBase::handleHoverActive(S32 x, S32 y, MASK mask) } // For safety, cap heights where objects can be dragged - if (grab_point_global.mdV[VZ] > LLWorld::getInstanceFast()->getRegionMaxHeight()) + if (grab_point_global.mdV[VZ] > LLWorld::getInstance()->getRegionMaxHeight()) { - grab_point_global.mdV[VZ] = LLWorld::getInstanceFast()->getRegionMaxHeight(); + grab_point_global.mdV[VZ] = LLWorld::getInstance()->getRegionMaxHeight(); } - grab_point_global = LLWorld::getInstanceFast()->clipToVisibleRegions(mDragStartPointGlobal, grab_point_global); + grab_point_global = LLWorld::getInstance()->clipToVisibleRegions(mDragStartPointGlobal, grab_point_global); // propagate constrained grab point back to grab offset mGrabHiddenOffsetFromCamera = grab_point_global - gAgentCamera.getCameraPositionGlobal(); @@ -686,7 +686,7 @@ void LLToolGrabBase::handleHoverActive(S32 x, S32 y, MASK mask) LLVector3 grab_pos_agent = gAgent.getPosAgentFromGlobal( grab_point_global ); LLCoordGL grab_center_gl( gViewerWindow->getWorldViewWidthScaled() / 2, gViewerWindow->getWorldViewHeightScaled() / 2); - LLViewerCamera::getInstanceFast()->projectPosAgentToScreen(grab_pos_agent, grab_center_gl); + LLViewerCamera::getInstance()->projectPosAgentToScreen(grab_pos_agent, grab_center_gl); const S32 ROTATE_H_MARGIN = gViewerWindow->getWorldViewWidthScaled() / 20; const F32 ROTATE_ANGLE_PER_SECOND = 30.f * DEG_TO_RAD; @@ -746,7 +746,7 @@ void LLToolGrabBase::handleHoverActive(S32 x, S32 y, MASK mask) gViewerWindow->moveCursorToCenter(); - LLSelectMgr::getInstanceFast()->updateSelectionCenter(); + LLSelectMgr::getInstance()->updateSelectionCenter(); } @@ -845,14 +845,14 @@ void LLToolGrabBase::handleHoverNonPhysical(S32 x, S32 y, MASK mask) //------------------------------------------------------ LLVector3d x_part; - x_part.setVec(LLViewerCamera::getInstanceFast()->getLeftAxis()); + x_part.setVec(LLViewerCamera::getInstance()->getLeftAxis()); x_part.mdV[VZ] = 0.0; x_part.normVec(); LLVector3d y_part; if( mVerticalDragging ) { - y_part.setVec(LLViewerCamera::getInstanceFast()->getUpAxis()); + y_part.setVec(LLViewerCamera::getInstance()->getUpAxis()); // y_part.setVec(0.f, 0.f, 1.f); } else @@ -1069,7 +1069,7 @@ void LLToolGrabBase::onMouseCaptureLost() LLVector3 grab_point_agent = objectp->getRenderPosition(); LLCoordGL gl_point; - if (LLViewerCamera::getInstanceFast()->projectPosAgentToScreen(grab_point_agent, gl_point)) + if (LLViewerCamera::getInstance()->projectPosAgentToScreen(grab_point_agent, gl_point)) { LLUI::setMousePositionScreen(gl_point.mX, gl_point.mY); } @@ -1093,7 +1093,7 @@ void LLToolGrabBase::onMouseCaptureLost() mGrabPick.mObjectID.setNull(); - LLSelectMgr::getInstanceFast()->updateSelectionCenter(); + LLSelectMgr::getInstance()->updateSelectionCenter(); gAgentCamera.setPointAt(POINTAT_TARGET_CLEAR); gAgentCamera.setLookAt(LOOKAT_TARGET_CLEAR); diff --git a/indra/newview/lltoolgun.cpp b/indra/newview/lltoolgun.cpp index 9a65c4f7484d3edd2d0fc513d51ce775aba767a5..5c6bb60e939c10e10584adeaf1c1c6896484031b 100644 --- a/indra/newview/lltoolgun.cpp +++ b/indra/newview/lltoolgun.cpp @@ -91,9 +91,9 @@ void LLToolGun::handleDeselect() BOOL LLToolGun::handleMouseDown(S32 x, S32 y, MASK mask) { gGrabTransientTool = this; - LLToolMgr::getInstanceFast()->getCurrentToolset()->selectTool( LLToolGrab::getInstanceFast() ); + LLToolMgr::getInstance()->getCurrentToolset()->selectTool( LLToolGrab::getInstance() ); - return LLToolGrab::getInstanceFast()->handleMouseDown(x, y, mask); + return LLToolGrab::getInstance()->handleMouseDown(x, y, mask); } BOOL LLToolGun::handleHover(S32 x, S32 y, MASK mask) @@ -114,7 +114,7 @@ BOOL LLToolGun::handleHover(S32 x, S32 y, MASK mask) if (dx != 0 || dy != 0) { // ...actually moved off center - const F32 fov = LLViewerCamera::getInstanceFast()->getView() / DEFAULT_FIELD_OF_VIEW; + const F32 fov = LLViewerCamera::getInstance()->getView() / DEFAULT_FIELD_OF_VIEW; static LLCachedControl<bool> invert_mouse(gSavedSettings, "InvertMouse"); if (invert_mouse) { @@ -130,7 +130,7 @@ BOOL LLToolGun::handleHover(S32 x, S32 y, MASK mask) static LLCachedControl<bool> mouse_sun(gSavedSettings, "MouseSun"); if (mouse_sun) { - const LLVector3& sunpos = LLViewerCamera::getInstanceFast()->getAtAxis(); + const LLVector3& sunpos = LLViewerCamera::getInstance()->getAtAxis(); gSky.setSunDirectionCFR(sunpos); gSavedSettings.setVector3("SkySunDefaultPosition", sunpos); } @@ -138,7 +138,7 @@ BOOL LLToolGun::handleHover(S32 x, S32 y, MASK mask) static LLCachedControl<bool> mouse_moon(gSavedSettings, "MouseMoon"); if (mouse_moon) { - const LLVector3& moonpos = LLViewerCamera::getInstanceFast()->getAtAxis(); + const LLVector3& moonpos = LLViewerCamera::getInstance()->getAtAxis(); gSky.setMoonDirectionCFR(moonpos); gSavedSettings.setVector3("SkyMoonDefaultPosition", moonpos); } @@ -187,11 +187,11 @@ void LLToolGun::draw() bool target_rendered = false; LLVector3d myPosition = gAgentCamera.getCameraPositionGlobal(); - LLQuaternion myRotation = LLViewerCamera::getInstanceFast()->getQuaternion(); + LLQuaternion myRotation = LLViewerCamera::getInstance()->getQuaternion(); myRotation.set(-myRotation.mQ[VX], -myRotation.mQ[VY], -myRotation.mQ[VZ], myRotation.mQ[VW]); LLWorld::pos_map_t positions; - LLWorld::getInstanceFast()->getAvatars(&positions, gAgent.getPositionGlobal(), iff_range); + LLWorld::getInstance()->getAvatars(&positions, gAgent.getPositionGlobal(), iff_range); for (const auto& position : positions) { const auto& id = position.first; diff --git a/indra/newview/lltoolindividual.cpp b/indra/newview/lltoolindividual.cpp index 3df391783789146f333e0d21b550d8e771a5cbcb..885c1442a0c1704cf84513b07d5b72609c297c3c 100644 --- a/indra/newview/lltoolindividual.cpp +++ b/indra/newview/lltoolindividual.cpp @@ -75,16 +75,16 @@ BOOL LLToolIndividual::handleMouseDown(S32 x, S32 y, MASK mask) void LLToolIndividual::pickCallback(const LLPickInfo& pick_info) { LLViewerObject* obj = pick_info.getObject(); - LLSelectMgr::getInstanceFast()->deselectAll(); + LLSelectMgr::getInstance()->deselectAll(); if(obj) { - LLSelectMgr::getInstanceFast()->selectObjectOnly(obj); + LLSelectMgr::getInstance()->selectObjectOnly(obj); } } BOOL LLToolIndividual::handleDoubleClick(S32 x, S32 y, MASK mask) { - if(!LLSelectMgr::getInstanceFast()->getSelection()->isEmpty()) + if(!LLSelectMgr::getInstance()->getSelection()->isEmpty()) { // You should already have an object selected from the mousedown. // If so, show its inventory. @@ -102,11 +102,11 @@ BOOL LLToolIndividual::handleDoubleClick(S32 x, S32 y, MASK mask) void LLToolIndividual::handleSelect() { const BOOL children_ok = TRUE; - LLViewerObject* obj = LLSelectMgr::getInstanceFast()->getSelection()->getFirstRootObject(children_ok); - LLSelectMgr::getInstanceFast()->deselectAll(); + LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getFirstRootObject(children_ok); + LLSelectMgr::getInstance()->deselectAll(); if(obj) { - LLSelectMgr::getInstanceFast()->selectObjectOnly(obj); + LLSelectMgr::getInstance()->selectObjectOnly(obj); } } diff --git a/indra/newview/lltoolmgr.cpp b/indra/newview/lltoolmgr.cpp index 21eb2af5d5d23036dea1ab7396bf625c2a0a3b17..64f7874e7b27cd9794c4cae136f5dfdd42388442 100644 --- a/indra/newview/lltoolmgr.cpp +++ b/indra/newview/lltoolmgr.cpp @@ -226,14 +226,14 @@ LLTool* LLToolMgr::getCurrentTool() } if (cur_tool) { - if ( LLToolCompInspect::getInstanceFast()->isToolCameraActive() - && prev_tool == LLToolCamera::getInstanceFast() - && cur_tool == LLToolPie::getInstanceFast() ) + if ( LLToolCompInspect::getInstance()->isToolCameraActive() + && prev_tool == LLToolCamera::getInstance() + && cur_tool == LLToolPie::getInstance() ) { LLFloaterInspect * inspect_instance = LLFloaterReg::findTypedInstance<LLFloaterInspect>("inspect"); if(inspect_instance && inspect_instance->getVisible()) { - setTransientTool(LLToolCompInspect::getInstanceFast()); + setTransientTool(LLToolCompInspect::getInstance()); } } else @@ -260,13 +260,13 @@ void LLToolMgr::updateToolStatus() bool LLToolMgr::inEdit() { - return mBaseTool != LLToolPie::getInstanceFast() && mBaseTool != gToolNull; + return mBaseTool != LLToolPie::getInstance() && mBaseTool != gToolNull; } bool LLToolMgr::canEdit() { // [RLVa:KB] - Patch: RLVa-2.1.0 - return LLViewerParcelMgr::getInstanceFast()->allowAgentBuild() && RlvActions::canBuild(); + return LLViewerParcelMgr::getInstance()->allowAgentBuild() && RlvActions::canBuild(); // [/RLVa:KB] // return LLViewerParcelMgr::getInstance()->allowAgentBuild(); } @@ -325,7 +325,7 @@ void LLToolMgr::enterBuildMode(bool verify_canedit /*=false*/) if (gSavedSettings.getBOOL("EditCameraMovement")) { // camera should be set - if (LLViewerJoystick::getInstanceFast()->getOverrideCamera()) + if (LLViewerJoystick::getInstance()->getOverrideCamera()) { handle_toggle_flycam(); } @@ -342,7 +342,7 @@ void LLToolMgr::enterBuildMode(bool verify_canedit /*=false*/) setCurrentToolset(gBasicToolset); - getCurrentToolset()->selectTool( LLToolCompCreate::getInstanceFast() ); + getCurrentToolset()->selectTool( LLToolCompCreate::getInstance() ); // Could be first use //LLFirstUse::useBuild(); @@ -350,7 +350,7 @@ void LLToolMgr::enterBuildMode(bool verify_canedit /*=false*/) gAgentCamera.resetView(false); // avoid spurious avatar movements - LLViewerJoystick::getInstanceFast()->setNeedsReset(); + LLViewerJoystick::getInstance()->setNeedsReset(); } // [RLVa:KB] - Checked: RLVa-2.1.0 @@ -381,7 +381,7 @@ void LLToolMgr::leaveBuildMode() gViewerWindow->showCursor(); } // avoid spurious avatar movements pulling out of edit mode - LLViewerJoystick::getInstanceFast()->setNeedsReset(); + LLViewerJoystick::getInstance()->setNeedsReset(); } } @@ -490,7 +490,7 @@ void LLToolset::addTool(LLTool* tool) void LLToolset::selectTool(LLTool* tool) { mSelectedTool = tool; - LLToolMgr::getInstanceFast()->setCurrentTool( mSelectedTool ); + LLToolMgr::getInstance()->setCurrentTool( mSelectedTool ); } @@ -500,7 +500,7 @@ void LLToolset::selectToolByIndex( S32 index ) if (tool) { mSelectedTool = tool; - LLToolMgr::getInstanceFast()->setCurrentTool( tool ); + LLToolMgr::getInstance()->setCurrentTool( tool ); } } @@ -514,7 +514,7 @@ BOOL LLToolset::isToolSelected( S32 index ) void LLToolset::selectFirstTool() { mSelectedTool = (0 < mToolList.size()) ? mToolList[0] : NULL; - LLToolMgr::getInstanceFast()->setCurrentTool( mSelectedTool ); + LLToolMgr::getInstance()->setCurrentTool( mSelectedTool ); } @@ -535,7 +535,7 @@ void LLToolset::selectNextTool() if( next ) { mSelectedTool = next; - LLToolMgr::getInstanceFast()->setCurrentTool( mSelectedTool ); + LLToolMgr::getInstance()->setCurrentTool( mSelectedTool ); } else { @@ -560,7 +560,7 @@ void LLToolset::selectPrevTool() if( prev ) { mSelectedTool = prev; - LLToolMgr::getInstanceFast()->setCurrentTool( mSelectedTool ); + LLToolMgr::getInstance()->setCurrentTool( mSelectedTool ); } else if (mToolList.size() > 0) { diff --git a/indra/newview/lltoolmorph.cpp b/indra/newview/lltoolmorph.cpp index 198d135af4d025858042be894f773a33972721a3..449e2e344a221bad0c5605e30fb8329932b657d9 100644 --- a/indra/newview/lltoolmorph.cpp +++ b/indra/newview/lltoolmorph.cpp @@ -195,10 +195,7 @@ BOOL LLVisualParamHint::render() gGL.pushMatrix(); gGL.loadIdentity(); - if (LLGLSLShader::sNoFixedFunction) - { - gUIProgram.bind(); - } + gUIProgram.bind(); LLGLSUIDefault gls_ui; //LLGLState::verify(TRUE); @@ -234,25 +231,24 @@ BOOL LLVisualParamHint::render() gGL.flush(); - LLViewerCamera::getInstanceFast()->setAspect((F32)mFullWidth / (F32)mFullHeight); - LLViewerCamera::getInstanceFast()->setOriginAndLookAt( + LLViewerCamera::getInstance()->setAspect((F32)mFullWidth / (F32)mFullHeight); + LLViewerCamera::getInstance()->setOriginAndLookAt( camera_pos, // camera LLVector3::z_axis, // up target_pos ); // point of interest - LLViewerCamera::getInstanceFast()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, FALSE); + LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, FALSE); + + if (gAgentAvatarp->mDrawable.notNull()) + { + LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE); + gGL.flush(); + gGL.setSceneBlendType(LLRender::BT_REPLACE); + gPipeline.generateImpostor(gAgentAvatarp, true); + gGL.setSceneBlendType(LLRender::BT_ALPHA); + gGL.flush(); + } - if (gAgentAvatarp->mDrawable.notNull() && - gAgentAvatarp->mDrawable->getFace(0)) - { - LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)gAgentAvatarp->mDrawable->getFace(0)->getPool(); - LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE); - gGL.setAlphaRejectSettings(LLRender::CF_ALWAYS); - gGL.setSceneBlendType(LLRender::BT_REPLACE); - avatarPoolp->renderAvatars(gAgentAvatarp); // renders only one avatar - gGL.setSceneBlendType(LLRender::BT_ALPHA); - gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); - } gAgentAvatarp->setVisualParamWeight(mVisualParam->getID(), mLastParamWeight, false); mWearablePtr->setVisualParamWeight(mVisualParam->getID(), mLastParamWeight, false); LLViewerWearable* wearable = (LLViewerWearable*)mWearablePtr; diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index 1d96fa4f1bbb783162be48cc502f9d5f7feff9e1..a54c96161b3f34b63650cc73f39f906982e500b8 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -204,7 +204,7 @@ BOOL LLToolPie::handleRightMouseDown(S32 x, S32 y, MASK mask) BOOL LLToolPie::handleRightMouseUp(S32 x, S32 y, MASK mask) { - LLToolMgr::getInstanceFast()->clearTransientTool(); + LLToolMgr::getInstance()->clearTransientTool(); return LLTool::handleRightMouseUp(x, y, mask); } @@ -243,12 +243,12 @@ BOOL LLToolPie::handleLeftClickPick() MASK mask = mPick.mKeyMask; if (mPick.mPickType == LLPickInfo::PICK_PARCEL_WALL) { - LLParcel* parcel = LLViewerParcelMgr::getInstanceFast()->getCollisionParcel(); + LLParcel* parcel = LLViewerParcelMgr::getInstance()->getCollisionParcel(); if (parcel) { - LLViewerParcelMgr::getInstanceFast()->selectCollisionParcel(); + LLViewerParcelMgr::getInstance()->selectCollisionParcel(); if (parcel->getParcelFlag(PF_USE_PASS_LIST) - && !LLViewerParcelMgr::getInstanceFast()->isCollisionBanned()) + && !LLViewerParcelMgr::getInstance()->isCollisionBanned()) { // if selling passes, just buy one void* deselect_when_done = (void*)TRUE; @@ -271,7 +271,7 @@ BOOL LLToolPie::handleLeftClickPick() if (mPick.mPickType != LLPickInfo::PICK_LAND) { - LLViewerParcelMgr::getInstanceFast()->deselectLand(); + LLViewerParcelMgr::getInstance()->deselectLand(); } if (object) @@ -354,7 +354,7 @@ BOOL LLToolPie::handleLeftClickPick() // pay event goes to object actually clicked on mClickActionObject = object; mLeftClickSelection = LLToolSelect::handleObjectSelection(mPick, FALSE, TRUE); - if (LLSelectMgr::getInstanceFast()->selectGetAllValid()) + if (LLSelectMgr::getInstance()->selectGetAllValid()) { // call this right away, since we have all the info we need to continue the action selectionPropertiesReceived(); @@ -368,7 +368,7 @@ BOOL LLToolPie::handleLeftClickPick() { mClickActionObject = parent; mLeftClickSelection = LLToolSelect::handleObjectSelection(mPick, FALSE, TRUE, TRUE); - if (LLSelectMgr::getInstanceFast()->selectGetAllValid()) + if (LLSelectMgr::getInstance()->selectGetAllValid()) { // call this right away, since we have all the info we need to continue the action selectionPropertiesReceived(); @@ -381,7 +381,7 @@ BOOL LLToolPie::handleLeftClickPick() { mClickActionObject = parent; mLeftClickSelection = LLToolSelect::handleObjectSelection(mPick, FALSE, TRUE, TRUE); - if (LLSelectMgr::getInstanceFast()->selectGetAllValid()) + if (LLSelectMgr::getInstance()->selectGetAllValid()) { // call this right away, since we have all the info we need to continue the action selectionPropertiesReceived(); @@ -405,10 +405,10 @@ BOOL LLToolPie::handleLeftClickPick() gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE); LLBBox bbox = object->getBoundingBoxAgent() ; - F32 angle_of_view = llmax(0.1f, LLViewerCamera::getInstanceFast()->getAspect() > 1.f ? LLViewerCamera::getInstanceFast()->getView() * LLViewerCamera::getInstanceFast()->getAspect() : LLViewerCamera::getInstanceFast()->getView()); + F32 angle_of_view = llmax(0.1f, LLViewerCamera::getInstance()->getAspect() > 1.f ? LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect() : LLViewerCamera::getInstance()->getView()); F32 distance = bbox.getExtentLocal().magVec() * PADDING_FACTOR / atan(angle_of_view); - LLVector3 obj_to_cam = LLViewerCamera::getInstanceFast()->getOrigin() - bbox.getCenterAgent(); + LLVector3 obj_to_cam = LLViewerCamera::getInstance()->getOrigin() - bbox.getCenterAgent(); obj_to_cam.normVec(); LLVector3d object_center_global = gAgent.getPosGlobalFromAgent(bbox.getCenterAgent()); @@ -452,9 +452,9 @@ BOOL LLToolPie::handleLeftClickPick() gGrabTransientTool = this; mMouseButtonDown = false; - LLToolGrab::getInstanceFast()->setClickedInMouselook(gAgentCamera.cameraMouselook()); - LLToolMgr::getInstanceFast()->getCurrentToolset()->selectTool( LLToolGrab::getInstanceFast() ); - return LLToolGrab::getInstanceFast()->handleObjectHit( mPick ); + LLToolGrab::getInstance()->setClickedInMouselook(gAgentCamera.cameraMouselook()); + LLToolMgr::getInstance()->getCurrentToolset()->selectTool( LLToolGrab::getInstance() ); + return LLToolGrab::getInstance()->handleObjectHit( mPick ); } LLHUDIcon* last_hit_hud_icon = mPick.mHUDIcon; @@ -485,10 +485,10 @@ BOOL LLToolPie::handleLeftClickPick() { // we left clicked on avatar, switch to focus mode mMouseButtonDown = false; - LLToolMgr::getInstanceFast()->setTransientTool(LLToolCamera::getInstanceFast()); + LLToolMgr::getInstance()->setTransientTool(LLToolCamera::getInstance()); gViewerWindow->hideCursor(); - LLToolCamera::getInstanceFast()->setMouseCapture(TRUE); - LLToolCamera::getInstanceFast()->pickCallback(mPick); + LLToolCamera::getInstance()->setMouseCapture(TRUE); + LLToolCamera::getInstance()->pickCallback(mPick); gAgentCamera.setFocusOnAvatar(TRUE, TRUE); return TRUE; @@ -563,7 +563,7 @@ ECursorType LLToolPie::cursorFromObject(LLViewerObject* object) case CLICK_ACTION_BUY: if ( mClickActionBuyEnabled ) { - LLSelectNode* node = LLSelectMgr::getInstanceFast()->getHoverNode(); + LLSelectNode* node = LLSelectMgr::getInstance()->getHoverNode(); if (!node || node->mSaleInfo.isForSale()) { // [RLVa:KB] - @buy @@ -668,7 +668,7 @@ bool LLToolPie::walkToClickedLocation() { const F64 SELF_CLICK_WALK_DISTANCE = 3.0; // pretend we picked some point a bit in front of avatar - mPick.mPosGlobal = gAgent.getPositionGlobal() + LLVector3d(LLViewerCamera::instanceFast().getAtAxis()) * SELF_CLICK_WALK_DISTANCE; + mPick.mPosGlobal = gAgent.getPositionGlobal() + LLVector3d(LLViewerCamera::instance().getAtAxis()) * SELF_CLICK_WALK_DISTANCE; } // if ((mPick.mPickType == LLPickInfo::PICK_LAND && !mPick.mPosGlobal.isExactlyZero()) || @@ -777,7 +777,7 @@ void LLToolPie::selectionPropertiesReceived() { // Make sure all data has been received. // This function will be called repeatedly as the data comes in. - if (!LLSelectMgr::getInstanceFast()->selectGetAllValid()) + if (!LLSelectMgr::getInstance()->selectGetAllValid()) { return; } @@ -832,7 +832,7 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask) return TRUE; } // [/RLVa:KB] - LLSelectMgr::getInstanceFast()->setHoverObject(object, mHoverPick.mObjectFace); + LLSelectMgr::getInstance()->setHoverObject(object, mHoverPick.mObjectFace); if (object) { parent = object->getRootEdit(); @@ -965,7 +965,7 @@ BOOL LLToolPie::handleMouseUp(S32 x, S32 y, MASK mask) setMouseCapture(FALSE); } - LLToolMgr::getInstanceFast()->clearTransientTool(); + LLToolMgr::getInstance()->clearTransientTool(); gAgentCamera.setLookAt(LOOKAT_TARGET_CONVERSATION, obj); // maybe look at object/person clicked on return LLTool::handleMouseUp(x, y, mask); @@ -1017,12 +1017,12 @@ BOOL LLToolPie::handleTooltipLand(std::string line, std::string tooltip_msg) static const LLCachedControl<bool> show_land_hover_tips(gSavedSettings, "ShowLandHoverTip"); if (!show_land_hover_tips) return TRUE; - LLViewerParcelMgr::getInstanceFast()->setHoverParcel( mHoverPick.mPosGlobal ); + LLViewerParcelMgr::getInstance()->setHoverParcel( mHoverPick.mPosGlobal ); // Didn't hit an object, but since we have a land point we // must be hovering over land. - LLParcel* hover_parcel = LLViewerParcelMgr::getInstanceFast()->getHoverParcel(); + LLParcel* hover_parcel = LLViewerParcelMgr::getInstance()->getHoverParcel(); LLUUID owner; if ( hover_parcel ) @@ -1254,7 +1254,7 @@ BOOL LLToolPie::handleTooltipObject( LLViewerObject* hover_object, std::string l // Default prefs will suppress display unless the object is interactive // static const LLCachedControl<bool> show_all_object_tips(gSavedSettings, "ShowAllObjectHoverTip"); - LLSelectNode *nodep = LLSelectMgr::getInstanceFast()->getHoverNode(); + LLSelectNode *nodep = LLSelectMgr::getInstance()->getHoverNode(); // only show tooltip if same inspector not already open LLFloater* existing_inspector = LLFloaterReg::findInstance("inspect_object"); @@ -1299,7 +1299,7 @@ BOOL LLToolPie::handleTooltipObject( LLViewerObject* hover_object, std::string l const LLMediaEntry* mep = has_media ? tep->getMediaData() : NULL; if (mep) { - viewer_media_t media_impl = LLViewerMedia::getInstanceFast()->getMediaImplFromTextureID(mep->getMediaID()); + viewer_media_t media_impl = LLViewerMedia::getInstance()->getMediaImplFromTextureID(mep->getMediaID()); LLPluginClassMedia* media_plugin = NULL; if (media_impl.notNull() && (media_impl->hasMedia())) @@ -1338,7 +1338,7 @@ BOOL LLToolPie::handleTooltipObject( LLViewerObject* hover_object, std::string l for_sale) && (has_media || needs_tooltip(nodep) || - needs_tooltip(LLSelectMgr::getInstanceFast()->getPrimaryHoverNode())); + needs_tooltip(LLSelectMgr::getInstance()->getPrimaryHoverNode())); if (show_all_object_tips || needs_tip) { @@ -1390,7 +1390,7 @@ BOOL LLToolPie::handleToolTip(S32 local_x, S32 local_y, MASK mask) // [/RLVa:KB] // update hover object and hover parcel - LLSelectMgr::getInstanceFast()->setHoverObject(hover_object, mHoverPick.mObjectFace); + LLSelectMgr::getInstance()->setHoverObject(hover_object, mHoverPick.mObjectFace); std::string tooltip_msg; @@ -1466,7 +1466,7 @@ void LLToolPie::showObjectInspector(const LLUUID& object_id, const S32& object_f void LLToolPie::playCurrentMedia(const LLPickInfo& info) { //FIXME: how do we handle object in different parcel than us? - LLParcel* parcel = LLViewerParcelMgr::getInstanceFast()->getAgentParcel(); + LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); if (!parcel) return; LLPointer<LLViewerObject> objectp = info.getObject(); @@ -1493,7 +1493,7 @@ void LLToolPie::playCurrentMedia(const LLPickInfo& info) LLPluginClassMedia* media_plugin = NULL; - viewer_media_t media_impl = LLViewerMedia::getInstanceFast()->getMediaImplFromTextureID(mep->getMediaID()); + viewer_media_t media_impl = LLViewerMedia::getInstance()->getMediaImplFromTextureID(mep->getMediaID()); if(media_impl.notNull() && media_impl->hasMedia()) { @@ -1518,7 +1518,7 @@ void LLToolPie::playCurrentMedia(const LLPickInfo& info) void LLToolPie::VisitHomePage(const LLPickInfo& info) { //FIXME: how do we handle object in different parcel than us? - LLParcel* parcel = LLViewerParcelMgr::getInstanceFast()->getAgentParcel(); + LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); if (!parcel) return; LLPointer<LLViewerObject> objectp = info.getObject(); @@ -1545,7 +1545,7 @@ void LLToolPie::VisitHomePage(const LLPickInfo& info) LLPluginClassMedia* media_plugin = NULL; - viewer_media_t media_impl = LLViewerMedia::getInstanceFast()->getMediaImplFromTextureID(mep->getMediaID()); + viewer_media_t media_impl = LLViewerMedia::getInstance()->getMediaImplFromTextureID(mep->getMediaID()); if(media_impl.notNull() && media_impl->hasMedia()) { @@ -1570,7 +1570,7 @@ void LLToolPie::handleDeselect() setMouseCapture( FALSE ); // Calls onMouseCaptureLost() indirectly } // remove temporary selection for pie menu - LLSelectMgr::getInstanceFast()->setHoverObject(NULL); + LLSelectMgr::getInstance()->setHoverObject(NULL); // Menu may be still up during transfer to different tool. // toolfocus and toolgrab should retain menu, they will clear it if needed @@ -1579,7 +1579,7 @@ void LLToolPie::handleDeselect() { // in most cases menu is useless without correct selection, so either keep both or discard both gMenuHolder->hideMenus(); - LLSelectMgr::getInstanceFast()->validateSelection(); + LLSelectMgr::getInstance()->validateSelection(); } } @@ -1642,7 +1642,7 @@ void LLToolPie::render() static void handle_click_action_play() { - LLParcel* parcel = LLViewerParcelMgr::getInstanceFast()->getAgentParcel(); + LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); if (!parcel) return; LLViewerMediaImpl::EMediaStatus status = LLViewerParcelMedia::getInstance()->getStatus(); @@ -1665,7 +1665,7 @@ static void handle_click_action_play() bool LLToolPie::handleMediaClick(const LLPickInfo& pick) { //FIXME: how do we handle object in different parcel than us? - LLParcel* parcel = LLViewerParcelMgr::getInstanceFast()->getAgentParcel(); + LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); LLPointer<LLViewerObject> objectp = pick.getObject(); @@ -1688,7 +1688,7 @@ bool LLToolPie::handleMediaClick(const LLPickInfo& pick) if (!mep) return false; - viewer_media_t media_impl = LLViewerMedia::getInstanceFast()->getMediaImplFromTextureID(mep->getMediaID()); + viewer_media_t media_impl = LLViewerMedia::getInstance()->getMediaImplFromTextureID(mep->getMediaID()); if (gSavedSettings.getBOOL("MediaOnAPrimUI")) { @@ -1719,7 +1719,7 @@ bool LLToolPie::handleMediaClick(const LLPickInfo& pick) bool LLToolPie::handleMediaDblClick(const LLPickInfo& pick) { //FIXME: how do we handle object in different parcel than us? - LLParcel* parcel = LLViewerParcelMgr::getInstanceFast()->getAgentParcel(); + LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); LLPointer<LLViewerObject> objectp = pick.getObject(); @@ -1742,7 +1742,7 @@ bool LLToolPie::handleMediaDblClick(const LLPickInfo& pick) if (!mep) return false; - viewer_media_t media_impl = LLViewerMedia::getInstanceFast()->getMediaImplFromTextureID(mep->getMediaID()); + viewer_media_t media_impl = LLViewerMedia::getInstance()->getMediaImplFromTextureID(mep->getMediaID()); if (gSavedSettings.getBOOL("MediaOnAPrimUI")) { @@ -1773,7 +1773,7 @@ bool LLToolPie::handleMediaDblClick(const LLPickInfo& pick) bool LLToolPie::handleMediaHover(const LLPickInfo& pick) { //FIXME: how do we handle object in different parcel than us? - LLParcel* parcel = LLViewerParcelMgr::getInstanceFast()->getAgentParcel(); + LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); if (!parcel) return false; LLPointer<LLViewerObject> objectp = pick.getObject(); @@ -1797,7 +1797,7 @@ bool LLToolPie::handleMediaHover(const LLPickInfo& pick) if (mep && gSavedSettings.getBOOL("MediaOnAPrimUI")) { - viewer_media_t media_impl = LLViewerMedia::getInstanceFast()->getMediaImplFromTextureID(mep->getMediaID()); + viewer_media_t media_impl = LLViewerMedia::getInstance()->getMediaImplFromTextureID(mep->getMediaID()); if(media_impl.notNull()) { @@ -1835,7 +1835,7 @@ bool LLToolPie::handleMediaMouseUp() if(mMediaMouseCaptureID.notNull()) { // Face media needs to know the mouse went up. - viewer_media_t media_impl = LLViewerMedia::getInstanceFast()->getMediaImplFromTextureID(mMediaMouseCaptureID); + viewer_media_t media_impl = LLViewerMedia::getInstance()->getMediaImplFromTextureID(mMediaMouseCaptureID); if(media_impl) { // This will send a mouseUp event to the plugin using the last known mouse coordinate (from a mouseDown or mouseMove), which is what we want. @@ -1853,7 +1853,7 @@ bool LLToolPie::handleMediaMouseUp() static void handle_click_action_open_media(LLPointer<LLViewerObject> objectp) { //FIXME: how do we handle object in different parcel than us? - LLParcel* parcel = LLViewerParcelMgr::getInstanceFast()->getAgentParcel(); + LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); if (!parcel) return; // did we hit an object? @@ -1864,7 +1864,7 @@ static void handle_click_action_open_media(LLPointer<LLViewerObject> objectp) if( face < 0 || face >= objectp->getNumTEs() ) return; // is media playing on this face? - if (LLViewerMedia::getInstanceFast()->getMediaImplFromTextureID(objectp->getTE(face)->getID()) != NULL) + if (LLViewerMedia::getInstance()->getMediaImplFromTextureID(objectp->getTE(face)->getID()) != NULL) { handle_click_action_play(); return; @@ -1884,7 +1884,7 @@ static ECursorType cursor_from_parcel_media(U8 click_action) //FIXME: how do we handle object in different parcel than us? ECursorType open_cursor = UI_CURSOR_ARROW; - LLParcel* parcel = LLViewerParcelMgr::getInstanceFast()->getAgentParcel(); + LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); if (!parcel) return open_cursor; open_cursor = UI_CURSOR_TOOLMEDIAOPEN; @@ -1909,7 +1909,7 @@ BOOL LLToolPie::handleRightClickPick() if (mPick.mPickType != LLPickInfo::PICK_LAND) { - LLViewerParcelMgr::getInstanceFast()->deselectLand(); + LLViewerParcelMgr::getInstance()->deselectLand(); } // didn't click in any UI object, so must have clicked in the world @@ -1921,7 +1921,7 @@ BOOL LLToolPie::handleRightClickPick() // Spawn pie menu if (mPick.mPickType == LLPickInfo::PICK_LAND) { - LLParcelSelectionHandle selection = LLViewerParcelMgr::getInstanceFast()->selectParcelAt( mPick.mPosGlobal ); + LLParcelSelectionHandle selection = LLViewerParcelMgr::getInstance()->selectParcelAt( mPick.mPosGlobal ); gMenuHolder->setParcelSelection(selection); gMenuLand->show(x, y); @@ -1941,7 +1941,7 @@ BOOL LLToolPie::handleRightClickPick() } else if (object) { - gMenuHolder->setObjectSelection(LLSelectMgr::getInstanceFast()->getSelection()); + gMenuHolder->setObjectSelection(LLSelectMgr::getInstance()->getSelection()); bool is_other_attachment = (object->isAttachment() && !object->isHUDAttachment() && !object->permYouOwner()); if (object->isAvatar() || is_other_attachment) @@ -1962,7 +1962,7 @@ BOOL LLToolPie::handleRightClickPick() LLVOAvatar* avatar = (LLVOAvatar*)object; std::string name = avatar->getFullname(); std::string mute_msg; - if (LLMuteList::getInstanceFast()->isMuted(avatar->getID(), avatar->getFullname())) + if (LLMuteList::getInstance()->isMuted(avatar->getID(), avatar->getFullname())) { mute_msg = LLTrans::getString("UnmuteAvatar"); } @@ -1973,7 +1973,7 @@ BOOL LLToolPie::handleRightClickPick() // [RLVa:KB] - Checked: 2010-04-11 (RLVa-1.2.0e) | Modified: RLVa-1.1.0l // Don't show the context menu on empty selection when fartouch restricted [see LLToolSelect::handleObjectSelection()] - if ( (!rlv_handler_t::isEnabled()) || (!LLSelectMgr::getInstanceFast()->getSelection()->isEmpty()) || + if ( (!rlv_handler_t::isEnabled()) || (!LLSelectMgr::getInstance()->getSelection()->isEmpty()) || (!gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) ) { // [/RLVa:KB] @@ -2003,7 +2003,7 @@ BOOL LLToolPie::handleRightClickPick() { // BUG: What about chatting child objects? std::string name; - LLSelectNode* node = LLSelectMgr::getInstanceFast()->getSelection()->getFirstRootNode(); + LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(); if (node) { name = node->mName; @@ -2012,7 +2012,7 @@ BOOL LLToolPie::handleRightClickPick() // [RLVa:KB] - Checked: 2010-04-11 (RLVa-1.2.el) | Modified: RLVa-1.1.0l // Don't show the pie menu on empty selection when fartouch/interaction restricted // (not entirely accurate in case of Tools / Select Only XXX [see LLToolSelect::handleObjectSelection()] - if ( (!rlv_handler_t::isEnabled()) || (!LLSelectMgr::getInstanceFast()->getSelection()->isEmpty()) || + if ( (!rlv_handler_t::isEnabled()) || (!LLSelectMgr::getInstance()->getSelection()->isEmpty()) || (!gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) ) { // [/RLVa:KB] @@ -2118,20 +2118,20 @@ void LLToolPie::startCameraSteering() if (avatar_object && ((LLVOAvatar*)avatar_object)->isSelf()) { // ...project pick point a few meters in front of avatar - mSteerPick.mPosGlobal = gAgent.getPositionGlobal() + LLVector3d(LLViewerCamera::instanceFast().getAtAxis()) * 3.0; + mSteerPick.mPosGlobal = gAgent.getPositionGlobal() + LLVector3d(LLViewerCamera::instance().getAtAxis()) * 3.0; } if (!mSteerPick.isValid()) { mSteerPick.mPosGlobal = gAgent.getPosGlobalFromAgent( - LLViewerCamera::instanceFast().getOrigin() + gViewerWindow->mouseDirectionGlobal(mSteerPick.mMousePt.mX, mSteerPick.mMousePt.mY) * 100.f); + LLViewerCamera::instance().getOrigin() + gViewerWindow->mouseDirectionGlobal(mSteerPick.mMousePt.mX, mSteerPick.mMousePt.mY) * 100.f); } setMouseCapture(TRUE); mMouseSteerX = mMouseDownX; mMouseSteerY = mMouseDownY; - const LLVector3 camera_to_rotation_center = gAgent.getFrameAgent().getOrigin() - LLViewerCamera::instanceFast().getOrigin(); + const LLVector3 camera_to_rotation_center = gAgent.getFrameAgent().getOrigin() - LLViewerCamera::instance().getOrigin(); const LLVector3 rotation_center_to_pick = gAgent.getPosAgentFromGlobal(mSteerPick.mPosGlobal) - gAgent.getFrameAgent().getOrigin(); mClockwise = camera_to_rotation_center * rotation_center_to_pick < 0.f; @@ -2146,7 +2146,7 @@ void LLToolPie::startCameraSteering() void LLToolPie::steerCameraWithMouse(S32 x, S32 y) { - const LLViewerCamera& camera = LLViewerCamera::instanceFast(); + const LLViewerCamera& camera = LLViewerCamera::instance(); const LLCoordFrame& rotation_frame = gAgent.getFrameAgent(); const LLVector3 pick_pos = gAgent.getPosAgentFromGlobal(mSteerPick.mPosGlobal); const LLVector3 pick_rotation_center = rotation_frame.getOrigin() + parallel_component(pick_pos - rotation_frame.getOrigin(), rotation_frame.getUpAxis()); diff --git a/indra/newview/lltoolpipette.cpp b/indra/newview/lltoolpipette.cpp index 17d3297e0a05e4e6c9f172a0d6f27adbcd855ef5..ff3dad26757367d2dcc7256622bd95d19f638445 100644 --- a/indra/newview/lltoolpipette.cpp +++ b/indra/newview/lltoolpipette.cpp @@ -69,9 +69,9 @@ BOOL LLToolPipette::handleMouseDown(S32 x, S32 y, MASK mask) BOOL LLToolPipette::handleMouseUp(S32 x, S32 y, MASK mask) { mSuccess = TRUE; - LLSelectMgr::getInstanceFast()->unhighlightAll(); + LLSelectMgr::getInstance()->unhighlightAll(); // *NOTE: This assumes the pipette tool is a transient tool. - LLToolMgr::getInstanceFast()->clearTransientTool(); + LLToolMgr::getInstance()->clearTransientTool(); setMouseCapture(FALSE); return TRUE; } @@ -115,7 +115,7 @@ void LLToolPipette::setTextureEntry(const LLTextureEntry* entry) void LLToolPipette::pickCallback(const LLPickInfo& pick_info) { LLViewerObject* hit_obj = pick_info.getObject(); - LLSelectMgr::getInstanceFast()->unhighlightAll(); + LLSelectMgr::getInstance()->unhighlightAll(); // if we clicked on a face of a valid prim, save off texture entry data if (hit_obj && @@ -123,9 +123,9 @@ void LLToolPipette::pickCallback(const LLPickInfo& pick_info) pick_info.mObjectFace != -1) { //TODO: this should highlight the selected face only - LLSelectMgr::getInstanceFast()->highlightObjectOnly(hit_obj); + LLSelectMgr::getInstance()->highlightObjectOnly(hit_obj); const LLTextureEntry* entry = hit_obj->getTE(pick_info.mObjectFace); - LLToolPipette::getInstanceFast()->setTextureEntry(entry); + LLToolPipette::getInstance()->setTextureEntry(entry); } } diff --git a/indra/newview/lltoolplacer.cpp b/indra/newview/lltoolplacer.cpp index a46676e8932fed87858ac3c8e009bb9289cfe391..8ebd470bb4e87fe61c531722af017dcc2ffcfddc 100644 --- a/indra/newview/lltoolplacer.cpp +++ b/indra/newview/lltoolplacer.cpp @@ -162,7 +162,7 @@ BOOL LLToolPlacer::raycastForNewObjPos( S32 x, S32 y, LLViewerObject** hit_obj, // [/RLVa:KB] // Find the sim where the surface lives. - LLViewerRegion *regionp = LLWorld::getInstanceFast()->getRegionFromPosGlobal(surface_pos_global); + LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(surface_pos_global); if (!regionp) { LL_WARNS() << "Trying to add object outside of all known regions!" << LL_ENDL; @@ -175,8 +175,8 @@ BOOL LLToolPlacer::raycastForNewObjPos( S32 x, S32 y, LLViewerObject** hit_obj, *region = regionp; *ray_start_region = regionp->getPosRegionFromGlobal( ray_start_global ); - F32 near_clip = LLViewerCamera::getInstanceFast()->getNear() + 0.01f; // Include an epsilon to avoid rounding issues. - *ray_start_region += LLViewerCamera::getInstanceFast()->getAtAxis() * near_clip; + F32 near_clip = LLViewerCamera::getInstance()->getNear() + 0.01f; // Include an epsilon to avoid rounding issues. + *ray_start_region += LLViewerCamera::getInstance()->getAtAxis() * near_clip; if( bypass_sim_raycast ) { @@ -463,7 +463,7 @@ BOOL LLToolPlacer::addObject( LLPCode pcode, S32 x, S32 y, U8 use_physics ) // Spawns a message, so must be after above send if (create_selected) { - LLSelectMgr::getInstanceFast()->deselectAll(); + LLSelectMgr::getInstance()->deselectAll(); gViewerWindow->getWindow()->incBusyCount(); } @@ -519,7 +519,7 @@ BOOL LLToolPlacer::addDuplicate(S32 x, S32 y) ray_target_id.setNull(); } - LLSelectMgr::getInstanceFast()->selectDuplicateOnRay(ray_start_region, + LLSelectMgr::getInstance()->selectDuplicateOnRay(ray_start_region, ray_end_region, b_hit_land, // suppress raycast FALSE, // intersection @@ -561,7 +561,7 @@ BOOL LLToolPlacer::placeObject(S32 x, S32 y, MASK mask) // ...and go back to the default tool if (added && !gSavedSettings.getBOOL("CreateToolKeepSelected")) { - LLToolMgr::getInstanceFast()->getCurrentToolset()->selectTool( LLToolCompTranslate::getInstance() ); + LLToolMgr::getInstance()->getCurrentToolset()->selectTool( LLToolCompTranslate::getInstance() ); } return added; diff --git a/indra/newview/lltoolselect.cpp b/indra/newview/lltoolselect.cpp index b5d1d7dce8b0a5ef557065be99faeddfece30d33..b6de45b09dc72e765c93a46e2e28c7d55649ca81 100644 --- a/indra/newview/lltoolselect.cpp +++ b/indra/newview/lltoolselect.cpp @@ -94,9 +94,9 @@ LLObjectSelectionHandle LLToolSelect::handleObjectSelection(const LLPickInfo& pi if (!RlvActions::canEdit(object)) { if (!temp_select) - return LLSelectMgr::getInstanceFast()->getSelection(); - else if (LLToolMgr::instanceFast().inBuildMode()) - LLToolMgr::instanceFast().leaveBuildMode(); + return LLSelectMgr::getInstance()->getSelection(); + else if (LLToolMgr::instance().inBuildMode()) + LLToolMgr::instance().leaveBuildMode(); } if ( (RlvActions::hasBehaviour(RLV_BHVR_FARTOUCH)) && ( (!object->isAttachment()) || (!object->permYouOwner())) ) @@ -112,13 +112,13 @@ LLObjectSelectionHandle LLToolSelect::handleObjectSelection(const LLPickInfo& pi { // Even the surface point is out of range so deny them the hit if ( (LLFloaterReg::instanceVisible("build")) && (pick.mKeyMask != MASK_SHIFT) && (pick.mKeyMask != MASK_CONTROL) ) - LLSelectMgr::getInstanceFast()->deselectAll(); - return LLSelectMgr::getInstanceFast()->getSelection(); + LLSelectMgr::getInstance()->deselectAll(); + return LLSelectMgr::getInstance()->getSelection(); } - else if (LLToolMgr::instanceFast().inBuildMode()) + else if (LLToolMgr::instance().inBuildMode()) { // Allow the selection but keep it temporary by pulling them out of build mode when they click too far - LLToolMgr::instanceFast().leaveBuildMode(); + LLToolMgr::instance().leaveBuildMode(); } } } @@ -129,11 +129,11 @@ LLObjectSelectionHandle LLToolSelect::handleObjectSelection(const LLPickInfo& pi BOOL select_movable = gSavedSettings.getBOOL("SelectMovableOnly"); // *NOTE: These settings must be cleaned up at bottom of function. - if (temp_select || LLSelectMgr::getInstanceFast()->mAllowSelectAvatar) + if (temp_select || LLSelectMgr::getInstance()->mAllowSelectAvatar) { gSavedSettings.setBOOL("SelectOwnedOnly", FALSE); gSavedSettings.setBOOL("SelectMovableOnly", FALSE); - LLSelectMgr::getInstanceFast()->setForceSelection(TRUE); + LLSelectMgr::getInstance()->setForceSelection(TRUE); } BOOL extend_select = (pick.mKeyMask == MASK_SHIFT) || (pick.mKeyMask == MASK_CONTROL); @@ -149,7 +149,7 @@ LLObjectSelectionHandle LLToolSelect::handleObjectSelection(const LLPickInfo& pi } else if (!extend_select) { - LLSelectMgr::getInstanceFast()->deselectAll(); + LLSelectMgr::getInstance()->deselectAll(); } } else @@ -158,7 +158,7 @@ LLObjectSelectionHandle LLToolSelect::handleObjectSelection(const LLPickInfo& pi if (already_selected && object->getNumTEs() > 0 && - !LLSelectMgr::getInstanceFast()->getSelection()->contains(object,SELECT_ALL_TES)) + !LLSelectMgr::getInstance()->getSelection()->contains(object,SELECT_ALL_TES)) { const LLTextureEntry* tep = object->getTE(pick.mObjectFace); if (tep && !tep->isSelected() && !LLViewerMediaFocus::getInstance()->getFocusedObjectID().isNull()) @@ -177,22 +177,22 @@ LLObjectSelectionHandle LLToolSelect::handleObjectSelection(const LLPickInfo& pi { if ( ignore_group ) { - LLSelectMgr::getInstanceFast()->deselectObjectOnly(object); + LLSelectMgr::getInstance()->deselectObjectOnly(object); } else { - LLSelectMgr::getInstanceFast()->deselectObjectAndFamily(object, TRUE, TRUE); + LLSelectMgr::getInstance()->deselectObjectAndFamily(object, TRUE, TRUE); } } else { if ( ignore_group ) { - LLSelectMgr::getInstanceFast()->selectObjectOnly(object, SELECT_ALL_TES); + LLSelectMgr::getInstance()->selectObjectOnly(object, SELECT_ALL_TES); } else { - LLSelectMgr::getInstanceFast()->selectObjectAndFamily(object); + LLSelectMgr::getInstance()->selectObjectAndFamily(object); } } } @@ -201,27 +201,27 @@ LLObjectSelectionHandle LLToolSelect::handleObjectSelection(const LLPickInfo& pi // Save the current zoom values because deselect resets them. F32 target_zoom; F32 current_zoom; - LLSelectMgr::getInstanceFast()->getAgentHUDZoom(target_zoom, current_zoom); + LLSelectMgr::getInstance()->getAgentHUDZoom(target_zoom, current_zoom); // JC - Change behavior to make it easier to select children // of linked sets. 9/3/2002 if( !already_selected || ignore_group) { // ...lose current selection in favor of just this object - LLSelectMgr::getInstanceFast()->deselectAll(); + LLSelectMgr::getInstance()->deselectAll(); } if ( ignore_group ) { - LLSelectMgr::getInstanceFast()->selectObjectOnly(object, SELECT_ALL_TES); + LLSelectMgr::getInstance()->selectObjectOnly(object, SELECT_ALL_TES); } else { - LLSelectMgr::getInstanceFast()->selectObjectAndFamily(object); + LLSelectMgr::getInstance()->selectObjectAndFamily(object); } // restore the zoom to the previously stored values. - LLSelectMgr::getInstanceFast()->setAgentHUDZoom(target_zoom, current_zoom); + LLSelectMgr::getInstance()->setAgentHUDZoom(target_zoom, current_zoom); } static LLCachedControl<bool> disablePointAt(gSavedSettings, "AlchemyPointAtPrivate", false); @@ -230,7 +230,7 @@ LLObjectSelectionHandle LLToolSelect::handleObjectSelection(const LLPickInfo& pi object != gAgentAvatarp) // and it's not you { // have avatar turn to face the selected object(s) - LLVector3d selection_center = LLSelectMgr::getInstanceFast()->getSelectionCenterGlobal(); + LLVector3d selection_center = LLSelectMgr::getInstance()->getSelectionCenterGlobal(); selection_center = selection_center - gAgent.getPositionGlobal(); LLVector3 selection_dir; selection_dir.setVec(selection_center); @@ -255,7 +255,7 @@ LLObjectSelectionHandle LLToolSelect::handleObjectSelection(const LLPickInfo& pi if (!already_selected) { LLViewerObject* root_object = (LLViewerObject*)object->getRootEdit(); - LLObjectSelectionHandle selection = LLSelectMgr::getInstanceFast()->getSelection(); + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); // this is just a temporary selection LLSelectNode* select_node = selection->findNode(root_object); @@ -281,14 +281,14 @@ LLObjectSelectionHandle LLToolSelect::handleObjectSelection(const LLPickInfo& pi } //if(!object) // Cleanup temp select settings above. - if (temp_select ||LLSelectMgr::getInstanceFast()->mAllowSelectAvatar) + if (temp_select ||LLSelectMgr::getInstance()->mAllowSelectAvatar) { gSavedSettings.setBOOL("SelectOwnedOnly", select_owned); gSavedSettings.setBOOL("SelectMovableOnly", select_movable); - LLSelectMgr::getInstanceFast()->setForceSelection(FALSE); + LLSelectMgr::getInstance()->setForceSelection(FALSE); } - return LLSelectMgr::getInstanceFast()->getSelection(); + return LLSelectMgr::getInstance()->getSelection(); } BOOL LLToolSelect::handleMouseUp(S32 x, S32 y, MASK mask) @@ -321,7 +321,7 @@ void LLToolSelect::onMouseCaptureLost() { // Finish drag - LLSelectMgr::getInstanceFast()->enableSilhouette(TRUE); + LLSelectMgr::getInstance()->enableSilhouette(TRUE); // Clean up drag-specific variables mIgnoreGroup = FALSE; diff --git a/indra/newview/lltoolselectrect.cpp b/indra/newview/lltoolselectrect.cpp index 39bf19cf9bad8c54a48fea5979a01e3d5c5d2e3a..202c5b99f9582046ef9eb97b487f9d2fd0712258 100644 --- a/indra/newview/lltoolselectrect.cpp +++ b/indra/newview/lltoolselectrect.cpp @@ -108,11 +108,11 @@ BOOL LLToolSelectRect::handleMouseUp(S32 x, S32 y, MASK mask) if (mask == MASK_CONTROL) { - LLSelectMgr::getInstanceFast()->deselectHighlightedObjects(); + LLSelectMgr::getInstance()->deselectHighlightedObjects(); } else { - LLSelectMgr::getInstanceFast()->selectHighlightedObjects(); + LLSelectMgr::getInstance()->selectHighlightedObjects(); } return TRUE; } @@ -132,7 +132,7 @@ BOOL LLToolSelectRect::handleHover(S32 x, S32 y, MASK mask) if (!mMouseOutsideSlop && !(mask & MASK_SHIFT) && !(mask & MASK_CONTROL)) { // just started rect select, and not adding to current selection - LLSelectMgr::getInstanceFast()->deselectAll(); + LLSelectMgr::getInstance()->deselectAll(); } mMouseOutsideSlop = TRUE; mDragEndX = x; diff --git a/indra/newview/lltracker.cpp b/indra/newview/lltracker.cpp index 09d4b5d75e6c9fb76212c77f23ce3ab99a7cf459..4285acf91ad538ec859a071f63f9402856b098ac 100644 --- a/indra/newview/lltracker.cpp +++ b/indra/newview/lltracker.cpp @@ -110,8 +110,16 @@ void LLTracker::stopTracking(bool clear_ui) // static virtual void LLTracker::drawHUDArrow() { - static const LLCachedControl<bool> render_tracker_beacon(gSavedSettings, "RenderTrackerBeacon"); - if (!render_tracker_beacon) return; + if (!LLWorld::instanceExists()) + { + return; + } + + static LLCachedControl<bool> render_beacon(gSavedSettings, "RenderTrackerBeacon", true); + if (!render_beacon) + { + return; + } if (gViewerWindow->getProgressView()->getVisible()) return; @@ -148,7 +156,7 @@ void LLTracker::drawHUDArrow() 0.9f * instance()->mTrackedPositionGlobal.mdV[VZ] + 0.1f * (LLWorld::getInstance()->resolveLandHeightGlobal(getTrackedPositionGlobal()) + 1.5f); #endif - instance()->mTrackedPositionGlobal.mdV[VZ] = llclamp((F32)instance()->mTrackedPositionGlobal.mdV[VZ], LLWorld::getInstanceFast()->resolveLandHeightGlobal(getTrackedPositionGlobal()) + 1.5f, (F32)instance()->getTrackedPositionGlobal().mdV[VZ]); + instance()->mTrackedPositionGlobal.mdV[VZ] = llclamp((F32)instance()->mTrackedPositionGlobal.mdV[VZ], LLWorld::getInstance()->resolveLandHeightGlobal(getTrackedPositionGlobal()) + 1.5f, (F32)instance()->getTrackedPositionGlobal().mdV[VZ]); instance()->drawMarker( getTrackedPositionGlobal(), map_track_color ); break; @@ -505,7 +513,7 @@ void LLTracker::drawBeacon(LLVector3 pos_agent, std::string direction, LLColor4 gGL.color4fv(fogged_color.mV); - LLVector3 x_axis = LLViewerCamera::getInstanceFast()->getLeftAxis(); + LLVector3 x_axis = LLViewerCamera::getInstance()->getLeftAxis(); F32 t = gRenderStartTime.getElapsedTimeF32(); for (U32 i = 0; i < BEACON_VERTS; i++) @@ -563,14 +571,14 @@ void LLTracker::renderBeacon(LLVector3d pos_global, F32 dist = (F32)to_vec.magVec(); F32 color_frac = 1.f; - if (dist > 0.99f * LLViewerCamera::getInstanceFast()->getFar()) + if (dist > 0.99f * LLViewerCamera::getInstance()->getFar()) { color_frac = 0.4f; // pos_global = gAgentCamera.getCameraPositionGlobal() + 0.99f*(LLViewerCamera::getInstance()->getFar()/dist)*to_vec; } else { - color_frac = 1.f - 0.6f*(dist/LLViewerCamera::getInstanceFast()->getFar()); + color_frac = 1.f - 0.6f*(dist/LLViewerCamera::getInstance()->getFar()); } LLColor4 fogged_color = color_frac * color + (1 - color_frac)*gSky.getSkyFogColor(); @@ -684,9 +692,9 @@ void LLTracker::drawMarker(const LLVector3d& pos_global, const LLColor4& color, S32 y = 0; const BOOL CLAMP = TRUE; - bool on_screen = LLViewerCamera::getInstanceFast()->projectPosAgentToScreen(pos_local, screen, CLAMP); + bool on_screen = LLViewerCamera::getInstance()->projectPosAgentToScreen(pos_local, screen, CLAMP); if (on_screen && is_iff) return; - if (on_screen || LLViewerCamera::getInstanceFast()->projectPosAgentToScreenEdge(pos_local, screen) ) + if (on_screen || LLViewerCamera::getInstance()->projectPosAgentToScreenEdge(pos_local, screen) ) { gHUDView->screenPointToLocal(screen.mX, screen.mY, &x, &y); diff --git a/indra/newview/llurldispatcher.cpp b/indra/newview/llurldispatcher.cpp index 3d2ef077c5d6abee9f538507793e996b6fe00771..10f6622ad1062c3ad7fddea855b199ab313927d4 100644 --- a/indra/newview/llurldispatcher.cpp +++ b/indra/newview/llurldispatcher.cpp @@ -208,7 +208,7 @@ bool LLURLDispatcherImpl::dispatchRegion(const LLSLURL& slurl, const std::string } // Request a region handle by name - LLWorldMapMessage::getInstanceFast()->sendNamedRegionRequest(slurl.getRegion(), + LLWorldMapMessage::getInstance()->sendNamedRegionRequest(slurl.getRegion(), LLURLDispatcherImpl::regionNameCallback, slurl.getSLURLString(), LLUI::getInstance()->mSettingGroups["config"]->getBOOL("SLURLTeleportDirectly")); // don't teleport @@ -365,7 +365,7 @@ class LLTeleportHandler : public LLCommandHandler, public LLEventAPI static void teleport_via_slapp(std::string region_name, std::string callback_url) { - LLWorldMapMessage::getInstanceFast()->sendNamedRegionRequest(region_name, + LLWorldMapMessage::getInstance()->sendNamedRegionRequest(region_name, LLURLDispatcherImpl::regionHandleCallback, callback_url, true); // teleport diff --git a/indra/newview/llviewerassetstorage.cpp b/indra/newview/llviewerassetstorage.cpp index 31b7f6d52cfdc7da9d4892803b8931e3985f4529..121b5b8e09b9c8930cd5ea70d02d647660f2807a 100644 --- a/indra/newview/llviewerassetstorage.cpp +++ b/indra/newview/llviewerassetstorage.cpp @@ -461,7 +461,7 @@ void LLViewerAssetStorage::queueRequestHttp( void LLViewerAssetStorage::capsRecvForRegion(const LLUUID& region_id, std::string pumpname) { - LLViewerRegion *regionp = LLWorld::instanceFast().getRegionFromID(region_id); + LLViewerRegion *regionp = LLWorld::instance().getRegionFromID(region_id); if (!regionp) { LL_WARNS("ViewerAsset") << "region not found for region_id " << region_id << LL_ENDL; diff --git a/indra/newview/llviewerassettype.cpp b/indra/newview/llviewerassettype.cpp index 750df51d9348b5a1b6c6bda27b920cec0370e91b..75eed356d34bb703da11e71671352cbd82d965c0 100644 --- a/indra/newview/llviewerassettype.cpp +++ b/indra/newview/llviewerassettype.cpp @@ -92,7 +92,7 @@ LLViewerAssetDictionary::LLViewerAssetDictionary() EDragAndDropType LLViewerAssetType::lookupDragAndDropType(EType asset_type) { - const LLViewerAssetDictionary *dict = LLViewerAssetDictionary::getInstanceFast(); + const LLViewerAssetDictionary *dict = LLViewerAssetDictionary::getInstance(); const ViewerAssetEntry *entry = dict->lookup(asset_type); if (entry) return entry->mDadType; diff --git a/indra/newview/llviewerassetupload.cpp b/indra/newview/llviewerassetupload.cpp index e5f795360c1e975b24b60a1e8962c34c49a20699..3f498bfe1b717fc8ff290c5a762266b746d4bda4 100644 --- a/indra/newview/llviewerassetupload.cpp +++ b/indra/newview/llviewerassetupload.cpp @@ -51,6 +51,10 @@ #include "llpreviewnotecard.h" #include "llpreviewgesture.h" #include "llcoproceduremanager.h" +#include "llthread.h" +#include "llkeyframemotion.h" +#include "lldatapacker.h" +#include "llvoavatarself.h" #include "lldatapacker.h" #include "llbvhloader.h" #include "llbvhconsts.h" @@ -491,9 +495,62 @@ LLSD LLNewFileResourceUploadInfo::exportTempFile() } infile.close(); } - else if (assetType == LLAssetType::AT_ANIMATION) + else if (exten == "anim") + { + // Default unless everything succeeds + errorLabel = "ProblemWithFile"; + error = true; + + // read from getFileName() + LLAPRFile infile; + infile.open(getFileName(),LL_APR_RB); + if (!infile.getFileHandle()) + { + LL_WARNS() << "Couldn't open file for reading: " << getFileName() << LL_ENDL; + errorMessage = llformat("Failed to open animation file %s\n", getFileName().c_str()); + } + else + { + S32 size = LLAPRFile::size(getFileName()); + U8* buffer = new U8[size]; + S32 size_read = infile.read(buffer,size); + if (size_read != size) + { + errorMessage = llformat("Failed to read animation file %s: wanted %d bytes, got %d\n", getFileName().c_str(), size, size_read); + } + else + { + LLDataPackerBinaryBuffer dp(buffer, size); + LLKeyframeMotion *motionp = new LLKeyframeMotion(getAssetId()); + motionp->setCharacter(gAgentAvatarp); + if (motionp->deserialize(dp, getAssetId(), false)) + { + // write to temp file + bool succ = motionp->dumpToFile(filename); + if (succ) + { + assetType = LLAssetType::AT_ANIMATION; + errorLabel = ""; + error = false; + } + else + { + errorMessage = "Failed saving temporary animation file"; + } + } + else + { + errorMessage = "Failed reading animation file"; + } + } + } + } + else { - filename = getFileName(); + // Unknown extension + errorMessage = llformat(LLTrans::getString("UnknownFileExtension").c_str(), exten.c_str()); + errorLabel = "ErrorMessage"; + error = TRUE;; } if (error) @@ -911,6 +968,7 @@ void LLViewerAssetUpload::HandleUploadError(LLCore::HttpStatus status, LLSD &res { args["FILE"] = uploadInfo->getDisplayName(); args["REASON"] = reason; + args["ERROR"] = reason; } LLNotificationsUtil::add(label, args); diff --git a/indra/newview/llvieweraudio.cpp b/indra/newview/llvieweraudio.cpp index 66c42f743b16fe781aa1027f9117685cb484a7a6..ea22680fe08f62567f57244e0e76a69129c6dac3 100644 --- a/indra/newview/llvieweraudio.cpp +++ b/indra/newview/llvieweraudio.cpp @@ -350,8 +350,8 @@ void init_audio() gAudiop->setListener(lpos_global_f, LLVector3::zero, // LLViewerCamera::getInstance()->getVelocity(), // !!! BUG need to replace this with smoothed velocity! - LLViewerCamera::getInstanceFast()->getUpAxis(), - LLViewerCamera::getInstanceFast()->getAtAxis()); + LLViewerCamera::getInstance()->getUpAxis(), + LLViewerCamera::getInstance()->getAtAxis()); // load up our initial set of sounds we'll want so they're in memory and ready to be played @@ -427,7 +427,7 @@ void audio_update_volume(bool force_update) static const LLCachedControl<F32> rolloff_volume(gSavedSettings, "AudioLevelRolloff"); static const LLCachedControl<F32> underwater_rolloff_volume(gSavedSettings, "AudioLevelUnderwaterRolloff"); - if(!LLViewerCamera::getInstanceFast()->cameraUnderWater()) + if(!LLViewerCamera::getInstance()->cameraUnderWater()) gAudiop->setRolloffFactor(rolloff_volume); else gAudiop->setRolloffFactor(underwater_rolloff_volume); @@ -437,7 +437,7 @@ void audio_update_volume(bool force_update) //Play any deferred sounds when unmuted if(!gAudiop->getMuted()) { - LLDeferredSounds::instanceFast().playdeferredSounds(); + LLDeferredSounds::instance().playdeferredSounds(); } if (force_update) @@ -458,15 +458,15 @@ void audio_update_volume(bool force_update) // Streaming Music - if (!progress_view_visible && LLViewerAudio::getInstanceFast()->getForcedTeleportFade()) + if (!progress_view_visible && LLViewerAudio::getInstance()->getForcedTeleportFade()) { - LLViewerAudio::getInstanceFast()->setWasPlaying(!gAudiop->getInternetStreamURL().empty()); - LLViewerAudio::getInstanceFast()->setForcedTeleportFade(false); + LLViewerAudio::getInstance()->setWasPlaying(!gAudiop->getInternetStreamURL().empty()); + LLViewerAudio::getInstance()->setForcedTeleportFade(false); } static const LLCachedControl<F32> music_volume_setting(gSavedSettings, "AudioLevelMusic"); static const LLCachedControl<bool> music_muted(gSavedSettings, "MuteMusic"); - const F32 fade_volume = LLViewerAudio::getInstanceFast()->getFadeVolume(); + const F32 fade_volume = LLViewerAudio::getInstance()->getFadeVolume(); const F32 music_volume = mute_volume * master_volume * music_volume_setting * fade_volume; gAudiop->setInternetStreamGain (music_muted ? 0.f : music_volume); @@ -476,7 +476,7 @@ void audio_update_volume(bool force_update) static const LLCachedControl<F32> media_volume_setting(gSavedSettings, "AudioLevelMedia"); static const LLCachedControl<bool> media_muted(gSavedSettings, "MuteMedia"); const F32 media_volume = mute_volume * master_volume * media_volume_setting; - LLViewerMedia::getInstanceFast()->setVolume( media_muted ? 0.0f : media_volume ); + LLViewerMedia::getInstance()->setVolume( media_muted ? 0.0f : media_volume ); // Voice, this is parametric singleton, it gets initialized when ready if (LLVoiceClient::instanceExists()) @@ -485,7 +485,7 @@ void audio_update_volume(bool force_update) static const LLCachedControl<bool> voice_mute(gSavedSettings, "MuteVoice"); static const LLCachedControl<F32> mic_volume(gSavedSettings, "AudioLevelMic"); const F32 voice_volume = mute_volume * master_volume * voice_volume_setting; - LLVoiceClient *voice_inst = LLVoiceClient::getInstanceFast(); + LLVoiceClient *voice_inst = LLVoiceClient::getInstance(); voice_inst->setVoiceVolume(voice_mute ? 0.f : voice_volume); voice_inst->setMicGain(voice_mute ? 0.f : mic_volume); @@ -513,8 +513,8 @@ void audio_update_listener() // LLViewerCamera::getInstance()VelocitySmoothed, // LLVector3::zero, gAgent.getVelocity(), // !!! *TODO: need to replace this with smoothed velocity! - LLViewerCamera::getInstanceFast()->getUpAxis(), - LLViewerCamera::getInstanceFast()->getAtAxis()); + LLViewerCamera::getInstance()->getUpAxis(), + LLViewerCamera::getInstance()->getAtAxis()); } } diff --git a/indra/newview/llvieweraudio.h b/indra/newview/llvieweraudio.h index ef5560c5070e04e9515f7b736bf2f48e663d1ac0..652e403381a360f355443f0916d022d9eb540066 100644 --- a/indra/newview/llvieweraudio.h +++ b/indra/newview/llvieweraudio.h @@ -33,8 +33,6 @@ // comment out to turn off wind #define kAUDIO_ENABLE_WIND //#define kAUDIO_ENABLE_WATER 1 // comment out to turn off water -#define kAUDIO_NUM_BUFFERS 30 -#define kAUDIO_NUM_SOURCES 30 void init_audio(); void audio_update_volume(bool force_update = true); diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp index 47fee65b54f158093fb1e73780f598140327b333..4bea1c49f04bd1cbd755acbe985299543c571c5e 100644 --- a/indra/newview/llviewercamera.cpp +++ b/indra/newview/llviewercamera.cpp @@ -63,9 +63,6 @@ LLTrace::CountStatHandle<> LLViewerCamera::sAngularVelocityStat("camera_angular_ LLViewerCamera::eCameraID LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; -// Build time optimization, generate this once in .cpp file -template class LLViewerCamera* LLSingleton<class LLViewerCamera>::getInstance(); - LLViewerCamera::LLViewerCamera() : LLCamera() { calcProjection(getFar()); @@ -87,7 +84,7 @@ void LLViewerCamera::updateCameraLocation(const LLVector3 ¢er, const LLVector3 &point_of_interest) { // do not update if avatar didn't move - if (!LLViewerJoystick::getInstanceFast()->getCameraNeedsUpdate()) + if (!LLViewerJoystick::getInstance()->getCameraNeedsUpdate()) { return; } diff --git a/indra/newview/llviewercamera.h b/indra/newview/llviewercamera.h index 1716b7c872e7a1630b218a5ee057a2f2e391c4e8..7f33a9ad041881866190b92ed22e9d4cb68d4bed 100644 --- a/indra/newview/llviewercamera.h +++ b/indra/newview/llviewercamera.h @@ -35,29 +35,14 @@ #include "lltrace.h" class LLViewerObject; - const BOOL FOR_SELECTION = TRUE; const BOOL NOT_FOR_SELECTION = FALSE; -// Build time optimization, generate this once in .cpp file -#ifndef LLVIEWERCAMERA_CPP -extern template class LLViewerCamera* LLSingleton<class LLViewerCamera>::getInstance(); -#endif - -LL_ALIGN_PREFIX(16) -class LLViewerCamera final : public LLCamera, public LLSingleton<LLViewerCamera> +class alignas(16) LLViewerCamera final : public LLCamera, public LLSimpleton<LLViewerCamera> { - LLSINGLETON(LLViewerCamera); + LL_ALIGN_NEW public: - void* operator new(size_t size) - { - return ll_aligned_malloc_16(size); - } - - void operator delete(void* ptr) - { - ll_aligned_free_16(ptr); - } + LLViewerCamera(); typedef enum { @@ -149,7 +134,7 @@ class LLViewerCamera final : public LLCamera, public LLSingleton<LLViewerCamera> S16 mZoomSubregion; public: -} LL_ALIGN_POSTFIX(16); +}; #endif // LL_LLVIEWERCAMERA_H diff --git a/indra/newview/llviewerchat.cpp b/indra/newview/llviewerchat.cpp index ed3e7435928c4f29a5b2c6243c5d2f38ab033ec5..9a1ce36737618764dd469b65958bdc065df91ff4 100644 --- a/indra/newview/llviewerchat.cpp +++ b/indra/newview/llviewerchat.cpp @@ -262,7 +262,7 @@ std::string LLViewerChat::getObjectImSLURL(const LLChat& chat, const LLSD& args) std::string slurl = args["slurl"].asString(); if (slurl.empty()) { - LLViewerRegion *region = LLWorld::getInstanceFast()->getRegionFromPosAgent(chat.mPosAgent); + LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosAgent(chat.mPosAgent); if(region) { LLSLURL region_slurl(region->getName(), chat.mPosAgent); diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 454d680927efb17fc71561448acc6c3600a31242..19125c85c40fb6885eacd687c2d96ebe36efd8cb 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -115,10 +115,14 @@ static bool handleRenderAvatarMouselookChanged(const LLSD& newvalue) static bool handleRenderFarClipChanged(const LLSD& newvalue) { - F32 draw_distance = (F32) newvalue.asReal(); + if (LLStartUp::getStartupState() >= STATE_STARTED) + { + F32 draw_distance = (F32)newvalue.asReal(); gAgentCamera.mDrawDistance = draw_distance; - LLWorld::getInstanceFast()->setLandFarClip(draw_distance); + LLWorld::getInstance()->setLandFarClip(draw_distance); return true; + } + return false; } static bool handleTerrainDetailChanged(const LLSD& newvalue) @@ -148,7 +152,7 @@ static bool handleAvatarHoverOffsetChanged(const LLSD& newvalue) static bool handleSetShaderChanged(const LLSD& newvalue) { // [RLVa:KB] - @setenv and @setsphere - if ( (RlvActions::isRlvEnabled()) && (!RlvActions::canChangeEnvironment() || (LLVfxManager::instanceFast().hasEffect(EVisualEffect::RlvSphere))) && + if ( (RlvActions::isRlvEnabled()) && (!RlvActions::canChangeEnvironment() || (LLVfxManager::instance().hasEffect(EVisualEffect::RlvSphere))) && (LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders"))&& (!gSavedSettings.getBOOL("WindLightUseAtmosShaders")) ) { gSavedSettings.setBOOL("WindLightUseAtmosShaders", TRUE); @@ -179,17 +183,6 @@ static bool handleSetShaderChanged(const LLSD& newvalue) return true; } -static bool handleAvatarVPChanged(const LLSD& newvalue) -{ - LLRenderTarget::sUseFBO = newvalue.asBoolean() - && gSavedSettings.getBOOL("RenderObjectBump") - && gSavedSettings.getBOOL("RenderTransparentWater") - && gSavedSettings.getBOOL("RenderDeferred"); - - handleSetShaderChanged(LLSD()); - return true; -} - static bool handleRenderPerfTestChanged(const LLSD& newvalue) { bool status = !newvalue.asBoolean(); @@ -229,10 +222,6 @@ static bool handleRenderPerfTestChanged(const LLSD& newvalue) bool handleRenderTransparentWaterChanged(const LLSD& newvalue) { - LLRenderTarget::sUseFBO = newvalue.asBoolean() - && gSavedSettings.getBOOL("RenderObjectBump") - && gSavedSettings.getBOOL("RenderAvatarVP") - && gSavedSettings.getBOOL("RenderDeferred"); if (gPipeline.isInit()) { gPipeline.updateRenderTransparentWater(); @@ -242,7 +231,7 @@ bool handleRenderTransparentWaterChanged(const LLSD& newvalue) gPipeline.resetVertexBuffers(); LLViewerShaderMgr::instance()->setShaders(); } - LLWorld::getInstanceFast()->updateWaterObjects(); + LLWorld::getInstance()->updateWaterObjects(); return true; } @@ -298,6 +287,13 @@ static bool validateAnisotropicFiltering(const LLSD& val) return filter_level == 0 || filter_level == 2 || filter_level == 4 || filter_level == 8 || filter_level == 16; } +static bool handleVSyncChanged(const LLSD& newvalue) +{ + gViewerWindow->getWindow()->toggleVSync(newvalue.asBoolean()); + + return true; +} + static bool handleVolumeLODChanged(const LLSD& newvalue) { LLVOVolume::sLODFactor = llclamp((F32) newvalue.asReal(), 0.01f, MAX_LOD_FACTOR); @@ -424,7 +420,7 @@ static bool handleJoystickChanged(const LLSD& newvalue) static bool handleUseOcclusionChanged(const LLSD& newvalue) { - LLPipeline::sUseOcclusion = (newvalue.asBoolean() && gGLManager.mHasOcclusionQuery && LLGLSLShader::sNoFixedFunction + LLPipeline::sUseOcclusion = (newvalue.asBoolean() && gGLManager.mHasOcclusionQuery && LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion") && !gUseWireframe) ? 2 : 0; return true; } @@ -501,10 +497,7 @@ static bool handleRenderDeferredChanged(const LLSD& newvalue) // static bool handleRenderBumpChanged(const LLSD& newval) { - LLRenderTarget::sUseFBO = newval.asBoolean() - && gSavedSettings.getBOOL("RenderTransparentWater") - && gSavedSettings.getBOOL("RenderAvatarVP") - && gSavedSettings.getBOOL("RenderDeferred"); + LLRenderTarget::sUseFBO = newval.asBoolean() && gSavedSettings.getBOOL("RenderDeferred"); if (gPipeline.isInit()) { gPipeline.updateRenderBump(); @@ -517,13 +510,6 @@ static bool handleRenderBumpChanged(const LLSD& newval) return true; } -static bool handleRenderDebugGLChanged(const LLSD& newvalue) -{ - gDebugGL = newvalue.asBoolean() || gDebugSession; - gGL.clearErrors(); - return true; -} - static bool handleRenderDebugPipelineChanged(const LLSD& newvalue) { gDebugPipeline = newvalue.asBoolean(); @@ -692,165 +678,193 @@ bool toggle_show_object_render_cost(const LLSD& newvalue) void handleRenderAutoMuteByteLimitChanged(const LLSD& new_value); //////////////////////////////////////////////////////////////////////////// +LLPointer<LLControlVariable> setting_get_control(LLControlGroup& group, const std::string& setting) +{ + LLPointer<LLControlVariable> cntrl_ptr = group.getControl(setting); + if (cntrl_ptr.isNull()) + { + LL_ERRS() << "Unable to set up setting listener for " << setting + << ". Please reinstall viewer from https ://secondlife.com/support/downloads/ and contact https://support.secondlife.com if issue persists after reinstall." + << LL_ENDL; + } + return cntrl_ptr; +} + +void setting_setup_signal_listener(LLControlGroup& group, const std::string& setting, std::function<void(const LLSD& newvalue)> callback) +{ + setting_get_control(group, setting)->getSignal()->connect([callback](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) + { + callback(new_val); + }); +} + +void setting_setup_signal_listener(LLControlGroup& group, const std::string& setting, std::function<void()> callback) +{ + setting_get_control(group, setting)->getSignal()->connect([callback](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) + { + callback(); + }); +} + void settings_setup_listeners() { - gSavedSettings.getControl("FirstPersonAvatarVisible")->getSignal()->connect(boost::bind(&handleRenderAvatarMouselookChanged, _2)); - gSavedSettings.getControl("RenderFarClip")->getSignal()->connect(boost::bind(&handleRenderFarClipChanged, _2)); - gSavedSettings.getControl("RenderTerrainDetail")->getSignal()->connect(boost::bind(&handleTerrainDetailChanged, _2)); - gSavedSettings.getControl("OctreeStaticObjectSizeFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2)); - gSavedSettings.getControl("OctreeDistanceFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2)); - gSavedSettings.getControl("OctreeMaxNodeCapacity")->getSignal()->connect(boost::bind(&handleRepartition, _2)); - gSavedSettings.getControl("OctreeAlphaDistanceFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2)); - gSavedSettings.getControl("OctreeAttachmentSizeFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2)); - gSavedSettings.getControl("RenderMaxTextureIndex")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); - gSavedSettings.getControl("RenderUseTriStrips")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); - gSavedSettings.getControl("RenderAvatarVP")->getSignal()->connect(boost::bind(&handleAvatarVPChanged, _2)); - gSavedSettings.getControl("RenderUIBuffer")->getSignal()->connect(boost::bind(&handleWindowResized, _2)); - gSavedSettings.getControl("RenderDepthOfField")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2)); - gSavedSettings.getControl("RenderFSAASamples")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2)); - gSavedSettings.getControl("RenderSpecularResX")->getSignal()->connect(boost::bind(&handleLUTBufferChanged, _2)); - gSavedSettings.getControl("RenderSpecularResY")->getSignal()->connect(boost::bind(&handleLUTBufferChanged, _2)); - gSavedSettings.getControl("RenderSpecularExponent")->getSignal()->connect(boost::bind(&handleLUTBufferChanged, _2)); - gSavedSettings.getControl("RenderShadowResolutionScale")->getSignal()->connect(boost::bind(&handleShadowsResized, _2)); - gSavedSettings.getControl("RenderGlow")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2)); - gSavedSettings.getControl("RenderGlow")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); - gSavedSettings.getControl("RenderGlowResolutionPow")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2)); - gSavedSettings.getControl("RenderAvatarCloth")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); - gSavedSettings.getControl("WindLightUseAtmosShaders")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); - gSavedSettings.getControl("RenderGammaFull")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); - gSavedSettings.getControl("RenderVolumeLODFactor")->getSignal()->connect(boost::bind(&handleVolumeLODChanged, _2)); - gSavedSettings.getControl("RenderAvatarLODFactor")->getSignal()->connect(boost::bind(&handleAvatarLODChanged, _2)); - gSavedSettings.getControl("RenderAvatarPhysicsLODFactor")->getSignal()->connect(boost::bind(&handleAvatarPhysicsLODChanged, _2)); - gSavedSettings.getControl("RenderTerrainLODFactor")->getSignal()->connect(boost::bind(&handleTerrainLODChanged, _2)); - gSavedSettings.getControl("RenderTreeLODFactor")->getSignal()->connect(boost::bind(&handleTreeLODChanged, _2)); - gSavedSettings.getControl("RenderFlexTimeFactor")->getSignal()->connect(boost::bind(&handleFlexLODChanged, _2)); - gSavedSettings.getControl("RenderGamma")->getSignal()->connect(boost::bind(&handleGammaChanged, _2)); - gSavedSettings.getControl("RenderFogRatio")->getSignal()->connect(boost::bind(&handleFogRatioChanged, _2)); - gSavedSettings.getControl("RenderMaxPartCount")->getSignal()->connect(boost::bind(&handleMaxPartCountChanged, _2)); - gSavedSettings.getControl("RenderDynamicLOD")->getSignal()->connect(boost::bind(&handleRenderDynamicLODChanged, _2)); - gSavedSettings.getControl("RenderLocalLights")->getSignal()->connect(boost::bind(&handleRenderLocalLightsChanged, _2)); - gSavedSettings.getControl("RenderDebugTextureBind")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); - gSavedSettings.getControl("RenderAutoMaskAlphaDeferred")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); - gSavedSettings.getControl("RenderAutoMaskAlphaNonDeferred")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); + setting_setup_signal_listener(gSavedSettings, "FirstPersonAvatarVisible", handleRenderAvatarMouselookChanged); + setting_setup_signal_listener(gSavedSettings, "RenderFarClip", handleRenderFarClipChanged); + setting_setup_signal_listener(gSavedSettings, "RenderTerrainDetail", handleTerrainDetailChanged); + setting_setup_signal_listener(gSavedSettings, "OctreeStaticObjectSizeFactor", handleRepartition); + setting_setup_signal_listener(gSavedSettings, "OctreeDistanceFactor", handleRepartition); + setting_setup_signal_listener(gSavedSettings, "OctreeMaxNodeCapacity", handleRepartition); + setting_setup_signal_listener(gSavedSettings, "OctreeAlphaDistanceFactor", handleRepartition); + setting_setup_signal_listener(gSavedSettings, "OctreeAttachmentSizeFactor", handleRepartition); + setting_setup_signal_listener(gSavedSettings, "RenderMaxTextureIndex", handleSetShaderChanged); + setting_setup_signal_listener(gSavedSettings, "RenderUseTriStrips", handleResetVertexBuffersChanged); + setting_setup_signal_listener(gSavedSettings, "RenderUIBuffer", handleWindowResized); + setting_setup_signal_listener(gSavedSettings, "RenderDepthOfField", handleReleaseGLBufferChanged); + setting_setup_signal_listener(gSavedSettings, "RenderFSAASamples", handleReleaseGLBufferChanged); + setting_setup_signal_listener(gSavedSettings, "RenderSpecularResX", handleLUTBufferChanged); + setting_setup_signal_listener(gSavedSettings, "RenderSpecularResY", handleLUTBufferChanged); + setting_setup_signal_listener(gSavedSettings, "RenderSpecularExponent", handleLUTBufferChanged); + setting_setup_signal_listener(gSavedSettings, "RenderShadowResolutionScale", handleShadowsResized); + setting_setup_signal_listener(gSavedSettings, "RenderGlow", handleReleaseGLBufferChanged); + setting_setup_signal_listener(gSavedSettings, "RenderGlow", handleSetShaderChanged); + setting_setup_signal_listener(gSavedSettings, "RenderGlowResolutionPow", handleReleaseGLBufferChanged); + setting_setup_signal_listener(gSavedSettings, "RenderAvatarCloth", handleSetShaderChanged); + setting_setup_signal_listener(gSavedSettings, "WindLightUseAtmosShaders", handleSetShaderChanged); + setting_setup_signal_listener(gSavedSettings, "RenderGammaFull", handleSetShaderChanged); + setting_setup_signal_listener(gSavedSettings, "RenderVolumeLODFactor", handleVolumeLODChanged); + setting_setup_signal_listener(gSavedSettings, "RenderAvatarLODFactor", handleAvatarLODChanged); + setting_setup_signal_listener(gSavedSettings, "RenderAvatarPhysicsLODFactor", handleAvatarPhysicsLODChanged); + setting_setup_signal_listener(gSavedSettings, "RenderTerrainLODFactor", handleTerrainLODChanged); + setting_setup_signal_listener(gSavedSettings, "RenderTreeLODFactor", handleTreeLODChanged); + setting_setup_signal_listener(gSavedSettings, "RenderFlexTimeFactor", handleFlexLODChanged); + setting_setup_signal_listener(gSavedSettings, "RenderGamma", handleGammaChanged); + setting_setup_signal_listener(gSavedSettings, "RenderFogRatio", handleFogRatioChanged); + setting_setup_signal_listener(gSavedSettings, "RenderMaxPartCount", handleMaxPartCountChanged); + setting_setup_signal_listener(gSavedSettings, "RenderDynamicLOD", handleRenderDynamicLODChanged); + setting_setup_signal_listener(gSavedSettings, "RenderLocalLights", handleRenderLocalLightsChanged); + setting_setup_signal_listener(gSavedSettings, "RenderDebugTextureBind", handleResetVertexBuffersChanged); + setting_setup_signal_listener(gSavedSettings, "RenderAutoMaskAlphaDeferred", handleResetVertexBuffersChanged); + setting_setup_signal_listener(gSavedSettings, "RenderAutoMaskAlphaNonDeferred", handleResetVertexBuffersChanged); gSavedSettings.getControl("RenderAutoMaskAlphaUseRMSE")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); gSavedSettings.getControl("RenderAutoMaskAlphaMaxRMSE")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); gSavedSettings.getControl("RenderAutoMaskAlphaMaxMid")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); - gSavedSettings.getControl("RenderObjectBump")->getSignal()->connect(boost::bind(&handleRenderBumpChanged, _2)); - gSavedSettings.getControl("RenderMaxVBOSize")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); - gSavedSettings.getControl("RenderDeferredNoise")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2)); - gSavedSettings.getControl("RenderDebugGL")->getSignal()->connect(boost::bind(&handleRenderDebugGLChanged, _2)); - gSavedSettings.getControl("RenderDebugPipeline")->getSignal()->connect(boost::bind(&handleRenderDebugPipelineChanged, _2)); + setting_setup_signal_listener(gSavedSettings, "RenderObjectBump", handleRenderBumpChanged); + setting_setup_signal_listener(gSavedSettings, "RenderMaxVBOSize", handleResetVertexBuffersChanged); + setting_setup_signal_listener(gSavedSettings, "RenderVSyncEnable", handleVSyncChanged); + setting_setup_signal_listener(gSavedSettings, "RenderDeferredNoise", handleReleaseGLBufferChanged); + setting_setup_signal_listener(gSavedSettings, "RenderDebugPipeline", handleRenderDebugPipelineChanged); gSavedSettings.getControl("RenderResolutionDivisor")->getValidateSignal()->connect(boost::bind(&validateRenderResolutionDivisor, _2)); - gSavedSettings.getControl("RenderResolutionDivisor")->getSignal()->connect(boost::bind(&handleRenderResolutionDivisorChanged, _2)); + setting_setup_signal_listener(gSavedSettings, "RenderResolutionDivisor", handleRenderResolutionDivisorChanged); // [SL:KB] - Patch: Settings-RenderResolutionMultiplier | Checked: Catznip-5.4 gSavedSettings.getControl("RenderResolutionMultiplier")->getSignal()->connect(boost::bind(&handleRenderResolutionDivisorChanged, _2)); // [/SL:KB] gSavedSettings.getControl("RenderWaterRefResolution")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2)); - gSavedSettings.getControl("RenderDeferred")->getSignal()->connect(boost::bind(&handleRenderDeferredChanged, _2)); - gSavedSettings.getControl("RenderShadowDetail")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); - gSavedSettings.getControl("RenderDeferredSSAO")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); - gSavedSettings.getControl("RenderPerformanceTest")->getSignal()->connect(boost::bind(&handleRenderPerfTestChanged, _2)); - gSavedSettings.getControl("TextureMemory")->getSignal()->connect(boost::bind(&handleVideoMemoryChanged, _2)); - gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&handleChatFontSizeChanged, _2)); - gSavedSettings.getControl("ChatPersistTime")->getSignal()->connect(boost::bind(&handleChatPersistTimeChanged, _2)); - gSavedSettings.getControl("ConsoleMaxLines")->getSignal()->connect(boost::bind(&handleConsoleMaxLinesChanged, _2)); - gSavedSettings.getControl("UploadBakedTexOld")->getSignal()->connect(boost::bind(&handleUploadBakedTexOldChanged, _2)); - gSavedSettings.getControl("UseOcclusion")->getSignal()->connect(boost::bind(&handleUseOcclusionChanged, _2)); - gSavedSettings.getControl("AudioLevelMaster")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); - gSavedSettings.getControl("AudioLevelSFX")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); - gSavedSettings.getControl("AudioLevelUI")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); - gSavedSettings.getControl("AudioLevelAmbient")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); - gSavedSettings.getControl("AudioLevelMusic")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); - gSavedSettings.getControl("AudioLevelMedia")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); - gSavedSettings.getControl("AudioLevelVoice")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); - gSavedSettings.getControl("AudioLevelDoppler")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); - gSavedSettings.getControl("AudioLevelRolloff")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); - gSavedSettings.getControl("AudioLevelUnderwaterRolloff")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); - gSavedSettings.getControl("MuteAudio")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); - gSavedSettings.getControl("MuteMusic")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); - gSavedSettings.getControl("MuteMedia")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); - gSavedSettings.getControl("MuteVoice")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); - gSavedSettings.getControl("MuteAmbient")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); - gSavedSettings.getControl("MuteUI")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); - gSavedSettings.getControl("RenderVBOEnable")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); - gSavedSettings.getControl("RenderUseVAO")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); - gSavedSettings.getControl("RenderVBOMappingDisable")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); - gSavedSettings.getControl("RenderUseStreamVBO")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); - gSavedSettings.getControl("RenderPreferStreamDraw")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); - gSavedSettings.getControl("WLSkyDetail")->getSignal()->connect(boost::bind(&handleWLSkyDetailChanged, _2)); - gSavedSettings.getControl("JoystickAxis0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("JoystickAxis1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("JoystickAxis2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("JoystickAxis3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("JoystickAxis4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("JoystickAxis5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("JoystickAxis6")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("FlycamAxisScale0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("FlycamAxisScale1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("FlycamAxisScale2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("FlycamAxisScale3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("FlycamAxisScale4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("FlycamAxisScale5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("FlycamAxisScale6")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("FlycamAxisDeadZone0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("FlycamAxisDeadZone1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("FlycamAxisDeadZone2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("FlycamAxisDeadZone3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("FlycamAxisDeadZone4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("FlycamAxisDeadZone5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("FlycamAxisDeadZone6")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("AvatarAxisScale0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("AvatarAxisScale1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("AvatarAxisScale2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("AvatarAxisScale3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("AvatarAxisScale4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("AvatarAxisScale5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("AvatarAxisDeadZone0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("AvatarAxisDeadZone1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("AvatarAxisDeadZone2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("AvatarAxisDeadZone3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("AvatarAxisDeadZone4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("AvatarAxisDeadZone5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("BuildAxisScale0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("BuildAxisScale1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("BuildAxisScale2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("BuildAxisScale3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("BuildAxisScale4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("BuildAxisScale5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("BuildAxisDeadZone0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("BuildAxisDeadZone1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("BuildAxisDeadZone2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("BuildAxisDeadZone3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("BuildAxisDeadZone4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("BuildAxisDeadZone5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("DebugViews")->getSignal()->connect(boost::bind(&handleDebugViewsChanged, _2)); - gSavedSettings.getControl("UserLogFile")->getSignal()->connect(boost::bind(&handleLogFileChanged, _2)); - gSavedSettings.getControl("RenderHideGroupTitle")->getSignal()->connect(boost::bind(handleHideGroupTitleChanged, _2)); - gSavedSettings.getControl("HighResSnapshot")->getSignal()->connect(boost::bind(handleHighResSnapshotChanged, _2)); - gSavedSettings.getControl("EnableVoiceChat")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2)); - gSavedSettings.getControl("PTTCurrentlyEnabled")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2)); - gSavedSettings.getControl("PushToTalkButton")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2)); - gSavedSettings.getControl("PushToTalkToggle")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2)); - gSavedSettings.getControl("VoiceEarLocation")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2)); - gSavedSettings.getControl("VoiceInputAudioDevice")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2)); - gSavedSettings.getControl("VoiceOutputAudioDevice")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2)); - gSavedSettings.getControl("AudioLevelMic")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2)); - gSavedSettings.getControl("LipSyncEnabled")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2)); - gSavedSettings.getControl("VelocityInterpolate")->getSignal()->connect(boost::bind(&handleVelocityInterpolate, _2)); - gSavedSettings.getControl("QAMode")->getSignal()->connect(boost::bind(&show_debug_menus)); - gSavedSettings.getControl("UseDebugMenus")->getSignal()->connect(boost::bind(&show_debug_menus)); - gSavedSettings.getControl("AgentPause")->getSignal()->connect(boost::bind(&toggle_agent_pause, _2)); - gSavedSettings.getControl("ShowNavbarNavigationPanel")->getSignal()->connect(boost::bind(&toggle_show_navigation_panel, _2)); - gSavedSettings.getControl("ShowMiniLocationPanel")->getSignal()->connect(boost::bind(&toggle_show_mini_location_panel, _2)); - gSavedSettings.getControl("ShowObjectRenderingCost")->getSignal()->connect(boost::bind(&toggle_show_object_render_cost, _2)); - gSavedSettings.getControl("ForceShowGrid")->getSignal()->connect(boost::bind(&handleForceShowGrid, _2)); - gSavedSettings.getControl("RenderTransparentWater")->getSignal()->connect(boost::bind(&handleRenderTransparentWaterChanged, _2)); - gSavedSettings.getControl("SpellCheck")->getSignal()->connect(boost::bind(&handleSpellCheckChanged)); - gSavedSettings.getControl("SpellCheckDictionary")->getSignal()->connect(boost::bind(&handleSpellCheckChanged)); - gSavedSettings.getControl("LoginLocation")->getSignal()->connect(boost::bind(&handleLoginLocationChanged)); - gSavedSettings.getControl("DebugAvatarJoints")->getCommitSignal()->connect(boost::bind(&handleDebugAvatarJointsChanged, _2)); - gSavedSettings.getControl("RenderAutoMuteByteLimit")->getSignal()->connect(boost::bind(&handleRenderAutoMuteByteLimitChanged, _2)); - gSavedPerAccountSettings.getControl("AvatarHoverOffsetZ")->getCommitSignal()->connect(boost::bind(&handleAvatarHoverOffsetChanged, _2)); + setting_setup_signal_listener(gSavedSettings, "RenderDeferred", handleRenderDeferredChanged); + setting_setup_signal_listener(gSavedSettings, "RenderShadowDetail", handleSetShaderChanged); + setting_setup_signal_listener(gSavedSettings, "RenderDeferredSSAO", handleSetShaderChanged); + setting_setup_signal_listener(gSavedSettings, "RenderPerformanceTest", handleRenderPerfTestChanged); + setting_setup_signal_listener(gSavedSettings, "TextureMemory", handleVideoMemoryChanged); + setting_setup_signal_listener(gSavedSettings, "ChatFontSize", handleChatFontSizeChanged); + setting_setup_signal_listener(gSavedSettings, "ChatPersistTime", handleChatPersistTimeChanged); + setting_setup_signal_listener(gSavedSettings, "ConsoleMaxLines", handleConsoleMaxLinesChanged); + setting_setup_signal_listener(gSavedSettings, "UploadBakedTexOld", handleUploadBakedTexOldChanged); + setting_setup_signal_listener(gSavedSettings, "UseOcclusion", handleUseOcclusionChanged); + setting_setup_signal_listener(gSavedSettings, "AudioLevelMaster", handleAudioVolumeChanged); + setting_setup_signal_listener(gSavedSettings, "AudioLevelSFX", handleAudioVolumeChanged); + setting_setup_signal_listener(gSavedSettings, "AudioLevelUI", handleAudioVolumeChanged); + setting_setup_signal_listener(gSavedSettings, "AudioLevelAmbient", handleAudioVolumeChanged); + setting_setup_signal_listener(gSavedSettings, "AudioLevelMusic", handleAudioVolumeChanged); + setting_setup_signal_listener(gSavedSettings, "AudioLevelMedia", handleAudioVolumeChanged); + setting_setup_signal_listener(gSavedSettings, "AudioLevelVoice", handleAudioVolumeChanged); + setting_setup_signal_listener(gSavedSettings, "AudioLevelDoppler", handleAudioVolumeChanged); + setting_setup_signal_listener(gSavedSettings, "AudioLevelRolloff", handleAudioVolumeChanged); + setting_setup_signal_listener(gSavedSettings, "AudioLevelUnderwaterRolloff", handleAudioVolumeChanged); + setting_setup_signal_listener(gSavedSettings, "MuteAudio", handleAudioVolumeChanged); + setting_setup_signal_listener(gSavedSettings, "MuteMusic", handleAudioVolumeChanged); + setting_setup_signal_listener(gSavedSettings, "MuteMedia", handleAudioVolumeChanged); + setting_setup_signal_listener(gSavedSettings, "MuteVoice", handleAudioVolumeChanged); + setting_setup_signal_listener(gSavedSettings, "MuteAmbient", handleAudioVolumeChanged); + setting_setup_signal_listener(gSavedSettings, "MuteUI", handleAudioVolumeChanged); + setting_setup_signal_listener(gSavedSettings, "RenderVBOEnable", handleResetVertexBuffersChanged); + setting_setup_signal_listener(gSavedSettings, "RenderUseVAO", handleResetVertexBuffersChanged); + setting_setup_signal_listener(gSavedSettings, "RenderVBOMappingDisable", handleResetVertexBuffersChanged); + setting_setup_signal_listener(gSavedSettings, "RenderUseStreamVBO", handleResetVertexBuffersChanged); + setting_setup_signal_listener(gSavedSettings, "RenderPreferStreamDraw", handleResetVertexBuffersChanged); + setting_setup_signal_listener(gSavedSettings, "WLSkyDetail", handleWLSkyDetailChanged); + setting_setup_signal_listener(gSavedSettings, "JoystickAxis0", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "JoystickAxis1", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "JoystickAxis2", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "JoystickAxis3", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "JoystickAxis4", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "JoystickAxis5", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "JoystickAxis6", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale0", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale1", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale2", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale3", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale4", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale5", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale6", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone0", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone1", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone2", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone3", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone4", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone5", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone6", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale0", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale1", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale2", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale3", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale4", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale5", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone0", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone1", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone2", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone3", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone4", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone5", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "BuildAxisScale0", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "BuildAxisScale1", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "BuildAxisScale2", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "BuildAxisScale3", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "BuildAxisScale4", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "BuildAxisScale5", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone0", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone1", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone2", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone3", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone4", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone5", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "DebugViews", handleDebugViewsChanged); + setting_setup_signal_listener(gSavedSettings, "UserLogFile", handleLogFileChanged); + setting_setup_signal_listener(gSavedSettings, "RenderHideGroupTitle", handleHideGroupTitleChanged); + setting_setup_signal_listener(gSavedSettings, "HighResSnapshot", handleHighResSnapshotChanged); + setting_setup_signal_listener(gSavedSettings, "EnableVoiceChat", handleVoiceClientPrefsChanged); + setting_setup_signal_listener(gSavedSettings, "PTTCurrentlyEnabled", handleVoiceClientPrefsChanged); + setting_setup_signal_listener(gSavedSettings, "PushToTalkButton", handleVoiceClientPrefsChanged); + setting_setup_signal_listener(gSavedSettings, "PushToTalkToggle", handleVoiceClientPrefsChanged); + setting_setup_signal_listener(gSavedSettings, "VoiceEarLocation", handleVoiceClientPrefsChanged); + setting_setup_signal_listener(gSavedSettings, "VoiceInputAudioDevice", handleVoiceClientPrefsChanged); + setting_setup_signal_listener(gSavedSettings, "VoiceOutputAudioDevice", handleVoiceClientPrefsChanged); + setting_setup_signal_listener(gSavedSettings, "AudioLevelMic", handleVoiceClientPrefsChanged); + setting_setup_signal_listener(gSavedSettings, "LipSyncEnabled", handleVoiceClientPrefsChanged); + setting_setup_signal_listener(gSavedSettings, "VelocityInterpolate", handleVelocityInterpolate); + setting_setup_signal_listener(gSavedSettings, "QAMode", show_debug_menus); + setting_setup_signal_listener(gSavedSettings, "UseDebugMenus", show_debug_menus); + setting_setup_signal_listener(gSavedSettings, "AgentPause", toggle_agent_pause); + setting_setup_signal_listener(gSavedSettings, "ShowNavbarNavigationPanel", toggle_show_navigation_panel); + setting_setup_signal_listener(gSavedSettings, "ShowMiniLocationPanel", toggle_show_mini_location_panel); + setting_setup_signal_listener(gSavedSettings, "ShowObjectRenderingCost", toggle_show_object_render_cost); + setting_setup_signal_listener(gSavedSettings, "ForceShowGrid", handleForceShowGrid); + setting_setup_signal_listener(gSavedSettings, "RenderTransparentWater", handleRenderTransparentWaterChanged); + setting_setup_signal_listener(gSavedSettings, "SpellCheck", handleSpellCheckChanged); + setting_setup_signal_listener(gSavedSettings, "SpellCheckDictionary", handleSpellCheckChanged); + setting_setup_signal_listener(gSavedSettings, "LoginLocation", handleLoginLocationChanged); + setting_setup_signal_listener(gSavedSettings, "DebugAvatarJoints", handleDebugAvatarJointsChanged); + setting_setup_signal_listener(gSavedSettings, "RenderAutoMuteByteLimit", handleRenderAutoMuteByteLimitChanged); + + setting_setup_signal_listener(gSavedPerAccountSettings, "AvatarHoverOffsetZ", handleAvatarHoverOffsetChanged); // [RLVa:KB] - Checked: 2015-12-27 (RLVa-1.5.0) gSavedSettings.getControl(RlvSettingNames::Main)->getSignal()->connect(boost::bind(&RlvSettings::onChangedSettingMain, _2)); // [/RLVa:KB] diff --git a/indra/newview/llviewercontrollistener.cpp b/indra/newview/llviewercontrollistener.cpp index 3443bb644a1e2cf507a58a6960a3ad909467a167..8820f9ec5676b9c7b698475d92bc116fdac790ec 100644 --- a/indra/newview/llviewercontrollistener.cpp +++ b/indra/newview/llviewercontrollistener.cpp @@ -127,7 +127,7 @@ struct Info LLEventAPI::Response response; std::string groupname; - LLControlGroup* group; + LLControlGroup::ptr_t group; std::string key; LLControlVariable* control; }; @@ -187,7 +187,7 @@ void LLViewerControlListener::groups(LLSD const & request) struct CollectVars: public LLControlGroup::ApplyFunctor { - CollectVars(LLControlGroup* g): + CollectVars(LLControlGroup::ptr_t g): mGroup(g) {} @@ -200,7 +200,7 @@ struct CollectVars: public LLControlGroup::ApplyFunctor ("comment", control->getComment())); } - LLControlGroup* mGroup; + LLControlGroup::ptr_t mGroup; LLSD vars; }; @@ -210,7 +210,7 @@ void LLViewerControlListener::vars(LLSD const & request) // control name. Response response(LLSD(), request); std::string groupname(request["group"]); - LLControlGroup* group(LLControlGroup::getInstance(groupname)); + auto group(LLControlGroup::getInstance(groupname)); if (! group) { return response.error(STRINGIZE("Unrecognized group '" << groupname << "'")); diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 7b6d60f654c83d513e11362eaaccfdc625c64ba5..b96844d27e0f8a2156ace48415caf57c0e0267a3 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -132,7 +132,8 @@ void display_startup() if ( !gViewerWindow || !gViewerWindow->getActive() || !gViewerWindow->getWindow()->getVisible() - || gViewerWindow->getWindow()->getMinimized() ) + || gViewerWindow->getWindow()->getMinimized() + || gNonInteractive) { return; } @@ -173,8 +174,6 @@ void display_startup() if (gViewerWindow) gViewerWindow->setup2DRender(); - gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); - gGL.color4f(1,1,1,1); if (gViewerWindow) gViewerWindow->draw(); @@ -206,19 +205,21 @@ void display_update_camera() { final_far *= 0.5f; } - LLViewerCamera::getInstanceFast()->setFar(final_far); + LLViewerCamera::getInstance()->setFar(final_far); gViewerWindow->setup3DRender(); // Update land visibility too - LLWorld::getInstanceFast()->setLandFarClip(final_far); + LLWorld::getInstance()->setLandFarClip(final_far); } // Write some stats to LL_INFOS() void display_stats() { + LL_PROFILE_ZONE_SCOPED static const LLCachedControl<F32> fps_log_freq(gSavedSettings, "FPSLogFrequency"); if (fps_log_freq > 0.f && gRecentFPSTime.getElapsedTimeF32() >= fps_log_freq) { + LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("DS - FPS"); F32 fps = gRecentFrameCount / fps_log_freq; LL_INFOS() << llformat("FPS: %.02f", fps) << LL_ENDL; gRecentFrameCount = 0; @@ -227,6 +228,7 @@ void display_stats() static const LLCachedControl<F32> mem_log_freq(gSavedSettings, "MemoryLogFrequency"); if (mem_log_freq > 0.f && gRecentMemoryTime.getElapsedTimeF32() >= mem_log_freq) { + LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("DS - Memory"); gMemoryAllocated = U64Bytes(LLMemory::getCurrentRSS()); U32Megabytes memory = gMemoryAllocated; LL_INFOS() << "MEMORY: " << memory << LL_ENDL; @@ -236,6 +238,7 @@ void display_stats() static const LLCachedControl<F32> asset_storage_log_freq(gSavedSettings, "AssetStorageLogFrequency"); if (asset_storage_log_freq > 0.f && gAssetStorageLogTime.getElapsedTimeF32() >= asset_storage_log_freq) { + LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("DS - Asset Storage"); gAssetStorageLogTime.reset(); gAssetStorage->logAssetStorageInfo(); } @@ -286,7 +289,7 @@ static std::string STR_DISPLAY_DONE("Display:Done"); // Paint the display! void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) { - LL_ALWAYS_RECORD_BLOCK_TIME(FTM_RENDER); + LL_RECORD_BLOCK_TIME(FTM_RENDER); LLVBOPool::deleteReleasedBuffers(); if (gWindowResized) @@ -343,7 +346,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) // Attempting to draw into a minimized window causes a GL error. JC if ( !gViewerWindow->getActive() || !gViewerWindow->getWindow()->getVisible() - || gViewerWindow->getWindow()->getMinimized() ) + || gViewerWindow->getWindow()->getMinimized() + || gNonInteractive) { // Clean up memory the pools may have allocated if (rebuild) @@ -615,9 +619,11 @@ pProgFloater->setProgressCancelButtonVisible(FALSE, LLTrans::getString("Cancel") // LLAppViewer::instance()->pingMainloopTimeout(STR_DISPLAY_CAMERA); - auto& vwrCamera = LLViewerCamera::instanceFast(); - vwrCamera.setZoomParameters(zoom_factor, subfield); - vwrCamera.setNear(MIN_NEAR_PLANE); + if (LLViewerCamera::instanceExists()) + { + LLViewerCamera::getInstance()->setZoomParameters(zoom_factor, subfield); + LLViewerCamera::getInstance()->setNear(MIN_NEAR_PLANE); + } ////////////////////////// // @@ -674,6 +680,7 @@ pProgFloater->setProgressCancelButtonVisible(FALSE, LLTrans::getString("Cancel") if (!gDisconnected) { + LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("display - 1"); LLAppViewer::instance()->pingMainloopTimeout(STR_DISPLAY_UPDATE); if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) { //don't draw hud objects in this frame @@ -692,7 +699,7 @@ pProgFloater->setProgressCancelButtonVisible(FALSE, LLTrans::getString("Cancel") { LL_RECORD_BLOCK_TIME(FTM_EEP_UPDATE); // update all the sky/atmospheric/water settings - LLEnvironment::getInstanceFast()->update(&vwrCamera); + LLEnvironment::instance().update(LLViewerCamera::getInstance()); } // *TODO: merge these two methods @@ -716,21 +723,6 @@ pProgFloater->setProgressCancelButtonVisible(FALSE, LLTrans::getString("Cancel") stop_glerror(); - S32 water_clip = 0; - if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT) > 1) && - (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_WATER) || - gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_VOIDWATER))) - { - if (vwrCamera.cameraUnderWater()) - { - water_clip = -1; - } - else - { - water_clip = 1; - } - } - LLAppViewer::instance()->pingMainloopTimeout(STR_DISPLAY_CULL); //Increment drawable frame counter @@ -748,21 +740,20 @@ pProgFloater->setProgressCancelButtonVisible(FALSE, LLTrans::getString("Cancel") LLGLState::checkStates(); LLGLState::checkTextureChannels(); - LLGLState::checkClientArrays(); static LLCullResult result; LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; - LLPipeline::sUnderWaterRender = vwrCamera.cameraUnderWater(); - gPipeline.updateCull(vwrCamera, result, water_clip); + LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater(); + gPipeline.updateCull(*LLViewerCamera::getInstance(), result); stop_glerror(); LLGLState::checkStates(); LLGLState::checkTextureChannels(); - LLGLState::checkClientArrays(); - + LLAppViewer::instance()->pingMainloopTimeout(STR_DISPLAY_SWAP); { + LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("display - 2") if (gResizeScreenTexture) { gResizeScreenTexture = FALSE; @@ -774,26 +765,23 @@ pProgFloater->setProgressCancelButtonVisible(FALSE, LLTrans::getString("Cancel") LLGLState::checkStates(); LLGLState::checkTextureChannels(); - LLGLState::checkClientArrays(); if (!for_snapshot) { if (gFrameCount > 1) { //for some reason, ATI 4800 series will error out if you //try to generate a shadow before the first frame is through - gPipeline.generateSunShadow(vwrCamera); + gPipeline.generateSunShadow(*LLViewerCamera::getInstance()); } LLVertexBuffer::unbind(); LLGLState::checkStates(); LLGLState::checkTextureChannels(); - LLGLState::checkClientArrays(); LLMatrix4a proj = get_current_projection(); LLMatrix4a mod = get_current_modelview(); glViewport(0,0,512,512); - LLVOAvatar::updateFreezeCounter() ; LLVOAvatar::updateImpostors(); @@ -807,25 +795,23 @@ pProgFloater->setProgressCancelButtonVisible(FALSE, LLTrans::getString("Cancel") LLGLState::checkStates(); LLGLState::checkTextureChannels(); - LLGLState::checkClientArrays(); } glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); } LLGLState::checkStates(); - LLGLState::checkClientArrays(); //if (!for_snapshot) { + LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("display - 3") LLAppViewer::instance()->pingMainloopTimeout(STR_DISPLAY_IMAGERY); - gPipeline.generateWaterReflection(vwrCamera); - gPipeline.generateHighlight(vwrCamera); + gPipeline.generateWaterReflection(*LLViewerCamera::getInstance()); + gPipeline.generateHighlight(*LLViewerCamera::getInstance()); gPipeline.renderPhysicsDisplay(); } LLGLState::checkStates(); - LLGLState::checkClientArrays(); ////////////////////////////////////// // @@ -841,13 +827,11 @@ pProgFloater->setProgressCancelButtonVisible(FALSE, LLTrans::getString("Cancel") { LL_RECORD_BLOCK_TIME(FTM_IMAGE_UPDATE_CLASS); - LLTrace::CountStatHandle<>* velocity_stat = LLViewerCamera::getVelocityStat(); - LLTrace::CountStatHandle<>* angular_velocity_stat = LLViewerCamera::getAngularVelocityStat(); - LLViewerTexture::updateClass(LLTrace::get_frame_recording().getPeriodMeanPerSec(*velocity_stat), - LLTrace::get_frame_recording().getPeriodMeanPerSec(*angular_velocity_stat)); + LLViewerTexture::updateClass(); } - + LLImageGLThread::updateClass(); + { LL_RECORD_BLOCK_TIME(FTM_IMAGE_UPDATE_BUMP); gBumpImageList.updateImages(); // must be called before gTextureList version so that it's textures are thrown out first. @@ -866,10 +850,9 @@ pProgFloater->setProgressCancelButtonVisible(FALSE, LLTrans::getString("Cancel") LLImageGL::deleteDeadTextures(); stop_glerror(); }*/ - } + } LLGLState::checkStates(); - LLGLState::checkClientArrays(); /////////////////////////////////// // @@ -881,8 +864,9 @@ pProgFloater->setProgressCancelButtonVisible(FALSE, LLTrans::getString("Cancel") // LLAppViewer::instance()->pingMainloopTimeout(STR_DISPLAY_STATE_SORT); { + LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("display - 4") LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; - gPipeline.stateSort(vwrCamera, result); + gPipeline.stateSort(*LLViewerCamera::getInstance(), result); stop_glerror(); if (rebuild) @@ -897,16 +881,15 @@ pProgFloater->setProgressCancelButtonVisible(FALSE, LLTrans::getString("Cancel") } } - LLSceneMonitor::getInstanceFast()->fetchQueryResult(); + LLSceneMonitor::getInstance()->fetchQueryResult(); LLGLState::checkStates(); - LLGLState::checkClientArrays(); LLPipeline::sUseOcclusion = occlusion; { LLAppViewer::instance()->pingMainloopTimeout(STR_DISPLAY_SKY); - LL_RECORD_BLOCK_TIME(FTM_UPDATE_SKY); + LL_PROFILE_ZONE_NAMED_CATEGORY_ENVIRONMENT("update sky"); //LL_RECORD_BLOCK_TIME(FTM_UPDATE_SKY); gSky.updateSky(); } @@ -958,10 +941,9 @@ pProgFloater->setProgressCancelButtonVisible(FALSE, LLTrans::getString("Cancel") // gGL.popMatrix(); //} - LLPipeline::sUnderWaterRender = vwrCamera.cameraUnderWater() ? TRUE : FALSE; + LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater() ? TRUE : FALSE; LLGLState::checkStates(); - LLGLState::checkClientArrays(); stop_glerror(); @@ -978,7 +960,7 @@ pProgFloater->setProgressCancelButtonVisible(FALSE, LLTrans::getString("Cancel") gPipeline.mScreen.bindTarget(); if (LLPipeline::sUnderWaterRender && !gPipeline.canUseWindLightShaders()) { - const LLColor3 col = LLEnvironment::getInstanceFast()->getCurrentWater()->getWaterFogColor(); + const LLColor3 col = LLEnvironment::getInstance()->getCurrentWater()->getWaterFogColor(); glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f); } gPipeline.mScreen.clear(); @@ -991,10 +973,11 @@ pProgFloater->setProgressCancelButtonVisible(FALSE, LLTrans::getString("Cancel") if (!(LLAppViewer::instance()->logoutRequestSent() && LLAppViewer::instance()->hasSavedFinalSnapshot()) && !gRestoreGL) { + LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("display - 5") LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; static LLCachedControl<bool> renderDepthPrePass(gSavedSettings, "RenderDepthPrePass"); - if (renderDepthPrePass && LLGLSLShader::sNoFixedFunction) + if (renderDepthPrePass) { gGL.setColorMask(false, false); @@ -1018,11 +1001,11 @@ pProgFloater->setProgressCancelButtonVisible(FALSE, LLTrans::getString("Cancel") gGL.setColorMask(true, false); if (LLPipeline::sRenderDeferred) { - gPipeline.renderGeomDeferred(vwrCamera); + gPipeline.renderGeomDeferred(*LLViewerCamera::getInstance()); } else { - gPipeline.renderGeom(vwrCamera, TRUE); + gPipeline.renderGeom(*LLViewerCamera::getInstance(), TRUE); } gGL.setColorMask(true, true); @@ -1068,7 +1051,7 @@ pProgFloater->setProgressCancelButtonVisible(FALSE, LLTrans::getString("Cancel") { //capture the frame buffer. - LLSceneMonitor::getInstanceFast()->capture(); + LLSceneMonitor::getInstance()->capture(); } LLAppViewer::instance()->pingMainloopTimeout(STR_DISPLAY_RENDERUI); @@ -1130,7 +1113,7 @@ void render_hud_attachments() if (!ALCinematicMode::isEnabled() && LLPipeline::sShowHUDAttachments && !gDisconnected && setup_hud_matrices()) { LLPipeline::sRenderingHUDs = TRUE; - LLCamera hud_cam = LLViewerCamera::instanceFast(); + LLCamera hud_cam = LLViewerCamera::instance(); hud_cam.setOrigin(-1.f,0,0); hud_cam.setAxes(LLVector3(1,0,0), LLVector3(0,1,0), LLVector3(0,0,1)); LLViewerCamera::updateFrustumPlanes(hud_cam, TRUE); @@ -1222,7 +1205,7 @@ LLRect get_whole_screen_region() LLRect whole_screen = gViewerWindow->getWorldViewRectScaled(); // apply camera zoom transform (for high res screenshots) - auto& vwrCamera = LLViewerCamera::instanceFast(); + auto& vwrCamera = LLViewerCamera::instance(); F32 zoom_factor = vwrCamera.getZoomFactor(); S16 sub_region = vwrCamera.getZoomSubRegion(); if (zoom_factor > 1.f) @@ -1242,7 +1225,7 @@ bool get_hud_matrices(const LLRect& screen_region, LLMatrix4a &proj, LLMatrix4a { if (isAgentAvatarValid() && gAgentAvatarp->hasHUDAttachment()) { - auto& vwrCamera = LLViewerCamera::instanceFast(); + auto& vwrCamera = LLViewerCamera::instance(); F32 zoom_level = gAgentCamera.mHUDCurZoom; LLBBox hud_bbox = gAgentAvatarp->getHUDBBox(); @@ -1304,7 +1287,7 @@ bool setup_hud_matrices(const LLRect& screen_region) void render_ui(F32 zoom_factor, int subfield) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_UI); + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; //LL_RECORD_BLOCK_TIME(FTM_RENDER_UI); LLGLState::checkStates(); @@ -1317,71 +1300,76 @@ void render_ui(F32 zoom_factor, int subfield) set_current_modelview(get_last_modelview()); } - if(LLSceneMonitor::getInstanceFast()->needsUpdate()) + if(LLSceneMonitor::getInstance()->needsUpdate()) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_SCENE_MON); gGL.pushMatrix(); gViewerWindow->setup2DRender(); - LLSceneMonitor::getInstanceFast()->compare(); + LLSceneMonitor::getInstance()->compare(); gViewerWindow->setup3DRender(); gGL.popMatrix(); } - // Finalize scene - gPipeline.renderFinalize(); + // Finalize scene + gPipeline.renderFinalize(); - LL_RECORD_BLOCK_TIME(FTM_RENDER_HUD); - render_hud_elements(); + { + // SL-15709 + // NOTE: Tracy only allows one ZoneScoped per function. + // Solutions are: + // 1. Use a new scope + // 2. Use named zones + // 3. Use transient zones + LL_PROFILE_ZONE_NAMED_CATEGORY_UI("HUD"); //LL_RECORD_BLOCK_TIME(FTM_RENDER_HUD); + render_hud_elements(); // [RLVa:KB] - Checked: RLVa-2.2 (@setoverlay) - if (RlvActions::hasBehaviour(RLV_BHVR_SETOVERLAY)) - { - LLVfxManager::instanceFast().runEffect(EVisualEffect::RlvOverlay); - } + if (RlvActions::hasBehaviour(RLV_BHVR_SETOVERLAY)) + { + LLVfxManager::instance().runEffect(EVisualEffect::RlvOverlay); + } // [/RLVa:KB] - render_hud_attachments(); + render_hud_attachments(); - LLGLSDefault gls_default; - LLGLSUIDefault gls_ui; - { - gPipeline.disableLights(); - } + LLGLSDefault gls_default; + LLGLSUIDefault gls_ui; + { + gPipeline.disableLights(); + } - { - gGL.color4f(1,1,1,1); - if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) { - if (!gDisconnected) + gGL.color4f(1,1,1,1); + if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_3D); - render_ui_3d(); + if (!gDisconnected) + { + LL_PROFILE_ZONE_NAMED_CATEGORY_UI("UI 3D"); //LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_3D); + render_ui_3d(); + LLGLState::checkStates(); + } + else + { + render_disconnected_background(); + } + + LL_PROFILE_ZONE_NAMED_CATEGORY_UI("UI 2D"); //LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_2D); + render_ui_2d(); LLGLState::checkStates(); } - else - { - render_disconnected_background(); - } + gGL.flush(); - LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_2D); - render_ui_2d(); - LLGLState::checkStates(); - } - gGL.flush(); - - { - LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_DEBUG_TEXT); gViewerWindow->setup2DRender(); gViewerWindow->updateDebugText(); gViewerWindow->drawDebugText(); + + LLVertexBuffer::unbind(); } - LLVertexBuffer::unbind(); - } + if (!gSnapshot) + { + set_current_modelview(saved_view); + gGL.popMatrix(); + } - if (!gSnapshot) - { - set_current_modelview(saved_view); - gGL.popMatrix(); - } + } // Tracy integration } static LLTrace::BlockTimerStatHandle FTM_SWAP("Swap"); @@ -1486,10 +1474,7 @@ void render_ui_3d() stop_glerror(); - if (LLGLSLShader::sNoFixedFunction) - { - gUIProgram.bind(); - } + gUIProgram.bind(); // Coordinate axes static LLCachedControl<bool> showAxes(gSavedSettings, "ShowAxes"); @@ -1516,7 +1501,7 @@ void render_ui_2d() // Menu overlays, HUD, etc gViewerWindow->setup2DRender(); - auto& vwrCamera = LLViewerCamera::instanceFast(); + auto& vwrCamera = LLViewerCamera::instance(); F32 zoom_factor = vwrCamera.getZoomFactor(); S16 sub_region = vwrCamera.getZoomSubRegion(); @@ -1531,7 +1516,6 @@ void render_ui_2d() } stop_glerror(); - //gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); // render outline for HUD if (isAgentAvatarValid() && gAgentCamera.mHUDCurZoom < 0.98f) @@ -1621,10 +1605,7 @@ void render_ui_2d() void render_disconnected_background() { - if (LLGLSLShader::sNoFixedFunction) - { - gUIProgram.bind(); - } + gUIProgram.bind(); gGL.color4f(1,1,1,1); if (!gDisconnectedImagep && gDisconnected) @@ -1696,11 +1677,7 @@ void render_disconnected_background() } gGL.flush(); - if (LLGLSLShader::sNoFixedFunction) - { - gUIProgram.unbind(); - } - + gUIProgram.unbind(); } void display_cleanup() diff --git a/indra/newview/llviewerdisplayname.cpp b/indra/newview/llviewerdisplayname.cpp index 72db71b772c7b7e29b5f65cae6ae9c166f3bd425..0911cd00d5e9335f32fd7786edae8cddf6998b1c 100644 --- a/indra/newview/llviewerdisplayname.cpp +++ b/indra/newview/llviewerdisplayname.cpp @@ -30,6 +30,8 @@ // viewer includes #include "llagent.h" +#include "llfloaterprofile.h" +#include "llfloaterreg.h" #include "llviewerregion.h" #include "llvoavatar.h" @@ -206,6 +208,12 @@ class LLDisplayNameUpdate : public LLHTTPNode { LLViewerDisplayName::sNameChangedSignal(); } + + LLFloaterProfile* profile_floater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::findInstance("profile", LLSD().with("id", agent_id))); + if (profile_floater) + { + profile_floater->refreshName(); + } } }; diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 224bda5e31e72c134ca04409f8058e0ba0358e2a..288c3bd2a78b88dbfc3124e4e4f46ef71ceef557 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -70,6 +70,7 @@ #include "llfloaterchatalerts.h" // [/SL:KB] #include "llfloaterchatvoicevolume.h" +#include "llfloaterclassified.h" #include "llfloaterconversationlog.h" #include "llfloaterconversationpreview.h" #include "llfloatercreatelandmark.h" @@ -219,6 +220,10 @@ LLFloaterOpenHandler gFloaterOpenHandler; void LLViewerFloaterReg::registerFloaters() { + if (gNonInteractive) + { + return; + } // *NOTE: Please keep these alphabetized for easier merges LLFloaterAboutUtil::registerFloater(); @@ -256,6 +261,7 @@ void LLViewerFloaterReg::registerFloaters() // [/SL:KB] LLFloaterReg::add("chat_voice", "floater_voice_chat_volume.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterChatVoiceVolume>); LLFloaterReg::add("nearby_chat", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterIMNearbyChat::buildFloater); + LLFloaterReg::add("classified", "floater_classified.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterClassified>); LLFloaterReg::add("compile_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCompileQueue>); LLFloaterReg::add("conversation", "floater_conversation_log.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterConversationLog>); LLFloaterReg::add("add_landmark", "floater_create_landmark.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCreateLandmark>); @@ -347,7 +353,6 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("prefs_translation", "floater_translation_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTranslationSettings>); LLFloaterReg::add("prefs_spellchecker", "floater_spellcheck.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSpellCheckerSettings>); LLFloaterReg::add("prefs_autoreplace", "floater_autoreplace.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAutoReplaceSettings>); - LLFloaterReg::add("picks", "floater_picks.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>); LLFloaterReg::add("pref_joystick", "floater_joystick.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterJoystick>); LLFloaterReg::add("preview_anim", "floater_preview_animation.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewAnim>, "preview"); LLFloaterReg::add("preview_conversation", "floater_conversation_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterConversationPreview>); diff --git a/indra/newview/llviewerfoldertype.cpp b/indra/newview/llviewerfoldertype.cpp index 908efd51f117c616d4ff3c1185ed6a37f540fae2..34abc63806252b03b81b59c701c51a0970198624 100644 --- a/indra/newview/llviewerfoldertype.cpp +++ b/indra/newview/llviewerfoldertype.cpp @@ -228,7 +228,7 @@ bool LLViewerFolderDictionary::initEnsemblesFromFile() const std::string &LLViewerFolderType::lookupXUIName(LLFolderType::EType folder_type) { - const ViewerFolderEntry *entry = LLViewerFolderDictionary::getInstanceFast()->lookup(folder_type); + const ViewerFolderEntry *entry = LLViewerFolderDictionary::getInstance()->lookup(folder_type); if (entry) { return entry->mName; @@ -238,12 +238,12 @@ const std::string &LLViewerFolderType::lookupXUIName(LLFolderType::EType folder_ LLFolderType::EType LLViewerFolderType::lookupTypeFromXUIName(const std::string &name) { - return LLViewerFolderDictionary::getInstanceFast()->lookup(name); + return LLViewerFolderDictionary::getInstance()->lookup(name); } const std::string &LLViewerFolderType::lookupIconName(LLFolderType::EType folder_type, BOOL is_open) { - const ViewerFolderEntry *entry = LLViewerFolderDictionary::getInstanceFast()->lookup(folder_type); + const ViewerFolderEntry *entry = LLViewerFolderDictionary::getInstance()->lookup(folder_type); if (entry) { if (is_open) @@ -253,7 +253,7 @@ const std::string &LLViewerFolderType::lookupIconName(LLFolderType::EType folder } // Error condition. Return something so that we don't show a grey box in inventory view. - const ViewerFolderEntry *default_entry = LLViewerFolderDictionary::getInstanceFast()->lookup(LLFolderType::FT_NONE); + const ViewerFolderEntry *default_entry = LLViewerFolderDictionary::getInstance()->lookup(LLFolderType::FT_NONE); if (default_entry) { return default_entry->mIconNameClosed; @@ -265,7 +265,7 @@ const std::string &LLViewerFolderType::lookupIconName(LLFolderType::EType folder BOOL LLViewerFolderType::lookupIsQuietType(LLFolderType::EType folder_type) { - const ViewerFolderEntry *entry = LLViewerFolderDictionary::getInstanceFast()->lookup(folder_type); + const ViewerFolderEntry *entry = LLViewerFolderDictionary::getInstance()->lookup(folder_type); if (entry) { return entry->mIsQuiet; @@ -275,7 +275,7 @@ BOOL LLViewerFolderType::lookupIsQuietType(LLFolderType::EType folder_type) bool LLViewerFolderType::lookupIsHiddenIfEmpty(LLFolderType::EType folder_type) { - const ViewerFolderEntry *entry = LLViewerFolderDictionary::getInstanceFast()->lookup(folder_type); + const ViewerFolderEntry *entry = LLViewerFolderDictionary::getInstance()->lookup(folder_type); if (entry) { return entry->mHideIfEmpty; @@ -285,7 +285,7 @@ bool LLViewerFolderType::lookupIsHiddenIfEmpty(LLFolderType::EType folder_type) const std::string &LLViewerFolderType::lookupNewCategoryName(LLFolderType::EType folder_type) { - const ViewerFolderEntry *entry = LLViewerFolderDictionary::getInstanceFast()->lookup(folder_type); + const ViewerFolderEntry *entry = LLViewerFolderDictionary::getInstance()->lookup(folder_type); if (entry) { return entry->mNewCategoryName; @@ -295,7 +295,7 @@ const std::string &LLViewerFolderType::lookupNewCategoryName(LLFolderType::EType LLFolderType::EType LLViewerFolderType::lookupTypeFromNewCategoryName(const std::string& name) { - for (const auto& pair : LLViewerFolderDictionary::instanceFast()) + for (const auto& pair : LLViewerFolderDictionary::instance()) { const ViewerFolderEntry *entry = pair.second; if (entry->mNewCategoryName == name) @@ -310,7 +310,7 @@ LLFolderType::EType LLViewerFolderType::lookupTypeFromNewCategoryName(const std: U64 LLViewerFolderType::lookupValidFolderTypes(const std::string& item_name) { U64 matching_folders = 0; - for (const auto& pair : LLViewerFolderDictionary::instanceFast()) + for (const auto& pair : LLViewerFolderDictionary::instance()) { const ViewerFolderEntry *entry = pair.second; if (entry->getIsAllowedName(item_name)) diff --git a/indra/newview/llviewerinput.cpp b/indra/newview/llviewerinput.cpp index da19e0e552dbfd64214203c4df3fc6f0ca653a6c..5f4b7a3b18549e665b7f4783e18b1284b1939655 100644 --- a/indra/newview/llviewerinput.cpp +++ b/indra/newview/llviewerinput.cpp @@ -286,7 +286,7 @@ bool agent_turn_left(EKeystate s) if(gAgent.isMovementLocked()) return false; - if (LLToolCamera::getInstanceFast()->mouseSteerMode()) + if (LLToolCamera::getInstance()->mouseSteerMode()) { agent_slide_left(s); } @@ -317,7 +317,7 @@ bool agent_turn_right( EKeystate s ) if(gAgent.isMovementLocked()) return false; - if (LLToolCamera::getInstanceFast()->mouseSteerMode()) + if (LLToolCamera::getInstance()->mouseSteerMode()) { agent_slide_right(s); } @@ -876,16 +876,16 @@ bool toggle_sit(EKeystate s) bool toggle_pause_media(EKeystate s) // analogue of play/pause button in top bar { if (KEYSTATE_DOWN != s) return true; - bool pause = LLViewerMedia::getInstanceFast()->isAnyMediaPlaying(); - LLViewerMedia::getInstanceFast()->setAllMediaPaused(pause); + bool pause = LLViewerMedia::getInstance()->isAnyMediaPlaying(); + LLViewerMedia::getInstance()->setAllMediaPaused(pause); return true; } bool toggle_enable_media(EKeystate s) { if (KEYSTATE_DOWN != s) return true; - bool pause = LLViewerMedia::getInstanceFast()->isAnyMediaPlaying() || LLViewerMedia::getInstanceFast()->isAnyMediaShowing(); - LLViewerMedia::getInstanceFast()->setAllMediaEnabled(!pause); + bool pause = LLViewerMedia::getInstance()->isAnyMediaPlaying() || LLViewerMedia::getInstance()->isAnyMediaShowing(); + LLViewerMedia::getInstance()->setAllMediaEnabled(!pause); return true; } @@ -899,13 +899,13 @@ bool walk_to(EKeystate s) // "return !has_teleported" return false; } - return LLToolPie::getInstanceFast()->walkToClickedLocation(); + return LLToolPie::getInstance()->walkToClickedLocation(); } bool teleport_to(EKeystate s) { if (KEYSTATE_DOWN != s) return false; - return LLToolPie::getInstanceFast()->teleportToClickedLocation(); + return LLToolPie::getInstance()->teleportToClickedLocation(); } bool toggle_voice(EKeystate s) diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index f174835eccdd1af3a425446f27f3f1211a59c9e1..a72aba8e19008465b3b0be0a46c4597a85dc8c1c 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -531,7 +531,7 @@ BOOL LLViewerInventoryItem::unpackMessage(const LLSD& item) { BOOL rv = LLInventoryItem::fromLLSD(item); - LLLocalizedInventoryItemsDictionary::getInstanceFast()->localizeInventoryObjectName(mName); + LLLocalizedInventoryItemsDictionary::getInstance()->localizeInventoryObjectName(mName); mIsComplete = TRUE; return rv; @@ -542,7 +542,7 @@ BOOL LLViewerInventoryItem::unpackMessage(LLMessageSystem* msg, const char* bloc { BOOL rv = LLInventoryItem::unpackMessage(msg, block, block_num); - LLLocalizedInventoryItemsDictionary::getInstanceFast()->localizeInventoryObjectName(mName); + LLLocalizedInventoryItemsDictionary::getInstance()->localizeInventoryObjectName(mName); mIsComplete = TRUE; return rv; @@ -930,7 +930,7 @@ void LLViewerInventoryCategory::changeType(LLFolderType::EType new_folder_type) void LLViewerInventoryCategory::localizeName() { - LLLocalizedInventoryItemsDictionary::getInstanceFast()->localizeInventoryObjectName(mName); + LLLocalizedInventoryItemsDictionary::getInstance()->localizeInventoryObjectName(mName); } // virtual @@ -1133,7 +1133,7 @@ void create_inventory_item(const LLUUID& agent_id, const LLUUID& session_id, std::string server_name = name; { - for (const auto& pair : LLLocalizedInventoryItemsDictionary::getInstanceFast()->mInventoryItemsDict) + for (const auto& pair : LLLocalizedInventoryItemsDictionary::getInstance()->mInventoryItemsDict) { const std::string& localized_name = pair.second; if(localized_name == name) @@ -2114,7 +2114,7 @@ void menu_create_inventory_item(LLInventoryPanel* panel, LLFolderBridge *bridge, else { // Use for all clothing and body parts. Adding new wearable types requires updating LLWearableDictionary. - LLWearableType::EType wearable_type = LLWearableType::getInstanceFast()->typeNameToType(type_name); + LLWearableType::EType wearable_type = LLWearableType::getInstance()->typeNameToType(type_name); if (wearable_type >= LLWearableType::WT_SHAPE && wearable_type < LLWearableType::WT_COUNT) { const LLUUID parent_id = bridge ? bridge->getUUID() : LLUUID::null; @@ -2355,12 +2355,12 @@ BOOL LLViewerInventoryItem::extractSortFieldAndDisplayName(const std::string& na // [SL:KB] - Patch: Build-ScriptRecover | Checked: 2013-03-10 (Catznip-3.4) bool LLViewerInventoryItem::lookupLocalizedName(std::string& name) { - return LLLocalizedInventoryItemsDictionary::instanceFast().localizeInventoryObjectName(name); + return LLLocalizedInventoryItemsDictionary::instance().localizeInventoryObjectName(name); } bool LLViewerInventoryItem::lookupSystemName(std::string& name) { - return LLLocalizedInventoryItemsDictionary::instanceFast().revertInventoryObjectName(name); + return LLLocalizedInventoryItemsDictionary::instance().revertInventoryObjectName(name); } // [/SL:KB] diff --git a/indra/newview/llviewerjointattachment.cpp b/indra/newview/llviewerjointattachment.cpp index 89c5aa24f34858fb8f398ad807c8075e37fc3cd0..14d710353279e7fd56038664723df841249a84f7 100644 --- a/indra/newview/llviewerjointattachment.cpp +++ b/indra/newview/llviewerjointattachment.cpp @@ -124,8 +124,7 @@ void LLViewerJointAttachment::setupDrawable(LLViewerObject *object) object->mDrawable->mXform.setRotation(current_rot); gPipeline.markMoved(object->mDrawable); gPipeline.markTextured(object->mDrawable); // face may need to change draw pool to/from POOL_HUD - object->mDrawable->setState(LLDrawable::USE_BACKLIGHT); - + if(mIsHUDAttachment) { for (S32 face_num = 0; face_num < object->mDrawable->getNumFaces(); face_num++) @@ -143,7 +142,6 @@ void LLViewerJointAttachment::setupDrawable(LLViewerObject *object) { if (childp && childp->mDrawable.notNull()) { - childp->mDrawable->setState(LLDrawable::USE_BACKLIGHT); gPipeline.markTextured(childp->mDrawable); // face may need to change draw pool to/from POOL_HUD gPipeline.markMoved(childp->mDrawable); @@ -284,7 +282,6 @@ void LLViewerJointAttachment::removeObject(LLViewerObject *object) object->mDrawable->mXform.setRotation(cur_rotation); gPipeline.markMoved(object->mDrawable, TRUE); gPipeline.markTextured(object->mDrawable); // face may need to change draw pool to/from POOL_HUD - object->mDrawable->clearState(LLDrawable::USE_BACKLIGHT); if (mIsHUDAttachment) { @@ -306,7 +303,6 @@ void LLViewerJointAttachment::removeObject(LLViewerObject *object) LLViewerObject* childp = *iter; if (childp && childp->mDrawable.notNull()) { - childp->mDrawable->clearState(LLDrawable::USE_BACKLIGHT); gPipeline.markTextured(childp->mDrawable); // face may need to change draw pool to/from POOL_HUD if (mIsHUDAttachment) { diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp index 113fa77401aac7f1561904623dd291023817c753..3a40fb1dc10a9f77f94f8948a2ca1f21e97d3699 100644 --- a/indra/newview/llviewerjointmesh.cpp +++ b/indra/newview/llviewerjointmesh.cpp @@ -219,7 +219,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) if (!mValid || !mMesh || !mFace || !mVisible || !mFace->getVertexBuffer() || mMesh->getNumFaces() == 0 || - (LLGLSLShader::sNoFixedFunction && LLGLSLShader::sCurBoundShaderPtr == NULL)) + LLGLSLShader::sCurBoundShaderPtr == NULL) { return 0; } @@ -240,7 +240,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) stop_glerror(); - LLGLSSpecular specular(LLColor4(1.f,1.f,1.f,1.f), (mFace->getPool()->getShaderLevel() > 0 || LLGLSLShader::sNoFixedFunction) ? 0.f : mShiny); + LLGLSSpecular specular(LLColor4(1.f,1.f,1.f,1.f), 0.f); //---------------------------------------------------------------- // setup current texture @@ -259,7 +259,6 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) else { gGL.diffuseColor4f(0.7f, 0.6f, 0.3f, 1.f); - gGL.getTexUnit(diffuse_channel)->setTextureColorBlend(LLTexUnit::TBO_LERP_TEX_ALPHA, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR); } } else if( !is_dummy && layerset ) @@ -320,11 +319,6 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) triangle_count += count; - if (mTestImageName) - { - gGL.getTexUnit(diffuse_channel)->setTextureBlendType(LLTexUnit::TB_MULT); - } - return triangle_count; } @@ -354,7 +348,6 @@ void LLViewerJointMesh::updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 //----------------------------------------------------------------------------- // updateFaceData() //----------------------------------------------------------------------------- -static LLTrace::BlockTimerStatHandle FTM_AVATAR_FACE("Avatar Face"); void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind, bool terse_update) { @@ -375,9 +368,8 @@ void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_w // since mMesh is being copied into mVertexBuffer every frame return; } - - - LL_RECORD_BLOCK_TIME(FTM_AVATAR_FACE); + + LL_PROFILE_ZONE_SCOPED; LLStrider<LLVector3> verticesp; LLStrider<LLVector3> normalsp; diff --git a/indra/newview/llviewerjoystick.cpp b/indra/newview/llviewerjoystick.cpp index 3fabcd357a2843abca2445f9307fbf6e40d21905..f45d125512669f9092904b67c5f2925b292f9e25 100644 --- a/indra/newview/llviewerjoystick.cpp +++ b/indra/newview/llviewerjoystick.cpp @@ -829,14 +829,14 @@ void LLViewerJoystick::moveObjects(bool reset) } // the selection update could fail, so we won't send - if (LLSelectMgr::getInstanceFast()->selectionMove(v, sDelta[3],sDelta[4],sDelta[5], upd_type)) + if (LLSelectMgr::getInstance()->selectionMove(v, sDelta[3],sDelta[4],sDelta[5], upd_type)) { toggle_send_to_sim = true; } } else if (toggle_send_to_sim) { - LLSelectMgr::getInstanceFast()->sendSelectionMove(); + LLSelectMgr::getInstance()->sendSelectionMove(); toggle_send_to_sim = false; } } @@ -1108,12 +1108,12 @@ void LLViewerJoystick::moveFlycam(bool reset) gSavedSettings.getS32("JoystickAxis6") }; - bool in_build_mode = LLToolMgr::getInstanceFast()->inBuildMode(); + bool in_build_mode = LLToolMgr::getInstance()->inBuildMode(); if (reset || mResetFlag) { - sFlycamPosition = LLViewerCamera::getInstanceFast()->getOrigin(); - sFlycamRotation = LLViewerCamera::getInstanceFast()->getQuaternion(); - sFlycamZoom = LLViewerCamera::getInstanceFast()->getView(); + sFlycamPosition = LLViewerCamera::getInstance()->getOrigin(); + sFlycamRotation = LLViewerCamera::getInstance()->getQuaternion(); + sFlycamZoom = LLViewerCamera::getInstance()->getView(); resetDeltas(axis); @@ -1318,7 +1318,7 @@ void LLViewerJoystick::scanJoystick() toggle_flycam = 0; } - if (!mOverrideCamera && !(LLToolMgr::getInstanceFast()->inBuildMode() && gSavedSettings.getBOOL("JoystickBuildEnabled"))) + if (!mOverrideCamera && !(LLToolMgr::getInstance()->inBuildMode() && gSavedSettings.getBOOL("JoystickBuildEnabled"))) { moveAvatar(); } diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index eb5cc29ac2bcd1fa2606ca25f0599d8ffdf88d45..f1bcfb1a35c63c4ec20375b267a44aadf19b37b8 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -39,6 +39,7 @@ #include "llfilepicker.h" #include "llfloaterwebcontent.h" // for handling window close requests and geometry change requests in media browser windows. #include "llfocusmgr.h" +#include "llimagegl.h" #include "llkeyboard.h" #include "lllogininstance.h" #include "llmarketplacefunctions.h" @@ -190,7 +191,7 @@ static void remove_media_impl(LLViewerMediaImpl* media) class LLViewerMediaMuteListObserver : public LLMuteListObserver { - /* virtual */ void onChange() { LLViewerMedia::getInstanceFast()->muteListChanged();} + /* virtual */ void onChange() { LLViewerMedia::getInstance()->muteListChanged();} }; static LLViewerMediaMuteListObserver sViewerMediaMuteListObserver; @@ -382,7 +383,7 @@ std::string LLViewerMedia::getCurrentUserAgent() // Just in case we need to check browser differences in A/B test // builds. - std::string channel = LLVersionInfo::instanceFast().getChannel(); + std::string channel = LLVersionInfo::instance().getChannel(); // append our magic version number string to the browser user agent id // See the HTTP 1.0 and 1.1 specifications for allowed formats: @@ -392,7 +393,7 @@ std::string LLViewerMedia::getCurrentUserAgent() // http://www.mozilla.org/build/revised-user-agent-strings.html std::ostringstream codec; codec << "SecondLife/"; - codec << LLVersionInfo::instanceFast().getVersion(); + codec << LLVersionInfo::instance().getVersion(); codec << " (" << channel << "; " << skin_name << " skin)"; LL_INFOS() << codec.str() << LL_ENDL; @@ -492,13 +493,13 @@ bool LLViewerMedia::isInterestingEnough(const LLVOVolume *object, const F64 &obj result = false; } // Focused? Then it is interesting! - else if (LLViewerMediaFocus::getInstanceFast()->getFocusedObjectID() == object->getID()) + else if (LLViewerMediaFocus::getInstance()->getFocusedObjectID() == object->getID()) { result = true; } // Selected? Then it is interesting! // XXX Sadly, 'contains()' doesn't take a const :( - else if (LLSelectMgr::getInstanceFast()->getSelection()->contains(const_cast<LLVOVolume*>(object))) + else if (LLSelectMgr::getInstance()->getSelection()->contains(const_cast<LLVOVolume*>(object))) { result = true; } @@ -606,6 +607,7 @@ static bool proximity_comparitor(const LLViewerMediaImpl* i1, const LLViewerMedi static LLTrace::BlockTimerStatHandle FTM_MEDIA_UPDATE("Update Media"); static LLTrace::BlockTimerStatHandle FTM_MEDIA_SPARE_IDLE("Spare Idle"); static LLTrace::BlockTimerStatHandle FTM_MEDIA_UPDATE_INTEREST("Update/Interest"); +static LLTrace::BlockTimerStatHandle FTM_MEDIA_UPDATE_VOLUME("Update/Volume"); static LLTrace::BlockTimerStatHandle FTM_MEDIA_SORT("Media Sort"); static LLTrace::BlockTimerStatHandle FTM_MEDIA_SORT2("Media Sort 2"); static LLTrace::BlockTimerStatHandle FTM_MEDIA_MISC("Misc"); @@ -614,18 +616,25 @@ static LLTrace::BlockTimerStatHandle FTM_MEDIA_MISC("Misc"); ////////////////////////////////////////////////////////////////////////////////////////// void LLViewerMedia::onIdle(void *dummy_arg) { - LLViewerMedia::getInstanceFast()->updateMedia(dummy_arg); + LLViewerMedia::getInstance()->updateMedia(dummy_arg); } ////////////////////////////////////////////////////////////////////////////////////////// void LLViewerMedia::updateMedia(void *dummy_arg) { - LL_RECORD_BLOCK_TIME(FTM_MEDIA_UPDATE); + LL_PROFILE_ZONE_SCOPED_CATEGORY_MEDIA; //LL_RECORD_BLOCK_TIME(FTM_MEDIA_UPDATE); // Enable/disable the plugin read thread static LLCachedControl<bool> pluginUseReadThread(gSavedSettings, "PluginUseReadThread"); LLPluginProcessParent::setUseReadThread(pluginUseReadThread); + // SL-16418 We can't call LLViewerMediaImpl->update() if we are in the state of shutting down. + if(LLApp::isExiting()) + { + setAllMediaEnabled(false); + return; + } + // HACK: we always try to keep a spare running webkit plugin around to improve launch times. // 2017-04-19 Removed CP - this doesn't appear to buy us much and consumes a lot of resources so // removing it for now. @@ -638,7 +647,7 @@ void LLViewerMedia::updateMedia(void *dummy_arg) impl_list::iterator end = sViewerMediaImplList.end(); { - LL_RECORD_BLOCK_TIME(FTM_MEDIA_UPDATE_INTEREST); + LL_PROFILE_ZONE_NAMED_CATEGORY_MEDIA("media update interest"); //LL_RECORD_BLOCK_TIME(FTM_MEDIA_UPDATE_INTEREST); for(; iter != end;) { LLViewerMediaImpl* pimpl = *iter++; @@ -650,12 +659,12 @@ void LLViewerMedia::updateMedia(void *dummy_arg) // Let the spare media source actually launch if(mSpareBrowserMediaSource) { - LL_RECORD_BLOCK_TIME(FTM_MEDIA_SPARE_IDLE); + LL_PROFILE_ZONE_NAMED_CATEGORY_MEDIA("media spare idle"); //LL_RECORD_BLOCK_TIME(FTM_MEDIA_SPARE_IDLE); mSpareBrowserMediaSource->idle(); } { - LL_RECORD_BLOCK_TIME(FTM_MEDIA_SORT); + LL_PROFILE_ZONE_NAMED_CATEGORY_MEDIA("media sort"); //LL_RECORD_BLOCK_TIME(FTM_MEDIA_SORT); // Sort the static instance list using our interest criteria sViewerMediaImplList.sort(priorityComparitor); } @@ -687,7 +696,7 @@ void LLViewerMedia::updateMedia(void *dummy_arg) // If max_normal + max_low is less than max_instances, things will tend to get unloaded instead of being set to slideshow. { - LL_RECORD_BLOCK_TIME(FTM_MEDIA_MISC); + LL_PROFILE_ZONE_NAMED_CATEGORY_MEDIA("media misc"); //LL_RECORD_BLOCK_TIME(FTM_MEDIA_MISC); for(; iter != end; iter++) { LLViewerMediaImpl* pimpl = *iter; @@ -808,7 +817,7 @@ void LLViewerMedia::updateMedia(void *dummy_arg) { if(LLViewerMedia::isParcelAudioPlaying() && gAudiop && LLViewerMedia::hasParcelAudio()) { - LLViewerAudio::getInstanceFast()->stopInternetStreamWithAutoFade(); + LLViewerAudio::getInstance()->stopInternetStreamWithAutoFade(); restore_parcel_audio = true; } } @@ -816,7 +825,7 @@ void LLViewerMedia::updateMedia(void *dummy_arg) { if(gAudiop && LLViewerMedia::hasParcelAudio() && restore_parcel_audio && gSavedSettings.getBOOL("MediaTentativeAutoPlay")) { - LLViewerAudio::getInstanceFast()->startInternetStreamWithAutoFade(LLViewerMedia::getParcelAudioURL()); + LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLViewerMedia::getParcelAudioURL()); restore_parcel_audio = false; } } @@ -873,7 +882,7 @@ void LLViewerMedia::updateMedia(void *dummy_arg) } else { - LL_RECORD_BLOCK_TIME(FTM_MEDIA_SORT2); + LL_PROFILE_ZONE_NAMED_CATEGORY_MEDIA("media sort2"); // LL_RECORD_BLOCK_TIME(FTM_MEDIA_SORT2); // Use a distance-based sort for proximity values. std::stable_sort(proximity_order.begin(), proximity_order.end(), proximity_comparitor); } @@ -927,7 +936,7 @@ void LLViewerMedia::setAllMediaEnabled(bool val) { if (!LLViewerMedia::isParcelMediaPlaying() && LLViewerMedia::hasParcelMedia()) { - LLViewerParcelMedia::getInstanceFast()->play(LLViewerParcelMgr::getInstanceFast()->getAgentParcel()); + LLViewerParcelMedia::getInstance()->play(LLViewerParcelMgr::getInstance()->getAgentParcel()); } static LLCachedControl<bool> audio_streaming_music(gSavedSettings, "AudioStreamingMusic", true); @@ -943,16 +952,16 @@ void LLViewerMedia::setAllMediaEnabled(bool val) } else { - LLViewerAudio::getInstanceFast()->startInternetStreamWithAutoFade(LLViewerMedia::getParcelAudioURL()); + LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLViewerMedia::getParcelAudioURL()); } } } else { // This actually unloads the impl, as opposed to "stop"ping the media - LLViewerParcelMedia::getInstanceFast()->stop(); + LLViewerParcelMedia::getInstance()->stop(); if (gAudiop) { - LLViewerAudio::getInstanceFast()->stopInternetStreamWithAutoFade(); + LLViewerAudio::getInstance()->stopInternetStreamWithAutoFade(); } } } @@ -993,14 +1002,14 @@ void LLViewerMedia::setAllMediaPaused(bool val) } } - LLParcel *agent_parcel = LLViewerParcelMgr::getInstanceFast()->getAgentParcel(); + LLParcel *agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); // Also do Parcel Media and Parcel Audio if (!val) { if (!LLViewerMedia::isParcelMediaPlaying() && LLViewerMedia::hasParcelMedia()) { - LLViewerParcelMedia::getInstanceFast()->play(agent_parcel); + LLViewerParcelMedia::getInstance()->play(agent_parcel); } static LLCachedControl<bool> audio_streaming_music(gSavedSettings, "AudioStreamingMusic", true); @@ -1016,30 +1025,30 @@ void LLViewerMedia::setAllMediaPaused(bool val) } else { - LLViewerAudio::getInstanceFast()->startInternetStreamWithAutoFade(LLViewerMedia::getParcelAudioURL()); + LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLViewerMedia::getParcelAudioURL()); } } } else { // This actually unloads the impl, as opposed to "stop"ping the media - LLViewerParcelMedia::getInstanceFast()->stop(); + LLViewerParcelMedia::getInstance()->stop(); if (gAudiop) { - LLViewerAudio::getInstanceFast()->stopInternetStreamWithAutoFade(); + LLViewerAudio::getInstance()->stopInternetStreamWithAutoFade(); } } // remove play choice for current parcel if (agent_parcel && gAgent.getRegion()) { - LLViewerParcelAskPlay::getInstanceFast()->resetSetting(gAgent.getRegion()->getRegionID(), agent_parcel->getLocalID()); + LLViewerParcelAskPlay::getInstance()->resetSetting(gAgent.getRegion()->getRegionID(), agent_parcel->getLocalID()); } } ////////////////////////////////////////////////////////////////////////////////////////// bool LLViewerMedia::isParcelMediaPlaying() { - viewer_media_t media = LLViewerParcelMedia::getInstanceFast()->getParcelMedia(); + viewer_media_t media = LLViewerParcelMedia::getInstance()->getParcelMedia(); return (LLViewerMedia::hasParcelMedia() && media && media->hasMedia()); } @@ -1191,7 +1200,7 @@ LLCore::HttpHeaders::ptr_t LLViewerMedia::getHttpHeaders() ///////////////////////////////////////////////////////////////////////////////////////// void LLViewerMedia::setOpenIDCookie(const std::string& url) { - if(!mOpenIDCookie.empty()) + if(!gNonInteractive && !mOpenIDCookie.empty()) { std::string profileUrl = getProfileURL(""); @@ -1461,7 +1470,7 @@ bool LLViewerMedia::hasInWorldMedia() ////////////////////////////////////////////////////////////////////////////////////////// bool LLViewerMedia::hasParcelMedia() { - return !LLViewerParcelMedia::getInstanceFast()->getURL().empty(); + return !LLViewerParcelMedia::getInstance()->getURL().empty(); } ////////////////////////////////////////////////////////////////////////////////////////// @@ -1473,7 +1482,7 @@ bool LLViewerMedia::hasParcelAudio() ////////////////////////////////////////////////////////////////////////////////////////// std::string LLViewerMedia::getParcelAudioURL() { - return LLViewerParcelMgr::getInstanceFast()->getAgentParcel()->getMusicURL(); + return LLViewerParcelMgr::getInstance()->getAgentParcel()->getMusicURL(); } ////////////////////////////////////////////////////////////////////////////////////////// @@ -1565,6 +1574,8 @@ LLViewerMediaImpl::LLViewerMediaImpl( const LLUUID& texture_id, media_tex->setMediaImpl(); } + mMainQueue = LL::WorkQueue::getInstance("mainloop"); + mTexUpdateQueue = LL::WorkQueue::getInstance("LLImageGL"); // Share work queue with tex loader. } ////////////////////////////////////////////////////////////////////////////////////////// @@ -1651,11 +1662,13 @@ void LLViewerMediaImpl::destroyMediaSource() cancelMimeTypeProbe(); + mLock.lock(); // Delay tear-down while bg thread is updating if(mMediaSource) { mMediaSource->setDeleteOK(true) ; mMediaSource = NULL; // shared pointer } + mLock.unlock(); } ////////////////////////////////////////////////////////////////////////////////////////// @@ -1668,6 +1681,11 @@ void LLViewerMediaImpl::setMediaType(const std::string& media_type) /*static*/ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_type, LLPluginClassMediaOwner *owner /* may be NULL */, S32 default_width, S32 default_height, F64 zoom_factor, const std::string target, bool clean_browser) { + if (gNonInteractive) + { + return NULL; + } + std::string plugin_basename = LLMIMETypes::implType(media_type); LLPluginClassMedia* media_source = NULL; @@ -1677,7 +1695,7 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_ if ((plugin_basename == "media_plugin_cef") && !gSavedSettings.getBOOL("PluginAttachDebuggerToPlugins") && !clean_browser) { - media_source = LLViewerMedia::getInstanceFast()->getSpareBrowserMediaSource(); + media_source = LLViewerMedia::getInstance()->getSpareBrowserMediaSource(); if(media_source) { media_source->setOwner(owner); @@ -1752,7 +1770,7 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_ media_source->enableMediaPluginDebugging( media_plugin_debugging_enabled || clean_browser); // need to set agent string here before instance created - media_source->setBrowserUserAgent(LLViewerMedia::getInstanceFast()->getCurrentUserAgent()); + media_source->setBrowserUserAgent(LLViewerMedia::getInstance()->getCurrentUserAgent()); // configure and pass proxy setup based on debug settings that are // configured by UI in prefs -> setup @@ -1828,7 +1846,7 @@ bool LLViewerMediaImpl::initializePlugin(const std::string& media_type) media_source->setDisableTimeout(gSavedSettings.getBOOL("DebugPluginDisableTimeout")); media_source->setLoop(mMediaLoop); media_source->setAutoScale(mMediaAutoScale); - media_source->setBrowserUserAgent(LLViewerMedia::getInstanceFast()->getCurrentUserAgent()); + media_source->setBrowserUserAgent(LLViewerMedia::getInstance()->getCurrentUserAgent()); media_source->focus(mHasFocus); media_source->setBackgroundColor(mBackgroundColor); @@ -2065,10 +2083,11 @@ void LLViewerMediaImpl::setMute(bool mute) ////////////////////////////////////////////////////////////////////////////////////////// void LLViewerMediaImpl::updateVolume() { + LL_RECORD_BLOCK_TIME(FTM_MEDIA_UPDATE_VOLUME); if(mMediaSource) { // always scale the volume by the global media volume - F32 volume = mRequestedVolume * LLViewerMedia::getInstanceFast()->getVolume(); + F32 volume = mRequestedVolume * LLViewerMedia::getInstance()->getVolume(); if (mProximityCamera > 0) { @@ -2782,207 +2801,279 @@ static LLTrace::BlockTimerStatHandle FTM_MEDIA_SET_SUBIMAGE("Set Subimage"); void LLViewerMediaImpl::update() { - LL_RECORD_BLOCK_TIME(FTM_MEDIA_DO_UPDATE); - if(mMediaSource == NULL) - { - if(mPriority == LLPluginClassMedia::PRIORITY_UNLOADED) - { - // This media source should not be loaded. - } - else if(mPriority <= LLPluginClassMedia::PRIORITY_SLIDESHOW) - { - // Don't load new instances that are at PRIORITY_SLIDESHOW or below. They're just kept around to preserve state. - } + LL_PROFILE_ZONE_SCOPED_CATEGORY_MEDIA; //LL_RECORD_BLOCK_TIME(FTM_MEDIA_DO_UPDATE); + if(mMediaSource == NULL) + { + if(mPriority == LLPluginClassMedia::PRIORITY_UNLOADED) + { + // This media source should not be loaded. + } + else if(mPriority <= LLPluginClassMedia::PRIORITY_SLIDESHOW) + { + // Don't load new instances that are at PRIORITY_SLIDESHOW or below. They're just kept around to preserve state. + } else if (!mMimeProbe.expired()) - { - // this media source is doing a MIME type probe -- don't try loading it again. - } - else - { - // This media may need to be loaded. - if(sMediaCreateTimer.hasExpired()) - { + { + // this media source is doing a MIME type probe -- don't try loading it again. + } + else + { + // This media may need to be loaded. + if(sMediaCreateTimer.hasExpired()) + { #ifdef SHOW_DEBUG - LL_DEBUGS("PluginPriority") << this << ": creating media based on timer expiration" << LL_ENDL; + LL_DEBUGS("PluginPriority") << this << ": creating media based on timer expiration" << LL_ENDL; #endif - createMediaSource(); - sMediaCreateTimer.setTimerExpirySec(LLVIEWERMEDIA_CREATE_DELAY); - } + createMediaSource(); + sMediaCreateTimer.setTimerExpirySec(LLVIEWERMEDIA_CREATE_DELAY); + } #ifdef SHOW_DEBUG - else - { - LL_DEBUGS("PluginPriority") << this << ": NOT creating media (waiting on timer)" << LL_ENDL; - } + else + { + LL_DEBUGS("PluginPriority") << this << ": NOT creating media (waiting on timer)" << LL_ENDL; + } #endif - } - } - else - { - updateVolume(); + } + } + else + { + updateVolume(); - // TODO: this is updated every frame - is this bad? - // Removing this as part of the post viewer64 media update - // Removed as not implemented in CEF embedded browser - // See MAINT-8194 for a more fuller description - // updateJavascriptObject(); - } + // TODO: this is updated every frame - is this bad? + // Removing this as part of the post viewer64 media update + // Removed as not implemented in CEF embedded browser + // See MAINT-8194 for a more fuller description + // updateJavascriptObject(); + } - if(mMediaSource == NULL) - { - return; - } + if(mMediaSource == NULL) + { + return; + } - // Make sure a navigate doesn't happen during the idle -- it can cause mMediaSource to get destroyed, which can cause a crash. - setNavigateSuspended(true); + // Make sure a navigate doesn't happen during the idle -- it can cause mMediaSource to get destroyed, which can cause a crash. + setNavigateSuspended(true); - mMediaSource->idle(); + mMediaSource->idle(); - setNavigateSuspended(false); + setNavigateSuspended(false); - if(mMediaSource == NULL) - { - return; - } + if(mMediaSource == NULL) + { + return; + } - if(mMediaSource->isPluginExited()) - { - resetPreviousMediaState(); - destroyMediaSource(); - return; - } + if(mMediaSource->isPluginExited()) + { + resetPreviousMediaState(); + destroyMediaSource(); + return; + } - if(!mMediaSource->textureValid()) - { - return; - } + if(!mMediaSource->textureValid()) + { + return; + } - if(mSuspendUpdates || !mVisible) - { - return; - } + if(mSuspendUpdates || !mVisible) + { + return; + } - LLViewerMediaTexture* placeholder_image = updatePlaceholderImage(); + + LLViewerMediaTexture* media_tex; + U8* data; + S32 data_width; + S32 data_height; + S32 x_pos; + S32 y_pos; + S32 width; + S32 height; + + if (preMediaTexUpdate(media_tex, data, data_width, data_height, x_pos, y_pos, width, height)) + { + // Push update to worker thread + auto main_queue = LLImageGLThread::sEnabled ? mMainQueue.lock() : nullptr; + if (main_queue) + { + mTextureUpdatePending = true; + ref(); // protect texture from deletion while active on bg queue + media_tex->ref(); + main_queue->postTo( + mTexUpdateQueue, // Worker thread queue + [=]() // work done on update worker thread + { +#if LL_IMAGEGL_THREAD_CHECK + media_tex->getGLTexture()->mActiveThread = LLThread::currentID(); +#endif + doMediaTexUpdate(media_tex, data, data_width, data_height, x_pos, y_pos, width, height, true); + }, + [=]() // callback to main thread + { +#if LL_IMAGEGL_THREAD_CHECK + media_tex->getGLTexture()->mActiveThread = LLThread::currentID(); +#endif + mTextureUpdatePending = false; + media_tex->unref(); + unref(); + }); + } + else + { + doMediaTexUpdate(media_tex, data, data_width, data_height, x_pos, y_pos, width, height, false); // otherwise, update on main thread + } + } +} - if(placeholder_image) - { - LLRect dirty_rect; +bool LLViewerMediaImpl::preMediaTexUpdate(LLViewerMediaTexture*& media_tex, U8*& data, S32& data_width, S32& data_height, S32& x_pos, S32& y_pos, S32& width, S32& height) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_MEDIA; - // Since we're updating this texture, we know it's playing. Tell the texture to do its replacement magic so it gets rendered. - placeholder_image->setPlaying(TRUE); + bool retval = false; - if(mMediaSource->getDirty(&dirty_rect)) - { - // Constrain the dirty rect to be inside the texture - S32 x_pos = llmax(dirty_rect.mLeft, 0); - S32 y_pos = llmax(dirty_rect.mBottom, 0); - S32 width = llmin(dirty_rect.mRight, placeholder_image->getWidth()) - x_pos; - S32 height = llmin(dirty_rect.mTop, placeholder_image->getHeight()) - y_pos; + if (!mTextureUpdatePending) + { + media_tex = updateMediaImage(); - if(width > 0 && height > 0) - { + if (media_tex && mMediaSource) + { + LLRect dirty_rect; + S32 media_width = mMediaSource->getTextureWidth(); + S32 media_height = mMediaSource->getTextureHeight(); + //S32 media_depth = mMediaSource->getTextureDepth(); - U8* data = NULL; - { - LL_RECORD_BLOCK_TIME(FTM_MEDIA_GET_DATA); - data = mMediaSource->getBitsData(); - } + // Since we're updating this texture, we know it's playing. Tell the texture to do its replacement magic so it gets rendered. + media_tex->setPlaying(TRUE); - if(data != NULL) - { - // Offset the pixels pointer to match x_pos and y_pos - data += ( x_pos * mMediaSource->getTextureDepth() * mMediaSource->getBitsWidth() ); - data += ( y_pos * mMediaSource->getTextureDepth() ); + if (mMediaSource->getDirty(&dirty_rect)) + { + // Constrain the dirty rect to be inside the texture + x_pos = llmax(dirty_rect.mLeft, 0); + y_pos = llmax(dirty_rect.mBottom, 0); + width = llmin(dirty_rect.mRight, media_width) - x_pos; + height = llmin(dirty_rect.mTop, media_height) - y_pos; - { - LL_RECORD_BLOCK_TIME(FTM_MEDIA_SET_SUBIMAGE); - placeholder_image->setSubImage( - data, - mMediaSource->getBitsWidth(), - mMediaSource->getBitsHeight(), - x_pos, - y_pos, - width, - height); - } - } + if (width > 0 && height > 0) + { + data = mMediaSource->getBitsData(); + data_width = mMediaSource->getWidth(); + data_height = mMediaSource->getHeight(); + + if (data != NULL) + { + // data is ready to be copied to GL + retval = true; + } + } - } + mMediaSource->resetDirty(); + } + } + } - mMediaSource->resetDirty(); - } - } + return retval; } +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::doMediaTexUpdate(LLViewerMediaTexture* media_tex, U8* data, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, bool sync) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_MEDIA; + mLock.lock(); // don't allow media source tear-down during update + + // wrap "data" in an LLImageRaw but do NOT make a copy + LLPointer<LLImageRaw> raw = new LLImageRaw(data, media_tex->getWidth(), media_tex->getHeight(), media_tex->getComponents(), true); + + // Allocate GL texture based on LLImageRaw but do NOT copy to GL + LLGLuint tex_name = 0; + media_tex->createGLTexture(0, raw, 0, TRUE, LLGLTexture::OTHER, true, &tex_name); + + // copy just the subimage covered by the image raw to GL + media_tex->setSubImage(data, data_width, data_height, x_pos, y_pos, width, height, tex_name); + + if (sync) + { + media_tex->getGLTexture()->syncToMainThread(tex_name); + } + else + { + media_tex->getGLTexture()->syncTexName(tex_name); + } + + // release the data pointer before freeing raw so LLImageRaw destructor doesn't + // free memory at data pointer + raw->releaseData(); + + mLock.unlock(); +} ////////////////////////////////////////////////////////////////////////////////////////// void LLViewerMediaImpl::updateImagesMediaStreams() { } - ////////////////////////////////////////////////////////////////////////////////////////// -LLViewerMediaTexture* LLViewerMediaImpl::updatePlaceholderImage() +LLViewerMediaTexture* LLViewerMediaImpl::updateMediaImage() { -// if(mTextureId.isNull()) + LL_PROFILE_ZONE_SCOPED_CATEGORY_MEDIA; +// if (!mMediaSource) // [SL:KB] - Patch: Render-TextureToggle (Catznip-4.0) - if ( (mTextureId.isNull()) || ((LLViewerFetchedTexture::sDefaultDiffuseImagep.notNull()) && (LLViewerFetchedTexture::sDefaultDiffuseImagep->getID() == mTextureId)) ) + if ( (!mMediaSource) || ((LLViewerFetchedTexture::sDefaultDiffuseImagep.notNull()) && (LLViewerFetchedTexture::sDefaultDiffuseImagep->getID() == mTextureId))) // [/SL:KB] - { - // The code that created this instance will read from the plugin's bits. - return NULL; - } - - LLViewerMediaTexture* placeholder_image = LLViewerTextureManager::getMediaTexture( mTextureId ); - - if (mNeedsNewTexture - || placeholder_image->getUseMipMaps() - || (placeholder_image->getWidth() != mMediaSource->getTextureWidth()) - || (placeholder_image->getHeight() != mMediaSource->getTextureHeight()) - || (mTextureUsedWidth != mMediaSource->getWidth()) - || (mTextureUsedHeight != mMediaSource->getHeight()) - ) - { - LL_DEBUGS("Media") << "initializing media placeholder" << LL_ENDL; - LL_DEBUGS("Media") << "movie image id " << mTextureId << LL_ENDL; - - int texture_width = mMediaSource->getTextureWidth(); - int texture_height = mMediaSource->getTextureHeight(); - int texture_depth = mMediaSource->getTextureDepth(); - - // MEDIAOPT: check to see if size actually changed before doing work - placeholder_image->destroyGLTexture(); - // MEDIAOPT: apparently just calling setUseMipMaps(FALSE) doesn't work? - placeholder_image->reinit(FALSE); // probably not needed - - // MEDIAOPT: seems insane that we actually have to make an imageraw then - // immediately discard it - LLPointer<LLImageRaw> raw = new LLImageRaw(texture_width, texture_height, texture_depth); - // Clear the texture to the background color, ignoring alpha. - // convert background color channels from [0.0, 1.0] to [0, 255]; - raw->clear(int(mBackgroundColor.mV[VX] * 255.0f), int(mBackgroundColor.mV[VY] * 255.0f), int(mBackgroundColor.mV[VZ] * 255.0f), 0xff); - int discard_level = 0; - - // ask media source for correct GL image format constants - placeholder_image->setExplicitFormat(mMediaSource->getTextureFormatInternal(), - mMediaSource->getTextureFormatPrimary(), - mMediaSource->getTextureFormatType(), - mMediaSource->getTextureFormatSwapBytes()); - - placeholder_image->createGLTexture(discard_level, raw); - - // MEDIAOPT: set this dynamically on play/stop - // FIXME -// placeholder_image->mIsMediaTexture = true; - mNeedsNewTexture = false; - - // If the amount of the texture being drawn by the media goes down in either width or height, - // recreate the texture to avoid leaving parts of the old image behind. - mTextureUsedWidth = mMediaSource->getWidth(); - mTextureUsedHeight = mMediaSource->getHeight(); - } + { + return nullptr; // not ready for updating + } - return placeholder_image; + llassert(!mTextureId.isNull()); + LLViewerMediaTexture* media_tex = LLViewerTextureManager::getMediaTexture( mTextureId ); + + if ( mNeedsNewTexture + || media_tex->getUseMipMaps() + || (media_tex->getWidth() != mMediaSource->getTextureWidth()) + || (media_tex->getHeight() != mMediaSource->getTextureHeight()) + || (mTextureUsedWidth != mMediaSource->getWidth()) + || (mTextureUsedHeight != mMediaSource->getHeight()) + ) + { + LL_DEBUGS("Media") << "initializing media placeholder" << LL_ENDL; + LL_DEBUGS("Media") << "movie image id " << mTextureId << LL_ENDL; + + int texture_width = mMediaSource->getTextureWidth(); + int texture_height = mMediaSource->getTextureHeight(); + int texture_depth = mMediaSource->getTextureDepth(); + + // MEDIAOPT: check to see if size actually changed before doing work + media_tex->destroyGLTexture(); + // MEDIAOPT: apparently just calling setUseMipMaps(FALSE) doesn't work? + media_tex->reinit(FALSE); // probably not needed + + // MEDIAOPT: seems insane that we actually have to make an imageraw then + // immediately discard it + LLPointer<LLImageRaw> raw = new LLImageRaw(texture_width, texture_height, texture_depth); + // Clear the texture to the background color, ignoring alpha. + // convert background color channels from [0.0, 1.0] to [0, 255]; + raw->clear(int(mBackgroundColor.mV[VX] * 255.0f), int(mBackgroundColor.mV[VY] * 255.0f), int(mBackgroundColor.mV[VZ] * 255.0f), 0xff); + + // ask media source for correct GL image format constants + media_tex->setExplicitFormat(mMediaSource->getTextureFormatInternal(), + mMediaSource->getTextureFormatPrimary(), + mMediaSource->getTextureFormatType(), + mMediaSource->getTextureFormatSwapBytes()); + + int discard_level = 0; + media_tex->createGLTexture(discard_level, raw); + + // MEDIAOPT: set this dynamically on play/stop + // FIXME +// media_tex->mIsMediaTexture = true; + mNeedsNewTexture = false; + + // If the amount of the texture being drawn by the media goes down in either width or height, + // recreate the texture to avoid leaving parts of the old image behind. + mTextureUsedWidth = mMediaSource->getWidth(); + mTextureUsedHeight = mMediaSource->getHeight(); + } + return media_tex; } @@ -3126,7 +3217,7 @@ bool LLViewerMediaImpl::isForcedUnloaded() const } // If this media's class is not supposed to be shown, unload - if (!shouldShowBasedOnClass()) + if (!shouldShowBasedOnClass() || isObscured()) { return true; } @@ -3580,7 +3671,7 @@ static LLTrace::BlockTimerStatHandle FTM_MEDIA_CALCULATE_INTEREST("Calculate Int void LLViewerMediaImpl::calculateInterest() { - LL_RECORD_BLOCK_TIME(FTM_MEDIA_CALCULATE_INTEREST); + LL_PROFILE_ZONE_SCOPED_CATEGORY_MEDIA; //LL_RECORD_BLOCK_TIME(FTM_MEDIA_CALCULATE_INTEREST); LLViewerMediaTexture* texture = LLViewerTextureManager::findMediaTexture( mTextureId ); if(texture != NULL) @@ -3631,7 +3722,7 @@ void LLViewerMediaImpl::calculateInterest() llassert(obj); if (!obj) continue; if(mutelist_exists && - LLMuteList::getInstanceFast()->isMuted(obj->getID())) + LLMuteList::getInstance()->isMuted(obj->getID())) { mIsMuted = true; } @@ -3640,11 +3731,11 @@ void LLViewerMediaImpl::calculateInterest() // We won't have full permissions data for all objects. Attempt to mute objects when we can tell their owners are muted. if (selectmgr_exists) { - LLPermissions* obj_perm = LLSelectMgr::getInstanceFast()->findObjectPermissions(obj); + LLPermissions* obj_perm = LLSelectMgr::getInstance()->findObjectPermissions(obj); if(obj_perm) { if(mutelist_exists && - LLMuteList::getInstanceFast()->isMuted(obj_perm->getOwner())) + LLMuteList::getInstance()->isMuted(obj_perm->getOwner())) mIsMuted = true; } } @@ -3912,6 +4003,40 @@ bool LLViewerMediaImpl::shouldShowBasedOnClass() const } } +////////////////////////////////////////////////////////////////////////////////////////// +// +bool LLViewerMediaImpl::isObscured() const +{ + if (getUsedInUI() || isParcelMedia() || isAttachedToHUD()) return false; + + LLParcel* agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); + if (!agent_parcel) + { + return false; + } + + if (agent_parcel->getObscureMOAP() && !isInAgentParcel()) + { + return true; + } + + return false; +} + +bool LLViewerMediaImpl::isAttachedToHUD() const +{ + std::list< LLVOVolume* >::const_iterator iter = mObjectList.begin(); + std::list< LLVOVolume* >::const_iterator end = mObjectList.end(); + for ( ; iter != end; iter++) + { + if ((*iter)->isHUDAttachment()) + { + return true; + } + } + return false; +} + ////////////////////////////////////////////////////////////////////////////////////////// // bool LLViewerMediaImpl::isAttachedToAnotherAvatar() const @@ -3986,5 +4111,5 @@ LLNotificationPtr LLViewerMediaImpl::getCurrentNotification() const // static bool LLViewerMediaImpl::isObjectInAgentParcel(LLVOVolume *obj) { - return (LLViewerParcelMgr::getInstanceFast()->inAgentParcel(obj->getPositionGlobal())); + return (LLViewerParcelMgr::getInstance()->inAgentParcel(obj->getPositionGlobal())); } diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h index 05f9f8d429105b1899df10b5945808963efe4368..e3e4ddeb8c6cbc0fa8a2f7aa5b2160303608b6a8 100644 --- a/indra/newview/llviewermedia.h +++ b/indra/newview/llviewermedia.h @@ -197,7 +197,7 @@ class LLViewerMediaImpl U8 media_loop); ~LLViewerMediaImpl(); - + // Override inherited version from LLViewerMediaEventEmitter virtual void emitEvent(LLPluginClassMedia* self, LLViewerMediaObserver::EMediaEvent event) override; @@ -266,6 +266,8 @@ class LLViewerMediaImpl void scaleTextureCoords(const LLVector2& texture_coords, S32 *x, S32 *y); void update(); + bool preMediaTexUpdate(LLViewerMediaTexture*& media_tex, U8*& data, S32& data_width, S32& data_height, S32& x_pos, S32& y_pos, S32& width, S32& height); + void doMediaTexUpdate(LLViewerMediaTexture* media_tex, U8* data, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, bool sync); void updateImagesMediaStreams(); LLUUID getMediaTextureID() const; @@ -421,6 +423,8 @@ class LLViewerMediaImpl void cancelMimeTypeProbe(); + bool isAttachedToHUD() const; + // Is this media attached to an avatar *not* self bool isAttachedToAnotherAvatar() const; @@ -433,12 +437,14 @@ class LLViewerMediaImpl private: bool isAutoPlayable() const; bool shouldShowBasedOnClass() const; + bool isObscured() const; static bool isObjectAttachedToAnotherAvatar(LLVOVolume *obj); static bool isObjectInAgentParcel(LLVOVolume *obj); private: // a single media url with some data and an impl. std::shared_ptr<LLPluginClassMedia> mMediaSource; + LLMutex mLock; F64 mZoomFactor; LLUUID mTextureId; bool mMovieImageHasMips; @@ -458,6 +464,7 @@ class LLViewerMediaImpl S32 mTextureUsedWidth; S32 mTextureUsedHeight; bool mSuspendUpdates; + bool mTextureUpdatePending = false; bool mVisible; ECursorType mLastSetCursor; EMediaNavState mMediaNavState; @@ -491,7 +498,7 @@ class LLViewerMediaImpl LLNotificationPtr mNotification; bool mCleanBrowser; // force the creation of a clean browsing target with full options enabled static std::vector<std::string> sMimeTypesFailed; - + LLPointer<LLImageRaw> mRawImage; //backing buffer for texture updates private: BOOL mIsUpdated ; std::list< LLVOVolume* > mObjectList ; @@ -501,7 +508,10 @@ class LLViewerMediaImpl bool mCanceling; private: - LLViewerMediaTexture *updatePlaceholderImage(); + LLViewerMediaTexture *updateMediaImage(); + LL::WorkQueue::weak_t mMainQueue; + LL::WorkQueue::weak_t mTexUpdateQueue; + }; #endif // LLVIEWERMEDIA_H diff --git a/indra/newview/llviewermediafocus.cpp b/indra/newview/llviewermediafocus.cpp index a9b0ae2d2e9de415ad53f560a1e391b4fd089cc0..ba80eeb6b6360c96f774b9e734610e585505d700 100644 --- a/indra/newview/llviewermediafocus.cpp +++ b/indra/newview/llviewermediafocus.cpp @@ -67,7 +67,7 @@ LLViewerMediaFocus::~LLViewerMediaFocus() void LLViewerMediaFocus::setFocusFace(LLPointer<LLViewerObject> objectp, S32 face, viewer_media_t media_impl, LLVector3 pick_normal) { - LLParcel *parcel = LLViewerParcelMgr::getInstanceFast()->getAgentParcel(); + LLParcel *parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); LLViewerMediaImpl *old_media_impl = getFocusedMediaImpl(); if(old_media_impl) @@ -76,7 +76,7 @@ void LLViewerMediaFocus::setFocusFace(LLPointer<LLViewerObject> objectp, S32 fac } // Always clear the current selection. If we're setting focus on a face, we'll reselect the correct object below. - LLSelectMgr::getInstanceFast()->deselectAll(); + LLSelectMgr::getInstance()->deselectAll(); mSelection = NULL; if (media_impl.notNull() && objectp.notNull()) @@ -89,7 +89,7 @@ void LLViewerMediaFocus::setFocusFace(LLPointer<LLViewerObject> objectp, S32 fac mFocusedObjectNormal = pick_normal; // Set the selection in the selection manager so we can draw the focus ring. - mSelection = LLSelectMgr::getInstanceFast()->selectObjectOnly(objectp, face); + mSelection = LLSelectMgr::getInstance()->selectObjectOnly(objectp, face); // Focusing on a media face clears its disable flag. media_impl->setDisabled(false); @@ -222,7 +222,7 @@ LLVector3d LLViewerMediaFocus::setCameraZoom(LLViewerObject* object, LLVector3 n // We need the aspect ratio, and the 3 components of the bbox as height, width, and depth. F32 aspect_ratio = getBBoxAspectRatio(bbox, normal, &height, &width, &depth); - F32 camera_aspect = LLViewerCamera::getInstanceFast()->getAspect(); + F32 camera_aspect = LLViewerCamera::getInstance()->getAspect(); LL_DEBUGS() << "normal = " << normal << ", aspect_ratio = " << aspect_ratio << ", camera_aspect = " << camera_aspect << LL_ENDL; @@ -239,14 +239,14 @@ LLVector3d LLViewerMediaFocus::setCameraZoom(LLViewerObject* object, LLVector3 n // We will add half the depth of the bounding box, as the distance projection uses the center point of the bbox. if(camera_aspect < 1.0f || invert) { - angle_of_view = llmax(0.1f, LLViewerCamera::getInstanceFast()->getView() * LLViewerCamera::getInstanceFast()->getAspect()); + angle_of_view = llmax(0.1f, LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect()); distance = width * 0.5 * padding_factor / tan(angle_of_view * 0.5f ); LL_DEBUGS() << "using width (" << width << "), angle_of_view = " << angle_of_view << ", distance = " << distance << LL_ENDL; } else { - angle_of_view = llmax(0.1f, LLViewerCamera::getInstanceFast()->getView()); + angle_of_view = llmax(0.1f, LLViewerCamera::getInstance()->getView()); distance = height * 0.5 * padding_factor / tan(angle_of_view * 0.5f ); LL_DEBUGS() << "using height (" << height << "), angle_of_view = " << angle_of_view << ", distance = " << distance << LL_ENDL; @@ -408,7 +408,7 @@ void LLViewerMediaFocus::update() clearFocus(); } } - else if(LLToolMgr::getInstanceFast()->inBuildMode()) + else if(LLToolMgr::getInstance()->inBuildMode()) { // Build tools are selected -- clear focus. clearFocus(); @@ -538,7 +538,7 @@ bool LLViewerMediaFocus::isHoveringOverFace(LLPointer<LLViewerObject> objectp, S LLViewerMediaImpl* LLViewerMediaFocus::getFocusedMediaImpl() { - return LLViewerMedia::getInstanceFast()->getMediaImplFromTextureID(mFocusedImplID); + return LLViewerMedia::getInstance()->getMediaImplFromTextureID(mFocusedImplID); } LLViewerObject* LLViewerMediaFocus::getFocusedObject() @@ -548,7 +548,7 @@ LLViewerObject* LLViewerMediaFocus::getFocusedObject() LLViewerMediaImpl* LLViewerMediaFocus::getHoverMediaImpl() { - return LLViewerMedia::getInstanceFast()->getMediaImplFromTextureID(mHoverImplID); + return LLViewerMedia::getInstance()->getMediaImplFromTextureID(mHoverImplID); } LLViewerObject* LLViewerMediaFocus::getHoverObject() @@ -558,7 +558,7 @@ LLViewerObject* LLViewerMediaFocus::getHoverObject() void LLViewerMediaFocus::focusZoomOnMedia(LLUUID media_id) { - LLViewerMediaImpl* impl = LLViewerMedia::getInstanceFast()->getMediaImplFromTextureID(media_id); + LLViewerMediaImpl* impl = LLViewerMedia::getInstance()->getMediaImplFromTextureID(media_id); if(impl) { @@ -575,7 +575,7 @@ void LLViewerMediaFocus::focusZoomOnMedia(LLUUID media_id) { // If that didn't work, use the inverse of the camera "look at" axis, which should keep the camera pointed in the same direction. // LL_INFOS() << "approximate face normal invalid, using camera direction." << LL_ENDL; - normal = LLViewerCamera::getInstanceFast()->getAtAxis(); + normal = LLViewerCamera::getInstance()->getAtAxis(); normal *= (F32)-1.0f; } diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 94fdf862706a80ea0466fdbd47189073605fed27..60d01aaced253a189e5a289cd125f5da0adc4f0a 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -33,10 +33,11 @@ #include "llviewermenu.h" // linden library includes -#include "llavatarnamecache.h" // IDEVO +#include "llavatarnamecache.h" // IDEVO (I Are Not Men!) +#include "llcombobox.h" +#include "llcoros.h" #include "llfloaterreg.h" #include "llfloatersidepanelcontainer.h" -#include "llcombobox.h" #include "llinventorypanel.h" #include "llnotifications.h" #include "llnotificationsutil.h" @@ -58,6 +59,7 @@ #include "llcompilequeue.h" #include "llconsole.h" #include "lldebugview.h" +#include "lldiskcache.h" #include "llenvironment.h" #include "llfilepicker.h" #include "llfirstuse.h" @@ -98,6 +100,7 @@ #include "llmarketplacefunctions.h" #include "llmenuoptionpathfindingrebakenavmesh.h" #include "llmoveview.h" +#include "llnavigationbar.h" #include "llparcel.h" #include "llregex.h" #include "llrootview.h" @@ -408,9 +411,25 @@ void initialize_menus(); void set_merchant_SLM_menu() { // All other cases (new merchant, not merchant, migrated merchant): show the new Marketplace Listings menu and enable the tool - gMenuHolder->getChild<LLView>("MarketplaceListings")->setVisible((BOOL)LLGridManager::getInstance()->isInSecondlife()); + bool in_sl = LLGridManager::getInstance()->isInSecondlife(); + gMenuHolder->getChild<LLView>("MarketplaceListings")->setVisible((BOOL)in_sl); LLCommand* command = LLCommandManager::instance().getCommand("marketplacelistings"); - gToolBarView->enableCommand(command->id(), LLGridManager::getInstance()->isInSecondlife()); + gToolBarView->enableCommand(command->id(), in_sl); + + if(in_sl) + { + const LLUUID marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false); + if (marketplacelistings_id.isNull()) + { + U32 mkt_status = LLMarketplaceData::instance().getSLMStatus(); + bool is_merchant = (mkt_status == MarketplaceStatusCodes::MARKET_PLACE_MERCHANT) || (mkt_status == MarketplaceStatusCodes::MARKET_PLACE_MIGRATED_MERCHANT); + if (is_merchant) + { + gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, true); + LL_WARNS("SLM") << "Creating the marketplace listings folder for a merchant" << LL_ENDL; + } + } + } } void check_merchant_status(bool force) @@ -1694,7 +1713,7 @@ class LLAdvancedEnableAppearanceToXML : public view_listener_t { bool handleEvent(const LLSD& userdata) { - LLViewerObject *obj = LLSelectMgr::getInstanceFast()->getSelection()->getPrimaryObject(); + LLViewerObject *obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); if (obj && obj->isAnimatedObject() && obj->getControlAvatar()) { return gSavedSettings.getBOOL("DebugAnimatedObjects"); @@ -1720,7 +1739,7 @@ class LLAdvancedAppearanceToXML : public view_listener_t bool handleEvent(const LLSD& userdata) { std::string emptyname; - LLViewerObject *obj = LLSelectMgr::getInstanceFast()->getSelection()->getPrimaryObject(); + LLViewerObject *obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); LLVOAvatar *avatar = NULL; if (obj) { @@ -2129,6 +2148,32 @@ class LLAdvancedDropPacket : public view_listener_t } }; +////////////////////// +// PURGE DISK CACHE // +////////////////////// + + +class LLAdvancedPurgeDiskCache : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + LL::WorkQueue::ptr_t main_queue = LL::WorkQueue::getInstance("mainloop"); + LL::WorkQueue::ptr_t general_queue = LL::WorkQueue::getInstance("General"); + llassert_always(main_queue); + llassert_always(general_queue); + main_queue->postTo( + general_queue, + []() // Work done on general queue + { + LLDiskCache::getInstance()->purge(); + // Nothing needed to return + }, + [](){}); // Callback to main thread is empty as there is nothing left to do + + return true; + } +}; + //////////////////// // EVENT Recorder // @@ -2354,18 +2399,6 @@ class LLAdvancedEnableObjectObjectOcclusion: public view_listener_t } }; -///////////////////////////////////// -// Enable Framebuffer Objects /// -///////////////////////////////////// -class LLAdvancedEnableRenderFBO: public view_listener_t -{ - bool handleEvent(const LLSD& userdata) - { - bool new_value = gGLManager.mHasFramebufferObject; - return new_value; - } -}; - ///////////////////////////////////// // Enable Deferred Rendering /// ///////////////////////////////////// @@ -2373,7 +2406,7 @@ class LLAdvancedEnableRenderDeferred: public view_listener_t { bool handleEvent(const LLSD& userdata) { - bool new_value = gGLManager.mHasFramebufferObject && LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1 && + bool new_value = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1 && LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) > 0; return new_value; } @@ -2386,7 +2419,7 @@ class LLAdvancedEnableRenderDeferredOptions: public view_listener_t { bool handleEvent(const LLSD& userdata) { - bool new_value = gGLManager.mHasFramebufferObject && LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1 && + bool new_value = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1 && LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) > 0 && gSavedSettings.getBOOL("RenderDeferred"); return new_value; } @@ -2438,6 +2471,7 @@ class LLAdvancedForceErrorLlerror : public view_listener_t return true; } }; + class LLAdvancedForceErrorBadMemoryAccess : public view_listener_t { bool handleEvent(const LLSD& userdata) @@ -2447,6 +2481,22 @@ class LLAdvancedForceErrorBadMemoryAccess : public view_listener_t } }; +class LLAdvancedForceErrorBadMemoryAccessCoro : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + LLCoros::instance().launch( + "AdvancedForceErrorBadMemoryAccessCoro", + [](){ + // Wait for one mainloop() iteration, letting the enclosing + // handleEvent() method return. + llcoro::suspend(); + force_error_bad_memory_access(NULL); + }); + return true; + } +}; + class LLAdvancedForceErrorInfiniteLoop : public view_listener_t { bool handleEvent(const LLSD& userdata) @@ -2465,6 +2515,22 @@ class LLAdvancedForceErrorSoftwareException : public view_listener_t } }; +class LLAdvancedForceErrorSoftwareExceptionCoro : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + LLCoros::instance().launch( + "AdvancedForceErrorSoftwareExceptionCoro", + [](){ + // Wait for one mainloop() iteration, letting the enclosing + // handleEvent() method return. + llcoro::suspend(); + force_error_software_exception(NULL); + }); + return true; + } +}; + class LLAdvancedForceErrorDriverCrash : public view_listener_t { bool handleEvent(const LLSD& userdata) @@ -2722,7 +2788,7 @@ class LLObjectReportAbuse : public view_listener_t { bool handleEvent(const LLSD& userdata) { - LLViewerObject* objectp = LLSelectMgr::getInstanceFast()->getSelection()->getPrimaryObject(); + LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); if (objectp) { LLFloaterReporter::showFromObject(objectp->getID()); @@ -2736,7 +2802,7 @@ class LLObjectEnableReportAbuse : public view_listener_t { bool handleEvent(const LLSD& userdata) { - bool new_value = LLSelectMgr::getInstanceFast()->getSelection()->getObjectCount() != 0; + bool new_value = LLSelectMgr::getInstance()->getSelection()->getObjectCount() != 0; return new_value; } }; @@ -2744,7 +2810,7 @@ class LLObjectEnableReportAbuse : public view_listener_t void handle_object_touch() { - LLViewerObject* object = LLSelectMgr::getInstanceFast()->getSelection()->getPrimaryObject(); + LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); if (!object) return; LLPickInfo pick = LLToolPie::getInstance()->getPick(); @@ -2765,6 +2831,32 @@ void handle_object_touch() send_ObjectDeGrab_message(object, pick); } +void handle_object_show_original() +{ + LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); + if (!object) + { + return; + } + + LLViewerObject *parent = (LLViewerObject*)object->getParent(); + while (parent) + { + if(parent->isAvatar()) + { + break; + } + object = parent; + parent = (LLViewerObject*)parent->getParent(); + } + + if (!object || object->isAvatar()) + { + return; + } + + show_item_original(object->getAttachmentItemID()); +} static void init_default_item_label(LLUICtrl* ctrl, const std::string& item_name) @@ -2798,7 +2890,7 @@ static LLStringExplicit get_default_item_label(const std::string& item_name) bool enable_object_touch(LLUICtrl* ctrl) { bool new_value = false; - LLViewerObject* obj = LLSelectMgr::getInstanceFast()->getSelection()->getPrimaryObject(); + LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); if (obj) { LLViewerObject* parent = (LLViewerObject*)obj->getParent(); @@ -2817,7 +2909,7 @@ bool enable_object_touch(LLUICtrl* ctrl) init_default_item_label(ctrl, item_name); // Update label based on the node touch name if available. - LLSelectNode* node = LLSelectMgr::getInstanceFast()->getSelection()->getFirstRootNode(); + LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(); if (node && node->mValid && !node->mTouchName.empty()) { ctrl->setValue(node->mTouchName); @@ -2832,7 +2924,7 @@ bool enable_object_touch(LLUICtrl* ctrl) //void label_touch(std::string& label, void*) //{ -// LLSelectNode* node = LLSelectMgr::getInstanceFast()->getSelection()->getFirstRootNode(); +// LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(); // if (node && node->mValid && !node->mTouchName.empty()) // { // label.assign(node->mTouchName); @@ -2856,7 +2948,7 @@ bool enable_object_open() { // Look for contents in root object, which is all the LLFloaterOpenObject // understands. - LLViewerObject* obj = LLSelectMgr::getInstanceFast()->getSelection()->getPrimaryObject(); + LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); if (!obj) return false; LLViewerObject* root = obj->getRootEdit(); @@ -2879,37 +2971,37 @@ class LLViewCheckJoystickFlycam : public view_listener_t { bool handleEvent(const LLSD& userdata) { - bool new_value = LLViewerJoystick::getInstanceFast()->getOverrideCamera(); + bool new_value = LLViewerJoystick::getInstance()->getOverrideCamera(); return new_value; } }; void handle_toggle_flycam() { - LLViewerJoystick::getInstanceFast()->toggleFlycam(); + LLViewerJoystick::getInstance()->toggleFlycam(); } class LLObjectBuild : public view_listener_t { bool handleEvent(const LLSD& userdata) { - if (gAgentCamera.getFocusOnAvatar() && !LLToolMgr::getInstanceFast()->inEdit() && gSavedSettings.getBOOL("EditCameraMovement") ) + if (gAgentCamera.getFocusOnAvatar() && !LLToolMgr::getInstance()->inEdit() && gSavedSettings.getBOOL("EditCameraMovement") ) { // zoom in if we're looking at the avatar gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE); - gAgentCamera.setFocusGlobal(LLToolPie::getInstanceFast()->getPick()); + gAgentCamera.setFocusGlobal(LLToolPie::getInstance()->getPick()); gAgentCamera.cameraZoomIn(0.666f); gAgentCamera.cameraOrbitOver( 30.f * DEG_TO_RAD ); gViewerWindow->moveCursorToCenter(); } else if ( gSavedSettings.getBOOL("EditCameraMovement") ) { - gAgentCamera.setFocusGlobal(LLToolPie::getInstanceFast()->getPick()); + gAgentCamera.setFocusGlobal(LLToolPie::getInstance()->getPick()); gViewerWindow->moveCursorToCenter(); } - LLToolMgr::getInstanceFast()->setCurrentToolset(gBasicToolset); - LLToolMgr::getInstanceFast()->getCurrentToolset()->selectTool( LLToolCompCreate::getInstanceFast() ); + LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset); + LLToolMgr::getInstance()->getCurrentToolset()->selectTool( LLToolCompCreate::getInstance() ); // Could be first use //LLFirstUse::useBuild(); @@ -2919,12 +3011,12 @@ class LLObjectBuild : public view_listener_t void handle_object_edit() { - LLViewerParcelMgr::getInstanceFast()->deselectLand(); + LLViewerParcelMgr::getInstance()->deselectLand(); - if (gAgentCamera.getFocusOnAvatar() && !LLToolMgr::getInstanceFast()->inEdit()) + if (gAgentCamera.getFocusOnAvatar() && !LLToolMgr::getInstance()->inEdit()) { LLFloaterTools::sPreviousFocusOnAvatar = true; - LLObjectSelectionHandle selection = LLSelectMgr::getInstanceFast()->getSelection(); + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); if (selection->getSelectType() == SELECT_TYPE_HUD || !gSavedSettings.getBOOL("EditCameraMovement")) { @@ -2950,11 +3042,11 @@ void handle_object_edit() LLFloaterReg::showInstance("build"); - LLToolMgr::getInstanceFast()->setCurrentToolset(gBasicToolset); - gFloaterTools->setEditTool( LLToolCompTranslate::getInstanceFast() ); + LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset); + gFloaterTools->setEditTool( LLToolCompTranslate::getInstance() ); - LLViewerJoystick::getInstanceFast()->moveObjects(true); - LLViewerJoystick::getInstanceFast()->setNeedsReset(true); + LLViewerJoystick::getInstance()->moveObjects(true); + LLViewerJoystick::getInstance()->setNeedsReset(true); // Could be first use //LLFirstUse::useBuild(); @@ -2967,8 +3059,8 @@ void handle_attachment_edit(const LLUUID& inv_item_id) { if (LLViewerObject* attached_obj = gAgentAvatarp->getWornAttachment(inv_item_id)) { - LLSelectMgr::getInstanceFast()->deselectAll(); - LLSelectMgr::getInstanceFast()->selectObjectAndFamily(attached_obj); + LLSelectMgr::getInstance()->deselectAll(); + LLSelectMgr::getInstance()->selectObjectAndFamily(attached_obj); handle_object_edit(); } @@ -2981,10 +3073,10 @@ void handle_attachment_touch(const LLUUID& inv_item_id) { if (LLViewerObject* attach_obj = gAgentAvatarp->getWornAttachment(gInventory.getLinkedItemID(inv_item_id))) { - LLSelectMgr::getInstanceFast()->deselectAll(); + LLSelectMgr::getInstance()->deselectAll(); - LLObjectSelectionHandle sel = LLSelectMgr::getInstanceFast()->selectObjectAndFamily(attach_obj); - if (!LLToolMgr::getInstanceFast()->inBuildMode()) + LLObjectSelectionHandle sel = LLSelectMgr::getInstance()->selectObjectAndFamily(attach_obj); + if (!LLToolMgr::getInstance()->inBuildMode()) { struct SetTransient : public LLSelectedNodeFunctor { @@ -3017,7 +3109,7 @@ bool enable_attachment_touch(const LLUUID& inv_item_id) void handle_object_inspect() { - LLObjectSelectionHandle selection = LLSelectMgr::getInstanceFast()->getSelection(); + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); LLViewerObject* selected_objectp = selection->getFirstRootObject(); if (selected_objectp) { @@ -3041,11 +3133,11 @@ class LLLandBuild : public view_listener_t { LLViewerParcelMgr::getInstance()->deselectLand(); - if (gAgentCamera.getFocusOnAvatar() && !LLToolMgr::getInstanceFast()->inEdit() && gSavedSettings.getBOOL("EditCameraMovement") ) + if (gAgentCamera.getFocusOnAvatar() && !LLToolMgr::getInstance()->inEdit() && gSavedSettings.getBOOL("EditCameraMovement") ) { // zoom in if we're looking at the avatar gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE); - gAgentCamera.setFocusGlobal(LLToolPie::getInstanceFast()->getPick()); + gAgentCamera.setFocusGlobal(LLToolPie::getInstance()->getPick()); gAgentCamera.cameraZoomIn(0.666f); gAgentCamera.cameraOrbitOver( 30.f * DEG_TO_RAD ); gViewerWindow->moveCursorToCenter(); @@ -3058,8 +3150,8 @@ class LLLandBuild : public view_listener_t } - LLToolMgr::getInstanceFast()->setCurrentToolset(gBasicToolset); - LLToolMgr::getInstanceFast()->getCurrentToolset()->selectTool( LLToolCompCreate::getInstanceFast() ); + LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset); + LLToolMgr::getInstance()->getCurrentToolset()->selectTool( LLToolCompCreate::getInstance() ); // Could be first use //LLFirstUse::useBuild(); @@ -3128,14 +3220,14 @@ bool enable_object_edit() if (gAgent.inPrelude()) { enable = LLViewerParcelMgr::getInstance()->allowAgentBuild() - || LLSelectMgr::getInstanceFast()->getSelection()->isAttachment(); + || LLSelectMgr::getInstance()->getSelection()->isAttachment(); } - else if (LLSelectMgr::getInstanceFast()->selectGetAllValidAndObjectsFound()) + else if (LLSelectMgr::getInstance()->selectGetAllValidAndObjectsFound()) { // [RLVa:KB] - @edit* if (RlvActions::isRlvEnabled() && !RlvActions::canEdit(ERlvCheckType::All)) { - LLObjectSelectionHandle hSel = LLSelectMgr::getInstanceFast()->getSelection(); + LLObjectSelectionHandle hSel = LLSelectMgr::getInstance()->getSelection(); RlvSelectIsEditable f; enable = (hSel.notNull()) && (!hSel->getFirstRootNode(&f, true)); } @@ -3165,7 +3257,7 @@ bool enable_object_build() bool enable_object_select_in_pathfinding_linksets() { - return LLPathfindingManager::getInstance()->isPathfindingEnabledForCurrentRegion() && LLSelectMgr::getInstanceFast()->selectGetEditableLinksets(); + return LLPathfindingManager::getInstance()->isPathfindingEnabledForCurrentRegion() && LLSelectMgr::getInstance()->selectGetEditableLinksets(); } bool visible_object_select_in_pathfinding_linksets() @@ -3175,7 +3267,7 @@ bool visible_object_select_in_pathfinding_linksets() bool enable_object_select_in_pathfinding_characters() { - return LLPathfindingManager::getInstance()->isPathfindingEnabledForCurrentRegion() && LLSelectMgr::getInstanceFast()->selectGetViewableCharacters(); + return LLPathfindingManager::getInstance()->isPathfindingEnabledForCurrentRegion() && LLSelectMgr::getInstance()->selectGetViewableCharacters(); } class LLSelfRemoveAllAttachments : public view_listener_t @@ -3225,7 +3317,7 @@ BOOL enable_has_attachments(void*) //void handle_follow(void *userdata) //{ // // follow a given avatar by ID -// LLViewerObject* objectp = LLSelectMgr::getInstanceFast()->getSelection()->getPrimaryObject(); +// LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); // if (objectp) // { // gAgent.startFollowPilot(objectp->getID()); @@ -3234,7 +3326,7 @@ BOOL enable_has_attachments(void*) bool enable_object_mute() { - LLObjectSelectionHandle selection = LLSelectMgr::getInstanceFast()->getSelection(); + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); LLViewerObject* object = selection->getPrimaryObject(); if (!object) return false; @@ -3253,13 +3345,13 @@ bool enable_object_mute() { // Just a regular object return selection->contains( object, SELECT_ALL_TES ) && - !LLMuteList::getInstanceFast()->isMuted(object->getID()); + !LLMuteList::getInstance()->isMuted(object->getID()); } } bool enable_object_unmute() { - LLObjectSelectionHandle selection = LLSelectMgr::getInstanceFast()->getSelection(); + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); LLViewerObject* object = selection->getPrimaryObject(); if (!object) return false; @@ -3275,7 +3367,7 @@ bool enable_object_unmute() { // Just a regular object return selection->contains( object, SELECT_ALL_TES ) && - LLMuteList::getInstanceFast()->isMuted(object->getID());; + LLMuteList::getInstance()->isMuted(object->getID());; } } @@ -3285,7 +3377,7 @@ class LLAvatarCheckImpostorMode : public view_listener_t { bool handleEvent(const LLSD& userdata) { - LLViewerObject* object = LLSelectMgr::getInstanceFast()->getSelection()->getPrimaryObject(); + LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); if (!object) return false; LLVOAvatar* avatar = find_avatar_from_object(object); @@ -3311,7 +3403,7 @@ class LLAvatarSetImpostorMode : public view_listener_t { bool handleEvent(const LLSD& userdata) { - LLViewerObject* object = LLSelectMgr::getInstanceFast()->getSelection()->getPrimaryObject(); + LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); if (!object) return false; LLVOAvatar* avatar = find_avatar_from_object(object); @@ -3343,7 +3435,7 @@ class LLObjectMute : public view_listener_t { bool handleEvent(const LLSD& userdata) { - LLViewerObject* object = LLSelectMgr::getInstanceFast()->getSelection()->getPrimaryObject(); + LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); if (!object) return true; LLUUID id; @@ -3376,7 +3468,7 @@ class LLObjectMute : public view_listener_t // it's an object id = object->getID(); - LLSelectNode* node = LLSelectMgr::getInstanceFast()->getSelection()->getFirstRootNode(); + LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(); if (node) { name = node->mName; @@ -3386,13 +3478,13 @@ class LLObjectMute : public view_listener_t } LLMute mute(id, name, type); - if (LLMuteList::getInstanceFast()->isMuted(mute.mID)) + if (LLMuteList::getInstance()->isMuted(mute.mID)) { - LLMuteList::getInstanceFast()->remove(mute); + LLMuteList::getInstance()->remove(mute); } else { - LLMuteList::getInstanceFast()->add(mute); + LLMuteList::getInstance()->add(mute); LLPanelBlockedList::showPanelAndSelect(mute.mID); } @@ -3443,7 +3535,7 @@ class LLAvatarReportAbuse : public view_listener_t { bool handleEvent(const LLSD& userdata) { - LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstanceFast()->getSelection()->getPrimaryObject() ); + LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() ); if(avatar) { @@ -3501,7 +3593,7 @@ void handle_avatar_freeze(const LLSD& avatar_id) else { avatar = find_avatar_from_object( - LLSelectMgr::getInstanceFast()->getSelection()->getPrimaryObject()); + LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()); } if (avatar) @@ -3522,7 +3614,7 @@ class LLAvatarDebug : public view_listener_t { bool handleEvent(const LLSD& userdata) { - LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstanceFast()->getSelection()->getPrimaryObject() ); + LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() ); if( avatar ) { if (avatar->isSelf()) @@ -3605,7 +3697,7 @@ void handle_avatar_eject(const LLSD& avatar_id) else { avatar = find_avatar_from_object( - LLSelectMgr::getInstanceFast()->getSelection()->getPrimaryObject()); + LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()); } if (avatar) @@ -3636,7 +3728,7 @@ bool enable_freeze_eject(const LLSD& avatar_id) else { avatar = find_avatar_from_object( - LLSelectMgr::getInstanceFast()->getSelection()->getPrimaryObject()); + LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()); } if (!avatar) return false; @@ -3690,9 +3782,9 @@ bool enable_buy_object() { // In order to buy, there must only be 1 purchaseable object in // the selection manager. - if(LLSelectMgr::getInstanceFast()->getSelection()->getRootObjectCount() != 1) return false; + if(LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() != 1) return false; LLViewerObject* obj = NULL; - LLSelectNode* node = LLSelectMgr::getInstanceFast()->getSelection()->getFirstRootNode(); + LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(); if(node) { obj = node->getObject(); @@ -3718,7 +3810,7 @@ bool enable_buy_object() // received by the viewer and cached in the selection manager. void handle_buy_object(LLSaleInfo sale_info) { - if(!LLSelectMgr::getInstanceFast()->selectGetAllRootsValid()) + if(!LLSelectMgr::getInstance()->selectGetAllRootsValid()) { LLNotificationsUtil::add("UnableToBuyWhileDownloading"); return; @@ -3726,7 +3818,7 @@ void handle_buy_object(LLSaleInfo sale_info) LLUUID owner_id; std::string owner_name; - BOOL owners_identical = LLSelectMgr::getInstanceFast()->selectGetOwner(owner_id, owner_name); + BOOL owners_identical = LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name); if (!owners_identical) { LLNotificationsUtil::add("CannotBuyObjectsFromDifferentOwners"); @@ -3734,9 +3826,9 @@ void handle_buy_object(LLSaleInfo sale_info) } LLPermissions perm; - BOOL valid = LLSelectMgr::getInstanceFast()->selectGetPermissions(perm); + BOOL valid = LLSelectMgr::getInstance()->selectGetPermissions(perm); LLAggregatePermissions ag_perm; - valid &= LLSelectMgr::getInstanceFast()->selectGetAggregatePermissions(ag_perm); + valid &= LLSelectMgr::getInstance()->selectGetAggregatePermissions(ag_perm); if(!valid || !sale_info.isForSale() || !perm.allowTransferTo(gAgent.getID())) { LLNotificationsUtil::add("ObjectNotForSale"); @@ -4089,7 +4181,7 @@ class LLAvatarEnableAddFriend : public view_listener_t { bool handleEvent(const LLSD& userdata) { - LLVOAvatar* avatar = find_avatar_from_object(LLSelectMgr::getInstanceFast()->getSelection()->getPrimaryObject()); + LLVOAvatar* avatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()); // bool new_value = avatar && !LLAvatarActions::isFriend(avatar->getID()); // [RLVa:KB] - Checked: RLVa-1.2.0 bool new_value = avatar && !LLAvatarActions::isFriend(avatar->getID()) && (RlvActions::canShowName(RlvActions::SNC_DEFAULT, avatar->getID())); @@ -4172,7 +4264,7 @@ bool is_object_sittable() } // [/RLVa:KB] - LLViewerObject* object = LLSelectMgr::getInstanceFast()->getSelection()->getPrimaryObject(); + LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); if (object && object->getPCode() == LL_PCODE_VOLUME) { @@ -4184,29 +4276,15 @@ bool is_object_sittable() } } - // only works on pie menu -void handle_object_sit_or_stand() +void handle_object_sit(LLViewerObject *object, const LLVector3 &offset) { - LLPickInfo pick = LLToolPie::getInstance()->getPick(); - LLViewerObject *object = pick.getObject();; - if (!object || pick.mPickType == LLPickInfo::PICK_FLORA) - { - return; - } - - if (sitting_on_selection()) - { - gAgent.standUp(); - return; - } - // get object selection offset // if (object && object->getPCode() == LL_PCODE_VOLUME) // [RLVa:KB] - Checked: 2010-03-06 (RLVa-1.2.0c) | Modified: RLVa-1.2.0c if ( (object && object->getPCode() == LL_PCODE_VOLUME) && - ((!rlv_handler_t::isEnabled()) || (RlvActions::canSit(object, pick.mObjectOffset))) ) + ((!rlv_handler_t::isEnabled()) || (RlvActions::canSit(object, offset))) ) // [/RLVa:KB] { // [RLVa:KB] - Checked: 2010-08-29 (RLVa-1.2.1c) | Added: RLVa-1.2.1c @@ -4227,12 +4305,42 @@ void handle_object_sit_or_stand() gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); gMessageSystem->nextBlockFast(_PREHASH_TargetObject); gMessageSystem->addUUIDFast(_PREHASH_TargetID, object->mID); - gMessageSystem->addVector3Fast(_PREHASH_Offset, pick.mObjectOffset); + gMessageSystem->addVector3Fast(_PREHASH_Offset, offset); object->getRegion()->sendReliableMessage(); } } +void handle_object_sit_or_stand() +{ + LLPickInfo pick = LLToolPie::getInstance()->getPick(); + LLViewerObject *object = pick.getObject(); + if (!object || pick.mPickType == LLPickInfo::PICK_FLORA) + { + return; + } + + if (sitting_on_selection()) + { + gAgent.standUp(); + return; + } + + handle_object_sit(object, pick.mObjectOffset); +} + +void handle_object_sit(const LLUUID& object_id) +{ + LLViewerObject* obj = gObjectList.findObject(object_id); + if (!obj) + { + return; + } + + LLVector3 offset(0, 0, 0); + handle_object_sit(obj, offset); +} + void near_sit_down_point(BOOL success, void *) { if (success) @@ -4408,7 +4516,7 @@ void handle_duplicate_in_place(void*) LL_INFOS() << "handle_duplicate_in_place" << LL_ENDL; LLVector3 offset(0.f, 0.f, 0.f); - LLSelectMgr::getInstanceFast()->selectDuplicate(offset, TRUE); + LLSelectMgr::getInstance()->selectDuplicate(offset, TRUE); } /* dead code 30-apr-2008 @@ -4416,20 +4524,20 @@ void handle_deed_object_to_group(void*) { LLUUID group_id; - LLSelectMgr::getInstanceFast()->selectGetGroup(group_id); - LLSelectMgr::getInstanceFast()->sendOwner(LLUUID::null, group_id, FALSE); + LLSelectMgr::getInstance()->selectGetGroup(group_id); + LLSelectMgr::getInstance()->sendOwner(LLUUID::null, group_id, FALSE); LLViewerStats::getInstance()->incStat(LLViewerStats::ST_RELEASE_COUNT); } BOOL enable_deed_object_to_group(void*) { - if(LLSelectMgr::getInstanceFast()->getSelection()->isEmpty()) return FALSE; + if(LLSelectMgr::getInstance()->getSelection()->isEmpty()) return FALSE; LLPermissions perm; LLUUID group_id; - if (LLSelectMgr::getInstanceFast()->selectGetGroup(group_id) && + if (LLSelectMgr::getInstance()->selectGetGroup(group_id) && gAgent.hasPowerInGroup(group_id, GP_OBJECT_DEED) && - LLSelectMgr::getInstanceFast()->selectGetPermissions(perm) && + LLSelectMgr::getInstance()->selectGetPermissions(perm) && perm.deedToGroup(gAgent.getID(), group_id)) { return TRUE; @@ -4483,8 +4591,8 @@ void handle_object_owner_permissive(void*) if(gAgent.isGodlike()) { // do the objects. - LLSelectMgr::getInstanceFast()->selectionSetObjectPermissions(PERM_BASE, TRUE, PERM_ALL, TRUE); - LLSelectMgr::getInstanceFast()->selectionSetObjectPermissions(PERM_OWNER, TRUE, PERM_ALL, TRUE); + LLSelectMgr::getInstance()->selectionSetObjectPermissions(PERM_BASE, TRUE, PERM_ALL, TRUE); + LLSelectMgr::getInstance()->selectionSetObjectPermissions(PERM_OWNER, TRUE, PERM_ALL, TRUE); } } @@ -4493,14 +4601,14 @@ void handle_object_owner_self(void*) // only send this if they're a god. if(gAgent.isGodlike()) { - LLSelectMgr::getInstanceFast()->sendOwner(gAgent.getID(), gAgent.getGroupID(), TRUE); + LLSelectMgr::getInstance()->sendOwner(gAgent.getID(), gAgent.getGroupID(), TRUE); } } // Shortcut to set owner permissions to not editable. void handle_object_lock(void*) { - LLSelectMgr::getInstanceFast()->selectionSetObjectPermissions(PERM_OWNER, FALSE, PERM_MODIFY); + LLSelectMgr::getInstance()->selectionSetObjectPermissions(PERM_OWNER, FALSE, PERM_MODIFY); } void handle_object_asset_ids(void*) @@ -4508,7 +4616,7 @@ void handle_object_asset_ids(void*) // only send this if they're a god. if (gAgent.isGodlike()) { - LLSelectMgr::getInstanceFast()->sendGodlikeRequest("objectinfo", "assetids"); + LLSelectMgr::getInstance()->sendGodlikeRequest("objectinfo", "assetids"); } } @@ -4568,7 +4676,7 @@ void handle_god_request_avatar_geometry(void *) { if (gAgent.isGodlike()) { - LLSelectMgr::getInstanceFast()->sendGodlikeRequest("avatar toggle", ""); + LLSelectMgr::getInstance()->sendGodlikeRequest("avatar toggle", ""); } } @@ -4581,7 +4689,7 @@ static bool get_derezzable_objects( { bool found = false; - LLObjectSelectionHandle selection = LLSelectMgr::getInstanceFast()->getSelection(); + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); if (derez_objectsp) derez_objectsp->reserve(selection->getRootObjectCount()); @@ -4788,13 +4896,13 @@ static void derez_objects(EDeRezDestination dest, const LLUUID& dest_id) void handle_take_copy() { - if (LLSelectMgr::getInstanceFast()->getSelection()->isEmpty()) return; + if (LLSelectMgr::getInstance()->getSelection()->isEmpty()) return; // [RLVa:KB] - Checked: 2010-03-07 (RLVa-1.2.0c) | Modified: RLVa-1.2.0a if ( (rlv_handler_t::isEnabled()) && (!RlvActions::canStand()) ) { // Allow only if the avie isn't sitting on any of the selected objects - LLObjectSelectionHandle hSel = LLSelectMgr::getInstanceFast()->getSelection(); + LLObjectSelectionHandle hSel = LLSelectMgr::getInstance()->getSelection(); RlvSelectIsSittingOn f(gAgentAvatarp); if ( (hSel.notNull()) && (hSel->getFirstRootNode(&f, TRUE) != NULL) ) return; @@ -4807,13 +4915,13 @@ void handle_take_copy() void handle_link_objects() { - if (LLSelectMgr::getInstanceFast()->getSelection()->isEmpty()) + if (LLSelectMgr::getInstance()->getSelection()->isEmpty()) { LLFloaterReg::toggleInstanceOrBringToFront("places"); } else { - LLSelectMgr::getInstanceFast()->linkObjects(); + LLSelectMgr::getInstance()->linkObjects(); } } @@ -4826,12 +4934,12 @@ class LLObjectReturn : public view_listener_t private: bool handleEvent(const LLSD& userdata) { - if (LLSelectMgr::getInstanceFast()->getSelection()->isEmpty()) return true; + if (LLSelectMgr::getInstance()->getSelection()->isEmpty()) return true; // [RLVa:KB] - Checked: 2010-03-24 (RLVa-1.4.0a) | Modified: RLVa-1.0.0b if ( (rlv_handler_t::isEnabled()) && (!rlvCanDeleteOrReturn()) ) return true; // [/RLVa:KB] - mObjectSelection = LLSelectMgr::getInstanceFast()->getEditSelection(); + mObjectSelection = LLSelectMgr::getInstance()->getEditSelection(); // Save selected objects, so that we still know what to return after the confirmation dialog resets selection. get_derezzable_objects(DRD_RETURN_TO_OWNER, mError, mFirstRegion, &mReturnableObjects); @@ -4872,7 +4980,7 @@ class LLObjectEnableReturn : public view_listener_t { bool handleEvent(const LLSD& userdata) { - if (LLSelectMgr::getInstanceFast()->getSelection()->isEmpty()) + if (LLSelectMgr::getInstance()->getSelection()->isEmpty()) { // Do not enable if nothing selected return false; @@ -4902,7 +5010,7 @@ class LLObjectEnableReturn : public view_listener_t void force_take_copy(void*) { - if (LLSelectMgr::getInstanceFast()->getSelection()->isEmpty()) return; + if (LLSelectMgr::getInstance()->getSelection()->isEmpty()) return; const LLUUID category_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OBJECT); derez_objects(DRD_FORCE_TO_GOD_INVENTORY, category_id); } @@ -4911,8 +5019,8 @@ void handle_take() { // we want to use the folder this was derezzed from if it's // available. Otherwise, derez to the normal place. - LLObjectSelectionHandle selection = LLSelectMgr::getInstanceFast()->getSelection(); -// if(LLSelectMgr::getInstanceFast()->getSelection()->isEmpty()) + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); +// if(LLSelectMgr::getInstance()->getSelection()->isEmpty()) // [RLVa:KB] - Checked: 2010-03-24 (RLVa-1.2.0e) | Modified: RLVa-1.0.0b if ( (selection->isEmpty()) || ((rlv_handler_t::isEnabled()) && (!rlvCanDeleteOrReturn())) ) // [/RLVa:KB] @@ -5026,7 +5134,7 @@ void handle_take() void handle_object_show_inspector() { - LLObjectSelectionHandle selection = LLSelectMgr::getInstanceFast()->getSelection(); + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); LLViewerObject* objectp = selection->getFirstRootObject(TRUE); if (!objectp) { @@ -5040,7 +5148,7 @@ void handle_object_show_inspector() void handle_avatar_show_inspector() { - LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstanceFast()->getSelection()->getPrimaryObject() ); + LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() ); if(avatar) { LLSD params; @@ -5074,7 +5182,7 @@ BOOL enable_take() return FALSE; } - for (LLSelectNode* node : LLSelectMgr::getInstanceFast()->getSelection()->valid_root_begin_end()) + for (LLSelectNode* node : LLSelectMgr::getInstance()->getSelection()->valid_root_begin_end()) { LLViewerObject* object = node->getObject(); if (object->isAvatar()) @@ -5108,7 +5216,7 @@ BOOL enable_take() void handle_buy_or_take() { - if (LLSelectMgr::getInstanceFast()->getSelection()->isEmpty()) + if (LLSelectMgr::getInstance()->getSelection()->isEmpty()) { return; } @@ -5182,7 +5290,7 @@ class LLToolsEnableBuyOrTake : public view_listener_t // FALSE if selection is a 'take' BOOL is_selection_buy_not_take() { - for (LLSelectNode* node : LLSelectMgr::getInstanceFast()->getSelection()->root_begin_end()) + for (LLSelectNode* node : LLSelectMgr::getInstance()->getSelection()->root_begin_end()) { LLViewerObject* obj = node->getObject(); if(obj && !(obj->permYouOwner()) && (node->mSaleInfo.isForSale())) @@ -5203,7 +5311,7 @@ BOOL is_selection_buy_not_take() S32 selection_price() { S32 total_price = 0; - for (LLSelectNode* node : LLSelectMgr::getInstanceFast()->getSelection()->root_begin_end()) + for (LLSelectNode* node : LLSelectMgr::getInstance()->getSelection()->root_begin_end()) { LLViewerObject* obj = node->getObject(); if(obj && !(obj->permYouOwner()) && (node->mSaleInfo.isForSale())) @@ -5250,10 +5358,10 @@ void show_buy_currency(const char* extra) void handle_buy() { - if (LLSelectMgr::getInstanceFast()->getSelection()->isEmpty()) return; + if (LLSelectMgr::getInstance()->getSelection()->isEmpty()) return; LLSaleInfo sale_info; - BOOL valid = LLSelectMgr::getInstanceFast()->selectGetSaleInfo(sale_info); + BOOL valid = LLSelectMgr::getInstance()->selectGetSaleInfo(sale_info); if (!valid) return; S32 price = sale_info.getSalePrice(); @@ -5293,7 +5401,7 @@ bool for_sale_selection(LLSelectNode* nodep) BOOL sitting_on_selection() { - LLSelectNode* node = LLSelectMgr::getInstanceFast()->getSelection()->getFirstRootNode(); + LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(); if (!node) { return FALSE; @@ -5320,7 +5428,7 @@ class LLToolsSaveToObjectInventory : public view_listener_t { bool handleEvent(const LLSD& userdata) { - LLSelectNode* node = LLSelectMgr::getInstanceFast()->getSelection()->getFirstRootNode(); + LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(); if(node && (node->mValid) && (!node->mFromTaskID.isNull())) { // *TODO: check to see if the fromtaskid object exists. @@ -5367,12 +5475,10 @@ class LLToolsEnablePathfindingRebakeRegion : public view_listener_t { bool returnValue = false; - if (LLPathfindingManager::getInstance() != NULL) - { - LLMenuOptionPathfindingRebakeNavmesh *rebakeInstance = LLMenuOptionPathfindingRebakeNavmesh::getInstance(); - returnValue = (rebakeInstance->canRebakeRegion() && - (rebakeInstance->getMode() == LLMenuOptionPathfindingRebakeNavmesh::kRebakeNavMesh_Available)); - } + if (LLNavigationBar::instanceExists()) + { + returnValue = LLNavigationBar::getInstance()->isRebakeNavMeshAvailable(); + } return returnValue; } }; @@ -5384,7 +5490,7 @@ class LLToolsSnapObjectXY : public view_listener_t { F64 snap_size = (F64)ALControlCache::GridResolution; - for (LLSelectNode* node : LLSelectMgr::getInstanceFast()->getSelection()->root_begin_end()) + for (LLSelectNode* node : LLSelectMgr::getInstance()->getSelection()->root_begin_end()) { LLViewerObject* obj = node->getObject(); if (obj->permModify()) @@ -5417,7 +5523,7 @@ class LLToolsSnapObjectXY : public view_listener_t obj->setPositionGlobal(pos_global, FALSE); } } - LLSelectMgr::getInstanceFast()->sendMultipleUpdate(UPD_POSITION); + LLSelectMgr::getInstance()->sendMultipleUpdate(UPD_POSITION); return true; } }; @@ -5427,9 +5533,9 @@ class LLToolsEnableSelectNextPart : public view_listener_t { bool handleEvent(const LLSD& userdata) { - bool new_value = (!LLSelectMgr::getInstanceFast()->getSelection()->isEmpty() + bool new_value = (!LLSelectMgr::getInstance()->getSelection()->isEmpty() && (ALControlCache::EditLinkedParts - || LLToolFace::getInstanceFast() == LLToolMgr::getInstanceFast()->getCurrentTool())); + || LLToolFace::getInstance() == LLToolMgr::getInstance()->getCurrentTool())); return new_value; } }; @@ -5441,7 +5547,7 @@ class LLToolsSelectNextPartFace : public view_listener_t { bool handleEvent(const LLSD& userdata) { - bool cycle_faces = LLToolFace::getInstanceFast() == LLToolMgr::getInstanceFast()->getCurrentTool(); + bool cycle_faces = LLToolFace::getInstance() == LLToolMgr::getInstance()->getCurrentTool(); bool cycle_linked = ALControlCache::EditLinkedParts; if (!cycle_faces && !cycle_linked) @@ -5462,7 +5568,7 @@ class LLToolsSelectNextPartFace : public view_listener_t if (cycle_faces) { // Cycle through faces of current selection, if end is reached, swithc to next part (if present) - LLSelectNode* nodep = LLSelectMgr::getInstanceFast()->getSelection()->getFirstNode(); + LLSelectNode* nodep = LLSelectMgr::getInstance()->getSelection()->getFirstNode(); if (!nodep) return false; to_select = nodep->getObject(); if (!to_select) return false; @@ -5506,10 +5612,10 @@ class LLToolsSelectNextPartFace : public view_listener_t } } - S32 object_count = LLSelectMgr::getInstanceFast()->getSelection()->getObjectCount(); + S32 object_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount(); if (cycle_linked && object_count && restart_face_on_part) { - LLViewerObject* selected = LLSelectMgr::getInstanceFast()->getSelection()->getFirstObject(); + LLViewerObject* selected = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); if (selected && selected->getRootEdit()) { LLViewerObject::child_list_t children = selected->getRootEdit()->getChildren(); @@ -5564,7 +5670,7 @@ class LLToolsSelectNextPartFace : public view_listener_t } if (fwd || prev) { - LLSelectMgr::getInstanceFast()->deselectAll(); + LLSelectMgr::getInstance()->deselectAll(); } if (cycle_faces) { @@ -5579,11 +5685,11 @@ class LLToolsSelectNextPartFace : public view_listener_t new_te = to_select->getNumTEs() - 1; } } - LLSelectMgr::getInstanceFast()->selectObjectOnly(to_select, new_te); + LLSelectMgr::getInstance()->selectObjectOnly(to_select, new_te); } else { - LLSelectMgr::getInstanceFast()->selectObjectOnly(to_select); + LLSelectMgr::getInstance()->selectObjectOnly(to_select); } return true; } @@ -5794,7 +5900,7 @@ bool enable_spellcheck_add_to_ignore(const LLUICtrl* ctrl) bool enable_object_return() { - return (!LLSelectMgr::getInstanceFast()->getSelection()->isEmpty() && + return (!LLSelectMgr::getInstance()->getSelection()->isEmpty() && (gAgent.isGodlike() || can_derez(DRD_RETURN_TO_OWNER))); } @@ -5808,7 +5914,7 @@ bool enable_object_delete() (LLGridManager::getInstance()->isInSLBeta() && gAgent.isGodlike()) || # endif - LLSelectMgr::getInstanceFast()->canDoDelete(); + LLSelectMgr::getInstance()->canDoDelete(); #endif return new_value; } @@ -5844,10 +5950,10 @@ static void return_objects(LLObjectsReturnPackage *objectsReturnPackage, const L void handle_object_return() { - if (!LLSelectMgr::getInstanceFast()->getSelection()->isEmpty()) + if (!LLSelectMgr::getInstance()->getSelection()->isEmpty()) { LLObjectsReturnPackage *objectsReturnPackage = new LLObjectsReturnPackage(); - objectsReturnPackage->mObjectSelection = LLSelectMgr::getInstanceFast()->getEditSelection(); + objectsReturnPackage->mObjectSelection = LLSelectMgr::getInstance()->getEditSelection(); // Save selected objects, so that we still know what to return after the confirmation dialog resets selection. get_derezzable_objects(DRD_RETURN_TO_OWNER, objectsReturnPackage->mError, objectsReturnPackage->mFirstRegion, &objectsReturnPackage->mReturnableObjects); @@ -5859,9 +5965,9 @@ void handle_object_return() void handle_object_delete() { - if (LLSelectMgr::getInstanceFast()) + if (LLSelectMgr::getInstance()) { - LLSelectMgr::getInstanceFast()->doDelete(); + LLSelectMgr::getInstance()->doDelete(); } // and close any pie/context menus when done @@ -5875,7 +5981,7 @@ void handle_object_delete() void handle_force_delete(void*) { - LLSelectMgr::getInstanceFast()->selectForceDelete(); + LLSelectMgr::getInstance()->selectForceDelete(); } class LLViewEnableJoystickFlycam : public view_listener_t @@ -5987,7 +6093,7 @@ class LLEditRedo : public view_listener_t void print_object_info(void*) { - LLSelectMgr::getInstanceFast()->selectionDump(); + LLSelectMgr::getInstance()->selectionDump(); } void print_agent_nvpairs(void*) @@ -6059,7 +6165,7 @@ void toggle_debug_menus(void*) // void handle_export_selected( void * ) // { -// LLObjectSelectionHandle selection = LLSelectMgr::getInstanceFast()->getSelection(); +// LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); // if (selection->isEmpty()) // { // return; @@ -6252,11 +6358,11 @@ void handle_look_at_selection(const LLSD& param) { const F32 PADDING_FACTOR = 1.75f; BOOL zoom = (param.asString() == "zoom"); - if (!LLSelectMgr::getInstanceFast()->getSelection()->isEmpty()) + if (!LLSelectMgr::getInstance()->getSelection()->isEmpty()) { gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE); - LLBBox selection_bbox = LLSelectMgr::getInstanceFast()->getBBoxOfSelection(); + LLBBox selection_bbox = LLSelectMgr::getInstance()->getBBoxOfSelection(); F32 angle_of_view = llmax(0.1f, LLViewerCamera::getInstance()->getAspect() > 1.f ? LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect() : LLViewerCamera::getInstance()->getView()); F32 distance = selection_bbox.getExtentLocal().magVec() * PADDING_FACTOR / atan(angle_of_view); @@ -6264,24 +6370,24 @@ void handle_look_at_selection(const LLSD& param) obj_to_cam.normVec(); LLUUID object_id; - if (LLSelectMgr::getInstanceFast()->getSelection()->getPrimaryObject()) + if (LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()) { - object_id = LLSelectMgr::getInstanceFast()->getSelection()->getPrimaryObject()->mID; + object_id = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()->mID; } if (zoom) { // Make sure we are not increasing the distance between the camera and object - LLVector3d orig_distance = gAgentCamera.getCameraPositionGlobal() - LLSelectMgr::getInstanceFast()->getSelectionCenterGlobal(); + LLVector3d orig_distance = gAgentCamera.getCameraPositionGlobal() - LLSelectMgr::getInstance()->getSelectionCenterGlobal(); distance = llmin(distance, (F32) orig_distance.length()); - gAgentCamera.setCameraPosAndFocusGlobal(LLSelectMgr::getInstanceFast()->getSelectionCenterGlobal() + LLVector3d(obj_to_cam * distance), - LLSelectMgr::getInstanceFast()->getSelectionCenterGlobal(), + gAgentCamera.setCameraPosAndFocusGlobal(LLSelectMgr::getInstance()->getSelectionCenterGlobal() + LLVector3d(obj_to_cam * distance), + LLSelectMgr::getInstance()->getSelectionCenterGlobal(), object_id ); } else { - gAgentCamera.setFocusGlobal( LLSelectMgr::getInstanceFast()->getSelectionCenterGlobal(), object_id ); + gAgentCamera.setFocusGlobal( LLSelectMgr::getInstance()->getSelectionCenterGlobal(), object_id ); } } } @@ -6311,7 +6417,7 @@ class LLAvatarInviteToGroup : public view_listener_t { bool handleEvent(const LLSD& userdata) { - LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstanceFast()->getSelection()->getPrimaryObject() ); + LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() ); // if(avatar) // [RLVa:KB] - Checked: RLVa-1.2.0 if ( (avatar) && (RlvActions::canShowName(RlvActions::SNC_DEFAULT, avatar->getID())) ) @@ -6327,7 +6433,7 @@ class LLAvatarAddFriend : public view_listener_t { bool handleEvent(const LLSD& userdata) { - LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstanceFast()->getSelection()->getPrimaryObject() ); + LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() ); // if(avatar && !LLAvatarActions::isFriend(avatar->getID())) // [RLVa:KB] - Checked: RLVa-1.2.0 if ( (avatar && !LLAvatarActions::isFriend(avatar->getID())) && (RlvActions::canShowName(RlvActions::SNC_DEFAULT, avatar->getID())) ) @@ -6366,6 +6472,29 @@ class LLAvatarToggleMyProfile : public view_listener_t } }; +class LLAvatarTogglePicks : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + LLFloater * instance = LLAvatarActions::getProfileFloater(gAgent.getID()); + if (LLFloater::isMinimized(instance) || (instance && !instance->hasFocus() && !instance->getIsChrome())) + { + instance->setMinimized(FALSE); + instance->setFocus(TRUE); + LLAvatarActions::showPicks(gAgent.getID()); + } + else if (picks_tab_visible()) + { + instance->closeFloater(); + } + else + { + LLAvatarActions::showPicks(gAgent.getID()); + } + return true; + } +}; + class LLAvatarToggleSearch : public view_listener_t { bool handleEvent(const LLSD& userdata) @@ -6392,34 +6521,11 @@ class LLAvatarToggleSearch : public view_listener_t } }; -class LLAvatarTogglePicks : public view_listener_t -{ - bool handleEvent(const LLSD& userdata) - { - LLFloater* instance = LLAvatarActions::getProfileFloater(gAgent.getID()); - if (LLFloater::isMinimized(instance) || (instance && !instance->hasFocus() && !instance->getIsChrome())) - { - instance->setMinimized(FALSE); - instance->setFocus(TRUE); - LLAvatarActions::showPicks(gAgent.getID()); - } - else if (picks_tab_visible()) - { - instance->closeFloater(); - } - else - { - LLAvatarActions::showPicks(gAgent.getID()); - } - return true; - } -}; - class LLAvatarResetSkeleton: public view_listener_t { bool handleEvent(const LLSD& userdata) { - LLVOAvatar* avatar = find_avatar_from_object(LLSelectMgr::getInstanceFast()->getSelection()->getPrimaryObject()); + LLVOAvatar* avatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()); if(avatar) { avatar->resetSkeleton(false); @@ -6435,7 +6541,7 @@ class LLAvatarEnableResetSkeleton: public view_listener_t { bool handleEvent(const LLSD& userdata) { - LLViewerObject *obj = LLSelectMgr::getInstanceFast()->getSelection()->getPrimaryObject(); + LLViewerObject *obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); if (obj && obj->getAvatar()) { return true; @@ -6449,7 +6555,7 @@ class LLAvatarResetSkeletonAndAnimations : public view_listener_t { bool handleEvent(const LLSD& userdata) { - LLVOAvatar* avatar = find_avatar_from_object(LLSelectMgr::getInstanceFast()->getSelection()->getPrimaryObject()); + LLVOAvatar* avatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()); if (avatar) { avatar->resetSkeleton(true); @@ -6461,11 +6567,29 @@ class LLAvatarResetSkeletonAndAnimations : public view_listener_t } }; +class LLAvatarResetSelfSkeletonAndAnimations : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + LLVOAvatar* avatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()); + if (avatar) + { + avatar->resetSkeleton(true); + } + else + { + gAgentAvatarp->resetSkeleton(true); + } + return true; + } +}; + + class LLAvatarAddContact : public view_listener_t { bool handleEvent(const LLSD& userdata) { - LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstanceFast()->getSelection()->getPrimaryObject() ); + LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() ); // if(avatar) // [RLVa:KB] - Checked: RLVa-1.2.0 if ( (avatar) && (RlvActions::canShowName(RlvActions::SNC_DEFAULT, avatar->getID())) ) @@ -6516,7 +6640,7 @@ bool complete_give_money(const LLSD& notification, const LLSD& response, LLObjec void handle_give_money_dialog() { LLNotification::Params params("DoNotDisturbModePay"); - params.functor.function(boost::bind(complete_give_money, _1, _2, LLSelectMgr::getInstanceFast()->getSelection())); + params.functor.function(boost::bind(complete_give_money, _1, _2, LLSelectMgr::getInstance()->getSelection())); if (gAgent.isDoNotDisturb()) { @@ -6531,7 +6655,7 @@ void handle_give_money_dialog() bool enable_pay_avatar() { - LLViewerObject* obj = LLSelectMgr::getInstanceFast()->getSelection()->getPrimaryObject(); + LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); LLVOAvatar* avatar = find_avatar_from_object(obj); // return (avatar != NULL); // [RLVa:KB] - @shownames and @pay @@ -6541,7 +6665,7 @@ bool enable_pay_avatar() bool enable_pay_object() { - LLViewerObject* object = LLSelectMgr::getInstanceFast()->getSelection()->getPrimaryObject(); + LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); if( object ) { LLViewerObject *parent = (LLViewerObject *)object->getParent(); @@ -6577,7 +6701,7 @@ bool enable_object_sit(LLUICtrl* ctrl) init_default_item_label(ctrl, item_name); // Update label - LLSelectNode* node = LLSelectMgr::getInstanceFast()->getSelection()->getFirstRootNode(); + LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(); if (node && node->mValid && !node->mSitName.empty()) { ctrl->setValue(node->mSitName); @@ -6603,7 +6727,7 @@ bool enable_object_sit(LLUICtrl* ctrl) void dump_select_mgr(void*) { - LLSelectMgr::getInstanceFast()->dump(); + LLSelectMgr::getInstance()->dump(); } void dump_inventory(void*) @@ -6845,7 +6969,7 @@ class LLShowAgentProfile : public view_listener_t } else if (userdata.asString() == "hit object") { - LLViewerObject* objectp = LLSelectMgr::getInstanceFast()->getSelection()->getPrimaryObject(); + LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); if (objectp) { agent_id = objectp->getID(); @@ -6888,7 +7012,7 @@ class LLToggleAgentProfile : public view_listener_t } else if (userdata.asString() == "hit object") { - LLViewerObject* objectp = LLSelectMgr::getInstanceFast()->getSelection()->getPrimaryObject(); + LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); if (objectp) { agent_id = objectp->getID(); @@ -6940,7 +7064,7 @@ class LLLandEdit : public view_listener_t LLFloaterReg::showInstance("build"); // Switch to land edit toolset - LLToolMgr::getInstanceFast()->getCurrentToolset()->selectTool( LLToolSelectLand::getInstance() ); + LLToolMgr::getInstance()->getCurrentToolset()->selectTool( LLToolSelectLand::getInstance() ); return true; } }; @@ -6949,7 +7073,7 @@ class LLMuteParticle : public view_listener_t { bool handleEvent(const LLSD& userdata) { - LLUUID id = LLToolPie::getInstanceFast()->getPick().mParticleOwnerID; + LLUUID id = LLToolPie::getInstance()->getPick().mParticleOwnerID; if (id.notNull()) { @@ -6957,13 +7081,13 @@ class LLMuteParticle : public view_listener_t LLAvatarNameCache::get(id, &av_name); LLMute mute(id, av_name.getUserName(), LLMute::AGENT); - if (LLMuteList::getInstanceFast()->isMuted(mute.mID)) + if (LLMuteList::getInstance()->isMuted(mute.mID)) { - LLMuteList::getInstanceFast()->remove(mute); + LLMuteList::getInstance()->remove(mute); } else { - LLMuteList::getInstanceFast()->add(mute); + LLMuteList::getInstance()->add(mute); LLPanelBlockedList::showPanelAndSelect(mute.mID); } } @@ -7010,7 +7134,7 @@ class LLObjectAttachToAvatar : public view_listener_t private: bool handleEvent(const LLSD& userdata) { - setObjectSelection(LLSelectMgr::getInstanceFast()->getSelection()); + setObjectSelection(LLSelectMgr::getInstance()->getSelection()); LLViewerObject* selectedObject = sObjectSelection->getFirstRootObject(); if (selectedObject) { @@ -7082,7 +7206,7 @@ void LLObjectAttachToAvatar::onNearAttachObject(BOOL success, void *user_data) // interpret 0 as "default location" attachment_id = 0; } - LLSelectMgr::getInstanceFast()->sendAttach(cb_data->getSelection(), attachment_id, cb_data->mReplace); + LLSelectMgr::getInstance()->sendAttach(cb_data->getSelection(), attachment_id, cb_data->mReplace); } LLObjectAttachToAvatar::setObjectSelection(NULL); @@ -7094,7 +7218,7 @@ void LLObjectAttachToAvatar::confirmReplaceAttachment(S32 option, LLViewerJointA { if (option == 0/*YES*/) { - LLViewerObject* selectedObject = LLSelectMgr::getInstanceFast()->getSelection()->getFirstRootObject(); + LLViewerObject* selectedObject = LLSelectMgr::getInstance()->getSelection()->getFirstRootObject(); if (selectedObject) { const F32 MIN_STOP_DISTANCE = 1.f; // meters @@ -7164,9 +7288,9 @@ void callback_attachment_drop(const LLSD& notification, const LLSD& response) } // reselect the object - LLSelectMgr::getInstanceFast()->selectObjectAndFamily(object); + LLSelectMgr::getInstance()->selectObjectAndFamily(object); - LLSelectMgr::getInstanceFast()->sendDropAttachment(); + LLSelectMgr::getInstance()->sendDropAttachment(); return; } @@ -7181,7 +7305,7 @@ class LLAttachmentDrop : public view_listener_t if (gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_REMOVE)) { // NOTE: copy/paste of the code in enable_detach() - LLObjectSelectionHandle hSelect = LLSelectMgr::getInstanceFast()->getSelection(); + LLObjectSelectionHandle hSelect = LLSelectMgr::getInstance()->getSelection(); RlvSelectHasLockedAttach f; if ( (hSelect->isAttachment()) && (hSelect->getFirstRootNode(&f, FALSE) != NULL) ) return true; @@ -7194,7 +7318,7 @@ class LLAttachmentDrop : public view_listener_t // [/RLVa:KB] LLSD payload; - LLViewerObject *object = LLSelectMgr::getInstanceFast()->getSelection()->getPrimaryObject(); + LLViewerObject *object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); if (object) { @@ -7287,7 +7411,7 @@ class LLAttachmentDetach : public view_listener_t { // Called when the user clicked on an object attached to them // and selected "Detach". - LLViewerObject *object = LLSelectMgr::getInstanceFast()->getSelection()->getPrimaryObject(); + LLViewerObject *object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); if (!object) { LL_WARNS() << "handle_detach() - no object to detach" << LL_ENDL; @@ -7321,7 +7445,7 @@ class LLAttachmentDetach : public view_listener_t // NOTE: copy/paste of the code in enable_detach() if ( (rlv_handler_t::isEnabled()) && (gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_REMOVE)) ) { - LLObjectSelectionHandle hSelect = LLSelectMgr::getInstanceFast()->getSelection(); + LLObjectSelectionHandle hSelect = LLSelectMgr::getInstance()->getSelection(); RlvSelectHasLockedAttach f; if ( (hSelect->isAttachment()) && (hSelect->getFirstRootNode(&f, FALSE) != NULL) ) return true; @@ -7370,12 +7494,12 @@ class LLAttachmentEnableDrop : public view_listener_t // in your inventory. Therefore, we disable the drop option until the // item is in your inventory - LLViewerObject* object = LLSelectMgr::getInstanceFast()->getSelection()->getPrimaryObject(); + LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); LLViewerJointAttachment* attachment = NULL; LLInventoryItem* item = NULL; // Do not enable drop if all faces of object are not enabled - if (object && LLSelectMgr::getInstanceFast()->getSelection()->contains(object,SELECT_ALL_TES )) + if (object && LLSelectMgr::getInstance()->getSelection()->contains(object,SELECT_ALL_TES )) { S32 attachmentID = ATTACHMENT_ID_FROM_STATE(object->getAttachmentState()); attachment = get_if_there(gAgentAvatarp->mAttachmentPoints, attachmentID, (LLViewerJointAttachment*)NULL); @@ -7413,9 +7537,9 @@ class LLAttachmentEnableDrop : public view_listener_t BOOL enable_detach(const LLSD&) { - LLViewerObject* object = LLSelectMgr::getInstanceFast()->getSelection()->getPrimaryObject(); + LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); - LLObjectSelectionHandle hSelect = LLSelectMgr::getInstanceFast()->getSelection(); + LLObjectSelectionHandle hSelect = LLSelectMgr::getInstance()->getSelection(); // Only enable detach if all faces of object are selected if (!object || @@ -7491,7 +7615,7 @@ BOOL object_selected_and_point_valid(const LLSD& sdParam) } // [/RLVa:KB] - LLObjectSelectionHandle selection = LLSelectMgr::getInstanceFast()->getSelection(); + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); for (LLObjectSelection::root_iterator iter = selection->root_begin(); iter != selection->root_end(); iter++) { @@ -7539,7 +7663,7 @@ BOOL object_is_wearable() { return FALSE; } - LLObjectSelectionHandle selection = LLSelectMgr::getInstanceFast()->getSelection(); + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); for (LLSelectNode* node : selection->valid_root_begin_end()) { if (node->mPermissions->getOwner() == gAgent.getID()) @@ -7573,7 +7697,7 @@ class LLAvatarSendIM : public view_listener_t { bool handleEvent(const LLSD& userdata) { - LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstanceFast()->getSelection()->getPrimaryObject() ); + LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() ); // if(avatar) // [RLVa:KB] - Checked: RLVa-1.2.0 if ( (avatar) && (RlvActions::canShowName(RlvActions::SNC_DEFAULT, avatar->getID())) ) @@ -7589,7 +7713,7 @@ class LLAvatarCall : public view_listener_t { bool handleEvent(const LLSD& userdata) { - LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstanceFast()->getSelection()->getPrimaryObject() ); + LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() ); // if(avatar) // [RLVa:KB] - Checked: RLVa-1.2.0 if ( (avatar) && (RlvActions::canShowName(RlvActions::SNC_DEFAULT, avatar->getID())) ) @@ -7606,7 +7730,7 @@ bool enable_avatar_call() { if (RlvActions::isRlvEnabled()) { - const LLVOAvatar* pAvatar = find_avatar_from_object(LLSelectMgr::getInstanceFast()->getSelection()->getPrimaryObject()); + const LLVOAvatar* pAvatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()); if ((!pAvatar) || (!RlvActions::canShowName(RlvActions::SNC_DEFAULT, pAvatar->getID()))) return false; } @@ -7648,7 +7772,7 @@ namespace bool queue_actions(LLFloaterScriptQueue* q, const std::string& msg) { QueueObjects func(q); - LLSelectMgr *mgr = LLSelectMgr::getInstanceFast(); + LLSelectMgr *mgr = LLSelectMgr::getInstance(); LLObjectSelectionHandle selectHandle = mgr->getSelection(); bool fail = selectHandle->applyToNodes(&func); if(fail) @@ -7687,7 +7811,7 @@ class LLToolsSelectedScriptAction : public view_listener_t // We'll allow resetting the scripts of objects on a non-attachable attach point since they wouldn't be able to circumvent anything if ( (rlv_handler_t::isEnabled()) && (gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_REMOVE)) ) { - LLObjectSelectionHandle hSel = LLSelectMgr::getInstanceFast()->getSelection(); + LLObjectSelectionHandle hSel = LLSelectMgr::getInstance()->getSelection(); RlvSelectHasLockedAttach f; if ( (hSel->isAttachment()) && (hSel->getFirstNode(&f) != NULL) ) return true; @@ -7756,7 +7880,7 @@ class LLToolsSelectedScriptAction : public view_listener_t void handle_selected_texture_info(void*) { - for (LLSelectNode* node : LLSelectMgr::getInstanceFast()->getSelection()->valid_begin_end()) + for (LLSelectNode* node : LLSelectMgr::getInstance()->getSelection()->valid_begin_end()) { std::string msg; msg.assign("Texture info for: "); @@ -7800,7 +7924,7 @@ void handle_selected_texture_info(void*) void handle_selected_material_info() { - for (LLSelectNode* node : LLSelectMgr::getInstanceFast()->getSelection()->valid_begin_end()) + for (LLSelectNode* node : LLSelectMgr::getInstance()->getSelection()->valid_begin_end()) { std::string msg; msg.assign("Material info for: \n"); @@ -8028,7 +8152,7 @@ class LLSomethingSelected : public view_listener_t { bool handleEvent(const LLSD& userdata) { - bool new_value = !(LLSelectMgr::getInstanceFast()->getSelection()->isEmpty()); + bool new_value = !(LLSelectMgr::getInstance()->getSelection()->isEmpty()); return new_value; } }; @@ -8037,7 +8161,7 @@ class LLSomethingSelectedNoHUD : public view_listener_t { bool handleEvent(const LLSD& userdata) { - LLObjectSelectionHandle selection = LLSelectMgr::getInstanceFast()->getSelection(); + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); bool new_value = !(selection->isEmpty()) && !(selection->getSelectType() == SELECT_TYPE_HUD); return new_value; } @@ -8045,7 +8169,7 @@ class LLSomethingSelectedNoHUD : public view_listener_t static bool is_editable_selected() { - LLObjectSelectionHandle hSelection = LLSelectMgr::getInstanceFast()->getSelection(); + LLObjectSelectionHandle hSelection = LLSelectMgr::getInstance()->getSelection(); // [RLVa:KB] - Checked: 2010-09-28 (RLVa-1.2.1f) | Modified: RLVa-1.0.5a // RELEASE-RLVa: [SL-2.2.0] Check that this still isn't called by anything but script actions in the Build menu if ( (rlv_handler_t::isEnabled()) && (gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_REMOVE)) ) @@ -8089,14 +8213,14 @@ class LLEditableSelectedMono : public view_listener_t bool enable_object_take_copy() { bool all_valid = false; - LLSelectMgr* select_mgr = LLSelectMgr::getInstanceFast(); + LLSelectMgr* select_mgr = LLSelectMgr::getInstance(); { if (!select_mgr->getSelection()->isEmpty()) { all_valid = true; #ifndef HACKED_GODLIKE_VIEWER # ifdef TOGGLE_HACKED_GODLIKE_VIEWER - if (!LLGridManager::getInstanceFast()->isInSLBeta() + if (!LLGridManager::getInstance()->isInSLBeta() || !gAgent.isGodlike()) # endif { @@ -8150,7 +8274,7 @@ bool LLHasAsset::operator()(LLInventoryCategory* cat, BOOL enable_save_into_task_inventory(void*) { - LLSelectNode* node = LLSelectMgr::getInstanceFast()->getSelection()->getFirstRootNode(); + LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(); if(node && (node->mValid) && (!node->mFromTaskID.isNull())) { // *TODO: check to see if the fromtaskid object exists. @@ -8196,7 +8320,7 @@ class LLToolsEnableToolNotPie : public view_listener_t { bool handleEvent(const LLSD& userdata) { - bool new_value = ( LLToolMgr::getInstanceFast()->getBaseTool() != LLToolPie::getInstanceFast() ); + bool new_value = ( LLToolMgr::getInstance()->getBaseTool() != LLToolPie::getInstance() ); return new_value; } }; @@ -8335,11 +8459,11 @@ class LLToolsEditLinkedParts : public view_listener_t gSavedSettings.setBOOL( "EditLinkedParts", select_individuals ); if (select_individuals) { - LLSelectMgr::getInstanceFast()->demoteSelectionToIndividuals(); + LLSelectMgr::getInstance()->demoteSelectionToIndividuals(); } else { - LLSelectMgr::getInstanceFast()->promoteSelectionToRoot(); + LLSelectMgr::getInstance()->promoteSelectionToRoot(); } return true; } @@ -8362,7 +8486,7 @@ void handle_dump_timers() void handle_debug_avatar_textures(void*) { - LLViewerObject* objectp = LLSelectMgr::getInstanceFast()->getSelection()->getPrimaryObject(); + LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); if (objectp) { LLFloaterReg::showInstance( "avatar_textures", LLSD(objectp->getID()) ); @@ -8526,17 +8650,17 @@ class LLToolsUseSelectionForGrid : public view_listener_t { bool handleEvent(const LLSD& userdata) { - LLSelectMgr::getInstanceFast()->clearGridObjects(); + LLSelectMgr::getInstance()->clearGridObjects(); struct f : public LLSelectedObjectFunctor { virtual bool apply(LLViewerObject* objectp) { - LLSelectMgr::getInstanceFast()->addGridObject(objectp); + LLSelectMgr::getInstance()->addGridObject(objectp); return true; } } func; - LLSelectMgr::getInstanceFast()->getSelection()->applyToRootObjects(&func); - LLSelectMgr::getInstanceFast()->setGridMode(GRID_MODE_REF_OBJECT); + LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func); + LLSelectMgr::getInstance()->setGridMode(GRID_MODE_REF_OBJECT); LLFloaterTools::setGridMode((S32)GRID_MODE_REF_OBJECT); return true; } @@ -8981,7 +9105,7 @@ class LLEditEnableTakeOff : public view_listener_t bool handleEvent(const LLSD& userdata) { std::string clothing = userdata.asString(); - LLWearableType::EType type = LLWearableType::getInstanceFast()->typeNameToType(clothing); + LLWearableType::EType type = LLWearableType::getInstance()->typeNameToType(clothing); // if (type >= LLWearableType::WT_SHAPE && type < LLWearableType::WT_COUNT) // [RLVa:KB] - Checked: 2010-03-20 (RLVa-1.2.0c) | Modified: RLVa-1.2.0a // NOTE: see below - enable if there is at least one wearable on this type that can be removed @@ -9004,7 +9128,7 @@ class LLEditTakeOff : public view_listener_t LLAppearanceMgr::instance().removeAllClothesFromAvatar(); else { - LLWearableType::EType type = LLWearableType::getInstanceFast()->typeNameToType(clothing); + LLWearableType::EType type = LLWearableType::getInstance()->typeNameToType(clothing); if (type >= LLWearableType::WT_SHAPE && type < LLWearableType::WT_COUNT && (gAgentWearables.getWearableCount(type) > 0)) @@ -9043,23 +9167,23 @@ class LLToolsSelectTool : public view_listener_t std::string tool_name = userdata.asString(); if (tool_name == "focus") { - LLToolMgr::getInstanceFast()->getCurrentToolset()->selectToolByIndex(1); + LLToolMgr::getInstance()->getCurrentToolset()->selectToolByIndex(1); } else if (tool_name == "move") { - LLToolMgr::getInstanceFast()->getCurrentToolset()->selectToolByIndex(2); + LLToolMgr::getInstance()->getCurrentToolset()->selectToolByIndex(2); } else if (tool_name == "edit") { - LLToolMgr::getInstanceFast()->getCurrentToolset()->selectToolByIndex(3); + LLToolMgr::getInstance()->getCurrentToolset()->selectToolByIndex(3); } else if (tool_name == "create") { - LLToolMgr::getInstanceFast()->getCurrentToolset()->selectToolByIndex(4); + LLToolMgr::getInstance()->getCurrentToolset()->selectToolByIndex(4); } else if (tool_name == "land") { - LLToolMgr::getInstanceFast()->getCurrentToolset()->selectToolByIndex(5); + LLToolMgr::getInstance()->getCurrentToolset()->selectToolByIndex(5); } // Note: if floater is not visible LLViewerWindow::updateLayout() will @@ -9159,10 +9283,10 @@ class LLWorldEnableEnvSettings : public view_listener_t if (event_name == "pause_clouds") { - return LLEnvironment::instanceFast().isCloudScrollPaused(); + return LLEnvironment::instance().isCloudScrollPaused(); } - LLSettingsSky::ptr_t sky = LLEnvironment::instanceFast().getEnvironmentFixedSky(LLEnvironment::ENV_LOCAL); + LLSettingsSky::ptr_t sky = LLEnvironment::instance().getEnvironmentFixedSky(LLEnvironment::ENV_LOCAL); if (!sky) { @@ -9579,7 +9703,7 @@ void initialize_menus() view_listener_t::addMenu(new LLToolsUseSelectionForGrid(), "Tools.UseSelectionForGrid"); view_listener_t::addMenu(new LLToolsSelectNextPartFace(), "Tools.SelectNextPart"); commit.add("Tools.Link", boost::bind(&handle_link_objects)); - commit.add("Tools.Unlink", boost::bind(&LLSelectMgr::unlinkObjects, LLSelectMgr::getInstanceFast())); + commit.add("Tools.Unlink", boost::bind(&LLSelectMgr::unlinkObjects, LLSelectMgr::getInstance())); view_listener_t::addMenu(new LLToolsStopAllAnimations(), "Tools.StopAllAnimations"); view_listener_t::addMenu(new LLToolsReleaseKeys(), "Tools.ReleaseKeys"); view_listener_t::addMenu(new LLToolsEnableReleaseKeys(), "Tools.EnableReleaseKeys"); @@ -9591,8 +9715,8 @@ void initialize_menus() view_listener_t::addMenu(new LLToolsEnableToolNotPie(), "Tools.EnableToolNotPie"); view_listener_t::addMenu(new LLToolsEnableSelectNextPart(), "Tools.EnableSelectNextPart"); - enable.add("Tools.EnableLink", boost::bind(&LLSelectMgr::enableLinkObjects, LLSelectMgr::getInstanceFast())); - enable.add("Tools.EnableUnlink", boost::bind(&LLSelectMgr::enableUnlinkObjects, LLSelectMgr::getInstanceFast())); + enable.add("Tools.EnableLink", boost::bind(&LLSelectMgr::enableLinkObjects, LLSelectMgr::getInstance())); + enable.add("Tools.EnableUnlink", boost::bind(&LLSelectMgr::enableUnlinkObjects, LLSelectMgr::getInstance())); view_listener_t::addMenu(new LLToolsEnableBuyOrTake(), "Tools.EnableBuyOrTake"); enable.add("Tools.EnableTakeCopy", boost::bind(&enable_object_take_copy)); enable.add("Tools.VisibleBuyObject", boost::bind(&tools_visible_buy_object)); @@ -9640,7 +9764,6 @@ void initialize_menus() view_listener_t::addMenu(new LLAdvancedCheckWireframe(), "Advanced.CheckWireframe"); // Develop > Render view_listener_t::addMenu(new LLAdvancedEnableObjectObjectOcclusion(), "Advanced.EnableObjectObjectOcclusion"); - view_listener_t::addMenu(new LLAdvancedEnableRenderFBO(), "Advanced.EnableRenderFBO"); view_listener_t::addMenu(new LLAdvancedEnableRenderDeferred(), "Advanced.EnableRenderDeferred"); view_listener_t::addMenu(new LLAdvancedEnableRenderDeferredOptions(), "Advanced.EnableRenderDeferredOptions"); view_listener_t::addMenu(new LLAdvancedToggleRandomizeFramerate(), "Advanced.ToggleRandomizeFramerate"); @@ -9742,6 +9865,9 @@ void initialize_menus() view_listener_t::addMenu(new LLAdvancedDisableMessageLog(), "Advanced.DisableMessageLog"); view_listener_t::addMenu(new LLAdvancedDropPacket(), "Advanced.DropPacket"); + // Advanced > Cache + view_listener_t::addMenu(new LLAdvancedPurgeDiskCache(), "Advanced.PurgeDiskCache"); + // Advanced > Recorder view_listener_t::addMenu(new LLAdvancedAgentPilot(), "Advanced.AgentPilot"); view_listener_t::addMenu(new LLAdvancedToggleAgentPilotLoop(), "Advanced.ToggleAgentPilotLoop"); @@ -9752,8 +9878,10 @@ void initialize_menus() view_listener_t::addMenu(new LLAdvancedForceErrorBreakpoint(), "Advanced.ForceErrorBreakpoint"); view_listener_t::addMenu(new LLAdvancedForceErrorLlerror(), "Advanced.ForceErrorLlerror"); view_listener_t::addMenu(new LLAdvancedForceErrorBadMemoryAccess(), "Advanced.ForceErrorBadMemoryAccess"); + view_listener_t::addMenu(new LLAdvancedForceErrorBadMemoryAccessCoro(), "Advanced.ForceErrorBadMemoryAccessCoro"); view_listener_t::addMenu(new LLAdvancedForceErrorInfiniteLoop(), "Advanced.ForceErrorInfiniteLoop"); view_listener_t::addMenu(new LLAdvancedForceErrorSoftwareException(), "Advanced.ForceErrorSoftwareException"); + view_listener_t::addMenu(new LLAdvancedForceErrorSoftwareExceptionCoro(), "Advanced.ForceErrorSoftwareExceptionCoro"); view_listener_t::addMenu(new LLAdvancedForceErrorDriverCrash(), "Advanced.ForceErrorDriverCrash"); view_listener_t::addMenu(new LLAdvancedForceErrorCoroutineCrash(), "Advanced.ForceErrorCoroutineCrash"); view_listener_t::addMenu(new LLAdvancedForceErrorThreadCrash(), "Advanced.ForceErrorThreadCrash"); @@ -9836,6 +9964,7 @@ void initialize_menus() view_listener_t::addMenu(new LLAvatarResetSkeleton(), "Avatar.ResetSkeleton"); view_listener_t::addMenu(new LLAvatarEnableResetSkeleton(), "Avatar.EnableResetSkeleton"); view_listener_t::addMenu(new LLAvatarResetSkeletonAndAnimations(), "Avatar.ResetSkeletonAndAnimations"); + view_listener_t::addMenu(new LLAvatarResetSelfSkeletonAndAnimations(), "Avatar.ResetSelfSkeletonAndAnimations"); enable.add("Avatar.IsMyProfileOpen", boost::bind(&my_profile_visible)); enable.add("Avatar.IsPicksTabOpen", boost::bind(&picks_tab_visible)); @@ -9847,12 +9976,13 @@ void initialize_menus() // Object pie menu view_listener_t::addMenu(new LLObjectBuild(), "Object.Build"); commit.add("Object.Touch", boost::bind(&handle_object_touch)); + commit.add("Object.ShowOriginal", boost::bind(&handle_object_show_original)); commit.add("Object.SitOrStand", boost::bind(&handle_object_sit_or_stand)); commit.add("Object.Delete", boost::bind(&handle_object_delete)); view_listener_t::addMenu(new LLObjectAttachToAvatar(true), "Object.AttachToAvatar"); view_listener_t::addMenu(new LLObjectAttachToAvatar(false), "Object.AttachAddToAvatar"); view_listener_t::addMenu(new LLObjectReturn(), "Object.Return"); - commit.add("Object.Duplicate", boost::bind(&LLSelectMgr::duplicate, LLSelectMgr::getInstanceFast())); + commit.add("Object.Duplicate", boost::bind(&LLSelectMgr::duplicate, LLSelectMgr::getInstance())); view_listener_t::addMenu(new LLObjectReportAbuse(), "Object.ReportAbuse"); view_listener_t::addMenu(new LLObjectMute(), "Object.Mute"); @@ -9874,7 +10004,7 @@ void initialize_menus() enable.add("Object.EnableSit", boost::bind(&enable_object_sit, _1)); view_listener_t::addMenu(new LLObjectEnableReturn(), "Object.EnableReturn"); - enable.add("Object.EnableDuplicate", boost::bind(&LLSelectMgr::canDuplicate, LLSelectMgr::getInstanceFast())); + enable.add("Object.EnableDuplicate", boost::bind(&LLSelectMgr::canDuplicate, LLSelectMgr::getInstance())); view_listener_t::addMenu(new LLObjectEnableReportAbuse(), "Object.EnableReportAbuse"); enable.add("Avatar.EnableMute", boost::bind(&enable_object_mute)); diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h index e27c9d69da6aed91df402db4bafe9ae38837692a..8566ff8fea945e60a15e73a01fa070069a99ebc6 100644 --- a/indra/newview/llviewermenu.h +++ b/indra/newview/llviewermenu.h @@ -139,6 +139,7 @@ void handle_save_snapshot(void *); void handle_toggle_flycam(); void handle_object_sit_or_stand(); +void handle_object_sit(const LLUUID& object_id); void handle_give_money_dialog(); bool enable_pay_object(); bool enable_buy_object(); diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index 462fd6e9f09ca610d725cbe3fadb0cb0851289bf..0055794db675358bd43bca2ac68a5c3af73c1d14 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -119,7 +119,7 @@ class LLMeshUploadVisible : public view_listener_t } }; -LLMutex LLFilePickerThread::sMutex(LLMutex::E_CONST_INIT); +LLMutex* LLFilePickerThread::sMutex = NULL; std::queue<LLFilePickerThread*> LLFilePickerThread::sDeadQ; void LLFilePickerThread::getFile() @@ -165,7 +165,7 @@ void LLFilePickerThread::run() } { - LLMutexLock lock(&sMutex); + LLMutexLock lock(sMutex); sDeadQ.push(this); } @@ -174,12 +174,16 @@ void LLFilePickerThread::run() //static void LLFilePickerThread::initClass() { + sMutex = new LLMutex(); } //static void LLFilePickerThread::cleanupClass() { clearDead(); + + delete sMutex; + sMutex = NULL; } //static @@ -187,7 +191,7 @@ void LLFilePickerThread::clearDead() { if (!sDeadQ.empty()) { - LLMutexLock lock(&sMutex); + LLMutexLock lock(sMutex); while (!sDeadQ.empty()) { LLFilePickerThread* thread = sDeadQ.front(); @@ -253,13 +257,13 @@ void LLFilePickerReplyThread::notify(const std::vector<std::string>& filenames) LLMediaFilePicker::LLMediaFilePicker(LLPluginClassMedia* plugin, LLFilePicker::ELoadFilter filter, bool get_multiple) : LLFilePickerThread(filter, get_multiple), - mPlugin(plugin->getSharedPrt()) + mPlugin(plugin->getSharedPtr()) { } LLMediaFilePicker::LLMediaFilePicker(LLPluginClassMedia* plugin, LLFilePicker::ESaveFilter filter, const std::string &proposed_name) : LLFilePickerThread(filter, proposed_name), - mPlugin(plugin->getSharedPrt()) + mPlugin(plugin->getSharedPtr()) { } diff --git a/indra/newview/llviewermenufile.h b/indra/newview/llviewermenufile.h index 07dbd37e2794897d05ee432ade0e828727008c57..06f5495f2af6e7ef0b48a591354b5bba3321a115 100644 --- a/indra/newview/llviewermenufile.h +++ b/indra/newview/llviewermenufile.h @@ -78,7 +78,7 @@ class LLFilePickerThread : public LLThread public: static std::queue<LLFilePickerThread*> sDeadQ; - static LLMutex sMutex; + static LLMutex* sMutex; static void initClass(); static void cleanupClass(); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index ffd6eb192227f304d54d847ae5e38838e5d1dd09..38febf6c3adc652acc48b4c8f5a9b1c318045dd8 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -35,6 +35,7 @@ #include "llcurrencywrapper.h" #include "lleconomy.h" #include "lleventtimer.h" +#include "llfloatercreatelandmark.h" #include "llfloaterreg.h" #include "llfolderview.h" #include "llfollowcamparams.h" @@ -199,7 +200,7 @@ void accept_friendship_coro(std::string url, LLSD notification) { LL_DEBUGS("Friendship") << "Adding friend to list" << httpResults << LL_ENDL; // add friend to recent people list - LLRecentPeople::instanceFast().add(payload["from_id"]); + LLRecentPeople::instance().add(payload["from_id"]); LLNotificationsUtil::add("FriendshipAcceptedByMe", notification["substitutions"], payload); @@ -297,7 +298,7 @@ bool friendship_offer_callback(const LLSD& notification, const LLSD& response) msg->sendReliable(LLHost(payload["sender"].asString())); // add friend to recent people list - LLRecentPeople::instanceFast().add(payload["from_id"]); + LLRecentPeople::instance().add(payload["from_id"]); LLNotificationsUtil::add("FriendshipAcceptedByMe", notification["substitutions"], payload); } @@ -480,7 +481,7 @@ void process_logout_reply(LLMessageSystem* msg, void**) void process_layer_data(LLMessageSystem *mesgsys, void **user_data) { - LLViewerRegion *regionp = LLWorld::getInstanceFast()->getRegion(mesgsys->getSender()); + LLViewerRegion *regionp = LLWorld::getInstance()->getRegion(mesgsys->getSender()); LL_DEBUGS_ONCE("SceneLoadTiming") << "Received layer data" << LL_ENDL; @@ -1579,6 +1580,17 @@ bool highlight_offered_object(const LLUUID& obj_id) } } + if (obj->getType() == LLAssetType::AT_LANDMARK) + { + LLFloaterCreateLandmark *floater = LLFloaterReg::findTypedInstance<LLFloaterCreateLandmark>("add_landmark"); + if (floater && floater->getItem() && floater->getItem()->getUUID() == obj_id) + { + // LLFloaterCreateLandmark is supposed to handle this, + // keep landmark creation floater at the front + return false; + } + } + return true; } @@ -1590,7 +1602,7 @@ void inventory_offer_mute_callback(const LLUUID& blocked_id, LLMute::EType mute_type = is_group ? LLMute::GROUP : LLMute::AGENT; LLMute mute(blocked_id, full_name, mute_type); - if (LLMuteList::getInstanceFast()->add(mute)) + if (LLMuteList::getInstance()->add(mute)) { LLPanelBlockedList::showPanelAndSelect(blocked_id); } @@ -1705,7 +1717,7 @@ void LLOfferInfo::sendReceiveResponse(bool accept, const LLUUID &destination_fol bool fRlvCanShowName = (!RlvActions::isRlvEnabled()) || (RlvActions::canShowName(RlvActions::SNC_DEFAULT, mFromID)) || (!RlvUtil::isNearbyAgent(mFromID)) || (RlvUIEnabler::hasOpenIM(mFromID)) || (RlvUIEnabler::hasOpenProfile(mFromID)); if (fRlvCanShowName) - LLRecentPeople::instanceFast().add(mFromID); + LLRecentPeople::instance().add(mFromID); // [/RLVa:KB] } @@ -1925,7 +1937,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::getInstanceFast()->isMuted(mFromID ) && ! LLMuteList::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 @@ -2134,7 +2146,7 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const default: // close button probably (or any of the fall-throughs from above) destination = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); - if (accept && LLMuteList::getInstanceFast()->isMuted(mFromID, mFromName)) + if (accept && LLMuteList::getInstance()->isMuted(mFromID, mFromName)) { // Note: muted offers are usually declined automatically, // but user can mute object after receiving message @@ -2324,11 +2336,9 @@ class LLPostponedServerObjectNotification: public LLPostponedNotification } }; -static LLTrace::BlockTimerStatHandle FTM_PROCESS_IMPROVED_IM("Process IM"); - void process_improved_im(LLMessageSystem *msg, void **user_data) { - LL_RECORD_BLOCK_TIME(FTM_PROCESS_IMPROVED_IM); + LL_PROFILE_ZONE_SCOPED; LLUUID from_id; BOOL from_group; @@ -2476,7 +2486,7 @@ void process_offer_callingcard(LLMessageSystem* msg, void**) if(!source_name.empty()) { if (gAgent.isDoNotDisturb() - || LLMuteList::getInstanceFast()->isMuted(source_id, source_name, LLMute::flagTextChat)) + || LLMuteList::getInstance()->isMuted(source_id, source_name, LLMute::flagTextChat)) { // automatically decline offer LLNotifications::instance().forceResponse(LLNotification::Params("OfferCallingCard").payload(payload), 1); @@ -2528,6 +2538,10 @@ void translateFailure(LLChat chat, LLSD toastArgs, int status, const std::string void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) { + if (gNonInteractive) + { + return; + } LLChat chat; std::string mesg; std::string from_name; @@ -2589,11 +2603,11 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) BOOL is_muted = FALSE; BOOL is_linden = FALSE; - is_muted = LLMuteList::getInstanceFast()->isMuted( + is_muted = LLMuteList::getInstance()->isMuted( from_id, from_name, LLMute::flagTextChat) - || LLMuteList::getInstanceFast()->isMuted(owner_id, LLMute::flagTextChat); + || LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagTextChat); is_linden = chat.mSourceType != CHAT_SOURCE_OBJECT && LLMuteList::isLinden(from_name); @@ -2706,7 +2720,7 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) if ( (!RlvActions::canShowName(RlvActions::SNC_DEFAULT, owner_id)) && (!is_owned_by_me) ) sdQuery["rlv_shownames"] = true; - const LLViewerRegion* pRegion = LLWorld::getInstanceFast()->getRegionFromPosAgent(chat.mPosAgent); + const LLViewerRegion* pRegion = LLWorld::getInstance()->getRegionFromPosAgent(chat.mPosAgent); if (pRegion) sdQuery["slurl"] = LLSLURL(pRegion->getName(), chat.mPosAgent).getLocationString(); @@ -3364,7 +3378,7 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**) F32 x, y; from_region_handle(region_handle, &x, &y); - LLViewerRegion* regionp = LLWorld::getInstanceFast()->getRegionFromHandle(region_handle); + LLViewerRegion* regionp = LLWorld::getInstance()->getRegionFromHandle(region_handle); if (!regionp) { if (gAgent.getRegion()) @@ -3420,7 +3434,7 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**) { // *NOTE: the LookAt data we get from the sim here doesn't // seem to be useful, so get it from the camera instead - look_at = LLViewerCamera::getInstanceFast()->getAtAxis(); + look_at = LLViewerCamera::getInstance()->getAtAxis(); } // Force the camera back onto the agent, don't animate. gAgentCamera.setFocusOnAvatar(TRUE, FALSE); @@ -3457,7 +3471,7 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**) look_at_point = agent_pos + look_at_point.rotVec(gAgent.getQuat()); static LLVector3 up_direction(0.0f, 0.0f, 1.0f); - LLViewerCamera::getInstanceFast()->lookAt(agent_pos, look_at_point, up_direction); + LLViewerCamera::getInstance()->lookAt(agent_pos, look_at_point, up_direction); } } @@ -3585,10 +3599,9 @@ const F32 THRESHOLD_HEAD_ROT_QDOT = 0.9997f; // ~= 2.5 degrees -- if its less th const F32 MAX_HEAD_ROT_QDOT = 0.99999f; // ~= 0.5 degrees -- if its greater than this then no need to update head_rot // between these values we delay the updates (but no more than one second) -static LLTrace::BlockTimerStatHandle FTM_AGENT_UPDATE_SEND("Send Message"); - void send_agent_update(BOOL force_send, BOOL send_reliable) { + LL_PROFILE_ZONE_SCOPED; if (gAgent.getTeleportState() != LLAgent::TELEPORT_NONE) { // We don't care if they want to send an agent update, they're not allowed to until the simulator @@ -3648,7 +3661,7 @@ void send_agent_update(BOOL force_send, BOOL send_reliable) U8 flag_change = 0; cam_center_chg = last_camera_pos_agent - camera_pos_agent; - cam_rot_chg = last_camera_at - LLViewerCamera::getInstanceFast()->getAtAxis(); + cam_rot_chg = last_camera_at - LLViewerCamera::getInstance()->getAtAxis(); // If a modifier key is held down, turn off // LBUTTON and ML_LBUTTON so that using the camera (alt-key) doesn't @@ -3769,7 +3782,6 @@ void send_agent_update(BOOL force_send, BOOL send_reliable) } */ - LL_RECORD_BLOCK_TIME(FTM_AGENT_UPDATE_SEND); // Build the message msg->newMessageFast(_PREHASH_AgentUpdate); msg->nextBlockFast(_PREHASH_AgentData); @@ -3786,9 +3798,9 @@ void send_agent_update(BOOL force_send, BOOL send_reliable) // } msg->addVector3Fast(_PREHASH_CameraCenter, camera_pos_agent); - msg->addVector3Fast(_PREHASH_CameraAtAxis, LLViewerCamera::getInstanceFast()->getAtAxis()); - msg->addVector3Fast(_PREHASH_CameraLeftAxis, LLViewerCamera::getInstanceFast()->getLeftAxis()); - msg->addVector3Fast(_PREHASH_CameraUpAxis, LLViewerCamera::getInstanceFast()->getUpAxis()); + msg->addVector3Fast(_PREHASH_CameraAtAxis, LLViewerCamera::getInstance()->getAtAxis()); + msg->addVector3Fast(_PREHASH_CameraLeftAxis, LLViewerCamera::getInstance()->getLeftAxis()); + msg->addVector3Fast(_PREHASH_CameraUpAxis, LLViewerCamera::getInstance()->getUpAxis()); msg->addF32Fast(_PREHASH_Far, gAgentCamera.mDrawDistance); msg->addU32Fast(_PREHASH_ControlFlags, control_flags); @@ -3823,9 +3835,9 @@ void send_agent_update(BOOL force_send, BOOL send_reliable) last_head_rot = head_rotation; last_render_state = render_state; last_camera_pos_agent = camera_pos_agent; - last_camera_at = LLViewerCamera::getInstanceFast()->getAtAxis(); - last_camera_left = LLViewerCamera::getInstanceFast()->getLeftAxis(); - last_camera_up = LLViewerCamera::getInstanceFast()->getUpAxis(); + last_camera_at = LLViewerCamera::getInstance()->getAtAxis(); + last_camera_left = LLViewerCamera::getInstance()->getLeftAxis(); + last_camera_up = LLViewerCamera::getInstance()->getUpAxis(); last_control_flags = control_flags; last_flags = flags; } @@ -3860,9 +3872,9 @@ static std::map<LLUUID, PostponedSoundData> postponed_sounds; void set_attached_sound(LLViewerObject *objectp, const LLUUID &object_id, const LLUUID &sound_id, const LLUUID& owner_id, const F32 gain, const U8 flags) { - if (LLMuteList::getInstanceFast()->isMuted(object_id)) return; + if (LLMuteList::getInstance()->isMuted(object_id)) return; - if (LLMuteList::getInstanceFast()->isMuted(owner_id, LLMute::flagObjectSounds)) return; + if (LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagObjectSounds)) return; // Don't play sounds from a region with maturity above current agent maturity LLVector3d pos = objectp->getPositionGlobal(); @@ -4019,11 +4031,9 @@ void process_terse_object_update_improved(LLMessageSystem *mesgsys, void **user_ } } -static LLTrace::BlockTimerStatHandle FTM_PROCESS_OBJECTS("Process Kill Objects"); - void process_kill_object(LLMessageSystem *mesgsys, void **user_data) { - LL_RECORD_BLOCK_TIME(FTM_PROCESS_OBJECTS); + LL_PROFILE_ZONE_SCOPED; LLUUID id; @@ -4032,7 +4042,7 @@ void process_kill_object(LLMessageSystem *mesgsys, void **user_data) LLViewerRegion* regionp = NULL; { LLHost host(ip, port); - regionp = LLWorld::getInstanceFast()->getRegion(host); + regionp = LLWorld::getInstance()->getRegion(host); } bool delete_object = LLViewerRegion::sVOCacheCullingEnabled; @@ -4091,7 +4101,7 @@ void process_kill_object(LLMessageSystem *mesgsys, void **user_data) // We should remove the object from selection after it is marked dead by gObjectList to make LLToolGrab, // which is using the object, release the mouse capture correctly when the object dies. // See LLToolGrab::handleHoverActive() and LLToolGrab::handleHoverNonPhysical(). - LLSelectMgr::getInstanceFast()->removeObjectFromSelections(id); + LLSelectMgr::getInstance()->removeObjectFromSelections(id); } } @@ -4116,7 +4126,7 @@ void process_time_synch(LLMessageSystem *mesgsys, void **user_data) mesgsys->getVector3Fast(_PREHASH_TimeInfo, _PREHASH_SunDirection, sun_direction); mesgsys->getVector3Fast(_PREHASH_TimeInfo, _PREHASH_SunAngVelocity, sun_ang_velocity); - LLWorld::getInstanceFast()->setSpaceTimeUSec(space_time_usec); + LLWorld::getInstance()->setSpaceTimeUSec(space_time_usec); LL_DEBUGS("WindlightSync") << "Sun phase: " << phase << " rad = " << fmodf(phase / F_TWO_PI + 0.25, 1.f) * 24.f << " h" << LL_ENDL; @@ -4160,17 +4170,17 @@ void process_sound_trigger(LLMessageSystem *msg, void **) // Don't play a trigger sound if you can't hear it due // to parcel "local audio only" settings. - if (!LLViewerParcelMgr::getInstanceFast()->canHearSound(pos_global)) return; + if (!LLViewerParcelMgr::getInstance()->canHearSound(pos_global)) return; // Don't play sounds triggered by someone you muted. - if (LLMuteList::getInstanceFast()->isMuted(owner_id, LLMute::flagObjectSounds)) return; + if (LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagObjectSounds)) return; // Don't play sounds from an object you muted - if (LLMuteList::getInstanceFast()->isMuted(object_id)) return; + if (LLMuteList::getInstance()->isMuted(object_id)) return; // Don't play sounds from an object whose parent you muted if (parent_id.notNull() - && LLMuteList::getInstanceFast()->isMuted(parent_id)) + && LLMuteList::getInstance()->isMuted(parent_id)) { return; } @@ -4221,8 +4231,8 @@ void process_preload_sound(LLMessageSystem *msg, void **user_data) LLViewerObject *objectp = gObjectList.findObject(object_id); if (!objectp) return; - if (LLMuteList::getInstanceFast()->isMuted(object_id)) return; - if (LLMuteList::getInstanceFast()->isMuted(owner_id, LLMute::flagObjectSounds)) return; + if (LLMuteList::getInstance()->isMuted(object_id)) return; + if (LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagObjectSounds)) return; LLAudioSource *sourcep = objectp->getAudioSource(owner_id); if (!sourcep) return; @@ -4320,8 +4330,8 @@ void process_sim_stats(LLMessageSystem *msg, void **user_data) F32 stat_value; msg->getU32Fast(_PREHASH_Stat, _PREHASH_StatID, stat_id, i); msg->getF32Fast(_PREHASH_Stat, _PREHASH_StatValue, stat_value, i); - LLStatViewer::SimMeasurementSampler* measurementp = LLStatViewer::SimMeasurementSampler::getInstance((ESimStatID)stat_id); - + auto measurementp = LLStatViewer::SimMeasurementSampler::getInstance((ESimStatID)stat_id); + if (measurementp ) { measurementp->sample(stat_value); @@ -4501,7 +4511,7 @@ void process_object_animation(LLMessageSystem *mesgsys, void **user_data) << uuid << " animation id " << animation_id << LL_ENDL; #endif } - LLObjectSignaledAnimationMap::instanceFast().getMap()[uuid] = signaled_anims; + LLObjectSignaledAnimationMap::instance().getMap()[uuid] = signaled_anims; LLViewerObject *objp = gObjectList.findObject(uuid); if (!objp) @@ -4872,7 +4882,7 @@ void process_time_dilation(LLMessageSystem *msg, void **user_data) // get the pointer to the right region U32 ip = msg->getSenderIP(); U32 port = msg->getSenderPort(); - LLViewerRegion *regionp = LLWorld::getInstanceFast()->getRegion(ip, port); + LLViewerRegion *regionp = LLWorld::getInstance()->getRegion(ip, port); if (regionp) { regionp->setTimeDilation(time_dilation); @@ -5149,7 +5159,7 @@ static void process_money_balance_reply_extended(LLMessageSystem* msg) is_name_group = is_source_group; name_id = source_id; - if (!reason.empty() && !LLMuteList::getInstanceFast()->isMuted(source_id)) + if (!reason.empty() && !LLMuteList::getInstance()->isMuted(source_id)) { message = LLTrans::getString("paid_you_ldollars" + gift_suffix, args); } @@ -6104,7 +6114,7 @@ bool script_question_cb(const LLSD& notification, const LLSD& response) void script_question_mute(const LLUUID& task_id, const std::string& object_name) { - LLMuteList::getInstanceFast()->add(LLMute(task_id, object_name, LLMute::OBJECT)); + LLMuteList::getInstance()->add(LLMute(task_id, object_name, LLMute::OBJECT)); // purge the message queue of any previously queued requests from the same source. DEV-4879 class OfferMatcher : public LLNotificationsUI::LLScreenChannel::Matcher @@ -6187,7 +6197,7 @@ void process_script_question(LLMessageSystem *msg, void **user_data) } // don't display permission requests if this object is muted - if (LLMuteList::getInstanceFast()->isMuted(taskid)) return; + if (LLMuteList::getInstance()->isMuted(taskid)) return; // throttle excessive requests from any specific user's scripts typedef LLKeyThrottle<std::string> LLStringThrottle; @@ -6232,15 +6242,15 @@ void process_script_question(LLMessageSystem *msg, void **user_data) if (("ScriptTakeMoney" == script_perm.question) && has_not_only_debit) continue; - if (script_perm.question == "JoinAnExperience") - { // Some experience only permissions do not have an explicit permission bit. Add them here. - script_question += " " + LLTrans::getString("ForceSitAvatar") + "\n"; + if (LLTrans::getString(script_perm.question).empty()) + { + continue; } script_question += " " + LLTrans::getString(script_perm.question) + "\n"; } } - + args["QUESTIONS"] = script_question; if (known_questions != questions) @@ -6585,7 +6595,7 @@ void process_teleport_local(LLMessageSystem *msg,void**) gAgent.setPositionAgent(pos); gAgentCamera.slamLookAt(look_at); - if ( !(gAgent.getTeleportKeepsLookAt() && LLViewerJoystick::getInstanceFast()->getOverrideCamera()) ) + if ( !(gAgent.getTeleportKeepsLookAt() && LLViewerJoystick::getInstance()->getOverrideCamera()) ) { gAgentCamera.resetView(TRUE, TRUE); } @@ -6729,7 +6739,7 @@ void send_lures(const LLSD& notification, const LLSD& response) // Add the recepient to the recent people list. // [RLVa:KB] - Checked: RLVa-2.0.1 if (fRlvCanShowName) - LLRecentPeople::instanceFast().add(target_id); + LLRecentPeople::instance().add(target_id); // [/RLVa:KB] // LLRecentPeople::instance().add(target_id); } @@ -6830,7 +6840,7 @@ bool teleport_request_callback(const LLSD& notification, const LLSD& response) LLAvatarName av_name; LLAvatarNameCache::get(from_id, &av_name); - if(LLMuteList::getInstanceFast()->isMuted(from_id) && !LLMuteList::isLinden(av_name.getUserName())) + if(LLMuteList::getInstance()->isMuted(from_id) && !LLMuteList::isLinden(av_name.getUserName())) { return false; } @@ -6986,7 +6996,7 @@ bool callback_script_dialog(const LLSD& notification, const LLSD& response) std::string object_name = notification["payload"]["object_name"].asString(); LLUUID object_id = notification["payload"]["object_id"].asUUID(); LLMute mute(object_id, object_name, LLMute::OBJECT); - if (LLMuteList::getInstanceFast()->add(mute)) + if (LLMuteList::getInstance()->add(mute)) { // This call opens the sidebar, displays the block list, and highlights the newly blocked // object in the list so the user can see that their block click has taken effect. @@ -7043,7 +7053,7 @@ void process_script_dialog(LLMessageSystem* msg, void**) msg->getUUIDFast(_PREHASH_OwnerData, _PREHASH_OwnerID, owner_id); } - if (LLMuteList::getInstanceFast()->isMuted(object_id) || LLMuteList::getInstanceFast()->isMuted(owner_id)) + if (LLMuteList::getInstance()->isMuted(object_id) || LLMuteList::getInstance()->isMuted(owner_id)) { return; } @@ -7144,7 +7154,7 @@ void callback_load_url_name(const LLUUID& id, const std::string& full_name, bool } // For legacy name-only mutes. - if (LLMuteList::getInstanceFast()->isMuted(LLUUID::null, owner_name)) + if (LLMuteList::getInstance()->isMuted(LLUUID::null, owner_name)) { continue; } @@ -7196,8 +7206,8 @@ void process_load_url(LLMessageSystem* msg, void**) // URL is safety checked in load_url above // Check if object or owner is muted - if (LLMuteList::getInstanceFast()->isMuted(object_id, object_name) || - LLMuteList::getInstanceFast()->isMuted(owner_id)) + if (LLMuteList::getInstance()->isMuted(object_id, object_name) || + LLMuteList::getInstance()->isMuted(owner_id)) { LL_INFOS("Messaging")<<"Ignoring load_url from muted object/owner."<<LL_ENDL; return; diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 6e428b0402cf1295389860bb7271a1ee349f087e..ab6e6e33b0db3c3bb651a1fe1f05d931154711ed 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -107,6 +107,7 @@ #include "llcleanup.h" #include "llcallstack.h" #include "llmeshrepository.h" +#include "llgl.h" // [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a) #include "rlvactions.h" #include "rlvcommon.h" @@ -150,23 +151,37 @@ const S32 MAX_OBJECT_BINARY_DATA_SIZE = 60 + 16; const F64 INVENTORY_UPDATE_WAIT_TIME_DESYNC = 5; // seconds const F64 INVENTORY_UPDATE_WAIT_TIME_OUTDATED = 1; -static LLTrace::BlockTimerStatHandle FTM_CREATE_OBJECT("Create Object"); - // static LLViewerObject *LLViewerObject::createObject(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp, S32 flags) { + LL_PROFILE_ZONE_SCOPED; #ifdef SHOW_DEBUG LL_DEBUGS("ObjectUpdate") << "creating " << id << LL_ENDL; dumpStack("ObjectUpdateStack"); #endif LLViewerObject *res = NULL; - LL_RECORD_BLOCK_TIME(FTM_CREATE_OBJECT); - + + if (gNonInteractive + && pcode != LL_PCODE_LEGACY_AVATAR + && pcode != LL_VO_SURFACE_PATCH + && pcode != LL_VO_WATER + && pcode != LL_VO_VOID_WATER + && pcode != LL_VO_WL_SKY + && pcode != LL_VO_SKY + && pcode != LL_VO_GROUND + && pcode != LL_VO_PART_GROUP + ) + { + return res; + } switch (pcode) { case LL_PCODE_VOLUME: - res = new LLVOVolume(id, pcode, regionp); break; + { + res = new LLVOVolume(id, pcode, regionp); break; + break; + } case LL_PCODE_LEGACY_AVATAR: { if (id == gAgentID) @@ -242,8 +257,7 @@ LLViewerObject *LLViewerObject::createObject(const LLUUID &id, const LLPCode pco } LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp, BOOL is_global) -: LLTrace::MemTrackable<LLViewerObject>("LLViewerObject"), - LLPrimitive(), +: LLPrimitive(), mChildList(), mID(id), mLocalID(0), @@ -350,6 +364,13 @@ LLViewerObject::~LLViewerObject() mPartSourcep = NULL; } + if (mText) + { + // something recovered LLHUDText when object was already dead + mText->markDead(); + mText = NULL; + } + // Delete memory associated with extra parameters. mExtraParameterList.clear(); @@ -487,7 +508,7 @@ void LLViewerObject::markDead() if (flagCameraSource()) { - LLFollowCamMgr::getInstanceFast()->removeFollowCamParams(mID); + LLFollowCamMgr::getInstance()->removeFollowCamParams(mID); } sNumZombieObjects++; @@ -938,9 +959,9 @@ void LLViewerObject::removeChild(LLViewerObject *childp) if (childp->isSelected()) { - LLSelectMgr::getInstanceFast()->deselectObjectAndFamily(childp); + LLSelectMgr::getInstance()->deselectObjectAndFamily(childp); BOOL add_to_end = TRUE; - LLSelectMgr::getInstanceFast()->selectObjectAndFamily(childp, add_to_end); + LLSelectMgr::getInstance()->selectObjectAndFamily(childp, add_to_end); } } @@ -1124,7 +1145,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, U32 retval = 0x0; - auto& worldInst = LLWorld::instanceFast(); + auto& worldInst = LLWorld::instance(); // If region is removed from the list it is also deleted. if (!worldInst.isRegionListed(mRegionp)) @@ -2470,11 +2491,19 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, needs_refresh = needs_refresh || child->mUserSelected; } + static LLCachedControl<bool> allow_select_avatar(gSavedSettings, "AllowSelectAvatar", FALSE); if (needs_refresh) { - LLSelectMgr::getInstanceFast()->updateSelectionCenter(); + LLSelectMgr::getInstance()->updateSelectionCenter(); dialog_refresh_all(); - } + } + else if (allow_select_avatar && asAvatar()) + { + // Override any avatar position updates received + // Works only if avatar was repositioned using build + // tools and build floater is visible + LLSelectMgr::getInstance()->overrideAvatarUpdates(); + } // Mark update time as approx. now, with the ping delay. @@ -2529,9 +2558,6 @@ void LLViewerObject::loadFlags(U32 flags) void LLViewerObject::idleUpdate(LLAgent &agent, const F64 &frame_time) { - //static LLTrace::BlockTimerStatHandle ftm("Viewer Object"); - //LL_RECORD_BLOCK_TIME(ftm); - if (!mDead) { if (!mStatic && sVelocityInterpolate && !isSelected()) @@ -2655,7 +2681,7 @@ void LLViewerObject::interpolateLinearMotion(const F64SecondsImplicit& frame_tim new_pos = new_pos + getPositionRegion(); new_v = new_v + vel; - auto& worldInst = LLWorld::instanceFast(); + auto& worldInst = LLWorld::instance(); // Clamp interpolated position to minimum underground and maximum region height LLVector3d new_pos_global = mRegionp->getPosGlobalFromRegion(new_pos); @@ -2823,7 +2849,7 @@ void LLViewerObject::doUpdateInventory( // make sure that the serial number does not match. deleteInventoryItem(item_id); LLPermissions perm(item->getPermissions()); - LLPermissions* obj_perm = LLSelectMgr::getInstanceFast()->findObjectPermissions(this); + LLPermissions* obj_perm = LLSelectMgr::getInstance()->findObjectPermissions(this); bool is_atomic = ((S32)LLAssetType::AT_OBJECT == item->getType()) ? false : true; if(obj_perm) { @@ -3140,7 +3166,7 @@ void LLViewerObject::updateControlAvatar() getControlAvatar()->updateAnimations(); if (isSelected()) { - LLSelectMgr::getInstanceFast()->pauseAssociatedAvatars(); + LLSelectMgr::getInstance()->pauseAssociatedAvatars(); } } } @@ -3691,7 +3717,7 @@ void LLViewerObject::setPixelAreaAndAngle(LLAgent &agent) // I don't think there's a better way to do this without calculating distance per-poly F32 range = sqrt(dx*dx + dy*dy + dz*dz) - min_scale/2; - LLViewerCamera* camera = LLViewerCamera::getInstanceFast(); + LLViewerCamera* camera = LLViewerCamera::getInstance(); if (range < 0.001f || isHUDAttachment()) // range == zero { mAppAngle = 180.f; @@ -3754,7 +3780,7 @@ void LLViewerObject::setScale(const LLVector3 &scale, BOOL damped) { if (!mOnMap) { - llassert_always(LLWorld::getInstanceFast()->getRegionFromHandle(getRegion()->getHandle())); + llassert_always(LLWorld::getInstance()->getRegionFromHandle(getRegion()->getHandle())); gObjectList.addToMap(this); mOnMap = TRUE; @@ -4229,7 +4255,7 @@ LLNameValue *LLViewerObject::getNVPair(const std::string& name) const void LLViewerObject::updatePositionCaches() const { // If region is removed from the list it is also deleted. - if(mRegionp && LLWorld::instanceFast().isRegionListed(mRegionp)) + if(mRegionp && LLWorld::instance().isRegionListed(mRegionp)) { if (!isRoot()) { @@ -4247,7 +4273,7 @@ void LLViewerObject::updatePositionCaches() const const LLVector3d LLViewerObject::getPositionGlobal() const { // If region is removed from the list it is also deleted. - if(mRegionp && LLWorld::instanceFast().isRegionListed(mRegionp)) + if(mRegionp && LLWorld::instance().isRegionListed(mRegionp)) { LLVector3d position_global = mRegionp->getPosGlobalFromRegion(getPositionRegion()); @@ -4267,7 +4293,7 @@ const LLVector3d LLViewerObject::getPositionGlobal() const const LLVector3 &LLViewerObject::getPositionAgent() const { // If region is removed from the list it is also deleted. - if(mRegionp && LLWorld::instanceFast().isRegionListed(mRegionp)) + if(mRegionp && LLWorld::instance().isRegionListed(mRegionp)) { if (mDrawable.notNull() && (!mDrawable->isRoot() && getParent())) { @@ -5695,7 +5721,7 @@ bool LLViewerObject::isOwnerInMuteList(LLUUID id) } else { - muted = LLMuteList::getInstanceFast()->isMuted(owner_id); + muted = LLMuteList::getInstance()->isMuted(owner_id); const F64 SECONDS_BETWEEN_MUTE_UPDATES = 1; mCachedMuteListUpdateTime = now + SECONDS_BETWEEN_MUTE_UPDATES; @@ -5771,7 +5797,7 @@ void LLViewerObject::setParticleSource(const LLPartSysData& particle_parameters, mPartSourcep->setImage(image); } } - LLViewerPartSim::getInstanceFast()->addPartSource(pss); + LLViewerPartSim::getInstance()->addPartSource(pss); } void LLViewerObject::unpackParticleSource(const S32 block_num, const LLUUID& owner_id) @@ -5793,7 +5819,7 @@ void LLViewerObject::unpackParticleSource(const S32 block_num, const LLUUID& own { LLPointer<LLViewerPartSourceScript> pss = LLViewerPartSourceScript::unpackPSS(this, NULL, block_num); //If the owner is muted, don't create the system - if(LLMuteList::getInstanceFast()->isMuted(owner_id, LLMute::flagParticles)) return; + if(LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagParticles)) return; // We need to be able to deal with a particle source that hasn't changed, but still got an update! if (pss) @@ -5801,7 +5827,7 @@ void LLViewerObject::unpackParticleSource(const S32 block_num, const LLUUID& own // LL_INFOS() << "Making particle system with owner " << owner_id << LL_ENDL; pss->setOwnerUUID(owner_id); mPartSourcep = pss; - LLViewerPartSim::getInstanceFast()->addPartSource(pss); + LLViewerPartSim::getInstance()->addPartSource(pss); } } if (mPartSourcep) @@ -5841,14 +5867,14 @@ void LLViewerObject::unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_ { LLPointer<LLViewerPartSourceScript> pss = LLViewerPartSourceScript::unpackPSS(this, NULL, dp, legacy); //If the owner is muted, don't create the system - if(LLMuteList::getInstanceFast()->isMuted(owner_id, LLMute::flagParticles)) return; + if(LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagParticles)) return; // We need to be able to deal with a particle source that hasn't changed, but still got an update! if (pss) { // LL_INFOS() << "Making particle system with owner " << owner_id << LL_ENDL; pss->setOwnerUUID(owner_id); mPartSourcep = pss; - LLViewerPartSim::getInstanceFast()->addPartSource(pss); + LLViewerPartSim::getInstance()->addPartSource(pss); } } if (mPartSourcep) @@ -6263,7 +6289,7 @@ BOOL LLViewerObject::permYouOwner() const return TRUE; #else # ifdef TOGGLE_HACKED_GODLIKE_VIEWER - if (LLGridManager::getInstanceFast()->isInSLBeta() + if (LLGridManager::getInstance()->isInSLBeta() && (gAgent.getGodLevel() >= GOD_MAINTENANCE)) { return TRUE; @@ -6300,7 +6326,7 @@ BOOL LLViewerObject::permOwnerModify() const return TRUE; #else # ifdef TOGGLE_HACKED_GODLIKE_VIEWER - if (LLGridManager::getInstanceFast()->isInSLBeta() + if (LLGridManager::getInstance()->isInSLBeta() && (gAgent.getGodLevel() >= GOD_MAINTENANCE)) { return TRUE; @@ -6324,7 +6350,7 @@ BOOL LLViewerObject::permModify() const return TRUE; #else # ifdef TOGGLE_HACKED_GODLIKE_VIEWER - if (LLGridManager::getInstanceFast()->isInSLBeta() + if (LLGridManager::getInstance()->isInSLBeta() && (gAgent.getGodLevel() >= GOD_MAINTENANCE)) { return TRUE; @@ -6348,7 +6374,7 @@ BOOL LLViewerObject::permCopy() const return TRUE; #else # ifdef TOGGLE_HACKED_GODLIKE_VIEWER - if (LLGridManager::getInstanceFast()->isInSLBeta() + if (LLGridManager::getInstance()->isInSLBeta() && (gAgent.getGodLevel() >= GOD_MAINTENANCE)) { return TRUE; @@ -6372,7 +6398,7 @@ BOOL LLViewerObject::permMove() const return TRUE; #else # ifdef TOGGLE_HACKED_GODLIKE_VIEWER - if (LLGridManager::getInstanceFast()->isInSLBeta() + if (LLGridManager::getInstance()->isInSLBeta() && (gAgent.getGodLevel() >= GOD_MAINTENANCE)) { return TRUE; @@ -6396,7 +6422,7 @@ BOOL LLViewerObject::permTransfer() const return TRUE; #else # ifdef TOGGLE_HACKED_GODLIKE_VIEWER - if (LLGridManager::getInstanceFast()->isInSLBeta() + if (LLGridManager::getInstance()->isInSLBeta() && (gAgent.getGodLevel() >= GOD_MAINTENANCE)) { return TRUE; @@ -6998,7 +7024,7 @@ class ObjectPhysicsProperties : public LLHTTPNode } } func(local_id); - LLSelectNode* node = LLSelectMgr::getInstanceFast()->getSelection()->getFirstNode(&func); + LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode(&func); if (node) { diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index cf53732ac537edf7693afa4ea6c8eba8b92b5e4d..e5e946ce62a1d789a80be0315fd5c752f8968323 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -111,8 +111,7 @@ struct PotentialReturnableObject class LLViewerObject : public LLPrimitive, public LLRefCount, - public LLGLUpdate, - public LLTrace::MemTrackable<LLViewerObject> + public LLGLUpdate { protected: virtual ~LLViewerObject(); // use unref() diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index c676949b9882a02fbde6b9dcf2b7438a16a22a68..631cf0fdf23af84f137795643c1244c6fd522df6 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -80,6 +80,7 @@ #include "llfloaterperms.h" #include "llvocache.h" #include "llcorehttputil.h" +#include "llstartup.h" #include <algorithm> #include <iterator> @@ -168,6 +169,8 @@ U64 LLViewerObjectList::getIndex(const U32 local_id, BOOL LLViewerObjectList::removeFromLocalIDTable(const LLViewerObject* objectp) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; + if(objectp && objectp->getRegion()) { U32 local_id = objectp->mLocalID; @@ -287,11 +290,11 @@ void LLViewerObjectList::processUpdateCore(LLViewerObject* objectp, && update_type != OUT_TERSE_IMPROVED && objectp->mCreateSelected) { - if ( LLToolMgr::getInstanceFast()->getCurrentTool() != LLToolPie::getInstanceFast() ) + if ( LLToolMgr::getInstance()->getCurrentTool() != LLToolPie::getInstance() ) { // LL_INFOS() << "DEBUG selecting " << objectp->mID << " " // << objectp->mLocalID << LL_ENDL; - LLSelectMgr::getInstanceFast()->selectObjectAndFamily(objectp); + LLSelectMgr::getInstance()->selectObjectAndFamily(objectp); dialog_refresh_all(); } @@ -305,9 +308,11 @@ static LLTrace::BlockTimerStatHandle FTM_PROCESS_OBJECTS("Process Objects"); LLViewerObject* LLViewerObjectList::processObjectUpdateFromCache(LLVOCacheEntry* entry, LLViewerRegion* regionp) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; + LLDataPacker *cached_dpp = entry->getDP(); - if (!cached_dpp) + if (!cached_dpp || gNonInteractive) { return NULL; //nothing cached. } @@ -316,7 +321,7 @@ LLViewerObject* LLViewerObjectList::processObjectUpdateFromCache(LLVOCacheEntry* U32 local_id; LLPCode pcode = 0; LLUUID fullid; - LLViewerStatsRecorder& recorder = LLViewerStatsRecorder::instanceFast(); + LLViewerStatsRecorder& recorder = LLViewerStatsRecorder::instance(); // Cache Hit. record(LLStatViewer::OBJECT_CACHE_HIT_RATE, LLUnits::Ratio::fromValue(1)); @@ -457,7 +462,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, U64 region_handle; mesgsys->getU64Fast(_PREHASH_RegionData, _PREHASH_RegionHandle, region_handle); - LLViewerRegion *regionp = LLWorld::getInstanceFast()->getRegionFromHandle(region_handle); + LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(region_handle); if (!regionp) { @@ -467,7 +472,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, U8 compressed_dpbuffer[2048]; LLDataPackerBinaryBuffer compressed_dp(compressed_dpbuffer, 2048); - LLViewerStatsRecorder& recorder = LLViewerStatsRecorder::instanceFast(); + LLViewerStatsRecorder& recorder = LLViewerStatsRecorder::instance(); for (i = 0; i < num_objects; i++) { @@ -580,6 +585,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, if(update_cache) { + //update object cache if the object receives a full-update or terse update objectp = regionp->updateCacheEntry(local_id, objectp); } @@ -733,14 +739,14 @@ void LLViewerObjectList::processCachedObjectUpdate(LLMessageSystem *mesgsys, U64 region_handle; mesgsys->getU64Fast(_PREHASH_RegionData, _PREHASH_RegionHandle, region_handle); - LLViewerRegion *regionp = LLWorld::getInstanceFast()->getRegionFromHandle(region_handle); + LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(region_handle); if (!regionp) { LL_WARNS() << "Object update from unknown region! " << region_handle << LL_ENDL; return; } - LLViewerStatsRecorder& recorder = LLViewerStatsRecorder::instanceFast(); + LLViewerStatsRecorder& recorder = LLViewerStatsRecorder::instance(); for (S32 i = 0; i < num_objects; i++) { @@ -830,7 +836,7 @@ void LLViewerObjectList::updateApparentAngles(LLAgent &agent) // Slam priorities for textures that we care about (hovered, selected, and focused) // Hovered // Assumes only one level deep of parenting - auto& select_mgr = LLSelectMgr::instanceFast(); + auto& select_mgr = LLSelectMgr::instance(); LLSelectNode* nodep = select_mgr.getHoverNode(); if (nodep) @@ -889,10 +895,9 @@ void LLViewerObjectList::updateApparentAngles(LLAgent &agent) LLVOAvatar::cullAvatarsByPixelArea(); } -static LLTrace::BlockTimerStatHandle FTM_IDLE_COPY("Idle Copy"); - void LLViewerObjectList::update(LLAgent &agent) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; static LLCachedControl<bool> cc_velocity_interpolate(gSavedSettings, "VelocityInterpolate"); static LLCachedControl<bool> cc_ping_interpolate(gSavedSettings, "PingInterpolate"); static LLCachedControl<F32> cc_interpolation_time(gSavedSettings, "InterpolationTime"); @@ -951,8 +956,6 @@ void LLViewerObjectList::update(LLAgent &agent) U32 idle_count = 0; { - LL_RECORD_BLOCK_TIME(FTM_IDLE_COPY); - for (std::vector<LLPointer<LLViewerObject> >::iterator active_iter = mActiveObjects.begin(); active_iter != mActiveObjects.end(); active_iter++) { @@ -1023,7 +1026,7 @@ void LLViewerObjectList::update(LLAgent &agent) // don't factor frames that were paused into the stats if (! mWasPaused) { - LLViewerStats::getInstanceFast()->updateFrameStats(time_diff); + LLViewerStats::getInstance()->updateFrameStats(time_diff); } /* @@ -1344,6 +1347,8 @@ void LLViewerObjectList::clearDebugText() void LLViewerObjectList::cleanupReferences(LLViewerObject *objectp) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; + bool new_dead_object = true; if (mDeadObjects.find(objectp->mID) != mDeadObjects.end()) { @@ -1396,11 +1401,9 @@ void LLViewerObjectList::cleanupReferences(LLViewerObject *objectp) } } -static LLTrace::BlockTimerStatHandle FTM_REMOVE_DRAWABLE("Remove Drawable"); - void LLViewerObjectList::removeDrawable(LLDrawable* drawablep) { - LL_RECORD_BLOCK_TIME(FTM_REMOVE_DRAWABLE); + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE; if (!drawablep) { @@ -1576,6 +1579,8 @@ void LLViewerObjectList::removeFromActiveList(LLViewerObject* objectp) void LLViewerObjectList::updateActive(LLViewerObject *objectp) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE; + if (objectp->isDead()) { return; // We don't update dead objects! @@ -1687,12 +1692,9 @@ void LLViewerObjectList::onPhysicsFlagsFetchFailure(const LLUUID& object_id) mPendingPhysicsFlags.erase(object_id); } -static LLTrace::BlockTimerStatHandle FTM_SHIFT_OBJECTS("Shift Objects"); -static LLTrace::BlockTimerStatHandle FTM_PIPELINE_SHIFT("Pipeline Shift"); -static LLTrace::BlockTimerStatHandle FTM_REGION_SHIFT("Region Shift"); - void LLViewerObjectList::shiftObjects(const LLVector3 &offset) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; // This is called when we shift our origin when we cross region boundaries... // We need to update many object caches, I'll document this more as I dig through the code // cleaning things out... @@ -1702,7 +1704,6 @@ void LLViewerObjectList::shiftObjects(const LLVector3 &offset) return; } - LL_RECORD_BLOCK_TIME(FTM_SHIFT_OBJECTS); LLViewerObject *objectp; for (vobj_list_t::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter) @@ -1720,15 +1721,9 @@ void LLViewerObjectList::shiftObjects(const LLVector3 &offset) } } - { - LL_RECORD_BLOCK_TIME(FTM_PIPELINE_SHIFT); gPipeline.shiftObjects(offset); - } - - { - LL_RECORD_BLOCK_TIME(FTM_REGION_SHIFT); - LLWorld::getInstanceFast()->shiftRegions(offset); -} + + LLWorld::getInstance()->shiftRegions(offset); } void LLViewerObjectList::repartitionObjects() @@ -1964,6 +1959,8 @@ void LLViewerObjectList::renderObjectBounds(const LLVector3 ¢er) void LLViewerObjectList::generatePickList(LLCamera &camera) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; + LLViewerObject *objectp; S32 i; // Reset all of the GL names to zero. @@ -1976,7 +1973,7 @@ void LLViewerObjectList::generatePickList(LLCamera &camera) std::vector<LLDrawable*> pick_drawables; - for (LLViewerRegion* region : LLWorld::getInstanceFast()->getRegionList()) + for (LLViewerRegion* region : LLWorld::getInstance()->getRegionList()) { for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) { @@ -2166,7 +2163,6 @@ LLViewerObject *LLViewerObjectList::createObjectFromCache(const LLPCode pcode, L LLViewerObject *LLViewerObjectList::createObject(const LLPCode pcode, LLViewerRegion *regionp, const LLUUID &uuid, const U32 local_id, const LLHost &sender) { - LLUUID fullid; if (uuid.isNull()) { @@ -2221,6 +2217,8 @@ LLViewerObject *LLViewerObjectList::replaceObject(const LLUUID &id, const LLPCod S32 LLViewerObjectList::findReferences(LLDrawable *drawablep) const { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE; + LLViewerObject *objectp; S32 num_refs = 0; @@ -2286,6 +2284,8 @@ void LLViewerObjectList::orphanize(LLViewerObject *childp, U32 parent_id, U32 ip void LLViewerObjectList::findOrphans(LLViewerObject* objectp, U32 ip, U32 port) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; + if (objectp->isDead()) { LL_WARNS() << "Trying to find orphans for dead obj " << objectp->mID @@ -2395,12 +2395,12 @@ void LLViewerObjectList::findOrphans(LLViewerObject* objectp, U32 ip, U32 port) if (orphans_found && objectp->isSelected()) { - LLSelectNode* nodep = LLSelectMgr::getInstanceFast()->getSelection()->findNode(objectp); + LLSelectNode* nodep = LLSelectMgr::getInstance()->getSelection()->findNode(objectp); if (nodep && !nodep->mIndividualSelection) { // rebuild selection with orphans - LLSelectMgr::getInstanceFast()->deselectObjectAndFamily(objectp); - LLSelectMgr::getInstanceFast()->selectObjectAndFamily(objectp); + LLSelectMgr::getInstance()->deselectObjectAndFamily(objectp); + LLSelectMgr::getInstance()->selectObjectAndFamily(objectp); } } } diff --git a/indra/newview/llvieweroctree.cpp b/indra/newview/llvieweroctree.cpp index 4721b083da96671b0c976d4e39817fe1e91c067f..638733ded3838956e20cd48e3e449b04506a9a44 100644 --- a/indra/newview/llvieweroctree.cpp +++ b/indra/newview/llvieweroctree.cpp @@ -32,6 +32,7 @@ #include "llappviewer.h" #include "llglslshader.h" #include "llviewershadermgr.h" +#include "lldrawpoolwater.h" //----------------------------------------------------------------------------------- //static variables definitions @@ -231,8 +232,7 @@ S32 AABBSphereIntersectR2(const LLVector4a& min, const LLVector4a& max, const LL //class LLViewerOctreeEntry definitions //----------------------------------------------------------------------------------- LLViewerOctreeEntry::LLViewerOctreeEntry() -: LLTrace::MemTrackable<LLViewerOctreeEntry, 16>("LLViewerOctreeEntry"), - mGroup(NULL), +: mGroup(NULL), mBinRadius(0.f), mBinIndex(-1), mVisible(0) @@ -458,8 +458,7 @@ LLViewerOctreeGroup::~LLViewerOctreeGroup() } LLViewerOctreeGroup::LLViewerOctreeGroup(OctreeNode* node) -: LLTrace::MemTrackable<LLViewerOctreeGroup, 16>("LLViewerOctreeGroup"), - mOctreeNode(node), +: mOctreeNode(node), mAnyVisible(0), mState(CLEAN) { @@ -517,6 +516,7 @@ bool LLViewerOctreeGroup::removeFromGroup(LLViewerOctreeEntry* entry) //virtual void LLViewerOctreeGroup::unbound() { + LL_PROFILE_ZONE_SCOPED; if (isDirty()) { return; @@ -545,6 +545,7 @@ void LLViewerOctreeGroup::unbound() //virtual void LLViewerOctreeGroup::rebound() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_OCTREE; if (!isDirty()) { return; @@ -563,7 +564,7 @@ void LLViewerOctreeGroup::rebound() group->setState(SKIP_FRUSTUM_CHECK); } - else if (mOctreeNode->isLeaf()) + else if (mOctreeNode->getChildCount() == 0) { //copy object bounding box if this is a leaf boundObjects(TRUE, mExtents[0], mExtents[1]); mBounds[0] = mObjectBounds[0]; @@ -787,38 +788,39 @@ void LLViewerOctreeGroup::checkStates() //occulsion culling functions and classes //------------------------------------------------------------------------------------------- std::set<U32> LLOcclusionCullingGroup::sPendingQueries; -class LLOcclusionQueryPool -{ -public: - LLOcclusionQueryPool() = default; - GLuint allocateName() - { - GLuint ret = 0; +static std::queue<GLuint> sFreeQueries; - glGenQueries(1, &ret); - - return ret; - } +#define QUERY_POOL_SIZE 1024 - void releaseName(GLuint name) - { -#if LL_TRACK_PENDING_OCCLUSION_QUERIES - LLOcclusionCullingGroup::sPendingQueries.erase(name); -#endif - glDeleteQueries(1, &name); - } -}; - -static LLOcclusionQueryPool sQueryPool; U32 LLOcclusionCullingGroup::getNewOcclusionQueryObjectName() { - return sQueryPool.allocateName(); + LL_PROFILE_ZONE_SCOPED; + + if (sFreeQueries.empty()) + { + //seed 1024 query names into the free query pool + GLuint queries[1024]; + glGenQueriesARB(1024, queries); + for (int i = 0; i < 1024; ++i) + { + sFreeQueries.push(queries[i]); + } + } + + // pull from pool + GLuint ret = sFreeQueries.front(); + sFreeQueries.pop(); + return ret; } void LLOcclusionCullingGroup::releaseOcclusionQueryObjectName(GLuint name) { - sQueryPool.releaseName(name); + if (name != 0) + { + LL_PROFILE_ZONE_SCOPED; + sFreeQueries.push(name); + } } //===================================== @@ -929,47 +931,55 @@ void LLOcclusionCullingGroup::releaseOcclusionQueryObjectNames() } } -void LLOcclusionCullingGroup::setOcclusionState(U32 state, S32 mode) -{ - if (mode > STATE_MODE_SINGLE) - { - if (mode == STATE_MODE_DIFF) - { - LLSpatialSetOcclusionStateDiff setter(state); - setter.traverse(mOctreeNode); - } - else if (mode == STATE_MODE_BRANCH) - { - LLSpatialSetOcclusionState setter(state); - setter.traverse(mOctreeNode); - } - else - { - for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) - { - mOcclusionState[i] |= state; - - if ((state & DISCARD_QUERY) && mOcclusionQuery[i]) - { - releaseOcclusionQueryObjectName(mOcclusionQuery[i]); - mOcclusionQuery[i] = 0; - } - } - } - } - else - { - if (state & OCCLUDED) - { - add(sNumObjectsOccluded, 1); - } - mOcclusionState[LLViewerCamera::sCurCameraID] |= state; - if ((state & DISCARD_QUERY) && mOcclusionQuery[LLViewerCamera::sCurCameraID]) - { - releaseOcclusionQueryObjectName(mOcclusionQuery[LLViewerCamera::sCurCameraID]); - mOcclusionQuery[LLViewerCamera::sCurCameraID] = 0; - } - } +void LLOcclusionCullingGroup::setOcclusionState(U32 state, S32 mode /* = STATE_MODE_SINGLE */ ) +{ + switch (mode) + { + case STATE_MODE_SINGLE: + if (state & OCCLUDED) + { + add(sNumObjectsOccluded, 1); + } + mOcclusionState[LLViewerCamera::sCurCameraID] |= state; + if ((state & DISCARD_QUERY) && mOcclusionQuery[LLViewerCamera::sCurCameraID]) + { + releaseOcclusionQueryObjectName(mOcclusionQuery[LLViewerCamera::sCurCameraID]); + mOcclusionQuery[LLViewerCamera::sCurCameraID] = 0; + } + break; + + case STATE_MODE_DIFF: + if (mOctreeNode) + { + LLSpatialSetOcclusionStateDiff setter(state); + setter.traverse(mOctreeNode); + } + break; + + case STATE_MODE_BRANCH: + if (mOctreeNode) + { + LLSpatialSetOcclusionState setter(state); + setter.traverse(mOctreeNode); + } + break; + + case STATE_MODE_ALL_CAMERAS: + for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) + { + mOcclusionState[i] |= state; + + if ((state & DISCARD_QUERY) && mOcclusionQuery[i]) + { + releaseOcclusionQueryObjectName(mOcclusionQuery[i]); + mOcclusionQuery[i] = 0; + } + } + break; + + default: + break; + } } class LLSpatialClearOcclusionState : public OctreeTraveler @@ -1004,43 +1014,49 @@ class LLSpatialClearOcclusionStateDiff : public LLSpatialClearOcclusionState } }; -void LLOcclusionCullingGroup::clearOcclusionState(U32 state, S32 mode) -{ - if (mode > STATE_MODE_SINGLE) - { - if (mode == STATE_MODE_DIFF) - { - LLSpatialClearOcclusionStateDiff clearer(state); - clearer.traverse(mOctreeNode); - } - else if (mode == STATE_MODE_BRANCH) - { - LLSpatialClearOcclusionState clearer(state); - clearer.traverse(mOctreeNode); - } - else - { - for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) - { - mOcclusionState[i] &= ~state; - } - } - } - else - { - if (state & OCCLUDED) - { - add(sNumObjectsUnoccluded, 1); - } - mOcclusionState[LLViewerCamera::sCurCameraID] &= ~state; - } +void LLOcclusionCullingGroup::clearOcclusionState(U32 state, S32 mode /* = STATE_MODE_SINGLE */) +{ + switch (mode) + { + case STATE_MODE_SINGLE: + if (state & OCCLUDED) + { + add(sNumObjectsUnoccluded, 1); + } + mOcclusionState[LLViewerCamera::sCurCameraID] &= ~state; + break; + + case STATE_MODE_DIFF: + if (mOctreeNode) + { + LLSpatialClearOcclusionStateDiff clearer(state); + clearer.traverse(mOctreeNode); + } + break; + + case STATE_MODE_BRANCH: + if (mOctreeNode) + { + LLSpatialClearOcclusionState clearer(state); + clearer.traverse(mOctreeNode); + } + break; + + case STATE_MODE_ALL_CAMERAS: + for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) + { + mOcclusionState[i] &= ~state; + } + break; + + default: + break; + } } -static LLTrace::BlockTimerStatHandle FTM_OCCLUSION_READBACK("Readback Occlusion"); -static LLTrace::BlockTimerStatHandle FTM_OCCLUSION_WAIT("Occlusion Wait"); - BOOL LLOcclusionCullingGroup::earlyFail(LLCamera* camera, const LLVector4a* bounds) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_OCTREE; if (camera->getOrigin().isExactlyZero()) { return FALSE; @@ -1089,101 +1105,82 @@ U32 LLOcclusionCullingGroup::getLastOcclusionIssuedTime() void LLOcclusionCullingGroup::checkOcclusion() { - if (LLPipeline::sUseOcclusion > 1) - { - LL_RECORD_BLOCK_TIME(FTM_OCCLUSION_READBACK); - LLOcclusionCullingGroup* parent = (LLOcclusionCullingGroup*)getParent(); - if (parent && parent->isOcclusionState(LLOcclusionCullingGroup::OCCLUDED)) - { //if the parent has been marked as occluded, the child is implicitly occluded - clearOcclusionState(QUERY_PENDING | DISCARD_QUERY); - } - else if (isOcclusionState(QUERY_PENDING)) - { //otherwise, if a query is pending, read it back - - GLuint available = 0; - if (mOcclusionQuery[LLViewerCamera::sCurCameraID]) - { - glGetQueryObjectuiv(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE, &available); - - static LLCachedControl<bool> wait_for_query(gSavedSettings, "RenderSynchronousOcclusion", true); - - U32 target_read_frame = !gGLManager.mIsIntel ? ((gFrameCount > 2) ? (gFrameCount - 2) : 0) : gFrameCount; - if (wait_for_query && mOcclusionIssued[LLViewerCamera::sCurCameraID] < target_read_frame) - { //query was issued last frame, wait until it's available - S32 max_loop = !gGLManager.mIsIntel ? 64 : 1024; - LL_RECORD_BLOCK_TIME(FTM_OCCLUSION_WAIT); - while (!available && max_loop-- > 0) - { - glGetQueryObjectuiv(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE, &available); - } - } - } - else - { - available = 1; - } - - if (available) - { //result is available, read it back, otherwise wait until next frame - GLuint res = 1; - if (!isOcclusionState(DISCARD_QUERY) && mOcclusionQuery[LLViewerCamera::sCurCameraID]) - { - glGetQueryObjectuiv(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT, &res); + if (LLPipeline::sUseOcclusion < 2) return; // 0 - NoOcclusion, 1 = ReadOnly, 2 = ModifyOcclusionState TODO: DJH 11-2021 ENUM this + + LL_PROFILE_ZONE_SCOPED_CATEGORY_OCTREE; + LLOcclusionCullingGroup* parent = (LLOcclusionCullingGroup*)getParent(); + if (parent && parent->isOcclusionState(LLOcclusionCullingGroup::OCCLUDED)) + { //if the parent has been marked as occluded, the child is implicitly occluded + clearOcclusionState(QUERY_PENDING | DISCARD_QUERY); + return; + } + + if (mOcclusionQuery[LLViewerCamera::sCurCameraID] && isOcclusionState(QUERY_PENDING)) + { + if (isOcclusionState(DISCARD_QUERY)) + { // delete the query to avoid holding onto hundreds of pending queries + releaseOcclusionQueryObjectName(mOcclusionQuery[LLViewerCamera::sCurCameraID]); + mOcclusionQuery[LLViewerCamera::sCurCameraID] = 0; + // mark non-occluded + clearOcclusionState(LLOcclusionCullingGroup::OCCLUDED, LLOcclusionCullingGroup::STATE_MODE_DIFF); + clearOcclusionState(QUERY_PENDING | DISCARD_QUERY); + } + else + { + GLuint available; + { + LL_PROFILE_ZONE_NAMED_CATEGORY_OCTREE("co - query available"); + glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE_ARB, &available); + } + + if (available) + { + GLuint query_result; // Will be # samples drawn, or a boolean depending on mHasOcclusionQuery2 (both are type GLuint) + { + LL_PROFILE_ZONE_NAMED_CATEGORY_OCTREE("co - query result"); + glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_ARB, &query_result); + } #if LL_TRACK_PENDING_OCCLUSION_QUERIES - sPendingQueries.erase(mOcclusionQuery[LLViewerCamera::sCurCameraID]); + sPendingQueries.erase(mOcclusionQuery[LLViewerCamera::sCurCameraID]); #endif - } - else if (mOcclusionQuery[LLViewerCamera::sCurCameraID]) - { //delete the query to avoid holding onto hundreds of pending queries - releaseOcclusionQueryObjectName(mOcclusionQuery[LLViewerCamera::sCurCameraID]); - mOcclusionQuery[LLViewerCamera::sCurCameraID] = 0; - } - - if (isOcclusionState(DISCARD_QUERY)) - { - res = 2; - } - if (res > 0) - { - assert_states_valid(this); - clearOcclusionState(LLOcclusionCullingGroup::OCCLUDED, LLOcclusionCullingGroup::STATE_MODE_DIFF); - assert_states_valid(this); - } - else - { - assert_states_valid(this); - - setOcclusionState(LLOcclusionCullingGroup::OCCLUDED, LLOcclusionCullingGroup::STATE_MODE_DIFF); - - assert_states_valid(this); - } - - clearOcclusionState(QUERY_PENDING | DISCARD_QUERY); - } - } - else if (mSpatialPartition->isOcclusionEnabled() && isOcclusionState(LLOcclusionCullingGroup::OCCLUDED)) - { //check occlusion has been issued for occluded node that has not had a query issued - assert_states_valid(this); - clearOcclusionState(LLOcclusionCullingGroup::OCCLUDED, LLOcclusionCullingGroup::STATE_MODE_DIFF); - assert_states_valid(this); - } - } +#if 0 // (12/2021) occasional false-negative occlusion tests produce water reflection errors, SL-16461 + // If/when water occlusion queries become 100% reliable, re-enable this optimization + + if (LLPipeline::RENDER_TYPE_WATER == mSpatialPartition->mDrawableType) + { + // Note any unoccluded water, for deciding on reflection/distortion passes + // (If occlusion is disabled, these are set within LLDrawPoolWater::render) + if (query_result > 0) + { + LLDrawPoolWater::sNeedsReflectionUpdate = TRUE; + LLDrawPoolWater::sNeedsDistortionUpdate = TRUE; + } + } +#endif + if (query_result > 0) + { + clearOcclusionState(LLOcclusionCullingGroup::OCCLUDED, LLOcclusionCullingGroup::STATE_MODE_DIFF); + } + else + { + setOcclusionState(LLOcclusionCullingGroup::OCCLUDED, LLOcclusionCullingGroup::STATE_MODE_DIFF); + } + clearOcclusionState(QUERY_PENDING); + } + } + } + else if (mSpatialPartition->isOcclusionEnabled() && isOcclusionState(LLOcclusionCullingGroup::OCCLUDED)) + { //check occlusion has been issued for occluded node that has not had a query issued + assert_states_valid(this); + clearOcclusionState(LLOcclusionCullingGroup::OCCLUDED, LLOcclusionCullingGroup::STATE_MODE_DIFF); + assert_states_valid(this); + } } -static LLTrace::BlockTimerStatHandle FTM_PUSH_OCCLUSION_VERTS("Push Occlusion"); -static LLTrace::BlockTimerStatHandle FTM_SET_OCCLUSION_STATE("Occlusion State"); -static LLTrace::BlockTimerStatHandle FTM_OCCLUSION_EARLY_FAIL("Occlusion Early Fail"); -static LLTrace::BlockTimerStatHandle FTM_OCCLUSION_ALLOCATE("Allocate"); -static LLTrace::BlockTimerStatHandle FTM_OCCLUSION_BUILD("Build"); -static LLTrace::BlockTimerStatHandle FTM_OCCLUSION_BEGIN_QUERY("Begin Query"); -static LLTrace::BlockTimerStatHandle FTM_OCCLUSION_END_QUERY("End Query"); -static LLTrace::BlockTimerStatHandle FTM_OCCLUSION_SET_BUFFER("Set Buffer"); -static LLTrace::BlockTimerStatHandle FTM_OCCLUSION_DRAW_WATER("Draw Water"); -static LLTrace::BlockTimerStatHandle FTM_OCCLUSION_DRAW("Draw"); - void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* shift) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_OCTREE; if (mSpatialPartition->isOcclusionEnabled() && LLPipeline::sUseOcclusion > 1) { //move mBounds to the agent space if necessary @@ -1196,7 +1193,7 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh } F32 OCCLUSION_FUDGE_Z = SG_OCCLUSION_FUDGE; //<-- #Solution #2 - if (LLDrawPool::POOL_WATER == mSpatialPartition->mDrawableType) + if (LLPipeline::RENDER_TYPE_VOIDWATER == mSpatialPartition->mDrawableType) { OCCLUSION_FUDGE_Z = 1.; } @@ -1204,7 +1201,7 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh // Don't cull hole/edge water, unless we have the GL_ARB_depth_clamp extension if (earlyFail(camera, bounds)) { - LL_RECORD_BLOCK_TIME(FTM_OCCLUSION_EARLY_FAIL); + LL_PROFILE_ZONE_NAMED_CATEGORY_OCTREE("doOcclusion - early fail"); setOcclusionState(LLOcclusionCullingGroup::DISCARD_QUERY); assert_states_valid(this); clearOcclusionState(LLOcclusionCullingGroup::OCCLUDED, LLOcclusionCullingGroup::STATE_MODE_DIFF); @@ -1215,11 +1212,10 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh if (!isOcclusionState(QUERY_PENDING) || isOcclusionState(DISCARD_QUERY)) { { //no query pending, or previous query to be discarded - LL_RECORD_BLOCK_TIME(FTM_RENDER_OCCLUSION); + LL_PROFILE_ZONE_NAMED_CATEGORY_OCTREE("doOcclusion - render"); if (!mOcclusionQuery[LLViewerCamera::sCurCameraID]) { - LL_RECORD_BLOCK_TIME(FTM_OCCLUSION_ALLOCATE); mOcclusionQuery[LLViewerCamera::sCurCameraID] = getNewOcclusionQueryObjectName(); } @@ -1227,8 +1223,8 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh // behind the far clip plane, and in the case of edge water to avoid // it being culled while still visible. bool const use_depth_clamp = gGLManager.mHasDepthClamp && - (mSpatialPartition->mDrawableType == LLDrawPool::POOL_WATER || - mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER); + (mSpatialPartition->mDrawableType == LLPipeline::RENDER_TYPE_WATER || + mSpatialPartition->mDrawableType == LLPipeline::RENDER_TYPE_VOIDWATER); LLGLEnable clamp(use_depth_clamp ? GL_DEPTH_CLAMP : 0); @@ -1244,15 +1240,19 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh add(sOcclusionQueries, 1); { - LL_RECORD_BLOCK_TIME(FTM_PUSH_OCCLUSION_VERTS); + LL_PROFILE_ZONE_NAMED_CATEGORY_OCTREE("doOcclusion - push"); //store which frame this query was issued on mOcclusionIssued[LLViewerCamera::sCurCameraID] = gFrameCount; - { - LL_RECORD_BLOCK_TIME(FTM_OCCLUSION_BEGIN_QUERY); - glBeginQuery(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]); - } + { + LL_PROFILE_ZONE_NAMED("glBeginQuery"); + + //get an occlusion query that hasn't been used in awhile + releaseOcclusionQueryObjectName(mOcclusionQuery[LLViewerCamera::sCurCameraID]); + mOcclusionQuery[LLViewerCamera::sCurCameraID] = getNewOcclusionQueryObjectName(); + glBeginQuery(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]); + } LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; llassert(shader); @@ -1262,9 +1262,9 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh bounds[1][1]+SG_OCCLUSION_FUDGE, bounds[1][2]+OCCLUSION_FUDGE_Z); - if (!use_depth_clamp && mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER) + if (!use_depth_clamp && mSpatialPartition->mDrawableType == LLPipeline::RENDER_TYPE_VOIDWATER) { - LL_RECORD_BLOCK_TIME(FTM_OCCLUSION_DRAW_WATER); + LL_PROFILE_ZONE_NAMED_CATEGORY_OCTREE("doOcclusion - draw water"); LLGLSquashToFarClip squash; if (camera->getOrigin().isExactlyZero()) @@ -1279,7 +1279,7 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh } else { - LL_RECORD_BLOCK_TIME(FTM_OCCLUSION_DRAW); + LL_PROFILE_ZONE_NAMED_CATEGORY_OCTREE("doOcclusion - draw"); if (camera->getOrigin().isExactlyZero()) { //origin is invalid, draw entire box gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0); @@ -1290,17 +1290,16 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, bounds[0])); } } - - - { - LL_RECORD_BLOCK_TIME(FTM_OCCLUSION_END_QUERY); + + { + LL_PROFILE_ZONE_NAMED("glEndQuery"); glEndQuery(mode); - } + } } } { - LL_RECORD_BLOCK_TIME(FTM_SET_OCCLUSION_STATE); + LL_PROFILE_ZONE_NAMED_CATEGORY_OCTREE("doOcclusion - set state"); setOcclusionState(LLOcclusionCullingGroup::QUERY_PENDING); clearOcclusionState(LLOcclusionCullingGroup::DISCARD_QUERY); } @@ -1331,8 +1330,13 @@ LLViewerOctreePartition::LLViewerOctreePartition() : LLViewerOctreePartition::~LLViewerOctreePartition() { - delete mOctree; - mOctree = NULL; + cleanup(); +} + +void LLViewerOctreePartition::cleanup() +{ + delete mOctree; + mOctree = nullptr; } BOOL LLViewerOctreePartition::isOcclusionEnabled() @@ -1340,6 +1344,7 @@ BOOL LLViewerOctreePartition::isOcclusionEnabled() return mOcclusionEnabled || LLPipeline::sUseOcclusion > 2; } + //----------------------------------------------------------------------------------- //class LLViewerOctreeCull definitions //----------------------------------------------------------------------------------- diff --git a/indra/newview/llvieweroctree.h b/indra/newview/llvieweroctree.h index 219ec7e8da7c47d2d46f6a512267ca2e6fd96bb0..7666062f990944701ad64be09627cd7f2a28e7ed 100644 --- a/indra/newview/llvieweroctree.h +++ b/indra/newview/llvieweroctree.h @@ -45,11 +45,11 @@ class LLViewerOctreeGroup; class LLViewerOctreeEntry; class LLViewerOctreePartition; -typedef LLOctreeListener<LLViewerOctreeEntry> OctreeListener; -typedef LLTreeNode<LLViewerOctreeEntry> TreeNode; -typedef LLOctreeNode<LLViewerOctreeEntry> OctreeNode; -typedef LLOctreeRoot<LLViewerOctreeEntry> OctreeRoot; -typedef LLOctreeTraveler<LLViewerOctreeEntry> OctreeTraveler; +typedef LLOctreeListener<LLViewerOctreeEntry, LLPointer<LLViewerOctreeEntry>> OctreeListener; +typedef LLTreeNode<LLViewerOctreeEntry> TreeNode; +typedef LLOctreeNode<LLViewerOctreeEntry, LLPointer<LLViewerOctreeEntry>> OctreeNode; +typedef LLOctreeRoot<LLViewerOctreeEntry, LLPointer<LLViewerOctreeEntry>> OctreeRoot; +typedef LLOctreeTraveler<LLViewerOctreeEntry, LLPointer<LLViewerOctreeEntry>> OctreeTraveler; #if LL_OCTREE_PARANOIA_CHECK #define assert_octree_valid(x) x->validate() @@ -71,8 +71,9 @@ S32 AABBSphereIntersectR2(const LLVector3& min, const LLVector3& max, const LLVe //defines data needed for octree of an entry //LL_ALIGN_PREFIX(16) -class LLViewerOctreeEntry : public LLRefCount, public LLTrace::MemTrackable<LLViewerOctreeEntry, 16> +class LLViewerOctreeEntry : public LLRefCount { + LL_ALIGN_NEW friend class LLViewerOctreeEntryData; public: @@ -178,8 +179,9 @@ class LLViewerOctreeEntryData : public LLRefCount //defines an octree group for an octree node, which contains multiple entries. //LL_ALIGN_PREFIX(16) class LLViewerOctreeGroup -: public LLOctreeListener<LLViewerOctreeEntry>, public LLTrace::MemTrackable<LLViewerOctreeGroup, 16> +: public OctreeListener { + LL_ALIGN_NEW friend class LLViewerOctreeCull; protected: virtual ~LLViewerOctreeGroup(); @@ -196,12 +198,11 @@ class LLViewerOctreeGroup }; public: - typedef LLOctreeNode<LLViewerOctreeEntry>::element_iter element_iter; - typedef LLOctreeNode<LLViewerOctreeEntry>::element_list element_list; + typedef OctreeNode::element_iter element_iter; + typedef OctreeNode::element_list element_list; LLViewerOctreeGroup(OctreeNode* node); LLViewerOctreeGroup(const LLViewerOctreeGroup& rhs) - : LLTrace::MemTrackable<LLViewerOctreeGroup, 16>("LLViewerOctreeGroup") { *this = rhs; } @@ -244,7 +245,6 @@ class LLViewerOctreeGroup const LLVector4a* getObjectExtents() const {return mObjectExtents;} //octree wrappers to make code more readable - element_list& getData() { return mOctreeNode->getData(); } element_iter getDataBegin() { return mOctreeNode->getDataBegin(); } element_iter getDataEnd() { return mOctreeNode->getDataEnd(); } U32 getElementCount() const { return mOctreeNode->getElementCount(); } @@ -351,6 +351,10 @@ class LLViewerOctreePartition virtual S32 cull(LLCamera &camera, bool do_occlusion) = 0; BOOL isOcclusionEnabled(); +protected: + // MUST call from destructor of any derived classes (SL-17276) + void cleanup(); + public: U32 mPartitionType; U32 mDrawableType; diff --git a/indra/newview/llviewerparcelmedia.cpp b/indra/newview/llviewerparcelmedia.cpp index 56ce405aa6972077a9c2b7802707fb9843948504..a0f62634049b7b0058a85bd4f26b8236a7031ffb 100644 --- a/indra/newview/llviewerparcelmedia.cpp +++ b/indra/newview/llviewerparcelmedia.cpp @@ -193,7 +193,7 @@ void LLViewerParcelMedia::play(LLParcel* parcel) LL_DEBUGS("Media") << "new media impl with mime type " << mime_type << ", url " << media_url << LL_ENDL; // There is no media impl, make a new one - mMediaImpl = LLViewerMedia::getInstanceFast()->newMediaImpl( + mMediaImpl = LLViewerMedia::getInstance()->newMediaImpl( placeholder_texture_id, media_width, media_height, @@ -290,13 +290,13 @@ std::string LLViewerParcelMedia::getURL() if(mMediaImpl.notNull()) url = mMediaImpl->getMediaURL(); - if(stricmp(LLViewerParcelMgr::getInstanceFast()->getAgentParcel()->getMediaType().c_str(), LLMIMETypes::getDefaultMimeType().c_str()) != 0) + if(stricmp(LLViewerParcelMgr::getInstance()->getAgentParcel()->getMediaType().c_str(), LLMIMETypes::getDefaultMimeType().c_str()) != 0) { if (url.empty()) - url = LLViewerParcelMgr::getInstanceFast()->getAgentParcel()->getMediaCurrentURL(); + url = LLViewerParcelMgr::getInstance()->getAgentParcel()->getMediaCurrentURL(); if (url.empty()) - url = LLViewerParcelMgr::getInstanceFast()->getAgentParcel()->getMediaURL(); + url = LLViewerParcelMgr::getInstance()->getAgentParcel()->getMediaURL(); } return url; @@ -363,7 +363,7 @@ void LLViewerParcelMedia::processParcelMediaCommandMessage( LLMessageSystem *msg } else { - LLParcel *parcel = LLViewerParcelMgr::getInstanceFast()->getAgentParcel(); + LLParcel *parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); play(parcel); } } @@ -379,7 +379,7 @@ void LLViewerParcelMedia::processParcelMediaCommandMessage( LLMessageSystem *msg { if(mMediaImpl.isNull()) { - LLParcel *parcel = LLViewerParcelMgr::getInstanceFast()->getAgentParcel(); + LLParcel *parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); play(parcel); } seek(time); @@ -419,7 +419,7 @@ void LLViewerParcelMedia::processParcelMediaUpdate( LLMessageSystem *msg) msg->getS32("DataBlockExtended", "MediaHeight", media_height); } - LLParcel *parcel = LLViewerParcelMgr::getInstanceFast()->getAgentParcel(); + LLParcel *parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); BOOL same = FALSE; if (parcel) { @@ -457,7 +457,7 @@ void LLViewerParcelMedia::sendMediaNavigateMessage(const std::string& url) // send navigate event to sim for link sharing LLSD body; body["agent-id"] = gAgent.getID(); - body["local-id"] = LLViewerParcelMgr::getInstanceFast()->getAgentParcel()->getLocalID(); + body["local-id"] = LLViewerParcelMgr::getInstance()->getAgentParcel()->getLocalID(); body["url"] = url; LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(region_url, body, diff --git a/indra/newview/llviewerparcelmediaautoplay.cpp b/indra/newview/llviewerparcelmediaautoplay.cpp index 2bb9e48bc1cbba9c504ed9b9edef3465c1180975..db8fcb4dc48a3866acec54a594f6e541a51d8eeb 100644 --- a/indra/newview/llviewerparcelmediaautoplay.cpp +++ b/indra/newview/llviewerparcelmediaautoplay.cpp @@ -77,7 +77,7 @@ BOOL LLViewerParcelMediaAutoPlay::tick() this_region_id = this_region->getRegionID(); } - this_parcel = LLViewerParcelMgr::getInstanceFast()->getAgentParcel(); + this_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); if (this_parcel) { @@ -164,7 +164,7 @@ void LLViewerParcelMediaAutoPlay::onStartMediaResponse(const LLUUID ®ion_id, { if (play) { - LLParcel *parcel = LLViewerParcelMgr::getInstanceFast()->getAgentParcel(); + LLParcel *parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); // make sure we are still there if (parcel->getLocalID() == parcel_id && gAgent.getRegion()->getRegionID() == region_id) diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index 585adacc7db67ea02c6555ff6f4007794a98ca7a..a545463d98c6bb51e1b21a2de9fd69970c5f1202 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -244,7 +244,7 @@ void LLViewerParcelMgr::dump() LLViewerRegion* LLViewerParcelMgr::getSelectionRegion() { - return LLWorld::getInstanceFast()->getRegionFromPosGlobal( mWestSouth ); + return LLWorld::getInstance()->getRegionFromPosGlobal( mWestSouth ); } @@ -531,8 +531,8 @@ LLParcelSelectionHandle LLViewerParcelMgr::selectLand(const LLVector3d &corner1, east_north_region_check.mdV[VX] -= 0.5; east_north_region_check.mdV[VY] -= 0.5; - LLViewerRegion *region = LLWorld::getInstanceFast()->getRegionFromPosGlobal(mWestSouth); - LLViewerRegion *region_other = LLWorld::getInstanceFast()->getRegionFromPosGlobal( east_north_region_check ); + LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosGlobal(mWestSouth); + LLViewerRegion *region_other = LLWorld::getInstance()->getRegionFromPosGlobal( east_north_region_check ); if(!region) { @@ -760,7 +760,7 @@ bool LLViewerParcelMgr::allowAgentDamage(const LLViewerRegion* region, const LLP BOOL LLViewerParcelMgr::isOwnedAt(const LLVector3d& pos_global) const { - LLViewerRegion* region = LLWorld::getInstanceFast()->getRegionFromPosGlobal( pos_global ); + LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal( pos_global ); if (!region) return FALSE; LLViewerParcelOverlay* overlay = region->getParcelOverlay(); @@ -773,7 +773,7 @@ BOOL LLViewerParcelMgr::isOwnedAt(const LLVector3d& pos_global) const BOOL LLViewerParcelMgr::isOwnedSelfAt(const LLVector3d& pos_global) const { - LLViewerRegion* region = LLWorld::getInstanceFast()->getRegionFromPosGlobal( pos_global ); + LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal( pos_global ); if (!region) return FALSE; LLViewerParcelOverlay* overlay = region->getParcelOverlay(); @@ -786,7 +786,7 @@ BOOL LLViewerParcelMgr::isOwnedSelfAt(const LLVector3d& pos_global) const BOOL LLViewerParcelMgr::isOwnedOtherAt(const LLVector3d& pos_global) const { - LLViewerRegion* region = LLWorld::getInstanceFast()->getRegionFromPosGlobal( pos_global ); + LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal( pos_global ); if (!region) return FALSE; LLViewerParcelOverlay* overlay = region->getParcelOverlay(); @@ -799,7 +799,7 @@ BOOL LLViewerParcelMgr::isOwnedOtherAt(const LLVector3d& pos_global) const BOOL LLViewerParcelMgr::isSoundLocal(const LLVector3d& pos_global) const { - LLViewerRegion* region = LLWorld::getInstanceFast()->getRegionFromPosGlobal( pos_global ); + LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal( pos_global ); if (!region) return FALSE; LLViewerParcelOverlay* overlay = region->getParcelOverlay(); @@ -842,7 +842,7 @@ BOOL LLViewerParcelMgr::canHearSound(const LLVector3d &pos_global) const BOOL LLViewerParcelMgr::inAgentParcel(const LLVector3d &pos_global) const { - LLViewerRegion* region = LLWorld::getInstanceFast()->getRegionFromPosGlobal(pos_global); + LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal(pos_global); LLViewerRegion* agent_region = gAgent.getRegion(); if (!region || !agent_region) return FALSE; @@ -900,11 +900,11 @@ LLParcel* LLViewerParcelMgr::getCollisionParcel() const void LLViewerParcelMgr::render() { static const LLCachedControl<bool> render_parcel_selection(gSavedSettings, "RenderParcelSelection"); - if (mSelected && mRenderSelection && render_parcel_selection) + if (mSelected && mRenderSelection && render_parcel_selection && !gDisconnected) { // Rendering is done in agent-coordinates, so need to supply // an appropriate offset to the render code. - LLViewerRegion* regionp = LLWorld::getInstanceFast()->getRegionFromPosGlobal(mWestSouth); + LLViewerRegion* regionp = LLWorld::getInstance()->getRegionFromPosGlobal(mWestSouth); if (!regionp) return; renderHighlightSegments(mHighlightSegments, regionp); @@ -940,7 +940,7 @@ void LLViewerParcelMgr::sendParcelAccessListRequest(U32 flags) return; } - LLViewerRegion *region = LLWorld::getInstanceFast()->getRegionFromPosGlobal( mWestSouth ); + LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosGlobal( mWestSouth ); if (!region) return; LLMessageSystem *msg = gMessageSystem; @@ -983,7 +983,7 @@ void LLViewerParcelMgr::sendParcelDwellRequest() return; } - LLViewerRegion *region = LLWorld::getInstanceFast()->getRegionFromPosGlobal( mWestSouth ); + LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosGlobal( mWestSouth ); if (!region) return; LLMessageSystem *msg = gMessageSystem; @@ -1015,7 +1015,7 @@ void LLViewerParcelMgr::sendParcelGodForceOwner(const LLUUID& owner_id) east_north_region_check.mdV[VX] -= 0.5; east_north_region_check.mdV[VY] -= 0.5; - LLViewerRegion *region = LLWorld::getInstanceFast()->getRegionFromPosGlobal( mWestSouth ); + LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosGlobal( mWestSouth ); if (!region) { // TODO: Add a force owner version of this alert. @@ -1024,7 +1024,7 @@ void LLViewerParcelMgr::sendParcelGodForceOwner(const LLUUID& owner_id) } // BUG: Make work for cross-region selections - LLViewerRegion *region2 = LLWorld::getInstanceFast()->getRegionFromPosGlobal( east_north_region_check ); + LLViewerRegion *region2 = LLWorld::getInstance()->getRegionFromPosGlobal( east_north_region_check ); if (region != region2) { LLNotificationsUtil::add("CannotSetLandOwnerMultipleRegions"); @@ -1075,7 +1075,7 @@ void LLViewerParcelMgr::sendParcelGodForceToContent() LLNotificationsUtil::add("CannotContentifyNothingSelected"); return; } - LLViewerRegion* region = LLWorld::getInstanceFast()->getRegionFromPosGlobal( mWestSouth ); + LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal( mWestSouth ); if (!region) { LLNotificationsUtil::add("CannotContentifyNoRegion"); @@ -1100,7 +1100,7 @@ void LLViewerParcelMgr::sendParcelRelease() return; } - LLViewerRegion *region = LLWorld::getInstanceFast()->getRegionFromPosGlobal( mWestSouth ); + LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosGlobal( mWestSouth ); if (!region) { LLNotificationsUtil::add("CannotReleaseLandNoRegion"); @@ -1162,7 +1162,7 @@ LLViewerParcelMgr::ParcelBuyInfo* LLViewerParcelMgr::setupParcelBuy( return NULL; } - LLViewerRegion *region = LLWorld::getInstanceFast()->getRegionFromPosGlobal( mWestSouth ); + LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosGlobal( mWestSouth ); if (!region) { LLNotificationsUtil::add("CannotBuyLandNoRegion"); @@ -1179,7 +1179,7 @@ LLViewerParcelMgr::ParcelBuyInfo* LLViewerParcelMgr::setupParcelBuy( east_north_region_check.mdV[VX] -= 0.5; east_north_region_check.mdV[VY] -= 0.5; - LLViewerRegion *region2 = LLWorld::getInstanceFast()->getRegionFromPosGlobal( east_north_region_check ); + LLViewerRegion *region2 = LLWorld::getInstance()->getRegionFromPosGlobal( east_north_region_check ); if (region != region2) { @@ -1273,7 +1273,7 @@ void LLViewerParcelMgr::sendParcelDeed(const LLUUID& group_id) LLNotificationsUtil::add("CannotDeedLandNoGroup"); return; } - LLViewerRegion *region = LLWorld::getInstanceFast()->getRegionFromPosGlobal( mWestSouth ); + LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosGlobal( mWestSouth ); if (!region) { LLNotificationsUtil::add("CannotDeedLandNoRegion"); @@ -1348,7 +1348,7 @@ void LLViewerParcelMgr::sendParcelPropertiesUpdate(LLParcel* parcel, bool use_ag if(!parcel) return; - LLViewerRegion *region = use_agent_region ? gAgent.getRegion() : LLWorld::getInstanceFast()->getRegionFromPosGlobal( mWestSouth ); + LLViewerRegion *region = use_agent_region ? gAgent.getRegion() : LLWorld::getInstance()->getRegionFromPosGlobal( mWestSouth ); if (!region) return; @@ -1402,7 +1402,7 @@ void LLViewerParcelMgr::setHoverParcel(const LLVector3d& pos) return; } - LLViewerRegion* region = LLWorld::getInstanceFast()->getRegionFromPosGlobal( pos ); + LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal( pos ); if (!region) { return; @@ -1529,7 +1529,7 @@ void LLViewerParcelMgr::processParcelOverlay(LLMessageSystem *msg, void **user) expected_size); LLHost host = msg->getSender(); - LLViewerRegion *region = LLWorld::getInstanceFast()->getRegion(host); + LLViewerRegion *region = LLWorld::getInstance()->getRegion(host); if (region) { region->mParcelOverlay->uncompressLandOverlay( sequence_id, sPackedOverlay ); @@ -1575,11 +1575,12 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use BOOL region_allow_environment_override = true; S32 parcel_environment_version = 0; BOOL agent_parcel_update = false; // updating previous(existing) agent parcel + U32 extended_flags = 0; //obscure MOAP S32 other_clean_time = 0; - LLViewerParcelMgr& parcel_mgr = LLViewerParcelMgr::instanceFast(); - LLViewerRegion* msg_region = LLWorld::getInstanceFast()->getRegion(msg->getSender()); + LLViewerParcelMgr& parcel_mgr = LLViewerParcelMgr::instance(); + LLViewerRegion* msg_region = LLWorld::getInstance()->getRegion(msg->getSender()); if(msg_region) parcel_mgr.mParcelsPerEdge = S32(msg_region->getWidth() / PARCEL_GRID_STEP_METERS); else @@ -1622,6 +1623,8 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use else if (sequence_id == 0 || sequence_id > parcel_mgr.mAgentParcelSequenceID) { // new agent parcel + // *TODO: Does it really make sense to set the agent parcel to this + // parcel if the client doesn't know what kind of parcel data this is? parcel_mgr.mAgentParcelSequenceID = sequence_id; parcel = parcel_mgr.mAgentParcel; } @@ -1673,6 +1676,11 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use msg->getBOOLFast(_PREHASH_RegionAllowAccessBlock, _PREHASH_RegionAllowAccessOverride, region_allow_access_override); } + if (msg->getNumberOfBlocksFast(_PREHASH_ParcelExtendedFlags)) + { + msg->getU32Fast(_PREHASH_ParcelExtendedFlags, _PREHASH_Flags, extended_flags); + } + if (msg->getNumberOfBlocksFast(_PREHASH_ParcelEnvironmentBlock)) { msg->getS32Fast(_PREHASH_ParcelEnvironmentBlock, _PREHASH_ParcelEnvironmentVersion, parcel_environment_version); @@ -1689,7 +1697,7 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use if (local_id == parcel_mgr.mAgentParcel->getLocalID()) { // Parcels in different regions can have same ids. - LLViewerRegion* parcel_region = LLWorld::getInstanceFast()->getRegion(msg->getSender()); + LLViewerRegion* parcel_region = LLWorld::getInstance()->getRegion(msg->getSender()); LLViewerRegion* agent_region = gAgent.getRegion(); if (parcel_region && agent_region && parcel_region->getRegionID() == agent_region->getRegionID()) { @@ -1729,6 +1737,8 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use parcel->setParcelEnvironmentVersion(cur_parcel_environment_version); parcel->setRegionAllowEnvironmentOverride(region_allow_environment_override); + parcel->setObscureMOAP((bool)extended_flags); + parcel->unpackMessage(msg); if (parcel == parcel_mgr.mAgentParcel) @@ -1789,7 +1799,7 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use (request_result == PARCEL_RESULT_MULTIPLE); // Select the whole parcel - LLViewerRegion* region = LLWorld::getInstanceFast()->getRegion( msg->getSender() ); + LLViewerRegion* region = LLWorld::getInstance()->getRegion( msg->getSender() ); if (region) { if (!snap_selection) @@ -1884,7 +1894,7 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use parcel_mgr.resetSegments(parcel_mgr.mCollisionSegments); parcel_mgr.writeSegmentsFromBitmap(parcel_mgr.mCollisionBitmap, parcel_mgr.mCollisionSegments); - LLViewerRegion* pRegion = LLWorld::getInstanceFast()->getRegion(msg->getSender()); + LLViewerRegion* pRegion = LLWorld::getInstance()->getRegion(msg->getSender()); parcel_mgr.mCollisionRegionHandle = (pRegion) ? pRegion->getHandle() : 0; if (parcel_mgr.mCollisionUpdateSignal) @@ -1892,7 +1902,7 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use } else if (sequence_id == HOVERED_PARCEL_SEQ_ID) { - LLViewerRegion *region = LLWorld::getInstanceFast()->getRegion( msg->getSender() ); + LLViewerRegion *region = LLWorld::getInstance()->getRegion( msg->getSender() ); if (region) { parcel_mgr.mHoverWestSouth = region->getPosGlobalFromRegion( aabb_min ); @@ -1906,8 +1916,13 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use } else { - // Check for video - LLViewerParcelMedia::getInstance()->update(parcel); + if (gNonInteractive) + { + return; + } + + // Check for video + LLViewerParcelMedia::getInstance()->update(parcel); // Then check for music if (gAudiop) @@ -1931,7 +1946,7 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use if (music_url.substr(0, 7) == "http://" || music_url.substr(0, 8) == "https://") { - LLViewerRegion *region = LLWorld::getInstanceFast()->getRegion(msg->getSender()); + LLViewerRegion *region = LLWorld::getInstance()->getRegion(msg->getSender()); if (region) { optionallyStartMusic(music_url, parcel->mLocalID, region->getRegionID(), !agent_parcel_update); @@ -2050,7 +2065,7 @@ void LLViewerParcelMgr::processParcelAccessListReply(LLMessageSystem *msg, void msg->getU32Fast( _PREHASH_Data, _PREHASH_Flags, message_flags); msg->getS32Fast( _PREHASH_Data, _PREHASH_LocalID, parcel_id); - LLParcel* parcel = LLViewerParcelMgr::getInstanceFast()->mCurrentParcel; + LLParcel* parcel = LLViewerParcelMgr::getInstance()->mCurrentParcel; if (!parcel) return; if (parcel_id != parcel->getLocalID()) @@ -2081,7 +2096,7 @@ void LLViewerParcelMgr::processParcelAccessListReply(LLMessageSystem *msg, void parcel->unpackAccessEntries(msg, &(parcel->mRenterList) ); }*/ - LLViewerParcelMgr::getInstanceFast()->notifyObservers(); + LLViewerParcelMgr::getInstance()->notifyObservers(); } @@ -2100,7 +2115,7 @@ void LLViewerParcelMgr::processParcelDwellReply(LLMessageSystem* msg, void**) F32 dwell; msg->getF32Fast(_PREHASH_Data, _PREHASH_Dwell, dwell); - auto& parcel_mgr = LLViewerParcelMgr::instanceFast(); + auto& parcel_mgr = LLViewerParcelMgr::instance(); if (local_id == parcel_mgr.mCurrentParcel->getLocalID()) { parcel_mgr.mSelectedDwell = dwell; @@ -2116,7 +2131,7 @@ void LLViewerParcelMgr::sendParcelAccessListUpdate(U32 which) return; } - LLViewerRegion* region = LLWorld::getInstanceFast()->getRegionFromPosGlobal( mWestSouth ); + LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal( mWestSouth ); if (!region) return; LLParcel* parcel = mCurrentParcel; @@ -2229,13 +2244,13 @@ bool LLViewerParcelMgr::deedAlertCB(const LLSD& notification, const LLSD& respon S32 option = LLNotificationsUtil::getSelectedOption(notification, response); if (option == 0) { - LLParcel* parcel = LLViewerParcelMgr::getInstanceFast()->getParcelSelection()->getParcel(); + LLParcel* parcel = LLViewerParcelMgr::getInstance()->getParcelSelection()->getParcel(); LLUUID group_id; if(parcel) { group_id = parcel->getGroupID(); } - LLViewerParcelMgr::getInstanceFast()->sendParcelDeed(group_id); + LLViewerParcelMgr::getInstance()->sendParcelDeed(group_id); } return false; } @@ -2269,7 +2284,7 @@ void LLViewerParcelMgr::startReleaseLand() } LLVector3d parcel_center = (mWestSouth + mEastNorth) / 2.0; - LLViewerRegion* region = LLWorld::getInstanceFast()->getRegionFromPosGlobal(parcel_center); + LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal(parcel_center); if (!region) { LLNotificationsUtil::add("CannotReleaseLandRegionNotFound"); @@ -2322,7 +2337,7 @@ bool LLViewerParcelMgr::canAgentBuyParcel(LLParcel* parcel, bool forGroup) const } LLVector3 parcel_coord = parcel->getCenterpoint(); - LLViewerRegion* regionp = LLWorld::getInstanceFast()->getRegionFromPosAgent(parcel_coord); + LLViewerRegion* regionp = LLWorld::getInstance()->getRegionFromPosAgent(parcel_coord); if (regionp) { U8 sim_access = regionp->getSimAccess(); @@ -2399,7 +2414,7 @@ bool LLViewerParcelMgr::callbackDivideLand(const LLSD& notification, const LLSD& LLVector3d east_north_d = ll_vector3d_from_sd(notification["payload"]["east_north_border"]); LLVector3d parcel_center = (west_south_d + east_north_d) / 2.0; - LLViewerRegion* region = LLWorld::getInstanceFast()->getRegionFromPosGlobal(parcel_center); + LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal(parcel_center); if (!region) { LLNotificationsUtil::add("CannotDivideLandNoRegion"); @@ -2462,7 +2477,7 @@ bool LLViewerParcelMgr::callbackJoinLand(const LLSD& notification, const LLSD& r LLVector3d east_north_d = ll_vector3d_from_sd(notification["payload"]["east_north_border"]); LLVector3d parcel_center = (west_south_d + east_north_d) / 2.0; - LLViewerRegion* region = LLWorld::getInstanceFast()->getRegionFromPosGlobal(parcel_center); + LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal(parcel_center); if (!region) { LLNotificationsUtil::add("CannotJoinLandNoRegion"); @@ -2511,7 +2526,7 @@ void LLViewerParcelMgr::startDeedLandToGroup() } LLVector3d parcel_center = (mWestSouth + mEastNorth) / 2.0; - LLViewerRegion* region = LLWorld::getInstanceFast()->getRegionFromPosGlobal(parcel_center); + LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal(parcel_center); if (!region) { LLNotificationsUtil::add("CannotDeedLandNoRegion"); @@ -2536,8 +2551,8 @@ void LLViewerParcelMgr::startDeedLandToGroup() } void LLViewerParcelMgr::reclaimParcel() { - LLParcel* parcel = LLViewerParcelMgr::getInstanceFast()->getParcelSelection()->getParcel(); - LLViewerRegion* regionp = LLViewerParcelMgr::getInstanceFast()->getSelectionRegion(); + LLParcel* parcel = LLViewerParcelMgr::getInstance()->getParcelSelection()->getParcel(); + LLViewerRegion* regionp = LLViewerParcelMgr::getInstance()->getSelectionRegion(); if(parcel && parcel->getOwnerID().notNull() && (parcel->getOwnerID() != gAgent.getID()) && regionp && (regionp->getOwner() == gAgent.getID())) @@ -2560,7 +2575,7 @@ bool LLViewerParcelMgr::releaseAlertCB(const LLSD& notification, const LLSD& res if (option == 0) { // Send the release message, not a force - LLViewerParcelMgr::getInstanceFast()->sendParcelRelease(); + LLViewerParcelMgr::getInstance()->sendParcelRelease(); } return false; } diff --git a/indra/newview/llviewerparceloverlay.cpp b/indra/newview/llviewerparceloverlay.cpp index 14fbcacbf61ec5626f83ca568dfe56956ce8973e..0ce295031e7925309c06aa0854d7f5f15237cfbb 100644 --- a/indra/newview/llviewerparceloverlay.cpp +++ b/indra/newview/llviewerparceloverlay.cpp @@ -274,7 +274,7 @@ BOOL LLViewerParcelOverlay::isSoundLocal(const LLVector3& pos) const { S32 row = S32(pos.mV[VY] / PARCEL_GRID_STEP_METERS); S32 column = S32(pos.mV[VX] / PARCEL_GRID_STEP_METERS); - return PARCEL_SOUND_LOCAL & mOwnership[row * mParcelGridsPerEdge + column]; + return parcelFlags(row, column, PARCEL_SOUND_LOCAL); } U8 LLViewerParcelOverlay::ownership( const LLVector3& pos) const @@ -288,12 +288,19 @@ U8 LLViewerParcelOverlay::parcelLineFlags(const LLVector3& pos) const { S32 row = S32(pos.mV[VY] / PARCEL_GRID_STEP_METERS); S32 column = S32(pos.mV[VX] / PARCEL_GRID_STEP_METERS); - return parcelLineFlags(row, column); + return parcelFlags(row, column, PARCEL_WEST_LINE | PARCEL_SOUTH_LINE); } U8 LLViewerParcelOverlay::parcelLineFlags(S32 row, S32 col) const { - U8 flags = PARCEL_WEST_LINE | PARCEL_SOUTH_LINE; - if (row > mParcelGridsPerEdge || col > mParcelGridsPerEdge) + return parcelFlags(row, col, PARCEL_WEST_LINE | PARCEL_SOUTH_LINE); +} + +U8 LLViewerParcelOverlay::parcelFlags(S32 row, S32 col, U8 flags) const +{ + if (row >= mParcelGridsPerEdge + || col >= mParcelGridsPerEdge + || row < 0 + || col < 0) { LL_WARNS() << "Attempted to get ownership out of region's overlay, row: " << row << " col: " << col << LL_ENDL; return flags; @@ -867,6 +874,7 @@ void LLViewerParcelOverlay::setDirty() void LLViewerParcelOverlay::updateGL() { + LL_PROFILE_ZONE_SCOPED updateOverlayTexture(); } @@ -916,13 +924,13 @@ S32 LLViewerParcelOverlay::renderPropertyLines () // Find camera height off the ground (not from zero) F32 ground_height_at_camera = land.resolveHeightGlobal( gAgentCamera.getCameraPositionGlobal() ); - F32 camera_z = LLViewerCamera::getInstanceFast()->getOrigin().mV[VZ]; + F32 camera_z = LLViewerCamera::getInstance()->getOrigin().mV[VZ]; F32 camera_height = camera_z - ground_height_at_camera; camera_height = llclamp(camera_height, 0.f, 100.f); // Pull lines toward camera by 1 cm per meter off the ground. - const LLVector3& CAMERA_AT = LLViewerCamera::getInstanceFast()->getAtAxis(); + const LLVector3& CAMERA_AT = LLViewerCamera::getInstance()->getAtAxis(); F32 pull_toward_camera_scale = 0.01f * camera_height; LLVector3 pull_toward_camera = CAMERA_AT; pull_toward_camera *= -pull_toward_camera_scale; @@ -930,8 +938,8 @@ S32 LLViewerParcelOverlay::renderPropertyLines () // Always fudge a little vertically. pull_toward_camera.mV[VZ] += 0.01f; - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.pushMatrix(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.pushMatrix(); // Move to appropriate region coords LLVector3 origin = mRegion->getOriginAgent(); @@ -950,7 +958,7 @@ S32 LLViewerParcelOverlay::renderPropertyLines () // Set up a cull plane 2 * PARCEL_GRID_STEP_METERS behind // the camera. The cull plane normal is the camera's at axis. - LLVector3 cull_plane_point = LLViewerCamera::getInstanceFast()->getAtAxis(); + LLVector3 cull_plane_point = LLViewerCamera::getInstance()->getAtAxis(); cull_plane_point *= -2.f * PARCEL_GRID_STEP_METERS; cull_plane_point += camera_region; @@ -1036,11 +1044,70 @@ S32 LLViewerParcelOverlay::renderPropertyLines () } - gGL.popMatrix(); + gGL.popMatrix(); return drawn; } +// Draw half of a single cell (no fill) in a grid drawn from left to right and from bottom to top +void grid_2d_part_lines(const F32 left, const F32 top, const F32 right, const F32 bottom, bool has_left, bool has_bottom) +{ + gGL.begin(LLRender::LINES); + + if (has_left) + { + gGL.vertex2f(left, bottom); + gGL.vertex2f(left, top); + } + if (has_bottom) + { + gGL.vertex2f(left, bottom); + gGL.vertex2f(right, bottom); + } + + gGL.end(); +} + +void LLViewerParcelOverlay::renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32 *parcel_outline_color) +{ + if (!mOwnership) + { + return; + } + if (!gSavedSettings.getBOOL("MiniMapShowPropertyLines")) + { + return; + } + + LLVector3 origin_agent = mRegion->getOriginAgent(); + LLVector3 rel_region_pos = origin_agent - gAgentCamera.getCameraPositionAgent(); + F32 region_left = rel_region_pos.mV[0] * scale_pixels_per_meter; + F32 region_bottom = rel_region_pos.mV[1] * scale_pixels_per_meter; + F32 map_parcel_width = PARCEL_GRID_STEP_METERS * scale_pixels_per_meter; + const S32 GRIDS_PER_EDGE = mParcelGridsPerEdge; + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + glLineWidth(1.0f); + gGL.color4fv(parcel_outline_color); + for (S32 i = 0; i < GRIDS_PER_EDGE + 1; i++) + { + const F32 bottom = region_bottom + (i * map_parcel_width); + const F32 top = bottom + map_parcel_width; + for (S32 j = 0; j < GRIDS_PER_EDGE + 1; j++) + { + const F32 left = region_left + (j * map_parcel_width); + const F32 right = left + map_parcel_width; + const bool is_region_boundary = i == GRIDS_PER_EDGE || j == GRIDS_PER_EDGE; + const U8 overlay = is_region_boundary ? 0 : mOwnership[(i * GRIDS_PER_EDGE) + j]; + // The property line vertices are three-dimensional, but here we only care about the x and y coordinates, as we are drawing on a + // 2D map + const bool has_left = i != GRIDS_PER_EDGE && (j == GRIDS_PER_EDGE || (overlay & PARCEL_WEST_LINE)); + const bool has_bottom = j != GRIDS_PER_EDGE && (i == GRIDS_PER_EDGE || (overlay & PARCEL_SOUTH_LINE)); + grid_2d_part_lines(left, top, right, bottom, has_left, has_bottom); + } + } +} + boost::signals2::connection LLViewerParcelOverlay::setUpdateCallback(const update_signal_t::slot_type& cb) { if (!mUpdateSignal) diff --git a/indra/newview/llviewerparceloverlay.h b/indra/newview/llviewerparceloverlay.h index 922548744bf0df2b6be88ab43b0bf5b480a16665..f1797db3b4c376b48b4a40eea35f39ab79189b90 100644 --- a/indra/newview/llviewerparceloverlay.h +++ b/indra/newview/llviewerparceloverlay.h @@ -70,6 +70,7 @@ class LLViewerParcelOverlay final : public LLGLUpdate // Returns the number of vertices drawn S32 renderPropertyLines(); + void renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32* parcel_outline_color); U8 ownership( const LLVector3& pos) const; U8 parcelLineFlags( const LLVector3& pos) const; @@ -86,12 +87,14 @@ class LLViewerParcelOverlay final : public LLGLUpdate typedef boost::signals2::signal<void (const LLViewerRegion*)> update_signal_t; static boost::signals2::connection setUpdateCallback(const update_signal_t::slot_type & cb); - + private: // This is in parcel rows and columns, not grid rows and columns // Stored in bottom three bits. U8 ownership(S32 row, S32 col) const - { return 0x7 & mOwnership[row * mParcelGridsPerEdge + col]; } + { return parcelFlags(row, col, (U8)0x7); } + + U8 parcelFlags(S32 row, S32 col, U8 flags) const; void addPropertyLine(std::vector<LLVector3>& vertex_array, std::vector<LLColor4U>& color_array, diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp index 8c8bd2517b99ad12ef088e04d1087d9a47e73347..c3ade861b34f29d1c6f2ab14f396379d3bcf292c 100644 --- a/indra/newview/llviewerpartsim.cpp +++ b/indra/newview/llviewerpartsim.cpp @@ -139,7 +139,7 @@ LLViewerPartGroup::LLViewerPartGroup(const LLVector3 ¢er_agent, const F32 bo mVOPartGroupp = NULL; mUniformParticles = TRUE; - mRegionp = LLWorld::getInstanceFast()->getRegionFromPosAgent(center_agent); + mRegionp = LLWorld::getInstance()->getRegionFromPosAgent(center_agent); llassert_always(center_agent.isFinite()); if (!mRegionp) @@ -281,7 +281,7 @@ void LLViewerPartGroup::updateParticles(const F32 lastdt) LLViewerPartSim::checkParticleCount(mParticles.size()); - LLViewerCamera* camera = LLViewerCamera::getInstanceFast(); + LLViewerCamera* camera = LLViewerCamera::getInstance(); LLViewerRegion *regionp = getRegion(); S32 end = (S32) mParticles.size(); for (S32 i = 0 ; i < (S32)mParticles.size();) @@ -408,7 +408,7 @@ void LLViewerPartGroup::updateParticles(const F32 lastdt) if (!posInGroup(part->mPosAgent, desired_size)) { // Transfer particles between groups - LLViewerPartSim::getInstanceFast()->put(part) ; + LLViewerPartSim::getInstance()->put(part) ; vector_replace_with_last(mParticles, mParticles.begin() + i); } else @@ -580,7 +580,7 @@ LLViewerPartGroup *LLViewerPartSim::put(LLViewerPart* part) } else { - LLViewerCamera* camera = LLViewerCamera::getInstanceFast(); + LLViewerCamera* camera = LLViewerCamera::getInstance(); F32 desired_size = calc_desired_size(camera, part->mPosAgent, part->mScale); S32 count = (S32) mViewerPartGroups.size(); diff --git a/indra/newview/llviewerpartsource.cpp b/indra/newview/llviewerpartsource.cpp index f8100a0741ee0df227417c0fbed8475027d15bc8..3eaca1969f8a332799032cdfa086cff81d7f0177 100644 --- a/indra/newview/llviewerpartsource.cpp +++ b/indra/newview/llviewerpartsource.cpp @@ -215,7 +215,7 @@ void LLViewerPartSourceScript::update(const F32 dt) first_run = TRUE; } - LLViewerCamera& vwrCamera = LLViewerCamera::instanceFast(); + LLViewerCamera& vwrCamera = LLViewerCamera::instance(); F32 max_time = llmax(1.f, 10.f*mPartSysData.mBurstRate); dt_update = llmin(max_time, dt_update); diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp old mode 100644 new mode 100755 index f593809c5c209bc5a6a8e943e32e3f47e6c932b0..32dfff141af9bda7123ef1fdf4854a167406223d --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -101,8 +101,6 @@ // The server only keeps our pending agent info for 60 seconds. // We want to allow for seed cap retry, but its not useful after that 60 seconds. -// Give it 3 chances, each at 18 seconds to give ourselves a few seconds to connect anyways if we give up. -const S32 MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN = 3; // Even though we gave up on login, keep trying for caps after we are logged in: const S32 MAX_CAP_REQUEST_ATTEMPTS = 30; const U32 DEFAULT_MAX_REGION_WIDE_PRIM_COUNT = 15000; @@ -184,7 +182,6 @@ class LLViewerRegionImpl mCompositionp(NULL), mEventPoll(NULL), mSeedCapMaxAttempts(MAX_CAP_REQUEST_ATTEMPTS), - mSeedCapMaxAttemptsBeforeLogin(MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN), mSeedCapAttempts(0), mHttpResponderID(0), mLastCameraUpdate(0), @@ -237,7 +234,6 @@ class LLViewerRegionImpl LLEventPoll* mEventPoll; S32 mSeedCapMaxAttempts; - S32 mSeedCapMaxAttemptsBeforeLogin; S32 mSeedCapAttempts; S32 mHttpResponderID; @@ -272,7 +268,13 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle) return; } - regionp = LLWorld::getInstanceFast()->getRegionFromHandle(regionHandle); + if (!LLWorld::instanceExists()) + { + LL_WARNS("AppInit", "Capabilities") << "Attempting to get capabilities, but world no longer exists!" << LL_ENDL; + return; + } + + regionp = LLWorld::getInstance()->getRegionFromHandle(regionHandle); if (!regionp) //region was removed { LL_WARNS("AppInit", "Capabilities") << "Attempting to get capabilities for region that no longer exists!" << LL_ENDL; @@ -286,19 +288,13 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle) if (url.empty()) { LL_WARNS("AppInit", "Capabilities") << "Failed to get seed capabilities, and can not determine url!" << LL_ENDL; + regionp->setCapabilitiesError(); return; // this error condition is not recoverable. } // record that we just entered a new region newRegionEntry(*regionp); - // After a few attempts, continue login. But keep trying to get the caps: - if (impl->mSeedCapAttempts >= impl->mSeedCapMaxAttemptsBeforeLogin && - STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState()) - { - LLStartUp::setStartupState(STATE_SEED_CAP_GRANTED); - } - if (impl->mSeedCapAttempts > impl->mSeedCapMaxAttempts) { // *TODO: Give a user pop-up about this error? @@ -330,10 +326,17 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle) if (LLApp::isExiting() || gDisconnected) { + LL_DEBUGS("AppInit", "Capabilities") << "Shutting down" << LL_ENDL; return; } - regionp = LLWorld::getInstanceFast()->getRegionFromHandle(regionHandle); + if (!LLWorld::instanceExists()) + { + LL_WARNS("AppInit", "Capabilities") << "Received capabilities, but world no longer exists!" << LL_ENDL; + return; + } + + regionp = LLWorld::getInstance()->getRegionFromHandle(regionHandle); if (!regionp) //region was removed { LL_WARNS("AppInit", "Capabilities") << "Received capabilities for region that no longer exists!" << LL_ENDL; @@ -342,13 +345,7 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle) impl = regionp->getRegionImplNC(); - if (id != impl->mHttpResponderID) // region is no longer referring to this request - { - LL_WARNS("AppInit", "Capabilities") << "Received results for a stale capabilities request!" << LL_ENDL; - // setup for retry. - ++(impl->mSeedCapAttempts); // <FS:Ansariel> Fix seed cap retry count - continue; - } + ++(impl->mSeedCapAttempts); if (!result.isMap() || result.has("error")) { @@ -371,6 +368,14 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle) // remove the http_result from the llsd result.erase("http_result"); + if (id != impl->mHttpResponderID) // region is no longer referring to this request + { + LL_WARNS("AppInit", "Capabilities") << "Received results for a stale capabilities request!" << LL_ENDL; + // setup for retry. + ++(impl->mSeedCapAttempts); + continue; + } + LLSD::map_const_iterator iter; for (iter = result.beginMap(); iter != result.endMap(); ++iter) { @@ -388,11 +393,6 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle) << " region name " << regionp->getName() << LL_ENDL; regionp->setCapabilitiesReceived(true); - if (STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState()) - { - LLStartUp::setStartupState(STATE_SEED_CAP_GRANTED); - } - break; } while (true); @@ -418,7 +418,14 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCompleteCoro(U64 regionHandle) // This loop is used for retrying a capabilities request. do { - regionp = LLWorld::getInstanceFast()->getRegionFromHandle(regionHandle); + LLWorld *world_inst = LLWorld::getInstance(); // Not a singleton! + if (!world_inst) + { + LL_WARNS("AppInit", "Capabilities") << "Attempting to get capabilities, but world no longer exists!" << LL_ENDL; + return; + } + + regionp = world_inst->getRegionFromHandle(regionHandle); if (!regionp) //region was removed { LL_WARNS("AppInit", "Capabilities") << "Attempting to get capabilities for region that no longer exists!" << LL_ENDL; @@ -429,6 +436,11 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCompleteCoro(U64 regionHandle) if (url.empty()) { LL_WARNS("AppInit", "Capabilities") << "Failed to get seed capabilities, and can not determine url!" << LL_ENDL; + if (regionp->getCapability("Seed").empty()) + { + // initial attempt failed to get this cap as well + regionp->setCapabilitiesError(); + } break; // this error condition is not recoverable. } @@ -441,6 +453,7 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCompleteCoro(U64 regionHandle) LL_INFOS("AppInit", "Capabilities") << "Requesting second Seed from " << url << " for region " << regionp->getRegionID() << LL_ENDL; regionp = NULL; + world_inst = NULL; result = httpAdapter->postAndSuspend(httpRequest, url, capabilityNames); LLSD httpResults = result["http_result"]; @@ -456,7 +469,14 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCompleteCoro(U64 regionHandle) break; } - regionp = LLWorld::getInstanceFast()->getRegionFromHandle(regionHandle); + world_inst = LLWorld::getInstance(); + if (!world_inst) + { + LL_WARNS("AppInit", "Capabilities") << "Received capabilities, but world no longer exists!" << LL_ENDL; + return; + } + + regionp = world_inst->getRegionFromHandle(regionHandle); if (!regionp) //region was removed { LL_WARNS("AppInit", "Capabilities") << "Received capabilities for region that no longer exists!" << LL_ENDL; @@ -539,7 +559,14 @@ void LLViewerRegionImpl::requestSimulatorFeatureCoro(std::string url, U64 region break; } - regionp = LLWorld::getInstanceFast()->getRegionFromHandle(regionHandle); + LLWorld *world_inst = LLWorld::getInstance(); // Not a singleton! + if (!world_inst) + { + LL_WARNS("AppInit", "Capabilities") << "Attempting to request Sim Feature, but world no longer exists!" << LL_ENDL; + return; + } + + regionp = world_inst->getRegionFromHandle(regionHandle); if (!regionp) //region was removed { LL_WARNS("AppInit", "SimulatorFeatures") << "Attempting to request Sim Feature for region that no longer exists!" << LL_ENDL; @@ -547,6 +574,7 @@ void LLViewerRegionImpl::requestSimulatorFeatureCoro(std::string url, U64 region } regionp = NULL; + world_inst = NULL; LLSD result = httpAdapter->getAndSuspend(httpRequest, url); LLSD httpResults = result["http_result"]; @@ -565,7 +593,14 @@ void LLViewerRegionImpl::requestSimulatorFeatureCoro(std::string url, U64 region // remove the http_result from the llsd result.erase("http_result"); - regionp = LLWorld::getInstanceFast()->getRegionFromHandle(regionHandle); + world_inst = LLWorld::getInstance(); + if (!world_inst) + { + LL_WARNS("AppInit", "Capabilities") << "Attempting to request Sim Feature, but world no longer exists!" << LL_ENDL; + return; + } + + regionp = world_inst->getRegionFromHandle(regionHandle); if (!regionp) //region was removed { LL_WARNS("AppInit", "SimulatorFeatures") << "Attempting to set Sim Feature for region that no longer exists!" << LL_ENDL; @@ -615,7 +650,7 @@ LLViewerRegion::LLViewerRegion(const U64 &handle, mCacheLoaded(FALSE), mCacheDirty(FALSE), mReleaseNotesRequested(FALSE), - mCapabilitiesReceived(false), + mCapabilitiesState(CAPABILITIES_STATE_INIT), mSimulatorFeaturesReceived(false), mBitsReceived(0.f), mPacketsReceived(0.f), @@ -780,7 +815,7 @@ void LLViewerRegion::loadObjectCache() if(LLVOCache::instanceExists()) { - LLVOCache::getInstanceFast()->readFromCache(mHandle, mImpl->mCacheID, mImpl->mCacheMap) ; + LLVOCache::getInstance()->readFromCache(mHandle, mImpl->mCacheID, mImpl->mCacheMap) ; if (mImpl->mCacheMap.empty()) { mCacheDirty = TRUE; @@ -806,7 +841,7 @@ void LLViewerRegion::saveObjectCache() const F32 start_time_threshold = 600.0f; //seconds bool removal_enabled = sVOCacheCullingEnabled && (mRegionTimer.getElapsedTimeF32() > start_time_threshold); //allow to remove invalid objects from object cache file. - LLVOCache::getInstanceFast()->writeToCache(mHandle, mImpl->mCacheID, mImpl->mCacheMap, mCacheDirty, removal_enabled) ; + LLVOCache::getInstance()->writeToCache(mHandle, mImpl->mCacheID, mImpl->mCacheMap, mCacheDirty, removal_enabled) ; mCacheDirty = FALSE; } @@ -1076,6 +1111,15 @@ S32 LLViewerRegion::renderPropertyLines() } } +void LLViewerRegion::renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32 *parcel_outline_color) +{ + if (mParcelOverlay) + { + mParcelOverlay->renderPropertyLinesOnMinimap(scale_pixels_per_meter, parcel_outline_color); + } +} + + // This gets called when the height field changes. void LLViewerRegion::dirtyHeights() { @@ -1339,7 +1383,7 @@ void LLViewerRegion::updateVisibleEntries(F32 max_time) } const F32 LARGE_SCENE_CONTRIBUTION = 1000.f; //a large number to force to load the object. - const LLVector3 camera_origin = LLViewerCamera::getInstanceFast()->getOrigin(); + const LLVector3 camera_origin = LLViewerCamera::getInstance()->getOrigin(); const U32 cur_frame = LLViewerOctreeEntryData::getCurrentFrame(); bool needs_update = ((cur_frame - mImpl->mLastCameraUpdate) > 5) && ((camera_origin - mImpl->mLastCameraOrigin).lengthSquared() > 10.f); U32 last_update = mImpl->mLastCameraUpdate; @@ -1656,9 +1700,9 @@ void LLViewerRegion::killInvisibleObjects(F32 max_time) LLTimer update_timer; LLVector4a camera_origin; - camera_origin.load3(LLViewerCamera::getInstanceFast()->getOrigin().mV); + camera_origin.load3(LLViewerCamera::getInstance()->getOrigin().mV); LLVector4a local_origin; - local_origin.load3((LLViewerCamera::getInstanceFast()->getOrigin() - getOriginAgent()).mV); + local_origin.load3((LLViewerCamera::getInstance()->getOrigin() - getOriginAgent()).mV); F32 back_threshold = LLVOCacheEntry::sRearFarRadius; size_t max_update = 64; @@ -1829,8 +1873,8 @@ LLViewerObject* LLViewerRegion::updateCacheEntry(U32 local_id, LLViewerObject* o objectp = addNewObject(entry); } - //remove from cache. - killCacheEntry(entry, true); + //remove from cache. + killCacheEntry(entry, true); return objectp; } @@ -1869,7 +1913,7 @@ F32 LLViewerRegion::getCompositionXY(const S32 x, const S32 y) const if (y >= mWidth) { LLVector3d center = getCenterGlobal() + LLVector3d(mWidth, mWidth, 0.f); - LLViewerRegion *regionp = LLWorld::getInstanceFast()->getRegionFromPosGlobal(center); + LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(center); if (regionp) { // OK, we need to do some hackery here - different simulators no longer use @@ -1896,7 +1940,7 @@ F32 LLViewerRegion::getCompositionXY(const S32 x, const S32 y) const else { LLVector3d center = getCenterGlobal() + LLVector3d(mWidth, 0.f, 0.f); - LLViewerRegion *regionp = LLWorld::getInstanceFast()->getRegionFromPosGlobal(center); + LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(center); if (regionp) { // OK, we need to do some hackery here - different simulators no longer use @@ -1924,7 +1968,7 @@ F32 LLViewerRegion::getCompositionXY(const S32 x, const S32 y) const else if (y >= mWidth) { LLVector3d center = getCenterGlobal() + LLVector3d(0.f, mWidth, 0.f); - LLViewerRegion *regionp = LLWorld::getInstanceFast()->getRegionFromPosGlobal(center); + LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(center); if (regionp) { // OK, we need to do some hackery here - different simulators no longer use @@ -2125,7 +2169,14 @@ class CoarseLocationUpdate final : public LLHTTPNode const LLSD& input) const override { LLHost host(input["sender"].asString()); - LLViewerRegion* region = LLWorld::getInstanceFast()->getRegion(host); + + LLWorld *world_inst = LLWorld::getInstance(); // Not a singleton! + if (!world_inst) + { + return; + } + + LLViewerRegion* region = world_inst->getRegion(host); if( !region ) { return; @@ -2336,6 +2387,11 @@ void LLViewerRegion::requestSimulatorFeatures() std::string coroname = LLCoros::instance().launch("LLViewerRegionImpl::requestSimulatorFeatureCoro", boost::bind(&LLViewerRegionImpl::requestSimulatorFeatureCoro, url, getHandle())); + + // requestSimulatorFeatures can be called from other coros, + // launch() acts like a suspend() + // Make sure we are still good to do + LLCoros::checkStop(); LL_INFOS("AppInit", "SimulatorFeatures") << "Launching " << coroname << " requesting simulator features from " << url << " for region " << getRegionID() << LL_ENDL; } @@ -3172,6 +3228,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) capabilityNames.append("AcceptFriendship"); capabilityNames.append("AcceptGroupInvite"); // ReadOfflineMsgs recieved messages only!!! capabilityNames.append("AgentPreferences"); + capabilityNames.append("AgentProfile"); capabilityNames.append("AgentState"); capabilityNames.append("AttachmentResources"); capabilityNames.append("AvatarPickerSearch"); @@ -3190,7 +3247,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) capabilityNames.append("EventQueueGet"); capabilityNames.append("ExtEnvironment"); - if (LLGridManager::instanceFast().isInSecondlife() || gSavedSettings.getBOOL("UseHTTPInventory")) + if (LLGridManager::instance().isInSecondlife() || gSavedSettings.getBOOL("UseHTTPInventory")) { capabilityNames.append("FetchLib2"); capabilityNames.append("FetchLibDescendents2"); @@ -3216,7 +3273,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) capabilityNames.append("IsExperienceContributor"); capabilityNames.append("RegionExperiences"); capabilityNames.append("ExperienceQuery"); - if(!LLGridManager::instanceFast().isInSecondlife()) + if(!LLGridManager::instance().isInSecondlife()) { capabilityNames.append("GetMesh"); capabilityNames.append("GetMesh2"); @@ -3224,7 +3281,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) capabilityNames.append("GetMetadata"); capabilityNames.append("GetObjectCost"); capabilityNames.append("GetObjectPhysicsData"); - if(!LLGridManager::instanceFast().isInSecondlife()) + if(!LLGridManager::instance().isInSecondlife()) { capabilityNames.append("GetTexture"); } @@ -3278,6 +3335,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) capabilityNames.append("UpdateScriptTask"); capabilityNames.append("UpdateSettingsAgentInventory"); capabilityNames.append("UpdateSettingsTaskInventory"); + capabilityNames.append("UploadAgentProfileImage"); capabilityNames.append("UploadBakedTexture"); capabilityNames.append("UserInfo"); capabilityNames.append("ViewerAsset"); @@ -3303,6 +3361,12 @@ void LLViewerRegion::setSeedCapability(const std::string& url) std::string coroname = LLCoros::instance().launch("LLEnvironmentRequest::requestBaseCapabilitiesCompleteCoro", boost::bind(&LLViewerRegionImpl::requestBaseCapabilitiesCompleteCoro, getHandle())); + + // setSeedCapability can be called from other coros, + // launch() acts like a suspend() + // Make sure we are still good to do + LLCoros::checkStop(); + return; } @@ -3316,6 +3380,11 @@ void LLViewerRegion::setSeedCapability(const std::string& url) LLCoros::instance().launch("LLViewerRegionImpl::requestBaseCapabilitiesCoro", boost::bind(&LLViewerRegionImpl::requestBaseCapabilitiesCoro, getHandle())); + // setSeedCapability can be called from other coros, + // launch() acts like a suspend() + // Make sure we are still good to do + LLCoros::checkStop(); + LL_INFOS("AppInit", "Capabilities") << "Launching " << coroname << " requesting seed capabilities from " << url << " for region " << getRegionID() << LL_ENDL; } @@ -3506,12 +3575,17 @@ std::set<std::string> LLViewerRegion::getAllCaps() bool LLViewerRegion::capabilitiesReceived() const { - return mCapabilitiesReceived; + return mCapabilitiesState == CAPABILITIES_STATE_RECEIVED; +} + +bool LLViewerRegion::capabilitiesError() const +{ + return mCapabilitiesState == CAPABILITIES_STATE_ERROR; } void LLViewerRegion::setCapabilitiesReceived(bool received) { - mCapabilitiesReceived = received; + mCapabilitiesState = received ? CAPABILITIES_STATE_RECEIVED : CAPABILITIES_STATE_INIT; // Tell interested parties that we've received capabilities, // so that they can safely use getCapability(). @@ -3526,6 +3600,11 @@ void LLViewerRegion::setCapabilitiesReceived(bool received) } } +void LLViewerRegion::setCapabilitiesError() +{ + mCapabilitiesState = CAPABILITIES_STATE_ERROR; +} + boost::signals2::connection LLViewerRegion::setCapabilitiesReceivedCallback(const caps_received_signal_t::slot_type& cb) { return mCapabilitiesReceivedSignal.connect(cb); @@ -3802,7 +3881,7 @@ std::string LLViewerRegion::getHGGrid() const } else { - authority = LLGridManager::getInstanceFast()->getGatekeeper(LLGridManager::getInstanceFast()->getGrid()); + authority = LLGridManager::getInstance()->getGatekeeper(LLGridManager::getInstance()->getGrid()); } return authority; } @@ -3820,7 +3899,7 @@ std::string LLViewerRegion::getHGGridName() const } else { - name = LLGridManager::getInstanceFast()->getGridLabel(); + name = LLGridManager::getInstance()->getGridLabel(); } return name; } @@ -3834,7 +3913,7 @@ std::string LLViewerRegion::getHGGridNick() const } else { - name = LLGridManager::getInstanceFast()->getGridId(); + name = LLGridManager::getInstance()->getGridId(); } return name; } diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index 18bdc4ed6a3787374c27163f52a031912c7c70de..7d6ee3e7c324a4af0559ba7b1c6f34260d033fab 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -158,6 +158,8 @@ class LLViewerRegion final : public LLCapabilityProvider // implements this inte // Draw lines in the dirt showing ownership. Return number of // vertices drawn. S32 renderPropertyLines(); + void renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32* parcel_outline_color); + // Call this whenever you change the height data in the region. // (Automatically called by LLSurfacePatch's update routine) @@ -279,7 +281,9 @@ class LLViewerRegion final : public LLCapabilityProvider // implements this inte // has region received its final (not seed) capability list? bool capabilitiesReceived() const; + bool capabilitiesError() const; void setCapabilitiesReceived(bool received); + void setCapabilitiesError(); boost::signals2::connection setCapabilitiesReceivedCallback(const caps_received_signal_t::slot_type& cb); static bool isSpecialCapabilityName(std::string_view name); @@ -590,12 +594,20 @@ class LLViewerRegion final : public LLCapabilityProvider // implements this inte BOOL mCacheLoaded; BOOL mCacheDirty; BOOL mAlive; // can become false if circuit disconnects - BOOL mCapabilitiesReceived; BOOL mSimulatorFeaturesReceived; BOOL mReleaseNotesRequested; BOOL mDead; //if true, this region is in the process of deleting. BOOL mPaused; //pause processing the objects in the region + typedef enum + { + CAPABILITIES_STATE_INIT = 0, + CAPABILITIES_STATE_ERROR, + CAPABILITIES_STATE_RECEIVED + } eCababilitiesState; + + eCababilitiesState mCapabilitiesState; + typedef std::map<U32, std::vector<U32> > orphan_list_t; orphan_list_t mOrphanMap; diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 01514de9e307375f4c8c29790b06326d491d9bb1..2dcd6d05529a80ee5d8f54bbdab42b9922074152 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -68,6 +68,7 @@ LLVector4 gShinyOrigin; //utility shaders LLGLSLShader gOcclusionProgram; +LLGLSLShader gSkinnedOcclusionProgram; LLGLSLShader gOcclusionCubeProgram; LLGLSLShader gCustomAlphaProgram; LLGLSLShader gGlowCombineProgram; @@ -78,6 +79,7 @@ LLGLSLShader gTwoTextureCompareProgram; LLGLSLShader gOneTextureFilterProgram; LLGLSLShader gOneTextureNoColorProgram; LLGLSLShader gDebugProgram; +LLGLSLShader gSkinnedDebugProgram; LLGLSLShader gClipProgram; LLGLSLShader gDownsampleDepthProgram; LLGLSLShader gDownsampleDepthRectProgram; @@ -87,56 +89,50 @@ LLGLSLShader gBenchmarkProgram; //object shaders LLGLSLShader gObjectSimpleProgram; +LLGLSLShader gSkinnedObjectSimpleProgram; LLGLSLShader gObjectSimpleImpostorProgram; +LLGLSLShader gSkinnedObjectSimpleImpostorProgram; LLGLSLShader gObjectPreviewProgram; +LLGLSLShader gPhysicsPreviewProgram; LLGLSLShader gObjectSimpleWaterProgram; +LLGLSLShader gSkinnedObjectSimpleWaterProgram; LLGLSLShader gObjectSimpleAlphaMaskProgram; +LLGLSLShader gSkinnedObjectSimpleAlphaMaskProgram; LLGLSLShader gObjectSimpleWaterAlphaMaskProgram; +LLGLSLShader gSkinnedObjectSimpleWaterAlphaMaskProgram; LLGLSLShader gObjectFullbrightProgram; +LLGLSLShader gSkinnedObjectFullbrightProgram; LLGLSLShader gObjectFullbrightWaterProgram; +LLGLSLShader gSkinnedObjectFullbrightWaterProgram; LLGLSLShader gObjectEmissiveProgram; +LLGLSLShader gSkinnedObjectEmissiveProgram; LLGLSLShader gObjectEmissiveWaterProgram; +LLGLSLShader gSkinnedObjectEmissiveWaterProgram; LLGLSLShader gObjectFullbrightAlphaMaskProgram; +LLGLSLShader gSkinnedObjectFullbrightAlphaMaskProgram; LLGLSLShader gObjectFullbrightWaterAlphaMaskProgram; +LLGLSLShader gSkinnedObjectFullbrightWaterAlphaMaskProgram; LLGLSLShader gObjectFullbrightShinyProgram; +LLGLSLShader gSkinnedObjectFullbrightShinyProgram; LLGLSLShader gObjectFullbrightShinyWaterProgram; +LLGLSLShader gSkinnedObjectFullbrightShinyWaterProgram; LLGLSLShader gObjectShinyProgram; +LLGLSLShader gSkinnedObjectShinyProgram; LLGLSLShader gObjectShinyWaterProgram; +LLGLSLShader gSkinnedObjectShinyWaterProgram; LLGLSLShader gObjectBumpProgram; +LLGLSLShader gSkinnedObjectBumpProgram; LLGLSLShader gTreeProgram; LLGLSLShader gTreeWaterProgram; LLGLSLShader gObjectFullbrightNoColorProgram; LLGLSLShader gObjectFullbrightNoColorWaterProgram; -LLGLSLShader gObjectSimpleNonIndexedProgram; LLGLSLShader gObjectSimpleNonIndexedTexGenProgram; LLGLSLShader gObjectSimpleNonIndexedTexGenWaterProgram; -LLGLSLShader gObjectSimpleNonIndexedWaterProgram; LLGLSLShader gObjectAlphaMaskNonIndexedProgram; LLGLSLShader gObjectAlphaMaskNonIndexedWaterProgram; LLGLSLShader gObjectAlphaMaskNoColorProgram; LLGLSLShader gObjectAlphaMaskNoColorWaterProgram; -LLGLSLShader gObjectFullbrightNonIndexedProgram; -LLGLSLShader gObjectFullbrightNonIndexedWaterProgram; -LLGLSLShader gObjectEmissiveNonIndexedProgram; -LLGLSLShader gObjectEmissiveNonIndexedWaterProgram; -LLGLSLShader gObjectFullbrightShinyNonIndexedProgram; -LLGLSLShader gObjectFullbrightShinyNonIndexedWaterProgram; -LLGLSLShader gObjectShinyNonIndexedProgram; -LLGLSLShader gObjectShinyNonIndexedWaterProgram; - -//object hardware skinning shaders -LLGLSLShader gSkinnedObjectSimpleProgram; -LLGLSLShader gSkinnedObjectFullbrightProgram; -LLGLSLShader gSkinnedObjectEmissiveProgram; -LLGLSLShader gSkinnedObjectFullbrightShinyProgram; -LLGLSLShader gSkinnedObjectShinySimpleProgram; - -LLGLSLShader gSkinnedObjectSimpleWaterProgram; -LLGLSLShader gSkinnedObjectFullbrightWaterProgram; -LLGLSLShader gSkinnedObjectEmissiveWaterProgram; -LLGLSLShader gSkinnedObjectFullbrightShinyWaterProgram; -LLGLSLShader gSkinnedObjectShinySimpleWaterProgram; //environment shaders LLGLSLShader gTerrainProgram; @@ -147,6 +143,7 @@ LLGLSLShader gUnderWaterProgram; //interface shaders LLGLSLShader gHighlightProgram; +LLGLSLShader gSkinnedHighlightProgram; LLGLSLShader gHighlightNormalProgram; LLGLSLShader gHighlightSpecularProgram; @@ -186,21 +183,20 @@ LLGLSLShader gDeferredWaterProgram; LLGLSLShader gDeferredUnderWaterProgram; LLGLSLShader gDeferredDiffuseProgram; LLGLSLShader gDeferredDiffuseAlphaMaskProgram; +LLGLSLShader gDeferredSkinnedDiffuseAlphaMaskProgram; LLGLSLShader gDeferredNonIndexedDiffuseProgram; LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskProgram; LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram; LLGLSLShader gDeferredSkinnedDiffuseProgram; LLGLSLShader gDeferredSkinnedBumpProgram; -LLGLSLShader gDeferredSkinnedAlphaProgram; -LLGLSLShader gDeferredSkinnedAlphaWaterProgram; LLGLSLShader gDeferredBumpProgram; LLGLSLShader gDeferredTerrainProgram; LLGLSLShader gDeferredTerrainWaterProgram; LLGLSLShader gDeferredTreeProgram; LLGLSLShader gDeferredTreeShadowProgram; +LLGLSLShader gDeferredSkinnedTreeShadowProgram; LLGLSLShader gDeferredAvatarProgram; LLGLSLShader gDeferredAvatarAlphaProgram; -LLGLSLShader gDeferredAvatarAlphaWaterProgram; LLGLSLShader gDeferredLightProgram; LLGLSLShader gDeferredMultiLightProgram[16]; LLGLSLShader gDeferredSpotLightProgram; @@ -210,9 +206,12 @@ LLGLSLShader gDeferredBlurLightProgram; LLGLSLShader gDeferredSoftenProgram; LLGLSLShader gDeferredSoftenWaterProgram; LLGLSLShader gDeferredShadowProgram; +LLGLSLShader gDeferredSkinnedShadowProgram; LLGLSLShader gDeferredShadowCubeProgram; LLGLSLShader gDeferredShadowAlphaMaskProgram; +LLGLSLShader gDeferredSkinnedShadowAlphaMaskProgram; LLGLSLShader gDeferredShadowFullbrightAlphaMaskProgram; +LLGLSLShader gDeferredSkinnedShadowFullbrightAlphaMaskProgram; LLGLSLShader gDeferredAvatarShadowProgram; LLGLSLShader gDeferredAvatarAlphaShadowProgram; LLGLSLShader gDeferredAvatarAlphaMaskShadowProgram; @@ -220,14 +219,20 @@ LLGLSLShader gDeferredAttachmentShadowProgram; LLGLSLShader gDeferredAttachmentAlphaShadowProgram; LLGLSLShader gDeferredAttachmentAlphaMaskShadowProgram; LLGLSLShader gDeferredAlphaProgram; +LLGLSLShader gDeferredSkinnedAlphaProgram; LLGLSLShader gDeferredAlphaImpostorProgram; +LLGLSLShader gDeferredSkinnedAlphaImpostorProgram; LLGLSLShader gDeferredAlphaWaterProgram; +LLGLSLShader gDeferredSkinnedAlphaWaterProgram; LLGLSLShader gDeferredAvatarEyesProgram; LLGLSLShader gDeferredFullbrightProgram; LLGLSLShader gDeferredFullbrightAlphaMaskProgram; LLGLSLShader gDeferredFullbrightWaterProgram; +LLGLSLShader gDeferredSkinnedFullbrightWaterProgram; LLGLSLShader gDeferredFullbrightAlphaMaskWaterProgram; +LLGLSLShader gDeferredSkinnedFullbrightAlphaMaskWaterProgram; LLGLSLShader gDeferredEmissiveProgram; +LLGLSLShader gDeferredSkinnedEmissiveProgram; LLGLSLShader gDeferredPostProgram; LLGLSLShader gDeferredCoFProgram; LLGLSLShader gDeferredDoFCombineProgram; @@ -240,8 +245,9 @@ LLGLSLShader gDeferredWLSunProgram; LLGLSLShader gDeferredWLMoonProgram; LLGLSLShader gDeferredStarProgram; LLGLSLShader gDeferredFullbrightShinyProgram; -LLGLSLShader gDeferredSkinnedFullbrightShinyProgram; +LLGLSLShader gDeferredSkinnedFullbrightShinyProgram; LLGLSLShader gDeferredSkinnedFullbrightProgram; +LLGLSLShader gDeferredSkinnedFullbrightAlphaMaskProgram; LLGLSLShader gNormalMapGenProgram; LLGLSLShader gDeferredPostCASProgram; LLGLSLShader gDeferredPostDLSProgram; @@ -255,6 +261,22 @@ LLGLSLShader gRlvSphereProgram; LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2]; LLGLSLShader gDeferredMaterialWaterProgram[LLMaterial::SHADER_COUNT*2]; +//helper for making a rigged variant of a given shader +bool make_rigged_variant(LLGLSLShader& shader, LLGLSLShader& riggedShader) +{ + riggedShader.mName = llformat("Skinned %s", shader.mName.c_str()); + riggedShader.mFeatures = shader.mFeatures; + riggedShader.mFeatures.hasObjectSkinning = true; + riggedShader.mDefines = shader.mDefines; // NOTE: Must come before addPermutation + riggedShader.addPermutation("HAS_SKIN", "1"); + riggedShader.mShaderFiles = shader.mShaderFiles; + riggedShader.mShaderLevel = shader.mShaderLevel; + riggedShader.mShaderGroup = shader.mShaderGroup; + + shader.mRiggedVariant = &riggedShader; + return riggedShader.createShader(NULL, NULL); +} + LLViewerShaderMgr::LLViewerShaderMgr() : mShaderLevel(SHADER_COUNT, 0), mMaxAvatarShaderLevel(0) @@ -267,82 +289,82 @@ LLViewerShaderMgr::LLViewerShaderMgr() : mShaderList.push_back(&gWLMoonProgram); mShaderList.push_back(&gAvatarProgram); mShaderList.push_back(&gObjectShinyProgram); - mShaderList.push_back(&gObjectShinyNonIndexedProgram); + mShaderList.push_back(&gSkinnedObjectShinyProgram); mShaderList.push_back(&gWaterProgram); mShaderList.push_back(&gWaterEdgeProgram); mShaderList.push_back(&gAvatarEyeballProgram); mShaderList.push_back(&gObjectSimpleProgram); + mShaderList.push_back(&gSkinnedObjectSimpleProgram); mShaderList.push_back(&gObjectSimpleImpostorProgram); + mShaderList.push_back(&gSkinnedObjectSimpleImpostorProgram); mShaderList.push_back(&gObjectPreviewProgram); mShaderList.push_back(&gImpostorProgram); mShaderList.push_back(&gObjectFullbrightNoColorProgram); mShaderList.push_back(&gObjectFullbrightNoColorWaterProgram); mShaderList.push_back(&gObjectSimpleAlphaMaskProgram); + mShaderList.push_back(&gSkinnedObjectSimpleAlphaMaskProgram); mShaderList.push_back(&gObjectBumpProgram); + mShaderList.push_back(&gSkinnedObjectBumpProgram); mShaderList.push_back(&gObjectEmissiveProgram); + mShaderList.push_back(&gSkinnedObjectEmissiveProgram); mShaderList.push_back(&gObjectEmissiveWaterProgram); + mShaderList.push_back(&gSkinnedObjectEmissiveWaterProgram); mShaderList.push_back(&gObjectFullbrightProgram); + mShaderList.push_back(&gSkinnedObjectFullbrightProgram); mShaderList.push_back(&gObjectFullbrightAlphaMaskProgram); + mShaderList.push_back(&gSkinnedObjectFullbrightAlphaMaskProgram); mShaderList.push_back(&gObjectFullbrightShinyProgram); + mShaderList.push_back(&gSkinnedObjectFullbrightShinyProgram); mShaderList.push_back(&gObjectFullbrightShinyWaterProgram); - mShaderList.push_back(&gObjectSimpleNonIndexedProgram); + mShaderList.push_back(&gSkinnedObjectFullbrightShinyWaterProgram); mShaderList.push_back(&gObjectSimpleNonIndexedTexGenProgram); mShaderList.push_back(&gObjectSimpleNonIndexedTexGenWaterProgram); - mShaderList.push_back(&gObjectSimpleNonIndexedWaterProgram); mShaderList.push_back(&gObjectAlphaMaskNonIndexedProgram); mShaderList.push_back(&gObjectAlphaMaskNonIndexedWaterProgram); mShaderList.push_back(&gObjectAlphaMaskNoColorProgram); mShaderList.push_back(&gObjectAlphaMaskNoColorWaterProgram); mShaderList.push_back(&gTreeProgram); mShaderList.push_back(&gTreeWaterProgram); - mShaderList.push_back(&gObjectFullbrightNonIndexedProgram); - mShaderList.push_back(&gObjectFullbrightNonIndexedWaterProgram); - mShaderList.push_back(&gObjectEmissiveNonIndexedProgram); - mShaderList.push_back(&gObjectEmissiveNonIndexedWaterProgram); - mShaderList.push_back(&gObjectFullbrightShinyNonIndexedProgram); - mShaderList.push_back(&gObjectFullbrightShinyNonIndexedWaterProgram); - mShaderList.push_back(&gSkinnedObjectSimpleProgram); - mShaderList.push_back(&gSkinnedObjectFullbrightProgram); - mShaderList.push_back(&gSkinnedObjectEmissiveProgram); - mShaderList.push_back(&gSkinnedObjectFullbrightShinyProgram); - mShaderList.push_back(&gSkinnedObjectShinySimpleProgram); - mShaderList.push_back(&gSkinnedObjectSimpleWaterProgram); - mShaderList.push_back(&gSkinnedObjectFullbrightWaterProgram); - mShaderList.push_back(&gSkinnedObjectEmissiveWaterProgram); - mShaderList.push_back(&gSkinnedObjectFullbrightShinyWaterProgram); - mShaderList.push_back(&gSkinnedObjectShinySimpleWaterProgram); mShaderList.push_back(&gTerrainProgram); mShaderList.push_back(&gTerrainWaterProgram); mShaderList.push_back(&gObjectSimpleWaterProgram); + mShaderList.push_back(&gSkinnedObjectSimpleWaterProgram); mShaderList.push_back(&gObjectFullbrightWaterProgram); + mShaderList.push_back(&gSkinnedObjectFullbrightWaterProgram); mShaderList.push_back(&gObjectSimpleWaterAlphaMaskProgram); + mShaderList.push_back(&gSkinnedObjectSimpleWaterAlphaMaskProgram); mShaderList.push_back(&gObjectFullbrightWaterAlphaMaskProgram); + mShaderList.push_back(&gSkinnedObjectFullbrightWaterAlphaMaskProgram); mShaderList.push_back(&gAvatarWaterProgram); mShaderList.push_back(&gObjectShinyWaterProgram); - mShaderList.push_back(&gObjectShinyNonIndexedWaterProgram); + mShaderList.push_back(&gSkinnedObjectShinyWaterProgram); mShaderList.push_back(&gUnderWaterProgram); mShaderList.push_back(&gDeferredSunProgram); mShaderList.push_back(&gDeferredSoftenProgram); mShaderList.push_back(&gDeferredSoftenWaterProgram); mShaderList.push_back(&gDeferredAlphaProgram); + mShaderList.push_back(&gDeferredSkinnedAlphaProgram); mShaderList.push_back(&gDeferredAlphaImpostorProgram); + mShaderList.push_back(&gDeferredSkinnedAlphaImpostorProgram); mShaderList.push_back(&gDeferredAlphaWaterProgram); - mShaderList.push_back(&gDeferredSkinnedAlphaProgram); - mShaderList.push_back(&gDeferredSkinnedAlphaWaterProgram); + mShaderList.push_back(&gDeferredSkinnedAlphaWaterProgram); mShaderList.push_back(&gDeferredFullbrightProgram); mShaderList.push_back(&gDeferredFullbrightAlphaMaskProgram); mShaderList.push_back(&gDeferredFullbrightWaterProgram); - mShaderList.push_back(&gDeferredFullbrightAlphaMaskWaterProgram); + mShaderList.push_back(&gDeferredSkinnedFullbrightWaterProgram); + mShaderList.push_back(&gDeferredFullbrightAlphaMaskWaterProgram); + mShaderList.push_back(&gDeferredSkinnedFullbrightAlphaMaskWaterProgram); mShaderList.push_back(&gDeferredFullbrightShinyProgram); - mShaderList.push_back(&gDeferredSkinnedFullbrightShinyProgram); + mShaderList.push_back(&gDeferredSkinnedFullbrightShinyProgram); mShaderList.push_back(&gDeferredSkinnedFullbrightProgram); + mShaderList.push_back(&gDeferredSkinnedFullbrightAlphaMaskProgram); mShaderList.push_back(&gDeferredEmissiveProgram); + mShaderList.push_back(&gDeferredSkinnedEmissiveProgram); mShaderList.push_back(&gDeferredAvatarEyesProgram); mShaderList.push_back(&gDeferredWaterProgram); mShaderList.push_back(&gDeferredUnderWaterProgram); mShaderList.push_back(&gDeferredTerrainWaterProgram); mShaderList.push_back(&gDeferredAvatarAlphaProgram); - mShaderList.push_back(&gDeferredAvatarAlphaWaterProgram); mShaderList.push_back(&gDeferredWLSkyProgram); mShaderList.push_back(&gDeferredWLCloudProgram); mShaderList.push_back(&gDeferredWLMoonProgram); @@ -393,7 +415,7 @@ void LLViewerShaderMgr::initAttribsAndUniforms(void) S32 LLViewerShaderMgr::getShaderLevel(S32 type) { - return LLPipeline::sDisableShaders ? 0 : mShaderLevel[type]; + return mShaderLevel[type]; } //============================================================================ @@ -409,12 +431,10 @@ void LLViewerShaderMgr::setShaders() return; } - if (!gGLManager.mHasShaderObjects - || !gGLManager.mHasVertexShader - || !gGLManager.mHasFragmentShader) + if (!gGLManager.mHasRequirements) { // Viewer will show 'hardware requirements' warning later - LL_INFOS("ShaderLoading") << "Shaders not supported" << LL_ENDL; + LL_INFOS("ShaderLoading") << "Not supported hardware/software" << LL_ENDL; return; } @@ -439,7 +459,7 @@ void LLViewerShaderMgr::setShaders() initAttribsAndUniforms(); gPipeline.releaseGLBuffers(); - LLPipeline::sWaterReflections = gGLManager.mHasCubeMap; + LLPipeline::sWaterReflections = gGLManager.mHasCubeMap && LLPipeline::sRenderTransparentWater; LLPipeline::sRenderGlow = gSavedSettings.getBOOL("RenderGlow"); LLPipeline::updateRenderDeferred(); @@ -464,7 +484,6 @@ void LLViewerShaderMgr::setShaders() } mMaxAvatarShaderLevel = 0; - LLGLSLShader::sNoFixedFunction = false; LLVertexBuffer::unbind(); llassert((gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 10)); @@ -473,10 +492,7 @@ void LLViewerShaderMgr::setShaders() bool hasWindLightShaders = LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders"); S32 shadow_detail = gSavedSettings.getS32("RenderShadowDetail"); bool doingWindLight = hasWindLightShaders && gSavedSettings.getBOOL("WindLightUseAtmosShaders"); - bool useRenderDeferred = doingWindLight && canRenderDeferred && gSavedSettings.getBOOL("RenderDeferred") && gSavedSettings.getBOOL("RenderAvatarVP"); - - //using shaders, disable fixed function - LLGLSLShader::sNoFixedFunction = true; + bool useRenderDeferred = doingWindLight && canRenderDeferred && gSavedSettings.getBOOL("RenderDeferred"); S32 light_class = 3; S32 interface_class = 2; @@ -534,184 +550,159 @@ void LLViewerShaderMgr::setShaders() mShaderLevel[SHADER_WINDLIGHT] = wl_class; mShaderLevel[SHADER_DEFERRED] = deferred_class; - BOOL loaded = loadBasicShaders(); - if (loaded) + std::string shader_name = loadBasicShaders(); + if (shader_name.empty()) { LL_INFOS() << "Loaded basic shaders." << LL_ENDL; } else { - LL_WARNS() << "Failed to load basic shaders." << LL_ENDL; - llassert(loaded); + LL_ERRS() << "Unable to load basic shader " << shader_name << ", verify graphics driver installed and current." << LL_ENDL; + reentrance = false; // For hygiene only, re-try probably helps nothing + return; } + gPipeline.mShadersLoaded = true; + + // Load all shaders to set max levels + BOOL loaded = loadShadersEnvironment(); + if (loaded) { - gPipeline.mVertexShadersEnabled = TRUE; - gPipeline.mVertexShadersLoaded = 1; - - // Load all shaders to set max levels - loaded = loadShadersEnvironment(); + LL_INFOS() << "Loaded environment shaders." << LL_ENDL; + } + else + { + LL_WARNS() << "Failed to load environment shaders." << LL_ENDL; + llassert(loaded); + } + if (loaded) + { + loaded = loadShadersWater(); if (loaded) { - LL_INFOS() << "Loaded environment shaders." << LL_ENDL; + LL_INFOS() << "Loaded water shaders." << LL_ENDL; } else { - LL_WARNS() << "Failed to load environment shaders." << LL_ENDL; + LL_WARNS() << "Failed to load water shaders." << LL_ENDL; llassert(loaded); } + } + if (loaded) + { + loaded = loadShadersWindLight(); if (loaded) { - loaded = loadShadersWater(); - if (loaded) - { - LL_INFOS() << "Loaded water shaders." << LL_ENDL; - } - else - { - LL_WARNS() << "Failed to load water shaders." << LL_ENDL; - llassert(loaded); - } + LL_INFOS() << "Loaded windlight shaders." << LL_ENDL; } - - if (loaded) + else { - loaded = loadShadersWindLight(); - if (loaded) - { - LL_INFOS() << "Loaded windlight shaders." << LL_ENDL; - } - else - { - LL_WARNS() << "Failed to load windlight shaders." << LL_ENDL; - llassert(loaded); - } + LL_WARNS() << "Failed to load windlight shaders." << LL_ENDL; + llassert(loaded); } + } + if (loaded) + { + loaded = loadShadersEffects(); if (loaded) { - loaded = loadShadersEffects(); - if (loaded) - { - LL_INFOS() << "Loaded effects shaders." << LL_ENDL; - } - else - { - LL_WARNS() << "Failed to load effects shaders." << LL_ENDL; - llassert(loaded); - } + LL_INFOS() << "Loaded effects shaders." << LL_ENDL; } - - if (loaded) + else { - loaded = loadShadersInterface(); - if (loaded) - { - LL_INFOS() << "Loaded interface shaders." << LL_ENDL; - } - else - { - LL_WARNS() << "Failed to load interface shaders." << LL_ENDL; - llassert(loaded); - } + LL_WARNS() << "Failed to load effects shaders." << LL_ENDL; + llassert(loaded); } + } + if (loaded) + { + loaded = loadShadersInterface(); if (loaded) { - // Load max avatar shaders to set the max level - mShaderLevel[SHADER_AVATAR] = 3; - mMaxAvatarShaderLevel = 3; + LL_INFOS() << "Loaded interface shaders." << LL_ENDL; + } + else + { + LL_WARNS() << "Failed to load interface shaders." << LL_ENDL; + llassert(loaded); + } + } + + if (loaded) + { + // Load max avatar shaders to set the max level + mShaderLevel[SHADER_AVATAR] = 3; + mMaxAvatarShaderLevel = 3; - if (gSavedSettings.getBOOL("RenderAvatarVP") && loadShadersObject()) - { //hardware skinning is enabled and rigged attachment shaders loaded correctly - BOOL avatar_cloth = gSavedSettings.getBOOL("RenderAvatarCloth"); + if (loadShadersObject()) + { //hardware skinning is enabled and rigged attachment shaders loaded correctly + BOOL avatar_cloth = gSavedSettings.getBOOL("RenderAvatarCloth"); - // cloth is a class3 shader - S32 avatar_class = avatar_cloth ? 3 : 1; + // cloth is a class3 shader + S32 avatar_class = avatar_cloth ? 3 : 1; - // Set the actual level - mShaderLevel[SHADER_AVATAR] = avatar_class; + // Set the actual level + mShaderLevel[SHADER_AVATAR] = avatar_class; - loaded = loadShadersAvatar(); - llassert(loaded); + loaded = loadShadersAvatar(); + llassert(loaded); - if (mShaderLevel[SHADER_AVATAR] != avatar_class) + if (mShaderLevel[SHADER_AVATAR] != avatar_class) + { + if(llmax(mShaderLevel[SHADER_AVATAR]-1,0) >= 3) { - if (mShaderLevel[SHADER_AVATAR] == 0) - { - gSavedSettings.setBOOL("RenderAvatarVP", FALSE); - } - if(llmax(mShaderLevel[SHADER_AVATAR]-1,0) >= 3) - { - avatar_cloth = true; - } - else - { - avatar_cloth = false; - } - gSavedSettings.setBOOL("RenderAvatarCloth", avatar_cloth); + avatar_cloth = true; } - } - else - { //hardware skinning not possible, neither is deferred rendering - mShaderLevel[SHADER_AVATAR] = 0; - mShaderLevel[SHADER_DEFERRED] = 0; - - if (gSavedSettings.getBOOL("RenderAvatarVP")) + else { - gSavedSettings.setBOOL("RenderDeferred", FALSE); - gSavedSettings.setBOOL("RenderAvatarCloth", FALSE); - gSavedSettings.setBOOL("RenderAvatarVP", FALSE); + avatar_cloth = false; } - - loadShadersAvatar(); // unloads - - loaded = loadShadersObject(); - llassert(loaded); + gSavedSettings.setBOOL("RenderAvatarCloth", avatar_cloth); } } + else + { //hardware skinning not possible, neither is deferred rendering + mShaderLevel[SHADER_AVATAR] = 0; + mShaderLevel[SHADER_DEFERRED] = 0; - if (!loaded) - { //some shader absolutely could not load, try to fall back to a simpler setting - if (gSavedSettings.getBOOL("WindLightUseAtmosShaders")) - { //disable windlight and try again - gSavedSettings.setBOOL("WindLightUseAtmosShaders", FALSE); - LL_WARNS() << "Falling back to no windlight shaders." << LL_ENDL; - reentrance = false; - setShaders(); - return; - } - } + gSavedSettings.setBOOL("RenderDeferred", FALSE); + gSavedSettings.setBOOL("RenderAvatarCloth", FALSE); - llassert(loaded); + loadShadersAvatar(); // unloads - if (loaded && !loadShadersDeferred()) - { //everything else succeeded but deferred failed, disable deferred and try again - gSavedSettings.setBOOL("RenderDeferred", FALSE); - LL_WARNS() << "Falling back to no deferred shaders." << LL_ENDL; + loaded = loadShadersObject(); + llassert(loaded); + } + } + + if (!loaded) + { //some shader absolutely could not load, try to fall back to a simpler setting + if (gSavedSettings.getBOOL("WindLightUseAtmosShaders")) + { //disable windlight and try again + gSavedSettings.setBOOL("WindLightUseAtmosShaders", FALSE); + LL_WARNS() << "Falling back to no windlight shaders." << LL_ENDL; reentrance = false; setShaders(); return; } + } + + llassert(loaded); + + if (loaded && !loadShadersDeferred()) + { //everything else succeeded but deferred failed, disable deferred and try again + gSavedSettings.setBOOL("RenderDeferred", FALSE); + LL_WARNS() << "Falling back to no deferred shaders." << LL_ENDL; + reentrance = false; + setShaders(); + return; } - else - { - LLGLSLShader::sNoFixedFunction = false; - gPipeline.mVertexShadersEnabled = FALSE; - gPipeline.mVertexShadersLoaded = 0; - mShaderLevel[SHADER_LIGHTING] = 0; - mShaderLevel[SHADER_INTERFACE] = 0; - mShaderLevel[SHADER_ENVIRONMENT] = 0; - mShaderLevel[SHADER_WATER] = 0; - mShaderLevel[SHADER_OBJECT] = 0; - mShaderLevel[SHADER_EFFECT] = 0; - mShaderLevel[SHADER_WINDLIGHT] = 0; - mShaderLevel[SHADER_AVATAR] = 0; - } - + if (gViewerWindow) { gViewerWindow->setCursor(UI_CURSOR_ARROW); @@ -724,8 +715,10 @@ void LLViewerShaderMgr::setShaders() void LLViewerShaderMgr::unloadShaders() { gOcclusionProgram.unload(); + gSkinnedOcclusionProgram.unload(); gOcclusionCubeProgram.unload(); gDebugProgram.unload(); + gSkinnedDebugProgram.unload(); gClipProgram.unload(); gDownsampleDepthProgram.unload(); gDownsampleDepthRectProgram.unload(); @@ -747,58 +740,51 @@ void LLViewerShaderMgr::unloadShaders() gObjectFullbrightNoColorProgram.unload(); gObjectFullbrightNoColorWaterProgram.unload(); gObjectSimpleProgram.unload(); + gSkinnedObjectSimpleProgram.unload(); gObjectSimpleImpostorProgram.unload(); + gSkinnedObjectSimpleImpostorProgram.unload(); gObjectPreviewProgram.unload(); + gPhysicsPreviewProgram.unload(); gImpostorProgram.unload(); gObjectSimpleAlphaMaskProgram.unload(); + gSkinnedObjectSimpleAlphaMaskProgram.unload(); gObjectBumpProgram.unload(); + gSkinnedObjectBumpProgram.unload(); gObjectSimpleWaterProgram.unload(); + gSkinnedObjectSimpleWaterProgram.unload(); gObjectSimpleWaterAlphaMaskProgram.unload(); + gSkinnedObjectSimpleWaterAlphaMaskProgram.unload(); gObjectFullbrightProgram.unload(); + gSkinnedObjectFullbrightProgram.unload(); gObjectFullbrightWaterProgram.unload(); + gSkinnedObjectFullbrightWaterProgram.unload(); gObjectEmissiveProgram.unload(); + gSkinnedObjectEmissiveProgram.unload(); gObjectEmissiveWaterProgram.unload(); + gSkinnedObjectEmissiveWaterProgram.unload(); gObjectFullbrightAlphaMaskProgram.unload(); + gSkinnedObjectFullbrightAlphaMaskProgram.unload(); gObjectFullbrightWaterAlphaMaskProgram.unload(); + gSkinnedObjectFullbrightWaterAlphaMaskProgram.unload(); gObjectShinyProgram.unload(); + gSkinnedObjectShinyProgram.unload(); gObjectFullbrightShinyProgram.unload(); + gSkinnedObjectFullbrightShinyProgram.unload(); gObjectFullbrightShinyWaterProgram.unload(); + gSkinnedObjectFullbrightShinyWaterProgram.unload(); gObjectShinyWaterProgram.unload(); + gSkinnedObjectShinyWaterProgram.unload(); - gObjectSimpleNonIndexedProgram.unload(); gObjectSimpleNonIndexedTexGenProgram.unload(); gObjectSimpleNonIndexedTexGenWaterProgram.unload(); - gObjectSimpleNonIndexedWaterProgram.unload(); gObjectAlphaMaskNonIndexedProgram.unload(); gObjectAlphaMaskNonIndexedWaterProgram.unload(); gObjectAlphaMaskNoColorProgram.unload(); gObjectAlphaMaskNoColorWaterProgram.unload(); - gObjectFullbrightNonIndexedProgram.unload(); - gObjectFullbrightNonIndexedWaterProgram.unload(); - gObjectEmissiveNonIndexedProgram.unload(); - gObjectEmissiveNonIndexedWaterProgram.unload(); gTreeProgram.unload(); gTreeWaterProgram.unload(); - gObjectShinyNonIndexedProgram.unload(); - gObjectFullbrightShinyNonIndexedProgram.unload(); - gObjectFullbrightShinyNonIndexedWaterProgram.unload(); - gObjectShinyNonIndexedWaterProgram.unload(); - - gSkinnedObjectSimpleProgram.unload(); - gSkinnedObjectFullbrightProgram.unload(); - gSkinnedObjectEmissiveProgram.unload(); - gSkinnedObjectFullbrightShinyProgram.unload(); - gSkinnedObjectShinySimpleProgram.unload(); - - gSkinnedObjectSimpleWaterProgram.unload(); - gSkinnedObjectFullbrightWaterProgram.unload(); - gSkinnedObjectEmissiveWaterProgram.unload(); - gSkinnedObjectFullbrightShinyWaterProgram.unload(); - gSkinnedObjectShinySimpleWaterProgram.unload(); - - gWaterProgram.unload(); gWaterEdgeProgram.unload(); gUnderWaterProgram.unload(); @@ -811,6 +797,7 @@ void LLViewerShaderMgr::unloadShaders() gAvatarEyeballProgram.unload(); gAvatarPickProgram.unload(); gHighlightProgram.unload(); + gSkinnedHighlightProgram.unload(); gHighlightNormalProgram.unload(); gHighlightSpecularProgram.unload(); @@ -824,12 +811,13 @@ void LLViewerShaderMgr::unloadShaders() gDeferredDiffuseProgram.unload(); gDeferredDiffuseAlphaMaskProgram.unload(); + gDeferredSkinnedDiffuseAlphaMaskProgram.unload(); gDeferredNonIndexedDiffuseAlphaMaskProgram.unload(); gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.unload(); gDeferredNonIndexedDiffuseProgram.unload(); gDeferredSkinnedDiffuseProgram.unload(); gDeferredSkinnedBumpProgram.unload(); - gDeferredSkinnedAlphaProgram.unload(); + gDeferredSkinnedAlphaWaterProgram.unload(); gDeferredPostCASProgram.unload(); @@ -849,10 +837,10 @@ void LLViewerShaderMgr::unloadShaders() mShaderLevel[SHADER_EFFECT] = 0; mShaderLevel[SHADER_WINDLIGHT] = 0; - gPipeline.mVertexShadersLoaded = 0; + gPipeline.mShadersLoaded = false; } -BOOL LLViewerShaderMgr::loadBasicShaders() +std::string LLViewerShaderMgr::loadBasicShaders() { // Load basic dependency shaders first // All of these have to load for any shaders to function @@ -909,7 +897,7 @@ BOOL LLViewerShaderMgr::loadBasicShaders() } shaders.push_back( make_pair( "objects/nonindexedTextureV.glsl", 1 ) ); - boost::unordered_map<std::string, std::string> attribs; + std::unordered_map<std::string, std::string> attribs; attribs["MAX_JOINTS_PER_MESH_OBJECT"] = fmt::to_string(LLSkinningUtil::getMaxJointCount()); @@ -938,8 +926,8 @@ BOOL LLViewerShaderMgr::loadBasicShaders() // Note usage of GL_VERTEX_SHADER if (loadShaderFile(shaders[i].first, shaders[i].second, GL_VERTEX_SHADER, &attribs) == 0) { - LL_SHADER_LOADING_WARNS() << "Failed to load vertex shader " << shaders[i].first << LL_ENDL; - return FALSE; + LL_WARNS("Shader") << "Failed to load vertex shader " << shaders[i].first << LL_ENDL; + return shaders[i].first; } } @@ -998,12 +986,12 @@ BOOL LLViewerShaderMgr::loadBasicShaders() // Note usage of GL_FRAGMENT_SHADER if (loadShaderFile(shaders[i].first, shaders[i].second, GL_FRAGMENT_SHADER, &attribs, index_channels[i]) == 0) { - LL_SHADER_LOADING_WARNS() << "Failed to load fragment shader " << shaders[i].first << LL_ENDL; - return FALSE; + LL_WARNS("Shader") << "Failed to load fragment shader " << shaders[i].first << LL_ENDL; + return shaders[i].first; } } - return TRUE; + return std::string(); } BOOL LLViewerShaderMgr::loadShadersEnvironment() @@ -1042,7 +1030,7 @@ BOOL LLViewerShaderMgr::loadShadersEnvironment() return FALSE; } - LLWorld::getInstanceFast()->updateWaterObjects(); + LLWorld::getInstance()->updateWaterObjects(); return TRUE; } @@ -1159,7 +1147,7 @@ BOOL LLViewerShaderMgr::loadShadersWater() return loadShadersWater(); } - LLWorld::getInstanceFast()->updateWaterObjects(); + LLWorld::getInstance()->updateWaterObjects(); return TRUE; } @@ -1221,15 +1209,15 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() { gDeferredTreeProgram.unload(); gDeferredTreeShadowProgram.unload(); + gDeferredSkinnedTreeShadowProgram.unload(); gDeferredDiffuseProgram.unload(); gDeferredDiffuseAlphaMaskProgram.unload(); + gDeferredSkinnedDiffuseAlphaMaskProgram.unload(); gDeferredNonIndexedDiffuseAlphaMaskProgram.unload(); gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.unload(); gDeferredNonIndexedDiffuseProgram.unload(); gDeferredSkinnedDiffuseProgram.unload(); gDeferredSkinnedBumpProgram.unload(); - gDeferredSkinnedAlphaProgram.unload(); - gDeferredSkinnedAlphaWaterProgram.unload(); gDeferredBumpProgram.unload(); gDeferredImpostorProgram.unload(); gDeferredTerrainProgram.unload(); @@ -1246,9 +1234,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredSoftenProgram.unload(); gDeferredSoftenWaterProgram.unload(); gDeferredShadowProgram.unload(); + gDeferredSkinnedShadowProgram.unload(); gDeferredShadowCubeProgram.unload(); gDeferredShadowAlphaMaskProgram.unload(); + gDeferredSkinnedShadowAlphaMaskProgram.unload(); gDeferredShadowFullbrightAlphaMaskProgram.unload(); + gDeferredSkinnedShadowFullbrightAlphaMaskProgram.unload(); gDeferredAvatarShadowProgram.unload(); gDeferredAvatarAlphaShadowProgram.unload(); gDeferredAvatarAlphaMaskShadowProgram.unload(); @@ -1257,14 +1248,18 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredAttachmentAlphaMaskShadowProgram.unload(); gDeferredAvatarProgram.unload(); gDeferredAvatarAlphaProgram.unload(); - gDeferredAvatarAlphaWaterProgram.unload(); gDeferredAlphaProgram.unload(); + gDeferredSkinnedAlphaProgram.unload(); gDeferredAlphaWaterProgram.unload(); + gDeferredSkinnedAlphaWaterProgram.unload(); gDeferredFullbrightProgram.unload(); gDeferredFullbrightAlphaMaskProgram.unload(); gDeferredFullbrightWaterProgram.unload(); + gDeferredSkinnedFullbrightWaterProgram.unload(); gDeferredFullbrightAlphaMaskWaterProgram.unload(); + gDeferredSkinnedFullbrightAlphaMaskWaterProgram.unload(); gDeferredEmissiveProgram.unload(); + gDeferredSkinnedEmissiveProgram.unload(); gDeferredAvatarEyesProgram.unload(); gDeferredPostProgram.unload(); gDeferredCoFProgram.unload(); @@ -1285,8 +1280,9 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredWLMoonProgram.unload(); gDeferredStarProgram.unload(); gDeferredFullbrightShinyProgram.unload(); - gDeferredSkinnedFullbrightShinyProgram.unload(); + gDeferredSkinnedFullbrightShinyProgram.unload(); gDeferredSkinnedFullbrightProgram.unload(); + gDeferredSkinnedFullbrightAlphaMaskProgram.unload(); gDeferredHighlightProgram.unload(); gDeferredHighlightNormalProgram.unload(); @@ -1351,7 +1347,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseIndexedF.glsl", GL_FRAGMENT_SHADER)); gDeferredDiffuseProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; gDeferredDiffuseProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredDiffuseProgram.createShader(NULL, NULL); + success = make_rigged_variant(gDeferredDiffuseProgram, gDeferredSkinnedDiffuseProgram); + success = success && gDeferredDiffuseProgram.createShader(NULL, NULL); } if (success) @@ -1363,7 +1360,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskIndexedF.glsl", GL_FRAGMENT_SHADER)); gDeferredDiffuseAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; gDeferredDiffuseAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredDiffuseAlphaMaskProgram.createShader(NULL, NULL); + success = make_rigged_variant(gDeferredDiffuseAlphaMaskProgram, gDeferredSkinnedDiffuseAlphaMaskProgram); + success = success && gDeferredDiffuseAlphaMaskProgram.createShader(NULL, NULL); } if (success) @@ -1403,144 +1401,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() llassert(success); } - if (success) - { - gDeferredSkinnedDiffuseProgram.mName = "Deferred Skinned Diffuse Shader"; - gDeferredSkinnedDiffuseProgram.mFeatures.hasObjectSkinning = true; - gDeferredSkinnedDiffuseProgram.mFeatures.encodesNormal = true; - gDeferredSkinnedDiffuseProgram.mFeatures.hasSrgb = true; - gDeferredSkinnedDiffuseProgram.mShaderFiles.clear(); - gDeferredSkinnedDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseSkinnedV.glsl", GL_VERTEX_SHADER)); - gDeferredSkinnedDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseF.glsl", GL_FRAGMENT_SHADER)); - gDeferredSkinnedDiffuseProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredSkinnedDiffuseProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - gDeferredSkinnedBumpProgram.mName = "Deferred Skinned Bump Shader"; - gDeferredSkinnedBumpProgram.mFeatures.hasObjectSkinning = true; - gDeferredSkinnedBumpProgram.mFeatures.encodesNormal = true; - gDeferredSkinnedBumpProgram.mShaderFiles.clear(); - gDeferredSkinnedBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpSkinnedV.glsl", GL_VERTEX_SHADER)); - gDeferredSkinnedBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpF.glsl", GL_FRAGMENT_SHADER)); - gDeferredSkinnedBumpProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredSkinnedBumpProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - gDeferredSkinnedAlphaProgram.mName = "Deferred Skinned Alpha Shader"; - gDeferredSkinnedAlphaProgram.mFeatures.hasObjectSkinning = true; - gDeferredSkinnedAlphaProgram.mFeatures.calculatesLighting = false; - gDeferredSkinnedAlphaProgram.mFeatures.hasLighting = false; - gDeferredSkinnedAlphaProgram.mFeatures.isAlphaLighting = true; - gDeferredSkinnedAlphaProgram.mFeatures.disableTextureIndex = true; - gDeferredSkinnedAlphaProgram.mFeatures.hasSrgb = true; - gDeferredSkinnedAlphaProgram.mFeatures.encodesNormal = true; - gDeferredSkinnedAlphaProgram.mFeatures.calculatesAtmospherics = true; - gDeferredSkinnedAlphaProgram.mFeatures.hasAtmospherics = true; - gDeferredSkinnedAlphaProgram.mFeatures.hasTransport = true; - gDeferredSkinnedAlphaProgram.mFeatures.hasGamma = true; - gDeferredSkinnedAlphaProgram.mFeatures.hasShadows = true; - - gDeferredSkinnedAlphaProgram.mShaderFiles.clear(); - gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER)); - gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER)); - gDeferredSkinnedAlphaProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - - gDeferredSkinnedAlphaProgram.clearPermutations(); - gDeferredSkinnedAlphaProgram.addPermutation("USE_DIFFUSE_TEX", "1"); - gDeferredSkinnedAlphaProgram.addPermutation("HAS_SKIN", "1"); - gDeferredSkinnedAlphaProgram.addPermutation("USE_VERTEX_COLOR", "1"); - - if (use_sun_shadow) - { - gDeferredSkinnedAlphaProgram.addPermutation("HAS_SHADOW", "1"); - } - - if (ambient_kill) - { - gDeferredSkinnedAlphaProgram.addPermutation("AMBIENT_KILL", "1"); - } - - if (sunlight_kill) - { - gDeferredSkinnedAlphaProgram.addPermutation("SUNLIGHT_KILL", "1"); - } - - if (local_light_kill) - { - gDeferredSkinnedAlphaProgram.addPermutation("LOCAL_LIGHT_KILL", "1"); - } - - success = gDeferredSkinnedAlphaProgram.createShader(NULL, NULL); - llassert(success); - - // Hack to include uniforms for lighting without linking in lighting file - gDeferredSkinnedAlphaProgram.mFeatures.calculatesLighting = true; - gDeferredSkinnedAlphaProgram.mFeatures.hasLighting = true; - } - - if (success) - { - gDeferredSkinnedAlphaWaterProgram.mName = "Deferred Skinned Underwater Alpha Shader"; - gDeferredSkinnedAlphaWaterProgram.mFeatures.hasObjectSkinning = true; - gDeferredSkinnedAlphaWaterProgram.mFeatures.calculatesLighting = false; - gDeferredSkinnedAlphaWaterProgram.mFeatures.hasLighting = false; - gDeferredSkinnedAlphaWaterProgram.mFeatures.isAlphaLighting = true; - gDeferredSkinnedAlphaWaterProgram.mFeatures.disableTextureIndex = true; - gDeferredSkinnedAlphaWaterProgram.mFeatures.hasSrgb = true; - gDeferredSkinnedAlphaWaterProgram.mFeatures.encodesNormal = true; - gDeferredSkinnedAlphaWaterProgram.mFeatures.calculatesAtmospherics = true; - gDeferredSkinnedAlphaWaterProgram.mFeatures.hasAtmospherics = true; - gDeferredSkinnedAlphaWaterProgram.mFeatures.hasTransport = true; - gDeferredSkinnedAlphaWaterProgram.mFeatures.hasGamma = true; - gDeferredSkinnedAlphaWaterProgram.mFeatures.hasWaterFog = true; - gDeferredSkinnedAlphaWaterProgram.mFeatures.hasShadows = true; - - gDeferredSkinnedAlphaWaterProgram.mShaderFiles.clear(); - gDeferredSkinnedAlphaWaterProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER)); - gDeferredSkinnedAlphaWaterProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER)); - gDeferredSkinnedAlphaWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - gDeferredSkinnedAlphaWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - - gDeferredSkinnedAlphaWaterProgram.clearPermutations(); - gDeferredSkinnedAlphaWaterProgram.addPermutation("USE_DIFFUSE_TEX", "1"); - gDeferredSkinnedAlphaWaterProgram.addPermutation("WATER_FOG", "1"); - gDeferredSkinnedAlphaWaterProgram.addPermutation("HAS_SKIN", "1"); - gDeferredSkinnedAlphaWaterProgram.addPermutation("USE_VERTEX_COLOR", "1"); - - if (use_sun_shadow) - { - gDeferredSkinnedAlphaWaterProgram.addPermutation("HAS_SHADOW", "1"); - } - - if (ambient_kill) - { - gDeferredSkinnedAlphaWaterProgram.addPermutation("AMBIENT_KILL", "1"); - } - - if (sunlight_kill) - { - gDeferredSkinnedAlphaWaterProgram.addPermutation("SUNLIGHT_KILL", "1"); - } - - if (local_light_kill) - { - gDeferredSkinnedAlphaWaterProgram.addPermutation("LOCAL_LIGHT_KILL", "1"); - } - - success = gDeferredSkinnedAlphaWaterProgram.createShader(NULL, NULL); - llassert(success); - - // Hack to include uniforms for lighting without linking in lighting file - gDeferredSkinnedAlphaWaterProgram.mFeatures.calculatesLighting = true; - gDeferredSkinnedAlphaWaterProgram.mFeatures.hasLighting = true; - } - if (success) { gDeferredBumpProgram.mName = "Deferred Bump Shader"; @@ -1549,7 +1409,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpV.glsl", GL_VERTEX_SHADER)); gDeferredBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpF.glsl", GL_FRAGMENT_SHADER)); gDeferredBumpProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredBumpProgram.createShader(NULL, NULL); + success = make_rigged_variant(gDeferredBumpProgram, gDeferredSkinnedBumpProgram); + success = success && gDeferredBumpProgram.createShader(NULL, NULL); llassert(success); } @@ -1618,6 +1479,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredMaterialProgram[i].addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode)); + if (alpha_mode != 0) + { + gDeferredMaterialProgram[i].mFeatures.hasAlphaMask = true; + gDeferredMaterialProgram[i].addPermutation("HAS_ALPHA_MASK", "1"); + } + if (use_sun_shadow) { gDeferredMaterialProgram[i].addPermutation("HAS_SUN_SHADOW", "1"); @@ -1637,6 +1504,10 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredMaterialProgram[i].addPermutation("HAS_SKIN", "1"); gDeferredMaterialProgram[i].mFeatures.hasObjectSkinning = true; } + else + { + gDeferredMaterialProgram[i].mRiggedVariant = &gDeferredMaterialProgram[i + 0x10]; + } success = gDeferredMaterialProgram[i].createShader(NULL, NULL); llassert(success); @@ -1672,6 +1543,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() } gDeferredMaterialWaterProgram[i].addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode)); + if (alpha_mode != 0) + { + gDeferredMaterialWaterProgram[i].mFeatures.hasAlphaMask = true; + gDeferredMaterialWaterProgram[i].addPermutation("HAS_ALPHA_MASK", "1"); + } + if (use_sun_shadow) { gDeferredMaterialWaterProgram[i].addPermutation("HAS_SUN_SHADOW", "1"); @@ -1682,6 +1559,10 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() { gDeferredMaterialWaterProgram[i].addPermutation("HAS_SKIN", "1"); } + else + { + gDeferredMaterialWaterProgram[i].mRiggedVariant = &(gDeferredMaterialWaterProgram[i + 0x10]); + } gDeferredMaterialWaterProgram[i].addPermutation("WATER_FOG","1"); if (ambient_kill) @@ -1757,10 +1638,25 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowV.glsl", GL_VERTEX_SHADER)); gDeferredTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowF.glsl", GL_FRAGMENT_SHADER)); gDeferredTreeShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + gDeferredTreeShadowProgram.mRiggedVariant = &gDeferredSkinnedTreeShadowProgram; success = gDeferredTreeShadowProgram.createShader(NULL, NULL); llassert(success); } + if (success) + { + gDeferredSkinnedTreeShadowProgram.mName = "Deferred Skinned Tree Shadow Shader"; + gDeferredSkinnedTreeShadowProgram.mShaderFiles.clear(); + gDeferredSkinnedTreeShadowProgram.mFeatures.isDeferred = true; + gDeferredSkinnedTreeShadowProgram.mFeatures.hasShadows = true; + gDeferredSkinnedTreeShadowProgram.mFeatures.hasObjectSkinning = true; + gDeferredSkinnedTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredSkinnedTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredSkinnedTreeShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gDeferredSkinnedTreeShadowProgram.createShader(NULL, NULL); + llassert(success); + } + if (success) { gDeferredImpostorProgram.mName = "Deferred Impostor Shader"; @@ -1948,172 +1844,238 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() if (success) { - gDeferredAlphaProgram.mName = "Deferred Alpha Shader"; - - gDeferredAlphaProgram.mFeatures.calculatesLighting = false; - gDeferredAlphaProgram.mFeatures.hasLighting = false; - gDeferredAlphaProgram.mFeatures.isAlphaLighting = true; - gDeferredAlphaProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels - gDeferredAlphaProgram.mFeatures.hasSrgb = true; - gDeferredAlphaProgram.mFeatures.encodesNormal = true; - gDeferredAlphaProgram.mFeatures.calculatesAtmospherics = true; - gDeferredAlphaProgram.mFeatures.hasAtmospherics = true; - gDeferredAlphaProgram.mFeatures.hasGamma = true; - gDeferredAlphaProgram.mFeatures.hasTransport = true; - gDeferredAlphaProgram.mFeatures.hasShadows = use_sun_shadow; - - if (mShaderLevel[SHADER_DEFERRED] < 1) - { - gDeferredAlphaProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; - } - else - { //shave off some texture units for shadow maps - gDeferredAlphaProgram.mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels - 6, 1); - } - - gDeferredAlphaProgram.mShaderFiles.clear(); - gDeferredAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER)); - gDeferredAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER)); - - gDeferredAlphaProgram.clearPermutations(); - gDeferredAlphaProgram.addPermutation("USE_VERTEX_COLOR", "1"); - gDeferredAlphaProgram.addPermutation("USE_INDEXED_TEX", "1"); - if (use_sun_shadow) + for (int i = 0; i < 2 && success; ++i) { - gDeferredAlphaProgram.addPermutation("HAS_SHADOW", "1"); - } + LLGLSLShader* shader = nullptr; + bool rigged = i == 1; + if (!rigged) + { + shader = &gDeferredAlphaProgram; + shader->mName = "Deferred Alpha Shader"; + shader->mRiggedVariant = &gDeferredSkinnedAlphaProgram; + } + else + { + shader = &gDeferredSkinnedAlphaProgram; + shader->mName = "Skinned Deferred Alpha Shader"; + shader->mFeatures.hasObjectSkinning = true; + } - if (ambient_kill) - { - gDeferredAlphaProgram.addPermutation("AMBIENT_KILL", "1"); - } + shader->mFeatures.calculatesLighting = false; + shader->mFeatures.hasLighting = false; + shader->mFeatures.isAlphaLighting = true; + shader->mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels + shader->mFeatures.hasSrgb = true; + shader->mFeatures.encodesNormal = true; + shader->mFeatures.calculatesAtmospherics = true; + shader->mFeatures.hasAtmospherics = true; + shader->mFeatures.hasGamma = true; + shader->mFeatures.hasTransport = true; + shader->mFeatures.hasShadows = use_sun_shadow; + + if (mShaderLevel[SHADER_DEFERRED] < 1) + { + shader->mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; + } + else + { //shave off some texture units for shadow maps + shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels - 6, 1); + } - if (sunlight_kill) - { - gDeferredAlphaProgram.addPermutation("SUNLIGHT_KILL", "1"); - } + shader->mShaderFiles.clear(); + shader->mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB)); + shader->mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB)); - if (local_light_kill) - { - gDeferredAlphaProgram.addPermutation("LOCAL_LIGHT_KILL", "1"); - } + shader->clearPermutations(); + shader->addPermutation("USE_VERTEX_COLOR", "1"); + shader->addPermutation("HAS_ALPHA_MASK", "1"); + shader->addPermutation("USE_INDEXED_TEX", "1"); + if (use_sun_shadow) + { + shader->addPermutation("HAS_SHADOW", "1"); + } - gDeferredAlphaProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + if (ambient_kill) + { + shader->addPermutation("AMBIENT_KILL", "1"); + } - success = gDeferredAlphaProgram.createShader(NULL, NULL); - llassert(success); + if (sunlight_kill) + { + shader->addPermutation("SUNLIGHT_KILL", "1"); + } + + if (local_light_kill) + { + shader->addPermutation("LOCAL_LIGHT_KILL", "1"); + } - // Hack - gDeferredAlphaProgram.mFeatures.calculatesLighting = true; - gDeferredAlphaProgram.mFeatures.hasLighting = true; + if (rigged) + { + shader->addPermutation("HAS_SKIN", "1"); + } + + shader->mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + + success = shader->createShader(NULL, NULL); + llassert(success); + + // Hack + shader->mFeatures.calculatesLighting = true; + shader->mFeatures.hasLighting = true; + } } if (success) { - gDeferredAlphaImpostorProgram.mName = "Deferred Alpha Impostor Shader"; + LLGLSLShader* shaders[] = { + &gDeferredAlphaImpostorProgram, + &gDeferredSkinnedAlphaImpostorProgram + }; -// Begin Hack - gDeferredAlphaImpostorProgram.mFeatures.calculatesLighting = false; - gDeferredAlphaImpostorProgram.mFeatures.hasLighting = false; + for (int i = 0; i < 2 && success; ++i) + { + bool rigged = i == 1; + LLGLSLShader* shader = shaders[i]; - gDeferredAlphaImpostorProgram.mFeatures.hasSrgb = true; - gDeferredAlphaImpostorProgram.mFeatures.isAlphaLighting = true; - gDeferredAlphaImpostorProgram.mFeatures.encodesNormal = true; - gDeferredAlphaImpostorProgram.mFeatures.hasShadows = use_sun_shadow; + shader->mName = rigged ? "Skinned Deferred Alpha Impostor Shader" : "Deferred Alpha Impostor Shader"; - if (mShaderLevel[SHADER_DEFERRED] < 1) - { - gDeferredAlphaImpostorProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; - } - else - { //shave off some texture units for shadow maps - gDeferredAlphaImpostorProgram.mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels - 6, 1); - } + // Begin Hack + shader->mFeatures.calculatesLighting = false; + shader->mFeatures.hasLighting = false; - gDeferredAlphaImpostorProgram.mShaderFiles.clear(); - gDeferredAlphaImpostorProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER)); - gDeferredAlphaImpostorProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER)); + shader->mFeatures.hasSrgb = true; + shader->mFeatures.isAlphaLighting = true; + shader->mFeatures.encodesNormal = true; + shader->mFeatures.hasShadows = use_sun_shadow; - gDeferredAlphaImpostorProgram.clearPermutations(); - gDeferredAlphaImpostorProgram.addPermutation("USE_INDEXED_TEX", "1"); - gDeferredAlphaImpostorProgram.addPermutation("FOR_IMPOSTOR", "1"); - gDeferredAlphaImpostorProgram.addPermutation("USE_VERTEX_COLOR", "1"); + if (mShaderLevel[SHADER_DEFERRED] < 1) + { + shader->mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; + } + else + { //shave off some texture units for shadow maps + shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels - 6, 1); + } - if (use_sun_shadow) - { - gDeferredAlphaImpostorProgram.addPermutation("HAS_SHADOW", "1"); - } + shader->mShaderFiles.clear(); + shader->mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB)); + shader->mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredAlphaImpostorProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + shader->clearPermutations(); + shader->addPermutation("USE_INDEXED_TEX", "1"); + shader->addPermutation("FOR_IMPOSTOR", "1"); + shader->addPermutation("HAS_ALPHA_MASK", "1"); + shader->addPermutation("USE_VERTEX_COLOR", "1"); + if (rigged) + { + shader->mFeatures.hasObjectSkinning = true; + shader->addPermutation("HAS_SKIN", "1"); + } - success = gDeferredAlphaImpostorProgram.createShader(NULL, NULL); - llassert(success); + if (use_sun_shadow) + { + shader->addPermutation("HAS_SHADOW", "1"); + } -// End Hack - gDeferredAlphaImpostorProgram.mFeatures.calculatesLighting = true; - gDeferredAlphaImpostorProgram.mFeatures.hasLighting = true; + shader->mRiggedVariant = &gDeferredSkinnedAlphaImpostorProgram; + shader->mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + if (!rigged) + { + shader->mRiggedVariant = shaders[1]; + } + success = shader->createShader(NULL, NULL); + llassert(success); + + // End Hack + shader->mFeatures.calculatesLighting = true; + shader->mFeatures.hasLighting = true; + } } - if (success) - { - gDeferredAlphaWaterProgram.mName = "Deferred Alpha Underwater Shader"; - gDeferredAlphaWaterProgram.mFeatures.calculatesLighting = false; - gDeferredAlphaWaterProgram.mFeatures.hasLighting = false; - gDeferredAlphaWaterProgram.mFeatures.isAlphaLighting = true; - gDeferredAlphaWaterProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels - gDeferredAlphaWaterProgram.mFeatures.hasWaterFog = true; - gDeferredAlphaWaterProgram.mFeatures.hasSrgb = true; - gDeferredAlphaWaterProgram.mFeatures.encodesNormal = true; - gDeferredAlphaWaterProgram.mFeatures.calculatesAtmospherics = true; - gDeferredAlphaWaterProgram.mFeatures.hasAtmospherics = true; - gDeferredAlphaWaterProgram.mFeatures.hasGamma = true; - gDeferredAlphaWaterProgram.mFeatures.hasTransport = true; - gDeferredAlphaWaterProgram.mFeatures.hasShadows = use_sun_shadow; - - if (mShaderLevel[SHADER_DEFERRED] < 1) - { - gDeferredAlphaWaterProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; - } - else - { //shave off some texture units for shadow maps - gDeferredAlphaWaterProgram.mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels - 6, 1); - } - gDeferredAlphaWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - gDeferredAlphaWaterProgram.mShaderFiles.clear(); - gDeferredAlphaWaterProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER)); - gDeferredAlphaWaterProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER)); - - gDeferredAlphaWaterProgram.clearPermutations(); - gDeferredAlphaWaterProgram.addPermutation("USE_INDEXED_TEX", "1"); - gDeferredAlphaWaterProgram.addPermutation("WATER_FOG", "1"); - gDeferredAlphaWaterProgram.addPermutation("USE_VERTEX_COLOR", "1"); - if (use_sun_shadow) - { - gDeferredAlphaWaterProgram.addPermutation("HAS_SHADOW", "1"); - } + if (success) + { + LLGLSLShader* shader[] = { + &gDeferredAlphaWaterProgram, + &gDeferredSkinnedAlphaWaterProgram + }; + + gDeferredAlphaWaterProgram.mRiggedVariant = &gDeferredSkinnedAlphaWaterProgram; + + gDeferredAlphaWaterProgram.mName = "Deferred Alpha Underwater Shader"; + gDeferredSkinnedAlphaWaterProgram.mName = "Deferred Skinned Alpha Underwater Shader"; - if (ambient_kill) + for (int i = 0; i < 2 && success; ++i) { - gDeferredAlphaWaterProgram.addPermutation("AMBIENT_KILL", "1"); - } + shader[i]->mFeatures.calculatesLighting = false; + shader[i]->mFeatures.hasLighting = false; + shader[i]->mFeatures.isAlphaLighting = true; + shader[i]->mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels + shader[i]->mFeatures.hasWaterFog = true; + shader[i]->mFeatures.hasSrgb = true; + shader[i]->mFeatures.encodesNormal = true; + shader[i]->mFeatures.calculatesAtmospherics = true; + shader[i]->mFeatures.hasAtmospherics = true; + shader[i]->mFeatures.hasGamma = true; + shader[i]->mFeatures.hasTransport = true; + shader[i]->mFeatures.hasShadows = use_sun_shadow; + + if (mShaderLevel[SHADER_DEFERRED] < 1) + { + shader[i]->mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; + } + else + { //shave off some texture units for shadow maps + shader[i]->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels - 6, 1); + } + shader[i]->mShaderGroup = LLGLSLShader::SG_WATER; + shader[i]->mShaderFiles.clear(); + shader[i]->mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB)); + shader[i]->mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB)); + + shader[i]->clearPermutations(); + shader[i]->addPermutation("USE_INDEXED_TEX", "1"); + shader[i]->addPermutation("WATER_FOG", "1"); + shader[i]->addPermutation("USE_VERTEX_COLOR", "1"); + shader[i]->addPermutation("HAS_ALPHA_MASK", "1"); + if (use_sun_shadow) + { + shader[i]->addPermutation("HAS_SHADOW", "1"); + } - if (sunlight_kill) - { - gDeferredAlphaWaterProgram.addPermutation("SUNLIGHT_KILL", "1"); - } + if (ambient_kill) + { + shader[i]->addPermutation("AMBIENT_KILL", "1"); + } - if (local_light_kill) - { - gDeferredAlphaWaterProgram.addPermutation("LOCAL_LIGHT_KILL", "1"); - } - gDeferredAlphaWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + if (sunlight_kill) + { + shader[i]->addPermutation("SUNLIGHT_KILL", "1"); + } - success = gDeferredAlphaWaterProgram.createShader(NULL, NULL); - llassert(success); + if (local_light_kill) + { + shader[i]->addPermutation("LOCAL_LIGHT_KILL", "1"); + } + + if (i == 1) + { // rigged variant + shader[i]->mFeatures.hasObjectSkinning = true; + shader[i]->addPermutation("HAS_SKIN", "1"); + } + else + { + shader[i]->mRiggedVariant = shader[1]; + } + shader[i]->mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - // Hack - gDeferredAlphaWaterProgram.mFeatures.calculatesLighting = true; - gDeferredAlphaWaterProgram.mFeatures.hasLighting = true; + success = shader[i]->createShader(NULL, NULL); + llassert(success); + + // Hack + shader[i]->mFeatures.calculatesLighting = true; + shader[i]->mFeatures.hasLighting = true; + } } if (success) @@ -2122,7 +2084,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredAvatarEyesProgram.mFeatures.disableTextureIndex = true; gDeferredAvatarEyesProgram.mFeatures.hasSrgb = true; gDeferredAvatarEyesProgram.mFeatures.encodesNormal = true; - gDeferredAvatarEyesProgram.mShaderFiles.clear(); + gDeferredAvatarEyesProgram.mShaderFiles.clear(); gDeferredAvatarEyesProgram.mShaderFiles.push_back(make_pair("deferred/avatarEyesV.glsl", GL_VERTEX_SHADER)); gDeferredAvatarEyesProgram.mShaderFiles.push_back(make_pair("deferred/diffuseF.glsl", GL_FRAGMENT_SHADER)); gDeferredAvatarEyesProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; @@ -2142,6 +2104,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER)); gDeferredFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER)); gDeferredFullbrightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = make_rigged_variant(gDeferredFullbrightProgram, gDeferredSkinnedFullbrightProgram); success = gDeferredFullbrightProgram.createShader(NULL, NULL); llassert(success); } @@ -2159,7 +2122,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER)); gDeferredFullbrightAlphaMaskProgram.addPermutation("HAS_ALPHA_MASK","1"); gDeferredFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredFullbrightAlphaMaskProgram.createShader(NULL, NULL); + success = make_rigged_variant(gDeferredFullbrightAlphaMaskProgram, gDeferredSkinnedFullbrightAlphaMaskProgram); + success = success && gDeferredFullbrightAlphaMaskProgram.createShader(NULL, NULL); llassert(success); } @@ -2178,10 +2142,11 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredFullbrightWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; gDeferredFullbrightWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; gDeferredFullbrightWaterProgram.addPermutation("WATER_FOG","1"); - success = gDeferredFullbrightWaterProgram.createShader(NULL, NULL); + success = make_rigged_variant(gDeferredFullbrightWaterProgram, gDeferredSkinnedFullbrightWaterProgram); + success = success && gDeferredFullbrightWaterProgram.createShader(NULL, NULL); llassert(success); } - + if (success) { gDeferredFullbrightAlphaMaskWaterProgram.mName = "Deferred Fullbright Underwater Alpha Masking Shader"; @@ -2198,7 +2163,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredFullbrightAlphaMaskWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; gDeferredFullbrightAlphaMaskWaterProgram.addPermutation("HAS_ALPHA_MASK","1"); gDeferredFullbrightAlphaMaskWaterProgram.addPermutation("WATER_FOG","1"); - success = gDeferredFullbrightAlphaMaskWaterProgram.createShader(NULL, NULL); + success = make_rigged_variant(gDeferredFullbrightAlphaMaskWaterProgram, gDeferredSkinnedFullbrightAlphaMaskWaterProgram); + success = success && gDeferredFullbrightAlphaMaskWaterProgram.createShader(NULL, NULL); llassert(success); } @@ -2212,46 +2178,11 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredFullbrightShinyProgram.mFeatures.hasSrgb = true; gDeferredFullbrightShinyProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels-1; gDeferredFullbrightShinyProgram.mShaderFiles.clear(); - gDeferredFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyV.glsl", GL_VERTEX_SHADER)); - gDeferredFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER)); + gDeferredFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB)); gDeferredFullbrightShinyProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredFullbrightShinyProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - gDeferredSkinnedFullbrightProgram.mName = "Skinned Fullbright Shader"; - gDeferredSkinnedFullbrightProgram.mFeatures.calculatesAtmospherics = true; - gDeferredSkinnedFullbrightProgram.mFeatures.hasAtmospherics = true; - gDeferredSkinnedFullbrightProgram.mFeatures.hasGamma = true; - gDeferredSkinnedFullbrightProgram.mFeatures.hasTransport = true; - gDeferredSkinnedFullbrightProgram.mFeatures.hasObjectSkinning = true; - gDeferredSkinnedFullbrightProgram.mFeatures.disableTextureIndex = true; - gDeferredSkinnedFullbrightProgram.mFeatures.hasSrgb = true; - gDeferredSkinnedFullbrightProgram.mShaderFiles.clear(); - gDeferredSkinnedFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightSkinnedV.glsl", GL_VERTEX_SHADER)); - gDeferredSkinnedFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER)); - gDeferredSkinnedFullbrightProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gDeferredSkinnedFullbrightProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - gDeferredSkinnedFullbrightShinyProgram.mName = "Skinned Fullbright Shiny Shader"; - gDeferredSkinnedFullbrightShinyProgram.mFeatures.calculatesAtmospherics = true; - gDeferredSkinnedFullbrightShinyProgram.mFeatures.hasAtmospherics = true; - gDeferredSkinnedFullbrightShinyProgram.mFeatures.hasGamma = true; - gDeferredSkinnedFullbrightShinyProgram.mFeatures.hasTransport = true; - gDeferredSkinnedFullbrightShinyProgram.mFeatures.hasObjectSkinning = true; - gDeferredSkinnedFullbrightShinyProgram.mFeatures.disableTextureIndex = true; - gDeferredSkinnedFullbrightShinyProgram.mFeatures.hasSrgb = true; - gDeferredSkinnedFullbrightShinyProgram.mShaderFiles.clear(); - gDeferredSkinnedFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinySkinnedV.glsl", GL_VERTEX_SHADER)); - gDeferredSkinnedFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER)); - gDeferredSkinnedFullbrightShinyProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gDeferredSkinnedFullbrightShinyProgram.createShader(NULL, NULL); + success = make_rigged_variant(gDeferredFullbrightShinyProgram, gDeferredSkinnedFullbrightShinyProgram); + success = success && gDeferredFullbrightShinyProgram.createShader(NULL, NULL); llassert(success); } @@ -2264,10 +2195,11 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredEmissiveProgram.mFeatures.hasSrgb = true; gDeferredEmissiveProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; gDeferredEmissiveProgram.mShaderFiles.clear(); - gDeferredEmissiveProgram.mShaderFiles.push_back(make_pair("deferred/emissiveV.glsl", GL_VERTEX_SHADER)); - gDeferredEmissiveProgram.mShaderFiles.push_back(make_pair("deferred/emissiveF.glsl", GL_FRAGMENT_SHADER)); + gDeferredEmissiveProgram.mShaderFiles.push_back(make_pair("deferred/emissiveV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredEmissiveProgram.mShaderFiles.push_back(make_pair("deferred/emissiveF.glsl", GL_FRAGMENT_SHADER_ARB)); gDeferredEmissiveProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredEmissiveProgram.createShader(NULL, NULL); + success = make_rigged_variant(gDeferredEmissiveProgram, gDeferredSkinnedEmissiveProgram); + success = success && gDeferredEmissiveProgram.createShader(NULL, NULL); llassert(success); } @@ -2403,17 +2335,36 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredShadowProgram.mFeatures.isDeferred = true; gDeferredShadowProgram.mFeatures.hasShadows = true; gDeferredShadowProgram.mShaderFiles.clear(); - gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowV.glsl", GL_VERTEX_SHADER)); - gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER)); + gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER_ARB)); gDeferredShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; //if (gGLManager.mHasDepthClamp) //{ // gDeferredShadowProgram.addPermutation("DEPTH_CLAMP", "1"); //} + gDeferredShadowProgram.mRiggedVariant = &gDeferredSkinnedShadowProgram; success = gDeferredShadowProgram.createShader(NULL, NULL); llassert(success); } + if (success) + { + gDeferredSkinnedShadowProgram.mName = "Deferred Skinned Shadow Shader"; + gDeferredSkinnedShadowProgram.mFeatures.isDeferred = true; + gDeferredSkinnedShadowProgram.mFeatures.hasShadows = true; + gDeferredSkinnedShadowProgram.mFeatures.hasObjectSkinning = true; + gDeferredSkinnedShadowProgram.mShaderFiles.clear(); + gDeferredSkinnedShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredSkinnedShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredSkinnedShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + //if (gGLManager.mHasDepthClamp) + //{ + // gDeferredSkinnedShadowProgram.addPermutation("DEPTH_CLAMP", "1"); + //} + success = gDeferredSkinnedShadowProgram.createShader(NULL, NULL); + llassert(success); + } + if (success) { gDeferredShadowCubeProgram.mName = "Deferred Shadow Cube Shader"; @@ -2447,10 +2398,31 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() //} gDeferredShadowFullbrightAlphaMaskProgram.addPermutation("IS_FULLBRIGHT", "1"); gDeferredShadowFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + gDeferredShadowFullbrightAlphaMaskProgram.mRiggedVariant = &gDeferredSkinnedShadowFullbrightAlphaMaskProgram; success = gDeferredShadowFullbrightAlphaMaskProgram.createShader(NULL, NULL); llassert(success); } + if (success) + { + gDeferredSkinnedShadowFullbrightAlphaMaskProgram.mName = "Deferred Skinned Shadow Fullbright Alpha Mask Shader"; + gDeferredSkinnedShadowFullbrightAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; + gDeferredSkinnedShadowFullbrightAlphaMaskProgram.mFeatures.hasObjectSkinning = true; + gDeferredSkinnedShadowFullbrightAlphaMaskProgram.mShaderFiles.clear(); + gDeferredSkinnedShadowFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredSkinnedShadowFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER_ARB)); + + gDeferredSkinnedShadowFullbrightAlphaMaskProgram.clearPermutations(); + //if (gGLManager.mHasDepthClamp) + //{ + // gDeferredSkinnedShadowFullbrightAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1"); + //} + gDeferredSkinnedShadowFullbrightAlphaMaskProgram.addPermutation("IS_FULLBRIGHT", "1"); + gDeferredSkinnedShadowFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gDeferredSkinnedShadowFullbrightAlphaMaskProgram.createShader(NULL, NULL); + llassert(success); + } + if (success) { gDeferredShadowAlphaMaskProgram.mName = "Deferred Shadow Alpha Mask Shader"; @@ -2464,10 +2436,28 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() // gDeferredShadowAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1"); //} gDeferredShadowAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + gDeferredShadowAlphaMaskProgram.mRiggedVariant = &gDeferredSkinnedShadowAlphaMaskProgram; success = gDeferredShadowAlphaMaskProgram.createShader(NULL, NULL); llassert(success); } + if (success) + { + gDeferredSkinnedShadowAlphaMaskProgram.mName = "Deferred Skinned Shadow Alpha Mask Shader"; + gDeferredSkinnedShadowAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; + gDeferredSkinnedShadowAlphaMaskProgram.mFeatures.hasObjectSkinning = true; + gDeferredSkinnedShadowAlphaMaskProgram.mShaderFiles.clear(); + gDeferredSkinnedShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredSkinnedShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER_ARB)); + //if (gGLManager.mHasDepthClamp) + //{ + // gDeferredSkinnedShadowAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1"); + //} + gDeferredSkinnedShadowAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gDeferredSkinnedShadowAlphaMaskProgram.createShader(NULL, NULL); + llassert(success); + } + if (success) { gDeferredAvatarShadowProgram.mName = "Deferred Avatar Shadow Shader"; @@ -2652,62 +2642,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredAvatarAlphaProgram.mFeatures.hasLighting = true; } - if (success) - { - gDeferredAvatarAlphaWaterProgram.mName = "Deferred Avatar Underwater Alpha Shader"; - gDeferredAvatarAlphaWaterProgram.mFeatures.hasSkinning = true; - gDeferredAvatarAlphaWaterProgram.mFeatures.calculatesLighting = false; - gDeferredAvatarAlphaWaterProgram.mFeatures.hasLighting = false; - gDeferredAvatarAlphaWaterProgram.mFeatures.isAlphaLighting = true; - gDeferredAvatarAlphaWaterProgram.mFeatures.disableTextureIndex = true; - gDeferredAvatarAlphaWaterProgram.mFeatures.hasSrgb = true; - gDeferredAvatarAlphaWaterProgram.mFeatures.encodesNormal = true; - gDeferredAvatarAlphaWaterProgram.mFeatures.calculatesAtmospherics = true; - gDeferredAvatarAlphaWaterProgram.mFeatures.hasAtmospherics = true; - gDeferredAvatarAlphaWaterProgram.mFeatures.hasTransport = true; - gDeferredAvatarAlphaWaterProgram.mFeatures.hasGamma = true; - gDeferredAvatarAlphaWaterProgram.mFeatures.hasWaterFog = true; - gDeferredAvatarAlphaWaterProgram.mFeatures.isDeferred = true; - gDeferredAvatarAlphaWaterProgram.mFeatures.hasShadows = true; - - gDeferredAvatarAlphaWaterProgram.mShaderFiles.clear(); - gDeferredAvatarAlphaWaterProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER)); - gDeferredAvatarAlphaWaterProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER)); - - gDeferredAvatarAlphaWaterProgram.clearPermutations(); - gDeferredAvatarAlphaWaterProgram.addPermutation("USE_DIFFUSE_TEX", "1"); - gDeferredAvatarAlphaWaterProgram.addPermutation("IS_AVATAR_SKIN", "1"); - gDeferredAvatarAlphaWaterProgram.addPermutation("WATER_FOG", "1"); - - if (use_sun_shadow) - { - gDeferredAvatarAlphaWaterProgram.addPermutation("HAS_SHADOW", "1"); - } - - if (ambient_kill) - { - gDeferredAvatarAlphaWaterProgram.addPermutation("AMBIENT_KILL", "1"); - } - - if (sunlight_kill) - { - gDeferredAvatarAlphaWaterProgram.addPermutation("SUNLIGHT_KILL", "1"); - } - - if (local_light_kill) - { - gDeferredAvatarAlphaWaterProgram.addPermutation("LOCAL_LIGHT_KILL", "1"); - } - gDeferredAvatarAlphaWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - gDeferredAvatarAlphaWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - - success = gDeferredAvatarAlphaWaterProgram.createShader(NULL, NULL); - llassert(success); - - gDeferredAvatarAlphaWaterProgram.mFeatures.calculatesLighting = true; - gDeferredAvatarAlphaWaterProgram.mFeatures.hasLighting = true; - } - if (success) { gDeferredPostGammaCorrectProgram.mName = "Deferred Gamma Correction Post Process"; @@ -3042,77 +2976,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() BOOL LLViewerShaderMgr::loadShadersObject() { BOOL success = TRUE; - - if (mShaderLevel[SHADER_OBJECT] == 0) - { - gObjectShinyProgram.unload(); - gObjectFullbrightShinyProgram.unload(); - gObjectFullbrightShinyWaterProgram.unload(); - gObjectShinyWaterProgram.unload(); - gObjectFullbrightNoColorProgram.unload(); - gObjectFullbrightNoColorWaterProgram.unload(); - gObjectSimpleProgram.unload(); - gObjectSimpleImpostorProgram.unload(); - gObjectPreviewProgram.unload(); - gImpostorProgram.unload(); - gObjectSimpleAlphaMaskProgram.unload(); - gObjectBumpProgram.unload(); - gObjectSimpleWaterProgram.unload(); - gObjectSimpleWaterAlphaMaskProgram.unload(); - gObjectEmissiveProgram.unload(); - gObjectEmissiveWaterProgram.unload(); - gObjectFullbrightProgram.unload(); - gObjectFullbrightAlphaMaskProgram.unload(); - gObjectFullbrightWaterProgram.unload(); - gObjectFullbrightWaterAlphaMaskProgram.unload(); - gObjectShinyNonIndexedProgram.unload(); - gObjectFullbrightShinyNonIndexedProgram.unload(); - gObjectFullbrightShinyNonIndexedWaterProgram.unload(); - gObjectShinyNonIndexedWaterProgram.unload(); - gObjectSimpleNonIndexedTexGenProgram.unload(); - gObjectSimpleNonIndexedTexGenWaterProgram.unload(); - gObjectSimpleNonIndexedWaterProgram.unload(); - gObjectAlphaMaskNonIndexedProgram.unload(); - gObjectAlphaMaskNonIndexedWaterProgram.unload(); - gObjectAlphaMaskNoColorProgram.unload(); - gObjectAlphaMaskNoColorWaterProgram.unload(); - gObjectFullbrightNonIndexedProgram.unload(); - gObjectFullbrightNonIndexedWaterProgram.unload(); - gObjectEmissiveNonIndexedProgram.unload(); - gObjectEmissiveNonIndexedWaterProgram.unload(); - gSkinnedObjectSimpleProgram.unload(); - gSkinnedObjectFullbrightProgram.unload(); - gSkinnedObjectEmissiveProgram.unload(); - gSkinnedObjectFullbrightShinyProgram.unload(); - gSkinnedObjectShinySimpleProgram.unload(); - gSkinnedObjectSimpleWaterProgram.unload(); - gSkinnedObjectFullbrightWaterProgram.unload(); - gSkinnedObjectEmissiveWaterProgram.unload(); - gSkinnedObjectFullbrightShinyWaterProgram.unload(); - gSkinnedObjectShinySimpleWaterProgram.unload(); - gTreeProgram.unload(); - gTreeWaterProgram.unload(); - - return TRUE; - } - if (success) - { - gObjectSimpleNonIndexedProgram.mName = "Non indexed Shader"; - gObjectSimpleNonIndexedProgram.mFeatures.calculatesLighting = true; - gObjectSimpleNonIndexedProgram.mFeatures.calculatesAtmospherics = true; - gObjectSimpleNonIndexedProgram.mFeatures.hasGamma = true; - gObjectSimpleNonIndexedProgram.mFeatures.hasAtmospherics = true; - gObjectSimpleNonIndexedProgram.mFeatures.hasLighting = true; - gObjectSimpleNonIndexedProgram.mFeatures.hasAlphaMask = true; // Fix for MAINT-8836 - gObjectSimpleNonIndexedProgram.mFeatures.disableTextureIndex = true; - gObjectSimpleNonIndexedProgram.mShaderFiles.clear(); - gObjectSimpleNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER)); - gObjectSimpleNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER)); - gObjectSimpleNonIndexedProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gObjectSimpleNonIndexedProgram.createShader(NULL, NULL); - } - if (success) { gObjectSimpleNonIndexedTexGenProgram.mName = "Non indexed tex-gen Shader"; @@ -3129,24 +2993,6 @@ BOOL LLViewerShaderMgr::loadShadersObject() success = gObjectSimpleNonIndexedTexGenProgram.createShader(NULL, NULL); } - - if (success) - { - gObjectSimpleNonIndexedWaterProgram.mName = "Non indexed Water Shader"; - gObjectSimpleNonIndexedWaterProgram.mFeatures.calculatesLighting = true; - gObjectSimpleNonIndexedWaterProgram.mFeatures.calculatesAtmospherics = true; - gObjectSimpleNonIndexedWaterProgram.mFeatures.hasWaterFog = true; - gObjectSimpleNonIndexedWaterProgram.mFeatures.hasAtmospherics = true; - gObjectSimpleNonIndexedWaterProgram.mFeatures.hasLighting = true; - gObjectSimpleNonIndexedWaterProgram.mFeatures.disableTextureIndex = true; - gObjectSimpleNonIndexedWaterProgram.mShaderFiles.clear(); - gObjectSimpleNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER)); - gObjectSimpleNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER)); - gObjectSimpleNonIndexedWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - gObjectSimpleNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - success = gObjectSimpleNonIndexedWaterProgram.createShader(NULL, NULL); - } - if (success) { gObjectSimpleNonIndexedTexGenWaterProgram.mName = "Non indexed tex-gen Water Shader"; @@ -3269,70 +3115,6 @@ BOOL LLViewerShaderMgr::loadShadersObject() success = gTreeWaterProgram.createShader(NULL, NULL); } - if (success) - { - gObjectFullbrightNonIndexedProgram.mName = "Non Indexed Fullbright Shader"; - gObjectFullbrightNonIndexedProgram.mFeatures.calculatesAtmospherics = true; - gObjectFullbrightNonIndexedProgram.mFeatures.hasGamma = true; - gObjectFullbrightNonIndexedProgram.mFeatures.hasTransport = true; - gObjectFullbrightNonIndexedProgram.mFeatures.isFullbright = true; - gObjectFullbrightNonIndexedProgram.mFeatures.disableTextureIndex = true; - gObjectFullbrightNonIndexedProgram.mShaderFiles.clear(); - gObjectFullbrightNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER)); - gObjectFullbrightNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER)); - gObjectFullbrightNonIndexedProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gObjectFullbrightNonIndexedProgram.createShader(NULL, NULL); - } - - if (success) - { - gObjectFullbrightNonIndexedWaterProgram.mName = "Non Indexed Fullbright Water Shader"; - gObjectFullbrightNonIndexedWaterProgram.mFeatures.calculatesAtmospherics = true; - gObjectFullbrightNonIndexedWaterProgram.mFeatures.isFullbright = true; - gObjectFullbrightNonIndexedWaterProgram.mFeatures.hasWaterFog = true; - gObjectFullbrightNonIndexedWaterProgram.mFeatures.hasTransport = true; - gObjectFullbrightNonIndexedWaterProgram.mFeatures.disableTextureIndex = true; - gObjectFullbrightNonIndexedWaterProgram.mFeatures.hasSrgb = true; - gObjectFullbrightNonIndexedWaterProgram.mShaderFiles.clear(); - gObjectFullbrightNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER)); - gObjectFullbrightNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER)); - gObjectFullbrightNonIndexedWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - gObjectFullbrightNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - success = gObjectFullbrightNonIndexedWaterProgram.createShader(NULL, NULL); - } - - if (success) - { - gObjectEmissiveNonIndexedProgram.mName = "Non Indexed Emissive Shader"; - gObjectEmissiveNonIndexedProgram.mFeatures.calculatesAtmospherics = true; - gObjectEmissiveNonIndexedProgram.mFeatures.hasGamma = true; - gObjectEmissiveNonIndexedProgram.mFeatures.hasTransport = true; - gObjectEmissiveNonIndexedProgram.mFeatures.isFullbright = true; - gObjectEmissiveNonIndexedProgram.mFeatures.disableTextureIndex = true; - gObjectEmissiveNonIndexedProgram.mFeatures.hasSrgb = true; - gObjectEmissiveNonIndexedProgram.mShaderFiles.clear(); - gObjectEmissiveNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/emissiveV.glsl", GL_VERTEX_SHADER)); - gObjectEmissiveNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER)); - gObjectEmissiveNonIndexedProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gObjectEmissiveNonIndexedProgram.createShader(NULL, NULL); - } - - if (success) - { - gObjectEmissiveNonIndexedWaterProgram.mName = "Non Indexed Emissive Water Shader"; - gObjectEmissiveNonIndexedWaterProgram.mFeatures.calculatesAtmospherics = true; - gObjectEmissiveNonIndexedWaterProgram.mFeatures.isFullbright = true; - gObjectEmissiveNonIndexedWaterProgram.mFeatures.hasWaterFog = true; - gObjectEmissiveNonIndexedWaterProgram.mFeatures.hasTransport = true; - gObjectEmissiveNonIndexedWaterProgram.mFeatures.disableTextureIndex = true; - gObjectEmissiveNonIndexedWaterProgram.mShaderFiles.clear(); - gObjectEmissiveNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/emissiveV.glsl", GL_VERTEX_SHADER)); - gObjectEmissiveNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER)); - gObjectEmissiveNonIndexedWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - gObjectEmissiveNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - success = gObjectEmissiveNonIndexedWaterProgram.createShader(NULL, NULL); - } - if (success) { gObjectFullbrightNoColorProgram.mName = "Non Indexed no color Fullbright Shader"; @@ -3365,73 +3147,6 @@ BOOL LLViewerShaderMgr::loadShadersObject() success = gObjectFullbrightNoColorWaterProgram.createShader(NULL, NULL); } - if (success) - { - gObjectShinyNonIndexedProgram.mName = "Non Indexed Shiny Shader"; - gObjectShinyNonIndexedProgram.mFeatures.calculatesAtmospherics = true; - gObjectShinyNonIndexedProgram.mFeatures.calculatesLighting = true; - gObjectShinyNonIndexedProgram.mFeatures.hasGamma = true; - gObjectShinyNonIndexedProgram.mFeatures.hasAtmospherics = true; - gObjectShinyNonIndexedProgram.mFeatures.isShiny = true; - gObjectShinyNonIndexedProgram.mFeatures.disableTextureIndex = true; - gObjectShinyNonIndexedProgram.mShaderFiles.clear(); - gObjectShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER)); - gObjectShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER)); - gObjectShinyNonIndexedProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gObjectShinyNonIndexedProgram.createShader(NULL, NULL); - } - - if (success) - { - gObjectShinyNonIndexedWaterProgram.mName = "Non Indexed Shiny Water Shader"; - gObjectShinyNonIndexedWaterProgram.mFeatures.calculatesAtmospherics = true; - gObjectShinyNonIndexedWaterProgram.mFeatures.calculatesLighting = true; - gObjectShinyNonIndexedWaterProgram.mFeatures.isShiny = true; - gObjectShinyNonIndexedWaterProgram.mFeatures.hasWaterFog = true; - gObjectShinyNonIndexedWaterProgram.mFeatures.hasAtmospherics = true; - gObjectShinyNonIndexedWaterProgram.mFeatures.disableTextureIndex = true; - gObjectShinyNonIndexedWaterProgram.mShaderFiles.clear(); - gObjectShinyNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyWaterF.glsl", GL_FRAGMENT_SHADER)); - gObjectShinyNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER)); - gObjectShinyNonIndexedWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - gObjectShinyNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - success = gObjectShinyNonIndexedWaterProgram.createShader(NULL, NULL); - } - - if (success) - { - gObjectFullbrightShinyNonIndexedProgram.mName = "Non Indexed Fullbright Shiny Shader"; - gObjectFullbrightShinyNonIndexedProgram.mFeatures.calculatesAtmospherics = true; - gObjectFullbrightShinyNonIndexedProgram.mFeatures.isFullbright = true; - gObjectFullbrightShinyNonIndexedProgram.mFeatures.isShiny = true; - gObjectFullbrightShinyNonIndexedProgram.mFeatures.hasGamma = true; - gObjectFullbrightShinyNonIndexedProgram.mFeatures.hasTransport = true; - gObjectFullbrightShinyNonIndexedProgram.mFeatures.disableTextureIndex = true; - gObjectFullbrightShinyNonIndexedProgram.mShaderFiles.clear(); - gObjectFullbrightShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER)); - gObjectFullbrightShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER)); - gObjectFullbrightShinyNonIndexedProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gObjectFullbrightShinyNonIndexedProgram.createShader(NULL, NULL); - } - - if (success) - { - gObjectFullbrightShinyNonIndexedWaterProgram.mName = "Non Indexed Fullbright Shiny Water Shader"; - gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.calculatesAtmospherics = true; - gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.isFullbright = true; - gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.isShiny = true; - gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.hasGamma = true; - gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.hasTransport = true; - gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.hasWaterFog = true; - gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.disableTextureIndex = true; - gObjectFullbrightShinyNonIndexedWaterProgram.mShaderFiles.clear(); - gObjectFullbrightShinyNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER)); - gObjectFullbrightShinyNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyWaterF.glsl", GL_FRAGMENT_SHADER)); - gObjectFullbrightShinyNonIndexedWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - gObjectFullbrightShinyNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - success = gObjectFullbrightShinyNonIndexedWaterProgram.createShader(NULL, NULL); - } - if (success) { gImpostorProgram.mName = "Impostor Shader"; @@ -3462,6 +3177,24 @@ BOOL LLViewerShaderMgr::loadShadersObject() gObjectPreviewProgram.mFeatures.hasLighting = true; } + if (success) + { + gPhysicsPreviewProgram.mName = "Preview Physics Shader"; + gPhysicsPreviewProgram.mFeatures.calculatesLighting = false; + gPhysicsPreviewProgram.mFeatures.calculatesAtmospherics = false; + gPhysicsPreviewProgram.mFeatures.hasGamma = false; + gPhysicsPreviewProgram.mFeatures.hasAtmospherics = false; + gPhysicsPreviewProgram.mFeatures.hasLighting = false; + gPhysicsPreviewProgram.mFeatures.mIndexedTextureChannels = 0; + gPhysicsPreviewProgram.mFeatures.disableTextureIndex = true; + gPhysicsPreviewProgram.mShaderFiles.clear(); + gPhysicsPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewPhysicsV.glsl", GL_VERTEX_SHADER_ARB)); + gPhysicsPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewPhysicsF.glsl", GL_FRAGMENT_SHADER_ARB)); + gPhysicsPreviewProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + success = gPhysicsPreviewProgram.createShader(NULL, NULL); + gPhysicsPreviewProgram.mFeatures.hasLighting = false; + } + if (success) { gObjectSimpleProgram.mName = "Simple Shader"; @@ -3475,7 +3208,8 @@ BOOL LLViewerShaderMgr::loadShadersObject() gObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER)); gObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER)); gObjectSimpleProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gObjectSimpleProgram.createShader(NULL, NULL); + success = make_rigged_variant(gObjectSimpleProgram, gSkinnedObjectSimpleProgram); + success = success && gObjectSimpleProgram.createShader(NULL, NULL); } if (success) @@ -3495,8 +3229,8 @@ BOOL LLViewerShaderMgr::loadShadersObject() gObjectSimpleImpostorProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER)); gObjectSimpleImpostorProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER)); gObjectSimpleImpostorProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - - success = gObjectSimpleImpostorProgram.createShader(NULL, NULL); + success = make_rigged_variant(gObjectSimpleImpostorProgram, gSkinnedObjectSimpleImpostorProgram); + success = success && gObjectSimpleImpostorProgram.createShader(NULL, NULL); } if (success) @@ -3513,30 +3247,30 @@ BOOL LLViewerShaderMgr::loadShadersObject() gObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER)); gObjectSimpleWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; gObjectSimpleWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + make_rigged_variant(gObjectSimpleWaterProgram, gSkinnedObjectSimpleWaterProgram); success = gObjectSimpleWaterProgram.createShader(NULL, NULL); } if (success) { gObjectBumpProgram.mName = "Bump Shader"; - /*gObjectBumpProgram.mFeatures.calculatesLighting = true; - gObjectBumpProgram.mFeatures.calculatesAtmospherics = true; - gObjectBumpProgram.mFeatures.hasGamma = true; - gObjectBumpProgram.mFeatures.hasAtmospherics = true; - gObjectBumpProgram.mFeatures.hasLighting = true; - gObjectBumpProgram.mFeatures.mIndexedTextureChannels = 0;*/ gObjectBumpProgram.mFeatures.encodesNormal = true; gObjectBumpProgram.mShaderFiles.clear(); gObjectBumpProgram.mShaderFiles.push_back(make_pair("objects/bumpV.glsl", GL_VERTEX_SHADER)); gObjectBumpProgram.mShaderFiles.push_back(make_pair("objects/bumpF.glsl", GL_FRAGMENT_SHADER)); gObjectBumpProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gObjectBumpProgram.createShader(NULL, NULL); + success = make_rigged_variant(gObjectBumpProgram, gSkinnedObjectBumpProgram); + success = success && gObjectBumpProgram.createShader(NULL, NULL); if (success) { //lldrawpoolbump assumes "texture0" has channel 0 and "texture1" has channel 1 - gObjectBumpProgram.bind(); - gObjectBumpProgram.uniform1i(sTexture0, 0); - gObjectBumpProgram.uniform1i(sTexture1, 1); - gObjectBumpProgram.unbind(); + LLGLSLShader* shader[] = { &gObjectBumpProgram, &gSkinnedObjectBumpProgram }; + for (int i = 0; i < 2; ++i) + { + shader[i]->bind(); + shader[i]->uniform1i(sTexture0, 0); + shader[i]->uniform1i(sTexture1, 1); + shader[i]->unbind(); + } } } @@ -3555,7 +3289,8 @@ BOOL LLViewerShaderMgr::loadShadersObject() gObjectSimpleAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER)); gObjectSimpleAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER)); gObjectSimpleAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gObjectSimpleAlphaMaskProgram.createShader(NULL, NULL); + success = make_rigged_variant(gObjectSimpleAlphaMaskProgram, gSkinnedObjectSimpleAlphaMaskProgram); + success = success && gObjectSimpleAlphaMaskProgram.createShader(NULL, NULL); } if (success) @@ -3573,7 +3308,8 @@ BOOL LLViewerShaderMgr::loadShadersObject() gObjectSimpleWaterAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER)); gObjectSimpleWaterAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; gObjectSimpleWaterAlphaMaskProgram.mShaderGroup = LLGLSLShader::SG_WATER; - success = gObjectSimpleWaterAlphaMaskProgram.createShader(NULL, NULL); + success = make_rigged_variant(gObjectSimpleWaterAlphaMaskProgram, gSkinnedObjectSimpleWaterAlphaMaskProgram); + success = success && gObjectSimpleWaterAlphaMaskProgram.createShader(NULL, NULL); } if (success) @@ -3589,7 +3325,8 @@ BOOL LLViewerShaderMgr::loadShadersObject() gObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER)); gObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER)); gObjectFullbrightProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gObjectFullbrightProgram.createShader(NULL, NULL); + success = make_rigged_variant(gObjectFullbrightProgram, gSkinnedObjectFullbrightProgram); + success = success && gObjectFullbrightProgram.createShader(NULL, NULL); } if (success) @@ -3597,7 +3334,7 @@ BOOL LLViewerShaderMgr::loadShadersObject() gObjectFullbrightWaterProgram.mName = "Fullbright Water Shader"; gObjectFullbrightWaterProgram.mFeatures.calculatesAtmospherics = true; gObjectFullbrightWaterProgram.mFeatures.isFullbright = true; - gObjectFullbrightWaterProgram.mFeatures.hasWaterFog = true; + gObjectFullbrightWaterProgram.mFeatures.hasWaterFog = true; gObjectFullbrightWaterProgram.mFeatures.hasTransport = true; gObjectFullbrightWaterProgram.mFeatures.mIndexedTextureChannels = 0; gObjectFullbrightWaterProgram.mShaderFiles.clear(); @@ -3605,7 +3342,8 @@ BOOL LLViewerShaderMgr::loadShadersObject() gObjectFullbrightWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER)); gObjectFullbrightWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; gObjectFullbrightWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - success = gObjectFullbrightWaterProgram.createShader(NULL, NULL); + success = make_rigged_variant(gObjectFullbrightWaterProgram, gSkinnedObjectFullbrightWaterProgram); + success = success && gObjectFullbrightWaterProgram.createShader(NULL, NULL); } if (success) @@ -3621,7 +3359,8 @@ BOOL LLViewerShaderMgr::loadShadersObject() gObjectEmissiveProgram.mShaderFiles.push_back(make_pair("objects/emissiveV.glsl", GL_VERTEX_SHADER)); gObjectEmissiveProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER)); gObjectEmissiveProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gObjectEmissiveProgram.createShader(NULL, NULL); + success = make_rigged_variant(gObjectEmissiveProgram, gSkinnedObjectEmissiveProgram); + success = success && gObjectEmissiveProgram.createShader(NULL, NULL); } if (success) @@ -3637,7 +3376,8 @@ BOOL LLViewerShaderMgr::loadShadersObject() gObjectEmissiveWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER)); gObjectEmissiveWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; gObjectEmissiveWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - success = gObjectEmissiveWaterProgram.createShader(NULL, NULL); + success = make_rigged_variant(gObjectEmissiveWaterProgram, gSkinnedObjectEmissiveWaterProgram); + success = success && gObjectEmissiveWaterProgram.createShader(NULL, NULL); } if (success) @@ -3654,12 +3394,13 @@ BOOL LLViewerShaderMgr::loadShadersObject() gObjectFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER)); gObjectFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER)); gObjectFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gObjectFullbrightAlphaMaskProgram.createShader(NULL, NULL); + success = make_rigged_variant(gObjectFullbrightAlphaMaskProgram, gSkinnedObjectFullbrightAlphaMaskProgram); + success = success && gObjectFullbrightAlphaMaskProgram.createShader(NULL, NULL); } if (success) { - gObjectFullbrightWaterAlphaMaskProgram.mName = "Fullbright Water Shader"; + gObjectFullbrightWaterAlphaMaskProgram.mName = "Fullbright Water Alpha Mask Shader"; gObjectFullbrightWaterAlphaMaskProgram.mFeatures.calculatesAtmospherics = true; gObjectFullbrightWaterAlphaMaskProgram.mFeatures.isFullbright = true; gObjectFullbrightWaterAlphaMaskProgram.mFeatures.hasWaterFog = true; @@ -3671,7 +3412,8 @@ BOOL LLViewerShaderMgr::loadShadersObject() gObjectFullbrightWaterAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER)); gObjectFullbrightWaterAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; gObjectFullbrightWaterAlphaMaskProgram.mShaderGroup = LLGLSLShader::SG_WATER; - success = gObjectFullbrightWaterAlphaMaskProgram.createShader(NULL, NULL); + success = make_rigged_variant(gObjectFullbrightWaterAlphaMaskProgram, gSkinnedObjectFullbrightWaterAlphaMaskProgram); + success = success && gObjectFullbrightWaterAlphaMaskProgram.createShader(NULL, NULL); } if (success) @@ -3687,7 +3429,8 @@ BOOL LLViewerShaderMgr::loadShadersObject() gObjectShinyProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER)); gObjectShinyProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER)); gObjectShinyProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gObjectShinyProgram.createShader(NULL, NULL); + success = make_rigged_variant(gObjectShinyProgram, gSkinnedObjectShinyProgram); + success = success && gObjectShinyProgram.createShader(NULL, NULL); } if (success) @@ -3704,7 +3447,8 @@ BOOL LLViewerShaderMgr::loadShadersObject() gObjectShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER)); gObjectShinyWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; gObjectShinyWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - success = gObjectShinyWaterProgram.createShader(NULL, NULL); + success = make_rigged_variant(gObjectShinyWaterProgram, gSkinnedObjectShinyWaterProgram); + success = success && gObjectShinyWaterProgram.createShader(NULL, NULL); } if (success) @@ -3720,7 +3464,8 @@ BOOL LLViewerShaderMgr::loadShadersObject() gObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER)); gObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER)); gObjectFullbrightShinyProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gObjectFullbrightShinyProgram.createShader(NULL, NULL); + success = make_rigged_variant(gObjectFullbrightShinyProgram, gSkinnedObjectFullbrightShinyProgram); + success = success && gObjectFullbrightShinyProgram.createShader(NULL, NULL); } if (success) @@ -3738,196 +3483,8 @@ BOOL LLViewerShaderMgr::loadShadersObject() gObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyWaterF.glsl", GL_FRAGMENT_SHADER)); gObjectFullbrightShinyWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; gObjectFullbrightShinyWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - success = gObjectFullbrightShinyWaterProgram.createShader(NULL, NULL); - } - - if (mShaderLevel[SHADER_AVATAR] > 0) - { //load hardware skinned attachment shaders - if (success) - { - gSkinnedObjectSimpleProgram.mName = "Skinned Simple Shader"; - gSkinnedObjectSimpleProgram.mFeatures.calculatesLighting = true; - gSkinnedObjectSimpleProgram.mFeatures.calculatesAtmospherics = true; - gSkinnedObjectSimpleProgram.mFeatures.hasGamma = true; - gSkinnedObjectSimpleProgram.mFeatures.hasAtmospherics = true; - gSkinnedObjectSimpleProgram.mFeatures.hasLighting = true; - gSkinnedObjectSimpleProgram.mFeatures.hasObjectSkinning = true; - gSkinnedObjectSimpleProgram.mFeatures.hasAlphaMask = true; - gSkinnedObjectSimpleProgram.mFeatures.disableTextureIndex = true; - gSkinnedObjectSimpleProgram.mShaderFiles.clear(); - gSkinnedObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleSkinnedV.glsl", GL_VERTEX_SHADER)); - gSkinnedObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER)); - gSkinnedObjectSimpleProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gSkinnedObjectSimpleProgram.createShader(NULL, NULL); - } - - if (success) - { - gSkinnedObjectFullbrightProgram.mName = "Skinned Fullbright Shader"; - gSkinnedObjectFullbrightProgram.mFeatures.calculatesAtmospherics = true; - gSkinnedObjectFullbrightProgram.mFeatures.hasGamma = true; - gSkinnedObjectFullbrightProgram.mFeatures.hasTransport = true; - gSkinnedObjectFullbrightProgram.mFeatures.isFullbright = true; - gSkinnedObjectFullbrightProgram.mFeatures.hasObjectSkinning = true; - gSkinnedObjectFullbrightProgram.mFeatures.hasAlphaMask = true; - gSkinnedObjectFullbrightProgram.mFeatures.disableTextureIndex = true; - gSkinnedObjectFullbrightProgram.mFeatures.hasSrgb = true; - gSkinnedObjectFullbrightProgram.mShaderFiles.clear(); - gSkinnedObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightSkinnedV.glsl", GL_VERTEX_SHADER)); - gSkinnedObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER)); - gSkinnedObjectFullbrightProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gSkinnedObjectFullbrightProgram.createShader(NULL, NULL); - } - - if (success) - { - gSkinnedObjectEmissiveProgram.mName = "Skinned Emissive Shader"; - gSkinnedObjectEmissiveProgram.mFeatures.calculatesAtmospherics = true; - gSkinnedObjectEmissiveProgram.mFeatures.hasGamma = true; - gSkinnedObjectEmissiveProgram.mFeatures.hasTransport = true; - gSkinnedObjectEmissiveProgram.mFeatures.isFullbright = true; - gSkinnedObjectEmissiveProgram.mFeatures.hasObjectSkinning = true; - gSkinnedObjectEmissiveProgram.mFeatures.disableTextureIndex = true; - gSkinnedObjectEmissiveProgram.mFeatures.hasSrgb = true; - gSkinnedObjectEmissiveProgram.mShaderFiles.clear(); - gSkinnedObjectEmissiveProgram.mShaderFiles.push_back(make_pair("objects/emissiveSkinnedV.glsl", GL_VERTEX_SHADER)); - gSkinnedObjectEmissiveProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER)); - gSkinnedObjectEmissiveProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gSkinnedObjectEmissiveProgram.createShader(NULL, NULL); - } - - if (success) - { - gSkinnedObjectEmissiveWaterProgram.mName = "Skinned Emissive Water Shader"; - gSkinnedObjectEmissiveWaterProgram.mFeatures.calculatesAtmospherics = true; - gSkinnedObjectEmissiveWaterProgram.mFeatures.hasGamma = true; - gSkinnedObjectEmissiveWaterProgram.mFeatures.hasTransport = true; - gSkinnedObjectEmissiveWaterProgram.mFeatures.isFullbright = true; - gSkinnedObjectEmissiveWaterProgram.mFeatures.hasObjectSkinning = true; - gSkinnedObjectEmissiveWaterProgram.mFeatures.disableTextureIndex = true; - gSkinnedObjectEmissiveWaterProgram.mFeatures.hasWaterFog = true; - gSkinnedObjectEmissiveWaterProgram.mShaderFiles.clear(); - gSkinnedObjectEmissiveWaterProgram.mShaderFiles.push_back(make_pair("objects/emissiveSkinnedV.glsl", GL_VERTEX_SHADER)); - gSkinnedObjectEmissiveWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER)); - gSkinnedObjectEmissiveWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gSkinnedObjectEmissiveWaterProgram.createShader(NULL, NULL); - } - - if (success) - { - gSkinnedObjectFullbrightShinyProgram.mName = "Skinned Fullbright Shiny Shader"; - gSkinnedObjectFullbrightShinyProgram.mFeatures.calculatesAtmospherics = true; - gSkinnedObjectFullbrightShinyProgram.mFeatures.hasGamma = true; - gSkinnedObjectFullbrightShinyProgram.mFeatures.hasTransport = true; - gSkinnedObjectFullbrightShinyProgram.mFeatures.isShiny = true; - gSkinnedObjectFullbrightShinyProgram.mFeatures.isFullbright = true; - gSkinnedObjectFullbrightShinyProgram.mFeatures.hasObjectSkinning = true; - gSkinnedObjectFullbrightShinyProgram.mFeatures.hasAlphaMask = true; - gSkinnedObjectFullbrightShinyProgram.mFeatures.disableTextureIndex = true; - gSkinnedObjectFullbrightShinyProgram.mShaderFiles.clear(); - gSkinnedObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinySkinnedV.glsl", GL_VERTEX_SHADER)); - gSkinnedObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER)); - gSkinnedObjectFullbrightShinyProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gSkinnedObjectFullbrightShinyProgram.createShader(NULL, NULL); - } - - if (success) - { - gSkinnedObjectShinySimpleProgram.mName = "Skinned Shiny Simple Shader"; - gSkinnedObjectShinySimpleProgram.mFeatures.calculatesLighting = true; - gSkinnedObjectShinySimpleProgram.mFeatures.calculatesAtmospherics = true; - gSkinnedObjectShinySimpleProgram.mFeatures.hasGamma = true; - gSkinnedObjectShinySimpleProgram.mFeatures.hasAtmospherics = true; - gSkinnedObjectShinySimpleProgram.mFeatures.hasObjectSkinning = true; - gSkinnedObjectShinySimpleProgram.mFeatures.hasAlphaMask = true; - gSkinnedObjectShinySimpleProgram.mFeatures.isShiny = true; - gSkinnedObjectShinySimpleProgram.mFeatures.disableTextureIndex = true; - gSkinnedObjectShinySimpleProgram.mShaderFiles.clear(); - gSkinnedObjectShinySimpleProgram.mShaderFiles.push_back(make_pair("objects/shinySimpleSkinnedV.glsl", GL_VERTEX_SHADER)); - gSkinnedObjectShinySimpleProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER)); - gSkinnedObjectShinySimpleProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gSkinnedObjectShinySimpleProgram.createShader(NULL, NULL); - } - - if (success) - { - gSkinnedObjectSimpleWaterProgram.mName = "Skinned Simple Water Shader"; - gSkinnedObjectSimpleWaterProgram.mFeatures.calculatesLighting = true; - gSkinnedObjectSimpleWaterProgram.mFeatures.calculatesAtmospherics = true; - gSkinnedObjectSimpleWaterProgram.mFeatures.hasGamma = true; - gSkinnedObjectSimpleWaterProgram.mFeatures.hasAtmospherics = true; - gSkinnedObjectSimpleWaterProgram.mFeatures.hasLighting = true; - gSkinnedObjectSimpleWaterProgram.mFeatures.disableTextureIndex = true; - gSkinnedObjectSimpleWaterProgram.mFeatures.hasWaterFog = true; - gSkinnedObjectSimpleWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - gSkinnedObjectSimpleWaterProgram.mFeatures.hasObjectSkinning = true; - gSkinnedObjectSimpleWaterProgram.mFeatures.disableTextureIndex = true; - gSkinnedObjectSimpleWaterProgram.mFeatures.hasAlphaMask = true; - gSkinnedObjectSimpleWaterProgram.mShaderFiles.clear(); - gSkinnedObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleSkinnedV.glsl", GL_VERTEX_SHADER)); - gSkinnedObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER)); - gSkinnedObjectSimpleWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gSkinnedObjectSimpleWaterProgram.createShader(NULL, NULL); - } - - if (success) - { - gSkinnedObjectFullbrightWaterProgram.mName = "Skinned Fullbright Water Shader"; - gSkinnedObjectFullbrightWaterProgram.mFeatures.calculatesAtmospherics = true; - gSkinnedObjectFullbrightWaterProgram.mFeatures.hasGamma = true; - gSkinnedObjectFullbrightWaterProgram.mFeatures.hasTransport = true; - gSkinnedObjectFullbrightWaterProgram.mFeatures.isFullbright = true; - gSkinnedObjectFullbrightWaterProgram.mFeatures.hasObjectSkinning = true; - gSkinnedObjectFullbrightWaterProgram.mFeatures.hasAlphaMask = true; - gSkinnedObjectFullbrightWaterProgram.mFeatures.hasWaterFog = true; - gSkinnedObjectFullbrightWaterProgram.mFeatures.disableTextureIndex = true; - gSkinnedObjectFullbrightWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - gSkinnedObjectFullbrightWaterProgram.mShaderFiles.clear(); - gSkinnedObjectFullbrightWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightSkinnedV.glsl", GL_VERTEX_SHADER)); - gSkinnedObjectFullbrightWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER)); - gSkinnedObjectFullbrightWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gSkinnedObjectFullbrightWaterProgram.createShader(NULL, NULL); - } - - if (success) - { - gSkinnedObjectFullbrightShinyWaterProgram.mName = "Skinned Fullbright Shiny Water Shader"; - gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.calculatesAtmospherics = true; - gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.hasGamma = true; - gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.hasTransport = true; - gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.isShiny = true; - gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.isFullbright = true; - gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.hasObjectSkinning = true; - gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.hasAlphaMask = true; - gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.hasWaterFog = true; - gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.disableTextureIndex = true; - gSkinnedObjectFullbrightShinyWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - gSkinnedObjectFullbrightShinyWaterProgram.mShaderFiles.clear(); - gSkinnedObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinySkinnedV.glsl", GL_VERTEX_SHADER)); - gSkinnedObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyWaterF.glsl", GL_FRAGMENT_SHADER)); - gSkinnedObjectFullbrightShinyWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gSkinnedObjectFullbrightShinyWaterProgram.createShader(NULL, NULL); - } - - if (success) - { - gSkinnedObjectShinySimpleWaterProgram.mName = "Skinned Shiny Simple Water Shader"; - gSkinnedObjectShinySimpleWaterProgram.mFeatures.calculatesLighting = true; - gSkinnedObjectShinySimpleWaterProgram.mFeatures.calculatesAtmospherics = true; - gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasGamma = true; - gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasAtmospherics = true; - gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasObjectSkinning = true; - gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasAlphaMask = true; - gSkinnedObjectShinySimpleWaterProgram.mFeatures.isShiny = true; - gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasWaterFog = true; - gSkinnedObjectShinySimpleWaterProgram.mFeatures.disableTextureIndex = true; - gSkinnedObjectShinySimpleWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - gSkinnedObjectShinySimpleWaterProgram.mShaderFiles.clear(); - gSkinnedObjectShinySimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/shinySimpleSkinnedV.glsl", GL_VERTEX_SHADER)); - gSkinnedObjectShinySimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyWaterF.glsl", GL_FRAGMENT_SHADER)); - gSkinnedObjectShinySimpleWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gSkinnedObjectShinySimpleWaterProgram.createShader(NULL, NULL); - } + success = make_rigged_variant(gObjectFullbrightShinyWaterProgram, gSkinnedObjectFullbrightShinyWaterProgram); + success = success && gObjectFullbrightShinyWaterProgram.createShader(NULL, NULL); } if( !success ) @@ -4040,12 +3597,6 @@ BOOL LLViewerShaderMgr::loadShadersInterface() { BOOL success = TRUE; - if (mShaderLevel[SHADER_INTERFACE] == 0) - { - gHighlightProgram.unload(); - return TRUE; - } - if (success) { gHighlightProgram.mName = "Highlight Shader"; @@ -4053,7 +3604,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface() gHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightV.glsl", GL_VERTEX_SHADER)); gHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER)); gHighlightProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; - success = gHighlightProgram.createShader(NULL, NULL); + success = make_rigged_variant(gHighlightProgram, gSkinnedHighlightProgram); + success = success && gHighlightProgram.createShader(NULL, NULL); } if (success) @@ -4255,9 +3807,21 @@ BOOL LLViewerShaderMgr::loadShadersInterface() gOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionV.glsl", GL_VERTEX_SHADER)); gOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionF.glsl", GL_FRAGMENT_SHADER)); gOcclusionProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; + gOcclusionProgram.mRiggedVariant = &gSkinnedOcclusionProgram; success = gOcclusionProgram.createShader(NULL, NULL); } + if (success) + { + gSkinnedOcclusionProgram.mName = "Skinned Occlusion Shader"; + gSkinnedOcclusionProgram.mFeatures.hasObjectSkinning = true; + gSkinnedOcclusionProgram.mShaderFiles.clear(); + gSkinnedOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); + gSkinnedOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionF.glsl", GL_FRAGMENT_SHADER_ARB)); + gSkinnedOcclusionProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; + success = gSkinnedOcclusionProgram.createShader(NULL, NULL); + } + if (success) { gOcclusionCubeProgram.mName = "Occlusion Cube Shader"; @@ -4274,8 +3838,10 @@ BOOL LLViewerShaderMgr::loadShadersInterface() gDebugProgram.mShaderFiles.clear(); gDebugProgram.mShaderFiles.push_back(make_pair("interface/debugV.glsl", GL_VERTEX_SHADER)); gDebugProgram.mShaderFiles.push_back(make_pair("interface/debugF.glsl", GL_FRAGMENT_SHADER)); + gDebugProgram.mRiggedVariant = &gSkinnedDebugProgram; gDebugProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; - success = gDebugProgram.createShader(NULL, NULL); + success = make_rigged_variant(gDebugProgram, gSkinnedDebugProgram); + success = success && gDebugProgram.createShader(NULL, NULL); } if (success) @@ -4444,7 +4010,7 @@ std::string LLViewerShaderMgr::getShaderDirPrefix(void) void LLViewerShaderMgr::updateShaderUniforms(LLGLSLShader * shader) { - LLEnvironment::getInstanceFast()->updateShaderUniforms(shader); + LLEnvironment::getInstance()->updateShaderUniforms(shader); } LLViewerShaderMgr::shader_iter LLViewerShaderMgr::beginShaders() const diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index 68c0c14c0f8c0ae5e2bb5681dc9c71d3be151b25..1a474f6a20bb42fce2ee735cf3ab18d894fe9058 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -51,7 +51,11 @@ class LLViewerShaderMgr: public LLShaderMgr void setShaders(); void unloadShaders(); S32 getShaderLevel(S32 type); - BOOL loadBasicShaders(); + + // loadBasicShaders in case of a failure returns + // name of a file error happened at, otherwise + // returns an empty string + std::string loadBasicShaders(); BOOL loadShadersEffects(); BOOL loadShadersDeferred(); BOOL loadShadersObject(); @@ -172,13 +176,12 @@ extern LLGLSLShader gOneTextureNoColorProgram; extern LLGLSLShader gObjectSimpleProgram; extern LLGLSLShader gObjectSimpleImpostorProgram; extern LLGLSLShader gObjectPreviewProgram; +extern LLGLSLShader gPhysicsPreviewProgram; extern LLGLSLShader gObjectSimpleAlphaMaskProgram; extern LLGLSLShader gObjectSimpleWaterProgram; extern LLGLSLShader gObjectSimpleWaterAlphaMaskProgram; -extern LLGLSLShader gObjectSimpleNonIndexedProgram; extern LLGLSLShader gObjectSimpleNonIndexedTexGenProgram; extern LLGLSLShader gObjectSimpleNonIndexedTexGenWaterProgram; -extern LLGLSLShader gObjectSimpleNonIndexedWaterProgram; extern LLGLSLShader gObjectAlphaMaskNonIndexedProgram; extern LLGLSLShader gObjectAlphaMaskNonIndexedWaterProgram; extern LLGLSLShader gObjectAlphaMaskNoColorProgram; @@ -191,8 +194,6 @@ extern LLGLSLShader gObjectEmissiveProgram; extern LLGLSLShader gObjectEmissiveWaterProgram; extern LLGLSLShader gObjectFullbrightAlphaMaskProgram; extern LLGLSLShader gObjectFullbrightWaterAlphaMaskProgram; -extern LLGLSLShader gObjectFullbrightNonIndexedProgram; -extern LLGLSLShader gObjectFullbrightNonIndexedWaterProgram; extern LLGLSLShader gObjectEmissiveNonIndexedProgram; extern LLGLSLShader gObjectEmissiveNonIndexedWaterProgram; extern LLGLSLShader gObjectBumpProgram; @@ -204,25 +205,9 @@ extern LLGLSLShader gObjectFullbrightLODProgram; extern LLGLSLShader gObjectFullbrightShinyProgram; extern LLGLSLShader gObjectFullbrightShinyWaterProgram; -extern LLGLSLShader gObjectFullbrightShinyNonIndexedProgram; -extern LLGLSLShader gObjectFullbrightShinyNonIndexedWaterProgram; extern LLGLSLShader gObjectShinyProgram; extern LLGLSLShader gObjectShinyWaterProgram; -extern LLGLSLShader gObjectShinyNonIndexedProgram; -extern LLGLSLShader gObjectShinyNonIndexedWaterProgram; - -extern LLGLSLShader gSkinnedObjectSimpleProgram; -extern LLGLSLShader gSkinnedObjectFullbrightProgram; -extern LLGLSLShader gSkinnedObjectEmissiveProgram; -extern LLGLSLShader gSkinnedObjectFullbrightShinyProgram; -extern LLGLSLShader gSkinnedObjectShinySimpleProgram; - -extern LLGLSLShader gSkinnedObjectSimpleWaterProgram; -extern LLGLSLShader gSkinnedObjectFullbrightWaterProgram; -extern LLGLSLShader gSkinnedObjectEmissiveWaterProgram; -extern LLGLSLShader gSkinnedObjectFullbrightShinyWaterProgram; -extern LLGLSLShader gSkinnedObjectShinySimpleWaterProgram; //environment shaders extern LLGLSLShader gTerrainProgram; @@ -276,10 +261,6 @@ extern LLGLSLShader gDeferredDiffuseAlphaMaskProgram; extern LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskProgram; extern LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram; extern LLGLSLShader gDeferredNonIndexedDiffuseProgram; -extern LLGLSLShader gDeferredSkinnedDiffuseProgram; -extern LLGLSLShader gDeferredSkinnedBumpProgram; -extern LLGLSLShader gDeferredSkinnedAlphaProgram; -extern LLGLSLShader gDeferredSkinnedAlphaWaterProgram; extern LLGLSLShader gDeferredBumpProgram; extern LLGLSLShader gDeferredTerrainProgram; extern LLGLSLShader gDeferredTerrainWaterProgram; @@ -320,15 +301,13 @@ extern LLGLSLShader gDeferredFullbrightAlphaMaskWaterProgram; extern LLGLSLShader gDeferredEmissiveProgram; extern LLGLSLShader gDeferredAvatarEyesProgram; extern LLGLSLShader gDeferredAvatarAlphaProgram; -extern LLGLSLShader gDeferredAvatarAlphaWaterProgram; +//extern LLGLSLShader gDeferredAvatarAlphaWaterProgram; extern LLGLSLShader gDeferredWLSkyProgram; extern LLGLSLShader gDeferredWLCloudProgram; extern LLGLSLShader gDeferredWLSunProgram; extern LLGLSLShader gDeferredWLMoonProgram; extern LLGLSLShader gDeferredStarProgram; extern LLGLSLShader gDeferredFullbrightShinyProgram; -extern LLGLSLShader gDeferredSkinnedFullbrightShinyProgram; -extern LLGLSLShader gDeferredSkinnedFullbrightProgram; extern LLGLSLShader gNormalMapGenProgram; extern LLGLSLShader gDeferredPostCASProgram; extern LLGLSLShader gDeferredPostDLSProgram; diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index 1fa4cad6ec240ea36d542a02d968544cabd96313..2f24c10ef7f62eafebb35bf273d1c02e7e0d48c8 100644 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -181,8 +181,9 @@ SimMeasurement<F64Kilobytes > SIM_UNACKED_BYTES("simtotalunackedbytes", "", LL_S SimMeasurement<F64Megabytes > SIM_PHYSICS_MEM("physicsmemoryallocated", "", LL_SIM_STAT_SIMPHYSICSMEMORY); LLTrace::SampleStatHandle<F64Milliseconds > FRAMETIME_JITTER("frametimejitter", "Average delta between successive frame times"), - FRAMETIME_SLEW("frametimeslew", "Average delta between frame time and mean"), - SIM_PING("simpingstat"); + FRAMETIME_SLEW("frametimeslew", "Average delta between frame time and mean"), + FRAMETIME("frametime", "Measured frame time"), + SIM_PING("simpingstat"); LLTrace::EventStatHandle<LLUnit<F64, LLUnits::Meters> > AGENT_POSITION_SNAP("agentpositionsnap", "agent position corrections"); @@ -260,8 +261,11 @@ void LLViewerStats::updateFrameStats(const F64Seconds time_diff) // new "stutter" meter add(LLStatViewer::FRAMETIME_DOUBLED, time_diff >= 2.0 * mLastTimeDiff ? 1 : 0); + sample(LLStatViewer::FRAMETIME, time_diff); + // old stats that were never really used - sample(LLStatViewer::FRAMETIME_JITTER, F64Milliseconds (mLastTimeDiff - time_diff)); + F64Seconds jit = (F64Seconds) std::fabs((mLastTimeDiff - time_diff)); + sample(LLStatViewer::FRAMETIME_JITTER, jit); F32Seconds average_frametime = gRenderStartTime.getElapsedTimeF32() / (F32)gFrameCount; sample(LLStatViewer::FRAMETIME_SLEW, F64Milliseconds (average_frametime - time_diff)); @@ -387,8 +391,12 @@ void update_statistics() gTransferManager.resetTransferBitsIn(LLTCT_ASSET); sample(LLStatViewer::VISIBLE_AVATARS, LLVOAvatar::sNumVisibleAvatars); - LLWorld::getInstanceFast()->updateNetStats(); - LLWorld::getInstanceFast()->requestCacheMisses(); + LLWorld *world = LLWorld::getInstance(); // not LLSingleton + if (world) + { + world->updateNetStats(); + world->requestCacheMisses(); + } // Reset all of these values. gVLManager.resetBitCounts(); @@ -497,7 +505,9 @@ void send_viewer_stats(bool include_preferences) system["ram"] = (S32) gSysMemory.getPhysicalMemoryKB().value(); system["os"] = LLOSInfo::instance().getOSStringSimple(); system["cpu"] = gSysCPU.getCPUString(); + system["cpu_sse"] = gSysCPU.getSSEVersions(); system["address_size"] = ADDRESS_SIZE; + system["os_bitness"] = LLOSInfo::instance().getOSBitness(); unsigned char MACAddress[MAC_ADDRESS_BYTES]; LLUUID::getNodeID(MACAddress); std::string macAddressString = llformat("%02x-%02x-%02x-%02x-%02x-%02x", @@ -539,7 +549,7 @@ void send_viewer_stats(bool include_preferences) { shader_level = 2; } - else if (gPipeline.canUseVertexShaders()) + else if (gPipeline.shadersLoaded()) { shader_level = 1; } diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h index ec5a61b8e2ffb1e9f0c8c22ca2d3477a152a6ce1..f84fef9764945071b5cf383137ce80bc3d49ebfe 100644 --- a/indra/newview/llviewerstats.h +++ b/indra/newview/llviewerstats.h @@ -217,8 +217,8 @@ extern SimMeasurement<F64Megabytes > SIM_PHYSICS_MEM; extern LLTrace::SampleStatHandle<F64Milliseconds > FRAMETIME_JITTER, - FRAMETIME_SLEW, - SIM_PING; + FRAMETIME_SLEW, + SIM_PING; extern LLTrace::EventStatHandle<LLUnit<F64, LLUnits::Meters> > AGENT_POSITION_SNAP; diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 0799fea31679387ae32bcd04cc33d5f12203014c..780208d20aa77a19016a9054252eea59e114ef7c 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -190,6 +190,7 @@ void LLViewerTextureManager::findFetchedTextures(const LLUUID& id, std::vector<L void LLViewerTextureManager::findTextures(const LLUUID& id, std::vector<LLViewerTexture*> &output) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; std::vector<LLViewerFetchedTexture*> fetched_output; gTextureList.findTexturesByID(id, fetched_output); std::vector<LLViewerFetchedTexture*>::iterator iter = fetched_output.begin(); @@ -214,6 +215,7 @@ void LLViewerTextureManager::findTextures(const LLUUID& id, std::vector<LLViewe LLViewerFetchedTexture* LLViewerTextureManager::findFetchedTexture(const LLUUID& id, S32 tex_type) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; return gTextureList.findImage(id, (ETexListType)tex_type); } @@ -487,11 +489,10 @@ const F32 GPU_MEMORY_CHECK_WAIT_TIME = 1.0f; F32 texmem_lower_bound_scale = 0.85f; F32 texmem_middle_bound_scale = 0.925f; -static LLTrace::BlockTimerStatHandle FTM_TEXTURE_MEMORY_CHECK("Memory Check"); - //static bool LLViewerTexture::isMemoryForTextureLow() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; static LLCachedControl<bool> disable_vidmem_check(gSavedSettings, "RenderDisableLowVidMem", true); if (disable_vidmem_check) return false; @@ -512,6 +513,7 @@ bool LLViewerTexture::isMemoryForTextureLow() //static bool LLViewerTexture::isMemoryForTextureSuficientlyFree() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; const S32Megabytes DESIRED_FREE_TEXTURE_MEMORY(50); const S32Megabytes DESIRED_FREE_MAIN_MEMORY(200); @@ -525,10 +527,12 @@ bool LLViewerTexture::isMemoryForTextureSuficientlyFree() //static void LLViewerTexture::getGPUMemoryForTextures(S32Megabytes &gpu, S32Megabytes &physical) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; static LLFrameTimer timer; + static S32Megabytes gpu_res = S32Megabytes(S32_MAX); static S32Megabytes physical_res = S32Megabytes(S32_MAX); - + if (timer.getElapsedTimeF32() < GPU_MEMORY_CHECK_WAIT_TIME) //call this once per second. { gpu = gpu_res; @@ -537,48 +541,31 @@ void LLViewerTexture::getGPUMemoryForTextures(S32Megabytes &gpu, S32Megabytes &p } timer.reset(); - LL_RECORD_BLOCK_TIME(FTM_TEXTURE_MEMORY_CHECK); - - if (gGLManager.mHasATIMemInfo) { - S32 meminfo[4]; - glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, meminfo); - gpu_res = (S32Megabytes)meminfo[0]; - + gpu_res = (S32Megabytes) LLImageGLThread::getFreeVRAMMegabytes(); + //check main memory, only works for windows. LLMemory::updateMemoryInfo(); physical_res = LLMemory::getAvailableMemKB(); - } - else if (gGLManager.mHasNVXMemInfo) - { - S32 free_memory; - glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &free_memory); - gpu_res = (S32Megabytes)(free_memory / 1024); - } - gpu = gpu_res; - physical = physical_res; + gpu = gpu_res; + physical = physical_res; + } } -static LLTrace::BlockTimerStatHandle FTM_TEXTURE_UPDATE_MEDIA("Media"); -static LLTrace::BlockTimerStatHandle FTM_TEXTURE_UPDATE_TEST("Test"); - //static -void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity) +void LLViewerTexture::updateClass() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; sCurrentTime = gFrameTimeSeconds; LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName); if (tester) { - LL_RECORD_BLOCK_TIME(FTM_TEXTURE_UPDATE_TEST); tester->update(); } - { - LL_RECORD_BLOCK_TIME(FTM_TEXTURE_UPDATE_MEDIA); - LLViewerMediaTexture::updateClass(); - } + LLViewerMediaTexture::updateClass(); sBoundTextureMemory = LLImageGL::sBoundTextureMemory; sTotalTextureMemory = LLImageGL::sGlobalTextureMemory; @@ -694,6 +681,9 @@ void LLViewerTexture::init(bool firstinit) mVolumeList[LLRender::LIGHT_TEX].clear(); mVolumeList[LLRender::SCULPT_TEX].clear(); + + mMainQueue = LL::WorkQueue::getInstance("mainloop"); + mImageQueue = LL::WorkQueue::getInstance("LLImageGL"); } //virtual @@ -715,6 +705,7 @@ void LLViewerTexture::cleanup() void LLViewerTexture::notifyAboutCreatingTexture() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; for(U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch) { for(U32 f = 0; f < mNumFaces[ch]; f++) @@ -726,6 +717,7 @@ void LLViewerTexture::notifyAboutCreatingTexture() void LLViewerTexture::notifyAboutMissingAsset() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; for(U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch) { for(U32 f = 0; f < mNumFaces[ch]; f++) @@ -738,6 +730,7 @@ void LLViewerTexture::notifyAboutMissingAsset() // virtual void LLViewerTexture::dump() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; LLGLTexture::dump(); LL_INFOS() << "LLViewerTexture" @@ -773,6 +766,7 @@ bool LLViewerTexture::isActiveFetching() bool LLViewerTexture::bindDebugImage(const S32 stage) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; if (stage < 0) return false; bool res = true; @@ -791,6 +785,7 @@ bool LLViewerTexture::bindDebugImage(const S32 stage) bool LLViewerTexture::bindDefaultImage(S32 stage) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; if (stage < 0) return false; bool res = true; @@ -833,6 +828,7 @@ void LLViewerTexture::forceImmediateUpdate() void LLViewerTexture::addTextureStats(F32 virtual_size, BOOL needs_gltexture) const { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; if(needs_gltexture) { mNeedsGLTexture = TRUE; @@ -843,14 +839,14 @@ void LLViewerTexture::addTextureStats(F32 virtual_size, BOOL needs_gltexture) co { //flag to reset the values because the old values are used. resetMaxVirtualSizeResetCounter(); - mMaxVirtualSize = virtual_size; - mAdditionalDecodePriority = 0.f; + mMaxVirtualSize = virtual_size; + mAdditionalDecodePriority = 0.f; mNeedsGLTexture = needs_gltexture; } else if (virtual_size > mMaxVirtualSize) { mMaxVirtualSize = virtual_size; - } + } } void LLViewerTexture::resetTextureStats() @@ -875,6 +871,7 @@ void LLViewerTexture::setKnownDrawSize(S32 width, S32 height) //virtual void LLViewerTexture::addFace(U32 ch, LLFace* facep) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); if(mNumFaces[ch] >= mFaceList[ch].size()) @@ -890,6 +887,7 @@ void LLViewerTexture::addFace(U32 ch, LLFace* facep) //virtual void LLViewerTexture::removeFace(U32 ch, LLFace* facep) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); if(mNumFaces[ch] > 1) @@ -930,6 +928,7 @@ S32 LLViewerTexture::getNumFaces(U32 ch) const //virtual void LLViewerTexture::addVolume(U32 ch, LLVOVolume* volumep) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; if (mNumVolumes[ch] >= mVolumeList[ch].size()) { mVolumeList[ch].resize(2 * mNumVolumes[ch] + 1); @@ -943,6 +942,7 @@ void LLViewerTexture::addVolume(U32 ch, LLVOVolume* volumep) //virtual void LLViewerTexture::removeVolume(U32 ch, LLVOVolume* volumep) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; if (mNumVolumes[ch] > 1) { S32 index = volumep->getIndexInTex(ch); @@ -966,6 +966,7 @@ S32 LLViewerTexture::getNumVolumes(U32 ch) const void LLViewerTexture::reorganizeFaceList() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; static const F32 MAX_WAIT_TIME = 20.f; // seconds static const U32 MAX_EXTRA_BUFFER_SIZE = 4; @@ -989,6 +990,7 @@ void LLViewerTexture::reorganizeFaceList() void LLViewerTexture::reorganizeVolumeList() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; static const F32 MAX_WAIT_TIME = 20.f; // seconds static const U32 MAX_EXTRA_BUFFER_SIZE = 4; @@ -1134,7 +1136,7 @@ void LLViewerFetchedTexture::init(bool firstinit) mLoadedCallbackDesiredDiscardLevel = S8_MAX; mPauseLoadedCallBacks = FALSE; - mNeedsCreateTexture = FALSE; + mNeedsCreateTexture = false; mIsRawImageValid = FALSE; mRawDiscardLevel = INVALID_DISCARD_LEVEL; @@ -1195,6 +1197,7 @@ FTType LLViewerFetchedTexture::getFTType() const void LLViewerFetchedTexture::cleanup() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; for(callback_list_t::iterator iter = mLoadedCallbackList.begin(); iter != mLoadedCallbackList.end(); ) { @@ -1220,6 +1223,7 @@ void LLViewerFetchedTexture::cleanup() //access the fast cache void LLViewerFetchedTexture::loadFromFastCache() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; if(!mInFastCacheList) { return; //no need to access the fast cache. @@ -1365,6 +1369,7 @@ void LLViewerFetchedTexture::dump() // ONLY called from LLViewerFetchedTextureList void LLViewerFetchedTexture::destroyTexture() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; if(LLImageGL::sGlobalTextureMemory < sMaxDesiredTextureMem * 0.95f)//not ready to release unused memory. { return ; @@ -1381,6 +1386,7 @@ void LLViewerFetchedTexture::destroyTexture() void LLViewerFetchedTexture::addToCreateTexture() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; bool force_update = false; if (getComponents() != mRawImage->getComponents()) { @@ -1412,16 +1418,17 @@ void LLViewerFetchedTexture::addToCreateTexture() { //just update some variables, not to create a real GL texture. createGLTexture(mRawDiscardLevel, mRawImage, 0, FALSE); - mNeedsCreateTexture = FALSE; + mNeedsCreateTexture = false; destroyRawImage(); } else if(!force_update && getDiscardLevel() > -1 && getDiscardLevel() <= mRawDiscardLevel) { - mNeedsCreateTexture = FALSE; + mNeedsCreateTexture = false; destroyRawImage(); } else { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; #if 1 // //if mRequestedDiscardLevel > mDesiredDiscardLevel, we assume the required image res keep going up, @@ -1452,7 +1459,7 @@ void LLViewerFetchedTexture::addToCreateTexture() mRawDiscardLevel += i; if(mRawDiscardLevel >= getDiscardLevel() && getDiscardLevel() > 0) { - mNeedsCreateTexture = FALSE; + mNeedsCreateTexture = false; destroyRawImage(); return; } @@ -1466,63 +1473,68 @@ void LLViewerFetchedTexture::addToCreateTexture() } } #endif - mNeedsCreateTexture = TRUE; - gTextureList.mCreateTextureList.insert(this); - } + scheduleCreateTexture(); + } return; } // ONLY called from LLViewerTextureList -BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/) +BOOL LLViewerFetchedTexture::preCreateTexture(S32 usename/*= 0*/) { - if (!mNeedsCreateTexture) - { - destroyRawImage(); - return FALSE; - } - mNeedsCreateTexture = FALSE; - if (mRawImage.isNull()) - { - LL_ERRS() << "LLViewerTexture trying to create texture with no Raw Image" << LL_ENDL; - } - if (mRawImage->isBufferInvalid()) - { - LL_WARNS() << "Can't create a texture: invalid image data" << LL_ENDL; - destroyRawImage(); - return FALSE; - } -// LL_INFOS() << llformat("IMAGE Creating (%d) [%d x %d] Bytes: %d ", -// mRawDiscardLevel, -// mRawImage->getWidth(), mRawImage->getHeight(),mRawImage->getDataSize()) -// << mID.getString() << LL_ENDL; - BOOL res = TRUE; + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; +#if LL_IMAGEGL_THREAD_CHECK + mGLTexturep->checkActiveThread(); +#endif - // store original size only for locally-sourced images - if (mUrl.compare(0, 7, "file://") == 0) - { - mOrigWidth = mRawImage->getWidth(); - mOrigHeight = mRawImage->getHeight(); + if (!mNeedsCreateTexture) + { + destroyRawImage(); + return FALSE; + } + mNeedsCreateTexture = false; + + if (mRawImage.isNull()) + { + LL_ERRS() << "LLViewerTexture trying to create texture with no Raw Image" << LL_ENDL; + } + if (mRawImage->isBufferInvalid()) + { + LL_WARNS() << "Can't create a texture: invalid image data" << LL_ENDL; + destroyRawImage(); + return FALSE; + } + // LL_INFOS() << llformat("IMAGE Creating (%d) [%d x %d] Bytes: %d ", + // mRawDiscardLevel, + // mRawImage->getWidth(), mRawImage->getHeight(),mRawImage->getDataSize()) + // << mID.getString() << LL_ENDL; + BOOL res = TRUE; + + // store original size only for locally-sourced images + if (mUrl.compare(0, 7, "file://") == 0) + { + mOrigWidth = mRawImage->getWidth(); + mOrigHeight = mRawImage->getHeight(); // This is only safe because it's a local image and fetcher doesn't use raw data // from local images, but this might become unsafe in case of changes to fetcher - if (mBoostLevel == BOOST_PREVIEW) - { - mRawImage->biasedScaleToPowerOfTwo(1024); - } - else - { // leave black border, do not scale image content - mRawImage->expandToPowerOfTwo(MAX_IMAGE_SIZE, FALSE); - } - - mFullWidth = mRawImage->getWidth(); - mFullHeight = mRawImage->getHeight(); - setTexelsPerImage(); - } - else - { - mOrigWidth = mFullWidth; - mOrigHeight = mFullHeight; - } + if (mBoostLevel == BOOST_PREVIEW) + { + mRawImage->biasedScaleToPowerOfTwo(1024); + } + else + { // leave black border, do not scale image content + mRawImage->expandToPowerOfTwo(MAX_IMAGE_SIZE, FALSE); + } + + mFullWidth = mRawImage->getWidth(); + mFullHeight = mRawImage->getHeight(); + setTexelsPerImage(); + } + else + { + mOrigWidth = mFullWidth; + mOrigHeight = mFullHeight; + } if (!mRawImage->mComment.empty()) { @@ -1557,43 +1569,43 @@ BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/) } } - bool size_okay = true; + bool size_okay = true; - S32 discard_level = mRawDiscardLevel; - if (mRawDiscardLevel < 0) - { + S32 discard_level = mRawDiscardLevel; + if (mRawDiscardLevel < 0) + { #ifdef SHOW_DEBUG - LL_DEBUGS() << "Negative raw discard level when creating image: " << mRawDiscardLevel << LL_ENDL; + LL_DEBUGS() << "Negative raw discard level when creating image: " << mRawDiscardLevel << LL_ENDL; #endif - discard_level = 0; - } + discard_level = 0; + } - U32 raw_width = mRawImage->getWidth() << discard_level; - U32 raw_height = mRawImage->getHeight() << discard_level; + U32 raw_width = mRawImage->getWidth() << discard_level; + U32 raw_height = mRawImage->getHeight() << discard_level; - if( raw_width > MAX_IMAGE_SIZE || raw_height > MAX_IMAGE_SIZE ) - { - LL_INFOS() << "Width or height is greater than " << MAX_IMAGE_SIZE << ": (" << raw_width << "," << raw_height << ")" << LL_ENDL; - size_okay = false; - } - - if (!LLImageGL::checkSize(mRawImage->getWidth(), mRawImage->getHeight())) - { - // A non power-of-two image was uploaded (through a non standard client) - LL_INFOS() << "Non power of two width or height: (" << mRawImage->getWidth() << "," << mRawImage->getHeight() << ")" << LL_ENDL; - size_okay = false; - } - - if( !size_okay ) - { - // An inappropriately-sized image was uploaded (through a non standard client) - // We treat these images as missing assets which causes them to - // be renderd as 'missing image' and to stop requesting data - LL_WARNS() << "!size_ok, setting as missing" << LL_ENDL; - setIsMissingAsset(); - destroyRawImage(); - return FALSE; - } + if (raw_width > MAX_IMAGE_SIZE || raw_height > MAX_IMAGE_SIZE) + { + LL_INFOS() << "Width or height is greater than " << MAX_IMAGE_SIZE << ": (" << raw_width << "," << raw_height << ")" << LL_ENDL; + size_okay = false; + } + + if (!LLImageGL::checkSize(mRawImage->getWidth(), mRawImage->getHeight())) + { + // A non power-of-two image was uploaded (through a non standard client) + LL_INFOS() << "Non power of two width or height: (" << mRawImage->getWidth() << "," << mRawImage->getHeight() << ")" << LL_ENDL; + size_okay = false; + } + + if (!size_okay) + { + // An inappropriately-sized image was uploaded (through a non standard client) + // We treat these images as missing assets which causes them to + // be renderd as 'missing image' and to stop requesting data + LL_WARNS() << "!size_ok, setting as missing" << LL_ENDL; + setIsMissingAsset(); + destroyRawImage(); + return FALSE; + } if (mGLTexturep->getHasExplicitFormat()) { @@ -1615,19 +1627,116 @@ BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/) } } - res = mGLTexturep->createGLTexture(mRawDiscardLevel, mRawImage, usename, TRUE, mBoostLevel); + return res; +} - notifyAboutCreatingTexture(); +BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/) +{ + if (!mNeedsCreateTexture) + { + return FALSE; + } - setActive(); + BOOL res = mGLTexturep->createGLTexture(mRawDiscardLevel, mRawImage, usename, TRUE, mBoostLevel); + + return res; +} - if (!needsToSaveRawImage()) - { - mNeedsAux = FALSE; - destroyRawImage(); - } +void LLViewerFetchedTexture::postCreateTexture() +{ + if (!mNeedsCreateTexture) + { + return; + } +#if LL_IMAGEGL_THREAD_CHECK + mGLTexturep->checkActiveThread(); +#endif - return res; + notifyAboutCreatingTexture(); + + setActive(); + + if (!needsToSaveRawImage()) + { + mNeedsAux = FALSE; + destroyRawImage(); + } + + mNeedsCreateTexture = false; +} + +void LLViewerFetchedTexture::scheduleCreateTexture() +{ + if (!mNeedsCreateTexture) + { + mNeedsCreateTexture = true; + if (preCreateTexture()) + { +#if LL_IMAGEGL_THREAD_CHECK + //grab a copy of the raw image data to make sure it isn't modified pending texture creation + U8* data = mRawImage->getData(); + U8* data_copy = nullptr; + S32 size = mRawImage->getDataSize(); + if (data != nullptr && size > 0) + { + data_copy = new U8[size]; + memcpy(data_copy, data, size); + } +#endif + mNeedsCreateTexture = true; + auto mainq = LLImageGLThread::sEnabled ? mMainQueue.lock() : nullptr; + if (mainq) + { + ref(); + mainq->postTo( + mImageQueue, + // work to be done on LLImageGL worker thread +#if LL_IMAGEGL_THREAD_CHECK + [this, data, data_copy, size]() + { + mGLTexturep->mActiveThread = LLThread::currentID(); + //verify data is unmodified + llassert(data == mRawImage->getData()); + llassert(mRawImage->getDataSize() == size); + llassert(memcmp(data, data_copy, size) == 0); +#else + [this]() + { +#endif + //actually create the texture on a background thread + createTexture(); + +#if LL_IMAGEGL_THREAD_CHECK + //verify data is unmodified + llassert(data == mRawImage->getData()); + llassert(mRawImage->getDataSize() == size); + llassert(memcmp(data, data_copy, size) == 0); +#endif + }, + // callback to be run on main thread +#if LL_IMAGEGL_THREAD_CHECK + [this, data, data_copy, size]() + { + mGLTexturep->mActiveThread = LLThread::currentID(); + llassert(data == mRawImage->getData()); + llassert(mRawImage->getDataSize() == size); + llassert(memcmp(data, data_copy, size) == 0); + delete[] data_copy; +#else + [this]() + { +#endif + //finalize on main thread + postCreateTexture(); + unref(); + }); + } + else + { + gTextureList.mCreateTextureList.insert(this); + } + } + } } // Call with 0,0 to turn this feature off. @@ -1919,6 +2028,7 @@ void LLViewerFetchedTexture::setAdditionalDecodePriority(F32 priority) void LLViewerFetchedTexture::updateVirtualSize() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; if(!mMaxVirtualSizeResetCounter) { addTextureStats(0.f, FALSE);//reset @@ -2010,6 +2120,7 @@ bool LLViewerFetchedTexture::isActiveFetching() bool LLViewerFetchedTexture::updateFetch() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; static LLCachedControl<bool> textures_decode_disabled(gSavedSettings,"TextureDecodeDisabled", false); static LLCachedControl<F32> sCameraMotionThreshold(gSavedSettings,"TextureCameraMotionThreshold", 0.2f); static LLCachedControl<S32> sCameraMotionBoost(gSavedSettings,"TextureCameraMotionBoost", 3); @@ -2112,7 +2223,7 @@ bool LLViewerFetchedTexture::updateFetch() } else { - mIsRawImageValid = TRUE; + mIsRawImageValid = TRUE; addToCreateTexture(); } @@ -2639,6 +2750,7 @@ void LLViewerFetchedTexture::pauseLoadedCallbacks(const LLLoadedCallbackEntry::s bool LLViewerFetchedTexture::doLoadedCallbacks() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; static const F32 MAX_INACTIVE_TIME = 900.f ; //seconds static const F32 MAX_IDLE_WAIT_TIME = 5.f ; //seconds @@ -2989,7 +3101,9 @@ void LLViewerFetchedTexture::destroyRawImage() //virtual void LLViewerFetchedTexture::switchToCachedImage() { - if(mCachedRawImage.notNull()) + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; + if(mCachedRawImage.notNull() && + !mNeedsCreateTexture) // <--- texture creation is pending, don't step on it { mRawImage = mCachedRawImage; @@ -3000,12 +3114,12 @@ void LLViewerFetchedTexture::switchToCachedImage() mComponents = mRawImage->getComponents(); mGLTexturep->setComponents(mComponents); gTextureList.dirtyImage(this); - } + } mIsRawImageValid = TRUE; mRawDiscardLevel = mCachedRawDiscardLevel; - gTextureList.mCreateTextureList.insert(this); - mNeedsCreateTexture = TRUE; + + scheduleCreateTexture(); } } @@ -3302,6 +3416,7 @@ bool LLViewerLODTexture::isUpdateFrozen() //virtual void LLViewerLODTexture::processTextureStats() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; updateVirtualSize(); static LLCachedControl<bool> textures_fullres(gSavedSettings,"TextureLoadFullRes", false); @@ -3465,6 +3580,7 @@ bool LLViewerLODTexture::scaleDown() //static void LLViewerMediaTexture::updateClass() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; static const F32 MAX_INACTIVE_TIME = 30.f; #if 0 @@ -3600,7 +3716,7 @@ void LLViewerMediaTexture::setMediaImpl() { if(!mMediaImplp) { - mMediaImplp = LLViewerMedia::getInstanceFast()->getMediaImplFromTextureID(mID); + mMediaImplp = LLViewerMedia::getInstance()->getMediaImplFromTextureID(mID); } } diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index 1bb1675889269ea75808311c6f8ce8621cd1fda3..fdd5dfdcec70673b98e6b3c8d702f37379f6b17e 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -27,6 +27,7 @@ #ifndef LL_LLVIEWERTEXTURE_H #define LL_LLVIEWERTEXTURE_H +#include "llatomic.h" #include "llgltexture.h" #include "lltimer.h" #include "llframetimer.h" @@ -35,6 +36,7 @@ #include "llrender.h" #include "llmetricperformancetester.h" #include "httpcommon.h" +#include "workqueue.h" #include <map> #include <list> @@ -113,7 +115,7 @@ class LLViewerTexture : public LLGLTexture public: static void initClass(); - static void updateClass(const F32 velocity, const F32 angular_velocity) ; + static void updateClass(); LLViewerTexture(BOOL usemipmaps = TRUE); LLViewerTexture(const LLUUID& id, BOOL usemipmaps) ; @@ -212,6 +214,9 @@ class LLViewerTexture : public LLGLTexture //do not use LLPointer here. LLViewerMediaTexture* mParcelMedia ; + LL::WorkQueue::weak_t mMainQueue; + LL::WorkQueue::weak_t mImageQueue; + static F32 sTexelPixelRatio; public: static const U32 sCurrentFileVersion; @@ -322,9 +327,13 @@ class LLViewerFetchedTexture : public LLViewerTexture void addToCreateTexture(); - - // ONLY call from LLViewerTextureList + //call to determine if createTexture is necessary + BOOL preCreateTexture(S32 usename = 0); + // ONLY call from LLViewerTextureList or ImageGL background thread BOOL createTexture(S32 usename = 0); + void postCreateTexture(); + void scheduleCreateTexture(); + void destroyTexture() ; virtual void processTextureStats() ; @@ -525,7 +534,7 @@ class LLViewerFetchedTexture : public LLViewerTexture LLFrameTimer mStopFetchingTimer; // Time since mDecodePriority == 0.f. BOOL mInImageList; // TRUE if image is in list (in which case don't reset priority!) - BOOL mNeedsCreateTexture; + LLAtomicBool mNeedsCreateTexture; BOOL mForSculpt ; //a flag if the texture is used as sculpt data. BOOL mIsFetched ; //is loaded from remote or from cache, not generated locally. diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index e3dc509a1314637498c941ecff1c8bbd5e9770e8..b39816b781702700a640768889a0690cc091980c 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -65,7 +65,6 @@ void (*LLViewerTextureList::sUUIDCallback)(void **, const LLUUID&) = NULL; S32 LLViewerTextureList::sNumImages = 0; LLViewerTextureList gTextureList; -static LLTrace::BlockTimerStatHandle FTM_PROCESS_IMAGES("Process Images"); ETexListType get_element_type(S32 priority) { @@ -111,6 +110,7 @@ void LLViewerTextureList::init() void LLViewerTextureList::doPreloadImages() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; LL_DEBUGS("ViewerImages") << "Preloading images..." << LL_ENDL; llassert_always(mInitialized) ; @@ -211,6 +211,7 @@ static std::string get_texture_list_name() void LLViewerTextureList::doPrefetchImages() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; gTextureTimer.start(); gTextureTimer.pause(); @@ -269,6 +270,7 @@ LLViewerTextureList::~LLViewerTextureList() void LLViewerTextureList::shutdown() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; // clear out preloads mImagePreloads.clear(); @@ -345,6 +347,7 @@ void LLViewerTextureList::shutdown() void LLViewerTextureList::dump() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; LL_INFOS() << "LLViewerTextureList::dump()" << LL_ENDL; for (LLViewerFetchedTexture* image : mImageList) { @@ -388,6 +391,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromFile(const std::string& LLGLenum primary_format, const LLUUID& force_id) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; if(!mInitialized) { return NULL ; @@ -415,6 +419,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromUrl(const std::string& LLGLenum primary_format, const LLUUID& force_id) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; if(!mInitialized) { return NULL ; @@ -504,6 +509,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id, LLGLenum primary_format, LLHost request_from_host) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; if(!mInitialized) { return NULL ; @@ -566,6 +572,7 @@ LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id, LLGLenum primary_format, LLHost request_from_host) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; static LLCachedControl<bool> fast_cache_fetching_enabled(gSavedSettings, "FastCacheFetchEnabled", true); LLPointer<LLViewerFetchedTexture> imagep ; @@ -621,6 +628,7 @@ LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id, void LLViewerTextureList::findTexturesByID(const LLUUID &image_id, std::vector<LLViewerFetchedTexture*> &output) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; LLTextureKey search_key(image_id, TEX_LIST_STANDARD); uuid_map_t::iterator iter = mUUIDMap.lower_bound(search_key); while (iter != mUUIDMap.end() && iter->first.textureId == image_id) @@ -632,6 +640,7 @@ void LLViewerTextureList::findTexturesByID(const LLUUID &image_id, std::vector<L LLViewerFetchedTexture *LLViewerTextureList::findImage(const LLTextureKey &search_key) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; auto iter = mUUIDHashMap.find(search_key); if (iter == mUUIDHashMap.cend()) return NULL; @@ -645,6 +654,7 @@ LLViewerFetchedTexture *LLViewerTextureList::findImage(const LLUUID &image_id, E void LLViewerTextureList::addImageToList(LLViewerFetchedTexture *image) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; assert_main_thread(); llassert_always(mInitialized) ; llassert(image); @@ -664,6 +674,7 @@ void LLViewerTextureList::addImageToList(LLViewerFetchedTexture *image) void LLViewerTextureList::removeImageFromList(LLViewerFetchedTexture *image) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; assert_main_thread(); llassert_always(mInitialized) ; llassert(image); @@ -712,6 +723,7 @@ void LLViewerTextureList::removeImageFromList(LLViewerFetchedTexture *image) void LLViewerTextureList::addImage(LLViewerFetchedTexture *new_image, ETexListType tex_type) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; if (!new_image) { return; @@ -736,6 +748,7 @@ void LLViewerTextureList::addImage(LLViewerFetchedTexture *new_image, ETexListTy void LLViewerTextureList::deleteImage(LLViewerFetchedTexture *image) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; if( image) { if (image->hasCallbacks()) @@ -761,18 +774,10 @@ void LLViewerTextureList::dirtyImage(LLViewerFetchedTexture *image) } //////////////////////////////////////////////////////////////////////////// -static LLTrace::BlockTimerStatHandle FTM_IMAGE_MARK_DIRTY("Dirty Images"); -static LLTrace::BlockTimerStatHandle FTM_IMAGE_UPDATE_PRIORITIES("Prioritize"); -static LLTrace::BlockTimerStatHandle FTM_IMAGE_CALLBACKS("Callbacks"); -static LLTrace::BlockTimerStatHandle FTM_IMAGE_FETCH("Fetch"); -static LLTrace::BlockTimerStatHandle FTM_FAST_CACHE_IMAGE_FETCH("Fast Cache Fetch"); -static LLTrace::BlockTimerStatHandle FTM_IMAGE_CREATE("Create"); -static LLTrace::BlockTimerStatHandle FTM_IMAGE_STATS("Stats"); -static LLTrace::BlockTimerStatHandle FTM_UPDATE_TEXTURES("Update Textures"); void LLViewerTextureList::updateImages(F32 max_time) { - LL_RECORD_BLOCK_TIME(FTM_UPDATE_TEXTURES); + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; static BOOL cleared = FALSE; if(gTeleportDisplay) { @@ -798,66 +803,49 @@ void LLViewerTextureList::updateImages(F32 max_time) sample(FORMATTED_MEM, F64Bytes(LLImageFormatted::sGlobalFormattedMemory)); } - { - //loading from fast cache - LL_RECORD_BLOCK_TIME(FTM_FAST_CACHE_IMAGE_FETCH); - max_time -= updateImagesLoadingFastCache(max_time); - } - - { - LL_RECORD_BLOCK_TIME(FTM_IMAGE_UPDATE_PRIORITIES); - updateImagesDecodePriorities(); - } - - F32 total_max_time = max_time; - - { - LL_RECORD_BLOCK_TIME(FTM_IMAGE_FETCH); - max_time -= updateImagesFetchTextures(max_time); - } + //loading from fast cache + max_time -= updateImagesLoadingFastCache(max_time); - { - LL_RECORD_BLOCK_TIME(FTM_IMAGE_CREATE); - max_time = llmax(max_time, total_max_time*.50f); // at least 50% of max_time - max_time -= updateImagesCreateTextures(max_time); - } + updateImagesDecodePriorities(); + + F32 total_max_time = max_time; + + max_time -= updateImagesFetchTextures(max_time); + + max_time = llmax(max_time, total_max_time*.50f); // at least 50% of max_time + max_time -= updateImagesCreateTextures(max_time); if (!mDirtyTextureList.empty()) { - LL_RECORD_BLOCK_TIME(FTM_IMAGE_MARK_DIRTY); gPipeline.dirtyPoolObjectTextures(mDirtyTextureList); mDirtyTextureList.clear(); } + bool didone = false; + for (image_list_t::iterator iter = mCallbackList.begin(); + iter != mCallbackList.end(); ) { - LL_RECORD_BLOCK_TIME(FTM_IMAGE_CALLBACKS); - bool didone = false; - for (image_list_t::iterator iter = mCallbackList.begin(); - iter != mCallbackList.end(); ) + //trigger loaded callbacks on local textures immediately + LLViewerFetchedTexture* image = *iter++; + if (!image->getUrl().empty()) { - //trigger loaded callbacks on local textures immediately - LLViewerFetchedTexture* image = *iter++; - if (!image->getUrl().empty()) - { - // Do stuff to handle callbacks, update priorities, etc. - didone = image->doLoadedCallbacks(); - } - else if (!didone) - { - // Do stuff to handle callbacks, update priorities, etc. - didone = image->doLoadedCallbacks(); - } + // Do stuff to handle callbacks, update priorities, etc. + didone = image->doLoadedCallbacks(); + } + else if (!didone) + { + // Do stuff to handle callbacks, update priorities, etc. + didone = image->doLoadedCallbacks(); } } + - { - LL_RECORD_BLOCK_TIME(FTM_IMAGE_STATS); - updateImagesUpdateStats(); - } + updateImagesUpdateStats(); } void LLViewerTextureList::clearFetchingRequests() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; if (LLAppViewer::getTextureFetch()->getNumRequests() == 0) { return; @@ -873,6 +861,7 @@ void LLViewerTextureList::clearFetchingRequests() void LLViewerTextureList::updateImagesDecodePriorities() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; // Update the decode priority for N images each frame { F32 lazy_flush_timeout = 30.f; // stop decoding @@ -988,6 +977,7 @@ void LLViewerTextureList::updateImagesDecodePriorities() void LLViewerTextureList::setDebugFetching(LLViewerFetchedTexture* tex, S32 debug_level) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; if(!tex->setDebugFetching(debug_level)) { return; @@ -1036,6 +1026,7 @@ void LLViewerTextureList::setDebugFetching(LLViewerFetchedTexture* tex, S32 debu F32 LLViewerTextureList::updateImagesCreateTextures(F32 max_time) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; if (gGLManager.mIsDisabled) return 0.0f; // @@ -1052,6 +1043,7 @@ F32 LLViewerTextureList::updateImagesCreateTextures(F32 max_time) enditer = iter; LLViewerFetchedTexture *imagep = *curiter; imagep->createTexture(); + imagep->postCreateTexture(); if (create_timer.getElapsedTimeF32() > max_time) { break; @@ -1063,6 +1055,7 @@ F32 LLViewerTextureList::updateImagesCreateTextures(F32 max_time) F32 LLViewerTextureList::updateImagesLoadingFastCache(F32 max_time) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; if (gGLManager.mIsDisabled) return 0.0f; if(mFastCacheList.empty()) { @@ -1093,6 +1086,7 @@ F32 LLViewerTextureList::updateImagesLoadingFastCache(F32 max_time) void LLViewerTextureList::forceImmediateUpdate(LLViewerFetchedTexture* imagep) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; if(!imagep) { return ; @@ -1112,6 +1106,7 @@ void LLViewerTextureList::forceImmediateUpdate(LLViewerFetchedTexture* imagep) F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; LLTimer image_op_timer; // Update fetch for N images each frame @@ -1164,15 +1159,14 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time) total_update_count--; } } - - S32 fetch_count = 0; + size_t min_update_count = llmin(MIN_UPDATE_COUNT,(S32)(entries.size()-max_priority_count)); S32 min_count = max_priority_count + min_update_count; for (entries_list_t::iterator iter3 = entries.begin(); iter3 != entries.end(); ) { LLViewerFetchedTexture* imagep = *iter3++; - fetch_count += (imagep->updateFetch() ? 1 : 0); + imagep->updateFetch(); if (min_count <= min_update_count) { mLastFetchKey = LLTextureKey(imagep->getID(), (ETexListType)imagep->getTextureListType()); @@ -1187,6 +1181,7 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time) void LLViewerTextureList::updateImagesUpdateStats() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; if (mForceResetTextureStats) { for (image_priority_list_t::iterator iter = mImageList.begin(); @@ -1201,6 +1196,7 @@ void LLViewerTextureList::updateImagesUpdateStats() void LLViewerTextureList::decodeAllImages(F32 max_time) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; LLTimer timer; //loading from fast cache @@ -1234,6 +1230,7 @@ void LLViewerTextureList::decodeAllImages(F32 max_time) LLViewerFetchedTexture* imagep = *iter++; imagep->updateFetch(); } + std::shared_ptr<LL::WorkQueue> main_queue = LLImageGLThread::sEnabled ? LL::WorkQueue::getInstance("mainloop") : NULL; // Run threads S32 fetch_pending = 0; while (1) @@ -1241,6 +1238,13 @@ void LLViewerTextureList::decodeAllImages(F32 max_time) LLAppViewer::instance()->getTextureCache()->update(1); // unpauses the texture cache thread LLAppViewer::instance()->getImageDecodeThread()->update(1); // unpauses the image thread fetch_pending = LLAppViewer::instance()->getTextureFetch()->update(1); // unpauses the texture fetch thread + + if (LLImageGLThread::sEnabled) + { + main_queue->runFor(std::chrono::milliseconds(1)); + fetch_pending += main_queue->size(); + } + if (fetch_pending == 0 || timer.getElapsedTimeF32() > max_time) { break; @@ -1271,8 +1275,10 @@ void LLViewerTextureList::decodeAllImages(F32 max_time) BOOL LLViewerTextureList::createUploadFile(const std::string& filename, const std::string& out_filename, - const U8 codec) + const U8 codec, + const S32 max_image_dimentions) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; // Load the image LLPointer<LLImageFormatted> image = LLImageFormatted::createFromType(codec); if (image.isNull()) @@ -1299,7 +1305,7 @@ BOOL LLViewerTextureList::createUploadFile(const std::string& filename, return FALSE; } // Convert to j2c (JPEG2000) and save the file locally - LLPointer<LLImageJ2C> compressedImage = convertToUploadFile(raw_image); + LLPointer<LLImageJ2C> compressedImage = convertToUploadFile(raw_image, max_image_dimentions); if (compressedImage.isNull()) { image->setLastError("Couldn't convert the image to jpeg2000."); @@ -1324,9 +1330,10 @@ BOOL LLViewerTextureList::createUploadFile(const std::string& filename, } // note: modifies the argument raw_image!!!! -LLPointer<LLImageJ2C> LLViewerTextureList::convertToUploadFile(LLPointer<LLImageRaw> raw_image) +LLPointer<LLImageJ2C> LLViewerTextureList::convertToUploadFile(LLPointer<LLImageRaw> raw_image, const S32 max_image_dimentions) { - raw_image->biasedScaleToPowerOfTwo(LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; + raw_image->biasedScaleToPowerOfTwo(max_image_dimentions); LLPointer<LLImageJ2C> compressedImage = new LLImageJ2C(); if (gSavedSettings.getBOOL("LosslessJ2CUpload") && @@ -1359,6 +1366,7 @@ LLPointer<LLImageJ2C> LLViewerTextureList::convertToUploadFile(LLPointer<LLImage // Returns min setting for TextureMemory (in MB) S32Megabytes LLViewerTextureList::getMinVideoRamSetting() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; U32Megabytes system_ram = gSysMemory.getPhysicalMemoryKB(); //min texture mem sets to 64M if total physical mem is more than 1.5GB return (system_ram > U32Megabytes(1500)) ? S32Megabytes(64) : gMinVideoRam ; @@ -1368,6 +1376,7 @@ S32Megabytes LLViewerTextureList::getMinVideoRamSetting() // Returns max setting for TextureMemory (in MB) S32Megabytes LLViewerTextureList::getMaxVideoRamSetting(bool get_recommended, float mem_multiplier) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; S32Megabytes max_texmem; if (gGLManager.mVRAM != 0) { @@ -1375,7 +1384,7 @@ S32Megabytes LLViewerTextureList::getMaxVideoRamSetting(bool get_recommended, fl // - it's going to be swapping constantly regardless S32Megabytes max_vram(gGLManager.mVRAM); - if(gGLManager.mIsATI) + if(gGLManager.mIsAMD) { //shrink the availabe vram for ATI cards because some of them do not handel texture swapping well. max_vram = max_vram * 0.75f; @@ -1448,6 +1457,7 @@ const S32Megabytes VIDEO_CARD_FRAMEBUFFER_MEM(12); const S32Megabytes MIN_MEM_FOR_NON_TEXTURE(512); void LLViewerTextureList::updateMaxResidentTexMem(S32Megabytes mem) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; // Initialize the image pipeline VRAM settings S32Megabytes cur_mem(gSavedSettings.getS32("TextureMemory")); F32 mem_multiplier = gSavedSettings.getF32("RenderTextureMemoryMultiple"); @@ -1523,8 +1533,8 @@ void LLViewerTextureList::receiveImageHeader(LLMessageSystem *msg, void **user_d { static LLCachedControl<bool> log_texture_traffic(gSavedSettings,"LogTextureNetworkTraffic", false) ; - LL_RECORD_BLOCK_TIME(FTM_PROCESS_IMAGES); - + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; + // Receive image header, copy into image object and decompresses // if this is a one-packet image. @@ -1595,7 +1605,7 @@ void LLViewerTextureList::receiveImagePacket(LLMessageSystem *msg, void **user_d { static LLCachedControl<bool> log_texture_traffic(gSavedSettings,"LogTextureNetworkTraffic", false) ; - LL_RECORD_BLOCK_TIME(FTM_PROCESS_IMAGES); + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; // Receives image packet, copy into image object, // checks if all packets received, decompresses if so. @@ -1668,7 +1678,7 @@ void LLViewerTextureList::receiveImagePacket(LLMessageSystem *msg, void **user_d // static void LLViewerTextureList::processImageNotInDatabase(LLMessageSystem *msg,void **user_data) { - LL_RECORD_BLOCK_TIME(FTM_PROCESS_IMAGES); + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; LLUUID image_id; msg->getUUIDFast(_PREHASH_ImageID, _PREHASH_ID, image_id); @@ -1701,6 +1711,7 @@ void LLUIImageList::cleanUp() LLUIImagePtr LLUIImageList::getUIImageByID(const LLUUID& image_id, S32 priority) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; // use id as image name std::string image_name = image_id.asString(); @@ -1719,6 +1730,7 @@ LLUIImagePtr LLUIImageList::getUIImageByID(const LLUUID& image_id, S32 priority) LLUIImagePtr LLUIImageList::getUIImage(const std::string& image_name, S32 priority) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; // look for existing image uuid_ui_image_map_t::iterator found_it = mUIImages.find(image_name); if (found_it != mUIImages.end()) @@ -1736,6 +1748,7 @@ LLUIImagePtr LLUIImageList::loadUIImageByName(const std::string& name, const std BOOL use_mips, const LLRect& scale_rect, const LLRect& clip_rect, LLViewerTexture::EBoostLevel boost_priority, LLUIImage::EScaleStyle scale_style) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; if (boost_priority == LLGLTexture::BOOST_NONE) { boost_priority = LLGLTexture::BOOST_UI; @@ -1748,6 +1761,7 @@ LLUIImagePtr LLUIImageList::loadUIImageByID(const LLUUID& id, BOOL use_mips, const LLRect& scale_rect, const LLRect& clip_rect, LLViewerTexture::EBoostLevel boost_priority, LLUIImage::EScaleStyle scale_style) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; if (boost_priority == LLGLTexture::BOOST_NONE) { boost_priority = LLGLTexture::BOOST_UI; @@ -1759,6 +1773,7 @@ LLUIImagePtr LLUIImageList::loadUIImageByID(const LLUUID& id, LLUIImagePtr LLUIImageList::loadUIImage(LLViewerFetchedTexture* imagep, const std::string& name, BOOL use_mips, const LLRect& scale_rect, const LLRect& clip_rect, LLUIImage::EScaleStyle scale_style) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; if (!imagep) return NULL; imagep->setAddressMode(LLTexUnit::TAM_CLAMP); @@ -1796,6 +1811,7 @@ LLUIImagePtr LLUIImageList::loadUIImage(LLViewerFetchedTexture* imagep, const st LLUIImagePtr LLUIImageList::preloadUIImage(const std::string& name, const std::string& filename, BOOL use_mips, const LLRect& scale_rect, const LLRect& clip_rect, LLUIImage::EScaleStyle scale_style) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; // look for existing image uuid_ui_image_map_t::iterator found_it = mUIImages.find(name); if (found_it != mUIImages.end()) @@ -1810,6 +1826,7 @@ LLUIImagePtr LLUIImageList::preloadUIImage(const std::string& name, const std::s //static void LLUIImageList::onUIImageLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* user_data ) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; if(!success || !user_data) { return; @@ -1911,6 +1928,7 @@ struct UIImageDeclarations : public LLInitParam::Block<UIImageDeclarations> bool LLUIImageList::initFromFile() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; // Look for textures.xml in all the right places. Pass // constraint=LLDir::ALL_SKINS because we want to overlay textures.xml // from all the skins directories. @@ -1985,9 +2003,18 @@ bool LLUIImageList::initFromFile() preloadUIImage(image.name, file_name, image.use_mips, image.scale, image.clip, image.scale_type); } - if (cur_pass == PASS_DECODE_NOW && !gSavedSettings.getBOOL("NoPreload")) + if (!gSavedSettings.getBOOL("NoPreload")) { - gTextureList.decodeAllImages(10.f); // decode preloaded images + if (cur_pass == PASS_DECODE_NOW) + { + // init fetching and decoding of preloaded images + gTextureList.decodeAllImages(9.f); + } + else + { + // decodeAllImages needs two passes to refresh stats and priorities on second pass + gTextureList.decodeAllImages(1.f); + } } } return true; diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h index feb9bc0c6866f5f256d1f82a681874867de80857..85f5d1064aa1f1f2b6e29ff553ec63aa21ef4516 100644 --- a/indra/newview/llviewertexturelist.h +++ b/indra/newview/llviewertexturelist.h @@ -105,8 +105,11 @@ class LLViewerTextureList friend class LLLocalBitmap; public: - static BOOL createUploadFile(const std::string& filename, const std::string& out_filename, const U8 codec); - static LLPointer<LLImageJ2C> convertToUploadFile(LLPointer<LLImageRaw> raw_image); + static BOOL createUploadFile(const std::string& filename, + const std::string& out_filename, + const U8 codec, + const S32 max_image_dimentions = LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); + static LLPointer<LLImageJ2C> convertToUploadFile(LLPointer<LLImageRaw> raw_image, const S32 max_image_dimentions = LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); static void processImageNotInDatabase( LLMessageSystem *msg, void **user_data ); static void receiveImageHeader(LLMessageSystem *msg, void **user_data); static void receiveImagePacket(LLMessageSystem *msg, void **user_data); diff --git a/indra/newview/llviewerwearable.cpp b/indra/newview/llviewerwearable.cpp index 7e233291fb0d686b3d7195038e802e1f501b1abb..ac291bf93cd545ef82ad96b7f8b77e18888b14a9 100644 --- a/indra/newview/llviewerwearable.cpp +++ b/indra/newview/llviewerwearable.cpp @@ -567,7 +567,7 @@ void LLViewerWearable::saveNewAsset() const void LLViewerWearable::onSaveNewAssetComplete(const LLUUID& new_asset_id, void* userdata, S32 status, LLExtStat ext_status) // StoreAssetData callback (fixed) { LLWearableSaveData* data = (LLWearableSaveData*)userdata; - const std::string& type_name = LLWearableType::getInstanceFast()->getTypeName(data->mType); + const std::string& type_name = LLWearableType::getInstance()->getTypeName(data->mType); if(0 == status) { // Success @@ -593,7 +593,7 @@ void LLViewerWearable::onSaveNewAssetComplete(const LLUUID& new_asset_id, void* std::ostream& operator<<(std::ostream &s, const LLViewerWearable &w) { - s << "wearable " << LLWearableType::getInstanceFast()->getTypeName(w.mType) << "\n"; + s << "wearable " << LLWearableType::getInstance()->getTypeName(w.mType) << "\n"; s << " Name: " << w.mName << "\n"; s << " Desc: " << w.mDescription << "\n"; //w.mPermissions diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 85be40f3ca06e37dad669e5d6447638031312e9e..06b1eb0e927fcc8d28262b6a1bb474f50c4b98b5 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -103,7 +103,6 @@ #include "llfilepicker.h" #include "llfirstuse.h" #include "llfloater.h" -#include "llfloaterbuildoptions.h" #include "llfloaterbuyland.h" #include "llfloatercamera.h" #include "llfloaterland.h" @@ -522,8 +521,8 @@ class LLDebugText static LLCachedControl<bool> analyze_target_texture(gSavedSettings, "AnalyzeTargetTexture", false); if (analyze_target_texture) { - LLSelectNode* nodep = LLSelectMgr::instanceFast().getPrimaryHoverNode(); - LLObjectSelectionHandle handle = LLSelectMgr::instanceFast().getHoverObjects(); + LLSelectNode* nodep = LLSelectMgr::instance().getPrimaryHoverNode(); + LLObjectSelectionHandle handle = LLSelectMgr::instance().getHoverObjects(); if (nodep || handle.notNull()) { @@ -668,12 +667,6 @@ class LLDebugText { LLTrace::Recording& last_frame_recording = LLTrace::get_frame_recording().getLastRecording(); - if (gPipeline.getUseVertexShaders() == 0) - { - addText(xpos, ypos, "Shaders Disabled"); - ypos += y_inc; - } - if (gGLManager.mHasATIMemInfo) { S32 meminfo[4]; @@ -707,7 +700,7 @@ class LLDebugText S32 visible_bytes = 0; const char* label = "Region"; - if (LLSelectMgr::getInstanceFast()->getSelection()->getObjectCount() == 0) + if (LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 0) { //region LLViewerRegion* region = gAgent.getRegion(); if (region) @@ -742,9 +735,9 @@ class LLDebugText else { label = "Selection"; - cost = LLSelectMgr::getInstanceFast()->getSelection()->getSelectedObjectStreamingCost(&total_bytes, &visible_bytes); - count = LLSelectMgr::getInstanceFast()->getSelection()->getSelectedObjectTriangleCount(&vcount); - object_count = LLSelectMgr::getInstanceFast()->getSelection()->getObjectCount(); + cost = LLSelectMgr::getInstance()->getSelection()->getSelectedObjectStreamingCost(&total_bytes, &visible_bytes); + count = LLSelectMgr::getInstance()->getSelection()->getSelectedObjectTriangleCount(&vcount); + object_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount(); } addText(xpos,ypos, llformat("%s streaming cost: %.1f", label, cost)); @@ -838,6 +831,12 @@ class LLDebugText ypos += y_inc; addText(xpos, ypos, llformat("%.3f/%.3f MB Mesh Cache Read/Write ", LLMeshRepository::sCacheBytesRead/(1024.f*1024.f), LLMeshRepository::sCacheBytesWritten/(1024.f*1024.f))); + ypos += y_inc; + + addText(xpos, ypos, llformat("%.3f/%.3f MB Mesh Skins/Decompositions Memory", LLMeshRepository::sCacheBytesSkins / (1024.f*1024.f), LLMeshRepository::sCacheBytesDecomps / (1024.f*1024.f))); + ypos += y_inc; + + addText(xpos, ypos, llformat("%.3f MB Mesh Headers Memory", LLMeshRepository::sCacheBytesHeaders / (1024.f*1024.f))); ypos += y_inc; } @@ -1007,7 +1006,7 @@ class LLDebugText { LLViewerObject* objectp = NULL ; - LLSelectNode* nodep = LLSelectMgr::instanceFast().getHoverNode(); + LLSelectNode* nodep = LLSelectMgr::instance().getHoverNode(); if (nodep) { objectp = nodep->getObject(); @@ -1102,12 +1101,12 @@ LLViewerWindow::Params::Params() void LLViewerWindow::handlePieMenu(S32 x, S32 y, MASK mask) { - if (CAMERA_MODE_CUSTOMIZE_AVATAR != gAgentCamera.getCameraMode() && LLToolMgr::getInstanceFast()->getCurrentTool() != LLToolPie::getInstanceFast() && gAgent.isInitialized()) + if (CAMERA_MODE_CUSTOMIZE_AVATAR != gAgentCamera.getCameraMode() && LLToolMgr::getInstance()->getCurrentTool() != LLToolPie::getInstance() && gAgent.isInitialized()) { // If the current tool didn't process the click, we should show // the pie menu. This can be done by passing the event to the pie // menu tool. - LLToolPie::getInstanceFast()->handleRightMouseDown(x, y, mask); + LLToolPie::getInstance()->handleRightMouseDown(x, y, mask); } } @@ -1187,7 +1186,7 @@ BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK m LLUI::resetMouseIdleTimer(); // Don't let the user move the mouse out of the window until mouse up. - if( LLToolMgr::getInstanceFast()->getCurrentTool()->clipMouseWhenDown() ) + if( LLToolMgr::getInstance()->getCurrentTool()->clipMouseWhenDown() ) { mWindow->setMouseClipping(down); } @@ -1265,7 +1264,7 @@ BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK m } // Do not allow tool manager to handle mouseclicks if we have disconnected - if(!gDisconnected && LLToolMgr::getInstanceFast()->getCurrentTool()->handleAnyMouseClick( x, y, mask, clicktype, down ) ) + if(!gDisconnected && LLToolMgr::getInstance()->getCurrentTool()->handleAnyMouseClick( x, y, mask, clicktype, down ) ) { #if AL_VIEWER_EVENT_RECORDER if (LLViewerEventRecorder::getLoggingStatus()) @@ -1437,7 +1436,7 @@ LLWindowCallbacks::DragNDropResult LLViewerWindow::handleDragNDrop( LLWindow *wi } } - LLSelectMgr::getInstanceFast()->unhighlightObjectOnly(mDragHoveredObject); + LLSelectMgr::getInstance()->unhighlightObjectOnly(mDragHoveredObject); mDragHoveredObject = NULL; } @@ -1449,9 +1448,9 @@ LLWindowCallbacks::DragNDropResult LLViewerWindow::handleDragNDrop( LLWindow *wi if ( obj != mDragHoveredObject) { // Highlight the dragged object - LLSelectMgr::getInstanceFast()->unhighlightObjectOnly(mDragHoveredObject); + LLSelectMgr::getInstance()->unhighlightObjectOnly(mDragHoveredObject); mDragHoveredObject = obj; - LLSelectMgr::getInstanceFast()->highlightObjectOnly(mDragHoveredObject); + LLSelectMgr::getInstance()->highlightObjectOnly(mDragHoveredObject); } result = (! te->hasMedia()) ? LLWindowCallbacks::DND_COPY : LLWindowCallbacks::DND_LINK; @@ -1471,7 +1470,7 @@ LLWindowCallbacks::DragNDropResult LLViewerWindow::handleDragNDrop( LLWindow *wi if (prim_media_dnd_enabled && result == LLWindowCallbacks::DND_NONE && !mDragHoveredObject.isNull()) { - LLSelectMgr::getInstanceFast()->unhighlightObjectOnly(mDragHoveredObject); + LLSelectMgr::getInstance()->unhighlightObjectOnly(mDragHoveredObject); mDragHoveredObject = NULL; } } @@ -1552,7 +1551,7 @@ void LLViewerWindow::handleMouseLeave(LLWindow *window) // Note: we won't get this if we have captured the mouse. llassert( gFocusMgr.getMouseCapture() == NULL ); mMouseInWindow = FALSE; - LLToolTipMgr::instanceFast().blockToolTips(); + LLToolTipMgr::instance().blockToolTips(); } BOOL LLViewerWindow::handleCloseRequest(LLWindow *window) @@ -1566,8 +1565,15 @@ BOOL LLViewerWindow::handleCloseRequest(LLWindow *window) void LLViewerWindow::handleQuit(LLWindow *window) { - LL_INFOS() << "Window forced quit" << LL_ENDL; - LLAppViewer::instance()->forceQuit(); + if (gNonInteractive) + { + LLAppViewer::instance()->requestQuit(); + } + else + { + LL_INFOS() << "Window forced quit" << LL_ENDL; + LLAppViewer::instance()->forceQuit(); + } } void LLViewerWindow::handleResize(LLWindow *window, S32 width, S32 height) @@ -1583,7 +1589,7 @@ void LLViewerWindow::handleFocus(LLWindow *window) LLModalDialog::onAppFocusGained(); gAgent.onAppFocusGained(); - LLToolMgr::getInstanceFast()->onAppFocusGained(); + LLToolMgr::getInstance()->onAppFocusGained(); // See if we're coming in with modifier keys held down if (gKeyboard) @@ -1601,7 +1607,7 @@ void LLViewerWindow::handleFocusLost(LLWindow *window) { gFocusMgr.setAppHasFocus(FALSE); //LLModalDialog::onAppFocusLost(); - LLToolMgr::getInstanceFast()->onAppFocusLost(); + LLToolMgr::getInstance()->onAppFocusLost(); gFocusMgr.setMouseCapture( NULL ); if (gMenuBarView) @@ -1614,9 +1620,11 @@ void LLViewerWindow::handleFocusLost(LLWindow *window) showCursor(); getWindow()->setMouseClipping(FALSE); - // If losing focus while keys are down, reset them. + // If losing focus while keys are down, handle them as + // an 'up' to correctly release states, then reset states if (gKeyboard) { + gKeyboard->resetKeyDownAndHandle(); gKeyboard->resetKeys(); } @@ -1660,8 +1668,8 @@ BOOL LLViewerWindow::handleTranslatedKeyUp(KEY key, MASK mask) gViewerInput.handleGlobalBindsKeyUp(key, mask); // Let the inspect tool code check for ALT key to set LLToolSelectRect active instead LLToolCamera - LLToolCompInspect * tool_inspectp = LLToolCompInspect::getInstanceFast(); - if (LLToolMgr::getInstanceFast()->getCurrentTool() == tool_inspectp) + LLToolCompInspect * tool_inspectp = LLToolCompInspect::getInstance(); + if (LLToolMgr::getInstance()->getCurrentTool() == tool_inspectp) { tool_inspectp->keyUp(key, mask); } @@ -1671,7 +1679,7 @@ BOOL LLViewerWindow::handleTranslatedKeyUp(KEY key, MASK mask) void LLViewerWindow::handleScanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level) { - LLViewerJoystick::getInstanceFast()->setCameraNeedsUpdate(true); + LLViewerJoystick::getInstance()->setCameraNeedsUpdate(true); gViewerInput.scanKey(key, key_down, key_up, key_level); return; // Be clear this function returns nothing } @@ -1718,7 +1726,7 @@ BOOL LLViewerWindow::handleActivateApp(LLWindow *window, BOOL activating) { //if (!activating) gAgentCamera.changeCameraToDefault(); - LLViewerJoystick::getInstanceFast()->setNeedsReset(true); + LLViewerJoystick::getInstance()->setNeedsReset(true); return FALSE; } @@ -1814,9 +1822,10 @@ void LLViewerWindow::handleDataCopy(LLWindow *window, S32 data_type, void *data) BOOL LLViewerWindow::handleTimerEvent(LLWindow *window) { - if (LLViewerJoystick::getInstanceFast()->getOverrideCamera()) + //TODO: just call this every frame from gatherInput instead of using a convoluted 30fps timer callback + if (LLViewerJoystick::getInstance()->getOverrideCamera()) { - LLViewerJoystick::getInstanceFast()->updateStatus(); + LLViewerJoystick::getInstance()->updateStatus(); return TRUE; } return FALSE; @@ -1825,9 +1834,9 @@ BOOL LLViewerWindow::handleTimerEvent(LLWindow *window) BOOL LLViewerWindow::handleDeviceChange(LLWindow *window) { // give a chance to use a joystick after startup (hot-plugging) - if (!LLViewerJoystick::getInstanceFast()->isJoystickInitialized() ) + if (!LLViewerJoystick::getInstance()->isJoystickInitialized() ) { - LLViewerJoystick::getInstanceFast()->init(true); + LLViewerJoystick::getInstance()->init(true); return TRUE; } return FALSE; @@ -1945,17 +1954,11 @@ LLViewerWindow::LLViewerWindow(const Params& p) p.title, p.name, p.x, p.y, p.width, p.height, 0, p.fullscreen, gHeadlessClient, - gSavedSettings.getBOOL("DisableVerticalSync"), + gSavedSettings.getBOOL("RenderVSyncEnable"), !gHeadlessClient, p.ignore_pixel_depth, gSavedSettings.getBOOL("RenderDeferred") ? 0 : gSavedSettings.getU32("RenderFSAASamples")); //don't use window level anti-aliasing if FBOs are enabled - if (!LLViewerShaderMgr::sInitialized) - { //immediately initialize shaders - LLViewerShaderMgr::sInitialized = TRUE; - LLViewerShaderMgr::instance()->setShaders(); - } - if (NULL == mWindow) { LLSplashScreen::update(LLTrans::getString("StartupRequireDriverUpdate")); @@ -1974,6 +1977,12 @@ LLViewerWindow::LLViewerWindow(const Params& p) #endif LLAppViewer::instance()->fastQuit(1); } + else if (!LLViewerShaderMgr::sInitialized) + { + //immediately initialize shaders + LLViewerShaderMgr::sInitialized = TRUE; + LLViewerShaderMgr::instance()->setShaders(); + } if (!LLAppViewer::instance()->restoreErrorTrap()) { @@ -2012,6 +2021,13 @@ LLViewerWindow::LLViewerWindow(const Params& p) } LLFontManager::initClass(); + // Init font system, load default fonts and generate basic glyphs + // currently it takes aprox. 0.5 sec and we would load these fonts anyway + // before login screen. + LLFontGL::initClass( gSavedSettings.getF32("FontScreenDPI"), + mDisplayScale.mV[VX], + mDisplayScale.mV[VY], + gDirUtilp->getAppRODataDir()); // // We want to set this stuff up BEFORE we initialize the pipeline, so we can turn off @@ -2027,7 +2043,7 @@ LLViewerWindow::LLViewerWindow(const Params& p) } LLVertexBuffer::initClass(gSavedSettings.getBOOL("RenderVBOEnable"), gSavedSettings.getBOOL("RenderVBOMappingDisable")); LL_INFOS("RenderInit") << "LLVertexBuffer initialization done." << LL_ENDL ; - gGL.init() ; + gGL.init(true); if (LLFeatureManager::getInstance()->isSafe() || (gSavedSettings.getS32("LastFeatureVersion") != LLFeatureManager::getInstance()->getVersion()) @@ -2052,20 +2068,12 @@ LLViewerWindow::LLViewerWindow(const Params& p) // Init the image list. Must happen after GL is initialized and before the images that // LLViewerWindow needs are requested. - LLImageGL::initClass(LLViewerTexture::MAX_GL_IMAGE_CATEGORY) ; + LLImageGL::initClass(mWindow, LLViewerTexture::MAX_GL_IMAGE_CATEGORY, false, gSavedSettings.getBOOL("RenderGLMultiThreaded")); gTextureList.init(); LLViewerTextureManager::init() ; gBumpImageList.init(); - // Init font system, but don't actually load the fonts yet - // because our window isn't onscreen and they take several - // seconds to parse. - LLFontGL::initClass( gSavedSettings.getF32("FontScreenDPI"), - mDisplayScale.mV[VX], - mDisplayScale.mV[VY], - gDirUtilp->getAppRODataDir()); - - // Create container for all sub-views + // Create container for all sub-views LLView::Params rvp; rvp.name("root"); rvp.rect(mWindowRectScaled); @@ -2096,29 +2104,6 @@ std::string LLViewerWindow::getLastSnapshotDir() void LLViewerWindow::initGLDefaults() { - gGL.setSceneBlendType(LLRender::BT_ALPHA); - - if (!LLGLSLShader::sNoFixedFunction) - { //initialize fixed function state - glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE ); - - glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,LLColor4::black.mV); - glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,LLColor4::white.mV); - - // lights for objects - glShadeModel( GL_SMOOTH ); - - gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); - } - - glPixelStorei(GL_PACK_ALIGNMENT,1); - glPixelStorei(GL_UNPACK_ALIGNMENT,1); - - gGL.setAmbientLightColor(LLColor4::black); - - glCullFace(GL_BACK); - // RN: Need this for translation and stretch manip. gBox.prerender(); } @@ -2151,6 +2136,8 @@ void LLViewerWindow::initBase() LL_DEBUGS("AppInit") << "initializing edit menu" << LL_ENDL; initialize_edit_menu(); + LLFontGL::loadCommonFonts(); + // Create the floater view at the start so that other views can add children to it. // (But wait to add it as a child of the root view so that it will be in front of the // other views.) @@ -2173,7 +2160,7 @@ void LLViewerWindow::initBase() // Get a pointer to the toolbar view holder LLPanel* panel_holder = main_view->getChild<LLPanel>("toolbar_view_holder"); // Load the toolbar view from file - gToolBarView = LLUICtrlFactory::getInstance()->createFromFile<LLToolBarView>("panel_toolbar_view.xml", panel_holder, LLDefaultChildRegistry::instanceFast()); + gToolBarView = LLUICtrlFactory::getInstance()->createFromFile<LLToolBarView>("panel_toolbar_view.xml", panel_holder, LLDefaultChildRegistry::instance()); if (!gToolBarView) { LL_ERRS() << "Failed to initialize viewer: Viewer couldn't process file panel_toolbar_view.xml, " @@ -2237,6 +2224,14 @@ void LLViewerWindow::initBase() void LLViewerWindow::initWorldUI() { + if (gNonInteractive) + { + gIMMgr = LLIMMgr::getInstance(); + LLNavigationBar::getInstance(); + gFloaterView->pushVisibleAll(FALSE); + return; + } + S32 height = mRootView->getRect().getHeight(); S32 width = mRootView->getRect().getWidth(); LLRect full_window(0, height, width, 0); @@ -2247,12 +2242,15 @@ void LLViewerWindow::initWorldUI() //getRootView()->sendChildToFront(gFloaterView); //getRootView()->sendChildToFront(gSnapshotFloaterView); - LLPanel* chiclet_container = getRootView()->getChild<LLPanel>("chiclet_container"); - LLChicletBar* chiclet_bar = LLChicletBar::getInstance(); - chiclet_bar->setShape(chiclet_container->getLocalRect()); - chiclet_bar->setFollowsAll(); - chiclet_container->addChild(chiclet_bar); - chiclet_container->setVisible(TRUE); + if (!gNonInteractive) + { + LLPanel* chiclet_container = getRootView()->getChild<LLPanel>("chiclet_container"); + LLChicletBar* chiclet_bar = LLChicletBar::getInstance(); + chiclet_bar->setShape(chiclet_container->getLocalRect()); + chiclet_bar->setFollowsAll(); + chiclet_container->addChild(chiclet_bar); + chiclet_container->setVisible(TRUE); + } LLRect morph_view_rect = full_window; morph_view_rect.stretch( -STATUS_BAR_HEIGHT ); @@ -2280,6 +2278,7 @@ void LLViewerWindow::initWorldUI() gStatusBar->setShape(status_bar_container->getLocalRect()); // sync bg color with menu bar gStatusBar->setBackgroundColor( gMenuBarView->getBackgroundColor().get() ); + // add InBack so that gStatusBar won't be drawn over menu status_bar_container->addChildInBack(gStatusBar); status_bar_container->setVisible(TRUE); @@ -2344,21 +2343,24 @@ void LLViewerWindow::initWorldUI() gToolBarView->setVisible(TRUE); } - LLMediaCtrl* destinations = LLFloaterReg::getInstance("destinations")->getChild<LLMediaCtrl>("destination_guide_contents"); - if (destinations) - { - destinations->setErrorPageURL(gSavedSettings.getString("GenericErrorPageURL")); - std::string url = gSavedSettings.getString("DestinationGuideURL"); - url = LLWeb::expandURLSubstitutions(url, LLSD()); - destinations->navigateTo(url, HTTP_CONTENT_TEXT_HTML); - } - LLMediaCtrl* avatar_picker = LLFloaterReg::getInstance("avatar")->findChild<LLMediaCtrl>("avatar_picker_contents"); - if (avatar_picker) + if (!gNonInteractive) { - avatar_picker->setErrorPageURL(gSavedSettings.getString("GenericErrorPageURL")); - std::string url = gSavedSettings.getString("AvatarPickerURL"); - url = LLWeb::expandURLSubstitutions(url, LLSD()); - avatar_picker->navigateTo(url, HTTP_CONTENT_TEXT_HTML); + LLMediaCtrl* destinations = LLFloaterReg::getInstance("destinations")->getChild<LLMediaCtrl>("destination_guide_contents"); + if (destinations) + { + destinations->setErrorPageURL(gSavedSettings.getString("GenericErrorPageURL")); + std::string url = gSavedSettings.getString("DestinationGuideURL"); + url = LLWeb::expandURLSubstitutions(url, LLSD()); + destinations->navigateTo(url, HTTP_CONTENT_TEXT_HTML); + } + LLMediaCtrl* avatar_picker = LLFloaterReg::getInstance("avatar")->findChild<LLMediaCtrl>("avatar_picker_contents"); + if (avatar_picker) + { + avatar_picker->setErrorPageURL(gSavedSettings.getString("GenericErrorPageURL")); + std::string url = gSavedSettings.getString("AvatarPickerURL"); + url = LLWeb::expandURLSubstitutions(url, LLSD()); + avatar_picker->navigateTo(url, HTTP_CONTENT_TEXT_HTML); + } } } @@ -2464,7 +2466,7 @@ void LLViewerWindow::shutdownGL() LLViewerTextureManager::cleanup() ; SUBSYSTEM_CLEANUP(LLImageGL) ; - + LL_INFOS() << "All textures and llimagegl images are destroyed!" << LL_ENDL ; LL_INFOS() << "Cleaning up select manager" << LL_ENDL; @@ -2554,10 +2556,11 @@ void LLViewerWindow::reshape(S32 width, S32 height) //glViewport(0, 0, width, height ); - if (height > 0) + LLViewerCamera * camera = LLViewerCamera::getInstance(); // simpleton, might not exist + if (height > 0 && camera) { - LLViewerCamera::getInstanceFast()->setViewHeightInPixels( mWorldViewRectRaw.getHeight() ); - LLViewerCamera::getInstanceFast()->setAspect( getWorldViewAspectRatio() ); + camera->setViewHeightInPixels( mWorldViewRectRaw.getHeight() ); + camera->setAspect( getWorldViewAspectRatio() ); } calcDisplayScale(); @@ -2602,7 +2605,7 @@ void LLViewerWindow::reshape(S32 width, S32 height) mWindow->setMinSize(min_window_width, min_window_height); LLCoordScreen window_rect; - if (mWindow->getSize(&window_rect)) + if (!gNonInteractive && mWindow->getSize(&window_rect)) { // Only save size if not maximized gSavedSettings.setU32("WindowWidth", window_rect.mX); @@ -2687,10 +2690,7 @@ void LLViewerWindow::drawDebugText() gGL.color4f(1,1,1,1); gGL.pushMatrix(); gGL.pushUIMatrix(); - if (LLGLSLShader::sNoFixedFunction) - { - gUIProgram.bind(); - } + gUIProgram.bind(); { // scale view by UI global scale factor and aspect ratio correction factor gGL.scaleUI(mDisplayScale.mV[VX], mDisplayScale.mV[VY], 1.f); @@ -2700,10 +2700,7 @@ void LLViewerWindow::drawDebugText() gGL.popMatrix(); gGL.flush(); - if (LLGLSLShader::sNoFixedFunction) - { - gUIProgram.unbind(); - } + gUIProgram.unbind(); } void LLViewerWindow::draw() @@ -2750,10 +2747,7 @@ void LLViewerWindow::draw() // Draw all nested UI views. // No translation needed, this view is glued to 0,0 - if (LLGLSLShader::sNoFixedFunction) - { - gUIProgram.bind(); - } + gUIProgram.bind(); gGL.pushMatrix(); LLUI::pushMatrix(); @@ -2764,8 +2758,8 @@ void LLViewerWindow::draw() LLVector2 old_scale_factor = LLUI::getScaleFactor(); // apply camera zoom transform (for high res screenshots) - F32 zoom_factor = LLViewerCamera::getInstanceFast()->getZoomFactor(); - S16 sub_region = LLViewerCamera::getInstanceFast()->getZoomSubRegion(); + F32 zoom_factor = LLViewerCamera::getInstance()->getZoomFactor(); + S16 sub_region = LLViewerCamera::getInstance()->getZoomSubRegion(); if (zoom_factor > 1.f) { //decompose subregion number to x and y values @@ -2780,7 +2774,7 @@ void LLViewerWindow::draw() } // Draw tool specific overlay on world - LLToolMgr::getInstanceFast()->getCurrentTool()->draw(); + LLToolMgr::getInstance()->getCurrentTool()->draw(); if( gAgentCamera.cameraMouselook() || LLFloaterCamera::inFreeCameraMode() ) { @@ -2829,14 +2823,9 @@ void LLViewerWindow::draw() LLUI::popMatrix(); gGL.popMatrix(); - if (LLGLSLShader::sNoFixedFunction) - { - gUIProgram.unbind(); - } + gUIProgram.unbind(); -//#if LL_DEBUG LLView::sIsDrawing = FALSE; -//#endif } // Takes a single keyup event, usually when UI is visible @@ -2894,7 +2883,7 @@ BOOL LLViewerWindow::handleKeyUp(KEY key, MASK mask) BOOL LLViewerWindow::handleKey(KEY key, MASK mask) { // hide tooltips on keypress - LLToolTipMgr::instanceFast().blockToolTips(); + LLToolTipMgr::instance().blockToolTips(); // Menus get handled on key down instead of key up // so keybindings have to be recorded before that @@ -2902,7 +2891,7 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask) { #if AL_VIEWER_EVENT_RECORDER LL_DEBUGS() << "Key handled by LLSetKeyBindDialog" << LL_ENDL; - LLViewerEventRecorder::instanceFast().logKeyEvent(key,mask); + LLViewerEventRecorder::instance().logKeyEvent(key,mask); #endif return TRUE; } @@ -2981,7 +2970,7 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask) { LL_DEBUGS() << "LLviewerWindow::handleKey handle nav keys for nav" << LL_ENDL; #if AL_VIEWER_EVENT_RECORDER - LLViewerEventRecorder::instanceFast().logKeyEvent(key,mask); + LLViewerEventRecorder::instance().logKeyEvent(key,mask); #endif return TRUE; } @@ -2997,7 +2986,7 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask) && keyboard_focus->handleKey(key,mask,FALSE)) { #if AL_VIEWER_EVENT_RECORDER - LLViewerEventRecorder::instanceFast().logKeyEvent(key,mask); + LLViewerEventRecorder::instance().logKeyEvent(key,mask); #endif return TRUE; } @@ -3008,7 +2997,7 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask) && gMenuBarView->handleAcceleratorKey(key, mask)) { #if AL_VIEWER_EVENT_RECORDER - LLViewerEventRecorder::instanceFast().logKeyEvent(key, mask); + LLViewerEventRecorder::instance().logKeyEvent(key, mask); #endif return TRUE; } @@ -3016,7 +3005,7 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask) if (gLoginMenuBarView && gLoginMenuBarView->handleAcceleratorKey(key, mask)) { #if AL_VIEWER_EVENT_RECORDER - LLViewerEventRecorder::instanceFast().logKeyEvent(key,mask); + LLViewerEventRecorder::instance().logKeyEvent(key,mask); #endif return TRUE; } @@ -3043,7 +3032,7 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask) mRootView->focusNextRoot(); } #if AL_VIEWER_EVENT_RECORDER - LLViewerEventRecorder::instanceFast().logKeyEvent(key,mask); + LLViewerEventRecorder::instance().logKeyEvent(key,mask); #endif return TRUE; } @@ -3051,7 +3040,7 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask) if (gEditMenu && gEditMenu->handleAcceleratorKey(key, mask)) { #if AL_VIEWER_EVENT_RECORDER - LLViewerEventRecorder::instanceFast().logKeyEvent(key,mask); + LLViewerEventRecorder::instance().logKeyEvent(key,mask); #endif return TRUE; } @@ -3103,7 +3092,7 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask) } } - if( LLToolMgr::getInstanceFast()->getCurrentTool()->handleKey(key, mask) ) + if( LLToolMgr::getInstance()->getCurrentTool()->handleKey(key, mask) ) { LL_DEBUGS() << "LLviewerWindow::handleKey toolbar handling?" << LL_ENDL; #if AL_VIEWER_EVENT_RECORDER @@ -3273,6 +3262,11 @@ void LLViewerWindow::handleScrollWheel(S32 clicks) void LLViewerWindow::handleScrollHWheel(S32 clicks) { + if (LLAppViewer::instance()->quitRequested()) + { + return; + } + LLUI::resetMouseIdleTimer(); LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture(); @@ -3397,7 +3391,7 @@ static LLTrace::BlockTimerStatHandle FTM_UPDATE_UI("Update UI"); // event processing. void LLViewerWindow::updateUI() { - LL_RECORD_BLOCK_TIME(FTM_UPDATE_UI); + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; //LL_RECORD_BLOCK_TIME(ftm); static std::string last_handle_msg; @@ -3768,7 +3762,7 @@ void LLViewerWindow::updateUI() if (!handled) { - LLTool *tool = LLToolMgr::getInstanceFast()->getCurrentTool(); + LLTool *tool = LLToolMgr::getInstance()->getCurrentTool(); if(mMouseInWindow && tool) { @@ -3836,7 +3830,7 @@ void LLViewerWindow::updateUI() params.sticky_rect = screen_sticky_rect; params.max_width = 400; - LLToolTipMgr::instanceFast().show(params); + LLToolTipMgr::instance().show(params); } // if there is a mouse captor, nothing else gets a tooltip else if (mouse_captor) @@ -3859,7 +3853,7 @@ void LLViewerWindow::updateUI() tool_tip_handled = mRootView->handleToolTip(local_x, local_y, mask ); } - LLTool* current_tool = LLToolMgr::getInstanceFast()->getCurrentTool(); + LLTool* current_tool = LLToolMgr::getInstance()->getCurrentTool(); if (!tool_tip_handled && current_tool) { current_tool->screenPointToLocal(x, y, &local_x, &local_y); @@ -3870,7 +3864,7 @@ void LLViewerWindow::updateUI() } else { // just have tools handle hover when UI is turned off - LLTool *tool = LLToolMgr::getInstanceFast()->getCurrentTool(); + LLTool *tool = LLToolMgr::getInstance()->getCurrentTool(); if(mMouseInWindow && tool) { @@ -3885,41 +3879,41 @@ void LLViewerWindow::updateUI() // cleanup unused selections when no modal dialogs are open if (LLModalDialog::activeCount() == 0) { - LLViewerParcelMgr::getInstanceFast()->deselectUnused(); + LLViewerParcelMgr::getInstance()->deselectUnused(); } if (LLModalDialog::activeCount() == 0) { - LLSelectMgr::getInstanceFast()->deselectUnused(); + LLSelectMgr::getInstance()->deselectUnused(); } } void LLViewerWindow::updateLayout() { - LLTool* tool = LLToolMgr::getInstanceFast()->getCurrentTool(); + LLTool* tool = LLToolMgr::getInstance()->getCurrentTool(); if (gFloaterTools != NULL && tool != NULL && tool != gToolNull - && tool != LLToolCompInspect::getInstanceFast() - && tool != LLToolDragAndDrop::getInstanceFast() + && tool != LLToolCompInspect::getInstance() + && tool != LLToolDragAndDrop::getInstance() && !LLPipeline::FreezeTime) { // Suppress the toolbox view if our source tool was the pie tool, // and we've overridden to something else. bool suppress_toolbox = - (LLToolMgr::getInstanceFast()->getBaseTool() == LLToolPie::getInstanceFast()) && - (LLToolMgr::getInstanceFast()->getCurrentTool() != LLToolPie::getInstanceFast()); + (LLToolMgr::getInstance()->getBaseTool() == LLToolPie::getInstance()) && + (LLToolMgr::getInstance()->getCurrentTool() != LLToolPie::getInstance()); LLMouseHandler *captor = gFocusMgr.getMouseCapture(); // With the null, inspect, or drag and drop tool, don't muck // with visibility. if (gFloaterTools->isMinimized() - || (tool != LLToolPie::getInstanceFast() // not default tool - && tool != LLToolCompGun::getInstanceFast() // not coming out of mouselook + || (tool != LLToolPie::getInstance() // not default tool + && tool != LLToolCompGun::getInstance() // not coming out of mouselook && !suppress_toolbox // not override in third person - && LLToolMgr::getInstanceFast()->getCurrentToolset()->isShowFloaterTools() + && LLToolMgr::getInstance()->getCurrentToolset()->isShowFloaterTools() && (!captor || dynamic_cast<LLView*>(captor) != NULL))) // not dragging { // Force floater tools to be visible (unless minimized) @@ -3953,8 +3947,15 @@ void LLViewerWindow::updateLayout() void LLViewerWindow::updateMouseDelta() { +#if LL_WINDOWS + LLCoordCommon delta; + mWindow->getCursorDelta(&delta); + S32 dx = delta.mX; + S32 dy = delta.mY; +#else S32 dx = lltrunc((F32) (mCurrentMousePoint.mX - mLastMousePoint.mX) * LLUI::getScaleFactor().mV[VX]); S32 dy = lltrunc((F32) (mCurrentMousePoint.mY - mLastMousePoint.mY) * LLUI::getScaleFactor().mV[VY]); +#endif //RN: fix for asynchronous notification of mouse leaving window not working LLCoordWindow mouse_pos; @@ -4050,9 +4051,9 @@ void LLViewerWindow::updateKeyboardFocus() } // last ditch force of edit menu to selection manager - if (LLEditMenuHandler::gEditMenuHandler == NULL && LLSelectMgr::getInstanceFast()->getSelection()->getObjectCount()) + if (LLEditMenuHandler::gEditMenuHandler == NULL && LLSelectMgr::getInstance()->getSelection()->getObjectCount()) { - LLEditMenuHandler::gEditMenuHandler = LLSelectMgr::getInstanceFast(); + LLEditMenuHandler::gEditMenuHandler = LLSelectMgr::getInstance(); } if (gFloaterView->getCycleMode()) @@ -4108,8 +4109,8 @@ void LLViewerWindow::updateWorldViewRect(bool use_full_window) { mWorldViewRectRaw = new_world_rect; gResizeScreenTexture = TRUE; - LLViewerCamera::getInstanceFast()->setViewHeightInPixels( mWorldViewRectRaw.getHeight() ); - LLViewerCamera::getInstanceFast()->setAspect( getWorldViewAspectRatio() ); + LLViewerCamera::getInstance()->setViewHeightInPixels( mWorldViewRectRaw.getHeight() ); + LLViewerCamera::getInstance()->setAspect( getWorldViewAspectRatio() ); LLRect old_world_rect_scaled = mWorldViewRectScaled; mWorldViewRectScaled = calcScaledRect(mWorldViewRectRaw, mDisplayScale); @@ -4159,12 +4160,12 @@ void LLViewerWindow::saveLastMouse(const LLCoordGL &point) // render_hud_elements: FALSE, FALSE, FALSE void LLViewerWindow::renderSelections( BOOL for_gl_pick, BOOL pick_parcel_walls, BOOL for_hud ) { - LLObjectSelectionHandle selection = LLSelectMgr::getInstanceFast()->getSelection(); + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); if (!for_hud && !for_gl_pick) { // Call this once and only once - LLSelectMgr::getInstanceFast()->updateSilhouettes(); + LLSelectMgr::getInstance()->updateSilhouettes(); } // Draw fence around land selections @@ -4172,18 +4173,18 @@ void LLViewerWindow::renderSelections( BOOL for_gl_pick, BOOL pick_parcel_walls, { if (pick_parcel_walls) { - LLViewerParcelMgr::getInstanceFast()->renderParcelCollision(); + LLViewerParcelMgr::getInstance()->renderParcelCollision(); } } else if (( for_hud && selection->getSelectType() == SELECT_TYPE_HUD) || (!for_hud && selection->getSelectType() != SELECT_TYPE_HUD)) { - LLSelectMgr::getInstanceFast()->renderSilhouettes(for_hud); + LLSelectMgr::getInstance()->renderSilhouettes(for_hud); stop_glerror(); // setup HUD render - if (selection->getSelectType() == SELECT_TYPE_HUD && LLSelectMgr::getInstanceFast()->getSelection()->getObjectCount()) + if (selection->getSelectType() == SELECT_TYPE_HUD && LLSelectMgr::getInstance()->getSelection()->getObjectCount()) { LLBBox hud_bbox = gAgentAvatarp->getHUDBBox(); @@ -4192,7 +4193,7 @@ void LLViewerWindow::renderSelections( BOOL for_gl_pick, BOOL pick_parcel_walls, gGL.pushMatrix(); gGL.loadIdentity(); F32 depth = llmax(1.f, hud_bbox.getExtentLocal().mV[VX] * 1.1f); - gGL.ortho(-0.5f * LLViewerCamera::getInstanceFast()->getAspect(), 0.5f * LLViewerCamera::getInstanceFast()->getAspect(), -0.5f, 0.5f, 0.f, depth); + gGL.ortho(-0.5f * LLViewerCamera::getInstance()->getAspect(), 0.5f * LLViewerCamera::getInstance()->getAspect(), -0.5f, 0.5f, 0.f, depth); gGL.matrixMode(LLRender::MM_MODELVIEW); gGL.pushMatrix(); @@ -4202,7 +4203,7 @@ void LLViewerWindow::renderSelections( BOOL for_gl_pick, BOOL pick_parcel_walls, } // Render light for editing - if (LLSelectMgr::sRenderLightRadius && LLToolMgr::getInstanceFast()->inEdit()) + if (LLSelectMgr::sRenderLightRadius && LLToolMgr::getInstance()->inEdit()) { gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); LLGLEnable gls_blend(GL_BLEND); @@ -4248,7 +4249,7 @@ void LLViewerWindow::renderSelections( BOOL for_gl_pick, BOOL pick_parcel_walls, return true; } } func; - LLSelectMgr::getInstanceFast()->getSelection()->applyToObjects(&func); + LLSelectMgr::getInstance()->getSelection()->applyToObjects(&func); gGL.popMatrix(); } @@ -4257,7 +4258,7 @@ void LLViewerWindow::renderSelections( BOOL for_gl_pick, BOOL pick_parcel_walls, // not be recalculated at this time. If they are, then group rotations will break. // Draw arrows at average center of all selected objects - LLTool* tool = LLToolMgr::getInstanceFast()->getCurrentTool(); + LLTool* tool = LLToolMgr::getInstance()->getCurrentTool(); if (tool) { if(tool->isAlwaysRendered()) @@ -4266,7 +4267,7 @@ void LLViewerWindow::renderSelections( BOOL for_gl_pick, BOOL pick_parcel_walls, } else { - if( !LLSelectMgr::getInstanceFast()->getSelection()->isEmpty() ) + if( !LLSelectMgr::getInstance()->getSelection()->isEmpty() ) { bool all_selected_objects_move; bool all_selected_objects_modify; @@ -4274,21 +4275,21 @@ void LLViewerWindow::renderSelections( BOOL for_gl_pick, BOOL pick_parcel_walls, // we might be better off with some kind of memory for selection and/or states, consider // optimizing, perhaps even some kind of selection generation at level of LLSelectMgr to // make whole viewer benefit. - LLSelectMgr::getInstanceFast()->selectGetEditMoveLinksetPermissions(all_selected_objects_move, all_selected_objects_modify); + LLSelectMgr::getInstance()->selectGetEditMoveLinksetPermissions(all_selected_objects_move, all_selected_objects_modify); BOOL draw_handles = TRUE; - if (tool == LLToolCompTranslate::getInstanceFast() && !all_selected_objects_move && !LLSelectMgr::getInstanceFast()->isMovableAvatarSelected()) + if (tool == LLToolCompTranslate::getInstance() && !all_selected_objects_move && !LLSelectMgr::getInstance()->isMovableAvatarSelected()) { draw_handles = FALSE; } - if (tool == LLToolCompRotate::getInstanceFast() && !all_selected_objects_move && !LLSelectMgr::getInstanceFast()->isMovableAvatarSelected()) + if (tool == LLToolCompRotate::getInstance() && !all_selected_objects_move && !LLSelectMgr::getInstance()->isMovableAvatarSelected()) { draw_handles = FALSE; } - if ( !all_selected_objects_modify && tool == LLToolCompScale::getInstanceFast() ) + if ( !all_selected_objects_modify && tool == LLToolCompScale::getInstance() ) { draw_handles = FALSE; } @@ -4457,7 +4458,7 @@ LLHUDIcon* LLViewerWindow::cursorIntersectIcon(S32 mouse_x, S32 mouse_y, F32 dep // world coordinates of mouse // VECTORIZE THIS LLVector3 mouse_direction_global = mouseDirectionGlobal(x,y); - LLVector3 mouse_point_global = LLViewerCamera::getInstanceFast()->getOrigin(); + LLVector3 mouse_point_global = LLViewerCamera::getInstance()->getOrigin(); LLVector3 mouse_world_start = mouse_point_global; LLVector3 mouse_world_end = mouse_point_global + mouse_direction_global * depth; @@ -4497,11 +4498,11 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de // world coordinates of mouse LLVector3 mouse_direction_global = mouseDirectionGlobal(x,y); - LLVector3 mouse_point_global = LLViewerCamera::getInstanceFast()->getOrigin(); + LLVector3 mouse_point_global = LLViewerCamera::getInstance()->getOrigin(); //get near clip plane - LLVector3 n = LLViewerCamera::getInstanceFast()->getAtAxis(); - LLVector3 p = mouse_point_global + n * LLViewerCamera::getInstanceFast()->getNear(); + LLVector3 n = LLViewerCamera::getInstance()->getAtAxis(); + LLVector3 p = mouse_point_global + n * LLViewerCamera::getInstance()->getNear(); //project mouse point onto plane LLVector3 pos; @@ -4511,7 +4512,7 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de LLVector3 mouse_world_start = mouse_point_global; LLVector3 mouse_world_end = mouse_point_global + mouse_direction_global * depth; - if (!LLViewerJoystick::getInstanceFast()->getOverrideCamera() && !gPipeline.RenderFocusPointFollowsPointer) + if (!LLViewerJoystick::getInstance()->getOverrideCamera() && !gPipeline.RenderFocusPointFollowsPointer) { //always set raycast intersection to mouse_world_end unless //flycam is on (for DoF effect) gDebugRaycastIntersection.load3(mouse_world_end.mV); @@ -4565,7 +4566,7 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de // [RLVa:KB] - Checked: 2010-03-31 (RLVa-1.2.0c) | Modified: RLVa-1.2.0c if ( (rlv_handler_t::isEnabled()) && (found) && - (LLToolCamera::getInstanceFast()->hasMouseCapture()) && (gKeyboard->currentMask(TRUE) & MASK_ALT) ) + (LLToolCamera::getInstance()->hasMouseCapture()) && (gKeyboard->currentMask(TRUE) & MASK_ALT) ) { found = NULL; } @@ -4587,10 +4588,10 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de // - the drag-and-drop tool is active (allows inventory offers) // - the camera tool is active // - the pie tool is active *and* we picked our own avie (allows "mouse steering" and the self pie menu) - LLTool* pCurTool = LLToolMgr::getInstanceFast()->getCurrentTool(); - if ( (LLToolDragAndDrop::getInstanceFast() != pCurTool) && - (!LLToolCamera::getInstanceFast()->hasMouseCapture()) && - ((LLToolPie::getInstanceFast() != pCurTool) || (gAgent.getID() != found->getID())) ) + LLTool* pCurTool = LLToolMgr::getInstance()->getCurrentTool(); + if ( (LLToolDragAndDrop::getInstance() != pCurTool) && + (!LLToolCamera::getInstance()->hasMouseCapture()) && + ((LLToolPie::getInstance() != pCurTool) || (gAgent.getID() != found->getID())) ) { found = NULL; } @@ -4605,7 +4606,7 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de // indicating direction of point on screen x,y LLVector3 LLViewerWindow::mouseDirectionGlobal(const S32 x, const S32 y) const { - auto& viewerCamera = LLViewerCamera::instanceFast(); + auto& viewerCamera = LLViewerCamera::instance(); // find vertical field of view F32 fov = viewerCamera.getView(); @@ -4651,7 +4652,7 @@ LLVector3 LLViewerWindow::mousePointHUD(const S32 x, const S32 y) const // indicating direction of point on screen x,y LLVector3 LLViewerWindow::mouseDirectionCamera(const S32 x, const S32 y) const { - auto& viewerCamera = LLViewerCamera::instanceFast(); + auto& viewerCamera = LLViewerCamera::instance(); // find vertical field of view F32 fov_height = viewerCamera.getView(); @@ -4737,7 +4738,7 @@ BOOL LLViewerWindow::mousePointOnLandGlobal(const S32 x, const S32 y, LLVector3d mouse_direction_global_d.setVec(mouse_direction_global * mouse_dir_scale); probe_point_global = camera_pos_global + mouse_direction_global_d; - regionp = LLWorld::getInstanceFast()->resolveRegionGlobal(probe_point_region, probe_point_global); + regionp = LLWorld::getInstance()->resolveRegionGlobal(probe_point_region, probe_point_global); if (!regionp) { @@ -4784,7 +4785,7 @@ BOOL LLViewerWindow::mousePointOnLandGlobal(const S32 x, const S32 y, LLVector3d mouse_direction_global_d.setVec(mouse_direction_global * mouse_dir_scale); probe_point_global = camera_pos_global + mouse_direction_global_d; - regionp = LLWorld::getInstanceFast()->resolveRegionGlobal(probe_point_region, probe_point_global); + regionp = LLWorld::getInstance()->resolveRegionGlobal(probe_point_region, probe_point_global); if (!regionp) { @@ -5132,7 +5133,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei LLRenderTarget scratch_space; - auto& viewerCamera = LLViewerCamera::instanceFast(); + auto& viewerCamera = LLViewerCamera::instance(); F32 scale_factor = 1.0f ; if (!keep_window_aspect || (image_width > window_width) || (image_height > window_height)) @@ -5223,7 +5224,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei F32 depth_conversion_factor_1 = (viewerCamera.getFar() + viewerCamera.getNear()) / (2.f * viewerCamera.getFar() * viewerCamera.getNear()); F32 depth_conversion_factor_2 = (viewerCamera.getFar() - viewerCamera.getNear()) / (2.f * viewerCamera.getFar() * viewerCamera.getNear()); - gObjectList.generatePickList(LLViewerCamera::instanceFast()); + gObjectList.generatePickList(LLViewerCamera::instance()); // Subimages are in fact partial rendering of the final view. This happens when the final view is bigger than the screen. // In most common cases, scale_factor is 1 and there's no more than 1 iteration on x and y @@ -5553,7 +5554,7 @@ void LLViewerWindow::drawMouselookInstructions() LLColor4(0.5f, 0.5f, 1.0f, 0.5f), LLFontGL::HCENTER, LLFontGL::TOP, LLFontGL::BOLD, LLFontGL::DROP_SHADOW); - LLViewerParcelMgr* vpm = LLViewerParcelMgr::getInstanceFast(); + LLViewerParcelMgr* vpm = LLViewerParcelMgr::getInstance(); const bool allow_damage = vpm->allowAgentDamage(gAgent.getRegion(), vpm->getAgentParcel()); if (allow_damage) { @@ -5672,12 +5673,13 @@ void LLViewerWindow::setup2DViewport(S32 x_offset, S32 y_offset) void LLViewerWindow::setup3DRender() { // setup perspective camera - LLViewerCamera::getInstanceFast()->setPerspective(NOT_FOR_SELECTION, mWorldViewRectRaw.mLeft, mWorldViewRectRaw.mBottom, mWorldViewRectRaw.getWidth(), mWorldViewRectRaw.getHeight(), FALSE, LLViewerCamera::getInstanceFast()->getNear(), MAX_FAR_CLIP*2.f); + LLViewerCamera::getInstance()->setPerspective(NOT_FOR_SELECTION, mWorldViewRectRaw.mLeft, mWorldViewRectRaw.mBottom, mWorldViewRectRaw.getWidth(), mWorldViewRectRaw.getHeight(), FALSE, LLViewerCamera::getInstance()->getNear(), MAX_FAR_CLIP*2.f); setup3DViewport(); } void LLViewerWindow::setup3DViewport(S32 x_offset, S32 y_offset) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI gGLViewport[0] = mWorldViewRectRaw.mLeft + x_offset; gGLViewport[1] = mWorldViewRectRaw.mBottom + y_offset; gGLViewport[2] = mWorldViewRectRaw.getWidth(); @@ -5825,7 +5827,7 @@ void LLViewerWindow::stopGL(BOOL save_state) shader->unload(); } - gGL.resetVertexBuffers(); + gGL.resetVertexBuffer(); LLVertexBuffer::cleanupClass(); @@ -5846,7 +5848,7 @@ void LLViewerWindow::restoreGL(const std::string& progress_message) LL_INFOS() << "Restoring GL..." << LL_ENDL; gGLManager.mIsDisabled = FALSE; - gGL.init(); + gGL.init(true); initGLDefaults(); gGL.refreshState(); LLGLState::restoreGL(); @@ -5909,8 +5911,6 @@ void LLViewerWindow::initFonts(F32 zoom_factor) mDisplayScale.mV[VX] * zoom_factor, mDisplayScale.mV[VY] * zoom_factor, font_dir); - // Force font reloads, which can be very slow - LLFontGL::loadDefaultFonts(); } void LLViewerWindow::requestResolutionUpdate() @@ -5952,7 +5952,7 @@ void LLViewerWindow::restartDisplay(BOOL show_progress_bar) } } -BOOL LLViewerWindow::changeDisplaySettings(LLCoordScreen size, BOOL disable_vsync, BOOL show_progress_bar) +BOOL LLViewerWindow::changeDisplaySettings(LLCoordScreen size, BOOL enable_vsync, BOOL show_progress_bar) { //BOOL was_maximized = gSavedSettings.getBOOL("WindowMaximized"); @@ -6166,11 +6166,6 @@ bool LLViewerWindow::getUIVisibility() return mUIVisible; } -void LLViewerWindow::setWindowTitle(const std::string& title) -{ - mWindow->setWindowTitle(title); -} - //////////////////////////////////////////////////////////////////////////// // // LLPickInfo @@ -6258,7 +6253,7 @@ void LLPickInfo::fetchResults() if ( (RlvActions::hasBehaviour(RLV_BHVR_SETOVERLAY)) && (hit_object) && (!hit_object->isHUDAttachment()) ) { std::list<RlvOverlayEffect*> effects; - LLVfxManager::instanceFast().getEffects<RlvOverlayEffect>(effects); + LLVfxManager::instance().getEffects<RlvOverlayEffect>(effects); for (const RlvOverlayEffect* pEffect : effects) { if (pEffect->getEnabled() && pEffect->hitTest(mMousePt)) diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index 9c7b7475ec8e0a1d0907de884c67564498aa68cc..6086180d535e290068cdfd4153de2e1c72c8d21b 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -175,7 +175,6 @@ class LLViewerWindow final : public LLWindowCallbacks void setUIVisibility(bool); bool getUIVisibility(); void handlePieMenu(S32 x, S32 y, MASK mask); - void setWindowTitle(const std::string& title); BOOL handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down); @@ -425,7 +424,7 @@ class LLViewerWindow final : public LLWindowCallbacks void requestResolutionUpdate(); void checkSettings(); void restartDisplay(BOOL show_progress_bar); - BOOL changeDisplaySettings(LLCoordScreen size, BOOL disable_vsync, BOOL show_progress_bar); + BOOL changeDisplaySettings(LLCoordScreen size, BOOL enable_vsync, BOOL show_progress_bar); BOOL getIgnoreDestroyWindow() { return mIgnoreActivate; } F32 getWorldViewAspectRatio() const; const LLVector2& getDisplayScale() const { return mDisplayScale; } diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index 5e055aaa0210fb59e1da7f7886f619e2cf4b4b32..bd873cf4731074b2823f8c09c23d50021997a299 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -254,6 +254,7 @@ BOOL LLVLComposition::generateComposition() BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, const F32 width, const F32 height) { + LL_PROFILE_ZONE_SCOPED llassert(mSurfacep); llassert(x >= 0.f); llassert(y >= 0.f); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index cd9921dea1e122c9969b2d2f3425a46707db7fe1..086d8b3808fc109dd6b3924c37d5ff31612657f5 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -1,4 +1,4 @@ -/** +/** * @File llvoavatar.cpp * @brief Implementation of LLVOAvatar class which is a derivation of LLViewerObject * @@ -120,6 +120,7 @@ #include "llsdserialize.h" #include "llcallstack.h" #include "llrendersphere.h" +#include "llskinningutil.h" #include "alcinematicmode.h" #include "llsidepanelappearance.h" @@ -136,6 +137,12 @@ const F32 MIN_HOVER_Z = -2.0; const F32 MIN_ATTACHMENT_COMPLEXITY = 0.f; const F32 DEFAULT_MAX_ATTACHMENT_COMPLEXITY = 1.0e6f; +// Unlike with 'self' avatar, server doesn't inform viewer about +// expected attachments so viewer has to wait to see if anything +// else will arrive +const F32 FIRST_APPEARANCE_CLOUD_MIN_DELAY = 3.f; // seconds +const F32 FIRST_APPEARANCE_CLOUD_MAX_DELAY = 45.f; + using namespace LLAvatarAppearanceDefines; //----------------------------------------------------------------------------- @@ -186,8 +193,6 @@ const F32 MAX_STANDOFF_DISTANCE_CHANGE = 32; // Should probably be 4 or 3, but didn't want to change it while change other logic - SJB const S32 SWITCH_TO_BAKED_DISCARD = 5; -const F32 FOOT_COLLIDE_FUDGE = 0.04f; - const F32 HOVER_EFFECT_MAX_SPEED = 3.f; const F32 HOVER_EFFECT_STRENGTH = 0.f; const F32 UNDERWATER_EFFECT_STRENGTH = 0.1f; @@ -338,6 +343,7 @@ class LLBodyNoiseMotion final : // must return FALSE when the motion is completed. virtual BOOL onUpdate(F32 time, U8* joint_mask) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; F32 nx[2]; nx[0]=time*TORSO_NOISE_SPEED; nx[1]=0.0f; @@ -458,6 +464,7 @@ class LLBreatheMotionRot final : // must return FALSE when the motion is completed. virtual BOOL onUpdate(F32 time, U8* joint_mask) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; mBreatheRate = 1.f; F32 breathe_amt = (sinf(mBreatheRate * time) * BREATHE_ROT_MOTION_STRENGTH); @@ -559,6 +566,7 @@ class LLPelvisFixMotion final : // must return FALSE when the motion is completed. virtual BOOL onUpdate(F32 time, U8* joint_mask) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; mPelvisState->setPosition(LLVector3::zero); return TRUE; @@ -585,7 +593,6 @@ class LLPelvisFixMotion final : //----------------------------------------------------------------------------- // Static Data //----------------------------------------------------------------------------- -S32 LLVOAvatar::sFreezeCounter = 0; U32 LLVOAvatar::sMaxNonImpostors = 12; // Set from RenderAvatarMaxNonImpostors bool LLVOAvatar::sLimitNonImpostors = false; // True unless RenderAvatarMaxNonImpostors is 0 (unlimited) F32 LLVOAvatar::sRenderDistance = 256.f; @@ -610,7 +617,6 @@ S32 LLVOAvatar::sNumVisibleChatBubbles = 0; BOOL LLVOAvatar::sDebugInvisible = FALSE; BOOL LLVOAvatar::sShowAttachmentPoints = FALSE; BOOL LLVOAvatar::sShowAnimationDebug = FALSE; -BOOL LLVOAvatar::sShowFootPlane = FALSE; BOOL LLVOAvatar::sVisibleInFirstPerson = FALSE; F32 LLVOAvatar::sLODFactor = 1.f; F32 LLVOAvatar::sPhysicsLODFactor = 1.f; @@ -619,6 +625,7 @@ F32 LLVOAvatar::sUnbakedTime = 0.f; F32 LLVOAvatar::sUnbakedUpdateTime = 0.f; F32 LLVOAvatar::sGreyTime = 0.f; F32 LLVOAvatar::sGreyUpdateTime = 0.f; +LLPointer<LLViewerTexture> LLVOAvatar::sCloudTexture = NULL; //----------------------------------------------------------------------------- // Helper functions @@ -675,6 +682,7 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, mVisuallyMuteSetting(AV_RENDER_NORMALLY), mMutedAVColor(LLColor4::white /* used for "uninitialize" */), mFirstFullyVisible(TRUE), + mFirstUseDelaySeconds(FIRST_APPEARANCE_CLOUD_MIN_DELAY), mFullyLoaded(FALSE), mPreviousFullyLoaded(FALSE), mFullyLoadedInitialized(FALSE), @@ -754,18 +762,18 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, mCurrentGesticulationLevel = 0; - + mFirstAppearanceMessageTimer.reset(); mRuthTimer.reset(); mRuthDebugTimer.reset(); mDebugExistenceTimer.reset(); mLastAppearanceMessageTimer.reset(); - if(LLSceneMonitor::getInstanceFast()->isEnabled()) + if(LLSceneMonitor::getInstance()->isEnabled()) { - LLSceneMonitor::getInstanceFast()->freezeAvatar((LLCharacter*)this); + LLSceneMonitor::getInstance()->freezeAvatar((LLCharacter*)this); } - mVisuallyMuteSetting = LLVOAvatar::VisualMuteSettings(LLRenderMuteList::getInstanceFast()->getSavedVisualMuteSetting(getID())); + mVisuallyMuteSetting = LLVOAvatar::VisualMuteSettings(LLRenderMuteList::getInstance()->getSavedVisualMuteSetting(getID())); } S32 LLVOAvatar::getNumBakes() const @@ -785,7 +793,7 @@ S32 LLVOAvatar::getNumBakes() const // << " bakesOnMesh = " << static_cast<const char *>(LLGridManager::instance().isInSecondLife()?"True":"False") // << LL_ENDL; // fallback, in SL assume BOM, elsewhere assume not. - return LLGridManager::instanceFast().isInSecondlife() ? BAKED_NUM_INDICES : BAKED_LEFT_ARM; + return LLGridManager::instance().isInSecondlife() ? BAKED_NUM_INDICES : BAKED_LEFT_ARM; } std::string LLVOAvatar::avString() const { @@ -802,6 +810,13 @@ std::string LLVOAvatar::avString() const void LLVOAvatar::debugAvatarRezTime(std::string notification_name, std::string comment) { + if (gDisconnected) + { + // If we disconected, these values are likely to be invalid and + // avString() might crash due to a dead sAvatarDictionary + return; + } + LL_INFOS("Avatar") << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ]" << avString() @@ -1155,6 +1170,7 @@ void LLVOAvatar::initClass() LLControlAvatar::sRegionChangedSlot = gAgent.addRegionChangedCallback(&LLControlAvatar::onRegionChanged); + sCloudTexture = LLViewerTextureManager::getFetchedTextureFromFile("SoftDotNoBack.png"); } @@ -1350,11 +1366,9 @@ void LLVOAvatar::updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax) } -static LLTrace::BlockTimerStatHandle FTM_AVATAR_EXTENT_UPDATE("Av Upd Extent"); - void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) { - LL_RECORD_BLOCK_TIME(FTM_AVATAR_EXTENT_UPDATE); + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; static LLCachedControl<S32> box_detail_cache(gSavedSettings, "AvatarBoundingBoxComplexity"); S32 box_detail = box_detail_cache; @@ -1459,7 +1473,7 @@ void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) continue; } LLDrawable* drawable = attached_object->mDrawable; - if (drawable && !drawable->isState(LLDrawable::RIGGED)) + if (drawable && !drawable->isState(LLDrawable::RIGGED | LLDrawable::RIGGED_CHILD)) // <-- don't extend bounding box if any rigged objects are present { const LLSpatialBridge* bridge = drawable->getSpatialBridge(); if (bridge) @@ -1531,7 +1545,7 @@ void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) size.setSub(newMax,newMin); size.mul(0.5f); - mPixelArea = LLPipeline::calcPixelArea(center, size, LLViewerCamera::instanceFast()); + mPixelArea = LLPipeline::calcPixelArea(center, size, LLViewerCamera::instance()); } void render_sphere_and_line(const LLVector3& begin_pos, const LLVector3& end_pos, F32 sphere_scale, const LLVector3& occ_color, const LLVector3& visible_color) @@ -2515,10 +2529,6 @@ S32 LLVOAvatar::setTETexture(const U8 te, const LLUUID& uuid) return setTETextureCore(te, image); } -static LLTrace::BlockTimerStatHandle FTM_AVATAR_UPDATE("Avatar Update"); -static LLTrace::BlockTimerStatHandle FTM_AVATAR_UPDATE_COMPLEXITY("Avatar Update Complexity"); -static LLTrace::BlockTimerStatHandle FTM_JOINT_UPDATE("Update Joints"); - //------------------------------------------------------------------------ // LLVOAvatar::dumpAnimationState() //------------------------------------------------------------------------ @@ -2551,7 +2561,7 @@ void LLVOAvatar::dumpAnimationState() //------------------------------------------------------------------------ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time) { - LL_RECORD_BLOCK_TIME(FTM_AVATAR_UPDATE); + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; if (isDead()) { @@ -2590,8 +2600,6 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time) // force asynchronous drawable update if(mDrawable.notNull()) { - LL_RECORD_BLOCK_TIME(FTM_JOINT_UPDATE); - if (isSitting() && getParent()) { LLViewerObject *root_object = (LLViewerObject*)getRoot(); @@ -2646,8 +2654,8 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time) BOOL detailed_update = updateCharacter(agent); static LLUICachedControl<bool> visualizers_in_calls("ShowVoiceVisualizersInCalls", false); - bool voice_enabled = (visualizers_in_calls || LLVoiceClient::getInstanceFast()->inProximalChannel()) && - LLVoiceClient::getInstanceFast()->getVoiceEnabled(mID); + bool voice_enabled = (visualizers_in_calls || LLVoiceClient::getInstance()->inProximalChannel()) && + LLVoiceClient::getInstance()->getVoiceEnabled(mID); idleUpdateVoiceVisualizer( voice_enabled ); idleUpdateMisc( detailed_update ); @@ -2691,9 +2699,8 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time) if ((LLFrameTimer::getFrameCount() + mID.mData[0]) % compl_upd_freq == 0) { - LL_RECORD_BLOCK_TIME(FTM_AVATAR_UPDATE_COMPLEXITY); - idleUpdateRenderComplexity(); -} + idleUpdateRenderComplexity(); + } idleUpdateDebugInfo(); } @@ -2753,7 +2760,7 @@ void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled) // Notice the calls to "gAwayTimer.reset()". This resets the timer that determines how long the avatar has been // "away", so that the avatar doesn't lapse into away-mode (and slump over) while the user is still talking. //----------------------------------------------------------------------------------------------------------------- - if (LLVoiceClient::getInstanceFast()->getIsSpeaking( mID )) + if (LLVoiceClient::getInstance()->getIsSpeaking( mID )) { if (!mVoiceVisualizer->getCurrentlySpeaking()) { @@ -2762,7 +2769,7 @@ void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled) //printf( "gAwayTimer.reset();\n" ); } - mVoiceVisualizer->setSpeakingAmplitude( LLVoiceClient::getInstanceFast()->getCurrentPower( mID ) ); + mVoiceVisualizer->setSpeakingAmplitude( LLVoiceClient::getInstance()->getCurrentPower( mID ) ); if( isSelf() ) { @@ -2807,10 +2814,17 @@ void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled) }//if ( voiceEnabled ) } -static LLTrace::BlockTimerStatHandle FTM_ATTACHMENT_UPDATE("Update Attachments"); +static void override_bbox(LLDrawable* drawable, LLVector4a* extents) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL; + drawable->setSpatialExtents(extents[0], extents[1]); + drawable->setPositionGroup(LLVector4a(0, 0, 0)); + drawable->movePartition(); +} void LLVOAvatar::idleUpdateMisc(bool detailed_update) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; if (LLVOAvatar::sJointDebug) { LL_INFOS() << getFullname() << ": joint touches: " << LLJoint::sNumTouches << " updates: " << LLJoint::sNumUpdates << LL_ENDL; @@ -2824,8 +2838,9 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update) // update attachments positions if (detailed_update) { - LL_RECORD_BLOCK_TIME(FTM_ATTACHMENT_UPDATE); - auto& selectMgr = LLSelectMgr::instanceFast(); + U32 draw_order = 0; + auto& selectMgr = LLSelectMgr::instance(); + S32 attachment_selected = selectMgr.getSelection()->getObjectCount() && selectMgr.getSelection()->isAttachment(); #if SLOW_ATTACHMENT_LIST for (const auto& attach_point_pair : mAttachmentPoints) { @@ -2839,28 +2854,71 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update) LLViewerJointAttachment* attachment = iter.second; LLViewerObject* attached_object = iter.first; #endif + if (!attached_object + || attached_object->isDead() + || !attachment->getValid() + || attached_object->mDrawable.isNull()) + { + continue; + } - BOOL visibleAttachment = visible || (attached_object && - !(attached_object->mDrawable->getSpatialBridge() && - attached_object->mDrawable->getSpatialBridge()->getRadius() < 2.0)); + LLSpatialBridge* bridge = attached_object->mDrawable->getSpatialBridge(); - if (visibleAttachment && attached_object && !attached_object->isDead() && attachment->getValid()) + if (visible || !(bridge && bridge->getRadius() < 2.0)) { - // if selecting any attachments, update all of them as non-damped - if (selectMgr.getSelection()->getObjectCount() && selectMgr.getSelection()->isAttachment()) - { - gPipeline.updateMoveNormalAsync(attached_object->mDrawable); - } - else - { - gPipeline.updateMoveDampedAsync(attached_object->mDrawable); - } - - LLSpatialBridge* bridge = attached_object->mDrawable->getSpatialBridge(); - if (bridge) - { - gPipeline.updateMoveNormalAsync(bridge); - } + //override rigged attachments' octree spatial extents with this avatar's bounding box + bool rigged = false; + if (bridge) + { + //transform avatar bounding box into attachment's coordinate frame + LLVector4a extents[2]; + bridge->transformExtents(mDrawable->getSpatialExtents(), extents); + + if (attached_object->mDrawable->isState(LLDrawable::RIGGED | LLDrawable::RIGGED_CHILD)) + { + rigged = true; + override_bbox(attached_object->mDrawable, extents); + } + } + + // if selecting any attachments, update all of them as non-damped + if (attachment_selected) + { + gPipeline.updateMoveNormalAsync(attached_object->mDrawable); + } + else + { + // Note: SL-17415; While most objects follow joints, + // some objects get position updates from server + gPipeline.updateMoveDampedAsync(attached_object->mDrawable); + } + + // override_bbox calls movePartition() and getSpatialPartition(), + // so bridge might no longer be valid, get it again. + // ex: animesh stops being an animesh + bridge = attached_object->mDrawable->getSpatialBridge(); + if (bridge) + { + if (!rigged) + { + gPipeline.updateMoveNormalAsync(bridge); + } + else + { + //specialized impl of updateMoveNormalAsync just for rigged attachment SpatialBridge + bridge->setState(LLDrawable::MOVE_UNDAMPED); + bridge->updateMove(); + bridge->setState(LLDrawable::EARLY_MOVE); + + LLSpatialGroup* group = attached_object->mDrawable->getSpatialGroup(); + if (group) + { //set draw order of group + group->mAvatarp = this; + group->mRenderOrder = draw_order++; + } + } + } + attached_object->updateText(); } } @@ -3018,7 +3076,7 @@ F32 LLVOAvatar::calcMorphAmount() void LLVOAvatar::idleUpdateLipSync(bool voice_enabled) { // Use the Lipsync_Ooh and Lipsync_Aah morphs for lip sync - auto& voiceClient = LLVoiceClient::instanceFast(); + auto& voiceClient = LLVoiceClient::instance(); if ( voice_enabled && mLastRezzedStatus > 0 // no point updating lip-sync for clouds && (voiceClient.lipSyncEnabled()) @@ -3064,9 +3122,9 @@ void LLVOAvatar::idleUpdateLoadingEffect() if (isSelf()) { LL_INFOS("Avatar") << avString() << "self isFullyLoaded, mFirstFullyVisible" << LL_ENDL; - LLAppearanceMgr::instanceFast().onFirstFullyVisible(); + LLAppearanceMgr::instance().onFirstFullyVisible(); - ALAOEngine::instanceFast().onLoginComplete(); + ALAOEngine::instance().onLoginComplete(); } else { @@ -3092,8 +3150,7 @@ void LLVOAvatar::idleUpdateLoadingEffect() particle_parameters.mPartData.mBlendFuncSource = LLPartData::LL_PART_BF_SOURCE_COLOR; particle_parameters.mPartData.mBlendFuncDest = LLPartData::LL_PART_BF_SOURCE_ALPHA; - LLViewerTexture* cloud = LLViewerTextureManager::getFetchedTextureFromFile("SoftDotNoBack.png"); - particle_parameters.mPartImageID = cloud->getID(); + particle_parameters.mPartImageID = sCloudTexture->getID(); particle_parameters.mMaxAge = 0.f; particle_parameters.mPattern = LLPartSysData::LL_PART_SRC_PATTERN_EXPLODE; particle_parameters.mInnerAngle = 0.f; @@ -3176,6 +3233,8 @@ void LLVOAvatar::idleUpdateWindEffect() void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; + // update chat bubble //-------------------------------------------------------------------- // draw text label over character's head @@ -3616,7 +3675,7 @@ void LLVOAvatar::invalidateNameTags() // Compute name tag position during idle update void LLVOAvatar::idleUpdateNameTagPosition(const LLVector3& root_pos_last) { - auto& viewerCamera = LLViewerCamera::instanceFast(); + auto& viewerCamera = LLViewerCamera::instance(); LLQuaternion root_rot = mRoot->getWorldRotation(); LLQuaternion inv_root_rot = ~root_rot; LLVector3 pixel_right_vec; @@ -3717,7 +3776,7 @@ void LLVOAvatar::idleUpdateBelowWater() BOOL was_below_water = mBelowWater; mBelowWater = avatar_height < water_height; if (isSelf() && mBelowWater != was_below_water) - ALAOEngine::instanceFast().checkBelowWater(mBelowWater); + ALAOEngine::instance().checkBelowWater(mBelowWater); } void LLVOAvatar::slamPosition() @@ -3787,7 +3846,7 @@ bool LLVOAvatar::isInMuteList() const } else { - muted = LLMuteList::getInstanceFast()->isMuted(getID(), getFullname()); + muted = LLMuteList::getInstance()->isMuted(getID(), getFullname()); const F64 SECONDS_BETWEEN_MUTE_UPDATES = 1; mCachedMuteListUpdateTime = now + SECONDS_BETWEEN_MUTE_UPDATES; @@ -3855,7 +3914,7 @@ void LLVOAvatar::updateAppearanceMessageDebugText() mUseServerBakes, central_bake_version); std::string origin_string = bakedTextureOriginInfo(); debug_line += " [" + origin_string + "]"; - S32 curr_cof_version = LLAppearanceMgr::instanceFast().getCOFVersion(); + S32 curr_cof_version = LLAppearanceMgr::instance().getCOFVersion(); S32 last_request_cof_version = mLastUpdateRequestCOFVersion; S32 last_received_cof_version = mLastUpdateReceivedCOFVersion; if (isSelf()) @@ -4180,8 +4239,8 @@ void LLVOAvatar::updateFootstepSounds() LLVector3d foot_pos_global = gAgent.getPosGlobalFromAgent(foot_pos_agent); - if (LLViewerParcelMgr::getInstanceFast()->canHearSound(foot_pos_global) - && !LLMuteList::getInstanceFast()->isMuted(getID(), LLMute::flagObjectSounds)) + if (LLViewerParcelMgr::getInstance()->canHearSound(foot_pos_global) + && !LLMuteList::getInstance()->isMuted(getID(), LLMute::flagObjectSounds)) { gAudiop->triggerSound(step_sound_id, getID(), STEP_VOLUME, LLAudioEngine::AUDIO_TYPE_AMBIENT, foot_pos_global); } @@ -4209,8 +4268,7 @@ void LLVOAvatar::computeUpdatePeriod() && (!isSelf() || visually_muted) && !isUIAvatar() && (sLimitNonImpostors || visually_muted) - && !mNeedsAnimUpdate - && !sFreezeCounter) + && !mNeedsAnimUpdate) { const LLVector4a* ext = mDrawable->getSpatialExtents(); LLVector4a size; @@ -4301,11 +4359,11 @@ void LLVOAvatar::updateOrientation(LLAgent& agent, F32 speed, F32 delta_time) // make sure fwdDir stays in same general direction as primdir if (gAgent.getFlying()) { - fwdDir = LLViewerCamera::getInstanceFast()->getAtAxis(); + fwdDir = LLViewerCamera::getInstance()->getAtAxis(); } else { - LLVector3 at_axis = LLViewerCamera::getInstanceFast()->getAtAxis(); + LLVector3 at_axis = LLViewerCamera::getInstance()->getAtAxis(); LLVector3 up_vector = gAgent.getReferenceUpVector(); at_axis -= up_vector * (at_axis * up_vector); at_axis.normalize(); @@ -4504,7 +4562,7 @@ void LLVOAvatar::updateRootPositionAndRotation(LLAgent& agent, F32 speed, bool w LLVector3 normal; resolveHeightGlobal(root_pos, ground_under_pelvis, normal); F32 foot_to_ground = (F32) (root_pos.mdV[VZ] - mPelvisToFoot - ground_under_pelvis.mdV[VZ]); - BOOL in_air = ((!LLWorld::getInstanceFast()->getRegionFromPosGlobal(ground_under_pelvis)) || + BOOL in_air = ((!LLWorld::getInstance()->getRegionFromPosGlobal(ground_under_pelvis)) || foot_to_ground > FOOT_GROUND_COLLISION_TOLERANCE); if (in_air && !mInAir) @@ -4725,7 +4783,12 @@ bool LLVOAvatar::updateCharacter(LLAgent &agent) } else if (!getParent() && isSitting() && !isMotionActive(ANIM_AGENT_SIT_GROUND_CONSTRAINED)) { - getOffObject(); + // If we are starting up, motion might be loading + LLMotion *motionp = mMotionController.findMotion(ANIM_AGENT_SIT_GROUND_CONSTRAINED); + if (!motionp || !mMotionController.isMotionLoading(motionp)) + { + getOffObject(); + } } //-------------------------------------------------------------------- @@ -4808,7 +4871,7 @@ void LLVOAvatar::updateHeadOffset() // since we only care about Z, just grab one of the eyes LLVector3 midEyePt = mEyeLeftp->getWorldPosition(); midEyePt -= mDrawable.notNull() ? mDrawable->getWorldPosition() : mRoot->getWorldPosition(); - midEyePt.mV[VZ] = llmax(-mPelvisToFoot + LLViewerCamera::getInstanceFast()->getNear(), midEyePt.mV[VZ]); + midEyePt.mV[VZ] = llmax(-mPelvisToFoot + LLViewerCamera::getInstance()->getNear(), midEyePt.mV[VZ]); if (mDrawable.notNull()) { @@ -5058,6 +5121,8 @@ bool LLVOAvatar::shouldAlphaMask() //----------------------------------------------------------------------------- U32 LLVOAvatar::renderSkinned() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; + U32 num_indices = 0; if (!mIsBuilt) @@ -5183,42 +5248,6 @@ U32 LLVOAvatar::renderSkinned() return num_indices; } - // render collision normal - // *NOTE: this is disabled (there is no UI for enabling sShowFootPlane) due - // to DEV-14477. the code is left here to aid in tracking down the cause - // of the crash in the future. -brad - if (sShowFootPlane && mDrawable.notNull()) - { - LLVector3 slaved_pos = mDrawable->getPositionAgent(); - LLVector3 foot_plane_normal(mFootPlane.mV[VX], mFootPlane.mV[VY], mFootPlane.mV[VZ]); - F32 dist_from_plane = (slaved_pos * foot_plane_normal) - mFootPlane.mV[VW]; - LLVector3 collide_point = slaved_pos; - collide_point.mV[VZ] -= foot_plane_normal.mV[VZ] * (dist_from_plane + COLLISION_TOLERANCE - FOOT_COLLIDE_FUDGE); - - gGL.begin(LLRender::LINES); - { - F32 SQUARE_SIZE = 0.2f; - gGL.color4f(1.f, 0.f, 0.f, 1.f); - - gGL.vertex3f(collide_point.mV[VX] - SQUARE_SIZE, collide_point.mV[VY] - SQUARE_SIZE, collide_point.mV[VZ]); - gGL.vertex3f(collide_point.mV[VX] + SQUARE_SIZE, collide_point.mV[VY] - SQUARE_SIZE, collide_point.mV[VZ]); - - gGL.vertex3f(collide_point.mV[VX] + SQUARE_SIZE, collide_point.mV[VY] - SQUARE_SIZE, collide_point.mV[VZ]); - gGL.vertex3f(collide_point.mV[VX] + SQUARE_SIZE, collide_point.mV[VY] + SQUARE_SIZE, collide_point.mV[VZ]); - - gGL.vertex3f(collide_point.mV[VX] + SQUARE_SIZE, collide_point.mV[VY] + SQUARE_SIZE, collide_point.mV[VZ]); - gGL.vertex3f(collide_point.mV[VX] - SQUARE_SIZE, collide_point.mV[VY] + SQUARE_SIZE, collide_point.mV[VZ]); - - gGL.vertex3f(collide_point.mV[VX] - SQUARE_SIZE, collide_point.mV[VY] + SQUARE_SIZE, collide_point.mV[VZ]); - gGL.vertex3f(collide_point.mV[VX] - SQUARE_SIZE, collide_point.mV[VY] - SQUARE_SIZE, collide_point.mV[VZ]); - - gGL.vertex3f(collide_point.mV[VX], collide_point.mV[VY], collide_point.mV[VZ]); - gGL.vertex3f(collide_point.mV[VX] + mFootPlane.mV[VX], collide_point.mV[VY] + mFootPlane.mV[VY], collide_point.mV[VZ] + mFootPlane.mV[VZ]); - - } - gGL.end(); - gGL.flush(); - } //-------------------------------------------------------------------- // render all geometry attached to the skeleton //-------------------------------------------------------------------- @@ -5226,11 +5255,6 @@ U32 LLVOAvatar::renderSkinned() bool should_alpha_mask = shouldAlphaMask(); LLGLState test(GL_ALPHA_TEST, should_alpha_mask); - if (should_alpha_mask && !LLGLSLShader::sNoFixedFunction) - { - gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); - } - BOOL first_pass = TRUE; if (!LLDrawPoolAvatar::sSkipOpaque) { @@ -5277,11 +5301,6 @@ U32 LLVOAvatar::renderSkinned() } } - if (should_alpha_mask && !LLGLSLShader::sNoFixedFunction) - { - gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); - } - if (!LLDrawPoolAvatar::sSkipTransparent || LLPipeline::sImpostorRender) { LLGLState blend(GL_BLEND, !mIsDummy); @@ -5297,21 +5316,21 @@ U32 LLVOAvatar::renderTransparent(BOOL first_pass) U32 num_indices = 0; if( isWearingWearableType( LLWearableType::WT_SKIRT ) && (isUIAvatar() || isTextureVisible(TEX_SKIRT_BAKED)) ) { - gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.25f); + gGL.flush(); LLViewerJoint* skirt_mesh = getViewerJoint(MESH_ID_SKIRT); if (skirt_mesh) { num_indices += skirt_mesh->render(mAdjustedPixelArea, FALSE); } first_pass = FALSE; - gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); + gGL.flush(); } if (!isSelf() || gAgent.needsRenderHead() || LLPipeline::sShadowRender) { if (LLPipeline::sImpostorRender) { - gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); + gGL.flush(); } if (isTextureVisible(TEX_HEAD_BAKED)) @@ -5334,7 +5353,7 @@ U32 LLVOAvatar::renderTransparent(BOOL first_pass) } if (LLPipeline::sImpostorRender) { - gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); + gGL.flush(); } } @@ -5366,11 +5385,6 @@ U32 LLVOAvatar::renderRigid() bool should_alpha_mask = shouldAlphaMask(); LLGLState test(GL_ALPHA_TEST, should_alpha_mask); - if (should_alpha_mask && !LLGLSLShader::sNoFixedFunction) - { - gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); - } - if (isTextureVisible(TEX_EYES_BAKED) || (getOverallAppearance() == AOA_JELLYDOLL && !isControlAvatar()) || isUIAvatar()) { LLViewerJoint* eyeball_left = getViewerJoint(MESH_ID_EYEBALL_LEFT); @@ -5385,11 +5399,6 @@ U32 LLVOAvatar::renderRigid() } } - if (should_alpha_mask && !LLGLSLShader::sNoFixedFunction) - { - gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); - } - return num_indices; } @@ -5400,7 +5409,7 @@ U32 LLVOAvatar::renderImpostor(LLColor4U color, S32 diffuse_channel) return 0; } - auto& camera = LLViewerCamera::instanceFast(); + auto& camera = LLViewerCamera::instance(); LLVector3 pos(getRenderPosition()+mImpostorOffset); LLVector3 at = (pos - camera.getOrigin()); @@ -5442,7 +5451,7 @@ U32 LLVOAvatar::renderImpostor(LLColor4U color, S32 diffuse_channel) } { LLGLEnable test(GL_ALPHA_TEST); - gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.f); + gGL.flush(); gGL.color4ubv(color.mV); gGL.getTexUnit(diffuse_channel)->bind(&mImpostor); @@ -5925,7 +5934,7 @@ const std::string LLVOAvatar::getImageURL(const U8 te, const LLUUID &uuid) std::string url = ""; if (isUsingServerBakes()) { - const std::string& appearance_service_url = LLAppearanceMgr::instanceFast().getAppearanceServiceURL(); + const std::string& appearance_service_url = LLAppearanceMgr::instance().getAppearanceServiceURL(); if (appearance_service_url.empty()) { // Probably a server-side issue if we get here: @@ -5960,7 +5969,7 @@ void LLVOAvatar::resolveHeightAgent(const LLVector3 &in_pos_agent, LLVector3 &ou void LLVOAvatar::resolveRayCollisionAgent(const LLVector3d start_pt, const LLVector3d end_pt, LLVector3d &out_pos, LLVector3 &out_norm) { LLViewerObject *obj; - LLWorld::getInstanceFast()->resolveStepHeightGlobal(this, start_pt, end_pt, out_pos, out_norm, &obj); + LLWorld::getInstance()->resolveStepHeightGlobal(this, start_pt, end_pt, out_pos, out_norm, &obj); } void LLVOAvatar::resolveHeightGlobal(const LLVector3d &inPos, LLVector3d &outPos, LLVector3 &outNorm) @@ -5969,7 +5978,7 @@ void LLVOAvatar::resolveHeightGlobal(const LLVector3d &inPos, LLVector3d &outPos LLVector3d p0 = inPos + zVec; LLVector3d p1 = inPos - zVec; LLViewerObject *obj; - LLWorld::getInstanceFast()->resolveStepHeightGlobal(this, p0, p1, outPos, outNorm, &obj); + LLWorld::getInstance()->resolveStepHeightGlobal(this, p0, p1, outPos, outNorm, &obj); if (!obj) { mStepOnLand = TRUE; @@ -6133,8 +6142,8 @@ BOOL LLVOAvatar::processSingleAnimationStateChange( const LLUUID& anim_id, BOOL if (gAudiop) { LLVector3d char_pos_global = gAgent.getPosGlobalFromAgent(getCharacterPosition()); - if (LLViewerParcelMgr::getInstanceFast()->canHearSound(char_pos_global) - && !LLMuteList::getInstanceFast()->isMuted(getID(), LLMute::flagObjectSounds)) + if (LLViewerParcelMgr::getInstance()->canHearSound(char_pos_global) + && !LLMuteList::getInstance()->isMuted(getID(), LLMute::flagObjectSounds)) { // RN: uncomment this to play on typing sound at fixed volume once sound engine is fixed // to support both spatialized and non-spatialized instances of the same sound @@ -6283,7 +6292,7 @@ BOOL LLVOAvatar::startMotion(const LLUUID& id, F32 time_offset) LLUUID remap_id; if(isSelf()) { - remap_id = ALAOEngine::getInstanceFast()->override(id, true); + remap_id = ALAOEngine::getInstance()->override(id, true); if(remap_id.isNull()) { remap_id = remapMotionID(id); @@ -6330,7 +6339,7 @@ BOOL LLVOAvatar::stopMotion(const LLUUID& id, BOOL stop_immediate) LLUUID remap_id; if(isSelf()) { - remap_id = ALAOEngine::getInstanceFast()->override(id, false); + remap_id = ALAOEngine::getInstance()->override(id, false); if (remap_id.isNull()) { remap_id = remapMotionID(id); @@ -6411,7 +6420,21 @@ LLJoint *LLVOAvatar::getJoint( const std::string &name ) if (iter == mJointMap.end() || iter->second == NULL) { //search for joint and cache found joint in lookup table - jointp = mRoot->findJoint(name); + if (mJointAliasMap.empty()) + { + getJointAliases(); + } + joint_alias_map_t::const_iterator alias_iter = mJointAliasMap.find(name); + std::string canonical_name; + if (alias_iter != mJointAliasMap.end()) + { + canonical_name = alias_iter->second; + } + else + { + canonical_name = name; + } + jointp = mRoot->findJoint(canonical_name); mJointMap[name] = jointp; } else @@ -6431,27 +6454,29 @@ LLJoint *LLVOAvatar::getJoint( const std::string &name ) LLJoint *LLVOAvatar::getJoint( S32 joint_num ) { LLJoint *pJoint = NULL; - S32 collision_start = mNumBones; - S32 attachment_start = mNumBones + mNumCollisionVolumes; - if (joint_num>=attachment_start) + if (joint_num >= 0) { - // Attachment IDs start at 1 - S32 attachment_id = joint_num - attachment_start + 1; - attachment_map_t::iterator iter = mAttachmentPoints.find(attachment_id); - if (iter != mAttachmentPoints.end()) + if (joint_num < mNumBones) { - pJoint = iter->second; + pJoint = mSkeleton[joint_num]; + } + else if (joint_num < mNumBones + mNumCollisionVolumes) + { + S32 collision_id = joint_num - mNumBones; + pJoint = &mCollisionVolumes[collision_id]; + } + else + { + // Attachment IDs start at 1 + S32 attachment_id = joint_num - (mNumBones + mNumCollisionVolumes) + 1; + attachment_map_t::iterator iter = mAttachmentPoints.find(attachment_id); + if (iter != mAttachmentPoints.end()) + { + pJoint = iter->second; + } } } - else if (joint_num>=collision_start) - { - S32 collision_id = joint_num-collision_start; - pJoint = &mCollisionVolumes[collision_id]; - } - else if (joint_num>=0) - { - pJoint = mSkeleton[joint_num]; - } + llassert(!pJoint || pJoint->getJointNum() == joint_num); return pJoint; } @@ -6709,6 +6734,16 @@ void LLVOAvatar::updateAttachmentOverrides() #endif } +void LLVOAvatar::notifyAttachmentMeshLoaded() +{ + if (!isFullyLoaded()) + { + // We just received mesh or skin info + // Reset timer to wait for more potential meshes or changes + mFullyLoadedTimer.reset(); + } +} + //----------------------------------------------------------------------------- // addAttachmentOverridesForObject //----------------------------------------------------------------------------- @@ -6805,7 +6840,7 @@ void LLVOAvatar::addAttachmentOverridesForObject(LLViewerObject *vo, std::set<LL LLJoint* pJoint = getJoint( lookingForJoint ); if (pJoint) { - const LLVector3& jointPos = pSkinData->mAlternateBindMatrix[i].getTranslation(); + const LLVector3& jointPos = LLVector3(pSkinData->mAlternateBindMatrix[i].getTranslation()); if (pJoint->aboveJointPosThreshold(jointPos)) { bool override_changed; @@ -7083,7 +7118,7 @@ void LLVOAvatar::getGround(const LLVector3 &in_pos_agent, LLVector3 &out_pos_age p1_global = gAgent.getPosGlobalFromAgent(in_pos_agent) - z_vec; LLViewerObject *obj; LLVector3d out_pos_global; - LLWorld::getInstanceFast()->resolveStepHeightGlobal(this, p0_global, p1_global, out_pos_global, outNorm, &obj); + LLWorld::getInstance()->resolveStepHeightGlobal(this, p0_global, p1_global, out_pos_global, outNorm, &obj); out_pos_agent = gAgent.getPosAgentFromGlobal(out_pos_global); } @@ -7302,7 +7337,7 @@ void LLVOAvatar::setPixelAreaAndAngle(LLAgent &agent) size.setSub(ext[1], ext[0]); size.mul(0.5f); - mImpostorPixelArea = LLPipeline::calcPixelArea(center, size, LLViewerCamera::instanceFast()); + mImpostorPixelArea = LLPipeline::calcPixelArea(center, size, LLViewerCamera::instance()); F32 range = mDrawable->mDistanceWRTCamera; @@ -7399,6 +7434,7 @@ void LLVOAvatar::updateGL() { if (mMeshTexturesDirty) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR updateMeshTextures(); mMeshTexturesDirty = FALSE; } @@ -7407,10 +7443,9 @@ void LLVOAvatar::updateGL() //----------------------------------------------------------------------------- // updateGeometry() //----------------------------------------------------------------------------- -static LLTrace::BlockTimerStatHandle FTM_UPDATE_AVATAR("Update Avatar"); BOOL LLVOAvatar::updateGeometry(LLDrawable *drawable) { - LL_RECORD_BLOCK_TIME(FTM_UPDATE_AVATAR); + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; if (!(gPipeline.hasRenderType(mIsControlAvatar ? LLPipeline::RENDER_TYPE_CONTROL_AV : LLPipeline::RENDER_TYPE_AVATAR))) { return TRUE; @@ -7459,6 +7494,14 @@ LLViewerJoint* LLVOAvatar::getViewerJoint(S32 idx) return (mMeshLOD[idx] && mMeshLOD[idx]->asViewerJoint()) ? mMeshLOD[idx]->asViewerJoint() : nullptr; } +//----------------------------------------------------------------------------- +// hideHair() +//----------------------------------------------------------------------------- +void LLVOAvatar::hideHair() +{ + mMeshLOD[MESH_ID_HAIR]->setVisible(FALSE, TRUE); +} + //----------------------------------------------------------------------------- // hideSkirt() //----------------------------------------------------------------------------- @@ -7610,8 +7653,8 @@ const LLViewerJointAttachment *LLVOAvatar::attachObject(LLViewerObject *viewer_o if (viewer_object->isSelected()) { - LLSelectMgr::getInstanceFast()->updateSelectionCenter(); - LLSelectMgr::getInstanceFast()->updatePointAt(); + LLSelectMgr::getInstance()->updateSelectionCenter(); + LLSelectMgr::getInstance()->updatePointAt(); } viewer_object->refreshBakeTexture(); @@ -7893,9 +7936,9 @@ void LLVOAvatar::sitOnObject(LLViewerObject *sit_object) gAgentCamera.changeCameraToMouselook(); } - if (gAgentCamera.getFocusOnAvatar() && LLToolMgr::getInstanceFast()->inEdit()) + if (gAgentCamera.getFocusOnAvatar() && LLToolMgr::getInstance()->inEdit()) { - LLSelectNode* node = LLSelectMgr::getInstanceFast()->getSelection()->getFirstRootNode(); + LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(); if (node && node->mValid) { LLViewerObject* root_object = node->getObject(); @@ -7950,7 +7993,7 @@ void LLVOAvatar::getOffObject() { stopMotionFromSource(sit_object->getID()); - auto& followcam_mgr = LLFollowCamMgr::instanceFast(); + auto& followcam_mgr = LLFollowCamMgr::instance(); followcam_mgr.setCameraActive(sit_object->getID(), FALSE); LLViewerObject::const_child_list_t& child_list = sit_object->getChildren(); @@ -8180,6 +8223,8 @@ void LLVOAvatar::onGlobalColorChanged(const LLTexGlobalColor* global_color, bool // Do rigged mesh attachments display with this av? bool LLVOAvatar::shouldRenderRigged() const { + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; + if (getOverallAppearance() == AOA_NORMAL) { return true; @@ -8380,7 +8425,7 @@ void LLVOAvatar::logMetricsTimerRecord(const std::string& phase_name, F32 elapse record["elapsed"] = elapsed; record["completed"] = completed; U32 grid_x(0), grid_y(0); - if (!isDead() && getRegion() && LLWorld::instanceFast().isRegionListed(getRegion())) + if (!isDead() && getRegion() && LLWorld::instance().isRegionListed(getRegion())) { record["central_bake_version"] = LLSD::Integer(getRegion()->getCentralBakeVersion()); grid_from_region_handle(getRegion()->getHandle(), &grid_x, &grid_y); @@ -8443,7 +8488,7 @@ void LLVOAvatar::updateRuthTimer(bool loading) << "( Head : " << isTextureDefined(TEX_HEAD_BAKED) << " )." << LL_ENDL; - LLAvatarPropertiesProcessor::getInstanceFast()->sendAvatarTexturesRequest(getID()); + LLAvatarPropertiesProcessor::getInstance()->sendAvatarTexturesRequest(getID()); mRuthTimer.reset(); } } @@ -8451,16 +8496,35 @@ void LLVOAvatar::updateRuthTimer(bool loading) BOOL LLVOAvatar::processFullyLoadedChange(bool loading) { // We wait a little bit before giving the 'all clear', to let things to - // settle down (models to snap into place, textures to get first packets) + // settle down (models to snap into place, textures to get first packets). + // And if viewer isn't aware of some parts yet, this gives them a chance + // to arrive. const F32 LOADED_DELAY = 1.f; - const F32 FIRST_USE_DELAY = 3.f; - if (loading) - mFullyLoadedTimer.reset(); + if (loading) + { + mFullyLoadedTimer.reset(); + } if (mFirstFullyVisible) { - mFullyLoaded = (mFullyLoadedTimer.getElapsedTimeF32() > FIRST_USE_DELAY); + if (!isSelf() && loading) + { + // Note that textures can causes 60s delay on thier own + // so this delay might end up on top of textures' delay + mFirstUseDelaySeconds = llclamp( + mFirstAppearanceMessageTimer.getElapsedTimeF32(), + FIRST_APPEARANCE_CLOUD_MIN_DELAY, + FIRST_APPEARANCE_CLOUD_MAX_DELAY); + + if (shouldImpostor()) + { + // Impostors are less of a priority, + // let them stay cloud longer + mFirstUseDelaySeconds *= 1.25; + } + } + mFullyLoaded = (mFullyLoadedTimer.getElapsedTimeF32() > mFirstUseDelaySeconds); } else { @@ -8687,6 +8751,7 @@ void LLVOAvatar::updateMeshVisibility() // virtual void LLVOAvatar::updateMeshTextures() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR static S32 update_counter = 0; mBakedTextureDebugText.clear(); @@ -9205,6 +9270,9 @@ void LLVOAvatar::onFirstTEMessageReceived() mMeshTexturesDirty = TRUE; gPipeline.markGLRebuild(this); + + mFirstAppearanceMessageTimer.reset(); + mFullyLoadedTimer.reset(); } } @@ -9264,7 +9332,7 @@ void dump_visual_param(apr_file_t* file, LLVisualParam* viewer_param, F32 value) S32 u8_value = F32_to_U8(value,viewer_param->getMinWeight(),viewer_param->getMaxWeight()); apr_file_printf(file, "\t\t<param id=\"%d\" name=\"%s\" display=\"%s\" value=\"%.3f\" u8=\"%d\" type=\"%s\" wearable=\"%s\" group=\"%d\"/>\n", viewer_param->getID(), viewer_param->getName().c_str(), viewer_param->getDisplayName().c_str(), value, u8_value, type_string.c_str(), - LLWearableType::getInstanceFast()->getTypeName(LLWearableType::EType(wtype)).c_str(), + LLWearableType::getInstance()->getTypeName(LLWearableType::EType(wtype)).c_str(), viewer_param->getGroup()); } @@ -9684,7 +9752,7 @@ void LLVOAvatar::applyParsedAppearanceMessage(LLAppearanceMessageContents& conte { // re-request appearance, hoping that it comes back with a shape next time LL_INFOS() << "Re-requesting AvatarAppearance for object: " << getID() << LL_ENDL; - LLAvatarPropertiesProcessor::getInstanceFast()->sendAvatarTexturesRequest(getID()); + LLAvatarPropertiesProcessor::getInstance()->sendAvatarTexturesRequest(getID()); mRuthTimer.reset(); } else @@ -9757,6 +9825,54 @@ LLViewerTexture* LLVOAvatar::getBakedTexture(const U8 te) } +const LLVOAvatar::MatrixPaletteCache& LLVOAvatar::updateSkinInfoMatrixPalette(const LLMeshSkinInfo* skin) +{ + U64 hash = skin->mHash; + MatrixPaletteCache& entry = mMatrixPaletteCache[hash]; + + if (entry.mFrame != gFrameCount) + { + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; + + entry.mFrame = gFrameCount; + + //build matrix palette + U32 count = LLSkinningUtil::getMeshJointCount(skin); + entry.mMatrixPalette.resize(count); + LLSkinningUtil::initSkinningMatrixPalette(&(entry.mMatrixPalette[0]), count, skin, this); + + const LLMatrix4a* mat = &(entry.mMatrixPalette[0]); + + entry.mGLMp.resize(count * 12); + + F32* mp = &(entry.mGLMp[0]); + + for (U32 i = 0; i < count; ++i) + { + F32* m = (F32*)mat[i].mMatrix[0].getF32ptr(); + + U32 idx = i * 12; + + mp[idx + 0] = m[0]; + mp[idx + 1] = m[1]; + mp[idx + 2] = m[2]; + mp[idx + 3] = m[12]; + + mp[idx + 4] = m[4]; + mp[idx + 5] = m[5]; + mp[idx + 6] = m[6]; + mp[idx + 7] = m[13]; + + mp[idx + 8] = m[8]; + mp[idx + 9] = m[9]; + mp[idx + 10] = m[10]; + mp[idx + 11] = m[14]; + } + } + + return entry; +} + // static void LLVOAvatar::getAnimLabels( std::vector<std::string>* labels ) { @@ -10063,7 +10179,7 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara } LLAPRFile outfile; - LLWearableType *wr_inst = LLWearableType::getInstanceFast(); + LLWearableType *wr_inst = LLWearableType::getInstance(); std::string fullpath = file_picker.getFirstFile(); if (APR_SUCCESS == outfile.open(fullpath, LL_APR_WB )) { @@ -10472,23 +10588,6 @@ LLHost LLVOAvatar::getObjectHost() const } } -//static -void LLVOAvatar::updateFreezeCounter(S32 counter) -{ - if(counter) - { - sFreezeCounter = counter; - } - else if(sFreezeCounter > 0) - { - sFreezeCounter--; - } - else - { - sFreezeCounter = 0; - } -} - BOOL LLVOAvatar::updateLOD() { if (mDrawable.isNull()) @@ -10551,6 +10650,7 @@ void showRigInfoTabExtents(LLVOAvatar *avatar, LLJointRiggingInfoTab& tab, S32& void LLVOAvatar::getAssociatedVolumes(std::vector<LLVOVolume*>& volumes) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; #if SLOW_ATTACHMENT_LIST for (const auto& attach_pair : mAttachmentPoints) { @@ -10612,14 +10712,10 @@ void LLVOAvatar::getAssociatedVolumes(std::vector<LLVOVolume*>& volumes) } } -static LLTrace::BlockTimerStatHandle FTM_AVATAR_RIGGING_INFO_UPDATE("Av Upd Rig Info"); -static LLTrace::BlockTimerStatHandle FTM_AVATAR_RIGGING_KEY_UPDATE("Av Upd Rig Key"); -static LLTrace::BlockTimerStatHandle FTM_AVATAR_RIGGING_AVOL_UPDATE("Av Upd Avol"); - // virtual void LLVOAvatar::updateRiggingInfo() { - LL_RECORD_BLOCK_TIME(FTM_AVATAR_RIGGING_INFO_UPDATE); + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; #ifdef SHOW_DEBUG LL_DEBUGS("RigSpammish") << getFullname() << " updating rig tab" << LL_ENDL; @@ -10627,16 +10723,12 @@ void LLVOAvatar::updateRiggingInfo() static std::vector<LLVOVolume*> volumes; volumes.clear(); - { - LL_RECORD_BLOCK_TIME(FTM_AVATAR_RIGGING_AVOL_UPDATE); - getAssociatedVolumes(volumes); - } + getAssociatedVolumes(volumes); mLastAssocVolSize = volumes.size(); size_t rig_hash; size_t rig_count; { - LL_RECORD_BLOCK_TIME(FTM_AVATAR_RIGGING_KEY_UPDATE); // Get current rigging info key rigging_info_hash_vec_t curr_rigging_info_key; @@ -10762,7 +10854,7 @@ void LLVOAvatar::getImpostorValues(LLVector4a* extents, LLVector3& angle, F32& d extents[0] = ext[0]; extents[1] = ext[1]; - auto& vwrCamera = LLViewerCamera::instanceFast(); + auto& vwrCamera = LLViewerCamera::instance(); LLVector3 at = vwrCamera.getOrigin()-(getRenderPosition()+mImpostorOffset); distance = at.normalize(); @@ -10808,6 +10900,7 @@ void LLVOAvatar::updateImpostorRendering(U32 newMaxNonImpostorsValue) void LLVOAvatar::idleUpdateRenderComplexity() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; if (isControlAvatar()) { LLControlAvatar *cav = static_cast<LLControlAvatar*>(this); @@ -11369,6 +11462,7 @@ void LLVOAvatar::updateOverallAppearanceAnimations() // Based on isVisuallyMuted(), but has 3 possible results. LLVOAvatar::AvatarOverallAppearance LLVOAvatar::getOverallAppearance() const { + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; AvatarOverallAppearance result = AOA_NORMAL; // Priority order (highest priority first) diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 9f3de4933b4eb60bd0cf412e563b4daffc399bf3..3071e3da87cc889271455e4c1c1ea39d8cd9279c 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -55,6 +55,7 @@ #include "llviewerstats.h" #include "llvovolume.h" #include "llavatarrendernotifier.h" +#include "llmodel.h" extern const LLUUID ANIM_AGENT_BODY_NOISE; extern const LLUUID ANIM_AGENT_BREATHE_ROT; @@ -79,6 +80,7 @@ class LLViewerJointMesh; const F32 MAX_AVATAR_LOD_FACTOR = 1.0f; +extern U32 gFrameCount; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // LLVOAvatar @@ -89,6 +91,7 @@ class LLVOAvatar : public LLViewerObject, public boost::signals2::trackable { + LL_ALIGN_NEW; LOG_CLASS(LLVOAvatar); public: @@ -101,16 +104,6 @@ class LLVOAvatar : **/ public: - void* operator new(size_t size) - { - return LLTrace::MemTrackable<LLViewerObject>::aligned_new<16>(size); - } - - void operator delete(void* ptr, size_t size) - { - LLTrace::MemTrackable<LLViewerObject>::aligned_delete<16>(ptr, size); - } - LLVOAvatar(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp); void markDead() override; static void initClass(); // Initialize data that's only init'd once per class. @@ -211,6 +204,11 @@ class LLVOAvatar : virtual LLJoint* getJoint(const std::string &name) override; LLJoint* getJoint(S32 num); + //if you KNOW joint_num is a valid animated joint index, use getSkeletonJoint for efficiency + inline LLJoint* getSkeletonJoint(S32 joint_num) { return mSkeleton[joint_num]; } + inline size_t getSkeletonJointCount() const { return mSkeleton.size(); } + + void notifyAttachmentMeshLoaded(); void addAttachmentOverridesForObject(LLViewerObject *vo, std::set<LLUUID>* meshes_seen = NULL, bool recursive = true); void removeAttachmentOverridesForObject(const LLUUID& mesh_id); void removeAttachmentOverridesForObject(LLViewerObject *vo); @@ -336,7 +334,6 @@ class LLVOAvatar : static bool sLimitNonImpostors; // use impostors for far away avatars static F32 sRenderDistance; // distance at which avatars will render. static BOOL sShowAnimationDebug; // show animation debug info - static BOOL sShowFootPlane; // show foot collision plane reported by server static BOOL sShowCollisionVolumes; // show skeletal collision volumes static BOOL sVisibleInFirstPerson; static S32 sNumLODChangesThisFrame; @@ -346,7 +343,8 @@ class LLVOAvatar : static F32 sLODFactor; // user-settable LOD factor static F32 sPhysicsLODFactor; // user-settable physics LOD factor static BOOL sJointDebug; // output total number of joints being touched for each avatar - static BOOL sDebugAvatarRotation; + + static LLPointer<LLViewerTexture> sCloudTexture; //-------------------------------------------------------------------- // Region state @@ -389,6 +387,9 @@ class LLVOAvatar : private: BOOL mFirstFullyVisible; + F32 mFirstUseDelaySeconds; + LLFrameTimer mFirstAppearanceMessageTimer; + BOOL mFullyLoaded; BOOL mPreviousFullyLoaded; BOOL mFullyLoadedInitialized; @@ -627,14 +628,6 @@ class LLVOAvatar : private: BOOL mCulled; - //-------------------------------------------------------------------- - // Freeze counter - //-------------------------------------------------------------------- -public: - static void updateFreezeCounter(S32 counter = 0); -private: - static S32 sFreezeCounter; - //-------------------------------------------------------------------- // Constants //-------------------------------------------------------------------- @@ -759,6 +752,34 @@ class LLVOAvatar : void updateMeshVisibility(); LLViewerTexture* getBakedTexture(const U8 te); + // Matrix palette cache entry + class alignas(16) MatrixPaletteCache + { + public: + // Last frame this entry was updated + U32 mFrame; + + // List of Matrix4a's for this entry + LLMeshSkinInfo::matrix_list_t mMatrixPalette; + + // Float array ready to be sent to GL + std::vector<F32> mGLMp; + + MatrixPaletteCache() : + mFrame(gFrameCount - 1) + { + } + }; + + // Accessor for Matrix Palette Cache + // Will do a map lookup for the entry associated with the given MeshSkinInfo + // Will update said entry if it hasn't been updated yet this frame + const MatrixPaletteCache& updateSkinInfoMatrixPalette(const LLMeshSkinInfo* skinInfo); + + // Map of LLMeshSkinInfo::mHash to MatrixPaletteCache + typedef std::unordered_map<U64, MatrixPaletteCache> matrix_palette_cache_t; + matrix_palette_cache_t mMatrixPaletteCache; + protected: void releaseMeshData(); virtual void restoreMeshData(); @@ -790,6 +811,7 @@ class LLVOAvatar : void parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMessageContents& msg); void processAvatarAppearance(LLMessageSystem* mesgsys); void applyParsedAppearanceMessage(LLAppearanceMessageContents& contents, bool slam_params); + void hideHair(); void hideSkirt(); void startAppearanceAnimation(); /*virtual*/ void bodySizeChanged() override; diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index cb717bb259353782da3e01c1bd815b430302a67c..0e148eebde938c1b1f944177c240655bd77f4190 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -366,7 +366,7 @@ BOOL LLVOAvatarSelf::buildSkeletonSelf(const LLAvatarSkeletonInfo *info) mScreenp = new LLViewerJoint("mScreen", NULL); // for now, put screen at origin, as it is only used during special // HUD rendering mode - F32 aspect = LLViewerCamera::getInstanceFast()->getAspect(); + F32 aspect = LLViewerCamera::getInstance()->getAspect(); LLVector3 scale(1.f, aspect, 1.f); mScreenp->setScale(scale); // SL-315 @@ -703,7 +703,7 @@ bool LLVOAvatarSelf::updateCharacter(LLAgent &agent) // update screen joint size if (mScreenp) { - F32 aspect = LLViewerCamera::getInstanceFast()->getAspect(); + F32 aspect = LLViewerCamera::getInstance()->getAspect(); LLVector3 scale(1.f, aspect, 1.f); mScreenp->setScale(scale); mScreenp->updateWorldMatrixChildren(); @@ -1023,7 +1023,7 @@ void LLVOAvatarSelf::idleUpdateTractorBeam() else if (!mBeam || mBeam->isDead()) { // VEFFECT: Tractor Beam - mBeam = (LLHUDEffectSpiral *)LLHUDManager::getInstanceFast()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM); + mBeam = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM); mBeam->setColor(LLColor4U(gAgent.getEffectColor())); mBeam->setSourceObject(this); mBeamTimer.reset(); @@ -1031,7 +1031,7 @@ void LLVOAvatarSelf::idleUpdateTractorBeam() if (!mBeam.isNull()) { - LLObjectSelectionHandle selection = LLSelectMgr::getInstanceFast()->getSelection(); + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); if (gAgentCamera.mPointAt.notNull()) { @@ -1048,7 +1048,7 @@ void LLVOAvatarSelf::idleUpdateTractorBeam() else { mBeam->setTargetObject(NULL); - LLTool *tool = LLToolMgr::getInstanceFast()->getCurrentTool(); + LLTool *tool = LLToolMgr::getInstance()->getCurrentTool(); if (tool->isEditing()) { if (tool->getEditingObject()) @@ -1334,7 +1334,7 @@ BOOL LLVOAvatarSelf::detachObject(LLViewerObject *viewer_object) // the simulator should automatically handle permission revocation stopMotionFromSource(attachment_id); - LLFollowCamMgr::getInstanceFast()->setCameraActive(viewer_object->getID(), FALSE); + LLFollowCamMgr::getInstance()->setCameraActive(viewer_object->getID(), FALSE); LLViewerObject::const_child_list_t& child_list = viewer_object->getChildren(); for (LLViewerObject* child_objectp : child_list) @@ -1343,7 +1343,7 @@ BOOL LLVOAvatarSelf::detachObject(LLViewerObject *viewer_object) // permissions revocation stopMotionFromSource(child_objectp->getID()); - LLFollowCamMgr::getInstanceFast()->setCameraActive(child_objectp->getID(), FALSE); + LLFollowCamMgr::getInstance()->setCameraActive(child_objectp->getID(), FALSE); } // Make sure the inventory is in sync with the avatar. @@ -1387,7 +1387,7 @@ BOOL LLVOAvatarSelf::detachAttachmentIntoInventory(const LLUUID &item_id) LLViewerObject *found_obj = gObjectList.findObject(item_id); if (found_obj) { - LLSelectMgr::getInstanceFast()->remove(found_obj); + LLSelectMgr::getInstance()->remove(found_obj); } // Error checking in case this object was attached to an invalid point @@ -2205,7 +2205,7 @@ void LLVOAvatarSelf::debugBakedTextureUpload(EBakedTextureIndex index, BOOL fini const std::string LLVOAvatarSelf::verboseDebugDumpLocalTextureDataInfo(const LLViewerTexLayerSet* layerset) const { std::ostringstream outbuf; - LLWearableType *wr_inst = LLWearableType::getInstanceFast(); + LLWearableType *wr_inst = LLWearableType::getInstance(); for (const auto& baked_pair : sAvatarDictionary->getBakedTextures()) { const EBakedTextureIndex baked_index = baked_pair.first; @@ -2279,7 +2279,7 @@ void LLVOAvatarSelf::dumpAllTextures() const const std::string LLVOAvatarSelf::debugDumpLocalTextureDataInfo(const LLViewerTexLayerSet* layerset) const { std::string text=""; - LLWearableType *wr_inst = LLWearableType::getInstanceFast(); + LLWearableType *wr_inst = LLWearableType::getInstance(); text = llformat("[Final:%d Avail:%d] ",isLocalTextureDataFinal(layerset), isLocalTextureDataAvailable(layerset)); @@ -3163,16 +3163,16 @@ F32 LLVOAvatarSelf::getAvatarOffset() /*const*/ //------------------------------------------------------------------------ BOOL LLVOAvatarSelf::needsRenderBeam() { - LLTool *tool = LLToolMgr::getInstanceFast()->getCurrentTool(); + LLTool *tool = LLToolMgr::getInstance()->getCurrentTool(); - BOOL is_touching_or_grabbing = (tool == LLToolGrab::getInstanceFast() && LLToolGrab::getInstanceFast()->isEditing()); - if (LLToolGrab::getInstanceFast()->getEditingObject() && - LLToolGrab::getInstanceFast()->getEditingObject()->isAttachment()) + BOOL is_touching_or_grabbing = (tool == LLToolGrab::getInstance() && LLToolGrab::getInstance()->isEditing()); + if (LLToolGrab::getInstance()->getEditingObject() && + LLToolGrab::getInstance()->getEditingObject()->isAttachment()) { // don't render selection beam on hud objects is_touching_or_grabbing = FALSE; } - return is_touching_or_grabbing || (getAttachmentState() & AGENT_STATE_EDITING && LLSelectMgr::getInstanceFast()->shouldShowSelection()); + return is_touching_or_grabbing || (getAttachmentState() & AGENT_STATE_EDITING && LLSelectMgr::getInstance()->shouldShowSelection()); } // static @@ -3216,7 +3216,7 @@ void LLVOAvatarSelf::dumpWearableInfo(LLAPRFile& outfile) apr_file_printf( file, "\n<wearable_info>\n" ); LLWearableData *wd = getWearableData(); - LLWearableType *wr_inst = LLWearableType::getInstanceFast(); + LLWearableType *wr_inst = LLWearableType::getInstance(); for (S32 type = 0; type < LLWearableType::WT_COUNT; type++) { const std::string& type_name = wr_inst->getTypeName((LLWearableType::EType)type); diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp index c35467a5a0af403fcf082af88d688a94e8cc6633..2ef06b048a632d7018e7c4bbaba43ed6d9965374 100644 --- a/indra/newview/llvocache.cpp +++ b/indra/newview/llvocache.cpp @@ -64,8 +64,7 @@ BOOL check_write(LLAPRFile* apr_file, void* src, S32 n_bytes) //--------------------------------------------------------------------------- LLVOCacheEntry::LLVOCacheEntry(U32 local_id, U32 crc, LLDataPackerBinaryBuffer &dp) -: LLTrace::MemTrackable<LLVOCacheEntry, 16>("LLVOCacheEntry"), - LLViewerOctreeEntryData(LLViewerOctreeEntry::LLVOCACHEENTRY), +: LLViewerOctreeEntryData(LLViewerOctreeEntry::LLVOCACHEENTRY), mLocalID(local_id), mCRC(crc), mUpdateFlags(-1), @@ -84,8 +83,7 @@ LLVOCacheEntry::LLVOCacheEntry(U32 local_id, U32 crc, LLDataPackerBinaryBuffer & } LLVOCacheEntry::LLVOCacheEntry() -: LLTrace::MemTrackable<LLVOCacheEntry, 16>("LLVOCacheEntry"), - LLViewerOctreeEntryData(LLViewerOctreeEntry::LLVOCACHEENTRY), +: LLViewerOctreeEntryData(LLViewerOctreeEntry::LLVOCACHEENTRY), mLocalID(0), mCRC(0), mUpdateFlags(-1), @@ -103,8 +101,7 @@ LLVOCacheEntry::LLVOCacheEntry() } LLVOCacheEntry::LLVOCacheEntry(LLAPRFile* apr_file) -: LLTrace::MemTrackable<LLVOCacheEntry, 16>("LLVOCacheEntry"), - LLViewerOctreeEntryData(LLViewerOctreeEntry::LLVOCACHEENTRY), +: LLViewerOctreeEntryData(LLViewerOctreeEntry::LLVOCACHEENTRY), mBuffer(NULL), mUpdateFlags(-1), mState(INACTIVE), @@ -370,15 +367,6 @@ void LLVOCacheEntry::updateDebugSettings() } timer.reset(); - //the number of frames invisible objects stay in memory - static LLCachedControl<U32> inv_obj_time(gSavedSettings,"NonvisibleObjectsInMemoryTime"); - sMinFrameRange = inv_obj_time - 1; //make 0 to be the maximum - - //min radius: all objects within this radius remain loaded in memory - static LLCachedControl<F32> min_radius(gSavedSettings,"SceneLoadMinRadius"); - sNearRadius = llmin((F32)min_radius, gAgentCamera.mDrawDistance); //can not exceed the draw distance - sNearRadius = llmax(sNearRadius, 1.f); //minimum value is 1.0m - //objects within the view frustum whose visible area is greater than this threshold will be loaded static LLCachedControl<F32> front_pixel_threshold(gSavedSettings,"SceneLoadFrontPixelThreshold"); sFrontPixelThreshold = front_pixel_threshold; @@ -388,29 +376,38 @@ void LLVOCacheEntry::updateDebugSettings() sRearPixelThreshold = rear_pixel_threshold; sRearPixelThreshold = llmax(sRearPixelThreshold, sFrontPixelThreshold); //can not be smaller than sFrontPixelThreshold. - // a percentage of draw distance beyond which all objects outside of view frustum will be unloaded, regardless of pixel threshold - static LLCachedControl<F32> rear_max_radius_frac(gSavedSettings,"SceneLoadRearMaxRadiusFraction"); - sRearFarRadius = llmax(rear_max_radius_frac * gAgentCamera.mDrawDistance / 100.f, 1.0f); //minimum value is 1.0m - sRearFarRadius = llmax(sRearFarRadius, (F32)min_radius); //can not be less than "SceneLoadMinRadius". - sRearFarRadius = llmin(sRearFarRadius, gAgentCamera.mDrawDistance); //can not be more than the draw distance. - - //make the above parameters adaptive to memory usage + //make parameters adaptive to memory usage //starts to put restrictions from low_mem_bound_MB, apply tightest restrictions when hits high_mem_bound_MB static LLCachedControl<U32> low_mem_bound_MB(gSavedSettings,"SceneLoadLowMemoryBound"); static LLCachedControl<U32> high_mem_bound_MB(gSavedSettings,"SceneLoadHighMemoryBound"); LLMemory::updateMemoryInfo() ; U32 allocated_mem = LLMemory::getAllocatedMemKB().value(); - allocated_mem /= 1024; //convert to MB. - if(allocated_mem < low_mem_bound_MB) - { - return; - } - F32 adjust_factor = llmax(0.f, (F32)(high_mem_bound_MB - allocated_mem) / (high_mem_bound_MB - low_mem_bound_MB)); - - sRearFarRadius = llmin(adjust_factor * sRearFarRadius, 96.f); //[0.f, 96.f] - sMinFrameRange = (U32)llclamp(adjust_factor * sMinFrameRange, 10.f, 64.f); //[10, 64] - sNearRadius = llmax(adjust_factor * sNearRadius, 1.0f); + static const F32 KB_to_MB = 1.f / 1024.f; + U32 clamped_memory = llclamp(allocated_mem * KB_to_MB, (F32) low_mem_bound_MB, (F32) high_mem_bound_MB); + const F32 adjust_range = high_mem_bound_MB - low_mem_bound_MB; + const F32 adjust_factor = (high_mem_bound_MB - clamped_memory) / adjust_range; // [0, 1] + + //min radius: all objects within this radius remain loaded in memory + static LLCachedControl<F32> min_radius(gSavedSettings,"SceneLoadMinRadius"); + static const F32 MIN_RADIUS = 1.0f; + const F32 draw_radius = gAgentCamera.mDrawDistance; + const F32 clamped_min_radius = llclamp((F32) min_radius, MIN_RADIUS, draw_radius); // [1, mDrawDistance] + sNearRadius = MIN_RADIUS + ((clamped_min_radius - MIN_RADIUS) * adjust_factor); + + // a percentage of draw distance beyond which all objects outside of view frustum will be unloaded, regardless of pixel threshold + static LLCachedControl<F32> rear_max_radius_frac(gSavedSettings,"SceneLoadRearMaxRadiusFraction"); + const F32 min_radius_plus_one = sNearRadius + 1.f; + const F32 max_radius = rear_max_radius_frac * gAgentCamera.mDrawDistance; + const F32 clamped_max_radius = llclamp(max_radius, min_radius_plus_one, draw_radius); // [sNearRadius, mDrawDistance] + sRearFarRadius = min_radius_plus_one + ((clamped_max_radius - min_radius_plus_one) * adjust_factor); + + //the number of frames invisible objects stay in memory + static LLCachedControl<U32> inv_obj_time(gSavedSettings,"NonvisibleObjectsInMemoryTime"); + static const U32 MIN_FRAMES = 10; + static const U32 MAX_FRAMES = 64; + const U32 clamped_frames = inv_obj_time ? llclamp((U32) inv_obj_time, MIN_FRAMES, MAX_FRAMES) : MAX_FRAMES; // [10, 64], with zero => 64 + sMinFrameRange = MIN_FRAMES + ((clamped_frames - MIN_FRAMES) * adjust_factor); } //static @@ -427,7 +424,7 @@ F32 LLVOCacheEntry::getSquaredPixelThreshold(bool is_front) } //object projected area threshold - F32 pixel_meter_ratio = LLViewerCamera::getInstanceFast()->getPixelMeterRatio(); + F32 pixel_meter_ratio = LLViewerCamera::getInstance()->getPixelMeterRatio(); F32 projection_threshold = pixel_meter_ratio > 0.f ? threshold / pixel_meter_ratio : 0.f; projection_threshold *= projection_threshold; @@ -616,7 +613,6 @@ void LLVOCacheGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* c } LLVOCachePartition::LLVOCachePartition(LLViewerRegion* regionp) -: LLTrace::MemTrackable<LLVOCachePartition>("LLVOCachePartition") { mLODPeriod = 16; mRegionp = regionp; @@ -633,6 +629,13 @@ LLVOCachePartition::LLVOCachePartition(LLViewerRegion* regionp) new LLVOCacheGroup(mOctree, this); } +LLVOCachePartition::~LLVOCachePartition() +{ + // SL-17276 make sure to do base class cleanup while this instance + // can still be treated as an LLVOCachePartition + cleanup(); +} + bool LLVOCachePartition::addEntry(LLViewerOctreeEntry* entry) { llassert(entry->hasVOCacheEntry()); diff --git a/indra/newview/llvocache.h b/indra/newview/llvocache.h index d94234bebe2a8513c6274ee11da0f67d12d59f8c..099bfe06a328bf4e4dea8782153709a04b2d179e 100644 --- a/indra/newview/llvocache.h +++ b/indra/newview/llvocache.h @@ -38,9 +38,9 @@ class LLCamera; class LLVOCacheEntry final -: public LLViewerOctreeEntryData, - public LLTrace::MemTrackable<LLVOCacheEntry, 16> +: public LLViewerOctreeEntryData { + LL_ALIGN_NEW public: enum { @@ -185,10 +185,11 @@ class LLVOCacheGroup final : public LLOcclusionCullingGroup virtual ~LLVOCacheGroup(); }; -class LLVOCachePartition final : public LLViewerOctreePartition, public LLTrace::MemTrackable<LLVOCachePartition> +class LLVOCachePartition final : public LLViewerOctreePartition { public: LLVOCachePartition(LLViewerRegion* regionp); + virtual ~LLVOCachePartition(); bool addEntry(LLViewerOctreeEntry* entry); void removeEntry(LLViewerOctreeEntry* entry); diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp index eba3950b0d9275a47273a0d23af816f492237d0b..f3263abeedb823137145360319ce3e70131fd859 100644 --- a/indra/newview/llvograss.cpp +++ b/indra/newview/llvograss.cpp @@ -316,7 +316,7 @@ void LLVOGrass::setPixelAreaAndAngle(LLAgent &agent) mAppAngle = (F32) atan2( max_scale, range) * RAD_TO_DEG; // Compute pixels per meter at the given range - auto& viewerCamera = LLViewerCamera::instanceFast(); + auto& viewerCamera = LLViewerCamera::instance(); F32 pixels_per_meter = viewerCamera.getViewHeightInPixels() / (tan(viewerCamera.getView()) * range); // Assume grass texture is a 5 meter by 5 meter sprite at the grass object's center @@ -457,7 +457,7 @@ void LLVOGrass::plantBlades() face->mCenterLocal = mPosition + mRegionp->getOriginAgent(); } - auto& viewerCamera = LLViewerCamera::instanceFast(); + auto& viewerCamera = LLViewerCamera::instance(); mDepth = (face->mCenterLocal - viewerCamera.getOrigin())* viewerCamera.getAtAxis(); mDrawable->setPosition(face->mCenterLocal); mDrawable->movePartition(); @@ -612,7 +612,7 @@ void LLGrassPartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_count mFaceList.clear(); - LLViewerCamera* camera = LLViewerCamera::getInstanceFast(); + LLViewerCamera* camera = LLViewerCamera::getInstance(); for (LLSpatialGroup::element_iter i = group->getDataBegin(), i_end = group->getDataEnd(); i != i_end; ++i) { LLDrawable* drawablep = (LLDrawable*)(*i)->getDrawable(); @@ -662,11 +662,9 @@ void LLGrassPartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_count } } -static LLTrace::BlockTimerStatHandle FTM_REBUILD_GRASS_VB("Grass VB"); - void LLGrassPartition::getGeometry(LLSpatialGroup* group) { - LL_RECORD_BLOCK_TIME(FTM_REBUILD_GRASS_VB); + LL_PROFILE_ZONE_SCOPED; std::sort(mFaceList.begin(), mFaceList.end(), LLFace::CompareDistanceGreater()); diff --git a/indra/newview/llvoground.cpp b/indra/newview/llvoground.cpp index 689705b150bd456b73d9f6f783c0e08f26eb1b31..95264fe77373a3c9db7633431c6b63a8fd4537c0 100644 --- a/indra/newview/llvoground.cpp +++ b/indra/newview/llvoground.cpp @@ -115,13 +115,13 @@ BOOL LLVOGround::updateGeometry(LLDrawable *drawable) // // // - LLVector3 at_dir = LLViewerCamera::getInstanceFast()->getAtAxis(); + LLVector3 at_dir = LLViewerCamera::getInstance()->getAtAxis(); at_dir.mV[VZ] = 0.f; if (at_dir.normVec() < 0.01) { // We really don't care, as we're not looking anywhere near the horizon. } - LLVector3 left_dir = LLViewerCamera::getInstanceFast()->getLeftAxis(); + LLVector3 left_dir = LLViewerCamera::getInstance()->getLeftAxis(); left_dir.mV[VZ] = 0.f; left_dir.normVec(); diff --git a/indra/newview/llvoicechannel.cpp b/indra/newview/llvoicechannel.cpp index d52cd652ce0e693e56224ea45c79e10414f64b24..5c2784b6805d0744168b1f1561d41a2a21f5048b 100644 --- a/indra/newview/llvoicechannel.cpp +++ b/indra/newview/llvoicechannel.cpp @@ -193,7 +193,7 @@ void LLVoiceChannel::handleError(EStatusType type) BOOL LLVoiceChannel::isActive() { // only considered active when currently bound channel matches what our channel - return callStarted() && LLVoiceClient::getInstanceFast()->getCurrentChannel() == mURI; + return callStarted() && LLVoiceClient::getInstance()->getCurrentChannel() == mURI; } BOOL LLVoiceChannel::callStarted() @@ -216,18 +216,18 @@ void LLVoiceChannel::deactivate() //Default mic is OFF when leaving voice calls if (gSavedSettings.getBOOL("AutoDisengageMic") && sCurrentVoiceChannel == this && - LLVoiceClient::getInstanceFast()->getUserPTTState()) + LLVoiceClient::getInstance()->getUserPTTState()) { gSavedSettings.setBOOL("PTTCurrentlyEnabled", true); - LLVoiceClient::getInstanceFast()->setUserPTTState(false); + LLVoiceClient::getInstance()->setUserPTTState(false); } } - LLVoiceClient::getInstanceFast()->removeObserver(this); + LLVoiceClient::getInstance()->removeObserver(this); if (sCurrentVoiceChannel == this) { // default channel is proximal channel - sCurrentVoiceChannel = LLVoiceChannelProximal::getInstanceFast(); + sCurrentVoiceChannel = LLVoiceChannelProximal::getInstance(); sCurrentVoiceChannel->activate(); } } @@ -435,13 +435,13 @@ void LLVoiceChannelGroup::activate() if (callStarted()) { // we have the channel info, just need to use it now - LLVoiceClient::getInstanceFast()->setNonSpatialChannel( + LLVoiceClient::getInstance()->setNonSpatialChannel( mURI, mCredentials); if (!gAgent.isInGroup(mSessionID)) // ad-hoc channel { - LLIMModel::LLIMSession* session = LLIMModel::getInstanceFast()->findIMSession(mSessionID); + LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(mSessionID); // Adding ad-hoc call participants to Recent People List. // If it's an outgoing ad-hoc, we can use mInitialTargetIDs that holds IDs of people we // called(both online and offline) as source to get people for recent (STORM-210). @@ -451,7 +451,7 @@ void LLVoiceChannelGroup::activate() it!=session->mInitialTargetIDs.end();++it) { const LLUUID id = *it; - LLRecentPeople::instanceFast().add(id); + LLRecentPeople::instance().add(id); } } // If this ad-hoc is incoming then trying to get ids of people from mInitialTargetIDs @@ -463,9 +463,9 @@ void LLVoiceChannelGroup::activate() } //Mic default state is OFF on initiating/joining Ad-Hoc/Group calls - if (LLVoiceClient::getInstanceFast()->getUserPTTState() && LLVoiceClient::getInstanceFast()->getPTTIsToggle()) + if (LLVoiceClient::getInstance()->getUserPTTState() && LLVoiceClient::getInstance()->getPTTIsToggle()) { - LLVoiceClient::getInstanceFast()->inputUserControlState(true); + LLVoiceClient::getInstance()->inputUserControlState(true); } } @@ -516,7 +516,7 @@ void LLVoiceChannelGroup::setChannelInfo( else if ( mIsRetrying ) { // we have the channel info, just need to use it now - LLVoiceClient::getInstanceFast()->setNonSpatialChannel( + LLVoiceClient::getInstance()->setNonSpatialChannel( mURI, mCredentials); } @@ -674,7 +674,7 @@ LLVoiceChannelProximal::LLVoiceChannelProximal() : BOOL LLVoiceChannelProximal::isActive() { - return callStarted() && LLVoiceClient::getInstanceFast()->inProximalChannel(); + return callStarted() && LLVoiceClient::getInstance()->inProximalChannel(); } void LLVoiceChannelProximal::activate() @@ -684,7 +684,7 @@ void LLVoiceChannelProximal::activate() if((LLVoiceChannel::sCurrentVoiceChannel != this) && (LLVoiceChannel::getState() == STATE_CONNECTED)) { // we're connected to a non-spatial channel, so disconnect. - LLVoiceClient::getInstanceFast()->leaveNonSpatialChannel(); + LLVoiceClient::getInstance()->leaveNonSpatialChannel(); } LLVoiceChannel::activate(); @@ -716,10 +716,10 @@ void LLVoiceChannelProximal::handleStatusChange(EStatusType status) // do not notify user when leaving proximal channel return; case STATUS_VOICE_DISABLED: - LLVoiceClient::getInstanceFast()->setUserPTTState(false); + LLVoiceClient::getInstance()->setUserPTTState(false); gAgent.setVoiceConnected(false); //skip showing "Voice not available at your current location" when agent voice is disabled (EXT-4749) - if(LLVoiceClient::getInstanceFast()->voiceEnabled() && LLVoiceClient::getInstanceFast()->isVoiceWorking()) + if(LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking()) { //TODO: remove or redirect this call status notification // LLCallInfoDialog::show("unavailable", mNotifyArgs); @@ -842,12 +842,12 @@ void LLVoiceChannelP2P::activate() if (mSessionHandle.empty()) { mReceivedCall = FALSE; - LLVoiceClient::getInstanceFast()->callUser(mOtherUserID); + LLVoiceClient::getInstance()->callUser(mOtherUserID); } // otherwise answering the call else { - if (!LLVoiceClient::getInstanceFast()->answerInvite(mSessionHandle)) + if (!LLVoiceClient::getInstance()->answerInvite(mSessionHandle)) { mCallEndedByAgent = false; mSessionHandle.clear(); @@ -862,9 +862,9 @@ void LLVoiceChannelP2P::activate() addToTheRecentPeopleList(); //Default mic is ON on initiating/joining P2P calls - if (!LLVoiceClient::getInstanceFast()->getUserPTTState() && LLVoiceClient::getInstanceFast()->getPTTIsToggle()) + if (!LLVoiceClient::getInstance()->getUserPTTState() && LLVoiceClient::getInstance()->getPTTIsToggle()) { - LLVoiceClient::getInstanceFast()->inputUserControlState(true); + LLVoiceClient::getInstance()->inputUserControlState(true); } } } @@ -896,7 +896,7 @@ void LLVoiceChannelP2P::setSessionHandle(const std::string& handle, const std::s // we are active and have priority, invite the other user again // under the assumption they will join this new session mSessionHandle.clear(); - LLVoiceClient::getInstanceFast()->callUser(mOtherUserID); + LLVoiceClient::getInstance()->callUser(mOtherUserID); return; } } @@ -912,7 +912,7 @@ void LLVoiceChannelP2P::setSessionHandle(const std::string& handle, const std::s { LL_WARNS("Voice") << "incoming SIP URL is not provided. Channel may not work properly." << LL_ENDL; // See LLVoiceClient::sessionAddedEvent() - setURI(LLVoiceClient::getInstanceFast()->sipURIFromID(mOtherUserID)); + setURI(LLVoiceClient::getInstance()->sipURIFromID(mOtherUserID)); } mReceivedCall = TRUE; @@ -945,5 +945,5 @@ void LLVoiceChannelP2P::setState(EState state) void LLVoiceChannelP2P::addToTheRecentPeopleList() { - LLRecentPeople::instanceFast().add(mOtherUserID); + LLRecentPeople::instance().add(mOtherUserID); } diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index 2f62675108ee3d6599861dba588a4c43f863266e..487e294d54c88397dc1d446c034d1382a4af9be3 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -200,6 +200,7 @@ const LLVoiceVersionInfo LLVoiceClient::getVersion() LLVoiceVersionInfo result; result.serverVersion = std::string(); result.serverType = std::string(); + result.mBuildVersion = std::string(); return result; } } diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h index d6cffe38851f26fe226d0dd326f5b6f349b698ba..61991dd0d92f9a4929b568856cf08a4df7879d4b 100644 --- a/indra/newview/llvoiceclient.h +++ b/indra/newview/llvoiceclient.h @@ -95,6 +95,7 @@ struct LLVoiceVersionInfo { std::string serverType; std::string serverVersion; + std::string mBuildVersion; }; ////////////////////////////////// diff --git a/indra/newview/llvoicevisualizer.cpp b/indra/newview/llvoicevisualizer.cpp index 52c0717d9ab1dd003201de3d89ca0f78f76254dd..6e08a2ff12f78d877c3a0a7b2dabc1f52065d638 100644 --- a/indra/newview/llvoicevisualizer.cpp +++ b/indra/newview/llvoicevisualizer.cpp @@ -361,7 +361,7 @@ void LLVoiceVisualizer::render() //------------------------------------------------------------- // create coordinates of the geometry for the dot //------------------------------------------------------------- - LLViewerCamera* camera = LLViewerCamera::getInstanceFast(); + LLViewerCamera* camera = LLViewerCamera::getInstance(); LLVector3 l = camera->getLeftAxis() * DOT_SIZE; LLVector3 u = camera->getUpAxis() * DOT_SIZE; diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index 1b498c341fc7d29faf2bd7e92b8a992843896c59..f42bca727a66b2255285cd3d413cbffe36574e69 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -696,6 +696,10 @@ void LLVivoxVoiceClient::voiceControlCoro() // surviving longer than LLVivoxVoiceClient voiceControlStateMachine(state); } + catch (const LLCoros::Stop&) + { + LL_DEBUGS("LLVivoxVoiceClient") << "Received a shutdown exception" << LL_ENDL; + } catch (const LLContinueError&) { LOG_UNHANDLED_EXCEPTION("LLVivoxVoiceClient"); @@ -1631,13 +1635,33 @@ bool LLVivoxVoiceClient::requestParcelVoiceInfo() } else { - LL_WARNS("Voice") << "No voice channel credentials" << LL_ENDL; - + LLVoiceChannel* channel = LLVoiceChannel::getCurrentVoiceChannel(); + if (channel != NULL) + { + if (channel->getSessionName().empty() && channel->getSessionID().isNull()) + { + if (LLViewerParcelMgr::getInstance()->allowAgentVoice()) + { + LL_WARNS("Voice") << "No channel credentials for default channel" << LL_ENDL; + } + } + else + { + LL_WARNS("Voice") << "No voice channel credentials" << LL_ENDL; + } + } } } else { - LL_WARNS("Voice") << "No voice credentials" << LL_ENDL; + if (LLViewerParcelMgr::getInstance()->allowAgentVoice()) + { + LL_WARNS("Voice") << "No voice credentials" << LL_ENDL; + } + else + { + LL_DEBUGS("Voice") << "No voice credentials" << LL_ENDL; + } } // set the spatial channel. If no voice credentials or uri are @@ -4541,7 +4565,7 @@ void LLVivoxVoiceClient::messageEvent( if(session) { bool is_do_not_disturb = gAgent.isDoNotDisturb(); - bool is_muted = LLMuteList::getInstanceFast()->isMuted(session->mCallerID, session->mName, LLMute::flagTextChat); + bool is_muted = LLMuteList::getInstance()->isMuted(session->mCallerID, session->mName, LLMute::flagTextChat); bool is_linden = LLMuteList::isLinden(session->mName); LLChat chat; @@ -4613,6 +4637,23 @@ void LLVivoxVoiceClient::sessionNotificationEvent(std::string &sessionHandle, st } } +void LLVivoxVoiceClient::voiceServiceConnectionStateChangedEvent(int statusCode, std::string &statusString, std::string &build_id) +{ + // We don't generally need to process this. However, one occurence is when we first connect, and so it is the + // earliest opportunity to learn what we're connected to. + if (statusCode) + { + LL_WARNS("Voice") << "VoiceServiceConnectionStateChangedEvent statusCode: " << statusCode << + "statusString: " << statusString << LL_ENDL; + return; + } + if (build_id.empty()) + { + return; + } + mVoiceVersion.mBuildVersion = build_id; +} + void LLVivoxVoiceClient::auxAudioPropertiesEvent(F32 energy) { LL_DEBUGS("VoiceEnergy") << "got energy " << energy << LL_ENDL; @@ -4729,7 +4770,7 @@ bool LLVivoxVoiceClient::participantState::updateMuteState() { bool result = false; - bool isMuted = LLMuteList::getInstanceFast()->isMuted(mAvatarID, LLMute::flagVoiceChat); + bool isMuted = LLMuteList::getInstance()->isMuted(mAvatarID, LLMute::flagVoiceChat); if(mOnMuteList != isMuted) { mOnMuteList = isMuted; @@ -4799,7 +4840,7 @@ void LLVivoxVoiceClient::sessionState::VerifySessions() if ((*it).expired()) { LL_WARNS("Voice") << "Expired session found! removing" << LL_ENDL; - mSession.erase(it++); + it = mSession.erase(it); } else ++it; @@ -4885,7 +4926,7 @@ LLVivoxVoiceClient::participantStatePtr_t LLVivoxVoiceClient::findParticipantByI bool LLVivoxVoiceClient::checkParcelChanged(bool update) { LLViewerRegion *region = gAgent.getRegion(); - LLParcel *parcel = LLViewerParcelMgr::getInstanceFast()->getAgentParcel(); + LLParcel *parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); if(region && parcel) { @@ -5457,8 +5498,8 @@ void LLVivoxVoiceClient::updatePosition(void) // They're currently always set to zero. // Send the current camera position to the voice code - rot.setRows(LLViewerCamera::getInstanceFast()->getAtAxis(), LLViewerCamera::getInstanceFast()->getLeftAxis (), LLViewerCamera::getInstanceFast()->getUpAxis()); - pos = gAgent.getRegion()->getPosGlobalFromRegion(LLViewerCamera::getInstanceFast()->getOrigin()); + rot.setRows(LLViewerCamera::getInstance()->getAtAxis(), LLViewerCamera::getInstance()->getLeftAxis (), LLViewerCamera::getInstance()->getUpAxis()); + pos = gAgent.getRegion()->getPosGlobalFromRegion(LLViewerCamera::getInstance()->getOrigin()); LLVivoxVoiceClient::getInstance()->setCameraPosition( pos, // position @@ -5607,7 +5648,7 @@ bool LLVivoxVoiceClient::voiceEnabled() { static const LLCachedControl<bool> enable_voice_chat(gSavedSettings, "EnableVoiceChat"); static const LLCachedControl<bool> cmd_line_disable_voice(gSavedSettings, "CmdLineDisableVoice"); - return enable_voice_chat && !cmd_line_disable_voice; + return enable_voice_chat && !cmd_line_disable_voice && !gNonInteractive; } void LLVivoxVoiceClient::setLipSyncEnabled(BOOL enabled) @@ -6839,7 +6880,7 @@ void LLVivoxVoiceClient::deleteVoiceFont(const LLUUID& id) if (list_iter->second == id) { LL_DEBUGS("VoiceFont") << "Removing " << id << " from the voice font list." << LL_ENDL; - mVoiceFontList.erase(list_iter++); + list_iter = mVoiceFontList.erase(list_iter); mVoiceFontListDirty = true; } else @@ -7612,6 +7653,8 @@ void LLVivoxProtocolParser::EndTag(const char *tag) connectorHandle = string; else if (!stricmp("VersionID", tag)) versionID = string; + else if (!stricmp("Version", tag)) + mBuildID = string; else if (!stricmp("AccountHandle", tag)) accountHandle = string; else if (!stricmp("State", tag)) @@ -7926,7 +7969,8 @@ void LLVivoxProtocolParser::processResponse(std::string tag) // We don't need to process this, but we also shouldn't warn on it, since that confuses people. } else if (!stricmp(eventTypeCstr, "VoiceServiceConnectionStateChangedEvent")) - { // Yet another ignored event + { + LLVivoxVoiceClient::getInstance()->voiceServiceConnectionStateChangedEvent(statusCode, statusString, mBuildID); } else if (!stricmp(eventTypeCstr, "AudioDeviceHotSwapEvent")) { diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h index 214527748a8ba80ae0c9a2ce49b14314d1f05e72..8e671ce70fd94bb510963325fc00d76f0dfd0c91 100644 --- a/indra/newview/llvoicevivox.h +++ b/indra/newview/llvoicevivox.h @@ -467,6 +467,7 @@ class LLVivoxVoiceClient final : public LLSingleton<LLVivoxVoiceClient>, void participantAddedEvent(std::string &sessionHandle, std::string &sessionGroupHandle, std::string &uriString, std::string &alias, std::string &nameString, std::string &displayNameString, int participantType); void participantRemovedEvent(std::string &sessionHandle, std::string &sessionGroupHandle, std::string &uriString, std::string &alias, std::string &nameString); void participantUpdatedEvent(std::string &sessionHandle, std::string &sessionGroupHandle, std::string &uriString, std::string &alias, bool isModeratorMuted, bool isSpeaking, int volume, F32 energy); + void voiceServiceConnectionStateChangedEvent(int statusCode, std::string &statusString, std::string &build_id); void auxAudioPropertiesEvent(F32 energy); void messageEvent(std::string &sessionHandle, std::string &uriString, std::string &alias, std::string &messageHeader, std::string &messageBody, std::string &applicationString); void sessionNotificationEvent(std::string &sessionHandle, std::string &uriString, std::string ¬ificationType); @@ -971,6 +972,7 @@ class LLVivoxProtocolParser : public LLIOPipe std::string actionString; std::string connectorHandle; std::string versionID; + std::string mBuildID; std::string accountHandle; std::string sessionHandle; std::string sessionGroupHandle; diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp index 13be46a29aaef6675119f133c06ec250340407c6..2280b86831911cace52b2baf59ddff4df374e039 100644 --- a/indra/newview/llvopartgroup.cpp +++ b/indra/newview/llvopartgroup.cpp @@ -223,7 +223,7 @@ void LLVOPartGroup::setPixelAreaAndAngle(LLAgent &agent) { // mPixelArea is calculated during render F32 mid_scale = getMidScale(); - F32 range = (getRenderPosition()-LLViewerCamera::getInstanceFast()->getOrigin()).length(); + F32 range = (getRenderPosition()-LLViewerCamera::getInstance()->getOrigin()).length(); if (range < 0.001f || isHUDAttachment()) // range == zero { @@ -307,10 +307,9 @@ LLVector3 LLVOPartGroup::getCameraPosition() const return gAgentCamera.getCameraPositionAgent(); } -static LLTrace::BlockTimerStatHandle FTM_UPDATE_PARTICLES("Update Particles"); BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable) { - LL_RECORD_BLOCK_TIME(FTM_UPDATE_PARTICLES); + LL_PROFILE_ZONE_SCOPED; dirtySpatialGroup(); @@ -351,7 +350,7 @@ BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable) F32 tot_area = 0; F32 max_area = LLViewerPartSim::getMaxPartCount() * MAX_PARTICLE_AREA_SCALE; - F32 pixel_meter_ratio = LLViewerCamera::getInstanceFast()->getPixelMeterRatio(); + F32 pixel_meter_ratio = LLViewerCamera::getInstance()->getPixelMeterRatio(); pixel_meter_ratio *= pixel_meter_ratio; LLViewerPartSim::checkParticleCount(mViewerPartGroupp->mParticles.size()) ; @@ -713,7 +712,7 @@ void LLVOPartGroup::getGeometry(S32 idx, *colorsp++ = color; //Only add emissive attributes if glowing (doing it for all particles is INCREDIBLY inefficient as it leads to a second, slower, render pass.) - if (gPipeline.canUseVertexShaders() && (pglow.mV[3] > 0 || part.mGlow.mV[3] > 0)) + if (pglow.mV[3] > 0 || part.mGlow.mV[3] > 0) { //only write glow if it is not zero *emissivep++ = pglow; *emissivep++ = pglow; @@ -724,7 +723,7 @@ void LLVOPartGroup::getGeometry(S32 idx, if (!(part.mFlags & LLPartData::LL_PART_EMISSIVE_MASK)) { //not fullbright, needs normal - LLVector3 normal = -LLViewerCamera::getInstanceFast()->getXAxis(); + LLVector3 normal = -LLViewerCamera::getInstance()->getXAxis(); *normalsp++ = normal; *normalsp++ = normal; *normalsp++ = normal; @@ -754,10 +753,9 @@ LLHUDParticlePartition::LLHUDParticlePartition(LLViewerRegion* regionp) : mPartitionType = LLViewerRegion::PARTITION_HUD_PARTICLE; } -static LLTrace::BlockTimerStatHandle FTM_REBUILD_PARTICLE_VBO("Particle VBO"); - void LLParticlePartition::rebuildGeom(LLSpatialGroup* group) { + LL_PROFILE_ZONE_SCOPED; if (group->isDead() || !group->hasState(LLSpatialGroup::GEOM_DIRTY)) { return; @@ -769,8 +767,6 @@ void LLParticlePartition::rebuildGeom(LLSpatialGroup* group) group->mLastUpdateViewAngle = group->mViewAngle; } - LL_RECORD_BLOCK_TIME(FTM_REBUILD_PARTICLE_VBO); - group->clearDrawMap(); //get geometry count @@ -803,7 +799,7 @@ void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_co mFaceList.clear(); - LLViewerCamera* camera = LLViewerCamera::getInstanceFast(); + LLViewerCamera* camera = LLViewerCamera::getInstance(); for (LLSpatialGroup::element_iter i = group->getDataBegin(), i_end = group->getDataEnd(); i != i_end; ++i) { LLDrawable* drawablep = (LLDrawable*)(*i)->getDrawable(); @@ -843,11 +839,9 @@ void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_co } -static LLTrace::BlockTimerStatHandle FTM_REBUILD_PARTICLE_GEOM("Particle Geom"); - void LLParticlePartition::getGeometry(LLSpatialGroup* group) { - LL_RECORD_BLOCK_TIME(FTM_REBUILD_PARTICLE_GEOM); + LL_PROFILE_ZONE_SCOPED; std::sort(mFaceList.begin(), mFaceList.end(), LLFace::CompareDistanceGreater()); diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp index 12a96ed9202b6e7ce64bd076985a848798f38067..0c11d68d92c61b7718544fb9f41415a820d9aa09 100644 --- a/indra/newview/llvosky.cpp +++ b/indra/newview/llvosky.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llvosky.cpp * @brief LLVOSky class implementation * * $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$ */ @@ -64,7 +64,7 @@ namespace constexpr S32 NUM_TILES_X = 8; constexpr S32 NUM_TILES_Y = 4; constexpr S32 NUM_TILES = NUM_TILES_X * NUM_TILES_Y; - constexpr S32 NUM_CUBEMAP_FACES = 6; // See sResolution for face dimensions + constexpr S32 NUM_CUBEMAP_FACES = 6; // See SKYTEX_RESOLUTION for face dimensions constexpr S32 TOTAL_TILES = NUM_CUBEMAP_FACES * NUM_TILES; constexpr S32 MAX_TILES = TOTAL_TILES + 1; @@ -75,14 +75,9 @@ namespace // Texture coordinates: const LLVector2 TEX00 = LLVector2(0.f, 0.f); - const LLVector2 TEX01 = LLVector2(0.f, 1.f); - const LLVector2 TEX10 = LLVector2(1.f, 0.f); - const LLVector2 TEX11 = LLVector2(1.f, 1.f); - - LLTrace::BlockTimerStatHandle FTM_VOSKY_UPDATETIMER("VOSky Update Timer Tick"); - LLTrace::BlockTimerStatHandle FTM_VOSKY_CALC("VOSky Update Calculations"); - LLTrace::BlockTimerStatHandle FTM_VOSKY_CREATETEXTURES("VOSky Update Textures"); - LLTrace::BlockTimerStatHandle FTM_VOSKY_UPDATEFORCED("VOSky Update Forced"); + const LLVector2 TEX01 = LLVector2(0.f, 1.f); + const LLVector2 TEX10 = LLVector2(1.f, 0.f); + const LLVector2 TEX11 = LLVector2(1.f, 1.f); constexpr F32Seconds UPDATE_EXPRY(0.25f); @@ -94,6 +89,7 @@ namespace S32 LLSkyTex::sCurrent = 0; + LLSkyTex::LLSkyTex() : mSkyData(NULL), mSkyDirs(NULL), @@ -104,15 +100,15 @@ LLSkyTex::LLSkyTex() : void LLSkyTex::init(bool isShiny) { mIsShiny = isShiny; - mSkyData = new LLColor4[SKYTEX_RES * SKYTEX_RES]; - mSkyDirs = new LLVector3[SKYTEX_RES * SKYTEX_RES]; + mSkyData = new LLColor4[SKYTEX_RESOLUTION * SKYTEX_RESOLUTION]; + mSkyDirs = new LLVector3[SKYTEX_RESOLUTION * SKYTEX_RESOLUTION]; for (S32 i = 0; i < 2; ++i) { mTexture[i] = LLViewerTextureManager::getLocalTexture(FALSE); mTexture[i]->setAddressMode(LLTexUnit::TAM_CLAMP); - mImageRaw[i] = new LLImageRaw(SKYTEX_RES, SKYTEX_RES, SKYTEX_COMPONENTS); - + mImageRaw[i] = new LLImageRaw(SKYTEX_RESOLUTION, SKYTEX_RESOLUTION, SKYTEX_COMPONENTS); + initEmpty(i); } } @@ -143,7 +139,7 @@ LLSkyTex::~LLSkyTex() S32 LLSkyTex::getResolution() { - return SKYTEX_RES; + return SKYTEX_RESOLUTION; } S32 LLSkyTex::getCurrent() @@ -171,11 +167,11 @@ S32 LLSkyTex::getWhich(const BOOL curr) void LLSkyTex::initEmpty(const S32 tex) { U8* data = mImageRaw[tex]->getData(); - for (S32 i = 0; i < SKYTEX_RES; ++i) + for (S32 i = 0; i < SKYTEX_RESOLUTION; ++i) { - for (S32 j = 0; j < SKYTEX_RES; ++j) + for (S32 j = 0; j < SKYTEX_RESOLUTION; ++j) { - const S32 basic_offset = (i * SKYTEX_RES + j); + const S32 basic_offset = (i * SKYTEX_RESOLUTION + j); S32 offset = basic_offset * SKYTEX_COMPONENTS; data[offset] = 0; data[offset+1] = 0; @@ -192,11 +188,11 @@ void LLSkyTex::initEmpty(const S32 tex) void LLSkyTex::create() { U8* data = mImageRaw[sCurrent]->getData(); - for (S32 i = 0; i < SKYTEX_RES; ++i) + for (S32 i = 0; i < SKYTEX_RESOLUTION; ++i) { - for (S32 j = 0; j < SKYTEX_RES; ++j) + for (S32 j = 0; j < SKYTEX_RESOLUTION; ++j) { - const S32 basic_offset = (i * SKYTEX_RES + j); + const S32 basic_offset = (i * SKYTEX_RESOLUTION + j); S32 offset = basic_offset * SKYTEX_COMPONENTS; U32* pix = (U32*)(data + offset); LLColor4U temp = LLColor4U(mSkyData[basic_offset]); @@ -207,7 +203,7 @@ void LLSkyTex::create() } void LLSkyTex::createGLImage(S32 which) -{ +{ mTexture[which]->setExplicitFormat(GL_RGBA8, GL_RGBA); mTexture[which]->createGLTexture(0, mImageRaw[which], 0, TRUE, LLGLTexture::LOCAL); mTexture[which]->setAddressMode(LLTexUnit::TAM_CLAMP); @@ -394,12 +390,8 @@ const LLVector3* LLHeavenBody::corners() const Sky ***************************************/ -namespace -{ - constexpr S32 VOSKY_RES = SKYTEX_RES; - constexpr S32 VOSKY_TILE_RES_X = VOSKY_RES / NUM_TILES_X; - constexpr S32 VOSKY_TILE_RES_Y = VOSKY_RES / NUM_TILES_Y; -} +const S32 SKYTEX_TILE_RES_X = SKYTEX_RESOLUTION / NUM_TILES_X; +const S32 SKYTEX_TILE_RES_Y = SKYTEX_RESOLUTION / NUM_TILES_Y; LLVOSky::LLVOSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) : LLStaticViewerObject(id, pcode, regionp, TRUE), @@ -434,7 +426,7 @@ LLVOSky::LLVOSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) { mFace[i] = NULL; } - + mCameraPosAgent = gAgentCamera.getCameraPositionAgent(); mAtmHeight = ATM_HEIGHT; mEarthCenter = LLVector3(mCameraPosAgent.mV[0], mCameraPosAgent.mV[1], -EARTH_RADIUS); @@ -462,12 +454,12 @@ void LLVOSky::init() llassert(!mInitialized); // Update sky at least once to get correct initial sun/moon directions and lighting calcs performed - const LLSettingsSky::ptr_t& psky = LLEnvironment::instanceFast().getCurrentSky(); - psky->update(); + const LLSettingsSky::ptr_t& psky = LLEnvironment::instance().getCurrentSky(); + psky->update(); - updateDirections(psky); + updateDirections(psky); - cacheEnvironment(psky, m_atmosphericsVars); + cacheEnvironment(psky,m_atmosphericsVars); // Initialize the cached normalized direction vectors for (S32 side = 0; side < NUM_CUBEMAP_FACES; ++side) @@ -491,32 +483,36 @@ void LLVOSky::init() mHaloMap = LLViewerTextureManager::getFetchedTexture(psky->getHaloTextureId(), FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); } -void LLVOSky::cacheEnvironment(const LLSettingsSky::ptr_t& psky, AtmosphericsVars& atmosphericsVars) + +void LLVOSky::cacheEnvironment(LLSettingsSky::ptr_t psky,AtmosphericsVars& atmosphericsVars) { - // invariants across whole sky tex process... - m_atmosphericsVars.blue_density = psky->getBlueDensity(); - m_atmosphericsVars.blue_horizon = psky->getBlueHorizon(); - m_atmosphericsVars.haze_density = psky->getHazeDensity(); - m_atmosphericsVars.haze_horizon = psky->getHazeHorizon(); - m_atmosphericsVars.density_multiplier = psky->getDensityMultiplier(); - m_atmosphericsVars.distance_multiplier = psky->getDistanceMultiplier(); - m_atmosphericsVars.max_y = psky->getMaxY(); - m_atmosphericsVars.sun_norm = LLEnvironment::getInstanceFast()->getClampedSunNorm(); - m_atmosphericsVars.sunlight = psky->getIsSunUp() ? psky->getSunlightColor() : psky->getMoonlightColor(); - m_atmosphericsVars.ambient = psky->getAmbientColor(); - m_atmosphericsVars.glow = psky->getGlow(); - m_atmosphericsVars.cloud_shadow = psky->getCloudShadow(); - m_atmosphericsVars.dome_radius = psky->getDomeRadius(); - m_atmosphericsVars.dome_offset = psky->getDomeOffset(); - m_atmosphericsVars.total_density = psky->getTotalDensityFast(m_atmosphericsVars.blue_density, m_atmosphericsVars.haze_density); - m_atmosphericsVars.light_atten = psky->getLightAttenuationFast(m_atmosphericsVars.density_multiplier, m_atmosphericsVars.blue_density, m_atmosphericsVars.haze_density, m_atmosphericsVars.max_y); - m_atmosphericsVars.light_transmittance = psky->getLightTransmittanceFast(m_atmosphericsVars.total_density, m_atmosphericsVars.density_multiplier, m_atmosphericsVars.max_y); - m_atmosphericsVars.gamma = psky->getGamma(); + // NOTE: Also see: LLAtmospherics::updateFog() + // invariants across whole sky tex process... + atmosphericsVars.blue_density = psky->getBlueDensity(); + atmosphericsVars.blue_horizon = psky->getBlueHorizon(); + atmosphericsVars.haze_density = psky->getHazeDensity(); + atmosphericsVars.haze_horizon = psky->getHazeHorizon(); + atmosphericsVars.density_multiplier = psky->getDensityMultiplier(); + atmosphericsVars.distance_multiplier = psky->getDistanceMultiplier(); + atmosphericsVars.max_y = psky->getMaxY(); + atmosphericsVars.sun_norm = LLEnvironment::instance().getClampedSunNorm(); + atmosphericsVars.sunlight = psky->getIsSunUp() ? psky->getSunlightColor() : psky->getMoonlightColor(); + atmosphericsVars.ambient = psky->getAmbientColor(); + atmosphericsVars.glow = psky->getGlow(); + atmosphericsVars.cloud_shadow = psky->getCloudShadow(); + atmosphericsVars.dome_radius = psky->getDomeRadius(); + atmosphericsVars.dome_offset = psky->getDomeOffset(); + atmosphericsVars.light_atten = psky->getLightAttenuation(atmosphericsVars.max_y); + atmosphericsVars.light_transmittance = psky->getLightTransmittance(atmosphericsVars.max_y); + atmosphericsVars.total_density = psky->getTotalDensity(); + atmosphericsVars.gamma = psky->getGamma(); } -void LLVOSky::calc(const LLSettingsSky::ptr_t& psky) +void LLVOSky::calc() { - cacheEnvironment(psky, m_atmosphericsVars); + LL_PROFILE_ZONE_SCOPED_CATEGORY_ENVIRONMENT; + LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); + cacheEnvironment(psky,m_atmosphericsVars); mSun.setColor(psky->getSunDiffuse()); mMoon.setColor(LLColor3(1.0f, 1.0f, 1.0f)); @@ -527,14 +523,14 @@ void LLVOSky::calc(const LLSettingsSky::ptr_t& psky) mMoon.renewColor(); } -void LLVOSky::initCubeMap() +void LLVOSky::initCubeMap() { std::vector<LLPointer<LLImageRaw> > images; for (S32 side = 0; side < NUM_CUBEMAP_FACES; side++) { images.push_back(mShinyTex[side].getImageRaw()); } - + if (!mCubeMap && gSavedSettings.getBOOL("RenderWater") && gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps) { mCubeMap = new LLCubeMap(false); @@ -570,13 +566,13 @@ void LLVOSky::restoreGL() mSkyTex[i].restoreGL(); } - const LLSettingsSky::ptr_t& psky = LLEnvironment::instanceFast().getCurrentSky(); + const LLSettingsSky::ptr_t& psky = LLEnvironment::instance().getCurrentSky(); - if (psky) + if (psky) { - setSunTextures(psky->getSunTextureId(), psky->getNextSunTextureId()); - setMoonTextures(psky->getMoonTextureId(), psky->getNextMoonTextureId()); - } + setSunTextures(psky->getSunTextureId(), psky->getNextSunTextureId()); + setMoonTextures(psky->getMoonTextureId(), psky->getNextMoonTextureId()); + } updateDirections(psky); @@ -585,7 +581,7 @@ void LLVOSky::restoreGL() initCubeMap(); } - forceSkyUpdate(); + forceSkyUpdate(); if (mDrawable) { @@ -599,8 +595,8 @@ void LLVOSky::initSkyTextureDirs(const S32 side, const S32 tile) S32 tile_x = tile % NUM_TILES_X; S32 tile_y = tile / NUM_TILES_X; - S32 tile_x_pos = tile_x * VOSKY_TILE_RES_X; - S32 tile_y_pos = tile_y * VOSKY_TILE_RES_Y; + S32 tile_x_pos = tile_x * SKYTEX_TILE_RES_X; + S32 tile_y_pos = tile_y * SKYTEX_TILE_RES_Y; F32 coeff[3] = {0, 0, 0}; const S32 curr_coef = side >> 1; // 0/1 = Z axis, 2/3 = Y, 4/5 = X @@ -610,11 +606,11 @@ void LLVOSky::initSkyTextureDirs(const S32 side, const S32 tile) coeff[curr_coef] = (F32)side_dir; - F32 inv_res = 1.f/ VOSKY_RES; + F32 inv_res = 1.f/SKYTEX_RESOLUTION; S32 x, y; - for (y = tile_y_pos; y < (tile_y_pos + VOSKY_TILE_RES_Y); ++y) + for (y = tile_y_pos; y < (tile_y_pos + SKYTEX_TILE_RES_Y); ++y) { - for (x = tile_x_pos; x < (tile_x_pos + VOSKY_TILE_RES_X); ++x) + for (x = tile_x_pos; x < (tile_x_pos + SKYTEX_TILE_RES_X); ++x) { coeff[x_coef] = F32((x<<1) + 1) * inv_res - 1.f; coeff[y_coef] = F32((y<<1) + 1) * inv_res - 1.f; @@ -626,21 +622,23 @@ void LLVOSky::initSkyTextureDirs(const S32 side, const S32 tile) } } -void LLVOSky::createSkyTexture(const LLSettingsSky::ptr_t& psky, AtmosphericsVars& vars, const S32 side, const S32 tile) +void LLVOSky::createSkyTexture(const LLSettingsSky::ptr_t &psky, AtmosphericsVars& vars, const S32 side, const S32 tile) { + const bool low_end = !gPipeline.canUseWindLightShaders(); + S32 tile_x = tile % NUM_TILES_X; S32 tile_y = tile / NUM_TILES_X; - S32 tile_x_pos = tile_x * VOSKY_TILE_RES_X; - S32 tile_y_pos = tile_y * VOSKY_TILE_RES_Y; + S32 tile_x_pos = tile_x * SKYTEX_TILE_RES_X; + S32 tile_y_pos = tile_y * SKYTEX_TILE_RES_Y; S32 x, y; - for (y = tile_y_pos; y < (tile_y_pos + VOSKY_TILE_RES_Y); ++y) + for (y = tile_y_pos; y < (tile_y_pos + SKYTEX_TILE_RES_Y); ++y) { - for (x = tile_x_pos; x < (tile_x_pos + VOSKY_TILE_RES_X); ++x) + for (x = tile_x_pos; x < (tile_x_pos + SKYTEX_TILE_RES_X); ++x) { - mSkyTex[side].setPixel(m_legacyAtmospherics.calcSkyColorInDir(psky, vars, mSkyTex[side].getDir(x, y), false), x, y); - mShinyTex[side].setPixel(m_legacyAtmospherics.calcSkyColorInDir(psky, vars, mShinyTex[side].getDir(x, y), true), x, y); + mSkyTex [side].setPixel(m_legacyAtmospherics.calcSkyColorInDir(psky, vars, mSkyTex [side].getDir(x, y), false, low_end), x, y); + mShinyTex[side].setPixel(m_legacyAtmospherics.calcSkyColorInDir(psky, vars, mShinyTex[side].getDir(x, y), true , low_end), x, y); } } } @@ -648,11 +646,11 @@ void LLVOSky::createSkyTexture(const LLSettingsSky::ptr_t& psky, AtmosphericsVar void LLVOSky::updateDirections(const LLSettingsSky::ptr_t& psky) { mSun.setDirection(psky->getSunDirection()); - mMoon.setDirection(psky->getMoonDirection()); + mMoon.setDirection(psky->getMoonDirection()); mSun.setRotation(psky->getSunRotation()); - mMoon.setRotation(psky->getMoonRotation()); - mSun.renewDirection(); - mMoon.renewDirection(); + mMoon.setRotation(psky->getMoonRotation()); + mSun.renewDirection(); + mMoon.renewDirection(); } void LLVOSky::idleUpdate(LLAgent &agent, const F64 &time) @@ -662,9 +660,7 @@ void LLVOSky::idleUpdate(LLAgent &agent, const F64 &time) void LLVOSky::forceSkyUpdate() { mForceUpdate = TRUE; - - m_lastAtmosphericsVars = AtmosphericsVars(); - + m_lastAtmosphericsVars = {}; mCubeMapUpdateStage = -1; } @@ -676,9 +672,11 @@ bool LLVOSky::updateSky() return TRUE; } + LL_PROFILE_ZONE_SCOPED_CATEGORY_ENVIRONMENT; + static S32 next_frame = 0; - - LLEnvironment& environment = LLEnvironment::instanceFast(); + + LLEnvironment& environment = LLEnvironment::instance(); const LLSettingsSky::ptr_t& psky = environment.getCurrentSky(); mNeedUpdate = mForceUpdate; @@ -696,11 +694,10 @@ bool LLVOSky::updateSky() mForceUpdate = FALSE; return TRUE; } - + if (mCubeMapUpdateStage < 0) { - LL_RECORD_BLOCK_TIME(FTM_VOSKY_CALC); - calc(psky); + calc(); bool same_atmospherics = approximatelyEqual(m_lastAtmosphericsVars, m_atmosphericsVars, UPDATE_MIN_DELTA_THRESHOLD); @@ -709,14 +706,14 @@ bool LLVOSky::updateSky() if (mNeedUpdate && (mForceUpdateThrottle.hasExpired() || mForceUpdate)) { // start updating cube map sides - updateFog(&environment, psky, LLViewerCamera::getInstanceFast()->getFar()); + updateFog(&environment, psky, LLViewerCamera::getInstance()->getFar()); mCubeMapUpdateStage = 0; mForceUpdate = FALSE; } } else if (mCubeMapUpdateStage == NUM_CUBEMAP_FACES) { - LL_RECORD_BLOCK_TIME(FTM_VOSKY_UPDATEFORCED); + LL_PROFILE_ZONE_NAMED("updateSky - forced"); LLSkyTex::stepCurrent(); bool is_alm_wl_sky = gPipeline.canUseWindLightShaders(); @@ -777,7 +774,7 @@ bool LLVOSky::updateSky() // run 0 to 5 faces, each face in own frame else if (mCubeMapUpdateStage >= 0 && mCubeMapUpdateStage < NUM_CUBEMAP_FACES) { - LL_RECORD_BLOCK_TIME(FTM_VOSKY_CREATETEXTURES); + LL_PROFILE_ZONE_NAMED("updateSky - create"); S32 side = mCubeMapUpdateStage; // CPU hungry part, createSkyTexture() is math heavy // Prior to EEP it was mostly per tile, but since EPP it is per face. @@ -860,10 +857,10 @@ void LLVOSky::setSunScale(F32 sun_scale) void LLVOSky::setMoonScale(F32 moon_scale) { mMoonScale = moon_scale; - } - +} + void LLVOSky::setSunTextures(const LLUUID& sun_texture, const LLUUID& sun_texture_next) - { +{ // We test the UUIDs here because we explicitly do not want the default image returned by getFetchedTexture in that case... mSunTexturep[0] = sun_texture.isNull() ? nullptr : LLViewerTextureManager::getFetchedTexture(sun_texture, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); mSunTexturep[1] = sun_texture_next.isNull() ? nullptr : LLViewerTextureManager::getFetchedTexture(sun_texture_next, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); @@ -881,30 +878,31 @@ void LLVOSky::setSunTextures(const LLUUID& sun_texture, const LLUUID& sun_textur LLViewerTexture* current_tex1 = mFace[FACE_SUN]->getTexture(LLRender::ALTERNATE_DIFFUSE_MAP); if (current_tex0 && (mSunTexturep[0] != current_tex0) && current_tex0->isViewerMediaTexture()) - { + { static_cast<LLViewerMediaTexture*>(current_tex0)->removeMediaFromFace(mFace[FACE_SUN]); } if (current_tex1 && (mSunTexturep[1] != current_tex1) && current_tex1->isViewerMediaTexture()) - { + { static_cast<LLViewerMediaTexture*>(current_tex1)->removeMediaFromFace(mFace[FACE_SUN]); - } + } mFace[FACE_SUN]->setTexture(LLRender::DIFFUSE_MAP, mSunTexturep[0]); if (can_use_wl) { if (mSunTexturep[1]) - { - mSunTexturep[1]->setAddressMode(LLTexUnit::TAM_CLAMP); - } + { + mSunTexturep[1]->setAddressMode(LLTexUnit::TAM_CLAMP); + } mFace[FACE_SUN]->setTexture(LLRender::ALTERNATE_DIFFUSE_MAP, mSunTexturep[1]); - } - } - } + } + } +} void LLVOSky::setMoonTextures(const LLUUID& moon_texture, const LLUUID& moon_texture_next) { + bool can_use_wl = gPipeline.canUseWindLightShaders(); mMoonTexturep[0] = moon_texture.isNull() ? nullptr : LLViewerTextureManager::getFetchedTexture(moon_texture, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); @@ -913,24 +911,24 @@ void LLVOSky::setMoonTextures(const LLUUID& moon_texture, const LLUUID& moon_tex if (mFace[FACE_MOON]) { if (mMoonTexturep[0]) - { - mMoonTexturep[0]->setAddressMode(LLTexUnit::TAM_CLAMP); - } + { + mMoonTexturep[0]->setAddressMode(LLTexUnit::TAM_CLAMP); + } mFace[FACE_MOON]->setTexture(LLRender::DIFFUSE_MAP, mMoonTexturep[0]); if (mMoonTexturep[1] && can_use_wl) - { - mMoonTexturep[1]->setAddressMode(LLTexUnit::TAM_CLAMP); + { + mMoonTexturep[1]->setAddressMode(LLTexUnit::TAM_CLAMP); mFace[FACE_MOON]->setTexture(LLRender::ALTERNATE_DIFFUSE_MAP, mMoonTexturep[1]); - } - } + } + } } void LLVOSky::setCloudNoiseTextures(const LLUUID& cloud_noise_texture, const LLUUID& cloud_noise_texture_next) { mCloudNoiseTexturep[0] = cloud_noise_texture.isNull() ? nullptr : LLViewerTextureManager::getFetchedTexture(cloud_noise_texture, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); mCloudNoiseTexturep[1] = cloud_noise_texture_next.isNull() ? nullptr : LLViewerTextureManager::getFetchedTexture(cloud_noise_texture_next, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); - + if (mCloudNoiseTexturep[0]) { mCloudNoiseTexturep[0]->setAddressMode(LLTexUnit::TAM_WRAP); @@ -944,7 +942,7 @@ void LLVOSky::setCloudNoiseTextures(const LLUUID& cloud_noise_texture, const LLU void LLVOSky::setBloomTextures(const LLUUID& bloom_texture, const LLUUID& bloom_texture_next) { - const LLSettingsSky::ptr_t& psky = LLEnvironment::instanceFast().getCurrentSky(); + const LLSettingsSky::ptr_t& psky = LLEnvironment::instance().getCurrentSky(); LLUUID bloom_tex = bloom_texture.isNull() ? psky->GetDefaultBloomTextureId() : bloom_texture; LLUUID bloom_tex_next = bloom_texture_next.isNull() ? (bloom_texture.isNull() ? psky->GetDefaultBloomTextureId() : bloom_texture) : bloom_texture_next; @@ -953,21 +951,19 @@ void LLVOSky::setBloomTextures(const LLUUID& bloom_texture, const LLUUID& bloom_ mBloomTexturep[1] = bloom_tex_next.isNull() ? nullptr : LLViewerTextureManager::getFetchedTexture(bloom_tex_next, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); if (mBloomTexturep[0]) -{ - mBloomTexturep[0]->setAddressMode(LLTexUnit::TAM_CLAMP); + { + mBloomTexturep[0]->setAddressMode(LLTexUnit::TAM_CLAMP); } if (mBloomTexturep[1]) - { - mBloomTexturep[1]->setAddressMode(LLTexUnit::TAM_CLAMP); + { + mBloomTexturep[1]->setAddressMode(LLTexUnit::TAM_CLAMP); } - } - -static LLTrace::BlockTimerStatHandle FTM_GEO_SKY("Sky Geometry"); +} BOOL LLVOSky::updateGeometry(LLDrawable *drawable) { - LL_RECORD_BLOCK_TIME(FTM_GEO_SKY); + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE; if (mFace[FACE_REFLECTION] == NULL) { LLDrawPoolWater *poolp = (LLDrawPoolWater*) gPipeline.getPool(LLDrawPool::POOL_WATER); @@ -996,11 +992,11 @@ BOOL LLVOSky::updateGeometry(LLDrawable *drawable) LLStrider<LLVector2> texCoordsp; LLStrider<U16> indicesp; U16 index_offset; - LLFace *face; + LLFace *face; for (S32 side = 0; side < NUM_CUBEMAP_FACES; ++side) { - face = mFace[FACE_SIDE0 + side]; + face = mFace[FACE_SIDE0 + side]; if (!face->getVertexBuffer()) { @@ -1012,7 +1008,7 @@ BOOL LLVOSky::updateGeometry(LLDrawable *drawable) face->setVertexBuffer(buff); index_offset = face->getGeometry(verticesp,normalsp,texCoordsp, indicesp); - + S32 vtx = 0; S32 curr_bit = side >> 1; // 0/1 = Z axis, 2/3 = Y, 4/5 = X S32 side_dir = side & 1; // even - 0, odd - 1 @@ -1047,7 +1043,7 @@ BOOL LLVOSky::updateGeometry(LLDrawable *drawable) } } - const LLVector3 &look_at = LLViewerCamera::getInstanceFast()->getAtAxis(); + const LLVector3 &look_at = LLViewerCamera::getInstance()->getAtAxis(); LLVector3 right = look_at % LLVector3::z_axis; LLVector3 up = right % look_at; right.normalize(); @@ -1056,7 +1052,7 @@ BOOL LLVOSky::updateGeometry(LLDrawable *drawable) bool draw_sun = updateHeavenlyBodyGeometry(drawable, mSunScale, FACE_SUN, mSun, up, right); bool draw_moon = updateHeavenlyBodyGeometry(drawable, mMoonScale, FACE_MOON, mMoon, up, right); - LLEnvironment& environment = LLEnvironment::instanceFast(); + LLEnvironment& environment = LLEnvironment::instance(); draw_sun &= environment.getIsSunUp(); draw_moon &= environment.getIsMoonUp(); @@ -1131,11 +1127,11 @@ bool LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, F32 scale, const hb.setVisible(TRUE); - facep = mFace[f]; + facep = mFace[f]; if (!facep->getVertexBuffer()) { - facep->setSize(4, 6); + facep->setSize(4, 6); LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolSky::VERTEX_DATA_MASK, GL_STREAM_DRAW); if (!buff->allocateBuffer(facep->getGeomCount(), facep->getIndicesCount(), TRUE)) { @@ -1223,7 +1219,7 @@ F32 dtClip(const LLVector3& v0, const LLVector3& v1, F32 far_clip2) void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H, const LLHeavenBody& HB) { - const LLVector3 &look_at = LLViewerCamera::getInstanceFast()->getAtAxis(); + const LLVector3 &look_at = LLViewerCamera::getInstance()->getAtAxis(); // const F32 water_height = gAgent.getRegion()->getWaterHeight() + 0.001f; // LLWorld::getInstance()->getWaterHeight() + 0.001f; @@ -1369,7 +1365,7 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H, dt_clip = -0.1f; } - LLFace *face = mFace[FACE_REFLECTION]; + LLFace *face = mFace[FACE_REFLECTION]; if (face) { @@ -1387,13 +1383,13 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H, face->setGeomIndex(0); face->setVertexBuffer(buff); } - + LLStrider<LLVector3> verticesp; LLStrider<LLVector3> normalsp; LLStrider<LLVector2> texCoordsp; LLStrider<U16> indicesp; S32 index_offset; - + index_offset = face->getGeometry(verticesp,normalsp,texCoordsp, indicesp); if (-1 == index_offset) { @@ -1411,7 +1407,7 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H, LLColor4 hb_refl_col = (1 - attenuation) * hb_col + attenuation * getSkyFogColor(); face->setFaceColor(hb_refl_col); - + LLVector3 v_far[2]; v_far[0] = v_refl_corner[1]; v_far[1] = v_refl_corner[3]; @@ -1526,64 +1522,61 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H, void LLVOSky::updateFog(LLEnvironment* environment, const LLSettingsSky::ptr_t& psky, const F32 distance) { - if (psky != nullptr) + if (psky) { - LLVector3 light_dir = LLVector3(environment->getClampedLightNorm()); - m_legacyAtmospherics.updateFog(distance, light_dir); + LLVector3 light_dir = LLVector3(environment->getClampedLightNorm()); + m_legacyAtmospherics.updateFog(distance, light_dir); } } -void LLVOSky::setSunAndMoonDirectionsCFR(const LLVector3& sun_dir_cfr, const LLVector3& moon_dir_cfr) +void LLVOSky::setSunAndMoonDirectionsCFR(const LLVector3 &sun_dir_cfr, const LLVector3 &moon_dir_cfr) { - mSun.setDirection(sun_dir_cfr); - mMoon.setDirection(moon_dir_cfr); + mSun.setDirection(sun_dir_cfr); + mMoon.setDirection(moon_dir_cfr); - // Push the sun "South" as it approaches directly overhead so that we can always see bump mapping - // on the upward facing faces of cubes. - { - // Same as dot product with the up direction + clamp. - F32 sunDot = llmax(0.f, sun_dir_cfr.mV[2]); - sunDot *= sunDot; + // Push the sun "South" as it approaches directly overhead so that we can always see bump mapping + // on the upward facing faces of cubes. + // Same as dot product with the up direction + clamp. + F32 sunDot = llmax(0.f, sun_dir_cfr.mV[2]); + sunDot *= sunDot; - // Create normalized vector that has the sunDir pushed south about an hour and change. - LLVector3 adjustedDir = (sun_dir_cfr + LLVector3(0.f, -0.70711f, 0.70711f)) * 0.5f; + // Create normalized vector that has the sunDir pushed south about an hour and change. + LLVector3 adjustedDir = (sun_dir_cfr + LLVector3(0.f, -0.70711f, 0.70711f)) * 0.5f; - // Blend between normal sun dir and adjusted sun dir based on how close we are - // to having the sun overhead. - mBumpSunDir = adjustedDir * sunDot + sun_dir_cfr * (1.0f - sunDot); - mBumpSunDir.normalize(); - } + // Blend between normal sun dir and adjusted sun dir based on how close we are + // to having the sun overhead. + mBumpSunDir = adjustedDir * sunDot + sun_dir_cfr * (1.0f - sunDot); + mBumpSunDir.normalize(); - const LLSettingsSky::ptr_t& psky = LLEnvironment::instanceFast().getCurrentSky(); - updateDirections(psky); + LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); + updateDirections(psky); } -void LLVOSky::setSunDirectionCFR(const LLVector3& sun_dir_cfr) +void LLVOSky::setSunDirectionCFR(const LLVector3 &sun_dir_cfr) { - mSun.setDirection(sun_dir_cfr); + mSun.setDirection(sun_dir_cfr); - // Push the sun "South" as it approaches directly overhead so that we can always see bump mapping - // on the upward facing faces of cubes. - { - // Same as dot product with the up direction + clamp. - F32 sunDot = llmax(0.f, sun_dir_cfr.mV[2]); - sunDot *= sunDot; + // Push the sun "South" as it approaches directly overhead so that we can always see bump mapping + // on the upward facing faces of cubes. + // Same as dot product with the up direction + clamp. + F32 sunDot = llmax(0.f, sun_dir_cfr.mV[2]); + sunDot *= sunDot; - // Create normalized vector that has the sunDir pushed south about an hour and change. - LLVector3 adjustedDir = (sun_dir_cfr + LLVector3(0.f, -0.70711f, 0.70711f)) * 0.5f; + // Create normalized vector that has the sunDir pushed south about an hour and change. + LLVector3 adjustedDir = (sun_dir_cfr + LLVector3(0.f, -0.70711f, 0.70711f)) * 0.5f; - // Blend between normal sun dir and adjusted sun dir based on how close we are - // to having the sun overhead. - mBumpSunDir = adjustedDir * sunDot + sun_dir_cfr * (1.0f - sunDot); - mBumpSunDir.normalize(); - } - const LLSettingsSky::ptr_t& psky = LLEnvironment::instanceFast().getCurrentSky(); - updateDirections(psky); + // Blend between normal sun dir and adjusted sun dir based on how close we are + // to having the sun overhead. + mBumpSunDir = adjustedDir * sunDot + sun_dir_cfr * (1.0f - sunDot); + mBumpSunDir.normalize(); + + LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); + updateDirections(psky); } -void LLVOSky::setMoonDirectionCFR(const LLVector3& moon_dir_cfr) +void LLVOSky::setMoonDirectionCFR(const LLVector3 &moon_dir_cfr) { - mMoon.setDirection(moon_dir_cfr); - const LLSettingsSky::ptr_t& psky = LLEnvironment::instanceFast().getCurrentSky(); - updateDirections(psky); + mMoon.setDirection(moon_dir_cfr); + LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); + updateDirections(psky); } diff --git a/indra/newview/llvosky.h b/indra/newview/llvosky.h index c115adf770e02417131e7a10cfce8619967e0776..5b7a4281d890852a7c31ac5d70be8ace04d88f94 100644 --- a/indra/newview/llvosky.h +++ b/indra/newview/llvosky.h @@ -38,16 +38,13 @@ #include "llsettingssky.h" #include "lllegacyatmospherics.h" -namespace -{ - constexpr F32 SKY_BOX_MULT = 16.0f; - constexpr F32 HEAVENLY_BODY_DIST = HORIZON_DIST - 20.f; - constexpr F32 HEAVENLY_BODY_FACTOR = 0.1f; - constexpr F32 HEAVENLY_BODY_SCALE = HEAVENLY_BODY_DIST * HEAVENLY_BODY_FACTOR; +const F32 SKY_BOX_MULT = 16.0f; +const F32 HEAVENLY_BODY_DIST = HORIZON_DIST - 20.f; +const F32 HEAVENLY_BODY_FACTOR = 0.1f; +const F32 HEAVENLY_BODY_SCALE = HEAVENLY_BODY_DIST * HEAVENLY_BODY_FACTOR; - constexpr S32 SKYTEX_COMPONENTS = 4; - constexpr S32 SKYTEX_RES = 64; -} +const F32 SKYTEX_COMPONENTS = 4; +const F32 SKYTEX_RESOLUTION = 64; class LLEnvironment; class LLFace; @@ -87,25 +84,25 @@ class LLSkyTex void setDir(const LLVector3 &dir, const S32 i, const S32 j) { - S32 offset = i * SKYTEX_RES + j; + S32 offset = i * SKYTEX_RESOLUTION + j; mSkyDirs[offset] = dir; } const LLVector3 &getDir(const S32 i, const S32 j) const { - S32 offset = i * SKYTEX_RES + j; + S32 offset = i * SKYTEX_RESOLUTION + j; return mSkyDirs[offset]; } void setPixel(const LLColor4 &col, const S32 i, const S32 j) { - S32 offset = i * SKYTEX_RES + j; + S32 offset = i * SKYTEX_RESOLUTION + j; mSkyData[offset] = col; } void setPixel(const LLColor4U &col, const S32 i, const S32 j) { - S32 offset = (i * SKYTEX_RES + j) * SKYTEX_COMPONENTS; + S32 offset = (i * SKYTEX_RESOLUTION + j) * SKYTEX_COMPONENTS; U32* pix = (U32*) &(mImageRaw[sCurrent]->getData()[offset]); *pix = col.asRGBA(); } @@ -113,7 +110,7 @@ class LLSkyTex LLColor4U getPixel(const S32 i, const S32 j) { LLColor4U col; - S32 offset = (i * SKYTEX_RES + j) * SKYTEX_COMPONENTS; + S32 offset = (i * SKYTEX_RESOLUTION + j) * SKYTEX_COMPONENTS; U32* pix = (U32*) &(mImageRaw[sCurrent]->getData()[offset]); col.fromRGBA( *pix ); return col; @@ -219,13 +216,12 @@ class LLVOSky final : public LLStaticViewerObject // Initialize/delete data that's only inited once per class. void init(); void initCubeMap(); - void initEmpty(); void cleanupGL(); void restoreGL(); - void cacheEnvironment(const LLSettingsSky::ptr_t& psky, AtmosphericsVars& atmosphericsVars); - void calc(const LLSettingsSky::ptr_t& psky); + void calc(); + void cacheEnvironment(LLSettingsSky::ptr_t psky, AtmosphericsVars& atmosphericsVars); /*virtual*/ void idleUpdate(LLAgent &agent, const F64 &time) override; bool updateSky(); @@ -259,8 +255,6 @@ class LLVOSky final : public LLStaticViewerObject LLColor4 getSkyFogColor() const { return m_legacyAtmospherics.getFogColor(); } LLColor4 getGLFogColor() const { return m_legacyAtmospherics.getGLFogColor(); } - LLColor4U getFadeColor() const; - void setCloudDensity(F32 cloud_density) { mCloudDensity = cloud_density; } void setWind ( const LLVector3& wind ) { mWind = wind.length(); } @@ -308,7 +302,7 @@ class LLVOSky final : public LLStaticViewerObject void updateDirections(const LLSettingsSky::ptr_t& psky); void initSkyTextureDirs(const S32 side, const S32 tile); - void createSkyTexture(const LLSettingsSky::ptr_t& psky, AtmosphericsVars& vars, const S32 side, const S32 tile); + void createSkyTexture(const LLSettingsSky::ptr_t &psky, AtmosphericsVars& vars, const S32 side, const S32 tile); LLPointer<LLViewerFetchedTexture> mSunTexturep[2]; LLPointer<LLViewerFetchedTexture> mMoonTexturep[2]; diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index 8ffb24744af243ee4f31d5ad425ee5764806982d..2e3cf4543586ade109a2eadbb193815e36276d74 100644 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -138,19 +138,19 @@ LLDrawable *LLVOSurfacePatch::createDrawable(LLPipeline *pipeline) return mDrawable; } -static LLTrace::BlockTimerStatHandle FTM_UPDATE_TERRAIN("Update Terrain"); void LLVOSurfacePatch::updateGL() { if (mPatchp) { + LL_PROFILE_ZONE_SCOPED mPatchp->updateGL(); } } BOOL LLVOSurfacePatch::updateGeometry(LLDrawable *drawable) { - LL_RECORD_BLOCK_TIME(FTM_UPDATE_TERRAIN); + LL_PROFILE_ZONE_SCOPED; dirtySpatialGroup(TRUE); @@ -996,10 +996,9 @@ LLVertexBuffer* LLTerrainPartition::createVertexBuffer(U32 type_mask, U32 usage) return new LLVertexBuffer(LLVOSurfacePatch::VERTEX_DATA_MASK, GL_DYNAMIC_DRAW); } -static LLTrace::BlockTimerStatHandle FTM_REBUILD_TERRAIN_VB("Terrain VB"); void LLTerrainPartition::getGeometry(LLSpatialGroup* group) { - LL_RECORD_BLOCK_TIME(FTM_REBUILD_TERRAIN_VB); + LL_PROFILE_ZONE_SCOPED; LLVertexBuffer* buffer = group->mVertexBuffer; diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp index 79e6df69cb2d73879c25989ca3b6e84bcb55f58a..8313760fd7f291c1c04b2e72550d181ca86f47a0 100644 --- a/indra/newview/llvotree.cpp +++ b/indra/newview/llvotree.cpp @@ -414,7 +414,7 @@ void LLVOTree::idleUpdate(LLAgent &agent, const F64 &time) void LLVOTree::setPixelAreaAndAngle(LLAgent &agent) { - auto& viewerCamera = LLViewerCamera::instanceFast(); + auto& viewerCamera = LLViewerCamera::instance(); LLVector3 center = getPositionAgent();//center of tree. LLVector3 viewer_pos_agent = gAgentCamera.getCameraPositionAgent(); @@ -491,7 +491,6 @@ LLDrawable* LLVOTree::createDrawable(LLPipeline *pipeline) const S32 LEAF_INDICES = 24; const S32 LEAF_VERTICES = 16; -static LLTrace::BlockTimerStatHandle FTM_UPDATE_TREE("Update Tree"); void LLVOTree::resetVertexBuffers() { @@ -500,7 +499,7 @@ void LLVOTree::resetVertexBuffers() BOOL LLVOTree::updateGeometry(LLDrawable *drawable) { - LL_RECORD_BLOCK_TIME(FTM_UPDATE_TREE); + LL_PROFILE_ZONE_SCOPED; if(mTrunkLOD >= sMAX_NUM_TREE_LOD_LEVELS) //do not display the tree. { @@ -902,7 +901,7 @@ void LLVOTree::updateMesh() LLMatrix4a rot_mat = trans_mat; - rot_mat.mul(LLQuaternion2(rot)); + rot_mat.mul(LLMatrix4a(LLQuaternion2(rot))); F32 radius = getScale().magVec()*0.05f; rot_mat.applyScale_affine(radius); @@ -1069,7 +1068,7 @@ void LLVOTree::genBranchPipeline(LLStrider<LLVector4a>& vertices, LLQuaternion(((constant_twist + ((i%2==0)?twist:-twist))*i)*DEG_TO_RAD, LLVector4(0.f, 0.f, 1.f)); LLMatrix4a rot_mat = trans_mat; - rot_mat.mul(LLQuaternion2(rot)); + rot_mat.mul(LLMatrix4a(LLQuaternion2(rot))); genBranchPipeline(vertices, normals, tex_coords, colors, indices, index_offset, rot_mat, trunk_LOD, stop_level, depth - 1, 0, scale*mScaleStep, twist, droop, branches, alpha); } diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 30afda205d7b7cc458af2258cd4ea53606d764fd..c22446e6caa0f8a90e4b3aff503ae38a5241a1e8 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -111,12 +111,6 @@ S32 LLVOVolume::mRenderComplexity_current = 0; LLPointer<LLObjectMediaDataClient> LLVOVolume::sObjectMediaClient = NULL; LLPointer<LLObjectMediaNavigateClient> LLVOVolume::sObjectMediaNavigateClient = NULL; -static LLTrace::BlockTimerStatHandle FTM_GEN_TRIANGLES("Generate Triangles"); -static LLTrace::BlockTimerStatHandle FTM_GEN_VOLUME("Generate Volumes"); -static LLTrace::BlockTimerStatHandle FTM_VOLUME_TEXTURES("Volume Textures"); - -extern BOOL gGLDebugLoggingEnabled; - // Implementation class of LLMediaDataClientObject. See llmediadataclient.h class LLMediaDataClientObjectImpl final : public LLMediaDataClientObject { @@ -197,7 +191,7 @@ class LLMediaDataClientObjectImpl final : public LLMediaDataClientObject virtual bool isInterestingEnough() const { - return LLViewerMedia::getInstanceFast()->isInterestingEnough(mObject, getMediaInterest()); + return LLViewerMedia::getInstance()->isInterestingEnough(mObject, getMediaInterest()); } virtual std::string getCapabilityUrl(const std::string &name) const @@ -237,6 +231,7 @@ LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *re mNumFaces = 0; mLODChanged = FALSE; mSculptChanged = FALSE; + mColorChanged = FALSE; mSpotLightPriority = 0.f; mSkinInfoFailed = false; @@ -246,6 +241,7 @@ LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *re mMediaImplList.resize(getNumTEs()); mLastFetchedMediaVersion = -1; + mServerDrawableUpdateCount = 0; memset(&mIndexInTex, 0, sizeof(S32) * LLRender::NUM_VOLUME_TEXTURE_CHANNELS); mMDCImplCount = 0; mLastRiggingInfoLOD = -1; @@ -350,6 +346,9 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, LLColor4U color; const S32 teDirtyBits = (TEM_CHANGE_TEXTURE|TEM_CHANGE_COLOR|TEM_CHANGE_MEDIA); + const bool previously_volume_changed = mVolumeChanged; + const bool previously_face_mapping_changed = mFaceMappingChanged; + const bool previously_color_changed = mColorChanged; // Do base class updates... U32 retval = LLViewerObject::processUpdateMessage(mesgsys, user_data, block_num, update_type, dp); @@ -472,7 +471,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, if(LLVOCache::instanceExists() && getRegion()) { - LLVOCache::getInstanceFast()->removeEntry(getRegion()->getHandle()) ; + LLVOCache::getInstance()->removeEntry(getRegion()->getHandle()) ; } LL_WARNS() << "Bogus TE data in " << getID() << LL_ENDL; @@ -578,9 +577,31 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, // ...and clean up any media impls cleanUpMediaImpls(); + if (( + (mVolumeChanged && !previously_volume_changed) || + (mFaceMappingChanged && !previously_face_mapping_changed) || + (mColorChanged && !previously_color_changed) + ) + && !mLODChanged) { + onDrawableUpdateFromServer(); + } + return retval; } +// Called when a volume, material, etc is updated by the server, possibly by a +// script. If this occurs too often for this object, mark it as active so that +// it doesn't disrupt the octree/render batches, thereby potentially causing a +// big performance penalty. +void LLVOVolume::onDrawableUpdateFromServer() +{ + constexpr U32 UPDATES_UNTIL_ACTIVE = 8; + ++mServerDrawableUpdateCount; + if (mDrawable && !mDrawable->isActive() && mServerDrawableUpdateCount > UPDATES_UNTIL_ACTIVE) + { + mDrawable->makeActive(); + } +} void LLVOVolume::animateTextures() { @@ -743,7 +764,7 @@ BOOL LLVOVolume::isVisible() const void LLVOVolume::updateTextureVirtualSize(bool forced) { - LL_RECORD_BLOCK_TIME(FTM_VOLUME_TEXTURES); + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; // Update the pixel area of all faces if (mDrawable.isNull()) @@ -789,7 +810,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced) const S32 num_faces = mDrawable->getNumFaces(); F32 min_vsize=999999999.f, max_vsize=0.f; - LLViewerCamera* camera = LLViewerCamera::getInstanceFast(); + LLViewerCamera* camera = LLViewerCamera::getInstance(); for (S32 i = 0; i < num_faces; i++) { LLFace* face = mDrawable->getFace(i); @@ -1010,13 +1031,14 @@ LLDrawable *LLVOVolume::createDrawable(LLPipeline *pipeline) updateRadius(); bool force_update = true; // avoid non-alpha mDistance update being optimized away - mDrawable->updateDistance(LLViewerCamera::instanceFast(), force_update); + mDrawable->updateDistance(LLViewerCamera::instance(), force_update); return mDrawable; } BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms_in, const S32 detail, bool unique_volume) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; LLVolumeParams volume_params = params_in; S32 last_lod = mVolumep.notNull() ? LLVolumeLODGroup::getVolumeDetailFromScale(mVolumep->getDetail()) : -1; @@ -1190,15 +1212,17 @@ void LLVOVolume::notifyMeshLoaded() mSculptChanged = TRUE; gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY, TRUE); - LLVOAvatar* rigged_avatar = getAvatar(); - if (rigged_avatar && !isAnimatedObject()) + LLVOAvatar *av = getAvatar(); + if (av && !isAnimatedObject()) { - rigged_avatar->addAttachmentOverridesForObject(this); + av->addAttachmentOverridesForObject(this); + av->notifyAttachmentMeshLoaded(); } - LLControlAvatar* control_avatar = getControlAvatar(); - if (control_avatar && isAnimatedObject()) + LLControlAvatar *cav = getControlAvatar(); + if (cav && isAnimatedObject()) { - control_avatar->addAttachmentOverridesForObject(this); + cav->addAttachmentOverridesForObject(this); + cav->notifyAttachmentMeshLoaded(); } updateVisualComplexity(); } @@ -1492,7 +1516,7 @@ BOOL LLVOVolume::calcLOD() static LLCachedControl<bool> ignore_fov_zoom(gSavedSettings,"IgnoreFOVZoomForLODs"); if(!ignore_fov_zoom) { - lod_factor *= DEFAULT_FIELD_OF_VIEW / LLViewerCamera::getInstanceFast()->getDefaultFOV(); + lod_factor *= DEFAULT_FIELD_OF_VIEW / LLViewerCamera::getInstance()->getDefaultFOV(); } mLODAdjustedDistance = distance; @@ -1672,6 +1696,7 @@ BOOL LLVOVolume::setParent(LLViewerObject* parent) // NOTE: regenFaces() MUST be followed by genTriangles()! void LLVOVolume::regenFaces() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; // remove existing faces BOOL count_changed = mNumFaces != getNumTEs(); @@ -1717,16 +1742,17 @@ void LLVOVolume::regenFaces() } } -BOOL LLVOVolume::genBBoxes(BOOL force_global) +BOOL LLVOVolume::genBBoxes(BOOL force_global, BOOL should_update_octree_bounds) { - BOOL res = TRUE; + LL_PROFILE_ZONE_SCOPED; + BOOL res = TRUE; - LLVector4a min,max; + LLVector4a min, max; - min.clear(); - max.clear(); + min.clear(); + max.clear(); - BOOL rebuild = mDrawable->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION | LLDrawable::REBUILD_RIGGED); + BOOL rebuild = mDrawable->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION | LLDrawable::REBUILD_RIGGED); if (getRiggedVolume()) { @@ -1735,17 +1761,17 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global) // updates needed, set REBUILD_RIGGED accordingly. // Without the flag, this will remove unused rigged volumes, which we are not currently very aggressive about. - updateRiggedVolume(); + updateRiggedVolume(false); + } + + LLVolume* volume = mRiggedVolume; + if (!volume) + { + volume = getVolume(); } - - LLVolume* volume = mRiggedVolume; - if (!volume) - { - volume = getVolume(); - } bool any_valid_boxes = false; - + #ifdef SHOW_DEBUG if (getRiggedVolume()) { @@ -1756,64 +1782,85 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global) for (S32 i = 0, num_vol_face = getVolume()->getNumVolumeFaces(), num_face = mDrawable->getNumFaces(), num_te = getNumTEs(); i < num_vol_face && i < num_face&& i < num_te; ++i) - { - if(num_face <= i ) - break; - - LLFace *face = mDrawable->getFace(i); - if (!face) - { - continue; - } + { + LLFace* face = mDrawable->getFace(i); + if (!face) + { + continue; + } BOOL face_res = face->genVolumeBBoxes(*volume, i, - mRelativeXform, - (mVolumeImpl && mVolumeImpl->isVolumeGlobal()) || force_global); + mRelativeXform, + (mVolumeImpl && mVolumeImpl->isVolumeGlobal()) || force_global); res &= face_res; // note that this result is never used - + // MAINT-8264 - ignore bboxes of ill-formed faces. if (!face_res) { continue; } - if (rebuild) - { + if (rebuild) + { #ifdef SHOW_DEBUG if (getRiggedVolume()) { LL_DEBUGS("RiggedBox") << "rebuilding box, face " << i << " extents " << face->mExtents[0] << ", " << face->mExtents[1] << LL_ENDL; } #endif - if (!any_valid_boxes) - { - min = face->mExtents[0]; - max = face->mExtents[1]; + if (!any_valid_boxes) + { + min = face->mExtents[0]; + max = face->mExtents[1]; any_valid_boxes = true; - } - else - { - min.setMin(min, face->mExtents[0]); - max.setMax(max, face->mExtents[1]); - } - } - } + } + else + { + min.setMin(min, face->mExtents[0]); + max.setMax(max, face->mExtents[1]); + } + } + } if (any_valid_boxes) { - if (rebuild) + if (rebuild && should_update_octree_bounds) { -#ifdef SHOW_DEBUG - if (getRiggedVolume()) + //get the Avatar associated with this object if it's rigged + LLVOAvatar* avatar = nullptr; + if (isRiggedMesh()) + { + if (!isAnimatedObject()) + { + if (isAttachment()) + { + avatar = getAvatar(); + } + } + else + { + LLControlAvatar* controlAvatar = getControlAvatar(); + if (controlAvatar && controlAvatar->mPlaying) + { + avatar = controlAvatar; + } + } + } + + mDrawable->setSpatialExtents(min, max); + + if (avatar) { - LL_DEBUGS("RiggedBox") << "rebuilding got extents " << min << ", " << max << LL_ENDL; + // put all rigged drawables in the same octree node for better batching + mDrawable->setPositionGroup(LLVector4a(0, 0, 0)); + } + else + { + min.add(max); + min.mul(0.5f); + mDrawable->setPositionGroup(min); } -#endif - mDrawable->setSpatialExtents(min,max); - min.add(max); - min.mul(0.5f); - mDrawable->setPositionGroup(min); } - + updateRadius(); mDrawable->movePartition(); } @@ -1823,8 +1870,8 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global) LL_DEBUGS("RiggedBox") << "genBBoxes failed to find any valid face boxes" << LL_ENDL; } #endif - - return res; + + return res; } void LLVOVolume::preRebuild() @@ -1866,7 +1913,7 @@ void LLVOVolume::updateRelativeXform(bool force_identity) } else { - mRelativeXform = LLQuaternion2(mDrawable->getRotation()); + mRelativeXform = LLMatrix4a(LLQuaternion2(mDrawable->getRotation())); mRelativeXform.applyScale_affine(mDrawable->getScale()); mRelativeXform.setTranslate_affine(mDrawable->getPosition()); } @@ -1882,7 +1929,7 @@ void LLVOVolume::updateRelativeXform(bool force_identity) LLQuaternion2 rot(getRotation()); if (mParent) { - LLMatrix4a lrot = LLQuaternion2(mParent->getRotation()); + LLMatrix4a lrot = LLMatrix4a(LLQuaternion2(mParent->getRotation())); lrot.rotate(pos,pos); LLVector4a lpos; lpos.load3(mParent->getPosition().mV); @@ -1890,7 +1937,7 @@ void LLVOVolume::updateRelativeXform(bool force_identity) rot.mul(LLQuaternion2(mParent->getRotation())); } - mRelativeXform = rot; + mRelativeXform = LLMatrix4a(rot); mRelativeXform.applyScale_affine(getScale()); mRelativeXform.setTranslate_affine(LLVector3(pos.getF32ptr())); @@ -1900,12 +1947,9 @@ void LLVOVolume::updateRelativeXform(bool force_identity) } } -static LLTrace::BlockTimerStatHandle FTM_GEN_FLEX("Generate Flexies"); -static LLTrace::BlockTimerStatHandle FTM_UPDATE_PRIMITIVES("Update Primitives"); -static LLTrace::BlockTimerStatHandle FTM_UPDATE_RIGGED_VOLUME("Update Rigged"); - -bool LLVOVolume::lodOrSculptChanged(LLDrawable *drawable, BOOL &compiled) +bool LLVOVolume::lodOrSculptChanged(LLDrawable *drawable, BOOL &compiled, BOOL &should_update_octree_bounds) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; bool regen_faces = false; LLVolume *old_volumep, *new_volumep; @@ -1918,7 +1962,6 @@ bool LLVOVolume::lodOrSculptChanged(LLDrawable *drawable, BOOL &compiled) old_volumep = NULL; { - LL_RECORD_BLOCK_TIME(FTM_GEN_VOLUME); const LLVolumeParams &volume_params = getVolume()->getParams(); setVolume(volume_params, 0); } @@ -1936,6 +1979,9 @@ bool LLVOVolume::lodOrSculptChanged(LLDrawable *drawable, BOOL &compiled) } compiled = TRUE; + // new_lod > old_lod breaks a feedback loop between LOD updates and + // bounding box updates. + should_update_octree_bounds = should_update_octree_bounds || mSculptChanged || new_lod > old_lod; sNumLODChanges += new_num_faces; if ((S32)getNumTEs() != getVolume()->getNumFaces()) @@ -1946,7 +1992,6 @@ bool LLVOVolume::lodOrSculptChanged(LLDrawable *drawable, BOOL &compiled) drawable->setState(LLDrawable::REBUILD_VOLUME); // for face->genVolumeTriangles() { - LL_RECORD_BLOCK_TIME(FTM_GEN_TRIANGLES); regen_faces = new_num_faces != old_num_faces || mNumFaces != (S32)getNumTEs(); if (regen_faces) { @@ -1971,14 +2016,11 @@ bool LLVOVolume::lodOrSculptChanged(LLDrawable *drawable, BOOL &compiled) BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) { - LL_RECORD_BLOCK_TIME(FTM_UPDATE_PRIMITIVES); + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; if (mDrawable->isState(LLDrawable::REBUILD_RIGGED)) { - { - LL_RECORD_BLOCK_TIME(FTM_UPDATE_RIGGED_VOLUME); - updateRiggedVolume(); - } + updateRiggedVolume(false); genBBoxes(FALSE); mDrawable->clearState(LLDrawable::REBUILD_RIGGED); } @@ -1987,7 +2029,6 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) { BOOL res; { - LL_RECORD_BLOCK_TIME(FTM_GEN_FLEX); res = mVolumeImpl->doUpdateGeometry(drawable); } updateFaceFlags(); @@ -2000,8 +2041,6 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) group->dirtyMesh(); } - BOOL compiled = FALSE; - updateRelativeXform(); if (mDrawable.isNull()) // Not sure why this is happening, but it is... @@ -2009,52 +2048,55 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) return TRUE; // No update to complete } + BOOL compiled = FALSE; + // This should be true in most cases, unless we're sure no octree update is + // needed. + BOOL should_update_octree_bounds = bool(getRiggedVolume()) || mDrawable->isState(LLDrawable::REBUILD_POSITION) || !mDrawable->getSpatialExtents()->isFinite3(); + if (mVolumeChanged || mFaceMappingChanged) { dirtySpatialGroup(drawable->isState(LLDrawable::IN_REBUILD_Q1)); bool was_regen_faces = false; + should_update_octree_bounds = true; if (mVolumeChanged) { - was_regen_faces = lodOrSculptChanged(drawable, compiled); + was_regen_faces = lodOrSculptChanged(drawable, compiled, should_update_octree_bounds); drawable->setState(LLDrawable::REBUILD_VOLUME); } - else if (mSculptChanged || mLODChanged) + else if (mSculptChanged || mLODChanged || mColorChanged) { compiled = TRUE; - was_regen_faces = lodOrSculptChanged(drawable, compiled); + was_regen_faces = lodOrSculptChanged(drawable, compiled, should_update_octree_bounds); } if (!was_regen_faces) { - LL_RECORD_BLOCK_TIME(FTM_GEN_TRIANGLES); regenFaces(); } - - genBBoxes(FALSE); } - else if (mLODChanged || mSculptChanged) + else if (mLODChanged || mSculptChanged || mColorChanged) { dirtySpatialGroup(drawable->isState(LLDrawable::IN_REBUILD_Q1)); - + compiled = TRUE; + lodOrSculptChanged(drawable, compiled, should_update_octree_bounds); + if(drawable->isState(LLDrawable::REBUILD_RIGGED | LLDrawable::RIGGED)) { updateRiggedVolume(false); } - compiled = TRUE; - lodOrSculptChanged(drawable, compiled); - - genBBoxes(FALSE); } // it has its own drawable (it's moved) or it has changed UVs or it has changed xforms from global<->local else { compiled = TRUE; // All it did was move or we changed the texture coordinate offset - LL_RECORD_BLOCK_TIME(FTM_GEN_TRIANGLES); - genBBoxes(FALSE); } + // Generate bounding boxes if needed, and update the object's size in the + // octree + genBBoxes(FALSE, should_update_octree_bounds); + // Update face flags updateFaceFlags(); @@ -2062,6 +2104,7 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) mLODChanged = FALSE; mSculptChanged = FALSE; mFaceMappingChanged = FALSE; + mColorChanged = FALSE; return LLViewerObject::updateGeometry(drawable); } @@ -2200,6 +2243,7 @@ S32 LLVOVolume::setTEColor(const U8 te, const LLColor4& color) if (mDrawable.notNull() && retval) { // These should only happen on updates which are not the initial update. + mColorChanged = TRUE; mDrawable->setState(LLDrawable::REBUILD_COLOR); dirtyMesh(); } @@ -2320,14 +2364,14 @@ S32 LLVOVolume::setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID) S32 res = LLViewerObject::setTEMaterialID(te, pMaterialID); #ifdef SHOW_DEBUG LL_DEBUGS("MaterialTEs") << "te "<< (S32)te << " materialid " << pMaterialID.asString() << " res " << res - << ( LLSelectMgr::getInstanceFast()->getSelection()->contains(const_cast<LLVOVolume*>(this), te) ? " selected" : " not selected" ) + << ( LLSelectMgr::getInstance()->getSelection()->contains(const_cast<LLVOVolume*>(this), te) ? " selected" : " not selected" ) << LL_ENDL; LL_DEBUGS("MaterialTEs") << " " << pMaterialID.asString() << LL_ENDL; #endif if (res) { - LLMaterialMgr::instanceFast().getTE(getRegion()->getRegionID(), pMaterialID, te, boost::bind(&LLVOVolume::setTEMaterialParamsCallbackTE, getID(), _1, _2, _3)); + LLMaterialMgr::instance().getTE(getRegion()->getRegionID(), pMaterialID, te, boost::bind(&LLVOVolume::setTEMaterialParamsCallbackTE, getID(), _1, _2, _3)); setChanged(ALL_CHANGED); if (!mDrawable.isNull()) @@ -2580,7 +2624,7 @@ S32 LLVOVolume::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialPa #ifdef SHOW_DEBUG LL_DEBUGS("MaterialTEs") << "te " << (S32)te << " material " << ((pMaterial) ? pMaterial->asLLSD() : LLSD("null")) << " res " << res - << ( LLSelectMgr::getInstanceFast()->getSelection()->contains(const_cast<LLVOVolume*>(this), te) ? " selected" : " not selected" ) + << ( LLSelectMgr::getInstance()->getSelection()->contains(const_cast<LLVOVolume*>(this), te) ? " selected" : " not selected" ) << LL_ENDL; #endif setChanged(ALL_CHANGED); @@ -2774,7 +2818,7 @@ void LLVOVolume::syncMediaData(S32 texture_index, const LLSD &media_data, bool m LLUUID updating_agent = LLTextureEntry::getAgentIDFromMediaVersionString(getMediaURL()); update_from_self = (updating_agent == gAgent.getID()); } - viewer_media_t media_impl = LLViewerMedia::getInstanceFast()->updateMediaImpl(mep, previous_url, update_from_self); + viewer_media_t media_impl = LLViewerMedia::getInstance()->updateMediaImpl(mep, previous_url, update_from_self); addMediaImpl(media_impl, texture_index) ; } @@ -2864,7 +2908,7 @@ bool LLVOVolume::hasMediaPermission(const LLMediaEntry* media_entry, MediaPermTy // Group permissions else if (0 != (media_perms & LLMediaEntry::PERM_GROUP)) { - LLPermissions* obj_perm = LLSelectMgr::getInstanceFast()->findObjectPermissions(this); + LLPermissions* obj_perm = LLSelectMgr::getInstance()->findObjectPermissions(this); if (obj_perm && gAgent.isInGroup(obj_perm->getGroup())) { return true; @@ -3122,7 +3166,7 @@ F64 LLVOVolume::getTotalMediaInterest() const // If this object is selected, this object has "high" interest, but since // there can be more than one, we still add in calculated impl interest // XXX Sadly, 'contains()' doesn't take a const :( - if (LLSelectMgr::getInstanceFast()->getSelection()->contains(const_cast<LLVOVolume*>(this))) + if (LLSelectMgr::getInstance()->getSelection()->contains(const_cast<LLVOVolume*>(this))) interest = F64_MAX / 2.0; int i = 0; @@ -3379,7 +3423,7 @@ F32 LLVOVolume::getSpotLightPriority() const void LLVOVolume::updateSpotLightPriority() { - auto& viewerCamera = LLViewerCamera::instanceFast(); + auto& viewerCamera = LLViewerCamera::instance(); F32 r = getLightRadius(); LLVector3 pos = mDrawable->getPositionAgent(); @@ -3624,61 +3668,6 @@ const LLMeshSkinInfo* LLVOVolume::getSkinInfo() const return nullptr; } -absl::optional<std::pair<LLMatrix4a*, F32*>> LLVOVolume::getCachedSkinRenderMatrix(U32& joint_count, LLVOAvatar *avatar, const LLMeshSkinInfo* skin) -{ - // Calculate this only once per frame - const U32 curFrameCount = LLFrameTimer::getFrameCount(); - if (curFrameCount == mSkinLastRenderFrame && (!mLODChanged && !mSculptChanged && !avatar->isEditingAppearance())) - { - joint_count = mSkinRenderMatrixJointCount; - return { {mSkinMatrixCache.get(), mSkinRenderMatrixCache.get()} }; - } - - if (!skin) - { - skin = getSkinInfo(); - if (!skin) - { - joint_count = 0; - return {}; - } - } - joint_count = LLSkinningUtil::getMeshJointCount(skin); - - if ((!mSkinMatrixCache || !mSkinRenderMatrixCache) || (joint_count != mSkinRenderMatrixJointCount)) - { - mSkinMatrixCache = std::make_unique<LLMatrix4a[]>(joint_count); - mSkinRenderMatrixCache = std::make_unique<F32[]>(joint_count * 12); - mSkinRenderMatrixJointCount = joint_count; - } - - LLSkinningUtil::initSkinningMatrixPalette(mSkinMatrixCache.get(), joint_count, skin, avatar); - - for (U32 i = 0; i < joint_count; ++i) - { - F32* m = (F32*)mSkinMatrixCache[i].mMatrix[0].getF32ptr(); - - U32 idx = i * 12; - - mSkinRenderMatrixCache[idx + 0] = m[0]; - mSkinRenderMatrixCache[idx + 1] = m[1]; - mSkinRenderMatrixCache[idx + 2] = m[2]; - mSkinRenderMatrixCache[idx + 3] = m[12]; - - mSkinRenderMatrixCache[idx + 4] = m[4]; - mSkinRenderMatrixCache[idx + 5] = m[5]; - mSkinRenderMatrixCache[idx + 6] = m[6]; - mSkinRenderMatrixCache[idx + 7] = m[13]; - - mSkinRenderMatrixCache[idx + 8] = m[8]; - mSkinRenderMatrixCache[idx + 9] = m[9]; - mSkinRenderMatrixCache[idx + 10] = m[10]; - mSkinRenderMatrixCache[idx + 11] = m[14]; - } - - mSkinLastRenderFrame = curFrameCount; - return { {mSkinMatrixCache.get(), mSkinRenderMatrixCache.get()} }; -} // virtual BOOL LLVOVolume::isRiggedMesh() const @@ -3840,11 +3829,9 @@ void LLVOVolume::afterReparent() } //---------------------------------------------------------------------------- -static LLTrace::BlockTimerStatHandle FTM_VOVOL_RIGGING_INFO("VOVol Rigging Info"); - void LLVOVolume::updateRiggingInfo() { - LL_RECORD_BLOCK_TIME(FTM_VOVOL_RIGGING_INFO); + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; if (isRiggedMesh()) { const LLMeshSkinInfo* skin = getSkinInfo(); @@ -4475,6 +4462,7 @@ void LLVOVolume::updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) F32 LLVOVolume::getBinRadius() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; F32 radius; F32 scale = 1.f; @@ -4670,9 +4658,9 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& if (mDrawable->isState(LLDrawable::RIGGED)) { - if (pick_rigged || LLToolMgr::getInstanceFast()->inBuildMode()) + if (pick_rigged || LLToolMgr::getInstance()->inBuildMode()) { - updateRiggedVolume(true); + updateRiggedVolume(true, LLRiggedVolume::DO_NOT_UPDATE_FACES); volume = mRiggedVolume; transform = false; } @@ -4747,6 +4735,9 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& continue; } + // This calculates the bounding box of the skinned mesh from scratch. It's actually quite expensive, but not nearly as expensive as building a full octree. + // rebuild_face_octrees = false because an octree for this face will be built later only if needed for narrow phase picking. + updateRiggedVolume(true, i, false); face_hit = volume->lineSegmentIntersect(local_start, local_end, i, &p, &tc, &n, &tn); @@ -4870,12 +4861,13 @@ void LLVOVolume::clearRiggedVolume() } } -void LLVOVolume::updateRiggedVolume(bool force_update) +void LLVOVolume::updateRiggedVolume(bool force_treat_as_rigged, LLRiggedVolume::FaceIndex face_index, bool rebuild_face_octrees) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; //Update mRiggedVolume to match current animation frame of avatar. //Also update position/size in octree. - if ((!force_update) && (!treatAsRigged())) + if ((!force_treat_as_rigged) && (!treatAsRigged())) { clearRiggedVolume(); @@ -4909,14 +4901,12 @@ void LLVOVolume::updateRiggedVolume(bool force_update) updateRelativeXform(); } - mRiggedVolume->update(mSkinInfo, avatar, volume, this); + mRiggedVolume->update(mSkinInfo, avatar, volume, face_index, rebuild_face_octrees); } -static LLTrace::BlockTimerStatHandle FTM_SKIN_RIGGED("Skin"); -static LLTrace::BlockTimerStatHandle FTM_RIGGED_OCTREE("Octree"); - -void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* volume, LLVOVolume* src_object) +void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* volume, FaceIndex face_index, bool rebuild_face_octrees) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; bool copy = false; S32 vol_num_faces = volume->getNumVolumeFaces(); if (vol_num_faces != getNumVolumeFaces()) @@ -4938,7 +4928,7 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons if (copy) { - copyVolumeFaces(volume); + copyVolumeFaces(volume); } else { @@ -4946,7 +4936,7 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons if (is_paused) { S32 frames_paused = LLFrameTimer::getFrameCount() - avatar->getMotionController().getPausedFrame(); - if (frames_paused > 2) + if (frames_paused > 1) { return; } @@ -4955,15 +4945,34 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons //build matrix palette - U32 maxJoints = 0; - auto ret = src_object->getCachedSkinRenderMatrix(maxJoints, avatar, skin); + static const size_t kMaxJoints = LL_MAX_JOINTS_PER_MESH_OBJECT; - LLMatrix4a* mat = ret.value().first; + LLMatrix4a mat[kMaxJoints]; + U32 maxJoints = LLSkinningUtil::getMeshJointCount(skin); + LLSkinningUtil::initSkinningMatrixPalette(mat, maxJoints, skin, avatar); + const LLMatrix4a bind_shape_matrix = skin->mBindShapeMatrix; S32 rigged_vert_count = 0; S32 rigged_face_count = 0; LLVector4a box_min, box_max; - for (S32 i = 0; i < vol_num_faces; ++i) + S32 face_begin; + S32 face_end; + if (face_index == DO_NOT_UPDATE_FACES) + { + face_begin = 0; + face_end = 0; + } + else if (face_index == UPDATE_ALL_FACES) + { + face_begin = 0; + face_end = vol_num_faces; + } + else + { + face_begin = face_index; + face_end = face_begin + 1; + } + for (S32 i = face_begin; i < face_end; ++i) { const LLVolumeFace& vol_face = volume->getVolumeFace(i); @@ -4974,13 +4983,11 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons if ( weight ) { LLSkinningUtil::checkSkinWeights(weight, dst_face.mNumVertices, skin); - LLMatrix4a bind_shape_matrix = skin->mBindShapeMatrix; LLVector4a* pos = dst_face.mPositions; if (pos && dst_face.mExtents) { - LL_RECORD_BLOCK_TIME(FTM_SKIN_RIGGED); rigged_vert_count += dst_face.mNumVertices; rigged_face_count++; @@ -5026,16 +5033,10 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons } + if (rebuild_face_octrees) { - LL_RECORD_BLOCK_TIME(FTM_RIGGED_OCTREE); - delete dst_face.mOctree; - dst_face.mOctree = NULL; - - LLVector4a size; - size.setSub(dst_face.mExtents[1], dst_face.mExtents[0]); - size.splat(size.getLength3().getF32()*0.5f); - - dst_face.createOctree(1.f); + dst_face.destroyOctree(); + dst_face.createOctree(); } } } @@ -5130,13 +5131,13 @@ bool can_batch_texture(LLFace* facep) const static U32 MAX_FACE_COUNT = 4096U; int32_t LLVolumeGeometryManager::sInstanceCount = 0; -LLFace** LLVolumeGeometryManager::sFullbrightFaces = NULL; -LLFace** LLVolumeGeometryManager::sBumpFaces = NULL; -LLFace** LLVolumeGeometryManager::sSimpleFaces = NULL; -LLFace** LLVolumeGeometryManager::sNormFaces = NULL; -LLFace** LLVolumeGeometryManager::sSpecFaces = NULL; -LLFace** LLVolumeGeometryManager::sNormSpecFaces = NULL; -LLFace** LLVolumeGeometryManager::sAlphaFaces = NULL; +LLFace** LLVolumeGeometryManager::sFullbrightFaces[2] = { NULL }; +LLFace** LLVolumeGeometryManager::sBumpFaces[2] = { NULL }; +LLFace** LLVolumeGeometryManager::sSimpleFaces[2] = { NULL }; +LLFace** LLVolumeGeometryManager::sNormFaces[2] = { NULL }; +LLFace** LLVolumeGeometryManager::sSpecFaces[2] = { NULL }; +LLFace** LLVolumeGeometryManager::sNormSpecFaces[2] = { NULL }; +LLFace** LLVolumeGeometryManager::sAlphaFaces[2] = { NULL }; LLVolumeGeometryManager::LLVolumeGeometryManager() : LLGeometryManager() @@ -5164,39 +5165,43 @@ LLVolumeGeometryManager::~LLVolumeGeometryManager() void LLVolumeGeometryManager::allocateFaces(U32 pMaxFaceCount) { - sFullbrightFaces = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount*sizeof(LLFace*))); - sBumpFaces = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount*sizeof(LLFace*))); - sSimpleFaces = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount*sizeof(LLFace*))); - sNormFaces = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount*sizeof(LLFace*))); - sSpecFaces = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount*sizeof(LLFace*))); - sNormSpecFaces = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount*sizeof(LLFace*))); - sAlphaFaces = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount*sizeof(LLFace*))); + for (int i = 0; i < 2; ++i) + { + sFullbrightFaces[i] = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount * sizeof(LLFace*))); + sBumpFaces[i] = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount * sizeof(LLFace*))); + sSimpleFaces[i] = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount * sizeof(LLFace*))); + sNormFaces[i] = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount * sizeof(LLFace*))); + sSpecFaces[i] = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount * sizeof(LLFace*))); + sNormSpecFaces[i] = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount * sizeof(LLFace*))); + sAlphaFaces[i] = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount * sizeof(LLFace*))); + } } void LLVolumeGeometryManager::freeFaces() { - ll_aligned_free<64>(sFullbrightFaces); - ll_aligned_free<64>(sBumpFaces); - ll_aligned_free<64>(sSimpleFaces); - ll_aligned_free<64>(sNormFaces); - ll_aligned_free<64>(sSpecFaces); - ll_aligned_free<64>(sNormSpecFaces); - ll_aligned_free<64>(sAlphaFaces); - - sFullbrightFaces = NULL; - sBumpFaces = NULL; - sSimpleFaces = NULL; - sNormFaces = NULL; - sSpecFaces = NULL; - sNormSpecFaces = NULL; - sAlphaFaces = NULL; + for (int i = 0; i < 2; ++i) + { + ll_aligned_free<64>(sFullbrightFaces[i]); + ll_aligned_free<64>(sBumpFaces[i]); + ll_aligned_free<64>(sSimpleFaces[i]); + ll_aligned_free<64>(sNormFaces[i]); + ll_aligned_free<64>(sSpecFaces[i]); + ll_aligned_free<64>(sNormSpecFaces[i]); + ll_aligned_free<64>(sAlphaFaces[i]); + + sFullbrightFaces[i] = NULL; + sBumpFaces[i] = NULL; + sSimpleFaces[i] = NULL; + sNormFaces[i] = NULL; + sSpecFaces[i] = NULL; + sNormSpecFaces[i] = NULL; + sAlphaFaces[i] = NULL; + } } -static LLTrace::BlockTimerStatHandle FTM_REGISTER_FACE("Register Face"); - void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, U32 type) { - LL_RECORD_BLOCK_TIME(FTM_REGISTER_FACE); + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; //if ( type == LLRenderPass::PASS_ALPHA // && facep->getTextureEntry()->getMaterialParams().notNull() // && !facep->getVertexBuffer()->hasDataType(LLVertexBuffer::TYPE_TANGENT) @@ -5211,7 +5216,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, // [RLVa:KB] - Checked: 2010-11-29 (RLVa-1.3.0c) | Modified: RLVa-1.3.0c const LLViewerObject* pObj = facep->getViewerObject(); bool selected = pObj->isSelected(); - if ( (pObj->isSelected() && LLSelectMgr::getInstanceFast()->mHideSelectedObjects) && + if ( (pObj->isSelected() && LLSelectMgr::getInstance()->mHideSelectedObjects) && ( (!RlvActions::isRlvEnabled()) || ( ((!pObj->isHUDAttachment()) || (!gRlvAttachmentLocks.isLockedAttachment(pObj->getRootEdit()))) && (RlvActions::canEdit(pObj)) ) ) ) @@ -5220,8 +5225,18 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, return; } + U32 passType = type; + + bool rigged = facep->isState(LLFace::RIGGED); + + if (rigged) + { + // hacky, should probably clean up -- if this face is rigged, put it in "type + 1" + // See LLRenderPass PASS_foo enum + passType += 1; + } //add face to drawmap - LLSpatialGroup::drawmap_elem_t& draw_vec = group->mDrawMap[type]; + LLSpatialGroup::drawmap_elem_t& draw_vec = group->mDrawMap[passType]; S32 idx = draw_vec.size()-1; @@ -5247,7 +5262,12 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, LLDrawable* drawable = facep->getDrawable(); - if (drawable->isState(LLDrawable::ANIMATED_CHILD)) + if (rigged) + { + // rigged meshes ignore their model matrix + model_mat = nullptr; + } + else if (drawable->isState(LLDrawable::ANIMATED_CHILD)) { model_mat = &drawable->getWorldMatrix(); } @@ -5288,6 +5308,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, } } + F32 vsize = facep->getVirtualSize(); //TODO -- adjust by texture scale? if (index < FACE_DO_NOT_BATCH_TEXTURES && idx >= 0) { @@ -5301,10 +5322,12 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, { batchable = true; draw_vec[idx]->mTextureList[index] = tex; + draw_vec[idx]->mTextureListVSize[index] = vsize; } else if (draw_vec[idx]->mTextureList[index] == tex) { //this face's texture index can be used with this batch batchable = true; + draw_vec[idx]->mTextureListVSize[index] = llmax(vsize, draw_vec[idx]->mTextureListVSize[index]); } } else @@ -5321,7 +5344,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() <= (U32) gGLManager.mGLMaxVertexRange && draw_vec[idx]->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange && #endif - draw_vec[idx]->mMaterial == mat && + //draw_vec[idx]->mMaterial == mat && draw_vec[idx]->mMaterialID == mat_id && draw_vec[idx]->mFullbright == fullbright && draw_vec[idx]->mBump == bump && @@ -5329,16 +5352,20 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, draw_vec[idx]->mTextureMatrix == tex_mat && draw_vec[idx]->mModelMatrix == model_mat && draw_vec[idx]->mShaderMask == shader_mask && - draw_vec[idx]->mSelected == selected) + draw_vec[idx]->mSelected == selected && + draw_vec[idx]->mAvatar == facep->mAvatar && + draw_vec[idx]->getSkinHash() == facep->getSkinHash()) { draw_vec[idx]->mCount += facep->getIndicesCount(); draw_vec[idx]->mEnd += facep->getGeomCount(); - draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, facep->getVirtualSize()); + draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, vsize); if (index < FACE_DO_NOT_BATCH_TEXTURES && index >= draw_vec[idx]->mTextureList.size()) { draw_vec[idx]->mTextureList.resize(index+1); draw_vec[idx]->mTextureList[index] = tex; + draw_vec[idx]->mTextureListVSize.resize(index + 1); + draw_vec[idx]->mTextureListVSize[index] = vsize; } draw_vec[idx]->validate(); update_min_max(draw_vec[idx]->mExtents[0], draw_vec[idx]->mExtents[1], facep->mExtents[0]); @@ -5353,7 +5380,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, LLPointer<LLDrawInfo> draw_info = new LLDrawInfo(start,end,count,offset, tex, facep->getVertexBuffer(), selected, fullbright, bump); draw_info->mGroup = group; - draw_info->mVSize = facep->getVirtualSize(); + draw_info->mVSize = vsize; draw_vec.push_back(draw_info); draw_info->mTextureMatrix = tex_mat; draw_info->mModelMatrix = model_mat; @@ -5375,6 +5402,8 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, draw_info->mSpecularMap = NULL; draw_info->mMaterial = mat; draw_info->mShaderMask = shader_mask; + draw_info->mAvatar = facep->mAvatar; + draw_info->mSkinInfo = facep->mSkinInfo; if (mat) { @@ -5426,6 +5455,8 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, { //initialize texture list for texture batching draw_info->mTextureList.resize(index+1); draw_info->mTextureList[index] = tex; + draw_info->mTextureListVSize.resize(index + 1); + draw_info->mTextureListVSize[index] = vsize; } draw_info->validate(); } @@ -5436,38 +5467,6 @@ void LLVolumeGeometryManager::getGeometry(LLSpatialGroup* group) } -static LLTrace::BlockTimerStatHandle FTM_REBUILD_VOLUME_VB("Volume VB"); -static LLTrace::BlockTimerStatHandle FTM_REBUILD_VOLUME_FACE_LIST("Build Face List"); -static LLTrace::BlockTimerStatHandle FTM_REBUILD_VOLUME_GEN_DRAW_INFO("Gen Draw Info"); - -static LLDrawPoolAvatar* get_avatar_drawpool(LLViewerObject* vobj) -{ - LLVOAvatar* avatar = vobj->getAvatar(); - - if (avatar) - { - LLDrawable* drawable = avatar->mDrawable; - if (drawable && drawable->getNumFaces() > 0) - { - LLFace* face = drawable->getFace(0); - if (face) - { - LLDrawPool* drawpool = face->getPool(); - if (drawpool) - { - if (drawpool->getType() == LLDrawPool::POOL_AVATAR - || drawpool->getType() == LLDrawPool::POOL_CONTROL_AV) - { - return (LLDrawPoolAvatar*) drawpool; - } - } - } - } - } - - return NULL; -} - void handleRenderAutoMuteByteLimitChanged(const LLSD& new_value) { static LLCachedControl<U32> render_auto_mute_byte_limit(gSavedSettings, "RenderAutoMuteByteLimit", 0U); @@ -5543,8 +5542,32 @@ void handleRenderAutoMuteByteLimitChanged(const LLSD& new_value) } } +// add a face pointer to a list of face pointers without going over MAX_COUNT faces +template<typename T> +static inline void add_face(T*** list, U32* count, T* face) +{ + if (face->isState(LLFace::RIGGED)) + { + if (count[1] < MAX_FACE_COUNT) + { + face->setDrawOrderIndex(count[1]); + list[1][count[1]++] = face; + } + } + else + { + if (count[0] < MAX_FACE_COUNT) + { + face->setDrawOrderIndex(count[0]); + list[0][count[0]++] = face; + } + } +} + void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; + if (group->changeLOD()) { group->mLastUpdateDistance = group->mDistance; @@ -5561,8 +5584,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) return; } - LL_RECORD_BLOCK_TIME(FTM_REBUILD_VOLUME_VB); - group->mBuilt = 1.f; group->mGeometryBytes = 0; @@ -5574,16 +5595,13 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) group->clearDrawMap(); - mFaceList.clear(); - - U32 fullbright_count = 0; - U32 bump_count = 0; - U32 simple_count = 0; - U32 alpha_count = 0; - U32 norm_count = 0; - U32 spec_count = 0; - U32 normspec_count = 0; - + U32 fullbright_count[2] = { 0 }; + U32 bump_count[2] = { 0 }; + U32 simple_count[2] = { 0 }; + U32 alpha_count[2] = { 0 }; + U32 norm_count[2] = { 0 }; + U32 spec_count[2] = { 0 }; + U32 normspec_count[2] = { 0 }; U32 useage = group->getSpatialPartition()->mBufferUsage; @@ -5605,7 +5623,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) #endif { - LL_RECORD_BLOCK_TIME(FTM_REBUILD_VOLUME_FACE_LIST); + LL_PROFILE_ZONE_NAMED("rebuildGeom - face list"); //get all the faces into a list for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(), drawable_end = group->getDataEnd(); drawable_iter != drawable_end; ++drawable_iter) @@ -5629,7 +5647,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) continue; } - bool is_mesh = vobj->isMesh(); + bool is_mesh = vobj->isMesh(); if (is_mesh && ((vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded()) || !gMeshRepo.meshRezEnabled())) { @@ -5670,15 +5688,32 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) drawablep->clearState(LLDrawable::HAS_ALPHA); - if (vobj->isRiggedMesh() && - ((vobj->isAnimatedObject() && vobj->getControlAvatar()) || - (!vobj->isAnimatedObject() && vobj->getAvatar()))) + LLVOAvatar* avatar = nullptr; + const LLMeshSkinInfo* skinInfo = nullptr; + if (is_mesh) { - vobj->getAvatar()->addAttachmentOverridesForObject(vobj, NULL, false); + skinInfo = vobj->getSkinInfo(); } - + + if (skinInfo) + { + if (vobj->isAnimatedObject()) + { + avatar = vobj->getControlAvatar(); + } + else + { + avatar = vobj->getAvatar(); + } + } + + if (avatar != nullptr) + { + avatar->addAttachmentOverridesForObject(vobj, NULL, false); + } + // Standard rigged mesh attachments: - bool rigged = !vobj->isAnimatedObject() && vobj->isRiggedMesh() && vobj->isAttachment(); + bool rigged = !vobj->isAnimatedObject() && skinInfo && vobj->isAttachment(); // Animated objects. Have to check for isRiggedMesh() to // exclude static objects in animated object linksets. rigged = rigged || (vobj->isAnimatedObject() && vobj->isRiggedMesh() && @@ -5702,183 +5737,34 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) //sum up face verts and indices drawablep->updateFaceSize(i); - - if (rigged) - { - if (!facep->isState(LLFace::RIGGED)) - { //completely reset vertex buffer - facep->clearVertexBuffer(); - } - - facep->setState(LLFace::RIGGED); - any_rigged_face = true; - - //get drawpool of avatar with rigged face - LLDrawPoolAvatar* pool = get_avatar_drawpool(vobj); - - if (pool) - { - const LLTextureEntry* te = facep->getTextureEntry(); - - //remove face from old pool if it exists - LLDrawPool* old_pool = facep->getPool(); - if (old_pool - && (old_pool->getType() == LLDrawPool::POOL_AVATAR || old_pool->getType() == LLDrawPool::POOL_CONTROL_AV)) - { - ((LLDrawPoolAvatar*) old_pool)->removeRiggedFace(facep); - } - - //add face to new pool - LLViewerTexture* tex = facep->getTexture(); - U32 type = gPipeline.getPoolTypeFromTE(te, tex); - - F32 te_alpha = te->getColor().mV[3]; - - if (te->getGlow()) - { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_GLOW); - } - - LLMaterial* mat = te->getMaterialParams().get(); - bool fullbright = te->getFullbright(); - - if (mat && LLPipeline::sRenderDeferred) - { - U8 alpha_mode = mat->getDiffuseAlphaMode(); - - bool is_alpha = type == LLDrawPool::POOL_ALPHA && - (alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND || - te_alpha < 0.999f); - - if (is_alpha) - { //this face needs alpha blending, override alpha mode - alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND; - } - - if (fullbright && (alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE)) - { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT); - } - else if (!is_alpha || te_alpha > 0.f) // //only add the face if it will actually be visible - { - U32 mask = mat->getShaderMask(alpha_mode); - pool->addRiggedFace(facep, mask); - } - - if(vobj->isAnimatedObject() && vobj->isRiggedMesh()) - { - pool->updateRiggedVertexBuffers(vobj->getAvatar()); - } - } - else if (mat) - { - bool is_alpha = type == LLDrawPool::POOL_ALPHA; - U8 mode = mat->getDiffuseAlphaMode(); - bool can_be_shiny = mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE || - mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE; - - if (mode == LLMaterial::DIFFUSE_ALPHA_MODE_MASK && te->getColor().mV[3] >= 0.999f) - { - pool->addRiggedFace(facep, fullbright ? LLDrawPoolAvatar::RIGGED_FULLBRIGHT : LLDrawPoolAvatar::RIGGED_SIMPLE); - } - else if (is_alpha || (te->getColor().mV[3] < 0.999f)) - { - if (te->getColor().mV[3] > 0.f) - { - pool->addRiggedFace(facep, fullbright ? LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA : LLDrawPoolAvatar::RIGGED_ALPHA); - } - } - else if (gPipeline.canUseVertexShaders() - && LLPipeline::sRenderBump - && te->getShiny() - && can_be_shiny) - { - pool->addRiggedFace(facep, fullbright ? LLDrawPoolAvatar::RIGGED_FULLBRIGHT_SHINY : LLDrawPoolAvatar::RIGGED_SHINY); - } - else - { - pool->addRiggedFace(facep, fullbright ? LLDrawPoolAvatar::RIGGED_FULLBRIGHT : LLDrawPoolAvatar::RIGGED_SIMPLE); - } - } - else - { - if (type == LLDrawPool::POOL_ALPHA) - { - if (te->getColor().mV[3] > 0.f) - { - if (te->getFullbright()) - { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA); - } - else - { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_ALPHA); - } - } - } - else if (te->getShiny()) - { - if (te->getFullbright()) - { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_SHINY); - } - else - { - if (LLPipeline::sRenderDeferred) - { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE); - } - else - { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SHINY); - } - } - } - else - { - if (te->getFullbright()) - { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT); - } - else - { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE); - } - } - - - if (LLPipeline::sRenderDeferred) - { - if (type != LLDrawPool::POOL_ALPHA && !te->getFullbright()) - { - if (te->getBumpmap()) - { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_BUMP); - } - else - { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_SIMPLE); - } - } - } - } - } - continue; - } - else - { - if (facep->isState(LLFace::RIGGED)) - { //face is not rigged but used to be, remove from rigged face pool - LLDrawPoolAvatar* pool = (LLDrawPoolAvatar*) facep->getPool(); - if (pool) - { - pool->removeRiggedFace(facep); - } - facep->clearState(LLFace::RIGGED); - } - } + if (rigged) + { + if (!facep->isState(LLFace::RIGGED)) + { //completely reset vertex buffer + facep->clearVertexBuffer(); + } + facep->setState(LLFace::RIGGED); + facep->mSkinInfo = (LLMeshSkinInfo*) skinInfo; // TODO -- fix ugly de-consting here + facep->mAvatar = avatar; + any_rigged_face = true; + } + else + { + if (facep->isState(LLFace::RIGGED)) + { + //face is not rigged but used to be, remove from rigged face pool + LLDrawPoolAvatar* pool = (LLDrawPoolAvatar*)facep->getPool(); + if (pool) + { + pool->removeFace(facep); + } + facep->clearState(LLFace::RIGGED); + facep->mAvatar = NULL; + facep->mSkinInfo = NULL; + } + } if (cur_total > max_total || facep->getIndicesCount() <= 0 || facep->getGeomCount() <= 0) { @@ -5886,10 +5772,12 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) continue; } - cur_total += facep->getGeomCount(); - - if (facep->hasGeometry() && facep->getPixelArea() > FORCE_CULL_AREA) + if (facep->hasGeometry() && + (rigged || // <-- HACK FIXME -- getPixelArea might be incorrect for rigged objects + facep->getPixelArea() > FORCE_CULL_AREA)) // <-- don't render tiny faces { + cur_total += facep->getGeomCount(); + const LLTextureEntry* te = facep->getTextureEntry(); LLViewerTexture* tex = facep->getTexture(); @@ -5947,28 +5835,19 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) { if (facep->canRenderAsMask()) { //can be treated as alpha mask - if (simple_count < MAX_FACE_COUNT) - { - sSimpleFaces[simple_count++] = facep; - } + add_face(sSimpleFaces, simple_count, facep); } else { - if (te->getColor().mV[3] > 0.f || te->getGlow() > 0.f) - { //only treat as alpha in the pipeline if < 100% transparent - drawablep->setState(LLDrawable::HAS_ALPHA); - if (alpha_count < MAX_FACE_COUNT) - { - sAlphaFaces[alpha_count++] = facep; - } - } - else if (LLDrawPoolAlpha::sShowDebugAlpha) - { - if (alpha_count < MAX_FACE_COUNT) - { - sAlphaFaces[alpha_count++] = facep; - } - } + if (te->getColor().mV[3] > 0.f || te->getGlow() > 0.f) + { //only treat as alpha in the pipeline if < 100% transparent + drawablep->setState(LLDrawable::HAS_ALPHA); + add_face(sAlphaFaces, alpha_count, facep); + } + else if (LLDrawPoolAlpha::sShowDebugAlpha) + { + add_face(sAlphaFaces, alpha_count, facep); + } } } else @@ -5988,81 +5867,51 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) { if (mat->getSpecularID().notNull()) { //has normal and specular maps (needs texcoord1, texcoord2, and tangent) - if (normspec_count < MAX_FACE_COUNT) - { - sNormSpecFaces[normspec_count++] = facep; - } + add_face(sNormSpecFaces, normspec_count, facep); } else { //has normal map (needs texcoord1 and tangent) - if (norm_count < MAX_FACE_COUNT) - { - sNormFaces[norm_count++] = facep; - } + add_face(sNormFaces, norm_count, facep); } } else if (mat->getSpecularID().notNull()) { //has specular map but no normal map, needs texcoord2 - if (spec_count < MAX_FACE_COUNT) - { - sSpecFaces[spec_count++] = facep; - } + add_face(sSpecFaces, spec_count, facep); } else { //has neither specular map nor normal map, only needs texcoord0 - if (simple_count < MAX_FACE_COUNT) - { - sSimpleFaces[simple_count++] = facep; - } + add_face(sSimpleFaces, simple_count, facep); } } else if (te->getBumpmap()) { //needs normal + tangent - if (bump_count < MAX_FACE_COUNT) - { - sBumpFaces[bump_count++] = facep; - } + add_face(sBumpFaces, bump_count, facep); } else if (te->getShiny() || !te->getFullbright()) { //needs normal - if (simple_count < MAX_FACE_COUNT) - { - sSimpleFaces[simple_count++] = facep; - } + add_face(sSimpleFaces, simple_count, facep); } else { //doesn't need normal facep->setState(LLFace::FULLBRIGHT); - if (fullbright_count < MAX_FACE_COUNT) - { - sFullbrightFaces[fullbright_count++] = facep; - } + add_face(sFullbrightFaces, fullbright_count, facep); } } else { if (te->getBumpmap() && LLPipeline::sRenderBump) { //needs normal + tangent - if (bump_count < MAX_FACE_COUNT) - { - sBumpFaces[bump_count++] = facep; - } + add_face(sBumpFaces, bump_count, facep); } else if ((te->getShiny() && LLPipeline::sRenderBump) || !(te->getFullbright() || bake_sunlight)) { //needs normal - if (simple_count < MAX_FACE_COUNT) - { - sSimpleFaces[simple_count++] = facep; - } + add_face(sSimpleFaces, simple_count, facep); } else { //doesn't need normal facep->setState(LLFace::FULLBRIGHT); - if (fullbright_count < MAX_FACE_COUNT) - { - sFullbrightFaces[fullbright_count++] = facep; - } + add_face(sFullbrightFaces, fullbright_count, facep); } } } @@ -6078,6 +5927,11 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) if (!drawablep->isState(LLDrawable::RIGGED)) { drawablep->setState(LLDrawable::RIGGED); + LLDrawable* root = drawablep->getRoot(); + if (root != drawablep) + { + root->setState(LLDrawable::RIGGED_CHILD); + } //first time this is drawable is being marked as rigged, // do another LoD update to use avatar bounding box @@ -6087,7 +5941,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) else { drawablep->clearState(LLDrawable::RIGGED); - vobj->updateRiggedVolume(); + vobj->updateRiggedVolume(false); } } } @@ -6117,6 +5971,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) BOOL batch_textures = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 1; + // add extra vertex data for deferred rendering (not necessarily for batching textures) if (batch_textures) { bump_mask = bump_mask | LLVertexBuffer::MAP_TANGENT; @@ -6129,13 +5984,24 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) U32 geometryBytes = 0; - geometryBytes += genDrawInfo(group, simple_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sSimpleFaces, simple_count, FALSE, batch_textures, FALSE); - geometryBytes += genDrawInfo(group, fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sFullbrightFaces, fullbright_count, FALSE, batch_textures); - geometryBytes += genDrawInfo(group, alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sAlphaFaces, alpha_count, TRUE, batch_textures); - geometryBytes += genDrawInfo(group, bump_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sBumpFaces, bump_count, FALSE, FALSE); - geometryBytes += genDrawInfo(group, norm_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sNormFaces, norm_count, FALSE, FALSE); - geometryBytes += genDrawInfo(group, spec_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sSpecFaces, spec_count, FALSE, FALSE); - geometryBytes += genDrawInfo(group, normspec_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sNormSpecFaces, normspec_count, FALSE, FALSE); + // generate render batches for static geometry + U32 extra_mask = LLVertexBuffer::MAP_TEXTURE_INDEX; + BOOL alpha_sort = TRUE; + BOOL rigged = FALSE; + for (int i = 0; i < 2; ++i) //two sets, static and rigged) + { + geometryBytes += genDrawInfo(group, simple_mask | extra_mask, sSimpleFaces[i], simple_count[i], FALSE, batch_textures, rigged); + geometryBytes += genDrawInfo(group, fullbright_mask | extra_mask, sFullbrightFaces[i], fullbright_count[i], FALSE, batch_textures, rigged); + geometryBytes += genDrawInfo(group, alpha_mask | extra_mask, sAlphaFaces[i], alpha_count[i], alpha_sort, batch_textures, rigged); + geometryBytes += genDrawInfo(group, bump_mask | extra_mask, sBumpFaces[i], bump_count[i], FALSE, FALSE, rigged); + geometryBytes += genDrawInfo(group, norm_mask | extra_mask, sNormFaces[i], norm_count[i], FALSE, FALSE, rigged); + geometryBytes += genDrawInfo(group, spec_mask | extra_mask, sSpecFaces[i], spec_count[i], FALSE, FALSE, rigged); + geometryBytes += genDrawInfo(group, normspec_mask | extra_mask, sNormSpecFaces[i], normspec_count[i], FALSE, FALSE, rigged); + + // for rigged set, add weights and disable alpha sorting (rigged items use depth buffer) + extra_mask |= LLVertexBuffer::MAP_WEIGHT4; + rigged = TRUE; + } group->mGeometryBytes = geometryBytes; @@ -6161,160 +6027,147 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) group->setState(LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO); } - mFaceList.clear(); } -static LLTrace::BlockTimerStatHandle FTM_REBUILD_MESH_FLUSH("Flush Mesh"); - void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; llassert(group); if (group && group->hasState(LLSpatialGroup::MESH_DIRTY) && !group->hasState(LLSpatialGroup::GEOM_DIRTY)) { - LL_RECORD_BLOCK_TIME(FTM_REBUILD_VOLUME_VB); - LL_RECORD_BLOCK_TIME(FTM_REBUILD_VOLUME_GEN_DRAW_INFO); //make sure getgeometryvolume shows up in the right place in timers + { + LL_PROFILE_ZONE_NAMED("rebuildMesh - gen draw info"); - group->mBuilt = 1.f; + group->mBuilt = 1.f; - S32 num_mapped_vertex_buffer = LLVertexBuffer::sMappedCount ; + S32 num_mapped_vertex_buffer = LLVertexBuffer::sMappedCount ; - const U32 MAX_BUFFER_COUNT = 4096; - LLVertexBuffer* locked_buffer[MAX_BUFFER_COUNT]; - - U32 buffer_count = 0; + const U32 MAX_BUFFER_COUNT = 4096; + LLVertexBuffer* locked_buffer[MAX_BUFFER_COUNT]; - for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(), drawable_end = group->getDataEnd(); drawable_iter != drawable_end; ++drawable_iter) - { - LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); + U32 buffer_count = 0; - if (drawablep && !drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) && !drawablep->isState(LLDrawable::RIGGED) ) + for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(), drawable_end = group->getDataEnd(); drawable_iter != drawable_end; ++drawable_iter) { - LLVOVolume* vobj = drawablep->getVOVolume(); + LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); + + if (drawablep && !drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL)) + { + LLVOVolume* vobj = drawablep->getVOVolume(); + + if (!vobj) continue; #ifdef SHOW_DEBUG - static const bool enable_log = debugLoggingEnabled("AnimatedObjectsLinkset"); - if (enable_log) - { - if (vobj && vobj->isAnimatedObject() && vobj->isRiggedMesh()) - { - std::string vobj_name = llformat("Vol%p", vobj); - F32 est_tris = vobj->getEstTrianglesMax(); - LL_DEBUGS("AnimatedObjectsLinkset") << vobj_name << " rebuildMesh, tris " << est_tris << LL_ENDL; - } - } + static const bool enable_log = debugLoggingEnabled("AnimatedObjectsLinkset"); + if (enable_log) + { + if (vobj->isAnimatedObject() && vobj->isRiggedMesh()) + { + std::string vobj_name = llformat("Vol%p", vobj); + F32 est_tris = vobj->getEstTrianglesMax(); + LL_DEBUGS("AnimatedObjectsLinkset") << vobj_name << " rebuildMesh, tris " << est_tris << LL_ENDL; + } + } #endif + if (vobj->isNoLOD()) continue; - if (!vobj || vobj->isNoLOD()) - { - continue; - } - - LLVolume* volume = vobj->getVolume(); + vobj->preRebuild(); - if (!volume) - { - continue; - } - - vobj->preRebuild(); - - if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) - { - vobj->updateRelativeXform(true); - } + if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) + { + vobj->updateRelativeXform(true); + } - for (S32 i = 0, i_end = drawablep->getNumFaces(); i < i_end; ++i) - { - LLFace* face = drawablep->getFace(i); - if (face) + LLVolume* volume = vobj->getVolume(); + if (!volume) continue; + for (S32 i = 0, i_end = drawablep->getNumFaces(); i < i_end; ++i) { - LLVertexBuffer* buff = face->getVertexBuffer(); - if (buff) + LLFace* face = drawablep->getFace(i); + if (face) { - llassert(!face->isState(LLFace::RIGGED)); - - if (!face->getGeometryVolume(*volume, face->getTEOffset(), - vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), face->getGeomIndex())) - { //something's gone wrong with the vertex buffer accounting, rebuild this group - group->dirtyGeom(); - gPipeline.markRebuild(group, TRUE); - } + LLVertexBuffer* buff = face->getVertexBuffer(); + if (buff) + { + if (!face->getGeometryVolume(*volume, face->getTEOffset(), + vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), face->getGeomIndex())) + { //something's gone wrong with the vertex buffer accounting, rebuild this group + group->dirtyGeom(); + gPipeline.markRebuild(group, TRUE); + } - if (buff->isLocked() && buffer_count < MAX_BUFFER_COUNT) - { - locked_buffer[buffer_count++] = buff; + if (buff->isLocked() && buffer_count < MAX_BUFFER_COUNT) + { + locked_buffer[buffer_count++] = buff; + } } } } + + if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) + { + vobj->updateRelativeXform(); + } + + drawablep->clearState(LLDrawable::REBUILD_ALL); } + } - if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) + { + LL_PROFILE_ZONE_NAMED("rebuildMesh - flush"); + for (LLVertexBuffer** iter = locked_buffer, ** end_iter = locked_buffer+buffer_count; iter != end_iter; ++iter) { - vobj->updateRelativeXform(); + (*iter)->flush(); } - - drawablep->clearState(LLDrawable::REBUILD_ALL); + // don't forget alpha + if(group != NULL && + !group->mVertexBuffer.isNull() && + group->mVertexBuffer->isLocked()) + { + group->mVertexBuffer->flush(); + } } - } - - { - LL_RECORD_BLOCK_TIME(FTM_REBUILD_MESH_FLUSH); - for (LLVertexBuffer** iter = locked_buffer, ** end_iter = locked_buffer+buffer_count; iter != end_iter; ++iter) - { - (*iter)->flush(); - } - - // don't forget alpha - if(group != NULL && - !group->mVertexBuffer.isNull() && - group->mVertexBuffer->isLocked()) - { - group->mVertexBuffer->flush(); - } - } - //if not all buffers are unmapped - if(num_mapped_vertex_buffer != LLVertexBuffer::sMappedCount) - { - LL_WARNS() << "Not all mapped vertex buffers are unmapped!" << LL_ENDL ; - for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(), drawable_end = group->getDataEnd(); drawable_iter != drawable_end; ++drawable_iter) + //if not all buffers are unmapped + if(num_mapped_vertex_buffer != LLVertexBuffer::sMappedCount) { - LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); - if(!drawablep) - { - continue; - } - for (S32 i = 0, i_end = drawablep->getNumFaces(); i < i_end; ++i) + LL_WARNS() << "Not all mapped vertex buffers are unmapped!" << LL_ENDL ; + for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(), drawable_end = group->getDataEnd(); drawable_iter != drawable_end; ++drawable_iter) { - LLFace* face = drawablep->getFace(i); - if (face) + LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); + if(!drawablep) + { + continue; + } + for (S32 i = 0, i_end = drawablep->getNumFaces(); i < i_end; ++i) { - LLVertexBuffer* buff = face->getVertexBuffer(); - if (buff && buff->isLocked()) + LLFace* face = drawablep->getFace(i); + if (face) { - buff->flush(); + LLVertexBuffer* buff = face->getVertexBuffer(); + if (buff && buff->isLocked()) + { + buff->flush(); + } } } } - } - } - - group->clearState(LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO); - } + } -// llassert(!group || !group->isState(LLSpatialGroup::NEW_DRAWINFO)); + group->clearState(LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO); + } + } } -struct CompareBatchBreakerModified +struct CompareBatchBreaker { bool operator()(const LLFace* const& lhs, const LLFace* const& rhs) { const LLTextureEntry* lte = lhs->getTextureEntry(); const LLTextureEntry* rte = rhs->getTextureEntry(); - if (lte->getBumpmap() != rte->getBumpmap()) + if (lte->getBumpmap() != rte->getBumpmap()) { return lte->getBumpmap() < rte->getBumpmap(); } @@ -6322,34 +6175,50 @@ struct CompareBatchBreakerModified { return lte->getFullbright() < rte->getFullbright(); } - else if (LLPipeline::sRenderDeferred && lte->getMaterialParams() != rte->getMaterialParams()) - { - return lte->getMaterialParams() < rte->getMaterialParams(); - } - else if (LLPipeline::sRenderDeferred && (lte->getMaterialParams() == rte->getMaterialParams()) && (lte->getShiny() != rte->getShiny())) + else if (LLPipeline::sRenderDeferred && lte->getMaterialID() != rte->getMaterialID()) + { + return lte->getMaterialID() < rte->getMaterialID(); + } + else if (lte->getShiny() != rte->getShiny()) { return lte->getShiny() < rte->getShiny(); } - else + else if (lhs->getTexture() != rhs->getTexture()) { return lhs->getTexture() < rhs->getTexture(); } + else + { + // all else being equal, maintain consistent draw order + return lhs->getDrawOrderIndex() < rhs->getDrawOrderIndex(); + } } }; -static LLTrace::BlockTimerStatHandle FTM_GEN_DRAW_INFO_SORT("Draw Info Face Sort"); -static LLTrace::BlockTimerStatHandle FTM_GEN_DRAW_INFO_FACE_SIZE("Face Sizing"); -static LLTrace::BlockTimerStatHandle FTM_GEN_DRAW_INFO_ALLOCATE("Allocate VB"); -static LLTrace::BlockTimerStatHandle FTM_GEN_DRAW_INFO_FIND_VB("Find VB"); -static LLTrace::BlockTimerStatHandle FTM_GEN_DRAW_INFO_RESIZE_VB("Resize VB"); - - - - +struct CompareBatchBreakerRigged +{ + bool operator()(const LLFace* const& lhs, const LLFace* const& rhs) + { + if (lhs->mAvatar != rhs->mAvatar) + { + return lhs->mAvatar < rhs->mAvatar; + } + else if (lhs->mSkinInfo->mHash != rhs->mSkinInfo->mHash) + { + return lhs->mSkinInfo->mHash < rhs->mSkinInfo->mHash; + } + else + { + // "inherit" non-rigged behavior + CompareBatchBreaker comp; + return comp(lhs, rhs); + } + } +}; -U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort, BOOL batch_textures, BOOL no_materials) +U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort, BOOL batch_textures, BOOL rigged) { - LL_RECORD_BLOCK_TIME(FTM_REBUILD_VOLUME_GEN_DRAW_INFO); + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; U32 geometryBytes = 0; U32 buffer_usage = group->mBufferUsage; @@ -6371,12 +6240,21 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace max_vertices = llmin(max_vertices, (U32) 65535); { - LL_RECORD_BLOCK_TIME(FTM_GEN_DRAW_INFO_SORT); - if (!distance_sort) - { - //sort faces by things that break batches - std::sort(faces, faces+face_count, CompareBatchBreakerModified()); - } + LL_PROFILE_ZONE_NAMED("genDrawInfo - sort"); + + if (rigged) + { + if (!distance_sort) // <--- alpha "sort" rigged faces by maintaining original draw order + { + //sort faces by things that break batches, including avatar and mesh id + std::sort(faces, faces + face_count, CompareBatchBreakerRigged()); + } + } + else if (!distance_sort) + { + //sort faces by things that break batches, not including avatar and mesh id + std::sort(faces, faces + face_count, CompareBatchBreaker()); + } else { //sort faces by distance @@ -6393,11 +6271,6 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace LLViewerTexture* last_tex = NULL; S32 buffer_index = 0; - if (distance_sort) - { - buffer_index = -1; - } - S32 texture_index_channels = 1; if (gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 30) @@ -6409,6 +6282,11 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace { texture_index_channels = gDeferredAlphaProgram.mFeatures.mIndexedTextureChannels; } + + if (distance_sort) + { + buffer_index = -1; + } static LLCachedControl<U32> max_texture_index(gSavedSettings, "RenderMaxTextureIndex", 16); texture_index_channels = llmin(texture_index_channels, (S32) max_texture_index); @@ -6423,7 +6301,9 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace //pull off next face LLFace* facep = *face_iter; LLViewerTexture* tex = facep->getTexture(); - LLMaterialPtr mat = facep->getTextureEntry()->getMaterialParams(); + const LLTextureEntry* te = facep->getTextureEntry(); + LLMaterialPtr mat = te->getMaterialParams(); + LLMaterialID matId = te->getMaterialID(); if (distance_sort) { @@ -6457,7 +6337,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace U32 texture_count = 0; { - LL_RECORD_BLOCK_TIME(FTM_GEN_DRAW_INFO_FACE_SIZE); + LL_PROFILE_ZONE_NAMED("genDrawInfo - face size"); if (batch_textures) { U8 cur_tex = 0; @@ -6546,11 +6426,14 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace while (i != end_faces && (LLPipeline::sTextureBindTest || (distance_sort || - ((*i)->getTexture() == tex && - ((*i)->getTextureEntry()->getMaterialParams() == mat))))) + ((*i)->getTexture() == tex)))) { facep = *i; - + const LLTextureEntry* nextTe = facep->getTextureEntry(); + if (nextTe->getMaterialID() != matId) + { + break; + } //face has no texture index facep->mDrawInfo = NULL; @@ -6580,7 +6463,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace LLPointer<LLVertexBuffer> buffer; { - LL_RECORD_BLOCK_TIME(FTM_GEN_DRAW_INFO_ALLOCATE); + LL_PROFILE_ZONE_NAMED("genDrawInfo - allocate"); buffer = createVertexBuffer(mask, buffer_usage); if(!buffer->allocateBuffer(geom_count, index_count, TRUE)) { @@ -6640,8 +6523,6 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace U32 te_idx = facep->getTEOffset(); - llassert(!facep->isState(LLFace::RIGGED)); - if (!facep->getGeometryVolume(*volume, te_idx, vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), index_offset,true)) { @@ -6745,10 +6626,6 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace } } } - else if (no_materials) - { - registerFace(group, facep, LLRenderPass::PASS_SIMPLE); - } else if (transparent) { registerFace(group, facep, LLRenderPass::PASS_ALPHA); @@ -6813,7 +6690,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace { registerFace(group, facep, LLRenderPass::PASS_ALPHA); } - else if (gPipeline.canUseVertexShaders() + else if (gPipeline.shadersLoaded() && LLPipeline::sRenderBump && te->getShiny() && can_be_shiny) @@ -6848,7 +6725,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace registerFace(group, facep, LLRenderPass::PASS_ALPHA); } } - else if (gPipeline.canUseVertexShaders() + else if (gPipeline.shadersLoaded() && LLPipeline::sRenderBump && te->getShiny() && can_be_shiny) @@ -6929,7 +6806,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace } - if (!gPipeline.canUseVertexShaders() && + if (!gPipeline.shadersLoaded() && !is_alpha && te->getShiny() && LLPipeline::sRenderBump) @@ -6973,16 +6850,41 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace return geometryBytes; } +void LLVolumeGeometryManager::addGeometryCount(LLSpatialGroup* group, U32& vertex_count, U32& index_count) +{ + //initialize to default usage for this partition + U32 usage = group->getSpatialPartition()->mBufferUsage; + + //for each drawable + for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) + { + LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); + + if (!drawablep || drawablep->isDead()) + { + continue; + } + + if (drawablep->isAnimating()) + { //fall back to stream draw for animating verts + usage = GL_STREAM_DRAW; + } + } + + group->mBufferUsage = usage; +} + void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32 &index_count) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; + //initialize to default usage for this partition U32 usage = group->getSpatialPartition()->mBufferUsage; - //clear off any old faces - mFaceList.clear(); + //clear off any old faces + mFaceList.clear(); //for each drawable - for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(), drawable_end = group->getDataEnd(); drawable_iter != drawable_end; ++drawable_iter) { LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 9a31b0fd9895f828df1f39bbbebda916a61ff5e9..fff8538e644cb30df21f3e4dfb6b9ac38858f395 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -67,7 +67,10 @@ class LLRiggedVolume final : public LLVolume { } - void update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* src_volume, LLVOVolume* src_object); + using FaceIndex = S32; + static const FaceIndex UPDATE_ALL_FACES = -1; + static const FaceIndex DO_NOT_UPDATE_FACES = -2; + void update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* src_volume, FaceIndex face_index = UPDATE_ALL_FACES, bool rebuild_face_octrees = true); std::string mExtraDebugText; }; @@ -238,7 +241,7 @@ class LLVOVolume final : public LLViewerObject void updateFaceFlags(); void regenFaces(); - BOOL genBBoxes(BOOL force_global); + BOOL genBBoxes(BOOL force_global, BOOL should_update_octree_bounds = TRUE); void preRebuild(); virtual void updateSpatialExtents(LLVector4a& min, LLVector4a& max); virtual F32 getBinRadius(); @@ -301,7 +304,9 @@ class LLVOVolume final : public LLViewerObject BOOL setIsFlexible(BOOL is_flexible); const LLMeshSkinInfo* getSkinInfo() const; - absl::optional<std::pair<LLMatrix4a*, F32*>> getCachedSkinRenderMatrix(U32& joint_count, LLVOAvatar* avatar, const LLMeshSkinInfo* skin = nullptr); + + //convenience accessor for mesh ID (which is stored in sculpt id for legacy reasons) + const LLUUID& getMeshID() const { return getVolume()->getParams().getSculptID(); } // Extended Mesh Properties U32 getExtendedMeshFlags() const; @@ -368,8 +373,9 @@ class LLVOVolume final : public LLViewerObject S32 getMDCImplCount() { return mMDCImplCount; } - //rigged volume update (for raycasting) - void updateRiggedVolume(bool force_update = false); + // Rigged volume update (for raycasting) + // By default, this updates the bounding boxes of all the faces and builds an octree for precise per-triangle raycasting + void updateRiggedVolume(bool force_treat_as_rigged, LLRiggedVolume::FaceIndex face_index = LLRiggedVolume::UPDATE_ALL_FACES, bool rebuild_face_octrees = true); LLRiggedVolume* getRiggedVolume(); //returns true if volume should be treated as a rigged volume @@ -392,13 +398,14 @@ class LLVOVolume final : public LLViewerObject static S32 mRenderComplexity_last; static S32 mRenderComplexity_current; + void onDrawableUpdateFromServer(); void requestMediaDataUpdate(bool isNew); void cleanUpMediaImpls(); void addMediaImpl(LLViewerMediaImpl* media_impl, S32 texture_index) ; void removeMediaImpl(S32 texture_index) ; private: - bool lodOrSculptChanged(LLDrawable *drawable, BOOL &compiled); + bool lodOrSculptChanged(LLDrawable *drawable, BOOL &compiled, BOOL &shouldUpdateOctreeBounds); public: @@ -419,6 +426,7 @@ class LLVOVolume final : public LLViewerObject S32 mLOD; BOOL mLODChanged; BOOL mSculptChanged; + BOOL mColorChanged; F32 mSpotLightPriority; LL_ALIGN_16(LLMatrix4a mRelativeXform); LL_ALIGN_16(LLMatrix4a mRelativeXformInvTrans); @@ -429,6 +437,7 @@ class LLVOVolume final : public LLViewerObject LLPointer<LLViewerFetchedTexture> mLightTexture; media_list_t mMediaImplList; S32 mLastFetchedMediaVersion; // as fetched from the server, starts as -1 + U32 mServerDrawableUpdateCount; S32 mIndexInTex[LLRender::NUM_VOLUME_TEXTURE_CHANNELS]; S32 mMDCImplCount; diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp index 509e532cb407b7daa26792559e911f7cc602d307..ba1e55d09f1c65dd42283f680715fe41bf148c20 100644 --- a/indra/newview/llvowater.cpp +++ b/indra/newview/llvowater.cpp @@ -108,17 +108,15 @@ LLDrawable *LLVOWater::createDrawable(LLPipeline *pipeline) } else { - mDrawable->setNumFaces(1, pool, LLWorld::getInstanceFast()->getDefaultWaterTexture()); + mDrawable->setNumFaces(1, pool, LLWorld::getInstance()->getDefaultWaterTexture()); } return mDrawable; } -static LLTrace::BlockTimerStatHandle FTM_UPDATE_WATER("Update Water"); - BOOL LLVOWater::updateGeometry(LLDrawable *drawable) { - LL_RECORD_BLOCK_TIME(FTM_UPDATE_WATER); + LL_PROFILE_ZONE_SCOPED; LLFace *face; if (drawable->getNumFaces() < 1) @@ -145,7 +143,7 @@ BOOL LLVOWater::updateGeometry(LLDrawable *drawable) static const unsigned int vertices_per_quad = 4; static const unsigned int indices_per_quad = 6; - const S32 size = LLPipeline::sRenderTransparentWater && LLGLSLShader::sNoFixedFunction ? 16 : 1; + const S32 size = LLPipeline::sRenderTransparentWater ? 16 : 1; const S32 num_quads = size * size; face->setSize(vertices_per_quad * num_quads, diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp index beb8acc231d475e955a7c4c0dc34ab88d88ae321..164907b7f897af8970d24aee9770f3f044276001 100644 --- a/indra/newview/llvowlsky.cpp +++ b/indra/newview/llvowlsky.cpp @@ -99,13 +99,14 @@ LLDrawable * LLVOWLSky::createDrawable(LLPipeline * pipeline) return mDrawable; } -inline F32 LLVOWLSky::calcPhi(U32 i, const U32 num_stacks) +// a tiny helper function for controlling the sky dome tesselation. +inline F32 calcPhi(const U32 &i, const F32 &reciprocal_num_stacks) { // Calc: PI/8 * 1-((1-t^4)*(1-t^4)) { 0<t<1 } // Demos: \pi/8*\left(1-((1-x^{4})*(1-x^{4}))\right)\ \left\{0<x\le1\right\} // i should range from [0..SKY_STACKS] so t will range from [0.f .. 1.f] - F32 t = float(i) / float(num_stacks); + F32 t = float(i) * reciprocal_num_stacks; //SL-16127: remove: / float(getNumStacks()); // ^4 the parameter of the tesselation to bias things toward 0 (the dome's apex) t *= t; @@ -143,11 +144,9 @@ void LLVOWLSky::restoreGL() gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE); } -static LLTrace::BlockTimerStatHandle FTM_GEO_SKY("Windlight Sky Geometry"); - BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable) { - LL_RECORD_BLOCK_TIME(FTM_GEO_SKY); + LL_PROFILE_ZONE_SCOPED; LLStrider<LLVector3> vertices; LLStrider<LLVector2> texCoords; LLStrider<U16> indices; @@ -191,6 +190,8 @@ BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable) } { + const F32 dome_radius = LLEnvironment::instance().getCurrentSky()->getDomeRadius(); + static LLCachedControl<S32> max_vbo_size(gSavedSettings, "RenderMaxVBOSize", 512); const U32 max_buffer_bytes = max_vbo_size*1024; const U32 data_mask = LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK; @@ -209,7 +210,12 @@ BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable) mStripsVerts.resize(strips_segments, NULL); - const F32 dome_radius = LLEnvironment::getInstanceFast()->getCurrentSky()->getDomeRadius(); +#if RELEASE_SHOW_DEBUG + LL_INFOS() << "WL Skydome strips in " << strips_segments << " batches." << LL_ENDL; + + LLTimer timer; + timer.start(); +#endif for (U32 i = 0; i < strips_segments ;++i) { @@ -234,29 +240,42 @@ BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable) const U32 num_indices_this_seg = 1+num_stacks_this_seg*(2+2*verts_per_stack); llassert(num_indices_this_seg * sizeof(U16) <= max_buffer_bytes); - if (!segment->allocateBuffer(num_verts_this_seg, num_indices_this_seg, TRUE)) + bool allocated = segment->allocateBuffer(num_verts_this_seg, num_indices_this_seg, TRUE); +#if RELEASE_SHOW_WARNS + if( !allocated ) { LL_WARNS() << "Failed to allocate Vertex Buffer on update to " << num_verts_this_seg << " vertices and " << num_indices_this_seg << " indices" << LL_ENDL; } +#else + (void) allocated; +#endif // lock the buffer BOOL success = segment->getVertexStrider(vertices) && segment->getTexCoord0Strider(texCoords) && segment->getIndexStrider(indices); - if(!success) +#if RELEASE_SHOW_DEBUG + if(!success) { LL_ERRS() << "Failed updating WindLight sky geometry." << LL_ENDL; } +#else + (void) success; +#endif // fill it - buildStripsBuffer(begin_stack, end_stack, vertices, texCoords, indices, verts_per_stack, total_stacks, dome_radius); + buildStripsBuffer(begin_stack, end_stack, vertices, texCoords, indices, dome_radius, verts_per_stack, total_stacks); // and unlock the buffer segment->flush(); } + +#if RELEASE_SHOW_DEBUG + LL_INFOS() << "completed in " << llformat("%.2f", timer.getElapsedTimeF32().value()) << "seconds" << LL_ENDL; +#endif } updateStarColors(); @@ -319,7 +338,7 @@ void LLVOWLSky::drawDome(void) void LLVOWLSky::initStars() { - const F32 DISTANCE_TO_STARS = LLEnvironment::instanceFast().getCurrentSky()->getDomeRadius(); + const F32 DISTANCE_TO_STARS = LLEnvironment::instance().getCurrentSky()->getDomeRadius(); // Initialize star map mStarVertices.resize(getStarsNumVerts()); @@ -357,15 +376,16 @@ void LLVOWLSky::initStars() void LLVOWLSky::buildStripsBuffer(U32 begin_stack, U32 end_stack, - LLStrider<LLVector3> & vertices, - LLStrider<LLVector2> & texCoords, - LLStrider<U16> & indices, - const U32 num_slices, - const U32 num_stacks, - const F32 dome_radius) + LLStrider<LLVector3> & vertices, + LLStrider<LLVector2> & texCoords, + LLStrider<U16> & indices, + const F32 dome_radius, + const U32& num_slices, + const U32& num_stacks) { U32 i, j; F32 phi0, theta, x0, y0, z0; + const F32 reciprocal_num_stacks = 1.f / num_stacks; llassert(end_stack <= num_stacks); @@ -376,7 +396,7 @@ void LLVOWLSky::buildStripsBuffer(U32 begin_stack, for(i = begin_stack + 1; i <= end_stack+1; ++i) #endif { - phi0 = calcPhi(i, num_stacks); + phi0 = calcPhi(i, reciprocal_num_stacks); for(j = 0; j < num_slices; ++j) { @@ -393,11 +413,11 @@ void LLVOWLSky::buildStripsBuffer(U32 begin_stack, #else if (i == num_stacks-2) { - *vertices++ = LLVector3(x0* dome_radius, y0*dome_radius-1024.f*2.f, z0* dome_radius); + *vertices++ = LLVector3(x0*dome_radius, y0*dome_radius-1024.f*2.f, z0*dome_radius); } else if (i == num_stacks-1) { - *vertices++ = LLVector3(0, y0* dome_radius -1024.f*2.f, 0); + *vertices++ = LLVector3(0, y0*dome_radius-1024.f*2.f, 0); } else { @@ -415,6 +435,7 @@ void LLVOWLSky::buildStripsBuffer(U32 begin_stack, //build triangle strip... *indices++ = 0 ; + S32 k = 0 ; for(i = 1; i <= end_stack - begin_stack; ++i) { diff --git a/indra/newview/llvowlsky.h b/indra/newview/llvowlsky.h index 47f4ece338791e9911ff54c661f22a7578b7d656..d56d61f9909161a228425c7a531fd98511cba0b3 100644 --- a/indra/newview/llvowlsky.h +++ b/indra/newview/llvowlsky.h @@ -55,8 +55,6 @@ class LLVOWLSky final : public LLStaticViewerObject { void restoreGL(); private: - // a tiny helper function for controlling the sky dome tesselation. - static F32 calcPhi(U32 i, const U32 num_stacks); // helper function for initializing the stars. void initStars(); @@ -66,12 +64,12 @@ class LLVOWLSky final : public LLStaticViewerObject { // begin_stack is the first stack to be included, end_stack is the first // stack not to be included. static void buildStripsBuffer(U32 begin_stack, U32 end_stack, - LLStrider<LLVector3> & vertices, - LLStrider<LLVector2> & texCoords, - LLStrider<U16> & indices, - const U32 num_slices, - const U32 num_stacks, - const F32 radius); + LLStrider<LLVector3> & vertices, + LLStrider<LLVector2> & texCoords, + LLStrider<U16> & indices, + const F32 RADIUS, + const U32& num_slices, + const U32& num_stacks); // helper function for updating the stars colors. void updateStarColors(); diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp index 972cbe844b00b43459dc6472a1ce71360770f09a..e2a7c3b13f6e0fdaacacbad3c155e7e9bf720186 100644 --- a/indra/newview/llwearableitemslist.cpp +++ b/indra/newview/llwearableitemslist.cpp @@ -824,7 +824,7 @@ void LLWearableItemsList::ContextMenu::show(LLView* spawning_view, LLWearableTyp setMenuItemVisible(menup, "wearable_attach_to", false); setMenuItemVisible(menup, "wearable_attach_to_hud", false); - std::string new_label = LLTrans::getString("create_new_" + LLWearableType::getInstanceFast()->getTypeName(w_type)); + std::string new_label = LLTrans::getString("create_new_" + LLWearableType::getInstance()->getTypeName(w_type)); LLMenuItemGL* menu_item = menup->getChild<LLMenuItemGL>("create_new"); menu_item->setLabel(new_label); @@ -1049,7 +1049,7 @@ void LLWearableItemsList::ContextMenu::updateItemsLabels(LLContextMenu* menu) if (!item || !item->isWearableType()) return; LLWearableType::EType w_type = item->getWearableType(); - std::string new_label = LLTrans::getString("create_new_" + LLWearableType::getInstanceFast()->getTypeName(w_type)); + std::string new_label = LLTrans::getString("create_new_" + LLWearableType::getInstance()->getTypeName(w_type)); LLMenuItemGL* menu_item = menu->getChild<LLMenuItemGL>("create_new"); menu_item->setLabel(new_label); diff --git a/indra/newview/llwearablelist.cpp b/indra/newview/llwearablelist.cpp index ab0f2da882c39012177fcee1f9cfc63bf542165a..7a4971dd9d8d080f781aa8b20f5fb5d0046b0061 100644 --- a/indra/newview/llwearablelist.cpp +++ b/indra/newview/llwearablelist.cpp @@ -268,7 +268,7 @@ LLViewerWearable* LLWearableList::createNewWearable( LLWearableType::EType type, wearable->setType( type, avatarp ); // LLWearableType has pre-translated getTypeLabel(), but it returns 'name', not 'New Name'. - std::string name = LLTrans::getString( LLWearableType::getInstanceFast()->getTypeDefaultNewName(wearable->getType()) ); + std::string name = LLTrans::getString( LLWearableType::getInstance()->getTypeDefaultNewName(wearable->getType()) ); wearable->setName( name ); LLPermissions perm; diff --git a/indra/newview/llwebprofile.cpp b/indra/newview/llwebprofile.cpp index 55ff7295ff4e41d270d069063713c301b08c0cfc..8d51b0d3fcfc3959e1713df9488ce595e94860de 100644 --- a/indra/newview/llwebprofile.cpp +++ b/indra/newview/llwebprofile.cpp @@ -84,7 +84,7 @@ void LLWebProfile::setAuthCookie(const std::string& cookie) LLCore::HttpHeaders::ptr_t LLWebProfile::buildDefaultHeaders() { LLCore::HttpHeaders::ptr_t httpHeaders(std::make_shared<LLCore::HttpHeaders>()); - LLSD headers = LLViewerMedia::getInstanceFast()->getHeaders(); + LLSD headers = LLViewerMedia::getInstance()->getHeaders(); for (LLSD::map_iterator it = headers.beginMap(); it != headers.endMap(); ++it) { diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index 7c0c2db39ff3e52c7aa3622863dec92492985bc7..af24e410fd922750acd5f30bf4881b3a439d5d47 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -118,7 +118,7 @@ LLWorld::LLWorld() : } -void LLWorld::destroyClass() +void LLWorld::resetClass() { mHoleWaterObjects.clear(); gObjectList.destroy(); @@ -654,7 +654,7 @@ LLVector3 LLWorld::resolveLandNormalGlobal(const LLVector3d &pos_global) void LLWorld::updateVisibilities() { - auto& viewerCamera = LLViewerCamera::instanceFast(); + auto& viewerCamera = LLViewerCamera::instance(); F32 cur_far_clip = viewerCamera.getFar(); @@ -720,7 +720,7 @@ void LLWorld::updateRegions(F32 max_update_time) LLTimer update_timer; mNumOfActiveCachedObjects = 0; - if(LLViewerCamera::getInstanceFast()->isChanged()) + if(LLViewerCamera::getInstance()->isChanged()) { LLViewerRegion::sLastCameraUpdated = LLViewerOctreeEntryData::getCurrentFrame() + 1; } @@ -819,20 +819,19 @@ void LLWorld::refreshLimits() void LLWorld::updateParticles() { - LLViewerPartSim::getInstanceFast()->updateSimulation(); + LLViewerPartSim::getInstance()->updateSimulation(); } void LLWorld::renderPropertyLines() { S32 region_count = 0; - S32 vertex_count = 0; for (region_list_t::iterator iter = mVisibleRegionList.begin(); iter != mVisibleRegionList.end(); ++iter) { LLViewerRegion* regionp = *iter; region_count++; - vertex_count += regionp->renderPropertyLines(); + regionp->renderPropertyLines(); } } @@ -840,13 +839,11 @@ void LLWorld::renderPropertyLines() void LLWorld::updateNetStats() { F64Bits bits; - U32 packets = 0; for (LLViewerRegion* regionp : mActiveRegionList) { regionp->updateNetStats(); bits += regionp->mBitsReceived; - packets += llfloor( regionp->mPacketsReceived ); regionp->mBitsReceived = (F32Bits)0.f; regionp->mPacketsReceived = 0.f; } @@ -899,7 +896,7 @@ void LLWorld::printPacketsLost() void LLWorld::processCoarseUpdate(LLMessageSystem* msg, void** user_data) { - LLViewerRegion* region = LLWorld::getInstanceFast()->getRegion(msg->getSender()); + LLViewerRegion* region = LLWorld::getInstance()->getRegion(msg->getSender()); if( region ) { region->updateCoarseLocations(msg); @@ -942,6 +939,7 @@ void LLWorld::waterHeightRegionInfo(std::string const& sim_name, F32 water_heigh void LLWorld::precullWaterObjects(LLCamera& camera, LLCullResult* cull, bool include_void_water) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; if (!gAgent.getRegion()) { return; @@ -1014,7 +1012,7 @@ void LLWorld::updateWaterObjects() S32 const rwidth = (S32)regionp->getWidth(); // We only want to fill in water for stuff that's near us, say, within 256 or 512m - S32 range = LLViewerCamera::getInstanceFast()->getFar() > 256.f ? 512 : 256; + S32 range = LLViewerCamera::getInstance()->getFar() > 256.f ? 512 : 256; from_region_handle(regionp->getHandle(), ®ion_x, ®ion_y); @@ -1132,12 +1130,13 @@ void LLWorld::updateWaterObjects() void LLWorld::shiftRegions(const LLVector3& offset) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; for (LLViewerRegion* region : getRegionList()) { region->updateRenderMatrix(); } - LLViewerPartSim::getInstanceFast()->shift(offset); + LLViewerPartSim::getInstance()->shift(offset); } LLViewerTexture* LLWorld::getDefaultWaterTexture() @@ -1195,11 +1194,9 @@ void LLWorld::disconnectRegions() } } -static LLTrace::BlockTimerStatHandle FTM_ENABLE_SIMULATOR("Enable Sim"); - void process_enable_simulator(LLMessageSystem *msg, void **user_data) { - LL_RECORD_BLOCK_TIME(FTM_ENABLE_SIMULATOR); + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; // enable the appropriate circuit for this simulator and // add its values into the gSimulator structure U64 handle; @@ -1280,7 +1277,7 @@ class LLEstablishAgentCommunication final : public LLHTTPNode return; } - LLViewerRegion* regionp = LLWorld::getInstanceFast()->getRegion(sim); + LLViewerRegion* regionp = LLWorld::getInstance()->getRegion(sim); if (!regionp) { LL_WARNS() << "Got EstablishAgentCommunication for unknown region " @@ -1295,17 +1292,16 @@ class LLEstablishAgentCommunication final : public LLHTTPNode } }; -static LLTrace::BlockTimerStatHandle FTM_DISABLE_REGION("Disable Region"); // disable the circuit to this simulator // Called in response to "DisableSimulator" message. void process_disable_simulator(LLMessageSystem *mesgsys, void **user_data) { - LL_RECORD_BLOCK_TIME(FTM_DISABLE_REGION); + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; LLHost host = mesgsys->getSender(); //LL_INFOS() << "Disabling simulator with message from " << host << LL_ENDL; - LLWorld::getInstanceFast()->removeRegion(host); + LLWorld::getInstance()->removeRegion(host); mesgsys->disableCircuit(host); } @@ -1314,7 +1310,7 @@ void process_disable_simulator(LLMessageSystem *mesgsys, void **user_data) void process_region_handshake(LLMessageSystem* msg, void** user_data) { LLHost host = msg->getSender(); - LLViewerRegion* regionp = LLWorld::getInstanceFast()->getRegion(host); + LLViewerRegion* regionp = LLWorld::getInstance()->getRegion(host); if (!regionp) { LL_WARNS() << "Got region handshake for unknown region " @@ -1348,7 +1344,7 @@ void send_agent_pause() gAgentPauseSerialNum++; gMessageSystem->addU32Fast(_PREHASH_SerialNum, gAgentPauseSerialNum); - for (LLViewerRegion* regionp : LLWorld::getInstanceFast()->getRegionList()) + for (LLViewerRegion* regionp : LLWorld::getInstance()->getRegionList()) { gMessageSystem->sendReliable(regionp->getHost()); } @@ -1389,6 +1385,7 @@ bool LLWorld::isCapURLMapped(const std::string &cap_url) void send_agent_resume() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK // Note: used to check for LLWorld initialization before it became a singleton. // Rather than just remove this check I'm changing it to assure that the message // system has been initialized. -MG @@ -1406,7 +1403,7 @@ void send_agent_resume() gMessageSystem->addU32Fast(_PREHASH_SerialNum, gAgentPauseSerialNum); - for (LLViewerRegion* regionp : LLWorld::getInstanceFast()->getRegionList()) + for (LLViewerRegion* regionp : LLWorld::getInstance()->getRegionList()) { gMessageSystem->sendReliable(regionp->getHost()); } diff --git a/indra/newview/llworld.h b/indra/newview/llworld.h index 7eef611e3cf404da067024e72783bfba0c229f2e..74cf88ea7915c89554b8c19158e0b8fd5f4b290f 100644 --- a/indra/newview/llworld.h +++ b/indra/newview/llworld.h @@ -72,11 +72,14 @@ class CapUrlMatches // as simulators are connected to, viewer_regions are popped off the stack and connected as required // as simulators are removed, they are pushed back onto the stack -class LLWorld final : public LLSingleton<LLWorld> +class LLWorld final : public LLSimpleton<LLWorld> { - LLSINGLETON(LLWorld); public: - void destroyClass(); + LLWorld(); + + // Clear any objects, regions + // Prepares class to be reused or destroyed + void resetClass(); LLViewerRegion* addRegion(const U64 ®ion_handle, const LLHost &host); // safe to call if already present, does the "right thing" if diff --git a/indra/newview/llworldmap.cpp b/indra/newview/llworldmap.cpp index 760a85df4bb421ef1dba484339ee66e746f7cf12..72a22ee598265028809485fe9297e345b15aeabf 100644 --- a/indra/newview/llworldmap.cpp +++ b/indra/newview/llworldmap.cpp @@ -159,7 +159,7 @@ void LLSimInfo::updateAgentCount(F64 time) { if ((time - mAgentsUpdateTime > AGENTS_UPDATE_TIMER) || mFirstAgentRequest) { - LLWorldMapMessage::getInstanceFast()->sendItemRequest(MAP_ITEM_AGENT_LOCATIONS, mHandle); + LLWorldMapMessage::getInstance()->sendItemRequest(MAP_ITEM_AGENT_LOCATIONS, mHandle); mAgentsUpdateTime = time; mFirstAgentRequest = false; } @@ -398,7 +398,7 @@ void LLWorldMap::reloadItems(bool force) //LL_INFOS("WorldMap") << "LLWorldMap::reloadItems()" << LL_ENDL; if (clearItems(force)) { - auto& world_map_message = LLWorldMapMessage::instanceFast(); + auto& world_map_message = LLWorldMapMessage::instance(); world_map_message.sendItemRequest(MAP_ITEM_TELEHUB); world_map_message.sendItemRequest(MAP_ITEM_PG_EVENT); world_map_message.sendItemRequest(MAP_ITEM_MATURE_EVENT); @@ -633,7 +633,7 @@ void LLWorldMap::updateRegions(S32 x0, S32 y0, S32 x1, S32 y1) mMapBlockLastUpdateOffsets.swap(new_offsets); // Load the region info those blocks - auto& world_map_message = LLWorldMapMessage::instanceFast(); + auto& world_map_message = LLWorldMapMessage::instance(); for (S32 block_x = llmax(x0, 0); block_x <= llmin(x1, MAP_BLOCK_RES-1); ++block_x) { for (S32 block_y = llmax(y0, 0); block_y <= llmin(y1, MAP_BLOCK_RES-1); ++block_y) diff --git a/indra/newview/llworldmapmessage.cpp b/indra/newview/llworldmapmessage.cpp index 9e92011815f5ac9df46c49a097913f34335a4614..94ff0c014766c530be1ef1e824e34e4a4c966617 100644 --- a/indra/newview/llworldmapmessage.cpp +++ b/indra/newview/llworldmapmessage.cpp @@ -150,6 +150,10 @@ void LLWorldMapMessage::sendMapBlockRequest(U16 min_x, U16 min_y, U16 max_x, U16 // public static void LLWorldMapMessage::processMapBlockReply(LLMessageSystem* msg, void**) { + if (gNonInteractive) + { + return; + } U32 agent_flags; msg->getU32Fast(_PREHASH_AgentData, _PREHASH_Flags, agent_flags); @@ -165,8 +169,8 @@ void LLWorldMapMessage::processMapBlockReply(LLMessageSystem* msg, void**) bool found_null_sim = false; - auto& world_map = LLWorldMap::instanceFast(); - auto& world_map_message = LLWorldMapMessage::instanceFast(); + auto& world_map = LLWorldMap::instance(); + auto& world_map_message = LLWorldMapMessage::instance(); for (S32 block=0; block<num_blocks; ++block) { @@ -258,7 +262,7 @@ void LLWorldMapMessage::processMapItemReply(LLMessageSystem* msg, void**) S32 num_blocks = msg->getNumberOfBlocksFast(_PREHASH_Data); - auto& world_map = LLWorldMap::instanceFast(); + auto& world_map = LLWorldMap::instance(); for (S32 block=0; block<num_blocks; ++block) { diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp index 90d434c1876a896bf1f0c1d0e57553a877fcb180..754193c481b1988b86a61d0a7c771b5fe7979bdf 100644 --- a/indra/newview/llworldmapview.cpp +++ b/indra/newview/llworldmapview.cpp @@ -63,9 +63,15 @@ #include "llglheaders.h" +// # Constants +static const F32 MAP_DEFAULT_SCALE = 128.f; +static const F32 MAP_ITERP_TIME_CONSTANT = 0.75f; +static const F32 MAP_ZOOM_ACCELERATION_TIME = 0.3f; +static const F32 MAP_ZOOM_MAX_INTERP = 0.5f; +static const F32 MAP_SCALE_SNAP_THRESHOLD = 0.005f; + // Basically a C++ implementation of the OCEAN_COLOR defined in mapstitcher.py // Please ensure consistency between those 2 files (TODO: would be better to get that color from an asset source...) -// # Constants // OCEAN_COLOR = "#1D475F" const F32 OCEAN_RED = (F32)(0x1D)/255.f; const F32 OCEAN_GREEN = (F32)(0x47)/255.f; @@ -98,14 +104,12 @@ LLUIImagePtr LLWorldMapView::sClassifiedsImage = NULL; LLUIImagePtr LLWorldMapView::sForSaleImage = NULL; LLUIImagePtr LLWorldMapView::sForSaleAdultImage = NULL; -F32 LLWorldMapView::sPanX = 0.f; -F32 LLWorldMapView::sPanY = 0.f; -F32 LLWorldMapView::sTargetPanX = 0.f; -F32 LLWorldMapView::sTargetPanY = 0.f; S32 LLWorldMapView::sTrackingArrowX = 0; S32 LLWorldMapView::sTrackingArrowY = 0; bool LLWorldMapView::sVisibleTilesLoaded = false; -F32 LLWorldMapView::sMapScale = 128.f; +F32 LLWorldMapView::sMapScaleSetting = MAP_DEFAULT_SCALE; +LLVector2 LLWorldMapView::sZoomPivot = LLVector2(0.0f, 0.0f); +LLFrameTimer LLWorldMapView::sZoomTimer = LLFrameTimer(); std::map<std::string,std::string> LLWorldMapView::sStringsMap; @@ -174,20 +178,27 @@ void LLWorldMapView::cleanupClass() sForSaleAdultImage = NULL; } -LLWorldMapView::LLWorldMapView() -: LLPanel(), - mBackgroundColor( LLColor4( OCEAN_RED, OCEAN_GREEN, OCEAN_BLUE, 1.f ) ), - mItemPicked(FALSE), - mPanning( FALSE ), - mMouseDownPanX( 0 ), - mMouseDownPanY( 0 ), - mMouseDownX( 0 ), - mMouseDownY( 0 ), - mSelectIDStart(0) +LLWorldMapView::LLWorldMapView() : + LLPanel(), + mBackgroundColor(LLColor4(OCEAN_RED, OCEAN_GREEN, OCEAN_BLUE, 1.f)), + mItemPicked(FALSE), + mPanX(0.f), + mPanY(0.f), + mTargetPanX(0.f), + mTargetPanY(0.f), + mPanning(FALSE), + mMouseDownPanX(0), + mMouseDownPanY(0), + mMouseDownX(0), + mMouseDownY(0), + mSelectIDStart(0), + mMapScale(0.f), + mTargetMapScale(0.f), + mMapIterpTime(MAP_ITERP_TIME_CONSTANT) { - //LL_INFOS("WorldMap") << "Creating the Map -> LLWorldMapView::LLWorldMapView()" << LL_ENDL; + // LL_INFOS("WorldMap") << "Creating the Map -> LLWorldMapView::LLWorldMapView()" << LL_ENDL; - clearLastClick(); + clearLastClick(); } BOOL LLWorldMapView::postBuild() @@ -218,6 +229,9 @@ BOOL LLWorldMapView::postBuild() mTextBoxNorthEast ->reshapeToFitText(); mTextBoxSouthWest->reshapeToFitText(); mTextBoxNorthWest ->reshapeToFitText(); + + sZoomTimer.stop(); + setScale(sMapScaleSetting, true); return true; } @@ -235,59 +249,111 @@ void LLWorldMapView::cleanupTextures() { } +void LLWorldMapView::zoom(F32 zoom) +{ + mTargetMapScale = scaleFromZoom(zoom); + if (!sZoomTimer.getStarted() && mMapScale != mTargetMapScale) + { + sZoomPivot = LLVector2(0, 0); + sZoomTimer.start(); + } +} -// static -void LLWorldMapView::setScale( F32 scale ) +void LLWorldMapView::zoomWithPivot(F32 zoom, S32 x, S32 y) { - if (scale != sMapScale) - { - F32 old_scale = sMapScale; + mTargetMapScale = scaleFromZoom(zoom); + sZoomPivot = LLVector2(x, y); + if (!sZoomTimer.getStarted() && mMapScale != mTargetMapScale) + { + sZoomTimer.start(); + } +} - sMapScale = scale; - if (sMapScale <= 0.f) - { - sMapScale = 0.1f; - } +F32 LLWorldMapView::getZoom() { return LLWorldMapView::zoomFromScale(mMapScale); } - F32 ratio = (scale / old_scale); - sPanX *= ratio; - sPanY *= ratio; - sTargetPanX = sPanX; - sTargetPanY = sPanY; - sVisibleTilesLoaded = false; - } -} +F32 LLWorldMapView::getScale() { return mMapScale; } +// static +void LLWorldMapView::setScaleSetting(F32 scaleSetting) { sMapScaleSetting = scaleSetting; } // static -void LLWorldMapView::translatePan( S32 delta_x, S32 delta_y ) +F32 LLWorldMapView::getScaleSetting() { return sMapScaleSetting; } + +void LLWorldMapView::setScale(F32 scale, bool snap) +{ + if (scale != mMapScale) + { + F32 old_scale = mMapScale; + + mMapScale = scale; + // Set the scale used when saving the setting + sMapScaleSetting = scale; + if (mMapScale <= 0.f) + { + mMapScale = 0.1f; + } + mMapIterpTime = MAP_ITERP_TIME_CONSTANT; + F32 ratio = (scale / old_scale); + mPanX *= ratio; + mPanY *= ratio; + mTargetPanX = mPanX; + mTargetPanY = mPanY; + sVisibleTilesLoaded = false; + + // If we are zooming relative to somewhere else rather than the center of the map, compensate for the difference in panning here + if (!sZoomPivot.isExactlyZero()) + { + LLVector2 relative_pivot; + relative_pivot.mV[VX] = sZoomPivot.mV[VX] - (getRect().getWidth() / 2.0); + relative_pivot.mV[VY] = sZoomPivot.mV[VY] - (getRect().getHeight() / 2.0); + LLVector2 zoom_pan_offset = relative_pivot - (relative_pivot * scale / old_scale); + mPanX += zoom_pan_offset.mV[VX]; + mPanY += zoom_pan_offset.mV[VY]; + mTargetPanX += zoom_pan_offset.mV[VX]; + mTargetPanY += zoom_pan_offset.mV[VY]; + } + } + + if (snap) + { + mTargetMapScale = scale; + } +} + +// static +void LLWorldMapView::translatePan(S32 delta_x, S32 delta_y) { - sPanX += delta_x; - sPanY += delta_y; - sTargetPanX = sPanX; - sTargetPanY = sPanY; - sVisibleTilesLoaded = false; + mPanX += delta_x; + mPanY += delta_y; + mTargetPanX = mPanX; + mTargetPanY = mPanY; + sVisibleTilesLoaded = false; } // static -void LLWorldMapView::setPan( S32 x, S32 y, BOOL snap ) +void LLWorldMapView::setPan(S32 x, S32 y, BOOL snap) { - sTargetPanX = (F32)x; - sTargetPanY = (F32)y; - if (snap) - { - sPanX = sTargetPanX; - sPanY = sTargetPanY; - } - sVisibleTilesLoaded = false; + mMapIterpTime = MAP_ITERP_TIME_CONSTANT; + mTargetPanX = (F32) x; + mTargetPanY = (F32) y; + if (snap) + { + mPanX = mTargetPanX; + mPanY = mTargetPanY; + } + sVisibleTilesLoaded = false; } -bool LLWorldMapView::showRegionInfo() +// static +void LLWorldMapView::setPanWithInterpTime(S32 x, S32 y, BOOL snap, F32 interp_time) { - return (LLWorldMipmap::scaleToLevel(sMapScale) <= DRAW_SIMINFO_THRESHOLD ? true : false); + setPan(x, y, snap); + mMapIterpTime = interp_time; } +bool LLWorldMapView::showRegionInfo() { return (LLWorldMipmap::scaleToLevel(mMapScale) <= DRAW_SIMINFO_THRESHOLD ? true : false); } + /////////////////////////////////////////////////////////////////////////////////// // HELPERS @@ -308,9 +374,28 @@ void LLWorldMapView::draw() mVisibleRegions.clear(); - // animate pan if necessary - sPanX = ll_lerp(sPanX, sTargetPanX, LLSmoothInterpolation::getInterpolant(0.1f)); - sPanY = ll_lerp(sPanY, sTargetPanY, LLSmoothInterpolation::getInterpolant(0.1f)); + // animate pan if necessary + mPanX = ll_lerp(mPanX, mTargetPanX, LLSmoothInterpolation::getInterpolant(mMapIterpTime)); + mPanY = ll_lerp(mPanY, mTargetPanY, LLSmoothInterpolation::getInterpolant(mMapIterpTime)); + + //RN: snaps to zoom value because interpolation caused jitter in the text rendering + if (!sZoomTimer.getStarted() && mMapScale != mTargetMapScale) + { + sZoomTimer.start(); + } + bool snap_scale = false; + F32 interp = llmin(MAP_ZOOM_MAX_INTERP, sZoomTimer.getElapsedTimeF32() / MAP_ZOOM_ACCELERATION_TIME); + F32 current_zoom_val = zoomFromScale(mMapScale); + F32 target_zoom_val = zoomFromScale(mTargetMapScale); + F32 new_zoom_val = ll_lerp(current_zoom_val, target_zoom_val, interp); + if (abs(new_zoom_val - current_zoom_val) < MAP_SCALE_SNAP_THRESHOLD) + { + sZoomTimer.stop(); + snap_scale = true; + new_zoom_val = target_zoom_val; + } + F32 map_scale = scaleFromZoom(new_zoom_val); + setScale(map_scale, snap_scale); const S32 width = getRect().getWidth(); const S32 height = getRect().getHeight(); @@ -318,7 +403,7 @@ void LLWorldMapView::draw() const F32 half_height = F32(height) / 2.0f; LLVector3d camera_global = gAgentCamera.getCameraPositionGlobal(); - S32 level = LLWorldMipmap::scaleToLevel(sMapScale); + S32 level = LLWorldMipmap::scaleToLevel(mMapScale); LLLocalClipRect clip(getLocalRect()); { @@ -329,26 +414,23 @@ void LLWorldMapView::draw() // Clear the background alpha to 0 gGL.flush(); gGL.setColorMask(false, true); - gGL.setAlphaRejectSettings(LLRender::CF_GREATER_EQUAL, 0.f); + gGL.flush(); gGL.setSceneBlendType(LLRender::BT_REPLACE); gGL.color4f(0.0f, 0.0f, 0.0f, 0.0f); gl_rect_2d(0, height, width, 0); } gGL.flush(); - - gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); gGL.setColorMask(true, true); // Draw the image tiles drawMipmap(width, height); gGL.flush(); - gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); gGL.setColorMask(true, true); // Draw per sim overlayed information (names, mature, offline...) - for (const auto& sim_info_pair : LLWorldMap::getInstanceFast()->getRegionMap()) + for (const auto& sim_info_pair : LLWorldMap::getInstance()->getRegionMap()) { U64 handle = sim_info_pair.first; LLSimInfo* info = sim_info_pair.second.get(); @@ -357,15 +439,15 @@ void LLWorldMapView::draw() // Find x and y position relative to camera's center. LLVector3d rel_region_pos = origin_global - camera_global; - F32 relative_x = (rel_region_pos.mdV[0] / REGION_WIDTH_METERS) * sMapScale; - F32 relative_y = (rel_region_pos.mdV[1] / REGION_WIDTH_METERS) * sMapScale; + F32 relative_x = (rel_region_pos.mdV[0] / REGION_WIDTH_METERS) * mMapScale; + F32 relative_y = (rel_region_pos.mdV[1] / REGION_WIDTH_METERS) * mMapScale; // Coordinates of the sim in pixels in the UI panel // When the view isn't panned, 0,0 = center of rectangle - F32 bottom = sPanY + half_height + relative_y; - F32 left = sPanX + half_width + relative_x; - F32 top = bottom+ (sMapScale * (info->getSizeY() / REGION_WIDTH_METERS)); - F32 right = left + (sMapScale * (info->getSizeX() / REGION_WIDTH_METERS)); + F32 bottom = mPanY + half_height + relative_y; + F32 left = mPanX + half_width + relative_x; + F32 top = bottom+ (mMapScale * (info->getSizeY() / REGION_WIDTH_METERS)); + F32 right = left + (mMapScale * (info->getSizeX() / REGION_WIDTH_METERS)); // Discard if region is outside the screen rectangle (not visible on screen) if ((top < 0.f) || (bottom > height) || @@ -426,8 +508,8 @@ void LLWorldMapView::draw() if (overlayimage) { // Inform the fetch mechanism of the size we need - S32 x_draw_size = ll_round(sMapScale); - S32 y_draw_size = ll_round(sMapScale); + S32 x_draw_size = ll_round(mMapScale); + S32 y_draw_size = ll_round(mMapScale); x_draw_size *= (info->getSizeX() / REGION_WIDTH_METERS); y_draw_size *= (info->getSizeY() / REGION_WIDTH_METERS); @@ -458,7 +540,7 @@ void LLWorldMapView::draw() } // Draw the region name in the lower left corner - if (sMapScale >= DRAW_TEXT_THRESHOLD) + if (mMapScale >= DRAW_TEXT_THRESHOLD) { static LLCachedControl<bool> mapShowAgentCount(gSavedSettings, "AlchemyMapShowAgentCount", true); LLFontGL* font = LLFontGL::getFont(LLFontDescriptor("SansSerif", "Small", LLFontGL::BOLD)); @@ -496,7 +578,7 @@ void LLWorldMapView::draw() LLColor4::white, LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW, S32_MAX, //max_chars - sMapScale, //max_pixels + mMapScale, //max_pixels NULL, TRUE); //use ellipses } @@ -509,13 +591,13 @@ void LLWorldMapView::draw() LLGLSUIDefault gls_ui; { gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.setAlphaRejectSettings(LLRender::CF_GREATER_EQUAL, 0.f); + gGL.flush(); gGL.blendFunc(LLRender::BF_ONE_MINUS_DEST_ALPHA, LLRender::BF_DEST_ALPHA); gGL.color4fv( mBackgroundColor.mV ); gl_rect_2d(0, height, width, 0); } - gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); + gGL.flush(); gGL.setSceneBlendType(LLRender::BT_ALPHA); // Draw item infos if we're not zoomed out too much and there's something to draw @@ -578,13 +660,13 @@ void LLWorldMapView::draw() drawTracking( pos_global, map_track_color, TRUE, LLTracker::getLabel(), LLTracker::getToolTip() ); } } - else if (LLWorldMap::getInstanceFast()->isTracking()) + else if (LLWorldMap::getInstance()->isTracking()) { - if (LLWorldMap::getInstanceFast()->isTrackingInvalidLocation()) + if (LLWorldMap::getInstance()->isTrackingInvalidLocation()) { // We know this location to be invalid, draw a blue circle LLColor4 loading_color(0.0, 0.5, 1.0, 1.0); - drawTracking( LLWorldMap::getInstanceFast()->getTrackedPositionGlobal(), loading_color, TRUE, getString("InvalidLocation"), ""); + drawTracking( LLWorldMap::getInstance()->getTrackedPositionGlobal(), loading_color, TRUE, getString("InvalidLocation"), ""); } else { @@ -592,7 +674,7 @@ void LLWorldMapView::draw() double value = fmod(current_time, 2); value = 0.5 + 0.5*cos(value * F_PI); LLColor4 loading_color(0.0, F32(value/2), F32(value), 1.0); - drawTracking( LLWorldMap::getInstanceFast()->getTrackedPositionGlobal(), loading_color, TRUE, getString("Loading"), ""); + drawTracking( LLWorldMap::getInstance()->getTrackedPositionGlobal(), loading_color, TRUE, getString("Loading"), ""); } } @@ -616,16 +698,16 @@ void LLWorldMapView::setVisible(BOOL visible) if (!visible) { // Drop the download of tiles and images priority to nil if we hide the map - LLWorldMap::getInstanceFast()->dropImagePriorities(); + LLWorldMap::getInstance()->dropImagePriorities(); } } void LLWorldMapView::drawMipmap(S32 width, S32 height) { // Compute the level of the mipmap to use for the current scale level - S32 level = LLWorldMipmap::scaleToLevel(sMapScale); + S32 level = LLWorldMipmap::scaleToLevel(mMapScale); // Set the tile boost level so that unused tiles get to 0 - LLWorldMap::getInstanceFast()->equalizeBoostLevels(); + LLWorldMap::getInstance()->equalizeBoostLevels(); // Render whatever we already have loaded if we haven't the current level // complete and use it as a background (scaled up or scaled down) @@ -690,7 +772,7 @@ bool LLWorldMapView::drawMipmapLevel(S32 width, S32 height, S32 level, bool load // Convert to the mipmap level coordinates for that point (i.e. which tile to we hit) LLWorldMipmap::globalToMipmap(pos_global[VX], pos_global[VY], level, &grid_x, &grid_y); // Get the tile. Note: NULL means that the image does not exist (so it's considered "complete" as far as fetching is concerned) - LLPointer<LLViewerFetchedTexture> simimage = LLWorldMap::getInstanceFast()->getObjectsTile(grid_x, grid_y, level, load); + LLPointer<LLViewerFetchedTexture> simimage = LLWorldMap::getInstance()->getObjectsTile(grid_x, grid_y, level, load); if (simimage) { // Checks that the image has a valid texture @@ -833,7 +915,7 @@ void LLWorldMapView::drawItems() for (handle_list_t::iterator iter = mVisibleRegions.begin(); iter != mVisibleRegions.end(); ++iter) { U64 handle = *iter; - LLSimInfo* info = LLWorldMap::getInstanceFast()->simInfoFromHandle(handle); + LLSimInfo* info = LLWorldMap::getInstance()->simInfoFromHandle(handle); if ((info == NULL) || (info->isDown())) { continue; @@ -885,7 +967,7 @@ void LLWorldMapView::drawAgents() for (handle_list_t::iterator iter = mVisibleRegions.begin(); iter != mVisibleRegions.end(); ++iter) { U64 handle = *iter; - LLSimInfo* siminfo = LLWorldMap::getInstanceFast()->simInfoFromHandle(handle); + LLSimInfo* siminfo = LLWorldMap::getInstance()->simInfoFromHandle(handle); if ((siminfo == NULL) || (siminfo->isDown())) { continue; @@ -905,10 +987,10 @@ void LLWorldMapView::drawAgents() void LLWorldMapView::drawFrustum() { - auto& viewerCamera = LLViewerCamera::instanceFast(); + auto& viewerCamera = LLViewerCamera::instance(); // Draw frustum - F32 meters_to_pixels = sMapScale/ REGION_WIDTH_METERS; + F32 meters_to_pixels = mMapScale/ REGION_WIDTH_METERS; F32 horiz_fov = viewerCamera.getView() * viewerCamera.getAspect(); F32 far_clip_meters = viewerCamera.getFar(); @@ -918,8 +1000,8 @@ void LLWorldMapView::drawFrustum() F32 half_width_pixels = half_width_meters * meters_to_pixels; // Compute the frustum coordinates. Take the UI scale into account. - F32 ctr_x = ((getLocalRect().getWidth() * 0.5f + sPanX) * LLUI::getScaleFactor().mV[VX]); - F32 ctr_y = ((getLocalRect().getHeight() * 0.5f + sPanY) * LLUI::getScaleFactor().mV[VY]); + F32 ctr_x = ((getLocalRect().getWidth() * 0.5f + mPanX) * LLUI::getScaleFactor().mV[VX]); + F32 ctr_y = ((getLocalRect().getHeight() * 0.5f + mPanY) * LLUI::getScaleFactor().mV[VY]); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); @@ -976,13 +1058,13 @@ LLVector3 LLWorldMapView::globalPosToView( const LLVector3d& global_pos ) LLVector3 pos_local; pos_local.setVec(relative_pos_global); // convert to floats from doubles - pos_local.mV[VX] *= sMapScale / REGION_WIDTH_METERS; - pos_local.mV[VY] *= sMapScale / REGION_WIDTH_METERS; + pos_local.mV[VX] *= mMapScale / REGION_WIDTH_METERS; + pos_local.mV[VY] *= mMapScale / REGION_WIDTH_METERS; // leave Z component in meters - pos_local.mV[VX] += getRect().getWidth() / 2 + sPanX; - pos_local.mV[VY] += getRect().getHeight() / 2 + sPanY; + pos_local.mV[VX] += getRect().getWidth() / 2 + mPanX; + pos_local.mV[VY] += getRect().getHeight() / 2 + mPanY; return pos_local; } @@ -1056,12 +1138,12 @@ void LLWorldMapView::drawTracking(const LLVector3d& pos_global, const LLColor4& // If you change this, then you need to change LLTracker::getTrackedPositionGlobal() as well LLVector3d LLWorldMapView::viewPosToGlobal( S32 x, S32 y ) { - x -= llfloor((getRect().getWidth() / 2 + sPanX)); - y -= llfloor((getRect().getHeight() / 2 + sPanY)); + x -= llfloor((getRect().getWidth() / 2 + mPanX)); + y -= llfloor((getRect().getHeight() / 2 + mPanY)); LLVector3 pos_local( (F32)x, (F32)y, 0.f ); - pos_local *= ( REGION_WIDTH_METERS / sMapScale ); + pos_local *= ( REGION_WIDTH_METERS / mMapScale ); LLVector3d pos_global; pos_global.setVec( pos_local ); @@ -1085,7 +1167,7 @@ BOOL LLWorldMapView::handleToolTip( S32 x, S32 y, MASK mask ) U64 handle = to_region_handle(pos_global); std::string tooltip_msg; - LLSimInfo* info = LLWorldMap::getInstanceFast()->simInfoFromHandle(handle); + LLSimInfo* info = LLWorldMap::getInstance()->simInfoFromHandle(handle); if (info) { LLViewerRegion *region = gAgent.getRegion(); @@ -1483,7 +1565,7 @@ bool LLWorldMapView::checkItemHit(S32 x, S32 y, LLItemInfo& item, LLUUID* id, bo if (y < item_y - BIG_DOT_RADIUS) return false; if (y > item_y + BIG_DOT_RADIUS) return false; - LLSimInfo* sim_info = LLWorldMap::getInstanceFast()->simInfoFromHandle(item.getRegionHandle()); + LLSimInfo* sim_info = LLWorldMap::getInstance()->simInfoFromHandle(item.getRegionHandle()); if (sim_info) { if (track) @@ -1521,9 +1603,9 @@ void LLWorldMapView::handleClick(S32 x, S32 y, MASK mask, *hit_type = 0; // hit nothing - LLWorldMap::getInstanceFast()->cancelTracking(); + LLWorldMap::getInstance()->cancelTracking(); - S32 level = LLWorldMipmap::scaleToLevel(sMapScale); + S32 level = LLWorldMipmap::scaleToLevel(mMapScale); // If the zoom level is not too far out already, test hits if (level <= DRAW_SIMINFO_THRESHOLD) { @@ -1537,7 +1619,7 @@ void LLWorldMapView::handleClick(S32 x, S32 y, MASK mask, for (handle_list_t::iterator iter = mVisibleRegions.begin(); iter != mVisibleRegions.end(); ++iter) { U64 handle = *iter; - LLSimInfo* siminfo = LLWorldMap::getInstanceFast()->simInfoFromHandle(handle); + LLSimInfo* siminfo = LLWorldMap::getInstance()->simInfoFromHandle(handle); if ((siminfo == NULL) || (siminfo->isDown())) { continue; @@ -1640,8 +1722,8 @@ BOOL LLWorldMapView::handleMouseDown( S32 x, S32 y, MASK mask ) { gFocusMgr.setMouseCapture( this ); - mMouseDownPanX = ll_round(sPanX); - mMouseDownPanY = ll_round(sPanY); + mMouseDownPanX = ll_round(mPanX); + mMouseDownPanY = ll_round(mPanY); mMouseDownX = x; mMouseDownY = y; sHandledLastClick = TRUE; @@ -1656,8 +1738,8 @@ BOOL LLWorldMapView::handleMouseUp( S32 x, S32 y, MASK mask ) { // restore mouse cursor S32 local_x, local_y; - local_x = mMouseDownX + llfloor(sPanX - mMouseDownPanX); - local_y = mMouseDownY + llfloor(sPanY - mMouseDownPanY); + local_x = mMouseDownX + llfloor(mPanX - mMouseDownPanX); + local_y = mMouseDownY + llfloor(mPanY - mMouseDownPanY); LLRect clip_rect = getRect(); clip_rect.stretch(-8); clip_rect.clipPointToRect(mMouseDownX, mMouseDownY, local_x, local_y); @@ -1685,7 +1767,7 @@ BOOL LLWorldMapView::handleMouseUp( S32 x, S32 y, MASK mask ) void LLWorldMapView::updateVisibleBlocks() { - if (LLWorldMipmap::scaleToLevel(sMapScale) > DRAW_SIMINFO_THRESHOLD) + if (LLWorldMipmap::scaleToLevel(mMapScale) > DRAW_SIMINFO_THRESHOLD) { // If we're zoomed out too much, we just don't load all those sim info: too much! return; @@ -1701,17 +1783,17 @@ void LLWorldMapView::updateVisibleBlocks() const F32 half_height = F32(height) / 2.0f; // Compute center into sim grid coordinates - S32 world_center_x = S32((-sPanX / sMapScale) + (camera_global.mdV[0] / REGION_WIDTH_METERS)); - S32 world_center_y = S32((-sPanY / sMapScale) + (camera_global.mdV[1] / REGION_WIDTH_METERS)); + S32 world_center_x = S32((-mPanX / mMapScale) + (camera_global.mdV[0] / REGION_WIDTH_METERS)); + S32 world_center_y = S32((-mPanY / mMapScale) + (camera_global.mdV[1] / REGION_WIDTH_METERS)); // Compute the boundaries into sim grid coordinates - S32 world_left = world_center_x - S32(half_width / sMapScale) - 1; - S32 world_right = world_center_x + S32(half_width / sMapScale) + 1; - S32 world_bottom = world_center_y - S32(half_height / sMapScale) - 1; - S32 world_top = world_center_y + S32(half_height / sMapScale) + 1; + S32 world_left = world_center_x - S32(half_width / mMapScale) - 1; + S32 world_right = world_center_x + S32(half_width / mMapScale) + 1; + S32 world_bottom = world_center_y - S32(half_height / mMapScale) - 1; + S32 world_top = world_center_y + S32(half_height / mMapScale) + 1; - //LL_INFOS("WorldMap") << "LLWorldMapView::updateVisibleBlocks() : sMapScale = " << sMapScale << ", left = " << world_left << ", right = " << world_right << ", bottom = " << world_bottom << ", top = " << world_top << LL_ENDL; - LLWorldMap::getInstanceFast()->updateRegions(world_left, world_bottom, world_right, world_top); + //LL_INFOS("WorldMap") << "LLWorldMapView::updateVisibleBlocks() : mMapScale = " << mMapScale << ", left = " << world_left << ", right = " << world_right << ", bottom = " << world_bottom << ", top = " << world_top << LL_ENDL; + LLWorldMap::getInstance()->updateRegions(world_left, world_bottom, world_right, world_top); } BOOL LLWorldMapView::handleHover( S32 x, S32 y, MASK mask ) @@ -1731,10 +1813,10 @@ BOOL LLWorldMapView::handleHover( S32 x, S32 y, MASK mask ) F32 delta_y = (F32)(gViewerWindow->getCurrentMouseDY()); // Set pan to value at start of drag + offset - sPanX += delta_x; - sPanY += delta_y; - sTargetPanX = sPanX; - sTargetPanY = sPanY; + mPanX += delta_x; + mPanY += delta_y; + mTargetPanX = mPanX; + mTargetPanY = mPanY; gViewerWindow->moveCursorToCenter(); } @@ -1796,7 +1878,7 @@ BOOL LLWorldMapView::handleDoubleClick( S32 x, S32 y, MASK mask ) { LLVector3d pos_global = viewPosToGlobal(x, y); std::string sim_name; - if (LLWorldMap::getInstanceFast()->simNameFromPosGlobal(pos_global, sim_name)) + if (LLWorldMap::getInstance()->simNameFromPosGlobal(pos_global, sim_name)) { LLFloaterReg::hideInstance("world_map"); LLFloaterReg::showInstance("search", LLSD().with("category", "land").with("query", sim_name)); @@ -1811,15 +1893,15 @@ BOOL LLWorldMapView::handleDoubleClick( S32 x, S32 y, MASK mask ) } default: { - if (LLWorldMap::getInstanceFast()->isTracking()) + if (LLWorldMap::getInstance()->isTracking()) { - LLWorldMap::getInstanceFast()->setTrackingDoubleClick(); + LLWorldMap::getInstance()->setTrackingDoubleClick(); } else { // Teleport if we got a valid location LLVector3d pos_global = viewPosToGlobal(x,y); - LLSimInfo* sim_info = LLWorldMap::getInstanceFast()->simInfoFromPosGlobal(pos_global); + LLSimInfo* sim_info = LLWorldMap::getInstance()->simInfoFromPosGlobal(pos_global); if (sim_info && !sim_info->isDown()) { gAgent.teleportViaLocation( pos_global ); @@ -1833,4 +1915,8 @@ BOOL LLWorldMapView::handleDoubleClick( S32 x, S32 y, MASK mask ) return FALSE; } +// static +F32 LLWorldMapView::scaleFromZoom(F32 zoom) { return exp2(zoom) * 256.0f; } +// static +F32 LLWorldMapView::zoomFromScale(F32 scale) { return log2(scale / 256.f); } diff --git a/indra/newview/llworldmapview.h b/indra/newview/llworldmapview.h index c607816192304365fe38366b67d3c9fd6fc8846d..5f9a560ad6fcc7087001615907ff33bda539dbb1 100644 --- a/indra/newview/llworldmapview.h +++ b/indra/newview/llworldmapview.h @@ -67,12 +67,22 @@ class LLWorldMapView final : public LLPanel bool checkItemHit(S32 x, S32 y, LLItemInfo& item, LLUUID* id, bool track); void handleClick(S32 x, S32 y, MASK mask, S32* hit_type, LLUUID* id); - // Scale and pan are shared across all instances! (i.e. Terrain and Objects maps are always registered) - static void setScale( F32 scale ); - static void translatePan( S32 delta_x, S32 delta_y ); - static void setPan( S32 x, S32 y, BOOL snap = TRUE ); + // Scale, aka zoom, is shared across all instances! (i.e. Terrain and Objects maps are always registered) + // Zoom is used for UI and will interpolate the map scale over multiple frames. + void zoom(F32 zoom); + void zoomWithPivot(F32 zoom, S32 x, S32 y); + F32 getZoom(); + // Scale is a linear scaling factor of in-world coordinates + F32 getScale(); + // setScaleSetting/getScaleSetting are for the default map setting on login + static void setScaleSetting(F32 scaleSetting); + static F32 getScaleSetting(); + // Pan is in pixels relative to the center of the map. + void translatePan( S32 delta_x, S32 delta_y ); + void setPan( S32 x, S32 y, BOOL snap = TRUE ); + void setPanWithInterpTime(S32 x, S32 y, BOOL snap, F32 interp_time); // Return true if the current scale level is above the threshold for accessing region info - static bool showRegionInfo(); + bool showRegionInfo(); LLVector3 globalPosToView(const LLVector3d& global_pos); LLVector3d viewPosToGlobal(S32 x,S32 y); @@ -154,14 +164,12 @@ class LLWorldMapView final : public LLPanel static LLUIImagePtr sForSaleAdultImage; static LLUIImagePtr sIFFArrowImage; - static F32 sMapScale; // scale = size of a region in pixels - BOOL mItemPicked; - static F32 sPanX; // in pixels - static F32 sPanY; // in pixels - static F32 sTargetPanX; // in pixels - static F32 sTargetPanY; // in pixels + F32 mPanX; // in pixels + F32 mPanY; // in pixels + F32 mTargetPanX; // in pixels + F32 mTargetPanY; // in pixels static S32 sTrackingArrowX; static S32 sTrackingArrowY; static bool sVisibleTilesLoaded; @@ -195,6 +203,19 @@ class LLWorldMapView final : public LLPanel private: void drawTileOutline(S32 level, F32 top, F32 left, F32 bottom, F32 right); + + void setScale(F32 scale, bool snap = true); + + static F32 scaleFromZoom(F32 zoom); + static F32 zoomFromScale(F32 scale); + + F32 mMapScale; + F32 mTargetMapScale; + static F32 sMapScaleSetting; + static LLVector2 sZoomPivot; + static LLFrameTimer sZoomTimer; + + F32 mMapIterpTime; }; #endif diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp index 7b3461baf2e8696bba328c82e0db4f9b1d3f94a8..f8e5695079af16501b90adfe4322f8a272def78d 100644 --- a/indra/newview/llxmlrpctransaction.cpp +++ b/indra/newview/llxmlrpctransaction.cpp @@ -40,6 +40,7 @@ #include "httpoptions.h" #include "httpheaders.h" #include "bufferarray.h" +#include "llversioninfo.h" #include "llviewercontrol.h" // Have to include these last to avoid queue redefinition! @@ -382,6 +383,15 @@ void LLXMLRPCTransaction::Impl::init(XMLRPC_REQUEST request, bool useGzip, const httpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_TEXT_XML); + std::string user_agent = llformat("%s %d.%d.%d (%d)", + LLVersionInfo::instance().getChannel().c_str(), + LLVersionInfo::instance().getMajor(), + LLVersionInfo::instance().getMinor(), + LLVersionInfo::instance().getPatch(), + LLVersionInfo::instance().getBuild()); + + httpHeaders->append(HTTP_OUT_HEADER_USER_AGENT, user_agent); + ///* Setting the DNS cache timeout to -1 disables it completely. //This might help with bug #503 */ //httpOpts->setDNSCacheTimeout(-1); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 0cc60d2c50174c5cf42178d01177a4418cfc58ee..4063198a478e04550c600be27580dfe0b6ead67c 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -152,7 +152,6 @@ bool gShiftFrame = false; //cached settings -bool LLPipeline::RenderAvatarVP; bool LLPipeline::WindLightUseAtmosShaders; bool LLPipeline::RenderDeferred; F32 LLPipeline::RenderDeferredSunWash; @@ -254,7 +253,6 @@ const LLMatrix4a* gGLLastMatrix = NULL; LLTrace::BlockTimerStatHandle FTM_RENDER_GEOMETRY("Render Geometry"); LLTrace::BlockTimerStatHandle FTM_RENDER_GRASS("Grass"); LLTrace::BlockTimerStatHandle FTM_RENDER_INVISIBLE("Invisible"); -LLTrace::BlockTimerStatHandle FTM_RENDER_OCCLUSION("Occlusion"); LLTrace::BlockTimerStatHandle FTM_RENDER_SHINY("Shiny"); LLTrace::BlockTimerStatHandle FTM_RENDER_SIMPLE("Simple"); LLTrace::BlockTimerStatHandle FTM_RENDER_TERRAIN("Terrain"); @@ -269,7 +267,6 @@ LLTrace::BlockTimerStatHandle FTM_RENDER_MATERIALS("Render Materials"); LLTrace::BlockTimerStatHandle FTM_RENDER_FULLBRIGHT("Fullbright"); LLTrace::BlockTimerStatHandle FTM_RENDER_GLOW("Glow"); LLTrace::BlockTimerStatHandle FTM_GEO_UPDATE("Geo Update"); -LLTrace::BlockTimerStatHandle FTM_PIPELINE_CREATE("Pipeline Create"); LLTrace::BlockTimerStatHandle FTM_POOLRENDER("RenderPool"); LLTrace::BlockTimerStatHandle FTM_POOLS("Pools"); LLTrace::BlockTimerStatHandle FTM_DEFERRED_POOLRENDER("RenderPool (Deferred)"); @@ -277,7 +274,6 @@ LLTrace::BlockTimerStatHandle FTM_DEFERRED_POOLS("Pools (Deferred)"); LLTrace::BlockTimerStatHandle FTM_POST_DEFERRED_POOLRENDER("RenderPool (Post)"); LLTrace::BlockTimerStatHandle FTM_POST_DEFERRED_POOLS("Pools (Post)"); LLTrace::BlockTimerStatHandle FTM_RENDER_DEFERRED_BLOOM("HDRBloom"); -LLTrace::BlockTimerStatHandle FTM_RENDER_BLOOM_FBO("First FBO"); LLTrace::BlockTimerStatHandle FTM_STATESORT("Sort Draw State"); LLTrace::BlockTimerStatHandle FTM_PIPELINE("Pipeline"); LLTrace::BlockTimerStatHandle FTM_CLIENT_COPY("Client Copy"); @@ -286,11 +282,8 @@ LLTrace::BlockTimerStatHandle FTM_RENDER_DEFERRED("Deferred Shading"); LLTrace::BlockTimerStatHandle FTM_RENDER_UI_HUD("HUD"); LLTrace::BlockTimerStatHandle FTM_RENDER_UI_3D("3D"); LLTrace::BlockTimerStatHandle FTM_RENDER_UI_2D("2D"); -LLTrace::BlockTimerStatHandle FTM_RENDER_UI_DEBUG_TEXT("Debug Text"); -LLTrace::BlockTimerStatHandle FTM_RENDER_UI_SCENE_MON("Scene Mon"); static LLTrace::BlockTimerStatHandle FTM_STATESORT_DRAWABLE("Sort Drawables"); -static LLTrace::BlockTimerStatHandle FTM_STATESORT_POSTSORT("Post Sort"); static LLStaticHashedString sTint("tint"); static LLStaticHashedString sAmbiance("ambiance"); @@ -351,7 +344,6 @@ S32 LLPipeline::sUseOcclusion = 0; bool LLPipeline::sDelayVBUpdate = true; bool LLPipeline::sAutoMaskAlphaDeferred = true; bool LLPipeline::sAutoMaskAlphaNonDeferred = false; -bool LLPipeline::sDisableShaders = false; bool LLPipeline::sRenderTransparentWater = true; bool LLPipeline::sRenderBump = true; bool LLPipeline::sBakeSunlight = false; @@ -372,7 +364,6 @@ bool LLPipeline::sRenderAttachedLights = true; bool LLPipeline::sRenderAttachedParticles = true; bool LLPipeline::sRenderDeferred = false; S32 LLPipeline::sVisibleLightCount = 0; -F32 LLPipeline::sMinRenderSize = 0.f; bool LLPipeline::sRenderingHUDs; F32 LLPipeline::sDistortionWaterClipPlaneMargin = 1.0125f; // [SL:KB] - Patch: Render-TextureToggle (Catznip-4.0) @@ -389,10 +380,12 @@ static LLCullResult* sCull = NULL; void validate_framebuffer_object(); - -bool addDeferredAttachments(LLRenderTarget& target) +// Add color attachments for deferred rendering +// target -- RenderTarget to add attachments to +// for_impostor -- whether or not these render targets are for an impostor (if true, avoids implicit sRGB conversions) +bool addDeferredAttachments(LLRenderTarget& target, bool for_impostor = false) { - return target.addColorAttachment(GL_SRGB8_ALPHA8) && //specular + return target.addColorAttachment(for_impostor ? GL_RGBA : GL_SRGB8_ALPHA8) && //specular target.addColorAttachment(GL_RGBA12); //normal+z } @@ -402,8 +395,7 @@ LLPipeline::LLPipeline() : mTextureMatrixOps(0), mNumVisibleNodes(0), mInitialized(false), - mVertexShadersEnabled(false), - mVertexShadersLoaded(0), + mShadersLoaded(false), mRenderDebugFeatureMask(0), mRenderDebugMask(0), mOldRenderDebugMask(0), @@ -509,6 +501,10 @@ void LLPipeline::init() { clearAllRenderTypes(); } + else if (gNonInteractive) + { + clearAllRenderTypes(); + } else { setAllRenderTypes(); // By default, all rendering types start enabled @@ -572,7 +568,6 @@ void LLPipeline::init() connectRefreshCachedSettingsSafe("RenderAvatarMaxNonImpostors"); connectRefreshCachedSettingsSafe("RenderDelayVBUpdate"); connectRefreshCachedSettingsSafe("UseOcclusion"); - connectRefreshCachedSettingsSafe("RenderAvatarVP"); connectRefreshCachedSettingsSafe("WindLightUseAtmosShaders"); connectRefreshCachedSettingsSafe("RenderDeferred"); connectRefreshCachedSettingsSafe("RenderDeferredSunWash"); @@ -771,8 +766,6 @@ void LLPipeline::destroyGL() } } -static LLTrace::BlockTimerStatHandle FTM_RESIZE_SCREEN_TEXTURE("Resize Screen Texture"); - void LLPipeline::requestResizeScreenTexture() { gResizeScreenTexture = TRUE; @@ -792,8 +785,7 @@ void LLPipeline::resizeShadowTexture() void LLPipeline::resizeScreenTexture() { - LL_RECORD_BLOCK_TIME(FTM_RESIZE_SCREEN_TEXTURE); - if (gPipeline.canUseVertexShaders() && assertInitialized()) + if (gPipeline.shadersLoaded()) { GLuint resX = gViewerWindow->getWorldViewWidthRaw(); GLuint resY = gViewerWindow->getWorldViewHeightRaw(); @@ -822,8 +814,8 @@ void LLPipeline::resizeScreenTexture() releaseShadowTargets(); allocateScreenBuffer(resX,resY); gResizeScreenTexture = FALSE; - } - } + } + } } void LLPipeline::allocatePhysicsBuffer() @@ -1148,10 +1140,8 @@ void LLPipeline::updateRenderDeferred() RenderDeferred && LLRenderTarget::sUseFBO && LLPipeline::sRenderBump && - LLPipeline::sRenderTransparentWater && - RenderAvatarVP && WindLightUseAtmosShaders && - (bool) LLFeatureManager::getInstanceFast()->isFeatureAvailable("RenderDeferred"); + (bool) LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred"); // [RLVa:KB] - @setsphere if (!sRenderDeferred && RlvActions::hasBehaviour(RLV_BHVR_SETSPHERE) && WindLightUseAtmosShaders) { @@ -1175,12 +1165,10 @@ void LLPipeline::refreshCachedSettings() LLPipeline::sUseOcclusion = (!gUseWireframe - && LLGLSLShader::sNoFixedFunction - && LLFeatureManager::getInstanceFast()->isFeatureAvailable("UseOcclusion") + && LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion") && gSavedSettings.getBOOL("UseOcclusion") && gGLManager.mHasOcclusionQuery) ? 2 : 0; - RenderAvatarVP = gSavedSettings.getBOOL("RenderAvatarVP"); WindLightUseAtmosShaders = gSavedSettings.getBOOL("WindLightUseAtmosShaders"); RenderDeferred = gSavedSettings.getBOOL("RenderDeferred"); RenderDeferredSunWash = gSavedSettings.getF32("RenderDeferredSunWash"); @@ -1262,6 +1250,12 @@ void LLPipeline::refreshCachedSettings() RenderNormalMapScale = gSavedSettings.getF32("RenderNormalMapScale"); RenderSpotLight = nullptr; updateRenderDeferred(); + + if (gNonInteractive) + { + LLVOAvatar::sMaxNonImpostors = 1; + LLVOAvatar::updateImpostorRendering(LLVOAvatar::sMaxNonImpostors); + } } void LLPipeline::releaseGLBuffers() @@ -1366,7 +1360,8 @@ void LLPipeline::releaseShadowTargets() void LLPipeline::createGLBuffers() { - stop_glerror(); + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; + stop_glerror(); assertInitialized(); updateRenderDeferred(); @@ -1592,12 +1587,9 @@ void LLPipeline::restoreGL() { assertInitialized(); - if (mVertexShadersEnabled) - { - LLViewerShaderMgr::instance()->setShaders(); - } + LLViewerShaderMgr::instance()->setShaders(); - for (LLViewerRegion* region : LLWorld::getInstanceFast()->getRegionList()) + for (LLViewerRegion* region : LLWorld::getInstance()->getRegionList()) { for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) { @@ -1605,31 +1597,19 @@ void LLPipeline::restoreGL() if (part) { part->restoreGL(); - } + } } } } - -bool LLPipeline::canUseVertexShaders() +bool LLPipeline::shadersLoaded() { - if (sDisableShaders || - !gGLManager.mHasVertexShader || - !gGLManager.mHasFragmentShader || - (assertInitialized() && mVertexShadersLoaded != 1) ) - { - return false; - } - else - { - return true; - } + return (assertInitialized() && mShadersLoaded); } bool LLPipeline::canUseWindLightShaders() const { - return (!LLPipeline::sDisableShaders && - gWLSkyProgram.mProgramObject != 0 && + return (gWLSkyProgram.mProgramObject != 0 && LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1); } @@ -1647,8 +1627,7 @@ bool LLPipeline::canUseAntiAliasing() const void LLPipeline::unloadShaders() { LLViewerShaderMgr::instance()->unloadShaders(); - - mVertexShadersLoaded = 0; + mShadersLoaded = false; } void LLPipeline::assertInitializedDoError() @@ -1734,6 +1713,7 @@ class LLOctreeDirtyTexture : public OctreeTraveler // Called when a texture changes # of channels (causes faces to move to alpha pool) void LLPipeline::dirtyPoolObjectTextures(const std::set<LLViewerFetchedTexture*>& textures) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; assertInitialized(); // *TODO: This is inefficient and causes frame spikes; need a better way to do this @@ -1748,7 +1728,7 @@ void LLPipeline::dirtyPoolObjectTextures(const std::set<LLViewerFetchedTexture*> } LLOctreeDirtyTexture dirty(textures); - for (LLViewerRegion* region : LLWorld::getInstanceFast()->getRegionList()) + for (LLViewerRegion* region : LLWorld::getInstance()->getRegionList()) { for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) { @@ -1942,15 +1922,9 @@ void LLPipeline::allocDrawable(LLViewerObject *vobj) } -static LLTrace::BlockTimerStatHandle FTM_UNLINK("Unlink"); -static LLTrace::BlockTimerStatHandle FTM_REMOVE_FROM_MOVE_LIST("Movelist"); -static LLTrace::BlockTimerStatHandle FTM_REMOVE_FROM_SPATIAL_PARTITION("Spatial Partition"); -static LLTrace::BlockTimerStatHandle FTM_REMOVE_FROM_LIGHT_SET("Light Set"); -static LLTrace::BlockTimerStatHandle FTM_REMOVE_FROM_HIGHLIGHT_SET("Highlight Set"); - void LLPipeline::unlinkDrawable(LLDrawable *drawable) { - LL_RECORD_BLOCK_TIME(FTM_UNLINK); + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; assertInitialized(); @@ -1959,7 +1933,6 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable) // Based on flags, remove the drawable from the queues that it's on. if (drawablep->isState(LLDrawable::ON_MOVE_LIST)) { - LL_RECORD_BLOCK_TIME(FTM_REMOVE_FROM_MOVE_LIST); LLDrawable::drawable_vector_t::iterator iter = std::find(mMovedList.begin(), mMovedList.end(), drawablep); if (iter != mMovedList.end()) { @@ -1969,7 +1942,6 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable) if (drawablep->getSpatialGroup()) { - LL_RECORD_BLOCK_TIME(FTM_REMOVE_FROM_SPATIAL_PARTITION); if (!drawablep->getSpatialGroup()->getSpatialPartition()->remove(drawablep, drawablep->getSpatialGroup())) { #ifdef LL_RELEASE_FOR_DOWNLOAD @@ -1980,30 +1952,24 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable) } } - { - LL_RECORD_BLOCK_TIME(FTM_REMOVE_FROM_LIGHT_SET); - mLights.erase(drawablep); + mLights.erase(drawablep); - for (light_set_t::iterator iter = mNearbyLights.begin(); - iter != mNearbyLights.end(); iter++) + for (light_set_t::iterator iter = mNearbyLights.begin(); + iter != mNearbyLights.end(); iter++) + { + if (iter->drawable == drawablep) { - if (iter->drawable == drawablep) - { - mNearbyLights.erase(iter); - break; - } + mNearbyLights.erase(iter); + break; } } - { - LL_RECORD_BLOCK_TIME(FTM_REMOVE_FROM_HIGHLIGHT_SET); - HighlightItem item(drawablep); - mHighlightSet.erase(item); + HighlightItem item(drawablep); + mHighlightSet.erase(item); - if (mHighlightObject == drawablep) - { - mHighlightObject = NULL; - } + if (mHighlightObject == drawablep) + { + mHighlightObject = NULL; } for (U32 i = 0; i < 2; ++i) @@ -2018,14 +1984,12 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable) mTargetShadowSpotLight[i] = NULL; } } - - } //static void LLPipeline::removeMutedAVsLights(LLVOAvatar* muted_avatar) { - LL_RECORD_BLOCK_TIME(FTM_REMOVE_FROM_LIGHT_SET); + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; for (light_set_t::iterator iter = gPipeline.mNearbyLights.begin(); iter != gPipeline.mNearbyLights.end();) { @@ -2058,7 +2022,7 @@ U32 LLPipeline::addObject(LLViewerObject *vobj) void LLPipeline::createObjects(F32 max_dtime) { - LL_RECORD_BLOCK_TIME(FTM_PIPELINE_CREATE); + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; LLTimer update_timer; @@ -2082,6 +2046,7 @@ void LLPipeline::createObjects(F32 max_dtime) void LLPipeline::createObject(LLViewerObject* vobj) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; LLDrawable* drawablep = vobj->mDrawable; if (!drawablep) @@ -2119,6 +2084,7 @@ void LLPipeline::createObject(LLViewerObject* vobj) void LLPipeline::resetFrameStats() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; assertInitialized(); if (mOldRenderDebugMask != mRenderDebugMask) @@ -2131,6 +2097,7 @@ void LLPipeline::resetFrameStats() //external functions for asynchronous updating void LLPipeline::updateMoveDampedAsync(LLDrawable* drawablep) { + LL_PROFILE_ZONE_SCOPED; if (FreezeTime) { return; @@ -2161,6 +2128,7 @@ void LLPipeline::updateMoveDampedAsync(LLDrawable* drawablep) void LLPipeline::updateMoveNormalAsync(LLDrawable* drawablep) { + LL_PROFILE_ZONE_SCOPED; if (FreezeTime) { return; @@ -2191,6 +2159,7 @@ void LLPipeline::updateMoveNormalAsync(LLDrawable* drawablep) void LLPipeline::updateMovedList(LLDrawable::drawable_vector_t& moved_list) { + LL_PROFILE_ZONE_SCOPED; LLDrawable::drawable_vector_t newList; // removing elements in the middle of a vector is a really bad idea. I'll just create a new one and swap it at the end. for (LLDrawable::drawable_vector_t::iterator iter = moved_list.begin(); @@ -2231,14 +2200,9 @@ void LLPipeline::updateMovedList(LLDrawable::drawable_vector_t& moved_list) moved_list.swap( newList ); } -static LLTrace::BlockTimerStatHandle FTM_OCTREE_BALANCE("Balance Octree"); -static LLTrace::BlockTimerStatHandle FTM_UPDATE_MOVE("Update Move"); -static LLTrace::BlockTimerStatHandle FTM_RETEXTURE("Retexture"); -static LLTrace::BlockTimerStatHandle FTM_MOVED_LIST("Moved List"); - void LLPipeline::updateMove() { - LL_RECORD_BLOCK_TIME(FTM_UPDATE_MOVE); + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; if (FreezeTime) { @@ -2247,45 +2211,34 @@ void LLPipeline::updateMove() assertInitialized(); + for (LLDrawable* drawablep : mRetexturedList) { - LL_RECORD_BLOCK_TIME(FTM_RETEXTURE); - - for (LLDrawable* drawablep : mRetexturedList) + if (drawablep && !drawablep->isDead()) { - if (drawablep && !drawablep->isDead()) - { - drawablep->updateTexture(); - } + drawablep->updateTexture(); } - mRetexturedList.clear(); } + mRetexturedList.clear(); - { - LL_RECORD_BLOCK_TIME(FTM_MOVED_LIST); - updateMovedList(mMovedList); - } + updateMovedList(mMovedList); //balance octrees + for (LLViewerRegion* region : LLWorld::getInstance()->getRegionList()) { - LL_RECORD_BLOCK_TIME(FTM_OCTREE_BALANCE); - - for (LLViewerRegion* region : LLWorld::getInstanceFast()->getRegionList()) + for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) { - for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) + LLSpatialPartition* part = region->getSpatialPartition(i); + if (part) { - LLSpatialPartition* part = region->getSpatialPartition(i); - if (part) - { - part->mOctree->balance(); - } + part->mOctree->balance(); } + } - //balance the VO Cache tree - LLVOCachePartition* vo_part = region->getVOCachePartition(); - if(vo_part) - { - vo_part->mOctree->balance(); - } + //balance the VO Cache tree + LLVOCachePartition* vo_part = region->getVOCachePartition(); + if(vo_part) + { + vo_part->mOctree->balance(); } } } @@ -2347,6 +2300,7 @@ void LLPipeline::grabReferences(LLCullResult& result) void LLPipeline::clearReferences() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; sCull = NULL; mGroupSaveQ1.clear(); } @@ -2530,7 +2484,7 @@ void LLPipeline::checkReferences(LLSpatialGroup* group) bool LLPipeline::visibleObjectsInFrustum(LLCamera& camera) { - for (LLViewerRegion* region : LLWorld::getInstanceFast()->getRegionList()) + for (LLViewerRegion* region : LLWorld::getInstance()->getRegionList()) { for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) { @@ -2563,7 +2517,7 @@ bool LLPipeline::getVisibleExtents(LLCamera& camera, LLVector3& min, LLVector3& bool res = true; - for (LLViewerRegion* region : LLWorld::getInstanceFast()->getRegionList()) + for (LLViewerRegion* region : LLWorld::getInstance()->getRegionList()) { for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) { @@ -2588,20 +2542,28 @@ bool LLPipeline::getVisibleExtents(LLCamera& camera, LLVector3& min, LLVector3& static LLTrace::BlockTimerStatHandle FTM_CULL("Object Culling"); -void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_clip, LLPlane* planep) +void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, LLPlane* planep) { static LLCachedControl<bool> use_occlusion(gSavedSettings,"UseOcclusion"); - static bool can_use_occlusion = LLGLSLShader::sNoFixedFunction - && LLFeatureManager::getInstanceFast()->isFeatureAvailable("UseOcclusion") + static bool can_use_occlusion = LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion") && gGLManager.mHasOcclusionQuery; - LL_RECORD_BLOCK_TIME(FTM_CULL); + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; //LL_RECORD_BLOCK_TIME(FTM_CULL); + + if (planep != nullptr) + { + camera.setUserClipPlane(*planep); + } + else + { + camera.disableUserClipPlane(); + } grabReferences(result); sCull->clear(); - bool to_texture = LLPipeline::sUseOcclusion > 1 && gPipeline.canUseVertexShaders(); + bool to_texture = LLPipeline::sUseOcclusion > 1 && gPipeline.shadersLoaded(); if (to_texture) { @@ -2635,7 +2597,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl LLGLDepthTest depth(GL_TRUE, GL_FALSE); bool bound_shader = false; - if (gPipeline.canUseVertexShaders() && LLGLSLShader::sCurBoundShader == 0) + if (gPipeline.shadersLoaded() && LLGLSLShader::sCurBoundShader == 0) { //if no shader is currently bound, use the occlusion shader instead of fixed function if we can // (shadow render uses a special shader that clamps to clip planes) bound_shader = true; @@ -2651,12 +2613,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX); } - if (!sReflectionRender) - { - camera.disableUserClipPlane(); - } - - for (LLViewerRegion* region : LLWorld::getInstanceFast()->getRegionList()) + for (LLViewerRegion* region : LLWorld::getInstance()->getRegionList()) { for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) { @@ -2674,8 +2631,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl LLVOCachePartition* vo_part = region->getVOCachePartition(); if(vo_part) { - bool do_occlusion_cull = can_use_occlusion && use_occlusion && !gUseWireframe && 0 > water_clip /* && !gViewerWindow->getProgressView()->getVisible()*/; - do_occlusion_cull &= !sReflectionRender; + bool do_occlusion_cull = can_use_occlusion && use_occlusion && !gUseWireframe; vo_part->cull(camera, do_occlusion_cull); } } @@ -2719,7 +2675,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl if (render_water) { - LLWorld::getInstanceFast()->precullWaterObjects(camera, sCull, render_water); + LLWorld::getInstance()->precullWaterObjects(camera, sCull, render_water); } gGL.matrixMode(LLRender::MM_PROJECTION); @@ -2759,20 +2715,6 @@ void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera) group->updateDistance(camera); } - const F32 MINIMUM_PIXEL_AREA = 16.f; - - if (group->mPixelArea < MINIMUM_PIXEL_AREA) - { - return; - } - - const LLVector4a* bounds = group->getBounds(); - if (sMinRenderSize > 0.f && - llmax(llmax(bounds[1][0], bounds[1][1]), bounds[1][2]) < sMinRenderSize) - { - return; - } - assertInitialized(); if (!group->getSpatialPartition()->mRenderByGroup) @@ -2874,7 +2816,8 @@ void LLPipeline::doOcclusion(LLCamera& camera, LLRenderTarget& source, LLRenderT void LLPipeline::doOcclusion(LLCamera& camera) { - if (LLPipeline::sUseOcclusion > 1 && !LLSpatialPartition::sTeleportRequested && + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; + if (LLPipeline::sUseOcclusion > 1 && !LLSpatialPartition::sTeleportRequested && (sCull->hasOcclusionGroups() || LLVOCachePartition::sNeedsOcclusionCheck)) { LLVertexBuffer::unbind(); @@ -2895,7 +2838,7 @@ void LLPipeline::doOcclusion(LLCamera& camera) LLGLDisable cull(GL_CULL_FACE); - bool bind_shader = LLGLSLShader::sNoFixedFunction && LLGLSLShader::sCurBoundShader == 0; + bool bind_shader = (LLGLSLShader::sCurBoundShader == 0); if (bind_shader) { if (LLPipeline::sShadowRender) @@ -2922,7 +2865,7 @@ void LLPipeline::doOcclusion(LLCamera& camera) } //apply occlusion culling to object cache tree - for (LLViewerRegion* region : LLWorld::getInstanceFast()->getRegionList()) + for (LLViewerRegion* region : LLWorld::getInstance()->getRegionList()) { LLVOCachePartition* vo_part = region->getVOCachePartition(); if(vo_part) @@ -2957,14 +2900,10 @@ bool LLPipeline::updateDrawableGeom(LLDrawable* drawablep, bool priority) return update_complete; } -static LLTrace::BlockTimerStatHandle FTM_SEED_VBO_POOLS("Seed VBO Pool"); - -static LLTrace::BlockTimerStatHandle FTM_UPDATE_GL("Update GL"); - void LLPipeline::updateGL() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; { - LL_RECORD_BLOCK_TIME(FTM_UPDATE_GL); while (!LLGLUpdate::sGLQ.empty()) { LLGLUpdate* glu = LLGLUpdate::sGLQ.front(); @@ -2975,15 +2914,13 @@ void LLPipeline::updateGL() } { //seed VBO Pools - LL_RECORD_BLOCK_TIME(FTM_SEED_VBO_POOLS); LLVertexBuffer::seedPools(); } } -static LLTrace::BlockTimerStatHandle FTM_REBUILD_PRIORITY_GROUPS("Rebuild Priority Groups"); - void LLPipeline::clearRebuildGroups() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; LLSpatialGroup::sg_vector_t hudGroups; mGroupQ1Locked = true; @@ -3074,7 +3011,7 @@ void LLPipeline::clearRebuildDrawables() void LLPipeline::rebuildPriorityGroups() { - LL_RECORD_BLOCK_TIME(FTM_REBUILD_PRIORITY_GROUPS); + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; LLTimer update_timer; assertInitialized(); @@ -3094,8 +3031,6 @@ void LLPipeline::rebuildPriorityGroups() } -static LLTrace::BlockTimerStatHandle FTM_REBUILD_GROUPS("Rebuild Groups"); - void LLPipeline::rebuildGroups() { if (mGroupQ2.empty()) @@ -3103,7 +3038,7 @@ void LLPipeline::rebuildGroups() return; } - LL_RECORD_BLOCK_TIME(FTM_REBUILD_GROUPS); + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; mGroupQ2Locked = true; // Iterate through some drawables on the non-priority build queue S32 size = (S32) mGroupQ2.size(); @@ -3349,12 +3284,9 @@ void LLPipeline::markShift(LLDrawable *drawablep) } } -static LLTrace::BlockTimerStatHandle FTM_SHIFT_DRAWABLE("Shift Drawable"); -static LLTrace::BlockTimerStatHandle FTM_SHIFT_OCTREE("Shift Octree"); -static LLTrace::BlockTimerStatHandle FTM_SHIFT_HUD("Shift HUD"); - void LLPipeline::shiftObjects(const LLVector3 &offset) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; assertInitialized(); glClear(GL_DEPTH_BUFFER_BIT); @@ -3363,42 +3295,32 @@ void LLPipeline::shiftObjects(const LLVector3 &offset) LLVector4a offseta; offseta.load3(offset.mV); + for (LLDrawable* drawablep : mShiftList) { - LL_RECORD_BLOCK_TIME(FTM_SHIFT_DRAWABLE); - - for (LLDrawable* drawablep : mShiftList) + if (drawablep->isDead()) { - if (drawablep->isDead()) - { - continue; - } - drawablep->shiftPos(offseta); - drawablep->clearState(LLDrawable::ON_SHIFT_LIST); - } - mShiftList.resize(0); + continue; + } + drawablep->shiftPos(offseta); + drawablep->clearState(LLDrawable::ON_SHIFT_LIST); } - + mShiftList.resize(0); + for (LLViewerRegion* region : LLWorld::getInstance()->getRegionList()) { - LL_RECORD_BLOCK_TIME(FTM_SHIFT_OCTREE); - for (LLViewerRegion* region : LLWorld::getInstanceFast()->getRegionList()) + for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) { - for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) + LLSpatialPartition* part = region->getSpatialPartition(i); + if (part) { - LLSpatialPartition* part = region->getSpatialPartition(i); - if (part) - { - part->shift(offseta); - } + part->shift(offseta); } } } - { - LL_RECORD_BLOCK_TIME(FTM_SHIFT_HUD); - LLHUDText::shiftAll(offset); - LLHUDNameTag::shiftAll(offset); - } + LLHUDText::shiftAll(offset); + LLHUDNameTag::shiftAll(offset); + display_update_camera(); } @@ -3429,10 +3351,9 @@ void LLPipeline::markPartitionMove(LLDrawable* drawable) } } -static LLTrace::BlockTimerStatHandle FTM_PROCESS_PARTITIONQ("PartitionQ"); void LLPipeline::processPartitionQ() { - LL_RECORD_BLOCK_TIME(FTM_PROCESS_PARTITIONQ); + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; for (LLDrawable* drawable : mPartitionQ) { if (!drawable->isDead()) @@ -3534,10 +3455,10 @@ void LLPipeline::markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags f } } -static LLTrace::BlockTimerStatHandle FTM_RESET_DRAWORDER("Reset Draw Order"); - void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; + if (hasAnyRenderType(LLPipeline::RENDER_TYPE_AVATAR, LLPipeline::RENDER_TYPE_CONTROL_AV, LLPipeline::RENDER_TYPE_GROUND, @@ -3549,12 +3470,9 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) LLPipeline::END_RENDER_TYPES)) { //clear faces from face pools - LL_RECORD_BLOCK_TIME(FTM_RESET_DRAWORDER); gPipeline.resetDrawOrders(); } - LL_RECORD_BLOCK_TIME(FTM_STATESORT); - //LLVertexBuffer::unbind(); grabReferences(result); @@ -3585,7 +3503,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) { LLSpatialGroup* last_group = NULL; - BOOL fov_changed = LLViewerCamera::getInstanceFast()->isDefaultFOVChanged(); + BOOL fov_changed = LLViewerCamera::getInstance()->isDefaultFOVChanged(); for (LLCullResult::bridge_iterator i = sCull->beginVisibleBridge(), i_end = sCull->endVisibleBridge(); i != i_end; ++i) { LLCullResult::bridge_iterator cur_iter = i; @@ -3639,7 +3557,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) } { - LL_RECORD_BLOCK_TIME(FTM_STATESORT_DRAWABLE); + LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWABLE("stateSort"); // LL_RECORD_BLOCK_TIME(FTM_STATESORT_DRAWABLE); for (LLCullResult::drawable_iterator iter = sCull->beginVisibleList(), iter_end = sCull->endVisibleList(); iter != iter_end; ++iter) { @@ -3669,12 +3587,12 @@ void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera) group->mLastUpdateDistance = group->mDistance; } } - } void LLPipeline::stateSort(LLSpatialBridge* bridge, LLCamera& camera, BOOL fov_changed) { - if (bridge->getSpatialGroup()->changeLOD() || fov_changed) + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; + if (bridge->getSpatialGroup()->changeLOD() || fov_changed) { bool force_update = false; bridge->updateDistance(camera, force_update); @@ -3683,7 +3601,8 @@ void LLPipeline::stateSort(LLSpatialBridge* bridge, LLCamera& camera, BOOL fov_c void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera) { - if (!drawablep + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; + if (!drawablep || drawablep->isDead() || !hasRenderType(drawablep->getRenderType())) { @@ -3698,7 +3617,7 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera) return; } - if (LLSelectMgr::getInstanceFast()->mHideSelectedObjects) + if (LLSelectMgr::getInstance()->mHideSelectedObjects) { // if (drawablep->getVObj().notNull() && // drawablep->getVObj()->isSelected()) @@ -3978,9 +3897,36 @@ void renderSoundHighlights(LLDrawable* drawablep) } } +void LLPipeline::touchTexture(LLViewerTexture* tex, F32 vsize) +{ + if (tex) + { + LLImageGL* gl_tex = tex->getGLTexture(); + if (gl_tex && gl_tex->updateBindStats(gl_tex->mTextureMemory)) + { + tex->setActive(); + tex->addTextureStats(vsize); + } + } + + +} +void LLPipeline::touchTextures(LLDrawInfo* info) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; + for (int i = 0; i < info->mTextureList.size(); ++i) + { + touchTexture(info->mTextureList[i], info->mTextureListVSize[i]); + } + + touchTexture(info->mTexture, info->mVSize); + touchTexture(info->mSpecularMap, info->mVSize); + touchTexture(info->mNormalMap, info->mVSize); +} + void LLPipeline::postSort(LLCamera& camera) { - LL_RECORD_BLOCK_TIME(FTM_STATESORT_POSTSORT); + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; assertInitialized(); @@ -4030,20 +3976,14 @@ void LLPipeline::postSort(LLCamera& camera) for (LLSpatialGroup::drawmap_elem_t::iterator k = src_vec.begin(), k_end = src_vec.end(); k != k_end; ++k) { - if (sMinRenderSize > 0.f) - { - LLVector4a bounds; - bounds.setSub((*k)->mExtents[1],(*k)->mExtents[0]); - - if (llmax(llmax(bounds[0], bounds[1]), bounds[2]) > sMinRenderSize) - { - sCull->pushDrawInfo(j->first, *k); - } - } - else - { - sCull->pushDrawInfo(j->first, *k); - } + LLDrawInfo* info = *k; + + sCull->pushDrawInfo(j->first, info); + if (!sShadowRender && !sReflectionRender) + { + touchTextures(info); + //addTrianglesDrawn(info->mCount, info->mDrawMode); + } } } @@ -4072,6 +4012,16 @@ void LLPipeline::postSort(LLCamera& camera) sCull->pushAlphaGroup(group); } } + + LLSpatialGroup::draw_map_t::iterator rigged_alpha = group->mDrawMap.find(LLRenderPass::PASS_ALPHA_RIGGED); + + if (rigged_alpha != group->mDrawMap.end()) + { //store rigged alpha groups for LLDrawPoolAlpha prepass (skip distance update, rigged attachments use depth buffer) + if (hasRenderType(LLDrawPool::POOL_ALPHA)) + { + sCull->pushRiggedAlphaGroup(group); + } + } } } @@ -4095,7 +4045,11 @@ void LLPipeline::postSort(LLCamera& camera) if (!sShadowRender) { + // order alpha groups by distance std::sort(sCull->beginAlphaGroups(), sCull->endAlphaGroups(), LLSpatialGroup::CompareDepthGreater()); + + // order rigged alpha groups by avatar attachment order + std::sort(sCull->beginRiggedAlphaGroups(), sCull->endRiggedAlphaGroups(), LLSpatialGroup::CompareRenderOrder()); } LL_PUSH_CALLSTACKS(); @@ -4153,7 +4107,7 @@ void LLPipeline::postSort(LLCamera& camera) } LL_PUSH_CALLSTACKS(); // If managing your telehub, draw beacons at telehub and currently selected spawnpoint. - if (LLFloaterTelehub::renderBeacons()) + if (LLFloaterTelehub::renderBeacons() && !sShadowRender) { LLFloaterTelehub::addBeacons(); } @@ -4162,11 +4116,14 @@ void LLPipeline::postSort(LLCamera& camera) { mSelectedFaces.clear(); - // Draw face highlights for selected faces. - if (LLSelectMgr::getInstanceFast()->getTEMode()) + if (!gNonInteractive) { LLPipeline::setRenderHighlightTextureChannel(gFloaterTools->getPanelFace()->getTextureChannelToEdit()); + } + // Draw face highlights for selected faces. + if (LLSelectMgr::getInstance()->getTEMode()) + { struct f : public LLSelectedTEFunctor { virtual bool apply(LLViewerObject* object, S32 te) @@ -4182,7 +4139,7 @@ void LLPipeline::postSort(LLCamera& camera) return true; } } func; - LLSelectMgr::getInstanceFast()->getSelection()->applyToTEs(&func); + LLSelectMgr::getInstance()->getSelection()->applyToTEs(&func); } } @@ -4193,8 +4150,8 @@ void LLPipeline::postSort(LLCamera& camera) void render_hud_elements() { - LL_RECORD_BLOCK_TIME(FTM_RENDER_UI); - gPipeline.disableLights(); + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; //LL_RECORD_BLOCK_TIME(FTM_RENDER_UI); + gPipeline.disableLights(); LLGLDisable fog(GL_FOG); LLGLSUIDefault gls_ui; @@ -4206,10 +4163,7 @@ void render_hud_elements() gGL.color4f(1,1,1,1); - if (LLGLSLShader::sNoFixedFunction) - { - gUIProgram.bind(); - } + gUIProgram.bind(); LLGLDepthTest depth(GL_TRUE, GL_FALSE); if (!LLPipeline::sReflectionRender && gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) @@ -4220,10 +4174,13 @@ void render_hud_elements() // Draw the tracking overlays LLTracker::render3D(); - // Show the property lines - LLWorld::getInstanceFast()->renderPropertyLines(); - LLViewerParcelMgr::getInstanceFast()->render(); - LLViewerParcelMgr::getInstanceFast()->renderParcelCollision(); + if (LLWorld::instanceExists()) + { + // Show the property lines + LLWorld::getInstance()->renderPropertyLines(); + } + LLViewerParcelMgr::getInstance()->render(); + LLViewerParcelMgr::getInstance()->renderParcelCollision(); // Render name tags. LLHUDObject::renderAll(); @@ -4231,17 +4188,14 @@ void render_hud_elements() else if (gForceRenderLandFence) { // This is only set when not rendering the UI, for parcel snapshots - LLViewerParcelMgr::getInstanceFast()->render(); + LLViewerParcelMgr::getInstance()->render(); } else if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) { LLHUDText::renderAllHUD(); } - if (LLGLSLShader::sNoFixedFunction) - { - gUIProgram.unbind(); - } + gUIProgram.unbind(); gGL.flush(); } @@ -4273,10 +4227,7 @@ void LLPipeline::renderHighlights() gGL.setColorMask(false, false); - if (LLGLSLShader::sNoFixedFunction) - { - gHighlightProgram.bind(); - } + gHighlightProgram.bind(); for (std::set<HighlightItem>::iterator iter = mHighlightSet.begin(); iter != mHighlightSet.end(); ++iter) { @@ -4478,7 +4429,7 @@ U32 LLPipeline::sCurRenderPoolType = 0 ; void LLPipeline::renderGeom(LLCamera& camera, bool forceVBOUpdate) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_GEOMETRY); + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; //LL_RECORD_BLOCK_TIME(FTM_RENDER_GEOMETRY); assertInitialized(); @@ -4505,7 +4456,6 @@ void LLPipeline::renderGeom(LLCamera& camera, bool forceVBOUpdate) // Do verification of GL state LLGLState::checkStates(); LLGLState::checkTextureChannels(); - LLGLState::checkClientArrays(); if (mRenderDebugMask & RENDER_DEBUG_VERIFY) { if (!verify()) @@ -4561,7 +4511,7 @@ void LLPipeline::renderGeom(LLCamera& camera, bool forceVBOUpdate) } { - LL_RECORD_BLOCK_TIME(FTM_POOLS); + LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("pools"); //LL_RECORD_BLOCK_TIME(FTM_POOLS); // HACK: don't calculate local lights if we're rendering the HUD! // Removing this check will cause bad flickering when there are @@ -4608,7 +4558,7 @@ void LLPipeline::renderGeom(LLCamera& camera, bool forceVBOUpdate) pool_set_t::iterator iter2 = iter1; if (hasRenderType(poolp->getType()) && poolp->getNumPasses() > 0) { - LL_RECORD_BLOCK_TIME(FTM_POOLRENDER); + LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("pool render"); //LL_RECORD_BLOCK_TIME(FTM_POOLRENDER); gGLLastMatrix = NULL; gGL.loadMatrix(gGLModelView); @@ -4735,98 +4685,104 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera) { LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderGeomDeferred"); - LL_RECORD_BLOCK_TIME(FTM_RENDER_GEOMETRY); - - LL_RECORD_BLOCK_TIME(FTM_DEFERRED_POOLS); + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_GEOMETRY); + { + // SL-15709 -- NOTE: Tracy only allows one ZoneScoped per function. + // Solutions are: + // 1. Use a new scope + // 2. Use named zones + // 3. Use transient zones + LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("deferred pools"); //LL_RECORD_BLOCK_TIME(FTM_DEFERRED_POOLS); - LLGLEnable cull(GL_CULL_FACE); + LLGLEnable cull(GL_CULL_FACE); - for (LLDrawPool* poolp : mPools) - { - if (hasRenderType(poolp->getType())) + for (LLDrawPool* poolp : mPools) { - poolp->prerender(); + if (hasRenderType(poolp->getType())) + { + poolp->prerender(); + } } - } - LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE : 0); + LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE : 0); - LLVertexBuffer::unbind(); + LLVertexBuffer::unbind(); - LLGLState::checkStates(); - LLGLState::checkTextureChannels(); - LLGLState::checkClientArrays(); + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); - U32 cur_type = 0; + U32 cur_type = 0; - gGL.setColorMask(true, true); + gGL.setColorMask(true, true); - pool_set_t::iterator iter1 = mPools.begin(); - pool_set_t::iterator pools_end = mPools.end(); + pool_set_t::iterator iter1 = mPools.begin(); + pool_set_t::iterator pools_end = mPools.end(); - while ( iter1 != pools_end ) - { - LLDrawPool *poolp = *iter1; + while ( iter1 != pools_end ) + { + LLDrawPool *poolp = *iter1; - cur_type = poolp->getType(); + cur_type = poolp->getType(); - pool_set_t::iterator iter2 = iter1; - if (hasRenderType(poolp->getType()) && poolp->getNumDeferredPasses() > 0) - { - LL_RECORD_BLOCK_TIME(FTM_DEFERRED_POOLRENDER); + pool_set_t::iterator iter2 = iter1; + if (hasRenderType(poolp->getType()) && poolp->getNumDeferredPasses() > 0) + { + LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("deferred pool render"); //LL_RECORD_BLOCK_TIME(FTM_DEFERRED_POOLRENDER); - gGLLastMatrix = NULL; - gGL.loadMatrix(gGLModelView); + gGLLastMatrix = NULL; + gGL.loadMatrix(gGLModelView); - for( S32 i = 0; i < poolp->getNumDeferredPasses(); i++ ) - { - LLVertexBuffer::unbind(); - poolp->beginDeferredPass(i); - for (iter2 = iter1; iter2 != pools_end; ++iter2) + for( S32 i = 0; i < poolp->getNumDeferredPasses(); i++ ) { - LLDrawPool *p = *iter2; - if (p->getType() != cur_type) + LLVertexBuffer::unbind(); + poolp->beginDeferredPass(i); + for (iter2 = iter1; iter2 != pools_end; ++iter2) { - break; + LLDrawPool *p = *iter2; + if (p->getType() != cur_type) + { + break; + } + + if ( !p->getSkipRenderFlag() ) { p->renderDeferred(i); } } - - if ( !p->getSkipRenderFlag() ) { p->renderDeferred(i); } - } - poolp->endDeferredPass(i); - LLVertexBuffer::unbind(); + poolp->endDeferredPass(i); + LLVertexBuffer::unbind(); - if (gDebugGL || gDebugPipeline) - { - LLGLState::checkStates(); + if (gDebugGL || gDebugPipeline) + { + LLGLState::checkStates(); + } } } - } - else - { - // Skip all pools of this type - for (iter2 = iter1; iter2 != pools_end; ++iter2) + else { - LLDrawPool *p = *iter2; - if (p->getType() != cur_type) + // Skip all pools of this type + for (iter2 = iter1; iter2 != pools_end; ++iter2) { - break; + LLDrawPool *p = *iter2; + if (p->getType() != cur_type) + { + break; + } } } + iter1 = iter2; + stop_glerror(); } - iter1 = iter2; - stop_glerror(); - } - gGLLastMatrix = NULL; - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.loadMatrix(gGLModelView); + gGLLastMatrix = NULL; + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.loadMatrix(gGLModelView); - gGL.setColorMask(true, false); + gGL.setColorMask(true, false); + + } // Tracy ZoneScoped } void LLPipeline::renderGeomPostDeferred(LLCamera& camera, bool do_occlusion) { - LL_RECORD_BLOCK_TIME(FTM_POST_DEFERRED_POOLS); + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_POST_DEFERRED_POOLS); U32 cur_type = 0; LLGLEnable cull(GL_CULL_FACE); @@ -4861,7 +4817,7 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera, bool do_occlusion) pool_set_t::iterator iter2 = iter1; if (hasRenderType(poolp->getType()) && poolp->getNumPostDeferredPasses() > 0) { - LL_RECORD_BLOCK_TIME(FTM_POST_DEFERRED_POOLRENDER); + LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("deferred poolrender"); //LL_RECORD_BLOCK_TIME(FTM_POST_DEFERRED_POOLRENDER); gGLLastMatrix = NULL; gGL.loadMatrix(gGLModelView); @@ -4922,7 +4878,8 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera, bool do_occlusion) void LLPipeline::renderGeomShadow(LLCamera& camera) { - U32 cur_type = 0; + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; + U32 cur_type = 0; LLGLEnable cull(GL_CULL_FACE); @@ -5003,12 +4960,9 @@ void LLPipeline::renderPhysicsDisplay() gGL.setColorMask(true, false); - if (LLGLSLShader::sNoFixedFunction) - { - gDebugProgram.bind(); - } + gDebugProgram.bind(); - for (LLViewerRegion* region : LLWorld::getInstanceFast()->getRegionList()) + for (LLViewerRegion* region : LLWorld::getInstance()->getRegionList()) { for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) { @@ -5025,11 +4979,7 @@ void LLPipeline::renderPhysicsDisplay() gGL.flush(); - if (LLGLSLShader::sNoFixedFunction) - { - gDebugProgram.unbind(); - } - + gDebugProgram.unbind(); mPhysicsDisplay.flush(); } @@ -5056,13 +5006,10 @@ void LLPipeline::renderDebug() if ( pathfindingCharacter->getVisible() || gAgentCamera.cameraMouselook() ) { - if (LLGLSLShader::sNoFixedFunction) - { - gPathfindingProgram.bind(); - gPathfindingProgram.uniform1f(sTint, 1.f); - gPathfindingProgram.uniform1f(sAmbiance, 1.f); - gPathfindingProgram.uniform1f(sAlphaScale, 1.f); - } + gPathfindingProgram.bind(); + gPathfindingProgram.uniform1f(sTint, 1.f); + gPathfindingProgram.uniform1f(sAmbiance, 1.f); + gPathfindingProgram.uniform1f(sAlphaScale, 1.f); //Requried character physics capsule render parameters LLUUID id; @@ -5071,21 +5018,14 @@ void LLPipeline::renderDebug() if ( pathfindingCharacter->isPhysicsCapsuleEnabled( id, pos, rot ) ) { - if (LLGLSLShader::sNoFixedFunction) - { - //remove blending artifacts - gGL.setColorMask(false, false); - llPathingLibInstance->renderSimpleShapeCapsuleID( gGL, id, pos, rot ); - gGL.setColorMask(true, false); - LLGLEnable blend(GL_BLEND); - gPathfindingProgram.uniform1f(sAlphaScale, 0.90f); - llPathingLibInstance->renderSimpleShapeCapsuleID( gGL, id, pos, rot ); - gPathfindingProgram.bind(); - } - else - { - llPathingLibInstance->renderSimpleShapeCapsuleID( gGL, id, pos, rot ); - } + //remove blending artifacts + gGL.setColorMask(false, false); + llPathingLibInstance->renderSimpleShapeCapsuleID( gGL, id, pos, rot ); + gGL.setColorMask(true, false); + LLGLEnable blend(GL_BLEND); + gPathfindingProgram.uniform1f(sAlphaScale, 0.90f); + llPathingLibInstance->renderSimpleShapeCapsuleID( gGL, id, pos, rot ); + gPathfindingProgram.bind(); } } } @@ -5101,14 +5041,11 @@ void LLPipeline::renderDebug() { F32 ambiance = gSavedSettings.getF32("PathfindingAmbiance"); - if (LLGLSLShader::sNoFixedFunction) - { - gPathfindingProgram.bind(); + gPathfindingProgram.bind(); - gPathfindingProgram.uniform1f(sTint, 1.f); - gPathfindingProgram.uniform1f(sAmbiance, ambiance); - gPathfindingProgram.uniform1f(sAlphaScale, 1.f); - } + gPathfindingProgram.uniform1f(sTint, 1.f); + gPathfindingProgram.uniform1f(sAmbiance, ambiance); + gPathfindingProgram.uniform1f(sAlphaScale, 1.f); if ( !pathfindingConsole->isRenderWorld() ) { @@ -5140,18 +5077,11 @@ void LLPipeline::renderDebug() } //render edges - if (LLGLSLShader::sNoFixedFunction) - { - gPathfindingNoNormalsProgram.bind(); - gPathfindingNoNormalsProgram.uniform1f(sTint, 1.f); - gPathfindingNoNormalsProgram.uniform1f(sAlphaScale, 1.f); - llPathingLibInstance->renderNavMeshEdges(); - gPathfindingProgram.bind(); - } - else - { - llPathingLibInstance->renderNavMeshEdges(); - } + gPathfindingNoNormalsProgram.bind(); + gPathfindingNoNormalsProgram.uniform1f(sTint, 1.f); + gPathfindingNoNormalsProgram.uniform1f(sAlphaScale, 1.f); + llPathingLibInstance->renderNavMeshEdges(); + gPathfindingProgram.bind(); gGL.flush(); glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); @@ -5162,53 +5092,31 @@ void LLPipeline::renderDebug() if ( LLPathfindingPathTool::getInstance()->isRenderPath() ) { //The path - if (LLGLSLShader::sNoFixedFunction) - { - gUIProgram.bind(); - gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep); - llPathingLibInstance->renderPath(); - gPathfindingProgram.bind(); - } - else - { - llPathingLibInstance->renderPath(); - } - //The bookends - if (LLGLSLShader::sNoFixedFunction) - { - //remove blending artifacts - gGL.setColorMask(false, false); - llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_START ); - llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_END ); + gUIProgram.bind(); + gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep); + llPathingLibInstance->renderPath(); + gPathfindingProgram.bind(); + + //The bookends + //remove blending artifacts + gGL.setColorMask(false, false); + llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_START ); + llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_END ); - gGL.setColorMask(true, false); - //render the bookends - LLGLEnable blend(GL_BLEND); - gPathfindingProgram.uniform1f(sAlphaScale, 0.90f); - llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_START ); - llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_END ); - gPathfindingProgram.bind(); - } - else - { - llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_START ); - llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_END ); - } - + gGL.setColorMask(true, false); + //render the bookends + LLGLEnable blend(GL_BLEND); + gPathfindingProgram.uniform1f(sAlphaScale, 0.90f); + llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_START ); + llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_END ); + gPathfindingProgram.bind(); } if ( pathfindingConsole->isRenderWaterPlane() ) { - if (LLGLSLShader::sNoFixedFunction) - { - LLGLEnable blend(GL_BLEND); - gPathfindingProgram.uniform1f(sAlphaScale, 0.90f); - llPathingLibInstance->renderSimpleShapes( gGL, gAgent.getRegion()->getWaterHeight() ); - } - else - { - llPathingLibInstance->renderSimpleShapes( gGL, gAgent.getRegion()->getWaterHeight() ); - } + LLGLEnable blend(GL_BLEND); + gPathfindingProgram.uniform1f(sAlphaScale, 0.90f); + llPathingLibInstance->renderSimpleShapes( gGL, gAgent.getRegion()->getWaterHeight() ); } //physics/exclusion shapes if ( pathfindingConsole->isRenderAnyShapes() ) @@ -5339,18 +5247,11 @@ void LLPipeline::renderDebug() } //render edges - if (LLGLSLShader::sNoFixedFunction) - { - gPathfindingNoNormalsProgram.bind(); - gPathfindingNoNormalsProgram.uniform1f(sTint, gSavedSettings.getF32("PathfindingXRayTint")); - gPathfindingNoNormalsProgram.uniform1f(sAlphaScale, gSavedSettings.getF32("PathfindingXRayOpacity")); - llPathingLibInstance->renderNavMeshEdges(); - gPathfindingProgram.bind(); - } - else - { - llPathingLibInstance->renderNavMeshEdges(); - } + gPathfindingNoNormalsProgram.bind(); + gPathfindingNoNormalsProgram.uniform1f(sTint, gSavedSettings.getF32("PathfindingXRayTint")); + gPathfindingNoNormalsProgram.uniform1f(sAlphaScale, gSavedSettings.getF32("PathfindingXRayOpacity")); + llPathingLibInstance->renderNavMeshEdges(); + gPathfindingProgram.bind(); gGL.flush(); gGL.setLineWidth(1.0f); @@ -5359,10 +5260,7 @@ void LLPipeline::renderDebug() glPolygonOffset(0.f, 0.f); gGL.flush(); - if (LLGLSLShader::sNoFixedFunction) - { - gPathfindingProgram.unbind(); - } + gPathfindingProgram.unbind(); } } } @@ -5377,10 +5275,7 @@ void LLPipeline::renderDebug() if (!hud_only && !mDebugBlips.empty()) { //render debug blips - if (LLGLSLShader::sNoFixedFunction) - { - gUIProgram.bind(); - } + gUIProgram.bind(); gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep, true); @@ -5414,7 +5309,7 @@ void LLPipeline::renderDebug() // Debug stuff. - for (LLViewerRegion* region : LLWorld::getInstanceFast()->getRegionList()) + for (LLViewerRegion* region : LLWorld::getInstance()->getRegionList()) { for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) { @@ -5442,7 +5337,7 @@ void LLPipeline::renderDebug() } } - if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION) && LLGLSLShader::sNoFixedFunction) + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION)) { //render visible selected group occlusion geometry gDebugProgram.bind(); LLGLDepthTest depth(GL_TRUE, GL_FALSE); @@ -5464,44 +5359,38 @@ void LLPipeline::renderDebug() visible_selected_groups.clear(); - if (LLGLSLShader::sNoFixedFunction) - { - gUIProgram.bind(); - } + gUIProgram.bind(); if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_RAYCAST) && !hud_only) { //draw crosshairs on particle intersection if (gDebugRaycastParticle) { - if (LLGLSLShader::sNoFixedFunction) - { //this debug display requires shaders - gDebugProgram.bind(); + gDebugProgram.bind(); - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - LLVector3 center(gDebugRaycastParticleIntersection.getF32ptr()); - LLVector3 size(0.1f, 0.1f, 0.1f); + LLVector3 center(gDebugRaycastParticleIntersection.getF32ptr()); + LLVector3 size(0.1f, 0.1f, 0.1f); - LLVector3 p[6]; + LLVector3 p[6]; - p[0] = center + size.scaledVec(LLVector3(1,0,0)); - p[1] = center + size.scaledVec(LLVector3(-1,0,0)); - p[2] = center + size.scaledVec(LLVector3(0,1,0)); - p[3] = center + size.scaledVec(LLVector3(0,-1,0)); - p[4] = center + size.scaledVec(LLVector3(0,0,1)); - p[5] = center + size.scaledVec(LLVector3(0,0,-1)); + p[0] = center + size.scaledVec(LLVector3(1,0,0)); + p[1] = center + size.scaledVec(LLVector3(-1,0,0)); + p[2] = center + size.scaledVec(LLVector3(0,1,0)); + p[3] = center + size.scaledVec(LLVector3(0,-1,0)); + p[4] = center + size.scaledVec(LLVector3(0,0,1)); + p[5] = center + size.scaledVec(LLVector3(0,0,-1)); - gGL.begin(LLRender::LINES); - gGL.diffuseColor3f(1.f, 1.f, 0.f); - for (U32 i = 0; i < 6; i++) - { - gGL.vertex3fv(p[i].mV); - } - gGL.end(); - gGL.flush(); - - gDebugProgram.unbind(); + gGL.begin(LLRender::LINES); + gGL.diffuseColor3f(1.f, 1.f, 0.f); + for (U32 i = 0; i < 6; i++) + { + gGL.vertex3fv(p[i].mV); } + gGL.end(); + gGL.flush(); + + gDebugProgram.unbind(); } } @@ -5617,8 +5506,8 @@ void LLPipeline::renderDebug() /*gGL.flush(); gGL.setLineWidth(16-i*2); - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstanceFast()->getRegionList().begin(); - iter != LLWorld::getInstanceFast()->getRegionList().end(); ++iter) + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* region = *iter; for (U32 j = 0; j < LLViewerRegion::NUM_PARTITIONS; j++) @@ -5734,17 +5623,12 @@ void LLPipeline::renderDebug() } gGL.flush(); - if (LLGLSLShader::sNoFixedFunction) - { - gUIProgram.unbind(); - } + gUIProgram.unbind(); } -static LLTrace::BlockTimerStatHandle FTM_REBUILD_POOLS("Rebuild Pools"); - void LLPipeline::rebuildPools() { - LL_RECORD_BLOCK_TIME(FTM_REBUILD_POOLS); + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; assertInitialized(); @@ -6088,6 +5972,7 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp ) void LLPipeline::resetDrawOrders() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; assertInitialized(); // Iterate through all of the draw pools and rebuild them. for (LLDrawPool* poolp : mPools) @@ -6105,14 +5990,14 @@ void LLPipeline::setupAvatarLights(bool for_edit) { assertInitialized(); - LLEnvironment& environment = LLEnvironment::instanceFast(); + LLEnvironment& environment = LLEnvironment::instance(); bool sun_up = environment.getIsSunUp(); if (for_edit) { LLColor4 diffuse(1.f, 1.f, 1.f, 0.f); LLVector4a light_pos_cam(-8.f, 0.25f, 10.f, 0.f); // w==0 => directional light - LLMatrix4a camera_rot = LLViewerCamera::getInstanceFast()->getModelview(); + LLMatrix4a camera_rot = LLViewerCamera::getInstance()->getModelview(); camera_rot.extractRotation_affine(); camera_rot.invert(); LLVector4a light_pos; @@ -6399,14 +6284,9 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) { assertInitialized(); - LLEnvironment& environment = LLEnvironment::instanceFast(); + LLEnvironment& environment = LLEnvironment::instance(); const LLSettingsSky::ptr_t& psky = environment.getCurrentSky(); - if (!LLGLSLShader::sNoFixedFunction) - { - gGL.syncMatrices(); - } - // Ambient LLColor4 ambient = psky->getTotalAmbient(); gGL.setAmbientLightColor(ambient); @@ -6528,21 +6408,19 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) continue; } - LLVector3 light_pos(light->getRenderPosition()); - LLVector4 light_pos_gl(light_pos, 1.0f); - - F32 light_radius = llmax(light->getLightRadius(), 0.001f); - F32 size = light_radius * (sRenderDeferred ? 1.5f : 1.0f); + LLVector3 light_pos(light->getRenderPosition()); + LLVector4 light_pos_gl(light_pos, 1.0f); - if (size <= 0.001f) + F32 adjusted_radius = light->getLightRadius() * (sRenderDeferred ? 1.5f : 1.0f); + if (adjusted_radius <= 0.001f) { continue; } - F32 x = (3.f * (1.f + (light->getLightFalloff() * 2.0f))); // why this magic? probably trying to match a historic behavior. - F32 linatten = x / (light_radius); // % of brightness at radius + F32 x = (3.f * (1.f + (light->getLightFalloff() * 2.0f))); // why this magic? probably trying to match a historic behavior. + F32 linatten = x / adjusted_radius; // % of brightness at radius - mHWLightColors[cur_light] = light_color; + mHWLightColors[cur_light] = light_color; LLLightState* light_state = gGL.getLight(cur_light); light_state->setPosition(light_pos_gl); @@ -6551,7 +6429,7 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) light_state->setConstantAttenuation(0.f); if (sRenderDeferred) { - light_state->setLinearAttenuation(size); + light_state->setLinearAttenuation(linatten); light_state->setQuadraticAttenuation(light->getLightFalloff(DEFERRED_LIGHT_FALLOFF) + 1.f); // get falloff to match for forward deferred rendering lights } else @@ -6607,11 +6485,6 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) // prev site of forward (non-deferred) character light injection, removed by SL-13522 09/20 // Init GL state - if (!LLGLSLShader::sNoFixedFunction) - { - glDisable(GL_LIGHTING); - } - for (S32 i = 0; i < 8; ++i) { gGL.getLight(i)->disable(); @@ -6630,13 +6503,6 @@ void LLPipeline::enableLights(U32 mask) if (mLightMask != mask) { stop_glerror(); - if (!mLightMask) - { - if (!LLGLSLShader::sNoFixedFunction) - { - glEnable(GL_LIGHTING); - } - } if (mask) { stop_glerror(); @@ -6656,13 +6522,6 @@ void LLPipeline::enableLights(U32 mask) } stop_glerror(); } - else - { - if (!LLGLSLShader::sNoFixedFunction) - { - glDisable(GL_LIGHTING); - } - } mLightMask = mask; stop_glerror(); } @@ -6713,11 +6572,6 @@ void LLPipeline::enableLightsPreview() { disableLights(); - if (!LLGLSLShader::sNoFixedFunction) - { - glEnable(GL_LIGHTING); - } - LLColor4 ambient = PreviewAmbientColor; gGL.setAmbientLightColor(ambient); @@ -7241,7 +7095,7 @@ LLVOPartGroup* LLPipeline::lineSegmentIntersectParticle(const LLVector4a& start, LLDrawable* drawable = NULL; - for (LLViewerRegion* region : LLWorld::getInstanceFast()->getRegionList()) + for (LLViewerRegion* region : LLWorld::getInstance()->getRegionList()) { LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_PARTICLE); if (part && hasRenderType(part->mDrawableType)) @@ -7290,7 +7144,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector4a& start, sPickAvatar = false; //! LLToolMgr::getInstance()->inBuildMode(); - for (LLViewerRegion* region : LLWorld::getInstanceFast()->getRegionList()) + for (LLViewerRegion* region : LLWorld::getInstance()->getRegionList()) { for (U32 j = 0; j < LLViewerRegion::NUM_PARTITIONS; j++) { @@ -7354,7 +7208,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector4a& start, //check against avatars sPickAvatar = true; - for (LLViewerRegion* region : LLWorld::getInstanceFast()->getRegionList()) + for (LLViewerRegion* region : LLWorld::getInstance()->getRegionList()) { LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_AVATAR); if (part && hasRenderType(part->mDrawableType)) @@ -7432,7 +7286,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInHUD(const LLVector4a& start, c { LLDrawable* drawable = NULL; - for (LLViewerRegion* region : LLWorld::getInstanceFast()->getRegionList()) + for (LLViewerRegion* region : LLWorld::getInstance()->getRegionList()) { bool toggle = false; if (!hasRenderType(LLPipeline::RENDER_TYPE_HUD)) @@ -7494,8 +7348,6 @@ void LLPipeline::resetVertexBuffers() mResetVertexBuffers = true; } -static LLTrace::BlockTimerStatHandle FTM_RESET_VB("Reset VB"); - void LLPipeline::doResetVertexBuffers(bool forced) { if (!mResetVertexBuffers) @@ -7517,7 +7369,7 @@ void LLPipeline::doResetVertexBuffers(bool forced) } } - LL_RECORD_BLOCK_TIME(FTM_RESET_VB); + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; mResetVertexBuffers = false; mForwardVB = nullptr; @@ -7527,10 +7379,11 @@ void LLPipeline::doResetVertexBuffers(bool forced) mDeferredVB = NULL; mCubeVB = NULL; + mDeferredVB = NULL; mALRenderUtil->resetVertexBuffers(); - for (LLViewerRegion* region : LLWorld::getInstanceFast()->getRegionList()) + for (LLViewerRegion* region : LLWorld::getInstance()->getRegionList()) { for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) { @@ -7545,7 +7398,7 @@ void LLPipeline::doResetVertexBuffers(bool forced) { LLSpatialPartition::sTeleportRequested = FALSE; - LLWorld::getInstanceFast()->clearAllVisibleObjects(); + LLWorld::getInstance()->clearAllVisibleObjects(); clearRebuildDrawables(); } @@ -7560,11 +7413,11 @@ void LLPipeline::doResetVertexBuffers(bool forced) LLPathingLib::getInstance()->cleanupVBOManager(); } LLVOPartGroup::destroyGL(); + gGL.resetVertexBuffer(); - gGL.resetVertexBuffers(); SUBSYSTEM_CLEANUP(LLVertexBuffer); - if (LLVertexBuffer::sGLCount > 0) + if (LLVertexBuffer::sGLCount != 0) { LL_WARNS() << "VBO wipe failed -- " << LLVertexBuffer::sGLCount << " buffers remaining." << LL_ENDL; } @@ -7585,8 +7438,10 @@ void LLPipeline::doResetVertexBuffers(bool forced) LLPipeline::sTextureBindTest = gSavedSettings.getBOOL("RenderDebugTextureBind"); LLVertexBuffer::initClass(LLVertexBuffer::sEnableVBOs, LLVertexBuffer::sDisableVBOMapping); + gGL.initVertexBuffer(); - gGL.restoreVertexBuffers(); + mDeferredVB = new LLVertexBuffer(DEFERRED_VB_MASK, 0); + mDeferredVB->allocateBuffer(8, 0, true); LLVOPartGroup::restoreGL(); @@ -7607,32 +7462,91 @@ void LLPipeline::doResetVertexBuffers(bool forced) mALRenderUtil->restoreVertexBuffers(); } -void LLPipeline::renderObjects(U32 type, U32 mask, bool texture, bool batch_texture) +void LLPipeline::renderObjects(U32 type, U32 mask, bool texture, bool batch_texture, bool rigged) { assertInitialized(); gGL.loadMatrix(gGLModelView); gGLLastMatrix = NULL; - mSimplePool->pushBatches(type, mask, texture, batch_texture); + if (rigged) + { + mSimplePool->pushRiggedBatches(type + 1, mask, texture, batch_texture); + } + else + { + mSimplePool->pushBatches(type, mask, texture, batch_texture); + } gGL.loadMatrix(gGLModelView); gGLLastMatrix = NULL; } -void LLPipeline::renderMaskedObjects(U32 type, U32 mask, bool texture, bool batch_texture) +void LLPipeline::renderAlphaObjects(U32 mask, bool texture, bool batch_texture, bool rigged) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; + assertInitialized(); + gGL.loadMatrix(gGLModelView); + gGLLastMatrix = NULL; + U32 type = LLRenderPass::PASS_ALPHA; + LLVOAvatar* lastAvatar = nullptr; + U64 lastMeshId = 0; + for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i) + { + LLDrawInfo* pparams = *i; + if (pparams) + { + if (rigged) + { + if (pparams->mAvatar != nullptr) + { + if (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash) + { + mSimplePool->uploadMatrixPalette(*pparams); + lastAvatar = pparams->mAvatar; + lastMeshId = pparams->mSkinInfo->mHash; + } + + mSimplePool->pushBatch(*pparams, mask | LLVertexBuffer::MAP_WEIGHT4, texture, batch_texture); + } + } + else if (pparams->mAvatar == nullptr) + { + mSimplePool->pushBatch(*pparams, mask, texture, batch_texture); + } + } + } + gGL.loadMatrix(gGLModelView); + gGLLastMatrix = NULL; +} + +void LLPipeline::renderMaskedObjects(U32 type, U32 mask, bool texture, bool batch_texture, bool rigged) { assertInitialized(); gGL.loadMatrix(gGLModelView); gGLLastMatrix = NULL; - mAlphaMaskPool->pushMaskBatches(type, mask, texture, batch_texture); + if (rigged) + { + mAlphaMaskPool->pushRiggedMaskBatches(type+1, mask, texture, batch_texture); + } + else + { + mAlphaMaskPool->pushMaskBatches(type, mask, texture, batch_texture); + } gGL.loadMatrix(gGLModelView); gGLLastMatrix = NULL; } -void LLPipeline::renderFullbrightMaskedObjects(U32 type, U32 mask, bool texture, bool batch_texture) +void LLPipeline::renderFullbrightMaskedObjects(U32 type, U32 mask, bool texture, bool batch_texture, bool rigged) { assertInitialized(); gGL.loadMatrix(gGLModelView); gGLLastMatrix = NULL; - mFullbrightAlphaMaskPool->pushMaskBatches(type, mask, texture, batch_texture); + if (rigged) + { + mFullbrightAlphaMaskPool->pushRiggedMaskBatches(type+1, mask, texture, batch_texture); + } + else + { + mFullbrightAlphaMaskPool->pushMaskBatches(type, mask, texture, batch_texture); + } gGL.loadMatrix(gGLModelView); gGLLastMatrix = NULL; } @@ -7714,11 +7628,8 @@ void LLPipeline::renderFinalize() LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM); if (sRenderGlow) { - { - LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM_FBO); - mGlow[1].bindTarget(); - mGlow[1].clear(); - } + mGlow[1].bindTarget(); + mGlow[1].clear(); gGlowExtractProgram.bind(); F32 minLum = llmax((F32)RenderGlowMinLuminance, 0.0f); @@ -7784,11 +7695,8 @@ void LLPipeline::renderFinalize() for (S32 i = 0; i < kernel; i++) { - { - LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM_FBO); - mGlow[i % 2].bindTarget(); - mGlow[i % 2].clear(); - } + mGlow[i % 2].bindTarget(); + mGlow[i % 2].clear(); gGL.getTexUnit(0)->bind(&mGlow[(i + 1) % 2]); @@ -7843,8 +7751,8 @@ void LLPipeline::renderFinalize() // [/RLVa:KB] if (LLPipeline::sRenderDeferred) { - auto& viewerCamera = LLViewerCamera::instanceFast(); - bool dof_enabled = (RenderDepthOfFieldInEditMode || !LLToolMgr::getInstanceFast()->inBuildMode()) && + auto& viewerCamera = LLViewerCamera::instance(); + bool dof_enabled = (RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) && RenderDepthOfField; bool multisample = RenderFSAASamples > 1 && (mFXAABuffer.isComplete() || (mSMAAEdgeBuffer.isComplete() && mSMAABlendBuffer.isComplete())); @@ -7869,10 +7777,10 @@ void LLPipeline::renderFinalize() LLVector3 focus_point; - LLViewerObject *obj = LLViewerMediaFocus::getInstanceFast()->getFocusedObject(); + LLViewerObject *obj = LLViewerMediaFocus::getInstance()->getFocusedObject(); if (obj && obj->mDrawable && obj->isSelected()) { // focus on selected media object - S32 face_idx = LLViewerMediaFocus::getInstanceFast()->getFocusedFace(); + S32 face_idx = LLViewerMediaFocus::getInstance()->getFocusedFace(); if (obj && obj->mDrawable) { LLFace *face = obj->mDrawable->getFace(face_idx); @@ -7894,7 +7802,7 @@ void LLPipeline::renderFinalize() // </FS:Beq> if (focus_point.isExactlyZero()) { - if (LLViewerJoystick::getInstanceFast()->getOverrideCamera() || LLPipeline::RenderFocusPointFollowsPointer) + if (LLViewerJoystick::getInstance()->getOverrideCamera() || LLPipeline::RenderFocusPointFollowsPointer) { // focus on point under cursor focus_point.set(gDebugRaycastIntersection.getF32ptr()); } @@ -8132,7 +8040,7 @@ void LLPipeline::renderFinalize() if (RlvActions::hasBehaviour(RLV_BHVR_SETSPHERE)) { LLShaderEffectParams params(pRenderBuffer, &mScreen, !multisample); - LLVfxManager::instanceFast().runEffect(EVisualEffect::RlvSphere, ¶ms); + LLVfxManager::instance().runEffect(EVisualEffect::RlvSphere, ¶ms); pRenderBuffer = params.m_pDstBuffer; } // [/RLVa:KB] @@ -8387,7 +8295,7 @@ void LLPipeline::renderFinalize() if (RlvActions::hasBehaviour(RLV_BHVR_SETSPHERE)) { LLShaderEffectParams params(&mScreen, &mDeferredLight, false); - LLVfxManager::instanceFast().runEffect(EVisualEffect::RlvSphere, ¶ms); + LLVfxManager::instance().runEffect(EVisualEffect::RlvSphere, ¶ms); pRenderBuffer = params.m_pDstBuffer; } // [/RLVa:KB] @@ -8421,18 +8329,7 @@ void LLPipeline::renderFinalize() LLGLDisable blend(GL_BLEND); - if (LLGLSLShader::sNoFixedFunction) - { - gGlowCombineProgram.bind(); - } - else - { - // tex unit 0 - gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_COLOR); - // tex unit 1 - gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_ADD, LLTexUnit::TBS_TEX_COLOR, - LLTexUnit::TBS_PREV_COLOR); - } + gGlowCombineProgram.bind(); gGL.getTexUnit(0)->bind(&mGlow[1]); // [RLVa:KB] - @setsphere @@ -8445,28 +8342,14 @@ void LLPipeline::renderFinalize() mForwardVB->setBuffer(mask); mForwardVB->drawArrays(LLRender::TRIANGLE_STRIP, 0, 3); - if (LLGLSLShader::sNoFixedFunction) - { - gGlowCombineProgram.unbind(); - } - else - { - gGL.getTexUnit(1)->disable(); - gGL.getTexUnit(1)->setTextureBlendType(LLTexUnit::TB_MULT); - - gGL.getTexUnit(0)->activate(); - gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); - } + gGlowCombineProgram.unbind(); } gGL.setSceneBlendType(LLRender::BT_ALPHA); if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES)) { - if (LLGLSLShader::sNoFixedFunction) - { - gSplatTextureRectProgram.bind(); - } + gSplatTextureRectProgram.bind(); gGL.setColorMask(true, false); @@ -8492,10 +8375,7 @@ void LLPipeline::renderFinalize() gGL.end(); gGL.flush(); - if (LLGLSLShader::sNoFixedFunction) - { - gSplatTextureRectProgram.unbind(); - } + gSplatTextureRectProgram.unbind(); } if (LLRenderTarget::sUseFBO) @@ -8516,11 +8396,9 @@ void LLPipeline::renderFinalize() LLGLState::checkTextureChannels(); } -static LLTrace::BlockTimerStatHandle FTM_BIND_DEFERRED("Bind Deferred"); - void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_target) { - LL_RECORD_BLOCK_TIME(FTM_BIND_DEFERRED); + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; LLRenderTarget* deferred_target = &mDeferredScreen; LLRenderTarget* deferred_depth_target = &mDeferredDepth; @@ -8657,7 +8535,7 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_ shader.uniform2f(LLShaderMgr::DEFERRED_PROJ_SHADOW_RES, mShadow[4].getWidth(), mShadow[4].getHeight()); //F32 shadow_offset_error = 1.f + RenderShadowOffsetError * fabsf(LLViewerCamera::getInstance()->getOrigin().mV[2]); - F32 shadow_bias_error = RenderShadowBiasError * fabsf(LLViewerCamera::getInstanceFast()->getOrigin().mV[2]) / 3000.f; + F32 shadow_bias_error = RenderShadowBiasError * fabsf(LLViewerCamera::getInstance()->getOrigin().mV[2]) / 3000.f; F32 shadow_bias = RenderShadowBias + shadow_bias_error; shader.uniform1f(LLShaderMgr::DEFERRED_SHADOW_OFFSET, RenderShadowOffset); //*shadow_offset_error); @@ -8700,7 +8578,7 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_ if (shader.getUniformLocation(LLShaderMgr::DEFERRED_NEAR_CLIP) > -1) { - shader.uniform1f(LLShaderMgr::DEFERRED_NEAR_CLIP, LLViewerCamera::getInstanceFast()->getNear() * 2.f); + shader.uniform1f(LLShaderMgr::DEFERRED_NEAR_CLIP, LLViewerCamera::getInstance()->getNear() * 2.f); } shader.uniform3fv(LLShaderMgr::DEFERRED_SUN_DIR, 1, mTransformedSunDir.getF32ptr()); @@ -8716,10 +8594,6 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_ shader.uniform4fv(LLShaderMgr::SUNLIGHT_COLOR, 1, mSunDiffuse.mV); shader.uniform4fv(LLShaderMgr::MOONLIGHT_COLOR, 1, mMoonDiffuse.mV); - - const LLSettingsSky::ptr_t& sky = LLEnvironment::getInstanceFast()->getCurrentSky(); - - static_cast<LLSettingsVOSky*>(sky.get())->updateShader(&shader); } LLColor3 pow3f(LLColor3 v, F32 f) @@ -8738,19 +8612,9 @@ LLVector4 pow4fsrgb(LLVector4 v, F32 f) return v; } -static LLTrace::BlockTimerStatHandle FTM_GI_TRACE("Trace"); -static LLTrace::BlockTimerStatHandle FTM_GI_GATHER("Gather"); -static LLTrace::BlockTimerStatHandle FTM_SUN_SHADOW("Shadow Map"); -static LLTrace::BlockTimerStatHandle FTM_SOFTEN_SHADOW("Shadow Soften"); -static LLTrace::BlockTimerStatHandle FTM_EDGE_DETECTION("Find Edges"); -static LLTrace::BlockTimerStatHandle FTM_LOCAL_LIGHTS("Local Lights"); -static LLTrace::BlockTimerStatHandle FTM_ATMOSPHERICS("Atmospherics"); -static LLTrace::BlockTimerStatHandle FTM_FULLSCREEN_LIGHTS("Fullscreen Lights"); -static LLTrace::BlockTimerStatHandle FTM_PROJECTORS("Projectors"); -static LLTrace::BlockTimerStatHandle FTM_POST("Post"); - void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; if (!sCull) { return; @@ -8762,9 +8626,10 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target) LLRenderTarget *deferred_depth_target = &mDeferredDepth; LLRenderTarget *deferred_light_target = &mDeferredLight; - LLViewerCamera& camera = LLViewerCamera::instanceFast(); + LLViewerCamera& camera = LLViewerCamera::instance(); { + LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("deferred"); //LL_RECORD_BLOCK_TIME(FTM_RENDER_DEFERRED); { LLGLDepthTest depth(GL_TRUE); deferred_depth_target->copyContents(*deferred_target, @@ -8821,7 +8686,7 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target) { deferred_light_target->bindTarget(); { // paint shadow/SSAO light map (direct lighting lightmap) - LL_RECORD_BLOCK_TIME(FTM_SUN_SHADOW); + LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - sun shadow"); bindDeferredShader(gDeferredSunProgram, deferred_light_target); mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); glClearColor(1, 1, 1, 1); @@ -8847,7 +8712,7 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target) if (RenderDeferredSSAO) { // soften direct lighting lightmap - LL_RECORD_BLOCK_TIME(FTM_SOFTEN_SHADOW); + LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - soften shadow"); // blur lightmap mHDRScreen.bindTarget(); glClearColor(1, 1, 1, 1); @@ -8925,7 +8790,7 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target) { // apply sunlight contribution LLGLSLShader &soften_shader = LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram; - LL_RECORD_BLOCK_TIME(FTM_ATMOSPHERICS); + LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - atmospherics"); bindDeferredShader(soften_shader); S32 channel = soften_shader.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredScreen.getUsage()); @@ -8934,7 +8799,7 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target) gGL.getTexUnit(channel)->setTextureColorSpace(LLTexUnit::TCS_SRGB); } - LLEnvironment &environment = LLEnvironment::instanceFast(); + LLEnvironment &environment = LLEnvironment::instance(); soften_shader.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0); soften_shader.uniform4fv(LLShaderMgr::LIGHTNORM, 1, environment.getClampedLightNorm().mV); @@ -9001,6 +8866,7 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target) LLVertexBuffer::unbind(); { + LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - local lights"); bindDeferredShader(gDeferredLightProgram); if (mCubeVB.isNull()) @@ -9073,7 +8939,6 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target) continue; } - LL_RECORD_BLOCK_TIME(FTM_LOCAL_LIGHTS); gDeferredLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c); gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s); gDeferredLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV); @@ -9110,6 +8975,7 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target) if (!spot_lights.empty()) { + LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - projectors"); LLGLDepthTest depth(GL_TRUE, GL_FALSE); bindDeferredShader(gDeferredSpotLightProgram); @@ -9119,7 +8985,6 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target) for (LLDrawable* drawablep : spot_lights) { - LL_RECORD_BLOCK_TIME(FTM_PROJECTORS); LLVOVolume *volume = drawablep->getVOVolume(); @@ -9148,6 +9013,7 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target) } { + LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - fullscreen lights"); LLGLDepthTest depth(GL_FALSE); // full screen blit @@ -9167,7 +9033,6 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target) while (!fullscreen_lights.empty()) { - LL_RECORD_BLOCK_TIME(FTM_FULLSCREEN_LIGHTS); light[count] = fullscreen_lights.front(); fullscreen_lights.pop_front(); col[count] = light_colors.front(); @@ -9199,7 +9064,6 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target) for (LLDrawable* drawablep : fullscreen_spot_lights) { - LL_RECORD_BLOCK_TIME(FTM_PROJECTORS); LLVOVolume *volume = drawablep->getVOVolume(); LLVector4a center; @@ -9642,8 +9506,19 @@ inline float sgn(float a) void LLPipeline::generateWaterReflection(LLCamera& camera_in) { - if (LLPipeline::sWaterReflections && assertInitialized() && LLDrawPoolWater::sNeedsReflectionUpdate) + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; + + if (!assertInitialized()) { + return; + } + + if (LLPipeline::sWaterReflections && LLDrawPoolWater::sNeedsReflectionUpdate) + { + //disable occlusion culling for reflection/refraction passes (save setting to restore later) + S32 occlude = LLPipeline::sUseOcclusion; + LLPipeline::sUseOcclusion = 0; + bool skip_avatar_update = false; if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK || !LLVOAvatar::sVisibleInFirstPerson) { @@ -9653,7 +9528,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) LLCamera camera = camera_in; camera.setFar(camera_in.getFar() * 0.75f); - bool camera_is_underwater = LLViewerCamera::getInstanceFast()->cameraUnderWater(); + bool camera_is_underwater = LLViewerCamera::getInstance()->cameraUnderWater(); LLPipeline::sReflectionRender = true; @@ -9680,26 +9555,19 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) //plane params LLPlane plane; LLVector3 pnorm; - S32 water_clip = 0; - if (!camera_is_underwater) + + if (camera_is_underwater) { - //camera is above water, clip plane points up - pnorm.setVec(0,0,1); - plane.setVec(pnorm, -water_height); - water_clip = 1; + //camera is below water, cull above water + pnorm.setVec(0, 0, 1); } else { - //camera is below water, clip plane points down - pnorm = LLVector3(0,0,-1); - plane.setVec(pnorm, water_height); - water_clip = -1; + //camera is above water, cull below water + pnorm = LLVector3(0, 0, -1); } - S32 occlusion = LLPipeline::sUseOcclusion; - - //disable occlusion culling for reflection map for now - LLPipeline::sUseOcclusion = 0; + plane.setVec(LLVector3(0, 0, water_height), pnorm); if (!camera_is_underwater) { @@ -9800,7 +9668,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) LLGLUserClipPlane clip_plane(plane, mReflectionModelView, saved_projection); LLGLDisable cull(GL_CULL_FACE); - updateCull(camera, mReflectedObjects, -water_clip, &plane); + updateCull(camera, mReflectedObjects, &plane); stateSort(camera, mReflectedObjects); renderGeom(camera); } @@ -9818,8 +9686,6 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) set_current_modelview(saved_modelview); } - //LLPipeline::sUseOcclusion = occlusion; - camera.setOrigin(camera_in.getOrigin()); //render distortion map static bool last_update = true; @@ -9855,10 +9721,14 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) { LLPipeline::sDistortionRender = true; - LLColor3 col = LLEnvironment::getInstanceFast()->getCurrentWater()->getWaterFogColor(); + LLColor3 col = LLEnvironment::getInstance()->getCurrentWater()->getWaterFogColor(); glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f); - LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER1; + // HACK FIX -- pretend underwater camera is the world camera to fix weird visibility artifacts + // during distortion render (doesn't break main render because the camera is the same perspective + // as world camera and occlusion culling is disabled for this pass) + //LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER1; + LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; mWaterDis.bindTarget(); mWaterDis.getViewport(gGLViewport); @@ -9867,41 +9737,47 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) mWaterDis.clear(); gGL.setColorMask(true, false); - F32 water_dist = water_height * LLPipeline::sDistortionWaterClipPlaneMargin; + F32 water_dist = water_height; //clip out geometry on the same side of water as the camera w/ enough margin to not include the water geo itself, // but not so much as to clip out parts of avatars that should be seen under the water in the distortion map - LLPlane plane(-pnorm, water_dist); + LLPlane plane; + + if (camera_is_underwater) + { + //nudge clip plane below water to avoid visible holes in objects intersecting water surface + water_dist /= LLPipeline::sDistortionWaterClipPlaneMargin; + //camera is below water, clip plane points up + pnorm.setVec(0, 0, -1); + } + else + { + //nudge clip plane above water to avoid visible holes in objects intersecting water surface + water_dist *= LLPipeline::sDistortionWaterClipPlaneMargin; + //camera is above water, clip plane points down + pnorm = LLVector3(0, 0, 1); + } + + plane.setVec(LLVector3(0, 0, water_dist), pnorm); + LLGLUserClipPlane clip_plane(plane, saved_modelview, saved_projection); gGL.setColorMask(true, true); mWaterDis.clear(); gGL.setColorMask(true, false); - // ignore clip plane if we're underwater and viewing distortion map of objects above waterline - if (camera_is_underwater) - { - clip_plane.disable(); - } - if (reflection_detail >= WATER_REFLECT_NONE_WATER_TRANSPARENT) { - updateCull(camera, mRefractedObjects, water_clip, &plane); + updateCull(camera, mRefractedObjects, &plane); stateSort(camera, mRefractedObjects); renderGeom(camera); } - if (LLGLSLShader::sNoFixedFunction) - { - gUIProgram.bind(); - } + gUIProgram.bind(); - LLWorld::getInstanceFast()->renderPropertyLines(); + LLWorld::getInstance()->renderPropertyLines(); - if (LLGLSLShader::sNoFixedFunction) - { - gUIProgram.unbind(); - } + gUIProgram.unbind(); mWaterDis.flush(); } @@ -9914,7 +9790,6 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) gPipeline.popRenderTypeMask(); - LLPipeline::sUseOcclusion = occlusion; LLPipeline::sUnderWaterRender = false; LLPipeline::sReflectionRender = false; @@ -9936,6 +9811,32 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) } LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; + + // restore occlusion culling + LLPipeline::sUseOcclusion = occlude; + } + else + { + // Initial sky pass is still needed even if water reflection is not rendering + bool camera_is_underwater = LLViewerCamera::getInstance()->cameraUnderWater(); + if (!camera_is_underwater) + { + gPipeline.pushRenderTypeMask(); + { + gPipeline.andRenderTypeMask( + LLPipeline::RENDER_TYPE_SKY, + LLPipeline::RENDER_TYPE_WL_SKY, + LLPipeline::END_RENDER_TYPES); + + LLCamera camera = camera_in; + camera.setFar(camera_in.getFar() * 0.75f); + + updateCull(camera, mSky); + stateSort(camera, mSky); + renderGeom(camera, TRUE); + } + gPipeline.popRenderTypeMask(); + } } } @@ -9952,200 +9853,208 @@ static LLTrace::BlockTimerStatHandle FTM_SHADOW_FULLBRIGHT_ALPHA_MASKED("Fullbri void LLPipeline::renderShadow(const LLMatrix4a& view, const LLMatrix4a& proj, LLCamera& shadow_cam, LLCullResult &result, bool use_shader, bool use_occlusion, U32 target_width) { - LL_RECORD_BLOCK_TIME(FTM_SHADOW_RENDER); + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; //LL_RECORD_BLOCK_TIME(FTM_SHADOW_RENDER); - //clip out geometry on the same side of water as the camera - S32 occlude = LLPipeline::sUseOcclusion; - if (!use_occlusion) - { - LLPipeline::sUseOcclusion = 0; - } - LLPipeline::sShadowRender = true; - - static const U32 types[] = { - LLRenderPass::PASS_SIMPLE, - LLRenderPass::PASS_FULLBRIGHT, - LLRenderPass::PASS_SHINY, - LLRenderPass::PASS_BUMP, - LLRenderPass::PASS_FULLBRIGHT_SHINY , - LLRenderPass::PASS_MATERIAL, - LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, - LLRenderPass::PASS_SPECMAP, - LLRenderPass::PASS_SPECMAP_EMISSIVE, - LLRenderPass::PASS_NORMMAP, - LLRenderPass::PASS_NORMMAP_EMISSIVE, - LLRenderPass::PASS_NORMSPEC, - LLRenderPass::PASS_NORMSPEC_EMISSIVE, - }; + //disable occlusion culling for shadow passes (save setting to restore later) + S32 occlude = LLPipeline::sUseOcclusion; + if (!use_occlusion) + { + LLPipeline::sUseOcclusion = 0; + } + LLPipeline::sShadowRender = true; + + static const U32 types[] = { + LLRenderPass::PASS_SIMPLE, + LLRenderPass::PASS_FULLBRIGHT, + LLRenderPass::PASS_SHINY, + LLRenderPass::PASS_BUMP, + LLRenderPass::PASS_FULLBRIGHT_SHINY , + LLRenderPass::PASS_MATERIAL, + LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, + LLRenderPass::PASS_SPECMAP, + LLRenderPass::PASS_SPECMAP_EMISSIVE, + LLRenderPass::PASS_NORMMAP, + LLRenderPass::PASS_NORMMAP_EMISSIVE, + LLRenderPass::PASS_NORMSPEC, + LLRenderPass::PASS_NORMSPEC_EMISSIVE, + }; + + LLGLEnable cull(GL_CULL_FACE); + + //enable depth clamping if available + //LLGLEnable depth_clamp(gGLManager.mHasDepthClamp ? GL_DEPTH_CLAMP : 0); - LLGLEnable cull(GL_CULL_FACE); + if (use_shader) + { + gDeferredShadowCubeProgram.bind(); + } - //enable depth clamping if available - //LLGLEnable depth_clamp(gGLManager.mHasDepthClamp ? GL_DEPTH_CLAMP : 0); + LLRenderTarget& occlusion_target = mShadowOcclusion[LLViewerCamera::sCurCameraID - 1]; - if (use_shader) - { - gDeferredShadowCubeProgram.bind(); - } + occlusion_target.bindTarget(); + updateCull(shadow_cam, result); + occlusion_target.flush(); - LLRenderTarget& occlusion_target = mShadowOcclusion[LLViewerCamera::sCurCameraID-1]; + stateSort(shadow_cam, result); - occlusion_target.bindTarget(); - updateCull(shadow_cam, result); - occlusion_target.flush(); - stateSort(shadow_cam, result); - - - //generate shadow map - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.pushMatrix(); + //generate shadow map + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.pushMatrix(); gGL.loadMatrix(proj); - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.pushMatrix(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.pushMatrix(); gGL.loadMatrix(view); - stop_glerror(); - gGLLastMatrix = NULL; + stop_glerror(); + gGLLastMatrix = NULL; - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - stop_glerror(); - - LLEnvironment& environment = LLEnvironment::instanceFast(); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - LLVertexBuffer::unbind(); + stop_glerror(); - { - if (!use_shader) - { //occlusion program is general purpose depth-only no-textures - gOcclusionProgram.bind(); - } - else - { - gDeferredShadowProgram.bind(); - gDeferredShadowProgram.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0); - } + LLEnvironment& environment = LLEnvironment::instance(); + + LLVertexBuffer::unbind(); + + for (int j = 0; j < 2; ++j) // 0 -- static, 1 -- rigged + { + bool rigged = j == 1; + if (!use_shader) + { //occlusion program is general purpose depth-only no-textures + gOcclusionProgram.bind(rigged); + } + else + { + gDeferredShadowProgram.bind(rigged); + LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0); + } - gGL.diffuseColor4f(1,1,1,1); + gGL.diffuseColor4f(1, 1, 1, 1); // if not using VSM, disable color writes if (LLPipeline::RenderShadowDetail <= 2) { - gGL.setColorMask(false, false); + gGL.setColorMask(false, false); } - - LL_RECORD_BLOCK_TIME(FTM_SHADOW_SIMPLE); - - gGL.getTexUnit(0)->disable(); - for (U32 i = 0; i < sizeof(types)/sizeof(U32); ++i) - { - renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE); - } - gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); - if (!use_shader) - { - gOcclusionProgram.unbind(); - } - } - - if (use_shader) - { - LL_RECORD_BLOCK_TIME(FTM_SHADOW_GEOM); - gDeferredShadowProgram.unbind(); - renderGeomShadow(shadow_cam); - gDeferredShadowProgram.bind(); - gDeferredShadowProgram.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0); - } - else - { - LL_RECORD_BLOCK_TIME(FTM_SHADOW_GEOM); + LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow simple"); //LL_RECORD_BLOCK_TIME(FTM_SHADOW_SIMPLE); - renderGeomShadow(shadow_cam); - } + gGL.getTexUnit(0)->disable(); + for (U32 i = 0; i < sizeof(types) / sizeof(U32); ++i) + { + renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE, FALSE, rigged); + } + gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); + if (!use_shader) + { + gOcclusionProgram.unbind(); + } - { - LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA); - gDeferredShadowAlphaMaskProgram.bind(); - gDeferredShadowAlphaMaskProgram.uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width); - gDeferredShadowAlphaMaskProgram.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0); + } - U32 mask = LLVertexBuffer::MAP_VERTEX | - LLVertexBuffer::MAP_TEXCOORD0 | - LLVertexBuffer::MAP_COLOR | - LLVertexBuffer::MAP_TEXTURE_INDEX; + if (use_shader) + { + LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow geom"); //LL_RECORD_BLOCK_TIME(FTM_SHADOW_GEOM); - { - LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA_MASKED); - renderMaskedObjects(LLRenderPass::PASS_ALPHA_MASK, mask, TRUE, TRUE); - } + gDeferredShadowProgram.unbind(); + renderGeomShadow(shadow_cam); + gDeferredShadowProgram.bind(); + gDeferredShadowProgram.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0); + } + else + { + LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow geom"); //LL_RECORD_BLOCK_TIME(FTM_SHADOW_GEOM); - { - LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA_BLEND); - gDeferredShadowAlphaMaskProgram.setMinimumAlpha(0.598f); - renderObjects(LLRenderPass::PASS_ALPHA, mask, TRUE, TRUE); - } + renderGeomShadow(shadow_cam); + } + + { + LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha"); //LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA); + for (int i = 0; i < 2; ++i) { - LL_RECORD_BLOCK_TIME(FTM_SHADOW_FULLBRIGHT_ALPHA_MASKED); - gDeferredShadowFullbrightAlphaMaskProgram.bind(); - gDeferredShadowFullbrightAlphaMaskProgram.uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width); - gDeferredShadowFullbrightAlphaMaskProgram.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0); - renderFullbrightMaskedObjects(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, mask, TRUE, TRUE); - } + bool rigged = i == 1; - mask = mask & ~LLVertexBuffer::MAP_TEXTURE_INDEX; + gDeferredShadowAlphaMaskProgram.bind(rigged); + LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width); + LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0); - { - LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA_TREE); - gDeferredTreeShadowProgram.bind(); - gDeferredTreeShadowProgram.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0); - renderMaskedObjects(LLRenderPass::PASS_NORMSPEC_MASK, mask); - renderMaskedObjects(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, mask); - renderMaskedObjects(LLRenderPass::PASS_SPECMAP_MASK, mask); - renderMaskedObjects(LLRenderPass::PASS_NORMMAP_MASK, mask); + U32 mask = LLVertexBuffer::MAP_VERTEX | + LLVertexBuffer::MAP_TEXCOORD0 | + LLVertexBuffer::MAP_COLOR | + LLVertexBuffer::MAP_TEXTURE_INDEX; + + { + LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha masked"); //LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA_MASKED); + renderMaskedObjects(LLRenderPass::PASS_ALPHA_MASK, mask, TRUE, TRUE, rigged); + } + + { + LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha blend"); //LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA_BLEND); + LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(0.598f); + renderAlphaObjects(mask, TRUE, TRUE, rigged); + } + + + { + LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow fullbright alpha masked"); //LL_RECORD_BLOCK_TIME(FTM_SHADOW_FULLBRIGHT_ALPHA_MASKED); + gDeferredShadowFullbrightAlphaMaskProgram.bind(rigged); + LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width); + LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0); + renderFullbrightMaskedObjects(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, mask, TRUE, TRUE, rigged); + } + + + { + LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha grass"); //LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA_GRASS); + gDeferredTreeShadowProgram.bind(rigged); + if (i == 0) + { + LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(0.598f); + renderObjects(LLRenderPass::PASS_GRASS, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, TRUE); + } + + U32 no_idx_mask = mask & ~LLVertexBuffer::MAP_TEXTURE_INDEX; + renderMaskedObjects(LLRenderPass::PASS_NORMSPEC_MASK, no_idx_mask, true, false, rigged); + renderMaskedObjects(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, no_idx_mask, true, false, rigged); + renderMaskedObjects(LLRenderPass::PASS_SPECMAP_MASK, no_idx_mask, true, false, rigged); + renderMaskedObjects(LLRenderPass::PASS_NORMMAP_MASK, no_idx_mask, true, false, rigged); + } } - - { - LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA_GRASS); - gDeferredTreeShadowProgram.setMinimumAlpha(0.598f); - renderObjects(LLRenderPass::PASS_GRASS, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, TRUE); - } } - //glCullFace(GL_BACK); + //glCullFace(GL_BACK); - gDeferredShadowCubeProgram.bind(); - gGLLastMatrix = NULL; - gGL.loadMatrix(gGLModelView); + gDeferredShadowCubeProgram.bind(); + gGLLastMatrix = NULL; + gGL.loadMatrix(gGLModelView); - LLRenderTarget& occlusion_source = mShadow[LLViewerCamera::sCurCameraID-1]; + LLRenderTarget& occlusion_source = mShadow[LLViewerCamera::sCurCameraID - 1]; - doOcclusion(shadow_cam, occlusion_source, occlusion_target); + doOcclusion(shadow_cam, occlusion_source, occlusion_target); - if (use_shader) - { - gDeferredShadowProgram.unbind(); - } - - gGL.setColorMask(true, true); - - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.popMatrix(); - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.popMatrix(); - gGLLastMatrix = NULL; + if (use_shader) + { + gDeferredShadowProgram.unbind(); + } + + gGL.setColorMask(true, true); + + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.popMatrix(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.popMatrix(); + gGLLastMatrix = NULL; - LLPipeline::sUseOcclusion = occlude; - LLPipeline::sShadowRender = false; + LLPipeline::sUseOcclusion = occlude; + LLPipeline::sShadowRender = false; } -static LLTrace::BlockTimerStatHandle FTM_VISIBLE_CLOUD("Visible Cloud"); bool LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector3& max, std::vector<LLVector3>& fp, LLVector3 light_dir) { - LL_RECORD_BLOCK_TIME(FTM_VISIBLE_CLOUD); + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; //get point cloud of intersection of frust and min, max if (getVisibleExtents(camera, min, max)) @@ -10357,10 +10266,7 @@ void LLPipeline::generateHighlight(LLCamera& camera) gGL.setColorMask(true, true); mHighlight.clear(); - if (LLGLSLShader::sNoFixedFunction) - { - gHighlightProgram.bind(); - } + gHighlightProgram.bind(); gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep); for (std::set<HighlightItem>::iterator iter = mHighlightSet.begin(); iter != mHighlightSet.end(); ) @@ -10402,9 +10308,6 @@ LLRenderTarget* LLPipeline::getShadowTarget(U32 i) } static LLTrace::BlockTimerStatHandle FTM_GEN_SUN_SHADOW("Gen Sun Shadow"); -static LLTrace::BlockTimerStatHandle FTM_GEN_SUN_SHADOW_SETUP("Sun Shadow Setup"); -static LLTrace::BlockTimerStatHandle FTM_GEN_SUN_SHADOW_RENDER_DIRECTIONAL("Render Dir"); -static LLTrace::BlockTimerStatHandle FTM_GEN_SUN_SHADOW_SPOT_SETUP("Spot Shadow Setup"); static LLTrace::BlockTimerStatHandle FTM_GEN_SUN_SHADOW_SPOT_RENDER("Spot Shadow Render"); void LLPipeline::generateSunShadow(LLCamera& camera) @@ -10414,7 +10317,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera) return; } - LL_RECORD_BLOCK_TIME(FTM_GEN_SUN_SHADOW); + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; //LL_RECORD_BLOCK_TIME(FTM_GEN_SUN_SHADOW); bool skip_avatar_update = false; if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK || !LLVOAvatar::sVisibleInFirstPerson) @@ -10469,11 +10372,34 @@ void LLPipeline::generateSunShadow(LLCamera& camera) LLPipeline::RENDER_TYPE_PASS_NORMSPEC_BLEND, LLPipeline::RENDER_TYPE_PASS_NORMSPEC_MASK, LLPipeline::RENDER_TYPE_PASS_NORMSPEC_EMISSIVE, + LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK_RIGGED, + LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK_RIGGED, + LLPipeline::RENDER_TYPE_PASS_SIMPLE_RIGGED, + LLPipeline::RENDER_TYPE_PASS_BUMP_RIGGED, + LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_RIGGED, + LLPipeline::RENDER_TYPE_PASS_SHINY_RIGGED, + LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY_RIGGED, + LLPipeline::RENDER_TYPE_PASS_MATERIAL_RIGGED, + LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA_RIGGED, + LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA_MASK_RIGGED, + LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA_EMISSIVE_RIGGED, + LLPipeline::RENDER_TYPE_PASS_SPECMAP_RIGGED, + LLPipeline::RENDER_TYPE_PASS_SPECMAP_BLEND_RIGGED, + LLPipeline::RENDER_TYPE_PASS_SPECMAP_MASK_RIGGED, + LLPipeline::RENDER_TYPE_PASS_SPECMAP_EMISSIVE_RIGGED, + LLPipeline::RENDER_TYPE_PASS_NORMMAP_RIGGED, + LLPipeline::RENDER_TYPE_PASS_NORMMAP_BLEND_RIGGED, + LLPipeline::RENDER_TYPE_PASS_NORMMAP_MASK_RIGGED, + LLPipeline::RENDER_TYPE_PASS_NORMMAP_EMISSIVE_RIGGED, + LLPipeline::RENDER_TYPE_PASS_NORMSPEC_RIGGED, + LLPipeline::RENDER_TYPE_PASS_NORMSPEC_BLEND_RIGGED, + LLPipeline::RENDER_TYPE_PASS_NORMSPEC_MASK_RIGGED, + LLPipeline::RENDER_TYPE_PASS_NORMSPEC_EMISSIVE_RIGGED, END_RENDER_TYPES); gGL.setColorMask(false, false); - LLEnvironment& environment = LLEnvironment::instanceFast(); + LLEnvironment& environment = LLEnvironment::instance(); //get sun view matrix @@ -11160,17 +11086,28 @@ void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, bool textu } } -static LLTrace::BlockTimerStatHandle FTM_IMPOSTOR_MARK_VISIBLE("Impostor Mark Visible"); -static LLTrace::BlockTimerStatHandle FTM_IMPOSTOR_SETUP("Impostor Setup"); -static LLTrace::BlockTimerStatHandle FTM_IMPOSTOR_BACKGROUND("Impostor Background"); -static LLTrace::BlockTimerStatHandle FTM_IMPOSTOR_ALLOCATE("Impostor Allocate"); -static LLTrace::BlockTimerStatHandle FTM_IMPOSTOR_RESIZE("Impostor Resize"); +void LLPipeline::renderRiggedGroups(LLRenderPass* pass, U32 type, U32 mask, bool texture) +{ + for (LLCullResult::sg_iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i) + { + LLSpatialGroup* group = *i; + if (!group->isDead() && + (!sUseOcclusion || !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) && + gPipeline.hasRenderType(group->getSpatialPartition()->mDrawableType) && + group->mDrawMap.find(type) != group->mDrawMap.end()) + { + pass->renderRiggedGroup(group, type, mask, texture); + } + } +} + +static LLTrace::BlockTimerStatHandle FTM_GENERATE_IMPOSTOR("Generate Impostor"); -void LLPipeline::generateImpostor(LLVOAvatar* avatar) +void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar) { + LL_RECORD_BLOCK_TIME(FTM_GENERATE_IMPOSTOR); LLGLState::checkStates(); LLGLState::checkTextureChannels(); - LLGLState::checkClientArrays(); static LLCullResult result; result.clear(); @@ -11187,13 +11124,14 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) assertInitialized(); - bool visually_muted = avatar->isVisuallyMuted(); + // previews can't be muted or impostered + bool visually_muted = !preview_avatar && avatar->isVisuallyMuted(); #ifdef SHOW_DEBUG LL_DEBUGS_ONCE("AvatarRenderPipeline") << "Avatar " << avatar->getID() << " is " << ( visually_muted ? "" : "not ") << "visually muted" << LL_ENDL; #endif - bool too_complex = avatar->isTooComplex(); + bool too_complex = !preview_avatar && avatar->isTooComplex(); #ifdef SHOW_DEBUG LL_DEBUGS_ONCE("AvatarRenderPipeline") << "Avatar " << avatar->getID() << " is " << ( too_complex ? "" : "not ") << "too complex" @@ -11204,37 +11142,31 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) if (visually_muted || too_complex) { + // only show jelly doll geometry andRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, LLPipeline::RENDER_TYPE_CONTROL_AV, END_RENDER_TYPES); } else { - andRenderTypeMask(LLPipeline::RENDER_TYPE_ALPHA, - LLPipeline::RENDER_TYPE_FULLBRIGHT, - LLPipeline::RENDER_TYPE_VOLUME, - LLPipeline::RENDER_TYPE_GLOW, - LLPipeline::RENDER_TYPE_BUMP, - LLPipeline::RENDER_TYPE_PASS_SIMPLE, - LLPipeline::RENDER_TYPE_PASS_ALPHA, - LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK, - LLPipeline::RENDER_TYPE_PASS_BUMP, - LLPipeline::RENDER_TYPE_PASS_POST_BUMP, - LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT, - LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK, - LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY, - LLPipeline::RENDER_TYPE_PASS_GLOW, - LLPipeline::RENDER_TYPE_PASS_GRASS, - LLPipeline::RENDER_TYPE_PASS_SHINY, - LLPipeline::RENDER_TYPE_PASS_INVISIBLE, - LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY, - LLPipeline::RENDER_TYPE_AVATAR, - LLPipeline::RENDER_TYPE_CONTROL_AV, - LLPipeline::RENDER_TYPE_ALPHA_MASK, - LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK, - LLPipeline::RENDER_TYPE_INVISIBLE, - LLPipeline::RENDER_TYPE_SIMPLE, - END_RENDER_TYPES); + //hide world geometry + clearRenderTypeMask( + RENDER_TYPE_SKY, + RENDER_TYPE_WL_SKY, + RENDER_TYPE_GROUND, + RENDER_TYPE_TERRAIN, + RENDER_TYPE_GRASS, + RENDER_TYPE_CONTROL_AV, // Animesh + RENDER_TYPE_TREE, + RENDER_TYPE_VOIDWATER, + RENDER_TYPE_WATER, + RENDER_TYPE_PASS_GRASS, + RENDER_TYPE_HUD, + RENDER_TYPE_PARTICLES, + RENDER_TYPE_CLOUDS, + RENDER_TYPE_HUD_PARTICLES, + END_RENDER_TYPES + ); } S32 occlusion = sUseOcclusion; @@ -11245,30 +11177,53 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) sShadowRender = true; sImpostorRender = true; - LLViewerCamera& viewer_camera = LLViewerCamera::instanceFast(); + LLViewerCamera& viewer_camera = LLViewerCamera::instance(); { - LL_RECORD_BLOCK_TIME(FTM_IMPOSTOR_MARK_VISIBLE); markVisible(avatar->mDrawable, viewer_camera); + if (preview_avatar) + { + // Only show rigged attachments for preview #if SLOW_ATTACHMENT_LIST - for (const auto& attach_pair : avatar->mAttachmentPoints) - { - LLViewerJointAttachment *attachment = attach_pair.second; - for (LLViewerObject* attached_object : attachment->mAttachedObjects) - { - if (attached_object) + for (const auto& attach_pair : avatar->mAttachmentPoints) + { + LLViewerJointAttachment *attachment = attach_pair.second; + for (LLViewerObject* attached_object : attachment->mAttachedObjects) + { #else - for(auto attachment_iter = avatar->mAttachedObjectsVector.begin(), attachment_end = avatar->mAttachedObjectsVector.end(); - attachment_iter != attachment_end;++attachment_iter) - {{ - if (LLViewerObject* attached_object = attachment_iter->first) + for(auto attachment_iter = avatar->mAttachedObjectsVector.begin(), attachment_end = avatar->mAttachedObjectsVector.end(); + attachment_iter != attachment_end;++attachment_iter) + {{ + LLViewerObject* attached_object = attachment_iter->first; #endif - { - markVisible(attached_object->mDrawable->getSpatialBridge(), viewer_camera); - } - } - } + if (attached_object && attached_object->isRiggedMesh()) + { + markVisible(attached_object->mDrawable->getSpatialBridge(), viewer_camera); + } + } + } + } + else + { + LLVOAvatar::attachment_map_t::iterator iter; + for (iter = avatar->mAttachmentPoints.begin(); + iter != avatar->mAttachmentPoints.end(); + ++iter) + { + LLViewerJointAttachment *attachment = iter->second; + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) + { + LLViewerObject* attached_object = attachment_iter->get(); + if (attached_object) + { + markVisible(attached_object->mDrawable->getSpatialBridge(), viewer_camera); + } + } + } + } } stateSort(viewer_camera, result); @@ -11278,8 +11233,8 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) U32 resY = 0; U32 resX = 0; + if (!preview_avatar) { - LL_RECORD_BLOCK_TIME(FTM_IMPOSTOR_SETUP); const LLVector4a* ext = avatar->mDrawable->getSpatialExtents(); LLVector3 pos(avatar->getRenderPosition()+avatar->getImpostorOffset()); @@ -11336,17 +11291,11 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) if (!avatar->mImpostor.isComplete()) { - LL_RECORD_BLOCK_TIME(FTM_IMPOSTOR_ALLOCATE); - + avatar->mImpostor.allocate(resX, resY, GL_RGBA, TRUE, FALSE); if (LLPipeline::sRenderDeferred) { - avatar->mImpostor.allocate(resX,resY,GL_SRGB8_ALPHA8,TRUE,FALSE); - addDeferredAttachments(avatar->mImpostor); - } - else - { - avatar->mImpostor.allocate(resX,resY,GL_RGBA,TRUE,FALSE); + addDeferredAttachments(avatar->mImpostor, true); } gGL.getTexUnit(0)->bind(&avatar->mImpostor); @@ -11355,7 +11304,6 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) } else if(resX != avatar->mImpostor.getWidth() || resY != avatar->mImpostor.getHeight()) { - LL_RECORD_BLOCK_TIME(FTM_IMPOSTOR_RESIZE); avatar->mImpostor.resize(resX,resY); } @@ -11369,7 +11317,20 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) LLDrawPoolAvatar::sMinimumAlpha = 0.f; } - if (LLPipeline::sRenderDeferred) + if (preview_avatar) + { + // previews don't care about imposters + if (LLPipeline::sRenderDeferred) + { + renderGeomDeferred(camera); + renderGeomPostDeferred(camera); + } + else + { + renderGeom(camera); + } + } + else if (LLPipeline::sRenderDeferred) { avatar->mImpostor.clear(); renderGeomDeferred(camera); @@ -11417,10 +11378,10 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) LLDrawPoolAvatar::sMinimumAlpha = old_alpha; { //create alpha mask based on depth buffer (grey out if muted) - LL_RECORD_BLOCK_TIME(FTM_IMPOSTOR_BACKGROUND); if (LLPipeline::sRenderDeferred) { GLuint buff = GL_COLOR_ATTACHMENT0; + LL_PROFILER_GPU_ZONEC( "gl.DrawBuffersARB", 0x8000FF ); glDrawBuffers(1, &buff); } @@ -11449,11 +11410,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) static const F32 clip_plane = 0.99999f; - if (LLGLSLShader::sNoFixedFunction) - { - gDebugProgram.bind(); - } - + gDebugProgram.bind(); if (visually_muted) { // Visually muted avatar @@ -11463,7 +11420,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) #endif gGL.diffuseColor4fv( muted_color.mV ); } - else + else if (!preview_avatar) { //grey muted avatar #ifdef SHOW_DEBUG LL_DEBUGS_ONCE("AvatarRenderPipeline") << "Avatar " << avatar->getID() << " MUTED set grey" << LL_ENDL; @@ -11471,7 +11428,6 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) gGL.diffuseColor4fv(LLColor4::pink.mV ); } - { gGL.begin(LLRender::TRIANGLE_STRIP); gGL.vertex3f(-1, -1, clip_plane); gGL.vertex3f(1, -1, clip_plane); @@ -11479,21 +11435,19 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) gGL.vertex3f(1, 1, clip_plane); gGL.end(); gGL.flush(); - } - if (LLGLSLShader::sNoFixedFunction) - { - gDebugProgram.unbind(); - } + gDebugProgram.unbind(); gGL.popMatrix(); gGL.matrixMode(LLRender::MM_MODELVIEW); gGL.popMatrix(); } - avatar->mImpostor.flush(); - - avatar->setImpostorDim(tdim); + if (!preview_avatar) + { + avatar->mImpostor.flush(); + avatar->setImpostorDim(tdim); + } sUseOcclusion = occlusion; sReflectionRender = false; @@ -11506,14 +11460,16 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) gGL.matrixMode(LLRender::MM_MODELVIEW); gGL.popMatrix(); - avatar->mNeedsImpostorUpdate = FALSE; - avatar->cacheImpostorValues(); - avatar->mLastImpostorUpdateFrameTime = gFrameTimeSeconds; + if (!preview_avatar) + { + avatar->mNeedsImpostorUpdate = FALSE; + avatar->cacheImpostorValues(); + avatar->mLastImpostorUpdateFrameTime = gFrameTimeSeconds; + } LLVertexBuffer::unbind(); LLGLState::checkStates(); LLGLState::checkTextureChannels(); - LLGLState::checkClientArrays(); } bool LLPipeline::hasRenderBatches(const U32 type) const @@ -11541,6 +11497,16 @@ LLCullResult::sg_iterator LLPipeline::endAlphaGroups() return sCull->endAlphaGroups(); } +LLCullResult::sg_iterator LLPipeline::beginRiggedAlphaGroups() +{ + return sCull->beginRiggedAlphaGroups(); +} + +LLCullResult::sg_iterator LLPipeline::endRiggedAlphaGroups() +{ + return sCull->endRiggedAlphaGroups(); +} + bool LLPipeline::hasRenderType(const U32 type) const { // STORM-365 : LLViewerJointAttachment::setAttachmentVisibility() is setting type to 0 to actually mean "do not render" diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index bd36a31ae94c67afbd38b996b9cc7db3f00cf856..afae90d3edcabeadfcc64309266e553fa53e7797 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -68,7 +68,6 @@ bool setup_hud_matrices(const LLRect& screen_region); // specify portion of scre extern LLTrace::BlockTimerStatHandle FTM_RENDER_GEOMETRY; extern LLTrace::BlockTimerStatHandle FTM_RENDER_GRASS; extern LLTrace::BlockTimerStatHandle FTM_RENDER_INVISIBLE; -extern LLTrace::BlockTimerStatHandle FTM_RENDER_OCCLUSION; extern LLTrace::BlockTimerStatHandle FTM_RENDER_SHINY; extern LLTrace::BlockTimerStatHandle FTM_RENDER_SIMPLE; extern LLTrace::BlockTimerStatHandle FTM_RENDER_TERRAIN; @@ -89,8 +88,6 @@ extern LLTrace::BlockTimerStatHandle FTM_CLIENT_COPY; extern LLTrace::BlockTimerStatHandle FTM_RENDER_UI_HUD; extern LLTrace::BlockTimerStatHandle FTM_RENDER_UI_3D; extern LLTrace::BlockTimerStatHandle FTM_RENDER_UI_2D; -extern LLTrace::BlockTimerStatHandle FTM_RENDER_UI_DEBUG_TEXT; -extern LLTrace::BlockTimerStatHandle FTM_RENDER_UI_SCENE_MON; class LLPipeline { @@ -139,7 +136,7 @@ class LLPipeline void allocatePhysicsBuffer(); void resetVertexBuffers(LLDrawable* drawable); - void generateImpostor(LLVOAvatar* avatar); + void generateImpostor(LLVOAvatar* avatar, bool preview_avatar = false); void bindScreenToTexture(); void renderFinalize(); @@ -230,9 +227,7 @@ class LLPipeline S32 getLightingDetail() const { return mLightingDetail; } S32 getMaxLightingDetail() const; - void setUseVertexShaders(bool use_shaders); - bool getUseVertexShaders() const { return mVertexShadersEnabled; } - bool canUseVertexShaders(); + bool shadersLoaded(); bool canUseWindLightShaders() const; bool canUseWindLightShadersOnObjects() const; bool canUseAntiAliasing() const; @@ -247,7 +242,7 @@ class LLPipeline bool visibleObjectsInFrustum(LLCamera& camera); bool getVisibleExtents(LLCamera& camera, LLVector3 &min, LLVector3& max); bool getVisiblePointCloud(LLCamera& camera, LLVector3 &min, LLVector3& max, std::vector<LLVector3>& fp, LLVector3 light_dir = LLVector3(0,0,0)); - void updateCull(LLCamera& camera, LLCullResult& result, S32 water_clip = 0, LLPlane* plane = NULL); //if water_clip is 0, ignore water plane, 1, cull to above plane, -1, cull to below plane + void updateCull(LLCamera& camera, LLCullResult& result, LLPlane* plane = NULL); //if water_clip is 0, ignore water plane, 1, cull to above plane, -1, cull to below plane void createObjects(F32 max_dtime); void createObject(LLViewerObject* vobj); void processPartitionQ(); @@ -267,13 +262,20 @@ class LLPipeline void stateSort(LLSpatialBridge* bridge, LLCamera& camera, BOOL fov_changed = FALSE); void stateSort(LLDrawable* drawablep, LLCamera& camera); void postSort(LLCamera& camera); + + //update stats for textures in given DrawInfo + void touchTextures(LLDrawInfo* info); + void touchTexture(LLViewerTexture* tex, F32 vsize); + void forAllVisibleDrawables(void (*func)(LLDrawable*)); - void renderObjects(U32 type, U32 mask, bool texture = true, bool batch_texture = false); - void renderMaskedObjects(U32 type, U32 mask, bool texture = true, bool batch_texture = false); - void renderFullbrightMaskedObjects(U32 type, U32 mask, bool texture = true, bool batch_texture = false); + void renderObjects(U32 type, U32 mask, bool texture = true, bool batch_texture = false, bool rigged = false); + void renderAlphaObjects(U32 mask, bool texture = true, bool batch_texture = false, bool rigged = false); + void renderMaskedObjects(U32 type, U32 mask, bool texture = true, bool batch_texture = false, bool rigged = false); + void renderFullbrightMaskedObjects(U32 type, U32 mask, bool texture = true, bool batch_texture = false, bool rigged = false); void renderGroups(LLRenderPass* pass, U32 type, U32 mask, bool texture); + void renderRiggedGroups(LLRenderPass* pass, U32 type, U32 mask, bool texture); void grabReferences(LLCullResult& result); void clearReferences(); @@ -338,6 +340,8 @@ class LLPipeline LLCullResult::drawinfo_iterator endRenderMap(U32 type); LLCullResult::sg_iterator beginAlphaGroups(); LLCullResult::sg_iterator endAlphaGroups(); + LLCullResult::sg_iterator beginRiggedAlphaGroups(); + LLCullResult::sg_iterator endRiggedAlphaGroups(); bool hasRenderDebugFeatureMask(const U32 mask) const { return bool(mRenderDebugFeatureMask & mask); } @@ -461,34 +465,61 @@ class LLPipeline RENDER_TYPE_ALPHA = LLDrawPool::POOL_ALPHA, RENDER_TYPE_GLOW = LLDrawPool::POOL_GLOW, RENDER_TYPE_PASS_SIMPLE = LLRenderPass::PASS_SIMPLE, + RENDER_TYPE_PASS_SIMPLE_RIGGED = LLRenderPass::PASS_SIMPLE_RIGGED, RENDER_TYPE_PASS_GRASS = LLRenderPass::PASS_GRASS, RENDER_TYPE_PASS_FULLBRIGHT = LLRenderPass::PASS_FULLBRIGHT, + RENDER_TYPE_PASS_FULLBRIGHT_RIGGED = LLRenderPass::PASS_FULLBRIGHT, RENDER_TYPE_PASS_INVISIBLE = LLRenderPass::PASS_INVISIBLE, + RENDER_TYPE_PASS_INVISIBLE_RIGGED = LLRenderPass::PASS_INVISIBLE_RIGGED, RENDER_TYPE_PASS_INVISI_SHINY = LLRenderPass::PASS_INVISI_SHINY, + RENDER_TYPE_PASS_INVISI_SHINY_RIGGED = LLRenderPass::PASS_INVISI_SHINY_RIGGED, RENDER_TYPE_PASS_FULLBRIGHT_SHINY = LLRenderPass::PASS_FULLBRIGHT_SHINY, + RENDER_TYPE_PASS_FULLBRIGHT_SHINY_RIGGED = LLRenderPass::PASS_FULLBRIGHT_SHINY_RIGGED, RENDER_TYPE_PASS_SHINY = LLRenderPass::PASS_SHINY, + RENDER_TYPE_PASS_SHINY_RIGGED = LLRenderPass::PASS_SHINY_RIGGED, RENDER_TYPE_PASS_BUMP = LLRenderPass::PASS_BUMP, + RENDER_TYPE_PASS_BUMP_RIGGED = LLRenderPass::PASS_BUMP_RIGGED, RENDER_TYPE_PASS_POST_BUMP = LLRenderPass::PASS_POST_BUMP, + RENDER_TYPE_PASS_POST_BUMP_RIGGED = LLRenderPass::PASS_POST_BUMP_RIGGED, RENDER_TYPE_PASS_GLOW = LLRenderPass::PASS_GLOW, + RENDER_TYPE_PASS_GLOW_RIGGED = LLRenderPass::PASS_GLOW_RIGGED, RENDER_TYPE_PASS_ALPHA = LLRenderPass::PASS_ALPHA, RENDER_TYPE_PASS_ALPHA_MASK = LLRenderPass::PASS_ALPHA_MASK, + RENDER_TYPE_PASS_ALPHA_MASK_RIGGED = LLRenderPass::PASS_ALPHA_MASK_RIGGED, RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK = LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, + RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK_RIGGED = LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK_RIGGED, RENDER_TYPE_PASS_MATERIAL = LLRenderPass::PASS_MATERIAL, + RENDER_TYPE_PASS_MATERIAL_RIGGED = LLRenderPass::PASS_MATERIAL_RIGGED, RENDER_TYPE_PASS_MATERIAL_ALPHA = LLRenderPass::PASS_MATERIAL_ALPHA, + RENDER_TYPE_PASS_MATERIAL_ALPHA_RIGGED = LLRenderPass::PASS_MATERIAL_ALPHA_RIGGED, RENDER_TYPE_PASS_MATERIAL_ALPHA_MASK = LLRenderPass::PASS_MATERIAL_ALPHA_MASK, + RENDER_TYPE_PASS_MATERIAL_ALPHA_MASK_RIGGED = LLRenderPass::PASS_MATERIAL_ALPHA_MASK_RIGGED, RENDER_TYPE_PASS_MATERIAL_ALPHA_EMISSIVE= LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, + RENDER_TYPE_PASS_MATERIAL_ALPHA_EMISSIVE_RIGGED = LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE_RIGGED, RENDER_TYPE_PASS_SPECMAP = LLRenderPass::PASS_SPECMAP, + RENDER_TYPE_PASS_SPECMAP_RIGGED = LLRenderPass::PASS_SPECMAP_RIGGED, RENDER_TYPE_PASS_SPECMAP_BLEND = LLRenderPass::PASS_SPECMAP_BLEND, + RENDER_TYPE_PASS_SPECMAP_BLEND_RIGGED = LLRenderPass::PASS_SPECMAP_BLEND_RIGGED, RENDER_TYPE_PASS_SPECMAP_MASK = LLRenderPass::PASS_SPECMAP_MASK, + RENDER_TYPE_PASS_SPECMAP_MASK_RIGGED = LLRenderPass::PASS_SPECMAP_MASK_RIGGED, RENDER_TYPE_PASS_SPECMAP_EMISSIVE = LLRenderPass::PASS_SPECMAP_EMISSIVE, + RENDER_TYPE_PASS_SPECMAP_EMISSIVE_RIGGED = LLRenderPass::PASS_SPECMAP_EMISSIVE_RIGGED, RENDER_TYPE_PASS_NORMMAP = LLRenderPass::PASS_NORMMAP, + RENDER_TYPE_PASS_NORMMAP_RIGGED = LLRenderPass::PASS_NORMMAP_RIGGED, RENDER_TYPE_PASS_NORMMAP_BLEND = LLRenderPass::PASS_NORMMAP_BLEND, + RENDER_TYPE_PASS_NORMMAP_BLEND_RIGGED = LLRenderPass::PASS_NORMMAP_BLEND_RIGGED, RENDER_TYPE_PASS_NORMMAP_MASK = LLRenderPass::PASS_NORMMAP_MASK, + RENDER_TYPE_PASS_NORMMAP_MASK_RIGGED = LLRenderPass::PASS_NORMMAP_MASK_RIGGED, RENDER_TYPE_PASS_NORMMAP_EMISSIVE = LLRenderPass::PASS_NORMMAP_EMISSIVE, + RENDER_TYPE_PASS_NORMMAP_EMISSIVE_RIGGED = LLRenderPass::PASS_NORMMAP_EMISSIVE_RIGGED, RENDER_TYPE_PASS_NORMSPEC = LLRenderPass::PASS_NORMSPEC, + RENDER_TYPE_PASS_NORMSPEC_RIGGED = LLRenderPass::PASS_NORMSPEC_RIGGED, RENDER_TYPE_PASS_NORMSPEC_BLEND = LLRenderPass::PASS_NORMSPEC_BLEND, + RENDER_TYPE_PASS_NORMSPEC_BLEND_RIGGED = LLRenderPass::PASS_NORMSPEC_BLEND_RIGGED, RENDER_TYPE_PASS_NORMSPEC_MASK = LLRenderPass::PASS_NORMSPEC_MASK, + RENDER_TYPE_PASS_NORMSPEC_MASK_RIGGED = LLRenderPass::PASS_NORMSPEC_MASK_RIGGED, RENDER_TYPE_PASS_NORMSPEC_EMISSIVE = LLRenderPass::PASS_NORMSPEC_EMISSIVE, + RENDER_TYPE_PASS_NORMSPEC_EMISSIVE_RIGGED = LLRenderPass::PASS_NORMSPEC_EMISSIVE_RIGGED, // Following are object types (only used in drawable mRenderType) RENDER_TYPE_HUD = LLRenderPass::NUM_RENDER_TYPES, RENDER_TYPE_VOLUME, @@ -573,7 +604,6 @@ class LLPipeline static bool sDelayVBUpdate; static bool sAutoMaskAlphaDeferred; static bool sAutoMaskAlphaNonDeferred; - static bool sDisableShaders; // if true, rendering will be done without shaders static bool sRenderTransparentWater; static bool sRenderBump; static bool sBakeSunlight; @@ -596,7 +626,6 @@ class LLPipeline static bool sRenderAttachedParticles; static bool sRenderDeferred; static S32 sVisibleLightCount; - static F32 sMinRenderSize; static bool sRenderingHUDs; static F32 sDistortionWaterClipPlaneMargin; // [SL:KB] - Patch: Render-TextureToggle (Catznip-4.0) @@ -693,8 +722,7 @@ class LLPipeline LL_ALIGN_16(LLVector4a mTransformedMoonDir); bool mInitialized; - bool mVertexShadersEnabled; - S32 mVertexShadersLoaded; // 0 = no, 1 = yes, -1 = failed + bool mShadersLoaded; protected: bool mRenderTypeEnabled[NUM_RENDER_TYPES]; @@ -894,7 +922,6 @@ class LLPipeline //cached settings static bool WindLightUseAtmosShaders; - static bool RenderAvatarVP; static bool RenderDeferred; static F32 RenderDeferredSunWash; static U32 RenderFSAASamples; diff --git a/indra/newview/rlvactions.cpp b/indra/newview/rlvactions.cpp index 3bab288d2b2f0763162a4129aaeb2824cb51f2d4..a626f89fe83b14352c822303cce2ccdfe2c2493a 100644 --- a/indra/newview/rlvactions.cpp +++ b/indra/newview/rlvactions.cpp @@ -51,7 +51,7 @@ bool RlvActions::canChangeToMouselook() // User can switch to mouselook if: // - not specifically prevented from going into mouselook (NOTE: if an object has exclusive camera control only that object can prevent mouselook) // - there is no minimum camera distance defined (or it's higher than > 0m) - const RlvBehaviourModifier* pCamDistMinModifier = RlvBehaviourDictionary::instanceFast().getModifier(RLV_MODIFIER_SETCAM_AVDISTMIN); + const RlvBehaviourModifier* pCamDistMinModifier = RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SETCAM_AVDISTMIN); return ( (!gRlvHandler.hasBehaviour(RLV_BHVR_SETCAM)) ? !gRlvHandler.hasBehaviour(RLV_BHVR_SETCAM_MOUSELOOK) : !gRlvHandler.hasBehaviour(pCamDistMinModifier->getPrimaryObject(), RLV_BHVR_SETCAM_MOUSELOOK) ) && ( (!pCamDistMinModifier->hasValue()) || (pCamDistMinModifier->getValue<float>() == 0.f) ); @@ -158,12 +158,12 @@ static bool rlvCheckAvatarIMDistance(const LLUUID& idAvatar, ERlvBehaviourModifi // min <= max <= dist | block | allow | block | F | ^ (see above) | F // off-region | block | allow | block | F | ^ (see above) | F - const RlvBehaviourModifier *pBhvrModDistMin = RlvBehaviourDictionary::instanceFast().getModifier(eModDistMin), *pBhvrModDistMax = RlvBehaviourDictionary::instanceFast().getModifier(eModDistMax); + const RlvBehaviourModifier *pBhvrModDistMin = RlvBehaviourDictionary::instance().getModifier(eModDistMin), *pBhvrModDistMax = RlvBehaviourDictionary::instance().getModifier(eModDistMax); if (pBhvrModDistMin->hasValue()) { LLVector3d posAgent; bool fHasMax = pBhvrModDistMax->hasValue(); float nMinDist = pBhvrModDistMin->getValue<float>(), nMaxDist = (fHasMax) ? pBhvrModDistMax->getValue<float>() : std::numeric_limits<float>::max(); - float nDist = (LLWorld::getInstanceFast()->getAvatar(idAvatar, posAgent)) ? llabs(dist_vec_squared(gAgent.getPositionGlobal(), posAgent)) : std::numeric_limits<float>::max(); + float nDist = (LLWorld::getInstance()->getAvatar(idAvatar, posAgent)) ? llabs(dist_vec_squared(gAgent.getPositionGlobal(), posAgent)) : std::numeric_limits<float>::max(); return (nMinDist < nMaxDist) && (nMinDist <= nDist) && (nDist <= nMaxDist); } return false; @@ -257,7 +257,7 @@ bool RlvActions::canShowNameTag(const LLVOAvatar* pAvatar) if ( (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMETAGS)) || (gRlvHandler.isException(RLV_BHVR_SHOWNAMETAGS, pAvatar->getID())) || (gAgentID == pAvatar->getID()) ) return true; - const F32 nShowNameTagsDist = RlvBehaviourDictionary::instanceFast().getModifier(RLV_MODIFIER_SHOWNAMETAGSDIST)->getValue<F32>(); + const F32 nShowNameTagsDist = RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SHOWNAMETAGSDIST)->getValue<F32>(); return (nShowNameTagsDist != 0.f) && (dist_vec_squared(pAvatar->getPositionGlobal(), gAgent.getPositionGlobal()) < nShowNameTagsDist * nShowNameTagsDist); } @@ -365,13 +365,13 @@ bool RlvActions::canTeleportToLocal(const LLVector3d& posGlobal) if ( (fCanTeleport) && (gRlvHandler.hasBehaviourExcept(RLV_BHVR_SITTP, idRlvObjExcept)) ) { const F32 nDistSq = (posGlobal - gAgent.getPositionGlobal()).lengthSquared(); - const F32 nSitTpDist = RlvBehaviourDictionary::instanceFast().getModifier(RLV_MODIFIER_SITTPDIST)->getValue<F32>(); + const F32 nSitTpDist = RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SITTPDIST)->getValue<F32>(); fCanTeleport = nDistSq < nSitTpDist * nSitTpDist; } if ( (fCanTeleport) && (gRlvHandler.hasBehaviourExcept(RLV_BHVR_TPLOCAL, idRlvObjExcept)) ) { const F32 nDistSq = (LLVector2(posGlobal.mdV[0], posGlobal.mdV[1]) - LLVector2(gAgent.getPositionGlobal().mdV[0], gAgent.getPositionGlobal().mdV[1])).lengthSquared(); - const F32 nTpLocalDist = llmin(RlvBehaviourDictionary::instanceFast().getModifier(RLV_MODIFIER_TPLOCALDIST)->getValue<float>(), RLV_MODIFIER_TPLOCAL_DEFAULT); + const F32 nTpLocalDist = llmin(RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_TPLOCALDIST)->getValue<float>(), RLV_MODIFIER_TPLOCAL_DEFAULT); fCanTeleport = nDistSq < nTpLocalDist * nTpLocalDist; } return fCanTeleport; @@ -403,7 +403,7 @@ bool RlvActions::canChangeEnvironment(const LLUUID& idRlvObject) bool RlvActions::hasPostProcess() { - return LLVfxManager::instanceFast().hasEffect(EVisualEffect::RlvSphere); + return LLVfxManager::instance().hasEffect(EVisualEffect::RlvSphere); } // ============================================================================ @@ -697,7 +697,7 @@ bool RlvActions::canViewWireframe() template<> const float& RlvActions::getModifierValue<float>(ERlvBehaviourModifier eBhvrMod) { - return RlvBehaviourDictionary::instanceFast().getModifier(eBhvrMod)->getValue<float>(); + return RlvBehaviourDictionary::instance().getModifier(eBhvrMod)->getValue<float>(); } // Checked: 2013-05-10 (RLVa-1.4.9) diff --git a/indra/newview/rlvcommon.cpp b/indra/newview/rlvcommon.cpp index bda1d65d2cca46a17346db4eed22008240a805cf..fc9fcb2ee573746ac667d8bb956deca62e258c0e 100644 --- a/indra/newview/rlvcommon.cpp +++ b/indra/newview/rlvcommon.cpp @@ -488,13 +488,13 @@ void RlvUtil::filterLocation(std::string& strUTF8Text) { // Filter any mention of the surrounding region names const std::string& strHiddenRegion = RlvStrings::getString(RlvStringKeys::Hidden::Region); - for (LLViewerRegion* pRegion : LLWorld::getInstanceFast()->getRegionList()) + for (LLViewerRegion* pRegion : LLWorld::getInstance()->getRegionList()) { boost::replace_all_regex(strUTF8Text, boost::regex("\\b" + escape_for_regex(pRegion->getName()) + "\\b", boost::regex::icase), strHiddenRegion); } // Filter any mention of the parcel name - LLViewerParcelMgr* pParcelMgr = LLViewerParcelMgr::getInstanceFast(); + LLViewerParcelMgr* pParcelMgr = LLViewerParcelMgr::getInstance(); if (pParcelMgr) boost::replace_all_regex(strUTF8Text, boost::regex("\\b" + escape_for_regex(pParcelMgr->getAgentParcelName()) + "\\b", boost::regex::icase), RlvStrings::getString(RlvStringKeys::Hidden::Parcel)); } @@ -503,7 +503,7 @@ void RlvUtil::filterLocation(std::string& strUTF8Text) void RlvUtil::filterNames(std::string& strUTF8Text, bool fFilterLegacy, bool fClearMatches) { uuid_vec_t idAgents; - LLWorld::getInstanceFast()->getAvatars(&idAgents, NULL); + LLWorld::getInstance()->getAvatars(&idAgents, NULL); for (int idxAgent = 0, cntAgent = idAgents.size(); idxAgent < cntAgent; idxAgent++) { LLAvatarName avName; @@ -573,7 +573,7 @@ bool RlvUtil::isNearbyAgent(const LLUUID& idAgent) if ( (idAgent.notNull()) && (gAgent.getID() != idAgent) ) { std::vector<LLUUID> idAgents; - LLWorld::getInstanceFast()->getAvatars(&idAgents, NULL); + LLWorld::getInstance()->getAvatars(&idAgents, NULL); for (int idxAgent = 0, cntAgent = idAgents.size(); idxAgent < cntAgent; idxAgent++) if (idAgents[idxAgent] == idAgent) @@ -585,7 +585,7 @@ bool RlvUtil::isNearbyAgent(const LLUUID& idAgent) // Checked: 2010-04-05 (RLVa-1.2.0d) | Modified: RLVa-1.2.0d bool RlvUtil::isNearbyRegion(const std::string& strRegion) { - for (LLViewerRegion* pRegion : LLWorld::getInstanceFast()->getRegionList()) + for (LLViewerRegion* pRegion : LLWorld::getInstance()->getRegionList()) if (pRegion->getName() == strRegion) return true; return false; @@ -749,7 +749,7 @@ bool rlvMenuCanShowName() bool fEnable = true; if (rlv_handler_t::isEnabled()) { - const LLVOAvatar* pAvatar = find_avatar_from_object(LLSelectMgr::getInstanceFast()->getSelection()->getPrimaryObject()); + const LLVOAvatar* pAvatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()); fEnable = (pAvatar) && (RlvActions::canShowName(RlvActions::SNC_DEFAULT, pAvatar->getID())); } return fEnable; @@ -761,7 +761,7 @@ bool rlvMenuEnableIfNot(const LLSD& sdParam) bool fEnable = true; if (rlv_handler_t::isEnabled()) { - ERlvBehaviour eBhvr = RlvBehaviourDictionary::instanceFast().getBehaviourFromString(sdParam.asString(), RLV_TYPE_ADDREM); + ERlvBehaviour eBhvr = RlvBehaviourDictionary::instance().getBehaviourFromString(sdParam.asString(), RLV_TYPE_ADDREM); fEnable = (eBhvr != RLV_BHVR_UNKNOWN) ? !gRlvHandler.hasBehaviour(eBhvr) : true; } return fEnable; @@ -789,7 +789,7 @@ bool rlvCanDeleteOrReturn() { /*virtual*/ bool apply(LLViewerObject* pObj) { return rlvCanDeleteOrReturn(pObj); } } f; - LLObjectSelectionHandle hSel = LLSelectMgr::getInstanceFast()->getSelection(); + LLObjectSelectionHandle hSel = LLSelectMgr::getInstance()->getSelection(); return (hSel.notNull()) && (0 != hSel->getRootObjectCount()) && (hSel->applyToRootObjects(&f, false)); } return true; diff --git a/indra/newview/rlveffects.cpp b/indra/newview/rlveffects.cpp index f54ae7ae507f6096be2e0e3a16d7df1ccf719408..74e74fcc73c375b88af6263dd749e268a52260c0 100644 --- a/indra/newview/rlveffects.cpp +++ b/indra/newview/rlveffects.cpp @@ -51,7 +51,7 @@ RlvOverlayEffect::~RlvOverlayEffect() // static ERlvCmdRet RlvOverlayEffect::onAlphaValueChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue) { - if (RlvOverlayEffect* pEffect = LLVfxManager::instanceFast().getEffect<RlvOverlayEffect>(idRlvObj)) + if (RlvOverlayEffect* pEffect = LLVfxManager::instance().getEffect<RlvOverlayEffect>(idRlvObj)) { pEffect->m_nAlpha = (newValue) ? boost::get<float>(newValue.value()) : c_DefaultAlpha; } @@ -61,7 +61,7 @@ ERlvCmdRet RlvOverlayEffect::onAlphaValueChanged(const LLUUID& idRlvObj, const b // static ERlvCmdRet RlvOverlayEffect::onColorValueChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue) { - if (RlvOverlayEffect* pEffect = LLVfxManager::instanceFast().getEffect<RlvOverlayEffect>(idRlvObj)) + if (RlvOverlayEffect* pEffect = LLVfxManager::instance().getEffect<RlvOverlayEffect>(idRlvObj)) { pEffect->m_Color = LLColor3( (newValue) ? boost::get<LLVector3>(newValue.value()).mV : c_DefaultColor); } @@ -71,7 +71,7 @@ ERlvCmdRet RlvOverlayEffect::onColorValueChanged(const LLUUID& idRlvObj, const b // static ERlvCmdRet RlvOverlayEffect::onTextureChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue) { - if (RlvOverlayEffect* pEffect = LLVfxManager::instanceFast().getEffect<RlvOverlayEffect>(idRlvObj)) + if (RlvOverlayEffect* pEffect = LLVfxManager::instance().getEffect<RlvOverlayEffect>(idRlvObj)) { if (newValue) pEffect->setImage(boost::get<LLUUID>(newValue.value())); @@ -114,10 +114,7 @@ void RlvOverlayEffect::run(const LLVisualEffectParams*) { if (m_pImage) { - if (LLGLSLShader::sNoFixedFunction) - { - gUIProgram.bind(); - } + gUIProgram.bind(); int nWidth = gViewerWindow->getWorldViewWidthScaled(); int nHeight = gViewerWindow->getWorldViewHeightScaled(); @@ -144,10 +141,7 @@ void RlvOverlayEffect::run(const LLVisualEffectParams*) gGL.flush(); gViewerWindow->setup3DRender(); - if (LLGLSLShader::sNoFixedFunction) - { - gUIProgram.unbind(); - } + gUIProgram.unbind(); } } @@ -181,7 +175,7 @@ RlvSphereEffect::~RlvSphereEffect() // static ERlvCmdRet RlvSphereEffect::onModeChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue) { - if (RlvSphereEffect* pEffect = LLVfxManager::instanceFast().getEffect<RlvSphereEffect>(idRlvObj)) + if (RlvSphereEffect* pEffect = LLVfxManager::instance().getEffect<RlvSphereEffect>(idRlvObj)) { pEffect->m_eMode = (ESphereMode)((newValue) ? boost::get<int>(newValue.value()) : c_SphereDefaultMode); } @@ -191,7 +185,7 @@ ERlvCmdRet RlvSphereEffect::onModeChanged(const LLUUID& idRlvObj, const boost::o // static ERlvCmdRet RlvSphereEffect::onOriginChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue) { - if (RlvSphereEffect* pEffect = LLVfxManager::instanceFast().getEffect<RlvSphereEffect>(idRlvObj)) + if (RlvSphereEffect* pEffect = LLVfxManager::instance().getEffect<RlvSphereEffect>(idRlvObj)) { pEffect->m_eOrigin = (ESphereOrigin)((newValue) ? boost::get<int>(newValue.value()) : c_SphereDefaultOrigin); } @@ -201,7 +195,7 @@ ERlvCmdRet RlvSphereEffect::onOriginChanged(const LLUUID& idRlvObj, const boost: // static ERlvCmdRet RlvSphereEffect::onColorChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue) { - if (RlvSphereEffect* pEffect = LLVfxManager::instanceFast().getEffect<RlvSphereEffect>(idRlvObj)) + if (RlvSphereEffect* pEffect = LLVfxManager::instance().getEffect<RlvSphereEffect>(idRlvObj)) { LLVector4 vecColor = (newValue) ? LLVector4(boost::get<LLVector3>(newValue.value()), 1.0f) : LLVector4(c_SphereDefaultColor); if (!pEffect->m_nTweenDuration) @@ -215,7 +209,7 @@ ERlvCmdRet RlvSphereEffect::onColorChanged(const LLUUID& idRlvObj, const boost:: // static ERlvCmdRet RlvSphereEffect::onDistMinChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue) { - if (RlvSphereEffect* pEffect = LLVfxManager::instanceFast().getEffect<RlvSphereEffect>(idRlvObj)) + if (RlvSphereEffect* pEffect = LLVfxManager::instance().getEffect<RlvSphereEffect>(idRlvObj)) { float nDistanceMin = (newValue) ? boost::get<float>(newValue.value()) : c_SphereDefaultDistance; if (!pEffect->m_nTweenDuration) @@ -229,7 +223,7 @@ ERlvCmdRet RlvSphereEffect::onDistMinChanged(const LLUUID& idRlvObj, const boost // static ERlvCmdRet RlvSphereEffect::onDistMaxChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue) { - if (RlvSphereEffect* pEffect = LLVfxManager::instanceFast().getEffect<RlvSphereEffect>(idRlvObj)) + if (RlvSphereEffect* pEffect = LLVfxManager::instance().getEffect<RlvSphereEffect>(idRlvObj)) { float nDistanceMax = (newValue) ? boost::get<float>(newValue.value()) : c_SphereDefaultDistance; if (!pEffect->m_nTweenDuration) @@ -243,7 +237,7 @@ ERlvCmdRet RlvSphereEffect::onDistMaxChanged(const LLUUID& idRlvObj, const boost // static ERlvCmdRet RlvSphereEffect::onDistExtendChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue) { - if (RlvSphereEffect* pEffect = LLVfxManager::instanceFast().getEffect<RlvSphereEffect>(idRlvObj)) + if (RlvSphereEffect* pEffect = LLVfxManager::instance().getEffect<RlvSphereEffect>(idRlvObj)) { pEffect->m_eDistExtend = (ESphereDistExtend)((newValue) ? boost::get<int>(newValue.value()) : c_SphereDefaultDistanceExtend); } @@ -253,7 +247,7 @@ ERlvCmdRet RlvSphereEffect::onDistExtendChanged(const LLUUID& idRlvObj, const bo // static ERlvCmdRet RlvSphereEffect::onParamsChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue) { - if (RlvSphereEffect* pEffect = LLVfxManager::instanceFast().getEffect<RlvSphereEffect>(idRlvObj)) + if (RlvSphereEffect* pEffect = LLVfxManager::instance().getEffect<RlvSphereEffect>(idRlvObj)) { LLVector4 params = LLVector4((newValue) ? boost::get<LLVector4>(newValue.value()).mV : c_SphereDefaultColor); if (!pEffect->m_nTweenDuration) @@ -267,7 +261,7 @@ ERlvCmdRet RlvSphereEffect::onParamsChanged(const LLUUID& idRlvObj, const boost: // static ERlvCmdRet RlvSphereEffect::onTweenDurationChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue) { - if (RlvSphereEffect* pEffect = LLVfxManager::instanceFast().getEffect<RlvSphereEffect>(idRlvObj)) + if (RlvSphereEffect* pEffect = LLVfxManager::instance().getEffect<RlvSphereEffect>(idRlvObj)) { pEffect->m_nTweenDuration = (newValue) ? boost::get<float>(newValue.value()) : 0; } @@ -277,7 +271,7 @@ ERlvCmdRet RlvSphereEffect::onTweenDurationChanged(const LLUUID& idRlvObj, const // static ERlvCmdRet RlvSphereEffect::onValueMinChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue) { - if (RlvSphereEffect* pEffect = LLVfxManager::instanceFast().getEffect<RlvSphereEffect>(idRlvObj)) + if (RlvSphereEffect* pEffect = LLVfxManager::instance().getEffect<RlvSphereEffect>(idRlvObj)) { float nValueMin = (newValue) ? boost::get<float>(newValue.value()) : c_SphereDefaultAlpha;; if (!pEffect->m_nTweenDuration) @@ -291,7 +285,7 @@ ERlvCmdRet RlvSphereEffect::onValueMinChanged(const LLUUID& idRlvObj, const boos // static ERlvCmdRet RlvSphereEffect::onValueMaxChanged(const LLUUID& idRlvObj, const boost::optional<RlvBehaviourModifierValue> newValue) { - if (RlvSphereEffect* pEffect = LLVfxManager::instanceFast().getEffect<RlvSphereEffect>(idRlvObj)) + if (RlvSphereEffect* pEffect = LLVfxManager::instance().getEffect<RlvSphereEffect>(idRlvObj)) { float nValueMax = (newValue) ? boost::get<float>(newValue.value()) : c_SphereDefaultAlpha; if (!pEffect->m_nTweenDuration) @@ -315,7 +309,7 @@ void RlvSphereEffect::setShaderUniforms(LLGLSLShader* pShader) switch (m_eOrigin) { case ESphereOrigin::Camera: - posSphereOrigin.setVec(LLViewerCamera::instanceFast().getOrigin(), 1.0f); + posSphereOrigin.setVec(LLViewerCamera::instance().getOrigin(), 1.0f); break; case ESphereOrigin::Avatar: default: diff --git a/indra/newview/rlvfloaters.cpp b/indra/newview/rlvfloaters.cpp index ac7226c0d6d3b7bdb1b8c36f5d4473cd667708e1..d9733274f1420e63a2534d121355281b23e55698 100644 --- a/indra/newview/rlvfloaters.cpp +++ b/indra/newview/rlvfloaters.cpp @@ -45,7 +45,7 @@ std::string rlvGetItemName(const LLViewerInventoryItem* pItem) { if ( (pItem) && ((LLAssetType::AT_BODYPART == pItem->getType()) || (LLAssetType::AT_CLOTHING == pItem->getType())) ) { - return llformat("%s (%s)", pItem->getName().c_str(), LLWearableType::getInstanceFast()->getTypeName(pItem->getWearableType()).c_str()); + return llformat("%s (%s)", pItem->getName().c_str(), LLWearableType::getInstance()->getTypeName(pItem->getWearableType()).c_str()); } else if ( (pItem) && (LLAssetType::AT_OBJECT == pItem->getType()) && (isAgentAvatarValid()) ) { @@ -192,7 +192,7 @@ std::string rlvFolderLockSourceToTarget(RlvFolderLocks::folderlock_source_t lock } case RlvFolderLocks::ST_WEARABLETYPE: { - const std::string& strTypeName = LLWearableType::getInstanceFast()->getTypeName(boost::get<LLWearableType::EType>(lockSource.second)); + const std::string& strTypeName = LLWearableType::getInstance()->getTypeName(boost::get<LLWearableType::EType>(lockSource.second)); return llformat("Wearable type (%s)", strTypeName.c_str()); } default: @@ -379,7 +379,7 @@ void RlvFloaterBehaviours::refreshAll() // for (int idxModifier = 0; idxModifier < RLV_MODIFIER_COUNT; idxModifier++) { - const RlvBehaviourModifier* pBhvrModifier = RlvBehaviourDictionary::instanceFast().m_BehaviourModifiers[idxModifier]; + const RlvBehaviourModifier* pBhvrModifier = RlvBehaviourDictionary::instance().m_BehaviourModifiers[idxModifier]; if (pBhvrModifier) { sdModifierRow["enabled"] = (pBhvrModifier->hasValue()); @@ -531,7 +531,7 @@ void RlvFloaterLocks::refreshAll() for (RlvWearableLocks::rlv_wearabletypelock_map_t::const_iterator itWearableType = wearableTypeAdd.begin(); itWearableType != wearableTypeAdd.end(); ++itWearableType) { - sdColumns[2]["value"] = LLWearableType::getInstanceFast()->getTypeLabel(itWearableType->first); + sdColumns[2]["value"] = LLWearableType::getInstance()->getTypeLabel(itWearableType->first); sdColumns[3]["value"] = rlvGetItemNameFromObjID(itWearableType->second); pLockList->addElement(sdRow, ADD_BOTTOM); @@ -542,7 +542,7 @@ void RlvFloaterLocks::refreshAll() for (RlvWearableLocks::rlv_wearabletypelock_map_t::const_iterator itWearableType = wearableTypeRem.begin(); itWearableType != wearableTypeRem.end(); ++itWearableType) { - sdColumns[2]["value"] = LLWearableType::getInstanceFast()->getTypeName(itWearableType->first); + sdColumns[2]["value"] = LLWearableType::getInstance()->getTypeName(itWearableType->first); sdColumns[3]["value"] = rlvGetItemNameFromObjID(itWearableType->second); pLockList->addElement(sdRow, ADD_BOTTOM); @@ -761,7 +761,7 @@ BOOL RlvFloaterConsole::postBuild() void RlvFloaterConsole::onClose(bool fQuitting) { - RlvBehaviourDictionary::instanceFast().clearModifiers(gAgent.getID()); + RlvBehaviourDictionary::instance().clearModifiers(gAgent.getID()); gRlvHandler.processCommand(gAgent.getID(), "clear", true); } diff --git a/indra/newview/rlvhandler.cpp b/indra/newview/rlvhandler.cpp index b109540f6dc2beff232bfc3497849b872301c772..920dceb55d4f51a68ccd5ef2a5953afce797ddc0 100644 --- a/indra/newview/rlvhandler.cpp +++ b/indra/newview/rlvhandler.cpp @@ -304,7 +304,7 @@ bool RlvHandler::isException(ERlvBehaviour eBhvr, const RlvExceptionOption& varO bool RlvHandler::isPermissive(ERlvBehaviour eBhvr) const { - return (RlvBehaviourDictionary::instanceFast().getHasStrict(eBhvr)) + return (RlvBehaviourDictionary::instance().getHasStrict(eBhvr)) ? !((hasBehaviour(RLV_BHVR_PERMISSIVE)) || (isException(RLV_BHVR_PERMISSIVE, eBhvr, ERlvExceptionCheck::Permissive))) : true; } @@ -536,7 +536,7 @@ ERlvCmdRet RlvHandler::processCommand(std::reference_wrapper<const RlvCommand> r if (0 == itObj->second.m_Commands.size()) { RLV_DEBUGS << "\t- command list empty => removing " << idCurObj << RLV_ENDL; - RlvBehaviourDictionary::instanceFast().clearModifiers(idCurObj); + RlvBehaviourDictionary::instance().clearModifiers(idCurObj); m_Objects.erase(itObj); } } @@ -1802,7 +1802,7 @@ template<> ERlvCmdRet RlvBehaviourGenericHandler<RLV_OPTION_MODIFIER>::onCommand(const RlvCommand& rlvCmd, bool& fRefCount) { // There should be an option and it should specify a valid modifier (RlvBehaviourModifier performs the appropriate type checks) - RlvBehaviourModifier* pBhvrModifier = RlvBehaviourDictionary::instanceFast().getModifierFromBehaviour(rlvCmd.getBehaviourType()); + RlvBehaviourModifier* pBhvrModifier = RlvBehaviourDictionary::instance().getModifierFromBehaviour(rlvCmd.getBehaviourType()); RlvBehaviourModifierValue modValue; if ( (!rlvCmd.hasOption()) || (!pBhvrModifier) || (!pBhvrModifier->convertOptionValue(rlvCmd.getOption(), pBhvrModifier->getType(), modValue)) ) return RLV_RET_FAILED_OPTION; @@ -1841,7 +1841,7 @@ ERlvCmdRet RlvBehaviourGenericHandler<RLV_OPTION_NONE_OR_MODIFIER>::onCommand(co } // @bhvr=n : add the default option on an empty modifier if needed - RlvBehaviourModifier* pBhvrModifier = RlvBehaviourDictionary::instanceFast().getModifierFromBehaviour(rlvCmd.getBehaviourType()); + RlvBehaviourModifier* pBhvrModifier = RlvBehaviourDictionary::instance().getModifierFromBehaviour(rlvCmd.getBehaviourType()); if ( (pBhvrModifier) && (pBhvrModifier->getAddDefault()) ) { // HACK-RLVa: reference counting doesn't happen until control returns to our caller but the modifier callbacks will happen now so we need to adjust the reference counts here @@ -2081,17 +2081,17 @@ ERlvCmdRet RlvBehaviourHandler<RLV_BHVR_SETOVERLAY>::onCommand(const RlvCommand& { if (gRlvHandler.hasBehaviour(rlvCmd.getObjectID(), rlvCmd.getBehaviourType())) { - LLVfxManager::instanceFast().addEffect(new RlvOverlayEffect(gRlvHandler.getCurrentObject())); + LLVfxManager::instance().addEffect(new RlvOverlayEffect(gRlvHandler.getCurrentObject())); } else { - LLVfxManager::instanceFast().removeEffect<RlvOverlayEffect>(gRlvHandler.getCurrentObject()); + LLVfxManager::instance().removeEffect<RlvOverlayEffect>(gRlvHandler.getCurrentObject()); } } // Refresh overlay effects according to object hierarchy std::list<RlvOverlayEffect*> effects; - if (LLVfxManager::instanceFast().getEffects<RlvOverlayEffect>(effects)) + if (LLVfxManager::instance().getEffects<RlvOverlayEffect>(effects)) { auto itActiveEffect = std::find_if(effects.begin(), effects.end(), [](const LLVisualEffect* pEffect) { return pEffect->getEnabled(); }); if (effects.end() == itActiveEffect) @@ -2105,7 +2105,7 @@ ERlvCmdRet RlvBehaviourHandler<RLV_BHVR_SETOVERLAY>::onCommand(const RlvCommand& { bool isActive = (idActiveRootObj.isNull() && pEffect == effects.front()) || (Rlv::getObjectRootId(pEffect->getId()) == idActiveRootObj); int nPriority = (isActive) ? 256 - Rlv::getObjectLinkNumber(pEffect->getId()) : pEffect->getPriority(); - LLVfxManager::instanceFast().updateEffect(pEffect, isActive, nPriority); + LLVfxManager::instance().updateEffect(pEffect, isActive, nPriority); pEffect->setBlockTouch(gRlvHandler.hasBehaviour(pEffect->getId(), RLV_BHVR_SETOVERLAY_TOUCH)); } } @@ -2117,7 +2117,7 @@ ERlvCmdRet RlvBehaviourHandler<RLV_BHVR_SETOVERLAY>::onCommand(const RlvCommand& template<> template<> ERlvCmdRet RlvBehaviourHandler<RLV_BHVR_SETOVERLAY_TOUCH>::onCommand(const RlvCommand& rlvCmd, bool& fRefCount) { - if (RlvOverlayEffect* pOverlayEffect = LLVfxManager::instanceFast().getEffect<RlvOverlayEffect>(rlvCmd.getObjectID())) + if (RlvOverlayEffect* pOverlayEffect = LLVfxManager::instance().getEffect<RlvOverlayEffect>(rlvCmd.getObjectID())) { pOverlayEffect->setBlockTouch( RLV_TYPE_ADD == rlvCmd.getParamType() ); } @@ -2138,7 +2138,7 @@ ERlvCmdRet RlvBehaviourHandler<RLV_BHVR_SETSPHERE>::onCommand(const RlvCommand& { if (gRlvHandler.hasBehaviour(rlvCmd.getObjectID(), rlvCmd.getBehaviourType())) { - LLVfxManager::instanceFast().addEffect(new RlvSphereEffect(rlvCmd.getObjectID())); + LLVfxManager::instance().addEffect(new RlvSphereEffect(rlvCmd.getObjectID())); Rlv::forceAtmosphericShadersIfAvailable(); @@ -2163,7 +2163,7 @@ ERlvCmdRet RlvBehaviourHandler<RLV_BHVR_SETSPHERE>::onCommand(const RlvCommand& } else { - LLVfxManager::instanceFast().removeEffect<RlvSphereEffect>(gRlvHandler.getCurrentObject()); + LLVfxManager::instance().removeEffect<RlvSphereEffect>(gRlvHandler.getCurrentObject()); } } return eRet; @@ -2225,7 +2225,7 @@ ERlvCmdRet RlvBehaviourRecvSendStartIMHandler::onCommand(const RlvCommand& rlvCm return RLV_RET_FAILED_OPTION; } - RlvBehaviourModifier *pBhvrModDistMin = RlvBehaviourDictionary::instanceFast().getModifier(eModDistMin), *pBhvrModDistMax = RlvBehaviourDictionary::instanceFast().getModifier(eModDistMax); + RlvBehaviourModifier *pBhvrModDistMin = RlvBehaviourDictionary::instance().getModifier(eModDistMin), *pBhvrModDistMax = RlvBehaviourDictionary::instance().getModifier(eModDistMax); if (RLV_TYPE_ADD == rlvCmd.getParamType()) { pBhvrModDistMin->addValue(nDistMin * nDistMin, rlvCmd.getObjectID(), rlvCmd.getBehaviourType()); @@ -2270,9 +2270,9 @@ void RlvBehaviourCamEyeFocusOffsetHandler::onCommandToggle(ERlvBehaviour eBhvr, } else { - const RlvBehaviourModifier* pBhvrEyeOffsetModifier = RlvBehaviourDictionary::instanceFast().getModifier(RLV_MODIFIER_SETCAM_EYEOFFSET); - const RlvBehaviourModifier* pBhvrEyeOffsetScaleModifier = RlvBehaviourDictionary::instanceFast().getModifier(RLV_MODIFIER_SETCAM_EYEOFFSETSCALE); - const RlvBehaviourModifier* pBhvrFocusOffsetModifier = RlvBehaviourDictionary::instanceFast().getModifier(RLV_MODIFIER_SETCAM_FOCUSOFFSET); + const RlvBehaviourModifier* pBhvrEyeOffsetModifier = RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SETCAM_EYEOFFSET); + const RlvBehaviourModifier* pBhvrEyeOffsetScaleModifier = RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SETCAM_EYEOFFSETSCALE); + const RlvBehaviourModifier* pBhvrFocusOffsetModifier = RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SETCAM_FOCUSOFFSET); if ( (!pBhvrEyeOffsetModifier->hasValue()) && (!pBhvrEyeOffsetScaleModifier->hasValue()) && (!pBhvrFocusOffsetModifier->hasValue()) ) { gRlvHandler.setCameraOverride(false); @@ -2284,7 +2284,7 @@ void RlvBehaviourCamEyeFocusOffsetHandler::onCommandToggle(ERlvBehaviour eBhvr, template<> void RlvBehaviourModifierHandler<RLV_MODIFIER_SETCAM_EYEOFFSET>::onValueChange() const { - if (RlvBehaviourModifier* pBhvrModifier = RlvBehaviourDictionary::instanceFast().getModifier(RLV_MODIFIER_SETCAM_EYEOFFSET)) + if (RlvBehaviourModifier* pBhvrModifier = RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SETCAM_EYEOFFSET)) { LLControlVariable* pControl = gSavedSettings.getControl("CameraOffsetRLVaView"); if (pBhvrModifier->hasValue()) @@ -2298,7 +2298,7 @@ void RlvBehaviourModifierHandler<RLV_MODIFIER_SETCAM_EYEOFFSET>::onValueChange() template<> void RlvBehaviourModifierHandler<RLV_MODIFIER_SETCAM_EYEOFFSETSCALE>::onValueChange() const { - if (RlvBehaviourModifier* pBhvrModifier = RlvBehaviourDictionary::instanceFast().getModifier(RLV_MODIFIER_SETCAM_EYEOFFSETSCALE)) + if (RlvBehaviourModifier* pBhvrModifier = RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SETCAM_EYEOFFSETSCALE)) { LLControlVariable* pControl = gSavedSettings.getControl("CameraOffsetScaleRLVa"); if (pBhvrModifier->hasValue()) @@ -2312,7 +2312,7 @@ void RlvBehaviourModifierHandler<RLV_MODIFIER_SETCAM_EYEOFFSETSCALE>::onValueCha template<> void RlvBehaviourModifierHandler<RLV_MODIFIER_SETCAM_FOCUSOFFSET>::onValueChange() const { - if (RlvBehaviourModifier* pBhvrModifier = RlvBehaviourDictionary::instanceFast().getModifier(RLV_MODIFIER_SETCAM_FOCUSOFFSET)) + if (RlvBehaviourModifier* pBhvrModifier = RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SETCAM_FOCUSOFFSET)) { LLControlVariable* pControl = gSavedSettings.getControl("FocusOffsetRLVaView"); if (pBhvrModifier->hasValue()) @@ -2380,7 +2380,7 @@ void RlvBehaviourToggleHandler<RLV_BHVR_SETCAM_MOUSELOOK>::onCommandToggle(ERlvB template<> void RlvBehaviourModifierHandler<RLV_MODIFIER_SETCAM_TEXTURE>::onValueChange() const { - if (RlvBehaviourModifier* pBhvrModifier = RlvBehaviourDictionary::instanceFast().getModifier(RLV_MODIFIER_SETCAM_TEXTURE)) + if (RlvBehaviourModifier* pBhvrModifier = RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SETCAM_TEXTURE)) { if (pBhvrModifier->hasValue()) { @@ -2437,16 +2437,16 @@ void RlvBehaviourToggleHandler<RLV_BHVR_SETCAM>::onCommandToggle(ERlvBehaviour e gRlvHandler.setCameraOverride(fHasBhvr); RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SETCAM_AVDIST)->setPrimaryObject(idRlvObject); - RlvBehaviourDictionary::instanceFast().getModifier(RLV_MODIFIER_SETCAM_AVDISTMIN)->setPrimaryObject(idRlvObject); - RlvBehaviourDictionary::instanceFast().getModifier(RLV_MODIFIER_SETCAM_AVDISTMAX)->setPrimaryObject(idRlvObject); - RlvBehaviourDictionary::instanceFast().getModifier(RLV_MODIFIER_SETCAM_ORIGINDISTMIN)->setPrimaryObject(idRlvObject); - RlvBehaviourDictionary::instanceFast().getModifier(RLV_MODIFIER_SETCAM_ORIGINDISTMAX)->setPrimaryObject(idRlvObject); - RlvBehaviourDictionary::instanceFast().getModifier(RLV_MODIFIER_SETCAM_EYEOFFSET)->setPrimaryObject(idRlvObject); - RlvBehaviourDictionary::instanceFast().getModifier(RLV_MODIFIER_SETCAM_EYEOFFSETSCALE)->setPrimaryObject(idRlvObject); - RlvBehaviourDictionary::instanceFast().getModifier(RLV_MODIFIER_SETCAM_FOCUSOFFSET)->setPrimaryObject(idRlvObject); - RlvBehaviourDictionary::instanceFast().getModifier(RLV_MODIFIER_SETCAM_FOVMIN)->setPrimaryObject(idRlvObject); - RlvBehaviourDictionary::instanceFast().getModifier(RLV_MODIFIER_SETCAM_FOVMAX)->setPrimaryObject(idRlvObject); - RlvBehaviourDictionary::instanceFast().getModifier(RLV_MODIFIER_SETCAM_TEXTURE)->setPrimaryObject(idRlvObject); + RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SETCAM_AVDISTMIN)->setPrimaryObject(idRlvObject); + RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SETCAM_AVDISTMAX)->setPrimaryObject(idRlvObject); + RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SETCAM_ORIGINDISTMIN)->setPrimaryObject(idRlvObject); + RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SETCAM_ORIGINDISTMAX)->setPrimaryObject(idRlvObject); + RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SETCAM_EYEOFFSET)->setPrimaryObject(idRlvObject); + RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SETCAM_EYEOFFSETSCALE)->setPrimaryObject(idRlvObject); + RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SETCAM_FOCUSOFFSET)->setPrimaryObject(idRlvObject); + RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SETCAM_FOVMIN)->setPrimaryObject(idRlvObject); + RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SETCAM_FOVMAX)->setPrimaryObject(idRlvObject); + RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SETCAM_TEXTURE)->setPrimaryObject(idRlvObject); } // Handles: @setdebug=n|y toggles @@ -2746,7 +2746,7 @@ ERlvCmdRet RlvForceGenericHandler<RLV_OPTION_MODIFIER>::onCommand(const RlvComma return RLV_RET_FAILED_NOBEHAVIOUR; // There should be an option and it should specify a valid modifier (RlvBehaviourModifier performs the appropriate type checks) - RlvBehaviourModifier* pBhvrModifier = RlvBehaviourDictionary::instanceFast().getModifierFromBehaviour(rlvCmd.getBehaviourType()); + RlvBehaviourModifier* pBhvrModifier = RlvBehaviourDictionary::instance().getModifierFromBehaviour(rlvCmd.getBehaviourType()); RlvBehaviourModifierValue modValue; if ( (!rlvCmd.hasOption()) || (!pBhvrModifier) || (!pBhvrModifier->convertOptionValue(rlvCmd.getOption(), pBhvrModifier->getType(), modValue)) ) return RLV_RET_FAILED_OPTION; @@ -3110,7 +3110,7 @@ ERlvCmdRet RlvForceHandler<RLV_BHVR_SETOVERLAY_TWEEN>::onCommand(const RlvComman if (!pRlvObj) return RLV_RET_FAILED_NOBEHAVIOUR; - RlvOverlayEffect* pOverlayEffect = LLVfxManager::instanceFast().getEffect<RlvOverlayEffect>(rlvCmd.getObjectID()); + RlvOverlayEffect* pOverlayEffect = LLVfxManager::instance().getEffect<RlvOverlayEffect>(rlvCmd.getObjectID()); if (!pOverlayEffect) return RLV_RET_FAILED_LOCK; @@ -3629,8 +3629,8 @@ ERlvCmdRet RlvReplyCamMinMaxModifierHandler::onCommand(const RlvCommand& rlvCmd, { if ( (rlvCmd.hasOption()) || (!boost::starts_with(rlvCmd.getBehaviour(), "getcam_")) ) return RLV_RET_FAILED_OPTION; - ERlvBehaviour eBhvr = RlvBehaviourDictionary::instanceFast().getBehaviourFromString("setcam_" + rlvCmd.getBehaviour().substr(7), RLV_TYPE_ADDREM); - if (RlvBehaviourModifier* pBhvrModifier = RlvBehaviourDictionary::instanceFast().getModifierFromBehaviour(eBhvr)) + ERlvBehaviour eBhvr = RlvBehaviourDictionary::instance().getBehaviourFromString("setcam_" + rlvCmd.getBehaviour().substr(7), RLV_TYPE_ADDREM); + if (RlvBehaviourModifier* pBhvrModifier = RlvBehaviourDictionary::instance().getModifierFromBehaviour(eBhvr)) strReply = (pBhvrModifier->hasValue()) ? llformat("%.3f", pBhvrModifier->getValue<float>()) : LLStringUtil::null; return RLV_RET_SUCCESS; } @@ -3644,7 +3644,7 @@ ERlvCmdRet RlvBehaviourCamZoomMinMaxHandler::onCommand(const RlvCommand& rlvCmd, if ( (rlvCmd.hasOption()) && (!RlvCommandOptionHelper::parseOption(rlvCmd.getOption(), nMult)) ) return RLV_RET_FAILED_OPTION; - RlvBehaviourModifier* pBhvrModifier = RlvBehaviourDictionary::instanceFast().getModifier( (RLV_BHVR_CAMZOOMMIN == rlvCmd.getBehaviourType()) ? RLV_MODIFIER_SETCAM_FOVMIN : RLV_MODIFIER_SETCAM_FOVMAX); + RlvBehaviourModifier* pBhvrModifier = RlvBehaviourDictionary::instance().getModifier( (RLV_BHVR_CAMZOOMMIN == rlvCmd.getBehaviourType()) ? RLV_MODIFIER_SETCAM_FOVMIN : RLV_MODIFIER_SETCAM_FOVMAX); if (pBhvrModifier) { if (RLV_TYPE_ADD == rlvCmd.getParamType()) @@ -3679,7 +3679,7 @@ ERlvCmdRet RlvReplyHandler<RLV_BHVR_GETCAM_TEXTURES>::onCommand(const RlvCommand { if (rlvCmd.hasOption()) return RLV_RET_FAILED_OPTION; - if (RlvBehaviourModifier* pBhvrModifier = RlvBehaviourDictionary::instanceFast().getModifier(RLV_MODIFIER_SETCAM_TEXTURE)) + if (RlvBehaviourModifier* pBhvrModifier = RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SETCAM_TEXTURE)) strReply = (pBhvrModifier->hasValue()) ? pBhvrModifier->getValue<LLUUID>().asString() : LLStringUtil::null; return RLV_RET_SUCCESS; } @@ -3708,7 +3708,7 @@ ERlvCmdRet RlvReplyHandler<RLV_BHVR_GETCOMMAND>::onCommand(const RlvCommand& rlv } std::list<std::string> cmdList; - if (RlvBehaviourDictionary::instanceFast().getCommands((optionList.size() >= 1) ? optionList[0] : LLStringUtil::null, eType, cmdList)) + if (RlvBehaviourDictionary::instance().getCommands((optionList.size() >= 1) ? optionList[0] : LLStringUtil::null, eType, cmdList)) strReply = boost::algorithm::join(cmdList, (optionList.size() >= 3) ? optionList[2] : std::string(RLV_OPTION_SEPARATOR) ); return RLV_RET_SUCCESS; } @@ -3846,7 +3846,7 @@ ERlvCmdRet RlvHandler::onGetOutfit(const RlvCommand& rlvCmd, std::string& strRep // (Compatibility: RLV-1.16.1 will execute @getoutfit=<channel> if <layer> is invalid while we just return failure) LLWearableType::EType wtType = LLWearableType::WT_INVALID; - if ( (rlvCmd.hasOption()) && ((wtType = LLWearableType::getInstanceFast()->typeNameToType(rlvCmd.getOption())) == LLWearableType::WT_INVALID) ) + if ( (rlvCmd.hasOption()) && ((wtType = LLWearableType::getInstance()->typeNameToType(rlvCmd.getOption())) == LLWearableType::WT_INVALID) ) return RLV_RET_FAILED_OPTION; const LLWearableType::EType wtRlvTypes[] = @@ -3866,7 +3866,7 @@ ERlvCmdRet RlvHandler::onGetOutfit(const RlvCommand& rlvCmd, std::string& strRep // (nor do we hide a layer if the issuing object is the only one that has this layer locked) bool fWorn = (gAgentWearables.getWearableCount(wtRlvTypes[idxType]) > 0) && ( (!RlvSettings::getHideLockedLayers()) || - (LLAssetType::AT_BODYPART == LLWearableType::getInstanceFast()->getAssetType(wtRlvTypes[idxType])) || + (LLAssetType::AT_BODYPART == LLWearableType::getInstance()->getAssetType(wtRlvTypes[idxType])) || (RlvForceWear::isForceRemovable(wtRlvTypes[idxType], true, rlvCmd.getObjectID())) ); strReply.push_back( (fWorn) ? '1' : '0' ); } @@ -3907,7 +3907,7 @@ ERlvCmdRet RlvHandler::onGetOutfitNames(const RlvCommand& rlvCmd, std::string& s { if (!strReply.empty()) strReply.push_back(','); - strReply.append(LLWearableType::getInstanceFast()->getTypeName(wtType)); + strReply.append(LLWearableType::getInstance()->getTypeName(wtType)); } } return RLV_RET_SUCCESS; diff --git a/indra/newview/rlvhelper.cpp b/indra/newview/rlvhelper.cpp index 8c84ac42e10de476fd76eb32c6502996a1be368f..55064629b62c22c6ff4786ec1354476fc4ffd9ca 100644 --- a/indra/newview/rlvhelper.cpp +++ b/indra/newview/rlvhelper.cpp @@ -743,7 +743,7 @@ RlvCommand::RlvCommand(const LLUUID& idObj, const std::string& strCommand) return; } - m_pBhvrInfo = RlvBehaviourDictionary::instanceFast().getBehaviourInfo(m_strBehaviour, m_eParamType, &m_fStrict, &m_eBhvrModifier); + m_pBhvrInfo = RlvBehaviourDictionary::instance().getBehaviourInfo(m_strBehaviour, m_eParamType, &m_fStrict, &m_eBhvrModifier); } RlvCommand::RlvCommand(const RlvCommand& rlvCmd, ERlvParamType eParamType) @@ -866,7 +866,7 @@ bool RlvCommandOptionHelper::parseOption<float>(const std::string& strOption, fl template<> bool RlvCommandOptionHelper::parseOption<LLWearableType::EType>(const std::string& strOption, LLWearableType::EType& wtOption) { - wtOption = LLWearableType::getInstanceFast()->typeNameToType(strOption); + wtOption = LLWearableType::getInstance()->typeNameToType(strOption); return (LLWearableType::WT_INVALID != wtOption) && (LLWearableType::WT_NONE != wtOption); } @@ -1217,7 +1217,7 @@ std::string RlvObject::getStatusString(const std::string& strFilter, const std:: void RlvObject::clearModifiers(ERlvBehaviour eBhvr) { - if (const RlvBehaviourInfo* pBhvrInfo = RlvBehaviourDictionary::instanceFast().getBehaviourInfo(eBhvr, RLV_TYPE_ADDREM)) + if (const RlvBehaviourInfo* pBhvrInfo = RlvBehaviourDictionary::instance().getBehaviourInfo(eBhvr, RLV_TYPE_ADDREM)) { for (const auto& modifierEntry : pBhvrInfo->getModifiers()) { @@ -1909,13 +1909,13 @@ void RlvBehaviourNotifyHandler::sendNotification(const std::string& strText, con // Checked: 2011-03-31 (RLVa-1.3.0f) | Added: RLVa-1.3.0f void RlvBehaviourNotifyHandler::onWear(LLWearableType::EType eType, bool fAllowed) { - sendNotification(llformat("worn %s %s", (fAllowed) ? "legally" : "illegally", LLWearableType::getInstanceFast()->getTypeName(eType).c_str())); + sendNotification(llformat("worn %s %s", (fAllowed) ? "legally" : "illegally", LLWearableType::getInstance()->getTypeName(eType).c_str())); } // Checked: 2011-03-31 (RLVa-1.3.0f) | Added: RLVa-1.3.0f void RlvBehaviourNotifyHandler::onTakeOff(LLWearableType::EType eType, bool fAllowed) { - sendNotification(llformat("unworn %s %s", (fAllowed) ? "legally" : "illegally", LLWearableType::getInstanceFast()->getTypeName(eType).c_str())); + sendNotification(llformat("unworn %s %s", (fAllowed) ? "legally" : "illegally", LLWearableType::getInstance()->getTypeName(eType).c_str())); } // Checked: 2011-03-31 (RLVa-1.3.0f) | Added: RLVa-1.3.0f diff --git a/indra/newview/rlvmodifiers.h b/indra/newview/rlvmodifiers.h index a1c328fc3adc2d166c80232e15e3af72283d27db..a17a7525a1e46989b6288ea28759f2adfc8309a8 100644 --- a/indra/newview/rlvmodifiers.h +++ b/indra/newview/rlvmodifiers.h @@ -85,7 +85,7 @@ class RlvBehaviourModifierCache : public LLRefCount, public LLInstanceTracker<Rl RlvBehaviourModifierCache(ERlvBehaviourModifier eModifier) : LLInstanceTracker<RlvBehaviourModifierCache<T>, ERlvBehaviourModifier>(eModifier) { - if (RlvBehaviourModifier* pBhvrModifier = RlvBehaviourDictionary::instanceFast().getModifier(eModifier)) + if (RlvBehaviourModifier* pBhvrModifier = RlvBehaviourDictionary::instance().getModifier(eModifier)) { mConnection = pBhvrModifier->getSignal().connect(boost::bind(&RlvBehaviourModifierCache<T>::handleValueChange, this, _1)); mCachedValue = pBhvrModifier->getValue<T>(); @@ -121,7 +121,7 @@ class RlvCachedBehaviourModifier public: RlvCachedBehaviourModifier(ERlvBehaviourModifier eModifier) { - if ((mCachedModifierPtr = RlvBehaviourModifierCache<T>::getInstance(eModifier)) == nullptr) + if ((mCachedModifierPtr = RlvBehaviourModifierCache<T>::getInstance(eModifier).get()) == nullptr) mCachedModifierPtr = new RlvBehaviourModifierCache<T>(eModifier); } diff --git a/indra/newview/rlvui.cpp b/indra/newview/rlvui.cpp index d5a98aeb653223fdd9293ed28f94295a96d47ad5..e10dae635140a041ed324497f83f02de863b4554 100644 --- a/indra/newview/rlvui.cpp +++ b/indra/newview/rlvui.cpp @@ -386,13 +386,13 @@ bool RlvUIEnabler::canViewParcelProperties() { // RELEASE-RLVa: [SL-3.2] Check that opening the "About Land" floater still sets focus to the current parcel is none is selected const LLParcel* pParcel = NULL; - if (LLViewerParcelMgr::getInstanceFast()->selectionEmpty()) + if (LLViewerParcelMgr::getInstance()->selectionEmpty()) { - pParcel = LLViewerParcelMgr::getInstanceFast()->getAgentParcel(); + pParcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); } else { - LLParcelSelection* pParcelSel = LLViewerParcelMgr::getInstanceFast()->getFloatingParcelSelection(); + LLParcelSelection* pParcelSel = LLViewerParcelMgr::getInstance()->getFloatingParcelSelection(); if (pParcelSel->hasOthersSelected()) return false; pParcel = pParcelSel->getParcel(); diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index e519ea5e851e986280a99b9e9d17b541b95e7754..15e45944590c25c7a2ac4109e508ed1e26d25e39 100644 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -528,6 +528,9 @@ <color name="MapParcelBoundryLine" reference="White" /> + <color + name="MapParcelOutlineColor" + value="1 1 0 0.5" /> <color name="MapTrackColor" reference="Red" /> @@ -619,10 +622,10 @@ reference="Black_10" /> <color name="NetMapGroupOwnAboveWater" - reference="Purple" /> + value="0.85 0 0.85 1" /> <color name="NetMapGroupOwnBelowWater" - value="0.78 0 0.78 1" /> + value="0.63 0 0.63 1" /> <color name="NetMapOtherOwnAboveWater" value="0.24 0.24 0.24 1" /> @@ -631,10 +634,10 @@ value="0.12 0.12 0.12 1" /> <color name="NetMapYouOwnAboveWater" - value="0 1 1 1" /> + value="0 0.85 0.85 1" /> <color name="NetMapYouOwnBelowWater" - value="0 0.78 0.78 1" /> + value="0 0.63 0.63 1" /> <color name="NotifyBoxColor" value="LtGray" /> diff --git a/indra/newview/skins/default/textures/icons/ClipboardMenu_Disabled.png b/indra/newview/skins/default/textures/icons/ClipboardMenu_Disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..9a81c5f94b65713dcac65f5e743639162bcb8481 Binary files /dev/null and b/indra/newview/skins/default/textures/icons/ClipboardMenu_Disabled.png differ diff --git a/indra/newview/skins/default/textures/icons/ClipboardMenu_Off.png b/indra/newview/skins/default/textures/icons/ClipboardMenu_Off.png new file mode 100644 index 0000000000000000000000000000000000000000..88012cf8d124c6a6cb083d597fb92c689f1f9c5f Binary files /dev/null and b/indra/newview/skins/default/textures/icons/ClipboardMenu_Off.png differ diff --git a/indra/newview/skins/default/textures/icons/ClipboardMenu_Press.png b/indra/newview/skins/default/textures/icons/ClipboardMenu_Press.png new file mode 100644 index 0000000000000000000000000000000000000000..ab02e7d42d798f997296e721023759f7e6600d1f Binary files /dev/null and b/indra/newview/skins/default/textures/icons/ClipboardMenu_Press.png differ diff --git a/indra/newview/skins/default/textures/icons/ClipboardSmallMenu_Disabled.png b/indra/newview/skins/default/textures/icons/ClipboardSmallMenu_Disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..63b4bd212739ec9a9c54b782beb31a7b70a63c73 Binary files /dev/null and b/indra/newview/skins/default/textures/icons/ClipboardSmallMenu_Disabled.png differ diff --git a/indra/newview/skins/default/textures/icons/ClipboardSmallMenu_Off.png b/indra/newview/skins/default/textures/icons/ClipboardSmallMenu_Off.png new file mode 100644 index 0000000000000000000000000000000000000000..4200182b0cec4c7ff7aea2bf60232207640aad9f Binary files /dev/null and b/indra/newview/skins/default/textures/icons/ClipboardSmallMenu_Off.png differ diff --git a/indra/newview/skins/default/textures/icons/ClipboardSmallMenu_Press.png b/indra/newview/skins/default/textures/icons/ClipboardSmallMenu_Press.png new file mode 100644 index 0000000000000000000000000000000000000000..e12887f4891a587ad029d994844bb9c0ac766022 Binary files /dev/null and b/indra/newview/skins/default/textures/icons/ClipboardSmallMenu_Press.png differ diff --git a/indra/newview/skins/default/textures/icons/Profile_Friend_Offline.png b/indra/newview/skins/default/textures/icons/Profile_Friend_Offline.png new file mode 100644 index 0000000000000000000000000000000000000000..aeba6b70f785ed9b7f01bb8662710c5f31ebf48f Binary files /dev/null and b/indra/newview/skins/default/textures/icons/Profile_Friend_Offline.png differ diff --git a/indra/newview/skins/default/textures/icons/Profile_Friend_Online.png b/indra/newview/skins/default/textures/icons/Profile_Friend_Online.png new file mode 100644 index 0000000000000000000000000000000000000000..d668fd8dfa0460456e5b17b80fd63aac95d1c841 Binary files /dev/null and b/indra/newview/skins/default/textures/icons/Profile_Friend_Online.png differ diff --git a/indra/newview/skins/default/textures/icons/Profile_Perm_Find_Disabled.png b/indra/newview/skins/default/textures/icons/Profile_Perm_Find_Disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..8f8caa10d84d90e3b34c88804711d845a2f08317 Binary files /dev/null and b/indra/newview/skins/default/textures/icons/Profile_Perm_Find_Disabled.png differ diff --git a/indra/newview/skins/default/textures/icons/Profile_Perm_Find_Enabled.png b/indra/newview/skins/default/textures/icons/Profile_Perm_Find_Enabled.png new file mode 100644 index 0000000000000000000000000000000000000000..42a209dda51f25e0d012d202526010f7449dfe1c Binary files /dev/null and b/indra/newview/skins/default/textures/icons/Profile_Perm_Find_Enabled.png differ diff --git a/indra/newview/skins/default/textures/icons/Profile_Perm_Objects_Disabled.png b/indra/newview/skins/default/textures/icons/Profile_Perm_Objects_Disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..644edf0ef611607ca797b5c3636eb8daa1f820a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icons/Profile_Perm_Objects_Disabled.png differ diff --git a/indra/newview/skins/default/textures/icons/Profile_Perm_Objects_Enabled.png b/indra/newview/skins/default/textures/icons/Profile_Perm_Objects_Enabled.png new file mode 100644 index 0000000000000000000000000000000000000000..629c05ecb83947b0ab424ce7ed867747d4f4f006 Binary files /dev/null and b/indra/newview/skins/default/textures/icons/Profile_Perm_Objects_Enabled.png differ diff --git a/indra/newview/skins/default/textures/icons/Profile_Perm_Online_Disabled.png b/indra/newview/skins/default/textures/icons/Profile_Perm_Online_Disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..ecf66c0ee100c4e5152357429d5e471be4386f91 Binary files /dev/null and b/indra/newview/skins/default/textures/icons/Profile_Perm_Online_Disabled.png differ diff --git a/indra/newview/skins/default/textures/icons/Profile_Perm_Online_Enabled.png b/indra/newview/skins/default/textures/icons/Profile_Perm_Online_Enabled.png new file mode 100644 index 0000000000000000000000000000000000000000..26123938fa11d606d0f4867854120701da771cc9 Binary files /dev/null and b/indra/newview/skins/default/textures/icons/Profile_Perm_Online_Enabled.png differ diff --git a/indra/newview/skins/default/textures/icons/avaline_default_icon.jpg b/indra/newview/skins/default/textures/icons/avaline_default_icon.jpg deleted file mode 100644 index 3bb7f7183cd751eddcabd75da8b9f1dc9e86f0f3..0000000000000000000000000000000000000000 Binary files a/indra/newview/skins/default/textures/icons/avaline_default_icon.jpg and /dev/null differ diff --git a/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_off.png b/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_off.png new file mode 100644 index 0000000000000000000000000000000000000000..3a2ed399b228453d4101b5eb22e6f98ddb4d4941 Binary files /dev/null and b/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_off.png differ diff --git a/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_off_pressed.png b/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_off_pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..789f59a49109b5474aa0b86fc2c9d3fc278836f0 Binary files /dev/null and b/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_off_pressed.png differ diff --git a/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_on.png b/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_on.png new file mode 100644 index 0000000000000000000000000000000000000000..4fb56c389c8e476c183c65b46b4ed3d98fa4747e Binary files /dev/null and b/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_on.png differ diff --git a/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_on_pressed.png b/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_on_pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..ae04a256a4ded26470906d4140d68fdd6c7ac3a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_on_pressed.png differ diff --git a/indra/newview/skins/default/textures/map_ui_collapse_icon.png b/indra/newview/skins/default/textures/map_ui_collapse_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..e4de49d4af82e3a4a0952eedf81f0c58782dd0ae Binary files /dev/null and b/indra/newview/skins/default/textures/map_ui_collapse_icon.png differ diff --git a/indra/newview/skins/default/textures/map_ui_expand_icon.png b/indra/newview/skins/default/textures/map_ui_expand_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..08734b4cc096d3aeec81ca89e205814c94dc676c Binary files /dev/null and b/indra/newview/skins/default/textures/map_ui_expand_icon.png differ diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index dec8376955f65c961c54c0f2bce5a1977554022a..38860cb95a559fe787d9a13bda77a3ebec8c10bf 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -71,8 +71,6 @@ with the same filename but different name <texture name="Move" file_name="icons/move.png" preload="false" /> <texture name="Move_Off" file_name="icons/move_off.png" preload="false" /> - <texture name="Avaline_Icon" file_name="icons/avaline_default_icon.jpg" preload="true" /> - <texture name="BackArrow_Off" file_name="icons/BackArrow_Off.png" preload="false" /> <texture name="BackButton_Off" file_name="icons/back_arrow_off.png" preload="false" scale.left="22" scale.top="12" scale.right="25" scale.bottom="12" /> @@ -466,6 +464,13 @@ with the same filename but different name <texture name="OptionsMenu_Off" file_name="icons/OptionsMenu_Off.png" preload="false" /> <texture name="OptionsMenu_Press" file_name="icons/OptionsMenu_Press.png" preload="false" /> + <texture name="ClipboardSmallMenu_Disabled" file_name="icons/ClipboardSmallMenu_Disabled.png" preload="false" /> + <texture name="ClipboardSmallMenu_Off" file_name="icons/ClipboardSmallMenu_Off.png" preload="false" /> + <texture name="ClipboardSmallMenu_Press" file_name="icons/ClipboardSmallMenu_Press.png" preload="false" /> + <texture name="ClipboardMenu_Disabled" file_name="icons/ClipboardMenu_Disabled.png" preload="false" /> + <texture name="ClipboardMenu_Off" file_name="icons/ClipboardMenu_Off.png" preload="false" /> + <texture name="ClipboardMenu_Press" file_name="icons/ClipboardMenu_Press.png" preload="false" /> + <texture name="OutboxStatus_Success" file_name="green_checkmark.png" preload="false" /> <texture name="OutboxStatus_Warning" file_name="icons/pop_up_caution.png" preload="false" /> <texture name="OutboxStatus_Error" file_name="red_x.png" preload="false" /> @@ -527,6 +532,19 @@ with the same filename but different name <texture name="Play_Over" file_name="icons/Play_Over.png" preload="false" /> <texture name="Play_Press" file_name="icons/Play_Press.png" preload="false" /> + <texture name="Profile_Group_Visibility_Off" file_name="icons/profile_group_visibility_eye_off.png" preload="true"/> + <texture name="Profile_Group_Visibility_Off_Pressed" file_name="icons/profile_group_visibility_eye_off_pressed.png" preload="true"/> + <texture name="Profile_Group_Visibility_On" file_name="icons/profile_group_visibility_eye_on.png" preload="true"/> + <texture name="Profile_Group_Visibility_On_Pressed" file_name="icons/profile_group_visibility_eye_on_pressed.png" preload="true"/> + <texture name="Profile_Friend_Offline" file_name="icons/Profile_Friend_Offline.png" preload="true"/> + <texture name="Profile_Friend_Online" file_name="icons/Profile_Friend_Online.png" preload="true"/> + <texture name="Profile_Perm_Find_Disabled" file_name="icons/Profile_Perm_Find_Disabled.png" preload="true"/> + <texture name="Profile_Perm_Find_Enabled" file_name="icons/Profile_Perm_Find_Enabled.png" preload="true"/> + <texture name="Profile_Perm_Objects_Disabled" file_name="icons/Profile_Perm_Objects_Disabled.png" preload="true"/> + <texture name="Profile_Perm_Objects_Enabled" file_name="icons/Profile_Perm_Objects_Enabled.png" preload="true"/> + <texture name="Profile_Perm_Online_Disabled" file_name="icons/Profile_Perm_Online_Disabled.png" preload="true"/> + <texture name="Profile_Perm_Online_Enabled" file_name="icons/Profile_Perm_Online_Enabled.png" preload="true"/> + <texture name="ProgressBar" file_name="widgets/ProgressBar.png" preload="true" scale.left="4" scale.top="11" scale.right="48" scale.bottom="3" /> <texture name="ProgressBarSolid" file_name="widgets/ProgressBarSolid.png" preload="true" scale.left="4" scale.top="11" scale.right="48" scale.bottom="3" /> <texture name="ProgressTrack" file_name="widgets/ProgressTrack.png" preload="true" scale.left="4" scale.top="13" scale.right="148" scale.bottom="2" /> @@ -635,8 +653,7 @@ with the same filename but different name <texture name="login_sl_logo" file_name="windows/login_sl_logo.png" preload="true" /> <texture name="login_sl_logo_small" file_name="windows/login_sl_logo_small.png" preload="true" /> - <texture name="first_login_image_left" file_name="windows/first_login_image_left.png" preload="true" /> - <texture name="first_login_image_right" file_name="windows/first_login_image_right.png" preload="true" /> + <texture name="first_login_image" file_name="windows/first_login_image.jpg" preload="true" /> <texture name="Stepper_Down_Off" file_name="widgets/Stepper_Down_Off.png" preload="false" /> <texture name="Stepper_Down_Press" file_name="widgets/Stepper_Down_Press.png" preload="false" /> @@ -834,6 +851,8 @@ with the same filename but different name <texture name="map_infohub.tga" /> <texture name="map_telehub.tga" /> <texture name="map_track_16.tga" /> + <texture name="map_ui_collapse_icon.png" /> + <texture name="map_ui_expand_icon.png" /> <texture name="notify_caution_icon.tga" /> diff --git a/indra/newview/skins/default/textures/windows/first_login_image.jpg b/indra/newview/skins/default/textures/windows/first_login_image.jpg new file mode 100644 index 0000000000000000000000000000000000000000..30f31341edc886fa2c0b23f6b4cb442495fcff17 Binary files /dev/null and b/indra/newview/skins/default/textures/windows/first_login_image.jpg differ diff --git a/indra/newview/skins/default/textures/windows/first_login_image_left.png b/indra/newview/skins/default/textures/windows/first_login_image_left.png deleted file mode 100644 index 77904d7d1288e123016e1d4f4c19a3c607336a8f..0000000000000000000000000000000000000000 Binary files a/indra/newview/skins/default/textures/windows/first_login_image_left.png and /dev/null differ diff --git a/indra/newview/skins/default/textures/windows/first_login_image_right.png b/indra/newview/skins/default/textures/windows/first_login_image_right.png deleted file mode 100644 index 35ecce9c0703486c9f9f08378bcd0aff354c01d2..0000000000000000000000000000000000000000 Binary files a/indra/newview/skins/default/textures/windows/first_login_image_right.png and /dev/null differ diff --git a/indra/newview/skins/default/xui/da/floater_about.xml b/indra/newview/skins/default/xui/da/floater_about.xml index edcf7b1140c7c6649c52dbdd4d0c6a0930ca7bfd..887581c0e2112dbfe2615ff5a53d395b1189ef5a 100644 --- a/indra/newview/skins/default/xui/da/floater_about.xml +++ b/indra/newview/skins/default/xui/da/floater_about.xml @@ -60,7 +60,6 @@ DBus/dbus-glib Copyright (C) 2002, 2003 CodeFactory AB / Copyright (C) 2003, 20 expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd. FreeType Copyright (C) 1996-2002, The FreeType Project (www.freetype.org). GL Copyright (C) 1999-2004 Brian Paul. -GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University and David Luebke, Brenden Schubert, University of Virginia. google-perftools Copyright (c) 2005, Google Inc. Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited. jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW) diff --git a/indra/newview/skins/default/xui/da/panel_region_texture.xml b/indra/newview/skins/default/xui/da/panel_region_texture.xml index 45946fd222a2a8aed3ee4312c695814a27a534b4..c8a3ad328ec01438320912cd0679b6a08381ec5a 100644 --- a/indra/newview/skins/default/xui/da/panel_region_texture.xml +++ b/indra/newview/skins/default/xui/da/panel_region_texture.xml @@ -7,8 +7,8 @@ ukendt </text> <text name="detail_texture_text"> - Terræn teksturer (kræver 512x512, 24 bit .tga filer) - </text> + Terræn teksturer (kræver 1024x1024, 24 bit .tga filer) + </text> <text name="height_text_lbl"> 1 (Lav) </text> diff --git a/indra/newview/skins/default/xui/da/strings.xml b/indra/newview/skins/default/xui/da/strings.xml index 814305c1bc230461d41b52da57f31687bd244be6..e4f99d14e9b4b4182a171f1d6119e1e18545a3c2 100644 --- a/indra/newview/skins/default/xui/da/strings.xml +++ b/indra/newview/skins/default/xui/da/strings.xml @@ -106,7 +106,7 @@ <string name="LoginFailedNoNetwork"> Netværksfejl: Kunne ikke etablere forbindelse, check venligst din netværksforbindelse. </string> - <string name="LoginFailed"> + <string name="LoginFailedHeader"> Login fejlede. </string> <string name="Quit"> @@ -443,9 +443,6 @@ Prøv venligst om lidt igen. <string name="GroupNameNone"> (ingen) </string> - <string name="AvalineCaller"> - Avaline opkalder [ORDER] - </string> <string name="AssetErrorNone"> Ingen fejl </string> diff --git a/indra/newview/skins/default/xui/de/floater_about.xml b/indra/newview/skins/default/xui/de/floater_about.xml index 42e23b208995dafc49e70ae1a2802b164bda65bc..b2708f71416b80b31ba969d1033b74e9d9934b1d 100644 --- a/indra/newview/skins/default/xui/de/floater_about.xml +++ b/indra/newview/skins/default/xui/de/floater_about.xml @@ -19,7 +19,6 @@ mit Open-Source-Beiträgen von:</text> expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd. FreeType Copyright (C) 1996-2002, 2006 David Turner, Robert Wilhelm und Werner Lemberg. GL Copyright (C) 1999-2004 Brian Paul. - GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University sowie David Luebke, Brenden Schubert, University of Virginia. google-perftools Copyright (c) 2005, Google Inc. Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited. jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW). diff --git a/indra/newview/skins/default/xui/de/panel_region_terrain.xml b/indra/newview/skins/default/xui/de/panel_region_terrain.xml index 7801be30e482860200f5b456a2bdedd9cb85e2f0..42ba5b5269b20232748dfaee0f551c5ace327a0c 100644 --- a/indra/newview/skins/default/xui/de/panel_region_terrain.xml +++ b/indra/newview/skins/default/xui/de/panel_region_terrain.xml @@ -10,8 +10,8 @@ <spinner label="Obere Terraingrenze" name="terrain_raise_spin"/> <spinner label="Untere Terraingrenze" name="terrain_lower_spin"/> <text name="detail_texture_text"> - Terraintexturen (erfordert 24-Bit-.tga-Dateien mit einer Größe von 512x512) - </text> + Terraintexturen (erfordert 24-Bit-.tga-Dateien mit einer Größe von 1024x1024) + </text> <text name="height_text_lbl"> 1 (niedrig) </text> diff --git a/indra/newview/skins/default/xui/de/strings.xml b/indra/newview/skins/default/xui/de/strings.xml index 554647bb92cd04669ef564a10c678b1e75be0df8..5f5f5b7a688db0d8f4d35c8c3289fcedc34e55f1 100644 --- a/indra/newview/skins/default/xui/de/strings.xml +++ b/indra/newview/skins/default/xui/de/strings.xml @@ -186,7 +186,7 @@ Voice-Server-Version: [VOICE_VERSION] <string name="LoginFailedNoNetwork"> Netzwerkfehler: Verbindung konnte nicht hergestellt werden. Bitte überprüfen Sie Ihre Netzwerkverbindung. </string> - <string name="LoginFailed"> + <string name="LoginFailedHeader"> Anmeldung fehlgeschlagen </string> <string name="Quit"> @@ -691,9 +691,6 @@ nächsten Eigentümer angehängt werden. <string name="GroupNameNone"> (keiner) </string> - <string name="AvalineCaller"> - Avaline-Anfrufer [ORDER] - </string> <string name="AssetErrorNone"> Kein Fehler </string> @@ -5134,7 +5131,7 @@ Bitte überprüfen Sie http://status.secondlifegrid.net, um herauszufinden, ob e <string name="PremiumMembership"> Premium </string> - <string name="Premium PlusMembership"> + <string name="Premium_PlusMembership"> Premium Plus </string> <string name="DeleteItems"> diff --git a/indra/newview/skins/default/xui/en/floater_about.xml b/indra/newview/skins/default/xui/en/floater_about.xml index fb683ee1651075de3e98b0f7937e1bccf8839054..4f8ab4f1a879ef083a4009d34c58f50019f03961 100644 --- a/indra/newview/skins/default/xui/en/floater_about.xml +++ b/indra/newview/skins/default/xui/en/floater_about.xml @@ -102,11 +102,11 @@ Dummy Name replaced at run time expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd. FreeType Copyright (C) 1996-2002, 2006 David Turner, Robert Wilhelm, and Werner Lemberg. GL Copyright (C) 1999-2004 Brian Paul. - GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University and David Luebke, Brenden Schubert, University of Virginia. google-perftools Copyright (c) 2005, Google Inc. Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited. jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW) jpeglib Copyright (C) 1991-1998, Thomas G. Lane. + meshoptimizer Copyright (c) 2016-2021 Arseny Kapoulkine ogg/vorbis Copyright (C) 2002, Xiphophorus OpenSSL Copyright (C) 1998-2008 The OpenSSL Project. PCRE Copyright (c) 1997-2012 University of Cambridge diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml index 8419d7d5a7f493388cf288460dac3e0abe80c389..e89505449d78ebb42074d7b64a97e60fcc07f598 100644 --- a/indra/newview/skins/default/xui/en/floater_about_land.xml +++ b/indra/newview/skins/default/xui/en/floater_about_land.xml @@ -164,6 +164,7 @@ left_pad="2" name="Description" spellcheck="true" + parse_urls="true" top_delta="0" width="365" word_wrap="true" /> @@ -1927,7 +1928,29 @@ Only large parcels can be listed in search. left="110" name="parcel_enable_voice_channel_local" width="300" /> - </panel> + <text + type="string" + length="1" + follows="left|top" + height="16" + layout="topleft" + left="10" + mouse_opaque="false" + name="media" + top_pad="10" + width="100"> + Media: + </text> + <check_box + height="16" + label="Obscure MOAP" + layout="topleft" + left="110" + left_pad="0" + name="obscure_moap" + tool_tip="Media on a prim located outside the parcel should not play automatically for an agent within this parcel and vice versa." + width="300" /> + </panel> <panel border="true" follows="all" diff --git a/indra/newview/skins/default/xui/en/floater_picks.xml b/indra/newview/skins/default/xui/en/floater_classified.xml similarity index 86% rename from indra/newview/skins/default/xui/en/floater_picks.xml rename to indra/newview/skins/default/xui/en/floater_classified.xml index 3cd6abafe54a51bbfd2e6da2b664e9fc570e42e2..5b14c827d018b7c34001b7853ea696981734d4c6 100644 --- a/indra/newview/skins/default/xui/en/floater_picks.xml +++ b/indra/newview/skins/default/xui/en/floater_classified.xml @@ -7,11 +7,10 @@ help_topic="sidebar_me" min_width="333" min_height="440" - name="floater_picks" + name="floater_classified" save_rect="true" save_visibility="false" - reuse_instance="true" - title="Picks" + title="Classified" width="333" > <panel class="panel_classified_info" diff --git a/indra/newview/skins/default/xui/en/floater_create_landmark.xml b/indra/newview/skins/default/xui/en/floater_create_landmark.xml index 5edc3d767488bdd9f148da3adc9fa064e749e508..6735e43f79ec8c32136ac8abb9ebf69bd9d756a9 100644 --- a/indra/newview/skins/default/xui/en/floater_create_landmark.xml +++ b/indra/newview/skins/default/xui/en/floater_create_landmark.xml @@ -88,6 +88,7 @@ spellcheck="true" text_readonly_color="white" text_type="ascii_with_newline" + commit_on_focus_lost="true" top_pad="5" width="290" wrap="true" /> 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 9a9fd32a773b3a07584c45368ce4f062d17bc6de..3c8f4158605579d383dfa14fdcad8c1e0fc97ecb 100644 --- a/indra/newview/skins/default/xui/en/floater_display_name.xml +++ b/indra/newview/skins/default/xui/en/floater_display_name.xml @@ -23,7 +23,7 @@ use_ellipses="true" width="380" wrap="true"> - The name you give your avatar is called your Display Name. You can change it once a week. + Your display name is what other people see above your head. It is different from your login name. You can change it once a week. </text> <text type="string" @@ -83,21 +83,12 @@ tool_tip="Save your new Display Name" top_pad="40" width="120" /> - <button - height="23" - label="Reset" - layout="topleft" - font="SansSerif" - left_pad="5" - name="reset_btn" - tool_tip="Make Display Name the same as Username" - width="120" /> <button height="23" label="Cancel" font="SansSerif" layout="topleft" - left_pad="5" + left_pad="125" name="cancel_btn" width="120" /> </floater> diff --git a/indra/newview/skins/default/xui/en/floater_map.xml b/indra/newview/skins/default/xui/en/floater_map.xml index 42aef9dd0cf94c40e2ec7f8bcb452f13aaac1075..201563290eb204ad0f221dbe16e68950136465f6 100644 --- a/indra/newview/skins/default/xui/en/floater_map.xml +++ b/indra/newview/skins/default/xui/en/floater_map.xml @@ -19,11 +19,35 @@ <!-- RLVa shows the anonymized name on the regular tooltip when @shownames=n restricted (rather than show the avatar inspector) --> <floater.string name="ToolTipMsg"> - [AGENT][REGION](Double-click to open Map, shift-drag to pan) + [PARCEL_NAME_MSG][PARCEL_SALE_PRICE_MSG][PARCEL_SALE_AREA_MSG][PARCEL_OWNER_MSG][REGION_NAME_MSG][TOOL_TIP_HINT_MSG] + </floater.string> + <floater.string + name="ParcelNameMsg"> + [PARCEL_NAME] + </floater.string> + <floater.string + name="ParcelSalePriceMsg"> + Price: L$[PRICE] (L$[PRICE_PER_SQM]/m²) + </floater.string> + <floater.string + name="ParcelSaleAreaMsg"> + Area: [AREA]m² + </floater.string> + <floater.string + name="ParcelOwnerMsg"> + Owner: [PARCEL_OWNER] + </floater.string> + <floater.string + name="RegionNameMsg"> + Region: [REGION_NAME] </floater.string> <floater.string - name="AltToolTipMsg"> - [REGION](Double-click to teleport, shift-drag to pan) + name="ToolTipHintMsg"> + Double-click to open map + </floater.string> + <floater.string + name="AltToolTipHintMsg"> + Double-click to teleport </floater.string> <floater.string name="mini_map_caption"> Mini-map @@ -41,113 +65,73 @@ <text type="string" length="1" - bottom="218" label="N" layout="topleft" - left="0" name="floater_map_north" - right="10" - text_color="1 1 1 0.7" - font_shadow="hard" - top="189"> + text_color="1 1 1 0.7"> N </text> <text type="string" length="1" - bottom="218" label="E" layout="topleft" - left="0" name="floater_map_east" - right="10" - text_color="1 1 1 0.7" - font_shadow="hard" - top="189"> + text_color="1 1 1 0.7"> E </text> <text type="string" length="1" - bottom="205" label="W" layout="topleft" - left="0" name="floater_map_west" - right="11" - text_color="1 1 1 0.7" - font_shadow="hard" - top="175"> + text_color="1 1 1 0.7"> W </text> <text type="string" length="1" - bottom="218" label="S" layout="topleft" - left="0" name="floater_map_south" - right="10" - text_color="1 1 1 0.7" - font_shadow="hard" - top="189"> + text_color="1 1 1 0.7"> S </text> <text type="string" length="1" - bottom="218" label="SE" layout="topleft" - left="0" name="floater_map_southeast" - right="20" - text_color="1 1 1 0.7" - font_shadow="hard" - top="189"> + text_color="1 1 1 0.7"> SE </text> <text type="string" length="1" - bottom="218" label="NE" layout="topleft" - left="0" name="floater_map_northeast" - right="20" - text_color="1 1 1 0.7" - font_shadow="hard" - top="189"> + text_color="1 1 1 0.7"> NE </text> <text type="string" length="1" - bottom="218" label="SW" layout="topleft" - left="0" name="floater_map_southwest" - right="20" - text_color="1 1 1 0.7" - font_shadow="hard" - top="189"> + text_color="1 1 1 0.7"> SW </text> <text type="string" length="1" - bottom="218" label="NW" layout="topleft" - left="0" name="floater_map_northwest" - right="20" - text_color="1 1 1 0.7" - font_shadow="hard" - top="189"> + text_color="1 1 1 0.7"> NW </text> </floater> diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml index e499ddbc2f396f3ea6789c060c29fc775cad031d..21c894d3afeef19e9cd40fcdb670579cf13993a1 100644 --- a/indra/newview/skins/default/xui/en/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml @@ -830,6 +830,7 @@ <combo_item name="physics_medium"> Medium </combo_item> <combo_item name="physics_low"> Low </combo_item> <combo_item name="physics_lowest"> Lowest </combo_item> + <combo_item name="physics_bounding_box"> Bounding Box </combo_item> <combo_item name="load_from_file"> From file </combo_item> </combo_box> <line_editor diff --git a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml index 7620029749f6afce02cd5d8e69e6efee645f442c..59beb60d9420e339987e760a8fb4589e8aa200b3 100644 --- a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml +++ b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml @@ -103,6 +103,18 @@ Low </text> + <check_box + control_name="RenderVSyncEnable" + height="16" + initial_value="true" + label="Enable VSync" + layout="topleft" + left="30" + top_delta="16" + name="vsync" + tool_tip="Synchronizes the frame rate to the refresh rate of the monitor, which results in smooth performance." + width="315" /> + <text type="string" length="1" @@ -324,18 +336,6 @@ (0 = default brightness, lower = brighter) </text> - <check_box - control_name="RenderVBOEnable" - height="16" - initial_value="true" - label="Enable OpenGL Vertex Buffer Objects" - layout="topleft" - left="30" - top_delta="16" - name="vbo" - tool_tip="Enabling this on modern hardware gives a performance gain. However, older hardware often has poor implementations of VBOs and you may get crashes when this is enabled." - width="315" /> - <check_box control_name="RenderCompressTextures" height="16" @@ -694,20 +694,6 @@ Low </text> - <check_box - control_name="RenderAvatarVP" - height="16" - initial_value="true" - label="Avatar Hardware skinning" - layout="topleft" - left="440" - name="AvatarVertexProgram" - top_delta="16" - width="280"> - <check_box.commit_callback - function="Pref.RenderOptionUpdate" /> - </check_box> - <check_box control_name="RenderAvatarCloth" height="16" @@ -942,7 +928,7 @@ layout="topleft" left="13" name="horiz_border" - top_pad="5" + top_pad="21" top_delta="5" width="774"/> <button diff --git a/indra/newview/skins/default/xui/en/floater_profile.xml b/indra/newview/skins/default/xui/en/floater_profile.xml index 9e01e0c1d188e48e2f6580e3697fcec91fa11b59..32ab811a6e62f97ab93dd0e1bd5669799b54394f 100644 --- a/indra/newview/skins/default/xui/en/floater_profile.xml +++ b/indra/newview/skins/default/xui/en/floater_profile.xml @@ -2,13 +2,13 @@ <floater name="avatarinfo" height="510" - width="450" + width="510" layout="topleft" can_close="true" can_resize="true" help_topic="panel_my_profile_tab" min_height="510" - min_width="450" + min_width="510" positioning="centered" save_rect="true" title="Profile" @@ -18,7 +18,7 @@ top="0" left="0" height="500" - width="445" + width="505" follows="all" class="panel_profile" > @@ -27,16 +27,17 @@ top_pad="5" left="0" height="500" - width="445" + width="505" follows="all" layout="topleft" halign="center" - tab_min_width="55" + tab_min_width="81" + tab_height="30" tab_position="top" > <panel name="panel_profile_secondlife" - label="2nd Life" + label="BIO" layout="topleft" class="panel_profile_secondlife" filename="panel_profile_secondlife.xml" @@ -44,23 +45,15 @@ /> <panel name="panel_profile_web" - label="Feed" + label="FEED" layout="topleft" class="panel_profile_web" filename="panel_profile_web.xml" help_topic="profile_web_tab" /> - <panel - name="panel_profile_interests" - label="Interests" - layout="topleft" - class="panel_profile_interests" - filename="panel_profile_interests.xml" - help_topic="profile_interests_tab" - /> <panel name="panel_profile_picks" - label="Picks" + label="PICKS" layout="topleft" class="panel_profile_picks" filename="panel_profile_picks.xml" @@ -68,7 +61,7 @@ /> <panel name="panel_profile_classifieds" - label="Classified" + label="CLASSIFIEDS" layout="topleft" class="panel_profile_classifieds" filename="panel_profile_classifieds.xml" @@ -76,7 +69,7 @@ /> <panel name="panel_profile_firstlife" - label="Real Life" + label="REAL LIFE" layout="topleft" class="panel_profile_firstlife" filename="panel_profile_firstlife.xml" @@ -84,37 +77,12 @@ /> <panel name="panel_profile_notes" - label="Notes" + label="MY NOTES" layout="topleft" class="panel_profile_notes" filename="panel_profile_notes.xml" help_topic="profile_notes_tab" /> </tab_container> - <button - name="ok_btn" - label="OK" - tool_tip="Save changes to profile and close" - bottom_delta="0" - left="10" - height="20" - width="90" - follows="left|bottom" - layout="topleft" - visible="false" - /> - <button - name="cancel_btn" - label="Cancel" - tool_tip="Discard unsaved changes and close" - bottom_delta="0" - right="-10" - height="20" - width="90" - follows="right|bottom" - layout="topleft" - label_selected="Cancel" - visible="false" - /> </panel> </floater> diff --git a/indra/newview/skins/default/xui/en/floater_profile_permissions.xml b/indra/newview/skins/default/xui/en/floater_profile_permissions.xml new file mode 100644 index 0000000000000000000000000000000000000000..9f3b4d9a00b50c143c9c1f9b9e70a32bc140c7b9 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_profile_permissions.xml @@ -0,0 +1,76 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + can_resize="false" + show_title="false" + can_minimize="false" + can_close="false" + header_height="10" + bg_opaque_image="Window_NoTitle_Foreground" + bg_alpha_image="Window_NoTitle_Background" + height="115" + layout="topleft" + name="profile_permissions" + width="300"> + <string + name="description_string" + value="Allow [AGENT_NAME] to:" /> + <text + name="perm_description" + value="Allow agent to:" + top="1" + left="12" + right="-6" + height="16" + follows="top|left" + layout="topleft" + font.style="BOLD" + /> + <check_box + name="online_check" + label="See when I am online" + top_pad="5" + left="16" + height="16" + width="293" + follows="top|left" + layout="topleft" + /> + <check_box + name="map_check" + label="Find me on the world map" + top_pad="5" + left="16" + height="16" + width="293" + follows="top|left" + layout="topleft" + /> + <check_box + name="objects_check" + label="Edit, delete or take my objects from my land" + top_pad="5" + left="16" + height="16" + width="293" + follows="top|left" + layout="topleft" + /> + <button + name="perms_btn_ok" + label="OK" + top_pad="5" + left="42" + height="20" + width="100" + follows="top|left" + layout="topleft"/> + <button + name="perms_btn_cancel" + label="Cancel" + top_delta="0" + left_pad="12" + height="20" + width="100" + follows="top|left" + layout="topleft"/> +</floater> diff --git a/indra/newview/skins/default/xui/en/floater_profile_texture.xml b/indra/newview/skins/default/xui/en/floater_profile_texture.xml new file mode 100644 index 0000000000000000000000000000000000000000..3b351a332525b541868ca9bd50769166dbb369b5 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_profile_texture.xml @@ -0,0 +1,88 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + can_resize="false" + show_title="false" + can_minimize="false" + can_close="false" + header_height="10" + height="223" + width="200" + layout="topleft" + min_height="128" + min_width="128" + name="profile_texture"> + <layout_stack + name="preview_stack" + top="0" + left="0" + right="-1" + bottom="-1" + follows="all" + orientation="vertical" + layout="topleft" + animate="false"> + <layout_panel + name="texture_panel" + height="196" + follows="left|top" + auto_resize="true" + layout="topleft"> + <icon + name="profile_pic" + image_name="Generic_Person_Large" + layout="topleft" + follows="all" + top="5" + left="5" + bottom="-1" + right="-5"/> + </layout_panel> + <layout_panel + name="buttons_panel" + height="26" + auto_resize="false" + layout="topleft"> + <layout_stack + name="buttons_stack" + top="0" + left="0" + right="-1" + bottom="-1" + follows="all" + orientation="horizontal" + layout="topleft" + animate="false"> + <layout_panel + follows="all" + layout="topleft" + name="resizer_left" + auto_resize="true" + width="1"> + </layout_panel> + <layout_panel + follows="all" + layout="topleft" + name="close_panel" + auto_resize="false" + width="112"> + <button + follows="top|left" + height="22" + label="Close" + layout="topleft" + left="1" + top="0" + width="110" + name="close_btn"/> + </layout_panel> + <layout_panel + follows="all" + layout="topleft" + name="resizer_right" + auto_resize="true" + width="1"> + </layout_panel> + </layout_stack> + </layout_panel> + </layout_stack> +</floater> diff --git a/indra/newview/skins/default/xui/en/floater_report_abuse.xml b/indra/newview/skins/default/xui/en/floater_report_abuse.xml index d07e3cb31b20a5f03571220e85c5418dfb8b4bc5..343e72f057fc0a65a3922fcdfaeadfc660e067e4 100644 --- a/indra/newview/skins/default/xui/en/floater_report_abuse.xml +++ b/indra/newview/skins/default/xui/en/floater_report_abuse.xml @@ -11,6 +11,11 @@ name="Screenshot"> Screenshot </floater.string> + <floater.string + name="chat_report_format"> +Time: [MSG_TIME] +Text: [MSG_DESCRIPTION] + </floater.string> <texture_picker allow_no_texture="true" default_image_name="None" @@ -19,7 +24,7 @@ layout="topleft" left="60" name="screenshot" - top="15" + top="20" width="220" /> <text type="string" diff --git a/indra/newview/skins/default/xui/en/floater_stats.xml b/indra/newview/skins/default/xui/en/floater_stats.xml index f9d44b2c6931d6d7592c3af5cda4cf620787b4c4..b9ca0108b6b3c4e4a262513142ce4e7632a77baa 100644 --- a/indra/newview/skins/default/xui/en/floater_stats.xml +++ b/indra/newview/skins/default/xui/en/floater_stats.xml @@ -35,6 +35,25 @@ decimal_digits="1" show_bar="true" show_history="true"/> + <stat_bar name="frame_mean" + label="frame (mean)" + unit_label="ms" + stat="frametime" + decimal_digits="1" + show_bar="false" + show_history="false"/> + <stat_bar name="frame_median" + label="frame (median)" + unit_label="ms" + stat="frametime" + show_median="true" + decimal_digits="1" + show_bar="false" + show_history="false"/> + <stat_bar name="framet_jitter" + label="jitter" + decimal_digits="1" + stat="frametimejitter"/> <stat_bar name="bandwidth" label="UDP Data Received" stat="activemessagedatareceived" diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml index 3e7a183628c57b7ef994f72383fa57e9677f2846..858c070cbea09a79cff01da421b24e03f883eb8c 100644 --- a/indra/newview/skins/default/xui/en/floater_tools.xml +++ b/indra/newview/skins/default/xui/en/floater_tools.xml @@ -2,7 +2,7 @@ <floater positioning="none" legacy_header_height="18" - height="620" + height="629" layout="topleft" bg_opaque_image="Window_NoTitle_Foreground" bg_alpha_image="Window_NoTitle_Background" @@ -68,7 +68,7 @@ </floater.string> <floater.string name="status_selectcount"> - [OBJ_COUNT] objects selected, land impact [LAND_IMPACT] + [OBJ_COUNT] objects selected, land impact [LAND_IMPACT] [secondlife:///app/openfloater/object_weights More info] </floater.string> <floater.string name="status_remaining_capacity"> @@ -822,6 +822,7 @@ Nothing selected. </text> <text + text_color="LtGray_50" type="string" length="1" height="16" @@ -833,8 +834,9 @@ top_delta="0" visible="false" width="280"> - </text> + </text> <text + text_color="LtGray_50" type="string" length="1" height="16" @@ -1480,16 +1482,40 @@ even though the user gets a free copy. tool_tip="Causes object to not collide with other objects or avatars" top_pad="0" width="123" /> - <text + <view_border + bevel_style="none" + follows="top|left" + height="0" + layout="topleft" + left_delta="0" + name="object_horizontal" + top_pad="10" + width="95" /> + <menu_button + menu_filename="menu_copy_paste_pos.xml" + follows="top|left" + height="11" + image_disabled="ClipboardSmallMenu_Disabled" + image_selected="ClipboardSmallMenu_Press" + image_unselected="ClipboardSmallMenu_Off" + layout="topleft" + left_delta="0" + top_pad="13" + name="clipboard_pos_btn" + tool_tip="Paste options" + width="19"/> + <text type="string" length="1" follows="left|top" height="10" layout="topleft" name="label position" - top_pad="10" + tool_tip="Position (meters)" + left_pad="8" + top_delta="0" width="121"> - Position (meters) + Position (m) </text> <spinner follows="left|top" @@ -1499,12 +1525,12 @@ even though the user gets a free copy. label="X" label_width="10" layout="topleft" - left_delta="0" + left_delta="-27" max_val="512" min_val="-256" name="Pos X" text_enabled_color="1 0 0.3 .7" - top_pad="5" + top_pad="8" width="87" /> <spinner follows="left|top" @@ -1531,21 +1557,36 @@ even though the user gets a free copy. layout="topleft" left_delta="0" max_val="4096" + min_val="-32" name="Pos Z" text_enabled_color="0 0.8 1 .65" top_pad="3" width="87" /> + <menu_button + menu_filename="menu_copy_paste_size.xml" + follows="top|left" + height="11" + image_disabled="ClipboardSmallMenu_Disabled" + image_selected="ClipboardSmallMenu_Press" + image_unselected="ClipboardSmallMenu_Off" + layout="topleft" + left_delta="0" + top_pad="13" + name="clipboard_size_btn" + tool_tip="Paste options" + width="19"/> <text type="string" length="1" follows="left|top" height="10" layout="topleft" - left_delta="0" + left_pad="8" + top_delta="0" name="label size" - top_pad="6" + tool_tip="Size (meters)" width="121"> - Size (meters) + Size (m) </text> <spinner follows="left|top" @@ -1555,12 +1596,12 @@ even though the user gets a free copy. label="X" label_width="10" layout="topleft" - left_delta="0" + left_delta="-27" max_val="64" min_val="0.01" name="Scale X" text_enabled_color="1 1 1 1" - top_pad="5" + top_pad="8" width="87" /> <spinner follows="left|top" @@ -1592,17 +1633,31 @@ even though the user gets a free copy. text_enabled_color="1 1 1 1" top_pad="3" width="87" /> + <menu_button + menu_filename="menu_copy_paste_rot.xml" + follows="top|left" + height="11" + image_disabled="ClipboardSmallMenu_Disabled" + image_selected="ClipboardSmallMenu_Press" + image_unselected="ClipboardSmallMenu_Off" + layout="topleft" + left_delta="0" + top_pad="13" + name="clipboard_rot_btn" + tool_tip="Paste options" + width="19"/> <text type="string" length="1" follows="left|top" height="10" layout="topleft" - left_delta="0" + left_pad="8" + top_delta="0" name="label rotation" - top_pad="10" + tool_tip="Rotation (degrees)" width="121"> - Rotation (degrees) + Rotation (°) </text> <spinner decimal_digits="2" @@ -1613,12 +1668,12 @@ even though the user gets a free copy. label="X" label_width="10" layout="topleft" - left_delta="0" + left_delta="-27" max_val="9999" min_val="-9999" name="Rot X" text_enabled_color="1 1 1 1" - top_pad="5" + top_pad="8" width="87" /> <spinner decimal_digits="2" @@ -1664,13 +1719,23 @@ even though the user gets a free copy. width="150"> Prim Type </text>--> + + <view_border + bevel_style="none" + follows="top|left" + layout="topleft" + name="object_vertical" + left="117" + top="6" + height="500" + width="0"/> <combo_box height="19" layout="topleft" name="comboBaseType" top="6" left="125" - width="150"> + width="125"> <combo_box.item label="Box" name="Box" @@ -1760,13 +1825,26 @@ even though the user gets a free copy. value="Path33Profile5" label="33->HalfCircle" /> </combo_box> + <menu_button + menu_filename="menu_copy_paste_object.xml" + follows="top|left" + height="15" + image_disabled="ClipboardMenu_Disabled" + image_selected="ClipboardMenu_Press" + image_unselected="ClipboardMenu_Off" + layout="topleft" + left_pad="8" + top_delta="2" + name="clipboard_obj_params_btn" + tool_tip="Paste options" + width="22"/> <text type="string" length="1" follows="left|top" height="10" layout="topleft" - left_delta="0" + left="125" name="text cut" top_pad="5" width="150"> @@ -1806,7 +1884,7 @@ even though the user gets a free copy. layout="topleft" left="125" name="text hollow" - top_pad="6" + top_pad="7" width="68"> Hollow </text> @@ -1854,7 +1932,7 @@ even though the user gets a free copy. layout="topleft" left="125" name="Hollow Shape" - top_pad="4" + top_pad="7" width="150"> Hollow Shape </text> @@ -1890,7 +1968,7 @@ even though the user gets a free copy. layout="topleft" left_delta="0" name="text twist" - top_pad="5" + top_pad="7" width="150"> Twist (begin/end) </text> @@ -1932,12 +2010,12 @@ even though the user gets a free copy. layout="topleft" left="125" name="scale_taper" - top_pad="3" + top_pad="7" width="150"> Taper </text> <text - visible="false" + visible="false" type="string" length="1" follows="left|top" @@ -1985,7 +2063,7 @@ even though the user gets a free copy. layout="topleft" left="125" name="text topshear" - top_pad="3" + top_pad="5" width="141"> Top Shear </text> @@ -2028,12 +2106,12 @@ even though the user gets a free copy. layout="topleft" left="125" name="advanced_cut" - top_pad="3" + top_pad="7" width="150"> Profile Cut (begin/end) </text> <text - visible="false" + visible="false" type="string" length="1" follows="left|top" @@ -2092,7 +2170,7 @@ even though the user gets a free copy. layout="topleft" left="125" name="text taper2" - top_pad="3" + top_pad="7" width="150"> Taper </text> @@ -2135,7 +2213,7 @@ even though the user gets a free copy. layout="topleft" left="125" name="text radius delta" - top_pad="2" + top_pad="7" width="78"> Radius </text> @@ -2263,6 +2341,19 @@ even though the user gets a free copy. <panel.string name="None">None</panel.string> <panel.string name="Prim">Prim</panel.string> <panel.string name="Convex Hull">Convex Hull</panel.string> + <menu_button + menu_filename="menu_copy_paste_features.xml" + follows="top|left" + height="15" + image_disabled="ClipboardMenu_Disabled" + image_selected="ClipboardMenu_Press" + image_unselected="ClipboardMenu_Off" + layout="topleft" + left="258" + top="8" + name="clipboard_features_params_btn" + tool_tip="Paste options" + width="22"/> <text type="string" length="1" @@ -2415,6 +2506,15 @@ even though the user gets a free copy. name="FlexForceZ" top_pad="4" width="128" /> + <view_border + bevel_style="none" + follows="top|left" + height="0" + layout="topleft" + left="8" + name="object_horizontal" + top_pad="10" + width="278" /> <check_box height="16" @@ -2423,7 +2523,7 @@ even though the user gets a free copy. left="10" name="Light Checkbox Ctrl" tool_tip="Causes object to emit light" - top_pad="15" + top_pad="8" width="60" /> <color_swatch can_apply_immediately="true" @@ -2450,6 +2550,19 @@ even though the user gets a free copy. name="light texture control" tool_tip="Click to choose a projection image (only has effect with deferred rendering enabled)" width="32" /> + <menu_button + menu_filename="menu_copy_paste_light.xml" + follows="top|left" + height="15" + image_disabled="ClipboardMenu_Disabled" + image_selected="ClipboardMenu_Press" + image_unselected="ClipboardMenu_Off" + layout="topleft" + left="258" + top_delta="0" + name="clipboard_light_params_btn" + tool_tip="Paste options" + width="22"/> <spinner follows="left|top" height="19" @@ -2462,7 +2575,7 @@ even though the user gets a free copy. max_val="1" min_val="0" name="Light Intensity" - top_pad="3" + top_pad="26" width="128" /> <spinner bottom_delta="0" decimal_digits="3" @@ -2684,7 +2797,7 @@ even though the user gets a free copy. border_visible="true" bevel_style="in" follows="left|top|right" - height="325" + height="335" layout="topleft" left="10" name="contents_inventory" diff --git a/indra/newview/skins/default/xui/en/floater_world_map.xml b/indra/newview/skins/default/xui/en/floater_world_map.xml index a78f0efeee8de889e34044275be07d9bcf6677ba..ee2159a7e15318b83e1a98474f2bb12f657f7885 100644 --- a/indra/newview/skins/default/xui/en/floater_world_map.xml +++ b/indra/newview/skins/default/xui/en/floater_world_map.xml @@ -735,6 +735,7 @@ name="zoom_icon" top_pad="7" width="16" ></icon> + <!-- NOTE: min_val for zoom slider is hardcoded for performance reasons --> <slider follows="right|left|bottom" height="16" @@ -742,7 +743,7 @@ initial_value="-2" left_pad="1" layout="topleft" - max_val="0" + max_val="4" min_val="-8" name="zoom slider" show_text="false" diff --git a/indra/newview/skins/default/xui/en/main_view.xml b/indra/newview/skins/default/xui/en/main_view.xml index 9885e37cea6d26fe3a09b69b7b77b9b4c5638c2d..842184de883cea353f714d0ebc0f86c4eee72980 100644 --- a/indra/newview/skins/default/xui/en/main_view.xml +++ b/indra/newview/skins/default/xui/en/main_view.xml @@ -8,6 +8,16 @@ tab_stop="false" name="main_view" width="1024"> + + <!-- At the moment layout_stack is not an LLUICtrl, + but Tab requires focus_root to function and focus_root + functionality is implemented in LLUICtrl --> + <panel follows="all" + height="768" + name="menu_tab_wrapper" + mouse_opaque="false" + focus_root="true" + top="0"> <layout_stack border_size="0" follows="all" mouse_opaque="false" @@ -18,12 +28,12 @@ <layout_panel mouse_opaque="true" follows="left|right|top" name="status_bar_container" - tab_stop="false" height="19" left="0" top="0" width="1024" auto_resize="false" + default_tab_group="1" visible="true"> <view mouse_opaque="false" follows="all" @@ -31,13 +41,13 @@ left="0" top="0" width="1024" + tab_group="1" height="19"/> </layout_panel> <layout_panel auto_resize="false" height="34" mouse_opaque="false" name="nav_bar_container" - tab_stop="false" width="1024" visible="false"/> <layout_panel auto_resize="true" @@ -99,6 +109,7 @@ tab_stop="false"/> </layout_panel> </layout_stack> + </panel> <!--menu_tab_wrapper--> <panel top="0" follows="all" diff --git a/indra/newview/skins/default/xui/en/menu_attachment_self.xml b/indra/newview/skins/default/xui/en/menu_attachment_self.xml index 9fd37581ed7a75ffcb8be300998c3ae6e1ccfb31..ec2d39ced0532b0282575336ac0e21f6b556815a 100644 --- a/indra/newview/skins/default/xui/en/menu_attachment_self.xml +++ b/indra/newview/skins/default/xui/en/menu_attachment_self.xml @@ -33,6 +33,13 @@ function="Object.EnableTouch" name="EnableTouch"/> </menu_item_call> + <menu_item_call + label="Show in inventory" + layout="topleft" + name="Show original"> + <menu_item_call.on_click + function="Object.ShowOriginal" /> + </menu_item_call> <menu_item_separator layout="topleft" /> <menu_item_call diff --git a/indra/newview/skins/default/xui/en/menu_avatar_icon.xml b/indra/newview/skins/default/xui/en/menu_avatar_icon.xml index 55ec42bbf7c098be286732816c7ff608fc4eef03..2cef9c1de8b86bbdece669187c5d317689fa26db 100644 --- a/indra/newview/skins/default/xui/en/menu_avatar_icon.xml +++ b/indra/newview/skins/default/xui/en/menu_avatar_icon.xml @@ -97,6 +97,13 @@ <on_click function="AvatarIcon.Action" parameter="pay" /> <on_enable function="AvatarIcon.Enable" parameter="can_pay" /> </menu_item_call> + <menu_item_call + label="Report Abuse" + layout="topleft" + name="Report Abuse"> + <on_click function="AvatarIcon.Action" parameter="report_abuse" /> + <on_enable function="AvatarIcon.Enable" parameter="report_abuse" /> + </menu_item_call> <menu_item_check label="Block Voice" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/menu_avatar_self.xml b/indra/newview/skins/default/xui/en/menu_avatar_self.xml index d5421874c8eacf450447d77ea0101234cc147b35..408edb43d33d4d074ed874fd2aa44228a81b4a70 100644 --- a/indra/newview/skins/default/xui/en/menu_avatar_self.xml +++ b/indra/newview/skins/default/xui/en/menu_avatar_self.xml @@ -321,4 +321,11 @@ <menu_item_call.on_visible function="EnableMuteParticle" /> </menu_item_call> + <menu_item_separator/> + <menu_item_call label="View Profile" + layout="topleft" + name="show_avatar_profile"> + <menu_item_call.on_click + function="Avatar.ToggleMyProfile" /> + </menu_item_call> </context_menu> diff --git a/indra/newview/skins/default/xui/en/menu_conversation.xml b/indra/newview/skins/default/xui/en/menu_conversation.xml index 3d10e3fab9548a262358d93ac6124008e8d4d1db..cadc32c24a986348d89b72a2dfe5d85f37719d27 100644 --- a/indra/newview/skins/default/xui/en/menu_conversation.xml +++ b/indra/newview/skins/default/xui/en/menu_conversation.xml @@ -132,6 +132,13 @@ <on_click function="Avatar.DoToSelected" parameter="pay" /> <on_enable function="Avatar.EnableItem" parameter="can_pay" /> </menu_item_call> + <menu_item_call + label="Report Abuse" + layout="topleft" + name="report_abuse"> + <on_click function="Avatar.DoToSelected" parameter="report_abuse" /> + <on_enable function="Avatar.EnableItem" parameter="report_abuse" /> + </menu_item_call> <menu_item_check label="Block Voice" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/menu_copy_paste_color.xml b/indra/newview/skins/default/xui/en/menu_copy_paste_color.xml new file mode 100644 index 0000000000000000000000000000000000000000..4c12180daf32f53bc78324a03f636e3f449118fb --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_copy_paste_color.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<toggleable_menu + layout="topleft" + name="Copy Paste Color Menu"> + <menu_item_call + label="Copy" + layout="topleft" + name="params_copy" + visible="true"> + <on_click function="PanelFace.menuDoToSelected" parameter="color_copy" /> + </menu_item_call> + <menu_item_call + label="Paste" + layout="topleft" + name="params_paste" + visible="true"> + <on_click function="PanelFace.menuDoToSelected" parameter="color_paste" /> + <on_enable function="PanelFace.menuEnable" parameter="color_paste" /> + </menu_item_call> +</toggleable_menu> + diff --git a/indra/newview/skins/default/xui/en/menu_copy_paste_features.xml b/indra/newview/skins/default/xui/en/menu_copy_paste_features.xml new file mode 100644 index 0000000000000000000000000000000000000000..4823d74a261c2ecb57d359a05b4af5708610cf53 --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_copy_paste_features.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<toggleable_menu + layout="topleft" + name="Copy Paste Features Menu"> + <menu_item_call + label="Copy" + layout="topleft" + name="params_copy" + visible="true"> + <on_click function="PanelVolume.menuDoToSelected" parameter="features_copy" /> + </menu_item_call> + <menu_item_call + label="Paste" + layout="topleft" + name="params_paste" + visible="true"> + <on_click function="PanelVolume.menuDoToSelected" parameter="features_paste" /> + <on_enable function="PanelVolume.menuEnable" parameter="features_paste" /> + </menu_item_call> +</toggleable_menu> + diff --git a/indra/newview/skins/default/xui/en/menu_copy_paste_light.xml b/indra/newview/skins/default/xui/en/menu_copy_paste_light.xml new file mode 100644 index 0000000000000000000000000000000000000000..5de23dfee3f9bdd0a4d57d7ea8a4ca9aa7585c22 --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_copy_paste_light.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<toggleable_menu + layout="topleft" + name="Copy Paste Light Menu"> + <menu_item_call + label="Copy" + layout="topleft" + name="params_copy" + visible="true"> + <on_click function="PanelVolume.menuDoToSelected" parameter="light_copy" /> + </menu_item_call> + <menu_item_call + label="Paste" + layout="topleft" + name="params_paste" + visible="true"> + <on_click function="PanelVolume.menuDoToSelected" parameter="light_paste" /> + <on_enable function="PanelVolume.menuEnable" parameter="light_paste" /> + </menu_item_call> +</toggleable_menu> + diff --git a/indra/newview/skins/default/xui/en/menu_copy_paste_object.xml b/indra/newview/skins/default/xui/en/menu_copy_paste_object.xml new file mode 100644 index 0000000000000000000000000000000000000000..bdc4537a9dc0d39c0ace17aec056fe448c589ee0 --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_copy_paste_object.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<toggleable_menu + layout="topleft" + name="Copy Paste Object Menu"> + <menu_item_call + label="Copy" + layout="topleft" + name="params_copy" + visible="true"> + <on_click function="PanelObject.menuDoToSelected" parameter="params_copy" /> + </menu_item_call> + <menu_item_call + label="Paste" + layout="topleft" + name="params_paste" + visible="true"> + <on_click function="PanelObject.menuDoToSelected" parameter="params_paste" /> + <on_enable function="PanelObject.menuEnable" parameter="params_paste" /> + </menu_item_call> +</toggleable_menu> + diff --git a/indra/newview/skins/default/xui/en/menu_copy_paste_pos.xml b/indra/newview/skins/default/xui/en/menu_copy_paste_pos.xml new file mode 100644 index 0000000000000000000000000000000000000000..3ea95b281f08d6e64d558cb1301d3b6b205a819d --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_copy_paste_pos.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<toggleable_menu + layout="topleft" + name="Copy Paste Position Menu"> + <menu_item_call + label="Copy all" + layout="topleft" + name="psr_copy" + visible="true"> + <on_click function="PanelObject.menuDoToSelected" parameter="psr_copy" /> + <on_enable function="PanelObject.menuEnable" parameter="psr_copy" /> + </menu_item_call> + <menu_item_call + label="Copy position" + layout="topleft" + name="pos_copy" + visible="true"> + <on_click function="PanelObject.menuDoToSelected" parameter="pos_copy" /> + </menu_item_call> + <menu_item_call + label="Paste all" + layout="topleft" + name="psr_paste" + visible="true"> + <on_click function="PanelObject.menuDoToSelected" parameter="psr_paste" /> + <on_enable function="PanelObject.menuEnable" parameter="psr_paste" /> + </menu_item_call> + <menu_item_call + label="Paste position" + layout="topleft" + name="pos_paste" + visible="true"> + <on_click function="PanelObject.menuDoToSelected" parameter="pos_paste" /> + <on_enable function="PanelObject.menuEnable" parameter="pos_paste" /> + </menu_item_call> +</toggleable_menu> + diff --git a/indra/newview/skins/default/xui/en/menu_copy_paste_rot.xml b/indra/newview/skins/default/xui/en/menu_copy_paste_rot.xml new file mode 100644 index 0000000000000000000000000000000000000000..06ce80f8977c32488cd7b58d5f3a9cdfe09562e5 --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_copy_paste_rot.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<toggleable_menu + layout="topleft" + name="Copy Paste Rotation Menu"> + <menu_item_call + label="Copy all" + layout="topleft" + name="psr_copy" + visible="true"> + <on_click function="PanelObject.menuDoToSelected" parameter="psr_copy" /> + <on_enable function="PanelObject.menuEnable" parameter="rot_paste" /> + </menu_item_call> + <menu_item_call + label="Copy rotation" + layout="topleft" + name="rot_copy" + visible="true"> + <on_click function="PanelObject.menuDoToSelected" parameter="rot_copy" /> + </menu_item_call> + <menu_item_call + label="Paste all" + layout="topleft" + name="psr_paste" + visible="true"> + <on_click function="PanelObject.menuDoToSelected" parameter="psr_paste" /> + <on_enable function="PanelObject.menuEnable" parameter="psr_paste" /> + </menu_item_call> + <menu_item_call + label="Paste rotation" + layout="topleft" + name="rot_paste" + visible="true"> + <on_click function="PanelObject.menuDoToSelected" parameter="rot_paste" /> + <on_enable function="PanelObject.menuEnable" parameter="rot_paste" /> + </menu_item_call> +</toggleable_menu> + diff --git a/indra/newview/skins/default/xui/en/menu_copy_paste_size.xml b/indra/newview/skins/default/xui/en/menu_copy_paste_size.xml new file mode 100644 index 0000000000000000000000000000000000000000..7082a0e65b37c10df8cf24a7bf3c9f392dcb24b9 --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_copy_paste_size.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<toggleable_menu + layout="topleft" + name="Copy Paste Size Menu"> + <menu_item_call + label="Copy all" + layout="topleft" + name="psr_copy" + visible="true"> + <on_click function="PanelObject.menuDoToSelected" parameter="psr_copy" /> + <on_enable function="PanelObject.menuEnable" parameter="psr_copy" /> + </menu_item_call> + <menu_item_call + label="Copy size" + layout="topleft" + name="size_copy" + visible="true"> + <on_click function="PanelObject.menuDoToSelected" parameter="size_copy" /> + </menu_item_call> + <menu_item_call + label="Paste all" + layout="topleft" + name="psr_paste" + visible="true"> + <on_click function="PanelObject.menuDoToSelected" parameter="psr_paste" /> + <on_enable function="PanelObject.menuEnable" parameter="psr_paste" /> + </menu_item_call> + <menu_item_call + label="Paste size" + layout="topleft" + name="size_paste" + visible="true"> + <on_click function="PanelObject.menuDoToSelected" parameter="size_paste" /> + <on_enable function="PanelObject.menuEnable" parameter="size_paste" /> + </menu_item_call> +</toggleable_menu> + diff --git a/indra/newview/skins/default/xui/en/menu_copy_paste_texture.xml b/indra/newview/skins/default/xui/en/menu_copy_paste_texture.xml new file mode 100644 index 0000000000000000000000000000000000000000..f358affc23d2e32d512e8646abaa3ade304e66eb --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_copy_paste_texture.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<toggleable_menu + layout="topleft" + name="Copy Paste Texture Menu"> + <menu_item_call + label="Copy" + layout="topleft" + name="params_copy" + visible="true"> + <on_click function="PanelFace.menuDoToSelected" parameter="texture_copy" /> + </menu_item_call> + <menu_item_call + label="Paste" + layout="topleft" + name="params_paste" + visible="true"> + <on_click function="PanelFace.menuDoToSelected" parameter="texture_paste" /> + <on_enable function="PanelFace.menuEnable" parameter="texture_paste" /> + </menu_item_call> +</toggleable_menu> + diff --git a/indra/newview/skins/default/xui/en/menu_gesture_gear.xml b/indra/newview/skins/default/xui/en/menu_gesture_gear.xml index 5cae643e44f5dc9475c354705d7cc08a7c47d0f5..359c093eff9fd9584318b2518b8033f2af9de82d 100644 --- a/indra/newview/skins/default/xui/en/menu_gesture_gear.xml +++ b/indra/newview/skins/default/xui/en/menu_gesture_gear.xml @@ -9,7 +9,7 @@ layout="topleft" name="activate"> <on_click - function="Gesture.Action.ToogleActiveState" /> + function="Gesture.Action.ToggleActiveState" /> </menu_item_call> <menu_item_call label="Rename" diff --git a/indra/newview/skins/default/xui/en/menu_im_conversation.xml b/indra/newview/skins/default/xui/en/menu_im_conversation.xml index b793dcce83fceda795fcb82cd51b1a1736d9d86e..9f8002ab3c2998d1732c45b6ad4b19cf2050389d 100644 --- a/indra/newview/skins/default/xui/en/menu_im_conversation.xml +++ b/indra/newview/skins/default/xui/en/menu_im_conversation.xml @@ -79,6 +79,13 @@ </menu_item_call> <menu_item_separator layout="topleft"/> + <menu_item_call + label="Report Abuse" + layout="topleft" + name="Report Abuse"> + <on_click function="Avatar.GearDoToSelected" parameter="report_abuse" /> + <on_enable function="Avatar.EnableGearItem" parameter="report_abuse" /> + </menu_item_call> <menu_item_check label="Block Voice" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml index e419455729720252f24935b0a0e74f9ebe851334..59d4829cb9957b50cdea0bb4ee6fbe9561afb659 100644 --- a/indra/newview/skins/default/xui/en/menu_inventory.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory.xml @@ -912,6 +912,25 @@ function="Inventory.DoToSelected" parameter="apply_settings_parcel" /> </menu_item_call> + <menu_item_separator + layout="topleft" + name="Subfolder Separator" /> + <menu_item_call + label="Create folder from selected" + layout="topleft" + name="New folder from selected"> + <menu_item_call.on_click + function="Inventory.DoToSelected" + parameter="new_folder_from_selected" /> + </menu_item_call> + <menu_item_call + label="Ungroup folder items" + layout="topleft" + name="Ungroup folder items"> + <menu_item_call.on_click + function="Inventory.DoToSelected" + parameter="ungroup_folder_items" /> + </menu_item_call> <menu_item_separator layout="topleft" name="Marketplace Separator" /> diff --git a/indra/newview/skins/default/xui/en/menu_mini_map.xml b/indra/newview/skins/default/xui/en/menu_mini_map.xml index ac3c4db40a0b6dc4117e4953e87ef7108b98a1a7..8caff8f775f290158b7e5ca9358846388b40e15d 100644 --- a/indra/newview/skins/default/xui/en/menu_mini_map.xml +++ b/indra/newview/skins/default/xui/en/menu_mini_map.xml @@ -8,52 +8,76 @@ top="724" visible="false" width="128"> - <menu_item_call - label="Zoom Close" - name="Zoom Close"> - <menu_item_call.on_click - function="Minimap.Zoom" + <menu_item_check + label="Zoom very close" + name="Zoom very close"> + <menu_item_check.on_check + function="Minimap.Zoom.Check" + parameter="very close" /> + <menu_item_check.on_click + function="Minimap.Zoom.Set" + parameter="very close" /> + </menu_item_check> + <menu_item_check + label="Zoom close" + name="Zoom close"> + <menu_item_check.on_check + function="Minimap.Zoom.Check" parameter="close" /> - </menu_item_call> - <menu_item_call - label="Zoom Medium" - name="Zoom Medium"> - <menu_item_call.on_click - function="Minimap.Zoom" + <menu_item_check.on_click + function="Minimap.Zoom.Set" + parameter="close" /> + </menu_item_check> + <menu_item_check + label="Zoom medium" + name="Zoom medium"> + <menu_item_check.on_check + function="Minimap.Zoom.Check" parameter="medium" /> - </menu_item_call> - <menu_item_call - label="Zoom Far" - name="Zoom Far"> - <menu_item_call.on_click - function="Minimap.Zoom" + <menu_item_check.on_click + function="Minimap.Zoom.Set" + parameter="medium" /> + </menu_item_check> + <menu_item_check + label="Zoom far" + name="Zoom far"> + <menu_item_check.on_check + function="Minimap.Zoom.Check" parameter="far" /> - </menu_item_call> - <menu_item_call - label="Zoom Default" - name="Zoom Default"> - <menu_item_call.on_click - function="Minimap.Zoom" - parameter="default" /> - </menu_item_call> + <menu_item_check.on_click + function="Minimap.Zoom.Set" + parameter="far" /> + </menu_item_check> <menu_item_separator /> <menu_item_check - label="Rotate Map" - name="Rotate Map"> + label="North at top" + name="North at top"> <menu_item_check.on_check - control="MiniMapRotate" /> + function="Minimap.MapOrientation.Check" + parameter="north_at_top" /> <menu_item_check.on_click - function="ToggleControl" - parameter="MiniMapRotate" /> + function="Minimap.MapOrientation.Set" + parameter="north_at_top" /> </menu_item_check> <menu_item_check - label="Auto Center" - name="Auto Center"> + label="Camera at top" + name="Camera at top"> <menu_item_check.on_check - control="MiniMapAutoCenter" /> + function="Minimap.MapOrientation.Check" + parameter="camera_at_top" /> <menu_item_check.on_click - function="ToggleControl" - parameter="MiniMapAutoCenter" /> + function="Minimap.MapOrientation.Set" + parameter="camera_at_top" /> + </menu_item_check> + <menu_item_separator /> + <menu_item_check + label="Auto-center map" + name="Auto-center map"> + <menu_item_check.on_check + control="MiniMapAutoCenter" /> + <menu_item_check.on_click + function="ToggleControl" + parameter="MiniMapAutoCenter" /> </menu_item_check> <menu_item_separator /> <menu_item_check @@ -97,13 +121,13 @@ label="Parcel Boundries" name="Parcel Boundries"> <menu_item_check.on_check - control="AlchemyMinimapParcelBoundries" /> + control="MiniMapShowPropertyLines" /> <menu_item_check.on_click function="ToggleControl" - parameter="AlchemyMinimapParcelBoundries" /> + parameter="MiniMapShowPropertyLines" /> </menu_item_check> <menu_item_check - enabled_control="AlchemyMinimapParcelBoundries" + enabled_control="MiniMapShowPropertyLines" label="Parcels For Sale" name="Parcels For Sale"> <menu_item_check.on_check @@ -113,7 +137,7 @@ parameter="AlchemyMiniMapForSaleParcels" /> </menu_item_check> <menu_item_check - enabled_control="AlchemyMinimapParcelBoundries" + enabled_control="MiniMapShowPropertyLines" label="Parcel Access" name="Parcel Access"> <menu_item_check.on_check @@ -125,13 +149,25 @@ <menu_item_separator /> <menu_item_call - label="Stop Tracking" - name="Stop Tracking"> + label="Re-center map" + name="Re-center map"> + <menu_item_call.on_click + function="Minimap.Center.Activate" /> + </menu_item_call> + <menu_item_call + label="Stop tracking" + name="Stop tracking"> <menu_item_call.on_click function="Minimap.Tracker" parameter="task_properties" /> </menu_item_call> <menu_item_separator /> + <menu_item_call + label="About Land" + name="About Land"> + <menu_item_call.on_click + function="Minimap.AboutLand" /> + </menu_item_call> <menu_item_call label="World Map" name="World Map"> diff --git a/indra/newview/skins/default/xui/en/menu_name_field.xml b/indra/newview/skins/default/xui/en/menu_name_field.xml deleted file mode 100644 index 62fbabefddc975cb46945c48f72225eaeba1747f..0000000000000000000000000000000000000000 --- a/indra/newview/skins/default/xui/en/menu_name_field.xml +++ /dev/null @@ -1,39 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<toggleable_menu - name="CopyMenu"> - <menu_item_call - label="Copy Username" - name="copy_username"> - <menu_item_call.on_click - function="Profile.CopyName" - parameter="user_name"/> - </menu_item_call> - <menu_item_call - label="Copy Display Name" - name="copy_display_name"> - <menu_item_call.on_click - function="Profile.CopyName" - parameter="display_name"/> - </menu_item_call> - <menu_item_call - label="Copy Account Name" - name="account_name"> - <menu_item_call.on_click - function="Profile.CopyName" - parameter="account_name"/> - </menu_item_call> - <menu_item_call - label="Copy SLurl" - name="copy_slurl"> - <menu_item_call.on_click - function="Profile.CopyName" - parameter="slurl"/> - </menu_item_call> - <menu_item_call - label="Copy ID" - name="copy_uuid"> - <menu_item_call.on_click - function="Profile.CopyName" - parameter="id"/> - </menu_item_call> -</toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_profile_other.xml b/indra/newview/skins/default/xui/en/menu_profile_other.xml new file mode 100644 index 0000000000000000000000000000000000000000..4db4d0922bff01021eaa54012c72ebbafc3b0f1a --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_profile_other.xml @@ -0,0 +1,171 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<toggleable_menu + layout="topleft" + name="Avatar Profile Menu"> + <menu_item_call + label="IM" + layout="topleft" + name="im"> + <menu_item_call.on_click + function="Profile.Commit" + parameter="im"/> + </menu_item_call> + <menu_item_call + label="Offer Teleport" + name="offer_teleport"> + <menu_item_call.on_click + function="Profile.Commit" + parameter="offer_teleport"/> + <menu_item_call.on_enable + function="Profile.EnableItem" + parameter="offer_teleport"/> + </menu_item_call> + <menu_item_call + label="Request Teleport" + name="request_teleport"> + <menu_item_call.on_click + function="Profile.Commit" + parameter="request_teleport"/> + <menu_item_call.on_enable + function="Profile.EnableItem" + parameter="request_teleport"/> + </menu_item_call> + <menu_item_call + label="Voice call" + layout="topleft" + name="voice_call"> + <menu_item_call.on_click + function="Profile.Commit" + parameter="voice_call"/> + <menu_item_call.on_enable + function="Profile.EnableItem" + parameter="voice_call"/> + </menu_item_call> + <menu_item_separator /> + <menu_item_call + label="View chat history..." + layout="topleft" + name="chat_history"> + <menu_item_call.on_click + function="Profile.Commit" + parameter="chat_history"/> + <menu_item_call.on_enable + function="Profile.EnableItem" + parameter="chat_history"/> + </menu_item_call> + <menu_item_separator name="separator_chat_history"/> + <menu_item_call + label="Add Friend" + layout="topleft" + name="add_friend"> + <menu_item_call.on_click + function="Profile.Commit" + parameter="add_friend"/> + <menu_item_call.on_visible + function="Profile.EnableItem" + parameter="add_friend"/> + </menu_item_call> + <menu_item_call + label="Remove Friend" + layout="topleft" + name="remove_friend"> + <menu_item_call.on_click + function="Profile.Commit" + parameter="remove_friend"/> + <menu_item_call.on_enable + function="Profile.EnableItem" + parameter="remove_friend"/> + </menu_item_call> + <menu_item_call + label="Invite to group..." + layout="topleft" + name="invite_to_group"> + <menu_item_call.on_click + function="Profile.Commit" + parameter="invite_to_group"/> + </menu_item_call> + <menu_item_separator name="separator_invite_to_group"/> + <menu_item_call + label="Permissions" + layout="topleft" + name="agent_permissions"> + <menu_item_call.on_click + function="Profile.Commit" + parameter="agent_permissions"/> + <menu_item_call.on_visible + function="Profile.EnableItem" + parameter="agent_permissions"/> + </menu_item_call> + <menu_item_call + label="Map" + layout="topleft" + name="map"> + <menu_item_call.on_click + function="Profile.Commit" + parameter="can_show_on_map"/> + <menu_item_call.on_enable + function="Profile.EnableItem" + parameter="can_show_on_map"/> + </menu_item_call> + <menu_item_call + label="Share" + layout="topleft" + name="share"> + <menu_item_call.on_click + function="Profile.Commit" + parameter="share"/> + </menu_item_call> + <menu_item_call + label="Pay" + layout="topleft" + name="pay"> + <menu_item_call.on_click + function="Profile.Commit" + parameter="pay"/> + </menu_item_call> + <menu_item_check + label="Block/Unblock" + layout="topleft" + name="block_unblock"> + <menu_item_check.on_click + function="Profile.Commit" + parameter="toggle_block_agent"/> + <menu_item_check.on_check + function="Profile.CheckItem" + parameter="toggle_block_agent"/> + <menu_item_check.on_enable + function="Profile.EnableItem" + parameter="toggle_block_agent"/> + </menu_item_check> + <menu_item_separator name="separator_copy_options"/> + <menu_item_call + label="Copy Display Name" + layout="topleft" + name="copy_display_name"> + <menu_item_call.on_click + function="Profile.Commit" + parameter="copy_display_name"/> + <menu_item_call.on_enable + function="Profile.EnableItem" + parameter="copy_display_name"/> + </menu_item_call> + <menu_item_call + label="Copy Agent Name" + layout="topleft" + name="copy_name"> + <menu_item_call.on_click + function="Profile.Commit" + parameter="copy_username"/> + <menu_item_call.on_enable + function="Profile.EnableItem" + parameter="copy_username"/> + </menu_item_call> + <menu_item_call + label="Copy Agent Id" + layout="topleft" + name="copy_id"> + <menu_item_call.on_click + function="Profile.Commit" + parameter="copy_user_id"/> + </menu_item_call> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_profile_self.xml b/indra/newview/skins/default/xui/en/menu_profile_self.xml new file mode 100644 index 0000000000000000000000000000000000000000..d0bd4000f853d56eb0d5c266fab2d8155958416a --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_profile_self.xml @@ -0,0 +1,85 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<toggleable_menu + layout="topleft" + name="Avatar Profile Menu Self"> + <menu_item_call + label="Edit Display Name" + layout="topleft" + name="edit_display_name"> + <on_click + function="Profile.Commit" + parameter="edit_display_name"/> + </menu_item_call> + <menu_item_call + label="Edit Partner" + layout="topleft" + name="edit_partner"> + <on_click + function="Profile.Commit" + parameter="edit_partner"/> + </menu_item_call> + <menu_item_call + label="Upload Photo" + layout="topleft" + name="upload_photo"> + <menu_item_call.on_click + function="Profile.Commit" + parameter="upload_photo"/> + <menu_item_call.on_enable + function="Profile.EnableItem" + parameter="upload_photo"/> + </menu_item_call> + <menu_item_call + label="Change Photo" + layout="topleft" + name="change_photo"> + <menu_item_call.on_click + function="Profile.Commit" + parameter="change_photo"/> + <menu_item_call.on_enable + function="Profile.EnableItem" + parameter="change_photo"/> + </menu_item_call> + <menu_item_call + label="Remove Photo" + layout="topleft" + name="remove_photo"> + <menu_item_call.on_click + function="Profile.Commit" + parameter="remove_photo"/> + <menu_item_call.on_enable + function="Profile.EnableItem" + parameter="remove_photo"/> + </menu_item_call> + <menu_item_separator name="separator_copy_options"/> + <menu_item_call + label="Copy Display Name" + layout="topleft" + name="copy_display_name"> + <menu_item_call.on_click + function="Profile.Commit" + parameter="copy_display_name"/> + <menu_item_call.on_enable + function="Profile.EnableItem" + parameter="copy_display_name"/> + </menu_item_call> + <menu_item_call + label="Copy Agent Name" + layout="topleft" + name="copy_name"> + <menu_item_call.on_click + function="Profile.Commit" + parameter="copy_username"/> + <menu_item_call.on_enable + function="Profile.EnableItem" + parameter="copy_username"/> + </menu_item_call> + <menu_item_call + label="Copy Agent Id" + layout="topleft" + name="copy_id"> + <menu_item_call.on_click + function="Profile.Commit" + parameter="copy_user_id"/> + </menu_item_call> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_url_agent.xml b/indra/newview/skins/default/xui/en/menu_url_agent.xml index e8b6116026a90669a877477e5486ef19503f0963..5ca8be212306c345e2bb55a712db966810e0eca3 100644 --- a/indra/newview/skins/default/xui/en/menu_url_agent.xml +++ b/indra/newview/skins/default/xui/en/menu_url_agent.xml @@ -29,7 +29,14 @@ name="remove_friend"> <menu_item_call.on_click function="Url.RemoveFriend" /> - </menu_item_call> + </menu_item_call> + <menu_item_call + label="Report Abuse" + layout="topleft" + name="report_abuse"> + <menu_item_call.on_click + function="Url.ReportAbuse" /> + </menu_item_call> <menu_item_separator layout="topleft" /> <menu_item_call diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 21244cc9166547bafac35d4f7f233d9834f9e63b..d8ea6f6c40ad83e7040422655cac01483b55ec4c 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -445,7 +445,7 @@ <menu_item_call label="Stop animations" name="Stop Animating My Avatar" - allow_key_repeat="true" + allow_key_repeat="true" shortcut="alt|shift|A"> <menu_item_call.on_click function="Tools.StopAllAnimations" /> @@ -482,6 +482,20 @@ parameter="gestures" /> </menu_item_check> <menu_item_separator/> + <menu_item_call + label="Reset skeleton" + layout="topleft" + name="Reset Skeleton"> + <menu_item_call.on_click + function="Avatar.ResetSkeleton" /> + </menu_item_call> + <menu_item_call + label="Reset skeleton and animations" + layout="topleft" + name="Reset Skeleton And Animations"> + <menu_item_call.on_click + function="Avatar.ResetSelfSkeletonAndAnimations" /> + </menu_item_call> <menu_item_call label="Undeform Me" name="Undeform Me"> @@ -3026,6 +3040,12 @@ function="World.EnvPreset" <menu_item_call.on_click function="Advanced.ForceErrorBadMemoryAccess" /> </menu_item_call> + <menu_item_call + label="Force Bad Memory Access in Coroutine" + name="Force Bad Memory Access in Coroutine"> + <menu_item_call.on_click + function="Advanced.ForceErrorBadMemoryAccessCoro" /> + </menu_item_call> <menu_item_call label="Force Infinite Loop" name="Force Infinite Loop"> @@ -3501,14 +3521,14 @@ function="World.EnvPreset" <menu_item_separator /> <menu_item_check - label="Debug GL" + label="Start Debug GL on next run" name="Debug GL"> <menu_item_check.on_check function="CheckControl" - parameter="RenderDebugGL" /> + parameter="RenderDebugGLSession" /> <menu_item_check.on_click function="ToggleControl" - parameter="RenderDebugGL" /> + parameter="RenderDebugGLSession" /> </menu_item_check> <menu_item_check label="Debug Pipeline" @@ -3740,6 +3760,18 @@ function="World.EnvPreset" function="Advanced.DropPacket" /> </menu_item_call> </menu> + <menu + create_jump_keys="true" + label="Cache" + name="Cache" + tear_off="true"> + <menu_item_call + label="Purge Disk Cache" + name="Purge Disk Cache"> + <menu_item_call.on_click + function="Advanced.PurgeDiskCache" /> + </menu_item_call> + </menu> <menu_item_call label="Dump Scripted Camera" name="Dump Scripted Camera"> diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 02dc891b16fd7885b74e38d7601126beeea9edcf..12f5dddceefd97d9758c559514ee94e649e4aa58 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -1515,7 +1515,19 @@ Insufficient funds to create classified. <notification icon="alertmodal.tga" - name="DeleteAvatarPick" + name="ProfileDeleteClassified" + type="alertmodal"> +Delete classified <nolink>[CLASSIFIED]</nolink>? + <tag>confirm</tag> + <usetemplate + name="okcancelbuttons" + notext="Cancel" + yestext="OK"/> + </notification> + + <notification + icon="alertmodal.tga" + name="ProfileDeletePick" type="alertmodal"> Delete pick <nolink>[PICK]</nolink>? <tag>confirm</tag> @@ -1525,6 +1537,32 @@ Delete pick <nolink>[PICK]</nolink>? yestext="OK"/> </notification> + <notification + icon="alert.tga" + name="ProfileUnpublishedClassified" + type="alertmodal"> + You have unpublished classifieds. They will be lost if you close the window. + <tag>confirm</tag> + <usetemplate + name="okcancelbuttons" + notext="Cancel" + yestext="OK"/> + </notification> + + <notification + icon="alert.tga" + name="ProfileUnsavedChanges" + type="alertmodal"> + You have usaved changes. + <tag>confirm</tag> + <tag>save</tag> + <usetemplate + canceltext="Cancel" + name="yesnocancelbuttons" + notext="Discard" + yestext="Save"/> + </notification> + <notification icon="alertmodal.tga" name="DeleteOutfits" @@ -4055,7 +4093,7 @@ Are you sure you want to return objects owned by [USER_NAME]? Couldn't set region textures: Terrain texture [TEXTURE_NUM] has an invalid bit depth of [TEXTURE_BIT_DEPTH]. -Replace texture [TEXTURE_NUM] with a 24-bit 512x512 or smaller image then click "Apply" again. +Replace texture [TEXTURE_NUM] with a 24-bit [MAX_SIZE]x[MAX_SIZE] or smaller image then click "Apply" again. <tag>fail</tag> </notification> @@ -4066,7 +4104,7 @@ Replace texture [TEXTURE_NUM] with a 24-bit 512x512 or smaller image then click Couldn't set region textures: Terrain texture [TEXTURE_NUM] is too large at [TEXTURE_SIZE_X]x[TEXTURE_SIZE_Y]. -Replace texture [TEXTURE_NUM] with a 24-bit 512x512 or smaller image then click "Apply" again. +Replace texture [TEXTURE_NUM] with a 24-bit [MAX_SIZE]x[MAX_SIZE] or smaller image then click "Apply" again. </notification> <notification @@ -8956,13 +8994,6 @@ See SecondLife.log for details type="alert"> Error while requesting mesh upload permissons. </notification> - - <notification - name="MeshUploadProfilerError" - icon="alert.tga" - type="alert"> -Mesh uploader is incompatible with RenderGLCoreProfile, please turn RenderGLCoreProfile off in debug settings and restart the viewer. - </notification> <notification name="RegionCapabilityRequestError" @@ -9221,6 +9252,29 @@ We cannot display a preview of this texture because it is no-copy and/or no-tran yestext="OK"/> </notification> + <notification + icon="alertmodal.tga" + name="FacePasteFailed" + type="alertmodal"> +Paste failed. [REASON] + <usetemplate + name="okbutton" + yestext="OK"/> + </notification> + + <notification + icon="alertmodal.tga" + name="FacePasteTexturePermissions" + type="alertmodal"> + You applied a texture with limited permissions, object will inherit permissions from texture. + <usetemplate + ignoretext="Paste: You applied a texture with limited permissions" + name="notifyignore"/> + <usetemplate + name="okbutton" + yestext="OK"/> + </notification> + <notification icon="alertmodal.tga" name="ConfirmLeaveCall" @@ -9817,18 +9871,6 @@ Do you wish to continue? yestext="OK"/> </notification> - <global name="UnsupportedShaderRequirements"> -You do not appear to meet the hardware requirements for [APP_NAME]. [APP_NAME] requires OpenGL 2.0 or later shader support. If this is the case, you may want to make sure that you have the latest drivers for your graphics card, and service packs and patches for your operating system. - -If you continue to have problems, please visit the [SUPPORT_SITE]. - </global> - - <global name="UnsupportedGLRequirements"> -You do not appear to have the proper hardware requirements for [APP_NAME]. [APP_NAME] requires an OpenGL graphics card that has multitexture support. If this is the case, you may want to make sure that you have the latest drivers for your graphics card, and service packs and patches for your operating system. - -If you continue to have problems, please visit the [SUPPORT_SITE]. - </global> - <global name="UnsupportedIntelDriver"> The installed Intel graphics driver for [GPUNAME], version [VERSION], is significantly out of date and is known to cause excessive rates of program crashes. You are strongly advised to update to a current Intel driver @@ -11869,7 +11911,7 @@ This Region does not support environmental settings. <notification icon="alertmodal.tga" - label="Save Outfit" + label="Save Environmental Settings" name="SaveSettingAs" type="alertmodal"> <unique/> @@ -12048,6 +12090,40 @@ Unpacking: [UNPACK_TIME]s [USIZE]KB </form> </notification> + <notification + icon="alertmodal.tga" + label="Create subfolder" + name="CreateSubfolder" + type="alertmodal"> + <unique/> + Name the new folder: + <tag>confirm</tag> + <form name="form"> + <input name="message" type="text"> + [DESC] + </input> + <button + default="true" + index="0" + name="OK" + text="OK"/> + <button + index="1" + name="Cancel" + text="Cancel"/> + </form> + </notification> + <notification + icon="alertmodal.tga" + name="SameFolderRequired" + type="alert"> + Selected items must be in the same folder. + <tag>fail</tag> + <usetemplate + name="okbutton" + yestext="OK"/> + </notification> + <!-- ALCHEMY BELOW THIS LINE --> <notification icon="notifytip.tga" diff --git a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml index 7428b8d5412a733e0b8da1cbdbd0a70a38bba776..2f9c6439524158f92466d2ef6bdd6c8609d7a9a9 100644 --- a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml +++ b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml @@ -183,6 +183,7 @@ right="-3" mouse_opaque="true" name="speaking_indicator" + tool_tip="Voice volume" visible="true" width="20" /> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_edit_classified.xml b/indra/newview/skins/default/xui/en/panel_edit_classified.xml deleted file mode 100644 index 396a5cc8df2abadae5ac47c355093b6da2554946..0000000000000000000000000000000000000000 --- a/indra/newview/skins/default/xui/en/panel_edit_classified.xml +++ /dev/null @@ -1,352 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<panel - background_visible="true" - bevel_style="in" - follows="left|top|right|bottom" - height="569" - label="Edit Classified" - layout="topleft" - left="0" - min_height="350" - name="panel_edit_classified" - help_topic="profile_edit_classified" - top="0" - width="333"> - <panel.string - name="location_notice"> - (will update after save) - </panel.string> - <string name="publish_label"> - Publish - </string> - <string name="save_label"> - Save - </string> - <button - follows="top|left" - height="24" - image_hover_unselected="BackButton_Over" - image_pressed="BackButton_Press" - image_unselected="BackButton_Off" - layout="topleft" - name="back_btn" - left="10" - tab_stop="false" - top="2" - width="30" - use_draw_context_alpha="false" /> - <text - type="string" - length="1" - follows="top" - font="SansSerifHugeBold" - height="26" - layout="topleft" - left_pad="4" - name="title" - text_color="LtGray" - top="0" - width="250"> - Edit Classified - </text> - <scroll_container - color="DkGray2" - follows="all" - height="502" - layout="topleft" - left="8" - top_pad="10" - name="profile_scroll" - reserve_scroll_corner="false" - opaque="true" - width="312"> - <panel - name="scroll_content_panel" - follows="left|top" - min_height="300" - layout="topleft" - top="0" - background_visible="false" - height="690" - left="0" - width="285"> - <panel - name="snapshot_panel" - layout="topleft" - follows="left|top|right" - height="197" - left="10" - top="10" - width="272"> - <texture_picker - fallback_image="default_land_picture.j2c" - follows="left|top|right" - height="197" - width="272" - layout="topleft" - top="0" - left="0" - name="classified_snapshot" /> - <icon - height="197" - image_name="spacer24.tga" - layout="topleft" - name="edit_icon" - label="" - tool_tip="Click to select an image" - top="0" - left="0" - width="272" /> - </panel> - <text - type="string" - length="1" - follows="left|top" - height="15" - font="SansSerifSmall" - font.style="BOLD" - layout="topleft" - left="10" - top="215" - name="Name:" - text_color="white" - width="280"> - Title: - </text> - <line_editor - follows="left|top|right" - font="SansSerif" - height="20" - layout="topleft" - left="10" - top_pad="2" - max_length_bytes="30" - name="classified_name" - prevalidate_callback="ascii" - width="273" /> - <text - type="string" - length="1" - follows="left|top" - height="15" - font="SansSerifSmall" - font.style="BOLD" - layout="topleft" - left="10" - top_pad="20" - name="description_label" - text_color="white" - width="280"> - Description: - </text> - <text_editor - follows="left|top|right" - height="100" - width="273" - layout="topleft" - left="10" - top_pad="2" - max_length="256" - name="classified_desc" - word_wrap="true" /> - <text - type="string" - length="1" - font="SansSerifSmall" - font.style="BOLD" - follows="left|top" - height="15" - layout="topleft" - left="10" - name="location_label" - text_color="white" - top_pad="20" - width="280"> - Location: - </text> - <text - type="string" - length="1" - follows="left|top" - height="30" - layout="topleft" - left="10" - name="classified_location" - right="-10" - top_pad="2" - width="280" - word_wrap="true"> - loading... - </text> - <button - follows="left|top" - height="23" - label="Set to Current Location" - layout="topleft" - left="10" - top_pad="5" - name="set_to_curr_location_btn" - width="200" /> - <text - follows="left|top" - font.style="BOLD" - height="10" - layout="topleft" - left="10" - name="category_label" - text_color="white" - top_pad="15" - value="Category:" - width="250" /> - <combo_box - follows="left|top" - height="23" - label="" - left="10" - name="category" - top_pad="5" - width="156" /> - <text - follows="left|top" - font.style="BOLD" - height="10" - layout="topleft" - left="10" - name="content_type_label" - text_color="white" - top_pad="15" - value="Content type:" - width="250" /> - <icons_combo_box - follows="left|top" - height="23" - label="General Content" - layout="topleft" - left="10" - name="content_type" - top_pad="5" - width="156"> - <icons_combo_box.drop_down_button - image_overlay="Parcel_PG_Light" - image_overlay_alignment="left" - imgoverlay_label_space="3" - pad_left="3"/> - <icons_combo_box.item - label="Moderate Content" - name="mature_ci" - value="Mature"> - <item.columns - halign="center" - type="icon" - value="Parcel_M_Light" - width="20"/> - </icons_combo_box.item> - <icons_combo_box.item - label="General Content" - name="pg_ci" - value="PG"> - <item.columns - halign="center" - type="icon" - value="Parcel_PG_Light" - width="20"/> - </icons_combo_box.item> - </icons_combo_box> - <check_box - height="16" - label="Auto renew each week" - layout="topleft" - left="10" - name="auto_renew" - top_pad="15" - width="250" /> - <text - follows="left|top" - height="10" - layout="topleft" - left="10" - name="price_for_listing_label" - text_color="white" - top_pad="15" - value="Price for listing:" - width="250" /> - <spinner - decimal_digits="0" - follows="left|top" - halign="left" - height="23" - increment="1" - label_width="20" - label="L$" - v_pad="10" - layout="topleft" - left="10" - value="50" - min_val="50" - max_val="99999" - name="price_for_listing" - top_pad="5" - tool_tip="Price for listing." - width="105" /> - </panel> - </scroll_container> - <panel - follows="left|right|bottom" - height="23" - label="bottom_panel" - layout="topleft" - left="8" - name="bottom_panel" - top_pad="5" - width="303"> - - <layout_stack - follows="bottom|left|right" - height="23" - layout="topleft" - name="bottom_panel_ls" - left="1" - orientation="horizontal" - top_pad="0" - width="309"> - - <layout_panel - follows="bottom|left|right" - height="23" - layout="bottomleft" - left="0" - name="save_changes_btn_lp" - auto_resize="true" - width="156"> - <button - follows="bottom|left|right" - height="23" - label="[LABEL]" - layout="topleft" - name="save_changes_btn" - left="1" - top="0" - width="155" /> - </layout_panel> - - <layout_panel - follows="bottom|left|right" - height="23" - layout="bottomleft" - left_pad="3" - name="cancel_btn_lp" - auto_resize="true" - width="157"> - <button - follows="bottom|left|right" - height="23" - label="Cancel" - layout="topleft" - name="cancel_btn" - left="1" - top="0" - width="156" /> - </layout_panel> - </layout_stack> - </panel> -</panel> diff --git a/indra/newview/skins/default/xui/en/panel_edit_pick.xml b/indra/newview/skins/default/xui/en/panel_edit_pick.xml deleted file mode 100644 index 829562740f4c5c5ab4b5f49e7df1dd89354fe69b..0000000000000000000000000000000000000000 --- a/indra/newview/skins/default/xui/en/panel_edit_pick.xml +++ /dev/null @@ -1,237 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<panel - background_visible="true" - bevel_style="in" - follows="left|top|right|bottom" - height="569" - label="Edit Pick" - layout="topleft" - left="0" - min_height="350" - name="panel_edit_pick" - help_topic="profile_edit_pick" - top="0" - width="333"> - <panel.string - name="location_notice"> - (will update after save) - </panel.string> - <button - follows="top|left" - height="24" - image_hover_unselected="BackButton_Over" - image_pressed="BackButton_Press" - image_unselected="BackButton_Off" - layout="topleft" - name="back_btn" - left="10" - tab_stop="false" - top="4" - width="30" - use_draw_context_alpha="false" /> - <text - type="string" - length="1" - follows="top" - font="SansSerifHugeBold" - height="26" - layout="topleft" - left_pad="4" - name="title" - text_color="LtGray" - top="4" - width="250"> - Edit Pick - </text> - <scroll_container - color="DkGray2" - follows="all" - height="501" - layout="topleft" - left="8" - top_pad="9" - name="profile_scroll" - opaque="true" - width="312"> - <panel - name="scroll_content_panel" - follows="left|top|right" - min_height="300" - layout="topleft" - top="0" - background_visible="false" - height="500" - left="0" - width="285"> - <texture_picker - fallback_image="default_land_picture.j2c" - follows="left|top|right" - height="197" - width="272" - layout="topleft" - no_commit_on_selection="true" - top="10" - left="11" - name="pick_snapshot" /> - <icon - height="197" - image_name="spacer24.tga" - layout="topleft" - name="edit_icon" - label="" - tool_tip="Click to select an image" - top="10" - left="11" - width="286" /> - <text - type="string" - length="1" - follows="left|top|right" - height="15" - font="SansSerifSmall" - font.style="BOLD" - layout="topleft" - left="10" - top="215" - name="Name:" - text_color="white" - width="280"> - Title: - </text> - <line_editor - follows="left|top|right" - font="SansSerif" - height="20" - layout="topleft" - left="10" - top_pad="2" - max_length_bytes="63" - name="pick_name" - width="273" /> - <text - type="string" - length="1" - follows="left|top|right" - height="15" - font="SansSerifSmall" - font.style="BOLD" - layout="topleft" - left="10" - top_pad="20" - name="description_label" - text_color="white" - width="280"> - Description: - </text> - <text_editor - follows="left|top|right" - height="100" - width="273" - hide_scrollbar="false" - layout="topleft" - left="10" - top_pad="2" - max_length="1023" - name="pick_desc" - spellcheck="true" - word_wrap="true" /> - <text - type="string" - length="1" - font="SansSerifSmall" - font.style="BOLD" - follows="left|top|right" - height="15" - layout="topleft" - left="10" - name="location_label" - text_color="white" - top_pad="20" - width="280"> - Location: - </text> - <text - type="string" - length="1" - follows="left|top|right" - height="50" - layout="topleft" - left="10" - name="pick_location" - top_pad="2" - width="280" - word_wrap="true"> - loading... - </text> - <button - follows="left|top" - height="23" - label="Set to Current Location" - layout="topleft" - left="8" - top_pad="0" - name="set_to_curr_location_btn" - width="200" /> - </panel> - </scroll_container> - <panel - follows="left|right|bottom" - height="23" - label="bottom_panel" - layout="topleft" - left="8" - name="bottom_panel" - top_pad="5" - width="315"> - - <layout_stack - follows="bottom|left|right" - height="23" - layout="topleft" - name="layout_stack1" - left="0" - orientation="horizontal" - top_pad="0" - width="313"> - - <layout_panel - follows="bottom|left|right" - height="23" - layout="topleft" - left="0" - name="layout_panel1" - auto_resize="true" - width="150"> - <button - follows="bottom|left|right" - height="23" - label="Save Pick" - layout="topleft" - name="save_changes_btn" - top="0" - left="1" - width="149" /> - </layout_panel> - - <layout_panel - follows="bottom|left|right" - height="23" - layout="topleft" - left_pad="4" - name="layout_panel2" - auto_resize="true" - width="146"> - <button - follows="bottom|left|right" - height="23" - label="Cancel" - layout="topleft" - name="cancel_btn" - top="0" - left="1" - width="145" /> - </layout_panel> - </layout_stack> - - </panel> -</panel> diff --git a/indra/newview/skins/default/xui/en/panel_edit_profile.xml b/indra/newview/skins/default/xui/en/panel_edit_profile.xml deleted file mode 100644 index 2c7c8133d139125ab611f159c346a84adc25988f..0000000000000000000000000000000000000000 --- a/indra/newview/skins/default/xui/en/panel_edit_profile.xml +++ /dev/null @@ -1,472 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<panel - background_visible="true" - class="edit_profile_panel" - follows="all" - height="585" - label="Profile Edit" - layout="topleft" - left="0" - name="edit_profile_panel" - top="0" - width="313"> - <string - name="CaptionTextAcctInfo"> - [ACCTTYPE] -[PAYMENTINFO] [AGEVERIFICATION] - </string> - <string - name="RegisterDateFormat"> - [REG_DATE] ([AGE]) - </string> - <string - name="AcctTypeResident" - value="Resident" /> - <string - name="AcctTypeTrial" - value="Trial" /> - <string - name="AcctTypeCharterMember" - value="Charter Member" /> - <string - name="AcctTypeEmployee" - value="Linden Lab Employee" /> - <string - name="PaymentInfoUsed" - value="Payment Info Used" /> - <string - name="PaymentInfoOnFile" - value="Payment Info On File" /> - <string - name="NoPaymentInfoOnFile" - value="No Payment Info On File" /> - <string - name="AgeVerified" - value="Age-verified" /> - <string - name="NotAgeVerified" - value="Not Age-verified" /> - <string - name="partner_edit_link_url"> - http://www.secondlife.com/account/partners.php?lang=en - </string> - <string - name="my_account_link_url"> - http://secondlife.com/my - </string> - <string - name="no_partner_text" - value="None" /> - <scroll_container - color="DkGray2" - follows="all" - height="537" - min_height="300" - layout="topleft" - left="8" - width="292" - name="profile_scroll" - reserve_scroll_corner="true" - opaque="true" - top="10"> - <panel - name="scroll_content_panel" - follows="left|top|right" - layout="topleft" - top="0" - height="537" - min_height="300" - left="0" - width="292"> - <panel - name="data_panel" - follows="left|top|right" - layout="topleft" - top="0" - height="537" - min_height="300" - left="0" - width="292"> - <text - top="5" - follows="top|left" - height="13" - layout="topleft" - left="10" - name="display_name_label" - text_color="LtGray" - value="Display Name:" - width="80" /> - <text - top="5" - follows="top|left" - height="13" - layout="topleft" - left="10" - name="solo_username_label" - text_color="LtGray" - value="Username:" - visible="false" - width="80" /> - <button - name="set_name" - layout="topleft" - follows="top|left" - image_overlay="Edit_Wrench" - top="21" - left="10" - height="23" - width="23" - tool_tip="Set Display Name"/> - <text - follows="top|left" - font="SansSerifBigBold" - height="20" - layout="topleft" - left="10" - name="solo_user_name" - text_color="white" - top_delta="3" - translate="false" - value="TestString PleaseIgnore" - use_ellipses="true" - visible="false" - width="275" /> - <text - follows="top|left" - font="SansSerifBigBold" - height="20" - layout="topleft" - left="43" - name="user_name" - text_color="white" - top_delta="0" - translate="false" - value="TestString PleaseIgnore" - use_ellipses="true" - visible="true" - width="250" /> - <text - follows="top|left" - font="SansSerifBold" - height="20" - layout="topleft" - left_delta="0" - name="user_name_small" - text_color="white" - top_delta="-4" - translate="false" - value="TestString PleaseIgnore" - use_ellipses="true" - visible="false" - wrap="true" - width="245" /> - <text - follows="top|left" - height="13" - layout="topleft" - left="10" - name="user_label" - text_color="LtGray" - top_pad="8" - value="Username:" - width="70" /> - <text - follows="top|left" - height="20" - layout="topleft" - left_pad="0" - name="user_slid" - text_color="EmphasisColor" - font="SansSerifBold" - top_delta="-2" - translate="false" - use_ellipses="true" - value="teststring.pleaseignore" - wrap="true" - width="205" /> - <panel - name="lifes_images_panel" - follows="left|top|right" - height="244" - layout="topleft" - top="65" - left="0" - width="292"> - <panel - follows="left|top" - height="117" - layout="topleft" - left="10" - name="second_life_image_panel" - top="0" - width="282"> - <text - follows="left|top|right" - font.style="BOLD" - height="15" - layout="topleft" - left="0" - top="10" - name="second_life_photo_title_text" - text_color="white" - value="[SECOND_LIFE]:" - width="100" /> - <texture_picker - allow_no_texture="true" - default_image_name="None" - enabled="false" - fallback_image="default_profile_picture.j2c" - follows="top|left" - height="124" - layout="topleft" - left="1" - name="2nd_life_pic" - top_pad="0" - width="102" /> - </panel> - <icon - height="102" - image_name="spacer24.tga" - layout="topleft" - name="2nd_life_edit_icon" - label="" - left="11" - top_pad="-92" - tool_tip="Click to select an image" - width="102" /> - </panel> - <text_editor - type="string" - length="1" - follows="left|top|right" - font="SansSerifSmall" - height="102" - layout="topleft" - left="123" - top="90" - max_length="512" - name="sl_description_edit" - width="157" - word_wrap="true"> - </text_editor> - <panel - follows="left|top" - height="117" - layout="topleft" - top_pad="5" - left="10" - name="first_life_image_panel" - width="285"> - <text - follows="left|top|right" - font.style="BOLD" - height="15" - layout="topleft" - left="0" - top_pad="10" - name="real_world_photo_title_text" - text_color="white" - value="Real World:" - width="100" /> - <texture_picker - allow_no_texture="true" - default_image_name="None" - enabled="false" - fallback_image="Generic_Person_Large" - follows="top|left" - height="124" - layout="topleft" - left="1" - name="real_world_pic" - top_pad="0" - width="102" /> - </panel> - <icon - height="102" - image_name="spacer24.tga" - layout="topleft" - name="real_world_edit_icon" - label="" - left="11" - top_pad="-92" - tool_tip="Click to select an image" - width="102" /> - <text_editor - type="string" - length="1" - follows="left|top|right" - font="SansSerifSmall" - height="102" - layout="topleft" - left="123" - max_length="512" - top="223" - name="fl_description_edit" - width="157" - word_wrap="true"> - </text_editor> - <text - type="string" - length="1" - follows="left|top" - font="SansSerifSmall" - font.style="BOLD" - height="15" - layout="topleft" - left="10" - name="title_homepage_text" - text_color="white" - top_pad="10" - width="100"> - Homepage: - </text> - <line_editor - follows="left|top|right" - font="SansSerifSmall" - height="20" - layout="topleft" - left="10" - top_pad="0" - value="http://" - name="homepage_edit" - width="272"> - </line_editor> - <text - follows="left|top" - font="SansSerifSmall" - font.style="BOLD" - height="15" - layout="topleft" - left="10" - name="title_acc_status_text" - text_color="white" - top_pad="10" - value="My Account:" - width="100" /> - <text_editor - allow_scroll="false" - bg_visible="false" - follows="left|top|right" - h_pad="0" - height="28" - layout="topleft" - left="10" - name="acc_status_text" - read_only="true" - top_pad="5" - v_pad="0" - value="Resident. No payment info on file." - width="200" - word_wrap="true" /> - <text - type="string" - follows="left|top" - font="SansSerifSmall" - height="15" - layout="topleft" - left="10" - name="my_account_link" - value="[[URL] Go to My Dashboard]" - width="200" /> - <text - follows="left|top" - font="SansSerifSmall" - font.style="BOLD" - height="15" - layout="topleft" - left="10" - name="title_partner_text" - text_color="white" - top_pad="10" - value="My Partner:" - width="150" /> - <panel - follows="left|top|right" - height="15" - layout="topleft" - left="10" - name="partner_data_panel" - width="200"> - <text - follows="left|top|right" - height="12" - initial_value="(retrieving)" - layout="topleft" - left="0" - name="partner_text" - top="0" - use_ellipses="true" - width="280"/> - </panel> - <text - follows="left|top" - height="15" - layout="topleft" - link="true" - left="10" - name="partner_edit_link" - value="[[URL] Edit]" - width="70" /> - </panel> - </panel> - </scroll_container> - <panel - follows="bottom|left|right" - height="28" - left="0" - name="profile_me_buttons_panel" - top_pad="0" - width="313"> - - <layout_stack - follows="bottom|left|right" - height="28" - layout="topleft" - name="bottom_panel_ls" - left="7" - orientation="horizontal" - top_pad="0" - width="295"> - - <layout_panel - follows="bottom|left|right" - height="23" - layout="bottomleft" - name="save_changes_btn_lp" - top="0" - auto_resize="true" - width="153"> - <button - follows="bottom|left|right" - height="23" - label="Save Changes" - layout="topleft" - left="1" - name="save_btn" - top="0" - width="152" /> - </layout_panel> - - <layout_panel - follows="bottom|left|right" - height="23" - layout="bottomleft" - left_pad="3" - name="show_on_map_btn_lp" - top="0" - auto_resize="true" - width="154"> - <button - follows="bottom|left|right" - height="23" - label="Cancel" - layout="topleft" - left="1" - name="cancel_btn" - top="0" - width="153" /> - </layout_panel> - </layout_stack> - </panel> -</panel> diff --git a/indra/newview/skins/default/xui/en/panel_group_general.xml b/indra/newview/skins/default/xui/en/panel_group_general.xml index 27a6ab289b0da46f7ee26d3a0aeff4abd9299923..9585aa483e3cb3bda67ddf91d909a481e6f748be 100644 --- a/indra/newview/skins/default/xui/en/panel_group_general.xml +++ b/indra/newview/skins/default/xui/en/panel_group_general.xml @@ -95,6 +95,7 @@ Hover your mouse over the options for more help. layout="topleft" max_length="511" name="charter" + parse_urls="true" top="105" right="-4" bg_readonly_color="DkGray2" diff --git a/indra/newview/skins/default/xui/en/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/en/panel_group_list_item_short.xml index fb46d1cce30bfea3b98d90424d36fc3489a2c607..b72af7221e4890c9f9767e68b07431c01e58dc5d 100644 --- a/indra/newview/skins/default/xui/en/panel_group_list_item_short.xml +++ b/indra/newview/skins/default/xui/en/panel_group_list_item_short.xml @@ -53,12 +53,39 @@ text_color="ScrollUnselectedColor" use_ellipses="true" /> + <button + name="visibility_hide_btn" + tool_tip="Hide group on my profile" + top_delta="-3" + left_pad="3" + right="-53" + height="20" + width="20" + follows="right" + image_pressed="Profile_Group_Visibility_Off_Pressed" + image_unselected="Profile_Group_Visibility_Off" + tab_stop="false" + visible="false" + /> + <button + name="visibility_show_btn" + tool_tip="Show group on my profile" + top_delta="0" + right_delta="0" + height="20" + width="20" + follows="right" + image_pressed="Profile_Group_Visibility_On_Pressed" + image_unselected="Profile_Group_Visibility_On" + tab_stop="false" + visible="false" + /> <button name="info_btn" tool_tip="More info" - top_delta="-2" + top_delta="2" left_pad="3" - right="-31" + right="-30" height="16" width="16" follows="right" diff --git a/indra/newview/skins/default/xui/en/panel_login_first.xml b/indra/newview/skins/default/xui/en/panel_login_first.xml index 5568ccb7928635b35c67ff12868c4fcabebf83f6..d36c83d292e342c4da499cc773bce9557e49588c 100644 --- a/indra/newview/skins/default/xui/en/panel_login_first.xml +++ b/indra/newview/skins/default/xui/en/panel_login_first.xml @@ -98,7 +98,7 @@ auto_resize="false" follows="left|right|top" name="widget_container" - width="532" + width="730" left="0" top="0" height="80"> @@ -106,7 +106,7 @@ allow_text_entry="true" follows="left|bottom" height="32" - left="2" + left="42" label="Username" combo_editor.font="SansSerifLarge" max_chars="128" @@ -126,7 +126,7 @@ follows="left|top" width="200" height="32" - left="220" + left="262" max_length_chars="16" name="password_edit" label="Password" @@ -145,42 +145,58 @@ label_color="White" font="SansSerifLarge" name="connect_btn" - left="432" - width="100" + left_pad="15" + width="120" height="32" top="0" /> + <text + follows="left|top" + font="SansSerifLarge" + font.style="BOLD" + text_color="EmphasisColor" + height="34" + name="sign_up_text" + left_pad="10" + top="0" + width="200" + valign="center"> + Sign up + </text> <check_box - control_name="RememberPassword" follows="left|top" font="SansSerifLarge" - left="0" + left="42" top="32" height="24" label="Remember me" + word_wrap="down" check_button.bottom="3" - name="remember_check" - width="145" /> - <text + name="remember_name" + tool_tip="Already remembered user can be forgotten from Me > Preferences > Advanced > Remembered Usernames." + width="198" /> + <check_box + control_name="RememberPassword" follows="left|top" font="SansSerifLarge" text_color="EmphasisColor" - height="16" - name="forgot_password_text" - left="219" - top="34" - width="200"> - Forgotten password - </text> + height="24" + left="262" + bottom_delta="0" + label="Remember password" + word_wrap="down" + check_button.bottom="3" + name="remember_password" + width="198" /> <text follows="left|top" font="SansSerifLarge" text_color="EmphasisColor" height="16" - name="sign_up_text" - left="432" + name="forgot_password_text" + left="492" top="34" width="200"> - Sign up + Forgotten password </text> </layout_panel> <layout_panel @@ -216,24 +232,17 @@ auto_resize="false" follows="left|right|top" name="images_container" - width="832" + width="675" left="0" top="0" height="500"> <icon - height="400" - width="400" - image_name="first_login_image_left" + height="450" + width="675" + image_name="first_login_image" left="0" name="image_left" top="0" /> - <icon - height="400" - width="400" - image_name="first_login_image_right" - left_pad="32" - name="image_right" - top="0" /> </layout_panel> <layout_panel height="100" diff --git a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml index 11f79b6753b9bbb159533f144c0f6bc1cee8df60..8e9c86f12cd25e6324699fd3ab21f57bdd794024 100644 --- a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml +++ b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml @@ -4,7 +4,6 @@ background_visible="true" bg_opaque_color="MouseGray" follows="left|top|right" - focus_root="true" height="34" layout="topleft" name="navigation_bar" diff --git a/indra/newview/skins/default/xui/en/panel_pick_info.xml b/indra/newview/skins/default/xui/en/panel_pick_info.xml deleted file mode 100644 index 99c47eb8257efaf0d6f189b4d17a15c0ff01aa11..0000000000000000000000000000000000000000 --- a/indra/newview/skins/default/xui/en/panel_pick_info.xml +++ /dev/null @@ -1,190 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<panel - background_visible="true" - follows="all" - height="570" - layout="topleft" - left="0" - min_height="350" - name="panel_pick_info" - help_topic="profile_pick_info" - top="0" - width="333"> - <button - follows="top|left" - height="24" - image_hover_unselected="BackButton_Over" - image_pressed="BackButton_Press" - image_unselected="BackButton_Off" - layout="topleft" - name="back_btn" - left="10" - tab_stop="false" - top="2" - width="30" - use_draw_context_alpha="false" /> - <text - follows="top|left|right" - font="SansSerifHugeBold" - height="26" - layout="topleft" - left_pad="4" - name="title" - text_color="LtGray" - top="2" - value="Pick Info" - use_ellipses="true" - width="275" /> - <scroll_container - color="DkGray2" - opaque="true" - follows="all" - height="503" - layout="topleft" - left="8" - top_pad="10" - name="profile_scroll" - width="312"> - <panel - name="scroll_content_panel" - follows="left|top|right" - min_height="300" - layout="topleft" - top="0" - background_visible="false" - height="400" - left="0" - width="285"> - <texture_picker - fallback_image="default_land_picture.j2c" - enabled="false" - follows="left|top|right" - height="197" - layout="topleft" - left="11" - name="pick_snapshot" - top="10" - width="272" /> - <text_editor - allow_scroll="false" - bg_visible="false" - follows="left|top|right" - h_pad="0" - height="35" - width="280" - layout="topleft" - font="SansSerifBig" - font.style="BOLD" - left="10" - top_pad="10" - name="pick_name" - read_only="true" - text_color="white" - v_pad="0" - value="[name]" - use_ellipses="true" /> - <text_editor - allow_scroll="false" - bg_visible="false" - follows="left|top|right" - h_pad="0" - height="25" - layout="topleft" - left="10" - name="pick_location" - read_only="true" - width="280" - word_wrap="true" - v_pad="0" - value="[loading...]" /> - <text_editor - bg_readonly_color="DkGray2" - follows="all" - height="100" - width="280" - parse_urls="true" - layout="topleft" - left="10" - top_pad="2" - max_length="1023" - name="pick_desc" - read_only="true" - text_readonly_color="white" - value="[description]" - wrap="true" /> - </panel> - </scroll_container> - <panel - follows="left|right|bottom" - height="23" - layout="topleft" - top_pad="5" - left="8" - name="buttons"> - - <layout_stack - follows="bottom|left|right" - height="23" - layout="topleft" - name="layout_stack1" - left="0" - orientation="horizontal" - top_pad="0" - width="312"> - - <layout_panel - follows="bottom|left|right" - height="23" - layout="bottomleft" - left="0" - name="layout_panel1" - auto_resize="true" - width="101"> - <button - follows="bottom|left|right" - height="23" - label="Teleport" - layout="topleft" - name="teleport_btn" - top="0" - width="101" /> - </layout_panel> - - <layout_panel - follows="bottom|left|right" - height="23" - layout="bottomleft" - left_pad="3" - name="show_on_map_btn_lp" - auto_resize="true" - width="100"> - <button - follows="bottom|left|right" - height="23" - label="Map" - layout="topleft" - name="show_on_map_btn" - top_pad="0" - width="100" /> - </layout_panel> - - <layout_panel - follows="bottom|left|right" - height="23" - layout="bottomleft" - left_pad="3" - name="edit_btn_lp" - auto_resize="true" - width="101"> - <button - follows="bottom|left|right" - height="23" - label="Edit" - layout="topleft" - name="edit_btn" - top_pad="0" - width="101" /> - </layout_panel> - </layout_stack> - </panel> -</panel> diff --git a/indra/newview/skins/default/xui/en/panel_picks.xml b/indra/newview/skins/default/xui/en/panel_picks.xml deleted file mode 100644 index 8def96cada1d79213cd0561a9ef88e1af84d4bdc..0000000000000000000000000000000000000000 --- a/indra/newview/skins/default/xui/en/panel_picks.xml +++ /dev/null @@ -1,227 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<panel -bg_opaque_color="DkGray2" - background_visible="true" - background_opaque="true" - follows="all" - height="571" - label="Picks" - layout="topleft" - left="8" - name="panel_picks" - top_pad="0" - width="313"> - <string - name="no_picks" - value="No Picks" /> - <string - name="no_classifieds" - value="No Classifieds" /> - <text - type="string" - follows="all" - height="535" - layout="topleft" - left="6" - name="picks_panel_text" - wrap="true" - top="10" - width="313"/> - <accordion - fit_parent="true" - follows="all" - height="514" - layout="topleft" - left="0" - name="accordion" - top="0" - single_expansion="true" - width="313"> - <accordion_tab - layout="topleft" - height="235" - min_height="150" - name="tab_picks" - title="Picks" - visible="false"> - <flat_list_view - color="DkGray2" - follows="all" - layout="topleft" - left="0" - name="picks_list" - opaque="true" - top="0" - width="313" /> - </accordion_tab> - <accordion_tab - layout="topleft" - height="235" - name="tab_classifieds" - title="Classifieds" - visible="false"> - <flat_list_view - color="DkGray2" - follows="all" - layout="topleft" - left="0" - name="classifieds_list" - opaque="true" - top="0" - width="313" /> - </accordion_tab> - </accordion> - <panel - bg_opaque_color="DkGray2" - background_visible="true" - background_opaque="true" - bevel_style="none" - enabled="false" - follows="bottom|left|right" - left="1" - height="27" - label="bottom_panel" - layout="topleft" - name="edit_panel" - top_pad="0" - width="312"> - - <layout_stack - follows="bottom|left|right" - height="23" - layout="bottomleft" - name="edit_panel_ls" - left="10" - orientation="horizontal" - top_pad="0" - width="293"> - - <layout_panel - follows="bottom|left" - height="18" - layout="bottomleft" - left="0" - name="gear_menu_btn" - auto_resize="true" - width="51"> - <button - follows="bottom|left" - height="18" - image_disabled="AddItem_Disabled" - image_selected="AddItem_Press" - image_unselected="AddItem_Off" - layout="topleft" - left="0" - name="new_btn" - tool_tip="Create a new pick or classified at the current location" - top="0" - width="18" /> - </layout_panel> - - <layout_panel - follows="bottom|right" - height="18" - layout="bottomleft" - name="trash_btn_lp" - auto_resize="true" - width="18"> - <button - follows="bottom|right" - height="18" - image_disabled="TrashItem_Disabled" - image_selected="TrashItem_Press" - image_unselected="TrashItem_Off" - layout="topleft" - name="trash_btn" - top="0" - width="18" /> - </layout_panel> - - </layout_stack> - </panel> - - <panel - bg_opaque_color="DkGray" - background_visible="true" - background_opaque="true" - follows="bottom|left|right" - layout="topleft" - left="0" - height="30" - name="buttons_cucks" - top_pad="0" - width="313"> - - <layout_stack - follows="bottom|left|right" - height="28" - layout="topleft" - left="2" - name="buttons_cucks_ls" - orientation="horizontal" - top="0" - width="313"> - - <layout_panel - follows="bottom|left|right" - height="28" - layout="topleft" - left="0" - name="info_btn_lp" - auto_resize="true" - top="0" - width="95"> - <button - enabled="false" - follows="top|left|right" - height="23" - label="Info" - layout="topleft" - name="info_btn" - tab_stop="false" - tool_tip="Show pick information" - width="95" /> - </layout_panel> - - <layout_panel - follows="bottom|left|right" - height="28" - layout="bottomleft" - left_pad="2" - name="teleport_btn_lp" - auto_resize="true" - width="117"> - <button - enabled="false" - follows="top|left|right" - height="23" - label="Teleport" - layout="topleft" - name="teleport_btn" - tab_stop="false" - tool_tip="Teleport to the corresponding area" - width="117" /> - </layout_panel> - - <layout_panel - follows="bottom|left|right" - height="28" - layout="bottomleft" - name="show_on_map_btn_lp" - auto_resize="true" - left_pad="2" - width="90"> - <button - enabled="false" - follows="top|left|right" - height="23" - label="Map" - layout="topleft" - name="show_on_map_btn" - tab_stop="false" - tool_tip="Show the corresponding area on the World Map" - width="88" /> - </layout_panel> - </layout_stack> - </panel> -</panel> diff --git a/indra/newview/skins/default/xui/en/panel_profile_classified.xml b/indra/newview/skins/default/xui/en/panel_profile_classified.xml index 4b451b3e1cabd24500609743ffef838965782d12..d2e2b9a574046ff1d1ab7c62200cc35ee59d0f07 100644 --- a/indra/newview/skins/default/xui/en/panel_profile_classified.xml +++ b/indra/newview/skins/default/xui/en/panel_profile_classified.xml @@ -4,7 +4,7 @@ top="0" left="0" height="420" - width="325" + width="315" follows="all" layout="topleft" help_topic="panel_profile_classified" @@ -60,25 +60,44 @@ > Save </string> - <scroll_container - name="profile_scroll" - top="0" - left="0" - bottom="-35" - width="320" + + <layout_stack + name="main_classifieds_stack" + top="0" + bottom="-1" + left="0" + width="310" + follows="all" + layout="topleft" + orientation="vertical" + animate="false" + > + <layout_panel follows="all" + width="310" + height="300" layout="topleft" - color="DkGray2" - opaque="true" - reserve_scroll_corner="false" - > + name="scroll_layout_panel" + auto_resize="true"> + <scroll_container + name="profile_scroll" + top="0" + left="0" + height="300" + width="310" + follows="all" + layout="topleft" + color="DkGray2" + opaque="true" + reserve_scroll_corner="false" + > <panel name="info_scroll_content_panel" top="0" left="0" height="562" - width="290" - follows="left|top" + width="280" + follows="left|top|right" layout="topleft" background_visible="false" min_height="200" @@ -88,9 +107,9 @@ enabled="false" top="0" left="10" - height="197" - width="275" - follows="left|top|right" + height="161" + width="260" + follows="left|top" layout="topleft" fallback_image="default_land_picture.j2c" /> @@ -100,19 +119,19 @@ tool_tip="Click to select an image" top="0" left="0" - height="197" - width="272" + height="161" + width="260" layout="topleft" - follows="left|top|right" + follows="left|top" image_name="spacer24.tga" visible="false" /> <layout_stack name="info_panel" - top="180" + top="145" left="0" height="375" - width="320" + width="310" follows="all" layout="topleft" visible="true" @@ -124,7 +143,7 @@ top="0" left="0" height="160" - width="290" + width="280" follows="all" layout="topleft" auto_resize="false" @@ -134,7 +153,7 @@ top="0" left="10" height="35" - width="280" + width="270" follows="left|top|right" layout="topleft" allow_scroll="false" @@ -167,7 +186,7 @@ top_pad="5" left="10" height="30" - width="290" + width="280" follows="left|top" layout="topleft" allow_scroll="false" @@ -430,7 +449,7 @@ </layout_stack> <panel name="edit_panel" - top="180" + top="145" left="0" height="420" width="320" @@ -620,33 +639,52 @@ /> </panel> </panel> - </scroll_container> - <layout_stack - name="edit_btns_pnl" - bottom="-1" - left="9" + </scroll_container> + </layout_panel> + + <layout_panel + follows="all" + width="310" height="25" - follows="left|right|bottom" layout="topleft" - orientation="horizontal" - animate="false" - > + name="util_buttons_lp" + auto_resize="true"> + <layout_stack + name="util_buttons_stack" + bottom="-1" + left="1" + right="-1" + height="25" + follows="left|bottom|right" + layout="topleft" + orientation="horizontal" + animate="false" + > + <layout_panel + follows="all" + layout="topleft" + name="util_resizer_left" + auto_resize="true" + user_resize="false" + width="1"/> + <layout_panel follows="all" height="25" layout="topleft" left="0" name="teleport_btn_lp" - auto_resize="true" + auto_resize="false" top="0" - width="101"> + width="85"> <button name="teleport_btn" label="Teleport" top="0" left="0" height="23" - width="101" + max_width="101" + width="85" follows="bottom|left|right" layout="topleft" /> @@ -658,15 +696,16 @@ layout="bottomleft" left_pad="2" name="map_btn_lp" - auto_resize="true" - width="100"> + auto_resize="false" + max_width="101" + width="85"> <button name="show_on_map_btn" label="Map" top="0" left="0" height="23" - width="100" + width="85" follows="bottom|left|right" layout="topleft" /> @@ -678,60 +717,112 @@ layout="bottomleft" left_pad="2" name="edit_btn_lp" - auto_resize="true" - width="101"> + auto_resize="false" + max_width="101" + width="85"> <button name="edit_btn" label="Edit" top="0" left="0" height="23" - width="101" + width="85" follows="bottom|left|right" layout="topleft" /> </layout_panel> <layout_panel - follows="all" - height="25" - layout="topleft" - left="0" - name="save_btn_lp" - auto_resize="true" - top="0" - width="155"> - <button - name="save_changes_btn" - label="[LABEL]" - top="0" - left="0" - left_pad="5" - height="23" - width="155" - follows="bottom|left|right" - layout="topleft" + follows="all" + layout="topleft" + name="util_resizer_right" + auto_resize="true" + width="1"> + </layout_panel> + </layout_stack> + </layout_panel> + <layout_panel + follows="all" + width="310" + height="41" + layout="topleft" + name="publish_layout_panel" + auto_resize="false"> + <view_border + bevel_style="none" + height="0" + follows="left|top|right" + layout="topleft" + left="0" + name="publish_emphasis_border" + top="5" + width="310"/> + <layout_stack + name="publish_stack" + left="1" + right="-1" + top="11" + height="25" + follows="left|top|right" + layout="topleft" + orientation="horizontal" + animate="false" + > + <layout_panel + follows="all" + layout="topleft" + name="pbl_resizer_left" + auto_resize="true" + user_resize="false" + width="1"/> + + <layout_panel + follows="all" + layout="topleft" + name="save_btn_lp" + auto_resize="false" + width="134"> + <button + name="save_changes_btn" + label="[LABEL]" + top="0" + left="0" + left_pad="5" + height="23" + width="134" + follows="left|top" + layout="topleft" /> </layout_panel> <layout_panel - follows="all" - height="25" - layout="bottomleft" - left_pad="2" - name="cancel_btn_lp" - auto_resize="true" - width="156"> - <button - name="cancel_btn" - label="Cancel" - top="0" - left="0" - height="23" - width="156" - follows="bottom|left|right" - layout="topleft" + follows="all" + layout="bottomleft" + left_pad="2" + name="cancel_btn_lp" + auto_resize="false" + width="134"> + <button + name="cancel_btn" + label="Cancel" + top="0" + left="0" + height="23" + width="134" + follows="left|top" + layout="topleft" /> </layout_panel> - </layout_stack> + + <layout_panel + follows="all" + layout="topleft" + name="pbl_resizer_right" + auto_resize="true" + width="1"> + </layout_panel> + + </layout_stack> + </layout_panel> + </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_profile_classifieds.xml b/indra/newview/skins/default/xui/en/panel_profile_classifieds.xml index ff27113d533c89b25ed38d905e544867c05f4405..2b2f60e0c20ab4c2fada2f6e9435ccbc4e108153 100644 --- a/indra/newview/skins/default/xui/en/panel_profile_classifieds.xml +++ b/indra/newview/skins/default/xui/en/panel_profile_classifieds.xml @@ -13,66 +13,130 @@ name="no_classifieds" value="No Classifieds" /> - <loading_indicator - name="progress_indicator" - top="20" - right="-10" - height="23" - width="23" - follows="top|right" - layout="topleft" - visible="false" - /> - <button - name="new_btn" - label="New..." - tool_tip="Create a new classified at the current location" - enabled="false" - top="25" - left="5" - height="20" - width="70" - follows="left|top" - layout="topleft" - visible="true" - /> - <button - name="delete_btn" - label="Delete..." - tool_tip="Delete currently selected classified" - enabled="false" - left_pad="5" - height="20" - width="70" - follows="left|top" - layout="topleft" - visible="true" - /> - <tab_container - name="tab_classifieds" - top="50" - bottom="-21" - left="4" - right="-4" + + <layout_stack + name="main_stack" + top="0" + left="0" + right="-1" + bottom="-1" + follows="all" + layout="topleft" + animate="false" + orientation="vertical"> + <layout_panel + name="buttons_header" follows="all" layout="topleft" - halign="left" - tab_position="left" - tab_width="85" - use_ellipses="true" - /> - <text - name="classifieds_panel_text" - top="300" - left="110" - right="-110" - height="25" - follows="left|top|right" + height="50" + auto_resize="false" + user_resize="false"> + <button + name="new_btn" + label="New..." + tool_tip="Create a new classified at the current location" + enabled="false" + top="25" + left="5" + height="20" + width="70" + follows="left|top" + layout="topleft" + visible="true" + /> + <button + name="delete_btn" + label="Delete..." + tool_tip="Delete currently selected classified" + enabled="false" + left_pad="5" + height="20" + width="70" + follows="left|top" + layout="topleft" + visible="true" + /> + </layout_panel> + <layout_panel + name="main_body" + follows="all" layout="topleft" - halign="center" - mouse_opaque="false" - wrap="true" - > - Loading... - </text> + height="430" + auto_resize="true" + user_resize="false"> + <tab_container + name="tab_classifieds" + top="0" + bottom="-1" + left="4" + right="-4" + follows="all" + layout="topleft" + halign="left" + tab_position="left" + tab_width="150" + use_ellipses="true" + /> + + <layout_stack + name="indicator_stack" + top="220" + left="0" + right="-1" + height="28" + follows="top|left|right" + layout="topleft" + animate="false" + orientation="horizontal"> + <layout_panel + name="indicator_spacer_left" + follows="all" + layout="topleft" + width="100" + auto_resize="true" + user_resize="false"> + </layout_panel> + <layout_panel + name="buttons_header" + follows="all" + layout="topleft" + width="25" + auto_resize="false" + user_resize="false"> + <loading_indicator + name="progress_indicator" + top="1" + left="1" + height="23" + width="23" + follows="top|left" + layout="topleft" + visible="false" + /> + </layout_panel> + <layout_panel + name="indicator_spacer_right" + follows="all" + layout="topleft" + width="100" + auto_resize="true" + user_resize="false"> + </layout_panel> + </layout_stack> + <text + name="classifieds_panel_text" + top="250" + left="110" + right="-110" + height="25" + follows="left|top|right" + layout="topleft" + halign="center" + mouse_opaque="false" + wrap="true" + > + Loading... + </text> + </layout_panel> + </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_profile_firstlife.xml b/indra/newview/skins/default/xui/en/panel_profile_firstlife.xml index 7bda6d1718ec97756ddd8d0766fa75120facad1d..ca1e405a62cd5e076e6eefd0932f862aa88c0464 100644 --- a/indra/newview/skins/default/xui/en/panel_profile_firstlife.xml +++ b/indra/newview/skins/default/xui/en/panel_profile_firstlife.xml @@ -19,33 +19,85 @@ layout="topleft" visible="false" /> - <texture_picker + <icon name="real_world_pic" - enabled="false" + image_name="Generic_Person_Large" + follows="top|left" + layout="topleft" top="10" - left="6" - height="225" - width="202" + left="8" + height="160" + width="160"/> + <loading_indicator + name="image_upload_indicator" + top="79" + left="77" + height="23" + width="23" follows="top|left" layout="topleft" - allow_no_texture="true" - default_image_name="None" - fallback_image="Generic_Person_Large" - /> + visible="false"/> + <button + name="fl_upload_image" + label="Upload Photo" + top="102" + left="175" + height="20" + width="120" + follows="top|left" + layout="topleft"/> + <button + name="fl_change_image" + label="Change Photo" + top_pad="5" + left="175" + height="20" + width="120" + follows="top|left" + layout="topleft"/> + <button + name="fl_remove_image" + label="Remove Photo" + top_pad="5" + left_delta="0" + height="20" + width="120" + follows="top|left" + layout="topleft"/> <text_editor name="fl_description_edit" trusted_content="false" enabled="false" - top="225" + top="180" left="6" - right="-7" - height="183" + right="-6" + height="224" follows="all" layout="topleft" bg_readonly_color="Transparent" border_visible="true" - max_length="253" + max_length="65000" parse_urls="true" word_wrap="true" /> + <button + name="fl_save_changes" + label="Save" + top_pad="5" + right="-108" + height="20" + width="80" + enabled="false" + follows="right|bottom" + layout="topleft"/> + <button + name="fl_discard_changes" + label="Discard" + top_delta="0" + right="-4" + height="20" + width="100" + enabled="false" + follows="right|bottom" + layout="topleft"/> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_profile_interests.xml b/indra/newview/skins/default/xui/en/panel_profile_interests.xml deleted file mode 100644 index 0359b0bc4bb2d20dfd1d0fe9af33cee94304890e..0000000000000000000000000000000000000000 --- a/indra/newview/skins/default/xui/en/panel_profile_interests.xml +++ /dev/null @@ -1,250 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<panel - name="panel_profile_interests" - label="Interests" - top="0" - left="0" - height="480" - width="420" - follows="all" - layout="topleft" -> - <loading_indicator - name="progress_indicator" - top="5" - right="-10" - height="23" - width="23" - follows="top|right" - layout="topleft" - visible="false" - /> - <text - name="I Want To:" - top="10" - left="4" - height="16" - width="70" - follows="left|top" - layout="topleft" - halign="right" - > - I Want To: - </text> - <check_box - name="chk0" - label="Build" - enabled="false" - top_delta="0" - left="75" - height="16" - width="90" - follows="left|top" - layout="topleft" - /> - <check_box - name="chk1" - label="Explore" - enabled="false" - left_pad="80" - height="16" - width="90" - follows="left|top" - layout="topleft" - /> - <check_box - name="chk2" - label="Meet" - enabled="false" - top_pad="5" - left="75" - height="16" - width="90" - follows="left|top" - layout="topleft" - /> - <check_box - name="chk6" - label="Be Hired" - enabled="false" - left_pad="80" - height="16" - width="90" - follows="left|top" - layout="topleft" - /> - <check_box - name="chk3" - label="Group" - enabled="false" - top_pad="5" - left="75" - height="16" - width="90" - follows="left|top" - layout="topleft" - /> - <check_box - name="chk4" - label="Buy" - enabled="false" - left_pad="80" - height="16" - width="90" - follows="left|top" - layout="topleft" - /> - <check_box - name="chk5" - label="Sell" - enabled="false" - top_pad="5" - left="75" - height="16" - width="90" - follows="left|top" - layout="topleft" - /> - <check_box - name="chk7" - label="Hire" - enabled="false" - left_pad="80" - height="16" - width="90" - follows="left|top" - layout="topleft" - /> - <line_editor - name="want_to_edit" - enabled="false" - top_pad="10" - left="76" - height="18" - width="330" - follows="left|top|right" - layout="topleft" - text_pad_left="4" - max_length_bytes="254" - > - (loading...) - </line_editor> - - <text - name="Skills:" - top_pad="20" - left="4" - height="16" - width="70" - follows="left|top" - layout="topleft" - halign="right" - > - Skills: - </text> - <check_box - name="schk0" - label="Textures" - enabled="false" - top_delta="0" - left="75" - height="16" - width="90" - follows="left|top" - layout="topleft" - /> - <check_box - name="schk1" - label="Architecture" - enabled="false" - left_pad="80" - height="16" - width="90" - follows="left|top" - layout="topleft" - /> - <!-- The next two are out of order on purpose due to legacy ordering --> - <check_box - name="schk3" - label="Modeling" - enabled="false" - top_pad="5" - left="75" - height="16" - width="90" - follows="left|top" - layout="topleft" - /> - <check_box - name="schk2" - label="Event Planning" - enabled="false" - left_pad="80" - height="16" - width="90" - follows="left|top" - layout="topleft" - /> - <check_box - name="schk4" - label="Scripting" - enabled="false" - top_pad="5" - left="75" - height="16" - width="90" - follows="left|top" - layout="topleft" - /> - <check_box - name="schk5" - label="Custom Characters" - enabled="false" - left_pad="80" - height="16" - width="90" - follows="left|top" - layout="topleft" - /> - <line_editor - name="skills_edit" - enabled="false" - top_pad="10" - left="76" - height="18" - width="330" - follows="left|top|right" - layout="topleft" - text_pad_left="4" - max_length_bytes="254" - > - (loading...) - </line_editor> - - <text - name="Languages:" - top_pad="20" - left="4" - height="16" - width="70" - follows="left|top" - layout="topleft" - halign="right" - > - Languages: - </text> - <line_editor - name="languages_edit" - enabled="false" - top_delta="-1" - left="76" - height="18" - width="330" - follows="left|top|right" - layout="topleft" - text_pad_left="4" - max_length_bytes="254" - > - (loading...) - </line_editor> -</panel> diff --git a/indra/newview/skins/default/xui/en/panel_profile_notes.xml b/indra/newview/skins/default/xui/en/panel_profile_notes.xml index 179fa0136caeb8ec945a6185630ff668af1280f7..16e7365042b05baba529f2cb8c6920049418534a 100644 --- a/indra/newview/skins/default/xui/en/panel_profile_notes.xml +++ b/indra/newview/skins/default/xui/en/panel_profile_notes.xml @@ -9,14 +9,6 @@ follows="all" layout="topleft" > - <!--these strings will be combined into one with different styles--> - <string name="header_symbol_limit"> -Warning: Your notes contain more than 1000 characters. - </string> - <string name="body_symbol_limit"> -Only first 1000 characters are shown here. If you edit your notes and click OK, the extra characters will be lost. To preserve the extra characters, you must edit it [[PROFILE_URL] on the web] - </string> - <loading_indicator name="progress_indicator" top="3" @@ -29,7 +21,7 @@ Only first 1000 characters are shown here. If you edit your notes and click OK, /> <text name="status_message" - value="Private notes on this avatar:" + value="Make notes about this person here. No one else can see your notes." top="6" left="6" right="-6" @@ -41,66 +33,33 @@ Only first 1000 characters are shown here. If you edit your notes and click OK, <text_editor name="notes_edit" enabled="false" - top_pad="4" + top="28" left="6" right="-6" - height="311" + bottom="-26" follows="all" layout="topleft" - max_length="1000" + max_length="65530" word_wrap="true" /> - <text - layout="topleft" - follows="left|bottom|right" - top_pad="2" - left="6" - right="-6" - height ="28" - name="character_limit_warning" - word_wrap="true"> - Placeholder: Your notes contain more than 1000 characters. Only first 1000 characters are shown here. If you edit your notes and click OK, the extra characters will be lost. To preserve the extra characters, you must edit it [https://my.secondlife.com/settings/profile on the web] - </text> - <text - name="status_message2" - value="Allow this avatar to:" - top_pad="11" - left="6" - right="-6" - height="16" - follows="left|bottom|right" - layout="topleft" - font.style="BOLD" - /> - <check_box - name="status_check" - label="See when I am online" + <button + name="notes_save_changes" + label="Save" + bottom="-1" + right="-108" + height="20" + width="80" enabled="false" - top_pad="0" - left="10" - height="16" - width="293" - follows="left|bottom|right" - layout="topleft" - /> - <check_box - name="map_check" - label="Find me on the world map" - enabled="false" - left="10" - height="16" - width="293" - follows="left|bottom|right" - layout="topleft" - /> - <check_box - name="objects_check" - label="Edit, delete or take my objects" + follows="bottom|right" + layout="topleft"/> + <button + name="notes_discard_changes" + label="Discard" + bottom="-1" + right="-4" + height="20" + width="100" enabled="false" - left="10" - height="16" - width="293" - follows="left|bottom|right" - layout="topleft" - /> + follows="bottom|right" + layout="topleft"/> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_profile_pick.xml b/indra/newview/skins/default/xui/en/panel_profile_pick.xml index 0417df43c9d6f638f72d0b5a3f661690e070e51c..3e91640093855a3785f3b6ec6477a90d7e3f5d48 100644 --- a/indra/newview/skins/default/xui/en/panel_profile_pick.xml +++ b/indra/newview/skins/default/xui/en/panel_profile_pick.xml @@ -14,98 +14,301 @@ > (will update after save) </panel.string> - <texture_picker - name="pick_snapshot" - top="10" - left="10" - height="180" - width="290" - follows="left|top" - layout="topleft" - fallback_image="default_land_picture.j2c" - /> - <line_editor - name="pick_name" - enabled="false" - top_pad="-15" - left="10" - height="20" - width="290" - follows="left|right|top" - layout="topleft" - /> - <text_editor - name="pick_desc" - trusted_content="false" - always_show_icons="true" - enabled="false" - top_pad="8" - left="10" - height="70" - width="290" + + <layout_stack + name="main_pick_stack" + left="1" + right="-1" + top="0" + bottom="-1" + follows="all" + layout="topleft" + orientation="vertical" + animate="false"> + <layout_panel follows="all" - layout="topleft" - allow_html="true" - border_visible="true" - h_pad="4" - max_length="1023" - v_pad="3" - word_wrap="true" - /> - <line_editor - name="pick_location" - enabled="false" - left="10" - height="20" - width="290" - follows="left|right|bottom" - layout="topleft" - length="1" - type="string" - > - Loading... - </line_editor> - <button - name="teleport_btn" - label="Teleport" - bottom="-40" - left="10" - height="20" - width="80" - follows="left|bottom" - layout="topleft" - /> - <button - name="show_on_map_btn" - label="Show on Map" - bottom_delta="0" - left_pad="5" - height="20" - width="100" - follows="left|bottom" - layout="topleft" - /> - <button - name="set_to_curr_location_btn" - label="Set Location" - tool_tip="Set to Current Location" - bottom_delta="0" - left_pad="5" - height="20" - width="100" - follows="left|bottom" - layout="topleft" - visible="false" - /> - <button - name="save_changes_btn" - label="Save Pick" - bottom="-15" - left="10" - height="20" - width="100" - follows="left|bottom" - layout="topleft" - visible="false" - /> + layout="bottomleft" + left_pad="2" + name="main_pick_lp" + auto_resize="true" + height="314"> + <texture_picker + name="pick_snapshot" + top="10" + left="10" + height="161" + width="260" + follows="left|top" + layout="topleft" + fallback_image="default_land_picture.j2c" + /> + <text + name="title_label" + top_pad="-15" + left="10" + height="15" + width="280" + follows="left|top" + layout="topleft" + font="SansSerifSmall" + font.style="BOLD" + length="1" + text_color="white" + type="string" + > + Title: + </text> + <line_editor + name="pick_name" + enabled="false" + top_pad="2" + left="10" + height="20" + width="290" + follows="left|right|top" + layout="topleft" + /> + <text + name="description_label" + top_pad="10" + left="10" + height="15" + width="280" + follows="left|top" + layout="topleft" + font="SansSerifSmall" + font.style="BOLD" + length="1" + text_color="white" + type="string" + > + Description: + </text> + <text_editor + name="pick_desc" + trusted_content="false" + always_show_icons="true" + enabled="false" + top_pad="2" + left="10" + height="45" + width="290" + follows="all" + layout="topleft" + allow_html="true" + border_visible="true" + h_pad="4" + max_length="1023" + v_pad="3" + word_wrap="true" + /> + <text + name="location_label" + bottom="-25" + left="10" + height="15" + width="280" + follows="left|right|bottom" + layout="topleft" + font="SansSerifSmall" + font.style="BOLD" + length="1" + text_color="white" + type="string" + > + Location: + </text> + <line_editor + name="pick_location" + enabled="false" + bottom="-1" + left="10" + height="23" + width="290" + follows="left|right|bottom" + layout="topleft" + length="1" + type="string" + > + Loading... + </line_editor> + </layout_panel> + + + <layout_panel + follows="all" + layout="bottomleft" + name="save_changes_lp" + auto_resize="false" + height="25"> + <layout_stack + name="save_changes_stack" + left="1" + right="-1" + top="0" + height="25" + follows="left|top|right" + layout="topleft" + orientation="horizontal" + animate="false"> + + <layout_panel + follows="all" + layout="topleft" + name="util_resizer_left" + auto_resize="true" + width="1"> + </layout_panel> + + <layout_panel + follows="all" + layout="bottomleft" + left_pad="2" + name="map_btn_lp" + auto_resize="false" + width="100"> + <button + name="show_on_map_btn" + label="Show on Map" + left="0" + top="0" + height="23" + width="100" + follows="left|top" + layout="topleft" + /> + </layout_panel> + + <layout_panel + follows="all" + layout="bottomleft" + left_pad="2" + name="tp_btn_lp" + auto_resize="false" + width="100"> + <button + name="teleport_btn" + label="Teleport" + left="0" + top="0" + height="23" + width="100" + follows="left|top" + layout="topleft" + /> + </layout_panel> + + <layout_panel + follows="all" + layout="topleft" + name="util_resizer_right" + auto_resize="true" + width="1"> + </layout_panel> + + </layout_stack> + </layout_panel> + + <layout_panel + follows="all" + layout="bottomleft" + name="save_changes_lp" + auto_resize="false" + height="41"> + <view_border + bevel_style="none" + height="0" + follows="left|top|right" + layout="topleft" + left="0" + name="save_emphasis_border" + top="5" + width="310"/> + <layout_stack + name="save_changes_stack" + left="1" + right="-1" + top="11" + height="25" + follows="left|top|right" + layout="topleft" + orientation="horizontal" + animate="false"> + + <layout_panel + follows="all" + layout="topleft" + name="save_resizer_left" + auto_resize="true" + width="1"> + </layout_panel> + + <layout_panel + follows="all" + layout="bottomleft" + left_pad="2" + name="create_btn_lp" + auto_resize="false" + width="130"> + <button + name="create_changes_btn" + label="Create Pick" + left="0" + top="0" + height="23" + width="130" + follows="left|top" + layout="topleft" + /> + </layout_panel> + + <layout_panel + follows="all" + layout="bottomleft" + left_pad="2" + name="save_btn_lp" + auto_resize="false" + width="130"> + <button + name="save_changes_btn" + label="Save Pick" + left="0" + top="0" + height="23" + width="130" + follows="left|top" + layout="topleft" + /> + </layout_panel> + + <layout_panel + follows="all" + layout="bottomleft" + left_pad="2" + name="cancel_btn_lp" + auto_resize="false" + width="130"> + <button + name="cancel_changes_btn" + label="Cancel" + left="0" + top="0" + height="23" + width="130" + follows="left|top" + layout="topleft" + /> + </layout_panel> + + <layout_panel + follows="all" + layout="topleft" + name="save_resizer_right" + auto_resize="true" + width="1"> + </layout_panel> + + </layout_stack> + </layout_panel> + </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_profile_picks.xml b/indra/newview/skins/default/xui/en/panel_profile_picks.xml index efa0e38e39a2f9b3cc38bcc5c42caf2e179b047e..77c85f4233aea5ad76443814e7aea60a86a446f4 100644 --- a/indra/newview/skins/default/xui/en/panel_profile_picks.xml +++ b/indra/newview/skins/default/xui/en/panel_profile_picks.xml @@ -13,77 +13,142 @@ name="no_picks" value="No Picks" /> - <loading_indicator - name="progress_indicator" - top="20" - right="-10" - height="23" - width="23" - follows="top|right" - layout="topleft" - visible="false" - /> - <text - name="Tell everyone about your favorite places in [CURRENT_GRID]." - top="5" - left="5" - right="-5" - height="16" - follows="left|top|right" + + <layout_stack + name="main_stack" + top="0" + left="0" + right="-1" + bottom="-1" + follows="all" + layout="topleft" + animate="false" + orientation="vertical"> + <layout_panel + name="buttons_header" + follows="all" layout="topleft" - halign="center" + height="50" + auto_resize="false" + user_resize="false"> + <text + name="header_text" + top="5" + left="5" + right="-5" + height="16" + follows="left|top|right" + layout="topleft" + halign="center" > - Tell everyone about your favorite places in [CURRENT_GRID]. - </text> - <button - name="new_btn" - label="New..." - tool_tip="Create a new pick at the current location" - enabled="false" - top_pad="4" - left="5" - height="20" - width="70" - follows="left|top" - layout="topleft" - visible="false" + Tell everyone about your favorite places in [CURRENT_GRID]. + </text> + <button + name="new_btn" + label="New..." + tool_tip="Create a new pick at the current location" + enabled="false" + top_pad="4" + left="5" + height="20" + width="70" + follows="left|top" + layout="topleft" + visible="false" /> - <button - name="delete_btn" - label="Delete..." - tool_tip="Delete currently selected pick" - enabled="false" - left_pad="5" - height="20" - width="70" - follows="left|top" - layout="topleft" - visible="false" + <button + name="delete_btn" + label="Delete..." + tool_tip="Delete currently selected pick" + enabled="false" + left_pad="5" + height="20" + width="70" + follows="left|top" + layout="topleft" + visible="false" /> - <tab_container - name="tab_picks" - top="50" - bottom="-5" - left="4" - right="-4" + </layout_panel> + <layout_panel + name="main_body" follows="all" layout="topleft" - halign="left" - tab_position="left" - use_ellipses="true" + height="430" + auto_resize="true" + user_resize="false"> + <tab_container + name="tab_picks" + top="0" + bottom="-5" + left="4" + right="-4" + tab_width="150" + follows="all" + layout="topleft" + halign="left" + tab_position="left" + use_ellipses="true" /> - <text - name="picks_panel_text" - top="300" - left="110" - right="-110" - height="25" - follows="left|top|right" + + <layout_stack + name="indicator_stack" + top="220" + left="0" + right="-1" + height="28" + follows="top|left|right" layout="topleft" - halign="center" - mouse_opaque="false" - wrap="true" + animate="false" + orientation="horizontal"> + <layout_panel + name="indicator_spacer_left" + follows="all" + layout="topleft" + width="100" + auto_resize="true" + user_resize="false"> + </layout_panel> + <layout_panel + name="buttons_header" + follows="all" + layout="topleft" + width="25" + auto_resize="false" + user_resize="false"> + <loading_indicator + name="progress_indicator" + top="1" + left="1" + height="23" + width="23" + follows="top|left" + layout="topleft" + visible="false" + /> + </layout_panel> + <layout_panel + name="indicator_spacer_right" + follows="all" + layout="topleft" + width="100" + auto_resize="true" + user_resize="false"> + </layout_panel> + </layout_stack> + <text + name="picks_panel_text" + top="250" + left="100" + right="-100" + height="25" + follows="left|top|right" + layout="topleft" + halign="center" + mouse_opaque="false" + wrap="true" > Loading... - </text> + </text> + </layout_panel> + </layout_stack> </panel> 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 9d6ec3e279fd3c6e4330452c16aabd758e51e059..551b4778762a98af802aab0183462caf5684a1be 100644 --- a/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml +++ b/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml @@ -9,552 +9,541 @@ follows="all" layout="topleft" > - <string - name="status_online" - > - Currently Online - </string> - <string - name="status_offline" - > - Currently Offline - </string> - <string - name="CaptionTextAcctInfo" - > - [ACCTTYPE] + <string + name="date_format" + value="SL birthdate: [mth,datetime,slt] [day,datetime,slt], [year,datetime,slt]" /> + <string + name="age_format" + value="[AGE]" /> + <string + name="partner_text" + value="Partner: [LINK]" /> + <string + name="CaptionTextAcctInfo"> +Account: [ACCTTYPE] [PAYMENTINFO] </string> - <string - name="payment_update_link_url" - > - http://www.secondlife.com/account/billing.php?lang=en - </string> - <string - name="partner_edit_link_url" - > - http://www.secondlife.com/account/partners.php?lang=en - </string> - <string - name="my_account_link_url" - value="http://secondlife.com/account" - /> - <string - name="no_partner_text" - value="None" - /> - <string - name="no_group_text" - value="None" - /> - <string - name="RegisterDateFormat" - > - [REG_DATE] - </string> - <string - name="name_text_args" - > - [NAME] - </string> - <string - name="display_name_text_args" - > - [DISPLAY_NAME] - </string> - <string - name="FSDev" - value=" Developer" - /> - <string - name="FSSupp" - value=" Support" - /> - <string - name="FSQualityAssurance" - value=" Bug Hunter" - /> - <string - name="FSGW" - value=" Gateway" - /> - <loading_indicator - name="progress_indicator" - top="4" - right="-10" - height="23" - width="23" - follows="top|right" - layout="topleft" - visible="false" - /> - <text - name="name_label" - value="Name:" - top="8" - left="6" - height="20" - width="55" - follows="left|top" - layout="topleft" - halign="right" - /> - <button - name="set_name" - label="Name:" - tool_tip="Set Display Name" - enabled="false" - top_delta="0" - left_delta="0" - height="20" - width="55" - follows="top|left" + + <layout_stack + name="image_stack" + top="8" + left="6" + bottom="-1" + width="160" + border_size="0" + follows="left|top|bottom" + layout="topleft" + animate="false" + orientation="vertical"> + <layout_panel + name="image_panel" + follows="all" layout="topleft" - visible="false" - /> - <panel - name="name_holder" - top_delta="0" - left_pad="4" - right="-5" - height="20" - follows="left|top|right" + width="160" + height="160" + auto_resize="false" + user_resize="false"> + + <icon + name="2nd_life_pic" + image_name="Generic_Person_Large" + layout="topleft" + follows="all" + interactable="true" + top="0" + left="2" + bottom="-1" + right="-1"/> + + <loading_indicator + name="image_upload_indicator" + top="69" + left="69" + height="23" + width="23" + follows="top|left" + layout="topleft" + visible="false"/> + </layout_panel> + + <layout_panel + name="basics_panel" + follows="all" layout="topleft" - allow_scroll="false" - bg_visible="false" - border_visible="false"> - <text_editor - name="complete_name" + height="54" + auto_resize="false" + user_resize="false" + > + <line_editor + name="user_name" + border_thickness="0" + use_bg_color="false" + background_image_disabled="" + background_image_focused="" + enabled="false" value="(loading...)" + top="4" + left="3" + right="-1" + height="16" + follows="left|top|right" + layout="topleft"/> + + <line_editor + name="sl_birth_date" + border_thickness="0" + use_bg_color="false" + background_image_disabled="" + background_image_focused="" enabled="false" + value="(loading...)" + top_pad="0" + left_delta="0" + right="-1" + height="16" + follows="left|top|right" + layout="topleft"/> + + <line_editor + name="user_age" + border_thickness="0" + use_bg_color="false" + background_image_disabled="" + background_image_focused="" + enabled="false" + value="(loading...)" + top_pad="0" + left_delta="0" + right="-1" + height="16" + follows="left|top|right" + layout="topleft"/> + </layout_panel> + <layout_panel + name="partner_layout" + follows="all" + layout="topleft" + height="30" + auto_resize="false" + user_resize="false" + visible="true"> + <text + type="string" + name="partner_link" + value="Partner: (loading...)" top="0" - left="0" + left="5" right="-1" - height="20" + height="28" follows="left|top|right" layout="topleft" - allow_scroll="false" - bg_visible="false" - border_visible="true" - h_pad="1" - v_pad="4" - max_length="254" - /> - <!--mouse_opaque="true"--> - <menu_button - name="copy_btn" - tool_tip="Copy options" + translate="false" + use_ellipses="true" + word_wrap="true" + visible="true"/> + </layout_panel> + + <layout_panel + name="partner_spacer_layout" + follows="all" + layout="topleft" + height="14" + auto_resize="false" + user_resize="false" + visible="true"> + </layout_panel> + + <layout_panel + name="frind_layout" + follows="all" + layout="topleft" + height="16" + auto_resize="false" + user_resize="false" + visible="false"> + <text + name="frind_text" + value="You are friends" + text_color="ConversationFriendColor" + top="0" + left="5" + right="-1" height="16" - right="-2" - top="2" - width="16" - image_selected="Copy" - image_unselected="Copy" - image_hover_selected="CopyBright" - image_hover_unselected="CopyBright" - hover_glow_amount="0.33" - chrome="true" - tab_stop="false" - follows="top|right" - layout="topleft" /> - </panel> - <layout_stack - name="imagepositioner" - top_pad="6" - left_delta="0" - right="-1" - height="158" - follows="top|left|right" + follows="left|top|right" + layout="topleft" + translate="false" + visible="true"/> + </layout_panel> + <layout_panel + name="online_layout" + follows="all" + layout="topleft" + height="16" + auto_resize="false" + user_resize="false" + visible="false"> + <icon + name="online_icon" + image_name="Profile_Friend_Online" + layout="topleft" + follows="left|top" + top="0" + left="5" + height="10" + width="10"/> + <text + name="online_text" + value="Online" + top="0" + left="18" + right="-1" + height="16" + follows="left|top|right" + layout="topleft" + translate="false" + visible="true"/> + </layout_panel> + <layout_panel + name="offline_layout" + follows="all" layout="topleft" - orientation="horizontal" - > - <layout_panel - name="image_stack" - follows="all" - layout="topleft" - width="158" - height="158" - auto_resize="false" - user_resize="false" - > - <!-- 23 pixels (BTN_HEIGHT_SMALL) are reserved by label field of texture and shouldn't be visible--> - <texture_picker - name="2nd_life_pic" - top="0" - left="0" - right="-1" - height="180" - follows="all" - layout="topleft" - allow_no_texture="true" - default_image_name="None" - fallback_image="Generic_Person_Large" - /> - </layout_panel> - <layout_panel - name="label_stack" - follows="all" - layout="topleft" - auto_resize="true" - user_resize="false" - > - <text - name="status" - value="Status Unknown" - top="1" - left="4" - right="-6" - height="16" - follows="top|left" - layout="topleft" - halign="center" - text_color="LtGray_50" - /> - <text - name="label" - value="[CURRENT_GRID] Birthdate:" - top_pad="2" - right="-6" - height="16" - follows="top|left" - layout="topleft" - /> - <text_editor - name="register_date" - value="(loading...)" - top_pad="0" - left_delta="2" - right="-6" - height="16" - follows="top|left|right" - layout="topleft" - allow_scroll="false" - bg_visible="false" - border_visible="true" - h_pad="2" - max_length="254" - read_only="true" - translate="false" - v_pad="2" - word_wrap="true" - /> - <text - name="label2" - value="Account:" - top_pad="5" - left_delta="-2" - right="-6" - height="16" - follows="top|left" - layout="topleft" - /> - <text_editor - name="acc_status_text" - top_pad="0" - left_delta="2" - right="-6" - height="44" - follows="top|left|right" - layout="topleft" - allow_scroll="false" - bg_visible="false" - border_visible="true" - h_pad="2" - read_only="true" - translate="false" - v_pad="2" - word_wrap="true" - /> - <text - name="partner_label" - value="Partner:" - top_pad="5" - left_delta="-2" - right="-6" - height="16" - follows="top|left" - layout="topleft" - /> - <text_editor - name="partner_text" - top_pad="0" - left_delta="0" - right="-6" - height="20" - follows="top|left|right" - layout="topleft" - allow_scroll="false" - bg_visible="false" - border_visible="true" - parse_urls="true" - h_pad="1" - read_only="true" - translate="false" - v_pad="4" - max_length="254" - /> - </layout_panel> - </layout_stack> - <text - name="Groups:" - value="Groups:" - top_pad="7" - left="6" height="16" - width="55" - follows="left|top" + auto_resize="false" + user_resize="false" + visible="false"> + <icon + name="offline_icon" + image_name="Profile_Friend_Offline" + layout="topleft" + follows="left|top" + top="0" + left="5" + height="10" + width="10"/> + <text + name="offline_text" + value="Offline" + top="0" + left="18" + right="-1" + height="16" + follows="left|top|right" + layout="topleft" + translate="false" + visible="true"/> + </layout_panel> + <layout_panel + name="account_layout" + follows="all" layout="topleft" - halign="right" - /> - <button - name="group_invite" - label="+" - tool_tip="Invite to Group" - top_delta="20" - left="40" - height="20" - width="20" - follows="left|top" + height="33" + auto_resize="false" + user_resize="false"> + <text + name="account_info" + value="Account: (loading...)" + top="0" + left="5" + right="-1" + height="16" + follows="left|top|right" + layout="topleft" + word_wrap="true"/> + </layout_panel> + <layout_panel + name="indicator_stack" + follows="all" layout="topleft" - label_selected="+" - /> - <group_list - name="group_list" - top_delta="-20" - left="66" - right="-7" - height="82" - follows="left|top|right" + height="33" + auto_resize="false" + user_resize="false"> + <loading_indicator + name="progress_indicator" + left="67" + top="0" + height="23" + width="23" + follows="left|top" + layout="topleft" + visible="true"/> + </layout_panel> + <layout_panel + name="settings_panel" + follows="all" layout="topleft" - border_visible="true" - color="ScrollBgWriteableColor" - for_agent="false" - /> + height="50" + auto_resize="false" + user_resize="false"> + <!-- only for self --> + <text + name="search_label" + value="Show my profile in search:" + top="1" + left="6" + right="-1" + height="16" + follows="left|top|right" + layout="topleft"/> + <combo_box + name="show_in_search" + tool_tip="Let people see you in search results" + left="1" + top="18" + height="23" + width="140" + follows="left|top" + layout="topleft" + visible="true" + enabled="false"> + <combo_box.item + name="Hide" + label="Hide" + value="0" /> + <combo_box.item + name="Show" + label="Show" + value="1" /> + </combo_box> + </layout_panel> + + <layout_panel + name="menu_panel" + follows="all" + layout="topleft" + height="55" + auto_resize="false" + user_resize="false" + > + <menu_button + layout="topleft" + follows="left|top" + left="1" + top="25" + height="25" + width="140" + label="Actions" + halign="left" + image_unselected="DropDown_Off" + image_selected="DropDown_On" + image_pressed="DropDown_Press" + image_pressed_selected="DropDown_Press" + image_disabled="DropDown_Disabled" + name="agent_actions_menu" /> + </layout_panel> + </layout_stack> + + <layout_stack + name="main_stack" + top="8" + left="168" + bottom="-1" + right="-1" + follows="all" + layout="topleft" + animate="false" + orientation="vertical"> + <layout_panel + name="display_name_panel" + follows="all" + layout="topleft" + height="24" + auto_resize="false" + user_resize="false"> + <line_editor + name="display_name" + border_thickness="0" + use_bg_color="false" + background_image_disabled="" + background_image_focused="" + enabled="false" + value="(loading...)" + font="SansSerifBigLarge" + top="0" + left="6" + height="19" + right="-86" + follows="left|top|right" + layout="topleft"/> + + <icon + tool_tip="Friend can see my online status" + mouse_opaque="true" + name="can_see_online" + image_name="Profile_Perm_Online_Enabled" + layout="topleft" + follows="right|top" + interactable="true" + top="0" + right="-61" + height="24" + width="24" + left_pad="2" /> + + <icon + tool_tip="Friend can not see my online status" + mouse_opaque="true" + name="cant_see_online" + image_name="Profile_Perm_Online_Disabled" + layout="topleft" + follows="right|top" + interactable="true" + top="0" + right="-61" + height="24" + width="24" + left_pad="2" /> - <layout_stack - name="aboutpositioner" - top_pad="7" - left="6" - right="-6" - height="130" + <icon + tool_tip="Friend can see me on map" + mouse_opaque="true" + name="can_see_on_map" + image_name="Profile_Perm_Find_Enabled" + layout="topleft" + follows="right|top" + interactable="true" + top="0" + right="-30" + height="24" + width="24" + left_pad="2" /> + + <icon + tool_tip="Friend can not see me on map" + mouse_opaque="true" + name="cant_see_on_map" + image_name="Profile_Perm_Find_Disabled" + layout="topleft" + follows="right|top" + interactable="true" + top="0" + right="-30" + height="24" + width="24" + left_pad="2" /> + + <icon + tool_tip="Friend can edit my objects" + mouse_opaque="true" + name="can_edit_objects" + image_name="Profile_Perm_Objects_Enabled" + layout="topleft" + follows="right|top" + interactable="true" + top="0" + right="-1" + height="24" + width="24" + left_pad="2" /> + + <icon + tool_tip="Friend can not edit my objects" + mouse_opaque="true" + name="cant_edit_objects" + image_name="Profile_Perm_Objects_Disabled" + layout="topleft" + follows="right|top" + interactable="true" + top="0" + right="-1" + height="24" + width="24" + left_pad="2" /> + + </layout_panel> + + <layout_panel + name="about_panel" follows="all" layout="topleft" - orientation="vertical" - > - <layout_panel - name="about_stack" + height="159" + auto_resize="true" + user_resize="false"> + <text_editor + name="sl_description_edit" + trusted_content="false" + always_show_icons="true" + commit_on_focus_lost="false" + enabled="false" + top="0" + left="2" + right="-1" + bottom="-1" follows="all" layout="topleft" - left="0" - height="105" - auto_resize="true" - user_resize="false"> - <text - name="About:" - value="About:" - top="1" - left="0" - height="16" - width="55" - follows="left|top" - layout="topleft" - halign="right" + bg_readonly_color="Transparent" + border_visible="true" + font="SansSerifSmall" + h_pad="2" + max_length="65000" + parse_urls="true" + word_wrap="true" /> - <text_editor - name="sl_description_edit" - trusted_content="false" - always_show_icons="true" + </layout_panel> + <layout_panel + name="about_buttons_panel" + follows="all" + layout="topleft" + height="34" + auto_resize="false" + user_resize="false"> + <button + name="save_description_changes" + label="Save" + top="1" + right="-105" + height="20" + width="80" enabled="false" - top="0" - left="60" + follows="top|right" + layout="topleft"/> + <button + name="discard_description_changes" + label="Discard" + top="1" right="-1" - bottom="-1" - follows="all" - layout="topleft" - bg_readonly_color="Transparent" - border_visible="true" - font="SansSerifSmall" - h_pad="2" - max_length="510" - parse_urls="true" - word_wrap="true" - /> - </layout_panel> - <layout_panel - name="give_stack" - follows="left|bottom" - layout="topleft" - left="0" - height="24" - auto_resize="false" - user_resize="false"> - <text - name="Give item:" - value="Give item:" - top="6" - left="0" - height="16" - width="55" - follows="left|bottom" - layout="topleft" - halign="right" - /> + height="20" + width="100" + enabled="false" + follows="top|right" + layout="topleft"/> <view_border - name="drop_target_rect_vis" - top_delta="0" - left="60" - right="-1" - height="16" - follows="left|bottom|right" - layout="topleft" - bevel_style="in" - /> - <text - name="Give inventory" - tool_tip="Drop inventory items here to give them to this person." - top_delta="0" - left="60" - right="-1" - height="16" - follows="left|bottom|right" - layout="topleft" - halign="center" - > - Drop inventory item here. - </text> - </layout_panel> - </layout_stack> - <layout_stack - name="buttonstack" - bottom="-3" - left="6" - right="-6" - height="44" - follows="left|bottom|right" - layout="topleft" - orientation="horizontal" - > - <layout_panel - name="left_buttonstack" - left="2" - right="-2" - height="42" - follows="all" - layout="topleft" - user_resize="false" - > - <button - name="show_on_map_btn" - label="Find on Map" - tool_tip="Locate the Resident on the map" - top="2" - left="2" - height="20" - follows="left|top|right" - layout="topleft" - label_selected="Find on Map" - /> - <button - name="pay" - label="Pay" - tool_tip="Pay money to the Resident" - top_pad="2" - height="20" - follows="left|top|right" - layout="topleft" - label_selected="Pay" - /> - </layout_panel> - <layout_panel - name="middle_buttonstack" - left="2" - right="-2" - follows="all" + bevel_style="none" + height="0" layout="topleft" - user_resize="false" - > - <button - name="teleport" - label="Offer Teleport" - tool_tip="Offer a teleport to the Resident" - top="2" - left="2" - height="20" - follows="left|top|right" - layout="topleft" - label_selected="Offer Teleport" - /> - <button - name="im" - label="Instant Message" - tool_tip="Open instant message session" - top_pad="2" - height="20" - follows="left|top|right" - layout="topleft" - label_selected="Instant Message" - /> - </layout_panel> - <layout_panel - name="right_buttonstack" - left="2" - right="-2" - follows="all" - layout="topleft" - user_resize="false" - > - <button - name="add_friend" - label="Add Friend" - tool_tip="Offer friendship to the Resident" - top="2" - left="2" - height="20" - follows="left|top|right" - layout="topleft" - label_selected="Add Friend" - /> - <button - name="block" - label="Block" - tool_tip="Block this Resident" - top_pad="2" - height="20" - follows="left|top|right" - layout="topleft" - /> - <button - name="unblock" - label="Unblock" - tool_tip="Unblock this Resident" - top_delta="0" - height="20" - follows="left|top|right" - layout="topleft" - /> - </layout_panel> - </layout_stack> - <check_box - name="show_in_search_checkbox" - label="Show in search" - tool_tip="Let people see you in search results" - enabled="false" - bottom="-30" - left="60" - height="16" - width="130" - follows="left|bottom" - layout="topleft" - visible="false" - /> - <profile_drop_target - name="drop_target" - top="0" - bottom="-1" - left="0" - right="-1" + left="0" + name="cost_text_border" + top_pad="9" + width="492"/> + </layout_panel> + + <layout_panel + name="groups_panel" follows="all" layout="topleft" - mouse_opaque="false" - /> + height="159" + auto_resize="true" + user_resize="false"> + <text + name="group_label" + value="Group memberships" + top="1" + left="2" + right="-1" + height="16" + follows="left|top|right" + layout="topleft"/> + <group_list + name="group_list" + top="18" + left="2" + right="-1" + bottom="-1" + follows="all" + layout="topleft" + border_visible="true" + color="ScrollBgWriteableColor" + for_agent="false"/> + + </layout_panel> + </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_status_bar.xml b/indra/newview/skins/default/xui/en/panel_status_bar.xml index 93fdced3cc3f586dfe1861f20735190d9708bc21..9f37ff066aa6cb4a38f707d306535374869c6c3f 100644 --- a/indra/newview/skins/default/xui/en/panel_status_bar.xml +++ b/indra/newview/skins/default/xui/en/panel_status_bar.xml @@ -11,7 +11,6 @@ mouse_opaque="false" name="status" top="19" - tab_stop="false" width="1000"> <panel.string name="packet_loss_tooltip"> diff --git a/indra/newview/skins/default/xui/en/panel_tools_texture.xml b/indra/newview/skins/default/xui/en/panel_tools_texture.xml index 90f32ae4526b85e238b745cb279abbb6cf8f2c64..c7052bb7371e93bdd9240bc2bdb0acb606079f9c 100644 --- a/indra/newview/skins/default/xui/en/panel_tools_texture.xml +++ b/indra/newview/skins/default/xui/en/panel_tools_texture.xml @@ -11,6 +11,36 @@ name="Texture" top="0" width="295"> + <panel.string + name="paste_error_face_selection_mismatch"> + When multiple faces are copied, the target object must have the same number of faces selected. + </panel.string> + <panel.string + name="paste_error_object_face_count_mismatch"> + When all faces of an object are copied, the target object must have the same number of faces. + </panel.string> + <panel.string + name="paste_error_inventory_not_found"> + One or more texture not found in inventory. + </panel.string> + <panel.string + name="paste_options"> + Paste options + </panel.string> + + <menu_button + menu_filename="menu_copy_paste_color.xml" + follows="top|left" + height="15" + image_disabled="ClipboardMenu_Disabled" + image_selected="ClipboardMenu_Press" + image_unselected="ClipboardMenu_Off" + layout="topleft" + left="258" + top="8" + name="clipboard_color_params_btn" + tool_tip="Paste options" + width="22"/> <text type="string" length="1" @@ -36,7 +66,7 @@ name="colorswatch" tool_tip="Click to open color picker" top="20" - width="64" /> + width="54" /> <text type="string" length="1" @@ -84,7 +114,7 @@ left_delta="0" name="glow" top_pad="4" - width="80" /> + width="77" /> <check_box height="19" label="Full Bright" @@ -93,13 +123,22 @@ name="checkbox fullbright" top_pad="4" width="81" /> + <view_border + bevel_style="none" + follows="top|left" + height="0" + layout="topleft" + left="8" + name="object_horizontal" + top_pad="4" + width="278" /> <combo_box height="23" layout="topleft" left="10" name="combobox matmedia" - top_pad="5" - width="100"> + top_pad="17" + width="90"> <combo_box.item label="Materials" name="Materials" @@ -113,7 +152,7 @@ control_name="ComboMaterialType" height="50" layout="topleft" - left_pad="20" + left_pad="5" top_delta="-10" width="150" visible = "false" @@ -139,7 +178,20 @@ layout="topleft" top_pad="1" value="2"/> - </radio_group> + </radio_group> + <menu_button + menu_filename="menu_copy_paste_texture.xml" + follows="top|left" + height="15" + image_disabled="ClipboardMenu_Disabled" + image_selected="ClipboardMenu_Press" + image_unselected="ClipboardMenu_Off" + layout="topleft" + left="258" + top_delta="0" + name="clipboard_texture_params_btn" + tool_tip="Paste options" + width="22"/> <check_box control_name="SyncMaterialSettings" follows="top|left" @@ -150,7 +202,7 @@ left="8" name="checkbox_sync_settings" tool_tip="Adjust all maps repeats simultaneously" - top_pad="-16" + top_pad="19" width="160" /> <texture_picker can_apply_immediately="true" @@ -498,10 +550,7 @@ top_pad="4" tool_tip="Add Media" label="Choose..." - width="85"> - <button.commit_callback - function="BuildTool.AddMedia"/> - </button> + width="85"/> <button follows="top|left" height="18" @@ -511,10 +560,7 @@ tool_tip="Delete this media texture" top_delta="0" label="Remove" - width="85"> - <button.commit_callback - function="BuildTool.DeleteMedia"/> - </button> + width="85"/> <button follows="left|top" height="18" @@ -771,14 +817,14 @@ top_delta="16" width="260" /> <button - left="10" - top="222" + follows="left|top" + layout="topleft" + left="9" + top="204" height="20" label="Align" label_selected="Align current texture layers" - layout="topleft" name="button align textures" - top_delta="0" tool_tip="Align current texture layers" width="66" /> <web_browser diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index d261ce670a3d56b3119c7df5cee9378faeaa1252..3229a9dcd1fe5457c77d86df9bc1aefcd0944e48 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -86,6 +86,7 @@ Voice Server Version: [VOICE_VERSION] </string> <string name="AboutTraffic">Packets Lost: [PACKETS_LOST,number,0]/[PACKETS_IN,number,0] ([PACKETS_PCT,number,1]%)</string> <string name="AboutTime">[month, datetime, slt] [day, datetime, slt] [year, datetime, slt] [hour, datetime, slt]:[min, datetime, slt]:[second,datetime,slt]</string> + <string name="LocalTime">[month, datetime, local] [day, datetime, local] [year, datetime, local] [hour, datetime, local]:[min, datetime, local]:[second,datetime, local]</string> <string name="ErrorFetchingServerReleaseNotesURL">Error fetching server release notes URL.</string> <string name="BuildConfiguration">Build Configuration</string> @@ -128,7 +129,7 @@ Voice Server Version: [VOICE_VERSION] <string name="CertAllocationFailure">Failed to allocate openssl memory for certificate.</string> <string name="LoginFailedNoNetwork">Network error: Could not establish connection, please check your network connection.</string> - <string name="LoginFailed">Login failed.</string> + <string name="LoginFailedHeader">Login failed.</string> <string name="Quit">Quit</string> <string name="AgniGridLabel">Second Life Main Grid (Agni)</string> @@ -138,6 +139,8 @@ Voice Server Version: [VOICE_VERSION] <string name="LoginFailedViewerNotPermitted"> The viewer you are using can no longer access [CURRENT_GRID]. Please visit the following page to download a new viewer: https://www.alchemyviewer.org/pages/downloads.html</string> + <string name="LoginFailed">Grid emergency login failure. +If you feel this is an error, please contact support.</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. @@ -161,15 +164,18 @@ Logins are currently restricted to [GRID_ADMIN] employees only.</string> People with free accounts will not be able to access [CURRENT_GRID] during this time, to make room for those who have paid for [CURRENT_GRID].</string> <string name="LoginFailedComputerProhibited">[CURRENT_GRID] cannot be accessed from this computer. If you feel this is an error, please contact support.</string> + <!--'Pacific time' placeholder for [TIME] in case time from server can't be decoded--> + <string name="PacificTime">Pacific Time</string> <string name="LoginFailedAcountSuspended">Your account is not accessible until -[TIME] Pacific Time.</string> +[TIME]. +If you feel this is an error, please contact support.</string> <string name="LoginFailedAccountDisabled">We are unable to complete your request at this time. Please contact [CURRENT_GRID] support for assistance.</string> <string name="LoginFailedTransformError">Data inconsistency found during login. Please contact [CURRENT_GRID] support.</string> <string name="LoginFailedAccountMaintenance">Your account is undergoing minor maintenance. Your account is not accessible until -[TIME] Pacific Time. +[TIME]. If you feel this is an error, please contact [CURRENT_GRID] support.</string> <string name="LoginFailedPendingLogoutFault">Request for logout responded with a fault from simulator.</string> <string name="LoginFailedPendingLogout">The system is logging you out right now. @@ -351,8 +357,6 @@ can be attached to notecards. <!-- Group name: text shown for LLUUID::null --> <string name="GroupNameNone">(none)</string> - <string name="AvalineCaller">Avaline Caller [ORDER]</string> - <!-- Asset errors. Used in llassetstorage.cpp, translation from error code to error message. --> <string name="AssetErrorNone">No error</string> <string name="AssetErrorRequestFailed">Asset request: failed</string> @@ -2346,6 +2350,14 @@ The [[MARKETPLACE_CREATE_STORE_URL] Marketplace store] is returning errors. </string> <string name="InventoryMarketplaceError"> An error occurred while opening Marketplace Listings. +If you continue to receive this message, please contact Second Life support for assistance at http://support.secondlife.com + </string> + <string name="InventoryMarketplaceConnectionError"> +Marketplace Listings failed to connect. +If you continue to receive this message, please contact Second Life support for assistance at http://support.secondlife.com + </string> + <string name="InventoryMarketplaceConnectionErrorReason"> +Marketplace Listings failed to connect. Reason: [REASON] If you continue to receive this message, please contact Second Life support for assistance at http://support.secondlife.com </string> <string name="InventoryMarketplaceListingsNoItemsTitle">Your Marketplace Listings folder is empty.</string> @@ -2825,8 +2837,8 @@ If you continue to receive this message, please contact Second Life support for <string name="NoPicksText">You haven't created any Picks. Click the New button to create a Pick.</string> <string name="NoClassifiedsText">You haven't created any Classifieds. Click the New button to create a Classified.</string> <string name="NoAvatarPicksClassifiedsText">User has no picks or classifieds</string> - <string name="NoAvatarPicksText">User has no picks</string> - <string name="NoAvatarClassifiedsText">User has no classifieds</string> + <string name="NoAvatarPicksText">This person has no picks</string> + <string name="NoAvatarClassifiedsText">This person has no classifieds</string> <string name="PicksClassifiedsLoadingText">Loading...</string> <!-- Multi Preview Floater --> @@ -3992,7 +4004,7 @@ Please check http://status.secondlifegrid.net to see if there is a known problem <!-- SL Membership --> <string name="BaseMembership">Base</string> <string name="PremiumMembership">Premium</string> - <string name="Premium PlusMembership">Premium Plus</string> + <string name="Premium_PlusMembership">Premium Plus</string> <string name="InternalMembership">Internal</string> <!-- No need to translate --> <string name="MembershipUpgradeText">Upgrade to Premium</string> diff --git a/indra/newview/skins/default/xui/es/floater_about.xml b/indra/newview/skins/default/xui/es/floater_about.xml index 8f143cf072ec2527bca0f75ce899f9626d83b171..f59f534908a50853753b3dd5f1ed5ba30b3627ec 100644 --- a/indra/newview/skins/default/xui/es/floater_about.xml +++ b/indra/newview/skins/default/xui/es/floater_about.xml @@ -19,7 +19,6 @@ con contribuciones de código abierto de:</text> expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd. FreeType Copyright (C) 1996-2002, 2006 David Turner, Robert Wilhelm y Werner Lemberg. GL Copyright (C) 1999-2004 Brian Paul. - GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University y David Luebke, Brenden Schubert, University of Virginia. google-perftools Copyright (c) 2005, Google Inc. Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited. jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW) diff --git a/indra/newview/skins/default/xui/es/panel_region_terrain.xml b/indra/newview/skins/default/xui/es/panel_region_terrain.xml index cb6c03dbb5fa2f6d67c2fbabf4838d0883115844..9aba5299cbf1d15fdd170c781676b17cdd4fcfef 100644 --- a/indra/newview/skins/default/xui/es/panel_region_terrain.xml +++ b/indra/newview/skins/default/xui/es/panel_region_terrain.xml @@ -12,8 +12,8 @@ del terreno" name="terrain_raise_spin"/> <spinner bottom_delta="-34" label="LÃmite de bajada del terreno" name="terrain_lower_spin"/> <text name="detail_texture_text"> - Texturas del terreno (requiere archivos .tga de 512x512, 24 bits) - </text> + Texturas del terreno (requiere archivos .tga de 1024x1024, 24 bits) + </text> <text name="height_text_lbl"> 1 (bajo) </text> diff --git a/indra/newview/skins/default/xui/es/strings.xml b/indra/newview/skins/default/xui/es/strings.xml index 4cdb8b004fc65e425e3954a7d7eb0122fa5f1756..ff2afd48467754a8834a47089265aeeaa21edf82 100644 --- a/indra/newview/skins/default/xui/es/strings.xml +++ b/indra/newview/skins/default/xui/es/strings.xml @@ -178,7 +178,7 @@ Versión del servidor de voz: [VOICE_VERSION] <string name="LoginFailedNoNetwork"> Error de red: no se ha podido conectar; por favor, revisa tu conexión a internet. </string> - <string name="LoginFailed"> + <string name="LoginFailedHeader"> Error en el inicio de sesión. </string> <string name="Quit"> @@ -680,9 +680,6 @@ pueden adjuntarse a las notas. <string name="GroupNameNone"> (ninguno) </string> - <string name="AvalineCaller"> - Avaline: [ORDER] - </string> <string name="AssetErrorNone"> No hay ningún error </string> diff --git a/indra/newview/skins/default/xui/fr/floater_about.xml b/indra/newview/skins/default/xui/fr/floater_about.xml index 1e2a14ab3e2030042a1c7bd66f239c23e39fb873..df6b61e293adfdd340aa8ef02db7aa54a66310e4 100644 --- a/indra/newview/skins/default/xui/fr/floater_about.xml +++ b/indra/newview/skins/default/xui/fr/floater_about.xml @@ -19,7 +19,6 @@ avec les contributions Open Source de :</text> expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd. FreeType Copyright (C) 1996-2002, 2006 David Turner, Robert Wilhelm et Werner Lemberg. GL Copyright (C) 1999-2004 Brian Paul. - GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University, et David Luebke, Brenden Schubert, University of Virginia. google-perftools Copyright (c) 2005, Google Inc. Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited. jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW) diff --git a/indra/newview/skins/default/xui/fr/panel_region_terrain.xml b/indra/newview/skins/default/xui/fr/panel_region_terrain.xml index 97f486d3a3dd0969abe776f12a0c67d7d9c80b0e..bbab00ca24643f3a8f462f8e9fdcd8987796cbaa 100644 --- a/indra/newview/skins/default/xui/fr/panel_region_terrain.xml +++ b/indra/newview/skins/default/xui/fr/panel_region_terrain.xml @@ -12,8 +12,8 @@ terrain" name="terrain_raise_spin"/> <spinner bottom_delta="-34" label="Limite d'abaissement du terrain" name="terrain_lower_spin"/> <text name="detail_texture_text"> - Textures du terrain (fichiers .tga 512 x 512, 24 bit requis) - </text> + Textures du terrain (fichiers .tga 1024 x 1024, 24 bit requis) + </text> <text name="height_text_lbl"> 1 (Bas) </text> diff --git a/indra/newview/skins/default/xui/fr/strings.xml b/indra/newview/skins/default/xui/fr/strings.xml index 266dd1646536463f31bbb201be2a385254cb81dd..20f7f491930669ef0281bf4cb56bcaa63bcfeb86 100644 --- a/indra/newview/skins/default/xui/fr/strings.xml +++ b/indra/newview/skins/default/xui/fr/strings.xml @@ -187,7 +187,7 @@ Voice Server Version: [VOICE_VERSION] <string name="LoginFailedNoNetwork"> Erreur réseau : impossible d'établir la connexion. Veuillez vérifier votre connexion réseau. </string> - <string name="LoginFailed"> + <string name="LoginFailedHeader"> Échec de la connexion. </string> <string name="Quit"> @@ -692,9 +692,6 @@ peuvent être joints aux notes. <string name="GroupNameNone"> (aucun) </string> - <string name="AvalineCaller"> - Appelant Avaline [ORDER] - </string> <string name="AssetErrorNone"> Aucune erreur </string> @@ -5135,7 +5132,7 @@ Veuillez vous reporter à http://status.secondlifegrid.net afin de déterminer s <string name="PremiumMembership"> Premium </string> - <string name="Premium PlusMembership"> + <string name="Premium_PlusMembership"> Premium Plus </string> <string name="DeleteItems"> diff --git a/indra/newview/skins/default/xui/it/floater_about.xml b/indra/newview/skins/default/xui/it/floater_about.xml index 9603238b66b0edf127272552ed851611c454b430..edb334e13ee83ed56959be173743a2de8f9fe579 100644 --- a/indra/newview/skins/default/xui/it/floater_about.xml +++ b/indra/newview/skins/default/xui/it/floater_about.xml @@ -19,7 +19,6 @@ con contributi open source da:</text> expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd. FreeType Copyright (C) 1996-2002, 2006 David Turner, Robert Wilhelm e Werner Lemberg. GL Copyright (C) 1999-2004 Brian Paul. - GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University e David Luebke, Brenden Schubert, University of Virginia. google-perftools Copyright (c) 2005, Google Inc. Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited. jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW) diff --git a/indra/newview/skins/default/xui/it/panel_region_terrain.xml b/indra/newview/skins/default/xui/it/panel_region_terrain.xml index c61ac3eccecac77b4a9433210d33498e9293c366..e08c55f63bb767bf59afe07759902b8e7a5cbd41 100644 --- a/indra/newview/skins/default/xui/it/panel_region_terrain.xml +++ b/indra/newview/skins/default/xui/it/panel_region_terrain.xml @@ -12,8 +12,8 @@ terreno" name="terrain_raise_spin"/> <spinner bottom_delta="-34" label="Limite di abbassamento del terreno" name="terrain_lower_spin"/> <text name="detail_texture_text"> - Texture terreno (richiede file 512x512, 24 bit .tga) - </text> + Texture terreno (richiede file 1024x1024, 24 bit .tga) + </text> <text name="height_text_lbl"> 1 (basso) </text> diff --git a/indra/newview/skins/default/xui/it/strings.xml b/indra/newview/skins/default/xui/it/strings.xml index 2dc4c2a2db85fdd1d34f8afb48a3c40af15cca9c..d05bc63f15e98fa622d6e549c6c24e1dae39155c 100644 --- a/indra/newview/skins/default/xui/it/strings.xml +++ b/indra/newview/skins/default/xui/it/strings.xml @@ -183,7 +183,7 @@ Versione server voce: [VOICE_VERSION] <string name="LoginFailedNoNetwork"> Errore di rete: Non è stato possibile stabilire un collegamento, controlla la tua connessione. </string> - <string name="LoginFailed"> + <string name="LoginFailedHeader"> Accesso non riuscito. </string> <string name="Quit"> @@ -685,9 +685,6 @@ possono essere allegati ai biglietti. <string name="GroupNameNone"> (nessuno) </string> - <string name="AvalineCaller"> - Chiamante Avaline [ORDER] - </string> <string name="AssetErrorNone"> Nessun errore </string> @@ -5050,7 +5047,7 @@ Consulta la pagina http://status.secondlifegrid.net per determinare se il proble <string name="PremiumMembership"> Premium </string> - <string name="Premium PlusMembership"> + <string name="Premium_PlusMembership"> Premium Plus </string> <string name="DeleteItems"> diff --git a/indra/newview/skins/default/xui/ja/floater_about.xml b/indra/newview/skins/default/xui/ja/floater_about.xml index cf5e97bd8d12bebe414ebdbcc196710a40a37828..6a39d057e21e32aa904cd872608a2f826a073327 100644 --- a/indra/newview/skins/default/xui/ja/floater_about.xml +++ b/indra/newview/skins/default/xui/ja/floater_about.xml @@ -19,7 +19,6 @@ DBus/dbus-glib Copyright (C) 2002, 2003 CodeFactory AB / Copyright (C) 2003, 20 expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd. FreeType Copyright (C) 1996-2002, 2006 David Turner, Robert Wilhelm, and Werner Lemberg. GL Copyright (C) 1999-2004 Brian Paul. -GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University and David Luebke, Brenden Schubert, University of Virginia. google-perftools Copyright (c) 2005, Google Inc. Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited. jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW) diff --git a/indra/newview/skins/default/xui/ja/panel_region_terrain.xml b/indra/newview/skins/default/xui/ja/panel_region_terrain.xml index fb853c1925cd73f043dc941339b29ab5a96fb4cf..c1080a7d7b6d6cb931df67bbd1af952e18b635f6 100644 --- a/indra/newview/skins/default/xui/ja/panel_region_terrain.xml +++ b/indra/newview/skins/default/xui/ja/panel_region_terrain.xml @@ -10,8 +10,8 @@ <spinner label="地形ã®ä¸Šæ˜‡é™åº¦" name="terrain_raise_spin"/> <spinner label="地形ã®ä¸‹é™é™åº¦" name="terrain_lower_spin"/> <text name="detail_texture_text"> - 地形テクスãƒãƒ£ï¼ˆ512x512 ã® 24 bit .tga ファイル) - </text> + 地形テクスãƒãƒ£ï¼ˆ1024x1024 ã® 24 bit .tga ファイル) + </text> <text name="height_text_lbl"> 1(低) </text> diff --git a/indra/newview/skins/default/xui/ja/strings.xml b/indra/newview/skins/default/xui/ja/strings.xml index edbd5bf1e53a46f8b9093fe676900743a9586588..f00546bf575a80db4fb9cd8cca76b331b19a53fb 100644 --- a/indra/newview/skins/default/xui/ja/strings.xml +++ b/indra/newview/skins/default/xui/ja/strings.xml @@ -186,7 +186,7 @@ LOD ä¿‚æ•°: [LOD_FACTOR] <string name="LoginFailedNoNetwork"> ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã‚¨ãƒ©ãƒ¼ï¼šæŽ¥ç¶šã‚’確立ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ãŠä½¿ã„ã®ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯æŽ¥ç¶šã‚’ã”確èªãã ã•ã„。 </string> - <string name="LoginFailed"> + <string name="LoginFailedHeader"> ãƒã‚°ã‚¤ãƒ³ã«å¤±æ•—ã—ã¾ã—ãŸã€‚ </string> <string name="Quit"> @@ -691,9 +691,6 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。 <string name="GroupNameNone"> (ãªã—) </string> - <string name="AvalineCaller"> - Avaline コール [ORDER] - </string> <string name="AssetErrorNone"> エラーãªã— </string> @@ -5133,7 +5130,7 @@ www.secondlife.com ã‹ã‚‰æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンãƒãƒ¼ãƒ‰ã—ã¦ãã <string name="PremiumMembership"> プレミアム</string> - <string name="Premium PlusMembership"> + <string name="Premium_PlusMembership"> プレミアムプラス </string> <string name="DeleteItems"> diff --git a/indra/newview/skins/default/xui/pl/panel_region_terrain.xml b/indra/newview/skins/default/xui/pl/panel_region_terrain.xml index f086a52dcd49f5f3c7495e061c33ff8389f1750f..2d4286334f3c51c6d360048e73fa3343820532ba 100644 --- a/indra/newview/skins/default/xui/pl/panel_region_terrain.xml +++ b/indra/newview/skins/default/xui/pl/panel_region_terrain.xml @@ -7,7 +7,7 @@ <spinner label="Górny limit terenu" name="terrain_raise_spin" /> <spinner label="Dolny limit terenu" name="terrain_lower_spin" /> <text name="detail_texture_text"> - Tekstury terenu (512x512 / 1024x1024, 24 bitowy plik .tga) + Tekstury terenu (1024x1024, 24 bitowy plik .tga) </text> <text name="height_text_lbl"> 1 (Nisko) diff --git a/indra/newview/skins/default/xui/pl/strings.xml b/indra/newview/skins/default/xui/pl/strings.xml index 5ae15967650989f64e166bc0d802934356a6e94a..ed670ce0a6c8e4342066400ff9011fea13caf08b 100644 --- a/indra/newview/skins/default/xui/pl/strings.xml +++ b/indra/newview/skins/default/xui/pl/strings.xml @@ -143,7 +143,7 @@ Wersja serwera gÅ‚osu (Voice Server): [VOICE_VERSION] <string name="LoginFailedNoNetwork"> Błąd sieci: Brak połączenia z sieciÄ…, sprawdź status swojego połączenia internetowego. </string> - <string name="LoginFailed"> + <string name="LoginFailedHeader"> Logowanie nie powiodÅ‚o siÄ™. </string> <string name="Quit"> @@ -596,9 +596,6 @@ Spróbuj zalogować siÄ™ ponownie za minutÄ™. <string name="GroupNameNone"> (brak danych) </string> - <string name="AvalineCaller"> - Avaline [ORDER] - </string> <string name="AssetErrorNone"> Brak błędu </string> diff --git a/indra/newview/skins/default/xui/pt/floater_about.xml b/indra/newview/skins/default/xui/pt/floater_about.xml index 65c457f822c067360373a909b462c8e91fff3398..3c0ca332ace3f5c90f24f36a603c90b9c358d2a5 100644 --- a/indra/newview/skins/default/xui/pt/floater_about.xml +++ b/indra/newview/skins/default/xui/pt/floater_about.xml @@ -19,7 +19,6 @@ com contribuições de código aberto de:</text> expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd. FreeType Copyright (C) 1996-2002, 2006 David Turner, Robert Wilhelm, and Werner Lemberg. GL Copyright (C) 1999-2004 Brian Paul. - GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University e David Luebke, Brenden Schubert, University of Virginia. google-perftools Copyright (c) 2005, Google Inc. Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited. jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW) diff --git a/indra/newview/skins/default/xui/pt/panel_region_terrain.xml b/indra/newview/skins/default/xui/pt/panel_region_terrain.xml index 74330a8946ee626584c145054261954f84acb626..1d312aeed94624045c39a3b86bb728362fbb1ad9 100644 --- a/indra/newview/skins/default/xui/pt/panel_region_terrain.xml +++ b/indra/newview/skins/default/xui/pt/panel_region_terrain.xml @@ -12,8 +12,8 @@ terreno" name="terrain_raise_spin"/> <spinner bottom_delta="-34" label="Limite mais baixo do terreno" name="terrain_lower_spin"/> <text name="detail_texture_text"> - Texturas de terreno (exige arquivos .tga 512x512, 24 bit) - </text> + Texturas de terreno (exige arquivos .tga 1024x1024, 24 bit) + </text> <text name="height_text_lbl"> 1 (Baixo) </text> diff --git a/indra/newview/skins/default/xui/pt/strings.xml b/indra/newview/skins/default/xui/pt/strings.xml index d95e6b55eacc360c15853a97ee92735e57b79571..9b541adbd34517f4fb3afe71368a4a0be6b77688 100644 --- a/indra/newview/skins/default/xui/pt/strings.xml +++ b/indra/newview/skins/default/xui/pt/strings.xml @@ -47,7 +47,7 @@ Placa de vÃdeo: [GRAPHICS_CARD_VENDOR] Placa gráfica: [GRAPHICS_CARD] </string> <string name="AboutDriver"> - Versão do driver de vÃdeo Windows: [GRAPHICS_CARD_VENDOR] + Versão do driver de vÃdeo Windows: [GRAPHICS_DRIVER_VERSION] </string> <string name="AboutOGL"> Versão do OpenGL: [OPENGL_VERSION] @@ -178,7 +178,7 @@ Versão do servidor de voz: [VOICE_VERSION] <string name="LoginFailedNoNetwork"> Erro de rede: Falha de conexão: verifique sua conexão à internet. </string> - <string name="LoginFailed"> + <string name="LoginFailedHeader"> Falha do login. </string> <string name="Quit"> @@ -645,9 +645,6 @@ ser anexado à s anotações. <string name="GroupNameNone"> (nenhum) </string> - <string name="AvalineCaller"> - Interlocutor Avaline [ORDER] - </string> <string name="AssetErrorNone"> Nenhum erro </string> diff --git a/indra/newview/skins/default/xui/ru/floater_about.xml b/indra/newview/skins/default/xui/ru/floater_about.xml index ee9f82847d10856766b00020e4297383edfd7485..44216e04306fb6034b3a20ed3397813a1b1141ed 100644 --- a/indra/newview/skins/default/xui/ru/floater_about.xml +++ b/indra/newview/skins/default/xui/ru/floater_about.xml @@ -19,7 +19,6 @@ expat (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd. FreeType (C) 1996-2002, 2006 David Turner, Robert Wilhelm и Werner Lemberg. GL (C) 1999-2004 Brian Paul. - GLOD (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, УниверÑитет Джона ГопкинÑа и David Luebke, Brenden Schubert, УниверÑитет Вирджинии. google-perftools (c) 2005, Google Inc. Havok.com(TM) (C) 1999-2001, Telekinesys Research Limited. jpeg2000 (C) 2001, David Taubman, УниверÑитет Ðового Южного УÑльÑа (UNSW) diff --git a/indra/newview/skins/default/xui/ru/panel_navigation_bar.xml b/indra/newview/skins/default/xui/ru/panel_navigation_bar.xml index 5e3de180f92c589fa951e1902f13455482e8e295..331ba889d87a66657ea3dbb13e7fdace03ccaa1b 100644 --- a/indra/newview/skins/default/xui/ru/panel_navigation_bar.xml +++ b/indra/newview/skins/default/xui/ru/panel_navigation_bar.xml @@ -14,7 +14,7 @@ <label name="favorites_bar_label" tool_tip="ПеретаÑкивайте Ñюда закладки, чтобы было удобнее переходить в любимые меÑта в Second Life!"> Избранное </label> - <more_button name=">>" tool_tip="Показать больше избранного"> + <more_button name=">>" tool_tip="Показать больше избранного" width="60"> Больше â–¼ </more_button> </favorites_bar> diff --git a/indra/newview/skins/default/xui/ru/panel_region_terrain.xml b/indra/newview/skins/default/xui/ru/panel_region_terrain.xml index af255652263855b21d710d6a215912e0b1a5cdf1..76b4f513a85a394d1dc66f15a66735c0e467430b 100644 --- a/indra/newview/skins/default/xui/ru/panel_region_terrain.xml +++ b/indra/newview/skins/default/xui/ru/panel_region_terrain.xml @@ -10,8 +10,8 @@ <spinner label="Верх. точка ландшафта" name="terrain_raise_spin"/> <spinner label="Ðиж. точка ландшафта" name="terrain_lower_spin"/> <text name="detail_texture_text"> - ТекÑтуры ландшафта (требованиÑ: 512x512, 24-битные, TGA) - </text> + ТекÑтуры ландшафта (требованиÑ: 1024x1024, 24-битные, TGA) + </text> <text name="height_text_lbl"> 1 (Ðиз) </text> diff --git a/indra/newview/skins/default/xui/ru/strings.xml b/indra/newview/skins/default/xui/ru/strings.xml index 85df6be4e842cfc110dca0a721bff3e189da5c1f..492972479e4d8e834cde926f98ca3a50ce1e3804 100644 --- a/indra/newview/skins/default/xui/ru/strings.xml +++ b/indra/newview/skins/default/xui/ru/strings.xml @@ -187,7 +187,7 @@ SLURL: <nolink>[SLURL]</nolink> <string name="LoginFailedNoNetwork"> Ошибка Ñети: не удалоÑÑŒ уÑтановить Ñоединение. Проверьте подключение к Ñети. </string> - <string name="LoginFailed"> + <string name="LoginFailedHeader"> Ошибка входа. </string> <string name="Quit"> @@ -689,9 +689,6 @@ support@secondlife.com. <string name="GroupNameNone"> (нет) </string> - <string name="AvalineCaller"> - [ORDER] абонента Avaline - </string> <string name="AssetErrorNone"> Ошибок нет </string> @@ -5129,7 +5126,7 @@ support@secondlife.com. <string name="PremiumMembership"> Премиум </string> - <string name="Premium PlusMembership"> + <string name="Premium_PlusMembership"> Премиум ÐŸÐ»ÑŽÑ </string> <string name="DeleteItems"> diff --git a/indra/newview/skins/default/xui/tr/floater_about.xml b/indra/newview/skins/default/xui/tr/floater_about.xml index b91575954b3dc01b12c853b36b4a7aaae0e54233..faa504a996060c27aaee2f6f5134cd5d415c56fa 100644 --- a/indra/newview/skins/default/xui/tr/floater_about.xml +++ b/indra/newview/skins/default/xui/tr/floater_about.xml @@ -19,7 +19,6 @@ açık kaynak kod katkısında bulunanlar ÅŸunlardır:</text> expat Telif Hakkı (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd. FreeType Telif Hakkı (C) 1996-2002, 2006 David Turner, Robert Wilhelm ve Werner Lemberg. GL Telif Hakkı (C) 1999-2004 Brian Paul. - GLOD Telif Hakkı (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University ve David Luebke, Brenden Schubert, University of Virginia. google-perftools Telif Hakkı (c) 2005, Google Inc. Havok.com(TM) Telif Hakkı (C) 1999-2001, Telekinesys Research Limited. jpeg2000 Telif Hakkı (C) 2001, David Taubman, The University of New South Wales (UNSW) diff --git a/indra/newview/skins/default/xui/tr/panel_navigation_bar.xml b/indra/newview/skins/default/xui/tr/panel_navigation_bar.xml index 8d43e3fb5a26afd0f5e1d78accce0fbb08f06ec5..ae9bc33bfa7e3f17ea8f826effc1b4076cf931fc 100644 --- a/indra/newview/skins/default/xui/tr/panel_navigation_bar.xml +++ b/indra/newview/skins/default/xui/tr/panel_navigation_bar.xml @@ -14,7 +14,7 @@ <label name="favorites_bar_label" tool_tip="Second Life içerisinde sık kullandığınız yerlere hızla eriÅŸmek için Yer İmlerini buraya sürükleyin!"> Favoriler ÇubuÄŸu </label> - <more_button name=">>" tool_tip="Favorilerimden daha çok göster"> + <more_button name=">>" tool_tip="Favorilerimden daha çok göster" width="65"> Daha Fazla â–¼ </more_button> </favorites_bar> diff --git a/indra/newview/skins/default/xui/tr/panel_region_terrain.xml b/indra/newview/skins/default/xui/tr/panel_region_terrain.xml index 3226ee008e70635ca0ab4072b4c9c91d7cac040e..e25047301d729417306db8eb162732bca0078bea 100644 --- a/indra/newview/skins/default/xui/tr/panel_region_terrain.xml +++ b/indra/newview/skins/default/xui/tr/panel_region_terrain.xml @@ -10,8 +10,8 @@ <spinner label="Yüzey Yükslt. Limiti" name="terrain_raise_spin"/> <spinner label="Yüzey Alçatma Limiti" name="terrain_lower_spin"/> <text name="detail_texture_text"> - Yüzey Dokuları (512x512, 24 bit .tga dosyalar gerektirir) - </text> + Yüzey Dokuları (1024x1024, 24 bit .tga dosyalar gerektirir) + </text> <text name="height_text_lbl"> 1 (Düşük) </text> diff --git a/indra/newview/skins/default/xui/tr/strings.xml b/indra/newview/skins/default/xui/tr/strings.xml index 21614679c3d3d18c313e4ca3eb3c6dc68e23c490..d598df72f86cc1fd8ff0a234f88f4735e3789d63 100644 --- a/indra/newview/skins/default/xui/tr/strings.xml +++ b/indra/newview/skins/default/xui/tr/strings.xml @@ -187,7 +187,7 @@ Ses Sunucusu Sürümü: [VOICE_VERSION] <string name="LoginFailedNoNetwork"> AÄŸ hatası: BaÄŸlantı kurulamadı, lütfen aÄŸ baÄŸlantınızı kontrol edin. </string> - <string name="LoginFailed"> + <string name="LoginFailedHeader"> Oturum açılamadı. </string> <string name="Quit"> @@ -689,9 +689,6 @@ kartlarına eklenebilir. <string name="GroupNameNone"> (hiçbiri) </string> - <string name="AvalineCaller"> - Avaline Arayanı [ORDER] - </string> <string name="AssetErrorNone"> Hata yok </string> diff --git a/indra/newview/skins/default/xui/zh/floater_about.xml b/indra/newview/skins/default/xui/zh/floater_about.xml index 9f6b4421a9a6b993e1f4e084c44f92696caa6ce8..d7d2a52750fee21d68b72c0fb335676a392b144e 100644 --- a/indra/newview/skins/default/xui/zh/floater_about.xml +++ b/indra/newview/skins/default/xui/zh/floater_about.xml @@ -19,7 +19,6 @@ expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd. FreeType Copyright (C) 1996-2002, 2006 David Turner, Robert Wilhelm, and Werner Lemberg. GL Copyright (C) 1999-2004 Brian Paul. - GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University and David Luebke, Brenden Schubert, University of Virginia. google-perftools Copyright (c) 2005, Google Inc. Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited. jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW) diff --git a/indra/newview/skins/default/xui/zh/panel_region_terrain.xml b/indra/newview/skins/default/xui/zh/panel_region_terrain.xml index 85e759e445f99d947c93cbc5772589712e8b55b0..81bce4687681eb9cb757cd962497e84e77168580 100644 --- a/indra/newview/skins/default/xui/zh/panel_region_terrain.xml +++ b/indra/newview/skins/default/xui/zh/panel_region_terrain.xml @@ -10,7 +10,7 @@ <spinner label="地形æå‡é™åˆ¶" name="terrain_raise_spin"/> <spinner label="地形é™ä½Žé™åˆ¶" name="terrain_lower_spin"/> <text name="detail_texture_text"> - 地形æè³ªï¼ˆé ˆ 512x512,24 ä½å…ƒ .tga æª”æ ¼å¼ï¼‰ + 地形æè³ªï¼ˆé ˆ 1024x1024,24 ä½å…ƒ .tga æª”æ ¼å¼ï¼‰ </text> <text name="height_text_lbl"> 1(低) diff --git a/indra/newview/skins/default/xui/zh/strings.xml b/indra/newview/skins/default/xui/zh/strings.xml index 234c9e29813800972c9413d57a177069837e4670..d310a6172a981ff733f296b54317844730e1b590 100644 --- a/indra/newview/skins/default/xui/zh/strings.xml +++ b/indra/newview/skins/default/xui/zh/strings.xml @@ -187,7 +187,7 @@ LibVLC版本:[LIBVLC_VERSION]N] <string name="LoginFailedNoNetwork"> ç¶²è·¯éŒ¯èª¤ï¼šç„¡æ³•å»ºç«‹é€£ç·šï¼Œè«‹æª¢æŸ¥ç¶²è·¯é€£ç·šæ˜¯å¦æ£å¸¸ã€‚ </string> - <string name="LoginFailed"> + <string name="LoginFailedHeader"> 登入失敗。 </string> <string name="Quit"> @@ -685,9 +685,6 @@ http://secondlife.com/viewer-access-faq <string name="GroupNameNone"> (無) </string> - <string name="AvalineCaller"> - Avaline 通話者 [ORDER] - </string> <string name="AssetErrorNone"> 無錯誤 </string> diff --git a/indra/newview/tests/lllogininstance_test.cpp b/indra/newview/tests/lllogininstance_test.cpp index 4327352915d63c9080640f29bd5148de44bc8528..b3622193e0573bdf6bbdccd972d1d3d7e0cd1255 100644 --- a/indra/newview/tests/lllogininstance_test.cpp +++ b/indra/newview/tests/lllogininstance_test.cpp @@ -202,11 +202,6 @@ std::string LLGridManager::getGridId(const std::string& grid) const return std::string(); } -//LLPointer<LLSecAPIHandler> getSecHandler(const std::string& handler_type) -//{ -// return nullptr; -//} - //----------------------------------------------------------------------------- #include "../llviewercontrol.h" LLControlGroup gSavedSettings("Global"); @@ -239,6 +234,7 @@ bool llHashedUniqueID(unsigned char* id) #include "../llappviewer.h" void LLAppViewer::forceQuit(void) {} bool LLAppViewer::isUpdaterMissing() { return true; } +bool LLAppViewer::waitForUpdater() { return false; } LLAppViewer * LLAppViewer::sInstance = 0; //----------------------------------------------------------------------------- diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 48eb0952d6e83ca917cbc1d719e91e135fedcdbe..7db141e2b6c0578734ab675dcf02724ca264fc68 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -509,6 +509,18 @@ def construct(self): self.path("kdud.dll", "kdud.dll") else: self.path(src="kdu.dll", dst="kdu.dll") + + # These need to be installed as a SxS assembly, currently a 'private' assembly. + # See http://msdn.microsoft.com/en-us/library/ms235291(VS.80).aspx + self.path("concrt140.dll") + self.path("msvcp140.dll") + self.path("msvcp140_1.dll") + self.path("msvcp140_2.dll") + self.path("msvcp140_atomic_wait.dll") + self.path("msvcp140_codecvt_ids.dll") + self.path("vccorlib140.dll") + self.path("vcruntime140.dll") + self.path("vcruntime140_1.dll") # SLVoice executable with self.prefix(src=os.path.join(pkgdir, 'bin', 'release')): @@ -530,6 +542,7 @@ def construct(self): self.path(src="licenses-win32.txt", dst="licenses.txt") self.path("featuretable.txt") + self.path("cube.dae") with self.prefix(src=pkgdir): self.path("ca-bundle.crt") @@ -567,10 +580,7 @@ def construct(self): self.path("v8_context_snapshot.bin") self.path("vk_swiftshader_icd.json") - # CEF software renderer files - with self.prefix(src=os.path.join(pkgdir, 'bin', config, 'swiftshader'), dst='swiftshader'): - self.path("libEGL.dll") - self.path("libGLESv2.dll") + self.path_optional("vcruntime140_1.dll") # CEF files common to all configurations with self.prefix(src=os.path.join(pkgdir, 'resources')): @@ -893,6 +903,7 @@ def construct(self): self.path("licenses-mac.txt", dst="licenses.txt") self.path("featuretable_mac.txt") + self.path("cube.dae") with self.prefix(src=pkgdir,dst=""): self.path("ca-bundle.crt") @@ -1142,14 +1153,11 @@ def construct(self): self.path("resources.pak") self.path("icudtl.dat") - with self.prefix(src=os.path.join(pkgdir, 'lib', 'release', 'swiftshader'), dst=os.path.join('bin', 'llplugin', 'swiftshader') ): - self.path("libEGL.so") - self.path("libGLESv2.so") - with self.prefix(src=os.path.join(pkgdir, 'resources', 'locales'), dst=os.path.join('bin', 'llplugin', 'locales')): self.path("*.pak") self.path("featuretable_linux.txt") + self.path("cube.dae") with self.prefix(src=pkgdir, dst="app_settings"): self.path("ca-bundle.crt") diff --git a/indra/test/test.cpp b/indra/test/test.cpp index bed7de63f791baf58df7e41f331c9b6eda5282b4..1e9833c4b0adddb5c6507c627faac957557b3ab0 100644 --- a/indra/test/test.cpp +++ b/indra/test/test.cpp @@ -105,6 +105,7 @@ class RecordToTempFile : public LLError::Recorder, public boost::noncopyable virtual void recordMessage(LLError::ELevel level, const std::string& message) { + LL_PROFILE_ZONE_SCOPED mFile << message << std::endl; } diff --git a/indra/viewer_components/login/lllogin.cpp b/indra/viewer_components/login/lllogin.cpp index af04dfe6d2ef21ed01550bd33145425fc51b1f51..c18c557dcebca9683af7d4da322f3015fd9f1c7e 100644 --- a/indra/viewer_components/login/lllogin.cpp +++ b/indra/viewer_components/login/lllogin.cpp @@ -252,21 +252,25 @@ void LLLogin::Impl::loginCoro(std::string uri, LLSD login_params) if (printable_params["wait_for_updater"].asBoolean()) { std::string reason_response = responses["data"]["reason"].asString(); - if (reason_response == "update") // No point waiting if not an update + // Timeout should produce the isUndefined() object passed here. + if (reason_response == "update") { - // Timeout should produce the isUndefined() object passed here. LL_INFOS("LLLogin") << "Login failure, waiting for sync from updater" << LL_ENDL; updater = llcoro::suspendUntilEventOnWithTimeout(sSyncPoint, 10, LLSD()); - - if (updater.isUndefined()) - { - LL_WARNS("LLLogin") << "Failed to hear from updater, proceeding with fail.login" - << LL_ENDL; - } - else - { - LL_DEBUGS("LLLogin") << "Got responses from updater and login.cgi" << LL_ENDL; - } + } + else + { + LL_DEBUGS("LLLogin") << "Login failure, waiting for sync from updater" << LL_ENDL; + updater = llcoro::suspendUntilEventOnWithTimeout(sSyncPoint, 3, LLSD()); + } + if (updater.isUndefined()) + { + LL_WARNS("LLLogin") << "Failed to hear from updater, proceeding with fail.login" + << LL_ENDL; + } + else + { + LL_DEBUGS("LLLogin") << "Got responses from updater and login.cgi" << LL_ENDL; } } diff --git a/scripts/content_tools/anim_tool.py b/scripts/content_tools/anim_tool.py index e7b86a88fa07f76f17a532c0e80b11dea0f50b52..4a0773951ecb9dfdf635badfe11a3fbcf7fe48ab 100644 --- a/scripts/content_tools/anim_tool.py +++ b/scripts/content_tools/anim_tool.py @@ -611,6 +611,7 @@ def main(*argv): parser = argparse.ArgumentParser(description="process SL animations") parser.add_argument("--verbose", help="verbose flag", action="store_true") parser.add_argument("--dump", help="dump to stdout", action="store_true") + parser.add_argument("--use_aliases", help="use alias names for bones", action="store_true") parser.add_argument("--rot", help="specify sequence of rotations", type=float_triple, nargs="+") parser.add_argument("--rand_pos", help="request NUM random positions (default %(default)s)", metavar="NUM", type=int, default=2) @@ -637,6 +638,7 @@ def main(*argv): parser.add_argument("--no_hud", help="omit hud joints from list of attachments", action="store_true") parser.add_argument("--base_priority", help="set base priority", type=int) parser.add_argument("--joint_priority", help="set joint priority for all joints", type=int) + parser.add_argument("--force_joints", help="don't check validity of joint names", action="store_true") parser.add_argument("infilename", help="name of a .anim file to input") parser.add_argument("outfilename", nargs="?", help="name of a .anim file to output") args = parser.parse_args(argv) @@ -661,7 +663,12 @@ def main(*argv): if lad_tree is None: raise Error("failed to parse " + args.lad) if args.joints: - joints = resolve_joints(args.joints, skel_tree, lad_tree, args.no_hud) + if args.force_joints: + joints = args.joints + else: + joints = resolve_joints(args.joints, skel_tree, lad_tree, args.no_hud) + if args.use_aliases: + joints = map(lambda name: "avatar_" + name, joints) if args.verbose: print("joints resolved to",joints) for name in joints: diff --git a/scripts/content_tools/skel_tool.py b/scripts/content_tools/skel_tool.py index 449ecd6a6ce01ede5688b5b1d10e6d303150efb7..696e4e29238f030c143581df7ea02d1eaecaad71 100644 --- a/scripts/content_tools/skel_tool.py +++ b/scripts/content_tools/skel_tool.py @@ -72,6 +72,22 @@ def check_symmetry(name, field, vec1, vec2): if vec1[2] != vec2[2]: print(name,field,"z match fail") +def enforce_alias_rules(tree, element, fix=False): + if element.tag != "bone": + return + alias_lis = [] + aliases = element.get("aliases") + if aliases: + alias_lis = aliases.split(" ") + name = element.get("name") + if name: + std_alias = "avatar_" + name + if not std_alias in alias_lis: + print "missing expected alias",name,std_alias + for alias in alias_lis: + if alias.startswith("avatar_") and alias != std_alias: + print "invalid avatar_ alias",name,alias + def enforce_symmetry(tree, element, field, fix=False): name = element.get("name") if not name: @@ -209,6 +225,7 @@ def validate_skel_tree(tree, ogtree, reftree, fix=False): unfixable += 1 fix_name(element) + enforce_alias_rules(tree, element, fix) enforce_precision_rules(element) for field in ["pos","pivot"]: enforce_symmetry(tree, element, field, fix) diff --git a/scripts/perf/perfbot_run.py b/scripts/perf/perfbot_run.py new file mode 100644 index 0000000000000000000000000000000000000000..55ea2fae66dd9d25a33a336eca3718efbe6f592f --- /dev/null +++ b/scripts/perf/perfbot_run.py @@ -0,0 +1,204 @@ +#!/usr/bin/env python3 +"""\ +@file perfbot_run.py +@brief Run a number of non interactive Viewers (PerfBots) with + a variety of options and settings. Pass --help for details. + +$LicenseInfo:firstyear=2007&license=viewerlgpl$ +Second Life Viewer Source Code +Copyright (C) 2021, Linden Research, Inc. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; +version 2.1 of the License only. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +$/LicenseInfo$ +""" + +import argparse +import subprocess +import os +import math +import time + +# Required parameters that are always passed in +# Specify noninteractive mode (SL-15999 for details) +PARAM_NON_INTERACTIVE = "--noninteractive" +# Run multiple Viewers at once +PARAM_MULTI = "--multiple" +# Specify username (first and last) and password +PARAM_LOGIN = "--login" +# SLURL to teleport to after login +PARAM_SLURL = "--slurl" + + +def gen_niv_script(args): + print(f"Reading creds from {(args.creds)} folder") + print(f"Using the non interactive Viewer from {(args.viewer)}") + print(f"Sleeping for {args.sleep}ms between Viewer launches") + + # Read the lines from the creds file. Typically this will be + # stored in the build-secrets-git private repository but you + # can point to any location with the --creds parameter + creds_lines = [] + with open(args.creds) as file: + creds_lines = file.readlines() + creds_lines = [line.rstrip() for line in creds_lines] + creds_lines = [line for line in creds_lines if not line.startswith("#") and len(line)] + # We cannot log in more users than we have credentials for + if args.num==0: + args.num = len(creds_lines) + if args.num > len(creds_lines): + print( + f"The number of agents specified ({(args.num)}) exceeds " + f"the number of valid entries ({(len(creds_lines))}) in " + f"the creds file " + ) + return + + print(f"Launching {(args.num)} instances of the Viewer") + + # The Viewer (in dev environments at least) needs a well specified + # working directory to function properly. We try to guess what it + # might be based on the full path to the Viewer executable but + # you can also specify it explicitly with the --cwd parameter + # (required for dev builds) + args.viewer = os.path.abspath(args.viewer) + if len(args.cwd) == 0: + working_dir = os.path.dirname(os.path.abspath(args.viewer)) + else: + working_dir = os.path.abspath(args.cwd) + print(f"Working directory is {working_dir}, cwd {args.cwd}") + os.chdir(working_dir) + + if args.dryrun: + print("Running in dry-run mode - no Viewers will be started") + print("") + + for inst in range(args.num): + + # Format of each cred line is username_first username_last password + # A space is used to separate each and a # at the start of a line + # removes it from the pool (useful if someone else is using a subset + # of the available ones) + creds = creds_lines[inst].split(" ") + username_first = creds[0] + username_last = creds[1] + password = creds[2] + + # The default layout is an evenly spaced circle in the + # center of the region. We may extend this to allow other + # patterns like a square/rectangle or a spiral. (Hint: it + # likely won't be needed :)) + center_x = 128 + center_y = 128 + if args.layout == "circle": + radius = 6 + angle = (2 * math.pi / args.num) * inst + region_x = int(math.sin(angle) * radius + center_x) + region_y = int(math.cos(angle) * radius + center_y) + region_z = 0 + elif args.layout == "square": + region_x = center_x + region_y = center_y + elif args.layout == "spiral": + region_x = center_x + region_y = center_y + slurl = f"secondlife://{args.region}/{region_x}/{region_y}/{region_z}" + + # Build the script line + script_cmd = [args.viewer] + script_cmd.append(PARAM_NON_INTERACTIVE) + script_cmd.append(PARAM_MULTI) + script_cmd.append(PARAM_LOGIN) + script_cmd.append(username_first) + script_cmd.append(username_last) + script_cmd.append(password) + script_cmd.append(PARAM_SLURL) + script_cmd.append(slurl) + + # Display the script we will execute. + cmd = "" + for p in script_cmd: + cmd = cmd + " " + p + print(cmd) + + # If --dry-run is specified, we do everything (including, most + # usefully, display the script lines) but do not start the Viewer + if args.dryrun == False: + print("opening viewer session with",script_cmd) + viewer_session = subprocess.Popen(script_cmd) + + # Sleeping a bit between launches seems to help avoid a CPU + # surge when N Viewers are started simulatanously. The default + # value can be changed with the --sleep parameter + time.sleep(args.sleep / 1000) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(allow_abbrev=False) + parser.add_argument( + "--num", + type=int, + default=0, + dest="num", + help="How many avatars to add to the script", + ) + parser.add_argument( + "--creds", + default="../../../build-secrets-git/perf/perfbot_creds.txt", + dest="creds", + help="Location of the text file containing user credentials", + ) + parser.add_argument( + "--viewer", + default="C:/Program Files/SecondLife/SecondLifeViewer.exe", + dest="viewer", + help="Location of the non interactive Viewer build", + ) + parser.add_argument( + "--cwd", + default="", + dest="cwd", + help="Location of the current working directory to use", + ) + parser.add_argument( + "--region", + default="Lag Me 5", + dest="region", + help="The SLURL for the Second Life region to visit", + ) + parser.add_argument( + "--layout", + default="circle", + dest="layout", + choices={"circle", "square", "spiral"}, + help="The geometric layout of the avatar destination locations", + ) + parser.add_argument( + "--sleep", + type=int, + default=1000, + dest="sleep", + help="Time to sleep between launches in milliseconds", + ) + parser.add_argument( + "--dry-run", + action="store_true", + dest="dryrun", + help="Dryrun mode - display parameters and script lines but do not start any Viewers", + ) + args = parser.parse_args() + + gen_niv_script(args)