merge changes for i18n fixes
commit
f57aa3e83f
18
.hgtags
18
.hgtags
|
|
@ -29,7 +29,25 @@ c6e6324f5be1401f077ad18a4a0f6b46451c2f7b last_sprint
|
|||
9822eb3e25f7fe0c28ffd8aba45c507caa383cbc 2.2.0-beta2
|
||||
b0cd7e150009809a0b5b0a9d5785cd4bb230413a 2.2.0-beta3
|
||||
00a831292231faad7e44c69f76cb96f175b8dfad 2.2.0-beta4
|
||||
98e0d6df638429fd2f0476667504bd5a6b298def 2.3.0-beta1
|
||||
1415e6538d54fd5d568ee88343424d57c6803c2c 2.2.0-release
|
||||
98e0d6df638429fd2f0476667504bd5a6b298def 2.3.0-start
|
||||
a3c12342b1af0951b8aa3b828aacef17fcea8178 2.3.0-beta1
|
||||
db0fe9bb65187f365e58a717dd23d0f4754a9c1d 2.3.0-beta2
|
||||
6ad3d6fa35a4e320e9ce442fce2bf9c7fc852556 2.3.0-beta3
|
||||
6ad3d6fa35a4e320e9ce442fce2bf9c7fc852556 2.3.0-release
|
||||
dbc206fc61d89ff4cfe15aade0bf0c7bc7fee1c9 2.4.0-start
|
||||
dc6483491b4af559060bccaef8e9045a303212dd 2.4.0-beta1
|
||||
dc6483491b4af559060bccaef8e9045a303212dd 2.4.0-beta1
|
||||
3bc1f50a72e117f4d4ad8d555f0c785ea8cc201e 2.4.0-beta1
|
||||
25bd6007e3d2fc15db9326ed4b18a24a5969a46a 2.4.0-beta2
|
||||
1ed382c6a08ba3850b6ce9061bc551ddece0ea07 2.4.0-release
|
||||
a82e5b1e22c7f90e3c7977d146b80588f004ed0d 2.5.0-start
|
||||
76f586a8e22b1abe6b2339758c8ac0fa718975de 76f586a8e22b
|
||||
76f586a8e22b1abe6b2339758c8ac0fa718975de 76f586a8e22b
|
||||
0000000000000000000000000000000000000000 76f586a8e22b
|
||||
0000000000000000000000000000000000000000 76f586a8e22b
|
||||
345b17e7cf630db77e840b4fe3451bd476d750a3 76f586a8e22b
|
||||
345b17e7cf630db77e840b4fe3451bd476d750a3 2.5.0-beta1
|
||||
345b17e7cf630db77e840b4fe3451bd476d750a3 76f586a8e22b
|
||||
0000000000000000000000000000000000000000 76f586a8e22b
|
||||
|
|
|
|||
28
BuildParams
28
BuildParams
|
|
@ -14,6 +14,9 @@ public_build = true
|
|||
# Update Public Inworld Build Status Indicators
|
||||
email_status_this_is_os = true
|
||||
|
||||
# Limit extent of codeticket updates to revisions after...
|
||||
codeticket_since = 2.2.0-release
|
||||
|
||||
# ========================================
|
||||
# Viewer Development
|
||||
# ========================================
|
||||
|
|
@ -51,6 +54,7 @@ viewer-release.viewer_channel = "Second Life Release"
|
|||
viewer-release.login_channel = "Second Life Release"
|
||||
viewer-release.build_debug_release_separately = true
|
||||
viewer-release.build_viewer_update_version_manager = true
|
||||
viewer-release.release-viewer.jira = DRTVWR-13
|
||||
|
||||
# ========================================
|
||||
# aimee
|
||||
|
|
@ -205,5 +209,29 @@ viewer-tut-teamcity.email = enus@lindenlab.com
|
|||
viewer-tut-teamcity.build_server = false
|
||||
viewer-tut-teamcity.build_server_tests = false
|
||||
|
||||
# ========================================
|
||||
# experience
|
||||
# ========================================
|
||||
viewer-experience.public_build = false
|
||||
viewer-experience.viewer_channel = "Second Life SkyLight Viewer"
|
||||
viewer-experience.login_channel = "Second Life SkyLight Viewer"
|
||||
|
||||
# =================================================================
|
||||
# asset delivery 2010 projects
|
||||
# =================================================================
|
||||
viewer-asset-delivery.viewer_channel = "Second Life Development"
|
||||
viewer-asset-delivery.login_channel = "Second Life Development"
|
||||
viewer-asset-delivery.build_viewer_update_version_manager = false
|
||||
viewer-asset-delivery.email = monty@lindenlab.com
|
||||
viewer-asset-delivery.build_server = false
|
||||
viewer-asset-delivery.build_server_tests = false
|
||||
|
||||
viewer-asset-delivery-metrics.viewer_channel = "Second Life Development"
|
||||
viewer-asset-delivery-metrics.login_channel = "Second Life Development"
|
||||
viewer-asset-delivery-metrics.build_viewer_update_version_manager = false
|
||||
viewer-asset-delivery-metrics.email = monty@lindenlab.com
|
||||
viewer-asset-delivery-metrics.build_server = false
|
||||
viewer-asset-delivery-metrics.build_server_tests = false
|
||||
|
||||
|
||||
# eof
|
||||
|
|
|
|||
26
build.sh
26
build.sh
|
|
@ -59,10 +59,11 @@ pre_build()
|
|||
-t $variant \
|
||||
-G "$cmake_generator" \
|
||||
configure \
|
||||
-DGRID:STRING="$viewer_grid" \
|
||||
-DGRID:STRING="$viewer_grid" \
|
||||
-DVIEWER_CHANNEL:STRING="$viewer_channel" \
|
||||
-DVIEWER_LOGIN_CHANNEL:STRING="$login_channel" \
|
||||
-DINSTALL_PROPRIETARY:BOOL=ON \
|
||||
-DRELEASE_CRASH_REPORTING:BOOL=ON \
|
||||
-DLOCALIZESETUP:BOOL=ON \
|
||||
-DPACKAGE:BOOL=ON \
|
||||
-DCMAKE_VERBOSE_MAKEFILE:BOOL=TRUE
|
||||
|
|
@ -169,13 +170,7 @@ do
|
|||
mkdir -p "$build_dir"
|
||||
if pre_build "$variant" "$build_dir" >> "$build_log" 2>&1
|
||||
then
|
||||
if $build_link_parallel
|
||||
then
|
||||
begin_section BuildParallel
|
||||
( build "$variant" "$build_dir" > "$build_dir/build.log" 2>&1 ) &
|
||||
build_processes="$build_processes $!"
|
||||
end_section BuildParallel
|
||||
elif $build_coverity
|
||||
if $build_coverity
|
||||
then
|
||||
mkdir -p "$build_dir/cvbuild"
|
||||
coverity_config=`cygpath --windows "$coverity_dir/config/coverity_config.xml"`
|
||||
|
|
@ -197,7 +192,6 @@ do
|
|||
begin_section CovAnalyze\
|
||||
&&\
|
||||
"$coverity_dir"/bin/cov-analyze\
|
||||
--cxx\
|
||||
--security\
|
||||
--concurrency\
|
||||
--dir "$coverity_tmpdir"\
|
||||
|
|
@ -208,14 +202,14 @@ do
|
|||
begin_section CovCommit\
|
||||
&&\
|
||||
"$coverity_dir"/bin/cov-commit-defects\
|
||||
--product "$coverity_product"\
|
||||
--stream "$coverity_product"\
|
||||
--dir "$coverity_tmpdir"\
|
||||
--remote "$coverity_server"\
|
||||
--host "$coverity_server"\
|
||||
--strip-path "$coverity_root"\
|
||||
--target "$branch/$arch"\
|
||||
--version "$revision"\
|
||||
--description "$repo: $variant $revision"\
|
||||
--user admin --password admin\
|
||||
--user admin --password coverity\
|
||||
>> "$build_log" 2>&1\
|
||||
|| record_failure "Coverity Build Failed"
|
||||
# since any step could have failed, rely on the enclosing block to close any pending sub-blocks
|
||||
|
|
@ -226,9 +220,15 @@ do
|
|||
then
|
||||
upload_item log "$build_dir"/cvbuild/build-log.txt text/plain
|
||||
fi
|
||||
elif $build_link_parallel
|
||||
then
|
||||
begin_section BuildParallel
|
||||
( build "$variant" "$build_dir" > "$build_dir/build.log" 2>&1 ) &
|
||||
build_processes="$build_processes $!"
|
||||
end_section BuildParallel
|
||||
else
|
||||
begin_section "Build$variant"
|
||||
build "$variant" "$build_dir" > "$build_log" 2>&1
|
||||
build "$variant" "$build_dir" >> "$build_log" 2>&1
|
||||
begin_section Tests
|
||||
grep --line-buffered "^##teamcity" "$build_log"
|
||||
end_section Tests
|
||||
|
|
|
|||
|
|
@ -61,21 +61,34 @@ Aimee Trescothick
|
|||
Alejandro Rosenthal
|
||||
VWR-1184
|
||||
Aleric Inglewood
|
||||
SNOW-240
|
||||
SNOW-522
|
||||
SNOW-626
|
||||
SNOW-756
|
||||
SNOW-764
|
||||
VWR-10001
|
||||
VWR-10579
|
||||
VWR-10759
|
||||
VWR-10837
|
||||
VWR-12691
|
||||
VWR-12984
|
||||
VWR-13996
|
||||
VWR-14426
|
||||
VWR-24247
|
||||
VWR-24251
|
||||
VWR-24252
|
||||
VWR-24254
|
||||
VWR-24261
|
||||
SNOW-84
|
||||
SNOW-477
|
||||
SNOW-744
|
||||
SNOW-766
|
||||
STORM-163
|
||||
Ales Beaumont
|
||||
VWR-9352
|
||||
SNOW-240
|
||||
Alexandrea Fride
|
||||
STORM-255
|
||||
Alissa Sabre
|
||||
VWR-81
|
||||
VWR-83
|
||||
|
|
@ -124,6 +137,7 @@ Alissa Sabre
|
|||
VWR-12617
|
||||
VWR-12620
|
||||
VWR-12789
|
||||
SNOW-322
|
||||
Angus Boyd
|
||||
VWR-592
|
||||
Ann Congrejo
|
||||
|
|
@ -140,6 +154,7 @@ Asuka Neely
|
|||
Balp Allen
|
||||
VWR-4157
|
||||
Be Holder
|
||||
SNOW-322
|
||||
SNOW-397
|
||||
Benja Kepler
|
||||
VWR-746
|
||||
|
|
@ -170,9 +185,11 @@ Boroondas Gupte
|
|||
SNOW-610
|
||||
SNOW-624
|
||||
SNOW-737
|
||||
STORM-318
|
||||
VWR-233
|
||||
VWR-20583
|
||||
VWR-20891
|
||||
VWR-23455
|
||||
WEB-262
|
||||
Bulli Schumann
|
||||
CT-218
|
||||
|
|
@ -202,6 +219,10 @@ Catherine Pfeffer
|
|||
Celierra Darling
|
||||
VWR-1274
|
||||
VWR-6975
|
||||
Cron Stardust
|
||||
VWR-10579
|
||||
Cypren Christenson
|
||||
STORM-417
|
||||
Dale Glass
|
||||
VWR-120
|
||||
VWR-560
|
||||
|
|
@ -343,7 +364,15 @@ JB Kraft
|
|||
Joghert LeSabre
|
||||
VWR-64
|
||||
Jonathan Yap
|
||||
STORM-596
|
||||
STORM-523
|
||||
STORM-616
|
||||
STORM-679
|
||||
STORM-737
|
||||
STORM-726
|
||||
STORM-812
|
||||
VWR-17801
|
||||
STORM-785
|
||||
Kage Pixel
|
||||
VWR-11
|
||||
Ken March
|
||||
|
|
@ -357,6 +386,9 @@ Khyota Wulluf
|
|||
VWR-9966
|
||||
Kitty Barnett
|
||||
VWR-19699
|
||||
STORM-288
|
||||
STORM-799
|
||||
STORM-800
|
||||
Kunnis Basiat
|
||||
VWR-82
|
||||
VWR-102
|
||||
|
|
@ -381,6 +413,8 @@ Malwina Dollinger
|
|||
CT-138
|
||||
march Korda
|
||||
SVC-1020
|
||||
Marine Kelley
|
||||
STORM-281
|
||||
Matthew Dowd
|
||||
VWR-1344
|
||||
VWR-1651
|
||||
|
|
@ -402,6 +436,7 @@ McCabe Maxsted
|
|||
VWR-8689
|
||||
VWR-9007
|
||||
Michelle2 Zenovka
|
||||
STORM-477
|
||||
VWR-2652
|
||||
VWR-2662
|
||||
VWR-2834
|
||||
|
|
@ -529,6 +564,7 @@ Pf Shan
|
|||
CT-230
|
||||
CT-231
|
||||
CT-321
|
||||
SNOW-422
|
||||
princess niven
|
||||
VWR-5733
|
||||
CT-85
|
||||
|
|
@ -562,8 +598,10 @@ Robin Cornelius
|
|||
SNOW-585
|
||||
SNOW-599
|
||||
SNOW-747
|
||||
STORM-422
|
||||
VWR-2488
|
||||
VWR-9557
|
||||
VWR-10579
|
||||
VWR-11128
|
||||
VWR-12533
|
||||
VWR-12587
|
||||
|
|
@ -585,6 +623,9 @@ Salahzar Stenvaag
|
|||
CT-321
|
||||
Sammy Frederix
|
||||
VWR-6186
|
||||
Satomi Ahn
|
||||
STORM-501
|
||||
STORM-229
|
||||
Scrippy Scofield
|
||||
VWR-3748
|
||||
Seg Baphomet
|
||||
|
|
@ -643,6 +684,7 @@ Strife Onizuka
|
|||
VWR-183
|
||||
VWR-2265
|
||||
VWR-4111
|
||||
SNOW-691
|
||||
Tayra Dagostino
|
||||
SNOW-517
|
||||
SNOW-543
|
||||
|
|
@ -695,6 +737,8 @@ Thraxis Epsilon
|
|||
VWR-383
|
||||
tiamat bingyi
|
||||
CT-246
|
||||
Tofu Buzzard
|
||||
STORM-546
|
||||
TraductoresAnonimos Alter
|
||||
CT-324
|
||||
Tue Torok
|
||||
|
|
@ -706,6 +750,8 @@ Tue Torok
|
|||
CT-74
|
||||
Twisted Laws
|
||||
SNOW-352
|
||||
STORM-466
|
||||
STORM-467
|
||||
Vadim Bigbear
|
||||
VWR-2681
|
||||
Vector Hastings
|
||||
|
|
@ -740,6 +786,23 @@ Whoops Babii
|
|||
VWR-8298
|
||||
Wilton Lundquist
|
||||
VWR-7682
|
||||
WolfPup Lowenhar
|
||||
SNOW-622
|
||||
SNOW-772
|
||||
STORM-102
|
||||
STORM-103
|
||||
STORM-143
|
||||
STORM-255
|
||||
STORM-256
|
||||
STORM-288
|
||||
STORM-535
|
||||
STORM-544
|
||||
STORM-654
|
||||
STORM-674
|
||||
STORM-776
|
||||
STORM-825
|
||||
VWR-20741
|
||||
VWR-20933
|
||||
Zai Lynch
|
||||
VWR-19505
|
||||
Zarkonnen Decosta
|
||||
|
|
|
|||
|
|
@ -442,6 +442,14 @@
|
|||
<boolean>true</boolean>
|
||||
</map>
|
||||
|
||||
<key>SimConsoleResponse</key>
|
||||
<map>
|
||||
<key>flavor</key>
|
||||
<string>llsd</string>
|
||||
<key>trusted-sender</key>
|
||||
<boolean>true</boolean>
|
||||
</map>
|
||||
|
||||
<key>DirLandReply</key>
|
||||
<map>
|
||||
<key>flavor</key>
|
||||
|
|
|
|||
|
|
@ -22,7 +22,10 @@ set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
|
|||
include(Variables)
|
||||
|
||||
if (DARWIN)
|
||||
cmake_minimum_required(VERSION 2.6.2 FATAL_ERROR)
|
||||
# 2.6.4 fixes a Mac bug in get_target_property(... "SLPlugin" LOCATION):
|
||||
# before that version it returns "pathname/SLPlugin", whereas the correct
|
||||
# answer is "pathname/SLPlugin.app/Contents/MacOS/SLPlugin".
|
||||
cmake_minimum_required(VERSION 2.6.4 FATAL_ERROR)
|
||||
endif (DARWIN)
|
||||
|
||||
if (NOT CMAKE_BUILD_TYPE)
|
||||
|
|
@ -40,6 +43,7 @@ add_subdirectory(${LIBS_OPEN_PREFIX}llaudio)
|
|||
add_subdirectory(${LIBS_OPEN_PREFIX}llcharacter)
|
||||
add_subdirectory(${LIBS_OPEN_PREFIX}llcommon)
|
||||
add_subdirectory(${LIBS_OPEN_PREFIX}llimage)
|
||||
add_subdirectory(${LIBS_OPEN_PREFIX}llkdu)
|
||||
add_subdirectory(${LIBS_OPEN_PREFIX}llimagej2coj)
|
||||
add_subdirectory(${LIBS_OPEN_PREFIX}llinventory)
|
||||
add_subdirectory(${LIBS_OPEN_PREFIX}llmath)
|
||||
|
|
@ -50,10 +54,6 @@ add_subdirectory(${LIBS_OPEN_PREFIX}llvfs)
|
|||
add_subdirectory(${LIBS_OPEN_PREFIX}llwindow)
|
||||
add_subdirectory(${LIBS_OPEN_PREFIX}llxml)
|
||||
|
||||
if (EXISTS ${LIBS_CLOSED_DIR}llkdu)
|
||||
add_subdirectory(${LIBS_CLOSED_PREFIX}llkdu)
|
||||
endif (EXISTS ${LIBS_CLOSED_DIR}llkdu)
|
||||
|
||||
add_subdirectory(${LIBS_OPEN_PREFIX}lscript)
|
||||
|
||||
if (WINDOWS AND EXISTS ${LIBS_CLOSED_DIR}copy_win_scripts)
|
||||
|
|
|
|||
|
|
@ -4,27 +4,28 @@
|
|||
|
||||
include(Variables)
|
||||
|
||||
|
||||
# Portable compilation flags.
|
||||
|
||||
if (EXISTS ${CMAKE_SOURCE_DIR}/llphysics)
|
||||
# The release build should only offer to send crash reports if we're
|
||||
# building from a Linden internal source tree.
|
||||
set(release_crash_reports 1)
|
||||
else (EXISTS ${CMAKE_SOURCE_DIR}/llphysics)
|
||||
set(release_crash_reports 0)
|
||||
endif (EXISTS ${CMAKE_SOURCE_DIR}/llphysics)
|
||||
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-D_DEBUG -DLL_DEBUG=1")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE
|
||||
"-DLL_RELEASE=1 -DLL_RELEASE_FOR_DOWNLOAD=1 -D_SECURE_SCL=0 -DLL_SEND_CRASH_REPORTS=${release_crash_reports} -DNDEBUG")
|
||||
"-DLL_RELEASE=1 -DLL_RELEASE_FOR_DOWNLOAD=1 -D_SECURE_SCL=0 -DNDEBUG")
|
||||
|
||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO
|
||||
"-DLL_RELEASE=1 -D_SECURE_SCL=0 -DLL_SEND_CRASH_REPORTS=0 -DNDEBUG -DLL_RELEASE_WITH_DEBUG_INFO=1")
|
||||
"-DLL_RELEASE=1 -D_SECURE_SCL=0 -DNDEBUG -DLL_RELEASE_WITH_DEBUG_INFO=1")
|
||||
|
||||
# Configure crash reporting
|
||||
set(RELEASE_CRASH_REPORTING OFF CACHE BOOL "Enable use of crash reporting in release builds")
|
||||
set(NON_RELEASE_CRASH_REPORTING OFF CACHE BOOL "Enable use of crash reporting in developer builds")
|
||||
|
||||
if(RELEASE_CRASH_REPORTING)
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DLL_SEND_CRASH_REPORTS=1")
|
||||
endif()
|
||||
|
||||
if(NON_RELEASE_CRASH_REPORTING)
|
||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DLL_SEND_CRASH_REPORTS=1")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DLL_SEND_CRASH_REPORTS=1")
|
||||
endif()
|
||||
|
||||
# Don't bother with a MinSizeRel build.
|
||||
|
||||
set(CMAKE_CONFIGURATION_TYPES "RelWithDebInfo;Release;Debug" CACHE STRING
|
||||
"Supported build types." FORCE)
|
||||
|
||||
|
|
@ -38,10 +39,10 @@ if (WINDOWS)
|
|||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Od /Zi /MDd /MP"
|
||||
CACHE STRING "C++ compiler debug options" FORCE)
|
||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO
|
||||
"${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Od /Zi /MD /MP"
|
||||
"${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Od /Zi /MD /MP /Ob2"
|
||||
CACHE STRING "C++ compiler release-with-debug options" FORCE)
|
||||
set(CMAKE_CXX_FLAGS_RELEASE
|
||||
"${CMAKE_CXX_FLAGS_RELEASE} ${LL_CXX_FLAGS} /O2 /Zi /MD /MP"
|
||||
"${CMAKE_CXX_FLAGS_RELEASE} ${LL_CXX_FLAGS} /O2 /Zi /MD /MP /Ob2"
|
||||
CACHE STRING "C++ compiler release options" FORCE)
|
||||
|
||||
set(CMAKE_CXX_STANDARD_LIBRARIES "")
|
||||
|
|
|
|||
|
|
@ -6,6 +6,11 @@ set(DB_FIND_REQUIRED ON)
|
|||
if (STANDALONE)
|
||||
include(FindBerkeleyDB)
|
||||
else (STANDALONE)
|
||||
set(DB_LIBRARIES db-4.2)
|
||||
if (LINUX)
|
||||
# Need to add dependency pthread explicitely to support ld.gold.
|
||||
set(DB_LIBRARIES db-4.2 pthread)
|
||||
else (LINUX)
|
||||
set(DB_LIBRARIES db-4.2)
|
||||
endif (LINUX)
|
||||
set(DB_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include)
|
||||
endif (STANDALONE)
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ set(cmake_SOURCE_FILES
|
|||
FindMySQL.cmake
|
||||
FindOpenJPEG.cmake
|
||||
FindXmlRpcEpi.cmake
|
||||
FindZLIB.cmake
|
||||
FMOD.cmake
|
||||
FreeType.cmake
|
||||
GStreamer010Plugin.cmake
|
||||
|
|
|
|||
|
|
@ -10,10 +10,10 @@ else (STANDALONE)
|
|||
use_prebuilt_binary(curl)
|
||||
if (WINDOWS)
|
||||
set(CURL_LIBRARIES
|
||||
debug libcurld
|
||||
optimized libcurl)
|
||||
debug libcurld.lib
|
||||
optimized libcurl.lib)
|
||||
else (WINDOWS)
|
||||
set(CURL_LIBRARIES curl)
|
||||
set(CURL_LIBRARIES libcurl.a)
|
||||
endif (WINDOWS)
|
||||
set(CURL_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include)
|
||||
endif (STANDALONE)
|
||||
|
|
|
|||
|
|
@ -60,22 +60,6 @@ if(WINDOWS)
|
|||
set(release_files ${release_files} fmod.dll)
|
||||
endif (FMOD)
|
||||
|
||||
#*******************************
|
||||
# LLKDU
|
||||
set(internal_llkdu_path "${CMAKE_SOURCE_DIR}/llkdu")
|
||||
if(NOT EXISTS ${internal_llkdu_path})
|
||||
if (EXISTS "${debug_src_dir}/llkdu.dll")
|
||||
set(debug_llkdu_src "${debug_src_dir}/llkdu.dll")
|
||||
set(debug_llkdu_dst "${SHARED_LIB_STAGING_DIR_DEBUG}/llkdu.dll")
|
||||
endif (EXISTS "${debug_src_dir}/llkdu.dll")
|
||||
|
||||
if (EXISTS "${release_src_dir}/llkdu.dll")
|
||||
set(release_llkdu_src "${release_src_dir}/llkdu.dll")
|
||||
set(release_llkdu_dst "${SHARED_LIB_STAGING_DIR_RELEASE}/llkdu.dll")
|
||||
set(relwithdebinfo_llkdu_dst "${SHARED_LIB_STAGING_DIR_RELWITHDEBINFO}/llkdu.dll")
|
||||
endif (EXISTS "${release_src_dir}/llkdu.dll")
|
||||
endif (NOT EXISTS ${internal_llkdu_path})
|
||||
|
||||
#*******************************
|
||||
# Copy MS C runtime dlls, required for packaging.
|
||||
# *TODO - Adapt this to support VC9
|
||||
|
|
@ -174,21 +158,6 @@ elseif(DARWIN)
|
|||
# fmod is statically linked on darwin
|
||||
set(fmod_files "")
|
||||
|
||||
#*******************************
|
||||
# LLKDU
|
||||
set(internal_llkdu_path "${CMAKE_SOURCE_DIR}/llkdu")
|
||||
if(NOT EXISTS ${internal_llkdu_path})
|
||||
if (EXISTS "${debug_src_dir}/libllkdu.dylib")
|
||||
set(debug_llkdu_src "${debug_src_dir}/libllkdu.dylib")
|
||||
set(debug_llkdu_dst "${SHARED_LIB_STAGING_DIR_DEBUG}/libllkdu.dylib")
|
||||
endif (EXISTS "${debug_src_dir}/libllkdu.dylib")
|
||||
|
||||
if (EXISTS "${release_src_dir}/libllkdu.dylib")
|
||||
set(release_llkdu_src "${release_src_dir}/libllkdu.dylib")
|
||||
set(release_llkdu_dst "${SHARED_LIB_STAGING_DIR_RELEASE}/libllkdu.dylib")
|
||||
set(relwithdebinfo_llkdu_dst "${SHARED_LIB_STAGING_DIR_RELWITHDEBINFO}/libllkdu.dylib")
|
||||
endif (EXISTS "${release_src_dir}/libllkdu.dylib")
|
||||
endif (NOT EXISTS ${internal_llkdu_path})
|
||||
elseif(LINUX)
|
||||
# linux is weird, multiple side by side configurations aren't supported
|
||||
# and we don't seem to have any debug shared libs built yet anyways...
|
||||
|
|
@ -242,21 +211,6 @@ elseif(LINUX)
|
|||
set(release_files ${release_files} "libfmod-3.75.so")
|
||||
endif (FMOD)
|
||||
|
||||
#*******************************
|
||||
# LLKDU
|
||||
set(internal_llkdu_path "${CMAKE_SOURCE_DIR}/llkdu")
|
||||
if(NOT EXISTS ${internal_llkdu_path})
|
||||
if (EXISTS "${debug_src_dir}/libllkdu.so")
|
||||
set(debug_llkdu_src "${debug_src_dir}/libllkdu.so")
|
||||
set(debug_llkdu_dst "${SHARED_LIB_STAGING_DIR_DEBUG}/libllkdu.so")
|
||||
endif (EXISTS "${debug_src_dir}/libllkdu.so")
|
||||
|
||||
if (EXISTS "${release_src_dir}/libllkdu.so")
|
||||
set(release_llkdu_src "${release_src_dir}/libllkdu.so")
|
||||
set(release_llkdu_dst "${SHARED_LIB_STAGING_DIR_RELEASE}/libllkdu.so")
|
||||
set(relwithdebinfo_llkdu_dst "${SHARED_LIB_STAGING_DIR_RELWITHDEBINFO}/libllkdu.so")
|
||||
endif (EXISTS "${release_src_dir}/libllkdu.so")
|
||||
endif(NOT EXISTS ${internal_llkdu_path})
|
||||
else(WINDOWS)
|
||||
message(STATUS "WARNING: unrecognized platform for staging 3rd party libs, skipping...")
|
||||
set(vivox_src_dir "${CMAKE_SOURCE_DIR}/newview/vivox-runtime/i686-linux")
|
||||
|
|
@ -334,40 +288,29 @@ copy_if_different(
|
|||
)
|
||||
set(third_party_targets ${third_party_targets} ${out_targets})
|
||||
|
||||
#*******************************
|
||||
# LLKDU
|
||||
set(internal_llkdu_path "${CMAKE_SOURCE_DIR}/llkdu")
|
||||
if(NOT EXISTS ${internal_llkdu_path})
|
||||
if (EXISTS "${debug_llkdu_src}")
|
||||
ADD_CUSTOM_COMMAND(
|
||||
OUTPUT ${debug_llkdu_dst}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${debug_llkdu_src} ${debug_llkdu_dst}
|
||||
DEPENDS ${debug_llkdu_src}
|
||||
COMMENT "Copying llkdu.dll ${SHARED_LIB_STAGING_DIR_DEBUG}"
|
||||
)
|
||||
set(third_party_targets ${third_party_targets} $} ${debug_llkdu_dst})
|
||||
endif (EXISTS "${debug_llkdu_src}")
|
||||
|
||||
if (EXISTS "${release_llkdu_src}")
|
||||
ADD_CUSTOM_COMMAND(
|
||||
OUTPUT ${release_llkdu_dst}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${release_llkdu_src} ${release_llkdu_dst}
|
||||
DEPENDS ${release_llkdu_src}
|
||||
COMMENT "Copying llkdu.dll ${SHARED_LIB_STAGING_DIR_RELEASE}"
|
||||
)
|
||||
set(third_party_targets ${third_party_targets} ${release_llkdu_dst})
|
||||
|
||||
ADD_CUSTOM_COMMAND(
|
||||
OUTPUT ${relwithdebinfo_llkdu_dst}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${release_llkdu_src} ${relwithdebinfo_llkdu_dst}
|
||||
DEPENDS ${release_llkdu_src}
|
||||
COMMENT "Copying llkdu.dll ${SHARED_LIB_STAGING_DIR_RELWITHDEBINFO}"
|
||||
)
|
||||
set(third_party_targets ${third_party_targets} ${relwithdebinfo_llkdu_dst})
|
||||
endif (EXISTS "${release_llkdu_src}")
|
||||
|
||||
endif (NOT EXISTS ${internal_llkdu_path})
|
||||
|
||||
if (FMOD_SDK_DIR)
|
||||
copy_if_different(
|
||||
${FMOD_SDK_DIR}
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/Debug"
|
||||
out_targets
|
||||
${fmod_files}
|
||||
)
|
||||
set(all_targets ${all_targets} ${out_targets})
|
||||
copy_if_different(
|
||||
${FMOD_SDK_DIR}
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/Release"
|
||||
out_targets
|
||||
${fmod_files}
|
||||
)
|
||||
set(all_targets ${all_targets} ${out_targets})
|
||||
copy_if_different(
|
||||
${FMOD_SDK_DIR}
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/RelWithDbgInfo"
|
||||
out_targets
|
||||
${fmod_files}
|
||||
)
|
||||
set(all_targets ${all_targets} ${out_targets})
|
||||
endif (FMOD_SDK_DIR)
|
||||
|
||||
if(NOT STANDALONE)
|
||||
add_custom_target(
|
||||
|
|
|
|||
|
|
@ -7,8 +7,10 @@ if (FMOD)
|
|||
set(FMOD_FIND_REQUIRED ON)
|
||||
include(FindFMOD)
|
||||
else (STANDALONE)
|
||||
include(Prebuilt)
|
||||
use_prebuilt_binary(fmod)
|
||||
if (INSTALL_PROPRIETARY)
|
||||
include(Prebuilt)
|
||||
use_prebuilt_binary(fmod)
|
||||
endif (INSTALL_PROPRIETARY)
|
||||
|
||||
if (WINDOWS)
|
||||
set(FMOD_LIBRARY fmod)
|
||||
|
|
|
|||
|
|
@ -21,7 +21,12 @@ EXEC_PROGRAM(${CMAKE_CXX_COMPILER}
|
|||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
# Try to find a library that was compiled with the same compiler version as we currently use.
|
||||
SET(JSONCPP_NAMES ${JSONCPP_NAMES} libjson_linux-gcc-${_gcc_COMPILER_VERSION}_libmt.so)
|
||||
IF (STANDALONE)
|
||||
# On standalone, assume that the system installed library was compiled with the used compiler.
|
||||
SET(JSONCPP_NAMES ${JSONCPP_NAMES} libjson.so)
|
||||
ENDIF (STANDALONE)
|
||||
FIND_LIBRARY(JSONCPP_LIBRARY
|
||||
NAMES ${JSONCPP_NAMES}
|
||||
PATHS /usr/lib /usr/local/lib
|
||||
|
|
|
|||
|
|
@ -0,0 +1,62 @@
|
|||
# -*- cmake -*-
|
||||
|
||||
# - Find llqtwebkit
|
||||
# Find the llqtwebkit includes and library
|
||||
# This module defines
|
||||
# LLQTWEBKIT_INCLUDE_DIR, where to find llqtwebkit.h, etc.
|
||||
# LLQTWEBKIT_LIBRARY, the llqtwebkit library with full path.
|
||||
# LLQTWEBKIT_FOUND, If false, do not try to use llqtwebkit.
|
||||
# also defined, but not for general use are
|
||||
# LLQTWEBKIT_LIBRARIES, the libraries needed to use llqtwebkit.
|
||||
# LLQTWEBKIT_LIBRARY_DIRS, where to find the llqtwebkit library.
|
||||
# LLQTWEBKIT_DEFINITIONS - You should add_definitions(${LLQTWEBKIT_DEFINITIONS})
|
||||
# before compiling code that includes llqtwebkit library files.
|
||||
|
||||
# Try to use pkg-config first.
|
||||
# This allows to have two different libllqtwebkit packages installed:
|
||||
# one for viewer 2.x and one for viewer 1.x.
|
||||
include(FindPkgConfig)
|
||||
if (PKG_CONFIG_FOUND)
|
||||
if (LLQtWebkit_FIND_REQUIRED AND LLQtWebkit_FIND_VERSION)
|
||||
set(_PACKAGE_ARGS libllqtwebkit>=${LLQtWebkit_FIND_VERSION} REQUIRED)
|
||||
else (LLQtWebkit_FIND_REQUIRED AND LLQtWebkit_FIND_VERSION)
|
||||
set(_PACKAGE_ARGS libllqtwebkit)
|
||||
endif (LLQtWebkit_FIND_REQUIRED AND LLQtWebkit_FIND_VERSION)
|
||||
if (NOT "${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" VERSION_LESS "2.8")
|
||||
# As virtually nobody will have a pkg-config file for this, do this check always quiet.
|
||||
# Unfortunately cmake 2.8 or higher is required for pkg_check_modules to have a 'QUIET'.
|
||||
set(_PACKAGE_ARGS ${_PACKAGE_ARGS} QUIET)
|
||||
endif ()
|
||||
pkg_check_modules(LLQTWEBKIT ${_PACKAGE_ARGS})
|
||||
endif (PKG_CONFIG_FOUND)
|
||||
set(LLQTWEBKIT_DEFINITIONS ${LLQTWEBKIT_CFLAGS_OTHER})
|
||||
|
||||
find_path(LLQTWEBKIT_INCLUDE_DIR llqtwebkit.h NO_SYSTEM_ENVIRONMENT_PATH HINTS ${LLQTWEBKIT_INCLUDE_DIRS})
|
||||
|
||||
find_library(LLQTWEBKIT_LIBRARY NAMES llqtwebkit NO_SYSTEM_ENVIRONMENT_PATH HINTS ${LLQTWEBKIT_LIBRARY_DIRS})
|
||||
|
||||
if (NOT PKG_CONFIG_FOUND OR NOT LLQTWEBKIT_FOUND) # If pkg-config couldn't find it, pretend we don't have pkg-config.
|
||||
set(LLQTWEBKIT_LIBRARIES llqtwebkit)
|
||||
get_filename_component(LLQTWEBKIT_LIBRARY_DIRS ${LLQTWEBKIT_LIBRARY} PATH)
|
||||
endif (NOT PKG_CONFIG_FOUND OR NOT LLQTWEBKIT_FOUND)
|
||||
|
||||
# Handle the QUIETLY and REQUIRED arguments and set LLQTWEBKIT_FOUND
|
||||
# to TRUE if all listed variables are TRUE.
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(
|
||||
LLQTWEBKIT
|
||||
DEFAULT_MSG
|
||||
LLQTWEBKIT_LIBRARY
|
||||
LLQTWEBKIT_INCLUDE_DIR
|
||||
LLQTWEBKIT_LIBRARIES
|
||||
LLQTWEBKIT_LIBRARY_DIRS
|
||||
)
|
||||
|
||||
mark_as_advanced(
|
||||
LLQTWEBKIT_LIBRARY
|
||||
LLQTWEBKIT_INCLUDE_DIR
|
||||
LLQTWEBKIT_LIBRARIES
|
||||
LLQTWEBKIT_LIBRARY_DIRS
|
||||
LLQTWEBKIT_DEFINITIONS
|
||||
)
|
||||
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
# -*- cmake -*-
|
||||
|
||||
# - Find NDOF
|
||||
# Find the NDOF includes and library
|
||||
# This module defines
|
||||
# NDOF_INCLUDE_DIR, where to find ndofdev_external.h, etc.
|
||||
# NDOF_LIBRARY, the library needed to use NDOF.
|
||||
# NDOF_FOUND, If false, do not try to use NDOF.
|
||||
|
||||
find_path(NDOF_INCLUDE_DIR ndofdev_external.h
|
||||
PATH_SUFFIXES ndofdev
|
||||
)
|
||||
|
||||
set(NDOF_NAMES ${NDOF_NAMES} ndofdev libndofdev)
|
||||
find_library(NDOF_LIBRARY
|
||||
NAMES ${NDOF_NAMES}
|
||||
)
|
||||
|
||||
if (NDOF_LIBRARY AND NDOF_INCLUDE_DIR)
|
||||
set(NDOF_FOUND "YES")
|
||||
else (NDOF_LIBRARY AND NDOF_INCLUDE_DIR)
|
||||
set(NDOF_FOUND "NO")
|
||||
endif (NDOF_LIBRARY AND NDOF_INCLUDE_DIR)
|
||||
|
||||
|
||||
if (NDOF_FOUND)
|
||||
if (NOT NDOF_FIND_QUIETLY)
|
||||
message(STATUS "Found NDOF: Library in '${NDOF_LIBRARY}' and header in '${NDOF_INCLUDE_DIR}' ")
|
||||
endif (NOT NDOF_FIND_QUIETLY)
|
||||
else (NDOF_FOUND)
|
||||
if (NDOF_FIND_REQUIRED)
|
||||
message(FATAL_ERROR " * * *\nCould not find NDOF library!\nIf you don't need Space Navigator Joystick support you can skip this test by configuring with -DNDOF:BOOL=OFF\n * * *")
|
||||
endif (NDOF_FIND_REQUIRED)
|
||||
endif (NDOF_FOUND)
|
||||
|
||||
mark_as_advanced(
|
||||
NDOF_LIBRARY
|
||||
NDOF_INCLUDE_DIR
|
||||
)
|
||||
|
|
@ -3,12 +3,11 @@
|
|||
# - Find Tut
|
||||
# Find the Tut unit test framework includes and library
|
||||
# This module defines
|
||||
# TUT_INCLUDE_DIR, where to find tut.h, etc.
|
||||
# TUT_INCLUDE_DIR, where to find tut/tut.hpp.
|
||||
# TUT_FOUND, If false, do not try to use Tut.
|
||||
|
||||
find_path(TUT_INCLUDE_DIR tut.h
|
||||
/usr/local/include/
|
||||
/usr/include
|
||||
find_path(TUT_INCLUDE_DIR tut/tut.hpp
|
||||
NO_SYSTEM_ENVIRONMENT_PATH
|
||||
)
|
||||
|
||||
if (TUT_INCLUDE_DIR)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,46 @@
|
|||
# -*- cmake -*-
|
||||
|
||||
# - Find zlib
|
||||
# Find the ZLIB includes and library
|
||||
# This module defines
|
||||
# ZLIB_INCLUDE_DIRS, where to find zlib.h, etc.
|
||||
# ZLIB_LIBRARIES, the libraries needed to use zlib.
|
||||
# ZLIB_FOUND, If false, do not try to use zlib.
|
||||
#
|
||||
# This FindZLIB is about 43 times as fast the one provided with cmake (2.8.x),
|
||||
# because it doesn't look up the version of zlib, resulting in a dramatic
|
||||
# speed up for configure (from 4 minutes 22 seconds to 6 seconds).
|
||||
#
|
||||
# Note: Since this file is only used for standalone, the windows
|
||||
# specific parts were left out.
|
||||
|
||||
FIND_PATH(ZLIB_INCLUDE_DIR zlib.h
|
||||
NO_SYSTEM_ENVIRONMENT_PATH
|
||||
)
|
||||
|
||||
FIND_LIBRARY(ZLIB_LIBRARY z)
|
||||
|
||||
if (ZLIB_LIBRARY AND ZLIB_INCLUDE_DIR)
|
||||
SET(ZLIB_INCLUDE_DIRS ${ZLIB_INCLUDE_DIR})
|
||||
SET(ZLIB_LIBRARIES ${ZLIB_LIBRARY})
|
||||
SET(ZLIB_FOUND "YES")
|
||||
else (ZLIB_LIBRARY AND ZLIB_INCLUDE_DIR)
|
||||
SET(ZLIB_FOUND "NO")
|
||||
endif (ZLIB_LIBRARY AND ZLIB_INCLUDE_DIR)
|
||||
|
||||
if (ZLIB_FOUND)
|
||||
if (NOT ZLIB_FIND_QUIETLY)
|
||||
message(STATUS "Found ZLIB: ${ZLIB_LIBRARIES}")
|
||||
SET(ZLIB_FIND_QUIETLY TRUE)
|
||||
endif (NOT ZLIB_FIND_QUIETLY)
|
||||
else (ZLIB_FOUND)
|
||||
if (ZLIB_FIND_REQUIRED)
|
||||
message(FATAL_ERROR "Could not find ZLIB library")
|
||||
endif (ZLIB_FIND_REQUIRED)
|
||||
endif (ZLIB_FOUND)
|
||||
|
||||
mark_as_advanced(
|
||||
ZLIB_LIBRARY
|
||||
ZLIB_INCLUDE_DIR
|
||||
)
|
||||
|
||||
|
|
@ -1,265 +1,276 @@
|
|||
# -*- cmake -*-
|
||||
include(LLTestCommand)
|
||||
include(GoogleMock)
|
||||
|
||||
MACRO(LL_ADD_PROJECT_UNIT_TESTS project sources)
|
||||
# Given a project name and a list of sourcefiles (with optional properties on each),
|
||||
# add targets to build and run the tests specified.
|
||||
# ASSUMPTIONS:
|
||||
# * this macro is being executed in the project file that is passed in
|
||||
# * current working SOURCE dir is that project dir
|
||||
# * there is a subfolder tests/ with test code corresponding to the filenames passed in
|
||||
# * properties for each sourcefile passed in indicate what libs to link that file with (MAKE NO ASSUMPTIONS ASIDE FROM TUT)
|
||||
#
|
||||
# More info and examples at: https://wiki.secondlife.com/wiki/How_to_add_unit_tests_to_indra_code
|
||||
#
|
||||
# WARNING: do NOT modify this code without working with poppy -
|
||||
# there is another branch that will conflict heavily with any changes here.
|
||||
INCLUDE(GoogleMock)
|
||||
|
||||
|
||||
IF(LL_TEST_VERBOSE)
|
||||
MESSAGE("LL_ADD_PROJECT_UNIT_TESTS UNITTEST_PROJECT_${project} sources: ${sources}")
|
||||
ENDIF(LL_TEST_VERBOSE)
|
||||
|
||||
# Start with the header and project-wide setup before making targets
|
||||
#project(UNITTEST_PROJECT_${project})
|
||||
# Setup includes, paths, etc
|
||||
SET(alltest_SOURCE_FILES
|
||||
${CMAKE_SOURCE_DIR}/test/test.cpp
|
||||
${CMAKE_SOURCE_DIR}/test/lltut.cpp
|
||||
)
|
||||
SET(alltest_DEP_TARGETS
|
||||
# needed by the test harness itself
|
||||
${APRUTIL_LIBRARIES}
|
||||
${APR_LIBRARIES}
|
||||
llcommon
|
||||
)
|
||||
IF(NOT "${project}" STREQUAL "llmath")
|
||||
# add llmath as a dep unless the tested module *is* llmath!
|
||||
LIST(APPEND alltest_DEP_TARGETS
|
||||
llmath
|
||||
)
|
||||
ENDIF(NOT "${project}" STREQUAL "llmath")
|
||||
SET(alltest_INCLUDE_DIRS
|
||||
${LLMATH_INCLUDE_DIRS}
|
||||
${LLCOMMON_INCLUDE_DIRS}
|
||||
${LIBS_OPEN_DIR}/test
|
||||
${GOOGLEMOCK_INCLUDE_DIRS}
|
||||
)
|
||||
SET(alltest_LIBRARIES
|
||||
${GOOGLEMOCK_LIBRARIES}
|
||||
${PTHREAD_LIBRARY}
|
||||
${WINDOWS_LIBRARIES}
|
||||
)
|
||||
# Headers, for convenience in targets.
|
||||
SET(alltest_HEADER_FILES
|
||||
${CMAKE_SOURCE_DIR}/test/test.h
|
||||
)
|
||||
|
||||
# Use the default flags
|
||||
if (LINUX)
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "")
|
||||
endif (LINUX)
|
||||
|
||||
# start the source test executable definitions
|
||||
SET(${project}_TEST_OUTPUT "")
|
||||
FOREACH (source ${sources})
|
||||
STRING( REGEX REPLACE "(.*)\\.[^.]+$" "\\1" name ${source} )
|
||||
STRING( REGEX REPLACE ".*\\.([^.]+)$" "\\1" extension ${source} )
|
||||
IF(LL_TEST_VERBOSE)
|
||||
MESSAGE("LL_ADD_PROJECT_UNIT_TESTS UNITTEST_PROJECT_${project} individual source: ${source} (${name}.${extension})")
|
||||
ENDIF(LL_TEST_VERBOSE)
|
||||
|
||||
#
|
||||
# Per-codefile additional / external source, header, and include dir property extraction
|
||||
#
|
||||
# Source
|
||||
GET_SOURCE_FILE_PROPERTY(${name}_test_additional_SOURCE_FILES ${source} LL_TEST_ADDITIONAL_SOURCE_FILES)
|
||||
IF(${name}_test_additional_SOURCE_FILES MATCHES NOTFOUND)
|
||||
SET(${name}_test_additional_SOURCE_FILES "")
|
||||
ENDIF(${name}_test_additional_SOURCE_FILES MATCHES NOTFOUND)
|
||||
SET(${name}_test_SOURCE_FILES ${source} tests/${name}_test.${extension} ${alltest_SOURCE_FILES} ${${name}_test_additional_SOURCE_FILES} )
|
||||
IF(LL_TEST_VERBOSE)
|
||||
MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_SOURCE_FILES ${${name}_test_SOURCE_FILES}")
|
||||
ENDIF(LL_TEST_VERBOSE)
|
||||
# Headers
|
||||
GET_SOURCE_FILE_PROPERTY(${name}_test_additional_HEADER_FILES ${source} LL_TEST_ADDITIONAL_HEADER_FILES)
|
||||
IF(${name}_test_additional_HEADER_FILES MATCHES NOTFOUND)
|
||||
SET(${name}_test_additional_HEADER_FILES "")
|
||||
ENDIF(${name}_test_additional_HEADER_FILES MATCHES NOTFOUND)
|
||||
SET(${name}_test_HEADER_FILES ${name}.h ${${name}_test_additional_HEADER_FILES})
|
||||
set_source_files_properties(${${name}_test_HEADER_FILES} PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
LIST(APPEND ${name}_test_SOURCE_FILES ${${name}_test_HEADER_FILES})
|
||||
IF(LL_TEST_VERBOSE)
|
||||
MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_HEADER_FILES ${${name}_test_HEADER_FILES}")
|
||||
ENDIF(LL_TEST_VERBOSE)
|
||||
# Include dirs
|
||||
GET_SOURCE_FILE_PROPERTY(${name}_test_additional_INCLUDE_DIRS ${source} LL_TEST_ADDITIONAL_INCLUDE_DIRS)
|
||||
IF(${name}_test_additional_INCLUDE_DIRS MATCHES NOTFOUND)
|
||||
SET(${name}_test_additional_INCLUDE_DIRS "")
|
||||
ENDIF(${name}_test_additional_INCLUDE_DIRS MATCHES NOTFOUND)
|
||||
INCLUDE_DIRECTORIES(${alltest_INCLUDE_DIRS} ${name}_test_additional_INCLUDE_DIRS )
|
||||
IF(LL_TEST_VERBOSE)
|
||||
MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_INCLUDE_DIRS ${${name}_test_additional_INCLUDE_DIRS}")
|
||||
ENDIF(LL_TEST_VERBOSE)
|
||||
|
||||
|
||||
# Setup target
|
||||
ADD_EXECUTABLE(PROJECT_${project}_TEST_${name} ${${name}_test_SOURCE_FILES})
|
||||
SET_TARGET_PROPERTIES(PROJECT_${project}_TEST_${name} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}")
|
||||
|
||||
#
|
||||
# Per-codefile additional / external project dep and lib dep property extraction
|
||||
#
|
||||
# WARNING: it's REALLY IMPORTANT to not mix these. I guarantee it will not work in the future. + poppy 2009-04-19
|
||||
# Projects
|
||||
GET_SOURCE_FILE_PROPERTY(${name}_test_additional_PROJECTS ${source} LL_TEST_ADDITIONAL_PROJECTS)
|
||||
IF(${name}_test_additional_PROJECTS MATCHES NOTFOUND)
|
||||
SET(${name}_test_additional_PROJECTS "")
|
||||
ENDIF(${name}_test_additional_PROJECTS MATCHES NOTFOUND)
|
||||
# Libraries
|
||||
GET_SOURCE_FILE_PROPERTY(${name}_test_additional_LIBRARIES ${source} LL_TEST_ADDITIONAL_LIBRARIES)
|
||||
IF(${name}_test_additional_LIBRARIES MATCHES NOTFOUND)
|
||||
SET(${name}_test_additional_LIBRARIES "")
|
||||
ENDIF(${name}_test_additional_LIBRARIES MATCHES NOTFOUND)
|
||||
IF(LL_TEST_VERBOSE)
|
||||
MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_PROJECTS ${${name}_test_additional_PROJECTS}")
|
||||
MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_LIBRARIES ${${name}_test_additional_LIBRARIES}")
|
||||
ENDIF(LL_TEST_VERBOSE)
|
||||
# Add to project
|
||||
TARGET_LINK_LIBRARIES(PROJECT_${project}_TEST_${name} ${alltest_LIBRARIES} ${alltest_DEP_TARGETS} ${${name}_test_additional_PROJECTS} ${${name}_test_additional_LIBRARIES} )
|
||||
|
||||
#
|
||||
# Setup test targets
|
||||
#
|
||||
GET_TARGET_PROPERTY(TEST_EXE PROJECT_${project}_TEST_${name} LOCATION)
|
||||
SET(TEST_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/PROJECT_${project}_TEST_${name}_ok.txt)
|
||||
SET(TEST_CMD ${TEST_EXE} --touch=${TEST_OUTPUT} --sourcedir=${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
# daveh - what configuration does this use? Debug? it's cmake-time, not build time. + poppy 2009-04-19
|
||||
IF(LL_TEST_VERBOSE)
|
||||
MESSAGE(STATUS "LL_ADD_PROJECT_UNIT_TESTS ${name} test_cmd = ${TEST_CMD}")
|
||||
ENDIF(LL_TEST_VERBOSE)
|
||||
|
||||
SET_TEST_PATH(LD_LIBRARY_PATH)
|
||||
LL_TEST_COMMAND(TEST_SCRIPT_CMD "${LD_LIBRARY_PATH}" ${TEST_CMD})
|
||||
IF(LL_TEST_VERBOSE)
|
||||
MESSAGE(STATUS "LL_ADD_PROJECT_UNIT_TESTS ${name} test_script = ${TEST_SCRIPT_CMD}")
|
||||
ENDIF(LL_TEST_VERBOSE)
|
||||
# Add test
|
||||
ADD_CUSTOM_COMMAND(
|
||||
OUTPUT ${TEST_OUTPUT}
|
||||
COMMAND ${TEST_SCRIPT_CMD}
|
||||
DEPENDS PROJECT_${project}_TEST_${name}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
)
|
||||
# Why not add custom target and add POST_BUILD command?
|
||||
# Slightly less uncertain behavior
|
||||
# (OUTPUT commands run non-deterministically AFAIK) + poppy 2009-04-19
|
||||
# > I did not use a post build step as I could not make it notify of a
|
||||
# > failure after the first time you build and fail a test. - daveh 2009-04-20
|
||||
LIST(APPEND ${project}_TEST_OUTPUT ${TEST_OUTPUT})
|
||||
ENDFOREACH (source)
|
||||
|
||||
# Add the test runner target per-project
|
||||
# (replaces old _test_ok targets all over the place)
|
||||
ADD_CUSTOM_TARGET(${project}_tests ALL DEPENDS ${${project}_TEST_OUTPUT})
|
||||
ADD_DEPENDENCIES(${project} ${project}_tests)
|
||||
ENDMACRO(LL_ADD_PROJECT_UNIT_TESTS)
|
||||
|
||||
FUNCTION(LL_ADD_INTEGRATION_TEST
|
||||
testname
|
||||
additional_source_files
|
||||
library_dependencies
|
||||
# variable args
|
||||
)
|
||||
if(TEST_DEBUG)
|
||||
message(STATUS "Adding INTEGRATION_TEST_${testname} - debug output is on")
|
||||
endif(TEST_DEBUG)
|
||||
|
||||
SET(source_files
|
||||
tests/${testname}_test.cpp
|
||||
${CMAKE_SOURCE_DIR}/test/test.cpp
|
||||
${CMAKE_SOURCE_DIR}/test/lltut.cpp
|
||||
${additional_source_files}
|
||||
)
|
||||
|
||||
SET(libraries
|
||||
${library_dependencies}
|
||||
${GOOGLEMOCK_LIBRARIES}
|
||||
${PTHREAD_LIBRARY}
|
||||
)
|
||||
|
||||
# Add test executable build target
|
||||
if(TEST_DEBUG)
|
||||
message(STATUS "ADD_EXECUTABLE(INTEGRATION_TEST_${testname} ${source_files})")
|
||||
endif(TEST_DEBUG)
|
||||
ADD_EXECUTABLE(INTEGRATION_TEST_${testname} ${source_files})
|
||||
SET_TARGET_PROPERTIES(INTEGRATION_TEST_${testname} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}")
|
||||
|
||||
# Add link deps to the executable
|
||||
if(TEST_DEBUG)
|
||||
message(STATUS "TARGET_LINK_LIBRARIES(INTEGRATION_TEST_${testname} ${libraries})")
|
||||
endif(TEST_DEBUG)
|
||||
TARGET_LINK_LIBRARIES(INTEGRATION_TEST_${testname} ${libraries})
|
||||
|
||||
# Create the test running command
|
||||
SET(test_command ${ARGN})
|
||||
GET_TARGET_PROPERTY(TEST_EXE INTEGRATION_TEST_${testname} LOCATION)
|
||||
LIST(FIND test_command "{}" test_exe_pos)
|
||||
IF(test_exe_pos LESS 0)
|
||||
# The {} marker means "the full pathname of the test executable."
|
||||
# test_exe_pos -1 means we didn't find it -- so append the test executable
|
||||
# name to $ARGN, the variable part of the arg list. This is convenient
|
||||
# shorthand for both straightforward execution of the test program (empty
|
||||
# $ARGN) and for running a "wrapper" program of some kind accepting the
|
||||
# pathname of the test program as the last of its args. You need specify
|
||||
# {} only if the test program's pathname isn't the last argument in the
|
||||
# desired command line.
|
||||
LIST(APPEND test_command "${TEST_EXE}")
|
||||
ELSE (test_exe_pos LESS 0)
|
||||
# Found {} marker at test_exe_pos. Remove the {}...
|
||||
LIST(REMOVE_AT test_command test_exe_pos)
|
||||
# ...and replace it with the actual name of the test executable.
|
||||
LIST(INSERT test_command test_exe_pos "${TEST_EXE}")
|
||||
ENDIF (test_exe_pos LESS 0)
|
||||
|
||||
SET_TEST_PATH(LD_LIBRARY_PATH)
|
||||
LL_TEST_COMMAND(TEST_SCRIPT_CMD "${LD_LIBRARY_PATH}" ${test_command})
|
||||
|
||||
if(TEST_DEBUG)
|
||||
message(STATUS "TEST_SCRIPT_CMD: ${TEST_SCRIPT_CMD}")
|
||||
endif(TEST_DEBUG)
|
||||
|
||||
ADD_CUSTOM_COMMAND(
|
||||
TARGET INTEGRATION_TEST_${testname}
|
||||
POST_BUILD
|
||||
COMMAND ${TEST_SCRIPT_CMD}
|
||||
)
|
||||
|
||||
# Use CTEST? Not sure how to yet...
|
||||
# ADD_TEST(INTEGRATION_TEST_RUNNER_${testname} ${TEST_SCRIPT_CMD})
|
||||
|
||||
ENDFUNCTION(LL_ADD_INTEGRATION_TEST)
|
||||
|
||||
MACRO(SET_TEST_PATH LISTVAR)
|
||||
IF(WINDOWS)
|
||||
# We typically build/package only Release variants of third-party
|
||||
# libraries, so append the Release staging dir in case the library being
|
||||
# sought doesn't have a debug variant.
|
||||
set(${LISTVAR} ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR} ${SHARED_LIB_STAGING_DIR}/Release)
|
||||
ELSEIF(DARWIN)
|
||||
# We typically build/package only Release variants of third-party
|
||||
# libraries, so append the Release staging dir in case the library being
|
||||
# sought doesn't have a debug variant.
|
||||
set(${LISTVAR} ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/Resources ${SHARED_LIB_STAGING_DIR}/Release/Resources /usr/lib)
|
||||
ELSE(WINDOWS)
|
||||
# Linux uses a single staging directory anyway.
|
||||
IF (STANDALONE)
|
||||
set(${LISTVAR} ${CMAKE_BINARY_DIR}/llcommon /usr/lib /usr/local/lib)
|
||||
ELSE (STANDALONE)
|
||||
set(${LISTVAR} ${SHARED_LIB_STAGING_DIR} /usr/lib)
|
||||
ENDIF (STANDALONE)
|
||||
ENDIF(WINDOWS)
|
||||
ENDMACRO(SET_TEST_PATH)
|
||||
# -*- cmake -*-
|
||||
include(LLTestCommand)
|
||||
include(GoogleMock)
|
||||
|
||||
MACRO(LL_ADD_PROJECT_UNIT_TESTS project sources)
|
||||
# Given a project name and a list of sourcefiles (with optional properties on each),
|
||||
# add targets to build and run the tests specified.
|
||||
# ASSUMPTIONS:
|
||||
# * this macro is being executed in the project file that is passed in
|
||||
# * current working SOURCE dir is that project dir
|
||||
# * there is a subfolder tests/ with test code corresponding to the filenames passed in
|
||||
# * properties for each sourcefile passed in indicate what libs to link that file with (MAKE NO ASSUMPTIONS ASIDE FROM TUT)
|
||||
#
|
||||
# More info and examples at: https://wiki.secondlife.com/wiki/How_to_add_unit_tests_to_indra_code
|
||||
#
|
||||
# WARNING: do NOT modify this code without working with poppy -
|
||||
# there is another branch that will conflict heavily with any changes here.
|
||||
INCLUDE(GoogleMock)
|
||||
|
||||
|
||||
IF(LL_TEST_VERBOSE)
|
||||
MESSAGE("LL_ADD_PROJECT_UNIT_TESTS UNITTEST_PROJECT_${project} sources: ${sources}")
|
||||
ENDIF(LL_TEST_VERBOSE)
|
||||
|
||||
# Start with the header and project-wide setup before making targets
|
||||
#project(UNITTEST_PROJECT_${project})
|
||||
# Setup includes, paths, etc
|
||||
SET(alltest_SOURCE_FILES
|
||||
${CMAKE_SOURCE_DIR}/test/test.cpp
|
||||
${CMAKE_SOURCE_DIR}/test/lltut.cpp
|
||||
)
|
||||
SET(alltest_DEP_TARGETS
|
||||
# needed by the test harness itself
|
||||
${APRUTIL_LIBRARIES}
|
||||
${APR_LIBRARIES}
|
||||
llcommon
|
||||
)
|
||||
IF(NOT "${project}" STREQUAL "llmath")
|
||||
# add llmath as a dep unless the tested module *is* llmath!
|
||||
LIST(APPEND alltest_DEP_TARGETS
|
||||
llmath
|
||||
)
|
||||
ENDIF(NOT "${project}" STREQUAL "llmath")
|
||||
SET(alltest_INCLUDE_DIRS
|
||||
${LLMATH_INCLUDE_DIRS}
|
||||
${LLCOMMON_INCLUDE_DIRS}
|
||||
${LIBS_OPEN_DIR}/test
|
||||
${GOOGLEMOCK_INCLUDE_DIRS}
|
||||
)
|
||||
SET(alltest_LIBRARIES
|
||||
${GOOGLEMOCK_LIBRARIES}
|
||||
${PTHREAD_LIBRARY}
|
||||
${WINDOWS_LIBRARIES}
|
||||
)
|
||||
# Headers, for convenience in targets.
|
||||
SET(alltest_HEADER_FILES
|
||||
${CMAKE_SOURCE_DIR}/test/test.h
|
||||
)
|
||||
|
||||
# Use the default flags
|
||||
if (LINUX)
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "")
|
||||
endif (LINUX)
|
||||
|
||||
# start the source test executable definitions
|
||||
SET(${project}_TEST_OUTPUT "")
|
||||
FOREACH (source ${sources})
|
||||
STRING( REGEX REPLACE "(.*)\\.[^.]+$" "\\1" name ${source} )
|
||||
STRING( REGEX REPLACE ".*\\.([^.]+)$" "\\1" extension ${source} )
|
||||
IF(LL_TEST_VERBOSE)
|
||||
MESSAGE("LL_ADD_PROJECT_UNIT_TESTS UNITTEST_PROJECT_${project} individual source: ${source} (${name}.${extension})")
|
||||
ENDIF(LL_TEST_VERBOSE)
|
||||
|
||||
#
|
||||
# Per-codefile additional / external source, header, and include dir property extraction
|
||||
#
|
||||
# Source
|
||||
GET_SOURCE_FILE_PROPERTY(${name}_test_additional_SOURCE_FILES ${source} LL_TEST_ADDITIONAL_SOURCE_FILES)
|
||||
IF(${name}_test_additional_SOURCE_FILES MATCHES NOTFOUND)
|
||||
SET(${name}_test_additional_SOURCE_FILES "")
|
||||
ENDIF(${name}_test_additional_SOURCE_FILES MATCHES NOTFOUND)
|
||||
SET(${name}_test_SOURCE_FILES ${source} tests/${name}_test.${extension} ${alltest_SOURCE_FILES} ${${name}_test_additional_SOURCE_FILES} )
|
||||
IF(LL_TEST_VERBOSE)
|
||||
MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_SOURCE_FILES ${${name}_test_SOURCE_FILES}")
|
||||
ENDIF(LL_TEST_VERBOSE)
|
||||
# Headers
|
||||
GET_SOURCE_FILE_PROPERTY(${name}_test_additional_HEADER_FILES ${source} LL_TEST_ADDITIONAL_HEADER_FILES)
|
||||
IF(${name}_test_additional_HEADER_FILES MATCHES NOTFOUND)
|
||||
SET(${name}_test_additional_HEADER_FILES "")
|
||||
ENDIF(${name}_test_additional_HEADER_FILES MATCHES NOTFOUND)
|
||||
SET(${name}_test_HEADER_FILES ${name}.h ${${name}_test_additional_HEADER_FILES})
|
||||
set_source_files_properties(${${name}_test_HEADER_FILES} PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
LIST(APPEND ${name}_test_SOURCE_FILES ${${name}_test_HEADER_FILES})
|
||||
IF(LL_TEST_VERBOSE)
|
||||
MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_HEADER_FILES ${${name}_test_HEADER_FILES}")
|
||||
ENDIF(LL_TEST_VERBOSE)
|
||||
# Include dirs
|
||||
GET_SOURCE_FILE_PROPERTY(${name}_test_additional_INCLUDE_DIRS ${source} LL_TEST_ADDITIONAL_INCLUDE_DIRS)
|
||||
IF(${name}_test_additional_INCLUDE_DIRS MATCHES NOTFOUND)
|
||||
SET(${name}_test_additional_INCLUDE_DIRS "")
|
||||
ENDIF(${name}_test_additional_INCLUDE_DIRS MATCHES NOTFOUND)
|
||||
INCLUDE_DIRECTORIES(${alltest_INCLUDE_DIRS} ${name}_test_additional_INCLUDE_DIRS )
|
||||
IF(LL_TEST_VERBOSE)
|
||||
MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_INCLUDE_DIRS ${${name}_test_additional_INCLUDE_DIRS}")
|
||||
ENDIF(LL_TEST_VERBOSE)
|
||||
|
||||
|
||||
# Setup target
|
||||
ADD_EXECUTABLE(PROJECT_${project}_TEST_${name} ${${name}_test_SOURCE_FILES})
|
||||
SET_TARGET_PROPERTIES(PROJECT_${project}_TEST_${name} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}")
|
||||
|
||||
#
|
||||
# Per-codefile additional / external project dep and lib dep property extraction
|
||||
#
|
||||
# WARNING: it's REALLY IMPORTANT to not mix these. I guarantee it will not work in the future. + poppy 2009-04-19
|
||||
# Projects
|
||||
GET_SOURCE_FILE_PROPERTY(${name}_test_additional_PROJECTS ${source} LL_TEST_ADDITIONAL_PROJECTS)
|
||||
IF(${name}_test_additional_PROJECTS MATCHES NOTFOUND)
|
||||
SET(${name}_test_additional_PROJECTS "")
|
||||
ENDIF(${name}_test_additional_PROJECTS MATCHES NOTFOUND)
|
||||
# Libraries
|
||||
GET_SOURCE_FILE_PROPERTY(${name}_test_additional_LIBRARIES ${source} LL_TEST_ADDITIONAL_LIBRARIES)
|
||||
IF(${name}_test_additional_LIBRARIES MATCHES NOTFOUND)
|
||||
SET(${name}_test_additional_LIBRARIES "")
|
||||
ENDIF(${name}_test_additional_LIBRARIES MATCHES NOTFOUND)
|
||||
IF(LL_TEST_VERBOSE)
|
||||
MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_PROJECTS ${${name}_test_additional_PROJECTS}")
|
||||
MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_LIBRARIES ${${name}_test_additional_LIBRARIES}")
|
||||
ENDIF(LL_TEST_VERBOSE)
|
||||
# Add to project
|
||||
TARGET_LINK_LIBRARIES(PROJECT_${project}_TEST_${name} ${alltest_LIBRARIES} ${alltest_DEP_TARGETS} ${${name}_test_additional_PROJECTS} ${${name}_test_additional_LIBRARIES} )
|
||||
# Compile-time Definitions
|
||||
GET_SOURCE_FILE_PROPERTY(${name}_test_additional_CFLAGS ${source} LL_TEST_ADDITIONAL_CFLAGS)
|
||||
IF(NOT ${name}_test_additional_CFLAGS MATCHES NOTFOUND)
|
||||
SET_TARGET_PROPERTIES(PROJECT_${project}_TEST_${name} PROPERTIES COMPILE_FLAGS ${${name}_test_additional_CFLAGS} )
|
||||
IF(LL_TEST_VERBOSE)
|
||||
MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_CFLAGS ${${name}_test_additional_CFLAGS}")
|
||||
ENDIF(LL_TEST_VERBOSE)
|
||||
ENDIF(NOT ${name}_test_additional_CFLAGS MATCHES NOTFOUND)
|
||||
|
||||
#
|
||||
# Setup test targets
|
||||
#
|
||||
GET_TARGET_PROPERTY(TEST_EXE PROJECT_${project}_TEST_${name} LOCATION)
|
||||
SET(TEST_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/PROJECT_${project}_TEST_${name}_ok.txt)
|
||||
SET(TEST_CMD ${TEST_EXE} --touch=${TEST_OUTPUT} --sourcedir=${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
# daveh - what configuration does this use? Debug? it's cmake-time, not build time. + poppy 2009-04-19
|
||||
IF(LL_TEST_VERBOSE)
|
||||
MESSAGE(STATUS "LL_ADD_PROJECT_UNIT_TESTS ${name} test_cmd = ${TEST_CMD}")
|
||||
ENDIF(LL_TEST_VERBOSE)
|
||||
|
||||
SET_TEST_PATH(LD_LIBRARY_PATH)
|
||||
LL_TEST_COMMAND(TEST_SCRIPT_CMD "${LD_LIBRARY_PATH}" ${TEST_CMD})
|
||||
IF(LL_TEST_VERBOSE)
|
||||
MESSAGE(STATUS "LL_ADD_PROJECT_UNIT_TESTS ${name} test_script = ${TEST_SCRIPT_CMD}")
|
||||
ENDIF(LL_TEST_VERBOSE)
|
||||
# Add test
|
||||
ADD_CUSTOM_COMMAND(
|
||||
OUTPUT ${TEST_OUTPUT}
|
||||
COMMAND ${TEST_SCRIPT_CMD}
|
||||
DEPENDS PROJECT_${project}_TEST_${name}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
)
|
||||
# Why not add custom target and add POST_BUILD command?
|
||||
# Slightly less uncertain behavior
|
||||
# (OUTPUT commands run non-deterministically AFAIK) + poppy 2009-04-19
|
||||
# > I did not use a post build step as I could not make it notify of a
|
||||
# > failure after the first time you build and fail a test. - daveh 2009-04-20
|
||||
LIST(APPEND ${project}_TEST_OUTPUT ${TEST_OUTPUT})
|
||||
ENDFOREACH (source)
|
||||
|
||||
# Add the test runner target per-project
|
||||
# (replaces old _test_ok targets all over the place)
|
||||
ADD_CUSTOM_TARGET(${project}_tests ALL DEPENDS ${${project}_TEST_OUTPUT})
|
||||
ADD_DEPENDENCIES(${project} ${project}_tests)
|
||||
ENDMACRO(LL_ADD_PROJECT_UNIT_TESTS)
|
||||
|
||||
FUNCTION(LL_ADD_INTEGRATION_TEST
|
||||
testname
|
||||
additional_source_files
|
||||
library_dependencies
|
||||
# variable args
|
||||
)
|
||||
if(TEST_DEBUG)
|
||||
message(STATUS "Adding INTEGRATION_TEST_${testname} - debug output is on")
|
||||
endif(TEST_DEBUG)
|
||||
|
||||
SET(source_files
|
||||
tests/${testname}_test.cpp
|
||||
${CMAKE_SOURCE_DIR}/test/test.cpp
|
||||
${CMAKE_SOURCE_DIR}/test/lltut.cpp
|
||||
${additional_source_files}
|
||||
)
|
||||
|
||||
SET(libraries
|
||||
${library_dependencies}
|
||||
${GOOGLEMOCK_LIBRARIES}
|
||||
${PTHREAD_LIBRARY}
|
||||
)
|
||||
|
||||
# Add test executable build target
|
||||
if(TEST_DEBUG)
|
||||
message(STATUS "ADD_EXECUTABLE(INTEGRATION_TEST_${testname} ${source_files})")
|
||||
endif(TEST_DEBUG)
|
||||
ADD_EXECUTABLE(INTEGRATION_TEST_${testname} ${source_files})
|
||||
SET_TARGET_PROPERTIES(INTEGRATION_TEST_${testname} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}")
|
||||
if(STANDALONE)
|
||||
SET_TARGET_PROPERTIES(INTEGRATION_TEST_${testname} PROPERTIES COMPILE_FLAGS -I"${TUT_INCLUDE_DIR}")
|
||||
endif(STANDALONE)
|
||||
|
||||
# Add link deps to the executable
|
||||
if(TEST_DEBUG)
|
||||
message(STATUS "TARGET_LINK_LIBRARIES(INTEGRATION_TEST_${testname} ${libraries})")
|
||||
endif(TEST_DEBUG)
|
||||
TARGET_LINK_LIBRARIES(INTEGRATION_TEST_${testname} ${libraries})
|
||||
|
||||
# Create the test running command
|
||||
SET(test_command ${ARGN})
|
||||
GET_TARGET_PROPERTY(TEST_EXE INTEGRATION_TEST_${testname} LOCATION)
|
||||
LIST(FIND test_command "{}" test_exe_pos)
|
||||
IF(test_exe_pos LESS 0)
|
||||
# The {} marker means "the full pathname of the test executable."
|
||||
# test_exe_pos -1 means we didn't find it -- so append the test executable
|
||||
# name to $ARGN, the variable part of the arg list. This is convenient
|
||||
# shorthand for both straightforward execution of the test program (empty
|
||||
# $ARGN) and for running a "wrapper" program of some kind accepting the
|
||||
# pathname of the test program as the last of its args. You need specify
|
||||
# {} only if the test program's pathname isn't the last argument in the
|
||||
# desired command line.
|
||||
LIST(APPEND test_command "${TEST_EXE}")
|
||||
ELSE (test_exe_pos LESS 0)
|
||||
# Found {} marker at test_exe_pos. Remove the {}...
|
||||
LIST(REMOVE_AT test_command test_exe_pos)
|
||||
# ...and replace it with the actual name of the test executable.
|
||||
LIST(INSERT test_command test_exe_pos "${TEST_EXE}")
|
||||
ENDIF (test_exe_pos LESS 0)
|
||||
|
||||
SET_TEST_PATH(LD_LIBRARY_PATH)
|
||||
LL_TEST_COMMAND(TEST_SCRIPT_CMD "${LD_LIBRARY_PATH}" ${test_command})
|
||||
|
||||
if(TEST_DEBUG)
|
||||
message(STATUS "TEST_SCRIPT_CMD: ${TEST_SCRIPT_CMD}")
|
||||
endif(TEST_DEBUG)
|
||||
|
||||
ADD_CUSTOM_COMMAND(
|
||||
TARGET INTEGRATION_TEST_${testname}
|
||||
POST_BUILD
|
||||
COMMAND ${TEST_SCRIPT_CMD}
|
||||
)
|
||||
|
||||
# Use CTEST? Not sure how to yet...
|
||||
# ADD_TEST(INTEGRATION_TEST_RUNNER_${testname} ${TEST_SCRIPT_CMD})
|
||||
|
||||
ENDFUNCTION(LL_ADD_INTEGRATION_TEST)
|
||||
|
||||
MACRO(SET_TEST_PATH LISTVAR)
|
||||
IF(WINDOWS)
|
||||
# We typically build/package only Release variants of third-party
|
||||
# libraries, so append the Release staging dir in case the library being
|
||||
# sought doesn't have a debug variant.
|
||||
set(${LISTVAR} ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR} ${SHARED_LIB_STAGING_DIR}/Release)
|
||||
ELSEIF(DARWIN)
|
||||
# We typically build/package only Release variants of third-party
|
||||
# libraries, so append the Release staging dir in case the library being
|
||||
# sought doesn't have a debug variant.
|
||||
set(${LISTVAR} ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/Resources ${SHARED_LIB_STAGING_DIR}/Release/Resources /usr/lib)
|
||||
ELSE(WINDOWS)
|
||||
# Linux uses a single staging directory anyway.
|
||||
IF (STANDALONE)
|
||||
set(${LISTVAR} ${CMAKE_BINARY_DIR}/llcommon /usr/lib /usr/local/lib)
|
||||
ELSE (STANDALONE)
|
||||
set(${LISTVAR} ${SHARED_LIB_STAGING_DIR} /usr/lib)
|
||||
ENDIF (STANDALONE)
|
||||
ENDIF(WINDOWS)
|
||||
ENDMACRO(SET_TEST_PATH)
|
||||
|
|
|
|||
|
|
@ -13,7 +13,14 @@ set(LLCOMMON_INCLUDE_DIRS
|
|||
${Boost_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
set(LLCOMMON_LIBRARIES llcommon)
|
||||
if (LINUX)
|
||||
# In order to support using ld.gold on linux, we need to explicitely
|
||||
# specify all libraries that llcommon uses.
|
||||
# llcommon uses `clock_gettime' which is provided by librt on linux.
|
||||
set(LLCOMMON_LIBRARIES llcommon rt)
|
||||
else (LINUX)
|
||||
set(LLCOMMON_LIBRARIES llcommon)
|
||||
endif (LINUX)
|
||||
|
||||
add_definitions(${TCMALLOC_FLAG})
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,20 @@
|
|||
# -*- cmake -*-
|
||||
include(Prebuilt)
|
||||
|
||||
# USE_KDU can be set when launching cmake or develop.py as an option using the argument -DUSE_KDU:BOOL=ON
|
||||
# When building using proprietary binaries though (i.e. having access to LL private servers), we always build with KDU
|
||||
if (INSTALL_PROPRIETARY AND NOT STANDALONE)
|
||||
use_prebuilt_binary(kdu)
|
||||
set(LLKDU_LIBRARY llkdu)
|
||||
set(USE_KDU ON)
|
||||
endif (INSTALL_PROPRIETARY AND NOT STANDALONE)
|
||||
|
||||
if (USE_KDU)
|
||||
use_prebuilt_binary(kdu)
|
||||
if (WINDOWS)
|
||||
set(KDU_LIBRARY kdu.lib)
|
||||
else (WINDOWS)
|
||||
set(KDU_LIBRARY libkdu.a)
|
||||
endif (WINDOWS)
|
||||
set(KDU_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/kdu)
|
||||
set(LLKDU_INCLUDE_DIRS ${LIBS_OPEN_DIR}/llkdu)
|
||||
set(LLKDU_LIBRARIES llkdu)
|
||||
endif (USE_KDU)
|
||||
|
|
|
|||
|
|
@ -5,4 +5,10 @@ set(LLPLUGIN_INCLUDE_DIRS
|
|||
${LIBS_OPEN_DIR}/llplugin
|
||||
)
|
||||
|
||||
set(LLPLUGIN_LIBRARIES llplugin)
|
||||
if (LINUX)
|
||||
# In order to support using ld.gold on linux, we need to explicitely
|
||||
# specify all libraries that llplugin uses.
|
||||
set(LLPLUGIN_LIBRARIES llplugin pthread)
|
||||
else (LINUX)
|
||||
set(LLPLUGIN_LIBRARIES llplugin)
|
||||
endif (LINUX)
|
||||
|
|
|
|||
|
|
@ -1,14 +1,32 @@
|
|||
# -*- cmake -*-
|
||||
include(Prebuilt)
|
||||
|
||||
use_prebuilt_binary(ndofdev)
|
||||
set(NDOF ON CACHE BOOL "Use NDOF space navigator joystick library.")
|
||||
|
||||
if (WINDOWS OR DARWIN OR LINUX)
|
||||
if (NDOF)
|
||||
if (STANDALONE)
|
||||
set(NDOF_FIND_REQUIRED ON)
|
||||
include(FindNDOF)
|
||||
else (STANDALONE)
|
||||
use_prebuilt_binary(ndofdev)
|
||||
|
||||
if (WINDOWS)
|
||||
set(NDOF_LIBRARY libndofdev)
|
||||
elseif (DARWIN OR LINUX)
|
||||
set(NDOF_LIBRARY ndofdev)
|
||||
endif (WINDOWS)
|
||||
|
||||
set(NDOF_INCLUDE_DIR ${ARCH_PREBUILT_DIRS}/include/ndofdev)
|
||||
set(NDOF_FOUND 1)
|
||||
endif (STANDALONE)
|
||||
endif (NDOF)
|
||||
|
||||
if (NDOF_FOUND)
|
||||
add_definitions(-DLIB_NDOF=1)
|
||||
endif (WINDOWS OR DARWIN OR LINUX)
|
||||
include_directories(${NDOF_INCLUDE_DIR})
|
||||
else (NDOF_FOUND)
|
||||
message(STATUS "Building without N-DoF joystick support")
|
||||
set(NDOF_INCLUDE_DIR "")
|
||||
set(NDOF_LIBRARY "")
|
||||
endif (NDOF_FOUND)
|
||||
|
||||
if (WINDOWS)
|
||||
set(NDOF_LIBRARY libndofdev)
|
||||
elseif (DARWIN OR LINUX)
|
||||
set(NDOF_LIBRARY ndofdev)
|
||||
endif (WINDOWS)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# -*- cmake -*-
|
||||
include(Prebuilt)
|
||||
|
||||
set(PULSEAUDIO ON CACHE BOOL "Build with PulseAudio support, if available.")
|
||||
set(PULSEAUDIO OFF CACHE BOOL "Build with PulseAudio support, if available.")
|
||||
|
||||
if (PULSEAUDIO)
|
||||
if (STANDALONE)
|
||||
|
|
|
|||
|
|
@ -9,10 +9,12 @@ if (WINDOWS)
|
|||
NAMES python25.exe python23.exe python.exe
|
||||
NO_DEFAULT_PATH # added so that cmake does not find cygwin python
|
||||
PATHS
|
||||
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.7\\InstallPath]
|
||||
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.6\\InstallPath]
|
||||
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.5\\InstallPath]
|
||||
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.4\\InstallPath]
|
||||
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.3\\InstallPath]
|
||||
[HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\2.7\\InstallPath]
|
||||
[HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\2.6\\InstallPath]
|
||||
[HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\2.5\\InstallPath]
|
||||
[HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\2.4\\InstallPath]
|
||||
|
|
|
|||
|
|
@ -7,8 +7,9 @@ macro (check_message_template _target)
|
|||
TARGET ${_target}
|
||||
POST_BUILD
|
||||
COMMAND ${PYTHON_EXECUTABLE}
|
||||
ARGS ${SCRIPTS_DIR}/template_verifier.py
|
||||
--mode=development --cache_master
|
||||
COMMENT "Verifying message template"
|
||||
ARGS ${SCRIPTS_DIR}/md5check.py
|
||||
3f19d130400c547de36278a6b6f9b028
|
||||
${SCRIPTS_DIR}/messages/message_template.msg
|
||||
COMMENT "Verifying message template - See http://wiki.secondlife.com/wiki/Template_verifier.py"
|
||||
)
|
||||
endmacro (check_message_template)
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ set(TUT_FIND_QUIETLY TRUE)
|
|||
|
||||
if (STANDALONE)
|
||||
include(FindTut)
|
||||
include_directories(${TUT_INCLUDE_DIR})
|
||||
else (STANDALONE)
|
||||
use_prebuilt_binary(tut)
|
||||
endif (STANDALONE)
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ include(Prebuilt)
|
|||
|
||||
if (NOT STANDALONE)
|
||||
use_prebuilt_binary(libuuid)
|
||||
use_prebuilt_binary(vivox)
|
||||
use_prebuilt_binary(slvoice)
|
||||
use_prebuilt_binary(fontconfig)
|
||||
endif(NOT STANDALONE)
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,29 @@ include(Linking)
|
|||
include(Prebuilt)
|
||||
|
||||
if (STANDALONE)
|
||||
# The minimal version, 4.4.3, is rather arbitrary: it's the version in Debian/Lenny.
|
||||
find_package(Qt4 4.4.3 COMPONENTS QtCore QtGui QtNetwork QtOpenGL QtWebKit REQUIRED)
|
||||
include(${QT_USE_FILE})
|
||||
set(QTDIR $ENV{QTDIR})
|
||||
if (QTDIR AND NOT "${QT_BINARY_DIR}" STREQUAL "${QTDIR}/bin")
|
||||
message(FATAL_ERROR "\"${QT_BINARY_DIR}\" is unequal \"${QTDIR}/bin\"; "
|
||||
"Qt is found by looking for qmake in your PATH. "
|
||||
"Please set your PATH such that 'qmake' is found in \$QTDIR/bin, "
|
||||
"or unset QTDIR if the found Qt is correct.")
|
||||
endif (QTDIR AND NOT "${QT_BINARY_DIR}" STREQUAL "${QTDIR}/bin")
|
||||
find_package(LLQtWebkit REQUIRED QUIET)
|
||||
# Add the plugins.
|
||||
set(QT_PLUGIN_LIBRARIES)
|
||||
foreach(qlibname qgif qjpeg)
|
||||
find_library(QT_PLUGIN_${qlibname} ${qlibname} PATHS ${QT_PLUGINS_DIR}/imageformats NO_DEFAULT_PATH)
|
||||
if (QT_PLUGIN_${qlibname})
|
||||
list(APPEND QT_PLUGIN_LIBRARIES ${QT_PLUGIN_${qlibname}})
|
||||
else (QT_PLUGIN_${qtlibname})
|
||||
message(FATAL_ERROR "Could not find the Qt plugin ${qlibname} in \"${QT_PLUGINS_DIR}/imageformats\"!")
|
||||
endif (QT_PLUGIN_${qlibname})
|
||||
endforeach(qlibname)
|
||||
# qjpeg depends on libjpeg
|
||||
list(APPEND QT_PLUGIN_LIBRARIES jpeg)
|
||||
set(WEBKITLIBPLUGIN OFF CACHE BOOL
|
||||
"WEBKITLIBPLUGIN support for the llplugin/llmedia test apps.")
|
||||
else (STANDALONE)
|
||||
|
|
@ -35,7 +58,7 @@ elseif (DARWIN)
|
|||
)
|
||||
elseif (LINUX)
|
||||
if (STANDALONE)
|
||||
set(WEBKIT_PLUGIN_LIBRARIES llqtwebkit)
|
||||
set(WEBKIT_PLUGIN_LIBRARIES ${LLQTWEBKIT_LIBRARY} ${QT_LIBRARIES} ${QT_PLUGIN_LIBRARIES})
|
||||
else (STANDALONE)
|
||||
set(WEBKIT_PLUGIN_LIBRARIES
|
||||
llqtwebkit
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ include(00-Common)
|
|||
include(LLCommon)
|
||||
include(LLImage)
|
||||
include(LLImageJ2COJ) # ugh, needed for images
|
||||
include(LLKDU)
|
||||
include(LLMath)
|
||||
include(LLMessage)
|
||||
include(LLRender)
|
||||
|
|
@ -71,6 +72,11 @@ endif (DARWIN)
|
|||
target_link_libraries(llui_libtest
|
||||
llui
|
||||
llmessage
|
||||
${LLRENDER_LIBRARIES}
|
||||
${LLIMAGE_LIBRARIES}
|
||||
${LLKDU_LIBRARIES}
|
||||
${KDU_LIBRARY}
|
||||
${LLIMAGEJ2COJ_LIBRARIES}
|
||||
${OS_LIBRARIES}
|
||||
${GOOGLE_PERFTOOLS_LIBRARIES}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -174,7 +174,7 @@ void export_test_floaters()
|
|||
std::string delim = gDirUtilp->getDirDelimiter();
|
||||
std::string xui_dir = get_xui_dir() + "en" + delim;
|
||||
std::string filename;
|
||||
while (gDirUtilp->getNextFileInDir(xui_dir, "floater_test_*.xml", filename, false))
|
||||
while (gDirUtilp->getNextFileInDir(xui_dir, "floater_test_*.xml", filename))
|
||||
{
|
||||
if (filename.find("_new.xml") != std::string::npos)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -52,20 +52,22 @@ def get_HKLM_registry_value(key_str, value_str):
|
|||
|
||||
def find_vc_dir():
|
||||
supported_versions = (r'8.0', r'9.0')
|
||||
supported_products = (r'VisualStudio', r'VCExpress')
|
||||
value_str = (r'ProductDir')
|
||||
|
||||
for version in supported_versions:
|
||||
key_str = (r'SOFTWARE\Microsoft\VisualStudio\%s\Setup\VC' %
|
||||
version)
|
||||
try:
|
||||
return get_HKLM_registry_value(key_str, value_str)
|
||||
except WindowsError, err:
|
||||
x64_key_str = (r'SOFTWARE\Wow6432Node\Microsoft\VisualStudio\%s\Setup\VS' %
|
||||
version)
|
||||
for product in supported_products:
|
||||
for version in supported_versions:
|
||||
key_str = (r'SOFTWARE\Microsoft\%s\%s\Setup\VC' %
|
||||
(product, version))
|
||||
try:
|
||||
return get_HKLM_registry_value(x64_key_str, value_str)
|
||||
except:
|
||||
print >> sys.stderr, "Didn't find MS VC version %s " % version
|
||||
return get_HKLM_registry_value(key_str, value_str)
|
||||
except WindowsError, err:
|
||||
x64_key_str = (r'SOFTWARE\Wow6432Node\Microsoft\VisualStudio\%s\Setup\VS' %
|
||||
version)
|
||||
try:
|
||||
return get_HKLM_registry_value(x64_key_str, value_str)
|
||||
except:
|
||||
print >> sys.stderr, "Didn't find MS %s version %s " % (product,version)
|
||||
|
||||
raise
|
||||
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ const guint ROTATE_IMAGE_TIMEOUT = 8000;
|
|||
typedef struct _updater_app_state {
|
||||
std::string app_name;
|
||||
std::string url;
|
||||
std::string file;
|
||||
std::string image_dir;
|
||||
std::string dest_dir;
|
||||
std::string strings_dirs;
|
||||
|
|
@ -113,7 +114,7 @@ BOOL install_package(std::string package_file, std::string destination);
|
|||
BOOL spawn_viewer(UpdaterAppState *app_state);
|
||||
|
||||
extern "C" {
|
||||
void on_window_closed(GtkWidget *sender, gpointer state);
|
||||
void on_window_closed(GtkWidget *sender, GdkEvent *event, gpointer state);
|
||||
gpointer worker_thread_cb(gpointer *data);
|
||||
int download_progress_cb(gpointer data, double t, double d, double utotal, double ulnow);
|
||||
gboolean rotate_image_cb(gpointer data);
|
||||
|
|
@ -216,11 +217,11 @@ gboolean rotate_image_cb(gpointer data)
|
|||
std::string next_image_filename(std::string& image_path)
|
||||
{
|
||||
std::string image_filename;
|
||||
gDirUtilp->getNextFileInDir(image_path, "/*.jpg", image_filename, true);
|
||||
gDirUtilp->getNextFileInDir(image_path, "/*.jpg", image_filename);
|
||||
return image_path + "/" + image_filename;
|
||||
}
|
||||
|
||||
void on_window_closed(GtkWidget *sender, gpointer data)
|
||||
void on_window_closed(GtkWidget *sender, GdkEvent* event, gpointer data)
|
||||
{
|
||||
UpdaterAppState *app_state;
|
||||
|
||||
|
|
@ -266,85 +267,95 @@ gpointer worker_thread_cb(gpointer data)
|
|||
CURLcode result;
|
||||
FILE *package_file;
|
||||
GError *error = NULL;
|
||||
char *tmp_filename = NULL;
|
||||
int fd;
|
||||
|
||||
//g_return_val_if_fail (data != NULL, NULL);
|
||||
app_state = (UpdaterAppState *) data;
|
||||
|
||||
try {
|
||||
// create temporary file to store the package.
|
||||
fd = g_file_open_tmp
|
||||
("secondlife-update-XXXXXX", &tmp_filename, &error);
|
||||
if (error != NULL)
|
||||
|
||||
if(!app_state->url.empty())
|
||||
{
|
||||
llerrs << "Unable to create temporary file: "
|
||||
<< error->message
|
||||
<< llendl;
|
||||
char* tmp_local_filename = NULL;
|
||||
// create temporary file to store the package.
|
||||
fd = g_file_open_tmp
|
||||
("secondlife-update-XXXXXX", &tmp_local_filename, &error);
|
||||
if (error != NULL)
|
||||
{
|
||||
llerrs << "Unable to create temporary file: "
|
||||
<< error->message
|
||||
<< llendl;
|
||||
|
||||
g_error_free(error);
|
||||
throw 0;
|
||||
g_error_free(error);
|
||||
throw 0;
|
||||
}
|
||||
|
||||
if(tmp_local_filename != NULL)
|
||||
{
|
||||
app_state->file = tmp_local_filename;
|
||||
g_free(tmp_local_filename);
|
||||
}
|
||||
|
||||
package_file = fdopen(fd, "wb");
|
||||
if (package_file == NULL)
|
||||
{
|
||||
llerrs << "Failed to create temporary file: "
|
||||
<< app_state->file.c_str()
|
||||
<< llendl;
|
||||
|
||||
gdk_threads_enter();
|
||||
display_error(app_state->window,
|
||||
LLTrans::getString("UpdaterFailDownloadTitle"),
|
||||
LLTrans::getString("UpdaterFailUpdateDescriptive"));
|
||||
gdk_threads_leave();
|
||||
throw 0;
|
||||
}
|
||||
|
||||
// initialize curl and start downloading the package
|
||||
llinfos << "Downloading package: " << app_state->url << llendl;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if (curl == NULL)
|
||||
{
|
||||
llerrs << "Failed to initialize libcurl" << llendl;
|
||||
|
||||
gdk_threads_enter();
|
||||
display_error(app_state->window,
|
||||
LLTrans::getString("UpdaterFailDownloadTitle"),
|
||||
LLTrans::getString("UpdaterFailUpdateDescriptive"));
|
||||
gdk_threads_leave();
|
||||
throw 0;
|
||||
}
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, app_state->url.c_str());
|
||||
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, TRUE);
|
||||
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, TRUE);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, package_file);
|
||||
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, FALSE);
|
||||
curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION,
|
||||
&download_progress_cb);
|
||||
curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, app_state);
|
||||
|
||||
result = curl_easy_perform(curl);
|
||||
fclose(package_file);
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
if (result)
|
||||
{
|
||||
llerrs << "Failed to download update: "
|
||||
<< app_state->url
|
||||
<< llendl;
|
||||
|
||||
gdk_threads_enter();
|
||||
display_error(app_state->window,
|
||||
LLTrans::getString("UpdaterFailDownloadTitle"),
|
||||
LLTrans::getString("UpdaterFailUpdateDescriptive"));
|
||||
gdk_threads_leave();
|
||||
|
||||
throw 0;
|
||||
}
|
||||
}
|
||||
|
||||
package_file = fdopen(fd, "wb");
|
||||
if (package_file == NULL)
|
||||
{
|
||||
llerrs << "Failed to create temporary file: "
|
||||
<< tmp_filename
|
||||
<< llendl;
|
||||
|
||||
gdk_threads_enter();
|
||||
display_error(app_state->window,
|
||||
LLTrans::getString("UpdaterFailDownloadTitle"),
|
||||
LLTrans::getString("UpdaterFailUpdateDescriptive"));
|
||||
gdk_threads_leave();
|
||||
throw 0;
|
||||
}
|
||||
|
||||
// initialize curl and start downloading the package
|
||||
llinfos << "Downloading package: " << app_state->url << llendl;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if (curl == NULL)
|
||||
{
|
||||
llerrs << "Failed to initialize libcurl" << llendl;
|
||||
|
||||
gdk_threads_enter();
|
||||
display_error(app_state->window,
|
||||
LLTrans::getString("UpdaterFailDownloadTitle"),
|
||||
LLTrans::getString("UpdaterFailUpdateDescriptive"));
|
||||
gdk_threads_leave();
|
||||
throw 0;
|
||||
}
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, app_state->url.c_str());
|
||||
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, TRUE);
|
||||
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, TRUE);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, package_file);
|
||||
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, FALSE);
|
||||
curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION,
|
||||
&download_progress_cb);
|
||||
curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, app_state);
|
||||
|
||||
result = curl_easy_perform(curl);
|
||||
fclose(package_file);
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
if (result)
|
||||
{
|
||||
llerrs << "Failed to download update: "
|
||||
<< app_state->url
|
||||
<< llendl;
|
||||
|
||||
gdk_threads_enter();
|
||||
display_error(app_state->window,
|
||||
LLTrans::getString("UpdaterFailDownloadTitle"),
|
||||
LLTrans::getString("UpdaterFailUpdateDescriptive"));
|
||||
gdk_threads_leave();
|
||||
|
||||
throw 0;
|
||||
}
|
||||
|
||||
|
||||
// now pulse the progres bar back and forth while the package is
|
||||
// being unpacked
|
||||
gdk_threads_enter();
|
||||
|
|
@ -357,7 +368,7 @@ gpointer worker_thread_cb(gpointer data)
|
|||
|
||||
// *TODO: if the destination is not writable, terminate this
|
||||
// thread and show file chooser?
|
||||
if (!install_package(tmp_filename, app_state->dest_dir))
|
||||
if (!install_package(app_state->file.c_str(), app_state->dest_dir))
|
||||
{
|
||||
llwarns << "Failed to install package to destination: "
|
||||
<< app_state->dest_dir
|
||||
|
|
@ -392,15 +403,6 @@ gpointer worker_thread_cb(gpointer data)
|
|||
app_state->failure = TRUE;
|
||||
}
|
||||
|
||||
// FIXME: delete package file also if delete-event is raised on window
|
||||
if (tmp_filename != NULL)
|
||||
{
|
||||
if (gDirUtilp->fileExists(tmp_filename))
|
||||
{
|
||||
LLFile::remove(tmp_filename);
|
||||
}
|
||||
}
|
||||
|
||||
gdk_threads_enter();
|
||||
updater_app_quit(app_state);
|
||||
gdk_threads_leave();
|
||||
|
|
@ -712,7 +714,7 @@ BOOL spawn_viewer(UpdaterAppState *app_state)
|
|||
|
||||
void show_usage_and_exit()
|
||||
{
|
||||
std::cout << "Usage: linux-updater --url URL --name NAME --dest PATH --stringsdir PATH1,PATH2 --stringsfile FILE"
|
||||
std::cout << "Usage: linux-updater <--url URL | --file FILE> --name NAME --dest PATH --stringsdir PATH1,PATH2 --stringsfile FILE"
|
||||
<< "[--image-dir PATH]"
|
||||
<< std::endl;
|
||||
exit(1);
|
||||
|
|
@ -728,6 +730,10 @@ void parse_args_and_init(int argc, char **argv, UpdaterAppState *app_state)
|
|||
{
|
||||
app_state->url = argv[i];
|
||||
}
|
||||
else if ((!strcmp(argv[i], "--file")) && (++i < argc))
|
||||
{
|
||||
app_state->file = argv[i];
|
||||
}
|
||||
else if ((!strcmp(argv[i], "--name")) && (++i < argc))
|
||||
{
|
||||
app_state->app_name = argv[i];
|
||||
|
|
@ -756,7 +762,7 @@ void parse_args_and_init(int argc, char **argv, UpdaterAppState *app_state)
|
|||
}
|
||||
|
||||
if (app_state->app_name.empty()
|
||||
|| app_state->url.empty()
|
||||
|| (app_state->url.empty() && app_state->file.empty())
|
||||
|| app_state->dest_dir.empty())
|
||||
{
|
||||
show_usage_and_exit();
|
||||
|
|
@ -771,10 +777,10 @@ void parse_args_and_init(int argc, char **argv, UpdaterAppState *app_state)
|
|||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
UpdaterAppState app_state;
|
||||
UpdaterAppState* app_state = new UpdaterAppState;
|
||||
GThread *worker_thread;
|
||||
|
||||
parse_args_and_init(argc, argv, &app_state);
|
||||
parse_args_and_init(argc, argv, app_state);
|
||||
|
||||
// Initialize logger, and rename old log file
|
||||
gDirUtilp->initAppDirs("SecondLife");
|
||||
|
|
@ -797,17 +803,29 @@ int main(int argc, char **argv)
|
|||
gtk_init(&argc, &argv);
|
||||
|
||||
// create UI
|
||||
updater_app_ui_init(&app_state);
|
||||
updater_app_ui_init(app_state);
|
||||
|
||||
//llinfos << "SAMPLE TRANSLATION IS: " << LLTrans::getString("LoginInProgress") << llendl;
|
||||
|
||||
// create download thread
|
||||
worker_thread = g_thread_create
|
||||
(GThreadFunc(worker_thread_cb), &app_state, FALSE, NULL);
|
||||
(GThreadFunc(worker_thread_cb), app_state, FALSE, NULL);
|
||||
|
||||
gdk_threads_enter();
|
||||
gtk_main();
|
||||
gdk_threads_leave();
|
||||
|
||||
return (app_state.failure == FALSE) ? 0 : 1;
|
||||
// Delete the file only if created from url download.
|
||||
if(!app_state->url.empty() && !app_state->file.empty())
|
||||
{
|
||||
if (gDirUtilp->fileExists(app_state->file))
|
||||
{
|
||||
LLFile::remove(app_state->file);
|
||||
}
|
||||
}
|
||||
|
||||
bool success = !app_state->failure;
|
||||
delete app_state;
|
||||
return success ? 0 : 1;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ include(LLVFS)
|
|||
|
||||
include_directories(
|
||||
${LLAUDIO_INCLUDE_DIRS}
|
||||
${FMOD_INCLUDE_DIR}
|
||||
${LLCOMMON_INCLUDE_DIRS}
|
||||
${LLMATH_INCLUDE_DIRS}
|
||||
${LLMESSAGE_INCLUDE_DIRS}
|
||||
|
|
@ -45,6 +44,10 @@ set(llaudio_HEADER_FILES
|
|||
)
|
||||
|
||||
if (FMOD)
|
||||
include_directories(
|
||||
${FMOD_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
list(APPEND llaudio_SOURCE_FILES
|
||||
llaudioengine_fmod.cpp
|
||||
lllistener_fmod.cpp
|
||||
|
|
|
|||
|
|
@ -1557,6 +1557,10 @@ bool LLAudioSource::hasPendingPreloads() const
|
|||
LLAudioData *adp = iter->second;
|
||||
// note: a bad UUID will forever be !hasDecodedData()
|
||||
// but also !hasValidData(), hence the check for hasValidData()
|
||||
if (!adp)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!adp->hasDecodedData() && adp->hasValidData())
|
||||
{
|
||||
// This source is still waiting for a preload
|
||||
|
|
|
|||
|
|
@ -120,6 +120,13 @@ S32 check_for_invalid_wav_formats(const std::string& in_fname, std::string& erro
|
|||
+ ((U32) wav_header[5] << 8)
|
||||
+ wav_header[4];
|
||||
|
||||
if (chunk_length > physical_file_size - file_pos - 4)
|
||||
{
|
||||
infile.close();
|
||||
error_msg = "SoundFileInvalidChunkSize";
|
||||
return(LLVORBISENC_CHUNK_SIZE_ERR);
|
||||
}
|
||||
|
||||
// llinfos << "chunk found: '" << wav_header[0] << wav_header[1] << wav_header[2] << wav_header[3] << "'" << llendl;
|
||||
|
||||
if (!(strncmp((char *)&(wav_header[0]),"fmt ",4)))
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ const S32 LLVORBISENC_MULTICHANNEL_ERR = 7; // can't do stereo
|
|||
const S32 LLVORBISENC_UNSUPPORTED_SAMPLE_RATE = 8; // unsupported sample rate
|
||||
const S32 LLVORBISENC_UNSUPPORTED_WORD_SIZE = 9; // unsupported word size
|
||||
const S32 LLVORBISENC_CLIP_TOO_LONG = 10; // source file is too long
|
||||
const S32 LLVORBISENC_CHUNK_SIZE_ERR = 11; // chunk size is wrong
|
||||
|
||||
const F32 LLVORBIS_CLIP_MAX_TIME = 10.0f;
|
||||
const U8 LLVORBIS_CLIP_MAX_CHANNELS = 2;
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ set(llcommon_SOURCE_FILES
|
|||
llmemorystream.cpp
|
||||
llmemtype.cpp
|
||||
llmetrics.cpp
|
||||
llmetricperformancetester.cpp
|
||||
llmortician.cpp
|
||||
lloptioninterface.cpp
|
||||
llptrto.cpp
|
||||
|
|
@ -92,6 +93,7 @@ set(llcommon_SOURCE_FILES
|
|||
llstringtable.cpp
|
||||
llsys.cpp
|
||||
llthread.cpp
|
||||
llthreadsafequeue.cpp
|
||||
lltimer.cpp
|
||||
lluri.cpp
|
||||
lluuid.cpp
|
||||
|
|
@ -186,6 +188,7 @@ set(llcommon_HEADER_FILES
|
|||
llmemorystream.h
|
||||
llmemtype.h
|
||||
llmetrics.h
|
||||
llmetricperformancetester.h
|
||||
llmortician.h
|
||||
llnametable.h
|
||||
lloptioninterface.h
|
||||
|
|
@ -223,6 +226,7 @@ set(llcommon_HEADER_FILES
|
|||
llstringtable.h
|
||||
llsys.h
|
||||
llthread.h
|
||||
llthreadsafequeue.h
|
||||
lltimer.h
|
||||
lltreeiterators.h
|
||||
lluri.h
|
||||
|
|
|
|||
|
|
@ -245,9 +245,6 @@ const U8 SIM_ACCESS_ADULT = 42; // Seriously Adult Only
|
|||
const U8 SIM_ACCESS_DOWN = 254;
|
||||
const U8 SIM_ACCESS_MAX = SIM_ACCESS_ADULT;
|
||||
|
||||
// group constants
|
||||
const S32 MAX_AGENT_GROUPS = 25;
|
||||
|
||||
// attachment constants
|
||||
const S32 MAX_AGENT_ATTACHMENTS = 38;
|
||||
const U8 ATTACHMENT_ADD = 0x80;
|
||||
|
|
@ -300,6 +297,14 @@ const U32 START_LOCATION_ID_COUNT = 6;
|
|||
// group constants
|
||||
const U32 GROUP_MIN_SIZE = 2;
|
||||
|
||||
// gMaxAgentGroups is now sent by login.cgi, which
|
||||
// looks it up from globals.xml.
|
||||
//
|
||||
// For now we need an old default value however,
|
||||
// so the viewer can be deployed ahead of login.cgi.
|
||||
//
|
||||
const S32 DEFAULT_MAX_AGENT_GROUPS = 25;
|
||||
|
||||
// radius within which a chat message is fully audible
|
||||
const F32 CHAT_WHISPER_RADIUS = 10.f;
|
||||
const F32 CHAT_NORMAL_RADIUS = 20.f;
|
||||
|
|
|
|||
|
|
@ -90,6 +90,10 @@ S32 LL_HEARTBEAT_SIGNAL = (SIGRTMAX >= 0) ? (SIGRTMAX-0) : SIGUSR2;
|
|||
// the static application instance
|
||||
LLApp* LLApp::sApplication = NULL;
|
||||
|
||||
// Allows the generation of core files for post mortem under gdb
|
||||
// and disables crashlogger
|
||||
BOOL LLApp::sDisableCrashlogger = FALSE;
|
||||
|
||||
// Local flag for whether or not to do logging in signal handlers.
|
||||
//static
|
||||
BOOL LLApp::sLogInSignal = FALSE;
|
||||
|
|
@ -461,11 +465,30 @@ bool LLApp::isQuitting()
|
|||
return (APP_STATUS_QUITTING == sStatus);
|
||||
}
|
||||
|
||||
// static
|
||||
bool LLApp::isExiting()
|
||||
{
|
||||
return isQuitting() || isError();
|
||||
}
|
||||
|
||||
void LLApp::disableCrashlogger()
|
||||
{
|
||||
// Disable Breakpad exception handler.
|
||||
if (mExceptionHandler != 0)
|
||||
{
|
||||
delete mExceptionHandler;
|
||||
mExceptionHandler = 0;
|
||||
}
|
||||
|
||||
sDisableCrashlogger = TRUE;
|
||||
}
|
||||
|
||||
// static
|
||||
bool LLApp::isCrashloggerDisabled()
|
||||
{
|
||||
return (sDisableCrashlogger == TRUE);
|
||||
}
|
||||
|
||||
#if !LL_WINDOWS
|
||||
// static
|
||||
U32 LLApp::getSigChildCount()
|
||||
|
|
@ -799,6 +822,15 @@ void default_unix_signal_handler(int signum, siginfo_t *info, void *)
|
|||
{
|
||||
llwarns << "Signal handler - Flagging error status and waiting for shutdown" << llendl;
|
||||
}
|
||||
|
||||
if (LLApp::isCrashloggerDisabled()) // Don't gracefully handle any signal, crash and core for a gdb post mortem
|
||||
{
|
||||
clear_signals();
|
||||
llwarns << "Fatal signal received, not handling the crash here, passing back to operating system" << llendl;
|
||||
raise(signum);
|
||||
return;
|
||||
}
|
||||
|
||||
// Flag status to ERROR, so thread_error does its work.
|
||||
LLApp::setError();
|
||||
// Block in the signal handler until somebody says that we're done.
|
||||
|
|
|
|||
|
|
@ -189,6 +189,11 @@ public:
|
|||
//
|
||||
virtual bool mainLoop() = 0; // Override for the application main loop. Needs to at least gracefully notice the QUITTING state and exit.
|
||||
|
||||
//
|
||||
// Crash logging
|
||||
//
|
||||
void disableCrashlogger(); // Let the OS handle the crashes
|
||||
static bool isCrashloggerDisabled(); // Get the here above set value
|
||||
|
||||
//
|
||||
// Application status
|
||||
|
|
@ -280,6 +285,7 @@ protected:
|
|||
static void setStatus(EAppStatus status); // Use this to change the application status.
|
||||
static EAppStatus sStatus; // Reflects current application status
|
||||
static BOOL sErrorThreadRunning; // Set while the error thread is running
|
||||
static BOOL sDisableCrashlogger; // Let the OS handle crashes for us.
|
||||
|
||||
#if !LL_WINDOWS
|
||||
static LLAtomicU32* sSigChildCount; // Number of SIGCHLDs received.
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
#include "linden_common.h"
|
||||
#include "llapr.h"
|
||||
#include "apr_dso.h"
|
||||
|
||||
apr_pool_t *gAPRPoolp = NULL; // Global APR memory pool
|
||||
LLVolatileAPRPool *LLAPRFile::sAPRFilePoolp = NULL ; //global volatile APR memory pool.
|
||||
|
|
@ -279,14 +280,31 @@ bool ll_apr_warn_status(apr_status_t status)
|
|||
{
|
||||
if(APR_SUCCESS == status) return false;
|
||||
char buf[MAX_STRING]; /* Flawfinder: ignore */
|
||||
apr_strerror(status, buf, MAX_STRING);
|
||||
apr_strerror(status, buf, sizeof(buf));
|
||||
LL_WARNS("APR") << "APR: " << buf << LL_ENDL;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ll_apr_warn_status(apr_status_t status, apr_dso_handle_t *handle)
|
||||
{
|
||||
bool result = ll_apr_warn_status(status);
|
||||
// Despite observed truncation of actual Mac dylib load errors, increasing
|
||||
// this buffer to more than MAX_STRING doesn't help: it appears that APR
|
||||
// stores the output in a fixed 255-character internal buffer. (*sigh*)
|
||||
char buf[MAX_STRING]; /* Flawfinder: ignore */
|
||||
apr_dso_error(handle, buf, sizeof(buf));
|
||||
LL_WARNS("APR") << "APR: " << buf << LL_ENDL;
|
||||
return result;
|
||||
}
|
||||
|
||||
void ll_apr_assert_status(apr_status_t status)
|
||||
{
|
||||
llassert(ll_apr_warn_status(status) == false);
|
||||
llassert(! ll_apr_warn_status(status));
|
||||
}
|
||||
|
||||
void ll_apr_assert_status(apr_status_t status, apr_dso_handle_t *handle)
|
||||
{
|
||||
llassert(! ll_apr_warn_status(status, handle));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -53,6 +53,8 @@
|
|||
extern LL_COMMON_API apr_thread_mutex_t* gLogMutexp;
|
||||
extern apr_thread_mutex_t* gCallStacksLogMutexp;
|
||||
|
||||
struct apr_dso_handle_t;
|
||||
|
||||
/**
|
||||
* @brief initialize the common apr constructs -- apr itself, the
|
||||
* global pool, and a mutex.
|
||||
|
|
@ -259,8 +261,11 @@ public:
|
|||
* @return Returns <code>true</code> if status is an error condition.
|
||||
*/
|
||||
bool LL_COMMON_API ll_apr_warn_status(apr_status_t status);
|
||||
/// There's a whole other APR error-message function if you pass a DSO handle.
|
||||
bool LL_COMMON_API ll_apr_warn_status(apr_status_t status, apr_dso_handle_t* handle);
|
||||
|
||||
void LL_COMMON_API ll_apr_assert_status(apr_status_t status);
|
||||
void LL_COMMON_API ll_apr_assert_status(apr_status_t status, apr_dso_handle_t* handle);
|
||||
|
||||
extern "C" LL_COMMON_API apr_pool_t* gAPRPoolp; // Global APR memory pool
|
||||
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ LLAvatarName::LLAvatarName()
|
|||
mLegacyFirstName(),
|
||||
mLegacyLastName(),
|
||||
mIsDisplayNameDefault(false),
|
||||
mIsDummy(false),
|
||||
mIsTemporaryName(false),
|
||||
mExpires(F64_MAX),
|
||||
mNextUpdate(0.0)
|
||||
{ }
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ public:
|
|||
// Under error conditions, we may insert "dummy" records with
|
||||
// names like "???" into caches as placeholders. These can be
|
||||
// shown in UI, but are not serialized.
|
||||
bool mIsDummy;
|
||||
bool mIsTemporaryName;
|
||||
|
||||
// Names can change, so need to keep track of when name was
|
||||
// last checked.
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ public:
|
|||
|
||||
LLDynamicArray(S32 size=0) : std::vector<Type>(size) { if (size < BlockSize) std::vector<Type>::reserve(BlockSize); }
|
||||
|
||||
void reset() { std::vector<Type>::resize(0); }
|
||||
void reset() { std::vector<Type>::clear(); }
|
||||
|
||||
// ACCESSORS
|
||||
const Type& get(S32 index) const { return std::vector<Type>::operator[](index); }
|
||||
|
|
|
|||
|
|
@ -475,7 +475,7 @@ void LLEventPump::stopListening(const std::string& name)
|
|||
*****************************************************************************/
|
||||
bool LLEventStream::post(const LLSD& event)
|
||||
{
|
||||
if (! mEnabled)
|
||||
if (! mEnabled || !mSignal)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
@ -515,6 +515,8 @@ bool LLEventQueue::post(const LLSD& event)
|
|||
|
||||
void LLEventQueue::flush()
|
||||
{
|
||||
if(!mSignal) return;
|
||||
|
||||
// Consider the case when a given listener on this LLEventQueue posts yet
|
||||
// another event on the same queue. If we loop over mEventQueue directly,
|
||||
// we'll end up processing all those events during the same flush() call
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ bool LLFastTimer::sPauseHistory = 0;
|
|||
bool LLFastTimer::sResetHistory = 0;
|
||||
LLFastTimer::CurTimerData LLFastTimer::sCurTimerData;
|
||||
BOOL LLFastTimer::sLog = FALSE;
|
||||
std::string LLFastTimer::sLogName = "";
|
||||
BOOL LLFastTimer::sMetricLog = FALSE;
|
||||
LLMutex* LLFastTimer::sLogLock = NULL;
|
||||
std::queue<LLSD> LLFastTimer::sLogQueue;
|
||||
|
|
|
|||
|
|
@ -211,6 +211,7 @@ public:
|
|||
static std::queue<LLSD> sLogQueue;
|
||||
static BOOL sLog;
|
||||
static BOOL sMetricLog;
|
||||
static std::string sLogName;
|
||||
static bool sPauseHistory;
|
||||
static bool sResetHistory;
|
||||
static U64 sTimerCycles;
|
||||
|
|
|
|||
|
|
@ -318,7 +318,12 @@ void llofstream::close()
|
|||
if(is_open())
|
||||
{
|
||||
if (_Filebuffer->close() == 0)
|
||||
{
|
||||
_Myios::setstate(ios_base::failbit); /*Flawfinder: ignore*/
|
||||
}
|
||||
delete _Filebuffer;
|
||||
_Filebuffer = NULL;
|
||||
_ShouldClose = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,254 @@
|
|||
/**
|
||||
* @file llmetricperformancetester.cpp
|
||||
* @brief LLMetricPerformanceTesterBasic and LLMetricPerformanceTesterWithSession classes implementation
|
||||
*
|
||||
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "linden_common.h"
|
||||
|
||||
#include "indra_constants.h"
|
||||
#include "llerror.h"
|
||||
#include "llsdserialize.h"
|
||||
#include "llstat.h"
|
||||
#include "lltreeiterators.h"
|
||||
#include "llmetricperformancetester.h"
|
||||
|
||||
//----------------------------------------------------------------------------------------------
|
||||
// LLMetricPerformanceTesterBasic : static methods and testers management
|
||||
//----------------------------------------------------------------------------------------------
|
||||
|
||||
LLMetricPerformanceTesterBasic::name_tester_map_t LLMetricPerformanceTesterBasic::sTesterMap ;
|
||||
|
||||
/*static*/
|
||||
void LLMetricPerformanceTesterBasic::cleanClass()
|
||||
{
|
||||
for (name_tester_map_t::iterator iter = sTesterMap.begin() ; iter != sTesterMap.end() ; ++iter)
|
||||
{
|
||||
delete iter->second ;
|
||||
}
|
||||
sTesterMap.clear() ;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
BOOL LLMetricPerformanceTesterBasic::addTester(LLMetricPerformanceTesterBasic* tester)
|
||||
{
|
||||
llassert_always(tester != NULL);
|
||||
std::string name = tester->getTesterName() ;
|
||||
if (getTester(name))
|
||||
{
|
||||
llerrs << "Tester name is already used by some other tester : " << name << llendl ;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
sTesterMap.insert(std::make_pair(name, tester));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
LLMetricPerformanceTesterBasic* LLMetricPerformanceTesterBasic::getTester(std::string name)
|
||||
{
|
||||
// Check for the requested metric name
|
||||
name_tester_map_t::iterator found_it = sTesterMap.find(name) ;
|
||||
if (found_it != sTesterMap.end())
|
||||
{
|
||||
return found_it->second ;
|
||||
}
|
||||
return NULL ;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
// Return TRUE if this metric is requested or if the general default "catch all" metric is requested
|
||||
BOOL LLMetricPerformanceTesterBasic::isMetricLogRequested(std::string name)
|
||||
{
|
||||
return (LLFastTimer::sMetricLog && ((LLFastTimer::sLogName == name) || (LLFastTimer::sLogName == DEFAULT_METRIC_NAME)));
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------
|
||||
// LLMetricPerformanceTesterBasic : Tester instance methods
|
||||
//----------------------------------------------------------------------------------------------
|
||||
|
||||
LLMetricPerformanceTesterBasic::LLMetricPerformanceTesterBasic(std::string name) :
|
||||
mName(name),
|
||||
mCount(0)
|
||||
{
|
||||
if (mName == std::string())
|
||||
{
|
||||
llerrs << "LLMetricPerformanceTesterBasic construction invalid : Empty name passed to constructor" << llendl ;
|
||||
}
|
||||
|
||||
mValidInstance = LLMetricPerformanceTesterBasic::addTester(this) ;
|
||||
}
|
||||
|
||||
LLMetricPerformanceTesterBasic::~LLMetricPerformanceTesterBasic()
|
||||
{
|
||||
}
|
||||
|
||||
void LLMetricPerformanceTesterBasic::preOutputTestResults(LLSD* sd)
|
||||
{
|
||||
incrementCurrentCount() ;
|
||||
(*sd)[getCurrentLabelName()]["Name"] = mName ;
|
||||
}
|
||||
|
||||
void LLMetricPerformanceTesterBasic::postOutputTestResults(LLSD* sd)
|
||||
{
|
||||
LLMutexLock lock(LLFastTimer::sLogLock);
|
||||
LLFastTimer::sLogQueue.push((*sd));
|
||||
}
|
||||
|
||||
void LLMetricPerformanceTesterBasic::outputTestResults()
|
||||
{
|
||||
LLSD sd;
|
||||
|
||||
preOutputTestResults(&sd) ;
|
||||
outputTestRecord(&sd) ;
|
||||
postOutputTestResults(&sd) ;
|
||||
}
|
||||
|
||||
void LLMetricPerformanceTesterBasic::addMetric(std::string str)
|
||||
{
|
||||
mMetricStrings.push_back(str) ;
|
||||
}
|
||||
|
||||
/*virtual*/
|
||||
void LLMetricPerformanceTesterBasic::analyzePerformance(std::ofstream* os, LLSD* base, LLSD* current)
|
||||
{
|
||||
resetCurrentCount() ;
|
||||
|
||||
std::string current_label = getCurrentLabelName();
|
||||
BOOL in_base = (*base).has(current_label) ;
|
||||
BOOL in_current = (*current).has(current_label) ;
|
||||
|
||||
while(in_base || in_current)
|
||||
{
|
||||
LLSD::String label = current_label ;
|
||||
|
||||
if(in_base && in_current)
|
||||
{
|
||||
*os << llformat("%s\n", label.c_str()) ;
|
||||
|
||||
for(U32 index = 0 ; index < mMetricStrings.size() ; index++)
|
||||
{
|
||||
switch((*current)[label][ mMetricStrings[index] ].type())
|
||||
{
|
||||
case LLSD::TypeInteger:
|
||||
compareTestResults(os, mMetricStrings[index],
|
||||
(S32)((*base)[label][ mMetricStrings[index] ].asInteger()), (S32)((*current)[label][ mMetricStrings[index] ].asInteger())) ;
|
||||
break ;
|
||||
case LLSD::TypeReal:
|
||||
compareTestResults(os, mMetricStrings[index],
|
||||
(F32)((*base)[label][ mMetricStrings[index] ].asReal()), (F32)((*current)[label][ mMetricStrings[index] ].asReal())) ;
|
||||
break;
|
||||
default:
|
||||
llerrs << "unsupported metric " << mMetricStrings[index] << " LLSD type: " << (S32)(*current)[label][ mMetricStrings[index] ].type() << llendl ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
incrementCurrentCount();
|
||||
current_label = getCurrentLabelName();
|
||||
in_base = (*base).has(current_label) ;
|
||||
in_current = (*current).has(current_label) ;
|
||||
}
|
||||
}
|
||||
|
||||
/*virtual*/
|
||||
void LLMetricPerformanceTesterBasic::compareTestResults(std::ofstream* os, std::string metric_string, S32 v_base, S32 v_current)
|
||||
{
|
||||
*os << llformat(" ,%s, %d, %d, %d, %.4f\n", metric_string.c_str(), v_base, v_current,
|
||||
v_current - v_base, (v_base != 0) ? 100.f * v_current / v_base : 0) ;
|
||||
}
|
||||
|
||||
/*virtual*/
|
||||
void LLMetricPerformanceTesterBasic::compareTestResults(std::ofstream* os, std::string metric_string, F32 v_base, F32 v_current)
|
||||
{
|
||||
*os << llformat(" ,%s, %.4f, %.4f, %.4f, %.4f\n", metric_string.c_str(), v_base, v_current,
|
||||
v_current - v_base, (fabs(v_base) > 0.0001f) ? 100.f * v_current / v_base : 0.f ) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------
|
||||
// LLMetricPerformanceTesterWithSession
|
||||
//----------------------------------------------------------------------------------------------
|
||||
|
||||
LLMetricPerformanceTesterWithSession::LLMetricPerformanceTesterWithSession(std::string name) :
|
||||
LLMetricPerformanceTesterBasic(name),
|
||||
mBaseSessionp(NULL),
|
||||
mCurrentSessionp(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
LLMetricPerformanceTesterWithSession::~LLMetricPerformanceTesterWithSession()
|
||||
{
|
||||
if (mBaseSessionp)
|
||||
{
|
||||
delete mBaseSessionp ;
|
||||
mBaseSessionp = NULL ;
|
||||
}
|
||||
if (mCurrentSessionp)
|
||||
{
|
||||
delete mCurrentSessionp ;
|
||||
mCurrentSessionp = NULL ;
|
||||
}
|
||||
}
|
||||
|
||||
/*virtual*/
|
||||
void LLMetricPerformanceTesterWithSession::analyzePerformance(std::ofstream* os, LLSD* base, LLSD* current)
|
||||
{
|
||||
// Load the base session
|
||||
resetCurrentCount() ;
|
||||
mBaseSessionp = loadTestSession(base) ;
|
||||
|
||||
// Load the current session
|
||||
resetCurrentCount() ;
|
||||
mCurrentSessionp = loadTestSession(current) ;
|
||||
|
||||
if (!mBaseSessionp || !mCurrentSessionp)
|
||||
{
|
||||
llerrs << "Error loading test sessions." << llendl ;
|
||||
}
|
||||
|
||||
// Compare
|
||||
compareTestSessions(os) ;
|
||||
|
||||
// Release memory
|
||||
if (mBaseSessionp)
|
||||
{
|
||||
delete mBaseSessionp ;
|
||||
mBaseSessionp = NULL ;
|
||||
}
|
||||
if (mCurrentSessionp)
|
||||
{
|
||||
delete mCurrentSessionp ;
|
||||
mCurrentSessionp = NULL ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------
|
||||
// LLTestSession
|
||||
//----------------------------------------------------------------------------------------------
|
||||
|
||||
LLMetricPerformanceTesterWithSession::LLTestSession::~LLTestSession()
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,206 @@
|
|||
/**
|
||||
* @file llmetricperformancetester.h
|
||||
* @brief LLMetricPerformanceTesterBasic and LLMetricPerformanceTesterWithSession classes definition
|
||||
*
|
||||
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_METRICPERFORMANCETESTER_H
|
||||
#define LL_METRICPERFORMANCETESTER_H
|
||||
|
||||
const std::string DEFAULT_METRIC_NAME("metric");
|
||||
|
||||
/**
|
||||
* @class LLMetricPerformanceTesterBasic
|
||||
* @brief Performance Metric Base Class
|
||||
*/
|
||||
class LL_COMMON_API LLMetricPerformanceTesterBasic
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Creates a basic tester instance.
|
||||
* @param[in] name - Unique string identifying this tester instance.
|
||||
*/
|
||||
LLMetricPerformanceTesterBasic(std::string name);
|
||||
virtual ~LLMetricPerformanceTesterBasic();
|
||||
|
||||
/**
|
||||
* @return Returns true if the instance has been added to the tester map.
|
||||
* Need to be tested after creation of a tester instance so to know if the tester is correctly handled.
|
||||
* A tester might not be added to the map if another tester with the same name already exists.
|
||||
*/
|
||||
BOOL isValid() const { return mValidInstance; }
|
||||
|
||||
/**
|
||||
* @brief Write a set of test results to the log LLSD.
|
||||
*/
|
||||
void outputTestResults() ;
|
||||
|
||||
/**
|
||||
* @brief Compare the test results.
|
||||
* By default, compares the test results against the baseline one by one, item by item,
|
||||
* in the increasing order of the LLSD record counter, starting from the first one.
|
||||
*/
|
||||
virtual void analyzePerformance(std::ofstream* os, LLSD* base, LLSD* current) ;
|
||||
|
||||
/**
|
||||
* @return Returns the number of the test metrics in this tester instance.
|
||||
*/
|
||||
S32 getNumberOfMetrics() const { return mMetricStrings.size() ;}
|
||||
/**
|
||||
* @return Returns the metric name at index
|
||||
* @param[in] index - Index on the list of metrics managed by this tester instance.
|
||||
*/
|
||||
std::string getMetricName(S32 index) const { return mMetricStrings[index] ;}
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @return Returns the name of this tester instance.
|
||||
*/
|
||||
std::string getTesterName() const { return mName ;}
|
||||
|
||||
/**
|
||||
* @brief Insert a new metric to be managed by this tester instance.
|
||||
* @param[in] str - Unique string identifying the new metric.
|
||||
*/
|
||||
void addMetric(std::string str) ;
|
||||
|
||||
/**
|
||||
* @brief Compare test results, provided in 2 flavors: compare integers and compare floats.
|
||||
* @param[out] os - Formatted output string holding the compared values.
|
||||
* @param[in] metric_string - Name of the metric.
|
||||
* @param[in] v_base - Base value of the metric.
|
||||
* @param[in] v_current - Current value of the metric.
|
||||
*/
|
||||
virtual void compareTestResults(std::ofstream* os, std::string metric_string, S32 v_base, S32 v_current) ;
|
||||
virtual void compareTestResults(std::ofstream* os, std::string metric_string, F32 v_base, F32 v_current) ;
|
||||
|
||||
/**
|
||||
* @brief Reset internal record count. Count starts with 1.
|
||||
*/
|
||||
void resetCurrentCount() { mCount = 1; }
|
||||
/**
|
||||
* @brief Increment internal record count.
|
||||
*/
|
||||
void incrementCurrentCount() { mCount++; }
|
||||
/**
|
||||
* @return Returns the label to be used for the current count. It's "TesterName"-"Count".
|
||||
*/
|
||||
std::string getCurrentLabelName() const { return llformat("%s-%d", mName.c_str(), mCount) ;}
|
||||
|
||||
/**
|
||||
* @brief Write a test record to the LLSD. Implementers need to overload this method.
|
||||
* @param[out] sd - The LLSD record to store metric data into.
|
||||
*/
|
||||
virtual void outputTestRecord(LLSD* sd) = 0 ;
|
||||
|
||||
private:
|
||||
void preOutputTestResults(LLSD* sd) ;
|
||||
void postOutputTestResults(LLSD* sd) ;
|
||||
|
||||
std::string mName ; // Name of this tester instance
|
||||
S32 mCount ; // Current record count
|
||||
BOOL mValidInstance; // TRUE if the instance is managed by the map
|
||||
std::vector< std::string > mMetricStrings ; // Metrics strings
|
||||
|
||||
// Static members managing the collection of testers
|
||||
public:
|
||||
// Map of all the tester instances in use
|
||||
typedef std::map< std::string, LLMetricPerformanceTesterBasic* > name_tester_map_t;
|
||||
static name_tester_map_t sTesterMap ;
|
||||
|
||||
/**
|
||||
* @return Returns a pointer to the tester
|
||||
* @param[in] name - Name of the tester instance queried.
|
||||
*/
|
||||
static LLMetricPerformanceTesterBasic* getTester(std::string name) ;
|
||||
|
||||
/**
|
||||
* @return Returns TRUE if that metric *or* the default catch all metric has been requested to be logged
|
||||
* @param[in] name - Name of the tester queried.
|
||||
*/
|
||||
static BOOL isMetricLogRequested(std::string name);
|
||||
|
||||
/**
|
||||
* @return Returns TRUE if there's a tester defined, FALSE otherwise.
|
||||
*/
|
||||
static BOOL hasMetricPerformanceTesters() { return !sTesterMap.empty() ;}
|
||||
/**
|
||||
* @brief Delete all testers and reset the tester map
|
||||
*/
|
||||
static void cleanClass() ;
|
||||
|
||||
private:
|
||||
// Add a tester to the map. Returns false if adding fails.
|
||||
static BOOL addTester(LLMetricPerformanceTesterBasic* tester) ;
|
||||
};
|
||||
|
||||
/**
|
||||
* @class LLMetricPerformanceTesterWithSession
|
||||
* @brief Performance Metric Class with custom session
|
||||
*/
|
||||
class LL_COMMON_API LLMetricPerformanceTesterWithSession : public LLMetricPerformanceTesterBasic
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @param[in] name - Unique string identifying this tester instance.
|
||||
*/
|
||||
LLMetricPerformanceTesterWithSession(std::string name);
|
||||
virtual ~LLMetricPerformanceTesterWithSession();
|
||||
|
||||
/**
|
||||
* @brief Compare the test results.
|
||||
* This will be loading the base and current sessions and compare them using the virtual
|
||||
* abstract methods loadTestSession() and compareTestSessions()
|
||||
*/
|
||||
virtual void analyzePerformance(std::ofstream* os, LLSD* base, LLSD* current) ;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @class LLMetricPerformanceTesterWithSession::LLTestSession
|
||||
* @brief Defines an interface for the two abstract virtual functions loadTestSession() and compareTestSessions()
|
||||
*/
|
||||
class LL_COMMON_API LLTestSession
|
||||
{
|
||||
public:
|
||||
virtual ~LLTestSession() ;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Convert an LLSD log into a test session.
|
||||
* @param[in] log - The LLSD record
|
||||
* @return Returns the record as a test session
|
||||
*/
|
||||
virtual LLMetricPerformanceTesterWithSession::LLTestSession* loadTestSession(LLSD* log) = 0;
|
||||
|
||||
/**
|
||||
* @brief Compare the base session and the target session. Assumes base and current sessions have been loaded.
|
||||
* @param[out] os - The comparison result as a standard stream
|
||||
*/
|
||||
virtual void compareTestSessions(std::ofstream* os) = 0;
|
||||
|
||||
LLTestSession* mBaseSessionp;
|
||||
LLTestSession* mCurrentSessionp;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -58,6 +58,11 @@ void LLProcessLauncher::setWorkingDirectory(const std::string &dir)
|
|||
mWorkingDir = dir;
|
||||
}
|
||||
|
||||
const std::string& LLProcessLauncher::getExecutable() const
|
||||
{
|
||||
return mExecutable;
|
||||
}
|
||||
|
||||
void LLProcessLauncher::clearArguments()
|
||||
{
|
||||
mLaunchArguments.clear();
|
||||
|
|
@ -260,14 +265,7 @@ int LLProcessLauncher::launch(void)
|
|||
delete[] fake_argv;
|
||||
|
||||
mProcessID = id;
|
||||
|
||||
// At this point, the child process will have been created (since that's how vfork works -- the child borrowed our execution context until it forked)
|
||||
// If the process doesn't exist at this point, the exec failed.
|
||||
if(!isRunning())
|
||||
{
|
||||
result = -1;
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@ public:
|
|||
void setExecutable(const std::string &executable);
|
||||
void setWorkingDirectory(const std::string &dir);
|
||||
|
||||
const std::string& getExecutable() const;
|
||||
|
||||
void clearArguments();
|
||||
void addArgument(const std::string &arg);
|
||||
void addArgument(const char *arg);
|
||||
|
|
|
|||
|
|
@ -179,7 +179,7 @@ public:
|
|||
void waitOnPending();
|
||||
void printQueueStats();
|
||||
|
||||
S32 getPending();
|
||||
virtual S32 getPending();
|
||||
bool getThreaded() { return mThreaded ? true : false; }
|
||||
|
||||
// Request accessors
|
||||
|
|
|
|||
|
|
@ -635,6 +635,26 @@ U32 LLMemoryInfo::getPhysicalMemoryClamped() const
|
|||
}
|
||||
}
|
||||
|
||||
//static
|
||||
void LLMemoryInfo::getAvailableMemoryKB(U32& avail_physical_mem_kb, U32& avail_virtual_mem_kb)
|
||||
{
|
||||
#if LL_WINDOWS
|
||||
MEMORYSTATUSEX state;
|
||||
state.dwLength = sizeof(state);
|
||||
GlobalMemoryStatusEx(&state);
|
||||
|
||||
avail_physical_mem_kb = (U32)(state.ullAvailPhys/1024) ;
|
||||
avail_virtual_mem_kb = (U32)(state.ullAvailVirtual/1024) ;
|
||||
|
||||
#else
|
||||
//do not know how to collect available memory info for other systems.
|
||||
//leave it blank here for now.
|
||||
|
||||
avail_physical_mem_kb = -1 ;
|
||||
avail_virtual_mem_kb = -1 ;
|
||||
#endif
|
||||
}
|
||||
|
||||
void LLMemoryInfo::stream(std::ostream& s) const
|
||||
{
|
||||
#if LL_WINDOWS
|
||||
|
|
|
|||
|
|
@ -114,6 +114,9 @@ public:
|
|||
** be returned.
|
||||
*/
|
||||
U32 getPhysicalMemoryClamped() const; ///< Memory size in clamped bytes
|
||||
|
||||
//get the available memory infomation in KiloBytes.
|
||||
static void getAvailableMemoryKB(U32& avail_physical_mem_kb, U32& avail_virtual_mem_kb);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -63,9 +63,6 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap
|
|||
{
|
||||
LLThread *threadp = (LLThread *)datap;
|
||||
|
||||
// Set thread state to running
|
||||
threadp->mStatus = RUNNING;
|
||||
|
||||
// Run the user supplied function
|
||||
threadp->run();
|
||||
|
||||
|
|
@ -147,26 +144,45 @@ void LLThread::shutdown()
|
|||
{
|
||||
// This thread just wouldn't stop, even though we gave it time
|
||||
llwarns << "LLThread::~LLThread() exiting thread before clean exit!" << llendl;
|
||||
// Put a stake in its heart.
|
||||
apr_thread_exit(mAPRThreadp, -1);
|
||||
return;
|
||||
}
|
||||
mAPRThreadp = NULL;
|
||||
}
|
||||
|
||||
delete mRunCondition;
|
||||
mRunCondition = 0;
|
||||
|
||||
if (mIsLocalPool)
|
||||
if (mIsLocalPool && mAPRPoolp)
|
||||
{
|
||||
apr_pool_destroy(mAPRPoolp);
|
||||
mAPRPoolp = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LLThread::start()
|
||||
{
|
||||
apr_thread_create(&mAPRThreadp, NULL, staticRun, (void *)this, mAPRPoolp);
|
||||
llassert(isStopped());
|
||||
|
||||
// Set thread state to running
|
||||
mStatus = RUNNING;
|
||||
|
||||
// We won't bother joining
|
||||
apr_thread_detach(mAPRThreadp);
|
||||
apr_status_t status =
|
||||
apr_thread_create(&mAPRThreadp, NULL, staticRun, (void *)this, mAPRPoolp);
|
||||
|
||||
if(status == APR_SUCCESS)
|
||||
{
|
||||
// We won't bother joining
|
||||
apr_thread_detach(mAPRThreadp);
|
||||
}
|
||||
else
|
||||
{
|
||||
mStatus = STOPPED;
|
||||
llwarns << "failed to start thread " << mName << llendl;
|
||||
ll_apr_warn_status(status);
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
|
|
|||
|
|
@ -0,0 +1,109 @@
|
|||
/**
|
||||
* @file llthread.cpp
|
||||
*
|
||||
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "linden_common.h"
|
||||
#include <apr_pools.h>
|
||||
#include <apr_queue.h>
|
||||
#include "llthreadsafequeue.h"
|
||||
|
||||
|
||||
|
||||
// LLThreadSafeQueueImplementation
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
LLThreadSafeQueueImplementation::LLThreadSafeQueueImplementation(apr_pool_t * pool, unsigned int capacity):
|
||||
mOwnsPool(pool == 0),
|
||||
mPool(pool),
|
||||
mQueue(0)
|
||||
{
|
||||
if(mOwnsPool) {
|
||||
apr_status_t status = apr_pool_create(&mPool, 0);
|
||||
if(status != APR_SUCCESS) throw LLThreadSafeQueueError("failed to allocate pool");
|
||||
} else {
|
||||
; // No op.
|
||||
}
|
||||
|
||||
apr_status_t status = apr_queue_create(&mQueue, capacity, mPool);
|
||||
if(status != APR_SUCCESS) throw LLThreadSafeQueueError("failed to allocate queue");
|
||||
}
|
||||
|
||||
|
||||
LLThreadSafeQueueImplementation::~LLThreadSafeQueueImplementation()
|
||||
{
|
||||
if(mQueue != 0) {
|
||||
if(apr_queue_size(mQueue) != 0) llwarns <<
|
||||
"terminating queue which still contains " << apr_queue_size(mQueue) <<
|
||||
" elements;" << "memory will be leaked" << LL_ENDL;
|
||||
apr_queue_term(mQueue);
|
||||
}
|
||||
if(mOwnsPool && (mPool != 0)) apr_pool_destroy(mPool);
|
||||
}
|
||||
|
||||
|
||||
void LLThreadSafeQueueImplementation::pushFront(void * element)
|
||||
{
|
||||
apr_status_t status = apr_queue_push(mQueue, element);
|
||||
|
||||
if(status == APR_EINTR) {
|
||||
throw LLThreadSafeQueueInterrupt();
|
||||
} else if(status != APR_SUCCESS) {
|
||||
throw LLThreadSafeQueueError("push failed");
|
||||
} else {
|
||||
; // Success.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool LLThreadSafeQueueImplementation::tryPushFront(void * element){
|
||||
return apr_queue_trypush(mQueue, element) == APR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
void * LLThreadSafeQueueImplementation::popBack(void)
|
||||
{
|
||||
void * element;
|
||||
apr_status_t status = apr_queue_pop(mQueue, &element);
|
||||
|
||||
if(status == APR_EINTR) {
|
||||
throw LLThreadSafeQueueInterrupt();
|
||||
} else if(status != APR_SUCCESS) {
|
||||
throw LLThreadSafeQueueError("pop failed");
|
||||
} else {
|
||||
return element;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool LLThreadSafeQueueImplementation::tryPopBack(void *& element)
|
||||
{
|
||||
return apr_queue_trypop(mQueue, &element) == APR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
size_t LLThreadSafeQueueImplementation::size()
|
||||
{
|
||||
return apr_queue_size(mQueue);
|
||||
}
|
||||
|
|
@ -0,0 +1,205 @@
|
|||
/**
|
||||
* @file llthreadsafequeue.h
|
||||
* @brief Base classes for thread, mutex and condition handling.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLTHREADSAFEQUEUE_H
|
||||
#define LL_LLTHREADSAFEQUEUE_H
|
||||
|
||||
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
|
||||
|
||||
struct apr_pool_t; // From apr_pools.h
|
||||
class LLThreadSafeQueueImplementation; // See below.
|
||||
|
||||
|
||||
//
|
||||
// A general queue exception.
|
||||
//
|
||||
class LL_COMMON_API LLThreadSafeQueueError:
|
||||
public std::runtime_error
|
||||
{
|
||||
public:
|
||||
LLThreadSafeQueueError(std::string const & message):
|
||||
std::runtime_error(message)
|
||||
{
|
||||
; // No op.
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// An exception raised when blocking operations are interrupted.
|
||||
//
|
||||
class LL_COMMON_API LLThreadSafeQueueInterrupt:
|
||||
public LLThreadSafeQueueError
|
||||
{
|
||||
public:
|
||||
LLThreadSafeQueueInterrupt(void):
|
||||
LLThreadSafeQueueError("queue operation interrupted")
|
||||
{
|
||||
; // No op.
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct apr_queue_t; // From apr_queue.h
|
||||
|
||||
|
||||
//
|
||||
// Implementation details.
|
||||
//
|
||||
class LL_COMMON_API LLThreadSafeQueueImplementation
|
||||
{
|
||||
public:
|
||||
LLThreadSafeQueueImplementation(apr_pool_t * pool, unsigned int capacity);
|
||||
~LLThreadSafeQueueImplementation();
|
||||
void pushFront(void * element);
|
||||
bool tryPushFront(void * element);
|
||||
void * popBack(void);
|
||||
bool tryPopBack(void *& element);
|
||||
size_t size();
|
||||
|
||||
private:
|
||||
bool mOwnsPool;
|
||||
apr_pool_t * mPool;
|
||||
apr_queue_t * mQueue;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Implements a thread safe FIFO.
|
||||
//
|
||||
template<typename ElementT>
|
||||
class LLThreadSafeQueue
|
||||
{
|
||||
public:
|
||||
typedef ElementT value_type;
|
||||
|
||||
// If the pool is set to NULL one will be allocated and managed by this
|
||||
// queue.
|
||||
LLThreadSafeQueue(apr_pool_t * pool = 0, unsigned int capacity = 1024);
|
||||
|
||||
// Add an element to the front of queue (will block if the queue has
|
||||
// reached capacity).
|
||||
//
|
||||
// This call will raise an interrupt error if the queue is deleted while
|
||||
// the caller is blocked.
|
||||
void pushFront(ElementT const & element);
|
||||
|
||||
// Try to add an element to the front ofqueue without blocking. Returns
|
||||
// true only if the element was actually added.
|
||||
bool tryPushFront(ElementT const & element);
|
||||
|
||||
// Pop the element at the end of the queue (will block if the queue is
|
||||
// empty).
|
||||
//
|
||||
// This call will raise an interrupt error if the queue is deleted while
|
||||
// the caller is blocked.
|
||||
ElementT popBack(void);
|
||||
|
||||
// Pop an element from the end of the queue if there is one available.
|
||||
// Returns true only if an element was popped.
|
||||
bool tryPopBack(ElementT & element);
|
||||
|
||||
// Returns the size of the queue.
|
||||
size_t size();
|
||||
|
||||
private:
|
||||
LLThreadSafeQueueImplementation mImplementation;
|
||||
};
|
||||
|
||||
|
||||
|
||||
// LLThreadSafeQueue
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
template<typename ElementT>
|
||||
LLThreadSafeQueue<ElementT>::LLThreadSafeQueue(apr_pool_t * pool, unsigned int capacity):
|
||||
mImplementation(pool, capacity)
|
||||
{
|
||||
; // No op.
|
||||
}
|
||||
|
||||
|
||||
template<typename ElementT>
|
||||
void LLThreadSafeQueue<ElementT>::pushFront(ElementT const & element)
|
||||
{
|
||||
ElementT * elementCopy = new ElementT(element);
|
||||
try {
|
||||
mImplementation.pushFront(elementCopy);
|
||||
} catch (LLThreadSafeQueueInterrupt) {
|
||||
delete elementCopy;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<typename ElementT>
|
||||
bool LLThreadSafeQueue<ElementT>::tryPushFront(ElementT const & element)
|
||||
{
|
||||
ElementT * elementCopy = new ElementT(element);
|
||||
bool result = mImplementation.tryPushFront(elementCopy);
|
||||
if(!result) delete elementCopy;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
template<typename ElementT>
|
||||
ElementT LLThreadSafeQueue<ElementT>::popBack(void)
|
||||
{
|
||||
ElementT * element = reinterpret_cast<ElementT *> (mImplementation.popBack());
|
||||
ElementT result(*element);
|
||||
delete element;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
template<typename ElementT>
|
||||
bool LLThreadSafeQueue<ElementT>::tryPopBack(ElementT & element)
|
||||
{
|
||||
void * storedElement;
|
||||
bool result = mImplementation.tryPopBack(storedElement);
|
||||
if(result) {
|
||||
ElementT * elementPtr = reinterpret_cast<ElementT *>(storedElement);
|
||||
element = *elementPtr;
|
||||
delete elementPtr;
|
||||
} else {
|
||||
; // No op.
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
template<typename ElementT>
|
||||
size_t LLThreadSafeQueue<ElementT>::size(void)
|
||||
{
|
||||
return mImplementation.size();
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -28,10 +28,14 @@
|
|||
#define LL_LLVERSIONVIEWER_H
|
||||
|
||||
const S32 LL_VERSION_MAJOR = 2;
|
||||
const S32 LL_VERSION_MINOR = 3;
|
||||
const S32 LL_VERSION_MINOR = 5;
|
||||
const S32 LL_VERSION_PATCH = 0;
|
||||
const S32 LL_VERSION_BUILD = 0;
|
||||
|
||||
const char * const LL_CHANNEL = "Second Life Developer";
|
||||
|
||||
#if LL_DARWIN
|
||||
const char * const LL_VERSION_BUNDLE_ID = "com.secondlife.indra.viewer";
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -3,12 +3,13 @@
|
|||
project(llimage)
|
||||
|
||||
include(00-Common)
|
||||
include(LLAddBuildTest)
|
||||
include(LLCommon)
|
||||
include(LLImage)
|
||||
include(LLMath)
|
||||
include(LLVFS)
|
||||
include(ZLIB)
|
||||
include(LLAddBuildTest)
|
||||
include(Tut)
|
||||
|
||||
include_directories(
|
||||
${LLCOMMON_INCLUDE_DIRS}
|
||||
|
|
@ -57,11 +58,18 @@ add_library (llimage ${llimage_SOURCE_FILES})
|
|||
# Sort by high-level to low-level
|
||||
target_link_libraries(llimage
|
||||
llcommon
|
||||
llimagej2coj # *HACK: In theory a noop for KDU builds?
|
||||
${JPEG_LIBRARIES}
|
||||
${PNG_LIBRARIES}
|
||||
${ZLIB_LIBRARIES}
|
||||
)
|
||||
|
||||
# Add tests
|
||||
#ADD_BUILD_TEST(llimageworker llimage)
|
||||
if (LL_TESTS)
|
||||
SET(llimage_TEST_SOURCE_FILES
|
||||
llimageworker.cpp
|
||||
)
|
||||
LL_ADD_PROJECT_UNIT_TESTS(llimage "${llimage_TEST_SOURCE_FILES}")
|
||||
endif (LL_TESTS)
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -52,13 +52,11 @@ LLMutex* LLImage::sMutex = NULL;
|
|||
void LLImage::initClass()
|
||||
{
|
||||
sMutex = new LLMutex(NULL);
|
||||
LLImageJ2C::openDSO();
|
||||
}
|
||||
|
||||
//static
|
||||
void LLImage::cleanupClass()
|
||||
{
|
||||
LLImageJ2C::closeDSO();
|
||||
delete sMutex;
|
||||
sMutex = NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,9 @@
|
|||
|
||||
#include "llimagedimensionsinfo.h"
|
||||
|
||||
// Value is true if one of Libjpeg's functions has encountered an error while working.
|
||||
static bool sJpegErrorEncountered = false;
|
||||
|
||||
bool LLImageDimensionsInfo::load(const std::string& src_filename,U32 codec)
|
||||
{
|
||||
clean();
|
||||
|
|
@ -101,9 +104,17 @@ bool LLImageDimensionsInfo::getImageDimensionsPng()
|
|||
return true;
|
||||
}
|
||||
|
||||
// Called instead of exit() if Libjpeg encounters an error.
|
||||
void on_jpeg_error(j_common_ptr cinfo)
|
||||
{
|
||||
(void) cinfo;
|
||||
sJpegErrorEncountered = true;
|
||||
llwarns << "Libjpeg has encountered an error!" << llendl;
|
||||
}
|
||||
|
||||
bool LLImageDimensionsInfo::getImageDimensionsJpeg()
|
||||
{
|
||||
sJpegErrorEncountered = false;
|
||||
clean();
|
||||
FILE *fp = fopen (mSrcFilename.c_str(), "rb");
|
||||
if (fp == NULL)
|
||||
|
|
@ -115,6 +126,9 @@ bool LLImageDimensionsInfo::getImageDimensionsJpeg()
|
|||
jpeg_error_mgr jerr;
|
||||
jpeg_decompress_struct cinfo;
|
||||
cinfo.err = jpeg_std_error(&jerr);
|
||||
// Call our function instead of exit() if Libjpeg encounters an error.
|
||||
// This is done to avoid crash in this case (STORM-472).
|
||||
cinfo.err->error_exit = on_jpeg_error;
|
||||
|
||||
jpeg_create_decompress (&cinfo);
|
||||
jpeg_stdio_src (&cinfo, fp);
|
||||
|
|
@ -128,6 +142,6 @@ bool LLImageDimensionsInfo::getImageDimensionsJpeg()
|
|||
jpeg_destroy_decompress(&cinfo);
|
||||
fclose(fp);
|
||||
|
||||
return true;
|
||||
return !sJpegErrorEncountered;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,148 +24,32 @@
|
|||
*/
|
||||
#include "linden_common.h"
|
||||
|
||||
#include "apr_pools.h"
|
||||
#include "apr_dso.h"
|
||||
|
||||
#include "lldir.h"
|
||||
#include "llimagej2c.h"
|
||||
#include "llmemtype.h"
|
||||
#include "lltimer.h"
|
||||
#include "llmath.h"
|
||||
|
||||
typedef LLImageJ2CImpl* (*CreateLLImageJ2CFunction)();
|
||||
typedef void (*DestroyLLImageJ2CFunction)(LLImageJ2CImpl*);
|
||||
typedef const char* (*EngineInfoLLImageJ2CFunction)();
|
||||
|
||||
//some "private static" variables so we only attempt to load
|
||||
//dynamic libaries once
|
||||
CreateLLImageJ2CFunction j2cimpl_create_func;
|
||||
DestroyLLImageJ2CFunction j2cimpl_destroy_func;
|
||||
EngineInfoLLImageJ2CFunction j2cimpl_engineinfo_func;
|
||||
apr_pool_t *j2cimpl_dso_memory_pool;
|
||||
apr_dso_handle_t *j2cimpl_dso_handle;
|
||||
|
||||
//Declare the prototype for theses functions here, their functionality
|
||||
//will be implemented in other files which define a derived LLImageJ2CImpl
|
||||
//but only ONE static library which has the implementation for this
|
||||
//function should ever be included
|
||||
// Declare the prototype for theses functions here. Their functionality
|
||||
// will be implemented in other files which define a derived LLImageJ2CImpl
|
||||
// but only ONE static library which has the implementation for these
|
||||
// functions should ever be included.
|
||||
LLImageJ2CImpl* fallbackCreateLLImageJ2CImpl();
|
||||
void fallbackDestroyLLImageJ2CImpl(LLImageJ2CImpl* impl);
|
||||
const char* fallbackEngineInfoLLImageJ2CImpl();
|
||||
|
||||
//static
|
||||
//Loads the required "create", "destroy" and "engineinfo" functions needed
|
||||
void LLImageJ2C::openDSO()
|
||||
{
|
||||
//attempt to load a DSO and get some functions from it
|
||||
std::string dso_name;
|
||||
std::string dso_path;
|
||||
|
||||
bool all_functions_loaded = false;
|
||||
apr_status_t rv;
|
||||
|
||||
#if LL_WINDOWS
|
||||
dso_name = "llkdu.dll";
|
||||
#elif LL_DARWIN
|
||||
dso_name = "libllkdu.dylib";
|
||||
#else
|
||||
dso_name = "libllkdu.so";
|
||||
#endif
|
||||
|
||||
dso_path = gDirUtilp->findFile(dso_name,
|
||||
gDirUtilp->getAppRODataDir(),
|
||||
gDirUtilp->getExecutableDir());
|
||||
|
||||
j2cimpl_dso_handle = NULL;
|
||||
j2cimpl_dso_memory_pool = NULL;
|
||||
|
||||
//attempt to load the shared library
|
||||
apr_pool_create(&j2cimpl_dso_memory_pool, NULL);
|
||||
rv = apr_dso_load(&j2cimpl_dso_handle,
|
||||
dso_path.c_str(),
|
||||
j2cimpl_dso_memory_pool);
|
||||
|
||||
//now, check for success
|
||||
if ( rv == APR_SUCCESS )
|
||||
{
|
||||
//found the dynamic library
|
||||
//now we want to load the functions we're interested in
|
||||
CreateLLImageJ2CFunction create_func = NULL;
|
||||
DestroyLLImageJ2CFunction dest_func = NULL;
|
||||
EngineInfoLLImageJ2CFunction engineinfo_func = NULL;
|
||||
|
||||
rv = apr_dso_sym((apr_dso_handle_sym_t*)&create_func,
|
||||
j2cimpl_dso_handle,
|
||||
"createLLImageJ2CKDU");
|
||||
if ( rv == APR_SUCCESS )
|
||||
{
|
||||
//we've loaded the create function ok
|
||||
//we need to delete via the DSO too
|
||||
//so lets check for a destruction function
|
||||
rv = apr_dso_sym((apr_dso_handle_sym_t*)&dest_func,
|
||||
j2cimpl_dso_handle,
|
||||
"destroyLLImageJ2CKDU");
|
||||
if ( rv == APR_SUCCESS )
|
||||
{
|
||||
//we've loaded the destroy function ok
|
||||
rv = apr_dso_sym((apr_dso_handle_sym_t*)&engineinfo_func,
|
||||
j2cimpl_dso_handle,
|
||||
"engineInfoLLImageJ2CKDU");
|
||||
if ( rv == APR_SUCCESS )
|
||||
{
|
||||
//ok, everything is loaded alright
|
||||
j2cimpl_create_func = create_func;
|
||||
j2cimpl_destroy_func = dest_func;
|
||||
j2cimpl_engineinfo_func = engineinfo_func;
|
||||
all_functions_loaded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !all_functions_loaded )
|
||||
{
|
||||
//something went wrong with the DSO or function loading..
|
||||
//fall back onto our satefy impl creation function
|
||||
|
||||
#if 0
|
||||
// precious verbose debugging, sadly we can't use our
|
||||
// 'llinfos' stream etc. this early in the initialisation seq.
|
||||
char errbuf[256];
|
||||
fprintf(stderr, "failed to load syms from DSO %s (%s)\n",
|
||||
dso_name.c_str(), dso_path.c_str());
|
||||
apr_strerror(rv, errbuf, sizeof(errbuf));
|
||||
fprintf(stderr, "error: %d, %s\n", rv, errbuf);
|
||||
apr_dso_error(j2cimpl_dso_handle, errbuf, sizeof(errbuf));
|
||||
fprintf(stderr, "dso-error: %d, %s\n", rv, errbuf);
|
||||
#endif
|
||||
|
||||
if ( j2cimpl_dso_handle )
|
||||
{
|
||||
apr_dso_unload(j2cimpl_dso_handle);
|
||||
j2cimpl_dso_handle = NULL;
|
||||
}
|
||||
|
||||
if ( j2cimpl_dso_memory_pool )
|
||||
{
|
||||
apr_pool_destroy(j2cimpl_dso_memory_pool);
|
||||
j2cimpl_dso_memory_pool = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
void LLImageJ2C::closeDSO()
|
||||
{
|
||||
if ( j2cimpl_dso_handle ) apr_dso_unload(j2cimpl_dso_handle);
|
||||
if (j2cimpl_dso_memory_pool) apr_pool_destroy(j2cimpl_dso_memory_pool);
|
||||
}
|
||||
// Test data gathering handle
|
||||
LLImageCompressionTester* LLImageJ2C::sTesterp = NULL ;
|
||||
const std::string sTesterName("ImageCompressionTester");
|
||||
|
||||
//static
|
||||
std::string LLImageJ2C::getEngineInfo()
|
||||
{
|
||||
if (!j2cimpl_engineinfo_func)
|
||||
j2cimpl_engineinfo_func = fallbackEngineInfoLLImageJ2CImpl;
|
||||
|
||||
return j2cimpl_engineinfo_func();
|
||||
return fallbackEngineInfoLLImageJ2CImpl();
|
||||
}
|
||||
|
||||
LLImageJ2C::LLImageJ2C() : LLImageFormatted(IMG_CODEC_J2C),
|
||||
|
|
@ -175,47 +59,32 @@ LLImageJ2C::LLImageJ2C() : LLImageFormatted(IMG_CODEC_J2C),
|
|||
mReversible(FALSE),
|
||||
mAreaUsedForDataSizeCalcs(0)
|
||||
{
|
||||
//We assume here that if we wanted to create via
|
||||
//a dynamic library that the approriate open calls were made
|
||||
//before any calls to this constructor.
|
||||
|
||||
//Therefore, a NULL creation function pointer here means
|
||||
//we either did not want to create using functions from the dynamic
|
||||
//library or there were issues loading it, either way
|
||||
//use our fall back
|
||||
if ( !j2cimpl_create_func )
|
||||
{
|
||||
j2cimpl_create_func = fallbackCreateLLImageJ2CImpl;
|
||||
}
|
||||
|
||||
mImpl = j2cimpl_create_func();
|
||||
mImpl = fallbackCreateLLImageJ2CImpl();
|
||||
|
||||
// Clear data size table
|
||||
for( S32 i = 0; i <= MAX_DISCARD_LEVEL; i++)
|
||||
{ // Array size is MAX_DISCARD_LEVEL+1
|
||||
mDataSizes[i] = 0;
|
||||
}
|
||||
|
||||
// If that test log has ben requested but not yet created, create it
|
||||
if (LLMetricPerformanceTesterBasic::isMetricLogRequested(sTesterName) && !LLMetricPerformanceTesterBasic::getTester(sTesterName))
|
||||
{
|
||||
sTesterp = new LLImageCompressionTester() ;
|
||||
if (!sTesterp->isValid())
|
||||
{
|
||||
delete sTesterp;
|
||||
sTesterp = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// virtual
|
||||
LLImageJ2C::~LLImageJ2C()
|
||||
{
|
||||
//We assume here that if we wanted to destroy via
|
||||
//a dynamic library that the approriate open calls were made
|
||||
//before any calls to this destructor.
|
||||
|
||||
//Therefore, a NULL creation function pointer here means
|
||||
//we either did not want to destroy using functions from the dynamic
|
||||
//library or there were issues loading it, either way
|
||||
//use our fall back
|
||||
if ( !j2cimpl_destroy_func )
|
||||
{
|
||||
j2cimpl_destroy_func = fallbackDestroyLLImageJ2CImpl;
|
||||
}
|
||||
|
||||
if ( mImpl )
|
||||
{
|
||||
j2cimpl_destroy_func(mImpl);
|
||||
fallbackDestroyLLImageJ2CImpl(mImpl);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -280,6 +149,7 @@ BOOL LLImageJ2C::decode(LLImageRaw *raw_imagep, F32 decode_time)
|
|||
// Returns TRUE to mean done, whether successful or not.
|
||||
BOOL LLImageJ2C::decodeChannels(LLImageRaw *raw_imagep, F32 decode_time, S32 first_channel, S32 max_channel_count )
|
||||
{
|
||||
LLTimer elapsed;
|
||||
LLMemType mt1(mMemType);
|
||||
|
||||
BOOL res = TRUE;
|
||||
|
|
@ -318,6 +188,21 @@ BOOL LLImageJ2C::decodeChannels(LLImageRaw *raw_imagep, F32 decode_time, S32 fir
|
|||
LLImage::setLastError(mLastError);
|
||||
}
|
||||
|
||||
LLImageCompressionTester* tester = (LLImageCompressionTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName);
|
||||
if (tester)
|
||||
{
|
||||
// Decompression stat gathering
|
||||
// Note that we *do not* take into account the decompression failures data so we might overestimate the time spent processing
|
||||
|
||||
// Always add the decompression time to the stat
|
||||
tester->updateDecompressionStats(elapsed.getElapsedTimeF32()) ;
|
||||
if (res)
|
||||
{
|
||||
// The whole data stream is finally decompressed when res is returned as TRUE
|
||||
tester->updateDecompressionStats(this->getDataSize(), raw_imagep->getDataSize()) ;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
@ -330,6 +215,7 @@ BOOL LLImageJ2C::encode(const LLImageRaw *raw_imagep, F32 encode_time)
|
|||
|
||||
BOOL LLImageJ2C::encode(const LLImageRaw *raw_imagep, const char* comment_text, F32 encode_time)
|
||||
{
|
||||
LLTimer elapsed;
|
||||
LLMemType mt1(mMemType);
|
||||
resetLastError();
|
||||
BOOL res = mImpl->encodeImpl(*this, *raw_imagep, comment_text, encode_time, mReversible);
|
||||
|
|
@ -337,6 +223,22 @@ BOOL LLImageJ2C::encode(const LLImageRaw *raw_imagep, const char* comment_text,
|
|||
{
|
||||
LLImage::setLastError(mLastError);
|
||||
}
|
||||
|
||||
LLImageCompressionTester* tester = (LLImageCompressionTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName);
|
||||
if (tester)
|
||||
{
|
||||
// Compression stat gathering
|
||||
// Note that we *do not* take into account the compression failures cases so we night overestimate the time spent processing
|
||||
|
||||
// Always add the compression time to the stat
|
||||
tester->updateCompressionStats(elapsed.getElapsedTimeF32()) ;
|
||||
if (res)
|
||||
{
|
||||
// The whole data stream is finally compressed when res is returned as TRUE
|
||||
tester->updateCompressionStats(this->getDataSize(), raw_imagep->getDataSize()) ;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
@ -540,3 +442,125 @@ void LLImageJ2C::updateRawDiscardLevel()
|
|||
LLImageJ2CImpl::~LLImageJ2CImpl()
|
||||
{
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------
|
||||
// Start of LLImageCompressionTester
|
||||
//----------------------------------------------------------------------------------------------
|
||||
LLImageCompressionTester::LLImageCompressionTester() : LLMetricPerformanceTesterBasic(sTesterName)
|
||||
{
|
||||
addMetric("Time Decompression (s)");
|
||||
addMetric("Volume In Decompression (kB)");
|
||||
addMetric("Volume Out Decompression (kB)");
|
||||
addMetric("Decompression Ratio (x:1)");
|
||||
addMetric("Perf Decompression (kB/s)");
|
||||
|
||||
addMetric("Time Compression (s)");
|
||||
addMetric("Volume In Compression (kB)");
|
||||
addMetric("Volume Out Compression (kB)");
|
||||
addMetric("Compression Ratio (x:1)");
|
||||
addMetric("Perf Compression (kB/s)");
|
||||
|
||||
mRunBytesInDecompression = 0;
|
||||
mRunBytesInCompression = 0;
|
||||
|
||||
mTotalBytesInDecompression = 0;
|
||||
mTotalBytesOutDecompression = 0;
|
||||
mTotalBytesInCompression = 0;
|
||||
mTotalBytesOutCompression = 0;
|
||||
|
||||
mTotalTimeDecompression = 0.0f;
|
||||
mTotalTimeCompression = 0.0f;
|
||||
}
|
||||
|
||||
LLImageCompressionTester::~LLImageCompressionTester()
|
||||
{
|
||||
LLImageJ2C::sTesterp = NULL;
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLImageCompressionTester::outputTestRecord(LLSD *sd)
|
||||
{
|
||||
std::string currentLabel = getCurrentLabelName();
|
||||
|
||||
F32 decompressionPerf = 0.0f;
|
||||
F32 compressionPerf = 0.0f;
|
||||
F32 decompressionRate = 0.0f;
|
||||
F32 compressionRate = 0.0f;
|
||||
|
||||
F32 totalkBInDecompression = (F32)(mTotalBytesInDecompression) / 1000.0;
|
||||
F32 totalkBOutDecompression = (F32)(mTotalBytesOutDecompression) / 1000.0;
|
||||
F32 totalkBInCompression = (F32)(mTotalBytesInCompression) / 1000.0;
|
||||
F32 totalkBOutCompression = (F32)(mTotalBytesOutCompression) / 1000.0;
|
||||
|
||||
if (!is_approx_zero(mTotalTimeDecompression))
|
||||
{
|
||||
decompressionPerf = totalkBInDecompression / mTotalTimeDecompression;
|
||||
}
|
||||
if (!is_approx_zero(totalkBInDecompression))
|
||||
{
|
||||
decompressionRate = totalkBOutDecompression / totalkBInDecompression;
|
||||
}
|
||||
if (!is_approx_zero(mTotalTimeCompression))
|
||||
{
|
||||
compressionPerf = totalkBInCompression / mTotalTimeCompression;
|
||||
}
|
||||
if (!is_approx_zero(totalkBOutCompression))
|
||||
{
|
||||
compressionRate = totalkBInCompression / totalkBOutCompression;
|
||||
}
|
||||
|
||||
(*sd)[currentLabel]["Time Decompression (s)"] = (LLSD::Real)mTotalTimeDecompression;
|
||||
(*sd)[currentLabel]["Volume In Decompression (kB)"] = (LLSD::Real)totalkBInDecompression;
|
||||
(*sd)[currentLabel]["Volume Out Decompression (kB)"]= (LLSD::Real)totalkBOutDecompression;
|
||||
(*sd)[currentLabel]["Decompression Ratio (x:1)"] = (LLSD::Real)decompressionRate;
|
||||
(*sd)[currentLabel]["Perf Decompression (kB/s)"] = (LLSD::Real)decompressionPerf;
|
||||
|
||||
(*sd)[currentLabel]["Time Compression (s)"] = (LLSD::Real)mTotalTimeCompression;
|
||||
(*sd)[currentLabel]["Volume In Compression (kB)"] = (LLSD::Real)totalkBInCompression;
|
||||
(*sd)[currentLabel]["Volume Out Compression (kB)"] = (LLSD::Real)totalkBOutCompression;
|
||||
(*sd)[currentLabel]["Compression Ratio (x:1)"] = (LLSD::Real)compressionRate;
|
||||
(*sd)[currentLabel]["Perf Compression (kB/s)"] = (LLSD::Real)compressionPerf;
|
||||
}
|
||||
|
||||
void LLImageCompressionTester::updateCompressionStats(const F32 deltaTime)
|
||||
{
|
||||
mTotalTimeCompression += deltaTime;
|
||||
}
|
||||
|
||||
void LLImageCompressionTester::updateCompressionStats(const S32 bytesCompress, const S32 bytesRaw)
|
||||
{
|
||||
mTotalBytesInCompression += bytesRaw;
|
||||
mRunBytesInCompression += bytesRaw;
|
||||
mTotalBytesOutCompression += bytesCompress;
|
||||
if (mRunBytesInCompression > (1000000))
|
||||
{
|
||||
// Output everything
|
||||
outputTestResults();
|
||||
// Reset the compression data of the run
|
||||
mRunBytesInCompression = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void LLImageCompressionTester::updateDecompressionStats(const F32 deltaTime)
|
||||
{
|
||||
mTotalTimeDecompression += deltaTime;
|
||||
}
|
||||
|
||||
void LLImageCompressionTester::updateDecompressionStats(const S32 bytesIn, const S32 bytesOut)
|
||||
{
|
||||
mTotalBytesInDecompression += bytesIn;
|
||||
mRunBytesInDecompression += bytesIn;
|
||||
mTotalBytesOutDecompression += bytesOut;
|
||||
if (mRunBytesInDecompression > (1000000))
|
||||
{
|
||||
// Output everything
|
||||
outputTestResults();
|
||||
// Reset the decompression data of the run
|
||||
mRunBytesInDecompression = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------
|
||||
// End of LLTexturePipelineTester
|
||||
//----------------------------------------------------------------------------------------------
|
||||
|
||||
|
|
|
|||
|
|
@ -29,8 +29,11 @@
|
|||
|
||||
#include "llimage.h"
|
||||
#include "llassettype.h"
|
||||
#include "llmetricperformancetester.h"
|
||||
|
||||
class LLImageJ2CImpl;
|
||||
class LLImageCompressionTester ;
|
||||
|
||||
class LLImageJ2C : public LLImageFormatted
|
||||
{
|
||||
protected:
|
||||
|
|
@ -69,14 +72,13 @@ public:
|
|||
static S32 calcHeaderSizeJ2C();
|
||||
static S32 calcDataSizeJ2C(S32 w, S32 h, S32 comp, S32 discard_level, F32 rate = 0.f);
|
||||
|
||||
static void openDSO();
|
||||
static void closeDSO();
|
||||
static std::string getEngineInfo();
|
||||
|
||||
|
||||
protected:
|
||||
friend class LLImageJ2CImpl;
|
||||
friend class LLImageJ2COJ;
|
||||
friend class LLImageJ2CKDU;
|
||||
friend class LLImageCompressionTester;
|
||||
void decodeFailed();
|
||||
void updateRawDiscardLevel();
|
||||
|
||||
|
|
@ -90,6 +92,9 @@ protected:
|
|||
BOOL mReversible;
|
||||
LLImageJ2CImpl *mImpl;
|
||||
std::string mLastError;
|
||||
|
||||
// Image compression/decompression tester
|
||||
static LLImageCompressionTester* sTesterp;
|
||||
};
|
||||
|
||||
// Derive from this class to implement JPEG2000 decoding
|
||||
|
|
@ -118,4 +123,40 @@ protected:
|
|||
|
||||
#define LINDEN_J2C_COMMENT_PREFIX "LL_"
|
||||
|
||||
//
|
||||
// This class is used for performance data gathering only.
|
||||
// Tracks the image compression / decompression data,
|
||||
// records and outputs them to the log file.
|
||||
//
|
||||
class LLImageCompressionTester : public LLMetricPerformanceTesterBasic
|
||||
{
|
||||
public:
|
||||
LLImageCompressionTester();
|
||||
~LLImageCompressionTester();
|
||||
|
||||
void updateDecompressionStats(const F32 deltaTime) ;
|
||||
void updateDecompressionStats(const S32 bytesIn, const S32 bytesOut) ;
|
||||
void updateCompressionStats(const F32 deltaTime) ;
|
||||
void updateCompressionStats(const S32 bytesIn, const S32 bytesOut) ;
|
||||
|
||||
protected:
|
||||
/*virtual*/ void outputTestRecord(LLSD* sd);
|
||||
|
||||
private:
|
||||
//
|
||||
// Data size
|
||||
//
|
||||
U32 mTotalBytesInDecompression; // Total bytes fed to decompressor
|
||||
U32 mTotalBytesOutDecompression; // Total bytes produced by decompressor
|
||||
U32 mTotalBytesInCompression; // Total bytes fed to compressor
|
||||
U32 mTotalBytesOutCompression; // Total bytes produced by compressor
|
||||
U32 mRunBytesInDecompression; // Bytes fed to decompressor in this run
|
||||
U32 mRunBytesInCompression; // Bytes fed to compressor in this run
|
||||
//
|
||||
// Time
|
||||
//
|
||||
F32 mTotalTimeDecompression; // Total time spent in computing decompression
|
||||
F32 mTotalTimeCompression; // Total time spent in computing compression
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -26,10 +26,8 @@
|
|||
*/
|
||||
|
||||
// Precompiled header: almost always required for newview cpp files
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
// Class to test
|
||||
#include "linden_common.h"
|
||||
// Class to test
|
||||
#include "../llimageworker.h"
|
||||
// For timer class
|
||||
#include "../llcommon/lltimer.h"
|
||||
|
|
@ -44,7 +42,17 @@
|
|||
// * Do not make any assumption as to how those classes or methods work (i.e. don't copy/paste code)
|
||||
// * A simulator for a class can be implemented here. Please comment and document thoroughly.
|
||||
|
||||
LLImageBase::LLImageBase() {}
|
||||
LLImageBase::LLImageBase()
|
||||
: mData(NULL),
|
||||
mDataSize(0),
|
||||
mWidth(0),
|
||||
mHeight(0),
|
||||
mComponents(0),
|
||||
mBadBufferAllocation(false),
|
||||
mAllowOverSize(false),
|
||||
mMemType(LLMemType::MTYPE_IMAGEBASE)
|
||||
{
|
||||
}
|
||||
LLImageBase::~LLImageBase() {}
|
||||
void LLImageBase::dump() { }
|
||||
void LLImageBase::sanityCheck() { }
|
||||
|
|
|
|||
|
|
@ -90,6 +90,12 @@ void info_callback(const char* msg, void*)
|
|||
lldebugs << "LLImageJ2COJ: " << chomp(msg) << llendl;
|
||||
}
|
||||
|
||||
// Divide a by 2 to the power of b and round upwards
|
||||
int ceildivpow2(int a, int b)
|
||||
{
|
||||
return (a + (1 << b) - 1) >> b;
|
||||
}
|
||||
|
||||
|
||||
LLImageJ2COJ::LLImageJ2COJ()
|
||||
: LLImageJ2CImpl()
|
||||
|
|
|
|||
|
|
@ -34,17 +34,11 @@ class LLImageJ2COJ : public LLImageJ2CImpl
|
|||
public:
|
||||
LLImageJ2COJ();
|
||||
virtual ~LLImageJ2COJ();
|
||||
|
||||
protected:
|
||||
/*virtual*/ BOOL getMetadata(LLImageJ2C &base);
|
||||
/*virtual*/ BOOL decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count);
|
||||
/*virtual*/ BOOL encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time=0.0,
|
||||
BOOL reversible = FALSE);
|
||||
int ceildivpow2(int a, int b)
|
||||
{
|
||||
// Divide a by b to the power of 2 and round upwards.
|
||||
return (a + (1 << b) - 1) >> b;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -61,8 +61,6 @@ static const std::string INV_FOLDER_ID_LABEL_WS("category_id");
|
|||
///----------------------------------------------------------------------------
|
||||
/// Local function declarations, constants, enums, and typedefs
|
||||
///----------------------------------------------------------------------------
|
||||
const U8 TASK_INVENTORY_ITEM_KEY = 0;
|
||||
const U8 TASK_INVENTORY_ASSET_KEY = 1;
|
||||
|
||||
const LLUUID MAGIC_ID("3c115e51-04f4-523c-9fa6-98aff1034730");
|
||||
|
||||
|
|
|
|||
|
|
@ -199,7 +199,7 @@ bool LLNotecard::importStream(std::istream& str)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if(text_len > mMaxText)
|
||||
if(text_len > mMaxText || text_len < 0)
|
||||
{
|
||||
llwarns << "Invalid Linden text length: " << text_len << llendl;
|
||||
return FALSE;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,55 @@
|
|||
# -*- cmake -*-
|
||||
|
||||
project(llkdu)
|
||||
|
||||
# Visual Studio 2005 has a dumb bug that causes it to fail compilation
|
||||
# of KDU if building with both optimisation and /WS (treat warnings as
|
||||
# errors), even when the specific warnings that make it croak are
|
||||
# disabled.
|
||||
|
||||
#set(VS_DISABLE_FATAL_WARNINGS ON)
|
||||
|
||||
include(00-Common)
|
||||
include(LLCommon)
|
||||
include(LLImage)
|
||||
include(LLKDU)
|
||||
include(LLMath)
|
||||
|
||||
include_directories(
|
||||
${LLCOMMON_INCLUDE_DIRS}
|
||||
${LLIMAGE_INCLUDE_DIRS}
|
||||
${KDU_INCLUDE_DIR}
|
||||
${LLMATH_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
set(llkdu_SOURCE_FILES
|
||||
llimagej2ckdu.cpp
|
||||
llkdumem.cpp
|
||||
)
|
||||
|
||||
set(llkdu_HEADER_FILES
|
||||
CMakeLists.txt
|
||||
|
||||
llimagej2ckdu.h
|
||||
llkdumem.h
|
||||
)
|
||||
|
||||
set_source_files_properties(${llkdu_HEADER_FILES}
|
||||
PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
|
||||
list(APPEND llkdu_SOURCE_FILES ${llkdu_HEADER_FILES})
|
||||
|
||||
if (USE_KDU)
|
||||
add_library (${LLKDU_LIBRARIES} ${llkdu_SOURCE_FILES})
|
||||
|
||||
# Add tests
|
||||
if (LL_TESTS)
|
||||
include(LLAddBuildTest)
|
||||
include(Tut)
|
||||
SET(llkdu_TEST_SOURCE_FILES
|
||||
llimagej2ckdu.cpp
|
||||
)
|
||||
LL_ADD_PROJECT_UNIT_TESTS(llkdu "${llkdu_TEST_SOURCE_FILES}")
|
||||
endif (LL_TESTS)
|
||||
|
||||
endif (USE_KDU)
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,90 @@
|
|||
/**
|
||||
* @file llimagej2ckdu.h
|
||||
* @brief This is an implementation of JPEG2000 encode/decode using Kakadu
|
||||
*
|
||||
* $LicenseInfo:firstyear=2010&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLIMAGEJ2CKDU_H
|
||||
#define LL_LLIMAGEJ2CKDU_H
|
||||
|
||||
#include "llimagej2c.h"
|
||||
|
||||
//
|
||||
// KDU core header files
|
||||
//
|
||||
#include "kdu_elementary.h"
|
||||
#include "kdu_messaging.h"
|
||||
#include "kdu_params.h"
|
||||
#include "kdu_compressed.h"
|
||||
#include "kdu_sample_processing.h"
|
||||
|
||||
class LLKDUDecodeState;
|
||||
class LLKDUMemSource;
|
||||
|
||||
class LLImageJ2CKDU : public LLImageJ2CImpl
|
||||
{
|
||||
public:
|
||||
enum ECodeStreamMode
|
||||
{
|
||||
MODE_FAST = 0,
|
||||
MODE_RESILIENT = 1,
|
||||
MODE_FUSSY = 2
|
||||
};
|
||||
LLImageJ2CKDU();
|
||||
virtual ~LLImageJ2CKDU();
|
||||
|
||||
protected:
|
||||
/*virtual*/ BOOL getMetadata(LLImageJ2C &base);
|
||||
/*virtual*/ BOOL decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count);
|
||||
/*virtual*/ BOOL encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time=0.0,
|
||||
BOOL reversible=FALSE);
|
||||
|
||||
private:
|
||||
void setupCodeStream(LLImageJ2C &base, BOOL keep_codestream, ECodeStreamMode mode);
|
||||
void cleanupCodeStream();
|
||||
BOOL initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, ECodeStreamMode mode, S32 first_channel, S32 max_channel_count );
|
||||
|
||||
// Encode variable
|
||||
LLKDUMemSource *mInputp;
|
||||
kdu_codestream *mCodeStreamp;
|
||||
kdu_coords *mTPosp; // tile position
|
||||
kdu_dims *mTileIndicesp;
|
||||
|
||||
// Temporary variables for in-progress decodes...
|
||||
LLImageRaw *mRawImagep;
|
||||
LLKDUDecodeState *mDecodeState;
|
||||
};
|
||||
|
||||
#if LL_WINDOWS
|
||||
# define LLSYMEXPORT __declspec(dllexport)
|
||||
#elif LL_LINUX
|
||||
# define LLSYMEXPORT __attribute__ ((visibility("default")))
|
||||
#else
|
||||
# define LLSYMEXPORT
|
||||
#endif
|
||||
|
||||
extern "C" LLSYMEXPORT const char* engineInfoLLImageJ2CKDU();
|
||||
extern "C" LLSYMEXPORT LLImageJ2CKDU* createLLImageJ2CKDU();
|
||||
extern "C" LLSYMEXPORT void destroyLLImageJ2CKDU(LLImageJ2CKDU* kdu);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,196 @@
|
|||
/**
|
||||
* @file llkdumem.cpp
|
||||
* @brief Helper class for kdu memory management
|
||||
*
|
||||
* $LicenseInfo:firstyear=2010&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "linden_common.h"
|
||||
#include "llkdumem.h"
|
||||
#include "llerror.h"
|
||||
|
||||
#if defined(LL_WINDOWS)
|
||||
# pragma warning(disable: 4702) // unreachable code
|
||||
#endif
|
||||
|
||||
LLKDUMemIn::LLKDUMemIn(const U8 *data,
|
||||
const U32 size,
|
||||
const U16 width,
|
||||
const U16 height,
|
||||
const U8 in_num_components,
|
||||
siz_params *siz)
|
||||
{
|
||||
U8 n;
|
||||
|
||||
first_comp_idx = 0;
|
||||
rows = height;
|
||||
cols = width;
|
||||
num_components = in_num_components;
|
||||
alignment_bytes = 0;
|
||||
|
||||
for (n=0; n<3; ++n)
|
||||
{
|
||||
precision[n] = 0;
|
||||
}
|
||||
|
||||
for (n=0; n < num_components; ++n)
|
||||
{
|
||||
siz->set(Sdims,n,0,rows);
|
||||
siz->set(Sdims,n,1,cols);
|
||||
siz->set(Ssigned,n,0,false);
|
||||
siz->set(Sprecision,n,0,8);
|
||||
}
|
||||
incomplete_lines = NULL;
|
||||
free_lines = NULL;
|
||||
num_unread_rows = rows;
|
||||
|
||||
mData = data;
|
||||
mDataSize = size;
|
||||
mCurPos = 0;
|
||||
}
|
||||
|
||||
LLKDUMemIn::~LLKDUMemIn()
|
||||
{
|
||||
if ((num_unread_rows > 0) || (incomplete_lines != NULL))
|
||||
{
|
||||
kdu_warning w;
|
||||
w << "Not all rows of image components "
|
||||
<< first_comp_idx << " through "
|
||||
<< first_comp_idx+num_components-1
|
||||
<< " were consumed!";
|
||||
}
|
||||
image_line_buf *tmp;
|
||||
while ((tmp=incomplete_lines) != NULL)
|
||||
{
|
||||
incomplete_lines = tmp->next;
|
||||
delete tmp;
|
||||
}
|
||||
while ((tmp=free_lines) != NULL)
|
||||
{
|
||||
free_lines = tmp->next;
|
||||
delete tmp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool LLKDUMemIn::get(int comp_idx, kdu_line_buf &line, int x_tnum)
|
||||
{
|
||||
int idx = comp_idx - this->first_comp_idx;
|
||||
assert((idx >= 0) && (idx < num_components));
|
||||
x_tnum = x_tnum*num_components+idx;
|
||||
image_line_buf *scan, *prev=NULL;
|
||||
for (scan=incomplete_lines; scan != NULL; prev=scan, scan=scan->next)
|
||||
{
|
||||
assert(scan->next_x_tnum >= x_tnum);
|
||||
if (scan->next_x_tnum == x_tnum)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (scan == NULL)
|
||||
{ // Need to read a new image line.
|
||||
assert(x_tnum == 0); // Must consume in very specific order.
|
||||
if (num_unread_rows == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if ((scan = free_lines) == NULL)
|
||||
{
|
||||
scan = new image_line_buf(cols+3,num_components);
|
||||
}
|
||||
free_lines = scan->next;
|
||||
if (prev == NULL)
|
||||
{
|
||||
incomplete_lines = scan;
|
||||
}
|
||||
else
|
||||
{
|
||||
prev->next = scan;
|
||||
}
|
||||
|
||||
// Copy from image buffer into scan.
|
||||
memcpy(scan->buf, mData+mCurPos, cols*num_components);
|
||||
mCurPos += cols*num_components;
|
||||
|
||||
num_unread_rows--;
|
||||
scan->accessed_samples = 0;
|
||||
scan->next_x_tnum = 0;
|
||||
}
|
||||
|
||||
assert((cols-scan->accessed_samples) >= line.get_width());
|
||||
|
||||
int comp_offset = idx;
|
||||
kdu_byte *sp = scan->buf+num_components*scan->accessed_samples + comp_offset;
|
||||
int n=line.get_width();
|
||||
|
||||
if (line.get_buf32() != NULL)
|
||||
{
|
||||
kdu_sample32 *dp = line.get_buf32();
|
||||
if (line.is_absolute())
|
||||
{ // 32-bit absolute integers
|
||||
for (; n > 0; n--, sp+=num_components, dp++)
|
||||
{
|
||||
dp->ival = ((kdu_int32)(*sp)) - 128;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // true 32-bit floats
|
||||
for (; n > 0; n--, sp+=num_components, dp++)
|
||||
{
|
||||
dp->fval = (((float)(*sp)) / 256.0F) - 0.5F;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
kdu_sample16 *dp = line.get_buf16();
|
||||
if (line.is_absolute())
|
||||
{ // 16-bit absolute integers
|
||||
for (; n > 0; n--, sp+=num_components, dp++)
|
||||
{
|
||||
dp->ival = ((kdu_int16)(*sp)) - 128;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // 16-bit normalized representation.
|
||||
for (; n > 0; n--, sp+=num_components, dp++)
|
||||
{
|
||||
dp->ival = (((kdu_int16)(*sp)) - 128) << (KDU_FIX_POINT-8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
scan->next_x_tnum++;
|
||||
if (idx == (num_components-1))
|
||||
{
|
||||
scan->accessed_samples += line.get_width();
|
||||
}
|
||||
if (scan->accessed_samples == cols)
|
||||
{ // Send empty line to free list.
|
||||
assert(scan == incomplete_lines);
|
||||
incomplete_lines = scan->next;
|
||||
scan->next = free_lines;
|
||||
free_lines = scan;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -0,0 +1,145 @@
|
|||
/**
|
||||
* @file llkdumem.h
|
||||
* @brief Helper class for kdu memory management
|
||||
*
|
||||
* $LicenseInfo:firstyear=2010&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLKDUMEM_H
|
||||
#define LL_LLKDUMEM_H
|
||||
|
||||
// Support classes for reading and writing from memory buffers in KDU
|
||||
#include "kdu_image.h"
|
||||
#include "kdu_elementary.h"
|
||||
#include "kdu_messaging.h"
|
||||
#include "kdu_params.h"
|
||||
#include "kdu_compressed.h"
|
||||
#include "kdu_sample_processing.h"
|
||||
#include "image_local.h"
|
||||
#include "stdtypes.h"
|
||||
|
||||
class LLKDUMemSource: public kdu_compressed_source
|
||||
{
|
||||
public: // Member functions
|
||||
LLKDUMemSource(U8 *input_buffer, U32 size)
|
||||
{
|
||||
mData = input_buffer;
|
||||
mSize = size;
|
||||
mCurPos = 0;
|
||||
}
|
||||
|
||||
~LLKDUMemSource()
|
||||
{
|
||||
}
|
||||
|
||||
int read(kdu_byte *buf, int num_bytes)
|
||||
{
|
||||
U32 num_out;
|
||||
num_out = num_bytes;
|
||||
|
||||
if ((mSize - mCurPos) < (U32)num_bytes)
|
||||
{
|
||||
num_out = mSize -mCurPos;
|
||||
}
|
||||
memcpy(buf, mData + mCurPos, num_out);
|
||||
mCurPos += num_out;
|
||||
return num_out;
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
mCurPos = 0;
|
||||
}
|
||||
|
||||
private: // Data
|
||||
U8 *mData;
|
||||
U32 mSize;
|
||||
U32 mCurPos;
|
||||
};
|
||||
|
||||
class LLKDUMemTarget: public kdu_compressed_target
|
||||
{
|
||||
public: // Member functions
|
||||
LLKDUMemTarget(U8 *output_buffer, U32 &output_size, const U32 buffer_size)
|
||||
{
|
||||
mData = output_buffer;
|
||||
mSize = buffer_size;
|
||||
mCurPos = 0;
|
||||
mOutputSize = &output_size;
|
||||
}
|
||||
|
||||
~LLKDUMemTarget()
|
||||
{
|
||||
}
|
||||
|
||||
bool write(const kdu_byte *buf, int num_bytes)
|
||||
{
|
||||
U32 num_out;
|
||||
num_out = num_bytes;
|
||||
|
||||
if ((mSize - mCurPos) < (U32)num_bytes)
|
||||
{
|
||||
num_out = mSize - mCurPos;
|
||||
memcpy(mData + mCurPos, buf, num_out);
|
||||
return false;
|
||||
}
|
||||
memcpy(mData + mCurPos, buf, num_out);
|
||||
mCurPos += num_out;
|
||||
*mOutputSize = mCurPos;
|
||||
return true;
|
||||
}
|
||||
|
||||
private: // Data
|
||||
U8 *mData;
|
||||
U32 mSize;
|
||||
U32 mCurPos;
|
||||
U32 *mOutputSize;
|
||||
};
|
||||
|
||||
class LLKDUMemIn : public kdu_image_in_base
|
||||
{
|
||||
public: // Member functions
|
||||
LLKDUMemIn(const U8 *data,
|
||||
const U32 size,
|
||||
const U16 rows,
|
||||
const U16 cols,
|
||||
U8 in_num_components,
|
||||
siz_params *siz);
|
||||
~LLKDUMemIn();
|
||||
|
||||
bool get(int comp_idx, kdu_line_buf &line, int x_tnum);
|
||||
|
||||
private: // Data
|
||||
const U8 *mData;
|
||||
int first_comp_idx;
|
||||
int num_components;
|
||||
int rows, cols;
|
||||
int alignment_bytes; // Number of 0's at end of each line.
|
||||
int precision[3];
|
||||
image_line_buf *incomplete_lines; // Each "sample" represents a full pixel
|
||||
image_line_buf *free_lines;
|
||||
int num_unread_rows;
|
||||
|
||||
U32 mCurPos;
|
||||
U32 mDataSize;
|
||||
};
|
||||
#endif
|
||||
|
|
@ -0,0 +1,248 @@
|
|||
/**
|
||||
* @file llimagej2ckdu_test.cpp
|
||||
* @author Merov Linden
|
||||
* @date 2010-12-17
|
||||
*
|
||||
* $LicenseInfo:firstyear=2006&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "linden_common.h"
|
||||
// Class to test
|
||||
#include "../llimagej2ckdu.h"
|
||||
#include "../llkdumem.h"
|
||||
// Tut header
|
||||
#include "../test/lltut.h"
|
||||
|
||||
// -------------------------------------------------------------------------------------------
|
||||
// Stubbing: Declarations required to link and run the class being tested
|
||||
// Notes:
|
||||
// * Add here stubbed implementation of the few classes and methods used in the class to be tested
|
||||
// * Add as little as possible (let the link errors guide you)
|
||||
// * Do not make any assumption as to how those classes or methods work (i.e. don't copy/paste code)
|
||||
// * A simulator for a class can be implemented here. Please comment and document thoroughly.
|
||||
|
||||
// End Stubbing
|
||||
// -------------------------------------------------------------------------------------------
|
||||
// Stubb the LL Image Classes
|
||||
LLImageRaw::LLImageRaw() { }
|
||||
LLImageRaw::~LLImageRaw() { }
|
||||
U8* LLImageRaw::allocateData(S32 ) { return NULL; }
|
||||
void LLImageRaw::deleteData() { }
|
||||
U8* LLImageRaw::reallocateData(S32 ) { return NULL; }
|
||||
BOOL LLImageRaw::resize(U16, U16, S8) { return TRUE; } // this method always returns TRUE...
|
||||
|
||||
LLImageBase::LLImageBase()
|
||||
: mData(NULL),
|
||||
mDataSize(0),
|
||||
mWidth(0),
|
||||
mHeight(0),
|
||||
mComponents(0),
|
||||
mBadBufferAllocation(false),
|
||||
mAllowOverSize(false),
|
||||
mMemType(LLMemType::MTYPE_IMAGEBASE)
|
||||
{ }
|
||||
LLImageBase::~LLImageBase() { }
|
||||
U8* LLImageBase::allocateData(S32 ) { return NULL; }
|
||||
void LLImageBase::deleteData() { }
|
||||
void LLImageBase::dump() { }
|
||||
const U8* LLImageBase::getData() const { return NULL; }
|
||||
U8* LLImageBase::getData() { return NULL; }
|
||||
U8* LLImageBase::reallocateData(S32 ) { return NULL; }
|
||||
void LLImageBase::sanityCheck() { }
|
||||
void LLImageBase::setSize(S32 , S32 , S32 ) { }
|
||||
|
||||
LLImageJ2CImpl::~LLImageJ2CImpl() { }
|
||||
|
||||
LLImageFormatted::LLImageFormatted(S8 ) { }
|
||||
LLImageFormatted::~LLImageFormatted() { }
|
||||
U8* LLImageFormatted::allocateData(S32 ) { return NULL; }
|
||||
S32 LLImageFormatted::calcDataSize(S32 ) { return 0; }
|
||||
S32 LLImageFormatted::calcDiscardLevelBytes(S32 ) { return 0; }
|
||||
BOOL LLImageFormatted::decodeChannels(LLImageRaw*, F32, S32, S32) { return FALSE; }
|
||||
BOOL LLImageFormatted::copyData(U8 *, S32) { return TRUE; } // this method always returns TRUE...
|
||||
void LLImageFormatted::deleteData() { }
|
||||
void LLImageFormatted::dump() { }
|
||||
U8* LLImageFormatted::reallocateData(S32 ) { return NULL; }
|
||||
void LLImageFormatted::resetLastError() { }
|
||||
void LLImageFormatted::sanityCheck() { }
|
||||
void LLImageFormatted::setLastError(const std::string& , const std::string& ) { }
|
||||
|
||||
LLImageJ2C::LLImageJ2C() : LLImageFormatted(IMG_CODEC_J2C) { }
|
||||
LLImageJ2C::~LLImageJ2C() { }
|
||||
S32 LLImageJ2C::calcDataSize(S32 ) { return 0; }
|
||||
S32 LLImageJ2C::calcDiscardLevelBytes(S32 ) { return 0; }
|
||||
S32 LLImageJ2C::calcHeaderSize() { return 0; }
|
||||
BOOL LLImageJ2C::decode(LLImageRaw*, F32) { return FALSE; }
|
||||
BOOL LLImageJ2C::decodeChannels(LLImageRaw*, F32, S32, S32 ) { return FALSE; }
|
||||
void LLImageJ2C::decodeFailed() { }
|
||||
BOOL LLImageJ2C::encode(const LLImageRaw*, F32) { return FALSE; }
|
||||
S8 LLImageJ2C::getRawDiscardLevel() { return 0; }
|
||||
void LLImageJ2C::resetLastError() { }
|
||||
void LLImageJ2C::setLastError(const std::string&, const std::string&) { }
|
||||
BOOL LLImageJ2C::updateData() { return FALSE; }
|
||||
void LLImageJ2C::updateRawDiscardLevel() { }
|
||||
|
||||
LLKDUMemIn::LLKDUMemIn(const U8*, const U32, const U16, const U16, const U8, siz_params*) { }
|
||||
LLKDUMemIn::~LLKDUMemIn() { }
|
||||
bool LLKDUMemIn::get(int, kdu_line_buf&, int) { return false; }
|
||||
|
||||
// Stub Kakadu Library calls
|
||||
kdu_tile_comp kdu_tile::access_component(int ) { kdu_tile_comp a; return a; }
|
||||
void kdu_tile::close(kdu_thread_env* ) { }
|
||||
int kdu_tile::get_num_components() { return 0; }
|
||||
bool kdu_tile::get_ycc() { return false; }
|
||||
void kdu_tile::set_components_of_interest(int , const int* ) { }
|
||||
kdu_resolution kdu_tile_comp::access_resolution() { kdu_resolution a; return a; }
|
||||
int kdu_tile_comp::get_bit_depth(bool ) { return 8; }
|
||||
bool kdu_tile_comp::get_reversible() { return false; }
|
||||
kdu_subband kdu_resolution::access_subband(int ) { kdu_subband a; return a; }
|
||||
void kdu_resolution::get_dims(kdu_dims& ) { }
|
||||
int kdu_resolution::which() { return 0; }
|
||||
kdu_decoder::kdu_decoder(kdu_subband , kdu_sample_allocator*, bool , float, int, kdu_thread_env*, kdu_thread_queue*) { }
|
||||
kdu_synthesis::kdu_synthesis(kdu_resolution, kdu_sample_allocator*, bool, float, kdu_thread_env*, kdu_thread_queue*) { }
|
||||
kdu_params::kdu_params(const char*, bool, bool, bool, bool, bool) { }
|
||||
kdu_params::~kdu_params() { }
|
||||
void kdu_params::set(const char* , int , int , bool ) { }
|
||||
void kdu_params::set(const char* , int , int , int ) { }
|
||||
void kdu_params::finalize_all(bool ) { }
|
||||
void kdu_params::copy_from(kdu_params*, int, int, int, int, int, bool, bool, bool) { }
|
||||
bool kdu_params::parse_string(const char*) { return false; }
|
||||
bool kdu_params::get(const char*, int, int, bool&, bool, bool, bool) { return false; }
|
||||
bool kdu_params::get(const char*, int, int, float&, bool, bool, bool) { return false; }
|
||||
bool kdu_params::get(const char*, int, int, int&, bool, bool, bool) { return false; }
|
||||
kdu_params* kdu_params::access_relation(int, int, int, bool) { return NULL; }
|
||||
kdu_params* kdu_params::access_cluster(const char*) { return NULL; }
|
||||
void kdu_codestream::set_fast() { }
|
||||
void kdu_codestream::set_fussy() { }
|
||||
void kdu_codestream::get_dims(int, kdu_dims&, bool ) { }
|
||||
void kdu_codestream::change_appearance(bool, bool, bool) { }
|
||||
void kdu_codestream::get_tile_dims(kdu_coords, int, kdu_dims&, bool ) { }
|
||||
void kdu_codestream::destroy() { }
|
||||
void kdu_codestream::collect_timing_stats(int ) { }
|
||||
void kdu_codestream::set_max_bytes(kdu_long, bool, bool ) { }
|
||||
void kdu_codestream::get_valid_tiles(kdu_dims& ) { }
|
||||
void kdu_codestream::create(siz_params*, kdu_compressed_target*, kdu_dims*, int, kdu_long ) { }
|
||||
void kdu_codestream::create(kdu_compressed_source*, kdu_thread_env*) { }
|
||||
void kdu_codestream::apply_input_restrictions( int, int, int, int, kdu_dims*, kdu_component_access_mode ) { }
|
||||
void kdu_codestream::get_subsampling(int , kdu_coords&, bool ) { }
|
||||
void kdu_codestream::flush(kdu_long *, int , kdu_uint16 *, bool, bool, double, kdu_thread_env*) { }
|
||||
void kdu_codestream::set_resilient(bool ) { }
|
||||
int kdu_codestream::get_num_components(bool ) { return 0; }
|
||||
siz_params* kdu_codestream::access_siz() { return NULL; }
|
||||
kdu_tile kdu_codestream::open_tile(kdu_coords , kdu_thread_env* ) { kdu_tile a; return a; }
|
||||
kdu_codestream_comment kdu_codestream::add_comment() { kdu_codestream_comment a; return a; }
|
||||
bool kdu_codestream_comment::put_text(const char*) { return false; }
|
||||
void kdu_customize_warnings(kdu_message*) { }
|
||||
void kdu_customize_errors(kdu_message*) { }
|
||||
void kdu_convert_ycc_to_rgb(kdu_line_buf&, kdu_line_buf&, kdu_line_buf&, int) { }
|
||||
kdu_long kdu_multi_analysis::create(kdu_codestream, kdu_tile, bool, kdu_roi_image*, bool, int, kdu_thread_env*, kdu_thread_queue*, bool ) { kdu_long a = 0; return a; }
|
||||
siz_params::siz_params() : kdu_params(NULL, false, false, false, false, false) { }
|
||||
void siz_params::finalize(bool ) { }
|
||||
void siz_params::copy_with_xforms(kdu_params*, int, int, bool, bool, bool) { }
|
||||
int siz_params::write_marker_segment(kdu_output*, kdu_params*, int) { return 0; }
|
||||
bool siz_params::check_marker_segment(kdu_uint16, int, kdu_byte a[], int&) { return false; }
|
||||
bool siz_params::read_marker_segment(kdu_uint16, int, kdu_byte a[], int) { return false; }
|
||||
|
||||
// -------------------------------------------------------------------------------------------
|
||||
// TUT
|
||||
// -------------------------------------------------------------------------------------------
|
||||
|
||||
namespace tut
|
||||
{
|
||||
// Test wrapper declarations
|
||||
struct llimagej2ckdu_test
|
||||
{
|
||||
// Derived test class
|
||||
class LLTestImageJ2CKDU : public LLImageJ2CKDU
|
||||
{
|
||||
public:
|
||||
// Provides public access to some protected methods for testing
|
||||
BOOL callGetMetadata(LLImageJ2C &base) { return getMetadata(base); }
|
||||
BOOL callDecodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count)
|
||||
{
|
||||
return decodeImpl(base, raw_image, decode_time, first_channel, max_channel_count);
|
||||
}
|
||||
BOOL callEncodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text)
|
||||
{
|
||||
return encodeImpl(base, raw_image, comment_text);
|
||||
}
|
||||
};
|
||||
// Instance to be tested
|
||||
LLTestImageJ2CKDU* mImage;
|
||||
|
||||
// Constructor and destructor of the test wrapper
|
||||
llimagej2ckdu_test()
|
||||
{
|
||||
mImage = new LLTestImageJ2CKDU;
|
||||
}
|
||||
~llimagej2ckdu_test()
|
||||
{
|
||||
delete mImage;
|
||||
}
|
||||
};
|
||||
|
||||
// Tut templating thingamagic: test group, object and test instance
|
||||
typedef test_group<llimagej2ckdu_test> llimagej2ckdu_t;
|
||||
typedef llimagej2ckdu_t::object llimagej2ckdu_object_t;
|
||||
tut::llimagej2ckdu_t tut_llimagej2ckdu("LLImageJ2CKDU");
|
||||
|
||||
// ---------------------------------------------------------------------------------------
|
||||
// Test functions
|
||||
// Notes:
|
||||
// * Test as many as you possibly can without requiring a full blown simulation of everything
|
||||
// * The tests are executed in sequence so the test instance state may change between calls
|
||||
// * Remember that you cannot test private methods with tut
|
||||
// ---------------------------------------------------------------------------------------
|
||||
|
||||
// Test 1 : test getMetadata()
|
||||
template<> template<>
|
||||
void llimagej2ckdu_object_t::test<1>()
|
||||
{
|
||||
LLImageJ2C* image = new LLImageJ2C();
|
||||
BOOL res = mImage->callGetMetadata(*image);
|
||||
// Trying to set up a data stream with all NIL values and stubbed KDU will "work" and return TRUE
|
||||
// Note that is linking with KDU, that call will throw an exception and fail, returning FALSE
|
||||
ensure("getMetadata() test failed", res == TRUE);
|
||||
}
|
||||
|
||||
// Test 2 : test decodeImpl()
|
||||
template<> template<>
|
||||
void llimagej2ckdu_object_t::test<2>()
|
||||
{
|
||||
LLImageJ2C* image = new LLImageJ2C();
|
||||
LLImageRaw* raw = new LLImageRaw();
|
||||
BOOL res = mImage->callDecodeImpl(*image, *raw, 0.0, 0, 0);
|
||||
// Decoding returns TRUE whenever there's nothing else to do, including if decoding failed, so we'll get TRUE here
|
||||
ensure("decodeImpl() test failed", res == TRUE);
|
||||
}
|
||||
|
||||
// Test 3 : test encodeImpl()
|
||||
template<> template<>
|
||||
void llimagej2ckdu_object_t::test<3>()
|
||||
{
|
||||
LLImageJ2C* image = new LLImageJ2C();
|
||||
LLImageRaw* raw = new LLImageRaw();
|
||||
BOOL res = mImage->callEncodeImpl(*image, *raw, NULL);
|
||||
// Encoding returns TRUE unless an exception was raised, so we'll get TRUE here though nothing really was done
|
||||
ensure("encodeImpl() test failed", res == TRUE);
|
||||
}
|
||||
}
|
||||
|
|
@ -280,7 +280,6 @@ namespace tut
|
|||
llmat_obj.setRows(llvec1, llvec2, llvec3);
|
||||
llmat_obj.orthogonalize();
|
||||
|
||||
skip("Grr, LLMatrix3::orthogonalize test is failing. Has it ever worked?");
|
||||
ensure("LLMatrix3::orthogonalize failed ",
|
||||
is_approx_equal(0.19611613f, llmat_obj.mMatrix[0][0]) &&
|
||||
is_approx_equal(0.78446454f, llmat_obj.mMatrix[0][1]) &&
|
||||
|
|
|
|||
|
|
@ -513,6 +513,10 @@ void LLAssetStorage::getAssetData(const LLUUID uuid, LLAssetType::EType type, LL
|
|||
|
||||
}
|
||||
|
||||
//
|
||||
// *NOTE: Logic here is replicated in LLViewerAssetStorage::_queueDataRequest.
|
||||
// Changes here may need to be replicated in the viewer's derived class.
|
||||
//
|
||||
void LLAssetStorage::_queueDataRequest(const LLUUID& uuid, LLAssetType::EType atype,
|
||||
LLGetAssetCallback callback,
|
||||
void *user_data, BOOL duplicate,
|
||||
|
|
|
|||
|
|
@ -81,8 +81,11 @@ namespace LLAvatarNameCache
|
|||
// only need per-frame timing resolution
|
||||
LLFrameTimer sRequestTimer;
|
||||
|
||||
// Periodically clean out expired entries from the cache
|
||||
//LLFrameTimer sEraseExpiredTimer;
|
||||
/// Maximum time an unrefreshed cache entry is allowed
|
||||
const F64 MAX_UNREFRESHED_TIME = 20.0 * 60.0;
|
||||
|
||||
/// Time when unrefreshed cached names were checked last
|
||||
static F64 sLastExpireCheck;
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// Internal methods
|
||||
|
|
@ -99,8 +102,9 @@ namespace LLAvatarNameCache
|
|||
|
||||
// Legacy name system callback
|
||||
void legacyNameCallback(const LLUUID& agent_id,
|
||||
const std::string& full_name,
|
||||
bool is_group);
|
||||
const std::string& full_name,
|
||||
bool is_group
|
||||
);
|
||||
|
||||
void requestNamesViaLegacy();
|
||||
|
||||
|
|
@ -117,7 +121,7 @@ namespace LLAvatarNameCache
|
|||
bool isRequestPending(const LLUUID& agent_id);
|
||||
|
||||
// Erase expired names from cache
|
||||
void eraseExpired();
|
||||
void eraseUnrefreshed();
|
||||
|
||||
bool expirationFromCacheControl(LLSD headers, F64 *expires);
|
||||
}
|
||||
|
|
@ -187,6 +191,7 @@ public:
|
|||
{
|
||||
// Pull expiration out of headers if available
|
||||
F64 expires = LLAvatarNameCache::nameExpirationFromHeaders(mHeaders);
|
||||
F64 now = LLFrameTimer::getTotalSeconds();
|
||||
|
||||
LLSD agents = content["agents"];
|
||||
LLSD::array_const_iterator it = agents.beginArray();
|
||||
|
|
@ -207,100 +212,91 @@ public:
|
|||
av_name.mDisplayName = av_name.mUsername;
|
||||
}
|
||||
|
||||
LL_DEBUGS("AvNameCache") << "LLAvatarNameResponder::result for " << agent_id << " "
|
||||
<< "user '" << av_name.mUsername << "' "
|
||||
<< "display '" << av_name.mDisplayName << "' "
|
||||
<< "expires in " << expires - now << " seconds"
|
||||
<< LL_ENDL;
|
||||
|
||||
// cache it and fire signals
|
||||
LLAvatarNameCache::processName(agent_id, av_name, true);
|
||||
}
|
||||
|
||||
// Same logic as error response case
|
||||
LLSD unresolved_agents = content["bad_ids"];
|
||||
if (unresolved_agents.size() > 0)
|
||||
S32 num_unresolved = unresolved_agents.size();
|
||||
if (num_unresolved > 0)
|
||||
{
|
||||
const std::string DUMMY_NAME("\?\?\?");
|
||||
LLAvatarName av_name;
|
||||
av_name.mUsername = DUMMY_NAME;
|
||||
av_name.mDisplayName = DUMMY_NAME;
|
||||
av_name.mIsDisplayNameDefault = false;
|
||||
av_name.mIsDummy = true;
|
||||
av_name.mExpires = expires;
|
||||
|
||||
LL_WARNS("AvNameCache") << "LLAvatarNameResponder::result " << num_unresolved << " unresolved ids; "
|
||||
<< "expires in " << expires - now << " seconds"
|
||||
<< LL_ENDL;
|
||||
it = unresolved_agents.beginArray();
|
||||
for ( ; it != unresolved_agents.endArray(); ++it)
|
||||
{
|
||||
const LLUUID& agent_id = *it;
|
||||
// cache it and fire signals
|
||||
LLAvatarNameCache::processName(agent_id, av_name, true);
|
||||
|
||||
LL_WARNS("AvNameCache") << "LLAvatarNameResponder::result "
|
||||
<< "failed id " << agent_id
|
||||
<< LL_ENDL;
|
||||
|
||||
LLAvatarNameCache::handleAgentError(agent_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
LL_DEBUGS("AvNameCache") << "LLAvatarNameResponder::result "
|
||||
<< LLAvatarNameCache::sCache.size() << " cached names"
|
||||
<< LL_ENDL;
|
||||
}
|
||||
|
||||
/*virtual*/ void error(U32 status, const std::string& reason)
|
||||
{
|
||||
// We're going to construct a dummy record and cache it for a while,
|
||||
// either briefly for a 503 Service Unavailable, or longer for other
|
||||
// errors.
|
||||
F64 retry_timestamp = errorRetryTimestamp(status);
|
||||
// If there's an error, it might be caused by PeopleApi,
|
||||
// or when loading textures on startup and using a very slow
|
||||
// network, this query may time out.
|
||||
// What we should do depends on whether or not we have a cached name
|
||||
LL_WARNS("AvNameCache") << "LLAvatarNameResponder::error " << status << " " << reason
|
||||
<< LL_ENDL;
|
||||
|
||||
// *NOTE: "??" starts trigraphs in C/C++, escape the question marks.
|
||||
const std::string DUMMY_NAME("\?\?\?");
|
||||
LLAvatarName av_name;
|
||||
av_name.mUsername = DUMMY_NAME;
|
||||
av_name.mDisplayName = DUMMY_NAME;
|
||||
av_name.mIsDisplayNameDefault = false;
|
||||
av_name.mIsDummy = true;
|
||||
av_name.mExpires = retry_timestamp;
|
||||
|
||||
// Add dummy records for all agent IDs in this request
|
||||
// Add dummy records for any agent IDs in this request that we do not have cached already
|
||||
std::vector<LLUUID>::const_iterator it = mAgentIDs.begin();
|
||||
for ( ; it != mAgentIDs.end(); ++it)
|
||||
{
|
||||
const LLUUID& agent_id = *it;
|
||||
// cache it and fire signals
|
||||
LLAvatarNameCache::processName(agent_id, av_name, true);
|
||||
}
|
||||
}
|
||||
|
||||
// Return time to retry a request that generated an error, based on
|
||||
// error type and headers. Return value is seconds-since-epoch.
|
||||
F64 errorRetryTimestamp(S32 status)
|
||||
{
|
||||
F64 now = LLFrameTimer::getTotalSeconds();
|
||||
|
||||
// Retry-After takes priority
|
||||
LLSD retry_after = mHeaders["retry-after"];
|
||||
if (retry_after.isDefined())
|
||||
{
|
||||
// We only support the delta-seconds type
|
||||
S32 delta_seconds = retry_after.asInteger();
|
||||
if (delta_seconds > 0)
|
||||
{
|
||||
// ...valid delta-seconds
|
||||
return now + F64(delta_seconds);
|
||||
}
|
||||
}
|
||||
|
||||
// If no Retry-After, look for Cache-Control max-age
|
||||
F64 expires = 0.0;
|
||||
if (LLAvatarNameCache::expirationFromCacheControl(mHeaders, &expires))
|
||||
{
|
||||
return expires;
|
||||
}
|
||||
|
||||
// No information in header, make a guess
|
||||
if (status == 503)
|
||||
{
|
||||
// ...service unavailable, retry soon
|
||||
const F64 SERVICE_UNAVAILABLE_DELAY = 600.0; // 10 min
|
||||
return now + SERVICE_UNAVAILABLE_DELAY;
|
||||
}
|
||||
else
|
||||
{
|
||||
// ...other unexpected error
|
||||
const F64 DEFAULT_DELAY = 3600.0; // 1 hour
|
||||
return now + DEFAULT_DELAY;
|
||||
LLAvatarNameCache::handleAgentError(agent_id);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Provide some fallback for agents that return errors
|
||||
void LLAvatarNameCache::handleAgentError(const LLUUID& agent_id)
|
||||
{
|
||||
std::map<LLUUID,LLAvatarName>::iterator existing = sCache.find(agent_id);
|
||||
if (existing == sCache.end())
|
||||
{
|
||||
// there is no existing cache entry, so make a temporary name from legacy
|
||||
LL_WARNS("AvNameCache") << "LLAvatarNameCache get legacy for agent "
|
||||
<< agent_id << LL_ENDL;
|
||||
gCacheName->get(agent_id, false, // legacy compatibility
|
||||
boost::bind(&LLAvatarNameCache::legacyNameCallback,
|
||||
_1, _2, _3));
|
||||
}
|
||||
else
|
||||
{
|
||||
// we have a chached (but probably expired) entry - since that would have
|
||||
// been returned by the get method, there is no need to signal anyone
|
||||
|
||||
// Clear this agent from the pending list
|
||||
LLAvatarNameCache::sPendingQueue.erase(agent_id);
|
||||
|
||||
const LLAvatarName& av_name = existing->second;
|
||||
LL_DEBUGS("AvNameCache") << "LLAvatarNameCache use cache for agent "
|
||||
<< agent_id
|
||||
<< "user '" << av_name.mUsername << "' "
|
||||
<< "display '" << av_name.mDisplayName << "' "
|
||||
<< "expires in " << av_name.mExpires - LLFrameTimer::getTotalSeconds() << " seconds"
|
||||
<< LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
void LLAvatarNameCache::processName(const LLUUID& agent_id,
|
||||
const LLAvatarName& av_name,
|
||||
bool add_to_cache)
|
||||
|
|
@ -342,6 +338,7 @@ void LLAvatarNameCache::requestNamesViaCapability()
|
|||
std::vector<LLUUID> agent_ids;
|
||||
agent_ids.reserve(128);
|
||||
|
||||
U32 ids = 0;
|
||||
ask_queue_t::const_iterator it = sAskQueue.begin();
|
||||
for ( ; it != sAskQueue.end(); ++it)
|
||||
{
|
||||
|
|
@ -352,11 +349,13 @@ void LLAvatarNameCache::requestNamesViaCapability()
|
|||
// ...starting new request
|
||||
url += sNameLookupURL;
|
||||
url += "?ids=";
|
||||
ids = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// ...continuing existing request
|
||||
url += "&ids=";
|
||||
ids++;
|
||||
}
|
||||
url += agent_id.asString();
|
||||
agent_ids.push_back(agent_id);
|
||||
|
|
@ -366,7 +365,9 @@ void LLAvatarNameCache::requestNamesViaCapability()
|
|||
|
||||
if (url.size() > NAME_URL_SEND_THRESHOLD)
|
||||
{
|
||||
//llinfos << "requestNames " << url << llendl;
|
||||
LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::requestNamesViaCapability first "
|
||||
<< ids << " ids"
|
||||
<< LL_ENDL;
|
||||
LLHTTPClient::get(url, new LLAvatarNameResponder(agent_ids));
|
||||
url.clear();
|
||||
agent_ids.clear();
|
||||
|
|
@ -375,7 +376,9 @@ void LLAvatarNameCache::requestNamesViaCapability()
|
|||
|
||||
if (!url.empty())
|
||||
{
|
||||
//llinfos << "requestNames " << url << llendl;
|
||||
LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::requestNamesViaCapability all "
|
||||
<< ids << " ids"
|
||||
<< LL_ENDL;
|
||||
LLHTTPClient::get(url, new LLAvatarNameResponder(agent_ids));
|
||||
url.clear();
|
||||
agent_ids.clear();
|
||||
|
|
@ -392,6 +395,11 @@ void LLAvatarNameCache::legacyNameCallback(const LLUUID& agent_id,
|
|||
// Construct a dummy record for this name. By convention, SLID is blank
|
||||
// Never expires, but not written to disk, so lasts until end of session.
|
||||
LLAvatarName av_name;
|
||||
LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::legacyNameCallback "
|
||||
<< "agent " << agent_id << " "
|
||||
<< "full name '" << full_name << "'"
|
||||
<< ( is_group ? " [group]" : "" )
|
||||
<< LL_ENDL;
|
||||
buildLegacyName(full_name, &av_name);
|
||||
|
||||
// Don't add to cache, the data already exists in the legacy name system
|
||||
|
|
@ -413,6 +421,8 @@ void LLAvatarNameCache::requestNamesViaLegacy()
|
|||
// invoked below. This should never happen in practice.
|
||||
sPendingQueue[agent_id] = now;
|
||||
|
||||
LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::requestNamesViaLegacy agent " << agent_id << LL_ENDL;
|
||||
|
||||
gCacheName->get(agent_id, false, // legacy compatibility
|
||||
boost::bind(&LLAvatarNameCache::legacyNameCallback,
|
||||
_1, _2, _3));
|
||||
|
|
@ -451,21 +461,24 @@ void LLAvatarNameCache::importFile(std::istream& istr)
|
|||
av_name.fromLLSD( it->second );
|
||||
sCache[agent_id] = av_name;
|
||||
}
|
||||
// entries may have expired since we last ran the viewer, just
|
||||
// clean them out now
|
||||
eraseExpired();
|
||||
llinfos << "loaded " << sCache.size() << llendl;
|
||||
LL_INFOS("AvNameCache") << "loaded " << sCache.size() << LL_ENDL;
|
||||
|
||||
// Some entries may have expired since the cache was stored,
|
||||
// but they will be flushed in the first call to eraseUnrefreshed
|
||||
// from LLAvatarNameResponder::idle
|
||||
}
|
||||
|
||||
void LLAvatarNameCache::exportFile(std::ostream& ostr)
|
||||
{
|
||||
LLSD agents;
|
||||
F64 max_unrefreshed = LLFrameTimer::getTotalSeconds() - MAX_UNREFRESHED_TIME;
|
||||
cache_t::const_iterator it = sCache.begin();
|
||||
for ( ; it != sCache.end(); ++it)
|
||||
{
|
||||
const LLUUID& agent_id = it->first;
|
||||
const LLAvatarName& av_name = it->second;
|
||||
if (!av_name.mIsDummy)
|
||||
// Do not write temporary or expired entries to the stored cache
|
||||
if (!av_name.mIsTemporaryName && av_name.mExpires >= max_unrefreshed)
|
||||
{
|
||||
// key must be a string
|
||||
agents[agent_id.asString()] = av_name.asLLSD();
|
||||
|
|
@ -500,62 +513,63 @@ void LLAvatarNameCache::idle()
|
|||
// return;
|
||||
//}
|
||||
|
||||
// Must be large relative to above
|
||||
|
||||
// No longer deleting expired entries, just re-requesting in the get
|
||||
// this way first synchronous get call on an expired entry won't return
|
||||
// legacy name. LF
|
||||
|
||||
//const F32 ERASE_EXPIRED_TIMEOUT = 60.f; // seconds
|
||||
//if (sEraseExpiredTimer.checkExpirationAndReset(ERASE_EXPIRED_TIMEOUT))
|
||||
//{
|
||||
// eraseExpired();
|
||||
//}
|
||||
|
||||
if (sAskQueue.empty())
|
||||
if (!sAskQueue.empty())
|
||||
{
|
||||
return;
|
||||
if (useDisplayNames())
|
||||
{
|
||||
requestNamesViaCapability();
|
||||
}
|
||||
else
|
||||
{
|
||||
// ...fall back to legacy name cache system
|
||||
requestNamesViaLegacy();
|
||||
}
|
||||
}
|
||||
|
||||
if (useDisplayNames())
|
||||
{
|
||||
requestNamesViaCapability();
|
||||
}
|
||||
else
|
||||
{
|
||||
// ...fall back to legacy name cache system
|
||||
requestNamesViaLegacy();
|
||||
}
|
||||
// erase anything that has not been refreshed for more than MAX_UNREFRESHED_TIME
|
||||
eraseUnrefreshed();
|
||||
}
|
||||
|
||||
bool LLAvatarNameCache::isRequestPending(const LLUUID& agent_id)
|
||||
{
|
||||
bool isPending = false;
|
||||
const F64 PENDING_TIMEOUT_SECS = 5.0 * 60.0;
|
||||
F64 now = LLFrameTimer::getTotalSeconds();
|
||||
F64 expire_time = now - PENDING_TIMEOUT_SECS;
|
||||
|
||||
pending_queue_t::const_iterator it = sPendingQueue.find(agent_id);
|
||||
if (it != sPendingQueue.end())
|
||||
{
|
||||
bool request_expired = (it->second < expire_time);
|
||||
return !request_expired;
|
||||
// in the list of requests in flight, retry if too old
|
||||
F64 expire_time = LLFrameTimer::getTotalSeconds() - PENDING_TIMEOUT_SECS;
|
||||
isPending = (it->second > expire_time);
|
||||
}
|
||||
return false;
|
||||
return isPending;
|
||||
}
|
||||
|
||||
void LLAvatarNameCache::eraseExpired()
|
||||
void LLAvatarNameCache::eraseUnrefreshed()
|
||||
{
|
||||
F64 now = LLFrameTimer::getTotalSeconds();
|
||||
cache_t::iterator it = sCache.begin();
|
||||
while (it != sCache.end())
|
||||
{
|
||||
cache_t::iterator cur = it;
|
||||
++it;
|
||||
const LLAvatarName& av_name = cur->second;
|
||||
if (av_name.mExpires < now)
|
||||
{
|
||||
sCache.erase(cur);
|
||||
}
|
||||
F64 max_unrefreshed = now - MAX_UNREFRESHED_TIME;
|
||||
|
||||
if (!sLastExpireCheck || sLastExpireCheck < max_unrefreshed)
|
||||
{
|
||||
sLastExpireCheck = now;
|
||||
cache_t::iterator it = sCache.begin();
|
||||
while (it != sCache.end())
|
||||
{
|
||||
cache_t::iterator cur = it;
|
||||
++it;
|
||||
const LLAvatarName& av_name = cur->second;
|
||||
if (av_name.mExpires < max_unrefreshed)
|
||||
{
|
||||
const LLUUID& agent_id = it->first;
|
||||
LL_DEBUGS("AvNameCache") << agent_id
|
||||
<< " user '" << av_name.mUsername << "' "
|
||||
<< "expired " << now - av_name.mExpires << " secs ago"
|
||||
<< LL_ENDL;
|
||||
sCache.erase(cur);
|
||||
}
|
||||
}
|
||||
LL_INFOS("AvNameCache") << sCache.size() << " cached avatar names" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -566,8 +580,11 @@ void LLAvatarNameCache::buildLegacyName(const std::string& full_name,
|
|||
av_name->mUsername = "";
|
||||
av_name->mDisplayName = full_name;
|
||||
av_name->mIsDisplayNameDefault = true;
|
||||
av_name->mIsDummy = true;
|
||||
av_name->mExpires = F64_MAX;
|
||||
av_name->mIsTemporaryName = true;
|
||||
av_name->mExpires = F64_MAX; // not used because these are not cached
|
||||
LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::buildLegacyName "
|
||||
<< full_name
|
||||
<< LL_ENDL;
|
||||
}
|
||||
|
||||
// fills in av_name if it has it in the cache, even if expired (can check expiry time)
|
||||
|
|
@ -590,6 +607,9 @@ bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name)
|
|||
{
|
||||
if (!isRequestPending(agent_id))
|
||||
{
|
||||
LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::get "
|
||||
<< "refresh agent " << agent_id
|
||||
<< LL_ENDL;
|
||||
sAskQueue.insert(agent_id);
|
||||
}
|
||||
}
|
||||
|
|
@ -611,6 +631,9 @@ bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name)
|
|||
|
||||
if (!isRequestPending(agent_id))
|
||||
{
|
||||
LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::get "
|
||||
<< "queue request for agent " << agent_id
|
||||
<< LL_ENDL;
|
||||
sAskQueue.insert(agent_id);
|
||||
}
|
||||
|
||||
|
|
@ -643,7 +666,6 @@ void LLAvatarNameCache::get(const LLUUID& agent_id, callback_slot_t slot)
|
|||
{
|
||||
// ...name already exists in cache, fire callback now
|
||||
fireSignal(agent_id, slot, av_name);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -739,6 +761,9 @@ F64 LLAvatarNameCache::nameExpirationFromHeaders(LLSD headers)
|
|||
|
||||
bool LLAvatarNameCache::expirationFromCacheControl(LLSD headers, F64 *expires)
|
||||
{
|
||||
bool fromCacheControl = false;
|
||||
F64 now = LLFrameTimer::getTotalSeconds();
|
||||
|
||||
// Allow the header to override the default
|
||||
LLSD cache_control_header = headers["cache-control"];
|
||||
if (cache_control_header.isDefined())
|
||||
|
|
@ -747,12 +772,16 @@ bool LLAvatarNameCache::expirationFromCacheControl(LLSD headers, F64 *expires)
|
|||
std::string cache_control = cache_control_header.asString();
|
||||
if (max_age_from_cache_control(cache_control, &max_age))
|
||||
{
|
||||
F64 now = LLFrameTimer::getTotalSeconds();
|
||||
*expires = now + (F64)max_age;
|
||||
return true;
|
||||
fromCacheControl = true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
LL_DEBUGS("AvNameCache")
|
||||
<< ( fromCacheControl ? "expires based on cache control " : "default expiration " )
|
||||
<< "in " << *expires - now << " seconds"
|
||||
<< LL_ENDL;
|
||||
|
||||
return fromCacheControl;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -82,6 +82,9 @@ namespace LLAvatarNameCache
|
|||
|
||||
void erase(const LLUUID& agent_id);
|
||||
|
||||
/// Provide some fallback for agents that return errors
|
||||
void handleAgentError(const LLUUID& agent_id);
|
||||
|
||||
// Force a re-fetch of the most recent data, but keep the current
|
||||
// data in cache
|
||||
void fetch(const LLUUID& agent_id);
|
||||
|
|
|
|||
|
|
@ -556,35 +556,43 @@ std::string LLCacheName::buildUsername(const std::string& full_name)
|
|||
//static
|
||||
std::string LLCacheName::buildLegacyName(const std::string& complete_name)
|
||||
{
|
||||
// regexp doesn't play nice with unicode, chop off the display name
|
||||
//boost::regexp was showing up in the crashreporter, so doing
|
||||
//painfully manual parsing using substr. LF
|
||||
S32 open_paren = complete_name.rfind(" (");
|
||||
S32 close_paren = complete_name.rfind(')');
|
||||
|
||||
if (open_paren == std::string::npos)
|
||||
if (open_paren != std::string::npos &&
|
||||
close_paren == complete_name.length()-1)
|
||||
{
|
||||
return complete_name;
|
||||
S32 length = close_paren - open_paren - 2;
|
||||
std::string legacy_name = complete_name.substr(open_paren+2, length);
|
||||
|
||||
if (legacy_name.length() > 0)
|
||||
{
|
||||
std::string cap_letter = legacy_name.substr(0, 1);
|
||||
LLStringUtil::toUpper(cap_letter);
|
||||
legacy_name = cap_letter + legacy_name.substr(1);
|
||||
|
||||
S32 separator = legacy_name.find('.');
|
||||
|
||||
if (separator != std::string::npos)
|
||||
{
|
||||
std::string last_name = legacy_name.substr(separator+1);
|
||||
legacy_name = legacy_name.substr(0, separator);
|
||||
|
||||
if (last_name.length() > 0)
|
||||
{
|
||||
cap_letter = last_name.substr(0, 1);
|
||||
LLStringUtil::toUpper(cap_letter);
|
||||
legacy_name = legacy_name + " " + cap_letter + last_name.substr(1);
|
||||
}
|
||||
}
|
||||
|
||||
return legacy_name;
|
||||
}
|
||||
}
|
||||
|
||||
std::string username = complete_name.substr(open_paren);
|
||||
boost::regex complete_name_regex("( \\()([a-z0-9]+)(.[a-z]+)*(\\))");
|
||||
boost::match_results<std::string::const_iterator> name_results;
|
||||
if (!boost::regex_match(username, name_results, complete_name_regex)) return complete_name;
|
||||
|
||||
std::string legacy_name = name_results[2];
|
||||
// capitalize the first letter
|
||||
std::string cap_letter = legacy_name.substr(0, 1);
|
||||
LLStringUtil::toUpper(cap_letter);
|
||||
legacy_name = cap_letter + legacy_name.substr(1);
|
||||
|
||||
if (name_results[3].matched)
|
||||
{
|
||||
std::string last_name = name_results[3];
|
||||
std::string cap_letter = last_name.substr(1, 1);
|
||||
LLStringUtil::toUpper(cap_letter);
|
||||
last_name = cap_letter + last_name.substr(2);
|
||||
legacy_name = legacy_name + " " + last_name;
|
||||
}
|
||||
|
||||
return legacy_name;
|
||||
return complete_name;
|
||||
}
|
||||
|
||||
// This is a little bit kludgy. LLCacheNameCallback is a slot instead of a function pointer.
|
||||
|
|
@ -967,6 +975,10 @@ void LLCacheName::Impl::processUUIDReply(LLMessageSystem* msg, bool isGroup)
|
|||
if (entry->mLastName.empty())
|
||||
{
|
||||
full_name = cleanFullName(entry->mFirstName);
|
||||
|
||||
//fix what we are putting in the cache
|
||||
entry->mFirstName = full_name;
|
||||
entry->mLastName = "Resident";
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ include_directories(
|
|||
${LLRENDER_INCLUDE_DIRS}
|
||||
${LLXML_INCLUDE_DIRS}
|
||||
${LLWINDOW_INCLUDE_DIRS}
|
||||
${LLQTWEBKIT_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
set(llplugin_SOURCE_FILES
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ void LLPluginClassMedia::idle(void)
|
|||
mPlugin->idle();
|
||||
}
|
||||
|
||||
if((mMediaWidth == -1) || (!mTextureParamsReceived) || (mPlugin == NULL) || (mPlugin->isBlocked()))
|
||||
if((mMediaWidth == -1) || (!mTextureParamsReceived) || (mPlugin == NULL) || (mPlugin->isBlocked()) || (mOwner == NULL))
|
||||
{
|
||||
// Can't process a size change at this time
|
||||
}
|
||||
|
|
@ -522,7 +522,15 @@ bool LLPluginClassMedia::keyEvent(EKeyEventType type, int key_code, MASK modifie
|
|||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
#if LL_DARWIN
|
||||
if(modifiers & MASK_ALT)
|
||||
{
|
||||
// Option-key modified characters should be handled by the unicode input path instead of this one.
|
||||
result = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(result)
|
||||
{
|
||||
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "key_event");
|
||||
|
|
@ -674,7 +682,21 @@ void LLPluginClassMedia::sendPickFileResponse(const std::string &file)
|
|||
{
|
||||
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "pick_file_response");
|
||||
message.setValue("file", file);
|
||||
if(mPlugin->isBlocked())
|
||||
if(mPlugin && mPlugin->isBlocked())
|
||||
{
|
||||
// If the plugin sent a blocking pick-file request, the response should unblock it.
|
||||
message.setValueBoolean("blocking_response", true);
|
||||
}
|
||||
sendMessage(message);
|
||||
}
|
||||
|
||||
void LLPluginClassMedia::sendAuthResponse(bool ok, const std::string &username, const std::string &password)
|
||||
{
|
||||
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "auth_response");
|
||||
message.setValueBoolean("ok", ok);
|
||||
message.setValue("username", username);
|
||||
message.setValue("password", password);
|
||||
if(mPlugin && mPlugin->isBlocked())
|
||||
{
|
||||
// If the plugin sent a blocking pick-file request, the response should unblock it.
|
||||
message.setValueBoolean("blocking_response", true);
|
||||
|
|
@ -947,6 +969,12 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
|
|||
{
|
||||
mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_PICK_FILE_REQUEST);
|
||||
}
|
||||
else if(message_name == "auth_request")
|
||||
{
|
||||
mAuthURL = message.getValue("url");
|
||||
mAuthRealm = message.getValue("realm");
|
||||
mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_AUTH_REQUEST);
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS("Plugin") << "Unknown " << message_name << " class message: " << message_name << LL_ENDL;
|
||||
|
|
@ -1019,6 +1047,15 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
|
|||
|
||||
mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_GEOMETRY_CHANGE);
|
||||
}
|
||||
else if(message_name == "link_hovered")
|
||||
{
|
||||
// text is not currently used -- the tooltip hover text is taken from the "title".
|
||||
mHoverLink = message.getValue("link");
|
||||
mHoverText = message.getValue("title");
|
||||
// message.getValue("text");
|
||||
|
||||
mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_LINK_HOVERED);
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS("Plugin") << "Unknown " << message_name << " class message: " << message_name << LL_ENDL;
|
||||
|
|
@ -1192,6 +1229,20 @@ void LLPluginClassMedia::proxyWindowClosed(const std::string &uuid)
|
|||
sendMessage(message);
|
||||
}
|
||||
|
||||
void LLPluginClassMedia::ignore_ssl_cert_errors(bool ignore)
|
||||
{
|
||||
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "ignore_ssl_cert_errors");
|
||||
message.setValueBoolean("ignore", ignore);
|
||||
sendMessage(message);
|
||||
}
|
||||
|
||||
void LLPluginClassMedia::addCertificateFilePath(const std::string& path)
|
||||
{
|
||||
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "add_certificate_file_path");
|
||||
message.setValue("path", path);
|
||||
sendMessage(message);
|
||||
}
|
||||
|
||||
void LLPluginClassMedia::crashPlugin()
|
||||
{
|
||||
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "crash");
|
||||
|
|
|
|||
|
|
@ -85,6 +85,8 @@ public:
|
|||
|
||||
void setBackgroundColor(LLColor4 color) { mBackgroundColor = color; };
|
||||
|
||||
void setOwner(LLPluginClassMediaOwner *owner) { mOwner = owner; };
|
||||
|
||||
// Returns true if all of the texture parameters (depth, format, size, and texture size) are set up and consistent.
|
||||
// This will initially be false, and will also be false for some time after setSize while the resize is processed.
|
||||
// Note that if this returns true, it is safe to use all the get() functions above without checking for invalid return values
|
||||
|
|
@ -159,6 +161,8 @@ public:
|
|||
|
||||
void sendPickFileResponse(const std::string &file);
|
||||
|
||||
void sendAuthResponse(bool ok, const std::string &username, const std::string &password);
|
||||
|
||||
// Valid after a MEDIA_EVENT_CURSOR_CHANGED event
|
||||
std::string getCursorName() const { return mCursorName; };
|
||||
|
||||
|
|
@ -198,6 +202,8 @@ public:
|
|||
void setBrowserUserAgent(const std::string& user_agent);
|
||||
void proxyWindowOpened(const std::string &target, const std::string &uuid);
|
||||
void proxyWindowClosed(const std::string &uuid);
|
||||
void ignore_ssl_cert_errors(bool ignore);
|
||||
void addCertificateFilePath(const std::string& path);
|
||||
|
||||
// This is valid after MEDIA_EVENT_NAVIGATE_BEGIN or MEDIA_EVENT_NAVIGATE_COMPLETE
|
||||
std::string getNavigateURI() const { return mNavigateURI; };
|
||||
|
|
@ -231,7 +237,15 @@ public:
|
|||
S32 getGeometryY() const { return mGeometryY; };
|
||||
S32 getGeometryWidth() const { return mGeometryWidth; };
|
||||
S32 getGeometryHeight() const { return mGeometryHeight; };
|
||||
|
||||
// These are valid during MEDIA_EVENT_AUTH_REQUEST
|
||||
std::string getAuthURL() const { return mAuthURL; };
|
||||
std::string getAuthRealm() const { return mAuthRealm; };
|
||||
|
||||
// These are valid during MEDIA_EVENT_LINK_HOVERED
|
||||
std::string getHoverText() const { return mHoverText; };
|
||||
std::string getHoverLink() const { return mHoverLink; };
|
||||
|
||||
std::string getMediaName() const { return mMediaName; };
|
||||
std::string getMediaDescription() const { return mMediaDescription; };
|
||||
|
||||
|
|
@ -369,6 +383,10 @@ protected:
|
|||
S32 mGeometryY;
|
||||
S32 mGeometryWidth;
|
||||
S32 mGeometryHeight;
|
||||
std::string mAuthURL;
|
||||
std::string mAuthRealm;
|
||||
std::string mHoverText;
|
||||
std::string mHoverLink;
|
||||
|
||||
/////////////////////////////////////////
|
||||
// media_time class
|
||||
|
|
|
|||
|
|
@ -59,7 +59,11 @@ public:
|
|||
MEDIA_EVENT_GEOMETRY_CHANGE, // The plugin requested its window geometry be changed (per the javascript window interface)
|
||||
|
||||
MEDIA_EVENT_PLUGIN_FAILED_LAUNCH, // The plugin failed to launch
|
||||
MEDIA_EVENT_PLUGIN_FAILED // The plugin died unexpectedly
|
||||
MEDIA_EVENT_PLUGIN_FAILED, // The plugin died unexpectedly
|
||||
|
||||
MEDIA_EVENT_AUTH_REQUEST, // The plugin wants to display an auth dialog
|
||||
|
||||
MEDIA_EVENT_LINK_HOVERED // Got a "link hovered" event from the plugin
|
||||
|
||||
} EMediaEvent;
|
||||
|
||||
|
|
|
|||
|
|
@ -610,41 +610,46 @@ void LLGLManager::shutdownGL()
|
|||
void LLGLManager::initExtensions()
|
||||
{
|
||||
#if LL_MESA_HEADLESS
|
||||
# if GL_ARB_multitexture
|
||||
# ifdef GL_ARB_multitexture
|
||||
mHasMultitexture = TRUE;
|
||||
# else
|
||||
mHasMultitexture = FALSE;
|
||||
# endif
|
||||
# if GL_ARB_texture_env_combine
|
||||
# ifdef GL_ARB_texture_env_combine
|
||||
mHasARBEnvCombine = TRUE;
|
||||
# else
|
||||
mHasARBEnvCombine = FALSE;
|
||||
# endif
|
||||
# if GL_ARB_texture_compression
|
||||
# ifdef GL_ARB_texture_compression
|
||||
mHasCompressedTextures = TRUE;
|
||||
# else
|
||||
mHasCompressedTextures = FALSE;
|
||||
# endif
|
||||
# if GL_ARB_vertex_buffer_object
|
||||
# ifdef GL_ARB_vertex_buffer_object
|
||||
mHasVertexBufferObject = TRUE;
|
||||
# else
|
||||
mHasVertexBufferObject = FALSE;
|
||||
# endif
|
||||
# if GL_EXT_framebuffer_object
|
||||
# ifdef GL_EXT_framebuffer_object
|
||||
mHasFramebufferObject = TRUE;
|
||||
# else
|
||||
mHasFramebufferObject = FALSE;
|
||||
# endif
|
||||
# if GL_EXT_framebuffer_multisample
|
||||
# ifdef GL_EXT_framebuffer_multisample
|
||||
mHasFramebufferMultisample = TRUE;
|
||||
# else
|
||||
mHasFramebufferMultisample = FALSE;
|
||||
# endif
|
||||
# if GL_ARB_draw_buffers
|
||||
# ifdef GL_ARB_draw_buffers
|
||||
mHasDrawBuffers = TRUE;
|
||||
#else
|
||||
mHasDrawBuffers = FALSE;
|
||||
# endif
|
||||
# if defined(GL_NV_depth_clamp) || defined(GL_ARB_depth_clamp)
|
||||
mHasDepthClamp = TRUE;
|
||||
#else
|
||||
mHasDepthClamp = FALSE;
|
||||
#endif
|
||||
# if GL_EXT_blend_func_separate
|
||||
mHasBlendFuncSeparate = TRUE;
|
||||
#else
|
||||
|
|
@ -671,6 +676,7 @@ void LLGLManager::initExtensions()
|
|||
mHasCompressedTextures = glh_init_extensions("GL_ARB_texture_compression");
|
||||
mHasOcclusionQuery = ExtensionExists("GL_ARB_occlusion_query", gGLHExts.mSysExts);
|
||||
mHasVertexBufferObject = ExtensionExists("GL_ARB_vertex_buffer_object", gGLHExts.mSysExts);
|
||||
mHasDepthClamp = ExtensionExists("GL_ARB_depth_clamp", gGLHExts.mSysExts) || ExtensionExists("GL_NV_depth_clamp", gGLHExts.mSysExts);
|
||||
// mask out FBO support when packed_depth_stencil isn't there 'cause we need it for LLRenderTarget -Brad
|
||||
mHasFramebufferObject = ExtensionExists("GL_EXT_framebuffer_object", gGLHExts.mSysExts)
|
||||
&& ExtensionExists("GL_EXT_packed_depth_stencil", gGLHExts.mSysExts);
|
||||
|
|
@ -694,6 +700,7 @@ void LLGLManager::initExtensions()
|
|||
if (getenv("LL_GL_NOEXT"))
|
||||
{
|
||||
//mHasMultitexture = FALSE; // NEEDED!
|
||||
mHasDepthClamp = FALSE;
|
||||
mHasARBEnvCombine = FALSE;
|
||||
mHasCompressedTextures = FALSE;
|
||||
mHasVertexBufferObject = FALSE;
|
||||
|
|
@ -755,6 +762,7 @@ void LLGLManager::initExtensions()
|
|||
if (strchr(blacklist,'s')) mHasFramebufferMultisample = FALSE;
|
||||
if (strchr(blacklist,'t')) mHasTextureRectangle = FALSE;
|
||||
if (strchr(blacklist,'u')) mHasBlendFuncSeparate = FALSE;//S
|
||||
if (strchr(blacklist,'v')) mHasDepthClamp = FALSE;
|
||||
|
||||
}
|
||||
#endif // LL_LINUX || LL_SOLARIS
|
||||
|
|
@ -1047,6 +1055,33 @@ void flush_glerror()
|
|||
glGetError();
|
||||
}
|
||||
|
||||
//this function outputs gl error to the log file, does not crash the code.
|
||||
void log_glerror()
|
||||
{
|
||||
if (LL_UNLIKELY(!gGLManager.mInited))
|
||||
{
|
||||
return ;
|
||||
}
|
||||
// Create or update texture to be used with this data
|
||||
GLenum error;
|
||||
error = glGetError();
|
||||
while (LL_UNLIKELY(error))
|
||||
{
|
||||
GLubyte const * gl_error_msg = gluErrorString(error);
|
||||
if (NULL != gl_error_msg)
|
||||
{
|
||||
llwarns << "GL Error: " << error << " GL Error String: " << gl_error_msg << llendl ;
|
||||
}
|
||||
else
|
||||
{
|
||||
// gluErrorString returns NULL for some extensions' error codes.
|
||||
// you'll probably have to grep for the number in glext.h.
|
||||
llwarns << "GL Error: UNKNOWN 0x" << std::hex << error << std::dec << llendl;
|
||||
}
|
||||
error = glGetError();
|
||||
}
|
||||
}
|
||||
|
||||
void do_assert_glerror()
|
||||
{
|
||||
if (LL_UNLIKELY(!gGLManager.mInited))
|
||||
|
|
@ -2037,7 +2072,7 @@ void LLGLDepthTest::checkState()
|
|||
}
|
||||
}
|
||||
|
||||
LLGLClampToFarClip::LLGLClampToFarClip(glh::matrix4f P)
|
||||
LLGLSquashToFarClip::LLGLSquashToFarClip(glh::matrix4f P)
|
||||
{
|
||||
for (U32 i = 0; i < 4; i++)
|
||||
{
|
||||
|
|
@ -2050,7 +2085,7 @@ LLGLClampToFarClip::LLGLClampToFarClip(glh::matrix4f P)
|
|||
glMatrixMode(GL_MODELVIEW);
|
||||
}
|
||||
|
||||
LLGLClampToFarClip::~LLGLClampToFarClip()
|
||||
LLGLSquashToFarClip::~LLGLSquashToFarClip()
|
||||
{
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
|
|
|
|||
|
|
@ -92,6 +92,7 @@ public:
|
|||
BOOL mHasOcclusionQuery;
|
||||
BOOL mHasPointParameters;
|
||||
BOOL mHasDrawBuffers;
|
||||
BOOL mHasDepthClamp;
|
||||
BOOL mHasTextureRectangle;
|
||||
|
||||
// Other extensions.
|
||||
|
|
@ -157,6 +158,7 @@ void rotate_quat(LLQuaternion& rotation);
|
|||
|
||||
void flush_glerror(); // Flush GL errors when we know we're handling them correctly.
|
||||
|
||||
void log_glerror();
|
||||
void assert_glerror();
|
||||
|
||||
void clear_glerror();
|
||||
|
|
@ -315,11 +317,11 @@ private:
|
|||
leaves this class.
|
||||
Does not stack.
|
||||
*/
|
||||
class LLGLClampToFarClip
|
||||
class LLGLSquashToFarClip
|
||||
{
|
||||
public:
|
||||
LLGLClampToFarClip(glh::matrix4f projection);
|
||||
~LLGLClampToFarClip();
|
||||
LLGLSquashToFarClip(glh::matrix4f projection);
|
||||
~LLGLSquashToFarClip();
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -829,5 +829,15 @@ extern void glGetBufferPointervARB (GLenum, GLenum, GLvoid* *);
|
|||
|
||||
#endif // LL_MESA / LL_WINDOWS / LL_DARWIN
|
||||
|
||||
// Even when GL_ARB_depth_clamp is available in the driver, the (correct)
|
||||
// headers, and therefore GL_DEPTH_CLAMP might not be defined.
|
||||
// In that case GL_DEPTH_CLAMP_NV should be defined, but why not just
|
||||
// use the known numeric.
|
||||
//
|
||||
// To avoid #ifdef's in the code. Just define this here.
|
||||
#ifndef GL_DEPTH_CLAMP
|
||||
// Probably (still) called GL_DEPTH_CLAMP_NV.
|
||||
#define GL_DEPTH_CLAMP 0x864F
|
||||
#endif
|
||||
|
||||
#endif // LL_LLGLHEADERS_H
|
||||
|
|
|
|||
|
|
@ -1069,6 +1069,8 @@ BOOL LLImageGL::setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_
|
|||
checkTexSize(true) ;
|
||||
llcallstacks << fb_x << " : " << fb_y << " : " << x_pos << " : " << y_pos << " : " << width << " : " << height <<
|
||||
" : " << (S32)mComponents << llcallstacksendl ;
|
||||
|
||||
log_glerror() ;
|
||||
}
|
||||
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, fb_x, fb_y, x_pos, y_pos, width, height);
|
||||
|
|
|
|||
|
|
@ -431,6 +431,9 @@ void LLTexUnit::setTextureFilteringOption(LLTexUnit::eTextureFilterOptions optio
|
|||
if (gGL.mMaxAnisotropy < 1.f)
|
||||
{
|
||||
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &gGL.mMaxAnisotropy);
|
||||
|
||||
llinfos << "gGL.mMaxAnisotropy: " << gGL.mMaxAnisotropy << llendl ;
|
||||
gGL.mMaxAnisotropy = llmax(1.f, gGL.mMaxAnisotropy) ;
|
||||
}
|
||||
glTexParameterf(sGLTextureType[mCurrTexType], GL_TEXTURE_MAX_ANISOTROPY_EXT, gGL.mMaxAnisotropy);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
#include "linden_common.h"
|
||||
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
#include "llsys.h"
|
||||
#include "llvertexbuffer.h"
|
||||
// #include "llrender.h"
|
||||
#include "llglheaders.h"
|
||||
|
|
@ -854,6 +854,14 @@ U8* LLVertexBuffer::mapBuffer(S32 access)
|
|||
|
||||
if (!mMappedData)
|
||||
{
|
||||
log_glerror();
|
||||
|
||||
//check the availability of memory
|
||||
U32 avail_phy_mem, avail_vir_mem;
|
||||
LLMemoryInfo::getAvailableMemoryKB(avail_phy_mem, avail_vir_mem) ;
|
||||
llinfos << "Available physical mwmory(KB): " << avail_phy_mem << llendl ;
|
||||
llinfos << "Available virtual memory(KB): " << avail_vir_mem << llendl;
|
||||
|
||||
//--------------------
|
||||
//print out more debug info before crash
|
||||
llinfos << "vertex buffer size: (num verts : num indices) = " << getNumVerts() << " : " << getNumIndices() << llendl ;
|
||||
|
|
@ -875,6 +883,8 @@ U8* LLVertexBuffer::mapBuffer(S32 access)
|
|||
|
||||
if (!mMappedIndexData)
|
||||
{
|
||||
log_glerror();
|
||||
|
||||
GLint buff;
|
||||
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff);
|
||||
if ((GLuint)buff != mGLIndices)
|
||||
|
|
|
|||
|
|
@ -111,6 +111,7 @@ set(llui_SOURCE_FILES
|
|||
llviewmodel.cpp
|
||||
llview.cpp
|
||||
llviewquery.cpp
|
||||
llwindowshade.cpp
|
||||
)
|
||||
|
||||
set(llui_HEADER_FILES
|
||||
|
|
@ -159,6 +160,7 @@ set(llui_HEADER_FILES
|
|||
llnotificationslistener.h
|
||||
llnotificationsutil.h
|
||||
llnotificationtemplate.h
|
||||
llnotificationvisibilityrule.h
|
||||
llpanel.h
|
||||
llprogressbar.h
|
||||
llradiogroup.h
|
||||
|
|
@ -209,6 +211,7 @@ set(llui_HEADER_FILES
|
|||
llviewmodel.h
|
||||
llview.h
|
||||
llviewquery.h
|
||||
llwindowshade.h
|
||||
)
|
||||
|
||||
set_source_files_properties(${llui_HEADER_FILES}
|
||||
|
|
|
|||
|
|
@ -203,7 +203,8 @@ void LLAccordionCtrlTab::LLAccordionCtrlTabHeader::draw()
|
|||
S32 width = getRect().getWidth();
|
||||
S32 height = getRect().getHeight();
|
||||
|
||||
gl_rect_2d(0,0,width - 1 ,height - 1,mHeaderBGColor.get(),true);
|
||||
F32 alpha = getCurrentTransparency();
|
||||
gl_rect_2d(0,0,width - 1 ,height - 1,mHeaderBGColor.get() % alpha,true);
|
||||
|
||||
LLAccordionCtrlTab* parent = dynamic_cast<LLAccordionCtrlTab*>(getParent());
|
||||
bool collapsible = (parent && parent->getCollapsible());
|
||||
|
|
@ -456,8 +457,7 @@ BOOL LLAccordionCtrlTab::handleMouseDown(S32 x, S32 y, MASK mask)
|
|||
{
|
||||
if(y >= (getRect().getHeight() - HEADER_HEIGHT) )
|
||||
{
|
||||
LLAccordionCtrlTabHeader* header = getChild<LLAccordionCtrlTabHeader>(DD_HEADER_NAME);
|
||||
header->setFocus(true);
|
||||
mHeader->setFocus(true);
|
||||
changeOpenClose(getDisplayChildren());
|
||||
|
||||
//reset stored state
|
||||
|
|
@ -509,10 +509,9 @@ void LLAccordionCtrlTab::setAccordionView(LLView* panel)
|
|||
|
||||
std::string LLAccordionCtrlTab::getTitle() const
|
||||
{
|
||||
LLAccordionCtrlTabHeader* header = findChild<LLAccordionCtrlTabHeader>(DD_HEADER_NAME);
|
||||
if (header)
|
||||
if (mHeader)
|
||||
{
|
||||
return header->getTitle();
|
||||
return mHeader->getTitle();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -522,57 +521,51 @@ std::string LLAccordionCtrlTab::getTitle() const
|
|||
|
||||
void LLAccordionCtrlTab::setTitle(const std::string& title, const std::string& hl)
|
||||
{
|
||||
LLAccordionCtrlTabHeader* header = findChild<LLAccordionCtrlTabHeader>(DD_HEADER_NAME);
|
||||
if (header)
|
||||
if (mHeader)
|
||||
{
|
||||
header->setTitle(title, hl);
|
||||
mHeader->setTitle(title, hl);
|
||||
}
|
||||
}
|
||||
|
||||
void LLAccordionCtrlTab::setTitleFontStyle(std::string style)
|
||||
{
|
||||
LLAccordionCtrlTabHeader* header = findChild<LLAccordionCtrlTabHeader>(DD_HEADER_NAME);
|
||||
if (header)
|
||||
if (mHeader)
|
||||
{
|
||||
header->setTitleFontStyle(style);
|
||||
mHeader->setTitleFontStyle(style);
|
||||
}
|
||||
}
|
||||
|
||||
void LLAccordionCtrlTab::setTitleColor(LLUIColor color)
|
||||
{
|
||||
LLAccordionCtrlTabHeader* header = findChild<LLAccordionCtrlTabHeader>(DD_HEADER_NAME);
|
||||
if (header)
|
||||
if (mHeader)
|
||||
{
|
||||
header->setTitleColor(color);
|
||||
mHeader->setTitleColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
boost::signals2::connection LLAccordionCtrlTab::setFocusReceivedCallback(const focus_signal_t::slot_type& cb)
|
||||
{
|
||||
LLAccordionCtrlTabHeader* header = findChild<LLAccordionCtrlTabHeader>(DD_HEADER_NAME);
|
||||
if (header)
|
||||
if (mHeader)
|
||||
{
|
||||
return header->setFocusReceivedCallback(cb);
|
||||
return mHeader->setFocusReceivedCallback(cb);
|
||||
}
|
||||
return boost::signals2::connection();
|
||||
}
|
||||
|
||||
boost::signals2::connection LLAccordionCtrlTab::setFocusLostCallback(const focus_signal_t::slot_type& cb)
|
||||
{
|
||||
LLAccordionCtrlTabHeader* header = findChild<LLAccordionCtrlTabHeader>(DD_HEADER_NAME);
|
||||
if (header)
|
||||
if (mHeader)
|
||||
{
|
||||
return header->setFocusLostCallback(cb);
|
||||
return mHeader->setFocusLostCallback(cb);
|
||||
}
|
||||
return boost::signals2::connection();
|
||||
}
|
||||
|
||||
void LLAccordionCtrlTab::setSelected(bool is_selected)
|
||||
{
|
||||
LLAccordionCtrlTabHeader* header = findChild<LLAccordionCtrlTabHeader>(DD_HEADER_NAME);
|
||||
if (header)
|
||||
if (mHeader)
|
||||
{
|
||||
header->setSelected(is_selected);
|
||||
mHeader->setSelected(is_selected);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -776,8 +769,7 @@ S32 LLAccordionCtrlTab::notify(const LLSD& info)
|
|||
|
||||
BOOL LLAccordionCtrlTab::handleKey(KEY key, MASK mask, BOOL called_from_parent)
|
||||
{
|
||||
LLAccordionCtrlTabHeader* header = getChild<LLAccordionCtrlTabHeader>(DD_HEADER_NAME);
|
||||
if( !header->hasFocus() )
|
||||
if( !mHeader->hasFocus() )
|
||||
return LLUICtrl::handleKey(key, mask, called_from_parent);
|
||||
|
||||
if ( (key == KEY_RETURN )&& mask == MASK_NONE)
|
||||
|
|
@ -830,15 +822,19 @@ BOOL LLAccordionCtrlTab::handleKey(KEY key, MASK mask, BOOL called_from_parent)
|
|||
|
||||
void LLAccordionCtrlTab::showAndFocusHeader()
|
||||
{
|
||||
LLAccordionCtrlTabHeader* header = getChild<LLAccordionCtrlTabHeader>(DD_HEADER_NAME);
|
||||
header->setFocus(true);
|
||||
header->setSelected(mSelectionEnabled);
|
||||
mHeader->setFocus(true);
|
||||
mHeader->setSelected(mSelectionEnabled);
|
||||
|
||||
LLRect screen_rc;
|
||||
LLRect selected_rc = header->getRect();
|
||||
LLRect selected_rc = mHeader->getRect();
|
||||
localRectToScreen(selected_rc, &screen_rc);
|
||||
notifyParent(LLSD().with("scrollToShowRect",screen_rc.getValue()));
|
||||
|
||||
// This call to notifyParent() is intended to deliver "scrollToShowRect" command
|
||||
// to the parent LLAccordionCtrl so by calling it from the direct parent of this
|
||||
// accordion tab (assuming that the parent is an LLAccordionCtrl) the calls chain
|
||||
// is shortened and messages from inside the collapsed tabs are avoided.
|
||||
// See STORM-536.
|
||||
getParent()->notifyParent(LLSD().with("scrollToShowRect",screen_rc.getValue()));
|
||||
}
|
||||
void LLAccordionCtrlTab::storeOpenCloseState()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -98,7 +98,8 @@ LLButton::Params::Params()
|
|||
is_toggle("is_toggle", false),
|
||||
scale_image("scale_image", true),
|
||||
hover_glow_amount("hover_glow_amount"),
|
||||
commit_on_return("commit_on_return", true)
|
||||
commit_on_return("commit_on_return", true),
|
||||
use_draw_context_alpha("use_draw_context_alpha", true)
|
||||
{
|
||||
addSynonym(is_toggle, "toggle");
|
||||
held_down_delay.seconds = 0.5f;
|
||||
|
|
@ -158,7 +159,8 @@ LLButton::LLButton(const LLButton::Params& p)
|
|||
mLastDrawCharsCount(0),
|
||||
mMouseDownSignal(NULL),
|
||||
mMouseUpSignal(NULL),
|
||||
mHeldDownSignal(NULL)
|
||||
mHeldDownSignal(NULL),
|
||||
mUseDrawContextAlpha(p.use_draw_context_alpha)
|
||||
|
||||
{
|
||||
static LLUICachedControl<S32> llbutton_orig_h_pad ("UIButtonOrigHPad", 0);
|
||||
|
|
@ -539,7 +541,7 @@ BOOL LLButton::handleHover(S32 x, S32 y, MASK mask)
|
|||
// virtual
|
||||
void LLButton::draw()
|
||||
{
|
||||
F32 alpha = getDrawContext().mAlpha;
|
||||
F32 alpha = mUseDrawContextAlpha ? getDrawContext().mAlpha : getCurrentTransparency();
|
||||
bool flash = FALSE;
|
||||
static LLUICachedControl<F32> button_flash_rate("ButtonFlashRate", 0);
|
||||
static LLUICachedControl<S32> button_flash_count("ButtonFlashCount", 0);
|
||||
|
|
|
|||
|
|
@ -124,6 +124,8 @@ public:
|
|||
Optional<F32> hover_glow_amount;
|
||||
Optional<TimeIntervalParam> held_down_delay;
|
||||
|
||||
Optional<bool> use_draw_context_alpha;
|
||||
|
||||
Params();
|
||||
};
|
||||
|
||||
|
|
@ -338,6 +340,8 @@ private:
|
|||
S32 mImageOverlayTopPad;
|
||||
S32 mImageOverlayBottomPad;
|
||||
|
||||
bool mUseDrawContextAlpha;
|
||||
|
||||
/*
|
||||
* Space between image_overlay and label
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -88,27 +88,19 @@ LLCheckBoxCtrl::LLCheckBoxCtrl(const LLCheckBoxCtrl::Params& p)
|
|||
tbparams.font(p.font);
|
||||
}
|
||||
mLabel = LLUICtrlFactory::create<LLTextBox> (tbparams);
|
||||
mLabel->reshapeToFitText();
|
||||
addChild(mLabel);
|
||||
|
||||
S32 text_width = mLabel->getTextBoundingRect().getWidth();
|
||||
S32 text_height = llround(mFont->getLineHeight());
|
||||
LLRect label_rect;
|
||||
label_rect.setOriginAndSize(
|
||||
llcheckboxctrl_hpad + llcheckboxctrl_btn_size + llcheckboxctrl_spacing,
|
||||
llcheckboxctrl_vpad + 1, // padding to get better alignment
|
||||
text_width + llcheckboxctrl_hpad,
|
||||
text_height );
|
||||
mLabel->setShape(label_rect);
|
||||
|
||||
LLRect label_rect = mLabel->getRect();
|
||||
|
||||
// Button
|
||||
// Note: button cover the label by extending all the way to the right.
|
||||
LLRect btn_rect;
|
||||
LLRect btn_rect = p.check_button.rect();
|
||||
btn_rect.setOriginAndSize(
|
||||
llcheckboxctrl_hpad,
|
||||
llcheckboxctrl_vpad,
|
||||
llcheckboxctrl_btn_size + llcheckboxctrl_spacing + text_width + llcheckboxctrl_hpad,
|
||||
llmax( text_height, llcheckboxctrl_btn_size() ) + llcheckboxctrl_vpad);
|
||||
btn_rect.mLeft,
|
||||
btn_rect.mBottom,
|
||||
llmax(btn_rect.mRight, label_rect.mRight - btn_rect.mLeft),
|
||||
llmax( label_rect.getHeight(), btn_rect.mTop));
|
||||
std::string active_true_id, active_false_id;
|
||||
std::string inactive_true_id, inactive_false_id;
|
||||
|
||||
|
|
@ -174,31 +166,20 @@ void LLCheckBoxCtrl::clear()
|
|||
|
||||
void LLCheckBoxCtrl::reshape(S32 width, S32 height, BOOL called_from_parent)
|
||||
{
|
||||
//stretch or shrink bounding rectangle of label when rebuilding UI at new scale
|
||||
static LLUICachedControl<S32> llcheckboxctrl_spacing ("UICheckboxctrlSpacing", 0);
|
||||
static LLUICachedControl<S32> llcheckboxctrl_hpad ("UICheckboxctrlHPad", 0);
|
||||
static LLUICachedControl<S32> llcheckboxctrl_vpad ("UICheckboxctrlVPad", 0);
|
||||
static LLUICachedControl<S32> llcheckboxctrl_btn_size ("UICheckboxctrlBtnSize", 0);
|
||||
|
||||
S32 text_width = mLabel->getTextBoundingRect().getWidth();
|
||||
S32 text_height = llround(mFont->getLineHeight());
|
||||
LLRect label_rect;
|
||||
label_rect.setOriginAndSize(
|
||||
llcheckboxctrl_hpad + llcheckboxctrl_btn_size + llcheckboxctrl_spacing,
|
||||
llcheckboxctrl_vpad,
|
||||
text_width,
|
||||
text_height );
|
||||
mLabel->setShape(label_rect);
|
||||
mLabel->reshapeToFitText();
|
||||
|
||||
LLRect btn_rect;
|
||||
LLRect label_rect = mLabel->getRect();
|
||||
|
||||
// Button
|
||||
// Note: button cover the label by extending all the way to the right.
|
||||
LLRect btn_rect = mButton->getRect();
|
||||
btn_rect.setOriginAndSize(
|
||||
llcheckboxctrl_hpad,
|
||||
llcheckboxctrl_vpad,
|
||||
llcheckboxctrl_btn_size + llcheckboxctrl_spacing + text_width,
|
||||
llmax( text_height, llcheckboxctrl_btn_size() ) );
|
||||
mButton->setShape( btn_rect );
|
||||
|
||||
LLUICtrl::reshape(width, height, called_from_parent);
|
||||
btn_rect.mLeft,
|
||||
btn_rect.mBottom,
|
||||
llmax(btn_rect.getWidth(), label_rect.mRight - btn_rect.mLeft),
|
||||
llmax(label_rect.mTop - btn_rect.mBottom, btn_rect.getHeight()));
|
||||
mButton->setShape(btn_rect);
|
||||
}
|
||||
|
||||
//virtual
|
||||
|
|
|
|||
|
|
@ -94,6 +94,7 @@ LLComboBox::LLComboBox(const LLComboBox::Params& p)
|
|||
mMaxChars(p.max_chars),
|
||||
mPrearrangeCallback(p.prearrange_callback()),
|
||||
mTextEntryCallback(p.text_entry_callback()),
|
||||
mTextChangedCallback(p.text_changed_callback()),
|
||||
mListPosition(p.list_position),
|
||||
mLastSelectedIndex(-1),
|
||||
mLabel(p.label)
|
||||
|
|
@ -769,7 +770,8 @@ BOOL LLComboBox::handleKeyHere(KEY key, MASK mask)
|
|||
return FALSE;
|
||||
}
|
||||
// if selection has changed, pop open list
|
||||
else if (mList->getLastSelectedItem() != last_selected_item)
|
||||
else if (mList->getLastSelectedItem() != last_selected_item ||
|
||||
(key == KEY_DOWN || key == KEY_UP) && !mList->isEmpty())
|
||||
{
|
||||
showList();
|
||||
}
|
||||
|
|
@ -833,6 +835,10 @@ void LLComboBox::onTextEntry(LLLineEditor* line_editor)
|
|||
mList->deselectAllItems();
|
||||
mLastSelectedIndex = -1;
|
||||
}
|
||||
if (mTextChangedCallback != NULL)
|
||||
{
|
||||
(mTextChangedCallback)(line_editor, LLSD());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -877,6 +883,10 @@ void LLComboBox::onTextEntry(LLLineEditor* line_editor)
|
|||
// RN: presumably text entry
|
||||
updateSelection();
|
||||
}
|
||||
if (mTextChangedCallback != NULL)
|
||||
{
|
||||
(mTextChangedCallback)(line_editor, LLSD());
|
||||
}
|
||||
}
|
||||
|
||||
void LLComboBox::updateSelection()
|
||||
|
|
|
|||
|
|
@ -73,7 +73,8 @@ public:
|
|||
allow_new_values;
|
||||
Optional<S32> max_chars;
|
||||
Optional<commit_callback_t> prearrange_callback,
|
||||
text_entry_callback;
|
||||
text_entry_callback,
|
||||
text_changed_callback;
|
||||
|
||||
Optional<EPreferredPosition, PreferredPositionValues> list_position;
|
||||
|
||||
|
|
@ -190,6 +191,7 @@ public:
|
|||
|
||||
void setPrearrangeCallback( commit_callback_t cb ) { mPrearrangeCallback = cb; }
|
||||
void setTextEntryCallback( commit_callback_t cb ) { mTextEntryCallback = cb; }
|
||||
void setTextChangedCallback( commit_callback_t cb ) { mTextChangedCallback = cb; }
|
||||
|
||||
void setButtonVisible(BOOL visible);
|
||||
|
||||
|
|
@ -220,6 +222,7 @@ private:
|
|||
BOOL mTextEntryTentative;
|
||||
commit_callback_t mPrearrangeCallback;
|
||||
commit_callback_t mTextEntryCallback;
|
||||
commit_callback_t mTextChangedCallback;
|
||||
commit_callback_t mSelectionCallback;
|
||||
boost::signals2::connection mTopLostSignalConnection;
|
||||
S32 mLastSelectedIndex;
|
||||
|
|
|
|||
|
|
@ -220,10 +220,15 @@ void LLDockControl::moveDockable()
|
|||
case TOP:
|
||||
x = dockRect.getCenterX() - dockableRect.getWidth() / 2;
|
||||
y = dockRect.mTop + dockableRect.getHeight();
|
||||
// unique docking used with dock tongue, so add tongue height o the Y coordinate
|
||||
// unique docking used with dock tongue, so add tongue height to the Y coordinate
|
||||
if (use_tongue)
|
||||
{
|
||||
y += mDockTongue->getHeight();
|
||||
|
||||
if ( y > rootRect.mTop)
|
||||
{
|
||||
y = rootRect.mTop;
|
||||
}
|
||||
}
|
||||
|
||||
// check is dockable inside root view rect
|
||||
|
|
@ -257,7 +262,7 @@ void LLDockControl::moveDockable()
|
|||
case BOTTOM:
|
||||
x = dockRect.getCenterX() - dockableRect.getWidth() / 2;
|
||||
y = dockRect.mBottom;
|
||||
// unique docking used with dock tongue, so add tongue height o the Y coordinate
|
||||
// unique docking used with dock tongue, so add tongue height to the Y coordinate
|
||||
if (use_tongue)
|
||||
{
|
||||
y -= mDockTongue->getHeight();
|
||||
|
|
@ -292,9 +297,21 @@ void LLDockControl::moveDockable()
|
|||
break;
|
||||
}
|
||||
|
||||
// move dockable
|
||||
dockableRect.setLeftTopAndSize(x, y, dockableRect.getWidth(),
|
||||
dockableRect.getHeight());
|
||||
S32 max_available_height = rootRect.getHeight() - mDockTongueY - mDockTongue->getHeight();
|
||||
|
||||
// A floater should be shrunk so it doesn't cover a part of its docking tongue and
|
||||
// there is a space between a dockable floater and a control to which it is docked.
|
||||
if (use_tongue && dockableRect.getHeight() >= max_available_height)
|
||||
{
|
||||
dockableRect.setLeftTopAndSize(x, y, dockableRect.getWidth(), max_available_height);
|
||||
mDockableFloater->reshape(dockableRect.getWidth(), dockableRect.getHeight());
|
||||
}
|
||||
else
|
||||
{
|
||||
// move dockable
|
||||
dockableRect.setLeftTopAndSize(x, y, dockableRect.getWidth(),
|
||||
dockableRect.getHeight());
|
||||
}
|
||||
LLRect localDocableParentRect;
|
||||
mDockableFloater->getParent()->screenRectToLocal(dockableRect,
|
||||
&localDocableParentRect);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
/**
|
||||
|
||||
* @file llfloater.cpp
|
||||
* @brief LLFloater base class
|
||||
*
|
||||
|
|
@ -61,7 +62,6 @@
|
|||
// use this to control "jumping" behavior when Ctrl-Tabbing
|
||||
const S32 TABBED_FLOATER_OFFSET = 0;
|
||||
|
||||
|
||||
std::string LLFloater::sButtonNames[BUTTON_COUNT] =
|
||||
{
|
||||
"llfloater_close_btn", //BUTTON_CLOSE
|
||||
|
|
@ -200,6 +200,21 @@ void LLFloater::initClass()
|
|||
{
|
||||
sButtonToolTips[i] = LLTrans::getString( sButtonToolTipsIndex[i] );
|
||||
}
|
||||
|
||||
LLControlVariable* ctrl = LLUI::sSettingGroups["config"]->getControl("ActiveFloaterTransparency").get();
|
||||
if (ctrl)
|
||||
{
|
||||
ctrl->getSignal()->connect(boost::bind(&LLFloater::updateActiveFloaterTransparency));
|
||||
updateActiveFloaterTransparency();
|
||||
}
|
||||
|
||||
ctrl = LLUI::sSettingGroups["config"]->getControl("InactiveFloaterTransparency").get();
|
||||
if (ctrl)
|
||||
{
|
||||
ctrl->getSignal()->connect(boost::bind(&LLFloater::updateInactiveFloaterTransparency));
|
||||
updateInactiveFloaterTransparency();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// defaults for floater param block pulled from widgets/floater.xml
|
||||
|
|
@ -207,7 +222,7 @@ static LLWidgetNameRegistry::StaticRegistrar sRegisterFloaterParams(&typeid(LLFl
|
|||
|
||||
LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p)
|
||||
: LLPanel(), // intentionally do not pass params here, see initFromParams
|
||||
mDragHandle(NULL),
|
||||
mDragHandle(NULL),
|
||||
mTitle(p.title),
|
||||
mShortTitle(p.short_title),
|
||||
mSingleInstance(p.single_instance),
|
||||
|
|
@ -347,6 +362,18 @@ void LLFloater::layoutDragHandle()
|
|||
updateTitleButtons();
|
||||
}
|
||||
|
||||
// static
|
||||
void LLFloater::updateActiveFloaterTransparency()
|
||||
{
|
||||
sActiveControlTransparency = LLUI::sSettingGroups["config"]->getF32("ActiveFloaterTransparency");
|
||||
}
|
||||
|
||||
// static
|
||||
void LLFloater::updateInactiveFloaterTransparency()
|
||||
{
|
||||
sInactiveControlTransparency = LLUI::sSettingGroups["config"]->getF32("InactiveFloaterTransparency");
|
||||
}
|
||||
|
||||
void LLFloater::addResizeCtrls()
|
||||
{
|
||||
// Resize bars (sides)
|
||||
|
|
@ -1163,6 +1190,7 @@ void LLFloater::setFocus( BOOL b )
|
|||
last_focus->setFocus(TRUE);
|
||||
}
|
||||
}
|
||||
updateTransparency(b ? TT_ACTIVE : TT_INACTIVE);
|
||||
}
|
||||
|
||||
// virtual
|
||||
|
|
@ -1435,6 +1463,9 @@ void LLFloater::setFrontmost(BOOL take_focus)
|
|||
// there are more than one floater view
|
||||
// so we need to query our parent directly
|
||||
((LLFloaterView*)getParent())->bringToFront(this, take_focus);
|
||||
|
||||
// Make sure to set the appropriate transparency type (STORM-732).
|
||||
updateTransparency(hasFocus() || getIsChrome() ? TT_ACTIVE : TT_INACTIVE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1622,7 +1653,8 @@ void LLFloater::onClickCloseBtn()
|
|||
// virtual
|
||||
void LLFloater::draw()
|
||||
{
|
||||
F32 alpha = getDrawContext().mAlpha;
|
||||
const F32 alpha = getCurrentTransparency();
|
||||
|
||||
// draw background
|
||||
if( isBackgroundVisible() )
|
||||
{
|
||||
|
|
@ -1720,7 +1752,6 @@ void LLFloater::draw()
|
|||
|
||||
void LLFloater::drawShadow(LLPanel* panel)
|
||||
{
|
||||
F32 alpha = panel->getDrawContext().mAlpha;
|
||||
S32 left = LLPANEL_BORDER_WIDTH;
|
||||
S32 top = panel->getRect().getHeight() - LLPANEL_BORDER_WIDTH;
|
||||
S32 right = panel->getRect().getWidth() - LLPANEL_BORDER_WIDTH;
|
||||
|
|
@ -1737,10 +1768,32 @@ void LLFloater::drawShadow(LLPanel* panel)
|
|||
shadow_color.mV[VALPHA] *= 0.5f;
|
||||
}
|
||||
gl_drop_shadow(left, top, right, bottom,
|
||||
shadow_color % alpha,
|
||||
shadow_color % getCurrentTransparency(),
|
||||
llround(shadow_offset));
|
||||
}
|
||||
|
||||
void LLFloater::updateTransparency(LLView* view, ETypeTransparency transparency_type)
|
||||
{
|
||||
child_list_t children = *view->getChildList();
|
||||
child_list_t::iterator it = children.begin();
|
||||
|
||||
LLUICtrl* ctrl = dynamic_cast<LLUICtrl*>(view);
|
||||
if (ctrl)
|
||||
{
|
||||
ctrl->setTransparencyType(transparency_type);
|
||||
}
|
||||
|
||||
for(; it != children.end(); ++it)
|
||||
{
|
||||
updateTransparency(*it, transparency_type);
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloater::updateTransparency(ETypeTransparency transparency_type)
|
||||
{
|
||||
updateTransparency(this, transparency_type);
|
||||
}
|
||||
|
||||
void LLFloater::setCanMinimize(BOOL can_minimize)
|
||||
{
|
||||
// if removing minimize/restore button programmatically,
|
||||
|
|
@ -2857,7 +2910,9 @@ bool LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, const std::str
|
|||
params.from_xui = true;
|
||||
applyXUILayout(params, parent);
|
||||
initFromParams(params);
|
||||
|
||||
// chrome floaters don't take focus at all
|
||||
setFocusRoot(!getIsChrome());
|
||||
|
||||
initFloater(params);
|
||||
|
||||
LLMultiFloater* last_host = LLFloater::getFloaterHost();
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue