Merge branch 'master' of https://vcs.firestormviewer.org/phoenix-firestorm
commit
2253723705
|
|
@ -8,6 +8,7 @@
|
|||
*.rej
|
||||
*.swp
|
||||
*.tar.bz2
|
||||
*.code-workspace
|
||||
*~
|
||||
|
||||
# Specific paths and/or names
|
||||
|
|
@ -108,3 +109,4 @@ my_autobuild.xml
|
|||
compile_commands.json
|
||||
# ignore tracy for now
|
||||
indra/tracy
|
||||
firestorm.code-workspace
|
||||
|
|
|
|||
|
|
@ -994,11 +994,11 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>c96fbccf3db01230832d8795318ee627</string>
|
||||
<string>ab6f79c425524500d638807a3aee0115</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>md5</string>
|
||||
<key>url</key>
|
||||
<string>file:///opt/firestorm/fmodstudio-2.01.09-darwin-211252249.tar.bz2</string>
|
||||
<string>file:///opt/firestorm/fmodstudio-2.02.01-darwin-211941804.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin</string>
|
||||
|
|
@ -1008,11 +1008,11 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>65d60415962cf65918c4fabe379ad43a</string>
|
||||
<string>729a2844a0de06d454f8de47d3a9cb10</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>md5</string>
|
||||
<key>url</key>
|
||||
<string>file:///opt/firestorm/fmodstudio-2.01.09-linux64-211101316.tar.bz2</string>
|
||||
<string>file:///opt/firestorm/fmodstudio-2.02.01-linux64-211941750.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux64</string>
|
||||
|
|
@ -1022,11 +1022,11 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>215de14980a03774795de8cde24f1ad5</string>
|
||||
<string>d8139acbaf2961a466244f39989f2b5b</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>md5</string>
|
||||
<key>url</key>
|
||||
<string>file:///c:/cygwin/opt/firestorm/fmodstudio-2.01.09-windows-211090925.tar.bz2</string>
|
||||
<string>file:///c:/cygwin/opt/firestorm/fmodstudio-2.02.01-windows-211941202.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows</string>
|
||||
|
|
@ -1036,18 +1036,18 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>a55f9ae859a5a60285f0c6c764729194</string>
|
||||
<string>4704da8c560610e7c5329cdc05c2fec3</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>md5</string>
|
||||
<key>url</key>
|
||||
<string>file:///c:/cygwin/opt/firestorm/fmodstudio-2.01.09-windows64-211090927.tar.bz2</string>
|
||||
<string>file:///c:/cygwin/opt/firestorm/fmodstudio-2.02.01-windows64-211941203.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows64</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>version</key>
|
||||
<string>2.01.09</string>
|
||||
<string>2.02.01</string>
|
||||
</map>
|
||||
<key>fontconfig</key>
|
||||
<map>
|
||||
|
|
@ -1932,9 +1932,9 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>8d0ad384de8fbbc9083cac20258fcb0c</string>
|
||||
<string>3b8b0f54c851f136e2a92e1c6ba724a5</string>
|
||||
<key>url</key>
|
||||
<string>file:///opt/firestorm/kdu-8.1-darwin64-210931415.tar.bz2</string>
|
||||
<string>file:///opt/firestorm/kdu-8.1-darwin64-211970151.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
|
|
@ -2405,18 +2405,18 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>40a87f5d505a141b2ec79513a6197c35</string>
|
||||
<string>0a6349b11c8e9d34f0c80b8081736e75</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>md5</string>
|
||||
<key>url</key>
|
||||
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76516/728250/llca-202102021657.555615-common-555615.tar.bz2</string>
|
||||
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/79438/751815/llca-202104010215.557744-common-557744.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>common</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>version</key>
|
||||
<string>202102021657.555615</string>
|
||||
<string>202104010215.557744</string>
|
||||
</map>
|
||||
<key>llphysicsextensions_source</key>
|
||||
<map>
|
||||
|
|
@ -2539,9 +2539,9 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>2aa4ec0d72bbe4b755730f1bf92b39e7</string>
|
||||
<string>ba49274838d4c6bbd612db969b04e607</string>
|
||||
<key>url</key>
|
||||
<string>file:///opt/firestorm/llphysicsextensions_tpv-1.0.542327-darwin64-542327.tar.bz2</string>
|
||||
<string>file:///opt/firestorm/llphysicsextensions_tpv-1.0.561414-darwin64-561414.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
|
|
@ -2563,9 +2563,9 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>ad9aba5e2c43a37b6530a0d2de64df1c</string>
|
||||
<string>30de712d424f179d89dd00c01ded7257</string>
|
||||
<key>url</key>
|
||||
<string>file:///c:/cygwin/opt/firestorm/llphysicsextensions_tpv-1.0.542327-windows-542327.tar.bz2</string>
|
||||
<string>file:///c:/cygwin/opt/firestorm/llphysicsextensions_tpv-1.0.561414-windows-561414.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows</string>
|
||||
|
|
@ -2575,16 +2575,16 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>46689ff1442a8eccac3a7f3258308e1e</string>
|
||||
<string>abac12c4a12441704fa8884f1ca043d8</string>
|
||||
<key>url</key>
|
||||
<string>file:///c:/cygwin/opt/firestorm/llphysicsextensions_tpv-1.0.542327-windows64-542327.tar.bz2</string>
|
||||
<string>file:///c:/cygwin/opt/firestorm/llphysicsextensions_tpv-1.0.561414-windows64-561414.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>version</key>
|
||||
<string>1.0.542327</string>
|
||||
<string>1.0.561414</string>
|
||||
</map>
|
||||
<key>mesa</key>
|
||||
<map>
|
||||
|
|
|
|||
22
build.sh
22
build.sh
|
|
@ -129,11 +129,6 @@ pre_build()
|
|||
then # show that we're doing this, just not the contents
|
||||
echo source "$bugsplat_sh"
|
||||
source "$bugsplat_sh"
|
||||
# important: we test this and use its value in [grand-]child processes
|
||||
if [ -n "${BUGSPLAT_DB:-}" ]
|
||||
then echo export BUGSPLAT_DB
|
||||
export BUGSPLAT_DB
|
||||
fi
|
||||
fi
|
||||
set -x
|
||||
|
||||
|
|
@ -426,6 +421,15 @@ then
|
|||
fi
|
||||
fi
|
||||
|
||||
# Some of the uploads takes a long time to finish in the codeticket backend,
|
||||
# causing the next codeticket upload attempt to fail.
|
||||
# Inserting this after each potentially large upload may prevent those errors.
|
||||
# JJ is making changes to Codeticket that we hope will eliminate this failure, then this can be removed
|
||||
wait_for_codeticket()
|
||||
{
|
||||
sleep $(( 60 * 6 ))
|
||||
}
|
||||
|
||||
# check status and upload results to S3
|
||||
if $succeeded
|
||||
then
|
||||
|
|
@ -442,6 +446,7 @@ then
|
|||
# Upload base package.
|
||||
python_cmd "$helpers/codeticket.py" addoutput Installer "$package" \
|
||||
|| fatal "Upload of installer failed"
|
||||
wait_for_codeticket
|
||||
|
||||
# Upload additional packages.
|
||||
for package_id in $additional_packages
|
||||
|
|
@ -451,6 +456,7 @@ then
|
|||
then
|
||||
python_cmd "$helpers/codeticket.py" addoutput "Installer $package_id" "$package" \
|
||||
|| fatal "Upload of installer $package_id failed"
|
||||
wait_for_codeticket
|
||||
else
|
||||
record_failure "Failed to find additional package for '$package_id'."
|
||||
fi
|
||||
|
|
@ -464,6 +470,7 @@ then
|
|||
# Upload crash reporter file
|
||||
python_cmd "$helpers/codeticket.py" addoutput "Symbolfile" "$VIEWER_SYMBOL_FILE" \
|
||||
|| fatal "Upload of symbolfile failed"
|
||||
wait_for_codeticket
|
||||
fi
|
||||
|
||||
# Upload the llphysicsextensions_tpv package, if one was produced
|
||||
|
|
@ -471,6 +478,9 @@ then
|
|||
if [ -r "$build_dir/llphysicsextensions_package" ]
|
||||
then
|
||||
llphysicsextensions_package=$(cat $build_dir/llphysicsextensions_package)
|
||||
# This next upload is a frequent failure; see if giving the last one some time helps
|
||||
# JJ is making changes to Codeticket that we hope will eliminate this failure soon
|
||||
sleep 300
|
||||
python_cmd "$helpers/codeticket.py" addoutput "Physics Extensions Package" "$llphysicsextensions_package" --private \
|
||||
|| fatal "Upload of physics extensions package failed"
|
||||
fi
|
||||
|
|
@ -483,6 +493,7 @@ then
|
|||
begin_section "Upload Extension $extension"
|
||||
. $extension
|
||||
[ $? -eq 0 ] || fatal "Upload of extension $extension failed"
|
||||
wait_for_codeticket
|
||||
end_section "Upload Extension $extension"
|
||||
done
|
||||
fi
|
||||
|
|
@ -492,7 +503,6 @@ then
|
|||
record_event "skipping upload of installer"
|
||||
fi
|
||||
|
||||
|
||||
else
|
||||
record_event "skipping upload of installer due to failed build"
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -228,6 +228,7 @@ Ansariel Hiller
|
|||
SL-13364
|
||||
SL-13858
|
||||
SL-13697
|
||||
SL-13395
|
||||
SL-3136
|
||||
Aralara Rajal
|
||||
Arare Chantilly
|
||||
|
|
@ -267,9 +268,10 @@ Benjamin Bigdipper
|
|||
Beq Janus
|
||||
BUG-227094
|
||||
SL-10288
|
||||
SL-11300
|
||||
SL-13583
|
||||
SL-14766
|
||||
SL-11300
|
||||
SL-14927
|
||||
Beth Walcher
|
||||
Bezilon Kasei
|
||||
Biancaluce Robbiani
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ project(${ROOT_PROJECT_NAME})
|
|||
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
|
||||
|
||||
include(Variables)
|
||||
include(bugsplat)
|
||||
include(BuildVersion)
|
||||
|
||||
set(LEGACY_STDIO_LIBS)
|
||||
|
|
@ -108,7 +109,10 @@ endif (WINDOWS AND EXISTS ${LIBS_CLOSED_DIR}copy_win_scripts)
|
|||
|
||||
add_custom_target(viewer)
|
||||
|
||||
if (NOT USE_BUGSPLAT)
|
||||
add_subdirectory(${LIBS_OPEN_PREFIX}llcrashlogger)
|
||||
endif (NOT USE_BUGSPLAT)
|
||||
|
||||
add_subdirectory(${LIBS_OPEN_PREFIX}llplugin)
|
||||
add_subdirectory(${LIBS_OPEN_PREFIX}llui)
|
||||
add_subdirectory(${LIBS_OPEN_PREFIX}viewer_components)
|
||||
|
|
@ -124,31 +128,18 @@ add_subdirectory(${LIBS_OPEN_PREFIX}media_plugins)
|
|||
endif (ENABLE_MEDIA_PLUGINS)
|
||||
|
||||
if (LINUX)
|
||||
add_subdirectory(${VIEWER_PREFIX}linux_crash_logger)
|
||||
if (INSTALL_PROPRIETARY)
|
||||
include(LLAppearanceUtility)
|
||||
add_subdirectory(${LLAPPEARANCEUTILITY_SRC_DIR} ${LLAPPEARANCEUTILITY_BIN_DIR})
|
||||
endif (INSTALL_PROPRIETARY)
|
||||
#<FS:TS> Huh? Where'd that target come from?
|
||||
#add_dependencies(viewer linux-crash-logger-strip-target)
|
||||
add_dependencies(viewer linux-crash-logger)
|
||||
elseif (DARWIN)
|
||||
add_subdirectory(${VIEWER_PREFIX}mac_crash_logger)
|
||||
add_dependencies(viewer mac-crash-logger)
|
||||
elseif (WINDOWS)
|
||||
add_subdirectory(${VIEWER_PREFIX}win_crash_logger)
|
||||
# cmake EXISTS requires an absolute path, see indra/cmake/Variables.cmake
|
||||
if (EXISTS ${VIEWER_DIR}win_setup)
|
||||
add_subdirectory(${VIEWER_DIR}win_setup)
|
||||
endif (EXISTS ${VIEWER_DIR}win_setup)
|
||||
# add_dependencies(viewer windows-setup windows-crash-logger)
|
||||
add_dependencies(viewer windows-crash-logger)
|
||||
endif (LINUX)
|
||||
|
||||
add_subdirectory(${VIEWER_PREFIX}newview)
|
||||
add_dependencies(viewer firestorm-bin)
|
||||
|
||||
add_subdirectory(${VIEWER_PREFIX}doxygen EXCLUDE_FROM_ALL)
|
||||
if (WINDOWS)
|
||||
# cmake EXISTS requires an absolute path, see indra/cmake/Variables.cmake
|
||||
if (EXISTS ${VIEWER_DIR}win_setup)
|
||||
add_subdirectory(${VIEWER_DIR}win_setup)
|
||||
endif (EXISTS ${VIEWER_DIR}win_setup)
|
||||
endif (WINDOWS)
|
||||
|
||||
# sets the 'startup project' for debugging from visual studio.
|
||||
set_property(
|
||||
|
|
@ -156,6 +147,33 @@ set_property(
|
|||
PROPERTY VS_STARTUP_PROJECT firestorm-bin
|
||||
)
|
||||
|
||||
if (USE_BUGSPLAT)
|
||||
if (BUGSPLAT_DB)
|
||||
message(STATUS "Building with BugSplat; database '${BUGSPLAT_DB}'")
|
||||
else (BUGSPLAT_DB)
|
||||
message(WARNING "Building with BugSplat, but no database name set (BUGSPLAT_DB)")
|
||||
endif (BUGSPLAT_DB)
|
||||
else (USE_BUGSPLAT)
|
||||
message(STATUS "Not building with BugSplat")
|
||||
if (LINUX)
|
||||
add_subdirectory(${VIEWER_PREFIX}linux_crash_logger)
|
||||
#<FS:TS> Huh? Where'd that target come from?
|
||||
#add_dependencies(viewer linux-crash-logger-strip-target)
|
||||
elseif (DARWIN)
|
||||
add_subdirectory(${VIEWER_PREFIX}mac_crash_logger)
|
||||
add_dependencies(viewer mac-crash-logger)
|
||||
elseif (WINDOWS)
|
||||
add_subdirectory(${VIEWER_PREFIX}win_crash_logger)
|
||||
# add_dependencies(viewer windows-setup windows-crash-logger)
|
||||
add_dependencies(viewer windows-crash-logger)
|
||||
endif (LINUX)
|
||||
endif (USE_BUGSPLAT)
|
||||
|
||||
add_subdirectory(${VIEWER_PREFIX}newview)
|
||||
add_dependencies(viewer firestorm-bin)
|
||||
|
||||
add_subdirectory(${VIEWER_PREFIX}doxygen EXCLUDE_FROM_ALL)
|
||||
|
||||
if (LL_TESTS)
|
||||
# Define after the custom targets are created so
|
||||
# individual apps can add themselves as dependencies
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ if(WINDOWS)
|
|||
|
||||
# Filenames are different for 32/64 bit BugSplat file and we don't
|
||||
# have any control over them so need to branch.
|
||||
if (BUGSPLAT_DB)
|
||||
if (USE_BUGSPLAT)
|
||||
if(ADDRESS_SIZE EQUAL 32)
|
||||
set(release_files ${release_files} BugSplat.dll)
|
||||
set(release_files ${release_files} BugSplatRc.dll)
|
||||
|
|
@ -82,7 +82,7 @@ if(WINDOWS)
|
|||
set(release_files ${release_files} BugSplatRc64.dll)
|
||||
set(release_files ${release_files} BsSndRpt64.exe)
|
||||
endif(ADDRESS_SIZE EQUAL 32)
|
||||
endif (BUGSPLAT_DB)
|
||||
endif (USE_BUGSPLAT)
|
||||
|
||||
set(release_files ${release_files} growl++.dll growl.dll )
|
||||
if (FMODSTUDIO)
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ include(LLTestCommand)
|
|||
#include(GoogleMock)
|
||||
# </FS:ND>
|
||||
|
||||
include(bugsplat)
|
||||
include(Tut)
|
||||
|
||||
#*****************************************************************************
|
||||
|
|
@ -92,6 +93,12 @@ MACRO(LL_ADD_PROJECT_UNIT_TESTS project sources)
|
|||
IF(LL_TEST_VERBOSE)
|
||||
MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_SOURCE_FILES ${${name}_test_SOURCE_FILES}")
|
||||
ENDIF(LL_TEST_VERBOSE)
|
||||
|
||||
if (USE_BUGSPLAT)
|
||||
SET_PROPERTY(SOURCE ${${name}_test_SOURCE_FILES}
|
||||
APPEND PROPERTY COMPILE_DEFINITIONS "${BUGSPLAT_DEFINE}")
|
||||
endif (USE_BUGSPLAT)
|
||||
|
||||
# Headers
|
||||
GET_OPT_SOURCE_FILE_PROPERTY(${name}_test_additional_HEADER_FILES ${source} LL_TEST_ADDITIONAL_HEADER_FILES)
|
||||
SET(${name}_test_HEADER_FILES ${name}.h ${${name}_test_additional_HEADER_FILES})
|
||||
|
|
@ -229,6 +236,11 @@ FUNCTION(LL_ADD_INTEGRATION_TEST
|
|||
SET_TARGET_PROPERTIES(INTEGRATION_TEST_${testname} PROPERTIES COMPILE_FLAGS -I"${TUT_INCLUDE_DIR}")
|
||||
endif(USESYSTEMLIBS)
|
||||
|
||||
if (USE_BUGSPLAT)
|
||||
SET_PROPERTY(SOURCE ${source_files}
|
||||
APPEND PROPERTY COMPILE_DEFINITIONS "${BUGSPLAT_DEFINE}")
|
||||
endif (USE_BUGSPLAT)
|
||||
|
||||
# The following was copied to llcorehttp/CMakeLists.txt's texture_load target.
|
||||
# Any changes made here should be replicated there.
|
||||
if (WINDOWS)
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ set(LL_TESTS OFF CACHE BOOL "Build and run unit and integration tests (disable f
|
|||
set(INCREMENTAL_LINK OFF CACHE BOOL "Use incremental linking on win32 builds (enable for faster links on some machines)")
|
||||
set(ENABLE_MEDIA_PLUGINS ON CACHE BOOL "Turn off building media plugins if they are imported by third-party library mechanism")
|
||||
set(VIEWER_SYMBOL_FILE "" CACHE STRING "Name of tarball into which to place symbol files")
|
||||
set(BUGSPLAT_DB "" CACHE STRING "BugSplat database name, if BugSplat crash reporting is desired")
|
||||
|
||||
if(LIBS_CLOSED_DIR)
|
||||
file(TO_CMAKE_PATH "${LIBS_CLOSED_DIR}" LIBS_CLOSED_DIR)
|
||||
|
|
|
|||
|
|
@ -1,27 +1,38 @@
|
|||
# BugSplat is engaged by setting BUGSPLAT_DB to the target BugSplat database
|
||||
# name.
|
||||
if (BUGSPLAT_DB)
|
||||
if (USESYSTEMLIBS)
|
||||
message(STATUS "Looking for system BugSplat")
|
||||
set(BUGSPLAT_FIND_QUIETLY ON)
|
||||
set(BUGSPLAT_FIND_REQUIRED ON)
|
||||
include(FindBUGSPLAT)
|
||||
else (USESYSTEMLIBS)
|
||||
message(STATUS "Engaging autobuild BugSplat")
|
||||
include(Prebuilt)
|
||||
use_prebuilt_binary(bugsplat)
|
||||
if (WINDOWS)
|
||||
set(BUGSPLAT_LIBRARIES
|
||||
${ARCH_PREBUILT_DIRS_RELEASE}/bugsplat.lib
|
||||
)
|
||||
elseif (DARWIN)
|
||||
find_library(BUGSPLAT_LIBRARIES BugsplatMac
|
||||
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}")
|
||||
message(FATAL_ERROR "Bugsplat for OSX not fully implemented, please adapt llappdelegate-objc.mm to honor options of sending user name and settings.xml.")
|
||||
else (WINDOWS)
|
||||
message(FATAL_ERROR "Bugsplat for Linux not implemented.")
|
||||
if (INSTALL_PROPRIETARY)
|
||||
# Note that viewer_manifest.py makes decision based on BUGSPLAT_DB and not USE_BUGSPLAT
|
||||
if (BUGSPLAT_DB)
|
||||
set(USE_BUGSPLAT ON CACHE BOOL "Use the BugSplat crash reporting system")
|
||||
else (BUGSPLAT_DB)
|
||||
set(USE_BUGSPLAT OFF CACHE BOOL "Use the BugSplat crash reporting system")
|
||||
endif (BUGSPLAT_DB)
|
||||
else (INSTALL_PROPRIETARY)
|
||||
set(USE_BUGSPLAT OFF CACHE BOOL "Use the BugSplat crash reporting system")
|
||||
endif (INSTALL_PROPRIETARY)
|
||||
|
||||
if (USE_BUGSPLAT)
|
||||
if (NOT USESYSTEMLIBS)
|
||||
include(Prebuilt)
|
||||
use_prebuilt_binary(bugsplat)
|
||||
if (WINDOWS)
|
||||
set(BUGSPLAT_LIBRARIES
|
||||
${ARCH_PREBUILT_DIRS_RELEASE}/bugsplat.lib
|
||||
)
|
||||
elseif (DARWIN)
|
||||
find_library(BUGSPLAT_LIBRARIES BugsplatMac REQUIRED
|
||||
NO_DEFAULT_PATH PATHS "${ARCH_PREBUILT_DIRS_RELEASE}")
|
||||
message("Bugsplat for OSX not fully implemented, please adapt llappdelegate-objc.mm to honor options of sending user name and settings.xml.")
|
||||
else (WINDOWS)
|
||||
message(FATAL_ERROR "BugSplat is not supported; add -DUSE_BUGSPLAT=OFF")
|
||||
endif (WINDOWS)
|
||||
else (NOT USESYSTEMLIBS)
|
||||
set(BUGSPLAT_FIND_QUIETLY ON)
|
||||
set(BUGSPLAT_FIND_REQUIRED ON)
|
||||
include(FindBUGSPLAT)
|
||||
endif (NOT USESYSTEMLIBS)
|
||||
|
||||
set(BUGSPLAT_DB "" CACHE STRING "BugSplat crash database name")
|
||||
|
||||
endif (WINDOWS)
|
||||
set(BUGSPLAT_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/bugsplat)
|
||||
endif (USESYSTEMLIBS)
|
||||
endif (BUGSPLAT_DB)
|
||||
set(BUGSPLAT_DEFINE "LL_BUGSPLAT")
|
||||
endif (USE_BUGSPLAT)
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
This component is no longer used in Linden Lab builds.
|
||||
Change requests to support continued use by open source
|
||||
builds are welcome.
|
||||
|
|
@ -4,6 +4,7 @@ project(llcommon)
|
|||
|
||||
include(00-Common)
|
||||
include(LLCommon)
|
||||
include(bugsplat)
|
||||
include(Linking)
|
||||
include(Boost)
|
||||
include(LLSharedLibs)
|
||||
|
|
@ -291,10 +292,10 @@ list(APPEND llcommon_HEADER_FILES "tea.h" )
|
|||
set_source_files_properties(${llcommon_HEADER_FILES}
|
||||
PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
|
||||
if (BUGSPLAT_DB)
|
||||
set_source_files_properties(llapp.cpp
|
||||
PROPERTIES COMPILE_DEFINITIONS "LL_BUGSPLAT")
|
||||
endif (BUGSPLAT_DB)
|
||||
if (USE_BUGSPLAT)
|
||||
set_source_files_properties(${llcommon_SOURCE_FILES}
|
||||
PROPERTIES COMPILE_DEFINITIONS "${BUGSPLAT_DEFINE}")
|
||||
endif (USE_BUGSPLAT)
|
||||
|
||||
list(APPEND llcommon_SOURCE_FILES ${llcommon_HEADER_FILES})
|
||||
|
||||
|
|
|
|||
|
|
@ -531,7 +531,12 @@ void LLApp::setupErrorHandling(bool second_instance)
|
|||
#endif // LL_LINUX
|
||||
|
||||
#endif // ! LL_WINDOWS
|
||||
|
||||
#ifdef LL_BUGSPLAT
|
||||
// do not start our own error thread
|
||||
#else // ! LL_BUGSPLAT
|
||||
startErrorThread();
|
||||
#endif
|
||||
}
|
||||
|
||||
void LLApp::startErrorThread()
|
||||
|
|
@ -811,7 +816,9 @@ void setup_signals()
|
|||
act.sa_flags = SA_SIGINFO;
|
||||
|
||||
// Synchronous signals
|
||||
# ifndef LL_BUGSPLAT
|
||||
sigaction(SIGABRT, &act, NULL);
|
||||
# endif
|
||||
sigaction(SIGALRM, &act, NULL);
|
||||
sigaction(SIGBUS, &act, NULL);
|
||||
sigaction(SIGFPE, &act, NULL);
|
||||
|
|
@ -848,7 +855,9 @@ void clear_signals()
|
|||
act.sa_flags = SA_SIGINFO;
|
||||
|
||||
// Synchronous signals
|
||||
# ifndef LL_BUGSPLAT
|
||||
sigaction(SIGABRT, &act, NULL);
|
||||
# endif
|
||||
sigaction(SIGALRM, &act, NULL);
|
||||
sigaction(SIGBUS, &act, NULL);
|
||||
sigaction(SIGFPE, &act, NULL);
|
||||
|
|
@ -901,6 +910,7 @@ void default_unix_signal_handler(int signum, siginfo_t *info, void *)
|
|||
|
||||
return;
|
||||
case SIGABRT:
|
||||
// Note that this handler is not set for SIGABRT when using Bugsplat
|
||||
// Abort just results in termination of the app, no funky error handling.
|
||||
if (LLApp::sLogInSignal)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -259,6 +259,10 @@ public:
|
|||
*/
|
||||
LLRunner& getRunner() { return mRunner; }
|
||||
|
||||
#ifdef LL_WINDOWS
|
||||
virtual void reportCrashToBugsplat(void* pExcepInfo /*EXCEPTION_POINTERS*/) { }
|
||||
#endif
|
||||
|
||||
public:
|
||||
typedef std::map<std::string, std::string> string_map;
|
||||
string_map mOptionMap; // Contains all command-line options and arguments in a map
|
||||
|
|
|
|||
|
|
@ -56,6 +56,10 @@
|
|||
#include "stringize.h"
|
||||
#include "llexception.h"
|
||||
|
||||
#if LL_WINDOWS
|
||||
#include <excpt.h>
|
||||
#endif
|
||||
|
||||
// static
|
||||
LLCoros::CoroData& LLCoros::get_CoroData(const std::string& caller)
|
||||
{
|
||||
|
|
@ -248,29 +252,58 @@ std::string LLCoros::launch(const std::string& prefix, const callable_t& callabl
|
|||
|
||||
#if LL_WINDOWS
|
||||
|
||||
void LLCoros::winlevel(const callable_t& callable)
|
||||
static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific
|
||||
|
||||
U32 cpp_exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop, const std::string& name)
|
||||
{
|
||||
// C++ exceptions were logged in toplevelTryWrapper, but not SEH
|
||||
// log SEH exceptions here, to make sure it gets into bugsplat's
|
||||
// report and because __try won't allow std::string operations
|
||||
if (code != STATUS_MSC_EXCEPTION)
|
||||
{
|
||||
LL_WARNS() << "SEH crash in " << name << ", code: " << code << LL_ENDL;
|
||||
}
|
||||
// Handle bugsplat here, since GetExceptionInformation() can only be
|
||||
// called from within filter for __except(filter), not from __except's {}
|
||||
// Bugsplat should get all exceptions, C++ and SEH
|
||||
LLApp::instance()->reportCrashToBugsplat(exception_infop);
|
||||
|
||||
// Only convert non C++ exceptions.
|
||||
if (code == STATUS_MSC_EXCEPTION)
|
||||
{
|
||||
// C++ exception, go on
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
else
|
||||
{
|
||||
// handle it
|
||||
return EXCEPTION_EXECUTE_HANDLER;
|
||||
}
|
||||
}
|
||||
|
||||
void LLCoros::winlevel(const std::string& name, const callable_t& callable)
|
||||
{
|
||||
__try
|
||||
{
|
||||
callable();
|
||||
toplevelTryWrapper(name, callable);
|
||||
}
|
||||
__except (msc_exception_filter(GetExceptionCode(), GetExceptionInformation()))
|
||||
__except (cpp_exception_filter(GetExceptionCode(), GetExceptionInformation(), name))
|
||||
{
|
||||
// convert to C++ styled exception
|
||||
// convert to C++ styled exception for handlers other than bugsplat
|
||||
// Note: it might be better to use _se_set_translator
|
||||
// if you want exception to inherit full callstack
|
||||
char integer_string[32];
|
||||
sprintf(integer_string, "SEH, code: %lu\n", GetExceptionCode());
|
||||
//
|
||||
// in case of bugsplat this will get to exceptionTerminateHandler and
|
||||
// looks like fiber will terminate application after that
|
||||
char integer_string[512];
|
||||
sprintf(integer_string, "SEH crash in %s, code: %lu\n", name.c_str(), GetExceptionCode());
|
||||
throw std::exception(integer_string);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// Top-level wrapper around caller's coroutine callable.
|
||||
// Normally we like to pass strings and such by const reference -- but in this
|
||||
// case, we WANT to copy both the name and the callable to our local stack!
|
||||
void LLCoros::toplevel(std::string name, callable_t callable)
|
||||
void LLCoros::toplevelTryWrapper(const std::string& name, const callable_t& callable)
|
||||
{
|
||||
// keep the CoroData on this top-level function's stack frame
|
||||
CoroData corodata(name);
|
||||
|
|
@ -280,18 +313,12 @@ void LLCoros::toplevel(std::string name, callable_t callable)
|
|||
// run the code the caller actually wants in the coroutine
|
||||
try
|
||||
{
|
||||
// <FS:Ansariel> Disable for more meaningful callstacks
|
||||
//#if LL_WINDOWS && LL_RELEASE_FOR_DOWNLOAD
|
||||
// winlevel(callable);
|
||||
//#else
|
||||
callable();
|
||||
//#endif
|
||||
// <FS:Ansariel> Disable for more meaningful callstacks
|
||||
}
|
||||
catch (const Stop& exc)
|
||||
{
|
||||
LL_INFOS("LLCoros") << "coroutine " << name << " terminating because "
|
||||
<< exc.what() << LL_ENDL;
|
||||
<< exc.what() << LL_ENDL;
|
||||
}
|
||||
catch (const LLContinueError&)
|
||||
{
|
||||
|
|
@ -304,10 +331,25 @@ void LLCoros::toplevel(std::string name, callable_t callable)
|
|||
{
|
||||
// Any OTHER kind of uncaught exception will cause the viewer to
|
||||
// crash, hopefully informatively.
|
||||
CRASH_ON_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << name));
|
||||
LOG_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << name));
|
||||
// to not modify callstack
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
// Top-level wrapper around caller's coroutine callable.
|
||||
// Normally we like to pass strings and such by const reference -- but in this
|
||||
// case, we WANT to copy both the name and the callable to our local stack!
|
||||
void LLCoros::toplevel(std::string name, callable_t callable)
|
||||
{
|
||||
#if LL_WINDOWS
|
||||
// Can not use __try in functions that require unwinding, so use one more wrapper
|
||||
winlevel(name, callable);
|
||||
#else
|
||||
toplevelTryWrapper(name, callable);
|
||||
#endif
|
||||
}
|
||||
|
||||
//static
|
||||
void LLCoros::checkStop()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -290,11 +290,12 @@ public:
|
|||
|
||||
private:
|
||||
std::string generateDistinctName(const std::string& prefix) const;
|
||||
#if LL_WINDOWS
|
||||
void winlevel(const std::string& name, const callable_t& callable);
|
||||
#endif
|
||||
void toplevelTryWrapper(const std::string& name, const callable_t& callable);
|
||||
void toplevel(std::string name, callable_t callable);
|
||||
struct CoroData;
|
||||
#if LL_WINDOWS
|
||||
static void winlevel(const callable_t& callable);
|
||||
#endif
|
||||
static CoroData& get_CoroData(const std::string& caller);
|
||||
|
||||
S32 mStackSize;
|
||||
|
|
|
|||
|
|
@ -488,8 +488,6 @@ namespace
|
|||
protected:
|
||||
Globals();
|
||||
public:
|
||||
std::ostringstream messageStream;
|
||||
bool messageStreamInUse;
|
||||
std::string mFatalMessage;
|
||||
|
||||
void addCallSite(LLError::CallSite&);
|
||||
|
|
@ -499,12 +497,7 @@ namespace
|
|||
CallSiteVector callSites;
|
||||
};
|
||||
|
||||
Globals::Globals()
|
||||
: messageStream(),
|
||||
messageStreamInUse(false),
|
||||
callSites()
|
||||
{
|
||||
}
|
||||
Globals::Globals() {}
|
||||
|
||||
Globals* Globals::getInstance()
|
||||
{
|
||||
|
|
@ -595,7 +588,7 @@ namespace LLError
|
|||
mFileLevelMap(),
|
||||
mTagLevelMap(),
|
||||
mUniqueLogMessages(),
|
||||
mCrashFunction(NULL),
|
||||
mCrashFunction([](const std::string&){}),
|
||||
mTimeFunction(NULL),
|
||||
mRecorders(),
|
||||
mShouldLogCallCounter(0)
|
||||
|
|
@ -780,7 +773,6 @@ namespace
|
|||
LLError::setDefaultLevel(LLError::LEVEL_INFO);
|
||||
LLError::setAlwaysFlush(true);
|
||||
LLError::setEnabledLogTypesMask(0xFFFFFFFF);
|
||||
LLError::setFatalFunction(LLError::crashAndLoop);
|
||||
LLError::setTimeFunction(LLError::utcTime);
|
||||
|
||||
// log_to_stderr is only false in the unit and integration tests to keep builds quieter
|
||||
|
|
@ -1419,57 +1411,7 @@ namespace LLError
|
|||
}
|
||||
|
||||
|
||||
std::ostringstream* Log::out()
|
||||
{
|
||||
LLMutexTrylock lock(getMutex<LOG_MUTEX>(),5);
|
||||
|
||||
if (lock.isLocked())
|
||||
{
|
||||
Globals* g = Globals::getInstance();
|
||||
|
||||
if (!g->messageStreamInUse)
|
||||
{
|
||||
g->messageStreamInUse = true;
|
||||
return &g->messageStream;
|
||||
}
|
||||
}
|
||||
|
||||
return new std::ostringstream;
|
||||
}
|
||||
|
||||
void Log::flush(std::ostringstream* out, char* message)
|
||||
{
|
||||
LLMutexTrylock lock(getMutex<LOG_MUTEX>(),5);
|
||||
if (!lock.isLocked())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(strlen(out->str().c_str()) < 128)
|
||||
{
|
||||
strcpy(message, out->str().c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
strncpy(message, out->str().c_str(), 127);
|
||||
message[127] = '\0' ;
|
||||
}
|
||||
|
||||
Globals* g = Globals::getInstance();
|
||||
if (out == &g->messageStream)
|
||||
{
|
||||
g->messageStream.clear();
|
||||
g->messageStream.str("");
|
||||
g->messageStreamInUse = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
delete out;
|
||||
}
|
||||
return ;
|
||||
}
|
||||
|
||||
void Log::flush(std::ostringstream* out, const CallSite& site)
|
||||
void Log::flush(const std::ostringstream& out, const CallSite& site)
|
||||
{
|
||||
LLMutexTrylock lock(getMutex<LOG_MUTEX>(),5);
|
||||
if (!lock.isLocked())
|
||||
|
|
@ -1480,21 +1422,11 @@ namespace LLError
|
|||
Globals* g = Globals::getInstance();
|
||||
SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig();
|
||||
|
||||
std::string message = out->str();
|
||||
if (out == &g->messageStream)
|
||||
{
|
||||
g->messageStream.clear();
|
||||
g->messageStream.str("");
|
||||
g->messageStreamInUse = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
delete out;
|
||||
}
|
||||
std::string message = out.str();
|
||||
|
||||
if (site.mPrintOnce)
|
||||
{
|
||||
std::ostringstream message_stream;
|
||||
std::ostringstream message_stream;
|
||||
|
||||
std::map<std::string, unsigned int>::iterator messageIter = s->mUniqueLogMessages.find(message);
|
||||
if (messageIter != s->mUniqueLogMessages.end())
|
||||
|
|
@ -1515,8 +1447,8 @@ namespace LLError
|
|||
message_stream << "ONCE: ";
|
||||
s->mUniqueLogMessages[message] = 1;
|
||||
}
|
||||
message_stream << message;
|
||||
message = message_stream.str();
|
||||
message_stream << message;
|
||||
message = message_stream.str();
|
||||
}
|
||||
|
||||
writeToRecorders(site, message);
|
||||
|
|
@ -1524,10 +1456,7 @@ namespace LLError
|
|||
if (site.mLevel == LEVEL_ERROR)
|
||||
{
|
||||
g->mFatalMessage = message;
|
||||
if (s->mCrashFunction)
|
||||
{
|
||||
s->mCrashFunction(message);
|
||||
}
|
||||
s->mCrashFunction(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1591,29 +1520,6 @@ namespace LLError
|
|||
return s->mShouldLogCallCounter;
|
||||
}
|
||||
|
||||
#if LL_WINDOWS
|
||||
// VC80 was optimizing the error away.
|
||||
#pragma optimize("", off)
|
||||
#endif
|
||||
void crashAndLoop(const std::string& message)
|
||||
{
|
||||
// Now, we go kaboom!
|
||||
int* make_me_crash = NULL;
|
||||
|
||||
*make_me_crash = 0;
|
||||
|
||||
while(true)
|
||||
{
|
||||
// Loop forever, in case the crash didn't work?
|
||||
}
|
||||
|
||||
// this is an attempt to let Coverity and other semantic scanners know that this function won't be returning ever.
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
#if LL_WINDOWS
|
||||
#pragma optimize("", on)
|
||||
#endif
|
||||
|
||||
std::string utcTime()
|
||||
{
|
||||
time_t now = time(NULL);
|
||||
|
|
@ -1630,33 +1536,7 @@ namespace LLError
|
|||
|
||||
namespace LLError
|
||||
{
|
||||
char** LLCallStacks::sBuffer = NULL ;
|
||||
S32 LLCallStacks::sIndex = 0 ;
|
||||
|
||||
//static
|
||||
void LLCallStacks::allocateStackBuffer()
|
||||
{
|
||||
if(sBuffer == NULL)
|
||||
{
|
||||
sBuffer = new char*[512] ;
|
||||
sBuffer[0] = new char[512 * 128] ;
|
||||
for(S32 i = 1 ; i < 512 ; i++)
|
||||
{
|
||||
sBuffer[i] = sBuffer[i-1] + 128 ;
|
||||
}
|
||||
sIndex = 0 ;
|
||||
}
|
||||
}
|
||||
|
||||
void LLCallStacks::freeStackBuffer()
|
||||
{
|
||||
if(sBuffer != NULL)
|
||||
{
|
||||
delete [] sBuffer[0] ;
|
||||
delete [] sBuffer ;
|
||||
sBuffer = NULL ;
|
||||
}
|
||||
}
|
||||
LLCallStacks::StringVector LLCallStacks::sBuffer ;
|
||||
|
||||
//static
|
||||
void LLCallStacks::push(const char* function, const int line)
|
||||
|
|
@ -1667,33 +1547,24 @@ namespace LLError
|
|||
return;
|
||||
}
|
||||
|
||||
if(sBuffer == NULL)
|
||||
{
|
||||
allocateStackBuffer();
|
||||
}
|
||||
|
||||
if(sIndex > 511)
|
||||
if(sBuffer.size() > 511)
|
||||
{
|
||||
clear() ;
|
||||
}
|
||||
|
||||
strcpy(sBuffer[sIndex], function) ;
|
||||
sprintf(sBuffer[sIndex] + strlen(function), " line: %d ", line) ;
|
||||
sIndex++ ;
|
||||
|
||||
return ;
|
||||
std::ostringstream out;
|
||||
insert(out, function, line);
|
||||
sBuffer.push_back(out.str());
|
||||
}
|
||||
|
||||
//static
|
||||
std::ostringstream* LLCallStacks::insert(const char* function, const int line)
|
||||
void LLCallStacks::insert(std::ostream& out, const char* function, const int line)
|
||||
{
|
||||
std::ostringstream* _out = LLError::Log::out();
|
||||
*_out << function << " line " << line << " " ;
|
||||
return _out ;
|
||||
out << function << " line " << line << " " ;
|
||||
}
|
||||
|
||||
//static
|
||||
void LLCallStacks::end(std::ostringstream* _out)
|
||||
void LLCallStacks::end(const std::ostringstream& out)
|
||||
{
|
||||
LLMutexTrylock lock(getMutex<STACKS_MUTEX>(), 5);
|
||||
if (!lock.isLocked())
|
||||
|
|
@ -1701,17 +1572,12 @@ namespace LLError
|
|||
return;
|
||||
}
|
||||
|
||||
if(sBuffer == NULL)
|
||||
{
|
||||
allocateStackBuffer();
|
||||
}
|
||||
|
||||
if(sIndex > 511)
|
||||
if(sBuffer.size() > 511)
|
||||
{
|
||||
clear() ;
|
||||
}
|
||||
|
||||
LLError::Log::flush(_out, sBuffer[sIndex++]) ;
|
||||
sBuffer.push_back(out.str());
|
||||
}
|
||||
|
||||
//static
|
||||
|
|
@ -1723,33 +1589,30 @@ namespace LLError
|
|||
return;
|
||||
}
|
||||
|
||||
if(sIndex > 0)
|
||||
if(! sBuffer.empty())
|
||||
{
|
||||
LL_INFOS() << " ************* PRINT OUT LL CALL STACKS ************* " << LL_ENDL;
|
||||
while(sIndex > 0)
|
||||
for (StringVector::const_reverse_iterator ri(sBuffer.rbegin()), re(sBuffer.rend());
|
||||
ri != re; ++ri)
|
||||
{
|
||||
sIndex-- ;
|
||||
LL_INFOS() << sBuffer[sIndex] << LL_ENDL;
|
||||
LL_INFOS() << (*ri) << LL_ENDL;
|
||||
}
|
||||
LL_INFOS() << " *************** END OF LL CALL STACKS *************** " << LL_ENDL;
|
||||
}
|
||||
|
||||
if(sBuffer != NULL)
|
||||
{
|
||||
freeStackBuffer();
|
||||
}
|
||||
cleanup();
|
||||
}
|
||||
|
||||
//static
|
||||
void LLCallStacks::clear()
|
||||
{
|
||||
sIndex = 0 ;
|
||||
sBuffer.clear();
|
||||
}
|
||||
|
||||
//static
|
||||
void LLCallStacks::cleanup()
|
||||
{
|
||||
freeStackBuffer();
|
||||
clear();
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, const LLStacktrace&)
|
||||
|
|
|
|||
|
|
@ -29,7 +29,9 @@
|
|||
#define LL_LLERROR_H
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <typeinfo>
|
||||
#include <vector>
|
||||
|
||||
#include "stdtypes.h"
|
||||
|
||||
|
|
@ -204,9 +206,7 @@ namespace LLError
|
|||
{
|
||||
public:
|
||||
static bool shouldLog(CallSite&);
|
||||
static std::ostringstream* out();
|
||||
static void flush(std::ostringstream* out, char* message);
|
||||
static void flush(std::ostringstream*, const CallSite&);
|
||||
static void flush(const std::ostringstream&, const CallSite&);
|
||||
static std::string demangle(const char* mangled);
|
||||
/// classname<TYPE>()
|
||||
template <typename T>
|
||||
|
|
@ -287,18 +287,15 @@ namespace LLError
|
|||
class LL_COMMON_API LLCallStacks
|
||||
{
|
||||
private:
|
||||
static char** sBuffer ;
|
||||
static S32 sIndex ;
|
||||
|
||||
static void allocateStackBuffer();
|
||||
static void freeStackBuffer();
|
||||
typedef std::vector<std::string> StringVector;
|
||||
static StringVector sBuffer ;
|
||||
|
||||
public:
|
||||
static void push(const char* function, const int line) ;
|
||||
static std::ostringstream* insert(const char* function, const int line) ;
|
||||
static void insert(std::ostream& out, const char* function, const int line) ;
|
||||
static void print() ;
|
||||
static void clear() ;
|
||||
static void end(std::ostringstream* _out) ;
|
||||
static void end(const std::ostringstream& out) ;
|
||||
static void cleanup();
|
||||
};
|
||||
|
||||
|
|
@ -312,10 +309,11 @@ namespace LLError
|
|||
//this is cheaper than llcallstacks if no need to output other variables to call stacks.
|
||||
#define LL_PUSH_CALLSTACKS() LLError::LLCallStacks::push(__FUNCTION__, __LINE__)
|
||||
|
||||
#define llcallstacks \
|
||||
{ \
|
||||
std::ostringstream* _out = LLError::LLCallStacks::insert(__FUNCTION__, __LINE__) ; \
|
||||
(*_out)
|
||||
#define llcallstacks \
|
||||
{ \
|
||||
std::ostringstream _out; \
|
||||
LLError::LLCallStacks::insert(_out, __FUNCTION__, __LINE__) ; \
|
||||
_out
|
||||
|
||||
#define llcallstacksendl \
|
||||
LLError::End(); \
|
||||
|
|
@ -361,11 +359,11 @@ typedef LLError::NoClassInfo _LL_CLASS_TO_LOG;
|
|||
static LLError::CallSite _site(lllog_site_args_(level, once, tags)); \
|
||||
lllog_test_()
|
||||
|
||||
#define lllog_test_() \
|
||||
if (LL_UNLIKELY(_site.shouldLog())) \
|
||||
{ \
|
||||
std::ostringstream* _out = LLError::Log::out(); \
|
||||
(*_out)
|
||||
#define lllog_test_() \
|
||||
if (LL_UNLIKELY(_site.shouldLog())) \
|
||||
{ \
|
||||
std::ostringstream _out; \
|
||||
_out
|
||||
|
||||
#define lllog_site_args_(level, once, tags) \
|
||||
level, __FILE__, __LINE__, typeid(_LL_CLASS_TO_LOG), \
|
||||
|
|
@ -384,15 +382,27 @@ typedef LLError::NoClassInfo _LL_CLASS_TO_LOG;
|
|||
// LL_CONT << " for " << t << " seconds" << LL_ENDL;
|
||||
//
|
||||
//Such computation is done iff the message will be logged.
|
||||
#define LL_CONT (*_out)
|
||||
#define LL_CONT _out
|
||||
|
||||
#define LL_NEWLINE '\n'
|
||||
|
||||
#define LL_ENDL \
|
||||
LLError::End(); \
|
||||
LLError::Log::flush(_out, _site); \
|
||||
} \
|
||||
} while(0)
|
||||
// Use this only in LL_ERRS or in a place that LL_ERRS may not be used
|
||||
#define LLERROR_CRASH \
|
||||
{ \
|
||||
int* make_me_crash = NULL;\
|
||||
*make_me_crash = 0; \
|
||||
exit(*make_me_crash); \
|
||||
}
|
||||
|
||||
#define LL_ENDL \
|
||||
LLError::End(); \
|
||||
LLError::Log::flush(_out, _site); \
|
||||
if (_site.mLevel == LLError::LEVEL_ERROR) \
|
||||
{ \
|
||||
LLERROR_CRASH \
|
||||
} \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
// NEW Macros for debugging, allow the passing of a string tag
|
||||
|
||||
|
|
|
|||
|
|
@ -94,14 +94,16 @@ namespace LLError
|
|||
*/
|
||||
|
||||
typedef boost::function<void(const std::string&)> FatalFunction;
|
||||
LL_COMMON_API void crashAndLoop(const std::string& message);
|
||||
// Default fatal function: access null pointer and loops forever
|
||||
|
||||
LL_COMMON_API void setFatalFunction(const FatalFunction&);
|
||||
// The fatal function will be called when an message of LEVEL_ERROR
|
||||
// The fatal function will be called after an message of LEVEL_ERROR
|
||||
// is logged. Note: supressing a LEVEL_ERROR message from being logged
|
||||
// (by, for example, setting a class level to LEVEL_NONE), will keep
|
||||
// the that message from causing the fatal funciton to be invoked.
|
||||
// that message from causing the fatal function to be invoked.
|
||||
// The passed FatalFunction will be the LAST log function called
|
||||
// before LL_ERRS crashes its caller. A FatalFunction can throw an
|
||||
// exception, or call exit(), to bypass the crash. It MUST disrupt the
|
||||
// flow of control because no caller expects LL_ERRS to return.
|
||||
|
||||
LL_COMMON_API FatalFunction getFatalFunction();
|
||||
// Retrieve the previously-set FatalFunction
|
||||
|
|
@ -147,14 +149,14 @@ namespace LLError
|
|||
virtual void recordMessage(LLError::ELevel, const std::string& message) = 0;
|
||||
// use the level for better display, not for filtering
|
||||
|
||||
virtual bool enabled() { return true; }
|
||||
virtual bool enabled() { return true; }
|
||||
|
||||
bool wantsTime();
|
||||
bool wantsTags();
|
||||
bool wantsLevel();
|
||||
bool wantsLocation();
|
||||
bool wantsFunctionName();
|
||||
bool wantsMultiline();
|
||||
bool wantsMultiline();
|
||||
|
||||
void showTime(bool show);
|
||||
void showTags(bool show);
|
||||
|
|
@ -165,15 +167,35 @@ namespace LLError
|
|||
|
||||
protected:
|
||||
bool mWantsTime;
|
||||
bool mWantsTags;
|
||||
bool mWantsLevel;
|
||||
bool mWantsLocation;
|
||||
bool mWantsFunctionName;
|
||||
bool mWantsMultiline;
|
||||
bool mWantsTags;
|
||||
bool mWantsLevel;
|
||||
bool mWantsLocation;
|
||||
bool mWantsFunctionName;
|
||||
bool mWantsMultiline;
|
||||
};
|
||||
|
||||
typedef boost::shared_ptr<Recorder> RecorderPtr;
|
||||
|
||||
/**
|
||||
* Instantiate GenericRecorder with a callable(level, message) to get
|
||||
* control on every log message without having to code an explicit
|
||||
* Recorder subclass.
|
||||
*/
|
||||
template <typename CALLABLE>
|
||||
class GenericRecorder: public Recorder
|
||||
{
|
||||
public:
|
||||
GenericRecorder(const CALLABLE& callable):
|
||||
mCallable(callable)
|
||||
{}
|
||||
void recordMessage(LLError::ELevel level, const std::string& message) override
|
||||
{
|
||||
mCallable(level, message);
|
||||
}
|
||||
private:
|
||||
CALLABLE mCallable;
|
||||
};
|
||||
|
||||
/**
|
||||
* @NOTE: addRecorder() and removeRecorder() uses the boost::shared_ptr to allow for shared ownership
|
||||
* while still ensuring that the allocated memory is eventually freed
|
||||
|
|
@ -181,6 +203,19 @@ namespace LLError
|
|||
LL_COMMON_API void addRecorder(RecorderPtr);
|
||||
LL_COMMON_API void removeRecorder(RecorderPtr);
|
||||
// each error message is passed to each recorder via recordMessage()
|
||||
/**
|
||||
* Call addGenericRecorder() with a callable(level, message) to get
|
||||
* control on every log message without having to code an explicit
|
||||
* Recorder subclass. Save the returned RecorderPtr if you later want to
|
||||
* call removeRecorder().
|
||||
*/
|
||||
template <typename CALLABLE>
|
||||
RecorderPtr addGenericRecorder(const CALLABLE& callable)
|
||||
{
|
||||
RecorderPtr ptr{ new GenericRecorder<CALLABLE>(callable) };
|
||||
addRecorder(ptr);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
LL_COMMON_API void logToFile(const std::string& filename);
|
||||
LL_COMMON_API void logToStderr();
|
||||
|
|
|
|||
|
|
@ -59,7 +59,6 @@ public:
|
|||
// pump name -- so it should NOT need tweaking for uniqueness.
|
||||
mReplyPump(LLUUID::generateNewID().asString()),
|
||||
mExpect(0),
|
||||
mPrevFatalFunction(LLError::getFatalFunction()),
|
||||
// Instantiate a distinct LLLeapListener for this plugin. (Every
|
||||
// plugin will want its own collection of managed listeners, etc.)
|
||||
// Pass it a callback to our connect() method, so it can send events
|
||||
|
|
@ -146,7 +145,9 @@ public:
|
|||
.listen("LLLeap", boost::bind(&LLLeapImpl::rstderr, this, _1));
|
||||
|
||||
// For our lifespan, intercept any LL_ERRS so we can notify plugin
|
||||
LLError::setFatalFunction(boost::bind(&LLLeapImpl::fatalFunction, this, _1));
|
||||
mRecorder = LLError::addGenericRecorder(
|
||||
[this](LLError::ELevel level, const std::string& message)
|
||||
{ onError(level, message); });
|
||||
|
||||
// Send child a preliminary event reporting our own reply-pump name --
|
||||
// which would otherwise be pretty tricky to guess!
|
||||
|
|
@ -162,8 +163,7 @@ public:
|
|||
virtual ~LLLeapImpl()
|
||||
{
|
||||
LL_DEBUGS("LLLeap") << "destroying LLLeap(\"" << mDesc << "\")" << LL_ENDL;
|
||||
// Restore original FatalFunction
|
||||
LLError::setFatalFunction(mPrevFatalFunction);
|
||||
LLError::removeRecorder(mRecorder);
|
||||
}
|
||||
|
||||
// Listener for failed launch attempt
|
||||
|
|
@ -377,28 +377,28 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
void fatalFunction(const std::string& error)
|
||||
void onError(LLError::ELevel level, const std::string& error)
|
||||
{
|
||||
// Notify plugin
|
||||
LLSD event;
|
||||
event["type"] = "error";
|
||||
event["error"] = error;
|
||||
mReplyPump.post(event);
|
||||
|
||||
// All the above really accomplished was to buffer the serialized
|
||||
// event in our WritePipe. Have to pump mainloop a couple times to
|
||||
// really write it out there... but time out in case we can't write.
|
||||
LLProcess::WritePipe& childin(mChild->getWritePipe(LLProcess::STDIN));
|
||||
LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop"));
|
||||
LLSD nop;
|
||||
F64 until = (LLTimer::getElapsedSeconds() + 2).value();
|
||||
while (childin.size() && LLTimer::getElapsedSeconds() < until)
|
||||
if (level == LLError::LEVEL_ERROR)
|
||||
{
|
||||
mainloop.post(nop);
|
||||
}
|
||||
// Notify plugin
|
||||
LLSD event;
|
||||
event["type"] = "error";
|
||||
event["error"] = error;
|
||||
mReplyPump.post(event);
|
||||
|
||||
// forward the call to the previous FatalFunction
|
||||
mPrevFatalFunction(error);
|
||||
// All the above really accomplished was to buffer the serialized
|
||||
// event in our WritePipe. Have to pump mainloop a couple times to
|
||||
// really write it out there... but time out in case we can't write.
|
||||
LLProcess::WritePipe& childin(mChild->getWritePipe(LLProcess::STDIN));
|
||||
LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop"));
|
||||
LLSD nop;
|
||||
F64 until = (LLTimer::getElapsedSeconds() + 2).value();
|
||||
while (childin.size() && LLTimer::getElapsedSeconds() < until)
|
||||
{
|
||||
mainloop.post(nop);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -421,7 +421,7 @@ private:
|
|||
mStdinConnection, mStdoutConnection, mStdoutDataConnection, mStderrConnection;
|
||||
boost::scoped_ptr<LLEventPump::Blocker> mBlocker;
|
||||
LLProcess::ReadPipe::size_type mExpect;
|
||||
LLError::FatalFunction mPrevFatalFunction;
|
||||
LLError::RecorderPtr mRecorder;
|
||||
boost::scoped_ptr<LLLeapListener> mListener;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -38,11 +38,6 @@
|
|||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace {
|
||||
void log(LLError::ELevel level,
|
||||
const char* p1, const char* p2, const char* p3, const char* p4);
|
||||
} // anonymous namespace
|
||||
|
||||
// Our master list of all LLSingletons is itself an LLSingleton. We used to
|
||||
// store it in a function-local static, but that could get destroyed before
|
||||
// the last of the LLSingletons -- and ~LLSingletonBase() definitely wants to
|
||||
|
|
@ -218,8 +213,8 @@ void LLSingletonBase::pop_initializing()
|
|||
|
||||
if (list.empty())
|
||||
{
|
||||
logerrs("Underflow in stack of currently-initializing LLSingletons at ",
|
||||
classname(this).c_str(), "::getInstance()");
|
||||
logerrs({"Underflow in stack of currently-initializing LLSingletons at ",
|
||||
classname(this), "::getInstance()"});
|
||||
}
|
||||
|
||||
// Now we know list.back() exists: capture it
|
||||
|
|
@ -240,9 +235,9 @@ void LLSingletonBase::pop_initializing()
|
|||
// Now validate the newly-popped LLSingleton.
|
||||
if (back != this)
|
||||
{
|
||||
logerrs("Push/pop mismatch in stack of currently-initializing LLSingletons: ",
|
||||
classname(this).c_str(), "::getInstance() trying to pop ",
|
||||
classname(back).c_str());
|
||||
logerrs({"Push/pop mismatch in stack of currently-initializing LLSingletons: ",
|
||||
classname(this), "::getInstance() trying to pop ",
|
||||
classname(back)});
|
||||
}
|
||||
|
||||
// log AFTER popping so logging singletons don't cry circularity
|
||||
|
|
@ -331,15 +326,15 @@ void LLSingletonBase::capture_dependency()
|
|||
//
|
||||
// Example: LLNotifications singleton initializes default channels.
|
||||
// Channels register themselves with singleton once done.
|
||||
logdebugs("LLSingleton circularity: ", out.str().c_str(),
|
||||
classname(this).c_str(), "");
|
||||
logdebugs({"LLSingleton circularity: ", out.str(),
|
||||
classname(this)});
|
||||
}
|
||||
else
|
||||
{
|
||||
// Actual circularity with other singleton (or single singleton is used extensively).
|
||||
// Dependency can be unclear.
|
||||
logwarns("LLSingleton circularity: ", out.str().c_str(),
|
||||
classname(this).c_str(), "");
|
||||
logwarns({"LLSingleton circularity: ", out.str(),
|
||||
classname(this)});
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -352,8 +347,8 @@ void LLSingletonBase::capture_dependency()
|
|||
if (current->mDepends.insert(this).second)
|
||||
{
|
||||
// only log the FIRST time we hit this dependency!
|
||||
logdebugs(classname(current).c_str(),
|
||||
" depends on ", classname(this).c_str());
|
||||
logdebugs({classname(current),
|
||||
" depends on ", classname(this)});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -401,7 +396,7 @@ LLSingletonBase::vec_t LLSingletonBase::dep_sort()
|
|||
|
||||
void LLSingletonBase::cleanup_()
|
||||
{
|
||||
logdebugs("calling ", classname(this).c_str(), "::cleanupSingleton()");
|
||||
logdebugs({"calling ", classname(this), "::cleanupSingleton()"});
|
||||
try
|
||||
{
|
||||
cleanupSingleton();
|
||||
|
|
@ -427,23 +422,23 @@ void LLSingletonBase::deleteAll()
|
|||
if (! sp->mDeleteSingleton)
|
||||
{
|
||||
// This Should Not Happen... but carry on.
|
||||
logwarns(name.c_str(), "::mDeleteSingleton not initialized!");
|
||||
logwarns({name, "::mDeleteSingleton not initialized!"});
|
||||
}
|
||||
else
|
||||
{
|
||||
// properly initialized: call it.
|
||||
logdebugs("calling ", name.c_str(), "::deleteSingleton()");
|
||||
logdebugs({"calling ", name, "::deleteSingleton()"});
|
||||
// From this point on, DO NOT DEREFERENCE sp!
|
||||
sp->mDeleteSingleton();
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
logwarns("Exception in ", name.c_str(), "::deleteSingleton(): ", e.what());
|
||||
logwarns({"Exception in ", name, "::deleteSingleton(): ", e.what()});
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
logwarns("Unknown exception in ", name.c_str(), "::deleteSingleton()");
|
||||
logwarns({"Unknown exception in ", name, "::deleteSingleton()"});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -451,49 +446,40 @@ void LLSingletonBase::deleteAll()
|
|||
/*---------------------------- Logging helpers -----------------------------*/
|
||||
namespace {
|
||||
|
||||
void log(LLError::ELevel level,
|
||||
const char* p1, const char* p2, const char* p3, const char* p4)
|
||||
std::ostream& operator<<(std::ostream& out, const LLSingletonBase::string_params& args)
|
||||
{
|
||||
LL_VLOGS(level, "LLSingleton") << p1 << p2 << p3 << p4 << LL_ENDL;
|
||||
// However many args there are in args, stream each of them to 'out'.
|
||||
for (auto arg : args)
|
||||
{
|
||||
out << arg;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
//static
|
||||
void LLSingletonBase::logwarns(const char* p1, const char* p2, const char* p3, const char* p4)
|
||||
void LLSingletonBase::logwarns(const string_params& args)
|
||||
{
|
||||
log(LLError::LEVEL_WARN, p1, p2, p3, p4);
|
||||
LL_WARNS("LLSingleton") << args << LL_ENDL;
|
||||
}
|
||||
|
||||
//static
|
||||
void LLSingletonBase::loginfos(const char* p1, const char* p2, const char* p3, const char* p4)
|
||||
void LLSingletonBase::loginfos(const string_params& args)
|
||||
{
|
||||
log(LLError::LEVEL_INFO, p1, p2, p3, p4);
|
||||
LL_INFOS("LLSingleton") << args << LL_ENDL;
|
||||
}
|
||||
|
||||
//static
|
||||
void LLSingletonBase::logdebugs(const char* p1, const char* p2, const char* p3, const char* p4)
|
||||
void LLSingletonBase::logdebugs(const string_params& args)
|
||||
{
|
||||
log(LLError::LEVEL_DEBUG, p1, p2, p3, p4);
|
||||
LL_DEBUGS("LLSingleton") << args << LL_ENDL;
|
||||
}
|
||||
|
||||
//static
|
||||
void LLSingletonBase::logerrs(const char* p1, const char* p2, const char* p3, const char* p4)
|
||||
void LLSingletonBase::logerrs(const string_params& args)
|
||||
{
|
||||
log(LLError::LEVEL_ERROR, p1, p2, p3, p4);
|
||||
// The other important side effect of LL_ERRS() is
|
||||
// https://www.youtube.com/watch?v=OMG7paGJqhQ (emphasis on OMG)
|
||||
std::ostringstream out;
|
||||
out << p1 << p2 << p3 << p4;
|
||||
auto crash = LLError::getFatalFunction();
|
||||
if (crash)
|
||||
{
|
||||
crash(out.str());
|
||||
}
|
||||
else
|
||||
{
|
||||
LLError::crashAndLoop(out.str());
|
||||
}
|
||||
LL_ERRS("LLSingleton") << args << LL_ENDL;
|
||||
}
|
||||
|
||||
std::string LLSingletonBase::demangle(const char* mangled)
|
||||
|
|
|
|||
|
|
@ -27,9 +27,10 @@
|
|||
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <initializer_list>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <typeinfo>
|
||||
#include <vector>
|
||||
#include "mutex.h"
|
||||
#include "lockstatic.h"
|
||||
#include "llthread.h" // on_main_thread()
|
||||
|
|
@ -111,14 +112,13 @@ protected:
|
|||
void capture_dependency();
|
||||
|
||||
// delegate logging calls to llsingleton.cpp
|
||||
static void logerrs(const char* p1, const char* p2="",
|
||||
const char* p3="", const char* p4="");
|
||||
static void logwarns(const char* p1, const char* p2="",
|
||||
const char* p3="", const char* p4="");
|
||||
static void loginfos(const char* p1, const char* p2="",
|
||||
const char* p3="", const char* p4="");
|
||||
static void logdebugs(const char* p1, const char* p2="",
|
||||
const char* p3="", const char* p4="");
|
||||
public:
|
||||
typedef std::initializer_list<const std::string> string_params;
|
||||
protected:
|
||||
static void logerrs (const string_params&);
|
||||
static void logwarns (const string_params&);
|
||||
static void loginfos (const string_params&);
|
||||
static void logdebugs(const string_params&);
|
||||
static std::string demangle(const char* mangled);
|
||||
// these classname() declarations restate template functions declared in
|
||||
// llerror.h because we avoid #including that here
|
||||
|
|
@ -368,8 +368,8 @@ private:
|
|||
// init stack to its previous size BEFORE logging so log-machinery
|
||||
// LLSingletons don't record a dependency on DERIVED_TYPE!
|
||||
LLSingleton_manage_master<DERIVED_TYPE>().reset_initializing(prev_size);
|
||||
logwarns("Error constructing ", classname<DERIVED_TYPE>().c_str(),
|
||||
": ", err.what());
|
||||
logwarns({"Error constructing ", classname<DERIVED_TYPE>(),
|
||||
": ", err.what()});
|
||||
// There isn't a separate EInitState value meaning "we attempted
|
||||
// to construct this LLSingleton subclass but could not," so use
|
||||
// DELETED. That seems slightly more appropriate than UNINITIALIZED.
|
||||
|
|
@ -397,8 +397,8 @@ private:
|
|||
// BEFORE logging, so log-machinery LLSingletons don't record a
|
||||
// dependency on DERIVED_TYPE!
|
||||
pop_initializing(lk->mInstance);
|
||||
logwarns("Error in ", classname<DERIVED_TYPE>().c_str(),
|
||||
"::initSingleton(): ", err.what());
|
||||
logwarns({"Error in ", classname<DERIVED_TYPE>(),
|
||||
"::initSingleton(): ", err.what()});
|
||||
// Get rid of the instance entirely. This call depends on our
|
||||
// recursive_mutex. We could have a deleteSingleton(LockStatic&)
|
||||
// overload and pass lk, but we don't strictly need it.
|
||||
|
|
@ -547,9 +547,9 @@ public:
|
|||
case CONSTRUCTING:
|
||||
// here if DERIVED_TYPE's constructor (directly or indirectly)
|
||||
// calls DERIVED_TYPE::getInstance()
|
||||
logerrs("Tried to access singleton ",
|
||||
classname<DERIVED_TYPE>().c_str(),
|
||||
" from singleton constructor!");
|
||||
logerrs({"Tried to access singleton ",
|
||||
classname<DERIVED_TYPE>(),
|
||||
" from singleton constructor!"});
|
||||
return nullptr;
|
||||
|
||||
case INITIALIZING:
|
||||
|
|
@ -564,9 +564,9 @@ public:
|
|||
|
||||
case DELETED:
|
||||
// called after deleteSingleton()
|
||||
logwarns("Trying to access deleted singleton ",
|
||||
classname<DERIVED_TYPE>().c_str(),
|
||||
" -- creating new instance");
|
||||
logwarns({"Trying to access deleted singleton ",
|
||||
classname<DERIVED_TYPE>(),
|
||||
" -- creating new instance"});
|
||||
// fall through
|
||||
case UNINITIALIZED:
|
||||
case QUEUED:
|
||||
|
|
@ -593,8 +593,8 @@ public:
|
|||
} // unlock 'lk'
|
||||
|
||||
// Per the comment block above, dispatch to the main thread.
|
||||
loginfos(classname<DERIVED_TYPE>().c_str(),
|
||||
"::getInstance() dispatching to main thread");
|
||||
loginfos({classname<DERIVED_TYPE>(),
|
||||
"::getInstance() dispatching to main thread"});
|
||||
auto instance = LLMainThreadTask::dispatch(
|
||||
[](){
|
||||
// VERY IMPORTANT to call getInstance() on the main thread,
|
||||
|
|
@ -604,16 +604,16 @@ public:
|
|||
// the main thread processes them, only the FIRST such request
|
||||
// actually constructs the instance -- every subsequent one
|
||||
// simply returns the existing instance.
|
||||
loginfos(classname<DERIVED_TYPE>().c_str(),
|
||||
"::getInstance() on main thread");
|
||||
loginfos({classname<DERIVED_TYPE>(),
|
||||
"::getInstance() on main thread"});
|
||||
return getInstance();
|
||||
});
|
||||
// record the dependency chain tracked on THIS thread, not the main
|
||||
// thread (consider a getInstance() overload with a tag param that
|
||||
// suppresses dep tracking when dispatched to the main thread)
|
||||
capture_dependency(instance);
|
||||
loginfos(classname<DERIVED_TYPE>().c_str(),
|
||||
"::getInstance() returning on requesting thread");
|
||||
loginfos({classname<DERIVED_TYPE>(),
|
||||
"::getInstance() returning on requesting thread"});
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
|
@ -682,16 +682,16 @@ private:
|
|||
// For organizational purposes this function shouldn't be called twice
|
||||
if (lk->mInitState != super::UNINITIALIZED)
|
||||
{
|
||||
super::logerrs("Tried to initialize singleton ",
|
||||
super::template classname<DERIVED_TYPE>().c_str(),
|
||||
" twice!");
|
||||
super::logerrs({"Tried to initialize singleton ",
|
||||
super::template classname<DERIVED_TYPE>(),
|
||||
" twice!"});
|
||||
return nullptr;
|
||||
}
|
||||
else if (on_main_thread())
|
||||
{
|
||||
// on the main thread, simply construct instance while holding lock
|
||||
super::logdebugs(super::template classname<DERIVED_TYPE>().c_str(),
|
||||
"::initParamSingleton()");
|
||||
super::logdebugs({super::template classname<DERIVED_TYPE>(),
|
||||
"::initParamSingleton()"});
|
||||
super::constructSingleton(lk, std::forward<Args>(args)...);
|
||||
return lk->mInstance;
|
||||
}
|
||||
|
|
@ -703,8 +703,8 @@ private:
|
|||
lk->mInitState = super::QUEUED;
|
||||
// very important to unlock here so main thread can actually process
|
||||
lk.unlock();
|
||||
super::loginfos(super::template classname<DERIVED_TYPE>().c_str(),
|
||||
"::initParamSingleton() dispatching to main thread");
|
||||
super::loginfos({super::template classname<DERIVED_TYPE>(),
|
||||
"::initParamSingleton() dispatching to main thread"});
|
||||
// Normally it would be the height of folly to reference-bind
|
||||
// 'args' into a lambda to be executed on some other thread! By
|
||||
// the time that thread executed the lambda, the references would
|
||||
|
|
@ -715,12 +715,12 @@ private:
|
|||
// references.
|
||||
auto instance = LLMainThreadTask::dispatch(
|
||||
[&](){
|
||||
super::loginfos(super::template classname<DERIVED_TYPE>().c_str(),
|
||||
"::initParamSingleton() on main thread");
|
||||
super::loginfos({super::template classname<DERIVED_TYPE>(),
|
||||
"::initParamSingleton() on main thread"});
|
||||
return initParamSingleton_(std::forward<Args>(args)...);
|
||||
});
|
||||
super::loginfos(super::template classname<DERIVED_TYPE>().c_str(),
|
||||
"::initParamSingleton() returning on requesting thread");
|
||||
super::loginfos({super::template classname<DERIVED_TYPE>(),
|
||||
"::initParamSingleton() returning on requesting thread"});
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
|
@ -748,14 +748,14 @@ public:
|
|||
{
|
||||
case super::UNINITIALIZED:
|
||||
case super::QUEUED:
|
||||
super::logerrs("Uninitialized param singleton ",
|
||||
super::template classname<DERIVED_TYPE>().c_str());
|
||||
super::logerrs({"Uninitialized param singleton ",
|
||||
super::template classname<DERIVED_TYPE>()});
|
||||
break;
|
||||
|
||||
case super::CONSTRUCTING:
|
||||
super::logerrs("Tried to access param singleton ",
|
||||
super::template classname<DERIVED_TYPE>().c_str(),
|
||||
" from singleton constructor!");
|
||||
super::logerrs({"Tried to access param singleton ",
|
||||
super::template classname<DERIVED_TYPE>(),
|
||||
" from singleton constructor!"});
|
||||
break;
|
||||
|
||||
case super::INITIALIZING:
|
||||
|
|
@ -767,8 +767,8 @@ public:
|
|||
return lk->mInstance;
|
||||
|
||||
case super::DELETED:
|
||||
super::logerrs("Trying to access deleted param singleton ",
|
||||
super::template classname<DERIVED_TYPE>().c_str());
|
||||
super::logerrs({"Trying to access deleted param singleton ",
|
||||
super::template classname<DERIVED_TYPE>()});
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -358,8 +358,9 @@ void LLThread::setQuitting()
|
|||
{
|
||||
mStatus = QUITTING;
|
||||
}
|
||||
// It's only safe to remove mRunCondition if all locked threads were notified
|
||||
mRunCondition->broadcast();
|
||||
mDataLock->unlock();
|
||||
wake();
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
|
|||
|
|
@ -280,7 +280,7 @@ std::string LLURI::escapePathAndData(const std::string &str)
|
|||
std::string fragment;
|
||||
|
||||
size_t fragment_pos = str.find('#');
|
||||
if (fragment_pos != std::string::npos)
|
||||
if ((fragment_pos != std::string::npos) && (fragment_pos > delim_pos))
|
||||
{
|
||||
query = str.substr(path_size, fragment_pos - path_size);
|
||||
fragment = str.substr(fragment_pos);
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
*/
|
||||
|
||||
#include <vector>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "linden_common.h"
|
||||
|
||||
|
|
@ -69,21 +70,41 @@ namespace
|
|||
|
||||
namespace
|
||||
{
|
||||
static bool fatalWasCalled;
|
||||
void fatalCall(const std::string&) { fatalWasCalled = true; }
|
||||
static bool fatalWasCalled = false;
|
||||
struct FatalWasCalled: public std::runtime_error
|
||||
{
|
||||
FatalWasCalled(const std::string& what): std::runtime_error(what) {}
|
||||
};
|
||||
void fatalCall(const std::string& msg) { throw FatalWasCalled(msg); }
|
||||
}
|
||||
|
||||
// Because we use LLError::setFatalFunction(fatalCall), any LL_ERRS call we
|
||||
// issue will throw FatalWasCalled. But we want the test program to continue.
|
||||
// So instead of writing:
|
||||
// LL_ERRS("tag") << "some message" << LL_ENDL;
|
||||
// write:
|
||||
// CATCH(LL_ERRS("tag"), "some message");
|
||||
#define CATCH(logcall, expr) \
|
||||
try \
|
||||
{ \
|
||||
logcall << expr << LL_ENDL; \
|
||||
} \
|
||||
catch (const FatalWasCalled&) \
|
||||
{ \
|
||||
fatalWasCalled = true; \
|
||||
}
|
||||
|
||||
namespace tut
|
||||
{
|
||||
class TestRecorder : public LLError::Recorder
|
||||
{
|
||||
public:
|
||||
TestRecorder()
|
||||
{
|
||||
showTime(false);
|
||||
}
|
||||
{
|
||||
showTime(false);
|
||||
}
|
||||
virtual ~TestRecorder()
|
||||
{}
|
||||
{}
|
||||
|
||||
virtual void recordMessage(LLError::ELevel level,
|
||||
const std::string& message)
|
||||
|
|
@ -252,7 +273,7 @@ namespace
|
|||
LL_DEBUGS("WriteTag","AnotherTag") << "one" << LL_ENDL;
|
||||
LL_INFOS("WriteTag") << "two" << LL_ENDL;
|
||||
LL_WARNS("WriteTag") << "three" << LL_ENDL;
|
||||
LL_ERRS("WriteTag") << "four" << LL_ENDL;
|
||||
CATCH(LL_ERRS("WriteTag"), "four");
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -380,7 +401,7 @@ namespace
|
|||
|
||||
std::string errorReturningLocation()
|
||||
{
|
||||
LL_ERRS() << "die" << LL_ENDL; int this_line = __LINE__;
|
||||
int this_line = __LINE__; CATCH(LL_ERRS(), "die");
|
||||
return locationString(this_line);
|
||||
}
|
||||
}
|
||||
|
|
@ -701,7 +722,7 @@ public:
|
|||
static void doDebug() { LL_DEBUGS() << "add dice" << LL_ENDL; }
|
||||
static void doInfo() { LL_INFOS() << "any idea" << LL_ENDL; }
|
||||
static void doWarn() { LL_WARNS() << "aim west" << LL_ENDL; }
|
||||
static void doError() { LL_ERRS() << "ate eels" << LL_ENDL; }
|
||||
static void doError() { CATCH(LL_ERRS(), "ate eels"); }
|
||||
static void doAll() { doDebug(); doInfo(); doWarn(); doError(); }
|
||||
};
|
||||
|
||||
|
|
@ -712,7 +733,7 @@ public:
|
|||
static void doDebug() { LL_DEBUGS() << "bed down" << LL_ENDL; }
|
||||
static void doInfo() { LL_INFOS() << "buy iron" << LL_ENDL; }
|
||||
static void doWarn() { LL_WARNS() << "bad word" << LL_ENDL; }
|
||||
static void doError() { LL_ERRS() << "big easy" << LL_ENDL; }
|
||||
static void doError() { CATCH(LL_ERRS(), "big easy"); }
|
||||
static void doAll() { doDebug(); doInfo(); doWarn(); doError(); }
|
||||
};
|
||||
|
||||
|
|
@ -874,13 +895,10 @@ namespace tut
|
|||
namespace
|
||||
{
|
||||
std::string writeTagWithSpaceReturningLocation()
|
||||
{
|
||||
LL_DEBUGS("Write Tag") << "not allowed" << LL_ENDL; int this_line = __LINE__;
|
||||
|
||||
std::ostringstream location;
|
||||
location << LLError::abbreviateFile(__FILE__).c_str() << "(" << this_line << ")";
|
||||
return location.str();
|
||||
}
|
||||
{
|
||||
int this_line = __LINE__; CATCH(LL_DEBUGS("Write Tag"), "not allowed");
|
||||
return locationString(this_line);
|
||||
}
|
||||
};
|
||||
|
||||
namespace tut
|
||||
|
|
@ -894,9 +912,9 @@ namespace tut
|
|||
|
||||
std::string location = writeTagWithSpaceReturningLocation();
|
||||
std::string expected = "Space is not allowed in a log tag at " + location;
|
||||
ensure_message_field_equals(0, LEVEL_FIELD, "ERROR");
|
||||
ensure_message_field_equals(0, MSG_FIELD, expected);
|
||||
ensure("fatal callback called", fatalWasCalled);
|
||||
ensure_message_field_equals(0, LEVEL_FIELD, "ERROR");
|
||||
ensure_message_field_equals(0, MSG_FIELD, expected);
|
||||
ensure("fatal callback called", fatalWasCalled);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -44,10 +44,6 @@
|
|||
#include <list>
|
||||
#include <string>
|
||||
|
||||
// statically reference the function in test.cpp... it's short, we could
|
||||
// replicate, but better to reuse
|
||||
extern void wouldHaveCrashed(const std::string& message);
|
||||
|
||||
struct WrapLLErrs
|
||||
{
|
||||
WrapLLErrs():
|
||||
|
|
@ -59,7 +55,8 @@ struct WrapLLErrs
|
|||
mPriorFatal(LLError::getFatalFunction())
|
||||
{
|
||||
// Make LL_ERRS call our own operator() method
|
||||
LLError::setFatalFunction(boost::bind(&WrapLLErrs::operator(), this, _1));
|
||||
LLError::setFatalFunction(
|
||||
[this](const std::string& message){ (*this)(message); });
|
||||
}
|
||||
|
||||
~WrapLLErrs()
|
||||
|
|
@ -199,11 +196,13 @@ public:
|
|||
// with that output. If it turns out that saveAndResetSettings() has
|
||||
// some bad effect, give up and just let the DEBUG level log messages
|
||||
// display.
|
||||
: boost::noncopyable(),
|
||||
: boost::noncopyable(),
|
||||
mFatalFunction(LLError::getFatalFunction()),
|
||||
mOldSettings(LLError::saveAndResetSettings()),
|
||||
mRecorder(new CaptureLogRecorder())
|
||||
mRecorder(new CaptureLogRecorder())
|
||||
{
|
||||
LLError::setFatalFunction(wouldHaveCrashed);
|
||||
// reinstate the FatalFunction we just reset
|
||||
LLError::setFatalFunction(mFatalFunction);
|
||||
LLError::setDefaultLevel(level);
|
||||
LLError::addRecorder(mRecorder);
|
||||
}
|
||||
|
|
@ -219,17 +218,18 @@ public:
|
|||
/// for the sought string.
|
||||
std::string messageWith(const std::string& search, bool required=true)
|
||||
{
|
||||
return boost::dynamic_pointer_cast<CaptureLogRecorder>(mRecorder)->messageWith(search, required);
|
||||
return boost::dynamic_pointer_cast<CaptureLogRecorder>(mRecorder)->messageWith(search, required);
|
||||
}
|
||||
|
||||
std::ostream& streamto(std::ostream& out) const
|
||||
{
|
||||
return boost::dynamic_pointer_cast<CaptureLogRecorder>(mRecorder)->streamto(out);
|
||||
return boost::dynamic_pointer_cast<CaptureLogRecorder>(mRecorder)->streamto(out);
|
||||
}
|
||||
|
||||
private:
|
||||
LLError::FatalFunction mFatalFunction;
|
||||
LLError::SettingsStoragePtr mOldSettings;
|
||||
LLError::RecorderPtr mRecorder;
|
||||
LLError::RecorderPtr mRecorder;
|
||||
};
|
||||
|
||||
#endif /* ! defined(LL_WRAPLLERRS_H) */
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ include(LLAddBuildTest)
|
|||
include(LLMessage)
|
||||
include(LLCommon)
|
||||
include(Tut)
|
||||
include(bugsplat)
|
||||
|
||||
include_directories (${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
|
|
|
|||
|
|
@ -56,7 +56,6 @@ void HttpReplyQueue::addOp(const HttpReplyQueue::opPtr_t &op)
|
|||
|
||||
mQueue.push_back(op);
|
||||
}
|
||||
mQueueCV.notify_all();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -98,7 +98,6 @@ protected:
|
|||
|
||||
OpContainer mQueue;
|
||||
LLCoreInt::HttpMutex mQueueMutex;
|
||||
LLCoreInt::HttpConditionVariable mQueueCV;
|
||||
|
||||
}; // end class HttpReplyQueue
|
||||
|
||||
|
|
|
|||
|
|
@ -142,13 +142,19 @@ void HttpRequestQueue::wakeAll()
|
|||
}
|
||||
|
||||
|
||||
void HttpRequestQueue::stopQueue()
|
||||
bool HttpRequestQueue::stopQueue()
|
||||
{
|
||||
{
|
||||
HttpScopedLock lock(mQueueMutex);
|
||||
|
||||
mQueueStopped = true;
|
||||
wakeAll();
|
||||
if (!mQueueStopped)
|
||||
{
|
||||
mQueueStopped = true;
|
||||
wakeAll();
|
||||
return true;
|
||||
}
|
||||
wakeAll();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ public:
|
|||
/// them on their way.
|
||||
///
|
||||
/// Threading: callable by any thread.
|
||||
void stopQueue();
|
||||
bool stopQueue();
|
||||
|
||||
protected:
|
||||
static HttpRequestQueue * sInstance;
|
||||
|
|
|
|||
|
|
@ -87,7 +87,11 @@ HttpService::~HttpService()
|
|||
// is a bit tricky.
|
||||
if (mRequestQueue)
|
||||
{
|
||||
mRequestQueue->stopQueue();
|
||||
if (mRequestQueue->stopQueue())
|
||||
{
|
||||
// Give mRequestQueue a chance to finish
|
||||
ms_sleep(10);
|
||||
}
|
||||
}
|
||||
|
||||
if (mThread)
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
namespace LLCore
|
||||
{
|
||||
|
||||
bool HttpOptions::sDefaultVerifyPeer = false;
|
||||
|
||||
HttpOptions::HttpOptions() :
|
||||
mWantHeaders(false),
|
||||
|
|
@ -43,7 +44,7 @@ HttpOptions::HttpOptions() :
|
|||
mMaxRetryBackoff(HTTP_RETRY_BACKOFF_MAX_DEFAULT),
|
||||
mUseRetryAfter(HTTP_USE_RETRY_AFTER_DEFAULT),
|
||||
mFollowRedirects(true),
|
||||
mVerifyPeer(false),
|
||||
mVerifyPeer(sDefaultVerifyPeer),
|
||||
mVerifyHost(false),
|
||||
mDNSCacheTimeout(-1L),
|
||||
mNoBody(false),
|
||||
|
|
@ -123,7 +124,15 @@ void HttpOptions::setHeadersOnly(bool nobody)
|
|||
{
|
||||
mNoBody = nobody;
|
||||
if (mNoBody)
|
||||
{
|
||||
setWantHeaders(true);
|
||||
setSSLVerifyPeer(false);
|
||||
}
|
||||
}
|
||||
|
||||
void HttpOptions::setDefaultSSLVerifyPeer(bool verify)
|
||||
{
|
||||
sDefaultVerifyPeer = verify;
|
||||
}
|
||||
|
||||
// <FS:Ansariel> GetIfModified request
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ public:
|
|||
|
||||
/// Instructs the LLCore::HTTPRequest to verify that the exchanged security
|
||||
/// certificate is authentic.
|
||||
/// Default: false
|
||||
/// Default: sDefaultVerifyPeer
|
||||
void setSSLVerifyPeer(bool verify);
|
||||
bool getSSLVerifyPeer() const
|
||||
{
|
||||
|
|
@ -178,6 +178,13 @@ public:
|
|||
return mNoBody;
|
||||
}
|
||||
|
||||
/// Sets default behavior for verifying that the name in the
|
||||
/// security certificate matches the name of the host contacted.
|
||||
/// Defaults false if not set, but should be set according to
|
||||
/// viewer's initialization options and command argunments, see
|
||||
/// NoVerifySSLCert
|
||||
static void setDefaultSSLVerifyPeer(bool verify);
|
||||
|
||||
// <FS:Ansariel> GetIfModified request
|
||||
void setLastModified(long last_modified);
|
||||
long getLastModified() const
|
||||
|
|
@ -200,6 +207,9 @@ protected:
|
|||
bool mVerifyHost;
|
||||
int mDNSCacheTimeout;
|
||||
bool mNoBody;
|
||||
|
||||
static bool sDefaultVerifyPeer;
|
||||
|
||||
long mLastModified; // <FS:Ansariel> GetIfModified request
|
||||
}; // end class HttpOptions
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
This component is no longer used in Linden Lab builds.
|
||||
Change requests to support continued use by open source
|
||||
builds are welcome.
|
||||
|
|
@ -520,6 +520,7 @@ bool LLCrashLogger::runCrashLogPost(std::string host, LLSD data, std::string msg
|
|||
LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
|
||||
|
||||
httpOpts->setTimeout(timeout);
|
||||
httpOpts->setSSLVerifyPeer(false);
|
||||
|
||||
for(int i = 0; i < retries; ++i)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -62,6 +62,11 @@ LLDiskCache::LLDiskCache(const std::string cache_dir,
|
|||
LLFile::mkdir(dirname);
|
||||
}
|
||||
// </FS:Ansariel>
|
||||
// <FS:Beq> add static assets into the new cache after clear.
|
||||
// Only missing entries are copied on init, skiplist is setup
|
||||
// For everything we populate FS specific assets to allow future updates
|
||||
prepopulateCacheWithStatic();
|
||||
// </FS:Beq>
|
||||
}
|
||||
|
||||
void LLDiskCache::purge()
|
||||
|
|
@ -117,6 +122,11 @@ void LLDiskCache::purge()
|
|||
|
||||
LL_INFOS() << "Purging cache to a maximum of " << mMaxSizeBytes << " bytes" << LL_ENDL;
|
||||
|
||||
// <FS:Beq> Extra accounting to track the retention of static assets
|
||||
int keep{0};
|
||||
int del{0};
|
||||
int skip{0};
|
||||
// </FS:Beq>
|
||||
uintmax_t file_size_total = 0;
|
||||
for (file_info_t& entry : file_info)
|
||||
{
|
||||
|
|
@ -126,17 +136,34 @@ void LLDiskCache::purge()
|
|||
if (file_size_total > mMaxSizeBytes)
|
||||
{
|
||||
action = "DELETE:";
|
||||
// <FS:Ansariel> Do not crash if we cannot delete the file for some reason
|
||||
//boost::filesystem::remove(entry.second.second);
|
||||
boost::filesystem::remove(entry.second.second, ec);
|
||||
if (ec.failed())
|
||||
// <FS:Beq> Make sure static assets are not eliminated
|
||||
auto uuid_as_string = gDirUtilp->getBaseFileName(entry.second.second,true);
|
||||
uuid_as_string = uuid_as_string.substr(mCacheFilenamePrefix.size() + 1, 36);// skip "sl_cache_" and trailing "_N"
|
||||
// LL_INFOS() << "checking UUID=" <<uuid_as_string<< LL_ENDL;
|
||||
if (std::find(mSkipList.begin(), mSkipList.end(), uuid_as_string) != mSkipList.end())
|
||||
{
|
||||
LL_WARNS() << "Failed to delete cache file " << entry.second.second << ": " << ec.message() << LL_ENDL;
|
||||
// this is one of our protected items so no purging
|
||||
action = "STATIC:";
|
||||
skip++;
|
||||
updateFileAccessTime(entry.second.second); // force these to the front of the list next time so that purge size works
|
||||
}
|
||||
else
|
||||
{
|
||||
del++; // Extra accounting to track the retention of static assets
|
||||
// </FS:Beq>
|
||||
// <FS:Ansariel> Do not crash if we cannot delete the file for some reason
|
||||
//boost::filesystem::remove(entry.second.second);
|
||||
boost::filesystem::remove(entry.second.second, ec);
|
||||
if (ec.failed())
|
||||
{
|
||||
LL_WARNS() << "Failed to delete cache file " << entry.second.second << ": " << ec.message() << LL_ENDL;
|
||||
}
|
||||
}
|
||||
// </FS:Ansariel>
|
||||
}
|
||||
else
|
||||
{
|
||||
keep++; // <FS:Beq/> Extra accounting to track the retention of static assets
|
||||
action = " KEEP:";
|
||||
}
|
||||
|
||||
|
|
@ -160,6 +187,7 @@ void LLDiskCache::purge()
|
|||
auto execute_time = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time).count();
|
||||
LL_INFOS() << "Total dir size after purge is " << dirFileSize(mCacheDir) << 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; // <FS:Beq/> Extra accounting to track the retention of static assets
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -321,8 +349,57 @@ const std::string LLDiskCache::getCacheInfo()
|
|||
return cache_info.str();
|
||||
}
|
||||
|
||||
// <FS:Beq> Copy static items into cache and add to the skip list that prevents their purging
|
||||
// Note that there is no de-duplication nor other validation of the list.
|
||||
void LLDiskCache::prepopulateCacheWithStatic()
|
||||
{
|
||||
mSkipList.clear();
|
||||
|
||||
std::vector<std::string> from_folders;
|
||||
from_folders.emplace_back(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "fs_static_assets"));
|
||||
#ifdef OPENSIM
|
||||
from_folders.emplace_back(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "static_assets"));
|
||||
#endif
|
||||
|
||||
for (const auto& from_folder : from_folders)
|
||||
{
|
||||
if (gDirUtilp->fileExists(from_folder))
|
||||
{
|
||||
auto assets_to_copy = gDirUtilp->getFilesInDir(from_folder);
|
||||
for (auto from_asset_file : assets_to_copy)
|
||||
{
|
||||
from_asset_file = from_folder + gDirUtilp->getDirDelimiter() + from_asset_file;
|
||||
// we store static assets as UUID.asset_type the asset_type is not used in the current simple cache format
|
||||
auto uuid_as_string{ gDirUtilp->getBaseFileName(from_asset_file, true) };
|
||||
auto to_asset_file = metaDataToFilepath(uuid_as_string, LLAssetType::AT_UNKNOWN, std::string());
|
||||
if (!gDirUtilp->fileExists(to_asset_file))
|
||||
{
|
||||
if (mEnableCacheDebugInfo)
|
||||
{
|
||||
LL_INFOS("LLDiskCache") << "Copying static asset " << from_asset_file << " to cache from " << from_folder << LL_ENDL;
|
||||
}
|
||||
if (!LLFile::copy(from_asset_file, to_asset_file))
|
||||
{
|
||||
LL_WARNS("LLDiskCache") << "Failed to copy " << from_asset_file << " to " << to_asset_file << LL_ENDL;
|
||||
}
|
||||
}
|
||||
if (std::find(mSkipList.begin(), mSkipList.end(), uuid_as_string) == mSkipList.end())
|
||||
{
|
||||
if (mEnableCacheDebugInfo)
|
||||
{
|
||||
LL_INFOS("LLDiskCache") << "Adding " << uuid_as_string << " to skip list" << LL_ENDL;
|
||||
}
|
||||
mSkipList.emplace_back(uuid_as_string);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// </FS:Beq>
|
||||
|
||||
void LLDiskCache::clearCache()
|
||||
{
|
||||
LL_INFOS() << "clearing cache " << mCacheDir << LL_ENDL;
|
||||
/**
|
||||
* See notes on performance in dirFileSize(..) - there may be
|
||||
* a quicker way to do this by operating on the parent dir vs
|
||||
|
|
@ -337,26 +414,50 @@ void LLDiskCache::clearCache()
|
|||
#endif
|
||||
if (boost::filesystem::is_directory(cache_path, ec) && !ec.failed())
|
||||
{
|
||||
LL_INFOS() << "is a directory: " << mCacheDir << LL_ENDL;
|
||||
// <FS:Ansariel> Optimize asset simple disk cache
|
||||
//for (auto& entry : boost::make_iterator_range(boost::filesystem::directory_iterator(cache_path, ec), {}))
|
||||
for (auto& entry : boost::make_iterator_range(boost::filesystem::recursive_directory_iterator(cache_path, ec), {}))
|
||||
// <FS:TS> FIRE-31070: Crash on clearing cache on macOS and Linux
|
||||
// On Unix-like operating systems, the recursive_directory_iterator gets very unhappy if you
|
||||
// delete a file out from under it in a for loop. This restructuring to a while loop and
|
||||
// manually incrementing the iterator avoids the problem. Note that the iterator must be
|
||||
// incremented *before* deleting the file.
|
||||
boost::filesystem::recursive_directory_iterator entry(cache_path, ec);
|
||||
boost::filesystem::recursive_directory_iterator cache_end;
|
||||
while (entry != cache_end)
|
||||
{
|
||||
if (boost::filesystem::is_regular_file(entry, ec) && !ec.failed())
|
||||
const boost::filesystem::path& remove_entry = entry->path();
|
||||
if (boost::filesystem::is_regular_file(remove_entry, ec) && !ec.failed())
|
||||
{
|
||||
if (entry.path().string().find(mCacheFilenamePrefix) != std::string::npos)
|
||||
if (remove_entry.string().find(mCacheFilenamePrefix) != std::string::npos)
|
||||
{
|
||||
// <FS:Ansariel> Do not crash if we cannot delete the file for some reason
|
||||
//boost::filesystem::remove(entry);
|
||||
boost::filesystem::remove(entry, ec);
|
||||
const boost::filesystem::path remove_path = remove_entry;
|
||||
++entry;
|
||||
boost::filesystem::remove(remove_path, ec);
|
||||
if (ec.failed())
|
||||
{
|
||||
LL_WARNS() << "Failed to delete cache file " << entry << ": " << ec.message() << LL_ENDL;
|
||||
LL_WARNS() << "Failed to delete cache file " << remove_path.string() << ": " << ec.message() << LL_ENDL;
|
||||
}
|
||||
// </FS:Ansariel>
|
||||
}
|
||||
else
|
||||
{
|
||||
++entry;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
++entry;
|
||||
}
|
||||
// </FS:TS> FIRE-31070
|
||||
}
|
||||
// <FS:Beq> add static assets into the new cache after clear
|
||||
LL_INFOS() << "prepopulating new cache " << LL_ENDL;
|
||||
prepopulateCacheWithStatic();
|
||||
}
|
||||
LL_INFOS() << "Cleared cache " << mCacheDir << LL_ENDL;
|
||||
}
|
||||
|
||||
uintmax_t LLDiskCache::dirFileSize(const std::string dir)
|
||||
|
|
|
|||
|
|
@ -131,6 +131,11 @@ class LLDiskCache :
|
|||
*/
|
||||
void purge();
|
||||
|
||||
// <FS:Beq>
|
||||
// copy from distribution into cache to replace static content
|
||||
void prepopulateCacheWithStatic();
|
||||
// </FS:Beq>
|
||||
|
||||
/**
|
||||
* Clear the cache by removing all the files in the specified cache
|
||||
* directory individually. Only the files that contain a prefix defined
|
||||
|
|
@ -191,6 +196,8 @@ class LLDiskCache :
|
|||
* various parts of the code
|
||||
*/
|
||||
bool mEnableCacheDebugInfo;
|
||||
|
||||
std::vector<std::string> mSkipList; // <FS:Beq/> Vector of "static" untouchable assets that should never be purged
|
||||
};
|
||||
|
||||
// <FS:Ansariel> Regular disk cache cleanup
|
||||
|
|
|
|||
|
|
@ -81,10 +81,7 @@ bool LLFileSystem::getExists(const LLUUID& file_id, const LLAssetType::EType fil
|
|||
}
|
||||
|
||||
// static
|
||||
// <FS:Ansariel> Fix log spam
|
||||
//bool LLFileSystem::removeFile(const LLUUID& file_id, const LLAssetType::EType file_type)
|
||||
bool LLFileSystem::removeFile(const LLUUID& file_id, const LLAssetType::EType file_type, int suppress_error /*= 0*/)
|
||||
// </FS:Ansariel>
|
||||
{
|
||||
FSZoneC(tracy::Color::Gold); // <FS:Beq> measure cache performance
|
||||
std::string id_str;
|
||||
|
|
@ -92,10 +89,7 @@ bool LLFileSystem::removeFile(const LLUUID& file_id, const LLAssetType::EType fi
|
|||
const std::string extra_info = "";
|
||||
const std::string filename = LLDiskCache::getInstance()->metaDataToFilepath(id_str, file_type, extra_info);
|
||||
|
||||
// <FS:Ansariel> Fix log spam
|
||||
//LLFile::remove(filename.c_str());
|
||||
LLFile::remove(filename.c_str(), suppress_error);
|
||||
// </FS:Ansariel>
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -115,10 +109,7 @@ bool LLFileSystem::renameFile(const LLUUID& old_file_id, const LLAssetType::ETyp
|
|||
const std::string new_filename = LLDiskCache::getInstance()->metaDataToFilepath(new_id_str, new_file_type, extra_info);
|
||||
|
||||
// Rename needs the new file to not exist.
|
||||
// <FS:Ansariel> Fix log spam
|
||||
//LLFileSystem::removeFile(new_file_id, new_file_type);
|
||||
LLFileSystem::removeFile(new_file_id, new_file_type, ENOENT);
|
||||
// </FS:Ansariel>
|
||||
|
||||
if (LLFile::rename(old_filename, new_filename) != 0)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -54,10 +54,7 @@ class LLFileSystem
|
|||
BOOL remove();
|
||||
|
||||
static bool getExists(const LLUUID& file_id, const LLAssetType::EType file_type);
|
||||
// <FS:Ansariel> Fix log spam
|
||||
//static bool removeFile(const LLUUID& file_id, const LLAssetType::EType file_type);
|
||||
static bool removeFile(const LLUUID& file_id, const LLAssetType::EType file_type, int suppress_error = 0);
|
||||
// </FS:Ansariel>
|
||||
static bool renameFile(const LLUUID& old_file_id, const LLAssetType::EType old_file_type,
|
||||
const LLUUID& new_file_id, const LLAssetType::EType new_file_type);
|
||||
static S32 getFileSize(const LLUUID& file_id, const LLAssetType::EType file_type);
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ include(LLKDU)
|
|||
include(LLImageJ2COJ)
|
||||
include(ZLIB)
|
||||
include(LLAddBuildTest)
|
||||
include(bugsplat)
|
||||
include(Tut)
|
||||
|
||||
include_directories(
|
||||
|
|
|
|||
|
|
@ -103,60 +103,104 @@ LLVector3 LLLandmark::getRegionPos() const
|
|||
|
||||
|
||||
// static
|
||||
LLLandmark* LLLandmark::constructFromString(const char *buffer)
|
||||
LLLandmark* LLLandmark::constructFromString(const char *buffer, const S32 buffer_size)
|
||||
{
|
||||
const char* cur = buffer;
|
||||
S32 chars_read = 0;
|
||||
S32 chars_read_total = 0;
|
||||
S32 count = 0;
|
||||
U32 version = 0;
|
||||
|
||||
bool bad_block = false;
|
||||
LLLandmark* result = NULL;
|
||||
|
||||
// read version
|
||||
count = sscanf( cur, "Landmark version %u\n%n", &version, &chars_read );
|
||||
if(count != 1)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
count = sscanf( buffer, "Landmark version %u\n%n", &version, &chars_read );
|
||||
chars_read_total += chars_read;
|
||||
|
||||
if(version == 1)
|
||||
{
|
||||
LLVector3d pos;
|
||||
cur += chars_read;
|
||||
// read position
|
||||
count = sscanf( cur, "position %lf %lf %lf\n%n", pos.mdV+VX, pos.mdV+VY, pos.mdV+VZ, &chars_read );
|
||||
if( count != 3 )
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
cur += chars_read;
|
||||
// LL_INFOS() << "Landmark read: " << pos << LL_ENDL;
|
||||
|
||||
return new LLLandmark(pos);
|
||||
}
|
||||
else if(version == 2)
|
||||
{
|
||||
// *NOTE: Changing the buffer size will require changing the
|
||||
// scanf call below.
|
||||
char region_id_str[MAX_STRING]; /* Flawfinder: ignore */
|
||||
LLVector3 pos;
|
||||
cur += chars_read;
|
||||
count = sscanf( /* Flawfinder: ignore */
|
||||
cur,
|
||||
"region_id %254s\n%n",
|
||||
region_id_str, &chars_read);
|
||||
if(count != 1) goto error;
|
||||
cur += chars_read;
|
||||
count = sscanf(cur, "local_pos %f %f %f\n%n", pos.mV+VX, pos.mV+VY, pos.mV+VZ, &chars_read);
|
||||
if(count != 3) goto error;
|
||||
cur += chars_read;
|
||||
LLLandmark* lm = new LLLandmark;
|
||||
lm->mRegionID.set(region_id_str);
|
||||
lm->mRegionPos = pos;
|
||||
return lm;
|
||||
}
|
||||
if (count != 1
|
||||
|| chars_read_total >= buffer_size)
|
||||
{
|
||||
bad_block = true;
|
||||
}
|
||||
|
||||
error:
|
||||
LL_INFOS() << "Bad Landmark Asset: bad _DATA_ block." << LL_ENDL;
|
||||
return NULL;
|
||||
if (!bad_block)
|
||||
{
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
LLVector3d pos;
|
||||
// read position
|
||||
count = sscanf(buffer + chars_read_total, "position %lf %lf %lf\n%n", pos.mdV + VX, pos.mdV + VY, pos.mdV + VZ, &chars_read);
|
||||
if (count != 3)
|
||||
{
|
||||
bad_block = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_DEBUGS("Landmark") << "Landmark read: " << pos << LL_ENDL;
|
||||
result = new LLLandmark(pos);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
// *NOTE: Changing the buffer size will require changing the
|
||||
// scanf call below.
|
||||
char region_id_str[MAX_STRING];
|
||||
LLVector3 pos;
|
||||
LLUUID region_id;
|
||||
count = sscanf( buffer + chars_read_total,
|
||||
"region_id %254s\n%n",
|
||||
region_id_str,
|
||||
&chars_read);
|
||||
chars_read_total += chars_read;
|
||||
|
||||
if (count != 1
|
||||
|| chars_read_total >= buffer_size
|
||||
|| !LLUUID::validate(region_id_str))
|
||||
{
|
||||
bad_block = true;
|
||||
}
|
||||
|
||||
if (!bad_block)
|
||||
{
|
||||
region_id.set(region_id_str);
|
||||
if (region_id.isNull())
|
||||
{
|
||||
bad_block = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!bad_block)
|
||||
{
|
||||
count = sscanf(buffer + chars_read_total, "local_pos %f %f %f\n%n", pos.mV + VX, pos.mV + VY, pos.mV + VZ, &chars_read);
|
||||
if (count != 3)
|
||||
{
|
||||
bad_block = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = new LLLandmark;
|
||||
result->mRegionID = region_id;
|
||||
result->mRegionPos = pos;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
LL_INFOS("Landmark") << "Encountered Unknown landmark version " << version << LL_ENDL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bad_block)
|
||||
{
|
||||
LL_INFOS("Landmark") << "Bad Landmark Asset: bad _DATA_ block." << LL_ENDL;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -176,7 +220,7 @@ void LLLandmark::requestRegionHandle(
|
|||
if(region_id.isNull())
|
||||
{
|
||||
// don't bother with checking - it's 0.
|
||||
LL_DEBUGS() << "requestRegionHandle: null" << LL_ENDL;
|
||||
LL_DEBUGS("Landmark") << "requestRegionHandle: null" << LL_ENDL;
|
||||
if(callback)
|
||||
{
|
||||
const U64 U64_ZERO = 0;
|
||||
|
|
@ -187,7 +231,7 @@ void LLLandmark::requestRegionHandle(
|
|||
{
|
||||
if(region_id == mLocalRegion.first)
|
||||
{
|
||||
LL_DEBUGS() << "requestRegionHandle: local" << LL_ENDL;
|
||||
LL_DEBUGS("Landmark") << "requestRegionHandle: local" << LL_ENDL;
|
||||
if(callback)
|
||||
{
|
||||
callback(region_id, mLocalRegion.second);
|
||||
|
|
@ -198,13 +242,13 @@ void LLLandmark::requestRegionHandle(
|
|||
region_map_t::iterator it = mRegions.find(region_id);
|
||||
if(it == mRegions.end())
|
||||
{
|
||||
LL_DEBUGS() << "requestRegionHandle: upstream" << LL_ENDL;
|
||||
LL_DEBUGS("Landmark") << "requestRegionHandle: upstream" << LL_ENDL;
|
||||
if(callback)
|
||||
{
|
||||
region_callback_map_t::value_type vt(region_id, callback);
|
||||
sRegionCallbackMap.insert(vt);
|
||||
}
|
||||
LL_DEBUGS() << "Landmark requesting information about: "
|
||||
LL_DEBUGS("Landmark") << "Landmark requesting information about: "
|
||||
<< region_id << LL_ENDL;
|
||||
msg->newMessage("RegionHandleRequest");
|
||||
msg->nextBlock("RequestBlock");
|
||||
|
|
@ -214,7 +258,7 @@ void LLLandmark::requestRegionHandle(
|
|||
else if(callback)
|
||||
{
|
||||
// we have the answer locally - just call the callack.
|
||||
LL_DEBUGS() << "requestRegionHandle: ready" << LL_ENDL;
|
||||
LL_DEBUGS("Landmark") << "requestRegionHandle: ready" << LL_ENDL;
|
||||
callback(region_id, (*it).second.mRegionHandle);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ public:
|
|||
|
||||
// constructs a new LLLandmark from a string
|
||||
// return NULL if there's an error
|
||||
static LLLandmark* constructFromString(const char *buffer);
|
||||
static LLLandmark* constructFromString(const char *buffer, const S32 buffer_size);
|
||||
|
||||
// register callbacks that this class handles
|
||||
static void registerCallbacks(LLMessageSystem* msg);
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ project(llmath)
|
|||
|
||||
include(00-Common)
|
||||
include(LLCommon)
|
||||
include(bugsplat)
|
||||
include(Boost)
|
||||
|
||||
include_directories(
|
||||
|
|
|
|||
|
|
@ -138,13 +138,24 @@ LLCoprocedureManager::~LLCoprocedureManager()
|
|||
close();
|
||||
}
|
||||
|
||||
LLCoprocedureManager::poolPtr_t LLCoprocedureManager::initializePool(const std::string &poolName)
|
||||
void LLCoprocedureManager::initializePool(const std::string &poolName)
|
||||
{
|
||||
poolMap_t::iterator it = mPoolMap.find(poolName);
|
||||
|
||||
if (it != mPoolMap.end())
|
||||
{
|
||||
// Pools are not supposed to be initialized twice
|
||||
// Todo: ideally restrict init to STATE_FIRST
|
||||
LL_WARNS("CoProcMgr") << "Pool is already present " << poolName << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
// Attempt to look up a pool size in the configuration. If found use that
|
||||
std::string keyName = "PoolSize" + poolName;
|
||||
int size = 0;
|
||||
|
||||
LL_ERRS_IF(poolName.empty(), "CoprocedureManager") << "Poolname must not be empty" << LL_ENDL;
|
||||
LL_INFOS("CoprocedureManager") << "Initializing pool " << poolName << LL_ENDL;
|
||||
|
||||
if (mPropertyQueryFn)
|
||||
{
|
||||
|
|
@ -171,8 +182,6 @@ LLCoprocedureManager::poolPtr_t LLCoprocedureManager::initializePool(const std::
|
|||
|
||||
bool inserted = mPoolMap.emplace(poolName, pool).second;
|
||||
LL_ERRS_IF(!inserted, "CoprocedureManager") << "Unable to add pool named \"" << poolName << "\" to map. FATAL!" << LL_ENDL;
|
||||
|
||||
return pool;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
|
@ -182,22 +191,28 @@ LLUUID LLCoprocedureManager::enqueueCoprocedure(const std::string &pool, const s
|
|||
// not exist, create it.
|
||||
poolMap_t::iterator it = mPoolMap.find(pool);
|
||||
|
||||
poolPtr_t targetPool = (it != mPoolMap.end()) ? it->second : initializePool(pool);
|
||||
if (it == mPoolMap.end())
|
||||
{
|
||||
// initializing pools in enqueueCoprocedure is not thread safe,
|
||||
// at the moment pools need to be initialized manually
|
||||
LL_ERRS() << "Uninitialized pool " << pool << LL_ENDL;
|
||||
}
|
||||
|
||||
poolPtr_t targetPool = it->second;
|
||||
return targetPool->enqueueCoprocedure(name, proc);
|
||||
}
|
||||
|
||||
void LLCoprocedureManager::setPropertyMethods(SettingQuery_t queryfn, SettingUpdate_t updatefn)
|
||||
{
|
||||
// functions to discover and store the pool sizes
|
||||
// Might be a better idea to make an initializePool(name, size) to init everything externally
|
||||
mPropertyQueryFn = queryfn;
|
||||
mPropertyDefineFn = updatefn;
|
||||
|
||||
// workaround until we get mutex into initializePool
|
||||
initializePool("AssetStorage");
|
||||
initializePool("Upload");
|
||||
initializePool("AIS");
|
||||
initializePool("ExpCache"); // <FS:Ansariel> FIRE-30731: ExpCache coroutine pool crash
|
||||
initializePool("AIS"); // it might be better to have some kind of on-demand initialization for AIS
|
||||
// "ExpCache" pool gets initialized in LLExperienceCache
|
||||
// asset storage pool gets initialized in LLViewerAssetStorage
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -79,6 +79,8 @@ public:
|
|||
|
||||
void close();
|
||||
void close(const std::string &pool);
|
||||
|
||||
void initializePool(const std::string &poolName);
|
||||
|
||||
private:
|
||||
|
||||
|
|
@ -87,8 +89,6 @@ private:
|
|||
|
||||
poolMap_t mPoolMap;
|
||||
|
||||
poolPtr_t initializePool(const std::string &poolName);
|
||||
|
||||
SettingQuery_t mPropertyQueryFn;
|
||||
SettingUpdate_t mPropertyDefineFn;
|
||||
|
||||
|
|
|
|||
|
|
@ -114,6 +114,8 @@ void LLExperienceCache::initSingleton()
|
|||
cache_stream >> (*this);
|
||||
}
|
||||
|
||||
LLCoprocedureManager::instance().initializePool("ExpCache");
|
||||
|
||||
LLCoros::instance().launch("LLExperienceCache::idleCoro",
|
||||
boost::bind(&LLExperienceCache::idleCoro, this));
|
||||
|
||||
|
|
|
|||
|
|
@ -91,6 +91,7 @@ namespace tut
|
|||
{
|
||||
Sync sync;
|
||||
int foo = 0;
|
||||
LLCoprocedureManager::instance().initializePool("PoolName");
|
||||
LLUUID queueId = LLCoprocedureManager::instance().enqueueCoprocedure("PoolName", "ProcName",
|
||||
[&foo, &sync] (LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t & ptr, const LLUUID & id) {
|
||||
sync.bump();
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ U32 LLRender::sUIVerts = 0;
|
|||
U32 LLTexUnit::sWhiteTexture = 0;
|
||||
bool LLRender::sGLCoreProfile = false;
|
||||
bool LLRender::sNsightDebugSupport = false;
|
||||
LLVector2 LLRender::sUIGLScaleFactor = LLVector2(1.f, 1.f);
|
||||
|
||||
static const U32 LL_NUM_TEXTURE_LAYERS = 32;
|
||||
static const U32 LL_NUM_LIGHT_UNITS = 8;
|
||||
|
|
|
|||
|
|
@ -480,6 +480,7 @@ public:
|
|||
static U32 sUIVerts;
|
||||
static bool sGLCoreProfile;
|
||||
static bool sNsightDebugSupport;
|
||||
static LLVector2 sUIGLScaleFactor;
|
||||
|
||||
private:
|
||||
friend class LLLightState;
|
||||
|
|
|
|||
|
|
@ -106,11 +106,10 @@ void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, S32 pixe
|
|||
top += LLFontGL::sCurOrigin.mY;
|
||||
|
||||
gGL.loadUIIdentity();
|
||||
LLRender2D *r2d_inst = LLRender2D::getInstance();
|
||||
gl_rect_2d(llfloor((F32)left * r2d_inst->mGLScaleFactor.mV[VX]) - pixel_offset,
|
||||
llfloor((F32)top * r2d_inst->mGLScaleFactor.mV[VY]) + pixel_offset,
|
||||
llfloor((F32)right * r2d_inst->mGLScaleFactor.mV[VX]) + pixel_offset,
|
||||
llfloor((F32)bottom * r2d_inst->mGLScaleFactor.mV[VY]) - pixel_offset,
|
||||
gl_rect_2d(llfloor((F32)left * LLRender::sUIGLScaleFactor.mV[VX]) - pixel_offset,
|
||||
llfloor((F32)top * LLRender::sUIGLScaleFactor.mV[VY]) + pixel_offset,
|
||||
llfloor((F32)right * LLRender::sUIGLScaleFactor.mV[VX]) + pixel_offset,
|
||||
llfloor((F32)bottom * LLRender::sUIGLScaleFactor.mV[VY]) - pixel_offset,
|
||||
filled);
|
||||
gGL.popUIMatrix();
|
||||
}
|
||||
|
|
@ -2017,7 +2016,6 @@ void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv
|
|||
|
||||
LLRender2D::LLRender2D(LLImageProviderInterface* image_provider)
|
||||
{
|
||||
mGLScaleFactor = LLVector2(1.f, 1.f);
|
||||
mImageProvider = image_provider;
|
||||
if(mImageProvider)
|
||||
{
|
||||
|
|
@ -2034,7 +2032,7 @@ LLRender2D::~LLRender2D()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
void LLRender2D::translate(F32 x, F32 y, F32 z)
|
||||
{
|
||||
gGL.translateUI(x,y,z);
|
||||
|
|
@ -2043,12 +2041,14 @@ void LLRender2D::translate(F32 x, F32 y, F32 z)
|
|||
LLFontGL::sCurDepth += z;
|
||||
}
|
||||
|
||||
// static
|
||||
void LLRender2D::pushMatrix()
|
||||
{
|
||||
gGL.pushUIMatrix();
|
||||
LLFontGL::sOriginStack.push_back(std::make_pair(LLFontGL::sCurOrigin, LLFontGL::sCurDepth));
|
||||
}
|
||||
|
||||
// static
|
||||
void LLRender2D::popMatrix()
|
||||
{
|
||||
gGL.popUIMatrix();
|
||||
|
|
@ -2057,6 +2057,7 @@ void LLRender2D::popMatrix()
|
|||
LLFontGL::sOriginStack.pop_back();
|
||||
}
|
||||
|
||||
// static
|
||||
void LLRender2D::loadIdentity()
|
||||
{
|
||||
gGL.loadUIIdentity();
|
||||
|
|
@ -2065,17 +2066,13 @@ void LLRender2D::loadIdentity()
|
|||
LLFontGL::sCurDepth = 0.f;
|
||||
}
|
||||
|
||||
void LLRender2D::setScaleFactor(const LLVector2 &scale_factor)
|
||||
{
|
||||
mGLScaleFactor = scale_factor;
|
||||
}
|
||||
|
||||
// static
|
||||
void LLRender2D::setLineWidth(F32 width)
|
||||
{
|
||||
// <FS> Line width OGL core profile fix by Rye Mutt
|
||||
//gGL.flush();
|
||||
//glLineWidth(width * lerp(mGLScaleFactor.mV[VX], mGLScaleFactor.mV[VY], 0.5f));
|
||||
gGL.setLineWidth(width * lerp(mGLScaleFactor.mV[VX], mGLScaleFactor.mV[VY], 0.5f));
|
||||
//glLineWidth(width * lerp(LLRender::sUIGLScaleFactor.mV[VX], LLRender::sUIGLScaleFactor.mV[VY], 0.5f));
|
||||
gGL.setLineWidth(width * lerp(LLRender::sUIGLScaleFactor.mV[VX], LLRender::sUIGLScaleFactor.mV[VY], 0.5f));
|
||||
}
|
||||
|
||||
LLPointer<LLUIImage> LLRender2D::getUIImageByID(const LLUUID& image_id, S32 priority)
|
||||
|
|
|
|||
|
|
@ -128,19 +128,16 @@ class LLRender2D : public LLParamSingleton<LLRender2D>
|
|||
LOG_CLASS(LLRender2D);
|
||||
~LLRender2D();
|
||||
public:
|
||||
void pushMatrix();
|
||||
void popMatrix();
|
||||
void loadIdentity();
|
||||
void translate(F32 x, F32 y, F32 z = 0.0f);
|
||||
static void pushMatrix();
|
||||
static void popMatrix();
|
||||
static void loadIdentity();
|
||||
static void translate(F32 x, F32 y, F32 z = 0.0f);
|
||||
|
||||
void setLineWidth(F32 width);
|
||||
void setScaleFactor(const LLVector2& scale_factor);
|
||||
static void setLineWidth(F32 width);
|
||||
|
||||
LLPointer<LLUIImage> getUIImageByID(const LLUUID& image_id, S32 priority = 0);
|
||||
LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority = 0);
|
||||
|
||||
LLVector2 mGLScaleFactor;
|
||||
|
||||
protected:
|
||||
// since LLRender2D has no control of image provider's lifecycle
|
||||
// we need a way to tell LLRender2D that provider died and
|
||||
|
|
|
|||
|
|
@ -1006,7 +1006,7 @@ void LLAccordionCtrlTab::drawChild(const LLRect& root_rect,LLView* child)
|
|||
LLRect screen_rect;
|
||||
localRectToScreen(child->getRect(),&screen_rect);
|
||||
|
||||
if ( root_rect.overlaps(screen_rect) && LLUI::getInstance()->mDirtyRect.overlaps(screen_rect))
|
||||
if ( root_rect.overlaps(screen_rect) && sDirtyRect.overlaps(screen_rect))
|
||||
{
|
||||
gGL.matrixMode(LLRender::MM_MODELVIEW);
|
||||
LLUI::pushMatrix();
|
||||
|
|
|
|||
|
|
@ -219,7 +219,9 @@ void LLConsole::draw()
|
|||
// <FS> Different draw options
|
||||
//LLUIImagePtr imagep = LLUI::getUIImage("transparent");
|
||||
|
||||
//F32 console_opacity = llclamp(LLUI::getInstance()->mSettingGroups["config"]->getF32("ConsoleBackgroundOpacity"), 0.f, 1.f);
|
||||
//static LLCachedControl<F32> console_bg_opacity(*LLUI::getInstance()->mSettingGroups["config"], "ConsoleBackgroundOpacity", 0.7f);
|
||||
//F32 console_opacity = llclamp(console_bg_opacity(), 0.f, 1.f);
|
||||
|
||||
//LLColor4 color = LLUIColorTable::instance().getColor("ConsoleBackground");
|
||||
//color.mV[VALPHA] *= console_opacity;
|
||||
|
||||
|
|
|
|||
|
|
@ -416,13 +416,15 @@ void LLFloater::layoutDragHandle()
|
|||
// static
|
||||
void LLFloater::updateActiveFloaterTransparency()
|
||||
{
|
||||
sActiveControlTransparency = LLUI::getInstance()->mSettingGroups["config"]->getF32("ActiveFloaterTransparency");
|
||||
static LLCachedControl<F32> active_transparency(*LLUI::getInstance()->mSettingGroups["config"], "ActiveFloaterTransparency", 1.f);
|
||||
sActiveControlTransparency = active_transparency;
|
||||
}
|
||||
|
||||
// static
|
||||
void LLFloater::updateInactiveFloaterTransparency()
|
||||
{
|
||||
sInactiveControlTransparency = LLUI::getInstance()->mSettingGroups["config"]->getF32("InactiveFloaterTransparency");
|
||||
static LLCachedControl<F32> inactive_transparency(*LLUI::getInstance()->mSettingGroups["config"], "InactiveFloaterTransparency", 0.95f);
|
||||
sInactiveControlTransparency = inactive_transparency;
|
||||
}
|
||||
|
||||
void LLFloater::addResizeCtrls()
|
||||
|
|
|
|||
|
|
@ -348,9 +348,9 @@ static LLTrace::BlockTimerStatHandle FTM_FILTER("Filter Folder View");
|
|||
void LLFolderView::filter( LLFolderViewFilter& filter )
|
||||
{
|
||||
LL_RECORD_BLOCK_TIME(FTM_FILTER);
|
||||
static LLCachedControl<S32> filter_visible(*LLUI::getInstance()->mSettingGroups["config"], "FilterItemsMaxTimePerFrameVisible", 10);
|
||||
static LLCachedControl<S32> filter_hidden(*LLUI::getInstance()->mSettingGroups["config"], "FilterItemsMaxTimePerFrameUnvisible", 1);
|
||||
filter.resetTime(llclamp(mParentPanel.get()->getVisible() ? filter_visible() : filter_hidden(), 1, 100));
|
||||
static LLCachedControl<S32> time_visible(*LLUI::getInstance()->mSettingGroups["config"], "FilterItemsMaxTimePerFrameVisible", 10);
|
||||
static LLCachedControl<S32> time_invisible(*LLUI::getInstance()->mSettingGroups["config"], "FilterItemsMaxTimePerFrameUnvisible", 1);
|
||||
filter.resetTime(llclamp((mParentPanel.get()->getVisible() ? time_visible() : time_invisible()), 1, 100));
|
||||
|
||||
// Note: we filter the model, not the view
|
||||
getViewModelItem()->filter(filter);
|
||||
|
|
@ -687,11 +687,8 @@ void LLFolderView::draw()
|
|||
closeAutoOpenedFolders();
|
||||
}
|
||||
|
||||
// <FS:Ansariel> Performance improvement
|
||||
//if (mSearchTimer.getElapsedTimeF32() > LLUI::getInstance()->mSettingGroups["config"]->getF32("TypeAheadTimeout") || !mSearchString.size())
|
||||
static LLCachedControl<F32> typeAheadTimeout(*LLUI::getInstance()->mSettingGroups["config"], "TypeAheadTimeout");
|
||||
if (mSearchTimer.getElapsedTimeF32() > typeAheadTimeout || !mSearchString.size())
|
||||
// </FS:Ansariel>
|
||||
static LLCachedControl<F32> type_ahead_timeout(*LLUI::getInstance()->mSettingGroups["config"], "TypeAheadTimeout", 1.5f);
|
||||
if (mSearchTimer.getElapsedTimeF32() > type_ahead_timeout || !mSearchString.size())
|
||||
{
|
||||
mSearchString.clear();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1052,9 +1052,10 @@ void LLFolderViewItem::draw()
|
|||
//
|
||||
if (filter_string_length > 0)
|
||||
{
|
||||
F32 match_string_left = text_left + font->getWidthF32(combined_string, 0, mViewModelItem->getFilterStringOffset());
|
||||
S32 filter_offset = mViewModelItem->getFilterStringOffset();
|
||||
F32 match_string_left = text_left + font->getWidthF32(combined_string, 0, filter_offset + filter_string_length) - font->getWidthF32(combined_string, filter_offset, filter_string_length);
|
||||
F32 yy = (F32)getRect().getHeight() - font->getLineHeight() - (F32)mTextPad - (F32)TOP_PAD;
|
||||
font->renderUTF8( combined_string, mViewModelItem->getFilterStringOffset(), match_string_left, yy,
|
||||
font->renderUTF8( combined_string, filter_offset, match_string_left, yy,
|
||||
sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
|
||||
filter_string_length, S32_MAX, &right_x, FALSE );
|
||||
}
|
||||
|
|
@ -1724,7 +1725,7 @@ void LLFolderViewFolder::destroyView()
|
|||
|
||||
// extractItem() removes the specified item from the folder, but
|
||||
// doesn't delete it.
|
||||
void LLFolderViewFolder::extractItem( LLFolderViewItem* item )
|
||||
void LLFolderViewFolder::extractItem( LLFolderViewItem* item, bool deparent_model )
|
||||
{
|
||||
if (item->isSelected())
|
||||
getRoot()->clearSelection();
|
||||
|
|
@ -1747,7 +1748,11 @@ void LLFolderViewFolder::extractItem( LLFolderViewItem* item )
|
|||
mItems.erase(it);
|
||||
}
|
||||
//item has been removed, need to update filter
|
||||
getViewModelItem()->removeChild(item->getViewModelItem());
|
||||
if (deparent_model)
|
||||
{
|
||||
// in some cases model does not belong to parent view, is shared between views
|
||||
getViewModelItem()->removeChild(item->getViewModelItem());
|
||||
}
|
||||
//because an item is going away regardless of filter status, force rearrange
|
||||
requestArrange();
|
||||
removeChild(item);
|
||||
|
|
|
|||
|
|
@ -413,7 +413,7 @@ public:
|
|||
|
||||
// extractItem() removes the specified item from the folder, but
|
||||
// doesn't delete it.
|
||||
virtual void extractItem( LLFolderViewItem* item );
|
||||
virtual void extractItem( LLFolderViewItem* item, bool deparent_model = true);
|
||||
|
||||
// This function is called by a child that needs to be resorted.
|
||||
void resort(LLFolderViewItem* item);
|
||||
|
|
|
|||
|
|
@ -48,9 +48,9 @@ std::string LLFolderViewModelCommon::getStatusText()
|
|||
|
||||
void LLFolderViewModelCommon::filter()
|
||||
{
|
||||
static LLCachedControl<S32> filter_visible(*LLUI::getInstance()->mSettingGroups["config"], "FilterItemsMaxTimePerFrameVisible", 10);
|
||||
getFilter().resetTime(llclamp(filter_visible(), 1, 100));
|
||||
mFolderView->getViewModelItem()->filter(getFilter());
|
||||
static LLCachedControl<S32> max_time(*LLUI::getInstance()->mSettingGroups["config"], "FilterItemsMaxTimePerFrameVisible", 10);
|
||||
getFilter().resetTime(llclamp(max_time(), 1, 100));
|
||||
mFolderView->getViewModelItem()->filter(getFilter());
|
||||
}
|
||||
|
||||
bool LLFolderViewModelItemCommon::hasFilterStringMatch()
|
||||
|
|
|
|||
|
|
@ -3378,7 +3378,11 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y, S3
|
|||
CURSOR_WIDTH + MOUSE_CURSOR_PADDING * 2,
|
||||
CURSOR_HEIGHT + MOUSE_CURSOR_PADDING * 2);
|
||||
menu->translateIntoRectWithExclusion( menu_region_rect, mouse_rect );
|
||||
if (menu->getRect().mTop > menu_region_rect.mTop)
|
||||
// <FS:Ansariel> FIRE-31065: Make sure menu is shown on the screen properly
|
||||
//if (menu->getRect().mTop > menu_region_rect.mTop)
|
||||
if (menu->getRect().mTop > menu_region_rect.mTop ||
|
||||
menu->getRect().mBottom < menu_region_rect.mBottom)
|
||||
// </FS:Ansariel>
|
||||
{
|
||||
// not enough space: align with top, ignore exclusion
|
||||
menu->translateIntoRect( menu_region_rect );
|
||||
|
|
|
|||
|
|
@ -136,6 +136,7 @@ LLMultiSlider::LLMultiSlider(const LLMultiSlider::Params& p)
|
|||
}
|
||||
}
|
||||
|
||||
mRoundedSquareImgp = LLUI::getUIImage("Rounded_Square");
|
||||
if (p.thumb_image.isProvided())
|
||||
{
|
||||
mThumbImagep = LLUI::getUIImage(p.thumb_image());
|
||||
|
|
@ -666,8 +667,6 @@ void LLMultiSlider::draw()
|
|||
F32 opacity = getEnabled() ? 1.f : 0.3f;
|
||||
|
||||
// Track
|
||||
LLUIImagePtr thumb_imagep = LLUI::getUIImage("Rounded_Square");
|
||||
|
||||
static LLUICachedControl<S32> multi_track_height_width ("UIMultiTrackHeight", 0);
|
||||
S32 height_offset = 0;
|
||||
S32 width_offset = 0;
|
||||
|
|
@ -685,7 +684,7 @@ void LLMultiSlider::draw()
|
|||
if(mDrawTrack)
|
||||
{
|
||||
track_rect.stretch(-1);
|
||||
thumb_imagep->draw(track_rect, mTrackColor.get() % opacity);
|
||||
mRoundedSquareImgp->draw(track_rect, mTrackColor.get() % opacity);
|
||||
}
|
||||
|
||||
// if we're supposed to use a drawn triangle
|
||||
|
|
@ -704,7 +703,7 @@ void LLMultiSlider::draw()
|
|||
mTriangleColor.get() % opacity, TRUE);
|
||||
}
|
||||
}
|
||||
else if (!thumb_imagep && !mThumbImagep)
|
||||
else if (!mRoundedSquareImgp && !mThumbImagep)
|
||||
{
|
||||
// draw all the thumbs
|
||||
curSldrIt = mThumbRects.end();
|
||||
|
|
@ -757,7 +756,7 @@ void LLMultiSlider::draw()
|
|||
}
|
||||
else
|
||||
{
|
||||
thumb_imagep->drawSolid(mDragStartThumbRect, mThumbCenterColor.get() % 0.3f);
|
||||
mRoundedSquareImgp->drawSolid(mDragStartThumbRect, mThumbCenterColor.get() % 0.3f);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -772,7 +771,7 @@ void LLMultiSlider::draw()
|
|||
}
|
||||
else
|
||||
{
|
||||
thumb_imagep->drawBorder(mThumbRects[mCurSlider], gFocusMgr.getFocusColor(), gFocusMgr.getFocusFlashWidth());
|
||||
mRoundedSquareImgp->drawBorder(mThumbRects[mCurSlider], gFocusMgr.getFocusColor(), gFocusMgr.getFocusFlashWidth());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -784,7 +783,7 @@ void LLMultiSlider::draw()
|
|||
}
|
||||
else
|
||||
{
|
||||
thumb_imagep->drawBorder(mThumbRects[mHoverSlider], gFocusMgr.getFocusColor(), gFocusMgr.getFocusFlashWidth());
|
||||
mRoundedSquareImgp->drawBorder(mThumbRects[mHoverSlider], gFocusMgr.getFocusColor(), gFocusMgr.getFocusFlashWidth());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -822,11 +821,11 @@ void LLMultiSlider::draw()
|
|||
}
|
||||
else if (capture == this)
|
||||
{
|
||||
thumb_imagep->drawSolid(mIt->second, curThumbColor);
|
||||
mRoundedSquareImgp->drawSolid(mIt->second, curThumbColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
thumb_imagep->drawSolid(mIt->second, curThumbColor % opacity);
|
||||
mRoundedSquareImgp->drawSolid(mIt->second, curThumbColor % opacity);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -846,11 +845,11 @@ void LLMultiSlider::draw()
|
|||
}
|
||||
else if (capture == this)
|
||||
{
|
||||
thumb_imagep->drawSolid(curSldrIt->second, mThumbCenterSelectedColor.get());
|
||||
mRoundedSquareImgp->drawSolid(curSldrIt->second, mThumbCenterSelectedColor.get());
|
||||
}
|
||||
else
|
||||
{
|
||||
thumb_imagep->drawSolid(curSldrIt->second, mThumbCenterSelectedColor.get() % opacity);
|
||||
mRoundedSquareImgp->drawSolid(curSldrIt->second, mThumbCenterSelectedColor.get() % opacity);
|
||||
}
|
||||
}
|
||||
if(hoverSldrIt != mThumbRects.end())
|
||||
|
|
@ -861,7 +860,7 @@ void LLMultiSlider::draw()
|
|||
}
|
||||
else
|
||||
{
|
||||
thumb_imagep->drawSolid(hoverSldrIt->second, mThumbCenterSelectedColor.get());
|
||||
mRoundedSquareImgp->drawSolid(hoverSldrIt->second, mThumbCenterSelectedColor.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -150,6 +150,7 @@ protected:
|
|||
LLUIColor mDisabledThumbColor;
|
||||
LLUIColor mTriangleColor;
|
||||
LLUIImagePtr mThumbImagep; //blimps on the slider, for now no 'disabled' support
|
||||
LLUIImagePtr mRoundedSquareImgp; //blimps on the slider, for now no 'disabled' support
|
||||
|
||||
const EOrientation mOrientation;
|
||||
|
||||
|
|
|
|||
|
|
@ -27,9 +27,8 @@
|
|||
|
||||
// Many classes just store a single LLNotificationPtr
|
||||
// and llnotifications.h is very large, so define this ligher header.
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
class LLNotification;
|
||||
typedef boost::shared_ptr<LLNotification> LLNotificationPtr;
|
||||
typedef std::shared_ptr<LLNotification> LLNotificationPtr;
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -85,7 +85,6 @@
|
|||
|
||||
#include <boost/utility.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
#include <boost/signals2.hpp>
|
||||
#include <boost/range.hpp>
|
||||
|
|
@ -307,7 +306,7 @@ typedef boost::shared_ptr<LLNotificationVisibilityRule> LLNotificationVisibility
|
|||
*/
|
||||
class LLNotification :
|
||||
boost::noncopyable,
|
||||
public boost::enable_shared_from_this<LLNotification>
|
||||
public std::enable_shared_from_this<LLNotification>
|
||||
{
|
||||
LOG_CLASS(LLNotification);
|
||||
friend class LLNotifications;
|
||||
|
|
@ -763,7 +762,10 @@ public:
|
|||
: mFilter(filter),
|
||||
mItems()
|
||||
{}
|
||||
virtual ~LLNotificationChannelBase() {}
|
||||
virtual ~LLNotificationChannelBase()
|
||||
{
|
||||
mItems.clear();
|
||||
}
|
||||
// you can also connect to a Channel, so you can be notified of
|
||||
// changes to this channel
|
||||
LLBoundListener connectChanged(const LLEventListener& slot)
|
||||
|
|
@ -893,6 +895,7 @@ class LLNotifications :
|
|||
{
|
||||
LLSINGLETON(LLNotifications);
|
||||
LOG_CLASS(LLNotifications);
|
||||
virtual ~LLNotifications() {}
|
||||
|
||||
public:
|
||||
|
||||
|
|
@ -1093,7 +1096,11 @@ public:
|
|||
LLPersistentNotificationChannel()
|
||||
: LLNotificationChannel("Persistent", "Visible", ¬ificationFilter)
|
||||
{}
|
||||
virtual ~LLPersistentNotificationChannel() {}
|
||||
|
||||
virtual ~LLPersistentNotificationChannel()
|
||||
{
|
||||
mHistory.clear();
|
||||
}
|
||||
|
||||
typedef std::vector<LLNotificationPtr> history_list_t;
|
||||
history_list_t::iterator beginHistory() { sortHistory(); return mHistory.begin(); }
|
||||
|
|
|
|||
|
|
@ -2193,6 +2193,13 @@ void LLTextEditor::showContextMenu(S32 x, S32 y, bool set_cursor_pos)
|
|||
mContextMenu = LLUICtrlFactory::instance().createFromFile<LLContextMenu>("menu_text_editor.xml",
|
||||
LLMenuGL::sMenuContainer,
|
||||
LLMenuHolderGL::child_registry_t::instance());
|
||||
// <FS:Beq> FIRE-31081 defend against null this prt exception in setItemVisible found in BugSplat
|
||||
if(!mContextMenu)
|
||||
{
|
||||
LL_WARNS() << "Failed to create context menu 'menu_text_editor'" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
// </FS:Beq>
|
||||
}
|
||||
|
||||
// Route menu to this class
|
||||
|
|
|
|||
|
|
@ -1337,7 +1337,7 @@ BOOL LLToolBarButton::handleHover(S32 x, S32 y, MASK mask)
|
|||
BOOL handled = FALSE;
|
||||
|
||||
S32 mouse_distance_squared = (x - mMouseDownX) * (x - mMouseDownX) + (y - mMouseDownY) * (y - mMouseDownY);
|
||||
S32 drag_threshold = LLUI::getInstance()->mSettingGroups["config"]->getS32("DragAndDropDistanceThreshold");
|
||||
static LLCachedControl<S32> drag_threshold(*LLUI::getInstance()->mSettingGroups["config"], "DragAndDropDistanceThreshold", 3);
|
||||
if (mouse_distance_squared > drag_threshold * drag_threshold
|
||||
&& hasMouseCapture() &&
|
||||
mStartDragItemCallback && mHandleDragItemCallback)
|
||||
|
|
|
|||
|
|
@ -358,8 +358,8 @@ void LLToolTip::draw()
|
|||
|
||||
if (mFadeTimer.getStarted())
|
||||
{
|
||||
F32 tool_tip_fade_time = LLUI::getInstance()->mSettingGroups["config"]->getF32("ToolTipFadeTime");
|
||||
alpha = clamp_rescale(mFadeTimer.getElapsedTimeF32(), 0.f, tool_tip_fade_time, 1.f, 0.f);
|
||||
static LLCachedControl<F32> tool_tip_fade_time(*LLUI::getInstance()->mSettingGroups["config"], "ToolTipFadeTime", 0.2f);
|
||||
alpha = clamp_rescale(mFadeTimer.getElapsedTimeF32(), 0.f, tool_tip_fade_time(), 1.f, 0.f);
|
||||
if (alpha == 0.f)
|
||||
{
|
||||
// finished fading out, so hide ourselves
|
||||
|
|
|
|||
|
|
@ -178,7 +178,6 @@ mAudioCallback(audio_callback),
|
|||
mDeferredAudioCallback(deferred_audio_callback),
|
||||
mWindow(NULL), // set later in startup
|
||||
mRootView(NULL),
|
||||
mDirty(FALSE),
|
||||
mHelpImpl(NULL)
|
||||
{
|
||||
LLRender2D::initParamSingleton(image_provider);
|
||||
|
|
@ -230,19 +229,6 @@ void LLUI::setPopupFuncs(const add_popup_t& add_popup, const remove_popup_t& rem
|
|||
mClearPopupsFunc = clear_popups;
|
||||
}
|
||||
|
||||
void LLUI::dirtyRect(LLRect rect)
|
||||
{
|
||||
if (!mDirty)
|
||||
{
|
||||
mDirtyRect = rect;
|
||||
mDirty = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
mDirtyRect.unionWith(rect);
|
||||
}
|
||||
}
|
||||
|
||||
void LLUI::setMousePositionScreen(S32 x, S32 y)
|
||||
{
|
||||
#if defined(LL_DARWIN)
|
||||
|
|
@ -577,6 +563,18 @@ const LLView* LLUI::resolvePath(const LLView* context, const std::string& path)
|
|||
return context;
|
||||
}
|
||||
|
||||
//static
|
||||
LLVector2& LLUI::getScaleFactor()
|
||||
{
|
||||
return LLRender::sUIGLScaleFactor;
|
||||
}
|
||||
|
||||
//static
|
||||
void LLUI::setScaleFactor(const LLVector2& scale_factor)
|
||||
{
|
||||
LLRender::sUIGLScaleFactor = scale_factor;
|
||||
}
|
||||
|
||||
|
||||
// LLLocalClipRect and LLScreenClipRect moved to lllocalcliprect.h/cpp
|
||||
|
||||
|
|
|
|||
|
|
@ -250,10 +250,6 @@ public:
|
|||
|
||||
void setPopupFuncs(const add_popup_t& add_popup, const remove_popup_t&, const clear_popups_t& );
|
||||
|
||||
LLRect mDirtyRect;
|
||||
BOOL mDirty;
|
||||
void dirtyRect(LLRect rect);
|
||||
|
||||
// Return the ISO639 language name ("en", "ko", etc.) for the viewer UI.
|
||||
// http://www.loc.gov/standards/iso639-2/php/code_list.php
|
||||
// <FS:Ansariel> FIRE-16709: Bypass FSEnabledLanguages for llGetAgentLanguage
|
||||
|
|
@ -321,14 +317,14 @@ public:
|
|||
void positionViewNearMouse(LLView* view, S32 spawn_x = S32_MAX, S32 spawn_y = S32_MAX);
|
||||
|
||||
// LLRender2D wrappers
|
||||
static void pushMatrix() { LLRender2D::getInstance()->pushMatrix(); }
|
||||
static void popMatrix() { LLRender2D::getInstance()->popMatrix(); }
|
||||
static void loadIdentity() { LLRender2D::getInstance()->loadIdentity(); }
|
||||
static void translate(F32 x, F32 y, F32 z = 0.0f) { LLRender2D::getInstance()->translate(x, y, z); }
|
||||
static void pushMatrix() { LLRender2D::pushMatrix(); }
|
||||
static void popMatrix() { LLRender2D::popMatrix(); }
|
||||
static void loadIdentity() { LLRender2D::loadIdentity(); }
|
||||
static void translate(F32 x, F32 y, F32 z = 0.0f) { LLRender2D::translate(x, y, z); }
|
||||
|
||||
static LLVector2& getScaleFactor() { return LLRender2D::getInstance()->mGLScaleFactor; }
|
||||
static void setScaleFactor(const LLVector2& scale_factor) { LLRender2D::getInstance()->setScaleFactor(scale_factor); }
|
||||
static void setLineWidth(F32 width) { LLRender2D::getInstance()->setLineWidth(width); }
|
||||
static LLVector2& getScaleFactor();
|
||||
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::getInstance()->getUIImageByID(image_id, priority); }
|
||||
static LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority = 0)
|
||||
|
|
|
|||
|
|
@ -179,7 +179,7 @@ void LLUrlEntryBase::callObservers(const std::string &id,
|
|||
bool LLUrlEntryBase::isLinkDisabled() const
|
||||
{
|
||||
// this allows us to have a global setting to turn off text hyperlink highlighting/action
|
||||
bool globally_disabled = LLUI::getInstance()->mSettingGroups["config"]->getBOOL("DisableTextHyperlinkActions");
|
||||
static LLCachedControl<bool> globally_disabled(*LLUI::getInstance()->mSettingGroups["config"], "DisableTextHyperlinkActions", false);
|
||||
|
||||
return globally_disabled;
|
||||
}
|
||||
|
|
@ -529,7 +529,9 @@ LLUrlEntrySecondlifeURL::LLUrlEntrySecondlifeURL()
|
|||
"|"
|
||||
"(https://([-\\w\\.]*\\.)?(secondlife|lindenlab|tilia-inc)\\.com(:\\d{1,5})?)"
|
||||
"|"
|
||||
"(https://([-\\w\\.]*\\.)?secondlifegrid\\.net(:\\d{1,5})?))"
|
||||
"(https://([-\\w\\.]*\\.)?secondlifegrid\\.net(:\\d{1,5})?)"
|
||||
"|"
|
||||
"(https?://([-\\w\\.]*\\.)?secondlife\\.io(:\\d{1,5})?))"
|
||||
"\\/\\S*",
|
||||
boost::regex::perl|boost::regex::icase);
|
||||
|
||||
|
|
@ -1275,7 +1277,7 @@ std::string LLUrlEntryPlace::getLocation(const std::string &url) const
|
|||
//
|
||||
LLUrlEntryRegion::LLUrlEntryRegion()
|
||||
{
|
||||
mPattern = boost::regex("secondlife:///app/region/[^/\\s]+(/\\d+)?(/\\d+)?(/\\d+)?/?",
|
||||
mPattern = boost::regex("secondlife:///app/region/[A-Za-z0-9()_%]+(/\\d+)?(/\\d+)?(/\\d+)?/?",
|
||||
boost::regex::perl|boost::regex::icase);
|
||||
mMenuName = "menu_url_slurl.xml";
|
||||
mTooltip = LLTrans::getString("TooltipSLURL");
|
||||
|
|
|
|||
|
|
@ -65,6 +65,8 @@ static const S32 LINE_HEIGHT = 15;
|
|||
|
||||
S32 LLView::sDepth = 0;
|
||||
bool LLView::sDebugRects = false;
|
||||
bool LLView::sIsRectDirty = false;
|
||||
LLRect LLView::sDirtyRect;
|
||||
bool LLView::sDebugRectsShowNames = true;
|
||||
bool LLView::sDebugKeys = false;
|
||||
bool LLView::sDebugMouseHandling = false;
|
||||
|
|
@ -941,14 +943,16 @@ BOOL LLView::handleToolTip(S32 x, S32 y, MASK mask)
|
|||
std::string tooltip = getToolTip();
|
||||
if (!tooltip.empty())
|
||||
{
|
||||
static LLCachedControl<F32> tooltip_fast_delay(*LLUI::getInstance()->mSettingGroups["config"], "ToolTipFastDelay", 0.1f);
|
||||
static LLCachedControl<F32> tooltip_delay(*LLUI::getInstance()->mSettingGroups["config"], "ToolTipDelay", 0.7f);
|
||||
static LLCachedControl<bool> allow_ui_tooltips(*LLUI::getInstance()->mSettingGroups["config"], "BasicUITooltips", true);
|
||||
// allow "scrubbing" over ui by showing next tooltip immediately
|
||||
// if previous one was still visible
|
||||
F32 timeout = LLToolTipMgr::instance().toolTipVisible()
|
||||
? LLUI::getInstance()->mSettingGroups["config"]->getF32( "ToolTipFastDelay" )
|
||||
: LLUI::getInstance()->mSettingGroups["config"]->getF32( "ToolTipDelay" );
|
||||
? tooltip_fast_delay
|
||||
: tooltip_delay;
|
||||
|
||||
// Even if we don't show tooltips, consume the event, nothing below should show tooltip
|
||||
bool allow_ui_tooltips = LLUI::getInstance()->mSettingGroups["config"]->getBOOL("BasicUITooltips");
|
||||
if (allow_ui_tooltips)
|
||||
{
|
||||
LLToolTipMgr::instance().show(LLToolTip::Params()
|
||||
|
|
@ -1245,7 +1249,7 @@ void LLView::drawChildren()
|
|||
if (viewp->getVisible() && viewp->getRect().isValid())
|
||||
{
|
||||
LLRect screen_rect = viewp->calcScreenRect();
|
||||
if ( rootp->getLocalRect().overlaps(screen_rect) && LLUI::getInstance()->mDirtyRect.overlaps(screen_rect))
|
||||
if ( rootp->getLocalRect().overlaps(screen_rect) && sDirtyRect.overlaps(screen_rect))
|
||||
{
|
||||
LLUI::pushMatrix();
|
||||
{
|
||||
|
|
@ -1287,7 +1291,15 @@ void LLView::dirtyRect()
|
|||
parent = parent->getParent();
|
||||
}
|
||||
|
||||
LLUI::getInstance()->dirtyRect(cur->calcScreenRect());
|
||||
if (!sIsRectDirty)
|
||||
{
|
||||
sDirtyRect = cur->calcScreenRect();
|
||||
sIsRectDirty = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
sDirtyRect.unionWith(cur->calcScreenRect());
|
||||
}
|
||||
}
|
||||
|
||||
//Draw a box for debugging.
|
||||
|
|
|
|||
|
|
@ -671,6 +671,9 @@ public:
|
|||
// Draw debug rectangles around widgets to help with alignment and spacing
|
||||
static bool sDebugRects;
|
||||
|
||||
static bool sIsRectDirty;
|
||||
static LLRect sDirtyRect;
|
||||
|
||||
// Draw widget names and sizes when drawing debug rectangles, turning this
|
||||
// off is useful to make the rectangles themselves easier to see.
|
||||
static bool sDebugRectsShowNames;
|
||||
|
|
|
|||
|
|
@ -739,11 +739,6 @@ namespace tut
|
|||
"XXX secondlife:///app/region/Burning%20Life%20(Hyper)/27/210/30 XXX",
|
||||
"secondlife:///app/region/Burning%20Life%20(Hyper)/27/210/30");
|
||||
|
||||
// DEV-35459: SLURLs and teleport Links not parsed properly
|
||||
testRegex("Region with quote", url,
|
||||
"XXX secondlife:///app/region/A'ksha%20Oasis/41/166/701 XXX",
|
||||
"secondlife:///app/region/A%27ksha%20Oasis/41/166/701");
|
||||
|
||||
// Rendering tests.
|
||||
testLabel("Render /app/region/Ahern/50/50/50/", url,
|
||||
"secondlife:///app/region/Ahern/50/50/50/",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
This component is no longer used in Linden Lab builds.
|
||||
Change requests to support continued use by open source
|
||||
builds are welcome.
|
||||
|
|
@ -8,9 +8,7 @@ include(00-Common)
|
|||
include(Linking)
|
||||
|
||||
include(Boost)
|
||||
if (BUGSPLAT_DB)
|
||||
include(bugsplat)
|
||||
endif (BUGSPLAT_DB)
|
||||
include(bugsplat)
|
||||
include(BuildPackagesInfo)
|
||||
include(BuildVersion)
|
||||
include(CMakeCopyIfDifferent)
|
||||
|
|
@ -110,18 +108,18 @@ include_directories(
|
|||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
)
|
||||
|
||||
if (BUGSPLAT_DB)
|
||||
include_directories(
|
||||
${BUGSPLAT_INCLUDE_DIR}
|
||||
)
|
||||
endif (BUGSPLAT_DB)
|
||||
|
||||
include_directories(SYSTEM
|
||||
${LLCOMMON_SYSTEM_INCLUDE_DIRS}
|
||||
${LLXML_SYSTEM_INCLUDE_DIRS}
|
||||
${LLPHYSICSEXTENSIONS_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
if (USE_BUGSPLAT)
|
||||
include_directories(AFTER
|
||||
${BUGSPLAT_INCLUDE_DIR}
|
||||
)
|
||||
endif (USE_BUGSPLAT)
|
||||
|
||||
set(viewer_SOURCE_FILES
|
||||
# <Add FS includes below this line>
|
||||
alfloaterregiontracker.cpp
|
||||
|
|
@ -1744,11 +1742,11 @@ if (DARWIN)
|
|||
${COREAUDIO_LIBRARY}
|
||||
)
|
||||
|
||||
if (BUGSPLAT_DB)
|
||||
if (USE_BUGSPLAT)
|
||||
list(APPEND viewer_LIBRARIES
|
||||
${BUGSPLAT_LIBRARIES}
|
||||
)
|
||||
endif (BUGSPLAT_DB)
|
||||
endif (USE_BUGSPLAT)
|
||||
|
||||
# Add resource files to the project.
|
||||
set(viewer_RESOURCE_FILES
|
||||
|
|
@ -2196,10 +2194,10 @@ if (SDL_FOUND)
|
|||
)
|
||||
endif (SDL_FOUND)
|
||||
|
||||
if (BUGSPLAT_DB)
|
||||
if (USE_BUGSPLAT)
|
||||
set_property(TARGET ${VIEWER_BINARY_NAME}
|
||||
PROPERTY COMPILE_DEFINITIONS "LL_BUGSPLAT")
|
||||
endif (BUGSPLAT_DB)
|
||||
PROPERTY COMPILE_DEFINITIONS "${BUGSPLAT_DEFINE}")
|
||||
endif (USE_BUGSPLAT)
|
||||
|
||||
# add package files
|
||||
file(GLOB EVENT_HOST_SCRIPT_GLOB_LIST
|
||||
|
|
@ -2285,9 +2283,12 @@ if (WINDOWS)
|
|||
media_plugin_cef
|
||||
media_plugin_libvlc
|
||||
#media_plugin_example # <FS:Ansariel> Don't package example plugin
|
||||
windows-crash-logger
|
||||
)
|
||||
|
||||
if (NOT USE_BUGSPLAT)
|
||||
LIST(APPEND COPY_INPUT_DEPENDENCIES windows-crash-logger)
|
||||
endif (NOT USE_BUGSPLAT)
|
||||
|
||||
# <FS:Ansariel> Only copy OpenJPEG dll if needed
|
||||
if (NOT USE_KDU)
|
||||
list(APPEND COPY_INPUT_DEPENDENCIES
|
||||
|
|
@ -2361,10 +2362,11 @@ if (WINDOWS)
|
|||
add_dependencies(${VIEWER_BINARY_NAME} copy_win_scripts)
|
||||
endif (EXISTS ${CMAKE_SOURCE_DIR}/copy_win_scripts)
|
||||
|
||||
add_dependencies(${VIEWER_BINARY_NAME}
|
||||
SLPlugin
|
||||
windows-crash-logger
|
||||
)
|
||||
add_dependencies(${VIEWER_BINARY_NAME} SLPlugin)
|
||||
|
||||
if (NOT USE_BUGSPLAT)
|
||||
add_dependencies(${VIEWER_BINARY_NAME} windows-crash-logger)
|
||||
endif (NOT USE_BUGSPLAT)
|
||||
|
||||
# sets the 'working directory' for debugging from visual studio.
|
||||
# Condition for version can be moved to requirements once build agents will be updated (see TOOL-3865)
|
||||
|
|
@ -2527,11 +2529,11 @@ target_link_libraries(${VIEWER_BINARY_NAME}
|
|||
|
||||
target_link_libraries(${VIEWER_BINARY_NAME} ${DISCORD_LIBRARY} )
|
||||
|
||||
if (BUGSPLAT_DB)
|
||||
if (USE_BUGSPLAT)
|
||||
target_link_libraries(${VIEWER_BINARY_NAME}
|
||||
${BUGSPLAT_LIBRARIES}
|
||||
)
|
||||
endif (BUGSPLAT_DB)
|
||||
endif (USE_BUGSPLAT)
|
||||
|
||||
if (WINDOWS)
|
||||
target_link_libraries(${VIEWER_BINARY_NAME}
|
||||
|
|
@ -2553,7 +2555,6 @@ if (LINUX)
|
|||
if (NOT ENABLE_MEDIA_PLUGINS)
|
||||
set(COPY_INPUT_DEPENDENCIES
|
||||
${VIEWER_BINARY_NAME}
|
||||
linux-crash-logger
|
||||
SLPlugin
|
||||
media_plugin_cef
|
||||
#media_plugin_gstreamer010
|
||||
|
|
@ -2571,6 +2572,10 @@ else (NOT ENABLE_MEDIA_PLUGINS)
|
|||
)
|
||||
endif (NOT ENABLE_MEDIA_PLUGINS)
|
||||
|
||||
if (NOT USE_BUGSPLAT)
|
||||
LIST(APPEND COPY_INPUT_DEPENDENCIES linux-crash-logger)
|
||||
endif (NOT USE_BUGSPLAT)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${product}.tar.bz2
|
||||
COMMAND ${PYTHON_EXECUTABLE}
|
||||
|
|
@ -2719,8 +2724,11 @@ if (DARWIN)
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
|
||||
)
|
||||
|
||||
add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_libvlc media_plugin_cef mac-crash-logger)
|
||||
add_dependencies(${VIEWER_BINARY_NAME} mac-crash-logger)
|
||||
add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_libvlc media_plugin_cef)
|
||||
|
||||
if (NOT USE_BUGSPLAT)
|
||||
add_dependencies(${VIEWER_BINARY_NAME} mac-crash-logger)
|
||||
endif (NOT USE_BUGSPLAT)
|
||||
|
||||
if (ENABLE_SIGNING)
|
||||
set(SIGNING_SETTING "--signature=${SIGNING_IDENTITY}")
|
||||
|
|
@ -2764,7 +2772,7 @@ endif (INSTALL)
|
|||
|
||||
# Note that the conventional VIEWER_SYMBOL_FILE is set by ../../build.sh
|
||||
if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIEWER_SYMBOL_FILE)
|
||||
if (NOT BUGSPLAT_DB)
|
||||
if (NOT USE_BUGSPLAT)
|
||||
# Breakpad symbol-file generation
|
||||
set(SYMBOL_SEARCH_DIRS "")
|
||||
if (WINDOWS)
|
||||
|
|
@ -2781,7 +2789,7 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE
|
|||
list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/llplugin/slplugin/${CMAKE_CFG_INTDIR}")
|
||||
list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/mac_crash_logger/${CMAKE_CFG_INTDIR}")
|
||||
list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/media_plugins/gstreamer010/${CMAKE_CFG_INTDIR}")
|
||||
## set(VIEWER_EXE_GLOBS "'${product}' SLPlugin mac-crash-logger")
|
||||
## set(VIEWER_EXE_GLOBS "'${product}' SLPlugin")
|
||||
set(VIEWER_EXE_GLOBS "'${product}' mac-crash-logger")
|
||||
set(VIEWER_LIB_GLOB "*.dylib")
|
||||
endif (DARWIN)
|
||||
|
|
@ -2820,7 +2828,7 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE
|
|||
add_dependencies(generate_symbols "${VIEWER_COPY_MANIFEST}")
|
||||
endif (WINDOWS OR LINUX)
|
||||
|
||||
else (NOT BUGSPLAT_DB)
|
||||
else (NOT USE_BUGSPLAT)
|
||||
# BugSplat symbol-file generation
|
||||
if (WINDOWS)
|
||||
# Just pack up a tarball containing only the .pdb file for the
|
||||
|
|
@ -2904,9 +2912,9 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE
|
|||
if (LINUX)
|
||||
# TBD
|
||||
endif (LINUX)
|
||||
endif (NOT BUGSPLAT_DB)
|
||||
endif (NOT USE_BUGSPLAT)
|
||||
|
||||
# for both BUGSPLAT_DB and Breakpad
|
||||
# for both Bugsplat and Breakpad
|
||||
add_dependencies(llpackage generate_symbols)
|
||||
endif ()
|
||||
|
||||
|
|
@ -3048,6 +3056,10 @@ if (LL_TESTS)
|
|||
${BOOST_CONTEXT_LIBRARY}
|
||||
)
|
||||
|
||||
LL_ADD_INTEGRATION_TEST(cppfeatures
|
||||
""
|
||||
"${test_libs}"
|
||||
)
|
||||
LL_ADD_INTEGRATION_TEST(llsechandler_basic
|
||||
llsechandler_basic.cpp
|
||||
"${test_libs}"
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
6.4.21
|
||||
6.4.22
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -17965,19 +17965,6 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<!-- SL-12594 removes fixed function rendering
|
||||
<key>VertexShaderEnable</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Enable/disable all GLSL shaders (debug)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
-->
|
||||
<key>VivoxAutoPostCrashDumps</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -18114,8 +18101,7 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<key>VivoxVadSensitivity</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>
|
||||
A dimensionless value between 0 and 100, indicating the 'sensitivity of the VAD'. Increasing this value corresponds to decreasing the sensitivity of the VAD and 0 is turned off altogether</string>
|
||||
<string>A dimensionless value between 0 and 100, indicating the 'sensitivity of the VAD'. Increasing this value corresponds to decreasing the sensitivity of the VAD and 0 is turned off altogether</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,28 @@
|
|||
LLWearable version 22
|
||||
RASL SOCKS BROWN
|
||||
|
||||
permissions 0
|
||||
{
|
||||
base_mask 7fffffff
|
||||
owner_mask 7fffffff
|
||||
group_mask 00000000
|
||||
everyone_mask 00000000
|
||||
next_owner_mask 00082000
|
||||
creator_id 79908808-d272-49a8-864a-d133a10931e9
|
||||
owner_id 79908808-d272-49a8-864a-d133a10931e9
|
||||
last_owner_id 79908808-d272-49a8-864a-d133a10931e9
|
||||
group_id 00000000-0000-0000-0000-000000000000
|
||||
}
|
||||
sale_info 0
|
||||
{
|
||||
sale_type not
|
||||
sale_price 10
|
||||
}
|
||||
type 7
|
||||
parameters 4
|
||||
617 1
|
||||
818 1
|
||||
819 1
|
||||
820 1
|
||||
textures 1
|
||||
12 301a3097-2858-7614-829d-c5859741246f
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
LLWearable version 22
|
||||
RASL F SHOP SHOES FOOTSHAPER
|
||||
|
||||
permissions 0
|
||||
{
|
||||
base_mask 7fffffff
|
||||
owner_mask 7fffffff
|
||||
group_mask 00000000
|
||||
everyone_mask 00000000
|
||||
next_owner_mask 00082000
|
||||
creator_id df110c10-72e6-40d6-8916-14b4b0366b18
|
||||
owner_id df110c10-72e6-40d6-8916-14b4b0366b18
|
||||
last_owner_id df110c10-72e6-40d6-8916-14b4b0366b18
|
||||
group_id 00000000-0000-0000-0000-000000000000
|
||||
}
|
||||
sale_info 0
|
||||
{
|
||||
sale_type not
|
||||
sale_price 10
|
||||
}
|
||||
type 6
|
||||
parameters 10
|
||||
198 1
|
||||
503 .17
|
||||
508 -1
|
||||
513 0
|
||||
514 .37
|
||||
616 .1
|
||||
654 .08
|
||||
812 1
|
||||
813 1
|
||||
817 1
|
||||
textures 1
|
||||
7 3ab7e2fa-9572-ef36-1a30-d855dbea4f92
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,29 @@
|
|||
LLWearable version 22
|
||||
RASL F LEARN LEGGINGS
|
||||
|
||||
permissions 0
|
||||
{
|
||||
base_mask 7fffffff
|
||||
owner_mask 7fffffff
|
||||
group_mask 00000000
|
||||
everyone_mask 00000000
|
||||
next_owner_mask 00082000
|
||||
creator_id 79908808-d272-49a8-864a-d133a10931e9
|
||||
owner_id 79908808-d272-49a8-864a-d133a10931e9
|
||||
last_owner_id 79908808-d272-49a8-864a-d133a10931e9
|
||||
group_id 00000000-0000-0000-0000-000000000000
|
||||
}
|
||||
sale_info 0
|
||||
{
|
||||
sale_type not
|
||||
sale_price 10
|
||||
}
|
||||
type 11
|
||||
parameters 5
|
||||
619 1
|
||||
624 1
|
||||
824 1
|
||||
825 1
|
||||
826 1
|
||||
textures 1
|
||||
17 6f5d29ce-548f-fdd0-b8e1-1f90a123b76e
|
||||
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue