From e10051ca080a02a8db6d66d1d2d1777256290be2 Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Thu, 1 Oct 2020 07:23:36 +0300 Subject: SL-14044 Updated VLC to codeticket version 549888 --- autobuild.xml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index eacf11fb0f..3115b32ab6 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3260,9 +3260,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 5e553a4358203f283c74744aed2fcd8c + b639d0035f4a8c9b4973be428a1b7e61 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/54836/510036/vlc_bin-2.2.8.538966-darwin64-538966.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/69569/671323/vlc_bin-3.0.9.549888-darwin64-549888.tar.bz2 name darwin64 @@ -3284,9 +3284,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - ca84b7c5f86e702fb35727eed8f0c8c4 + 4f50b0c47daa081dd4fcb83763d5b0b2 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/54958/511725/vlc_bin-2.2.8.538966-windows-538966.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/69567/671314/vlc_bin-3.0.9.549888-windows-549888.tar.bz2 name windows @@ -3296,16 +3296,16 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 93cd88d90cb8aedbed5cd90ff9262409 + c2f8c01fb6c261b72beb07f0c4cd423f url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/54954/511718/vlc_bin-2.2.8.538966-windows64-538966.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/69568/671315/vlc_bin-3.0.9.549888-windows64-549888.tar.bz2 name windows64 version - 2.2.8.538966 + 3.0.9.549888 xmlrpc-epi -- cgit v1.2.3 From 1811cdc447bbf7c6dfd186be8592cbda896f0df4 Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Thu, 1 Oct 2020 08:44:30 +0300 Subject: SL-14044 Windows build fix --- indra/media_plugins/libvlc/media_plugin_libvlc.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp index f7d35b33c2..5d4a488e64 100644 --- a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp +++ b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp @@ -34,6 +34,11 @@ #include "llpluginmessageclasses.h" #include "media_plugin_base.h" +#if defined(_MSC_VER) +#include +typedef SSIZE_T ssize_t; +#endif + #include "vlc/vlc.h" #include "vlc/libvlc_version.h" -- cgit v1.2.3 From 63d9d378f49dc4d8018c0fcad4fcaa17024b21e3 Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Mon, 1 Feb 2021 03:14:11 +0200 Subject: DRTVWR-520 Updated 3p-libs to use signed versions Updated apr-suite to codeticket build 555520 Updated curl to codeticket build 555526 Updated glod to codeticket build 555522 Updated expat to codeticket build 555519 Updated libhunspell to codeticket build 555528 Updated libndofdev to codeticket build 555523 Updated nghttp2 to codeticket build 555524 --- autobuild.xml | 90 +++++++++++++++++++++++++++++------------------------------ 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index e4b8f2e319..abdd3ec2d8 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -76,9 +76,9 @@ archive hash - 9b8bcc3be6dbe40a04c9c81c313f70dc + f3f49349055a525369a73139046a55a1 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/68333/658209/apr_suite-1.4.5.548882-darwin64-548882.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76345/727286/apr_suite-1.4.5.555520-darwin64-555520.tar.bz2 name darwin64 @@ -112,9 +112,9 @@ archive hash - 6bdf460c18ee004b41a46afc80041a92 + 0628a381c80cae621106e41a0b592bcd url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/68334/658225/apr_suite-1.4.5.548882-windows-548882.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76347/727295/apr_suite-1.4.5.555520-windows-555520.tar.bz2 name windows @@ -124,16 +124,16 @@ archive hash - 83104bfa4dabb77cd70d185e38a95b49 + 79fdb06371d6aeb29b52d593b2865f57 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/68332/658215/apr_suite-1.4.5.548882-windows64-548882.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76346/727296/apr_suite-1.4.5.555520-windows64-555520.tar.bz2 name windows64 version - 1.4.5.548882 + 1.4.5.555520 boost @@ -398,9 +398,9 @@ archive hash - f5ae57117a6518d11f49ccfbfbe0969d + d4c8b00a88e879bd1a7e6805af2ccb1c url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/64131/601402/curl-7.54.1.545369-darwin64-545369.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76361/727381/curl-7.54.1.555526-darwin64-555526.tar.bz2 name darwin64 @@ -434,11 +434,11 @@ archive hash - 2796ae7b09e730a55ac03f74ed669520 + 0bca1f79fc78b0045de18f69fea03093 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/64130/601396/curl-7.54.1.545369-windows-545369.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76362/727375/curl-7.54.1.555526-windows-555526.tar.bz2 name windows @@ -448,16 +448,16 @@ archive hash - a8f96e5cdb8128b23d49ff4c3f2233a4 + cca8ff1d59fcfc64e99c79a950f3abc1 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/64129/601382/curl-7.54.1.545369-windows64-545369.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76360/727374/curl-7.54.1.555526-windows64-555526.tar.bz2 name windows64 version - 7.54.1.545369 + 7.54.1.555526 db @@ -670,9 +670,9 @@ archive hash - 3656b7f7b655cb267fd94f089d2e145c + f4e80e0dfcab713a3da90cd8f7f23e7b url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/54860/510198/expat-2.1.1.538990-darwin64-538990.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76341/727265/expat-2.1.1.555519-darwin64-555519.tar.bz2 name darwin64 @@ -706,9 +706,9 @@ archive hash - c509f8afa1e02f4c16232cce7f6855f8 + cd4fe03473076c324d80ae3bd91a85bb url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/55056/512080/expat-2.1.1.538990-windows-538990.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76343/727273/expat-2.1.1.555519-windows-555519.tar.bz2 name windows @@ -718,16 +718,16 @@ archive hash - aba97cfdf44c04dbfcac89c7cb472580 + d2d74d73b914150982b1883a3b96e60b url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/55054/512068/expat-2.1.1.538990-windows64-538990.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76344/727279/expat-2.1.1.555519-windows64-555519.tar.bz2 name windows64 version - 2.1.1.538990 + 2.1.1.555519 fmodstudio @@ -1078,9 +1078,9 @@ archive hash - 343913fe1434da228c2210c23d2e3a1a + a9eaa005ff9d387f946283fbcb69b3c8 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/54850/510134/glod-1.0pre3.538980-darwin64-538980.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76353/727324/glod-1.0pre3.555522-darwin64-555522.tar.bz2 name darwin64 @@ -1139,7 +1139,7 @@ version - 1.0pre3.538980 + 1.0pre3.555522 google_breakpad @@ -1792,9 +1792,9 @@ archive hash - c327e6d6573fc0a808677de47f08acd9 + 2021ea3a19b81c82993e733709683303 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/54844/510092/libhunspell-1.3.2.538974-darwin64-538974.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76371/727419/libhunspell-1.3.2.555528-darwin64-555528.tar.bz2 name darwin64 @@ -1828,9 +1828,9 @@ archive hash - ec22ec25160bcfd2a74f1c7bc8ff6133 + 2253ec09136cc7c208481030d78d9dd7 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/54986/511824/libhunspell-1.3.2.538974-windows-538974.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76369/727412/libhunspell-1.3.2.555528-windows-555528.tar.bz2 name windows @@ -1840,16 +1840,16 @@ archive hash - f470c6f3f7b0559e95e76467b808de10 + 858d1708f6b3a74738a3d57a5387e20f url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/54985/511817/libhunspell-1.3.2.538974-windows64-538974.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76370/727413/libhunspell-1.3.2.555528-windows64-555528.tar.bz2 name windows64 version - 1.3.2.538974 + 1.3.2.555528 libndofdev @@ -1882,9 +1882,9 @@ archive hash - bf765dfe0b928ef3c531cd9618fee89b + a487fff84208a45844602c4a1f68c974 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/54843/510085/libndofdev-0.1.538973-darwin64-538973.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76356/727333/libndofdev-0.1.555523-darwin64-555523.tar.bz2 name darwin64 @@ -1894,9 +1894,9 @@ archive hash - 8abb7d216535009f6c0a7e43b0734b1e + 4c839555bf0ed9ae60ffc3f8a7c96f9b url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/54984/511810/libndofdev-0.1.538973-windows-538973.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76354/727340/libndofdev-0.1.555523-windows-555523.tar.bz2 name windows @@ -1906,16 +1906,16 @@ archive hash - 9da7aed5a914174dcb2be12ecd4a656f + cbc033ae3b034b992b59f6de1034247c url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/54983/511803/libndofdev-0.1.538973-windows64-538973.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76355/727341/libndofdev-0.1.555523-windows64-555523.tar.bz2 name windows64 version - 0.1.538973 + 0.1.555523 libpng @@ -2414,9 +2414,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 937ce1a2158c0cfff37f5989f5b24aba + e4f784d8a035c51921a1562ca7a1bab6 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/64066/601156/nghttp2-1.40.0.545354-darwin64-545354.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76357/727350/nghttp2-1.40.0.555524-darwin64-555524.tar.bz2 name darwin64 @@ -2450,9 +2450,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 138b881bdf37dff4e626e022a50dd11f + af05aa2994c9845308fecd094b7b2d25 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/64069/601181/nghttp2-1.40.0.545354-windows-545354.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76359/727360/nghttp2-1.40.0.555524-windows-555524.tar.bz2 name windows @@ -2462,9 +2462,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - c23c6480c7cbea60a2bd26e257adc0a7 + 5a55cede40eef16b9d1e47c418a2b77a url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/64068/601177/nghttp2-1.40.0.545354-windows64-545354.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76358/727359/nghttp2-1.40.0.555524-windows64-555524.tar.bz2 name windows64 @@ -2473,7 +2473,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors source_type hg version - 1.40.0.545354 + 1.40.0.555524 nvapi -- cgit v1.2.3 From cbee72276dfee6d84175177b7132cd310912db33 Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Mon, 1 Feb 2021 03:27:52 +0200 Subject: DRTVWR-520 Updated xmlrpc-epi to codeticket build 555529 --- autobuild.xml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index abdd3ec2d8..81a08e9462 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3340,9 +3340,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 99ea1808ee9f5b55029daa9fdef86776 + 922a0dea32266897ed1911200438e1e1 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/55063/512104/xmlrpc_epi-0.54.1.539072-darwin64-539072.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76372/727426/xmlrpc_epi-0.54.1.555529-darwin64-555529.tar.bz2 name darwin64 @@ -3376,9 +3376,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 94643b7cebb449f049fa9e32ae682bcd + 34b847e6b280048465fe7c6ce67fe05c url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/55138/512288/xmlrpc_epi-0.54.1.539072-windows-539072.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76374/727436/xmlrpc_epi-0.54.1.555529-windows-555529.tar.bz2 name windows @@ -3388,16 +3388,16 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - c409de1974a879291ce7daaf52348d85 + 8fbe7c4ea22bb7f23a93c73884ebb34c url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/55137/512279/xmlrpc_epi-0.54.1.539072-windows64-539072.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76373/727435/xmlrpc_epi-0.54.1.555529-windows64-555529.tar.bz2 name windows64 version - 0.54.1.539072 + 0.54.1.555529 zlib -- cgit v1.2.3 From 1fd44923b5e7f89fafe51471b7d83baf0339877d Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Mon, 1 Feb 2021 04:00:41 +0200 Subject: DRTVWR-520 Updated dullahan to codeticket build 555532 --- autobuild.xml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 81a08e9462..87bc308f85 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -580,9 +580,9 @@ archive hash - cc26af2ebfa241891caca829a6e46b88 + ecba88ae8fccfa5f52e51af596608c43 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/65005/607316/dullahan-1.7.0.202008031101_81.3.10_gb223419_chromium-81.0.4044.138-darwin64-546064.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76379/727449/dullahan-1.7.0.202102010142_81.3.10_gb223419_chromium-81.0.4044.138-darwin64-555532.tar.bz2 name darwin64 @@ -592,9 +592,9 @@ archive hash - 4e5b9e2fe65d94e30a4f3d831c767199 + 612ce2190e068ac34dc76861b3762e4f url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/65004/607304/dullahan-1.7.0.202008031759_81.3.10_gb223419_chromium-81.0.4044.138-windows-546064.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76383/727462/dullahan-1.7.0.202102010146_81.3.10_gb223419_chromium-81.0.4044.138-windows-555532.tar.bz2 name windows @@ -604,16 +604,16 @@ archive hash - 6f7bf7f915f3d75dbdad08a2d41ca74e + 59468c3908a6e61e095cf7bc08023ef7 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/65003/607308/dullahan-1.7.0.202008031800_81.3.10_gb223419_chromium-81.0.4044.138-windows64-546064.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76382/727466/dullahan-1.7.0.202102010146_81.3.10_gb223419_chromium-81.0.4044.138-windows64-555532.tar.bz2 name windows64 version - 1.7.0.202008031800_81.3.10_gb223419_chromium-81.0.4044.138 + 1.7.0.202102010146_81.3.10_gb223419_chromium-81.0.4044.138 elfio -- cgit v1.2.3 From fd8eab7e6126d5f92d0051bf551fa112dff198ac Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Wed, 10 Feb 2021 13:14:28 +0200 Subject: DRTVWR-520 Updated fmod to codeticket build 555876 --- autobuild.xml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 23ad979779..1f65879d77 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -748,9 +748,9 @@ archive hash - 89c37441a806ed80c0102d380eec6fd0 + 2995f0347fb20ae00a907c42ea5b4610 url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/65400/612632/fmodstudio-2.00.11.546392-darwin64-546392.tar.bz2 + https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/76852/730658/fmodstudio-2.01.07.555876-darwin64-555876.tar.bz2 name darwin64 @@ -784,9 +784,9 @@ archive hash - 0f44323b0d03b7d0d8a17eec83e103ce + d2d07717252e41f93afa4d6e5a4fee82 url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/65401/612647/fmodstudio-2.00.11.546392-windows-546392.tar.bz2 + https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/76854/730670/fmodstudio-2.01.07.555876-windows-555876.tar.bz2 name windows @@ -796,16 +796,16 @@ archive hash - 462d28eacf731a5d36ab031e7071c32a + 88c9e27c6b69e1833dadf4f23686f34a url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/65402/612648/fmodstudio-2.00.11.546392-windows64-546392.tar.bz2 + https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/76853/730669/fmodstudio-2.01.07.555876-windows64-555876.tar.bz2 name windows64 version - 2.00.11.546392 + 2.01.07.555876 fontconfig -- cgit v1.2.3 From 127446d9c84609aa2740f2987371999057753781 Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Wed, 10 Feb 2021 13:39:10 +0200 Subject: xcode buildfix --- indra/llplugin/llpluginprocessparent.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp index 7d18bae947..e5b4dec1bd 100644 --- a/indra/llplugin/llpluginprocessparent.cpp +++ b/indra/llplugin/llpluginprocessparent.cpp @@ -154,9 +154,9 @@ void LLPluginProcessParent::shutdown() { EState state = (*it).second->mState; if (state != STATE_CLEANUP - || state != STATE_EXITING - || state != STATE_DONE - || state != STATE_ERROR) + && state != STATE_EXITING + && state != STATE_DONE + && state != STATE_ERROR) { (*it).second->setState(STATE_GOODBYE); } -- cgit v1.2.3 From fc166dabc08d44b0956a43130cd2bd2e6722b854 Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Wed, 10 Feb 2021 15:59:04 +0200 Subject: DRTVWR-520 Updated fmod to codeticket build 555883 --- autobuild.xml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 1f65879d77..31f0a4e3cb 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -748,9 +748,9 @@ archive hash - 2995f0347fb20ae00a907c42ea5b4610 + d5528538e67c710387ae0c061a90cb23 url - https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/76852/730658/fmodstudio-2.01.07.555876-darwin64-555876.tar.bz2 + https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/76868/730756/fmodstudio-2.01.07.555883-darwin64-555883.tar.bz2 name darwin64 @@ -784,9 +784,9 @@ archive hash - d2d07717252e41f93afa4d6e5a4fee82 + a2bb6eaf51f933993b26a5fe7503a761 url - https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/76854/730670/fmodstudio-2.01.07.555876-windows-555876.tar.bz2 + https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/76869/730763/fmodstudio-2.01.07.555883-windows-555883.tar.bz2 name windows @@ -796,16 +796,16 @@ archive hash - 88c9e27c6b69e1833dadf4f23686f34a + 138d07dd516a9ad5b9787192fe6134dd url - https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/76853/730669/fmodstudio-2.01.07.555876-windows64-555876.tar.bz2 + https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/76867/730751/fmodstudio-2.01.07.555883-windows64-555883.tar.bz2 name windows64 version - 2.01.07.555876 + 2.01.07.555883 fontconfig -- cgit v1.2.3 From e320a463ac20cd064707f66f95d7e91531c7bb29 Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Wed, 10 Feb 2021 22:02:59 +0200 Subject: DRTVWR-520 Updated dullahan to codeticket build 555904 --- autobuild.xml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 31f0a4e3cb..61ea281b99 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -580,9 +580,9 @@ archive hash - ecba88ae8fccfa5f52e51af596608c43 + 46124156a4148d61c849d328c8659f78 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76379/727449/dullahan-1.7.0.202102010142_81.3.10_gb223419_chromium-81.0.4044.138-darwin64-555532.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76900/730915/dullahan-1.7.0.202102101914_81.3.10_gb223419_chromium-81.0.4044.138-darwin64-555904.tar.bz2 name darwin64 @@ -592,9 +592,9 @@ archive hash - 612ce2190e068ac34dc76861b3762e4f + d801e6c21333c94a7a04177aa91d5c1c url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76383/727462/dullahan-1.7.0.202102010146_81.3.10_gb223419_chromium-81.0.4044.138-windows-555532.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76901/730924/dullahan-1.7.0.202102101918_81.3.10_gb223419_chromium-81.0.4044.138-windows-555904.tar.bz2 name windows @@ -604,16 +604,16 @@ archive hash - 59468c3908a6e61e095cf7bc08023ef7 + dde4748dca0a75c6af30eca584e43352 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76382/727466/dullahan-1.7.0.202102010146_81.3.10_gb223419_chromium-81.0.4044.138-windows64-555532.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76902/730930/dullahan-1.7.0.202102101918_81.3.10_gb223419_chromium-81.0.4044.138-windows64-555904.tar.bz2 name windows64 version - 1.7.0.202102010146_81.3.10_gb223419_chromium-81.0.4044.138 + 1.7.0.202102101918_81.3.10_gb223419_chromium-81.0.4044.138 elfio -- cgit v1.2.3 From c2660c152fd5b86d6b8d2fc9053799ad0102962d Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Tue, 23 Feb 2021 23:07:12 +0200 Subject: DRTVWR-520 Updated boost to codeticket build 556301 --- autobuild.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 61ea281b99..01e471813a 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -166,9 +166,9 @@ archive hash - 3cc73623c9a976b4f8346a3837f7a916 + 3c0e9cfeb2a1c099a068aa999a54a1ce url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/64088/601256/boost-1.72-darwin64-545361.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/77456/734789/boost-1.72-darwin64-556301.tar.bz2 name darwin64 @@ -202,9 +202,9 @@ archive hash - 7d4b2511976449e9a4ec7be41dc8310f + 2f5b314539617871e9d104f1f83f0ccd url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/64092/601270/boost-1.72-windows-545361.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/77458/734770/boost-1.72-windows-556301.tar.bz2 name windows @@ -214,9 +214,9 @@ archive hash - 4ad8df0700745201cddf6b71d7b0949f + e8cdfffa30c85229befb0c901fedb7e3 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/64091/601265/boost-1.72-windows64-545361.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/77459/734776/boost-1.72-windows64-556301.tar.bz2 name windows64 -- cgit v1.2.3 From a0335671d527d40c3be50bf877837da2dc979096 Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Tue, 23 Feb 2021 23:34:25 +0200 Subject: DRTVWR-520 Updated googlemock to codeticket build 556304 --- autobuild.xml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 01e471813a..2d1e68afa5 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -1262,9 +1262,9 @@ archive hash - f9831360ced94943ab9dfb3fbf5256d3 + e280519baadf8369b4d7d1cd00506b49 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/64101/601290/googlemock-1.7.0.545363-darwin64-545363.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/77465/734807/googlemock-1.7.0.556304-darwin64-556304.tar.bz2 name darwin64 @@ -1298,9 +1298,9 @@ archive hash - 8149e46b4f7abb3ac284415cfe1366e1 + d4d5b681cb2d0a214bba2ad54a36dea9 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/64102/601296/googlemock-1.7.0.545363-windows-545363.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/77466/734805/googlemock-1.7.0.556304-windows-556304.tar.bz2 name windows @@ -1310,16 +1310,16 @@ archive hash - f3851eba809ead2810d702041569d36d + 5dfc8cc3160a6954757cebdeaaa30376 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/64100/601284/googlemock-1.7.0.545363-windows64-545363.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/77467/734815/googlemock-1.7.0.556304-windows64-556304.tar.bz2 name windows64 version - 1.7.0.545363 + 1.7.0.556304 gstreamer -- cgit v1.2.3 From 5f4f0d2936d8ca5f58be4be7572c3207b304a3b0 Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Tue, 23 Feb 2021 23:59:11 +0200 Subject: DRTVWR-520 Updated colladadom to codeticket build 556305 --- autobuild.xml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 2d1e68afa5..c3d7c03121 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -308,9 +308,9 @@ archive hash - 02e6a8207dcdaf243dcb6da19b8c3534 + 3250ad7a5e12e8656b0aa4701b38ad3a url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/64099/601302/colladadom-2.3.545362-darwin64-545362.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/77469/734822/colladadom-2.3.556305-darwin64-556305.tar.bz2 name darwin64 @@ -344,9 +344,9 @@ archive hash - 8a02a10fc69c8f504dc5335644db184a + 20b8a8395bbd8e86f48c75bf8fc2e642 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/64104/601313/colladadom-2.3.545362-windows-545362.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/77468/734828/colladadom-2.3.556305-windows-556305.tar.bz2 name windows @@ -356,16 +356,16 @@ archive hash - 742180324fca7ab92b6a61a36aab4f9d + bc88fdd32fd7d005c7dfc58c82260a29 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/64103/601314/colladadom-2.3.545362-windows64-545362.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/77470/734834/colladadom-2.3.556305-windows64-556305.tar.bz2 name windows64 version - 2.3.545362 + 2.3.556305 curl -- cgit v1.2.3 From 0e291f6c9722cecc8f1008543cafdf9c432b9f17 Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Mon, 22 Feb 2021 23:42:48 +0200 Subject: xcode buildfix --- indra/llcommon/llsingleton.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/llcommon/llsingleton.cpp b/indra/llcommon/llsingleton.cpp index 83a4b64e8f..ad933154c2 100644 --- a/indra/llcommon/llsingleton.cpp +++ b/indra/llcommon/llsingleton.cpp @@ -388,7 +388,7 @@ LLSingletonBase::vec_t LLSingletonBase::dep_sort() // extracts just the first (key) element from each sorted_iterator, then // uses vec_t's range constructor... but frankly this is more // straightforward, as long as we remember the above reserve() call! - for (const SingletonDeps::sorted_iterator::value_type& pair : sdeps.sort()) + for (const SingletonDeps::sorted_iterator::value_type pair : sdeps.sort()) { ret.push_back(pair.first); } -- cgit v1.2.3 From 6b73a8331f558f29903b797dedc09c7419958fdb Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 17 Mar 2021 00:19:38 +0200 Subject: SL-14541 removed breakpad, win_crash_logger, updated zlib --- autobuild.xml | 214 +++------- indra/CMakeLists.txt | 3 - indra/cmake/CMakeLists.txt | 2 - indra/cmake/FindGoogleBreakpad.cmake | 40 -- indra/cmake/GoogleBreakpad.cmake | 22 - indra/llcommon/CMakeLists.txt | 3 - indra/llcommon/llapp.cpp | 169 -------- indra/llcommon/llapp.h | 8 - indra/newview/CMakeLists.txt | 61 +-- indra/newview/generate_breakpad_symbols.py | 166 -------- indra/newview/llappviewer.cpp | 2 +- indra/newview/llappviewer.h | 1 - indra/newview/llappviewerwin32.cpp | 54 --- indra/newview/llappviewerwin32.h | 1 - indra/newview/viewer_manifest.py | 5 - indra/win_crash_logger/CMakeLists.txt | 105 ----- indra/win_crash_logger/StdAfx.cpp | 34 -- indra/win_crash_logger/StdAfx.h | 56 --- indra/win_crash_logger/ll_icon.ico | Bin 2238 -> 0 bytes indra/win_crash_logger/llcrashloggerwindows.cpp | 536 ------------------------ indra/win_crash_logger/llcrashloggerwindows.h | 86 ---- indra/win_crash_logger/resource.h | 63 --- indra/win_crash_logger/win_crash_logger.cpp | 70 ---- indra/win_crash_logger/win_crash_logger.h | 38 -- indra/win_crash_logger/win_crash_logger.ico | Bin 1078 -> 0 bytes indra/win_crash_logger/win_crash_logger.rc | 188 --------- 26 files changed, 65 insertions(+), 1862 deletions(-) delete mode 100644 indra/cmake/FindGoogleBreakpad.cmake delete mode 100644 indra/cmake/GoogleBreakpad.cmake delete mode 100755 indra/newview/generate_breakpad_symbols.py delete mode 100644 indra/win_crash_logger/CMakeLists.txt delete mode 100644 indra/win_crash_logger/StdAfx.cpp delete mode 100644 indra/win_crash_logger/StdAfx.h delete mode 100644 indra/win_crash_logger/ll_icon.ico delete mode 100644 indra/win_crash_logger/llcrashloggerwindows.cpp delete mode 100644 indra/win_crash_logger/llcrashloggerwindows.h delete mode 100644 indra/win_crash_logger/resource.h delete mode 100644 indra/win_crash_logger/win_crash_logger.cpp delete mode 100644 indra/win_crash_logger/win_crash_logger.h delete mode 100644 indra/win_crash_logger/win_crash_logger.ico delete mode 100755 indra/win_crash_logger/win_crash_logger.rc diff --git a/autobuild.xml b/autobuild.xml index c3d7c03121..6c43fa7bc2 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -166,9 +166,9 @@ archive hash - 3c0e9cfeb2a1c099a068aa999a54a1ce + 35cc090d942b85c9126ceac9912d52d6 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/77456/734789/boost-1.72-darwin64-556301.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78585/744021/boost-1.72-darwin64-557045.tar.bz2 name darwin64 @@ -202,9 +202,9 @@ archive hash - 2f5b314539617871e9d104f1f83f0ccd + 9aa4ce32df5f5e36124c990e2d77b885 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/77458/734770/boost-1.72-windows-556301.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78586/743982/boost-1.72-windows-557045.tar.bz2 name windows @@ -214,9 +214,9 @@ archive hash - e8cdfffa30c85229befb0c901fedb7e3 + a79511c9d8b956767ebaa405155d4238 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/77459/734776/boost-1.72-windows64-556301.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78584/743961/boost-1.72-windows64-557045.tar.bz2 name windows64 @@ -308,9 +308,9 @@ archive hash - 3250ad7a5e12e8656b0aa4701b38ad3a + 1d063cf1783e7788f17486c234adb1db url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/77469/734822/colladadom-2.3.556305-darwin64-556305.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78635/744249/colladadom-2.3.557064-darwin64-557064.tar.bz2 name darwin64 @@ -344,9 +344,9 @@ archive hash - 20b8a8395bbd8e86f48c75bf8fc2e642 + e78ecf919eee01567556787c3a358d15 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/77468/734828/colladadom-2.3.556305-windows-556305.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78637/744269/colladadom-2.3.557064-windows-557064.tar.bz2 name windows @@ -356,16 +356,16 @@ archive hash - bc88fdd32fd7d005c7dfc58c82260a29 + 7e63a212c8909a25236138422fe01298 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/77470/734834/colladadom-2.3.556305-windows64-556305.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78636/744273/colladadom-2.3.557064-windows64-557064.tar.bz2 name windows64 version - 2.3.556305 + 2.3.557064 curl @@ -398,9 +398,9 @@ archive hash - d4c8b00a88e879bd1a7e6805af2ccb1c + 7295ca3234ab21a98c39604f3b0985cb url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76361/727381/curl-7.54.1.555526-darwin64-555526.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78596/744055/curl-7.54.1.557049-darwin64-557049.tar.bz2 name darwin64 @@ -434,11 +434,11 @@ archive hash - 0bca1f79fc78b0045de18f69fea03093 + 0c31fa12a33ecc946c0c69259b6367a9 hash_algorithm md5 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76362/727375/curl-7.54.1.555526-windows-555526.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78598/744050/curl-7.54.1.557049-windows-557049.tar.bz2 name windows @@ -448,16 +448,16 @@ archive hash - cca8ff1d59fcfc64e99c79a950f3abc1 + 4c4d5971a59ae2e1f4467667df2a9aa4 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76360/727374/curl-7.54.1.555526-windows64-555526.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78597/744044/curl-7.54.1.557049-windows64-557049.tar.bz2 name windows64 version - 7.54.1.555526 + 7.54.1.557049 db @@ -880,9 +880,9 @@ archive hash - 81a2e9aca3e33c4eecf0081854540b07 + 3a478d6c8a10d49d9161ef864394b03c url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/56309/526711/freetype-2.4.4.539865-darwin64-539865.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78592/744013/freetype-2.4.4.557047-darwin64-557047.tar.bz2 name darwin64 @@ -916,9 +916,9 @@ archive hash - 1d1c7b60f71a5152ced60bee87f5bba8 + 7ee200d6b5fa282c7f973ade5615aa86 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/56312/526734/freetype-2.4.4.539865-windows-539865.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78594/744011/freetype-2.4.4.557047-windows-557047.tar.bz2 name windows @@ -928,16 +928,16 @@ archive hash - 53e78d4a607e959637e98a82a3cf5bea + 69307aaba16ac71531c9c4d930ace993 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/56310/526723/freetype-2.4.4.539865-windows64-539865.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78593/744010/freetype-2.4.4.557047-windows64-557047.tar.bz2 name windows64 version - 2.4.4.539865 + 2.4.4.557047 glext @@ -1141,96 +1141,6 @@ version 1.0pre3.555522 - google_breakpad - - copyright - Copyright (c) 2006, Google Inc. - description - Breakpad is a crossplatform library for capturing crash callstacks and runtime data. - license - bsd - license_file - LICENSES/google_breakpad.txt - name - google_breakpad - platforms - - darwin - - archive - - hash - 171b39db6d0702535b41fad5b476e39d - url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/google-breakpad_3p-update-google-breakpad/rev/298033/arch/Darwin/installer/google_breakpad-1413.298033-darwin-298033.tar.bz2 - - name - darwin - - darwin64 - - archive - - hash - ca33f234aae399b9e704e262f7e15d35 - url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/56338/526869/google_breakpad-1413.539880-darwin64-539880.tar.bz2 - - name - darwin64 - - linux - - archive - - hash - 352e673897e8f36f8470150b8ace6ce9 - url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-google-breakpad/rev/314225/arch/Linux/installer/google_breakpad-1413.314225-linux-314225.tar.bz2 - - name - linux - - linux64 - - archive - - hash - 6bddcc1ac470dd5eab459220102df9e9 - url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1835/4114/google_breakpad-1413.501824-linux64-501824.tar.bz2 - - name - linux64 - - windows - - archive - - hash - bfee0438617f57f02f7e8515a801cb20 - url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/56359/526982/google_breakpad-1413.539880-windows-539880.tar.bz2 - - name - windows - - windows64 - - archive - - hash - 6f983e754bb3046f065806b510b408c5 - url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/56358/526975/google_breakpad-1413.539880-windows64-539880.tar.bz2 - - name - windows64 - - - version - 1413.539880 - googlemock copyright @@ -1262,9 +1172,9 @@ archive hash - e280519baadf8369b4d7d1cd00506b49 + 19e925604bc1a91efb4b130e1edd8bf2 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/77465/734807/googlemock-1.7.0.556304-darwin64-556304.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78620/744140/googlemock-1.7.0.557057-darwin64-557057.tar.bz2 name darwin64 @@ -1298,9 +1208,9 @@ archive hash - d4d5b681cb2d0a214bba2ad54a36dea9 + eed7b41d0d1f41b24f315349ef78c728 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/77466/734805/googlemock-1.7.0.556304-windows-556304.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78622/744148/googlemock-1.7.0.557057-windows-557057.tar.bz2 name windows @@ -1310,16 +1220,16 @@ archive hash - 5dfc8cc3160a6954757cebdeaaa30376 + a6ad6fe722d2fe4e8137495af3f374c9 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/77467/734815/googlemock-1.7.0.556304-windows64-556304.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78621/744152/googlemock-1.7.0.557057-windows64-557057.tar.bz2 name windows64 version - 1.7.0.556304 + 1.7.0.557057 gstreamer @@ -1948,9 +1858,9 @@ archive hash - 0932b19bb6a8e2641706afd13d92951d + 2a41acc3116ce19a443873216cb882ad url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/56313/526740/libpng-1.6.8.539868-darwin64-539868.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78587/743948/libpng-1.6.8.557046-darwin64-557046.tar.bz2 name darwin64 @@ -1984,9 +1894,9 @@ archive hash - f498782698428888113b64a7505c8f7f + b935b440947f63c69700bdcf5095a8e1 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/56319/526770/libpng-1.6.8.539868-windows-539868.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78591/743970/libpng-1.6.8.557046-windows-557046.tar.bz2 name windows @@ -1996,16 +1906,16 @@ archive hash - f8ac4f690a2925418866bccf6eba3cf4 + d1cc8354ac4e877eefedf16b1be3aac6 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/56317/526762/libpng-1.6.8.539868-windows64-539868.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78589/743991/libpng-1.6.8.557046-windows64-557046.tar.bz2 name windows64 version - 1.6.8.539868 + 1.6.8.557046 libuuid @@ -2080,9 +1990,9 @@ archive hash - 0706b9c3889d767af9f5105d9ffa9b51 + 6677173bbbb0ea32369b5e9b6c9aa641 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/56327/526819/libxml2-2.9.4.539866-darwin64-539866.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78631/744225/libxml2-2.9.4.557062-darwin64-557062.tar.bz2 name darwin64 @@ -2116,9 +2026,9 @@ archive hash - 1b7b979a8387fbb0f278dc681558b9ef + ad6a596fbf0e83a21d95762da78437bc url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/56316/526755/libxml2-2.9.4.539866-windows-539866.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78633/744239/libxml2-2.9.4.557062-windows-557062.tar.bz2 name windows @@ -2128,16 +2038,16 @@ archive hash - 4f8ff97d6a9ab350306b62eec8adc810 + 6b5bb230684ecf28386d7c91c47bb6e1 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/56314/526748/libxml2-2.9.4.539866-windows64-539866.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78634/744240/libxml2-2.9.4.557062-windows64-557062.tar.bz2 name windows64 version - 2.9.4.539866 + 2.9.4.557062 llappearance_utility @@ -2828,9 +2738,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 18aef0c8fc471b6539addbdc019aea25 + 166aa05b379b13156de5821252040498 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/56325/526804/openssl-1.0.2l.539874-darwin64-539874.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78582/743936/openssl-1.0.2l.557043-darwin64-557043.tar.bz2 name darwin64 @@ -2864,9 +2774,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 2b2f61313b1cbd2893c1ba5bf15061fa + 68aae05216c035283c79aad6dd88d8da url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/56328/526826/openssl-1.0.2l.539874-windows-539874.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78590/743992/openssl-1.0.2l.557043-windows-557043.tar.bz2 name windows @@ -2876,16 +2786,16 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 59aae854155bc7119e0dca25e65828c0 + d2576a386559cefb654154d8f0de6337 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/56326/526811/openssl-1.0.2l.539874-windows64-539874.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78588/743976/openssl-1.0.2l.557043-windows64-557043.tar.bz2 name windows64 version - 1.0.2l.539874 + 1.0.2l.557043 pcre @@ -3430,9 +3340,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 9785bda5b4d3b41bf391b33d0da78c9e + 9181bc8229f1a8e480d2a40a2744ec28 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/54858/510190/zlib-1.2.8.538988-darwin64-538988.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78578/743913/zlib-1.2.11.557041-darwin64-557041.tar.bz2 name darwin64 @@ -3468,9 +3378,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - ebdb07d4aaa5312005a8773f625032a4 + 8308cbd2ea0fe290541698b0f63482e2 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/55048/512031/zlib-1.2.8.538988-windows-538988.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78579/743926/zlib-1.2.11.557041-windows-557041.tar.bz2 name windows @@ -3480,16 +3390,16 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 0ac95f3dece7d575ba45cf5728f53eea + 36bdc34f67d3ad3c57125dc1b16a3129 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/55047/512024/zlib-1.2.8.538988-windows64-538988.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78577/743920/zlib-1.2.11.557041-windows64-557041.tar.bz2 name windows64 version - 1.2.8.538988 + 1.2.11.557041 package_description diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt index 53e5d7b6a5..f5e814187d 100644 --- a/indra/CMakeLists.txt +++ b/indra/CMakeLists.txt @@ -74,13 +74,10 @@ elseif (DARWIN) add_subdirectory(${VIEWER_PREFIX}mac_crash_logger) add_dependencies(viewer mac-crash-logger) elseif (WINDOWS) - add_subdirectory(${VIEWER_PREFIX}win_crash_logger) # cmake EXISTS requires an absolute path, see indra/cmake/Variables.cmake if (EXISTS ${VIEWER_DIR}win_setup) add_subdirectory(${VIEWER_DIR}win_setup) endif (EXISTS ${VIEWER_DIR}win_setup) - # add_dependencies(viewer windows-setup windows-crash-logger) - add_dependencies(viewer windows-crash-logger) endif (LINUX) add_subdirectory(${VIEWER_PREFIX}newview) diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt index a17e37cd32..cca305c741 100644 --- a/indra/cmake/CMakeLists.txt +++ b/indra/cmake/CMakeLists.txt @@ -28,7 +28,6 @@ set(cmake_SOURCE_FILES FindAutobuild.cmake FindBerkeleyDB.cmake FindGLH.cmake - FindGoogleBreakpad.cmake FindHUNSPELL.cmake FindJsonCpp.cmake FindNDOF.cmake @@ -43,7 +42,6 @@ set(cmake_SOURCE_FILES GLH.cmake GLOD.cmake ## GStreamer010Plugin.cmake - GoogleBreakpad.cmake GoogleMock.cmake Havok.cmake Hunspell.cmake diff --git a/indra/cmake/FindGoogleBreakpad.cmake b/indra/cmake/FindGoogleBreakpad.cmake deleted file mode 100644 index 1a0493be5e..0000000000 --- a/indra/cmake/FindGoogleBreakpad.cmake +++ /dev/null @@ -1,40 +0,0 @@ -# -*- cmake -*- - -# - Find Google BreakPad -# Find the Google BreakPad includes and library -# This module defines -# BREAKPAD_EXCEPTION_HANDLER_INCLUDE_DIR, where to find exception_handler.h, etc. -# BREAKPAD_EXCEPTION_HANDLER_LIBRARIES, the libraries needed to use Google BreakPad. -# BREAKPAD_EXCEPTION_HANDLER_FOUND, If false, do not try to use Google BreakPad. -# also defined, but not for general use are -# BREAKPAD_EXCEPTION_HANDLER_LIBRARY, where to find the Google BreakPad library. - -FIND_PATH(BREAKPAD_EXCEPTION_HANDLER_INCLUDE_DIR google_breakpad/exception_handler.h) - -SET(BREAKPAD_EXCEPTION_HANDLER_NAMES ${BREAKPAD_EXCEPTION_HANDLER_NAMES} breakpad_client) -FIND_LIBRARY(BREAKPAD_EXCEPTION_HANDLER_LIBRARY - NAMES ${BREAKPAD_EXCEPTION_HANDLER_NAMES} - ) - -IF (BREAKPAD_EXCEPTION_HANDLER_LIBRARY AND BREAKPAD_EXCEPTION_HANDLER_INCLUDE_DIR) - SET(BREAKPAD_EXCEPTION_HANDLER_LIBRARIES ${BREAKPAD_EXCEPTION_HANDLER_LIBRARY}) - SET(BREAKPAD_EXCEPTION_HANDLER_FOUND "YES") -ELSE (BREAKPAD_EXCEPTION_HANDLER_LIBRARY AND BREAKPAD_EXCEPTION_HANDLER_INCLUDE_DIR) - SET(BREAKPAD_EXCEPTION_HANDLER_FOUND "NO") -ENDIF (BREAKPAD_EXCEPTION_HANDLER_LIBRARY AND BREAKPAD_EXCEPTION_HANDLER_INCLUDE_DIR) - - -IF (BREAKPAD_EXCEPTION_HANDLER_FOUND) - IF (NOT BREAKPAD_EXCEPTION_HANDLER_FIND_QUIETLY) - MESSAGE(STATUS "Found Google BreakPad: ${BREAKPAD_EXCEPTION_HANDLER_LIBRARIES}") - ENDIF (NOT BREAKPAD_EXCEPTION_HANDLER_FIND_QUIETLY) -ELSE (BREAKPAD_EXCEPTION_HANDLER_FOUND) - IF (BREAKPAD_EXCEPTION_HANDLER_FIND_REQUIRED) - MESSAGE(FATAL_ERROR "Could not find Google BreakPad library") - ENDIF (BREAKPAD_EXCEPTION_HANDLER_FIND_REQUIRED) -ENDIF (BREAKPAD_EXCEPTION_HANDLER_FOUND) - -MARK_AS_ADVANCED( - BREAKPAD_EXCEPTION_HANDLER_LIBRARY - BREAKPAD_EXCEPTION_HANDLER_INCLUDE_DIR - ) diff --git a/indra/cmake/GoogleBreakpad.cmake b/indra/cmake/GoogleBreakpad.cmake deleted file mode 100644 index 829e1ac08a..0000000000 --- a/indra/cmake/GoogleBreakpad.cmake +++ /dev/null @@ -1,22 +0,0 @@ -# -*- cmake -*- -include(Prebuilt) - -if (USESYSTEMLIBS) - set(BREAKPAD_EXCEPTION_HANDLER_FIND_REQUIRED ON) - include(FindGoogleBreakpad) -else (USESYSTEMLIBS) - use_prebuilt_binary(google_breakpad) - if (DARWIN) - set(BREAKPAD_EXCEPTION_HANDLER_LIBRARIES exception_handler) - endif (DARWIN) - if (LINUX) - set(BREAKPAD_EXCEPTION_HANDLER_LIBRARIES breakpad_client) - endif (LINUX) - if (WINDOWS) - set(BREAKPAD_EXCEPTION_HANDLER_LIBRARIES exception_handler crash_generation_client crash_generation_server common) - endif (WINDOWS) - # yes, this does look dumb, no, it's not incorrect - # - set(BREAKPAD_INCLUDE_DIRECTORIES "${LIBS_PREBUILT_DIR}/include/google_breakpad" "${LIBS_PREBUILT_DIR}/include/google_breakpad/google_breakpad") -endif (USESYSTEMLIBS) - diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index eeb315ead6..9cc7121253 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -8,7 +8,6 @@ include(Linking) include(Boost) include(LLSharedLibs) include(JsonCpp) -include(GoogleBreakpad) include(Copy3rdPartyLibs) include(ZLIB) include(URIPARSER) @@ -18,7 +17,6 @@ include_directories( ${LLCOMMON_INCLUDE_DIRS} ${JSONCPP_INCLUDE_DIR} ${ZLIB_INCLUDE_DIRS} - ${BREAKPAD_INCLUDE_DIRECTORIES} ${URIPARSER_INCLUDE_DIRS} ) @@ -285,7 +283,6 @@ endif(LLCOMMON_LINK_SHARED) target_link_libraries( llcommon - ${BREAKPAD_EXCEPTION_HANDLER_LIBRARIES} ${APRUTIL_LIBRARIES} ${APR_LIBRARIES} ${EXPAT_LIBRARIES} diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index a90b294550..c9e4cf2ab3 100644 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -46,7 +46,6 @@ #include "llstl.h" // for DeletePointer() #include "llstring.h" #include "lleventtimer.h" -#include "google_breakpad/exception_handler.h" #include "stringize.h" #include "llcleanup.h" #include "llevents.h" @@ -62,12 +61,6 @@ LONG WINAPI default_windows_exception_handler(struct _EXCEPTION_POINTERS *exception_infop); BOOL ConsoleCtrlHandler(DWORD fdwCtrlType); -bool windows_post_minidump_callback(const wchar_t* dump_path, - const wchar_t* minidump_id, - void* context, - EXCEPTION_POINTERS* exinfo, - MDRawAssertionInfo* assertion, - bool succeeded); #else # include # include // for fork() @@ -146,8 +139,6 @@ void LLApp::commonCtor() // Set the application to this instance. sApplication = this; - - mExceptionHandler = 0; // initialize the buffer to write the minidump filename to // (this is used to avoid allocating memory in the crash handler) @@ -177,8 +168,6 @@ LLApp::~LLApp() delete mThreadErrorp; mThreadErrorp = NULL; } - - if(mExceptionHandler != 0) delete mExceptionHandler; SUBSYSTEM_CLEANUP_DBG(LLCommon); } @@ -394,69 +383,6 @@ void LLApp::setupErrorHandling(bool second_instance) #if LL_WINDOWS -#if LL_SEND_CRASH_REPORTS && ! defined(LL_BUGSPLAT) - EnableCrashingOnCrashes(); - - // This sets a callback to handle w32 signals to the console window. - // The viewer shouldn't be affected, sicne its a windowed app. - SetConsoleCtrlHandler( (PHANDLER_ROUTINE) ConsoleCtrlHandler, TRUE); - - // Install the Google Breakpad crash handler for Windows - if(mExceptionHandler == 0) - { - if ( second_instance ) //BUG-5707 Firing teleport from a web browser causes second - { - mExceptionHandler = new google_breakpad::ExceptionHandler( - L"C:\\Temp\\", - 0, //No filter - windows_post_minidump_callback, - 0, - google_breakpad::ExceptionHandler::HANDLER_ALL); //No custom client info. - } - else - { - LL_WARNS() << "adding breakpad exception handler" << LL_ENDL; - - std::wstring wpipe_name; - wpipe_name = mCrashReportPipeStr + wstringize(getPid()); - - const std::wstring wdump_path(utf8str_to_utf16str(mDumpPath)); - - int retries = 30; - for (; retries > 0; --retries) - { - if (mExceptionHandler != 0) delete mExceptionHandler; - - mExceptionHandler = new google_breakpad::ExceptionHandler( - wdump_path, - NULL, //No filter - windows_post_minidump_callback, - 0, - google_breakpad::ExceptionHandler::HANDLER_ALL, - MiniDumpNormal, //Generate a 'normal' minidump. - wpipe_name.c_str(), - NULL); //No custom client info. - if (mExceptionHandler->IsOutOfProcess()) - { - LL_INFOS("CRASHREPORT") << "Successfully attached to Out of Process exception handler." << LL_ENDL; - break; - } - else - { - LL_WARNS("CRASHREPORT") << "Unable to attach to Out of Process exception handler. " << retries << " retries remaining." << LL_ENDL; - ::Sleep(100); //Wait a tick and try again. - } - } - - if (retries == 0) LL_WARNS("CRASHREPORT") << "Unable to attach to Out of Process exception handler." << LL_ENDL; - } - - if (mExceptionHandler) - { - mExceptionHandler->set_handle_debug_exceptions(true); - } - } -#endif // LL_SEND_CRASH_REPORTS && ! defined(LL_BUGSPLAT) #else // ! LL_WINDOWS #if defined(LL_BUGSPLAT) @@ -609,31 +535,6 @@ void LLApp::setError() setStatus(APP_STATUS_ERROR); } -void LLApp::setMiniDumpDir(const std::string &path) -{ - if (path.empty()) - { - mDumpPath = "/tmp"; - } - else - { - mDumpPath = path; - } - - if(mExceptionHandler == 0) return; -#ifdef LL_WINDOWS - std::wstring buffer(utf8str_to_utf16str(mDumpPath)); - if (buffer.size() > MAX_MINDUMP_PATH_LENGTH) buffer.resize(MAX_MINDUMP_PATH_LENGTH); - mExceptionHandler->set_dump_path(buffer); -#elif LL_LINUX - //google_breakpad::MinidumpDescriptor desc("/tmp"); //path works in debug fails in production inside breakpad lib so linux gets a little less stack reporting until it is patched. - google_breakpad::MinidumpDescriptor desc(mDumpPath); //path works in debug fails in production inside breakpad lib so linux gets a little less stack reporting until it is patched. - mExceptionHandler->set_minidump_descriptor(desc); -#else - mExceptionHandler->set_dump_path(mDumpPath); -#endif -} - void LLApp::setDebugFileNames(const std::string &path) { mStaticDebugFileName = path + "static_debug_info.log"; @@ -642,8 +543,6 @@ void LLApp::setDebugFileNames(const std::string &path) void LLApp::writeMiniDump() { - if(mExceptionHandler == 0) return; - mExceptionHandler->WriteMinidump(); } // static @@ -700,13 +599,6 @@ bool LLApp::isExiting() void LLApp::disableCrashlogger() { - // Disable Breakpad exception handler. - if (mExceptionHandler != 0) - { - delete mExceptionHandler; - mExceptionHandler = 0; - } - sDisableCrashlogger = TRUE; } @@ -1095,64 +987,3 @@ bool unix_post_minidump_callback(const char *dump_dir, } #endif // !WINDOWS -#ifdef LL_WINDOWS -bool windows_post_minidump_callback(const wchar_t* dump_path, - const wchar_t* minidump_id, - void* context, - EXCEPTION_POINTERS* exinfo, - MDRawAssertionInfo* assertion, - bool succeeded) -{ - char * path = LLApp::instance()->getMiniDumpFilename(); - S32 remaining = LLApp::MAX_MINDUMP_PATH_LENGTH; - size_t bytesUsed; - - LL_INFOS("MINIDUMPCALLBACK") << "Dump file was generated." << LL_ENDL; - bytesUsed = wcstombs(path, dump_path, static_cast(remaining)); - remaining -= bytesUsed; - path += bytesUsed; - if(remaining > 0 && bytesUsed > 0 && path[-1] != '\\') - { - *path++ = '\\'; - --remaining; - } - if(remaining > 0) - { - bytesUsed = wcstombs(path, minidump_id, static_cast(remaining)); - remaining -= bytesUsed; - path += bytesUsed; - } - if(remaining > 0) - { - strncpy(path, ".dmp", remaining); - } - - LL_INFOS("CRASHREPORT") << "generated minidump: " << LLApp::instance()->getMiniDumpFilename() << LL_ENDL; - // *NOTE:Mani - this code is stolen from LLApp, where its never actually used. - //OSMessageBox("Attach Debugger Now", "Error", OSMB_OK); - // *TODO: Translate the signals/exceptions into cross-platform stuff - // Windows implementation - LL_INFOS() << "Entering Windows Exception Handler..." << LL_ENDL; - - if (LLApp::isError()) - { - LL_WARNS() << "Got another fatal signal while in the error handler, die now!" << LL_ENDL; - } - - // Flag status to error, so thread_error starts its work - LLApp::setError(); - - // Block in the exception handler until the app has stopped - // This is pretty sketchy, but appears to work just fine - while (!LLApp::isStopped()) - { - ms_sleep(10); - } - -#ifndef LL_RELEASE_FOR_DOWNLOAD - return false; -#else - return true; -#endif -} -#endif diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h index 245c73e3a2..e590e5eafd 100644 --- a/indra/llcommon/llapp.h +++ b/indra/llcommon/llapp.h @@ -49,10 +49,6 @@ void clear_signals(); #endif -namespace google_breakpad { - class ExceptionHandler; // See exception_handler.h -} - class LL_COMMON_API LLApp { friend class LLErrorThread; @@ -236,7 +232,6 @@ public: static const U32 MAX_MINDUMP_PATH_LENGTH = 256; // change the directory where Breakpad minidump files are written to - void setMiniDumpDir(const std::string &path); void setDebugFileNames(const std::string &path); // Return the Google Breakpad minidump filename after a crash. @@ -312,9 +307,6 @@ private: private: // the static application instance if it was created. static LLApp* sApplication; - - google_breakpad::ExceptionHandler * mExceptionHandler; - #if !LL_WINDOWS friend void default_unix_signal_handler(int signum, siginfo_t *info, void *); diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 3439951e80..1caf591860 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1830,7 +1830,6 @@ if (WINDOWS) media_plugin_libvlc media_plugin_example winmm_shim - windows-crash-logger ) if (ADDRESS_SIZE EQUAL 64) @@ -1897,7 +1896,6 @@ if (WINDOWS) add_dependencies(${VIEWER_BINARY_NAME} SLPlugin - windows-crash-logger ) # sets the 'working directory' for debugging from visual studio. @@ -2246,62 +2244,7 @@ endif (INSTALL) # Note that the conventional VIEWER_SYMBOL_FILE is set by ../../build.sh if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIEWER_SYMBOL_FILE) - if (NOT BUGSPLAT_DB) - # Breakpad symbol-file generation - set(SYMBOL_SEARCH_DIRS "") - if (WINDOWS) - list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}") - # slplugin.exe failing symbols dump - need to debug, might have to do with updated version of google breakpad - # set(VIEWER_EXE_GLOBS "${VIEWER_BINARY_NAME}${CMAKE_EXECUTABLE_SUFFIX} slplugin.exe") - set(VIEWER_EXE_GLOBS "${VIEWER_BINARY_NAME}${CMAKE_EXECUTABLE_SUFFIX}") - set(VIEWER_LIB_GLOB "*${CMAKE_SHARED_MODULE_SUFFIX}") - set(VIEWER_COPY_MANIFEST copy_w_viewer_manifest) - endif (WINDOWS) - if (DARWIN) - list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}") - # *TODO: Generate these search dirs in the cmake files related to each binary. - list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/llplugin/slplugin/${CMAKE_CFG_INTDIR}") - list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/mac_crash_logger/${CMAKE_CFG_INTDIR}") - list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/media_plugins/gstreamer010/${CMAKE_CFG_INTDIR}") - set(VIEWER_EXE_GLOBS "'${product}' SLPlugin mac-crash-logger") - set(VIEWER_EXE_GLOBS "'${product}' mac-crash-logger") - set(VIEWER_LIB_GLOB "*.dylib") - endif (DARWIN) - if (LINUX) - list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_CURRENT_BINARY_DIR}/packaged") - set(VIEWER_EXE_GLOBS "do-not-directly-run-secondlife-bin SLPlugin") - set(VIEWER_EXE_GLOBS "do-not-directly-run-secondlife-bin") - set(VIEWER_LIB_GLOB "*${CMAKE_SHARED_MODULE_SUFFIX}*") - set(VIEWER_COPY_MANIFEST copy_l_viewer_manifest) - endif (LINUX) - - if(CMAKE_CFG_INTDIR STREQUAL ".") - set(LLBUILD_CONFIG ${CMAKE_BUILD_TYPE}) - else(CMAKE_CFG_INTDIR STREQUAL ".") - # set LLBUILD_CONFIG to be a shell variable evaluated at build time - # reflecting the configuration we are currently building. - set(LLBUILD_CONFIG ${CMAKE_CFG_INTDIR}) - endif(CMAKE_CFG_INTDIR STREQUAL ".") - add_custom_command(OUTPUT "${VIEWER_SYMBOL_FILE}" - COMMAND "${PYTHON_EXECUTABLE}" - ARGS - "${CMAKE_CURRENT_SOURCE_DIR}/generate_breakpad_symbols.py" - "${LLBUILD_CONFIG}" - "${SYMBOL_SEARCH_DIRS}" - "${VIEWER_EXE_GLOBS}" - "${VIEWER_LIB_GLOB}" - "${AUTOBUILD_INSTALL_DIR}/bin/dump_syms" - "${VIEWER_SYMBOL_FILE}" - DEPENDS generate_breakpad_symbols.py - VERBATIM) - - add_custom_target(generate_symbols DEPENDS "${VIEWER_SYMBOL_FILE}" ${VIEWER_BINARY_NAME} "${VIEWER_COPY_MANIFEST}") - add_dependencies(generate_symbols ${VIEWER_BINARY_NAME}) - if (WINDOWS OR LINUX) - add_dependencies(generate_symbols "${VIEWER_COPY_MANIFEST}") - endif (WINDOWS OR LINUX) - - else (NOT BUGSPLAT_DB) + if (BUGSPLAT_DB) # BugSplat symbol-file generation if (WINDOWS) # Just pack up a tarball containing only the .pdb file for the @@ -2385,7 +2328,7 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE if (LINUX) # TBD endif (LINUX) - endif (NOT BUGSPLAT_DB) + endif (BUGSPLAT_DB) # for both BUGSPLAT_DB and Breakpad add_dependencies(llpackage generate_symbols) diff --git a/indra/newview/generate_breakpad_symbols.py b/indra/newview/generate_breakpad_symbols.py deleted file mode 100755 index d351c406bc..0000000000 --- a/indra/newview/generate_breakpad_symbols.py +++ /dev/null @@ -1,166 +0,0 @@ -#!/usr/bin/env python -"""\ -@file generate_breakpad_symbols.py -@author Brad Kittenbrink -@brief Simple tool for generating google_breakpad symbol information - for the crash reporter. - -$LicenseInfo:firstyear=2010&license=viewerlgpl$ -Second Life Viewer Source Code -Copyright (C) 2010-2011, Linden Research, Inc. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; -version 2.1 of the License only. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA -$/LicenseInfo$ -""" - - -import collections -import fnmatch -import itertools -import os -import re -import sys -import shlex -import subprocess -import tarfile -import StringIO -import pprint - -DEBUG=False - -def usage(): - print >>sys.stderr, "usage: %s search_dirs viewer_exes libs_suffix dump_syms_tool viewer_symbol_file" % sys.argv[0] - -class MissingModuleError(Exception): - def __init__(self, modules): - Exception.__init__(self, "Failed to find required modules: %r" % modules) - self.modules = modules - -def main(configuration, search_dirs, viewer_exes, libs_suffix, dump_syms_tool, viewer_symbol_file): - print "generate_breakpad_symbols run with args: %s" % str((configuration, search_dirs, viewer_exes, libs_suffix, dump_syms_tool, viewer_symbol_file)) - - if not re.match("release", configuration, re.IGNORECASE): - print "skipping breakpad symbol generation for non-release build." - return 0 - - # split up list of viewer_exes - # "'Second Life' SLPlugin" becomes ['Second Life', 'SLPlugin'] - viewer_exes = shlex.split(viewer_exes) - - found_required = dict([(module, False) for module in viewer_exes]) - - def matches(f): - if f in viewer_exes: - found_required[f] = True - return True - return fnmatch.fnmatch(f, libs_suffix) - - search_dirs = search_dirs.split(";") - - def list_files(): - for search_dir in search_dirs: - for (dirname, subdirs, filenames) in os.walk(search_dir): - if DEBUG: - print "scanning '%s' for modules..." % dirname - for f in itertools.ifilter(matches, filenames): - yield os.path.join(dirname, f) - - def dump_module(m): - print "dumping module '%s' with '%s'..." % (m, dump_syms_tool) - dsym_full_path = m - child = subprocess.Popen([dump_syms_tool, dsym_full_path] , stdout=subprocess.PIPE) - out, err = child.communicate() - return (m,child.returncode, out, err) - - - modules = {} - - for m in list_files(): - if DEBUG: - print "examining module '%s' ... " % m, - filename=os.path.basename(m) - if -1 != m.find("DWARF"): - # Just use this module; it has the symbols we want. - modules[filename] = m - if DEBUG: - print "found dSYM entry" - elif filename not in modules: - # Only use this if we don't already have a (possibly better) entry. - modules[filename] = m - if DEBUG: - print "found new entry" - elif DEBUG: - print "ignoring entry" - - - print "Found these following modules:" - pprint.pprint( modules ) - - out = tarfile.open(viewer_symbol_file, 'w:bz2') - for (filename,status,symbols,err) in itertools.imap(dump_module, modules.values()): - if status == 0: - module_line = symbols[:symbols.index('\n')] - module_line = module_line.split() - hash_id = module_line[3] - module = ' '.join(module_line[4:]) - if sys.platform in ['win32', 'cygwin']: - mod_name = module[:module.rindex('.pdb')] - else: - mod_name = module - symbolfile = StringIO.StringIO(symbols) - info = tarfile.TarInfo("%(module)s/%(hash_id)s/%(mod_name)s.sym" % dict(module=module, hash_id=hash_id, mod_name=mod_name)) - info.size = symbolfile.len - out.addfile(info, symbolfile) - else: - print >>sys.stderr, "warning: failed to dump symbols for '%s': %s" % (filename, err) - - out.close() - - missing_modules = [m for (m,_) in - itertools.ifilter(lambda (k,v): not v, found_required.iteritems()) - ] - if missing_modules: - print >> sys.stderr, "failed to generate %s" % viewer_symbol_file - os.remove(viewer_symbol_file) - raise MissingModuleError(missing_modules) - - symbols = tarfile.open(viewer_symbol_file, 'r:bz2') - tarfile_members = symbols.getnames() - symbols.close() - - for required_module in viewer_exes: - def match_module_basename(m): - return os.path.splitext(required_module)[0].lower() \ - == os.path.splitext(os.path.basename(m))[0].lower() - # there must be at least one .sym file in tarfile_members that matches - # each required module (ignoring file extensions) - if not any(itertools.imap(match_module_basename, tarfile_members)): - print >> sys.stderr, "failed to find required %s in generated %s" \ - % (required_module, viewer_symbol_file) - os.remove(viewer_symbol_file) - raise MissingModuleError([required_module]) - - print "successfully generated %s including required modules '%s'" % (viewer_symbol_file, viewer_exes) - - return 0 - -if __name__ == "__main__": - if len(sys.argv) != 7: - usage() - sys.exit(1) - sys.exit(main(*sys.argv[1:])) - diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index f518704e06..fd06e39245 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -736,7 +736,7 @@ LLAppViewer::LLAppViewer() std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, ""); #endif // ! LL_BUGSPLAT mDumpPath = logdir; - setMiniDumpDir(logdir); + setDebugFileNames(logdir); } diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index 5332fe2deb..5240ae17d0 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -108,7 +108,6 @@ public: virtual bool restoreErrorTrap() = 0; // Require platform specific override to reset error handling mechanism. // return false if the error trap needed restoration. - virtual void initCrashReporting(bool reportFreeze = false) = 0; // What to do with crash report? static void handleViewerCrash(); // Hey! The viewer crashed. Do this, soon. void checkForCrash(); diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index 9b1c0d1f8b..f0bede5321 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -603,9 +603,6 @@ bool LLAppViewerWin32::init() #if ! defined(LL_BUGSPLAT) #pragma message("Building without BugSplat") - LLAppViewer* pApp = LLAppViewer::instance(); - pApp->initCrashReporting(); - #else // LL_BUGSPLAT #pragma message("Building with BugSplat") @@ -817,57 +814,6 @@ bool LLAppViewerWin32::restoreErrorTrap() //return LLWinDebug::checkExceptionHandler(); } -void LLAppViewerWin32::initCrashReporting(bool reportFreeze) -{ - if (isSecondInstance()) return; //BUG-5707 do not start another crash reporter for second instance. - - const char* logger_name = "win_crash_logger.exe"; - std::string exe_path = gDirUtilp->getExecutableDir(); - exe_path += gDirUtilp->getDirDelimiter(); - exe_path += logger_name; - - std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, ""); - std::string appname = gDirUtilp->getExecutableFilename(); - - S32 slen = logdir.length() -1; - S32 end = slen; - while (logdir.at(end) == '/' || logdir.at(end) == '\\') end--; - - if (slen !=end) - { - logdir = logdir.substr(0,end+1); - } - //std::string arg_str = "\"" + exe_path + "\" -dumpdir \"" + logdir + "\" -procname \"" + appname + "\" -pid " + stringize(LLApp::getPid()); - //_spawnl(_P_NOWAIT, exe_path.c_str(), arg_str.c_str(), NULL); - std::string arg_str = "\"" + exe_path + "\" -dumpdir \"" + logdir + "\" -procname \"" + appname + "\" -pid " + stringize(LLApp::getPid()); - - STARTUPINFO startInfo={sizeof(startInfo)}; - PROCESS_INFORMATION processInfo; - - std::wstring exe_wstr; - exe_wstr = utf8str_to_utf16str(exe_path); - - std::wstring arg_wstr; - arg_wstr = utf8str_to_utf16str(arg_str); - - LL_INFOS("CrashReport") << "Creating crash reporter process " << exe_path << " with params: " << arg_str << LL_ENDL; - if(CreateProcess(exe_wstr.c_str(), - &arg_wstr[0], // Application arguments - 0, - 0, - FALSE, - CREATE_DEFAULT_ERROR_MODE, - 0, - 0, // Working directory - &startInfo, - &processInfo) == FALSE) - // Could not start application -> call 'GetLastError()' - { - LL_WARNS("CrashReport") << "CreateProcess failed " << GetLastError() << LL_ENDL; - return; - } -} - //virtual bool LLAppViewerWin32::sendURLToOtherInstance(const std::string& url) { diff --git a/indra/newview/llappviewerwin32.h b/indra/newview/llappviewerwin32.h index c5fae6a3a3..2699224e58 100644 --- a/indra/newview/llappviewerwin32.h +++ b/indra/newview/llappviewerwin32.h @@ -51,7 +51,6 @@ protected: virtual bool beingDebugged(); virtual bool restoreErrorTrap(); - virtual void initCrashReporting(bool reportFreeze); virtual bool sendURLToOtherInstance(const std::string& url); diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 6d231040f7..af7e799269 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -680,11 +680,6 @@ class WindowsManifest(ViewerManifest): self.path("libvlccore.dll") self.path("plugins/") - # pull in the crash logger from other projects - # tag:"crash-logger" here as a cue to the exporter - self.path(src='../win_crash_logger/%s/windows-crash-logger.exe' % self.args['configuration'], - dst="win_crash_logger.exe") - if not self.is_packaging_viewer(): self.package_file = "copied_deps" diff --git a/indra/win_crash_logger/CMakeLists.txt b/indra/win_crash_logger/CMakeLists.txt deleted file mode 100644 index 86aa655f03..0000000000 --- a/indra/win_crash_logger/CMakeLists.txt +++ /dev/null @@ -1,105 +0,0 @@ -# -*- cmake -*- - -project(win_crash_logger) - -include(00-Common) -include(LLCommon) -include(LLCoreHttp) -include(LLCrashLogger) -include(LLMath) -include(LLMessage) -include(LLVFS) -include(LLWindow) -include(LLXML) -include(Linking) -include(LLSharedLibs) -include(GoogleBreakpad) -include(Boost) - -include_directories( - ${LLCOREHTTP_INCLUDE_DIRS} - ${LLCOMMON_INCLUDE_DIRS} - ${LLCRASHLOGGER_INCLUDE_DIRS} - ${LLMATH_INCLUDE_DIRS} - ${LLWINDOW_INCLUDE_DIRS} - ${LLXML_INCLUDE_DIRS} - ${LLVFS_INCLUDE_DIRS} - ${BREAKPAD_INCLUDE_DIRECTORIES} - ) -include_directories(SYSTEM - ${LLCOMMON_SYSTEM_INCLUDE_DIRS} - ${LLXML_SYSTEM_INCLUDE_DIRS} - ) - -set(win_crash_logger_SOURCE_FILES - win_crash_logger.cpp - llcrashloggerwindows.cpp - ) - -set(win_crash_logger_HEADER_FILES - CMakeLists.txt - - llcrashloggerwindows.h - resource.h - StdAfx.h - win_crash_logger.h - ) - -set_source_files_properties(${win_crash_logger_HEADER_FILES} - PROPERTIES HEADER_FILE_ONLY TRUE) - -set(win_crash_logger_RESOURCE_FILES - ll_icon.ico - ) - -set_source_files_properties(${win_crash_logger_RESOURCE_FILES} - PROPERTIES HEADER_FILE_ONLY TRUE) - -set(win_crash_logger_RESOURCE_FILES - win_crash_logger.rc - ${win_crash_logger_RESOURCE_FILES} - ) - -SOURCE_GROUP("Resource Files" FILES ${win_crash_logger_RESOURCE_FILES}) - -list(APPEND - win_crash_logger_SOURCE_FILES - ${win_crash_logger_HEADER_FILES} - ${win_crash_logger_RESOURCE_FILES} - ) - -add_executable(windows-crash-logger WIN32 ${win_crash_logger_SOURCE_FILES}) - - -target_link_libraries(windows-crash-logger - ${LEGACY_STDIO_LIBS} - ${BREAKPAD_EXCEPTION_HANDLER_LIBRARIES} - ${LLCRASHLOGGER_LIBRARIES} - ${LLWINDOW_LIBRARIES} - ${LLVFS_LIBRARIES} - ${LLXML_LIBRARIES} - ${LLMESSAGE_LIBRARIES} - ${LLMATH_LIBRARIES} - ${LLCOREHTTP_LIBRARIES} - ${LLCOMMON_LIBRARIES} - ${BOOST_CONTEXT_LIBRARY} - ${BOOST_FIBER_LIBRARY} - ${WINDOWS_LIBRARIES} - dxguid - ${GOOGLE_PERFTOOLS_LIBRARIES} - user32 - gdi32 - oleaut32 - wininet - Wldap32 - ) - -if (WINDOWS) - set_target_properties(windows-crash-logger - PROPERTIES - LINK_FLAGS "/NODEFAULTLIB:LIBCMT" - LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\"" - ) -endif (WINDOWS) - -ll_deploy_sharedlibs_command(windows-crash-logger) diff --git a/indra/win_crash_logger/StdAfx.cpp b/indra/win_crash_logger/StdAfx.cpp deleted file mode 100644 index f56711af73..0000000000 --- a/indra/win_crash_logger/StdAfx.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/** - * @file StdAfx.cpp - * @brief windows crash logger source file for includes - * - * $LicenseInfo:firstyear=2003&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$ - */ - -// stdafx.cpp : source file that includes just the standard includes -// win_crash_logger.pch will be the pre-compiled header -// stdafx.obj will contain the pre-compiled type information - -#include "stdafx.h" - -// TODO: reference any additional headers you need in STDAFX.H -// and not in this file diff --git a/indra/win_crash_logger/StdAfx.h b/indra/win_crash_logger/StdAfx.h deleted file mode 100644 index 35976658ac..0000000000 --- a/indra/win_crash_logger/StdAfx.h +++ /dev/null @@ -1,56 +0,0 @@ -/** - * @file StdAfx.h - * @brief standard system includes - * - * $LicenseInfo:firstyear=2003&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$ - */ - -// stdafx.h : include file for standard system include files, -// or project specific include files that are used frequently, but -// are changed infrequently -// - -#if !defined(AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_) -#define AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 - -#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers - -// Windows Header Files: -#include - -// C RunTime Header Files -#include -#include -#include - -// Local Header Files - -// TODO: reference additional headers your program requires here - -//{{AFX_INSERT_LOCATION}} -// Microsoft Visual C++ will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_) diff --git a/indra/win_crash_logger/ll_icon.ico b/indra/win_crash_logger/ll_icon.ico deleted file mode 100644 index 566346dfe3..0000000000 Binary files a/indra/win_crash_logger/ll_icon.ico and /dev/null differ diff --git a/indra/win_crash_logger/llcrashloggerwindows.cpp b/indra/win_crash_logger/llcrashloggerwindows.cpp deleted file mode 100644 index 267224a79b..0000000000 --- a/indra/win_crash_logger/llcrashloggerwindows.cpp +++ /dev/null @@ -1,536 +0,0 @@ -/** -* @file llcrashloggerwindows.cpp -* @brief Windows crash logger implementation -* -* $LicenseInfo:firstyear=2003&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 "stdafx.h" -#include "resource.h" -#include "llcrashloggerwindows.h" - -#include - -#include "boost/tokenizer.hpp" - -#include "indra_constants.h" // CRASH_BEHAVIOR_ASK, CRASH_SETTING_NAME -#include "llerror.h" -#include "llfile.h" -#include "lltimer.h" -#include "llstring.h" -#include "lldxhardware.h" -#include "lldir.h" -#include "llsdserialize.h" -#include "llsdutil.h" -#include "stringize.h" - -#include -#include - -#define MAX_LOADSTRING 100 -#define MAX_STRING 2048 -const char* const SETTINGS_FILE_HEADER = "version"; -const S32 SETTINGS_FILE_VERSION = 101; - -// Windows Message Handlers - -// Global Variables: -HINSTANCE hInst= NULL; // current instance -TCHAR szTitle[MAX_LOADSTRING]; /* Flawfinder: ignore */ // The title bar text -TCHAR szWindowClass[MAX_LOADSTRING]; /* Flawfinder: ignore */ // The title bar text - -std::string gProductName; -HWND gHwndReport = NULL; // Send/Don't Send dialog -HWND gHwndProgress = NULL; // Progress window -HCURSOR gCursorArrow = NULL; -HCURSOR gCursorWait = NULL; -BOOL gFirstDialog = TRUE; // Are we currently handling the Send/Don't Send dialog? -std::stringstream gDXInfo; -bool gSendLogs = false; - -LLCrashLoggerWindows* LLCrashLoggerWindows::sInstance = NULL; - -//Conversion from char* to wchar* -//Replacement for ATL macros, doesn't allocate memory -//For more info see: http://www.codeguru.com/forum/showthread.php?t=337247 -void ConvertLPCSTRToLPWSTR (const char* pCstring, WCHAR* outStr) -{ - if (pCstring != NULL) - { - int nInputStrLen = strlen (pCstring); - // Double NULL Termination - int nOutputStrLen = MultiByteToWideChar(CP_ACP, 0, pCstring, nInputStrLen, NULL, 0) + 2; - if (outStr) - { - memset (outStr, 0x00, sizeof (WCHAR)*nOutputStrLen); - MultiByteToWideChar (CP_ACP, 0, pCstring, nInputStrLen, outStr, nInputStrLen); - } - } -} - -void write_debug(const char *str) -{ - gDXInfo << str; /* Flawfinder: ignore */ -} - -void write_debug(std::string& str) -{ - write_debug(str.c_str()); -} - -void show_progress(const std::string& message) -{ - std::wstring msg = wstring_to_utf16str(utf8str_to_wstring(message)); - if (gHwndProgress) - { - SendDlgItemMessage(gHwndProgress, // handle to destination window - IDC_LOG, - WM_SETTEXT, // message to send - FALSE, // undo option - (LPARAM)msg.c_str()); - } -} - -void update_messages() -{ - MSG msg; - while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) - { - if (msg.message == WM_QUIT) - { - exit(0); - } - TranslateMessage(&msg); - DispatchMessage(&msg); - } -} - -void sleep_and_pump_messages( U32 seconds ) -{ - const U32 CYCLES_PER_SECOND = 10; - U32 cycles = seconds * CYCLES_PER_SECOND; - while( cycles-- ) - { - update_messages(); - ms_sleep(1000 / CYCLES_PER_SECOND); - } -} - -// Include product name in the window caption. -void LLCrashLoggerWindows::ProcessCaption(HWND hWnd) -{ - TCHAR templateText[MAX_STRING]; /* Flawfinder: ignore */ - TCHAR header[MAX_STRING]; - std::string final; - GetWindowText(hWnd, templateText, sizeof(templateText)); - final = llformat(ll_convert_wide_to_string(templateText, CP_ACP).c_str(), gProductName.c_str()); - ConvertLPCSTRToLPWSTR(final.c_str(), header); - SetWindowText(hWnd, header); -} - - -// Include product name in the diaog item text. -void LLCrashLoggerWindows::ProcessDlgItemText(HWND hWnd, int nIDDlgItem) -{ - TCHAR templateText[MAX_STRING]; /* Flawfinder: ignore */ - TCHAR header[MAX_STRING]; - std::string final; - GetDlgItemText(hWnd, nIDDlgItem, templateText, sizeof(templateText)); - final = llformat(ll_convert_wide_to_string(templateText, CP_ACP).c_str(), gProductName.c_str()); - ConvertLPCSTRToLPWSTR(final.c_str(), header); - SetDlgItemText(hWnd, nIDDlgItem, header); -} - -bool handle_button_click(WORD button_id) -{ - // Is this something other than Send or Don't Send? - if (button_id != IDOK - && button_id != IDCANCEL) - { - return false; - } - - // We're done with this dialog. - gFirstDialog = FALSE; - - // Send the crash report if requested - if (button_id == IDOK) - { - gSendLogs = TRUE; - WCHAR wbuffer[20000]; - GetDlgItemText(gHwndReport, // handle to dialog box - IDC_EDIT1, // control identifier - wbuffer, // pointer to buffer for text - 20000 // maximum size of string - ); - std::string user_text(ll_convert_wide_to_string(wbuffer, CP_ACP)); - // Activate and show the window. - ShowWindow(gHwndProgress, SW_SHOW); - // Try doing this second to make the progress window go frontmost. - ShowWindow(gHwndReport, SW_HIDE); - ((LLCrashLoggerWindows*)LLCrashLogger::instance())->setUserText(user_text); - ((LLCrashLoggerWindows*)LLCrashLogger::instance())->sendCrashLogs(); - } - // Quit the app - LLApp::setQuitting(); - return true; -} - - -LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam ) -{ - switch( message ) - { - case WM_CREATE: - return 0; - - case WM_COMMAND: - if( gFirstDialog ) - { - WORD button_id = LOWORD(wParam); - bool handled = handle_button_click(button_id); - if (handled) - { - return 0; - } - } - break; - - case WM_DESTROY: - // Closing the window cancels - LLApp::setQuitting(); - PostQuitMessage(0); - return 0; - } - - return DefWindowProc(hwnd, message, wParam, lParam); -} - - -LLCrashLoggerWindows::LLCrashLoggerWindows(void) -{ - if (LLCrashLoggerWindows::sInstance==NULL) - { - sInstance = this; - } -} - -LLCrashLoggerWindows::~LLCrashLoggerWindows(void) -{ - sInstance = NULL; -} - -bool LLCrashLoggerWindows::getMessageWithTimeout(MSG *msg, UINT to) -{ - bool res; - UINT_PTR timerID = SetTimer(NULL, NULL, to, NULL); - res = GetMessage(msg, NULL, 0, 0); - KillTimer(NULL, timerID); - if (!res) - return false; - if (msg->message == WM_TIMER && msg->hwnd == NULL && msg->wParam == 1) - return false; //TIMEOUT! You could call SetLastError() or something... - return true; -} - -int LLCrashLoggerWindows::processingLoop() { - const int millisecs=1000; - int retries = 0; - const int max_retries = 60; - - LL_DEBUGS("CRASHREPORT") << "Entering processing loop for OOP server" << LL_ENDL; - - LLSD options = getOptionData( LLApp::PRIORITY_COMMAND_LINE ); - - MSG msg; - - bool result; - - while (1) - { - result = getMessageWithTimeout(&msg, millisecs); - if ( result ) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - - if ( retries < max_retries ) //Wait up to 1 minute for the viewer to say hello. - { - if (mClientsConnected == 0) - { - LL_DEBUGS("CRASHREPORT") << "Waiting for client to connect." << LL_ENDL; - ++retries; - } - else - { - LL_INFOS("CRASHREPORT") << "Client has connected!" << LL_ENDL; - retries = max_retries; - } - } - else - { - if (mClientsConnected == 0) - { - break; - } - if (!mKeyMaster.isProcessAlive(mPID, mProcName) ) - { - break; - } - } - } - - LL_INFOS() << "session ending.." << LL_ENDL; - - std::string per_run_dir = options["dumpdir"].asString(); - std::string per_run_file = per_run_dir + "\\SecondLife.log"; - std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.log"); - - if (gDirUtilp->fileExists(per_run_dir)) - { - LL_INFOS ("CRASHREPORT") << "Copying " << log_file << " to " << per_run_file << LL_ENDL; - LLFile::copy(log_file, per_run_file); - } - return 0; -} - - -void LLCrashLoggerWindows::OnClientConnected(void* context, - const google_breakpad::ClientInfo* client_info) -{ - sInstance->mClientsConnected++; - LL_INFOS("CRASHREPORT") << "Client connected. pid = " << client_info->pid() << " total clients " << sInstance->mClientsConnected << LL_ENDL; -} - -void LLCrashLoggerWindows::OnClientExited(void* context, - const google_breakpad::ClientInfo* client_info) -{ - sInstance->mClientsConnected--; - LL_INFOS("CRASHREPORT") << "Client disconnected. pid = " << client_info->pid() << " total clients " << sInstance->mClientsConnected << LL_ENDL; -} - - -void LLCrashLoggerWindows::OnClientDumpRequest(void* context, - const google_breakpad::ClientInfo* client_info, - const std::wstring* file_path) -{ - if (!file_path) - { - LL_WARNS() << "dump with no file path" << LL_ENDL; - return; - } - if (!client_info) - { - LL_WARNS() << "dump with no client info" << LL_ENDL; - return; - } - - LLCrashLoggerWindows* self = static_cast(context); - if (!self) - { - LL_WARNS() << "dump with no context" << LL_ENDL; - return; - } - - //DWORD pid = client_info->pid(); -} - - -bool LLCrashLoggerWindows::initCrashServer() -{ - //For Breakpad on Windows we need a full Out of Process service to get good data. - //This routine starts up the service on a named pipe that the viewer will then - //communicate with. - using namespace google_breakpad; - - LLSD options = getOptionData( LLApp::PRIORITY_COMMAND_LINE ); - std::string dump_path = options["dumpdir"].asString(); - mClientsConnected = 0; - mPID = options["pid"].asInteger(); - mProcName = options["procname"].asString(); - - //Generate a quasi-uniq name for the named pipe. For our purposes - //this is unique-enough with least hassle. Worst case for duplicate name - //is a second instance of the viewer will not do crash reporting. - std::wstring wpipe_name; - wpipe_name = mCrashReportPipeStr + std::wstring(wstringize(mPID)); - - std::wstring wdump_path(utf8str_to_utf16str(dump_path)); - - //Pipe naming conventions: http://msdn.microsoft.com/en-us/library/aa365783%28v=vs.85%29.aspx - mCrashHandler = new CrashGenerationServer( wpipe_name, - NULL, - &LLCrashLoggerWindows::OnClientConnected, this, - /*NULL, NULL, */ &LLCrashLoggerWindows::OnClientDumpRequest, this, - &LLCrashLoggerWindows::OnClientExited, this, - NULL, NULL, - true, &wdump_path); - - if (!mCrashHandler) { - //Failed to start the crash server. - LL_WARNS() << "Failed to init crash server." << LL_ENDL; - return false; - } - - // Start servicing clients. - if (!mCrashHandler->Start()) { - LL_WARNS() << "Failed to start crash server." << LL_ENDL; - return false; - } - - LL_INFOS("CRASHREPORT") << "Initialized OOP server with pipe named " << stringize(wpipe_name) << LL_ENDL; - return true; -} - -bool LLCrashLoggerWindows::init(void) -{ - bool ok = LLCrashLogger::init(); - if(!ok) return false; - - initCrashServer(); - - /* - mbstowcs( gProductName, mProductName.c_str(), LL_ARRAY_SIZE(gProductName) ); - gProductName[ LL_ARRY_SIZE(gProductName) - 1 ] = 0; - swprintf(gProductName, L"Second Life"); - */ - - LL_INFOS() << "Loading dialogs" << LL_ENDL; - - // Initialize global strings - LoadString(mhInst, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); - LoadString(mhInst, IDC_WIN_CRASH_LOGGER, szWindowClass, MAX_LOADSTRING); - - gCursorArrow = LoadCursor(NULL, IDC_ARROW); - gCursorWait = LoadCursor(NULL, IDC_WAIT); - - // Register a window class that will be used by our dialogs - WNDCLASS wndclass; - wndclass.style = CS_HREDRAW | CS_VREDRAW; - wndclass.lpfnWndProc = WndProc; - wndclass.cbClsExtra = 0; - wndclass.cbWndExtra = DLGWINDOWEXTRA; // Required, since this is used for dialogs! - wndclass.hInstance = mhInst; - wndclass.hIcon = LoadIcon(hInst, MAKEINTRESOURCE( IDI_WIN_CRASH_LOGGER ) ); - wndclass.hCursor = gCursorArrow; - wndclass.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1); - wndclass.lpszMenuName = NULL; - wndclass.lpszClassName = szWindowClass; - RegisterClass( &wndclass ); - - return true; -} - -void LLCrashLoggerWindows::gatherPlatformSpecificFiles() -{ - updateApplication("Gathering hardware information. App may appear frozen."); - // DX hardware probe blocks, so we can't cancel during it - //Generate our dx_info.log file - SetCursor(gCursorWait); - // At this point we're responsive enough the user could click the close button - SetCursor(gCursorArrow); - //mDebugLog["DisplayDeviceInfo"] = gDXHardware.getDisplayInfo(); //Not initialized. -} - -bool LLCrashLoggerWindows::frame() -{ - LL_INFOS() << "CrashSubmitBehavior is " << mCrashBehavior << LL_ENDL; - - // Note: parent hwnd is 0 (the desktop). No dlg proc. See Petzold (5th ed) HexCalc example, Chapter 11, p529 - // win_crash_logger.rc has been edited by hand. - // Dialogs defined with CLASS "WIN_CRASH_LOGGER" (must be same as szWindowClass) - gProductName = mProductName; - gHwndProgress = CreateDialog(hInst, MAKEINTRESOURCE(IDD_PROGRESS), 0, NULL); - ProcessCaption(gHwndProgress); - ShowWindow(gHwndProgress, SW_HIDE ); - - if (mCrashBehavior == CRASH_BEHAVIOR_ALWAYS_SEND) - { - LL_INFOS() << "Showing crash report submit progress window." << LL_ENDL; - //ShowWindow(gHwndProgress, SW_SHOW ); Maint-5707 - sendCrashLogs(); - } - else if (mCrashBehavior == CRASH_BEHAVIOR_ASK) - { - gHwndReport = CreateDialog(hInst, MAKEINTRESOURCE(IDD_PREVREPORTBOX), 0, NULL); - // Ignore result - (void) SendDlgItemMessage(gHwndReport, IDC_CHECK_AUTO, BM_SETCHECK, 0, 0); - // Include the product name in the caption and various dialog items. - ProcessCaption(gHwndReport); - ProcessDlgItemText(gHwndReport, IDC_STATIC_MSG); - - // Update the header to include whether or not we crashed on the last run. - std::string headerStr; - TCHAR header[MAX_STRING]; - if (mCrashInPreviousExec) - { - headerStr = llformat("%s appears to have crashed or frozen the last time it ran.", mProductName.c_str()); - } - else - { - headerStr = llformat("%s appears to have crashed.", mProductName.c_str()); - } - ConvertLPCSTRToLPWSTR(headerStr.c_str(), header); - SetDlgItemText(gHwndReport, IDC_STATIC_HEADER, header); - ShowWindow(gHwndReport, SW_SHOW ); - - MSG msg; - memset(&msg, 0, sizeof(msg)); - while (!LLApp::isQuitting() && GetMessage(&msg, NULL, 0, 0)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - return true; // msg.wParam; - } - else - { - LL_WARNS() << "Unknown crash behavior " << mCrashBehavior << LL_ENDL; - return true; // 1; - } - return true; // 0; -} - -void LLCrashLoggerWindows::updateApplication(const std::string& message) -{ - LLCrashLogger::updateApplication(message); - if(!message.empty()) show_progress(message); - update_messages(); -} - -bool LLCrashLoggerWindows::cleanup() -{ - if(gSendLogs) - { - if(mSentCrashLogs) show_progress("Done"); - else show_progress("Could not connect to servers, logs not sent"); - sleep_and_pump_messages(3); - } - PostQuitMessage(0); - commonCleanup(); - mKeyMaster.releaseMaster(); - return true; -} - diff --git a/indra/win_crash_logger/llcrashloggerwindows.h b/indra/win_crash_logger/llcrashloggerwindows.h deleted file mode 100644 index f89b8708dc..0000000000 --- a/indra/win_crash_logger/llcrashloggerwindows.h +++ /dev/null @@ -1,86 +0,0 @@ -/** -* @file llcrashloggerwindows.h -* @brief Windows crash logger definition -* -* $LicenseInfo:firstyear=2003&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 LLCRASHLOGGERWINDOWS_H -#define LLCRASHLOGGERWINDOWS_H - -#include "llcrashlogger.h" -#include "windows.h" -#include "llstring.h" - -class LLSD; - -namespace google_breakpad { - class CrashGenerationServer; - class ClientInfo; -} - -class LLCrashLoggerWindows : public LLCrashLogger -{ -public: - LLCrashLoggerWindows(void); - ~LLCrashLoggerWindows(void); - static LLCrashLoggerWindows* sInstance; - - virtual bool init(); - virtual bool frame(); - virtual void updateApplication(const std::string& message = LLStringUtil::null); - virtual bool cleanup(); - virtual void gatherPlatformSpecificFiles(); - void setHandle(HINSTANCE hInst) { mhInst = hInst; } - int clients_connected() const { - return mClientsConnected; - } - bool getMessageWithTimeout(MSG *msg, UINT to); - - // Starts the processing loop. This function does not return unless the - // user is logging off or the user closes the crash service window. The - // return value is a good number to pass in ExitProcess(). - int processingLoop(); -private: - void ProcessDlgItemText(HWND hWnd, int nIDDlgItem); - void ProcessCaption(HWND hWnd); - bool initCrashServer(); - google_breakpad::CrashGenerationServer* mCrashHandler; - static void OnClientConnected(void* context, - const google_breakpad::ClientInfo* client_info); - - static void OnClientDumpRequest( - void* context, - const google_breakpad::ClientInfo* client_info, - const std::wstring* file_path); - - static void OnClientExited(void* context, - const google_breakpad::ClientInfo* client_info); - int mClientsConnected; - int mPID; - std::string mProcName; - - HINSTANCE mhInst; - -}; - -#endif diff --git a/indra/win_crash_logger/resource.h b/indra/win_crash_logger/resource.h deleted file mode 100644 index 37a387275e..0000000000 --- a/indra/win_crash_logger/resource.h +++ /dev/null @@ -1,63 +0,0 @@ -/** -* @file resource.h -* @brief Windows crash logger windows resources -* -* $LicenseInfo:firstyear=2003&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$ -*/ - -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by win_crash_logger.rc -// -#define IDC_MYICON 2 -#define IDD_REPORT 9 -#define IDD_WIN_CRASH_LOGGER_DIALOG 102 -#define IDD_ABOUTBOX 103 -#define IDS_APP_TITLE 103 -#define IDM_ABOUT 104 -#define IDM_EXIT 105 -#define IDS_HELLO 106 -#define IDI_WIN_CRASH_LOGGER 107 -#define IDI_SMALL 108 -#define IDC_WIN_CRASH_LOGGER 109 -#define IDR_MAINFRAME 128 -#define IDD_PROGRESS 129 -#define IDD_PREVREPORTBOX 130 -#define IDC_EDIT1 1000 -#define IDC_LOG 1004 -#define IDC_CHECK_AUTO 1006 -#define IDC_STATIC_HEADER 1007 -#define IDC_STATIC_WHATINFO 1008 -#define IDC_STATIC_MOTIVATION 1009 -#define IDC_STATIC_MSG 1010 -#define IDC_STATIC -1 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 131 -#define _APS_NEXT_COMMAND_VALUE 32771 -#define _APS_NEXT_CONTROL_VALUE 1011 -#define _APS_NEXT_SYMED_VALUE 110 -#endif -#endif diff --git a/indra/win_crash_logger/win_crash_logger.cpp b/indra/win_crash_logger/win_crash_logger.cpp deleted file mode 100644 index 58746eba02..0000000000 --- a/indra/win_crash_logger/win_crash_logger.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/** - * @file win_crash_logger.cpp - * @brief Windows crash logger implementation - * - * $LicenseInfo:firstyear=2003&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 "stdafx.h" -#include -#include "llcrashloggerwindows.h" - -#ifdef _UNICODE -int APIENTRY wWinMain(HINSTANCE hInstance, - HINSTANCE hPrevInstance, - LPWSTR lpCmdLine, - int nCmdShow) -#else -int APIENTRY WinMain(HINSTANCE hInstance, - HINSTANCE hPrevInstance, - LPSTR lpCmdLine, - int nCmdShow) -#endif //_UNICODE -{ - LL_INFOS() << "Starting crash reporter with args" << &lpCmdLine << LL_ENDL; - LLCrashLoggerWindows app; - app.setHandle(hInstance); -#ifdef _UNICODE - app.parseCommandOptions(__argc, __wargv); -#else - app.parseCommandOptions(__argc, __argv); -#endif //_UNICODE - - LLSD options = LLApp::instance()->getOptionData( - LLApp::PRIORITY_COMMAND_LINE); - if (!(options.has("pid") && options.has("dumpdir"))) - { - LL_WARNS() << "Insufficient parameters to crash report." << LL_ENDL; - } - if (! app.init()) - { - LL_WARNS() << "Unable to initialize application." << LL_ENDL; - return -1; - } - - app.processingLoop(); - app.frame(); - app.cleanup(); - LL_INFOS() << "Crash reporter finished normally." << LL_ENDL; - return 0; -} diff --git a/indra/win_crash_logger/win_crash_logger.h b/indra/win_crash_logger/win_crash_logger.h deleted file mode 100644 index 2cc2cf3dcf..0000000000 --- a/indra/win_crash_logger/win_crash_logger.h +++ /dev/null @@ -1,38 +0,0 @@ -/** - * @file win_crash_logger.h - * @brief Windows crash logger project includes - * - * $LicenseInfo:firstyear=2003&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$ - */ - - -#if !defined(AFX_WIN_CRASH_LOGGER_H__79802F4B_7C37_4F63_A2BB_0768788C3A27__INCLUDED_) -#define AFX_WIN_CRASH_LOGGER_H__79802F4B_7C37_4F63_A2BB_0768788C3A27__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 - -#include "resource.h" - - -#endif // !defined(AFX_WIN_CRASH_LOGGER_H__79802F4B_7C37_4F63_A2BB_0768788C3A27__INCLUDED_) diff --git a/indra/win_crash_logger/win_crash_logger.ico b/indra/win_crash_logger/win_crash_logger.ico deleted file mode 100644 index 386883523b..0000000000 Binary files a/indra/win_crash_logger/win_crash_logger.ico and /dev/null differ diff --git a/indra/win_crash_logger/win_crash_logger.rc b/indra/win_crash_logger/win_crash_logger.rc deleted file mode 100755 index 2819722f63..0000000000 --- a/indra/win_crash_logger/win_crash_logger.rc +++ /dev/null @@ -1,188 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#define APSTUDIO_HIDDEN_SYMBOLS -#include "windows.h" -#undef APSTUDIO_HIDDEN_SYMBOLS -#include "resource.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// English (U.S.) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -IDI_WIN_CRASH_LOGGER ICON "ll_icon.ico" - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -IDC_WIN_CRASH_LOGGER MENU -BEGIN - POPUP "&File" - BEGIN - MENUITEM "E&xit", IDM_EXIT - END - POPUP "&Help" - BEGIN - MENUITEM "&About ...", IDM_ABOUT - END -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_PROGRESS DIALOGEX 100, 100, 234, 33 -STYLE DS_SETFONT | DS_SETFOREGROUND | WS_CAPTION | WS_SYSMENU -CAPTION "%s Crash Logger" -CLASS "WIN_CRASH_LOGGER" -FONT 8, "MS Sans Serif", 0, 0, 0x0 -BEGIN - LTEXT "Static",IDC_LOG,7,7,220,8 -END - -IDD_REPORT DIALOGEX 100, 100, 297, 125 -STYLE DS_SETFONT | DS_SETFOREGROUND | WS_CAPTION | WS_SYSMENU -CAPTION "%s Crash Logger" -CLASS "WIN_CRASH_LOGGER" -FONT 8, "MS Sans Serif", 0, 0, 0x0 -BEGIN - DEFPUSHBUTTON "Send",IDOK,198,104,45,15,WS_GROUP - PUSHBUTTON "Don't Send",IDCANCEL,247,104,45,15,WS_GROUP - LTEXT "%s appears to have crashed.",IDC_STATIC_HEADER,4,4,288,14 - LTEXT "This crash reporter collects information about your computer's hardware, operating system, and some %s logs, which are used for debugging purposes only.",IDC_STATIC_WHATINFO,4,23,288,19,NOT WS_GROUP - CONTROL "Remember this choice",IDC_CHECK_AUTO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,106,89,13 - LTEXT "Sending crash reports is the best way to help us improve the quality of %s.",IDC_STATIC_MOTIVATION,4,43,288,8 - LTEXT "If you continue to experience this problem, please try:",IDC_STATIC,4,57,251,8 - LTEXT "- Contacting support by visiting http://www.secondlife.com/support",IDC_STATIC,4,67,231,8 -END - -IDD_PREVREPORTBOX DIALOGEX 100, 100, 232, 213 -STYLE DS_SETFONT | DS_SETFOREGROUND | WS_CAPTION | WS_SYSMENU -CAPTION "%s Crash Logger" -CLASS "WIN_CRASH_LOGGER" -FONT 8, "MS Sans Serif", 0, 0, 0x0 -BEGIN - DEFPUSHBUTTON "Send Report",IDOK,131,193,45,15,WS_GROUP - EDITTEXT IDC_EDIT1,3,100,223,89,ES_MULTILINE | ES_WANTRETURN | WS_VSCROLL - PUSHBUTTON "Don't Send",IDCANCEL,181,193,45,15,WS_GROUP - LTEXT "%s appears to have crashed or frozen the last time it ran.",IDC_STATIC_HEADER,4,4,214,8 - LTEXT "This crash reporter collects information about your computer's",IDC_STATIC,4,17,201,8 - LTEXT "hardware configuration, operating system, and some %s",IDC_STATIC_MSG,4,25,212,8 - LTEXT "logs, all of which are used for debugging purposes only.",IDC_STATIC,4,33,210,8 - LTEXT "In the space below, please briefly describe what you were doing",IDC_STATIC,3,48,208,8 - LTEXT "or trying to do just prior to the crash.",IDC_STATIC,3,56,204,8 - LTEXT "If you don't wish to send Linden Lab a crash report, press Don't Send.",IDC_STATIC,3,90,223,8 - LTEXT "This report is NOT read by customer support. If you have billing or",IDC_STATIC,3,68,208,8 - LTEXT "other questions, please go to: www.secondlife.com/support",IDC_STATIC,3,76,206,8 - CONTROL "Remember this choice",IDC_CHECK_AUTO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,3,193,89,13 -END - - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -2 TEXTINCLUDE -BEGIN - "#define APSTUDIO_HIDDEN_SYMBOLS\r\n" - "#include ""windows.h""\r\n" - "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n" - "#include ""resource.h""\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO -BEGIN - IDD_PROGRESS, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 227 - TOPMARGIN, 7 - BOTTOMMARGIN, 26 - END - - IDD_REPORT, DIALOG - BEGIN - RIGHTMARGIN, 292 - VERTGUIDE, 4 - BOTTOMMARGIN, 119 - HORZGUIDE, 4 - END -END -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE -BEGIN - IDS_APP_TITLE "win_crash_logger" - IDS_HELLO "Hello World!" - IDC_WIN_CRASH_LOGGER "WIN_CRASH_LOGGER" -END - -#endif // English (U.S.) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - -- cgit v1.2.3 From 2febf90744624120b9d93708792ed5aaedb8ad14 Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Wed, 17 Mar 2021 08:53:20 +0200 Subject: SL-14541 follow-up xcode buildfix --- indra/cmake/Copy3rdPartyLibs.cmake | 1 - indra/llcommon/llapp.cpp | 4 ---- indra/llcorehttp/CMakeLists.txt | 1 - indra/newview/viewer_manifest.py | 1 - 4 files changed, 7 deletions(-) diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index 8efad33f71..742acabe5f 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -157,7 +157,6 @@ elseif(DARWIN) libapr-1.dylib libaprutil-1.0.dylib libaprutil-1.dylib - libexception_handler.dylib ${EXPAT_COPY} libGLOD.dylib libhunspell-1.3.0.dylib diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index c9e4cf2ab3..f66a6fb4dc 100644 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -437,10 +437,6 @@ void LLApp::setupErrorHandling(bool second_instance) } #endif // ! LL_RELEASE_FOR_DOWNLOAD - if(installHandler && (mExceptionHandler == 0)) - { - mExceptionHandler = new google_breakpad::ExceptionHandler(mDumpPath, 0, &unix_post_minidump_callback, 0, true, 0); - } #elif LL_LINUX if(installHandler && (mExceptionHandler == 0)) { diff --git a/indra/llcorehttp/CMakeLists.txt b/indra/llcorehttp/CMakeLists.txt index 11b2e3e929..96a1057a63 100644 --- a/indra/llcorehttp/CMakeLists.txt +++ b/indra/llcorehttp/CMakeLists.txt @@ -176,7 +176,6 @@ if (DARWIN) set(copy_dylibs libapr-1.0.dylib libaprutil-1.0.dylib - libexception_handler.dylib libnghttp2*.dylib ${EXPAT_COPY} ) diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index af7e799269..5a39616d55 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -1024,7 +1024,6 @@ class DarwinManifest(ViewerManifest): "libapr-1.0.dylib", "libaprutil-1.0.dylib", "libexpat.1.dylib", - "libexception_handler.dylib", "libGLOD.dylib", # libnghttp2.dylib is a symlink to # libnghttp2.major.dylib, which is a symlink to -- cgit v1.2.3 From 680f2cfee6210f2526f572a996fc18adeadc4b76 Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Fri, 9 Apr 2021 19:15:30 +0300 Subject: Xcode12 linking fix (CEF) --- indra/cmake/CEFPlugin.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indra/cmake/CEFPlugin.cmake b/indra/cmake/CEFPlugin.cmake index b8e569d3a8..7d8bfb1b0f 100644 --- a/indra/cmake/CEFPlugin.cmake +++ b/indra/cmake/CEFPlugin.cmake @@ -24,7 +24,7 @@ elseif (DARWIN) message(FATAL_ERROR "AppKit not found") endif() - FIND_LIBRARY(CEF_LIBRARY "Chromium Embedded Framework" ${ARCH_PREBUILT_DIRS_RELEASE}) + set(CEF_LIBRARY "'${ARCH_PREBUILT_DIRS_RELEASE}/Chromium\ Embedded\ Framework.framework'") if (NOT CEF_LIBRARY) message(FATAL_ERROR "CEF not found") endif() @@ -33,7 +33,7 @@ elseif (DARWIN) ${ARCH_PREBUILT_DIRS_RELEASE}/libcef_dll_wrapper.a ${ARCH_PREBUILT_DIRS_RELEASE}/libdullahan.a ${APPKIT_LIBRARY} - ${CEF_LIBRARY} + "-F ${CEF_LIBRARY}" ) elseif (LINUX) -- cgit v1.2.3 From 45b5ac72b2384ea370e4138e08c4c8344d94b4e3 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 20 Apr 2021 01:07:53 +0300 Subject: SL-15141 Update CURL to 7.76.1 CURLE_SSL_CACERT is now identical to CURLE_SSL_PEER_CERTIFICATE --- autobuild.xml | 14 +++++++------- indra/newview/llxmlrpclistener.cpp | 2 +- indra/newview/llxmlrpctransaction.cpp | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 6c43fa7bc2..1645fae351 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -398,9 +398,9 @@ archive hash - 7295ca3234ab21a98c39604f3b0985cb + b9929a96097f09cc433484092cddf760 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78596/744055/curl-7.54.1.557049-darwin64-557049.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/80348/758363/curl-7.76.1.558412-darwin64-558412.tar.bz2 name darwin64 @@ -434,11 +434,11 @@ archive hash - 0c31fa12a33ecc946c0c69259b6367a9 + 17b3f80f28c3d58632abd7ae5144a93d hash_algorithm md5 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78598/744050/curl-7.54.1.557049-windows-557049.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/80349/758380/curl-7.76.1.558412-windows-558412.tar.bz2 name windows @@ -448,16 +448,16 @@ archive hash - 4c4d5971a59ae2e1f4467667df2a9aa4 + 17b64a8997755ecc0e3d0dd4d6e76b5d url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78597/744044/curl-7.54.1.557049-windows64-557049.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/80350/758379/curl-7.76.1.558412-windows64-558412.tar.bz2 name windows64 version - 7.54.1.557049 + 7.76.1.558412 db diff --git a/indra/newview/llxmlrpclistener.cpp b/indra/newview/llxmlrpclistener.cpp index bae615232e..1053059a33 100644 --- a/indra/newview/llxmlrpclistener.cpp +++ b/indra/newview/llxmlrpclistener.cpp @@ -344,7 +344,7 @@ public: switch (curlcode) { case CURLE_SSL_PEER_CERTIFICATE: - case CURLE_SSL_CACERT: + // same value as CURLE_SSL_CACERT: data["certificate"] = mTransaction->getErrorCertData(); break; diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp index 32c8ce66a0..1af4588240 100644 --- a/indra/newview/llxmlrpctransaction.cpp +++ b/indra/newview/llxmlrpctransaction.cpp @@ -499,10 +499,10 @@ void LLXMLRPCTransaction::Impl::setHttpStatus(const LLCore::HttpStatus &status) break; case CURLE_SSL_PEER_CERTIFICATE: + // same value as CURLE_SSL_CACERT: message = LLTrans::getString("ssl_peer_certificate"); break; - case CURLE_SSL_CACERT: case CURLE_SSL_CONNECT_ERROR: message = LLTrans::getString("ssl_connect_error"); break; -- cgit v1.2.3 From 2de92430efa91fec0fddcec9be0755a69ca4f7b5 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 20 Apr 2021 19:09:04 +0300 Subject: Revert "SL-15141 Update CURL to 7.76.1" due to OPS-4251 This reverts commit 45b5ac72b2384ea370e4138e08c4c8344d94b4e3 and updates curl links --- autobuild.xml | 14 +++++++------- indra/newview/llxmlrpclistener.cpp | 2 +- indra/newview/llxmlrpctransaction.cpp | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 1645fae351..490089752b 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -398,9 +398,9 @@ archive hash - b9929a96097f09cc433484092cddf760 + 52fc837a5840f5e6991842cf2f73a9d7 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/80348/758363/curl-7.76.1.558412-darwin64-558412.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/80409/758717/curl-7.54.1.558452-darwin64-558452.tar.bz2 name darwin64 @@ -434,11 +434,11 @@ archive hash - 17b3f80f28c3d58632abd7ae5144a93d + 8de0af7c8168406bf18bdcd5bc44e40e hash_algorithm md5 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/80349/758380/curl-7.76.1.558412-windows-558412.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/80411/758714/curl-7.54.1.558452-windows-558452.tar.bz2 name windows @@ -448,16 +448,16 @@ archive hash - 17b64a8997755ecc0e3d0dd4d6e76b5d + dc633acdbd3595db4f904e68e48b4744 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/80350/758379/curl-7.76.1.558412-windows64-558412.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/80410/758715/curl-7.54.1.558452-windows64-558452.tar.bz2 name windows64 version - 7.76.1.558412 + 7.54.1.558452 db diff --git a/indra/newview/llxmlrpclistener.cpp b/indra/newview/llxmlrpclistener.cpp index 1053059a33..bae615232e 100644 --- a/indra/newview/llxmlrpclistener.cpp +++ b/indra/newview/llxmlrpclistener.cpp @@ -344,7 +344,7 @@ public: switch (curlcode) { case CURLE_SSL_PEER_CERTIFICATE: - // same value as CURLE_SSL_CACERT: + case CURLE_SSL_CACERT: data["certificate"] = mTransaction->getErrorCertData(); break; diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp index 1af4588240..32c8ce66a0 100644 --- a/indra/newview/llxmlrpctransaction.cpp +++ b/indra/newview/llxmlrpctransaction.cpp @@ -499,10 +499,10 @@ void LLXMLRPCTransaction::Impl::setHttpStatus(const LLCore::HttpStatus &status) break; case CURLE_SSL_PEER_CERTIFICATE: - // same value as CURLE_SSL_CACERT: message = LLTrans::getString("ssl_peer_certificate"); break; + case CURLE_SSL_CACERT: case CURLE_SSL_CONNECT_ERROR: message = LLTrans::getString("ssl_connect_error"); break; -- cgit v1.2.3 From 5d4ca2edfb1d620f17b5c68b442445beeafdfef2 Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Tue, 20 Apr 2021 04:58:44 +0300 Subject: DRTVWR-520 Updated slvoice to codeticket build 558436 --- autobuild.xml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 490089752b..76c0831b72 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -2918,9 +2918,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 321a8542e7b693fbe8e44ebface06087 + 6ce3cbaed968a69fb7a2cca80220874d url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/55966/524403/slvoice-4.10.0000.32327.5fc3fe7c.539691-darwin64-539691.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/80380/758537/slvoice-4.10.0000.32327.5fc3fe7c.558436-darwin64-558436.tar.bz2 name darwin64 @@ -2954,9 +2954,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - fb1a57a1cf5e38a3d51b32307b93ffba + 2eb38c5eff4d0f18fbb89d0c30c4f0a4 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/55968/524423/slvoice-4.10.0000.32327.5fc3fe7c.539691-windows-539691.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/80382/758550/slvoice-4.10.0000.32327.5fc3fe7c.558436-windows-558436.tar.bz2 name windows @@ -2966,16 +2966,16 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 81df970eb0c97d415d7bd12049c82042 + 9ee8f3cbc5369c598a998c61961ed16d url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/55967/524409/slvoice-4.10.0000.32327.5fc3fe7c.539691-windows64-539691.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/80381/758551/slvoice-4.10.0000.32327.5fc3fe7c.558436-windows64-558436.tar.bz2 name windows64 version - 4.10.0000.32327.5fc3fe7c.539691 + 4.10.0000.32327.5fc3fe7c.558436 tut -- cgit v1.2.3 From 9080c818e09bac96a50322f4a5121e6bde743ac4 Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Wed, 21 Apr 2021 07:04:53 +0300 Subject: DRTVWR-520 Updated apr_suite to codeticket build 558565 --- autobuild.xml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 76c0831b72..97ed3e0aec 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -76,9 +76,9 @@ archive hash - f3f49349055a525369a73139046a55a1 + b6357ef3a0ec37877a5831820f25094e url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76345/727286/apr_suite-1.4.5.555520-darwin64-555520.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/80557/759704/apr_suite-1.4.5.558565-darwin64-558565.tar.bz2 name darwin64 @@ -112,9 +112,9 @@ archive hash - 0628a381c80cae621106e41a0b592bcd + cb48ac069440f6dcd564cfa9fd02a4c2 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76347/727295/apr_suite-1.4.5.555520-windows-555520.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/80556/759710/apr_suite-1.4.5.558565-windows-558565.tar.bz2 name windows @@ -124,16 +124,16 @@ archive hash - 79fdb06371d6aeb29b52d593b2865f57 + 646dc3828d9c39fb1e77c4eec44ed739 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76346/727296/apr_suite-1.4.5.555520-windows64-555520.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/80555/759709/apr_suite-1.4.5.558565-windows64-558565.tar.bz2 name windows64 version - 1.4.5.555520 + 1.4.5.558565 boost -- cgit v1.2.3 From 3623e6eb8aa7d277c4aa5f2e14c5c7982128435e Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Thu, 22 Apr 2021 09:37:50 +0300 Subject: DRTVWR-520 Updated dullahan to codeticket build 558653 --- autobuild.xml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 97ed3e0aec..417824b2b0 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -580,9 +580,9 @@ archive hash - 46124156a4148d61c849d328c8659f78 + 77d2bc0c26c5047ac9f8126f8fa5aa0f url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76900/730915/dullahan-1.7.0.202102101914_81.3.10_gb223419_chromium-81.0.4044.138-darwin64-555904.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/80680/760744/dullahan-1.7.0.202104220619_81.3.10_gb223419_chromium-81.0.4044.138-darwin64-558653.tar.bz2 name darwin64 @@ -592,9 +592,9 @@ archive hash - d801e6c21333c94a7a04177aa91d5c1c + 6a110e6b902617bab404b259110824bc url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76901/730924/dullahan-1.7.0.202102101918_81.3.10_gb223419_chromium-81.0.4044.138-windows-555904.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/80683/760762/dullahan-1.7.0.202104220629_81.3.10_gb223419_chromium-81.0.4044.138-windows-558653.tar.bz2 name windows @@ -604,16 +604,16 @@ archive hash - dde4748dca0a75c6af30eca584e43352 + 3826abcf9dd5a2b137aa69f4a2a881d1 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76902/730930/dullahan-1.7.0.202102101918_81.3.10_gb223419_chromium-81.0.4044.138-windows64-555904.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/80684/760763/dullahan-1.7.0.202104220629_81.3.10_gb223419_chromium-81.0.4044.138-windows64-558653.tar.bz2 name windows64 version - 1.7.0.202102101918_81.3.10_gb223419_chromium-81.0.4044.138 + 1.7.0.202104220629_81.3.10_gb223419_chromium-81.0.4044.138 elfio -- cgit v1.2.3 From ae11dfe1a3a67d0a100d47e1e667d8fc36b9ef83 Mon Sep 17 00:00:00 2001 From: Mnikolenko ProductEngine Date: Fri, 23 Apr 2021 15:08:50 +0300 Subject: build fix --- indra/llcommon/llapp.cpp | 8 ++++---- indra/newview/llappviewermacosx.cpp | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index f66a6fb4dc..fdb36e3f2c 100644 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -388,7 +388,7 @@ void LLApp::setupErrorHandling(bool second_instance) #if defined(LL_BUGSPLAT) // Don't install our own signal handlers -- BugSplat needs to hook them, // or it's completely ineffectual. - bool installHandler = false; + //bool installHandler = false; #else // ! LL_BUGSPLAT // @@ -400,7 +400,7 @@ void LLApp::setupErrorHandling(bool second_instance) setup_signals(); // Add google breakpad exception handler configured for Darwin/Linux. - bool installHandler = true; + //bool installHandler = true; #endif // ! LL_BUGSPLAT #if LL_DARWIN @@ -427,13 +427,13 @@ void LLApp::setupErrorHandling(bool second_instance) { // P_TRACED flag is set, so this process is being debugged; do not install // the handler - if(info.kp_proc.p_flag & P_TRACED) installHandler = false; + //if(info.kp_proc.p_flag & P_TRACED) installHandler = false; } else { // Failed to discover if the process is being debugged; default to // installing the handler. - installHandler = true; + //installHandler = true; } #endif // ! LL_RELEASE_FOR_DOWNLOAD diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp index 662164af2d..10d7dc69a4 100644 --- a/indra/newview/llappviewermacosx.cpp +++ b/indra/newview/llappviewermacosx.cpp @@ -243,11 +243,11 @@ bool LLAppViewerMacOSX::init() bool success = LLAppViewer::init(); #if LL_SEND_CRASH_REPORTS - if (success) + /*if (success) { LLAppViewer* pApp = LLAppViewer::instance(); pApp->initCrashReporting(); - } + }*/ #endif return success; -- cgit v1.2.3 From 8be9b87adfb3409f9b0959396e3d46af7b06a299 Mon Sep 17 00:00:00 2001 From: Mnikolenko ProductEngine Date: Fri, 23 Apr 2021 15:09:27 +0300 Subject: DRTVWR-520 added codesign for cef and libvlc --- indra/newview/viewer_manifest.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 5a39616d55..13ec6b60d5 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -1293,9 +1293,13 @@ class DarwinManifest(ViewerManifest): signed=False sign_attempts=3 sign_retry_wait=15 + libvlc_path = app_in_dmg + "/Contents/Resources/llplugin/media_plugin_libvlc.dylib" + cef_path = app_in_dmg + "/Contents/Resources/llplugin/media_plugin_cef.dylib" while (not signed) and (sign_attempts > 0): try: sign_attempts-=1; + self.run_command(['codesign', '--force', '--timestamp','--keychain', viewer_keychain, '--sign', identity, libvlc_path]) + self.run_command(['codesign', '--force', '--timestamp', '--keychain', viewer_keychain, '--sign', identity, cef_path]) self.run_command( # Note: See blurb above about names of keychains ['codesign', '--verbose', '--deep', '--force', -- cgit v1.2.3 From 430661f1351b177355de7f2a993f6e34c835f939 Mon Sep 17 00:00:00 2001 From: Mnikolenko ProductEngine Date: Mon, 26 Apr 2021 19:12:49 +0300 Subject: SL-15170 remove mac_crash_logger --- indra/CMakeLists.txt | 3 - indra/llcommon/llapp.cpp | 70 +- indra/mac_crash_logger/CMakeLists.txt | 95 - indra/mac_crash_logger/CrashReporter.nib | Bin 32286 -> 0 bytes indra/mac_crash_logger/CrashReporter.xib | 3895 -------------------- indra/mac_crash_logger/Info.plist | 28 - indra/mac_crash_logger/llcrashloggermac.cpp | 91 - indra/mac_crash_logger/llcrashloggermac.h | 45 - indra/mac_crash_logger/llcrashloggermacdelegate.h | 52 - indra/mac_crash_logger/llcrashloggermacdelegate.mm | 75 - indra/mac_crash_logger/mac_crash_logger.cpp | 58 - indra/newview/CMakeLists.txt | 3 +- indra/newview/llappviewermacosx.cpp | 27 +- indra/newview/llappviewermacosx.h | 1 - indra/newview/viewer_manifest.py | 24 +- 15 files changed, 19 insertions(+), 4448 deletions(-) delete mode 100644 indra/mac_crash_logger/CMakeLists.txt delete mode 100755 indra/mac_crash_logger/CrashReporter.nib delete mode 100755 indra/mac_crash_logger/CrashReporter.xib delete mode 100644 indra/mac_crash_logger/Info.plist delete mode 100644 indra/mac_crash_logger/llcrashloggermac.cpp delete mode 100644 indra/mac_crash_logger/llcrashloggermac.h delete mode 100644 indra/mac_crash_logger/llcrashloggermacdelegate.h delete mode 100644 indra/mac_crash_logger/llcrashloggermacdelegate.mm delete mode 100644 indra/mac_crash_logger/mac_crash_logger.cpp diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt index f5e814187d..eb205ccb11 100644 --- a/indra/CMakeLists.txt +++ b/indra/CMakeLists.txt @@ -70,9 +70,6 @@ if (LINUX) add_subdirectory(${LLAPPEARANCEUTILITY_SRC_DIR} ${LLAPPEARANCEUTILITY_BIN_DIR}) endif (INSTALL_PROPRIETARY) add_dependencies(viewer linux-crash-logger-strip-target) -elseif (DARWIN) - add_subdirectory(${VIEWER_PREFIX}mac_crash_logger) - add_dependencies(viewer mac-crash-logger) elseif (WINDOWS) # cmake EXISTS requires an absolute path, see indra/cmake/Variables.cmake if (EXISTS ${VIEWER_DIR}win_setup) diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index fdb36e3f2c..72dd0ea048 100644 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -385,70 +385,16 @@ void LLApp::setupErrorHandling(bool second_instance) #else // ! LL_WINDOWS -#if defined(LL_BUGSPLAT) - // Don't install our own signal handlers -- BugSplat needs to hook them, - // or it's completely ineffectual. - //bool installHandler = false; - -#else // ! LL_BUGSPLAT - // - // Start up signal handling. - // - // There are two different classes of signals. Synchronous signals are delivered to a specific - // thread, asynchronous signals can be delivered to any thread (in theory) - // - setup_signals(); - - // Add google breakpad exception handler configured for Darwin/Linux. - //bool installHandler = true; +#if ! defined(LL_BUGSPLAT) + // + // Start up signal handling. + // + // There are two different classes of signals. Synchronous signals are delivered to a specific + // thread, asynchronous signals can be delivered to any thread (in theory) + // + setup_signals(); #endif // ! LL_BUGSPLAT -#if LL_DARWIN - // For the special case of Darwin, we do not want to install the handler if - // the process is being debugged as the app will exit with value ABRT (6) if - // we do. Unfortunately, the code below which performs that test relies on - // the structure kinfo_proc which has been tagged by apple as an unstable - // API. We disable this test for shipping versions to avoid conflicts with - // future releases of Darwin. This test is really only needed for developers - // starting the app from a debugger anyway. - #ifndef LL_RELEASE_FOR_DOWNLOAD - int mib[4]; - mib[0] = CTL_KERN; - mib[1] = KERN_PROC; - mib[2] = KERN_PROC_PID; - mib[3] = getpid(); - - struct kinfo_proc info; - memset(&info, 0, sizeof(info)); - - size_t size = sizeof(info); - int result = sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, NULL, 0); - if((result == 0) || (errno == ENOMEM)) - { - // P_TRACED flag is set, so this process is being debugged; do not install - // the handler - //if(info.kp_proc.p_flag & P_TRACED) installHandler = false; - } - else - { - // Failed to discover if the process is being debugged; default to - // installing the handler. - //installHandler = true; - } - #endif // ! LL_RELEASE_FOR_DOWNLOAD - -#elif LL_LINUX - if(installHandler && (mExceptionHandler == 0)) - { - if (mDumpPath.empty()) - { - mDumpPath = "/tmp"; - } - google_breakpad::MinidumpDescriptor desc(mDumpPath); - mExceptionHandler = new google_breakpad::ExceptionHandler(desc, NULL, unix_minidump_callback, NULL, true, -1); - } -#endif // LL_LINUX - #endif // ! LL_WINDOWS startErrorThread(); } diff --git a/indra/mac_crash_logger/CMakeLists.txt b/indra/mac_crash_logger/CMakeLists.txt deleted file mode 100644 index 95637c9a28..0000000000 --- a/indra/mac_crash_logger/CMakeLists.txt +++ /dev/null @@ -1,95 +0,0 @@ -# -*- cmake -*- - -project(mac_crash_logger) - -include(00-Common) -include(LLCommon) -include(LLCoreHttp) -include(LLCrashLogger) -include(LLMath) -include(LLMessage) -include(LLVFS) -include(LLXML) -include(Linking) -include(LLSharedLibs) -include(Boost) - -include_directories( - ${LLCOREHTTP_INCLUDE_DIRS} - ${LLCOMMON_INCLUDE_DIRS} - ${LLCRASHLOGGER_INCLUDE_DIRS} - ${LLMATH_INCLUDE_DIRS} - ${LLVFS_INCLUDE_DIRS} - ${LLXML_INCLUDE_DIRS} - ) -include_directories(SYSTEM - ${LLCOMMON_SYSTEM_INCLUDE_DIRS} - ${LLXML_SYSTEM_INCLUDE_DIRS} - ) - -set(mac_crash_logger_SOURCE_FILES - mac_crash_logger.cpp - llcrashloggermac.cpp - llcrashloggermacdelegate.mm - ) - -set(mac_crash_logger_HEADER_FILES - CMakeLists.txt - - llcrashloggermac.h - llcrashloggermacdelegate.h - ) - -set_source_files_properties(${mac_crash_logger_HEADER_FILES} - PROPERTIES HEADER_FILE_ONLY TRUE) -list(APPEND mac_crash_logger_SOURCE_FILES ${mac_crash_logger_HEADER_FILES}) - -set(mac_crash_logger_RESOURCE_FILES - CrashReporter.nib/ - ) -set_source_files_properties( - ${mac_crash_logger_RESOURCE_FILES} - PROPERTIES - HEADER_FILE_ONLY TRUE - ) -SOURCE_GROUP("Resources" FILES ${mac_crash_logger_RESOURCE_FILES}) -list(APPEND mac_crash_logger_SOURCE_FILES ${mac_crash_logger_RESOURCE_FILES}) - -add_executable(mac-crash-logger - MACOSX_BUNDLE - ${mac_crash_logger_SOURCE_FILES}) - -set_target_properties(mac-crash-logger - PROPERTIES - MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist - ) - -find_library(COCOA_LIBRARY Cocoa) - -target_link_libraries(mac-crash-logger - ${LLCRASHLOGGER_LIBRARIES} - ${LLVFS_LIBRARIES} - ${COCOA_LIBRARIES} - ${LLXML_LIBRARIES} - ${LLMESSAGE_LIBRARIES} - ${LLVFS_LIBRARIES} - ${LLMATH_LIBRARIES} - ${LLCOREHTTP_LIBRARIES} - ${LLCOMMON_LIBRARIES} - ${BOOST_CONTEXT_LIBRARY} - ${BOOST_FIBER_LIBRARY} - ) - -add_custom_command( - TARGET mac-crash-logger POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS - -E - copy_if_different - ${CMAKE_CURRENT_SOURCE_DIR}/CrashReporter.nib - ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/mac-crash-logger.app/Contents/Resources/CrashReporter.nib - ) - -ll_deploy_sharedlibs_command(mac-crash-logger) - - diff --git a/indra/mac_crash_logger/CrashReporter.nib b/indra/mac_crash_logger/CrashReporter.nib deleted file mode 100755 index e9d9e05985..0000000000 Binary files a/indra/mac_crash_logger/CrashReporter.nib and /dev/null differ diff --git a/indra/mac_crash_logger/CrashReporter.xib b/indra/mac_crash_logger/CrashReporter.xib deleted file mode 100755 index f6d4776d51..0000000000 --- a/indra/mac_crash_logger/CrashReporter.xib +++ /dev/null @@ -1,3895 +0,0 @@ - - - - 1070 - 11G63 - 2182 - 1138.51 - 569.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 2182 - - - NSTextField - NSView - NSWindowTemplate - NSMenu - NSMenuItem - NSTextFieldCell - NSButtonCell - IBNSLayoutConstraint - NSButton - NSCustomObject - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - NSApplication - - - FirstResponder - - - NSApplication - - - AMainMenu - - - - Second Life Crash Logger - - 1048576 - 2147483647 - - NSImage - NSMenuCheckmark - - - NSImage - NSMenuMixedState - - submenuAction: - - Second Life Crash Logger - - - - About Second Life Crash Logger - - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Preferences… - , - 1048576 - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Services - - 1048576 - 2147483647 - - - submenuAction: - - Services - - _NSServicesMenu - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Hide Second Life Crash Logger - h - 1048576 - 2147483647 - - - - - - Hide Others - h - 1572864 - 2147483647 - - - - - - Show All - - 1048576 - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Quit Second Life Crash Logger - q - 1048576 - 2147483647 - - - - - _NSAppleMenu - - - - - File - - 1048576 - 2147483647 - - - submenuAction: - - File - - - - New - n - 1048576 - 2147483647 - - - - - - Open… - o - 1048576 - 2147483647 - - - - - - Open Recent - - 1048576 - 2147483647 - - - submenuAction: - - Open Recent - - - - Clear Menu - - 1048576 - 2147483647 - - - - - _NSRecentDocumentsMenu - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Close - w - 1048576 - 2147483647 - - - - - - Save… - s - 1048576 - 2147483647 - - - - - - Revert to Saved - - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Page Setup... - P - 1179648 - 2147483647 - - - - - - - Print… - p - 1048576 - 2147483647 - - - - - - - - - Edit - - 1048576 - 2147483647 - - - submenuAction: - - Edit - - - - Undo - z - 1048576 - 2147483647 - - - - - - Redo - Z - 1179648 - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Cut - x - 1048576 - 2147483647 - - - - - - Copy - c - 1048576 - 2147483647 - - - - - - Paste - v - 1048576 - 2147483647 - - - - - - Paste and Match Style - V - 1572864 - 2147483647 - - - - - - Delete - - 1048576 - 2147483647 - - - - - - Select All - a - 1048576 - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Find - - 1048576 - 2147483647 - - - submenuAction: - - Find - - - - Find… - f - 1048576 - 2147483647 - - - 1 - - - - Find and Replace… - f - 1572864 - 2147483647 - - - 12 - - - - Find Next - g - 1048576 - 2147483647 - - - 2 - - - - Find Previous - G - 1179648 - 2147483647 - - - 3 - - - - Use Selection for Find - e - 1048576 - 2147483647 - - - 7 - - - - Jump to Selection - j - 1048576 - 2147483647 - - - - - - - - - Spelling and Grammar - - 1048576 - 2147483647 - - - submenuAction: - - Spelling and Grammar - - - - Show Spelling and Grammar - : - 1048576 - 2147483647 - - - - - - Check Document Now - ; - 1048576 - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Check Spelling While Typing - - 1048576 - 2147483647 - - - - - - Check Grammar With Spelling - - 1048576 - 2147483647 - - - - - - Correct Spelling Automatically - - 2147483647 - - - - - - - - - Substitutions - - 1048576 - 2147483647 - - - submenuAction: - - Substitutions - - - - Show Substitutions - - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Smart Copy/Paste - f - 1048576 - 2147483647 - - - 1 - - - - Smart Quotes - g - 1048576 - 2147483647 - - - 2 - - - - Smart Dashes - - 2147483647 - - - - - - Smart Links - G - 1179648 - 2147483647 - - - 3 - - - - Text Replacement - - 2147483647 - - - - - - - - - Transformations - - 2147483647 - - - submenuAction: - - Transformations - - - - Make Upper Case - - 2147483647 - - - - - - Make Lower Case - - 2147483647 - - - - - - Capitalize - - 2147483647 - - - - - - - - - Speech - - 1048576 - 2147483647 - - - submenuAction: - - Speech - - - - Start Speaking - - 1048576 - 2147483647 - - - - - - Stop Speaking - - 1048576 - 2147483647 - - - - - - - - - - - - Format - - 2147483647 - - - submenuAction: - - Format - - - - Font - - 2147483647 - - - submenuAction: - - Font - - - - Show Fonts - t - 1048576 - 2147483647 - - - - - - Bold - b - 1048576 - 2147483647 - - - 2 - - - - Italic - i - 1048576 - 2147483647 - - - 1 - - - - Underline - u - 1048576 - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Bigger - + - 1048576 - 2147483647 - - - 3 - - - - Smaller - - - 1048576 - 2147483647 - - - 4 - - - - YES - YES - - - 2147483647 - - - - - - Kern - - 2147483647 - - - submenuAction: - - Kern - - - - Use Default - - 2147483647 - - - - - - Use None - - 2147483647 - - - - - - Tighten - - 2147483647 - - - - - - Loosen - - 2147483647 - - - - - - - - - Ligature - - 2147483647 - - - submenuAction: - - Ligature - - - - Use Default - - 2147483647 - - - - - - Use None - - 2147483647 - - - - - - Use All - - 2147483647 - - - - - - - - - Baseline - - 2147483647 - - - submenuAction: - - Baseline - - - - Use Default - - 2147483647 - - - - - - Superscript - - 2147483647 - - - - - - Subscript - - 2147483647 - - - - - - Raise - - 2147483647 - - - - - - Lower - - 2147483647 - - - - - - - - - YES - YES - - - 2147483647 - - - - - - Show Colors - C - 1048576 - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Copy Style - c - 1572864 - 2147483647 - - - - - - Paste Style - v - 1572864 - 2147483647 - - - - - _NSFontMenu - - - - - Text - - 2147483647 - - - submenuAction: - - Text - - - - Align Left - { - 1048576 - 2147483647 - - - - - - Center - | - 1048576 - 2147483647 - - - - - - Justify - - 2147483647 - - - - - - Align Right - } - 1048576 - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Writing Direction - - 2147483647 - - - submenuAction: - - Writing Direction - - - - YES - Paragraph - - 2147483647 - - - - - - CURlZmF1bHQ - - 2147483647 - - - - - - CUxlZnQgdG8gUmlnaHQ - - 2147483647 - - - - - - CVJpZ2h0IHRvIExlZnQ - - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - YES - Selection - - 2147483647 - - - - - - CURlZmF1bHQ - - 2147483647 - - - - - - CUxlZnQgdG8gUmlnaHQ - - 2147483647 - - - - - - CVJpZ2h0IHRvIExlZnQ - - 2147483647 - - - - - - - - - YES - YES - - - 2147483647 - - - - - - Show Ruler - - 2147483647 - - - - - - Copy Ruler - c - 1310720 - 2147483647 - - - - - - Paste Ruler - v - 1310720 - 2147483647 - - - - - - - - - - - - View - - 1048576 - 2147483647 - - - submenuAction: - - View - - - - Show Toolbar - t - 1572864 - 2147483647 - - - - - - Customize Toolbar… - - 1048576 - 2147483647 - - - - - - - - - Window - - 1048576 - 2147483647 - - - submenuAction: - - Window - - - - Minimize - m - 1048576 - 2147483647 - - - - - - Zoom - - 1048576 - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Bring All to Front - - 1048576 - 2147483647 - - - - - _NSWindowsMenu - - - - - Help - - 2147483647 - - - submenuAction: - - Help - - - - Second Life Crash Logger Help - ? - 1048576 - 2147483647 - - - - - _NSHelpMenu - - - - _NSMainMenu - - - 15 - 2 - {{335, 390}, {508, 477}} - 1954021376 - Second Life Crash Logger - NSWindow - - - - - 256 - - - - 268 - {{17, 228}, {474, 229}} - - - - _NS:9 - {250, 750} - YES - - 67239424 - 272891904 - - U2Vjb25kIExpZmUgYXBwZWFycyB0byBoYXZlIGNyYXNoZWQgb3IgZnJvemVuIHRoZSBsYXN0IHRpbWUg -aXQgcmFuLgoKVGhpcyBjcmFzaCByZXBvcnRlciBjb2xsZWN0cyBpbmZvcm1hdGlvbiBhYm91dCB5b3Vy -IGNvbXB1dGVyJ3MgaGFyZHdhcmUgY29uZmlndXJhdGlvbiwgb3BlcmF0aW5nIHN5c3RlbSwgYW5kIHNv -bWUgU2Vjb25kIExpZmUgbG9ncywgYWxsIG9mIHdoaWNoIGFyZSB1c2VkIGZvciBkZWJ1Z2dpbmcgcHVy -cG9zZXMgb25seS4KCkluIHRoZSBzcGFjZSBiZWxvdywgcGxlYXNlIGJyaWVmbHkgZGVzY3JpYmUgd2hh -dCB5b3Ugd2VyZSBkb2luZyBvciB0cnlpbmcgdG8gZG8ganVzdCBwcmlvciB0byB0aGUgY3Jhc2guICBU -aGFuayB5b3UgZm9yIHlvdXIgaGVscCEKClRoaXMgcmVwb3J0IGlzIE5PVCByZWFkIGJ5IEN1c3RvbWVy -IFN1cHBvcnQuICBJZiB5b3UgaGF2ZSBiaWxsaW5nIG9yIG90aGVyIHF1ZXN0aW9ucywgcGxlYXNlIGdv -IHRvOiBodHRwOi8vd3d3LnNlY29uZGxpZmUuY29tL3N1cHBvcnQvCgpJZiB5b3UgZG9uJ3Qgd2lzaCB0 -byBzZW5kIExpbmRlbiBMYWIgYSBjcmFzaCByZXBvcnQsIHByZXNzIENhbmNlbC4 - - - LucidaGrande - 13 - 16 - - _NS:9 - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - - - - 268 - {{20, 64}, {468, 163}} - - - - _NS:9 - {250, 750} - YES - - -1805517311 - 272891904 - - - LucidaGrande - 9 - 3614 - - _NS:9 - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - - - - - - 268 - {{16, 18}, {189, 30}} - - - - _NS:9 - YES - - -2080244224 - 262144 - Remember This Choice - - _NS:9 - - 1211912703 - 2 - - NSImage - NSSwitch - - - NSSwitch - - - - 200 - 25 - - - - - 268 - {{285, 23}, {91, 17}} - - - - _NS:9 - YES - - -2080244224 - 134479872 - Send Report - - _NS:9 - - -2038152961 - 164 - - - 400 - 75 - - - - - 268 - {{388, 23}, {100, 17}} - - - - _NS:9 - YES - - -2080244224 - 134479872 - Don't Send - - _NS:9 - - -2038152961 - 164 - - - 400 - 75 - - - - {508, 477} - - - - - {{0, 0}, {1680, 1028}} - {10000000000000, 10000000000000} - YES - - - LLCrashLoggerMacDelegate - - - - - - - terminate: - - - - 449 - - - - orderFrontStandardAboutPanel: - - - - 142 - - - - delegate - - - - 495 - - - - performMiniaturize: - - - - 37 - - - - arrangeInFront: - - - - 39 - - - - print: - - - - 86 - - - - runPageLayout: - - - - 87 - - - - clearRecentDocuments: - - - - 127 - - - - performClose: - - - - 193 - - - - toggleContinuousSpellChecking: - - - - 222 - - - - undo: - - - - 223 - - - - copy: - - - - 224 - - - - checkSpelling: - - - - 225 - - - - paste: - - - - 226 - - - - stopSpeaking: - - - - 227 - - - - cut: - - - - 228 - - - - showGuessPanel: - - - - 230 - - - - redo: - - - - 231 - - - - selectAll: - - - - 232 - - - - startSpeaking: - - - - 233 - - - - delete: - - - - 235 - - - - performZoom: - - - - 240 - - - - performFindPanelAction: - - - - 241 - - - - centerSelectionInVisibleArea: - - - - 245 - - - - toggleGrammarChecking: - - - - 347 - - - - toggleSmartInsertDelete: - - - - 355 - - - - toggleAutomaticQuoteSubstitution: - - - - 356 - - - - toggleAutomaticLinkDetection: - - - - 357 - - - - saveDocument: - - - - 362 - - - - revertDocumentToSaved: - - - - 364 - - - - runToolbarCustomizationPalette: - - - - 365 - - - - toggleToolbarShown: - - - - 366 - - - - hide: - - - - 367 - - - - hideOtherApplications: - - - - 368 - - - - unhideAllApplications: - - - - 370 - - - - newDocument: - - - - 373 - - - - openDocument: - - - - 374 - - - - raiseBaseline: - - - - 426 - - - - lowerBaseline: - - - - 427 - - - - copyFont: - - - - 428 - - - - subscript: - - - - 429 - - - - superscript: - - - - 430 - - - - tightenKerning: - - - - 431 - - - - underline: - - - - 432 - - - - orderFrontColorPanel: - - - - 433 - - - - useAllLigatures: - - - - 434 - - - - loosenKerning: - - - - 435 - - - - pasteFont: - - - - 436 - - - - unscript: - - - - 437 - - - - useStandardKerning: - - - - 438 - - - - useStandardLigatures: - - - - 439 - - - - turnOffLigatures: - - - - 440 - - - - turnOffKerning: - - - - 441 - - - - toggleAutomaticSpellingCorrection: - - - - 456 - - - - orderFrontSubstitutionsPanel: - - - - 458 - - - - toggleAutomaticDashSubstitution: - - - - 461 - - - - toggleAutomaticTextReplacement: - - - - 463 - - - - uppercaseWord: - - - - 464 - - - - capitalizeWord: - - - - 467 - - - - lowercaseWord: - - - - 468 - - - - pasteAsPlainText: - - - - 486 - - - - performFindPanelAction: - - - - 487 - - - - performFindPanelAction: - - - - 488 - - - - performFindPanelAction: - - - - 489 - - - - showHelp: - - - - 493 - - - - alignCenter: - - - - 518 - - - - pasteRuler: - - - - 519 - - - - toggleRuler: - - - - 520 - - - - alignRight: - - - - 521 - - - - copyRuler: - - - - 522 - - - - alignJustified: - - - - 523 - - - - alignLeft: - - - - 524 - - - - makeBaseWritingDirectionNatural: - - - - 525 - - - - makeBaseWritingDirectionLeftToRight: - - - - 526 - - - - makeBaseWritingDirectionRightToLeft: - - - - 527 - - - - makeTextWritingDirectionNatural: - - - - 528 - - - - makeTextWritingDirectionLeftToRight: - - - - 529 - - - - makeTextWritingDirectionRightToLeft: - - - - 530 - - - - performFindPanelAction: - - - - 535 - - - - window - - - - 532 - - - - remember: - - - - 1176 - - - - send: - - - - 1177 - - - - cancel: - - - - 1178 - - - - crashText - - - - 1179 - - - - rememberCheck - - - - 1187 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - -3 - - - Application - - - 29 - - - - - - - - - - - - - - 19 - - - - - - - - 56 - - - - - - - - 217 - - - - - - - - 83 - - - - - - - - 81 - - - - - - - - - - - - - - - - - 75 - - - - - 78 - - - - - 72 - - - - - 82 - - - - - 124 - - - - - - - - 77 - - - - - 73 - - - - - 79 - - - - - 112 - - - - - 74 - - - - - 125 - - - - - - - - 126 - - - - - 205 - - - - - - - - - - - - - - - - - - - - - - 202 - - - - - 198 - - - - - 207 - - - - - 214 - - - - - 199 - - - - - 203 - - - - - 197 - - - - - 206 - - - - - 215 - - - - - 218 - - - - - - - - 216 - - - - - - - - 200 - - - - - - - - - - - - - 219 - - - - - 201 - - - - - 204 - - - - - 220 - - - - - - - - - - - - - 213 - - - - - 210 - - - - - 221 - - - - - 208 - - - - - 209 - - - - - 57 - - - - - - - - - - - - - - - - - - 58 - - - - - 134 - - - - - 150 - - - - - 136 - - - - - 144 - - - - - 129 - - - - - 143 - - - - - 236 - - - - - 131 - - - - - - - - 149 - - - - - 145 - - - - - 130 - - - - - 24 - - - - - - - - - - - 92 - - - - - 5 - - - - - 239 - - - - - 23 - - - - - 295 - - - - - - - - 296 - - - - - - - - - 297 - - - - - 298 - - - - - 211 - - - - - - - - 212 - - - - - - - - - 195 - - - - - 196 - - - - - 346 - - - - - 348 - - - - - - - - 349 - - - - - - - - - - - - - - 350 - - - - - 351 - - - - - 354 - - - - - 371 - - - - - - - - 372 - - - - - - - - 3 - 0 - - 3 - 1 - - 20 - - 1000 - 8 - 29 - 3 - - - - - - - 6 - 0 - - 6 - 1 - - 20 - - 1000 - 8 - 29 - 3 - - - - - 5 - 0 - - 5 - 1 - - 20 - - 1000 - 8 - 29 - 3 - - - - - 6 - 0 - - 6 - 1 - - 20 - - 1000 - 8 - 29 - 3 - - - - - 5 - 0 - - 5 - 1 - - 20 - - 1000 - 8 - 29 - 3 - - - - - 4 - 0 - - 4 - 1 - - 64 - - 1000 - 3 - 9 - 3 - - - - - 6 - 0 - - 6 - 1 - - 20 - - 1000 - 8 - 29 - 3 - - - - - 5 - 0 - - 5 - 1 - - 20 - - 1000 - 8 - 29 - 3 - - - - - 4 - 0 - - 4 - 1 - - 21 - - 1000 - 3 - 9 - 3 - - - - - 6 - 0 - - 6 - 1 - - 132 - - 1000 - 3 - 9 - 3 - - - - - 11 - 0 - - 11 - 1 - - 0.0 - - 1000 - 6 - 24 - 2 - - - - - 10 - 0 - - 10 - 1 - - 0.0 - - 1000 - 6 - 24 - 2 - - - - - - - 375 - - - - - - - - 376 - - - - - - - - - 377 - - - - - - - - 388 - - - - - - - - - - - - - - - - - - - - - - - 389 - - - - - 390 - - - - - 391 - - - - - 392 - - - - - 393 - - - - - 394 - - - - - 395 - - - - - 396 - - - - - 397 - - - - - - - - 398 - - - - - - - - 399 - - - - - - - - 400 - - - - - 401 - - - - - 402 - - - - - 403 - - - - - 404 - - - - - 405 - - - - - - - - - - - - 406 - - - - - 407 - - - - - 408 - - - - - 409 - - - - - 410 - - - - - 411 - - - - - - - - - - 412 - - - - - 413 - - - - - 414 - - - - - 415 - - - - - - - - - - - 416 - - - - - 417 - - - - - 418 - - - - - 419 - - - - - 450 - - - - - - - - 451 - - - - - - - - - - 452 - - - - - 453 - - - - - 454 - - - - - 457 - - - - - 459 - - - - - 460 - - - - - 462 - - - - - 465 - - - - - 466 - - - - - 485 - - - - - 490 - - - - - - - - 491 - - - - - - - - 492 - - - - - 494 - - - - - 496 - - - - - - - - 497 - - - - - - - - - - - - - - - - - 498 - - - - - 499 - - - - - 500 - - - - - 501 - - - - - 502 - - - - - 503 - - - - - - - - 504 - - - - - 505 - - - - - 506 - - - - - 507 - - - - - 508 - - - - - - - - - - - - - - - - 509 - - - - - 510 - - - - - 511 - - - - - 512 - - - - - 513 - - - - - 514 - - - - - 515 - - - - - 516 - - - - - 517 - - - - - 534 - - - - - 536 - - - - - - 8 - 0 - - 0 - 1 - - 229 - - 1000 - 3 - 9 - 1 - - - - - - - 537 - - - - - 593 - - - - - - 8 - 0 - - 0 - 1 - - 163 - - 1000 - 3 - 9 - 1 - - - - - - - 594 - - - - - 727 - - - - - - 7 - 0 - - 0 - 1 - - 183 - - 1000 - 3 - 9 - 1 - - - - - 8 - 0 - - 0 - 1 - - 22 - - 1000 - 3 - 9 - 1 - - - - - - - 728 - - - - - 775 - - - - - - - - 776 - - - - - 780 - - - - - - 7 - 0 - - 0 - 1 - - 100 - - 1000 - 3 - 9 - 1 - - - - - - - 781 - - - - - 884 - - - - - 981 - - - - - 982 - - - - - 1022 - - - - - 1026 - - - - - 979 - - - - - 985 - - - - - 977 - - - - - 1099 - - - - - 1093 - - - - - 1100 - - - - - 1098 - - - - - 1168 - - - - - 1167 - - - - - 1095 - - - - - 1166 - - - - - 1076 - - - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{380, 496}, {480, 360}} - - - - - - - - - - - - - - - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 1187 - - - - - LLCrashLoggerMacDelegate - NSObject - - id - id - id - - - - cancel: - id - - - remember: - id - - - send: - id - - - - NSTextField - NSButton - NSWindow - - - - crashText - NSTextField - - - rememberCheck - NSButton - - - window - NSWindow - - - - IBProjectSource - ./Classes/LLCrashLoggerMacDelegate.h - - - - NSLayoutConstraint - NSObject - - IBProjectSource - ./Classes/NSLayoutConstraint.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - YES - 3 - - {11, 11} - {10, 3} - {15, 15} - - YES - - diff --git a/indra/mac_crash_logger/Info.plist b/indra/mac_crash_logger/Info.plist deleted file mode 100644 index 2ebed11c3f..0000000000 --- a/indra/mac_crash_logger/Info.plist +++ /dev/null @@ -1,28 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - mac-crash-logger - CFBundleGetInfoString - - CFBundleIconFile - - CFBundleInfoDictionaryVersion - 6.0 - CFBundlePackageType - APPL - CFBundleShortVersionString - - CFBundleSignature - ???? - CFBundleVersion - 1.0.0 - NSMainNibFile - CrashReporter - NSPrincipalClass - NSApplication - - diff --git a/indra/mac_crash_logger/llcrashloggermac.cpp b/indra/mac_crash_logger/llcrashloggermac.cpp deleted file mode 100644 index ec3616e26a..0000000000 --- a/indra/mac_crash_logger/llcrashloggermac.cpp +++ /dev/null @@ -1,91 +0,0 @@ -/** - * @file llcrashloggermac.cpp - * @brief Mac OSX crash logger implementation - * - * $LicenseInfo:firstyear=2003&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 "llcrashloggermac.h" - -#include - -#include "indra_constants.h" // CRASH_BEHAVIOR_ASK, CRASH_SETTING_NAME -#include "llerror.h" -#include "llfile.h" -#include "lltimer.h" -#include "llstring.h" -#include "lldir.h" -#include "llsdserialize.h" - -// Windows Message Handlers - -BOOL gFirstDialog = TRUE; -LLFILE *gDebugFile = NULL; - -std::string gUserNotes = ""; -bool gSendReport = false; -bool gRememberChoice = false; - -LLCrashLoggerMac::LLCrashLoggerMac(void) -{ -} - -LLCrashLoggerMac::~LLCrashLoggerMac(void) -{ -} - -bool LLCrashLoggerMac::init(void) -{ - bool ok = LLCrashLogger::init(); - return ok; -} - -void LLCrashLoggerMac::gatherPlatformSpecificFiles() -{ -} - -bool LLCrashLoggerMac::frame() -{ - - if (mCrashBehavior == CRASH_BEHAVIOR_ALWAYS_SEND) - { - gSendReport = true; - } - - if(gSendReport) - { - setUserText(gUserNotes); - sendCrashLogs(); - } - - LL_INFOS() << "Sending of logs complete" << LL_ENDL; - - return true; -} - -bool LLCrashLoggerMac::cleanup() -{ - commonCleanup(); - mKeyMaster.releaseMaster(); - return true; -} diff --git a/indra/mac_crash_logger/llcrashloggermac.h b/indra/mac_crash_logger/llcrashloggermac.h deleted file mode 100644 index 05ef8c9f53..0000000000 --- a/indra/mac_crash_logger/llcrashloggermac.h +++ /dev/null @@ -1,45 +0,0 @@ -/** - * @file llcrashloggermac.h - * @brief Mac OSX crash logger definition - * - * $LicenseInfo:firstyear=2003&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 LLCRASHLOGGERMAC_H -#define LLCRASHLOGGERMAC_H - -#include "linden_common.h" -#include "llcrashlogger.h" -#include "llstring.h" - -class LLCrashLoggerMac : public LLCrashLogger -{ -public: - LLCrashLoggerMac(void); - ~LLCrashLoggerMac(void); - virtual bool init(); - virtual bool frame(); - virtual bool cleanup(); - virtual void gatherPlatformSpecificFiles(); -}; - -#endif diff --git a/indra/mac_crash_logger/llcrashloggermacdelegate.h b/indra/mac_crash_logger/llcrashloggermacdelegate.h deleted file mode 100644 index c998a8efe2..0000000000 --- a/indra/mac_crash_logger/llcrashloggermacdelegate.h +++ /dev/null @@ -1,52 +0,0 @@ -/** - * @file llcrashloggermacdelegate.h - * @brief Mac OSX crash logger implementation - * - * $LicenseInfo:firstyear=2003&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$ - */ - -/* -#import - -@interface LLCrashLoggerMacDelegate : NSObject -{ - IBOutlet NSTextField *crashText; - IBOutlet NSButton *rememberCheck; - - NSWindow *_window; - bool mRemember; - -} - -- (void)setWindow:(NSWindow *)newWindow; -- (NSWindow *)window; - -- (IBAction)remember:(id)sender; -- (IBAction)send:(id)sender; -- (IBAction)cancel:(id)sender; - -@property (assign) IBOutlet NSWindow *window; - -@end -*/ - - diff --git a/indra/mac_crash_logger/llcrashloggermacdelegate.mm b/indra/mac_crash_logger/llcrashloggermacdelegate.mm deleted file mode 100644 index b2af76a47c..0000000000 --- a/indra/mac_crash_logger/llcrashloggermacdelegate.mm +++ /dev/null @@ -1,75 +0,0 @@ -/** - * @file llcrashloggermacdelegate.mm - * @brief Mac OSX crash logger implementation - * - * $LicenseInfo:firstyear=2003&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$ - */ - - -/* -#import "llcrashloggermacdelegate.h" -#include - -extern std::string gUserNotes; -extern bool gSendReport; -extern bool gRememberChoice; - -@implementation LLCrashLoggerMacDelegate - -- (void)setWindow:(NSWindow *)window -{ - _window = window; -} - -- (NSWindow *)window -{ - return _window; -} - -- (void)dealloc -{ - [super dealloc]; -} - -std::string* NSToString( NSString *ns_str ) -{ - return ( new std::string([ns_str UTF8String]) ); -} - -- (IBAction)remember:(id)sender -{ - gRememberChoice = [rememberCheck state]; -} - -- (IBAction)send:(id)sender -{ - std::string* user_input = NSToString([crashText stringValue]); - gUserNotes = *user_input; - gSendReport = true; -} - -- (IBAction)cancel:(id)sender -{ - [ _window close]; -} -@end -*/ \ No newline at end of file diff --git a/indra/mac_crash_logger/mac_crash_logger.cpp b/indra/mac_crash_logger/mac_crash_logger.cpp deleted file mode 100644 index 54e41a1954..0000000000 --- a/indra/mac_crash_logger/mac_crash_logger.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/** - * @file mac_crash_logger.cpp - * @brief Mac OSX crash logger implementation - * - * $LicenseInfo:firstyear=2003&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 "llcrashloggermac.h" -#include "indra_constants.h" -#include "llpidlock.h" - -#include - -int main(int argc, char **argv) -{ - LLCrashLoggerMac app; - app.parseCommandOptions(argc, argv); - - LLSD options = LLApp::instance()->getOptionData( - LLApp::PRIORITY_COMMAND_LINE); - - if (! app.init()) - { - LL_WARNS() << "Unable to initialize application." << LL_ENDL; - return 1; - } - - if (app.getCrashBehavior() != CRASH_BEHAVIOR_ALWAYS_SEND) - { -// return NSApplicationMain(argc, (const char **)argv); - } - app.frame(); - app.cleanup(); - - LL_INFOS() << "Crash reporter finished normally." << LL_ENDL; - - return 0; -} diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index de77e2404a..f4a5986bec 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -2204,8 +2204,7 @@ if (DARWIN) ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py ) - add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_libvlc media_plugin_cef mac-crash-logger) - add_dependencies(${VIEWER_BINARY_NAME} mac-crash-logger) + add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_libvlc media_plugin_cef) if (ENABLE_SIGNING) set(SIGNING_SETTING "--signature=${SIGNING_IDENTITY}") diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp index 10d7dc69a4..862e2b45df 100644 --- a/indra/newview/llappviewermacosx.cpp +++ b/indra/newview/llappviewermacosx.cpp @@ -240,17 +240,7 @@ LLAppViewerMacOSX::~LLAppViewerMacOSX() bool LLAppViewerMacOSX::init() { - bool success = LLAppViewer::init(); - -#if LL_SEND_CRASH_REPORTS - /*if (success) - { - LLAppViewer* pApp = LLAppViewer::instance(); - pApp->initCrashReporting(); - }*/ -#endif - - return success; + return LLAppViewer::init(); } // MacOSX may add and addition command line arguement for the process serial number. @@ -367,21 +357,6 @@ bool LLAppViewerMacOSX::restoreErrorTrap() return reset_count == 0; } -void LLAppViewerMacOSX::initCrashReporting(bool reportFreeze) -{ - std::string command_str = "mac-crash-logger.app"; - - std::stringstream pid_str; - pid_str << LLApp::getPid(); - std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, ""); - std::string appname = gDirUtilp->getExecutableFilename(); - std::string str[] = { "-pid", pid_str.str(), "-dumpdir", logdir, "-procname", appname.c_str() }; - std::vector< std::string > args( str, str + ( sizeof ( str ) / sizeof ( std::string ) ) ); - LL_WARNS() << "about to launch mac-crash-logger" << pid_str.str() - << " " << logdir << " " << appname << LL_ENDL; - launchApplication(&command_str, &args); -} - std::string LLAppViewerMacOSX::generateSerialNumber() { char serial_md5[MD5HEX_STR_SIZE]; // Flawfinder: ignore diff --git a/indra/newview/llappviewermacosx.h b/indra/newview/llappviewermacosx.h index d5a80864be..b0e325a955 100644 --- a/indra/newview/llappviewermacosx.h +++ b/indra/newview/llappviewermacosx.h @@ -44,7 +44,6 @@ public: protected: virtual bool restoreErrorTrap(); - virtual void initCrashReporting(bool reportFreeze); std::string generateSerialNumber(); virtual bool initParseCommandLine(LLCommandLineParser& clp); diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 13ec6b60d5..a981e7c758 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -1058,21 +1058,15 @@ class DarwinManifest(ViewerManifest): # our apps executable_path = {} - for app_bld_dir, app in (("mac_crash_logger", "mac-crash-logger.app"), - # plugin launcher - (os.path.join("llplugin", "slplugin"), "SLPlugin.app"), - ): - self.path2basename(os.path.join(os.pardir, - app_bld_dir, self.args['configuration']), - app) - executable_path[app] = \ - self.dst_path_of(os.path.join(app, "Contents", "MacOS")) - - # our apps dependencies on shared libs - # for each app, for each dylib we collected in dylibs, - # create a symlink to the real copy of the dylib. - with self.prefix(dst=os.path.join(app, "Contents", "Resources")): - for libfile in dylibs: + self.path2basename(os.path.join(os.pardir, os.path.join("llplugin", "slplugin"), self.args['configuration']), "SLPlugin.app") + executable_path["SLPlugin.app"] = \ + self.dst_path_of(os.path.join("SLPlugin.app", "Contents", "MacOS")) + + # our apps dependencies on shared libs + # for each app, for each dylib we collected in dylibs, + # create a symlink to the real copy of the dylib. + with self.prefix(dst=os.path.join("SLPlugin.app", "Contents", "Resources")): + for libfile in dylibs: self.relsymlinkf(os.path.join(libfile_parent, libfile)) # Dullahan helper apps go inside SLPlugin.app -- cgit v1.2.3 From 5d21daf2db6f20f9c72779aaa48a0388469b8839 Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Tue, 27 Apr 2021 06:11:17 +0300 Subject: DRTVWR-520 SLPlugin signing and hardened runtime for viewer --- indra/newview/viewer_manifest.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index a981e7c758..6cbb82b39b 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -1289,16 +1289,15 @@ class DarwinManifest(ViewerManifest): sign_retry_wait=15 libvlc_path = app_in_dmg + "/Contents/Resources/llplugin/media_plugin_libvlc.dylib" cef_path = app_in_dmg + "/Contents/Resources/llplugin/media_plugin_cef.dylib" + slplugin_path = app_in_dmg + "Contents/Resources/SLPlugin.app/Contents/MacOS/SLPlugin" while (not signed) and (sign_attempts > 0): try: sign_attempts-=1; + # Note: See blurb above about names of keychains self.run_command(['codesign', '--force', '--timestamp','--keychain', viewer_keychain, '--sign', identity, libvlc_path]) self.run_command(['codesign', '--force', '--timestamp', '--keychain', viewer_keychain, '--sign', identity, cef_path]) - self.run_command( - # Note: See blurb above about names of keychains - ['codesign', '--verbose', '--deep', '--force', - '--keychain', viewer_keychain, '--sign', identity, - app_in_dmg]) + self.run_command(['codesign', '--verbose', '--deep', '--force', '--options', 'runtime', '--keychain', viewer_keychain, '--sign', identity, slplugin_path]) + self.run_command(['codesign', '--verbose', '--deep', '--force', '--options', 'runtime', '--keychain', viewer_keychain, '--sign', identity, app_in_dmg]) signed=True # if no exception was raised, the codesign worked except ManifestError as err: if sign_attempts: @@ -1361,7 +1360,7 @@ class LinuxManifest(ViewerManifest): with self.prefix(dst="bin"): self.path("secondlife-bin","do-not-directly-run-secondlife-bin") self.path("../linux_crash_logger/linux-crash-logger","linux-crash-logger.bin") - self.path2basename("../llplugin/slplugin", "SLPlugin") + self.path2basename("../llplugin/slplugin", "SLPlugin") #this copies over the python wrapper script, associated utilities and required libraries, see SL-321, SL-322 and SL-323 with self.prefix(src="../viewer_components/manager", dst=""): self.path("*.py") -- cgit v1.2.3 From 38888d2657ffe83b93718a588c3b351ff17b2869 Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Tue, 27 Apr 2021 07:37:56 +0300 Subject: typo fix --- indra/newview/viewer_manifest.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 6cbb82b39b..816f3b23e4 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -1289,10 +1289,10 @@ class DarwinManifest(ViewerManifest): sign_retry_wait=15 libvlc_path = app_in_dmg + "/Contents/Resources/llplugin/media_plugin_libvlc.dylib" cef_path = app_in_dmg + "/Contents/Resources/llplugin/media_plugin_cef.dylib" - slplugin_path = app_in_dmg + "Contents/Resources/SLPlugin.app/Contents/MacOS/SLPlugin" + slplugin_path = app_in_dmg + "/Contents/Resources/SLPlugin.app/Contents/MacOS/SLPlugin" while (not signed) and (sign_attempts > 0): try: - sign_attempts-=1; + sign_attempts-=1 # Note: See blurb above about names of keychains self.run_command(['codesign', '--force', '--timestamp','--keychain', viewer_keychain, '--sign', identity, libvlc_path]) self.run_command(['codesign', '--force', '--timestamp', '--keychain', viewer_keychain, '--sign', identity, cef_path]) -- cgit v1.2.3 From 0c13a8d08f505a1e8a8f48b7436f78b91d16a2fc Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Tue, 27 Apr 2021 08:57:39 +0300 Subject: DRTVWR-520 Sign greenlet.so --- indra/newview/viewer_manifest.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 816f3b23e4..3c5240066f 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -1290,12 +1290,14 @@ class DarwinManifest(ViewerManifest): libvlc_path = app_in_dmg + "/Contents/Resources/llplugin/media_plugin_libvlc.dylib" cef_path = app_in_dmg + "/Contents/Resources/llplugin/media_plugin_cef.dylib" slplugin_path = app_in_dmg + "/Contents/Resources/SLPlugin.app/Contents/MacOS/SLPlugin" + greenlet_path = app_in_dmg + "/Contents/Resources/updater/greenlet.so" while (not signed) and (sign_attempts > 0): try: sign_attempts-=1 # Note: See blurb above about names of keychains self.run_command(['codesign', '--force', '--timestamp','--keychain', viewer_keychain, '--sign', identity, libvlc_path]) self.run_command(['codesign', '--force', '--timestamp', '--keychain', viewer_keychain, '--sign', identity, cef_path]) + self.run_command(['codesign', '--force', '--timestamp', '--keychain', viewer_keychain, '--sign', identity, greenlet_path]) self.run_command(['codesign', '--verbose', '--deep', '--force', '--options', 'runtime', '--keychain', viewer_keychain, '--sign', identity, slplugin_path]) self.run_command(['codesign', '--verbose', '--deep', '--force', '--options', 'runtime', '--keychain', viewer_keychain, '--sign', identity, app_in_dmg]) signed=True # if no exception was raised, the codesign worked -- cgit v1.2.3 From bd4ad276c0aec58a8852b848c190bd4b67e238f3 Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Thu, 29 Apr 2021 04:57:05 +0300 Subject: DRTVWR-520 Notarize the viewer on TeamCity --- indra/newview/installers/darwin/apple-notarize.sh | 42 +++++++++++++++++++++++ indra/newview/viewer_manifest.py | 1 + 2 files changed, 43 insertions(+) create mode 100644 indra/newview/installers/darwin/apple-notarize.sh diff --git a/indra/newview/installers/darwin/apple-notarize.sh b/indra/newview/installers/darwin/apple-notarize.sh new file mode 100644 index 0000000000..a590f52e38 --- /dev/null +++ b/indra/newview/installers/darwin/apple-notarize.sh @@ -0,0 +1,42 @@ +#!/bin/sh +​ +CONFIG_FILE="$build_secrets_checkout/code-signing-osx/notarize_creds.sh" +if [ -f "$CONFIG_FILE" ]; then + source $CONFIG_FILE + + app_file="$1" + zip_file=${app_file/app/zip} + ditto -c -k --keepParent "$app_file" "$zip_file" + ​ + ​ + requestUUID=$(xcrun altool --notarize-app --primary-bundle-id "com.secondlife.viewer" \ + --username $USERNAME \ + --password $PASSWORD \ + --asc-provider $ASC_PROVIDER \ + --file "$zip_file" 2>&1 \ + | awk '/RequestUUID/ { print $NF; }') + ​ + echo "Apple Notarization RequestUUID: $requestUUID" + ​ + if [[ -n $requestUUID ]]; then + status="in progress" + while [[ "$status" == "in progress" ]]; do + sleep 30 + status=$(xcrun altool --notarization-info "$requestUUID" \ + --username $USERNAME \ + --password $PASSWORD 2>&1 \ + | awk -F ': ' '/Status:/ { print $2; }' ) + echo "$status" + done + ​ + # log results + xcrun altool --notarization-info "$requestUUID" \ + --username $USERNAME \ + --password $PASSWORD + + if [["$status" == "success"]]; then + xcrun stapler staple "$app_file" + fi + fi +fi + diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 3c5240066f..fd8244b894 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -1310,6 +1310,7 @@ class DarwinManifest(ViewerManifest): print >> sys.stderr, "Maximum codesign attempts exceeded; giving up" raise self.run_command(['spctl', '-a', '-texec', '-vvvv', app_in_dmg]) + self.run_command([self.src_path_of("installers/darwin/apple-notarize.sh"), app_in_dmg]) finally: # Unmount the image even if exceptions from any of the above -- cgit v1.2.3 From 2f7e9aac00b0c76210154ca209cd83fac7b8086d Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Thu, 29 Apr 2021 06:21:04 +0300 Subject: buildfix (chmod a+x) --- indra/newview/installers/darwin/apple-notarize.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 indra/newview/installers/darwin/apple-notarize.sh diff --git a/indra/newview/installers/darwin/apple-notarize.sh b/indra/newview/installers/darwin/apple-notarize.sh old mode 100644 new mode 100755 -- cgit v1.2.3 From 487685fef1ad4afdb1d6692a4ab6b2980205abd7 Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Thu, 29 Apr 2021 08:07:24 +0300 Subject: DRTVWR-520 Safety check; remove temporary zip file --- indra/newview/installers/darwin/apple-notarize.sh | 61 +++++++++++------------ 1 file changed, 30 insertions(+), 31 deletions(-) diff --git a/indra/newview/installers/darwin/apple-notarize.sh b/indra/newview/installers/darwin/apple-notarize.sh index a590f52e38..00d10b222a 100755 --- a/indra/newview/installers/darwin/apple-notarize.sh +++ b/indra/newview/installers/darwin/apple-notarize.sh @@ -1,42 +1,41 @@ #!/bin/sh -​ CONFIG_FILE="$build_secrets_checkout/code-signing-osx/notarize_creds.sh" if [ -f "$CONFIG_FILE" ]; then source $CONFIG_FILE - app_file="$1" zip_file=${app_file/app/zip} ditto -c -k --keepParent "$app_file" "$zip_file" - ​ - ​ - requestUUID=$(xcrun altool --notarize-app --primary-bundle-id "com.secondlife.viewer" \ - --username $USERNAME \ - --password $PASSWORD \ - --asc-provider $ASC_PROVIDER \ - --file "$zip_file" 2>&1 \ - | awk '/RequestUUID/ { print $NF; }') - ​ - echo "Apple Notarization RequestUUID: $requestUUID" - ​ - if [[ -n $requestUUID ]]; then - status="in progress" - while [[ "$status" == "in progress" ]]; do - sleep 30 - status=$(xcrun altool --notarization-info "$requestUUID" \ - --username $USERNAME \ - --password $PASSWORD 2>&1 \ - | awk -F ': ' '/Status:/ { print $2; }' ) - echo "$status" - done - ​ - # log results - xcrun altool --notarization-info "$requestUUID" \ - --username $USERNAME \ - --password $PASSWORD - - if [["$status" == "success"]]; then - xcrun stapler staple "$app_file" + if [ -f "$zip_file" ]; then + requestUUID=$(xcrun altool --notarize-app --primary-bundle-id "com.secondlife.viewer" \ + --username $USERNAME \ + --password $PASSWORD \ + --asc-provider $ASC_PROVIDER \ + --file "$zip_file" 2>&1 \ + | awk '/RequestUUID/ { print $NF; }') + + echo "Apple Notarization RequestUUID: $requestUUID" + + if [[ -n $requestUUID ]]; then + status="in progress" + while [[ "$status" == "in progress" ]]; do + sleep 30 + status=$(xcrun altool --notarization-info "$requestUUID" \ + --username $USERNAME \ + --password $PASSWORD 2>&1 \ + | awk -F ': ' '/Status:/ { print $2; }' ) + echo "$status" + done + # log results + xcrun altool --notarization-info "$requestUUID" \ + --username $USERNAME \ + --password $PASSWORD + + if [["$status" == "success"]]; then + xcrun stapler staple "$app_file" + fi fi + #remove temporary file + rm "$zip_file" fi fi -- cgit v1.2.3 From 02405a74d2bdaa3ecd6510eb198e1bf98cb1b051 Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Sat, 1 May 2021 02:05:06 +0300 Subject: DRTVWR-520 Post-merge build fix + error handling improvement --- indra/newview/installers/darwin/apple-notarize.sh | 7 +++++-- indra/newview/viewer_manifest.py | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/indra/newview/installers/darwin/apple-notarize.sh b/indra/newview/installers/darwin/apple-notarize.sh index 00d10b222a..b953af81af 100755 --- a/indra/newview/installers/darwin/apple-notarize.sh +++ b/indra/newview/installers/darwin/apple-notarize.sh @@ -30,12 +30,15 @@ if [ -f "$CONFIG_FILE" ]; then --username $USERNAME \ --password $PASSWORD + #remove temporary file + rm "$zip_file" + if [["$status" == "success"]]; then xcrun stapler staple "$app_file" + elif [["$status" == "invalid"]]; then + exit 1 fi fi - #remove temporary file - rm "$zip_file" fi fi diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index e031557b69..80f6b2aa9f 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -1294,7 +1294,7 @@ class DarwinManifest(ViewerManifest): libvlc_path = app_in_dmg + "/Contents/Resources/llplugin/media_plugin_libvlc.dylib" cef_path = app_in_dmg + "/Contents/Resources/llplugin/media_plugin_cef.dylib" slplugin_path = app_in_dmg + "/Contents/Resources/SLPlugin.app/Contents/MacOS/SLPlugin" - greenlet_path = app_in_dmg + "/Contents/Resources/updater/greenlet.so" + greenlet_path = app_in_dmg + "/Contents/Resources/updater/greenlet/_greenlet.so" while (not signed) and (sign_attempts > 0): try: sign_attempts-=1 -- cgit v1.2.3 From 933b98880e836b74f65b8535fed6da3519b72cf4 Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Sat, 1 May 2021 02:14:34 +0300 Subject: DRTVWR-520 Updated uriparser to codeticket build 559132 --- autobuild.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 69ac7ca524..b7a2f0a132 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3038,9 +3038,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 60f008c5fd31641ad4e61ac751ce15d1 + c42575ac8997de979eadb082c33a578e url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/75748/723495/uriparser-0.9.4-darwin64-555117.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/81322/765512/uriparser-0.9.4-darwin64-559132.tar.bz2 name darwin64 @@ -3074,9 +3074,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 00aff37a6f5e1fe08456702d28706cf6 + 901b1063556fc6b2575e745eef2bf744 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/75751/723507/uriparser-0.9.4-windows-555117.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/81323/765528/uriparser-0.9.4-windows-559132.tar.bz2 name windows @@ -3086,9 +3086,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - ff27a91f3941c7bef5e1613a064cb048 + 962c01d553f286c430102998129fb0d6 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/75750/723506/uriparser-0.9.4-windows64-555117.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/81324/765527/uriparser-0.9.4-windows64-559132.tar.bz2 name windows64 -- cgit v1.2.3 From b91561e982dcf836e44a924018899a220c03cd9d Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 27 May 2021 00:04:08 +0300 Subject: SL-15211 Update OpenSSL library --- autobuild.xml | 28 ++++++++++---------- indra/cmake/Copy3rdPartyLibs.cmake | 11 ++++++-- indra/cmake/OpenSSL.cmake | 2 +- indra/llmessage/llblowfishcipher.cpp | 28 +++++++++++--------- indra/newview/CMakeLists.txt | 8 +++--- indra/newview/llsecapi.h | 2 +- indra/newview/llsechandler_basic.cpp | 48 ++++++++++++++++++++--------------- indra/newview/llsechandler_basic.h | 4 +-- indra/newview/tests/llsecapi_test.cpp | 2 +- indra/newview/viewer_manifest.py | 10 +++++--- 10 files changed, 83 insertions(+), 60 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index b7a2f0a132..fc7226c346 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -398,9 +398,9 @@ archive hash - 52fc837a5840f5e6991842cf2f73a9d7 + 13f74f43a6363ec998569f731fd869c5 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/80409/758717/curl-7.54.1.558452-darwin64-558452.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/82637/774617/curl-7.54.1.560191-darwin64-560191.tar.bz2 name darwin64 @@ -434,11 +434,11 @@ archive hash - 8de0af7c8168406bf18bdcd5bc44e40e + 0df99bd685dc3561ca8ea347b2921987 hash_algorithm md5 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/80411/758714/curl-7.54.1.558452-windows-558452.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/82639/774610/curl-7.54.1.560191-windows-560191.tar.bz2 name windows @@ -448,16 +448,16 @@ archive hash - dc633acdbd3595db4f904e68e48b4744 + 50db2a9e6b74ec4b0c38b1ea8f135735 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/80410/758715/curl-7.54.1.558452-windows64-558452.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/82638/774608/curl-7.54.1.560191-windows64-560191.tar.bz2 name windows64 version - 7.54.1.558452 + 7.54.1.560191 db @@ -2738,9 +2738,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 166aa05b379b13156de5821252040498 + 5503e4928bcdb0a29685b3242c4a409b url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78582/743936/openssl-1.0.2l.557043-darwin64-557043.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/82619/774464/openssl-1.1.1l.560177-darwin64-560177.tar.bz2 name darwin64 @@ -2774,9 +2774,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 68aae05216c035283c79aad6dd88d8da + d2153f20dc2d35c609b876a9f019a748 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78590/743992/openssl-1.0.2l.557043-windows-557043.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/82623/774521/openssl-1.1.1l.560177-windows-560177.tar.bz2 name windows @@ -2786,16 +2786,16 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - d2576a386559cefb654154d8f0de6337 + f40b8622ba38084b0962e273988d748f url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78588/743976/openssl-1.0.2l.557043-windows64-557043.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/82624/774520/openssl-1.1.1l.560177-windows64-560177.tar.bz2 name windows64 version - 1.0.2l.557043 + 1.1.1l.560177 pcre diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index 9978de6eba..848547f2a2 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -56,14 +56,21 @@ if(WINDOWS) libapr-1.dll libaprutil-1.dll libapriconv-1.dll - ssleay32.dll - libeay32.dll nghttp2.dll glod.dll libhunspell.dll uriparser.dll ) + # OpenSSL + if(ADDRESS_SIZE EQUAL 64) + set(release_files ${release_files} libcrypto-1_1-x64.dll) + set(release_files ${release_files} libssl-1_1-x64.dll) + else(ADDRESS_SIZE EQUAL 64) + set(release_files ${release_files} libcrypto-1_1.dll) + set(release_files ${release_files} libssl-1_1.dll) + endif(ADDRESS_SIZE EQUAL 64) + # Filenames are different for 32/64 bit BugSplat file and we don't # have any control over them so need to branch. if (BUGSPLAT_DB) diff --git a/indra/cmake/OpenSSL.cmake b/indra/cmake/OpenSSL.cmake index eb548bdcc1..32400f5e4e 100644 --- a/indra/cmake/OpenSSL.cmake +++ b/indra/cmake/OpenSSL.cmake @@ -9,7 +9,7 @@ if (USESYSTEMLIBS) else (USESYSTEMLIBS) use_prebuilt_binary(openssl) if (WINDOWS) - set(OPENSSL_LIBRARIES ssleay32 libeay32) + set(OPENSSL_LIBRARIES libssl libcrypto) else (WINDOWS) set(OPENSSL_LIBRARIES ssl crypto) endif (WINDOWS) diff --git a/indra/llmessage/llblowfishcipher.cpp b/indra/llmessage/llblowfishcipher.cpp index 0b5025a422..949d4cc0c7 100644 --- a/indra/llmessage/llblowfishcipher.cpp +++ b/indra/llmessage/llblowfishcipher.cpp @@ -52,24 +52,28 @@ U32 LLBlowfishCipher::encrypt(const U8* src, U32 src_len, U8* dst, U32 dst_len) if (src_len > dst_len) return 0; // OpenSSL uses "cipher contexts" to hold encryption parameters. - EVP_CIPHER_CTX context; - EVP_CIPHER_CTX_init(&context); + EVP_CIPHER_CTX *context = EVP_CIPHER_CTX_new(); + if (!context) + { + LL_WARNS() << "LLBlowfishCipher::encrypt EVP_CIPHER_CTX initiation failure" << LL_ENDL; + return 0; + } // We want a blowfish cyclic block chain cipher, but need to set // the key length before we pass in a key, so call EncryptInit // first with NULLs. - EVP_EncryptInit_ex(&context, EVP_bf_cbc(), NULL, NULL, NULL); - EVP_CIPHER_CTX_set_key_length(&context, (int)mSecretSize); + EVP_EncryptInit_ex(context, EVP_bf_cbc(), NULL, NULL, NULL); + EVP_CIPHER_CTX_set_key_length(context, (int)mSecretSize); // Complete initialization. Per EVP_EncryptInit man page, the // cipher pointer must be NULL. Apparently initial_vector must // be 8 bytes for blowfish, as this is the block size. unsigned char initial_vector[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - EVP_EncryptInit_ex(&context, NULL, NULL, mSecret, initial_vector); + EVP_EncryptInit_ex(context, NULL, NULL, mSecret, initial_vector); - int blocksize = EVP_CIPHER_CTX_block_size(&context); - int keylen = EVP_CIPHER_CTX_key_length(&context); - int iv_length = EVP_CIPHER_CTX_iv_length(&context); + int blocksize = EVP_CIPHER_CTX_block_size(context); + int keylen = EVP_CIPHER_CTX_key_length(context); + int iv_length = EVP_CIPHER_CTX_iv_length(context); LL_DEBUGS() << "LLBlowfishCipher blocksize " << blocksize << " keylen " << keylen << " iv_len " << iv_length @@ -77,7 +81,7 @@ U32 LLBlowfishCipher::encrypt(const U8* src, U32 src_len, U8* dst, U32 dst_len) int output_len = 0; int temp_len = 0; - if (!EVP_EncryptUpdate(&context, + if (!EVP_EncryptUpdate(context, dst, &output_len, src, @@ -89,18 +93,18 @@ U32 LLBlowfishCipher::encrypt(const U8* src, U32 src_len, U8* dst, U32 dst_len) // There may be some final data left to encrypt if the input is // not an exact multiple of the block size. - if (!EVP_EncryptFinal_ex(&context, (unsigned char*)(dst + output_len), &temp_len)) + if (!EVP_EncryptFinal_ex(context, (unsigned char*)(dst + output_len), &temp_len)) { LL_WARNS() << "LLBlowfishCipher::encrypt EVP_EncryptFinal failure" << LL_ENDL; goto ERROR; } output_len += temp_len; - EVP_CIPHER_CTX_cleanup(&context); + EVP_CIPHER_CTX_free(context); return output_len; ERROR: - EVP_CIPHER_CTX_cleanup(&context); + EVP_CIPHER_CTX_free(context); return 0; } diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 63045502c9..41b3b1d30f 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1828,10 +1828,6 @@ if (WINDOWS) ${CMAKE_CURRENT_SOURCE_DIR}/licenses-win32.txt ${CMAKE_CURRENT_SOURCE_DIR}/featuretable.txt ${CMAKE_CURRENT_SOURCE_DIR}/featuretable_xp.txt - ${ARCH_PREBUILT_DIRS_RELEASE}/libeay32.dll - ${ARCH_PREBUILT_DIRS_RELEASE}/ssleay32.dll - ${ARCH_PREBUILT_DIRS_DEBUG}/libeay32.dll - ${ARCH_PREBUILT_DIRS_DEBUG}/ssleay32.dll ${viewer_APPSETTINGS_FILES} SLPlugin media_plugin_cef @@ -1844,11 +1840,15 @@ if (WINDOWS) list(APPEND COPY_INPUT_DEPENDENCIES ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/vivoxsdk_x64.dll ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/ortp_x64.dll + ${ARCH_PREBUILT_DIRS_RELEASE}/libcrypto-1_1-x64.dll + ${ARCH_PREBUILT_DIRS_RELEASE}/libssl-1_1-x64.dll ) else (ADDRESS_SIZE EQUAL 64) list(APPEND COPY_INPUT_DEPENDENCIES ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/vivoxsdk.dll ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/ortp.dll + ${ARCH_PREBUILT_DIRS_RELEASE}/libcrypto-1_1.dll + ${ARCH_PREBUILT_DIRS_RELEASE}/libssl-1_1.dll ) endif (ADDRESS_SIZE EQUAL 64) diff --git a/indra/newview/llsecapi.h b/indra/newview/llsecapi.h index 14059f828a..1e6f2154bc 100644 --- a/indra/newview/llsecapi.h +++ b/indra/newview/llsecapi.h @@ -452,7 +452,7 @@ public: virtual LLPointer getCertificate(X509* openssl_cert)=0; // instantiate a chain from an X509_STORE_CTX - virtual LLPointer getCertificateChain(const X509_STORE_CTX* chain)=0; + virtual LLPointer getCertificateChain(X509_STORE_CTX* chain)=0; // instantiate a cert store given it's id. if a persisted version // exists, it'll be loaded. If not, one will be created (but not diff --git a/indra/newview/llsechandler_basic.cpp b/indra/newview/llsechandler_basic.cpp index 737ef30ada..94331fddfa 100644 --- a/indra/newview/llsechandler_basic.cpp +++ b/indra/newview/llsechandler_basic.cpp @@ -95,7 +95,7 @@ LLBasicCertificate::LLBasicCertificate(const std::string& pem_cert, LLBasicCertificate::LLBasicCertificate(X509* pCert, const LLSD* validation_params) { - if (!pCert || !pCert->cert_info) + if (!pCert) { LLTHROW(LLInvalidCertificate(LLSD::emptyMap())); } @@ -355,8 +355,8 @@ LLSD cert_name_from_X509_NAME(X509_NAME* name) char buffer[32]; X509_NAME_ENTRY *entry = X509_NAME_get_entry(name, entry_index); - std::string name_value = std::string((const char*)M_ASN1_STRING_data(X509_NAME_ENTRY_get_data(entry)), - M_ASN1_STRING_length(X509_NAME_ENTRY_get_data(entry))); + std::string name_value = std::string((const char*)ASN1_STRING_data(X509_NAME_ENTRY_get_data(entry)), + ASN1_STRING_length(X509_NAME_ENTRY_get_data(entry))); ASN1_OBJECT* name_obj = X509_NAME_ENTRY_get_object(entry); OBJ_obj2txt(buffer, sizeof(buffer), name_obj, 0); @@ -683,29 +683,29 @@ std::string LLBasicCertificateStore::storeId() const // LLBasicCertificateChain // This class represents a chain of certs, each cert being signed by the next cert // in the chain. Certs must be properly signed by the parent -LLBasicCertificateChain::LLBasicCertificateChain(const X509_STORE_CTX* store) +LLBasicCertificateChain::LLBasicCertificateChain(X509_STORE_CTX* store) { // we're passed in a context, which contains a cert, and a blob of untrusted // certificates which compose the chain. - if((store == NULL) || (store->cert == NULL)) + if((store == NULL) || X509_STORE_CTX_get0_cert(store) == NULL) { LL_WARNS("SECAPI") << "An invalid store context was passed in when trying to create a certificate chain" << LL_ENDL; return; } // grab the child cert - LLPointer current = new LLBasicCertificate(store->cert); + LLPointer current = new LLBasicCertificate(X509_STORE_CTX_get0_cert(store)); add(current); - if(store->untrusted != NULL) + if(X509_STORE_CTX_get0_untrusted(store) != NULL) { // if there are other certs in the chain, we build up a vector // of untrusted certs so we can search for the parents of each // consecutive cert. LLBasicCertificateVector untrusted_certs; - for(int i = 0; i < sk_X509_num(store->untrusted); i++) + for(int i = 0; i < sk_X509_num(X509_STORE_CTX_get0_untrusted(store)); i++) { - LLPointer cert = new LLBasicCertificate(sk_X509_value(store->untrusted, i)); + LLPointer cert = new LLBasicCertificate(sk_X509_value(X509_STORE_CTX_get0_untrusted(store), i)); untrusted_certs.add(cert); } @@ -1340,9 +1340,10 @@ void LLSecAPIBasicHandler::_readProtectedData() // read in the rest of the file. - EVP_CIPHER_CTX ctx; - EVP_CIPHER_CTX_init(&ctx); - EVP_DecryptInit(&ctx, EVP_rc4(), salt, NULL); + EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); + // todo: ctx error handling + + EVP_DecryptInit(ctx, EVP_rc4(), salt, NULL); // allocate memory: std::string decrypted_data; @@ -1350,14 +1351,14 @@ void LLSecAPIBasicHandler::_readProtectedData() // read data as a block: protected_data_stream.read((char *)buffer, BUFFER_READ_SIZE); - EVP_DecryptUpdate(&ctx, decrypted_buffer, &decrypted_length, + EVP_DecryptUpdate(ctx, decrypted_buffer, &decrypted_length, buffer, protected_data_stream.gcount()); decrypted_data.append((const char *)decrypted_buffer, protected_data_stream.gcount()); } // RC4 is a stream cipher, so we don't bother to EVP_DecryptFinal, as there is // no block padding. - EVP_CIPHER_CTX_cleanup(&ctx); + EVP_CIPHER_CTX_free(ctx); std::istringstream parse_stream(decrypted_data); if (parser->parse(parse_stream, mProtectedDataMap, LLSDSerialize::SIZE_UNLIMITED) == LLSDParser::PARSE_FAILURE) @@ -1393,12 +1394,14 @@ void LLSecAPIBasicHandler::_writeProtectedData() llofstream protected_data_stream(tmp_filename.c_str(), std::ios_base::binary); + EVP_CIPHER_CTX *ctx = NULL; try { - EVP_CIPHER_CTX ctx; - EVP_CIPHER_CTX_init(&ctx); - EVP_EncryptInit(&ctx, EVP_rc4(), salt, NULL); + ctx = EVP_CIPHER_CTX_new(); + // todo: ctx error handling + + EVP_EncryptInit(ctx, EVP_rc4(), salt, NULL); unsigned char unique_id[MAC_ADDRESS_BYTES]; LLMachineID::getUniqueID(unique_id, sizeof(unique_id)); LLXORCipher cipher(unique_id, sizeof(unique_id)); @@ -1413,13 +1416,13 @@ void LLSecAPIBasicHandler::_writeProtectedData() break; } int encrypted_length; - EVP_EncryptUpdate(&ctx, encrypted_buffer, &encrypted_length, + EVP_EncryptUpdate(ctx, encrypted_buffer, &encrypted_length, buffer, formatted_data_istream.gcount()); protected_data_stream.write((const char *)encrypted_buffer, encrypted_length); } // no EVP_EncrypteFinal, as this is a stream cipher - EVP_CIPHER_CTX_cleanup(&ctx); + EVP_CIPHER_CTX_free(ctx); protected_data_stream.close(); } @@ -1431,6 +1434,11 @@ void LLSecAPIBasicHandler::_writeProtectedData() // it may be, however. LLFile::remove(tmp_filename); + if (ctx) + { + EVP_CIPHER_CTX_free(ctx); + } + // EXP-1825 crash in LLSecAPIBasicHandler::_writeProtectedData() // Decided throwing an exception here was overkill until we figure out why this happens //LLTHROW(LLProtectedDataException("Error writing Protected Data Store")); @@ -1483,7 +1491,7 @@ LLPointer LLSecAPIBasicHandler::getCertificate(X509* openssl_cert } // instantiate a chain from an X509_STORE_CTX -LLPointer LLSecAPIBasicHandler::getCertificateChain(const X509_STORE_CTX* chain) +LLPointer LLSecAPIBasicHandler::getCertificateChain(X509_STORE_CTX* chain) { LLPointer result = new LLBasicCertificateChain(chain); return result; diff --git a/indra/newview/llsechandler_basic.h b/indra/newview/llsechandler_basic.h index 0bc7f5230f..82670f9083 100644 --- a/indra/newview/llsechandler_basic.h +++ b/indra/newview/llsechandler_basic.h @@ -197,7 +197,7 @@ class LLBasicCertificateChain : virtual public LLBasicCertificateVector, public { public: - LLBasicCertificateChain(const X509_STORE_CTX * store); + LLBasicCertificateChain(X509_STORE_CTX * store); virtual ~LLBasicCertificateChain() {} @@ -241,7 +241,7 @@ public: virtual LLPointer getCertificate(X509* openssl_cert); // instantiate a chain from an X509_STORE_CTX - virtual LLPointer getCertificateChain(const X509_STORE_CTX* chain); + virtual LLPointer getCertificateChain(X509_STORE_CTX* chain); // instantiate a cert store given it's id. if a persisted version // exists, it'll be loaded. If not, one will be created (but not diff --git a/indra/newview/tests/llsecapi_test.cpp b/indra/newview/tests/llsecapi_test.cpp index caa3016d2e..37fbbb449b 100644 --- a/indra/newview/tests/llsecapi_test.cpp +++ b/indra/newview/tests/llsecapi_test.cpp @@ -57,7 +57,7 @@ void LLSecAPIBasicHandler::init() {} LLSecAPIBasicHandler::~LLSecAPIBasicHandler() {} LLPointer LLSecAPIBasicHandler::getCertificate(const std::string& pem_cert) { return NULL; } LLPointer LLSecAPIBasicHandler::getCertificate(X509* openssl_cert) { return NULL; } -LLPointer LLSecAPIBasicHandler::getCertificateChain(const X509_STORE_CTX* chain) { return NULL; } +LLPointer LLSecAPIBasicHandler::getCertificateChain(X509_STORE_CTX* chain) { return NULL; } LLPointer LLSecAPIBasicHandler::getCertificateStore(const std::string& store_id) { return NULL; } void LLSecAPIBasicHandler::setProtectedData(const std::string& data_type, const std::string& data_id, const LLSD& data) {} void LLSecAPIBasicHandler::addToProtectedMap(const std::string& data_type, const std::string& data_id, const std::string& map_elem, const LLSD& data) {} diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 80f6b2aa9f..c0a0a7ec46 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -553,9 +553,13 @@ class WindowsManifest(ViewerManifest): self.path("vivoxsdk.dll") self.path("ortp.dll") - # Security - self.path("ssleay32.dll") - self.path("libeay32.dll") + # OpenSSL + if (self.address_size == 64): + self.path("libcrypto-1_1-x64.dll") + self.path("libssl-1_1-x64.dll") + else: + self.path("libcrypto-1_1.dll") + self.path("libssl-1_1.dll") # HTTP/2 self.path("nghttp2.dll") -- cgit v1.2.3 From c518a8cf0f5032ad9b8e80907e2d553b1911424d Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 27 May 2021 12:32:31 +0300 Subject: SL-15211 Remove unsused functions CRYPTO_set_id_callback and CRYPTO_set_locking_callback are no-op in ssl 1.1.x --- indra/llcorehttp/httpcommon.cpp | 55 ----------------------------------------- 1 file changed, 55 deletions(-) diff --git a/indra/llcorehttp/httpcommon.cpp b/indra/llcorehttp/httpcommon.cpp index e37a38b05f..bbf23a6d70 100644 --- a/indra/llcorehttp/httpcommon.cpp +++ b/indra/llcorehttp/httpcommon.cpp @@ -23,13 +23,6 @@ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ -#if LL_WINDOWS -#define SAFE_SSL 1 -#elif LL_DARWIN -#define SAFE_SSL 1 -#else -#define SAFE_SSL 1 -#endif #include "linden_common.h" // Modifies curl/curl.h interfaces #include "httpcommon.h" @@ -38,10 +31,6 @@ #include #include #include -#if SAFE_SSL -#include -#include // std::hash -#endif namespace LLCore @@ -348,34 +337,6 @@ void deallocateEasyCurl(CURL *curlp) } -#if SAFE_SSL -//static -void ssl_locking_callback(int mode, int type, const char *file, int line) -{ - if (type >= sSSLMutex.size()) - { - LL_WARNS() << "Attempt to get unknown MUTEX in SSL Lock." << LL_ENDL; - } - - if (mode & CRYPTO_LOCK) - { - sSSLMutex[type]->lock(); - } - else - { - sSSLMutex[type]->unlock(); - } -} - -//static -unsigned long ssl_thread_id(void) -{ - // std::thread::id is very deliberately opaque, but we can hash it - return std::hash()(LLThread::currentID()); -} -#endif - - } void initialize() @@ -387,27 +348,11 @@ void initialize() check_curl_code(code, CURL_GLOBAL_ALL); -#if SAFE_SSL - S32 mutex_count = CRYPTO_num_locks(); - for (S32 i = 0; i < mutex_count; i++) - { - sSSLMutex.push_back(LLMutex_ptr(new LLMutex())); - } - CRYPTO_set_id_callback(&ssl_thread_id); - CRYPTO_set_locking_callback(&ssl_locking_callback); -#endif - } void cleanup() { -#if SAFE_SSL - CRYPTO_set_id_callback(NULL); - CRYPTO_set_locking_callback(NULL); - sSSLMutex.clear(); -#endif - curl_global_cleanup(); } -- cgit v1.2.3 From 8f55c7ca759d0ed49d07c0e8c6578d7140e8f281 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 27 May 2021 13:33:51 +0300 Subject: SL-15211 Adjust unit tests --- indra/newview/tests/llsechandler_basic_test.cpp | 32 ++++++++++++------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/indra/newview/tests/llsechandler_basic_test.cpp b/indra/newview/tests/llsechandler_basic_test.cpp index e5d226a2a4..4c8d6c51b0 100644 --- a/indra/newview/tests/llsechandler_basic_test.cpp +++ b/indra/newview/tests/llsechandler_basic_test.cpp @@ -1217,8 +1217,8 @@ namespace tut // Single cert in the chain. X509_STORE_CTX *test_store = X509_STORE_CTX_new(); - test_store->cert = mX509ChildCert; - test_store->untrusted = NULL; + X509_STORE_CTX_set_cert(test_store, mX509ChildCert); + X509_STORE_CTX_set0_untrusted(test_store, NULL); test_chain = new LLBasicCertificateChain(test_store); X509_STORE_CTX_free(test_store); ensure_equals("two elements in store", test_chain->size(), 1); @@ -1229,9 +1229,9 @@ namespace tut // cert + CA test_store = X509_STORE_CTX_new(); - test_store->cert = mX509ChildCert; - test_store->untrusted = sk_X509_new_null(); - sk_X509_push(test_store->untrusted, mX509IntermediateCert); + X509_STORE_CTX_set_cert(test_store, mX509ChildCert); + X509_STORE_CTX_set0_untrusted(test_store, sk_X509_new_null()); + sk_X509_push(X509_STORE_CTX_get0_untrusted(test_store), mX509IntermediateCert); test_chain = new LLBasicCertificateChain(test_store); X509_STORE_CTX_free(test_store); ensure_equals("two elements in store", test_chain->size(), 2); @@ -1245,9 +1245,9 @@ namespace tut // cert + nonrelated test_store = X509_STORE_CTX_new(); - test_store->cert = mX509ChildCert; - test_store->untrusted = sk_X509_new_null(); - sk_X509_push(test_store->untrusted, mX509TestCert); + X509_STORE_CTX_set_cert(test_store, mX509ChildCert); + X509_STORE_CTX_set0_untrusted(test_store, sk_X509_new_null()); + sk_X509_push(X509_STORE_CTX_get0_untrusted(test_store), mX509TestCert); test_chain = new LLBasicCertificateChain(test_store); X509_STORE_CTX_free(test_store); ensure_equals("two elements in store", test_chain->size(), 1); @@ -1257,10 +1257,10 @@ namespace tut // cert + CA + nonrelated test_store = X509_STORE_CTX_new(); - test_store->cert = mX509ChildCert; - test_store->untrusted = sk_X509_new_null(); - sk_X509_push(test_store->untrusted, mX509IntermediateCert); - sk_X509_push(test_store->untrusted, mX509TestCert); + X509_STORE_CTX_set_cert(test_store, mX509ChildCert); + X509_STORE_CTX_set0_untrusted(test_store, sk_X509_new_null()); + sk_X509_push(X509_STORE_CTX_get0_untrusted(test_store), mX509IntermediateCert); + sk_X509_push(X509_STORE_CTX_get0_untrusted(test_store), mX509TestCert); test_chain = new LLBasicCertificateChain(test_store); X509_STORE_CTX_free(test_store); ensure_equals("two elements in store", test_chain->size(), 2); @@ -1273,10 +1273,10 @@ namespace tut // cert + intermediate + CA test_store = X509_STORE_CTX_new(); - test_store->cert = mX509ChildCert; - test_store->untrusted = sk_X509_new_null(); - sk_X509_push(test_store->untrusted, mX509IntermediateCert); - sk_X509_push(test_store->untrusted, mX509RootCert); + X509_STORE_CTX_set_cert(test_store, mX509ChildCert); + X509_STORE_CTX_set0_untrusted(test_store, sk_X509_new_null()); + sk_X509_push(X509_STORE_CTX_get0_untrusted(test_store), mX509IntermediateCert); + sk_X509_push(X509_STORE_CTX_get0_untrusted(test_store), mX509RootCert); test_chain = new LLBasicCertificateChain(test_store); X509_STORE_CTX_free(test_store); ensure_equals("three elements in store", test_chain->size(), 3); -- cgit v1.2.3 From 10f84d8244d01728338f1eb20b0b25271fc7db63 Mon Sep 17 00:00:00 2001 From: Dave Houlton Date: Tue, 20 Apr 2021 10:49:33 -0600 Subject: DRTVWR-528 remove wrapper code for RAD telemetry library --- indra/newview/CMakeLists.txt | 1 - indra/newview/llappviewer.cpp | 3 - indra/newview/llstartup.cpp | 3 - indra/newview/lltelemetry.cpp | 145 ------------------------------------------ indra/newview/lltelemetry.h | 81 ----------------------- 5 files changed, 233 deletions(-) delete mode 100644 indra/newview/lltelemetry.cpp delete mode 100644 indra/newview/lltelemetry.h diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 424fd17707..e8e5b83957 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -589,7 +589,6 @@ set(viewer_SOURCE_FILES llsyntaxid.cpp llsyswellitem.cpp llsyswellwindow.cpp - lltelemetry.cpp llteleporthistory.cpp llteleporthistorystorage.cpp lltextureatlas.cpp diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index c0971ba943..bc651188e0 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -91,7 +91,6 @@ #include "llsdutil_math.h" #include "lllocationhistory.h" #include "llfasttimerview.h" -#include "lltelemetry.h" #include "llvector4a.h" #include "llviewermenufile.h" #include "llvoicechannel.h" @@ -1679,8 +1678,6 @@ bool LLAppViewer::doFrame() LL_INFOS() << "Exiting main_loop" << LL_ENDL; } - LLPROFILE_UPDATE(); - return ! LLApp::isRunning(); } diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index c5d5be3509..55048b03be 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -179,7 +179,6 @@ #include "pipeline.h" #include "llappviewer.h" #include "llfasttimerview.h" -#include "lltelemetry.h" #include "llfloatermap.h" #include "llweb.h" #include "llvoiceclient.h" @@ -530,8 +529,6 @@ bool idle_startup() } #if LL_WINDOWS - LLPROFILE_STARTUP(); - // On the windows dev builds, unpackaged, the message.xml file will // be located in indra/build-vc**/newview//app_settings. std::string message_path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"message.xml"); diff --git a/indra/newview/lltelemetry.cpp b/indra/newview/lltelemetry.cpp deleted file mode 100644 index 0c63e2fede..0000000000 --- a/indra/newview/lltelemetry.cpp +++ /dev/null @@ -1,145 +0,0 @@ - /** - * @file lltelemetry.cpp - * @brief Wrapper for Rad Game Tools Telemetry - * - * $LicenseInfo:firstyear=2020&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2020, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" - -#include "lltelemetry.h" - -#if LLPROFILE_USE_RAD_TELEMETRY_PROFILER - #if LL_WINDOWS - #include "llwin32headers.h" - - // build-vc120-64\packages\lib\release - // build-vc150-64\packages\lib\release - #ifdef _MSC_VER - #pragma comment(lib,"rad_tm_win64.lib") - #else - #pragma message "NOTE: Rad GameTools Telemetry requested but non-MSVC compiler not yet supported on Windows" - #endif - #endif // LL_WINDOWS - - #if LL_DARWIN - #pragma message "NOTE: Rad Game Tools Telemetry requested but not yet supported on Darwin" - #endif - - #if LL_LINUX - #pragma message "NOTE: Rad Game Tools Telemetry requested but not yet supported on Linux" - #endif - -// -// local consts -// -static const tm_int32 TELEMETRY_BUFFER_SIZE = 8 * 1024 * 1024; - -// -// local globals -// -static char *gTelemetryBufferPtr = NULL; // Telemetry - -static const char *tm_status[ TMERR_INIT_NETWORKING_FAILED + 1 ] = -{ - "Telemetry pass: connected" // TM_OK - , "Telemetry FAIL: disabled via #define NTELEMETRY" // TMERR_DISABLED - , "Telemetry FAIL: invalid paramater" // TMERR_INVALID_PARAM - , "Telemetry FAIL: DLL not found" // TMERR_NULL_API - , "Telemetry FAIL: out of resources" // TMERR_OUT_OF_RESOURCES - , "Telemetry FAIL: tmInitialize() not called" // TMERR_UNINITIALIZED - , "Telemetry FAIL: bad hostname" // TMERR_BAD_HOSTNAME - , "Telemetry FAIL: couldn't connect to server" // TMERR_COULD_NOT_CONNECT - , "Telemetry FAIL: unknown network error" // TMERR_UNKNOWN_NETWORK - , "Telemetry FAIL: tmShutdown() already called" // TMERR_ALREADY_SHUTDOWN - , "Telemetry FAIL: memory buffer too small" // TMERR_ARENA_TOO_SMALL - , "Telemetry FAIL: server handshake error" // TMERR_BAD_HANDSHAKE - , "Telemetry FAIL: unaligned parameters" // TMERR_UNALIGNED - , "Telemetry FAIL: network not initialized" // TMERR_NETWORK_NOT_INITIALIZED -- WSAStartup not called before tmOpen() - , "Telemetry FAIL: bad version" // TMERR_BAD_VERSION - , "Telemetry FAIL: timer too large" // TMERR_BAD_TIMER - , "Telemetry FAIL: tmOpen() already called" // TMERR_ALREADY_OPENED - , "Telemetry FAIL: tmInitialize() already called" // TMERR_ALREADY_INITIALIZED - , "Telemetry FAIL: could't open file" // TMERR_FILE_OPEN_FAILED - , "Telemetry FAIL: tmOpen() failed networking" // TMERR_INIT_NETWORKING_FAILED -}; - -// -// exported functionality -// - -void telemetry_shutdown() -{ - #if LL_WINDOWS - if (gTelemetryBufferPtr) - { - tmClose(0); - tmShutdown(); - - delete[] gTelemetryBufferPtr; - gTelemetryBufferPtr = NULL; - } - #endif -} - -void telemetry_startup() -{ - #if LL_WINDOWS - tmLoadLibrary(TM_RELEASE); // Loads .dll - - gTelemetryBufferPtr = new char[ TELEMETRY_BUFFER_SIZE ]; - tmInitialize(TELEMETRY_BUFFER_SIZE, gTelemetryBufferPtr); - - tm_error telemetry_status = tmOpen( - 0, // unused - "SecondLife", // app name - __DATE__ " " __TIME__, // build identifier - "localhost", // server name (or filename) - TMCT_TCP, // connection type (or TMCT_FILE) - 4719, // port - TMOF_INIT_NETWORKING, // open flags - 250 ); // timeout ms - - if (telemetry_status == TMERR_UNKNOWN) - { - LL_ERRS() << "Telemetry FAIL: unknown error" << LL_ENDL; - } - else if (telemetry_status && (telemetry_status <= TMERR_INIT_NETWORKING_FAILED)) - { - LL_INFOS() << tm_status[ telemetry_status ] << LL_ENDL; - free(gTelemetryBufferPtr); - gTelemetryBufferPtr = NULL; - } - #endif // LL_WINDOWS -} - -// Called after we render a frame -void telemetry_update() -{ - #if LL_WINDOWS - if (gTelemetryBufferPtr) - { - tmTick(0); - } - #endif -} -#endif // LLPROFILE_USE_RAD_TELEMETRY_PROFILER diff --git a/indra/newview/lltelemetry.h b/indra/newview/lltelemetry.h deleted file mode 100644 index a73e5fcfa2..0000000000 --- a/indra/newview/lltelemetry.h +++ /dev/null @@ -1,81 +0,0 @@ -/** - * @file lltelemetry.h - * @brief Wrapper for Rad Game Tools Telemetry - * - * $LicenseInfo:firstyear=2020&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2020, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -/* -To use: - -1. Uncomment #define LLPROFILE_USE_RAD_TELEMETRY_PROFILER below - -2. Include this header file - #include "lltelemetry.h" - -3. Add zones to the functions you wish to profile - void onFoo() - { - LLPROFILE_ZONE("Foo"); - } -*/ -//#define LLPROFILE_USE_RAD_TELEMETRY_PROFILER 1 - -// Default NO local telemetry profiling -#ifndef LLPROFILE_USE_RAD_TELEMETRY_PROFILER - #define LLPROFILE_USE_RAD_TELEMETRY_PROFILER 0 - #define LLPROFILE_SHUTDOWN( ...) {} - #define LLPROFILE_STARTUP( ...) {} - #define LLPROFILE_UPDATE( ...) {} - - #define LLPROFILE_AUTO_CPU_MARKER_COLOR(r, g, b) - #define LLPROFILE_ENTER(name) - #define LLPROFILE_ENTER_FORMAT(format, ...) - #define LLPROFILE_FUNCTION - #define LLPROFILE_LEAVE() - #define LLPROFILE_THREAD_NAME(name) - #define LLPROFILE_ZONE(name) - #define LLPROFILE_ZONE_FORMAT(format, ...) -#else - #include - - #define LLPROFILE_SHUTDOWN telemetry_shutdown - #define LLPROFILE_STARTUP telemetry_startup - #define LLPROFILE_UPDATE telemetry_update - - #define LLPROFILE_AUTO_CPU_MARKER_COLOR(r, g, b) tmZoneColor(r, g, b) - #define LLPROFILE_ENTER(name) tmEnter(0, 0, name) - #define LLPROFILE_ENTER_FORMAT(format, ...) tmEnter(0, 0, format, __VA_ARGS__) - #define LLPROFILE_FUNCTION tmFunction(0, 0) - #define LLPROFILE_LEAVE() tmLeave(0) - #define LLPROFILE_THREAD_NAME(name) tmThreadName(0, 0, name) - #define LLPROFILE_ZONE(name) tmZone(0, 0, name) - #define LLPROFILE_ZONE_FORMAT(format, ...) tmZone(0, 0, format, __VA_ARGS__) -#endif // LLPROFILE_USE_RAD_TELEMETRY_PROFILER - -// -// exported functionality -// - -extern void telemetry_startup(); -extern void telemetry_shutdown(); -extern void telemetry_update(); // called after every frame update -- cgit v1.2.3 From e0eb9b96f7137e1d4ad4f8b7224cb8b6145ad77c Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Tue, 13 Jul 2021 14:55:11 +0100 Subject: SL-15572 - Possible fix for codeticket upload issue --- build.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/build.sh b/build.sh index 3b0cf97731..89e4492671 100755 --- a/build.sh +++ b/build.sh @@ -449,6 +449,7 @@ then # Upload additional packages. for package_id in $additional_packages do + sleep 240 package=$(installer_$arch "$package_id") if [ x"$package" != x ] then -- cgit v1.2.3 From 3d57b7946a1b432710b2909c8ece16e62e356148 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Tue, 13 Jul 2021 16:19:35 +0100 Subject: SL-15572 - more sleeps in build.sh --- build.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/build.sh b/build.sh index 89e4492671..491fdd6b94 100755 --- a/build.sh +++ b/build.sh @@ -449,10 +449,11 @@ then # Upload additional packages. for package_id in $additional_packages do - sleep 240 package=$(installer_$arch "$package_id") if [ x"$package" != x ] then + echo "sleeping 240" + sleep 240 python_cmd "$helpers/codeticket.py" addoutput "Installer $package_id" "$package" \ || fatal "Upload of installer $package_id failed" else @@ -466,6 +467,8 @@ then if [ "${RELEASE_CRASH_REPORTING:-}" != "OFF" ] then # Upload crash reporter file + echo "sleeping 240" + sleep 240 python_cmd "$helpers/codeticket.py" addoutput "Symbolfile" "$VIEWER_SYMBOL_FILE" \ || fatal "Upload of symbolfile failed" fi @@ -474,6 +477,8 @@ then # *TODO: Make this an upload-extension if [ -r "$build_dir/llphysicsextensions_package" ] then + echo "sleeping 240" + sleep 240 llphysicsextensions_package=$(cat $build_dir/llphysicsextensions_package) python_cmd "$helpers/codeticket.py" addoutput "Physics Extensions Package" "$llphysicsextensions_package" --private \ || fatal "Upload of physics extensions package failed" -- cgit v1.2.3 From 502afc5ed2cd883afb5e921cf33c8dff24d1336f Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Tue, 13 Jul 2021 18:20:56 +0100 Subject: SL-15572 - shorter sleeps in build.sh --- build.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/build.sh b/build.sh index 491fdd6b94..f7e90b8582 100755 --- a/build.sh +++ b/build.sh @@ -452,8 +452,8 @@ then package=$(installer_$arch "$package_id") if [ x"$package" != x ] then - echo "sleeping 240" - sleep 240 + echo "sleeping 30" + sleep 30 python_cmd "$helpers/codeticket.py" addoutput "Installer $package_id" "$package" \ || fatal "Upload of installer $package_id failed" else @@ -467,8 +467,8 @@ then if [ "${RELEASE_CRASH_REPORTING:-}" != "OFF" ] then # Upload crash reporter file - echo "sleeping 240" - sleep 240 + echo "sleeping 30" + sleep 30 python_cmd "$helpers/codeticket.py" addoutput "Symbolfile" "$VIEWER_SYMBOL_FILE" \ || fatal "Upload of symbolfile failed" fi @@ -477,8 +477,8 @@ then # *TODO: Make this an upload-extension if [ -r "$build_dir/llphysicsextensions_package" ] then - echo "sleeping 240" - sleep 240 + echo "sleeping 30" + sleep 30 llphysicsextensions_package=$(cat $build_dir/llphysicsextensions_package) python_cmd "$helpers/codeticket.py" addoutput "Physics Extensions Package" "$llphysicsextensions_package" --private \ || fatal "Upload of physics extensions package failed" -- cgit v1.2.3 From 4d15f18d924b403fd40ae737b9478aadc345a56a Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Tue, 13 Jul 2021 21:40:00 +0100 Subject: SL-15572 - retry logic for codeticket.py commands --- build.sh | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/build.sh b/build.sh index f7e90b8582..72fa5fc31e 100755 --- a/build.sh +++ b/build.sh @@ -16,6 +16,29 @@ # * The special style in which python is invoked is intentional to permit # use of a native python install on windows - which requires paths in DOS form +retry_cmd() +{ + max_attempts="$1"; shift + initial_wait="$1"; shift + attempt_num=1 + echo "trying" "$@" + until "$@" + do + if ((attempt_num==max_attempts)) + then + echo "Last attempt $attempt_num failed" + return 1 + else + wait_time=$(($attempt_num*$initial_wait)) + echo "Attempt $attempt_num failed. Trying again in $wait_time seconds..." + sleep $wait_time + attempt_num=$(($attempt_num+1)) + fi + done + echo "succeeded" + return 0 +} + build_dir_Darwin() { echo build-darwin-x86_64 @@ -443,7 +466,7 @@ then succeeded=$build_coverity else # Upload base package. - python_cmd "$helpers/codeticket.py" addoutput Installer "$package" \ + retry_cmd 4 30 python_cmd "$helpers/codeticket.py" addoutput Installer "$package" \ || fatal "Upload of installer failed" # Upload additional packages. @@ -452,9 +475,7 @@ then package=$(installer_$arch "$package_id") if [ x"$package" != x ] then - echo "sleeping 30" - sleep 30 - python_cmd "$helpers/codeticket.py" addoutput "Installer $package_id" "$package" \ + retry_cmd 4 30 python_cmd "$helpers/codeticket.py" addoutput "Installer $package_id" "$package" \ || fatal "Upload of installer $package_id failed" else record_failure "Failed to find additional package for '$package_id'." @@ -467,9 +488,7 @@ then if [ "${RELEASE_CRASH_REPORTING:-}" != "OFF" ] then # Upload crash reporter file - echo "sleeping 30" - sleep 30 - python_cmd "$helpers/codeticket.py" addoutput "Symbolfile" "$VIEWER_SYMBOL_FILE" \ + retry_cmd 4 30 python_cmd "$helpers/codeticket.py" addoutput "Symbolfile" "$VIEWER_SYMBOL_FILE" \ || fatal "Upload of symbolfile failed" fi @@ -477,10 +496,8 @@ then # *TODO: Make this an upload-extension if [ -r "$build_dir/llphysicsextensions_package" ] then - echo "sleeping 30" - sleep 30 llphysicsextensions_package=$(cat $build_dir/llphysicsextensions_package) - python_cmd "$helpers/codeticket.py" addoutput "Physics Extensions Package" "$llphysicsextensions_package" --private \ + retry_cmd 4 30 python_cmd "$helpers/codeticket.py" addoutput "Physics Extensions Package" "$llphysicsextensions_package" --private \ || fatal "Upload of physics extensions package failed" fi fi -- cgit v1.2.3 From b58fb175829423412fd7ecab8b3f49ee474f92cc Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Wed, 14 Jul 2021 23:35:45 +0300 Subject: SL-15585 Improved notarization error handling --- indra/newview/installers/darwin/apple-notarize.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/indra/newview/installers/darwin/apple-notarize.sh b/indra/newview/installers/darwin/apple-notarize.sh index b953af81af..be0f8a5717 100755 --- a/indra/newview/installers/darwin/apple-notarize.sh +++ b/indra/newview/installers/darwin/apple-notarize.sh @@ -36,8 +36,12 @@ if [ -f "$CONFIG_FILE" ]; then if [["$status" == "success"]]; then xcrun stapler staple "$app_file" elif [["$status" == "invalid"]]; then + echo "Notarization error: failed to process the app file" exit 1 fi + elif + echo "Notarization error: couldn't get request UUID" + exit 1 fi fi fi -- cgit v1.2.3 From 11635dc5b80b9e65dd53cf9a66f3861c90818d0a Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Thu, 15 Jul 2021 00:58:07 +0300 Subject: SL-15585 typo fix --- indra/newview/installers/darwin/apple-notarize.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/installers/darwin/apple-notarize.sh b/indra/newview/installers/darwin/apple-notarize.sh index be0f8a5717..2b3cce6078 100755 --- a/indra/newview/installers/darwin/apple-notarize.sh +++ b/indra/newview/installers/darwin/apple-notarize.sh @@ -39,7 +39,7 @@ if [ -f "$CONFIG_FILE" ]; then echo "Notarization error: failed to process the app file" exit 1 fi - elif + else echo "Notarization error: couldn't get request UUID" exit 1 fi -- cgit v1.2.3 From 54171dbc9fe3fa42ebbf59a243b7381fdb3aa662 Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Mon, 19 Jul 2021 18:58:04 +0300 Subject: SL-15585 more logging for altool --- indra/newview/installers/darwin/apple-notarize.sh | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/indra/newview/installers/darwin/apple-notarize.sh b/indra/newview/installers/darwin/apple-notarize.sh index 2b3cce6078..ecf5bd158a 100755 --- a/indra/newview/installers/darwin/apple-notarize.sh +++ b/indra/newview/installers/darwin/apple-notarize.sh @@ -6,12 +6,12 @@ if [ -f "$CONFIG_FILE" ]; then zip_file=${app_file/app/zip} ditto -c -k --keepParent "$app_file" "$zip_file" if [ -f "$zip_file" ]; then - requestUUID=$(xcrun altool --notarize-app --primary-bundle-id "com.secondlife.viewer" \ - --username $USERNAME \ - --password $PASSWORD \ - --asc-provider $ASC_PROVIDER \ - --file "$zip_file" 2>&1 \ - | awk '/RequestUUID/ { print $NF; }') + res=$(xcrun altool --notarize-app --primary-bundle-id "com.secondlife.viewer" \ + --username $USERNAME \ + --password $PASSWORD \ + --asc-provider $ASC_PROVIDER \ + --file "$zip_file" 2>&1) + requestUUID=$(echo $res | awk '/RequestUUID/ { print $NF; }') echo "Apple Notarization RequestUUID: $requestUUID" @@ -41,6 +41,7 @@ if [ -f "$CONFIG_FILE" ]; then fi else echo "Notarization error: couldn't get request UUID" + echo $res exit 1 fi fi -- cgit v1.2.3 From 1a782ed690e56bf81ec9073041c7559e1762855d Mon Sep 17 00:00:00 2001 From: Dave Houlton Date: Mon, 19 Jul 2021 16:26:33 -0600 Subject: SL-15595 update viewer autobuild to import tracy lib --- autobuild.xml | 64 +++++++++++++++++++++++++++++++++++++++++++ indra/cmake/Tracy.cmake | 17 ++++++++++++ indra/llcommon/CMakeLists.txt | 2 ++ indra/newview/CMakeLists.txt | 3 ++ 4 files changed, 86 insertions(+) create mode 100644 indra/cmake/Tracy.cmake diff --git a/autobuild.xml b/autobuild.xml index eb057ec8e0..db5825bec4 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3067,6 +3067,70 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors version 4.10.0000.32327.5fc3fe7c.539691 + tracy + + canonical_repo + https://bitbucket.org/lindenlab/3p-tracy + copyright + Copyright (c) 2017-2021, Bartosz Taudul (wolf@nereid.pl) + description + Tracy Profiler Library + license + bsd + license_file + LICENSES/tracy_license.txt + name + tracy + platforms + + darwin64 + + archive + + hash + c7820c2c3df46ffef6b09de4a8772f86 + url + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/84525/786813/tracy-v0.7.8.561601-darwin64-561601.tar.bz2 + + name + darwin64 + + windows + + archive + + hash + 503a6ea5c08e17a6709f11cb55b4204a + hash_algorithm + md5 + url + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/85310/791192/tracy-v0.7.8.562170-windows-562170.tar.bz2 + + name + windows + + windows64 + + archive + + hash + 3f61d596eee650763e3cb1d9f6869ed2 + hash_algorithm + md5 + url + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/85309/791191/tracy-v0.7.8.562170-windows64-562170.tar.bz2 + + name + windows64 + + + source + https://bitbucket.org/lindenlab/3p-tracy + source_type + git + version + v0.7.8.562170 + tut copyright diff --git a/indra/cmake/Tracy.cmake b/indra/cmake/Tracy.cmake new file mode 100644 index 0000000000..bf09bccd4b --- /dev/null +++ b/indra/cmake/Tracy.cmake @@ -0,0 +1,17 @@ +# -*- cmake -*- +include(Prebuilt) + +set(TRACY ON CACHE BOOL "Use Tracy profiler.") + +if (TRACY) + set(TRACY_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/tracy) + if (WINDOWS) + use_prebuilt_binary(tracy) + set(TRACY_LIBRARY tracy) + else (WINDOWS) + set(TRACY_LIBRARY "") + endif (WINDOWS) +else (TRACY) + set(TRACY_LIBRARY "") +endif (TRACY) + diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index dd266630ea..f1b0506659 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -13,6 +13,7 @@ include(GoogleBreakpad) include(Copy3rdPartyLibs) include(ZLIB) include(URIPARSER) +include(Tracy) include_directories( ${EXPAT_INCLUDE_DIRS} @@ -21,6 +22,7 @@ include_directories( ${ZLIB_INCLUDE_DIRS} ${BREAKPAD_INCLUDE_DIRECTORIES} ${URIPARSER_INCLUDE_DIRS} + ${TRACY_INCLUDE_DIR} ) # add_executable(lltreeiterators lltreeiterators.cpp) diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 2995a006ac..fbe75af712 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -47,6 +47,7 @@ include(OpenGL) include(OpenSSL) include(PNG) include(TemplateCheck) +include(Tracy) include(UI) include(UnixInstall) include(ViewerMiscLibs) @@ -92,6 +93,7 @@ include_directories( ${LIBS_PREBUILT_DIR}/include/collada/1.4 ${LLAPPEARANCE_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR} + ${TRACY_INCLUDE_DIR} ) include_directories(SYSTEM @@ -2066,6 +2068,7 @@ target_link_libraries(${VIEWER_BINARY_NAME} ${LLPHYSICS_LIBRARIES} ${LLPHYSICSEXTENSIONS_LIBRARIES} ${LLAPPEARANCE_LIBRARIES} + ${TRACY_LIBRARY} ) if (USE_BUGSPLAT) -- cgit v1.2.3 From 7d5cd52498e3da2b2438ad82fe450c923541e798 Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Tue, 27 Jul 2021 15:31:15 -0700 Subject: SL-15709: Add Tracy support to viewer --- doc/contributions.txt | 1 + indra/cmake/LLCommon.cmake | 2 +- indra/llcommon/CMakeLists.txt | 1 + indra/llcommon/linden_common.h | 2 + indra/llcommon/llfasttimer.h | 3 + indra/llcommon/llprofiler.h | 64 ++++++++++++++ indra/llcommon/llthread.cpp | 2 + indra/newview/llappviewer.cpp | 2 + indra/newview/llviewerdisplay.cpp | 81 ++++++++++-------- indra/newview/llvovolume.cpp | 175 ++++++++++++++++++++------------------ indra/newview/pipeline.cpp | 123 ++++++++++++++------------- 11 files changed, 277 insertions(+), 179 deletions(-) create mode 100644 indra/llcommon/llprofiler.h diff --git a/doc/contributions.txt b/doc/contributions.txt index 20980fdacd..a8deb9c2ae 100755 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -270,6 +270,7 @@ Beq Janus SL-13583 SL-14766 SL-14927 + SL-15709 Beth Walcher Bezilon Kasei Biancaluce Robbiani diff --git a/indra/cmake/LLCommon.cmake b/indra/cmake/LLCommon.cmake index 8900419f9b..c1cfa51cfb 100644 --- a/indra/cmake/LLCommon.cmake +++ b/indra/cmake/LLCommon.cmake @@ -30,7 +30,7 @@ else (LINUX) ${BOOST_FIBER_LIBRARY} ${BOOST_CONTEXT_LIBRARY} ${BOOST_THREAD_LIBRARY} - ${BOOST_SYSTEM_LIBRARY} ) + ${BOOST_SYSTEM_LIBRARY}) endif (LINUX) set(LLCOMMON_LINK_SHARED OFF CACHE BOOL "Build the llcommon target as a static library.") diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index f1b0506659..28bf5d0c39 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -201,6 +201,7 @@ set(llcommon_HEADER_FILES llmortician.h llnametable.h llpointer.h + llprofiler.h llpounceable.h llpredicate.h llpreprocessor.h diff --git a/indra/llcommon/linden_common.h b/indra/llcommon/linden_common.h index e5a913a6a9..45ac43910c 100644 --- a/indra/llcommon/linden_common.h +++ b/indra/llcommon/linden_common.h @@ -60,4 +60,6 @@ #include "llerror.h" #include "llfile.h" +#include "llprofiler.h" // must be before fast timer; needed due to LLThreads potentially needing access to tracy + #endif diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h index dfc63d08a2..c7d5bb3761 100644 --- a/indra/llcommon/llfasttimer.h +++ b/indra/llcommon/llfasttimer.h @@ -38,7 +38,10 @@ #define LL_FAST_TIMER_ON 1 #define LL_FASTTIMER_USE_RDTSC 1 +// NOTE: Also see llprofiler.h +#if !defined(LL_PROFILER_CONFIGURATION) // defined(LL_PROFILER_CONFIGURATION) && (LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_FAST_TIMER) #define LL_RECORD_BLOCK_TIME(timer_stat) const LLTrace::BlockTimer& LL_GLUE_TOKENS(block_time_recorder, __LINE__)(LLTrace::timeThisBlock(timer_stat)); (void)LL_GLUE_TOKENS(block_time_recorder, __LINE__); +#endif // LL_PROFILER_CONFIGURATION namespace LLTrace { diff --git a/indra/llcommon/llprofiler.h b/indra/llcommon/llprofiler.h new file mode 100644 index 0000000000..75954b9a79 --- /dev/null +++ b/indra/llcommon/llprofiler.h @@ -0,0 +1,64 @@ +/** + * @file llprofiler.h + * @brief Wrapper for Tracy and/or other profilers + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2021, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_PROFILER_H +#define LL_PROFILER_H + +#define LL_PROFILER_CONFIG_NONE 0 // No profiling +#define LL_PROFILER_CONFIG_FAST_TIMER 1 // Profiling on: Only Fast Timers +#define LL_PROFILER_CONFIG_TRACY 2 // Profiling on: Only Tracy +#define LL_PROFILER_CONFIG_TRACY_FAST_TIMER 3 // Profiling on: Fast Timers + Tracy + +#if defined(LL_PROFILER_CONFIGURATION) && (LL_PROFILER_CONFIGURATION > LL_PROFILER_CONFIG_NONE) + #if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY || LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY_FAST_TIMER + #define TRACY_ENABLE 1 + #define TRACY_NO_BROADCAST 1 + #define TRACY_ONLY_LOCALHOST 1 + #define TRACY_ONLY_IPV4 1 + #include "Tracy.hpp" + #endif + + #if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY + #define LL_PROFILER_FRAME_END FrameMark + #define LL_PROFILER_SET_THREAD_NAME( name ) tracy::SetThreadName( name ) + #define LL_RECORD_BLOCK_TIME(name) ZoneNamedN( ___tracy_scoped_zone, #name, true ); + #endif + #if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_FAST_TIMER + #define LL_PROFILER_FRAME_END + #define LL_PROFILER_SET_THREAD_NAME( name ) (void)(name) + #define LL_RECORD_BLOCK_TIME(name) const LLTrace::BlockTimer& LL_GLUE_TOKENS(block_time_recorder, __LINE__)(LLTrace::timeThisBlock(name)); (void)LL_GLUE_TOKENS(block_time_recorder, __LINE__); + #endif + #if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY_FAST_TIMER + #define LL_PROFILER_FRAME_END FrameMark + #define LL_PROFILER_SET_THREAD_NAME( name ) tracy::SetThreadName( name ) + #define LL_RECORD_BLOCK_TIME(name) ZoneNamedN( ___tracy_scoped_zone, #timer_stat, true ) const LLTrace::BlockTimer& LL_GLUE_TOKENS(block_time_recorder, __LINE__)(LLTrace::timeThisBlock(name)); (void)LL_GLUE_TOKENS(block_time_recorder, __LINE__); + #endif +#else + #define LL_PROFILER_FRAME_END + #define LL_PROFILER_SET_THREAD_NAME( name ) (void)(name) +#endif // LL_PROFILER + +#endif // LL_PROFILER_H diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index 6d531d842d..a8cc750437 100644 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -135,6 +135,8 @@ void LLThread::threadRun() set_thread_name(-1, mName.c_str()); #endif + LL_PROFILER_SET_THREAD_NAME( mName.c_str() ); + // this is the first point at which we're actually running in the new thread mID = currentID(); diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 79f1cc0e8f..94f0b31ecd 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1667,6 +1667,8 @@ bool LLAppViewer::doFrame() LL_INFOS() << "Exiting main_loop" << LL_ENDL; } + LL_PROFILER_FRAME_END + return ! LLApp::isRunning(); } diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 109dc93261..a590237440 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -1259,7 +1259,7 @@ bool setup_hud_matrices(const LLRect& screen_region) void render_ui(F32 zoom_factor, int subfield) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_UI); + LL_RECORD_BLOCK_TIME(FTM_RENDER_UI); LLGLState::checkStates(); @@ -1274,7 +1274,7 @@ void render_ui(F32 zoom_factor, int subfield) if(LLSceneMonitor::getInstance()->needsUpdate()) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_SCENE_MON); + LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_SCENE_MON); gGL.pushMatrix(); gViewerWindow->setup2DRender(); LLSceneMonitor::getInstance()->compare(); @@ -1282,55 +1282,64 @@ void render_ui(F32 zoom_factor, int subfield) gGL.popMatrix(); } - // Finalize scene - gPipeline.renderFinalize(); + // Finalize scene + gPipeline.renderFinalize(); - LL_RECORD_BLOCK_TIME(FTM_RENDER_HUD); - render_hud_elements(); - render_hud_attachments(); - - LLGLSDefault gls_default; - LLGLSUIDefault gls_ui; { - gPipeline.disableLights(); - } + // SL-15709 + // NOTE: Tracy only allows one ZoneScoped per function. + // Solutions are: + // 1. Use a new scope + // 2. Use named zones + // 3. Use transient zones + LL_RECORD_BLOCK_TIME(FTM_RENDER_HUD); + render_hud_elements(); + render_hud_attachments(); + + LLGLSDefault gls_default; + LLGLSUIDefault gls_ui; + { + gPipeline.disableLights(); + } - { - gGL.color4f(1,1,1,1); - if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) { - if (!gDisconnected) + gGL.color4f(1,1,1,1); + if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_3D); - render_ui_3d(); + if (!gDisconnected) + { + LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_3D); + render_ui_3d(); + LLGLState::checkStates(); + } + else + { + render_disconnected_background(); + } + + LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_2D); + render_ui_2d(); LLGLState::checkStates(); } - else + gGL.flush(); + { - render_disconnected_background(); + LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_DEBUG_TEXT); + gViewerWindow->setup2DRender(); + gViewerWindow->updateDebugText(); + gViewerWindow->drawDebugText(); } - LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_2D); - render_ui_2d(); - LLGLState::checkStates(); + LLVertexBuffer::unbind(); } - gGL.flush(); + if (!gSnapshot) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_DEBUG_TEXT); - gViewerWindow->setup2DRender(); - gViewerWindow->updateDebugText(); - gViewerWindow->drawDebugText(); + set_current_modelview(saved_view); + gGL.popMatrix(); } - LLVertexBuffer::unbind(); - } - - if (!gSnapshot) - { - set_current_modelview(saved_view); - gGL.popMatrix(); - } + } // Tracy integration } static LLTrace::BlockTimerStatHandle FTM_SWAP("Swap"); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index f063800587..f9b2285989 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -6045,123 +6045,130 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) if (group && group->hasState(LLSpatialGroup::MESH_DIRTY) && !group->hasState(LLSpatialGroup::GEOM_DIRTY)) { LL_RECORD_BLOCK_TIME(FTM_REBUILD_VOLUME_VB); - LL_RECORD_BLOCK_TIME(FTM_REBUILD_VOLUME_GEN_DRAW_INFO); //make sure getgeometryvolume shows up in the right place in timers + { + // SL-15709 -- NOTE: Tracy only allows one ZoneScoped per function. + // Solutions are: + // 1. Use a new scope + // 2. Use named zones + // 3. Use transient zones + LL_RECORD_BLOCK_TIME(FTM_REBUILD_VOLUME_GEN_DRAW_INFO); //make sure getgeometryvolume shows up in the right place in timers - group->mBuilt = 1.f; + group->mBuilt = 1.f; - S32 num_mapped_vertex_buffer = LLVertexBuffer::sMappedCount ; + S32 num_mapped_vertex_buffer = LLVertexBuffer::sMappedCount ; - const U32 MAX_BUFFER_COUNT = 4096; - LLVertexBuffer* locked_buffer[MAX_BUFFER_COUNT]; - - U32 buffer_count = 0; + const U32 MAX_BUFFER_COUNT = 4096; + LLVertexBuffer* locked_buffer[MAX_BUFFER_COUNT]; - for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) - { - LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); + U32 buffer_count = 0; - if (drawablep && !drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) && !drawablep->isState(LLDrawable::RIGGED) ) + for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) { - LLVOVolume* vobj = drawablep->getVOVolume(); - if (debugLoggingEnabled("AnimatedObjectsLinkset")) - { - if (vobj->isAnimatedObject() && vobj->isRiggedMesh()) - { - std::string vobj_name = llformat("Vol%p", vobj); - F32 est_tris = vobj->getEstTrianglesMax(); - LL_DEBUGS("AnimatedObjectsLinkset") << vobj_name << " rebuildMesh, tris " << est_tris << LL_ENDL; - } - } - if (vobj->isNoLOD()) continue; - - vobj->preRebuild(); - - if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) - { - vobj->updateRelativeXform(true); - } + LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); - LLVolume* volume = vobj->getVolume(); - for (S32 i = 0; i < drawablep->getNumFaces(); ++i) + if (drawablep && !drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) && !drawablep->isState(LLDrawable::RIGGED) ) { - LLFace* face = drawablep->getFace(i); - if (face) + LLVOVolume* vobj = drawablep->getVOVolume(); + if (debugLoggingEnabled("AnimatedObjectsLinkset")) { - LLVertexBuffer* buff = face->getVertexBuffer(); - if (buff) + if (vobj->isAnimatedObject() && vobj->isRiggedMesh()) { - llassert(!face->isState(LLFace::RIGGED)); + std::string vobj_name = llformat("Vol%p", vobj); + F32 est_tris = vobj->getEstTrianglesMax(); + LL_DEBUGS("AnimatedObjectsLinkset") << vobj_name << " rebuildMesh, tris " << est_tris << LL_ENDL; + } + } + if (vobj->isNoLOD()) continue; - if (!face->getGeometryVolume(*volume, face->getTEOffset(), - vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), face->getGeomIndex())) - { //something's gone wrong with the vertex buffer accounting, rebuild this group - group->dirtyGeom(); - gPipeline.markRebuild(group, TRUE); - } + vobj->preRebuild(); + if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) + { + vobj->updateRelativeXform(true); + } - if (buff->isLocked() && buffer_count < MAX_BUFFER_COUNT) + LLVolume* volume = vobj->getVolume(); + for (S32 i = 0; i < drawablep->getNumFaces(); ++i) + { + LLFace* face = drawablep->getFace(i); + if (face) + { + LLVertexBuffer* buff = face->getVertexBuffer(); + if (buff) { - locked_buffer[buffer_count++] = buff; + llassert(!face->isState(LLFace::RIGGED)); + + if (!face->getGeometryVolume(*volume, face->getTEOffset(), + vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), face->getGeomIndex())) + { //something's gone wrong with the vertex buffer accounting, rebuild this group + group->dirtyGeom(); + gPipeline.markRebuild(group, TRUE); + } + + + if (buff->isLocked() && buffer_count < MAX_BUFFER_COUNT) + { + locked_buffer[buffer_count++] = buff; + } } } } + + if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) + { + vobj->updateRelativeXform(); + } + + drawablep->clearState(LLDrawable::REBUILD_ALL); } + } - if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) + { + LL_RECORD_BLOCK_TIME(FTM_REBUILD_MESH_FLUSH); + for (LLVertexBuffer** iter = locked_buffer, ** end_iter = locked_buffer+buffer_count; iter != end_iter; ++iter) { - vobj->updateRelativeXform(); + (*iter)->flush(); } - - drawablep->clearState(LLDrawable::REBUILD_ALL); + // don't forget alpha + if(group != NULL && + !group->mVertexBuffer.isNull() && + group->mVertexBuffer->isLocked()) + { + group->mVertexBuffer->flush(); + } } - } - - { - LL_RECORD_BLOCK_TIME(FTM_REBUILD_MESH_FLUSH); - for (LLVertexBuffer** iter = locked_buffer, ** end_iter = locked_buffer+buffer_count; iter != end_iter; ++iter) - { - (*iter)->flush(); - } - - // don't forget alpha - if(group != NULL && - !group->mVertexBuffer.isNull() && - group->mVertexBuffer->isLocked()) - { - group->mVertexBuffer->flush(); - } - } - //if not all buffers are unmapped - if(num_mapped_vertex_buffer != LLVertexBuffer::sMappedCount) - { - LL_WARNS() << "Not all mapped vertex buffers are unmapped!" << LL_ENDL ; - for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) + //if not all buffers are unmapped + if(num_mapped_vertex_buffer != LLVertexBuffer::sMappedCount) { - LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); - if(!drawablep) - { - continue; - } - for (S32 i = 0; i < drawablep->getNumFaces(); ++i) + LL_WARNS() << "Not all mapped vertex buffers are unmapped!" << LL_ENDL ; + for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) { - LLFace* face = drawablep->getFace(i); - if (face) + LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); + if(!drawablep) + { + continue; + } + for (S32 i = 0; i < drawablep->getNumFaces(); ++i) { - LLVertexBuffer* buff = face->getVertexBuffer(); - if (buff && buff->isLocked()) + LLFace* face = drawablep->getFace(i); + if (face) { - buff->flush(); + LLVertexBuffer* buff = face->getVertexBuffer(); + if (buff && buff->isLocked()) + { + buff->flush(); + } } } } - } + } + + group->clearState(LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO); } - group->clearState(LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO); - } + } // Tracy integration // llassert(!group || !group->isState(LLSpatialGroup::NEW_DRAWINFO)); } diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index cd1b9c7c69..e7c2d4db39 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -4564,92 +4564,99 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera) LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderGeomDeferred"); LL_RECORD_BLOCK_TIME(FTM_RENDER_GEOMETRY); + { + // SL-15709 -- NOTE: Tracy only allows one ZoneScoped per function. + // Solutions are: + // 1. Use a new scope + // 2. Use named zones + // 3. Use transient zones + LL_RECORD_BLOCK_TIME(FTM_DEFERRED_POOLS); - LL_RECORD_BLOCK_TIME(FTM_DEFERRED_POOLS); - - LLGLEnable cull(GL_CULL_FACE); + LLGLEnable cull(GL_CULL_FACE); - for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) - { - LLDrawPool *poolp = *iter; - if (hasRenderType(poolp->getType())) + for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) { - poolp->prerender(); + LLDrawPool *poolp = *iter; + if (hasRenderType(poolp->getType())) + { + poolp->prerender(); + } } - } - LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0); + LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0); - LLVertexBuffer::unbind(); + LLVertexBuffer::unbind(); - LLGLState::checkStates(); - LLGLState::checkTextureChannels(); - LLGLState::checkClientArrays(); + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); + LLGLState::checkClientArrays(); - U32 cur_type = 0; + U32 cur_type = 0; - gGL.setColorMask(true, true); + gGL.setColorMask(true, true); - pool_set_t::iterator iter1 = mPools.begin(); + pool_set_t::iterator iter1 = mPools.begin(); - while ( iter1 != mPools.end() ) - { - LLDrawPool *poolp = *iter1; + while ( iter1 != mPools.end() ) + { + LLDrawPool *poolp = *iter1; - cur_type = poolp->getType(); + cur_type = poolp->getType(); - pool_set_t::iterator iter2 = iter1; - if (hasRenderType(poolp->getType()) && poolp->getNumDeferredPasses() > 0) - { - LL_RECORD_BLOCK_TIME(FTM_DEFERRED_POOLRENDER); + pool_set_t::iterator iter2 = iter1; + if (hasRenderType(poolp->getType()) && poolp->getNumDeferredPasses() > 0) + { + LL_RECORD_BLOCK_TIME(FTM_DEFERRED_POOLRENDER); - gGLLastMatrix = NULL; - gGL.loadMatrix(gGLModelView); + gGLLastMatrix = NULL; + gGL.loadMatrix(gGLModelView); - for( S32 i = 0; i < poolp->getNumDeferredPasses(); i++ ) - { - LLVertexBuffer::unbind(); - poolp->beginDeferredPass(i); - for (iter2 = iter1; iter2 != mPools.end(); iter2++) + for( S32 i = 0; i < poolp->getNumDeferredPasses(); i++ ) { - LLDrawPool *p = *iter2; - if (p->getType() != cur_type) + LLVertexBuffer::unbind(); + poolp->beginDeferredPass(i); + for (iter2 = iter1; iter2 != mPools.end(); iter2++) { - break; + LLDrawPool *p = *iter2; + if (p->getType() != cur_type) + { + break; + } + + if ( !p->getSkipRenderFlag() ) { p->renderDeferred(i); } } - - if ( !p->getSkipRenderFlag() ) { p->renderDeferred(i); } - } - poolp->endDeferredPass(i); - LLVertexBuffer::unbind(); + poolp->endDeferredPass(i); + LLVertexBuffer::unbind(); - if (gDebugGL || gDebugPipeline) - { - LLGLState::checkStates(); + if (gDebugGL || gDebugPipeline) + { + LLGLState::checkStates(); + } } } - } - else - { - // Skip all pools of this type - for (iter2 = iter1; iter2 != mPools.end(); iter2++) + else { - LLDrawPool *p = *iter2; - if (p->getType() != cur_type) + // Skip all pools of this type + for (iter2 = iter1; iter2 != mPools.end(); iter2++) { - break; + LLDrawPool *p = *iter2; + if (p->getType() != cur_type) + { + break; + } } } + iter1 = iter2; + stop_glerror(); } - iter1 = iter2; - stop_glerror(); - } - gGLLastMatrix = NULL; - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.loadMatrix(gGLModelView); + gGLLastMatrix = NULL; + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.loadMatrix(gGLModelView); - gGL.setColorMask(true, false); + gGL.setColorMask(true, false); + + } // Tracy ZoneScoped } void LLPipeline::renderGeomPostDeferred(LLCamera& camera, bool do_occlusion) -- cgit v1.2.3 From 908ce721792c7b549227e1ee23ae8b7b064ad439 Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Fri, 30 Jul 2021 09:36:38 -0700 Subject: SL-15709: Default to old fast timers --- indra/llcommon/llprofiler.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/indra/llcommon/llprofiler.h b/indra/llcommon/llprofiler.h index 75954b9a79..29331d35bf 100644 --- a/indra/llcommon/llprofiler.h +++ b/indra/llcommon/llprofiler.h @@ -32,6 +32,8 @@ #define LL_PROFILER_CONFIG_TRACY 2 // Profiling on: Only Tracy #define LL_PROFILER_CONFIG_TRACY_FAST_TIMER 3 // Profiling on: Fast Timers + Tracy +#define LL_PROFILER_CONFIGURATION LL_PROFILER_CONFIG_FAST_TIMER + #if defined(LL_PROFILER_CONFIGURATION) && (LL_PROFILER_CONFIGURATION > LL_PROFILER_CONFIG_NONE) #if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY || LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY_FAST_TIMER #define TRACY_ENABLE 1 -- cgit v1.2.3 From adb724564da73a4b2d1ebf7835ce628448048d87 Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Thu, 12 Aug 2021 23:13:18 +0300 Subject: DRTVWR-520 Updated dullahan to codeticket build 562751 --- autobuild.xml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index b01ee685f7..365311f369 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -580,9 +580,9 @@ archive hash - 49fff41e17e06cdf9eb0c737d20df52f + 499ae3458342185b47e6f1261d71891f url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/83411/779825/dullahan-1.12.2.202106220202_91.1.21_g9dd45fe_chromium-91.0.4472.114-darwin64-560751.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/86091/796295/dullahan-1.12.2.202108121937_91.1.21_g9dd45fe_chromium-91.0.4472.114-darwin64-562751.tar.bz2 name darwin64 @@ -592,9 +592,9 @@ archive hash - f51f324d50a2461cda273e84fa65e0ad + 4fa5ded4475264305a058423e553e6ad url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/83413/779836/dullahan-1.12.2.202106220213_91.1.21_g9dd45fe_chromium-91.0.4472.114-windows-560751.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/86096/796319/dullahan-1.12.2.202108121946_91.1.21_g9dd45fe_chromium-91.0.4472.114-windows-562751.tar.bz2 name windows @@ -604,16 +604,16 @@ archive hash - d3df46f6592715c75df2bf520c1ad68b + d4c5214819c901afc916e47f8715f3a7 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/83412/779840/dullahan-1.12.2.202106220213_91.1.21_g9dd45fe_chromium-91.0.4472.114-windows64-560751.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/86095/796323/dullahan-1.12.2.202108121946_91.1.21_g9dd45fe_chromium-91.0.4472.114-windows64-562751.tar.bz2 name windows64 version - 1.12.2.202106220213_91.1.21_g9dd45fe_chromium-91.0.4472.114 + 1.12.2.202108121946_91.1.21_g9dd45fe_chromium-91.0.4472.114 elfio -- cgit v1.2.3 From 574b05531ce3a0e535264937d299e5580fb31cdc Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Thu, 26 Aug 2021 22:50:08 -0700 Subject: SL-15709: Default Tracy to off --- indra/cmake/Tracy.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/cmake/Tracy.cmake b/indra/cmake/Tracy.cmake index bf09bccd4b..f4be4f72b3 100644 --- a/indra/cmake/Tracy.cmake +++ b/indra/cmake/Tracy.cmake @@ -1,7 +1,7 @@ # -*- cmake -*- include(Prebuilt) -set(TRACY ON CACHE BOOL "Use Tracy profiler.") +set(TRACY OFF CACHE BOOL "Use Tracy profiler.") if (TRACY) set(TRACY_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/tracy) -- cgit v1.2.3 From bb601196ddbe7d37584468f611ada67647a050d3 Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Thu, 26 Aug 2021 22:52:07 -0700 Subject: SL-15709: IF Tracy is enabled default to using only Tracy instead of Fast Timers; also print Tracy include directory --- indra/cmake/Tracy.cmake | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/indra/cmake/Tracy.cmake b/indra/cmake/Tracy.cmake index f4be4f72b3..4750bdc349 100644 --- a/indra/cmake/Tracy.cmake +++ b/indra/cmake/Tracy.cmake @@ -5,12 +5,25 @@ set(TRACY OFF CACHE BOOL "Use Tracy profiler.") if (TRACY) set(TRACY_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/tracy) + +# See: indra/llcommon/llprofiler.h + add_definitions(-DLL_PROFILER_CONFIGURATION=2) + use_prebuilt_binary(tracy) + if (WINDOWS) - use_prebuilt_binary(tracy) + MESSAGE(STATUS "Including Tracy for Windows: '${TRACY_INCLUDE_DIR}'") set(TRACY_LIBRARY tracy) - else (WINDOWS) - set(TRACY_LIBRARY "") endif (WINDOWS) + + if (DARWIN) + MESSAGE(STATUS "Including Tracy for Darwin: '${TRACY_INCLUDE_DIR}'") + set(TRACY_LIBRARY "") + endif (DARWIN) + + if (LINUX) + MESSAGE(STATUS "Including Tracy for Linux: '${TRACY_INCLUDE_DIR}'") + set(TRACY_LIBRARY "") + endif (LINUX) else (TRACY) set(TRACY_LIBRARY "") endif (TRACY) -- cgit v1.2.3 From c443dc51e48d34a00b61468514dab8209ee214ea Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Thu, 26 Aug 2021 22:52:49 -0700 Subject: SL-15709: Cleanup --- indra/llcommon/llfasttimer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h index c7d5bb3761..9bd93d7240 100644 --- a/indra/llcommon/llfasttimer.h +++ b/indra/llcommon/llfasttimer.h @@ -39,7 +39,7 @@ #define LL_FASTTIMER_USE_RDTSC 1 // NOTE: Also see llprofiler.h -#if !defined(LL_PROFILER_CONFIGURATION) // defined(LL_PROFILER_CONFIGURATION) && (LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_FAST_TIMER) +#if !defined(LL_PROFILER_CONFIGURATION) #define LL_RECORD_BLOCK_TIME(timer_stat) const LLTrace::BlockTimer& LL_GLUE_TOKENS(block_time_recorder, __LINE__)(LLTrace::timeThisBlock(timer_stat)); (void)LL_GLUE_TOKENS(block_time_recorder, __LINE__); #endif // LL_PROFILER_CONFIGURATION -- cgit v1.2.3 From cdf2bdafd394a97b917cc0a71b2bc8531cce40c7 Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Thu, 26 Aug 2021 23:58:45 -0700 Subject: SL-15709: Add Darwin support --- autobuild.xml | 14 +++++++------- indra/llcommon/llframetimer.cpp | 8 ++++++++ indra/llcommon/llprofiler.h | 2 ++ 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index db5825bec4..ec2fa6578b 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3088,9 +3088,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - c7820c2c3df46ffef6b09de4a8772f86 + da7317e4a81609f624f84780f28b07de url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/84525/786813/tracy-v0.7.8.561601-darwin64-561601.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/86972/801630/tracy-v0.7.8.563351-darwin64-563351.tar.bz2 name darwin64 @@ -3100,11 +3100,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 503a6ea5c08e17a6709f11cb55b4204a + 47c696cd2966c5cc3c8ba6115dd1f886 hash_algorithm md5 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/85310/791192/tracy-v0.7.8.562170-windows-562170.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/86973/801641/tracy-v0.7.8.563351-windows-563351.tar.bz2 name windows @@ -3114,11 +3114,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 3f61d596eee650763e3cb1d9f6869ed2 + b649ee6591e67d2341e886b3fc3484a7 hash_algorithm md5 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/85309/791191/tracy-v0.7.8.562170-windows64-562170.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/86974/801642/tracy-v0.7.8.563351-windows64-563351.tar.bz2 name windows64 @@ -3129,7 +3129,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors source_type git version - v0.7.8.562170 + v0.7.8.563351 tut diff --git a/indra/llcommon/llframetimer.cpp b/indra/llcommon/llframetimer.cpp index 1e9920746b..e293a557c0 100644 --- a/indra/llcommon/llframetimer.cpp +++ b/indra/llcommon/llframetimer.cpp @@ -29,6 +29,14 @@ #include "llframetimer.h" +// On Windows we build a static lib and link with that +// On macOS we don't bother building a stand alone lib, just include the one source file we need for Tracy support +#if LL_DARWIN + #if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY || LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY_FAST_TIMER + #include "TracyClient.cpp" + #endif // LL_PROFILER_CONFIGURATION +#endif // LL_DARWIN + // Static members //LLTimer LLFrameTimer::sInternalTimer; U64 LLFrameTimer::sStartTotalTime = totalTime(); diff --git a/indra/llcommon/llprofiler.h b/indra/llcommon/llprofiler.h index 29331d35bf..4674985e06 100644 --- a/indra/llcommon/llprofiler.h +++ b/indra/llcommon/llprofiler.h @@ -32,7 +32,9 @@ #define LL_PROFILER_CONFIG_TRACY 2 // Profiling on: Only Tracy #define LL_PROFILER_CONFIG_TRACY_FAST_TIMER 3 // Profiling on: Fast Timers + Tracy +#ifndef LL_PROFILER_CONFIGURATION #define LL_PROFILER_CONFIGURATION LL_PROFILER_CONFIG_FAST_TIMER +#endif #if defined(LL_PROFILER_CONFIGURATION) && (LL_PROFILER_CONFIGURATION > LL_PROFILER_CONFIG_NONE) #if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY || LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY_FAST_TIMER -- cgit v1.2.3 From 240000c01cb6dc43203584809eb63452b3c80b75 Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Tue, 31 Aug 2021 21:23:10 -0700 Subject: SL-15709: Use standardized autobuild name; set TRACY_INCLUDE_DIR if Tracy not enabled --- indra/cmake/Tracy.cmake | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/indra/cmake/Tracy.cmake b/indra/cmake/Tracy.cmake index 4750bdc349..dfa3e83039 100644 --- a/indra/cmake/Tracy.cmake +++ b/indra/cmake/Tracy.cmake @@ -1,9 +1,9 @@ # -*- cmake -*- include(Prebuilt) -set(TRACY OFF CACHE BOOL "Use Tracy profiler.") +set(USE_TRACY OFF CACHE BOOL "Use Tracy profiler.") -if (TRACY) +if (USE_TRACY) set(TRACY_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/tracy) # See: indra/llcommon/llprofiler.h @@ -24,7 +24,9 @@ if (TRACY) MESSAGE(STATUS "Including Tracy for Linux: '${TRACY_INCLUDE_DIR}'") set(TRACY_LIBRARY "") endif (LINUX) -else (TRACY) +else (USE_TRACY) + # Tracy.cmake should not set LLCOMMON_INCLUDE_DIRS, let LLCommon.cmake do that + set(TRACY_INCLUDE_DIR "") set(TRACY_LIBRARY "") -endif (TRACY) +endif (USE_TRACY) -- cgit v1.2.3 From 3176136686adb58f4add432b017a7017a3f405a5 Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Tue, 31 Aug 2021 21:41:03 -0700 Subject: SL-15709: Fix LLCommon not setting Tracy include directory and not linking to tracy.lib --- indra/cmake/LLCommon.cmake | 6 +++++- indra/llcommon/CMakeLists.txt | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/indra/cmake/LLCommon.cmake b/indra/cmake/LLCommon.cmake index c1cfa51cfb..b6f310fe12 100644 --- a/indra/cmake/LLCommon.cmake +++ b/indra/cmake/LLCommon.cmake @@ -3,12 +3,14 @@ include(APR) include(Boost) include(EXPAT) +include(Tracy) include(ZLIB) set(LLCOMMON_INCLUDE_DIRS ${LIBS_OPEN_DIR}/llcommon ${APRUTIL_INCLUDE_DIR} ${APR_INCLUDE_DIR} + ${TRACY_INCLUDE_DIR} ) set(LLCOMMON_SYSTEM_INCLUDE_DIRS ${Boost_INCLUDE_DIRS} @@ -30,7 +32,9 @@ else (LINUX) ${BOOST_FIBER_LIBRARY} ${BOOST_CONTEXT_LIBRARY} ${BOOST_THREAD_LIBRARY} - ${BOOST_SYSTEM_LIBRARY}) + ${BOOST_SYSTEM_LIBRARY} + ${TRACY_LIBRARY} + ) endif (LINUX) set(LLCOMMON_LINK_SHARED OFF CACHE BOOL "Build the llcommon target as a static library.") diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 28bf5d0c39..066d0404ac 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -305,6 +305,7 @@ target_link_libraries( ${BOOST_SYSTEM_LIBRARY} ${GOOGLE_PERFTOOLS_LIBRARIES} ${URIPARSER_LIBRARIES} + ${TRACY_LIBRARY} ) if (DARWIN) -- cgit v1.2.3 From 8c7db0ad6cbdcfa7d80636ed13ba657e7189420e Mon Sep 17 00:00:00 2001 From: Mnikolenko ProductEngine Date: Fri, 3 Sep 2021 22:21:29 +0300 Subject: SL-15902 Cleanup gSecAPIHandler --- indra/llcorehttp/httpcommon.cpp | 3 --- indra/newview/llappviewer.cpp | 4 +++- indra/newview/llsecapi.cpp | 6 ++++++ indra/newview/llsecapi.h | 2 ++ 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/indra/llcorehttp/httpcommon.cpp b/indra/llcorehttp/httpcommon.cpp index bbf23a6d70..61ba83594e 100644 --- a/indra/llcorehttp/httpcommon.cpp +++ b/indra/llcorehttp/httpcommon.cpp @@ -270,9 +270,6 @@ namespace LLHttp { namespace { -typedef boost::shared_ptr LLMutex_ptr; -std::vector sSSLMutex; - CURL *getCurlTemplateHandle() { static CURL *curlpTemplateHandle = NULL; diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 72eb344ded..69606793db 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -2006,7 +2006,9 @@ bool LLAppViewer::cleanup() if (LLConversationLog::instanceExists()) { LLConversationLog::instance().cache(); - } + } + + clearSecHandler(); if (mPurgeCacheOnExit) { diff --git a/indra/newview/llsecapi.cpp b/indra/newview/llsecapi.cpp index b9259cb18d..aba8ca5a4a 100644 --- a/indra/newview/llsecapi.cpp +++ b/indra/newview/llsecapi.cpp @@ -75,6 +75,12 @@ void initializeSecHandler() } } + +void clearSecHandler() +{ + gSecAPIHandler = NULL; + gHandlerMap.clear(); +} // start using a given security api handler. If the string is empty // the default is used LLPointer getSecHandler(const std::string& handler_type) diff --git a/indra/newview/llsecapi.h b/indra/newview/llsecapi.h index 1e6f2154bc..410737b27f 100644 --- a/indra/newview/llsecapi.h +++ b/indra/newview/llsecapi.h @@ -533,6 +533,8 @@ public: }; void initializeSecHandler(); + +void clearSecHandler(); // retrieve a security api depending on the api type LLPointer getSecHandler(const std::string& handler_type); -- cgit v1.2.3 From c37cc7c3a4888fdca132613d627d7ad90517332a Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Fri, 3 Sep 2021 17:20:22 -0700 Subject: SL-15709: Windows: Include Tracy source directly; don't use a library --- indra/cmake/LLCommon.cmake | 1 - indra/cmake/Tracy.cmake | 3 --- indra/llcommon/llframetimer.cpp | 11 ++++------- indra/llcommon/llprofiler.h | 6 ++++-- 4 files changed, 8 insertions(+), 13 deletions(-) diff --git a/indra/cmake/LLCommon.cmake b/indra/cmake/LLCommon.cmake index b6f310fe12..34499aaa36 100644 --- a/indra/cmake/LLCommon.cmake +++ b/indra/cmake/LLCommon.cmake @@ -33,7 +33,6 @@ else (LINUX) ${BOOST_CONTEXT_LIBRARY} ${BOOST_THREAD_LIBRARY} ${BOOST_SYSTEM_LIBRARY} - ${TRACY_LIBRARY} ) endif (LINUX) diff --git a/indra/cmake/Tracy.cmake b/indra/cmake/Tracy.cmake index dfa3e83039..1b8c3db2e2 100644 --- a/indra/cmake/Tracy.cmake +++ b/indra/cmake/Tracy.cmake @@ -12,17 +12,14 @@ if (USE_TRACY) if (WINDOWS) MESSAGE(STATUS "Including Tracy for Windows: '${TRACY_INCLUDE_DIR}'") - set(TRACY_LIBRARY tracy) endif (WINDOWS) if (DARWIN) MESSAGE(STATUS "Including Tracy for Darwin: '${TRACY_INCLUDE_DIR}'") - set(TRACY_LIBRARY "") endif (DARWIN) if (LINUX) MESSAGE(STATUS "Including Tracy for Linux: '${TRACY_INCLUDE_DIR}'") - set(TRACY_LIBRARY "") endif (LINUX) else (USE_TRACY) # Tracy.cmake should not set LLCOMMON_INCLUDE_DIRS, let LLCommon.cmake do that diff --git a/indra/llcommon/llframetimer.cpp b/indra/llcommon/llframetimer.cpp index e293a557c0..c54029e8b4 100644 --- a/indra/llcommon/llframetimer.cpp +++ b/indra/llcommon/llframetimer.cpp @@ -29,13 +29,10 @@ #include "llframetimer.h" -// On Windows we build a static lib and link with that -// On macOS we don't bother building a stand alone lib, just include the one source file we need for Tracy support -#if LL_DARWIN - #if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY || LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY_FAST_TIMER - #include "TracyClient.cpp" - #endif // LL_PROFILER_CONFIGURATION -#endif // LL_DARWIN +// We don't bother building a stand alone lib; we just need to include the one source file for Tracy support +#if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY || LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY_FAST_TIMER + #include "TracyClient.cpp" +#endif // LL_PROFILER_CONFIGURATION // Static members //LLTimer LLFrameTimer::sInternalTimer; diff --git a/indra/llcommon/llprofiler.h b/indra/llcommon/llprofiler.h index 4674985e06..062c9360dd 100644 --- a/indra/llcommon/llprofiler.h +++ b/indra/llcommon/llprofiler.h @@ -39,8 +39,10 @@ #if defined(LL_PROFILER_CONFIGURATION) && (LL_PROFILER_CONFIGURATION > LL_PROFILER_CONFIG_NONE) #if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY || LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY_FAST_TIMER #define TRACY_ENABLE 1 - #define TRACY_NO_BROADCAST 1 - #define TRACY_ONLY_LOCALHOST 1 +// Normally these would be enabled but we want to be able to build any viewer with Tracy enabled and run the Tracy server on another machine +// They must be undefined in order to work across multiple machines +// #define TRACY_NO_BROADCAST 1 +// #define TRACY_ONLY_LOCALHOST 1 #define TRACY_ONLY_IPV4 1 #include "Tracy.hpp" #endif -- cgit v1.2.3 From aa358035a3553e382128c62d24755b7dce2a8278 Mon Sep 17 00:00:00 2001 From: Dave Houlton Date: Tue, 20 Apr 2021 10:49:33 -0600 Subject: DRTVWR-528 remove wrapper code for RAD telemetry library --- indra/newview/CMakeLists.txt | 1 - indra/newview/llappviewer.cpp | 3 - indra/newview/llstartup.cpp | 3 - indra/newview/lltelemetry.cpp | 145 ------------------------------------------ indra/newview/lltelemetry.h | 81 ----------------------- 5 files changed, 233 deletions(-) delete mode 100644 indra/newview/lltelemetry.cpp delete mode 100644 indra/newview/lltelemetry.h diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 87caca56af..2995a006ac 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -587,7 +587,6 @@ set(viewer_SOURCE_FILES llsyntaxid.cpp llsyswellitem.cpp llsyswellwindow.cpp - lltelemetry.cpp llteleporthistory.cpp llteleporthistorystorage.cpp lltextureatlas.cpp diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 891722e1bd..79f1cc0e8f 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -91,7 +91,6 @@ #include "llsdutil_math.h" #include "lllocationhistory.h" #include "llfasttimerview.h" -#include "lltelemetry.h" #include "llvector4a.h" #include "llviewermenufile.h" #include "llvoicechannel.h" @@ -1668,8 +1667,6 @@ bool LLAppViewer::doFrame() LL_INFOS() << "Exiting main_loop" << LL_ENDL; } - LLPROFILE_UPDATE(); - return ! LLApp::isRunning(); } diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 1242131534..57c5074804 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -179,7 +179,6 @@ #include "pipeline.h" #include "llappviewer.h" #include "llfasttimerview.h" -#include "lltelemetry.h" #include "llfloatermap.h" #include "llweb.h" #include "llvoiceclient.h" @@ -530,8 +529,6 @@ bool idle_startup() } #if LL_WINDOWS - LLPROFILE_STARTUP(); - // On the windows dev builds, unpackaged, the message.xml file will // be located in indra/build-vc**/newview//app_settings. std::string message_path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"message.xml"); diff --git a/indra/newview/lltelemetry.cpp b/indra/newview/lltelemetry.cpp deleted file mode 100644 index 0c63e2fede..0000000000 --- a/indra/newview/lltelemetry.cpp +++ /dev/null @@ -1,145 +0,0 @@ - /** - * @file lltelemetry.cpp - * @brief Wrapper for Rad Game Tools Telemetry - * - * $LicenseInfo:firstyear=2020&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2020, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" - -#include "lltelemetry.h" - -#if LLPROFILE_USE_RAD_TELEMETRY_PROFILER - #if LL_WINDOWS - #include "llwin32headers.h" - - // build-vc120-64\packages\lib\release - // build-vc150-64\packages\lib\release - #ifdef _MSC_VER - #pragma comment(lib,"rad_tm_win64.lib") - #else - #pragma message "NOTE: Rad GameTools Telemetry requested but non-MSVC compiler not yet supported on Windows" - #endif - #endif // LL_WINDOWS - - #if LL_DARWIN - #pragma message "NOTE: Rad Game Tools Telemetry requested but not yet supported on Darwin" - #endif - - #if LL_LINUX - #pragma message "NOTE: Rad Game Tools Telemetry requested but not yet supported on Linux" - #endif - -// -// local consts -// -static const tm_int32 TELEMETRY_BUFFER_SIZE = 8 * 1024 * 1024; - -// -// local globals -// -static char *gTelemetryBufferPtr = NULL; // Telemetry - -static const char *tm_status[ TMERR_INIT_NETWORKING_FAILED + 1 ] = -{ - "Telemetry pass: connected" // TM_OK - , "Telemetry FAIL: disabled via #define NTELEMETRY" // TMERR_DISABLED - , "Telemetry FAIL: invalid paramater" // TMERR_INVALID_PARAM - , "Telemetry FAIL: DLL not found" // TMERR_NULL_API - , "Telemetry FAIL: out of resources" // TMERR_OUT_OF_RESOURCES - , "Telemetry FAIL: tmInitialize() not called" // TMERR_UNINITIALIZED - , "Telemetry FAIL: bad hostname" // TMERR_BAD_HOSTNAME - , "Telemetry FAIL: couldn't connect to server" // TMERR_COULD_NOT_CONNECT - , "Telemetry FAIL: unknown network error" // TMERR_UNKNOWN_NETWORK - , "Telemetry FAIL: tmShutdown() already called" // TMERR_ALREADY_SHUTDOWN - , "Telemetry FAIL: memory buffer too small" // TMERR_ARENA_TOO_SMALL - , "Telemetry FAIL: server handshake error" // TMERR_BAD_HANDSHAKE - , "Telemetry FAIL: unaligned parameters" // TMERR_UNALIGNED - , "Telemetry FAIL: network not initialized" // TMERR_NETWORK_NOT_INITIALIZED -- WSAStartup not called before tmOpen() - , "Telemetry FAIL: bad version" // TMERR_BAD_VERSION - , "Telemetry FAIL: timer too large" // TMERR_BAD_TIMER - , "Telemetry FAIL: tmOpen() already called" // TMERR_ALREADY_OPENED - , "Telemetry FAIL: tmInitialize() already called" // TMERR_ALREADY_INITIALIZED - , "Telemetry FAIL: could't open file" // TMERR_FILE_OPEN_FAILED - , "Telemetry FAIL: tmOpen() failed networking" // TMERR_INIT_NETWORKING_FAILED -}; - -// -// exported functionality -// - -void telemetry_shutdown() -{ - #if LL_WINDOWS - if (gTelemetryBufferPtr) - { - tmClose(0); - tmShutdown(); - - delete[] gTelemetryBufferPtr; - gTelemetryBufferPtr = NULL; - } - #endif -} - -void telemetry_startup() -{ - #if LL_WINDOWS - tmLoadLibrary(TM_RELEASE); // Loads .dll - - gTelemetryBufferPtr = new char[ TELEMETRY_BUFFER_SIZE ]; - tmInitialize(TELEMETRY_BUFFER_SIZE, gTelemetryBufferPtr); - - tm_error telemetry_status = tmOpen( - 0, // unused - "SecondLife", // app name - __DATE__ " " __TIME__, // build identifier - "localhost", // server name (or filename) - TMCT_TCP, // connection type (or TMCT_FILE) - 4719, // port - TMOF_INIT_NETWORKING, // open flags - 250 ); // timeout ms - - if (telemetry_status == TMERR_UNKNOWN) - { - LL_ERRS() << "Telemetry FAIL: unknown error" << LL_ENDL; - } - else if (telemetry_status && (telemetry_status <= TMERR_INIT_NETWORKING_FAILED)) - { - LL_INFOS() << tm_status[ telemetry_status ] << LL_ENDL; - free(gTelemetryBufferPtr); - gTelemetryBufferPtr = NULL; - } - #endif // LL_WINDOWS -} - -// Called after we render a frame -void telemetry_update() -{ - #if LL_WINDOWS - if (gTelemetryBufferPtr) - { - tmTick(0); - } - #endif -} -#endif // LLPROFILE_USE_RAD_TELEMETRY_PROFILER diff --git a/indra/newview/lltelemetry.h b/indra/newview/lltelemetry.h deleted file mode 100644 index a73e5fcfa2..0000000000 --- a/indra/newview/lltelemetry.h +++ /dev/null @@ -1,81 +0,0 @@ -/** - * @file lltelemetry.h - * @brief Wrapper for Rad Game Tools Telemetry - * - * $LicenseInfo:firstyear=2020&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2020, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -/* -To use: - -1. Uncomment #define LLPROFILE_USE_RAD_TELEMETRY_PROFILER below - -2. Include this header file - #include "lltelemetry.h" - -3. Add zones to the functions you wish to profile - void onFoo() - { - LLPROFILE_ZONE("Foo"); - } -*/ -//#define LLPROFILE_USE_RAD_TELEMETRY_PROFILER 1 - -// Default NO local telemetry profiling -#ifndef LLPROFILE_USE_RAD_TELEMETRY_PROFILER - #define LLPROFILE_USE_RAD_TELEMETRY_PROFILER 0 - #define LLPROFILE_SHUTDOWN( ...) {} - #define LLPROFILE_STARTUP( ...) {} - #define LLPROFILE_UPDATE( ...) {} - - #define LLPROFILE_AUTO_CPU_MARKER_COLOR(r, g, b) - #define LLPROFILE_ENTER(name) - #define LLPROFILE_ENTER_FORMAT(format, ...) - #define LLPROFILE_FUNCTION - #define LLPROFILE_LEAVE() - #define LLPROFILE_THREAD_NAME(name) - #define LLPROFILE_ZONE(name) - #define LLPROFILE_ZONE_FORMAT(format, ...) -#else - #include - - #define LLPROFILE_SHUTDOWN telemetry_shutdown - #define LLPROFILE_STARTUP telemetry_startup - #define LLPROFILE_UPDATE telemetry_update - - #define LLPROFILE_AUTO_CPU_MARKER_COLOR(r, g, b) tmZoneColor(r, g, b) - #define LLPROFILE_ENTER(name) tmEnter(0, 0, name) - #define LLPROFILE_ENTER_FORMAT(format, ...) tmEnter(0, 0, format, __VA_ARGS__) - #define LLPROFILE_FUNCTION tmFunction(0, 0) - #define LLPROFILE_LEAVE() tmLeave(0) - #define LLPROFILE_THREAD_NAME(name) tmThreadName(0, 0, name) - #define LLPROFILE_ZONE(name) tmZone(0, 0, name) - #define LLPROFILE_ZONE_FORMAT(format, ...) tmZone(0, 0, format, __VA_ARGS__) -#endif // LLPROFILE_USE_RAD_TELEMETRY_PROFILER - -// -// exported functionality -// - -extern void telemetry_startup(); -extern void telemetry_shutdown(); -extern void telemetry_update(); // called after every frame update -- cgit v1.2.3 From 2e88a3266529714efcf8ae092819a25393540c8a Mon Sep 17 00:00:00 2001 From: Dave Houlton Date: Mon, 19 Jul 2021 16:26:33 -0600 Subject: SL-15595 update viewer autobuild to import tracy lib --- autobuild.xml | 64 +++++++++++++++++++++++++++++++++++++++++++ indra/cmake/Tracy.cmake | 17 ++++++++++++ indra/llcommon/CMakeLists.txt | 2 ++ indra/newview/CMakeLists.txt | 3 ++ 4 files changed, 86 insertions(+) create mode 100644 indra/cmake/Tracy.cmake diff --git a/autobuild.xml b/autobuild.xml index 4768bd25c6..4eaa16e8d9 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3067,6 +3067,70 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors version 4.10.0000.32327.5fc3fe7c.539691 + tracy + + canonical_repo + https://bitbucket.org/lindenlab/3p-tracy + copyright + Copyright (c) 2017-2021, Bartosz Taudul (wolf@nereid.pl) + description + Tracy Profiler Library + license + bsd + license_file + LICENSES/tracy_license.txt + name + tracy + platforms + + darwin64 + + archive + + hash + c7820c2c3df46ffef6b09de4a8772f86 + url + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/84525/786813/tracy-v0.7.8.561601-darwin64-561601.tar.bz2 + + name + darwin64 + + windows + + archive + + hash + 503a6ea5c08e17a6709f11cb55b4204a + hash_algorithm + md5 + url + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/85310/791192/tracy-v0.7.8.562170-windows-562170.tar.bz2 + + name + windows + + windows64 + + archive + + hash + 3f61d596eee650763e3cb1d9f6869ed2 + hash_algorithm + md5 + url + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/85309/791191/tracy-v0.7.8.562170-windows64-562170.tar.bz2 + + name + windows64 + + + source + https://bitbucket.org/lindenlab/3p-tracy + source_type + git + version + v0.7.8.562170 + tut copyright diff --git a/indra/cmake/Tracy.cmake b/indra/cmake/Tracy.cmake new file mode 100644 index 0000000000..bf09bccd4b --- /dev/null +++ b/indra/cmake/Tracy.cmake @@ -0,0 +1,17 @@ +# -*- cmake -*- +include(Prebuilt) + +set(TRACY ON CACHE BOOL "Use Tracy profiler.") + +if (TRACY) + set(TRACY_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/tracy) + if (WINDOWS) + use_prebuilt_binary(tracy) + set(TRACY_LIBRARY tracy) + else (WINDOWS) + set(TRACY_LIBRARY "") + endif (WINDOWS) +else (TRACY) + set(TRACY_LIBRARY "") +endif (TRACY) + diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index dd266630ea..f1b0506659 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -13,6 +13,7 @@ include(GoogleBreakpad) include(Copy3rdPartyLibs) include(ZLIB) include(URIPARSER) +include(Tracy) include_directories( ${EXPAT_INCLUDE_DIRS} @@ -21,6 +22,7 @@ include_directories( ${ZLIB_INCLUDE_DIRS} ${BREAKPAD_INCLUDE_DIRECTORIES} ${URIPARSER_INCLUDE_DIRS} + ${TRACY_INCLUDE_DIR} ) # add_executable(lltreeiterators lltreeiterators.cpp) diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 2995a006ac..fbe75af712 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -47,6 +47,7 @@ include(OpenGL) include(OpenSSL) include(PNG) include(TemplateCheck) +include(Tracy) include(UI) include(UnixInstall) include(ViewerMiscLibs) @@ -92,6 +93,7 @@ include_directories( ${LIBS_PREBUILT_DIR}/include/collada/1.4 ${LLAPPEARANCE_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR} + ${TRACY_INCLUDE_DIR} ) include_directories(SYSTEM @@ -2066,6 +2068,7 @@ target_link_libraries(${VIEWER_BINARY_NAME} ${LLPHYSICS_LIBRARIES} ${LLPHYSICSEXTENSIONS_LIBRARIES} ${LLAPPEARANCE_LIBRARIES} + ${TRACY_LIBRARY} ) if (USE_BUGSPLAT) -- cgit v1.2.3 From df5127136f9f520aa31c06ddb37ac79b6a8dc16d Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Tue, 27 Jul 2021 15:31:15 -0700 Subject: SL-15709: Add Tracy support to viewer --- doc/contributions.txt | 1 + indra/cmake/LLCommon.cmake | 2 +- indra/llcommon/CMakeLists.txt | 1 + indra/llcommon/linden_common.h | 2 + indra/llcommon/llfasttimer.h | 3 + indra/llcommon/llprofiler.h | 64 ++++++++++++++ indra/llcommon/llthread.cpp | 2 + indra/newview/llappviewer.cpp | 2 + indra/newview/llviewerdisplay.cpp | 81 ++++++++++-------- indra/newview/llvovolume.cpp | 175 ++++++++++++++++++++------------------ indra/newview/pipeline.cpp | 123 ++++++++++++++------------- 11 files changed, 277 insertions(+), 179 deletions(-) create mode 100644 indra/llcommon/llprofiler.h diff --git a/doc/contributions.txt b/doc/contributions.txt index 20980fdacd..a8deb9c2ae 100755 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -270,6 +270,7 @@ Beq Janus SL-13583 SL-14766 SL-14927 + SL-15709 Beth Walcher Bezilon Kasei Biancaluce Robbiani diff --git a/indra/cmake/LLCommon.cmake b/indra/cmake/LLCommon.cmake index 8900419f9b..c1cfa51cfb 100644 --- a/indra/cmake/LLCommon.cmake +++ b/indra/cmake/LLCommon.cmake @@ -30,7 +30,7 @@ else (LINUX) ${BOOST_FIBER_LIBRARY} ${BOOST_CONTEXT_LIBRARY} ${BOOST_THREAD_LIBRARY} - ${BOOST_SYSTEM_LIBRARY} ) + ${BOOST_SYSTEM_LIBRARY}) endif (LINUX) set(LLCOMMON_LINK_SHARED OFF CACHE BOOL "Build the llcommon target as a static library.") diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index f1b0506659..28bf5d0c39 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -201,6 +201,7 @@ set(llcommon_HEADER_FILES llmortician.h llnametable.h llpointer.h + llprofiler.h llpounceable.h llpredicate.h llpreprocessor.h diff --git a/indra/llcommon/linden_common.h b/indra/llcommon/linden_common.h index e5a913a6a9..45ac43910c 100644 --- a/indra/llcommon/linden_common.h +++ b/indra/llcommon/linden_common.h @@ -60,4 +60,6 @@ #include "llerror.h" #include "llfile.h" +#include "llprofiler.h" // must be before fast timer; needed due to LLThreads potentially needing access to tracy + #endif diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h index dfc63d08a2..c7d5bb3761 100644 --- a/indra/llcommon/llfasttimer.h +++ b/indra/llcommon/llfasttimer.h @@ -38,7 +38,10 @@ #define LL_FAST_TIMER_ON 1 #define LL_FASTTIMER_USE_RDTSC 1 +// NOTE: Also see llprofiler.h +#if !defined(LL_PROFILER_CONFIGURATION) // defined(LL_PROFILER_CONFIGURATION) && (LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_FAST_TIMER) #define LL_RECORD_BLOCK_TIME(timer_stat) const LLTrace::BlockTimer& LL_GLUE_TOKENS(block_time_recorder, __LINE__)(LLTrace::timeThisBlock(timer_stat)); (void)LL_GLUE_TOKENS(block_time_recorder, __LINE__); +#endif // LL_PROFILER_CONFIGURATION namespace LLTrace { diff --git a/indra/llcommon/llprofiler.h b/indra/llcommon/llprofiler.h new file mode 100644 index 0000000000..75954b9a79 --- /dev/null +++ b/indra/llcommon/llprofiler.h @@ -0,0 +1,64 @@ +/** + * @file llprofiler.h + * @brief Wrapper for Tracy and/or other profilers + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2021, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_PROFILER_H +#define LL_PROFILER_H + +#define LL_PROFILER_CONFIG_NONE 0 // No profiling +#define LL_PROFILER_CONFIG_FAST_TIMER 1 // Profiling on: Only Fast Timers +#define LL_PROFILER_CONFIG_TRACY 2 // Profiling on: Only Tracy +#define LL_PROFILER_CONFIG_TRACY_FAST_TIMER 3 // Profiling on: Fast Timers + Tracy + +#if defined(LL_PROFILER_CONFIGURATION) && (LL_PROFILER_CONFIGURATION > LL_PROFILER_CONFIG_NONE) + #if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY || LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY_FAST_TIMER + #define TRACY_ENABLE 1 + #define TRACY_NO_BROADCAST 1 + #define TRACY_ONLY_LOCALHOST 1 + #define TRACY_ONLY_IPV4 1 + #include "Tracy.hpp" + #endif + + #if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY + #define LL_PROFILER_FRAME_END FrameMark + #define LL_PROFILER_SET_THREAD_NAME( name ) tracy::SetThreadName( name ) + #define LL_RECORD_BLOCK_TIME(name) ZoneNamedN( ___tracy_scoped_zone, #name, true ); + #endif + #if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_FAST_TIMER + #define LL_PROFILER_FRAME_END + #define LL_PROFILER_SET_THREAD_NAME( name ) (void)(name) + #define LL_RECORD_BLOCK_TIME(name) const LLTrace::BlockTimer& LL_GLUE_TOKENS(block_time_recorder, __LINE__)(LLTrace::timeThisBlock(name)); (void)LL_GLUE_TOKENS(block_time_recorder, __LINE__); + #endif + #if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY_FAST_TIMER + #define LL_PROFILER_FRAME_END FrameMark + #define LL_PROFILER_SET_THREAD_NAME( name ) tracy::SetThreadName( name ) + #define LL_RECORD_BLOCK_TIME(name) ZoneNamedN( ___tracy_scoped_zone, #timer_stat, true ) const LLTrace::BlockTimer& LL_GLUE_TOKENS(block_time_recorder, __LINE__)(LLTrace::timeThisBlock(name)); (void)LL_GLUE_TOKENS(block_time_recorder, __LINE__); + #endif +#else + #define LL_PROFILER_FRAME_END + #define LL_PROFILER_SET_THREAD_NAME( name ) (void)(name) +#endif // LL_PROFILER + +#endif // LL_PROFILER_H diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index 6d531d842d..a8cc750437 100644 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -135,6 +135,8 @@ void LLThread::threadRun() set_thread_name(-1, mName.c_str()); #endif + LL_PROFILER_SET_THREAD_NAME( mName.c_str() ); + // this is the first point at which we're actually running in the new thread mID = currentID(); diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 79f1cc0e8f..94f0b31ecd 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1667,6 +1667,8 @@ bool LLAppViewer::doFrame() LL_INFOS() << "Exiting main_loop" << LL_ENDL; } + LL_PROFILER_FRAME_END + return ! LLApp::isRunning(); } diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 109dc93261..a590237440 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -1259,7 +1259,7 @@ bool setup_hud_matrices(const LLRect& screen_region) void render_ui(F32 zoom_factor, int subfield) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_UI); + LL_RECORD_BLOCK_TIME(FTM_RENDER_UI); LLGLState::checkStates(); @@ -1274,7 +1274,7 @@ void render_ui(F32 zoom_factor, int subfield) if(LLSceneMonitor::getInstance()->needsUpdate()) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_SCENE_MON); + LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_SCENE_MON); gGL.pushMatrix(); gViewerWindow->setup2DRender(); LLSceneMonitor::getInstance()->compare(); @@ -1282,55 +1282,64 @@ void render_ui(F32 zoom_factor, int subfield) gGL.popMatrix(); } - // Finalize scene - gPipeline.renderFinalize(); + // Finalize scene + gPipeline.renderFinalize(); - LL_RECORD_BLOCK_TIME(FTM_RENDER_HUD); - render_hud_elements(); - render_hud_attachments(); - - LLGLSDefault gls_default; - LLGLSUIDefault gls_ui; { - gPipeline.disableLights(); - } + // SL-15709 + // NOTE: Tracy only allows one ZoneScoped per function. + // Solutions are: + // 1. Use a new scope + // 2. Use named zones + // 3. Use transient zones + LL_RECORD_BLOCK_TIME(FTM_RENDER_HUD); + render_hud_elements(); + render_hud_attachments(); + + LLGLSDefault gls_default; + LLGLSUIDefault gls_ui; + { + gPipeline.disableLights(); + } - { - gGL.color4f(1,1,1,1); - if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) { - if (!gDisconnected) + gGL.color4f(1,1,1,1); + if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_3D); - render_ui_3d(); + if (!gDisconnected) + { + LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_3D); + render_ui_3d(); + LLGLState::checkStates(); + } + else + { + render_disconnected_background(); + } + + LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_2D); + render_ui_2d(); LLGLState::checkStates(); } - else + gGL.flush(); + { - render_disconnected_background(); + LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_DEBUG_TEXT); + gViewerWindow->setup2DRender(); + gViewerWindow->updateDebugText(); + gViewerWindow->drawDebugText(); } - LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_2D); - render_ui_2d(); - LLGLState::checkStates(); + LLVertexBuffer::unbind(); } - gGL.flush(); + if (!gSnapshot) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_DEBUG_TEXT); - gViewerWindow->setup2DRender(); - gViewerWindow->updateDebugText(); - gViewerWindow->drawDebugText(); + set_current_modelview(saved_view); + gGL.popMatrix(); } - LLVertexBuffer::unbind(); - } - - if (!gSnapshot) - { - set_current_modelview(saved_view); - gGL.popMatrix(); - } + } // Tracy integration } static LLTrace::BlockTimerStatHandle FTM_SWAP("Swap"); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index f063800587..f9b2285989 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -6045,123 +6045,130 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) if (group && group->hasState(LLSpatialGroup::MESH_DIRTY) && !group->hasState(LLSpatialGroup::GEOM_DIRTY)) { LL_RECORD_BLOCK_TIME(FTM_REBUILD_VOLUME_VB); - LL_RECORD_BLOCK_TIME(FTM_REBUILD_VOLUME_GEN_DRAW_INFO); //make sure getgeometryvolume shows up in the right place in timers + { + // SL-15709 -- NOTE: Tracy only allows one ZoneScoped per function. + // Solutions are: + // 1. Use a new scope + // 2. Use named zones + // 3. Use transient zones + LL_RECORD_BLOCK_TIME(FTM_REBUILD_VOLUME_GEN_DRAW_INFO); //make sure getgeometryvolume shows up in the right place in timers - group->mBuilt = 1.f; + group->mBuilt = 1.f; - S32 num_mapped_vertex_buffer = LLVertexBuffer::sMappedCount ; + S32 num_mapped_vertex_buffer = LLVertexBuffer::sMappedCount ; - const U32 MAX_BUFFER_COUNT = 4096; - LLVertexBuffer* locked_buffer[MAX_BUFFER_COUNT]; - - U32 buffer_count = 0; + const U32 MAX_BUFFER_COUNT = 4096; + LLVertexBuffer* locked_buffer[MAX_BUFFER_COUNT]; - for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) - { - LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); + U32 buffer_count = 0; - if (drawablep && !drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) && !drawablep->isState(LLDrawable::RIGGED) ) + for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) { - LLVOVolume* vobj = drawablep->getVOVolume(); - if (debugLoggingEnabled("AnimatedObjectsLinkset")) - { - if (vobj->isAnimatedObject() && vobj->isRiggedMesh()) - { - std::string vobj_name = llformat("Vol%p", vobj); - F32 est_tris = vobj->getEstTrianglesMax(); - LL_DEBUGS("AnimatedObjectsLinkset") << vobj_name << " rebuildMesh, tris " << est_tris << LL_ENDL; - } - } - if (vobj->isNoLOD()) continue; - - vobj->preRebuild(); - - if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) - { - vobj->updateRelativeXform(true); - } + LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); - LLVolume* volume = vobj->getVolume(); - for (S32 i = 0; i < drawablep->getNumFaces(); ++i) + if (drawablep && !drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) && !drawablep->isState(LLDrawable::RIGGED) ) { - LLFace* face = drawablep->getFace(i); - if (face) + LLVOVolume* vobj = drawablep->getVOVolume(); + if (debugLoggingEnabled("AnimatedObjectsLinkset")) { - LLVertexBuffer* buff = face->getVertexBuffer(); - if (buff) + if (vobj->isAnimatedObject() && vobj->isRiggedMesh()) { - llassert(!face->isState(LLFace::RIGGED)); + std::string vobj_name = llformat("Vol%p", vobj); + F32 est_tris = vobj->getEstTrianglesMax(); + LL_DEBUGS("AnimatedObjectsLinkset") << vobj_name << " rebuildMesh, tris " << est_tris << LL_ENDL; + } + } + if (vobj->isNoLOD()) continue; - if (!face->getGeometryVolume(*volume, face->getTEOffset(), - vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), face->getGeomIndex())) - { //something's gone wrong with the vertex buffer accounting, rebuild this group - group->dirtyGeom(); - gPipeline.markRebuild(group, TRUE); - } + vobj->preRebuild(); + if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) + { + vobj->updateRelativeXform(true); + } - if (buff->isLocked() && buffer_count < MAX_BUFFER_COUNT) + LLVolume* volume = vobj->getVolume(); + for (S32 i = 0; i < drawablep->getNumFaces(); ++i) + { + LLFace* face = drawablep->getFace(i); + if (face) + { + LLVertexBuffer* buff = face->getVertexBuffer(); + if (buff) { - locked_buffer[buffer_count++] = buff; + llassert(!face->isState(LLFace::RIGGED)); + + if (!face->getGeometryVolume(*volume, face->getTEOffset(), + vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), face->getGeomIndex())) + { //something's gone wrong with the vertex buffer accounting, rebuild this group + group->dirtyGeom(); + gPipeline.markRebuild(group, TRUE); + } + + + if (buff->isLocked() && buffer_count < MAX_BUFFER_COUNT) + { + locked_buffer[buffer_count++] = buff; + } } } } + + if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) + { + vobj->updateRelativeXform(); + } + + drawablep->clearState(LLDrawable::REBUILD_ALL); } + } - if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) + { + LL_RECORD_BLOCK_TIME(FTM_REBUILD_MESH_FLUSH); + for (LLVertexBuffer** iter = locked_buffer, ** end_iter = locked_buffer+buffer_count; iter != end_iter; ++iter) { - vobj->updateRelativeXform(); + (*iter)->flush(); } - - drawablep->clearState(LLDrawable::REBUILD_ALL); + // don't forget alpha + if(group != NULL && + !group->mVertexBuffer.isNull() && + group->mVertexBuffer->isLocked()) + { + group->mVertexBuffer->flush(); + } } - } - - { - LL_RECORD_BLOCK_TIME(FTM_REBUILD_MESH_FLUSH); - for (LLVertexBuffer** iter = locked_buffer, ** end_iter = locked_buffer+buffer_count; iter != end_iter; ++iter) - { - (*iter)->flush(); - } - - // don't forget alpha - if(group != NULL && - !group->mVertexBuffer.isNull() && - group->mVertexBuffer->isLocked()) - { - group->mVertexBuffer->flush(); - } - } - //if not all buffers are unmapped - if(num_mapped_vertex_buffer != LLVertexBuffer::sMappedCount) - { - LL_WARNS() << "Not all mapped vertex buffers are unmapped!" << LL_ENDL ; - for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) + //if not all buffers are unmapped + if(num_mapped_vertex_buffer != LLVertexBuffer::sMappedCount) { - LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); - if(!drawablep) - { - continue; - } - for (S32 i = 0; i < drawablep->getNumFaces(); ++i) + LL_WARNS() << "Not all mapped vertex buffers are unmapped!" << LL_ENDL ; + for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) { - LLFace* face = drawablep->getFace(i); - if (face) + LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); + if(!drawablep) + { + continue; + } + for (S32 i = 0; i < drawablep->getNumFaces(); ++i) { - LLVertexBuffer* buff = face->getVertexBuffer(); - if (buff && buff->isLocked()) + LLFace* face = drawablep->getFace(i); + if (face) { - buff->flush(); + LLVertexBuffer* buff = face->getVertexBuffer(); + if (buff && buff->isLocked()) + { + buff->flush(); + } } } } - } + } + + group->clearState(LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO); } - group->clearState(LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO); - } + } // Tracy integration // llassert(!group || !group->isState(LLSpatialGroup::NEW_DRAWINFO)); } diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index cd1b9c7c69..e7c2d4db39 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -4564,92 +4564,99 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera) LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderGeomDeferred"); LL_RECORD_BLOCK_TIME(FTM_RENDER_GEOMETRY); + { + // SL-15709 -- NOTE: Tracy only allows one ZoneScoped per function. + // Solutions are: + // 1. Use a new scope + // 2. Use named zones + // 3. Use transient zones + LL_RECORD_BLOCK_TIME(FTM_DEFERRED_POOLS); - LL_RECORD_BLOCK_TIME(FTM_DEFERRED_POOLS); - - LLGLEnable cull(GL_CULL_FACE); + LLGLEnable cull(GL_CULL_FACE); - for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) - { - LLDrawPool *poolp = *iter; - if (hasRenderType(poolp->getType())) + for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) { - poolp->prerender(); + LLDrawPool *poolp = *iter; + if (hasRenderType(poolp->getType())) + { + poolp->prerender(); + } } - } - LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0); + LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0); - LLVertexBuffer::unbind(); + LLVertexBuffer::unbind(); - LLGLState::checkStates(); - LLGLState::checkTextureChannels(); - LLGLState::checkClientArrays(); + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); + LLGLState::checkClientArrays(); - U32 cur_type = 0; + U32 cur_type = 0; - gGL.setColorMask(true, true); + gGL.setColorMask(true, true); - pool_set_t::iterator iter1 = mPools.begin(); + pool_set_t::iterator iter1 = mPools.begin(); - while ( iter1 != mPools.end() ) - { - LLDrawPool *poolp = *iter1; + while ( iter1 != mPools.end() ) + { + LLDrawPool *poolp = *iter1; - cur_type = poolp->getType(); + cur_type = poolp->getType(); - pool_set_t::iterator iter2 = iter1; - if (hasRenderType(poolp->getType()) && poolp->getNumDeferredPasses() > 0) - { - LL_RECORD_BLOCK_TIME(FTM_DEFERRED_POOLRENDER); + pool_set_t::iterator iter2 = iter1; + if (hasRenderType(poolp->getType()) && poolp->getNumDeferredPasses() > 0) + { + LL_RECORD_BLOCK_TIME(FTM_DEFERRED_POOLRENDER); - gGLLastMatrix = NULL; - gGL.loadMatrix(gGLModelView); + gGLLastMatrix = NULL; + gGL.loadMatrix(gGLModelView); - for( S32 i = 0; i < poolp->getNumDeferredPasses(); i++ ) - { - LLVertexBuffer::unbind(); - poolp->beginDeferredPass(i); - for (iter2 = iter1; iter2 != mPools.end(); iter2++) + for( S32 i = 0; i < poolp->getNumDeferredPasses(); i++ ) { - LLDrawPool *p = *iter2; - if (p->getType() != cur_type) + LLVertexBuffer::unbind(); + poolp->beginDeferredPass(i); + for (iter2 = iter1; iter2 != mPools.end(); iter2++) { - break; + LLDrawPool *p = *iter2; + if (p->getType() != cur_type) + { + break; + } + + if ( !p->getSkipRenderFlag() ) { p->renderDeferred(i); } } - - if ( !p->getSkipRenderFlag() ) { p->renderDeferred(i); } - } - poolp->endDeferredPass(i); - LLVertexBuffer::unbind(); + poolp->endDeferredPass(i); + LLVertexBuffer::unbind(); - if (gDebugGL || gDebugPipeline) - { - LLGLState::checkStates(); + if (gDebugGL || gDebugPipeline) + { + LLGLState::checkStates(); + } } } - } - else - { - // Skip all pools of this type - for (iter2 = iter1; iter2 != mPools.end(); iter2++) + else { - LLDrawPool *p = *iter2; - if (p->getType() != cur_type) + // Skip all pools of this type + for (iter2 = iter1; iter2 != mPools.end(); iter2++) { - break; + LLDrawPool *p = *iter2; + if (p->getType() != cur_type) + { + break; + } } } + iter1 = iter2; + stop_glerror(); } - iter1 = iter2; - stop_glerror(); - } - gGLLastMatrix = NULL; - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.loadMatrix(gGLModelView); + gGLLastMatrix = NULL; + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.loadMatrix(gGLModelView); - gGL.setColorMask(true, false); + gGL.setColorMask(true, false); + + } // Tracy ZoneScoped } void LLPipeline::renderGeomPostDeferred(LLCamera& camera, bool do_occlusion) -- cgit v1.2.3 From 6d74ae649c6a05403f7ddc01a41d8def694e00e1 Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Fri, 30 Jul 2021 09:36:38 -0700 Subject: SL-15709: Default to old fast timers --- indra/llcommon/llprofiler.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/indra/llcommon/llprofiler.h b/indra/llcommon/llprofiler.h index 75954b9a79..29331d35bf 100644 --- a/indra/llcommon/llprofiler.h +++ b/indra/llcommon/llprofiler.h @@ -32,6 +32,8 @@ #define LL_PROFILER_CONFIG_TRACY 2 // Profiling on: Only Tracy #define LL_PROFILER_CONFIG_TRACY_FAST_TIMER 3 // Profiling on: Fast Timers + Tracy +#define LL_PROFILER_CONFIGURATION LL_PROFILER_CONFIG_FAST_TIMER + #if defined(LL_PROFILER_CONFIGURATION) && (LL_PROFILER_CONFIGURATION > LL_PROFILER_CONFIG_NONE) #if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY || LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY_FAST_TIMER #define TRACY_ENABLE 1 -- cgit v1.2.3 From 61175cfa018eba460d4f836dee5fabbe78799442 Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Thu, 26 Aug 2021 22:50:08 -0700 Subject: SL-15709: Default Tracy to off --- indra/cmake/Tracy.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/cmake/Tracy.cmake b/indra/cmake/Tracy.cmake index bf09bccd4b..f4be4f72b3 100644 --- a/indra/cmake/Tracy.cmake +++ b/indra/cmake/Tracy.cmake @@ -1,7 +1,7 @@ # -*- cmake -*- include(Prebuilt) -set(TRACY ON CACHE BOOL "Use Tracy profiler.") +set(TRACY OFF CACHE BOOL "Use Tracy profiler.") if (TRACY) set(TRACY_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/tracy) -- cgit v1.2.3 From a783f7c74abc3a5afc8dbd1af63b74e281f02308 Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Thu, 26 Aug 2021 22:52:07 -0700 Subject: SL-15709: IF Tracy is enabled default to using only Tracy instead of Fast Timers; also print Tracy include directory --- indra/cmake/Tracy.cmake | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/indra/cmake/Tracy.cmake b/indra/cmake/Tracy.cmake index f4be4f72b3..4750bdc349 100644 --- a/indra/cmake/Tracy.cmake +++ b/indra/cmake/Tracy.cmake @@ -5,12 +5,25 @@ set(TRACY OFF CACHE BOOL "Use Tracy profiler.") if (TRACY) set(TRACY_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/tracy) + +# See: indra/llcommon/llprofiler.h + add_definitions(-DLL_PROFILER_CONFIGURATION=2) + use_prebuilt_binary(tracy) + if (WINDOWS) - use_prebuilt_binary(tracy) + MESSAGE(STATUS "Including Tracy for Windows: '${TRACY_INCLUDE_DIR}'") set(TRACY_LIBRARY tracy) - else (WINDOWS) - set(TRACY_LIBRARY "") endif (WINDOWS) + + if (DARWIN) + MESSAGE(STATUS "Including Tracy for Darwin: '${TRACY_INCLUDE_DIR}'") + set(TRACY_LIBRARY "") + endif (DARWIN) + + if (LINUX) + MESSAGE(STATUS "Including Tracy for Linux: '${TRACY_INCLUDE_DIR}'") + set(TRACY_LIBRARY "") + endif (LINUX) else (TRACY) set(TRACY_LIBRARY "") endif (TRACY) -- cgit v1.2.3 From 92e53622ea33cf1558d7079e9341038dd242c3a5 Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Thu, 26 Aug 2021 22:52:49 -0700 Subject: SL-15709: Cleanup --- indra/llcommon/llfasttimer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h index c7d5bb3761..9bd93d7240 100644 --- a/indra/llcommon/llfasttimer.h +++ b/indra/llcommon/llfasttimer.h @@ -39,7 +39,7 @@ #define LL_FASTTIMER_USE_RDTSC 1 // NOTE: Also see llprofiler.h -#if !defined(LL_PROFILER_CONFIGURATION) // defined(LL_PROFILER_CONFIGURATION) && (LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_FAST_TIMER) +#if !defined(LL_PROFILER_CONFIGURATION) #define LL_RECORD_BLOCK_TIME(timer_stat) const LLTrace::BlockTimer& LL_GLUE_TOKENS(block_time_recorder, __LINE__)(LLTrace::timeThisBlock(timer_stat)); (void)LL_GLUE_TOKENS(block_time_recorder, __LINE__); #endif // LL_PROFILER_CONFIGURATION -- cgit v1.2.3 From 13ff2cba5365474fe53809968f66cc2fa20be4cc Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Thu, 26 Aug 2021 23:58:45 -0700 Subject: SL-15709: Add Darwin support --- autobuild.xml | 14 +++++++------- indra/llcommon/llframetimer.cpp | 8 ++++++++ indra/llcommon/llprofiler.h | 2 ++ 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 4eaa16e8d9..44781a358a 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3088,9 +3088,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - c7820c2c3df46ffef6b09de4a8772f86 + da7317e4a81609f624f84780f28b07de url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/84525/786813/tracy-v0.7.8.561601-darwin64-561601.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/86972/801630/tracy-v0.7.8.563351-darwin64-563351.tar.bz2 name darwin64 @@ -3100,11 +3100,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 503a6ea5c08e17a6709f11cb55b4204a + 47c696cd2966c5cc3c8ba6115dd1f886 hash_algorithm md5 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/85310/791192/tracy-v0.7.8.562170-windows-562170.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/86973/801641/tracy-v0.7.8.563351-windows-563351.tar.bz2 name windows @@ -3114,11 +3114,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 3f61d596eee650763e3cb1d9f6869ed2 + b649ee6591e67d2341e886b3fc3484a7 hash_algorithm md5 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/85309/791191/tracy-v0.7.8.562170-windows64-562170.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/86974/801642/tracy-v0.7.8.563351-windows64-563351.tar.bz2 name windows64 @@ -3129,7 +3129,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors source_type git version - v0.7.8.562170 + v0.7.8.563351 tut diff --git a/indra/llcommon/llframetimer.cpp b/indra/llcommon/llframetimer.cpp index 1e9920746b..e293a557c0 100644 --- a/indra/llcommon/llframetimer.cpp +++ b/indra/llcommon/llframetimer.cpp @@ -29,6 +29,14 @@ #include "llframetimer.h" +// On Windows we build a static lib and link with that +// On macOS we don't bother building a stand alone lib, just include the one source file we need for Tracy support +#if LL_DARWIN + #if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY || LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY_FAST_TIMER + #include "TracyClient.cpp" + #endif // LL_PROFILER_CONFIGURATION +#endif // LL_DARWIN + // Static members //LLTimer LLFrameTimer::sInternalTimer; U64 LLFrameTimer::sStartTotalTime = totalTime(); diff --git a/indra/llcommon/llprofiler.h b/indra/llcommon/llprofiler.h index 29331d35bf..4674985e06 100644 --- a/indra/llcommon/llprofiler.h +++ b/indra/llcommon/llprofiler.h @@ -32,7 +32,9 @@ #define LL_PROFILER_CONFIG_TRACY 2 // Profiling on: Only Tracy #define LL_PROFILER_CONFIG_TRACY_FAST_TIMER 3 // Profiling on: Fast Timers + Tracy +#ifndef LL_PROFILER_CONFIGURATION #define LL_PROFILER_CONFIGURATION LL_PROFILER_CONFIG_FAST_TIMER +#endif #if defined(LL_PROFILER_CONFIGURATION) && (LL_PROFILER_CONFIGURATION > LL_PROFILER_CONFIG_NONE) #if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY || LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY_FAST_TIMER -- cgit v1.2.3 From 91f4d7f7a04839bb9c5e320dcb5f90314586624f Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Tue, 31 Aug 2021 21:23:10 -0700 Subject: SL-15709: Use standardized autobuild name; set TRACY_INCLUDE_DIR if Tracy not enabled --- indra/cmake/Tracy.cmake | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/indra/cmake/Tracy.cmake b/indra/cmake/Tracy.cmake index 4750bdc349..dfa3e83039 100644 --- a/indra/cmake/Tracy.cmake +++ b/indra/cmake/Tracy.cmake @@ -1,9 +1,9 @@ # -*- cmake -*- include(Prebuilt) -set(TRACY OFF CACHE BOOL "Use Tracy profiler.") +set(USE_TRACY OFF CACHE BOOL "Use Tracy profiler.") -if (TRACY) +if (USE_TRACY) set(TRACY_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/tracy) # See: indra/llcommon/llprofiler.h @@ -24,7 +24,9 @@ if (TRACY) MESSAGE(STATUS "Including Tracy for Linux: '${TRACY_INCLUDE_DIR}'") set(TRACY_LIBRARY "") endif (LINUX) -else (TRACY) +else (USE_TRACY) + # Tracy.cmake should not set LLCOMMON_INCLUDE_DIRS, let LLCommon.cmake do that + set(TRACY_INCLUDE_DIR "") set(TRACY_LIBRARY "") -endif (TRACY) +endif (USE_TRACY) -- cgit v1.2.3 From 6d2cad965c63cd352f617537b73506790fd8f4a4 Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Tue, 31 Aug 2021 21:41:03 -0700 Subject: SL-15709: Fix LLCommon not setting Tracy include directory and not linking to tracy.lib --- indra/cmake/LLCommon.cmake | 6 +++++- indra/llcommon/CMakeLists.txt | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/indra/cmake/LLCommon.cmake b/indra/cmake/LLCommon.cmake index c1cfa51cfb..b6f310fe12 100644 --- a/indra/cmake/LLCommon.cmake +++ b/indra/cmake/LLCommon.cmake @@ -3,12 +3,14 @@ include(APR) include(Boost) include(EXPAT) +include(Tracy) include(ZLIB) set(LLCOMMON_INCLUDE_DIRS ${LIBS_OPEN_DIR}/llcommon ${APRUTIL_INCLUDE_DIR} ${APR_INCLUDE_DIR} + ${TRACY_INCLUDE_DIR} ) set(LLCOMMON_SYSTEM_INCLUDE_DIRS ${Boost_INCLUDE_DIRS} @@ -30,7 +32,9 @@ else (LINUX) ${BOOST_FIBER_LIBRARY} ${BOOST_CONTEXT_LIBRARY} ${BOOST_THREAD_LIBRARY} - ${BOOST_SYSTEM_LIBRARY}) + ${BOOST_SYSTEM_LIBRARY} + ${TRACY_LIBRARY} + ) endif (LINUX) set(LLCOMMON_LINK_SHARED OFF CACHE BOOL "Build the llcommon target as a static library.") diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 28bf5d0c39..066d0404ac 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -305,6 +305,7 @@ target_link_libraries( ${BOOST_SYSTEM_LIBRARY} ${GOOGLE_PERFTOOLS_LIBRARIES} ${URIPARSER_LIBRARIES} + ${TRACY_LIBRARY} ) if (DARWIN) -- cgit v1.2.3 From fb6cb050e448bda7e802e2b8828f60ede54872bb Mon Sep 17 00:00:00 2001 From: Runitai Linden Date: Mon, 13 Sep 2021 12:41:57 -0500 Subject: SL-15975 Add Tracy-only profile macros that are no-ops when Tracy is disabled. --- indra/llcommon/llprofiler.h | 6 ++++++ indra/newview/lldrawpoolavatar.cpp | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/indra/llcommon/llprofiler.h b/indra/llcommon/llprofiler.h index 062c9360dd..62e649913b 100644 --- a/indra/llcommon/llprofiler.h +++ b/indra/llcommon/llprofiler.h @@ -51,16 +51,22 @@ #define LL_PROFILER_FRAME_END FrameMark #define LL_PROFILER_SET_THREAD_NAME( name ) tracy::SetThreadName( name ) #define LL_RECORD_BLOCK_TIME(name) ZoneNamedN( ___tracy_scoped_zone, #name, true ); + #define LL_PROFILE_ZONE_NAMED(name) ZoneNamedN( ___tracy_scoped_zone, name, true ); + #define LL_PROFILE_ZONE_SCOPED ZoneScoped #endif #if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_FAST_TIMER #define LL_PROFILER_FRAME_END #define LL_PROFILER_SET_THREAD_NAME( name ) (void)(name) #define LL_RECORD_BLOCK_TIME(name) const LLTrace::BlockTimer& LL_GLUE_TOKENS(block_time_recorder, __LINE__)(LLTrace::timeThisBlock(name)); (void)LL_GLUE_TOKENS(block_time_recorder, __LINE__); + #define LL_PROFILE_ZONE_NAMED(name) // LL_PROFILE_ZONE_NAMED is a no-op when Tracy is disabled + #define LL_PROFILE_ZONE_SCOPED // LL_PROFILE_ZONE_SCOPED is a no-op when Tracy is disabled #endif #if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY_FAST_TIMER #define LL_PROFILER_FRAME_END FrameMark #define LL_PROFILER_SET_THREAD_NAME( name ) tracy::SetThreadName( name ) #define LL_RECORD_BLOCK_TIME(name) ZoneNamedN( ___tracy_scoped_zone, #timer_stat, true ) const LLTrace::BlockTimer& LL_GLUE_TOKENS(block_time_recorder, __LINE__)(LLTrace::timeThisBlock(name)); (void)LL_GLUE_TOKENS(block_time_recorder, __LINE__); + #define LL_PROFILE_ZONE_NAMED(name) ZoneNamedN( ___tracy_scoped_zone, #name, true ); + #define LL_PROFILE_ZONE_SCOPED ZoneScoped #endif #else #define LL_PROFILER_FRAME_END diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 687b13d2c8..c04142ab47 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1840,6 +1840,8 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( LLVolume* volume, LLVolumeFace& vol_face) { + LL_PROFILE_ZONE_SCOPED; + LLVector4a* weights = vol_face.mWeights; if (!weights) { @@ -2352,8 +2354,10 @@ void LLDrawPoolAvatar::updateRiggedVertexBuffers(LLVOAvatar* avatar) //update rigged vertex buffers for (U32 type = 0; type < NUM_RIGGED_PASSES; ++type) { + LL_PROFILE_ZONE_NAMED("Pass"); for (U32 i = 0; i < mRiggedFace[type].size(); ++i) { + LL_PROFILE_ZONE_NAMED("Face"); LLFace* face = mRiggedFace[type][i]; LLDrawable* drawable = face->getDrawable(); if (!drawable) -- cgit v1.2.3 From f844b4e6b950dd6a64c465f1b8d9f5fe3fa498f0 Mon Sep 17 00:00:00 2001 From: Runitai Linden Date: Tue, 14 Sep 2021 20:18:58 -0500 Subject: SL-15961 Convert LLMeshRepository::mSkinMap into unordered_map and reduce number of per-frame lookups to said map. --- indra/llcommon/lluuid.h | 11 +++++++ indra/newview/lldrawpoolavatar.cpp | 65 ++++++++++++++++++-------------------- indra/newview/lldrawpoolavatar.h | 3 +- indra/newview/llmeshrepository.cpp | 40 +++++++++++------------ indra/newview/llmeshrepository.h | 3 +- 5 files changed, 65 insertions(+), 57 deletions(-) diff --git a/indra/llcommon/lluuid.h b/indra/llcommon/lluuid.h index fe7482ba29..86a396ab06 100644 --- a/indra/llcommon/lluuid.h +++ b/indra/llcommon/lluuid.h @@ -184,6 +184,17 @@ struct boost::hash } }; +// Adapt boost hash to std hash +namespace std +{ + template<> struct hash + { + std::size_t operator()(LLUUID const& s) const noexcept + { + return boost::hash()(s); + } + }; +} #endif diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index c04142ab47..6c4844f9ee 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1836,7 +1836,7 @@ void LLDrawPoolAvatar::getRiggedGeometry( void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( LLVOAvatar* avatar, LLFace* face, - const LLMeshSkinInfo* skin, + const LLVOVolume* vobj, LLVolume* volume, LLVolumeFace& vol_face) { @@ -1848,14 +1848,14 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( return; } + if (!vobj || vobj->isNoLOD()) + { + return; + } + LLPointer buffer = face->getVertexBuffer(); LLDrawable* drawable = face->getDrawable(); - if (drawable->getVOVolume() && drawable->getVOVolume()->isNoLOD()) - { - return; - } - const U32 max_joints = LLSkinningUtil::getMaxJointCount(); #if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS @@ -1895,23 +1895,26 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( } #endif - // FIXME ugly const cast - LLSkinningUtil::scrubInvalidJoints(avatar, const_cast(skin)); - - U32 data_mask = face->getRiggedVertexBufferDataMask(); + U32 data_mask = face->getRiggedVertexBufferDataMask(); + const LLMeshSkinInfo* skin = nullptr; - if (!vol_face.mWeightsScrubbed) - { - LLSkinningUtil::scrubSkinWeights(weights, vol_face.mNumVertices, skin); - vol_face.mWeightsScrubbed = TRUE; - } - if (buffer.isNull() || buffer->getTypeMask() != data_mask || buffer->getNumVerts() != vol_face.mNumVertices || buffer->getNumIndices() != vol_face.mNumIndices || (drawable && drawable->isState(LLDrawable::REBUILD_ALL))) { + LL_PROFILE_ZONE_NAMED("Rigged VBO Rebuild"); + skin = vobj->getSkinInfo(); + // FIXME ugly const cast + LLSkinningUtil::scrubInvalidJoints(avatar, const_cast(skin)); + + if (!vol_face.mWeightsScrubbed) + { + LLSkinningUtil::scrubSkinWeights(weights, vol_face.mNumVertices, skin); + vol_face.mWeightsScrubbed = TRUE; + } + if (drawable && drawable->isState(LLDrawable::REBUILD_ALL)) { //rebuild EVERY face in the drawable, not just this one, to avoid missing drawable wide rebuild issues @@ -1937,18 +1940,13 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( } } - if (buffer.isNull() || - buffer->getNumVerts() != vol_face.mNumVertices || - buffer->getNumIndices() != vol_face.mNumIndices) - { - // Allocation failed - return; - } - - if (!buffer.isNull() && - sShaderLevel <= 0 && - face->mLastSkinTime < avatar->getLastSkinTime()) + if (sShaderLevel <= 0 && + face->mLastSkinTime < avatar->getLastSkinTime() && + !buffer.isNull() && + buffer->getNumVerts() == vol_face.mNumVertices && + buffer->getNumIndices() == vol_face.mNumIndices) { + LL_PROFILE_ZONE_NAMED("Software Skinning"); //perform software vertex skinning for this face LLStrider position; LLStrider normal; @@ -1965,6 +1963,11 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( LLVector4a* norm = has_normal ? (LLVector4a*) normal.get() : NULL; + if (skin == nullptr) + { + skin = vobj->getSkinInfo(); + } + //build matrix palette LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT]; U32 count = LLSkinningUtil::getMeshJointCount(skin); @@ -2380,16 +2383,10 @@ void LLDrawPoolAvatar::updateRiggedVertexBuffers(LLVOAvatar* avatar) continue; } - const LLMeshSkinInfo* skin = vobj->getSkinInfo(); - if (!skin) - { - continue; - } - stop_glerror(); LLVolumeFace& vol_face = volume->getVolumeFace(te); - updateRiggedFaceVertexBuffer(avatar, face, skin, volume, vol_face); + updateRiggedFaceVertexBuffer(avatar, face, vobj, volume, vol_face); } } } diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h index 92a8538958..9b26266ced 100644 --- a/indra/newview/lldrawpoolavatar.h +++ b/indra/newview/lldrawpoolavatar.h @@ -30,6 +30,7 @@ #include "lldrawpool.h" class LLVOAvatar; +class LLVOVolume; class LLGLSLShader; class LLFace; class LLMeshSkinInfo; @@ -253,7 +254,7 @@ typedef enum void getRiggedGeometry(LLFace* face, LLPointer& buffer, U32 data_mask, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face); void updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* facep, - const LLMeshSkinInfo* skin, + const LLVOVolume* vobj, LLVolume* volume, LLVolumeFace& vol_face); void updateRiggedVertexBuffers(LLVOAvatar* avatar); diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 2c1c1191da..8ac64dbd15 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -4046,28 +4046,26 @@ S32 LLMeshRepository::getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lo const LLMeshSkinInfo* LLMeshRepository::getSkinInfo(const LLUUID& mesh_id, const LLVOVolume* requesting_obj) { LL_RECORD_BLOCK_TIME(FTM_MESH_FETCH); + if (mesh_id.notNull()) + { + skin_map::iterator iter = mSkinMap.find(mesh_id); + if (iter != mSkinMap.end()) + { + return &(iter->second); + } - if (mesh_id.notNull()) - { - skin_map::iterator iter = mSkinMap.find(mesh_id); - if (iter != mSkinMap.end()) - { - return &(iter->second); - } - - //no skin info known about given mesh, try to fetch it - { - LLMutexLock lock(mMeshMutex); - //add volume to list of loading meshes - skin_load_map::iterator iter = mLoadingSkins.find(mesh_id); - if (iter == mLoadingSkins.end()) - { //no request pending for this skin info - mPendingSkinRequests.push(mesh_id); - } - mLoadingSkins[mesh_id].insert(requesting_obj->getID()); - } - } - + //no skin info known about given mesh, try to fetch it + { + LLMutexLock lock(mMeshMutex); + //add volume to list of loading meshes + skin_load_map::iterator iter = mLoadingSkins.find(mesh_id); + if (iter == mLoadingSkins.end()) + { //no request pending for this skin info + mPendingSkinRequests.push(mesh_id); + } + mLoadingSkins[mesh_id].insert(requesting_obj->getID()); + } + } return NULL; } diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index 81e49cb1d8..c1698194cb 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -27,6 +27,7 @@ #ifndef LL_MESH_REPOSITORY_H #define LL_MESH_REPOSITORY_H +#include #include "llassettype.h" #include "llmodel.h" #include "lluuid.h" @@ -613,7 +614,7 @@ public: typedef std::map > mesh_load_map; mesh_load_map mLoadingMeshes[4]; - typedef std::map skin_map; + typedef std::unordered_map skin_map; skin_map mSkinMap; typedef std::map decomposition_map; -- cgit v1.2.3 From a1a9c02148d8d0537b3736365d4d46b09d9891d2 Mon Sep 17 00:00:00 2001 From: Runitai Linden Date: Tue, 14 Sep 2021 20:50:55 -0500 Subject: SL-15038 Added Tracy instrumentation to name tags and chat bubbles. --- indra/newview/llhudnametag.cpp | 2 ++ indra/newview/llvoavatar.cpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp index 9d49c30a49..55a4b5a457 100644 --- a/indra/newview/llhudnametag.cpp +++ b/indra/newview/llhudnametag.cpp @@ -224,6 +224,7 @@ BOOL LLHUDNameTag::lineSegmentIntersect(const LLVector4a& start, const LLVector4 void LLHUDNameTag::render() { + LL_PROFILE_ZONE_SCOPED; if (sDisplayText) { LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); @@ -731,6 +732,7 @@ void LLHUDNameTag::updateSize() void LLHUDNameTag::updateAll() { + LL_PROFILE_ZONE_SCOPED; // iterate over all text objects, calculate their restoration forces, // and add them to the visible set if they are on screen and close enough sVisibleTextObjects.clear(); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index e085a945a8..ba9f8d14cb 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -3136,6 +3136,8 @@ void LLVOAvatar::idleUpdateWindEffect() void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) { + LL_PROFILE_ZONE_SCOPED; + // update chat bubble //-------------------------------------------------------------------- // draw text label over character's head -- cgit v1.2.3 From f2d4f83931f77282d6cdeba582def46b51c22b89 Mon Sep 17 00:00:00 2001 From: Dave Houlton Date: Wed, 15 Sep 2021 10:11:25 -0600 Subject: SL-15962 Add hooks for tracy memory profiling --- indra/llcommon/linden_common.h | 8 ++++++++ indra/llcommon/llcommon.cpp | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/indra/llcommon/linden_common.h b/indra/llcommon/linden_common.h index 45ac43910c..b2c5be6b76 100644 --- a/indra/llcommon/linden_common.h +++ b/indra/llcommon/linden_common.h @@ -27,6 +27,14 @@ #ifndef LL_LINDEN_COMMON_H #define LL_LINDEN_COMMON_H +#include "llprofiler.h" +#if (TRACY_ENABLE) // hooks for memory profiling +void *tracy_aligned_malloc(size_t size, size_t alignment); +void tracy_aligned_free(void *memblock); +#define _aligned_malloc(X, Y) tracy_aligned_malloc((X), (Y)) +#define _aligned_free(X) tracy_aligned_free((X)) +#endif + // *NOTE: Please keep includes here to a minimum! // // Files included here are included in every library .cpp file and diff --git a/indra/llcommon/llcommon.cpp b/indra/llcommon/llcommon.cpp index 96be913d17..da61e7539a 100644 --- a/indra/llcommon/llcommon.cpp +++ b/indra/llcommon/llcommon.cpp @@ -33,6 +33,48 @@ #include "lltracethreadrecorder.h" #include "llcleanup.h" +#if (TRACY_ENABLE) +// Override new/delet for tracy memory profiling +void *operator new(size_t size) +{ + auto ptr = (malloc) (size); + if (!ptr) + { + throw std::bad_alloc(); + return nullptr; + } + TracyAlloc(ptr, size); + return ptr; +} + +void operator delete(void *ptr) noexcept +{ + TracyFree(ptr); + (free)(ptr); +} + +// C-style malloc/free can't be so easily overridden, so we define tracy versions and use +// a pre-processor #define in linden_common.h to redirect to them. The parens around the native +// functions below prevents recursive substitution by the preprocessor. +// +// Unaligned mallocs are rare in LL code but hooking them causes problems in 3p lib code (looking at +// you, Havok), so we'll only capture the aligned version. + +void *tracy_aligned_malloc(size_t size, size_t alignment) +{ + auto ptr = (_aligned_malloc) (size, alignment); + if (ptr) TracyAlloc(ptr, size); + return ptr; +} + +void tracy_aligned_free(void *memblock) +{ + TracyFree(memblock); + (_aligned_free)(memblock); +} + +#endif + //static BOOL LLCommon::sAprInitialized = FALSE; -- cgit v1.2.3 From 7fe2856516d9e0de0fda6ff389ad3cc977b2d309 Mon Sep 17 00:00:00 2001 From: Runitai Linden Date: Mon, 13 Sep 2021 12:41:57 -0500 Subject: SL-15975 Add Tracy-only profile macros that are no-ops when Tracy is disabled. --- indra/llcommon/llprofiler.h | 6 ++++++ indra/newview/lldrawpoolavatar.cpp | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/indra/llcommon/llprofiler.h b/indra/llcommon/llprofiler.h index 062c9360dd..62e649913b 100644 --- a/indra/llcommon/llprofiler.h +++ b/indra/llcommon/llprofiler.h @@ -51,16 +51,22 @@ #define LL_PROFILER_FRAME_END FrameMark #define LL_PROFILER_SET_THREAD_NAME( name ) tracy::SetThreadName( name ) #define LL_RECORD_BLOCK_TIME(name) ZoneNamedN( ___tracy_scoped_zone, #name, true ); + #define LL_PROFILE_ZONE_NAMED(name) ZoneNamedN( ___tracy_scoped_zone, name, true ); + #define LL_PROFILE_ZONE_SCOPED ZoneScoped #endif #if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_FAST_TIMER #define LL_PROFILER_FRAME_END #define LL_PROFILER_SET_THREAD_NAME( name ) (void)(name) #define LL_RECORD_BLOCK_TIME(name) const LLTrace::BlockTimer& LL_GLUE_TOKENS(block_time_recorder, __LINE__)(LLTrace::timeThisBlock(name)); (void)LL_GLUE_TOKENS(block_time_recorder, __LINE__); + #define LL_PROFILE_ZONE_NAMED(name) // LL_PROFILE_ZONE_NAMED is a no-op when Tracy is disabled + #define LL_PROFILE_ZONE_SCOPED // LL_PROFILE_ZONE_SCOPED is a no-op when Tracy is disabled #endif #if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY_FAST_TIMER #define LL_PROFILER_FRAME_END FrameMark #define LL_PROFILER_SET_THREAD_NAME( name ) tracy::SetThreadName( name ) #define LL_RECORD_BLOCK_TIME(name) ZoneNamedN( ___tracy_scoped_zone, #timer_stat, true ) const LLTrace::BlockTimer& LL_GLUE_TOKENS(block_time_recorder, __LINE__)(LLTrace::timeThisBlock(name)); (void)LL_GLUE_TOKENS(block_time_recorder, __LINE__); + #define LL_PROFILE_ZONE_NAMED(name) ZoneNamedN( ___tracy_scoped_zone, #name, true ); + #define LL_PROFILE_ZONE_SCOPED ZoneScoped #endif #else #define LL_PROFILER_FRAME_END diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 687b13d2c8..c04142ab47 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1840,6 +1840,8 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( LLVolume* volume, LLVolumeFace& vol_face) { + LL_PROFILE_ZONE_SCOPED; + LLVector4a* weights = vol_face.mWeights; if (!weights) { @@ -2352,8 +2354,10 @@ void LLDrawPoolAvatar::updateRiggedVertexBuffers(LLVOAvatar* avatar) //update rigged vertex buffers for (U32 type = 0; type < NUM_RIGGED_PASSES; ++type) { + LL_PROFILE_ZONE_NAMED("Pass"); for (U32 i = 0; i < mRiggedFace[type].size(); ++i) { + LL_PROFILE_ZONE_NAMED("Face"); LLFace* face = mRiggedFace[type][i]; LLDrawable* drawable = face->getDrawable(); if (!drawable) -- cgit v1.2.3 From 04e1962d48e36f9055f0d893fc1b7a97d9e334c6 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Wed, 15 Sep 2021 20:06:56 +0100 Subject: SL-15742 - python 3 support for integration test script --- indra/llcommon/tests/llprocess_test.cpp | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/indra/llcommon/tests/llprocess_test.cpp b/indra/llcommon/tests/llprocess_test.cpp index f0eafa8201..447c7f50f2 100644 --- a/indra/llcommon/tests/llprocess_test.cpp +++ b/indra/llcommon/tests/llprocess_test.cpp @@ -356,14 +356,15 @@ namespace tut // Create a script file in a temporary place. NamedTempFile script("py", + "from __future__ import print_function" EOL "import sys" EOL "import time" EOL EOL "time.sleep(2)" EOL - "print >>sys.stdout, 'stdout after wait'" EOL + "print('stdout after wait',file=sys.stdout)" EOL "sys.stdout.flush()" EOL "time.sleep(2)" EOL - "print >>sys.stderr, 'stderr after wait'" EOL + "print('stderr after wait',file=sys.stderr)" EOL "sys.stderr.flush()" EOL ); @@ -568,12 +569,12 @@ namespace tut { set_test_name("arguments"); PythonProcessLauncher py(get_test_name(), - "from __future__ import with_statement\n" + "from __future__ import with_statement, print_function\n" "import sys\n" // note nonstandard output-file arg! "with open(sys.argv[3], 'w') as f:\n" " for arg in sys.argv[1:]:\n" - " print >>f, arg\n"); + " print(arg,file=f)\n"); // We expect that PythonProcessLauncher has already appended // its own NamedTempFile to mParams.args (sys.argv[0]). py.mParams.args.add("first arg"); // sys.argv[1] @@ -857,7 +858,8 @@ namespace tut set_test_name("'bogus' test"); CaptureLog recorder; PythonProcessLauncher py(get_test_name(), - "print 'Hello world'\n"); + "from __future__ import print_function\n" + "print('Hello world')\n"); py.mParams.files.add(LLProcess::FileParam("bogus")); py.mPy = LLProcess::create(py.mParams); ensure("should have rejected 'bogus'", ! py.mPy); @@ -872,7 +874,8 @@ namespace tut // Replace this test with one or more real 'file' tests when we // implement 'file' support PythonProcessLauncher py(get_test_name(), - "print 'Hello world'\n"); + "from __future__ import print_function\n" + "print('Hello world')\n"); py.mParams.files.add(LLProcess::FileParam()); py.mParams.files.add(LLProcess::FileParam("file")); py.mPy = LLProcess::create(py.mParams); @@ -887,7 +890,8 @@ namespace tut // implement 'tpipe' support CaptureLog recorder; PythonProcessLauncher py(get_test_name(), - "print 'Hello world'\n"); + "from __future__ import print_function\n" + "print('Hello world')\n"); py.mParams.files.add(LLProcess::FileParam()); py.mParams.files.add(LLProcess::FileParam("tpipe")); py.mPy = LLProcess::create(py.mParams); @@ -904,7 +908,8 @@ namespace tut // implement 'npipe' support CaptureLog recorder; PythonProcessLauncher py(get_test_name(), - "print 'Hello world'\n"); + "from __future__ import print_function\n" + "print('Hello world')\n"); py.mParams.files.add(LLProcess::FileParam()); py.mParams.files.add(LLProcess::FileParam()); py.mParams.files.add(LLProcess::FileParam("npipe")); @@ -980,7 +985,8 @@ namespace tut { set_test_name("get*Pipe() validation"); PythonProcessLauncher py(get_test_name(), - "print 'this output is expected'\n"); + "from __future__ import print_function\n" + "print('this output is expected')\n"); py.mParams.files.add(LLProcess::FileParam("pipe")); // pipe for stdin py.mParams.files.add(LLProcess::FileParam()); // inherit stdout py.mParams.files.add(LLProcess::FileParam("pipe")); // pipe for stderr @@ -1000,14 +1006,15 @@ namespace tut { set_test_name("talk to stdin/stdout"); PythonProcessLauncher py(get_test_name(), + "from __future__ import print_function\n" "import sys, time\n" - "print 'ok'\n" + "print('ok')\n" "sys.stdout.flush()\n" "# wait for 'go' from test program\n" "go = sys.stdin.readline()\n" "if go != 'go\\n':\n" " sys.exit('expected \"go\", saw %r' % go)\n" - "print 'ack'\n"); + "print('ack')\n"); py.mParams.files.add(LLProcess::FileParam("pipe")); // stdin py.mParams.files.add(LLProcess::FileParam("pipe")); // stdout py.launch(); @@ -1118,7 +1125,8 @@ namespace tut { set_test_name("ReadPipe \"eof\" event"); PythonProcessLauncher py(get_test_name(), - "print 'Hello from Python!'\n"); + "from __future__ import print_function\n" + "print('Hello from Python!')\n"); py.mParams.files.add(LLProcess::FileParam()); // stdin py.mParams.files.add(LLProcess::FileParam("pipe")); // stdout py.launch(); -- cgit v1.2.3 From a4c9fb003f36955cecb0b987b5ddf9a04edd0f90 Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Fri, 3 Sep 2021 17:20:22 -0700 Subject: SL-15709: Windows: Include Tracy source directly; don't use a library --- indra/cmake/LLCommon.cmake | 1 - indra/cmake/Tracy.cmake | 3 --- indra/llcommon/llframetimer.cpp | 11 ++++------- indra/llcommon/llprofiler.h | 6 ++++-- 4 files changed, 8 insertions(+), 13 deletions(-) diff --git a/indra/cmake/LLCommon.cmake b/indra/cmake/LLCommon.cmake index b6f310fe12..34499aaa36 100644 --- a/indra/cmake/LLCommon.cmake +++ b/indra/cmake/LLCommon.cmake @@ -33,7 +33,6 @@ else (LINUX) ${BOOST_CONTEXT_LIBRARY} ${BOOST_THREAD_LIBRARY} ${BOOST_SYSTEM_LIBRARY} - ${TRACY_LIBRARY} ) endif (LINUX) diff --git a/indra/cmake/Tracy.cmake b/indra/cmake/Tracy.cmake index dfa3e83039..1b8c3db2e2 100644 --- a/indra/cmake/Tracy.cmake +++ b/indra/cmake/Tracy.cmake @@ -12,17 +12,14 @@ if (USE_TRACY) if (WINDOWS) MESSAGE(STATUS "Including Tracy for Windows: '${TRACY_INCLUDE_DIR}'") - set(TRACY_LIBRARY tracy) endif (WINDOWS) if (DARWIN) MESSAGE(STATUS "Including Tracy for Darwin: '${TRACY_INCLUDE_DIR}'") - set(TRACY_LIBRARY "") endif (DARWIN) if (LINUX) MESSAGE(STATUS "Including Tracy for Linux: '${TRACY_INCLUDE_DIR}'") - set(TRACY_LIBRARY "") endif (LINUX) else (USE_TRACY) # Tracy.cmake should not set LLCOMMON_INCLUDE_DIRS, let LLCommon.cmake do that diff --git a/indra/llcommon/llframetimer.cpp b/indra/llcommon/llframetimer.cpp index e293a557c0..c54029e8b4 100644 --- a/indra/llcommon/llframetimer.cpp +++ b/indra/llcommon/llframetimer.cpp @@ -29,13 +29,10 @@ #include "llframetimer.h" -// On Windows we build a static lib and link with that -// On macOS we don't bother building a stand alone lib, just include the one source file we need for Tracy support -#if LL_DARWIN - #if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY || LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY_FAST_TIMER - #include "TracyClient.cpp" - #endif // LL_PROFILER_CONFIGURATION -#endif // LL_DARWIN +// We don't bother building a stand alone lib; we just need to include the one source file for Tracy support +#if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY || LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY_FAST_TIMER + #include "TracyClient.cpp" +#endif // LL_PROFILER_CONFIGURATION // Static members //LLTimer LLFrameTimer::sInternalTimer; diff --git a/indra/llcommon/llprofiler.h b/indra/llcommon/llprofiler.h index 4674985e06..062c9360dd 100644 --- a/indra/llcommon/llprofiler.h +++ b/indra/llcommon/llprofiler.h @@ -39,8 +39,10 @@ #if defined(LL_PROFILER_CONFIGURATION) && (LL_PROFILER_CONFIGURATION > LL_PROFILER_CONFIG_NONE) #if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY || LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY_FAST_TIMER #define TRACY_ENABLE 1 - #define TRACY_NO_BROADCAST 1 - #define TRACY_ONLY_LOCALHOST 1 +// Normally these would be enabled but we want to be able to build any viewer with Tracy enabled and run the Tracy server on another machine +// They must be undefined in order to work across multiple machines +// #define TRACY_NO_BROADCAST 1 +// #define TRACY_ONLY_LOCALHOST 1 #define TRACY_ONLY_IPV4 1 #include "Tracy.hpp" #endif -- cgit v1.2.3 From fc612fd8a0057daa7436c8d2285ccee0c634378a Mon Sep 17 00:00:00 2001 From: Runitai Linden Date: Mon, 13 Sep 2021 12:41:57 -0500 Subject: SL-15975 Add Tracy-only profile macros that are no-ops when Tracy is disabled. --- indra/llcommon/llprofiler.h | 6 ++++++ indra/newview/lldrawpoolavatar.cpp | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/indra/llcommon/llprofiler.h b/indra/llcommon/llprofiler.h index 062c9360dd..62e649913b 100644 --- a/indra/llcommon/llprofiler.h +++ b/indra/llcommon/llprofiler.h @@ -51,16 +51,22 @@ #define LL_PROFILER_FRAME_END FrameMark #define LL_PROFILER_SET_THREAD_NAME( name ) tracy::SetThreadName( name ) #define LL_RECORD_BLOCK_TIME(name) ZoneNamedN( ___tracy_scoped_zone, #name, true ); + #define LL_PROFILE_ZONE_NAMED(name) ZoneNamedN( ___tracy_scoped_zone, name, true ); + #define LL_PROFILE_ZONE_SCOPED ZoneScoped #endif #if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_FAST_TIMER #define LL_PROFILER_FRAME_END #define LL_PROFILER_SET_THREAD_NAME( name ) (void)(name) #define LL_RECORD_BLOCK_TIME(name) const LLTrace::BlockTimer& LL_GLUE_TOKENS(block_time_recorder, __LINE__)(LLTrace::timeThisBlock(name)); (void)LL_GLUE_TOKENS(block_time_recorder, __LINE__); + #define LL_PROFILE_ZONE_NAMED(name) // LL_PROFILE_ZONE_NAMED is a no-op when Tracy is disabled + #define LL_PROFILE_ZONE_SCOPED // LL_PROFILE_ZONE_SCOPED is a no-op when Tracy is disabled #endif #if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY_FAST_TIMER #define LL_PROFILER_FRAME_END FrameMark #define LL_PROFILER_SET_THREAD_NAME( name ) tracy::SetThreadName( name ) #define LL_RECORD_BLOCK_TIME(name) ZoneNamedN( ___tracy_scoped_zone, #timer_stat, true ) const LLTrace::BlockTimer& LL_GLUE_TOKENS(block_time_recorder, __LINE__)(LLTrace::timeThisBlock(name)); (void)LL_GLUE_TOKENS(block_time_recorder, __LINE__); + #define LL_PROFILE_ZONE_NAMED(name) ZoneNamedN( ___tracy_scoped_zone, #name, true ); + #define LL_PROFILE_ZONE_SCOPED ZoneScoped #endif #else #define LL_PROFILER_FRAME_END diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 687b13d2c8..c04142ab47 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1840,6 +1840,8 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( LLVolume* volume, LLVolumeFace& vol_face) { + LL_PROFILE_ZONE_SCOPED; + LLVector4a* weights = vol_face.mWeights; if (!weights) { @@ -2352,8 +2354,10 @@ void LLDrawPoolAvatar::updateRiggedVertexBuffers(LLVOAvatar* avatar) //update rigged vertex buffers for (U32 type = 0; type < NUM_RIGGED_PASSES; ++type) { + LL_PROFILE_ZONE_NAMED("Pass"); for (U32 i = 0; i < mRiggedFace[type].size(); ++i) { + LL_PROFILE_ZONE_NAMED("Face"); LLFace* face = mRiggedFace[type][i]; LLDrawable* drawable = face->getDrawable(); if (!drawable) -- cgit v1.2.3 From 84da92663aad221db19927de26922417e7cb45c6 Mon Sep 17 00:00:00 2001 From: Runitai Linden Date: Tue, 14 Sep 2021 20:18:58 -0500 Subject: SL-15961 Convert LLMeshRepository::mSkinMap into unordered_map and reduce number of per-frame lookups to said map. --- indra/llcommon/lluuid.h | 11 +++++++ indra/newview/lldrawpoolavatar.cpp | 65 ++++++++++++++++++-------------------- indra/newview/lldrawpoolavatar.h | 3 +- indra/newview/llmeshrepository.cpp | 40 +++++++++++------------ indra/newview/llmeshrepository.h | 3 +- 5 files changed, 65 insertions(+), 57 deletions(-) diff --git a/indra/llcommon/lluuid.h b/indra/llcommon/lluuid.h index fe7482ba29..86a396ab06 100644 --- a/indra/llcommon/lluuid.h +++ b/indra/llcommon/lluuid.h @@ -184,6 +184,17 @@ struct boost::hash } }; +// Adapt boost hash to std hash +namespace std +{ + template<> struct hash + { + std::size_t operator()(LLUUID const& s) const noexcept + { + return boost::hash()(s); + } + }; +} #endif diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index c04142ab47..6c4844f9ee 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1836,7 +1836,7 @@ void LLDrawPoolAvatar::getRiggedGeometry( void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( LLVOAvatar* avatar, LLFace* face, - const LLMeshSkinInfo* skin, + const LLVOVolume* vobj, LLVolume* volume, LLVolumeFace& vol_face) { @@ -1848,14 +1848,14 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( return; } + if (!vobj || vobj->isNoLOD()) + { + return; + } + LLPointer buffer = face->getVertexBuffer(); LLDrawable* drawable = face->getDrawable(); - if (drawable->getVOVolume() && drawable->getVOVolume()->isNoLOD()) - { - return; - } - const U32 max_joints = LLSkinningUtil::getMaxJointCount(); #if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS @@ -1895,23 +1895,26 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( } #endif - // FIXME ugly const cast - LLSkinningUtil::scrubInvalidJoints(avatar, const_cast(skin)); - - U32 data_mask = face->getRiggedVertexBufferDataMask(); + U32 data_mask = face->getRiggedVertexBufferDataMask(); + const LLMeshSkinInfo* skin = nullptr; - if (!vol_face.mWeightsScrubbed) - { - LLSkinningUtil::scrubSkinWeights(weights, vol_face.mNumVertices, skin); - vol_face.mWeightsScrubbed = TRUE; - } - if (buffer.isNull() || buffer->getTypeMask() != data_mask || buffer->getNumVerts() != vol_face.mNumVertices || buffer->getNumIndices() != vol_face.mNumIndices || (drawable && drawable->isState(LLDrawable::REBUILD_ALL))) { + LL_PROFILE_ZONE_NAMED("Rigged VBO Rebuild"); + skin = vobj->getSkinInfo(); + // FIXME ugly const cast + LLSkinningUtil::scrubInvalidJoints(avatar, const_cast(skin)); + + if (!vol_face.mWeightsScrubbed) + { + LLSkinningUtil::scrubSkinWeights(weights, vol_face.mNumVertices, skin); + vol_face.mWeightsScrubbed = TRUE; + } + if (drawable && drawable->isState(LLDrawable::REBUILD_ALL)) { //rebuild EVERY face in the drawable, not just this one, to avoid missing drawable wide rebuild issues @@ -1937,18 +1940,13 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( } } - if (buffer.isNull() || - buffer->getNumVerts() != vol_face.mNumVertices || - buffer->getNumIndices() != vol_face.mNumIndices) - { - // Allocation failed - return; - } - - if (!buffer.isNull() && - sShaderLevel <= 0 && - face->mLastSkinTime < avatar->getLastSkinTime()) + if (sShaderLevel <= 0 && + face->mLastSkinTime < avatar->getLastSkinTime() && + !buffer.isNull() && + buffer->getNumVerts() == vol_face.mNumVertices && + buffer->getNumIndices() == vol_face.mNumIndices) { + LL_PROFILE_ZONE_NAMED("Software Skinning"); //perform software vertex skinning for this face LLStrider position; LLStrider normal; @@ -1965,6 +1963,11 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( LLVector4a* norm = has_normal ? (LLVector4a*) normal.get() : NULL; + if (skin == nullptr) + { + skin = vobj->getSkinInfo(); + } + //build matrix palette LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT]; U32 count = LLSkinningUtil::getMeshJointCount(skin); @@ -2380,16 +2383,10 @@ void LLDrawPoolAvatar::updateRiggedVertexBuffers(LLVOAvatar* avatar) continue; } - const LLMeshSkinInfo* skin = vobj->getSkinInfo(); - if (!skin) - { - continue; - } - stop_glerror(); LLVolumeFace& vol_face = volume->getVolumeFace(te); - updateRiggedFaceVertexBuffer(avatar, face, skin, volume, vol_face); + updateRiggedFaceVertexBuffer(avatar, face, vobj, volume, vol_face); } } } diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h index 92a8538958..9b26266ced 100644 --- a/indra/newview/lldrawpoolavatar.h +++ b/indra/newview/lldrawpoolavatar.h @@ -30,6 +30,7 @@ #include "lldrawpool.h" class LLVOAvatar; +class LLVOVolume; class LLGLSLShader; class LLFace; class LLMeshSkinInfo; @@ -253,7 +254,7 @@ typedef enum void getRiggedGeometry(LLFace* face, LLPointer& buffer, U32 data_mask, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face); void updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* facep, - const LLMeshSkinInfo* skin, + const LLVOVolume* vobj, LLVolume* volume, LLVolumeFace& vol_face); void updateRiggedVertexBuffers(LLVOAvatar* avatar); diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 2c1c1191da..8ac64dbd15 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -4046,28 +4046,26 @@ S32 LLMeshRepository::getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lo const LLMeshSkinInfo* LLMeshRepository::getSkinInfo(const LLUUID& mesh_id, const LLVOVolume* requesting_obj) { LL_RECORD_BLOCK_TIME(FTM_MESH_FETCH); + if (mesh_id.notNull()) + { + skin_map::iterator iter = mSkinMap.find(mesh_id); + if (iter != mSkinMap.end()) + { + return &(iter->second); + } - if (mesh_id.notNull()) - { - skin_map::iterator iter = mSkinMap.find(mesh_id); - if (iter != mSkinMap.end()) - { - return &(iter->second); - } - - //no skin info known about given mesh, try to fetch it - { - LLMutexLock lock(mMeshMutex); - //add volume to list of loading meshes - skin_load_map::iterator iter = mLoadingSkins.find(mesh_id); - if (iter == mLoadingSkins.end()) - { //no request pending for this skin info - mPendingSkinRequests.push(mesh_id); - } - mLoadingSkins[mesh_id].insert(requesting_obj->getID()); - } - } - + //no skin info known about given mesh, try to fetch it + { + LLMutexLock lock(mMeshMutex); + //add volume to list of loading meshes + skin_load_map::iterator iter = mLoadingSkins.find(mesh_id); + if (iter == mLoadingSkins.end()) + { //no request pending for this skin info + mPendingSkinRequests.push(mesh_id); + } + mLoadingSkins[mesh_id].insert(requesting_obj->getID()); + } + } return NULL; } diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index 81e49cb1d8..c1698194cb 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -27,6 +27,7 @@ #ifndef LL_MESH_REPOSITORY_H #define LL_MESH_REPOSITORY_H +#include #include "llassettype.h" #include "llmodel.h" #include "lluuid.h" @@ -613,7 +614,7 @@ public: typedef std::map > mesh_load_map; mesh_load_map mLoadingMeshes[4]; - typedef std::map skin_map; + typedef std::unordered_map skin_map; skin_map mSkinMap; typedef std::map decomposition_map; -- cgit v1.2.3 From 6f03dc8d048ca82e49592b3358f7b1f2a74137ec Mon Sep 17 00:00:00 2001 From: Runitai Linden Date: Tue, 14 Sep 2021 20:50:55 -0500 Subject: SL-15038 Added Tracy instrumentation to name tags and chat bubbles. --- indra/newview/llhudnametag.cpp | 2 ++ indra/newview/llvoavatar.cpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp index 9d49c30a49..55a4b5a457 100644 --- a/indra/newview/llhudnametag.cpp +++ b/indra/newview/llhudnametag.cpp @@ -224,6 +224,7 @@ BOOL LLHUDNameTag::lineSegmentIntersect(const LLVector4a& start, const LLVector4 void LLHUDNameTag::render() { + LL_PROFILE_ZONE_SCOPED; if (sDisplayText) { LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); @@ -731,6 +732,7 @@ void LLHUDNameTag::updateSize() void LLHUDNameTag::updateAll() { + LL_PROFILE_ZONE_SCOPED; // iterate over all text objects, calculate their restoration forces, // and add them to the visible set if they are on screen and close enough sVisibleTextObjects.clear(); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index e085a945a8..ba9f8d14cb 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -3136,6 +3136,8 @@ void LLVOAvatar::idleUpdateWindEffect() void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) { + LL_PROFILE_ZONE_SCOPED; + // update chat bubble //-------------------------------------------------------------------- // draw text label over character's head -- cgit v1.2.3 From 6c6eb59e947631275b2149208e4b46977dfa0309 Mon Sep 17 00:00:00 2001 From: Dave Houlton Date: Wed, 15 Sep 2021 10:11:25 -0600 Subject: SL-15962 Add hooks for tracy memory profiling --- indra/llcommon/linden_common.h | 8 ++++++++ indra/llcommon/llcommon.cpp | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/indra/llcommon/linden_common.h b/indra/llcommon/linden_common.h index 45ac43910c..b2c5be6b76 100644 --- a/indra/llcommon/linden_common.h +++ b/indra/llcommon/linden_common.h @@ -27,6 +27,14 @@ #ifndef LL_LINDEN_COMMON_H #define LL_LINDEN_COMMON_H +#include "llprofiler.h" +#if (TRACY_ENABLE) // hooks for memory profiling +void *tracy_aligned_malloc(size_t size, size_t alignment); +void tracy_aligned_free(void *memblock); +#define _aligned_malloc(X, Y) tracy_aligned_malloc((X), (Y)) +#define _aligned_free(X) tracy_aligned_free((X)) +#endif + // *NOTE: Please keep includes here to a minimum! // // Files included here are included in every library .cpp file and diff --git a/indra/llcommon/llcommon.cpp b/indra/llcommon/llcommon.cpp index 96be913d17..da61e7539a 100644 --- a/indra/llcommon/llcommon.cpp +++ b/indra/llcommon/llcommon.cpp @@ -33,6 +33,48 @@ #include "lltracethreadrecorder.h" #include "llcleanup.h" +#if (TRACY_ENABLE) +// Override new/delet for tracy memory profiling +void *operator new(size_t size) +{ + auto ptr = (malloc) (size); + if (!ptr) + { + throw std::bad_alloc(); + return nullptr; + } + TracyAlloc(ptr, size); + return ptr; +} + +void operator delete(void *ptr) noexcept +{ + TracyFree(ptr); + (free)(ptr); +} + +// C-style malloc/free can't be so easily overridden, so we define tracy versions and use +// a pre-processor #define in linden_common.h to redirect to them. The parens around the native +// functions below prevents recursive substitution by the preprocessor. +// +// Unaligned mallocs are rare in LL code but hooking them causes problems in 3p lib code (looking at +// you, Havok), so we'll only capture the aligned version. + +void *tracy_aligned_malloc(size_t size, size_t alignment) +{ + auto ptr = (_aligned_malloc) (size, alignment); + if (ptr) TracyAlloc(ptr, size); + return ptr; +} + +void tracy_aligned_free(void *memblock) +{ + TracyFree(memblock); + (_aligned_free)(memblock); +} + +#endif + //static BOOL LLCommon::sAprInitialized = FALSE; -- cgit v1.2.3 From 76b31684de60186ad70616d5dd4be0f706663883 Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Wed, 15 Sep 2021 15:39:48 -0700 Subject: SL-16014 Add Tracy logging to lldrawpoolavatar.cpp --- indra/newview/lldrawpoolavatar.cpp | 126 ++++++++++++++++++++++++++++++++++++- 1 file changed, 125 insertions(+), 1 deletion(-) diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index c04142ab47..4f615d6107 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -121,6 +121,8 @@ LLDrawPoolAvatar::~LLDrawPoolAvatar() // virtual BOOL LLDrawPoolAvatar::isDead() { + LL_PROFILE_ZONE_SCOPED + if (!LLFacePool::isDead()) { return FALSE; @@ -138,11 +140,15 @@ BOOL LLDrawPoolAvatar::isDead() S32 LLDrawPoolAvatar::getShaderLevel() const { + LL_PROFILE_ZONE_SCOPED + return (S32) LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR); } void LLDrawPoolAvatar::prerender() { + LL_PROFILE_ZONE_SCOPED + mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR); sShaderLevel = mShaderLevel; @@ -169,6 +175,8 @@ void LLDrawPoolAvatar::prerender() LLMatrix4& LLDrawPoolAvatar::getModelView() { + LL_PROFILE_ZONE_SCOPED + static LLMatrix4 ret; ret.initRows(LLVector4(gGLModelView+0), @@ -257,6 +265,8 @@ void LLDrawPoolAvatar::endDeferredPass(S32 pass) void LLDrawPoolAvatar::renderDeferred(S32 pass) { + LL_PROFILE_ZONE_SCOPED + render(pass); } @@ -267,6 +277,8 @@ S32 LLDrawPoolAvatar::getNumPostDeferredPasses() void LLDrawPoolAvatar::beginPostDeferredPass(S32 pass) { + LL_PROFILE_ZONE_SCOPED + switch (pass) { case 0: @@ -295,6 +307,8 @@ void LLDrawPoolAvatar::beginPostDeferredPass(S32 pass) void LLDrawPoolAvatar::beginPostDeferredAlpha() { + LL_PROFILE_ZONE_SCOPED + sSkipOpaque = TRUE; sShaderLevel = mShaderLevel; sVertexProgram = &gDeferredAvatarAlphaProgram; @@ -309,6 +323,8 @@ void LLDrawPoolAvatar::beginPostDeferredAlpha() void LLDrawPoolAvatar::beginDeferredRiggedAlpha() { + LL_PROFILE_ZONE_SCOPED + sVertexProgram = &gDeferredSkinnedAlphaProgram; gPipeline.bindDeferredShader(*sVertexProgram); sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); @@ -317,6 +333,8 @@ void LLDrawPoolAvatar::beginDeferredRiggedAlpha() void LLDrawPoolAvatar::beginDeferredRiggedMaterialAlpha(S32 pass) { + LL_PROFILE_ZONE_SCOPED + switch (pass) { case 0: pass = 1; break; @@ -343,6 +361,8 @@ void LLDrawPoolAvatar::beginDeferredRiggedMaterialAlpha(S32 pass) void LLDrawPoolAvatar::endDeferredRiggedAlpha() { + LL_PROFILE_ZONE_SCOPED + LLVertexBuffer::unbind(); gPipeline.unbindDeferredShader(*sVertexProgram); sDiffuseChannel = 0; @@ -353,6 +373,8 @@ void LLDrawPoolAvatar::endDeferredRiggedAlpha() void LLDrawPoolAvatar::endPostDeferredPass(S32 pass) { + LL_PROFILE_ZONE_SCOPED + switch (pass) { case 0: @@ -381,6 +403,8 @@ void LLDrawPoolAvatar::endPostDeferredPass(S32 pass) void LLDrawPoolAvatar::endPostDeferredAlpha() { + LL_PROFILE_ZONE_SCOPED + // if we're in software-blending, remember to set the fence _after_ we draw so we wait till this rendering is done sRenderingSkinned = FALSE; sSkipOpaque = FALSE; @@ -392,6 +416,8 @@ void LLDrawPoolAvatar::endPostDeferredAlpha() void LLDrawPoolAvatar::renderPostDeferred(S32 pass) { + LL_PROFILE_ZONE_SCOPED + static const S32 actual_pass[] = { //map post deferred pass numbers to what render() expects 2, //skinned @@ -647,6 +673,8 @@ void LLDrawPoolAvatar::renderShadow(S32 pass) S32 LLDrawPoolAvatar::getNumPasses() { + LL_PROFILE_ZONE_SCOPED + if (LLPipeline::sImpostorRender) { return 8; @@ -660,6 +688,8 @@ S32 LLDrawPoolAvatar::getNumPasses() S32 LLDrawPoolAvatar::getNumDeferredPasses() { + LL_PROFILE_ZONE_SCOPED + if (LLPipeline::sImpostorRender) { return 19; @@ -780,6 +810,8 @@ void LLDrawPoolAvatar::endRenderPass(S32 pass) void LLDrawPoolAvatar::beginImpostor() { + LL_PROFILE_ZONE_SCOPED + if (!LLPipeline::sReflectionRender) { LLVOAvatar::sRenderDistance = llclamp(LLVOAvatar::sRenderDistance, 16.f, 256.f); @@ -798,6 +830,8 @@ void LLDrawPoolAvatar::beginImpostor() void LLDrawPoolAvatar::endImpostor() { + LL_PROFILE_ZONE_SCOPED + if (LLGLSLShader::sNoFixedFunction) { gImpostorProgram.unbind(); @@ -807,6 +841,8 @@ void LLDrawPoolAvatar::endImpostor() void LLDrawPoolAvatar::beginRigid() { + LL_PROFILE_ZONE_SCOPED + if (gPipeline.canUseVertexShaders()) { if (LLPipeline::sUnderWaterRender) @@ -840,6 +876,8 @@ void LLDrawPoolAvatar::beginRigid() void LLDrawPoolAvatar::endRigid() { + LL_PROFILE_ZONE_SCOPED + sShaderLevel = mShaderLevel; if (sVertexProgram != NULL) { @@ -849,6 +887,8 @@ void LLDrawPoolAvatar::endRigid() void LLDrawPoolAvatar::beginDeferredImpostor() { + LL_PROFILE_ZONE_SCOPED + if (!LLPipeline::sReflectionRender) { LLVOAvatar::sRenderDistance = llclamp(LLVOAvatar::sRenderDistance, 16.f, 256.f); @@ -865,6 +905,8 @@ void LLDrawPoolAvatar::beginDeferredImpostor() void LLDrawPoolAvatar::endDeferredImpostor() { + LL_PROFILE_ZONE_SCOPED + sShaderLevel = mShaderLevel; sVertexProgram->disableTexture(LLViewerShaderMgr::DEFERRED_NORMAL); sVertexProgram->disableTexture(LLViewerShaderMgr::SPECULAR_MAP); @@ -876,6 +918,8 @@ void LLDrawPoolAvatar::endDeferredImpostor() void LLDrawPoolAvatar::beginDeferredRigid() { + LL_PROFILE_ZONE_SCOPED + sVertexProgram = &gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram; sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); sVertexProgram->bind(); @@ -892,6 +936,8 @@ void LLDrawPoolAvatar::beginDeferredRigid() void LLDrawPoolAvatar::endDeferredRigid() { + LL_PROFILE_ZONE_SCOPED + sShaderLevel = mShaderLevel; sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP); sVertexProgram->unbind(); @@ -901,6 +947,8 @@ void LLDrawPoolAvatar::endDeferredRigid() void LLDrawPoolAvatar::beginSkinned() { + LL_PROFILE_ZONE_SCOPED + if (sShaderLevel > 0) { if (LLPipeline::sUnderWaterRender) @@ -967,6 +1015,8 @@ void LLDrawPoolAvatar::beginSkinned() void LLDrawPoolAvatar::endSkinned() { + LL_PROFILE_ZONE_SCOPED + // if we're in software-blending, remember to set the fence _after_ we draw so we wait till this rendering is done if (sShaderLevel > 0) { @@ -991,6 +1041,8 @@ void LLDrawPoolAvatar::endSkinned() void LLDrawPoolAvatar::beginRiggedSimple() { + LL_PROFILE_ZONE_SCOPED + if (sShaderLevel > 0) { if (LLPipeline::sUnderWaterRender) @@ -1031,6 +1083,8 @@ void LLDrawPoolAvatar::beginRiggedSimple() void LLDrawPoolAvatar::endRiggedSimple() { + LL_PROFILE_ZONE_SCOPED + LLVertexBuffer::unbind(); if (sShaderLevel > 0 || gPipeline.canUseVertexShaders()) { @@ -1041,27 +1095,37 @@ void LLDrawPoolAvatar::endRiggedSimple() void LLDrawPoolAvatar::beginRiggedAlpha() { + LL_PROFILE_ZONE_SCOPED + beginRiggedSimple(); } void LLDrawPoolAvatar::endRiggedAlpha() { + LL_PROFILE_ZONE_SCOPED + endRiggedSimple(); } void LLDrawPoolAvatar::beginRiggedFullbrightAlpha() { + LL_PROFILE_ZONE_SCOPED + beginRiggedFullbright(); } void LLDrawPoolAvatar::endRiggedFullbrightAlpha() { + LL_PROFILE_ZONE_SCOPED + endRiggedFullbright(); } void LLDrawPoolAvatar::beginRiggedGlow() { + LL_PROFILE_ZONE_SCOPED + if (sShaderLevel > 0) { if (LLPipeline::sUnderWaterRender) @@ -1108,11 +1172,15 @@ void LLDrawPoolAvatar::beginRiggedGlow() void LLDrawPoolAvatar::endRiggedGlow() { + LL_PROFILE_ZONE_SCOPED + endRiggedFullbright(); } void LLDrawPoolAvatar::beginRiggedFullbright() { + LL_PROFILE_ZONE_SCOPED + if (sShaderLevel > 0) { if (LLPipeline::sUnderWaterRender) @@ -1170,6 +1238,8 @@ void LLDrawPoolAvatar::beginRiggedFullbright() void LLDrawPoolAvatar::endRiggedFullbright() { + LL_PROFILE_ZONE_SCOPED + LLVertexBuffer::unbind(); if (sShaderLevel > 0 || gPipeline.canUseVertexShaders()) { @@ -1180,6 +1250,8 @@ void LLDrawPoolAvatar::endRiggedFullbright() void LLDrawPoolAvatar::beginRiggedShinySimple() { + LL_PROFILE_ZONE_SCOPED + if (sShaderLevel > 0) { if (LLPipeline::sUnderWaterRender) @@ -1220,6 +1292,8 @@ void LLDrawPoolAvatar::beginRiggedShinySimple() void LLDrawPoolAvatar::endRiggedShinySimple() { + LL_PROFILE_ZONE_SCOPED + LLVertexBuffer::unbind(); if (sShaderLevel > 0 || gPipeline.canUseVertexShaders()) { @@ -1231,6 +1305,8 @@ void LLDrawPoolAvatar::endRiggedShinySimple() void LLDrawPoolAvatar::beginRiggedFullbrightShiny() { + LL_PROFILE_ZONE_SCOPED + if (sShaderLevel > 0) { if (LLPipeline::sUnderWaterRender) @@ -1296,6 +1372,8 @@ void LLDrawPoolAvatar::beginRiggedFullbrightShiny() void LLDrawPoolAvatar::endRiggedFullbrightShiny() { + LL_PROFILE_ZONE_SCOPED + LLVertexBuffer::unbind(); if (sShaderLevel > 0 || gPipeline.canUseVertexShaders()) { @@ -1308,6 +1386,8 @@ void LLDrawPoolAvatar::endRiggedFullbrightShiny() void LLDrawPoolAvatar::beginDeferredRiggedSimple() { + LL_PROFILE_ZONE_SCOPED + sVertexProgram = &gDeferredSkinnedDiffuseProgram; sDiffuseChannel = 0; sVertexProgram->bind(); @@ -1323,6 +1403,8 @@ void LLDrawPoolAvatar::beginDeferredRiggedSimple() void LLDrawPoolAvatar::endDeferredRiggedSimple() { + LL_PROFILE_ZONE_SCOPED + LLVertexBuffer::unbind(); sVertexProgram->unbind(); sVertexProgram = NULL; @@ -1330,6 +1412,8 @@ void LLDrawPoolAvatar::endDeferredRiggedSimple() void LLDrawPoolAvatar::beginDeferredRiggedBump() { + LL_PROFILE_ZONE_SCOPED + sVertexProgram = &gDeferredSkinnedBumpProgram; sVertexProgram->bind(); if (LLPipeline::sRenderingHUDs) @@ -1346,6 +1430,8 @@ void LLDrawPoolAvatar::beginDeferredRiggedBump() void LLDrawPoolAvatar::endDeferredRiggedBump() { + LL_PROFILE_ZONE_SCOPED + LLVertexBuffer::unbind(); sVertexProgram->disableTexture(LLViewerShaderMgr::BUMP_MAP); sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP); @@ -1357,6 +1443,8 @@ void LLDrawPoolAvatar::endDeferredRiggedBump() void LLDrawPoolAvatar::beginDeferredRiggedMaterial(S32 pass) { + LL_PROFILE_ZONE_SCOPED + if (pass == 1 || pass == 5 || pass == 9 || @@ -1387,6 +1475,8 @@ void LLDrawPoolAvatar::beginDeferredRiggedMaterial(S32 pass) void LLDrawPoolAvatar::endDeferredRiggedMaterial(S32 pass) { + LL_PROFILE_ZONE_SCOPED + if (pass == 1 || pass == 5 || pass == 9 || @@ -1407,6 +1497,8 @@ void LLDrawPoolAvatar::endDeferredRiggedMaterial(S32 pass) void LLDrawPoolAvatar::beginDeferredSkinned() { + LL_PROFILE_ZONE_SCOPED + sShaderLevel = mShaderLevel; sVertexProgram = &gDeferredAvatarProgram; sRenderingSkinned = TRUE; @@ -1428,6 +1520,8 @@ void LLDrawPoolAvatar::beginDeferredSkinned() void LLDrawPoolAvatar::endDeferredSkinned() { + LL_PROFILE_ZONE_SCOPED + // if we're in software-blending, remember to set the fence _after_ we draw so we wait till this rendering is done sRenderingSkinned = FALSE; sVertexProgram->unbind(); @@ -1740,6 +1834,8 @@ void LLDrawPoolAvatar::getRiggedGeometry( LLVolume* volume, const LLVolumeFace& vol_face) { + LL_PROFILE_ZONE_SCOPED + face->setGeomIndex(0); face->setIndicesIndex(0); @@ -2040,6 +2136,8 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) { + LL_PROFILE_ZONE_SCOPED + if (!avatar->shouldRenderRigged()) { return; @@ -2332,16 +2430,22 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) void LLDrawPoolAvatar::renderDeferredRiggedSimple(LLVOAvatar* avatar) { + LL_PROFILE_ZONE_SCOPED + renderRigged(avatar, RIGGED_DEFERRED_SIMPLE); } void LLDrawPoolAvatar::renderDeferredRiggedBump(LLVOAvatar* avatar) { + LL_PROFILE_ZONE_SCOPED + renderRigged(avatar, RIGGED_DEFERRED_BUMP); } void LLDrawPoolAvatar::renderDeferredRiggedMaterial(LLVOAvatar* avatar, S32 pass) { + LL_PROFILE_ZONE_SCOPED + renderRigged(avatar, pass); } @@ -2396,27 +2500,37 @@ void LLDrawPoolAvatar::updateRiggedVertexBuffers(LLVOAvatar* avatar) void LLDrawPoolAvatar::renderRiggedSimple(LLVOAvatar* avatar) { + LL_PROFILE_ZONE_SCOPED + renderRigged(avatar, RIGGED_SIMPLE); } void LLDrawPoolAvatar::renderRiggedFullbright(LLVOAvatar* avatar) { + LL_PROFILE_ZONE_SCOPED + renderRigged(avatar, RIGGED_FULLBRIGHT); } void LLDrawPoolAvatar::renderRiggedShinySimple(LLVOAvatar* avatar) { + LL_PROFILE_ZONE_SCOPED + renderRigged(avatar, RIGGED_SHINY); } void LLDrawPoolAvatar::renderRiggedFullbrightShiny(LLVOAvatar* avatar) { + LL_PROFILE_ZONE_SCOPED + renderRigged(avatar, RIGGED_FULLBRIGHT_SHINY); } void LLDrawPoolAvatar::renderRiggedAlpha(LLVOAvatar* avatar) { + LL_PROFILE_ZONE_SCOPED + if (!mRiggedFace[RIGGED_ALPHA].empty()) { LLGLEnable blend(GL_BLEND); @@ -2434,6 +2548,8 @@ void LLDrawPoolAvatar::renderRiggedAlpha(LLVOAvatar* avatar) void LLDrawPoolAvatar::renderRiggedFullbrightAlpha(LLVOAvatar* avatar) { + LL_PROFILE_ZONE_SCOPED + if (!mRiggedFace[RIGGED_FULLBRIGHT_ALPHA].empty()) { LLGLEnable blend(GL_BLEND); @@ -2451,6 +2567,8 @@ void LLDrawPoolAvatar::renderRiggedFullbrightAlpha(LLVOAvatar* avatar) void LLDrawPoolAvatar::renderRiggedGlow(LLVOAvatar* avatar) { + LL_PROFILE_ZONE_SCOPED + if (!mRiggedFace[RIGGED_GLOW].empty()) { LLGLEnable blend(GL_BLEND); @@ -2478,6 +2596,8 @@ void LLDrawPoolAvatar::renderRiggedGlow(LLVOAvatar* avatar) //----------------------------------------------------------------------------- LLViewerTexture *LLDrawPoolAvatar::getDebugTexture() { + LL_PROFILE_ZONE_SCOPED + if (mReferences.empty()) { return NULL; @@ -2501,6 +2621,8 @@ LLColor3 LLDrawPoolAvatar::getDebugColor() const void LLDrawPoolAvatar::addRiggedFace(LLFace* facep, U32 type) { + LL_PROFILE_ZONE_SCOPED + llassert (facep->isState(LLFace::RIGGED)); llassert(getType() == LLDrawPool::POOL_AVATAR || getType() == LLDrawPool::POOL_CONTROL_AV); if (facep->getPool() && facep->getPool() != this) @@ -2523,6 +2645,8 @@ void LLDrawPoolAvatar::addRiggedFace(LLFace* facep, U32 type) void LLDrawPoolAvatar::removeRiggedFace(LLFace* facep) { + LL_PROFILE_ZONE_SCOPED + llassert (facep->isState(LLFace::RIGGED)); llassert(getType() == LLDrawPool::POOL_AVATAR || getType() == LLDrawPool::POOL_CONTROL_AV); if (facep->getPool() != this) @@ -2560,7 +2684,7 @@ LLVertexBufferAvatar::LLVertexBufferAvatar() : LLVertexBuffer(sDataMask, GL_STREAM_DRAW_ARB) //avatars are always stream draw due to morph targets { - + LL_PROFILE_ZONE_SCOPED } -- cgit v1.2.3 From b63cb4b0ae1b76c2623ae918866360645f30ee06 Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Wed, 15 Sep 2021 17:44:09 -0700 Subject: SL-16014: Add Tracy logging to doFrame() --- indra/newview/llappviewer.cpp | 74 ++++++++++++++++++++++++++++++++----------- 1 file changed, 56 insertions(+), 18 deletions(-) diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 94f0b31ecd..ab2b846c09 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1424,9 +1424,13 @@ bool LLAppViewer::doFrame() LLSD newFrame; LL_RECORD_BLOCK_TIME(FTM_FRAME); - LLTrace::BlockTimer::processTimes(); - LLTrace::get_frame_recording().nextPeriod(); - LLTrace::BlockTimer::logStats(); + + { + LL_PROFILE_ZONE_NAMED( ":blocktimer" ) + LLTrace::BlockTimer::processTimes(); + LLTrace::get_frame_recording().nextPeriod(); + LLTrace::BlockTimer::logStats(); + } LLTrace::get_thread_recorder()->pullFromChildren(); @@ -1434,6 +1438,7 @@ bool LLAppViewer::doFrame() LL_CLEAR_CALLSTACKS(); { + LL_PROFILE_ZONE_NAMED( ":processMiscNativeEvents" ) pingMainloopTimeout("Main:MiscNativeWindowEvents"); if (gViewerWindow) @@ -1442,7 +1447,10 @@ bool LLAppViewer::doFrame() gViewerWindow->getWindow()->processMiscNativeEvents(); } - pingMainloopTimeout("Main:GatherInput"); + { + LL_PROFILE_ZONE_NAMED( ":gatherInput" ) + pingMainloopTimeout("Main:GatherInput"); + } if (gViewerWindow) { @@ -1466,13 +1474,21 @@ bool LLAppViewer::doFrame() } } - // canonical per-frame event - mainloop.post(newFrame); - // give listeners a chance to run - llcoro::suspend(); + { + LL_PROFILE_ZONE_NAMED( ":mainloop" ) + // canonical per-frame event + mainloop.post(newFrame); + } + + { + LL_PROFILE_ZONE_NAMED( ":suspend" ) + // give listeners a chance to run + llcoro::suspend(); + } if (!LLApp::isExiting()) { + LL_PROFILE_ZONE_NAMED( ":JoystickKeyboard" ) pingMainloopTimeout("Main:JoystickKeyboard"); // Scan keyboard for movement keys. Command keys and typing @@ -1493,12 +1509,18 @@ bool LLAppViewer::doFrame() // Update state based on messages, user input, object idle. { - pauseMainloopTimeout(); // *TODO: Remove. Messages shouldn't be stalling for 20+ seconds! + { + LL_PROFILE_ZONE_NAMED( ":pauseMainloopTimeout" ) + pauseMainloopTimeout(); // *TODO: Remove. Messages shouldn't be stalling for 20+ seconds! + } LL_RECORD_BLOCK_TIME(FTM_IDLE); idle(); - resumeMainloopTimeout(); + { + LL_PROFILE_ZONE_NAMED( ":resumeMainloopTimeout" ) + resumeMainloopTimeout(); + } } if (gDoDisconnect && (LLStartUp::getStartupState() == STATE_STARTED)) @@ -1513,6 +1535,7 @@ bool LLAppViewer::doFrame() // *TODO: Should we run display() even during gHeadlessClient? DK 2011-02-18 if (!LLApp::isExiting() && !gHeadlessClient && gViewerWindow) { + LL_PROFILE_ZONE_NAMED( ":Display" ) pingMainloopTimeout("Main:Display"); gGLActive = TRUE; @@ -1533,16 +1556,22 @@ bool LLAppViewer::doFrame() } last_call = LLTimer::getTotalTime(); - pingMainloopTimeout("Main:Snapshot"); - LLFloaterSnapshot::update(); // take snapshots + { + LL_PROFILE_ZONE_NAMED( ":Snapshot" ) + pingMainloopTimeout("Main:Snapshot"); + LLFloaterSnapshot::update(); // take snapshots LLFloaterOutfitSnapshot::update(); - gGLActive = FALSE; + gGLActive = FALSE; + } } } - pingMainloopTimeout("Main:Sleep"); + { + LL_PROFILE_ZONE_NAMED( ":pauseMainloopTimeout" ) + pingMainloopTimeout("Main:Sleep"); - pauseMainloopTimeout(); + pauseMainloopTimeout(); + } // Sleep and run background threads { @@ -1615,16 +1644,22 @@ bool LLAppViewer::doFrame() total_io_pending += io_pending ; } - gMeshRepo.update() ; + + { + LL_PROFILE_ZONE_NAMED( ":gMeshRepo" ) + gMeshRepo.update() ; + } if(!total_work_pending) //pause texture fetching threads if nothing to process. { + LL_PROFILE_ZONE_NAMED( ":getTextureCache" ) LLAppViewer::getTextureCache()->pause(); LLAppViewer::getImageDecodeThread()->pause(); LLAppViewer::getTextureFetch()->pause(); } if(!total_io_pending) //pause file threads if nothing to process. { + LL_PROFILE_ZONE_NAMED( ":LLVFSThread" ) LLVFSThread::sLocal->pause(); LLLFSThread::sLocal->pause(); } @@ -1632,6 +1667,7 @@ bool LLAppViewer::doFrame() //texture fetching debugger if(LLTextureFetchDebugger::isEnabled()) { + LL_PROFILE_ZONE_NAMED( ":tex_fetch_debugger_instance" ) LLFloaterTextureFetchDebugger* tex_fetch_debugger_instance = LLFloaterReg::findTypedInstance("tex_fetch_debugger"); if(tex_fetch_debugger_instance) @@ -1640,8 +1676,10 @@ bool LLAppViewer::doFrame() } } - resumeMainloopTimeout(); - + { + LL_PROFILE_ZONE_NAMED( ":resumeMainloopTimeout" ) + resumeMainloopTimeout(); + } pingMainloopTimeout("Main:End"); } } -- cgit v1.2.3 From 6b7643c4f73b711075c31e98e27a1dedc540fbb2 Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Mon, 20 Sep 2021 08:33:41 -0700 Subject: SL-16014: Add macros for better markup in Tracy --- indra/llcommon/llprofiler.h | 50 +++++++++++++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/indra/llcommon/llprofiler.h b/indra/llcommon/llprofiler.h index 62e649913b..969328f338 100644 --- a/indra/llcommon/llprofiler.h +++ b/indra/llcommon/llprofiler.h @@ -48,25 +48,49 @@ #endif #if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY - #define LL_PROFILER_FRAME_END FrameMark - #define LL_PROFILER_SET_THREAD_NAME( name ) tracy::SetThreadName( name ) - #define LL_RECORD_BLOCK_TIME(name) ZoneNamedN( ___tracy_scoped_zone, #name, true ); - #define LL_PROFILE_ZONE_NAMED(name) ZoneNamedN( ___tracy_scoped_zone, name, true ); - #define LL_PROFILE_ZONE_SCOPED ZoneScoped + #define LL_PROFILER_FRAME_END FrameMark + #define LL_PROFILER_SET_THREAD_NAME( name ) tracy::SetThreadName( name ) + #define LL_RECORD_BLOCK_TIME(name) ZoneScoped // Want descriptive names; was: ZoneNamedN( ___tracy_scoped_zone, #name, true ); + #define LL_PROFILE_ZONE_NAMED(name) ZoneNamedN( ___tracy_scoped_zone, name, true ); + #define LL_PROFILE_ZONE_NAMED_COLOR(name,color) ZoneNamedNC( ___tracy_scopped_zone, name, color, true ) // RGB + #define LL_PROFILE_ZONE_SCOPED ZoneScoped + + #define LL_PROFILE_ZONE_NUM( val ) ZoneValue( val ) + #define LL_PROFILE_ZONE_TEXT( text, size ) ZoneText( text, size ) + + #define LL_PROFILE_ZONE_ERR(name) LL_PROFILE_ZONE_NAMED_COLOR( name, 0XFF0000 ) // RGB yellow + #define LL_PROFILE_ZONE_INFO(name) LL_PROFILE_ZONE_NAMED_COLOR( name, 0X00FFFF ) // RGB cyan + #define LL_PROFILE_ZONE_WARN(name) LL_PROFILE_ZONE_NAMED_COLOR( name, 0x0FFFF00 ) // RGB red #endif #if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_FAST_TIMER #define LL_PROFILER_FRAME_END - #define LL_PROFILER_SET_THREAD_NAME( name ) (void)(name) + #define LL_PROFILER_SET_THREAD_NAME( name ) (void)(name) #define LL_RECORD_BLOCK_TIME(name) const LLTrace::BlockTimer& LL_GLUE_TOKENS(block_time_recorder, __LINE__)(LLTrace::timeThisBlock(name)); (void)LL_GLUE_TOKENS(block_time_recorder, __LINE__); - #define LL_PROFILE_ZONE_NAMED(name) // LL_PROFILE_ZONE_NAMED is a no-op when Tracy is disabled - #define LL_PROFILE_ZONE_SCOPED // LL_PROFILE_ZONE_SCOPED is a no-op when Tracy is disabled + #define LL_PROFILE_ZONE_NAMED(name) // LL_PROFILE_ZONE_NAMED is a no-op when Tracy is disabled + #define LL_PROFILE_ZONE_SCOPED // LL_PROFILE_ZONE_SCOPED is a no-op when Tracy is disabled + #define LL_PRPFILE_ZONE_COLOR(name,color) // LL_RECORD_BLOCK_TIME(name) + + #define LL_PROFILE_ZONE_NUM( val ) (void)( val ); // Not supported + #define LL_PROFILE_ZONE_TEXT( text, size ) (void)( text ); void( size ); // Not supported + + #define LL_PROFILE_ZONE_ERR(name) (void)(name); // Not supported + #define LL_PROFILE_ZONE_INFO(name) (void)(name); // Not supported + #define LL_PROFILE_ZONE_WARN(name) (void)(name); // Not supported #endif #if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY_FAST_TIMER - #define LL_PROFILER_FRAME_END FrameMark - #define LL_PROFILER_SET_THREAD_NAME( name ) tracy::SetThreadName( name ) - #define LL_RECORD_BLOCK_TIME(name) ZoneNamedN( ___tracy_scoped_zone, #timer_stat, true ) const LLTrace::BlockTimer& LL_GLUE_TOKENS(block_time_recorder, __LINE__)(LLTrace::timeThisBlock(name)); (void)LL_GLUE_TOKENS(block_time_recorder, __LINE__); - #define LL_PROFILE_ZONE_NAMED(name) ZoneNamedN( ___tracy_scoped_zone, #name, true ); - #define LL_PROFILE_ZONE_SCOPED ZoneScoped + #define LL_PROFILER_FRAME_END FrameMark + #define LL_PROFILER_SET_THREAD_NAME( name ) tracy::SetThreadName( name ) + #define LL_RECORD_BLOCK_TIME(name) ZoneScoped const LLTrace::BlockTimer& LL_GLUE_TOKENS(block_time_recorder, __LINE__)(LLTrace::timeThisBlock(name)); (void)LL_GLUE_TOKENS(block_time_recorder, __LINE__); + #define LL_PROFILE_ZONE_NAMED(name) ZoneNamedN( ___tracy_scoped_zone, #name, true ); + #define LL_PROFILE_ZONE_NAMED_COLOR(name,color) ZoneNamedNC( ___tracy_scopped_zone, name, color, true ) // RGB + #define LL_PROFILE_ZONE_SCOPED ZoneScoped + + #define LL_PROFILE_ZONE_NUM( val ) ZoneValue( val ) + #define LL_PROFILE_ZONE_TEXT( text, size ) ZoneText( text, size ) + + #define LL_PROFILE_ZONE_ERR(name) LL_PROFILE_ZONE_NAMED_COLOR( name, 0XFF0000 ) // RGB yellow + #define LL_PROFILE_ZONE_INFO(name) LL_PROFILE_ZONE_NAMED_COLOR( name, 0X00FFFF ) // RGB cyan + #define LL_PROFILE_ZONE_WARN(name) LL_PROFILE_ZONE_NAMED_COLOR( name, 0x0FFFF00 ) // RGB red #endif #else #define LL_PROFILER_FRAME_END -- cgit v1.2.3 From b680bfcbe41acf5531b04b21e4994d7e936cf5b3 Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Mon, 20 Sep 2021 09:43:38 -0700 Subject: SL-16014: Add Tracy markup for lldrawable --- indra/newview/lldrawable.cpp | 45 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 507af56cb0..30c4a21e1c 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -101,6 +101,8 @@ LLDrawable::LLDrawable(LLViewerObject *vobj, bool new_entry) void LLDrawable::init(bool new_entry) { + LL_PROFILE_ZONE_SCOPED + // mXform mParent = NULL; mRenderType = 0; @@ -232,6 +234,8 @@ void LLDrawable::markDead() LLVOVolume* LLDrawable::getVOVolume() const { + LL_PROFILE_ZONE_SCOPED + LLViewerObject* objectp = mVObjp; if ( !isDead() && objectp && (objectp->getPCode() == LL_PCODE_VOLUME)) { @@ -335,6 +339,7 @@ static LLTrace::BlockTimerStatHandle FTM_ALLOCATE_FACE("Allocate Face"); LLFace* LLDrawable::addFace(LLFacePool *poolp, LLViewerTexture *texturep) { + LL_PROFILE_ZONE_SCOPED LLFace *face; { @@ -363,6 +368,8 @@ LLFace* LLDrawable::addFace(LLFacePool *poolp, LLViewerTexture *texturep) LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep) { + LL_PROFILE_ZONE_SCOPED + LLFace *face; { @@ -387,6 +394,8 @@ LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep) LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep, LLViewerTexture *normalp) { + LL_PROFILE_ZONE_SCOPED + LLFace *face; face = new LLFace(this, mVObjp); @@ -408,6 +417,8 @@ LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep, LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep, LLViewerTexture *normalp, LLViewerTexture *specularp) { + LL_PROFILE_ZONE_SCOPED + LLFace *face; face = new LLFace(this, mVObjp); @@ -430,6 +441,8 @@ LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep, void LLDrawable::setNumFaces(const S32 newFaces, LLFacePool *poolp, LLViewerTexture *texturep) { + LL_PROFILE_ZONE_SCOPED + if (newFaces == (S32)mFaces.size()) { return; @@ -453,6 +466,8 @@ void LLDrawable::setNumFaces(const S32 newFaces, LLFacePool *poolp, LLViewerText void LLDrawable::setNumFacesFast(const S32 newFaces, LLFacePool *poolp, LLViewerTexture *texturep) { + LL_PROFILE_ZONE_SCOPED + if (newFaces <= (S32)mFaces.size() && newFaces >= (S32)mFaces.size()/2) { return; @@ -476,6 +491,8 @@ void LLDrawable::setNumFacesFast(const S32 newFaces, LLFacePool *poolp, LLViewer void LLDrawable::mergeFaces(LLDrawable* src) { + LL_PROFILE_ZONE_SCOPED + U32 face_count = mFaces.size() + src->mFaces.size(); mFaces.reserve(face_count); @@ -509,6 +526,8 @@ void LLDrawable::updateMaterial() void LLDrawable::makeActive() { + LL_PROFILE_ZONE_SCOPED + #if !LL_RELEASE_FOR_DOWNLOAD if (mVObjp.notNull()) { @@ -572,6 +591,8 @@ void LLDrawable::makeActive() void LLDrawable::makeStatic(BOOL warning_enabled) { + LL_PROFILE_ZONE_SCOPED + if (isState(ACTIVE) && !isState(ACTIVE_CHILD) && !mVObjp->isAttachment() && @@ -618,6 +639,8 @@ void LLDrawable::makeStatic(BOOL warning_enabled) // Returns "distance" between target destination and resulting xfrom F32 LLDrawable::updateXform(BOOL undamped) { + LL_PROFILE_ZONE_SCOPED + BOOL damped = !undamped; // Position @@ -769,6 +792,8 @@ void LLDrawable::moveUpdatePipeline(BOOL moved) void LLDrawable::movePartition() { + LL_PROFILE_ZONE_SCOPED + LLSpatialPartition* part = getSpatialPartition(); if (part) { @@ -813,6 +838,8 @@ BOOL LLDrawable::updateMoveUndamped() void LLDrawable::updatePartition() { + LL_PROFILE_ZONE_SCOPED + if (!getVOVolume()) { movePartition(); @@ -830,6 +857,8 @@ void LLDrawable::updatePartition() BOOL LLDrawable::updateMoveDamped() { + LL_PROFILE_ZONE_SCOPED + F32 dist_squared = updateXform(FALSE); mGeneration++; @@ -853,6 +882,8 @@ BOOL LLDrawable::updateMoveDamped() void LLDrawable::updateDistance(LLCamera& camera, bool force_update) { + LL_PROFILE_ZONE_SCOPED + if (LLViewerCamera::sCurCameraID != LLViewerCamera::CAMERA_WORLD) { LL_WARNS() << "Attempted to update distance for non-world camera." << LL_ENDL; @@ -957,6 +988,8 @@ void LLDrawable::updateTexture() BOOL LLDrawable::updateGeometry(BOOL priority) { + LL_PROFILE_ZONE_SCOPED + llassert(mVObjp.notNull()); BOOL res = mVObjp->updateGeometry(this); return res; @@ -1034,6 +1067,8 @@ const LLVector3& LLDrawable::getBounds(LLVector3& min, LLVector3& max) const void LLDrawable::updateSpatialExtents() { + LL_PROFILE_ZONE_SCOPED + if (mVObjp) { const LLVector4a* exts = getSpatialExtents(); @@ -1164,6 +1199,8 @@ void LLDrawable::setGroup(LLViewerOctreeGroup *groupp) LLSpatialPartition* LLDrawable::getSpatialPartition() { + LL_PROFILE_ZONE_SCOPED + LLSpatialPartition* retval = NULL; if (!mVObjp || @@ -1247,6 +1284,8 @@ LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 dat LLDrawable(root->getVObj(), true), LLSpatialPartition(data_mask, render_by_group, GL_STREAM_DRAW_ARB, regionp) { + LL_PROFILE_ZONE_SCOPED + mBridge = this; mDrawable = root; root->setSpatialBridge(this); @@ -1292,6 +1331,8 @@ void LLSpatialBridge::destroyTree() void LLSpatialBridge::updateSpatialExtents() { + LL_PROFILE_ZONE_SCOPED + LLSpatialGroup* root = (LLSpatialGroup*) mOctree->getListener(0); { @@ -1455,6 +1496,8 @@ public: void LLSpatialBridge::setVisible(LLCamera& camera_in, std::vector* results, BOOL for_select) { + LL_PROFILE_ZONE_SCOPED + if (!gPipeline.hasRenderType(mDrawableType)) { return; @@ -1552,6 +1595,8 @@ void LLSpatialBridge::setVisible(LLCamera& camera_in, std::vector* void LLSpatialBridge::updateDistance(LLCamera& camera_in, bool force_update) { + LL_PROFILE_ZONE_SCOPED + if (mDrawable == NULL) { markDead(); -- cgit v1.2.3 From d324873f92fb5b8fe070548d3c12129fd9112893 Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Mon, 20 Sep 2021 09:44:34 -0700 Subject: SL-16014: Add Tracy markup to LLFace --- indra/newview/llface.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 4a802ad9aa..e9e011e01c 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -241,6 +241,8 @@ void LLFace::setPool(LLFacePool* pool) void LLFace::setPool(LLFacePool* new_pool, LLViewerTexture *texturep) { + LL_PROFILE_ZONE_SCOPED + if (!new_pool) { LL_ERRS() << "Setting pool to null!" << LL_ENDL; @@ -320,6 +322,8 @@ void LLFace::setSpecularMap(LLViewerTexture* tex) void LLFace::dirtyTexture() { + LL_PROFILE_ZONE_SCOPED + LLDrawable* drawablep = getDrawable(); if (mVObjp.notNull() && mVObjp->getVolume()) @@ -535,6 +539,8 @@ void LLFace::updateCenterAgent() void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color) { + LL_PROFILE_ZONE_SCOPED + if (mDrawablep == NULL || mDrawablep->getSpatialGroup() == NULL) { return; @@ -605,6 +611,8 @@ void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color) void renderFace(LLDrawable* drawable, LLFace *face) { + LL_PROFILE_ZONE_SCOPED + LLVOVolume* vobj = drawable->getVOVolume(); if (vobj) { @@ -891,6 +899,8 @@ bool less_than_max_mag(const LLVector4a& vec) BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f, const LLMatrix4& mat_vert_in, BOOL global_volume) { + LL_PROFILE_ZONE_SCOPED + //get bounding box if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION | LLDrawable::REBUILD_RIGGED)) { @@ -2375,6 +2385,8 @@ F32 LLFace::getTextureVirtualSize() BOOL LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius) { + LL_PROFILE_ZONE_SCOPED + //VECTORIZE THIS //get area of circle around face LLVector4a center; @@ -2654,6 +2666,8 @@ const LLMatrix4& LLFace::getRenderMatrix() const S32 LLFace::renderElements(const U16 *index_array) const { + LL_PROFILE_ZONE_SCOPED + S32 ret = 0; if (isState(GLOBAL)) @@ -2673,6 +2687,8 @@ S32 LLFace::renderElements(const U16 *index_array) const S32 LLFace::renderIndexed() { + LL_PROFILE_ZONE_SCOPED + if(mDrawablep == NULL || mDrawPoolp == NULL) { return 0; @@ -2683,6 +2699,8 @@ S32 LLFace::renderIndexed() S32 LLFace::renderIndexed(U32 mask) { + LL_PROFILE_ZONE_SCOPED + if (mVertexBuffer.isNull()) { return 0; -- cgit v1.2.3 From 710cf221484a3e28182b3353213b3569e883219f Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Mon, 20 Sep 2021 09:45:17 -0700 Subject: SL-16014: Add Tracy markup to LLSpatialGroup --- indra/newview/llspatialpartition.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index efa4a7fd66..f99b36ae19 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -503,7 +503,9 @@ LLSpatialGroup* LLSpatialGroup::getParent() } BOOL LLSpatialGroup::removeObject(LLDrawable *drawablep, BOOL from_octree) - { +{ + LL_PROFILE_ZONE_SCOPED + if(!drawablep) { return FALSE; @@ -591,6 +593,8 @@ public: void LLSpatialGroup::setState(U32 state, S32 mode) { + LL_PROFILE_ZONE_SCOPED + llassert(state <= LLSpatialGroup::STATE_MASK); if (mode > STATE_MODE_SINGLE) @@ -638,6 +642,8 @@ public: void LLSpatialGroup::clearState(U32 state, S32 mode) { + LL_PROFILE_ZONE_SCOPED + llassert(state <= LLSpatialGroup::STATE_MASK); if (mode > STATE_MODE_SINGLE) @@ -724,6 +730,8 @@ void LLSpatialGroup::updateDistance(LLCamera &camera) F32 LLSpatialPartition::calcDistance(LLSpatialGroup* group, LLCamera& camera) { + LL_PROFILE_ZONE_SCOPED + LLVector4a eye; LLVector4a origin; origin.load3(camera.getOrigin().mV); @@ -815,6 +823,8 @@ F32 LLSpatialGroup::getUpdateUrgency() const BOOL LLSpatialGroup::changeLOD() { + LL_PROFILE_ZONE_SCOPED + if (hasState(ALPHA_DIRTY | OBJECT_DIRTY)) { //a rebuild is going to happen, update distance and LoD @@ -907,6 +917,8 @@ void LLSpatialGroup::handleDestruction(const TreeNode* node) void LLSpatialGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* child) { + LL_PROFILE_ZONE_SCOPED + if (child->getListenerCount() == 0) { new LLSpatialGroup(child, getSpatialPartition()); -- cgit v1.2.3 From a1b9a5986121fec115d11cf8be65ff1e23ad03e7 Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Mon, 20 Sep 2021 09:45:52 -0700 Subject: SL-16014: Add Tracy markup to LLViewerObjectList --- indra/newview/llviewerobjectlist.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 63e48d1dd0..0b20556104 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -168,6 +168,8 @@ U64 LLViewerObjectList::getIndex(const U32 local_id, BOOL LLViewerObjectList::removeFromLocalIDTable(const LLViewerObject* objectp) { + LL_PROFILE_ZONE_SCOPED + if(objectp && objectp->getRegion()) { U32 local_id = objectp->mLocalID; @@ -303,6 +305,8 @@ static LLTrace::BlockTimerStatHandle FTM_PROCESS_OBJECTS("Process Objects"); LLViewerObject* LLViewerObjectList::processObjectUpdateFromCache(LLVOCacheEntry* entry, LLViewerRegion* regionp) { + LL_PROFILE_ZONE_SCOPED + LLDataPacker *cached_dpp = entry->getDP(); if (!cached_dpp) @@ -848,6 +852,8 @@ static LLTrace::BlockTimerStatHandle FTM_IDLE_COPY("Idle Copy"); void LLViewerObjectList::update(LLAgent &agent) { + LL_PROFILE_ZONE_SCOPED + // Update globals LLViewerObject::setVelocityInterpolate( gSavedSettings.getBOOL("VelocityInterpolate") ); LLViewerObject::setPingInterpolate( gSavedSettings.getBOOL("PingInterpolate") ); @@ -1293,6 +1299,8 @@ void LLViewerObjectList::clearDebugText() void LLViewerObjectList::cleanupReferences(LLViewerObject *objectp) { + LL_PROFILE_ZONE_SCOPED + bool new_dead_object = true; if (mDeadObjects.find(objectp->mID) != mDeadObjects.end()) { @@ -1523,6 +1531,8 @@ void LLViewerObjectList::removeFromActiveList(LLViewerObject* objectp) void LLViewerObjectList::updateActive(LLViewerObject *objectp) { + LL_PROFILE_ZONE_SCOPED + if (objectp->isDead()) { return; // We don't update dead objects! @@ -1843,6 +1853,8 @@ void LLViewerObjectList::renderObjectBounds(const LLVector3 ¢er) void LLViewerObjectList::generatePickList(LLCamera &camera) { + LL_PROFILE_ZONE_SCOPED + LLViewerObject *objectp; S32 i; // Reset all of the GL names to zero. @@ -2104,6 +2116,8 @@ LLViewerObject *LLViewerObjectList::replaceObject(const LLUUID &id, const LLPCod S32 LLViewerObjectList::findReferences(LLDrawable *drawablep) const { + LL_PROFILE_ZONE_SCOPED + LLViewerObject *objectp; S32 num_refs = 0; @@ -2167,6 +2181,8 @@ void LLViewerObjectList::orphanize(LLViewerObject *childp, U32 parent_id, U32 ip void LLViewerObjectList::findOrphans(LLViewerObject* objectp, U32 ip, U32 port) { + LL_PROFILE_ZONE_SCOPED + if (objectp->isDead()) { LL_WARNS() << "Trying to find orphans for dead obj " << objectp->mID -- cgit v1.2.3 From 51062b60382049e3ade7c53caabcc08927b64fbb Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Mon, 20 Sep 2021 09:46:43 -0700 Subject: SL-16014: Add Tracy markup for LLSD --- indra/llcommon/llsdutil.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/indra/llcommon/llsdutil.cpp b/indra/llcommon/llsdutil.cpp index eb3a96b133..c2fe15e9b7 100644 --- a/indra/llcommon/llsdutil.cpp +++ b/indra/llcommon/llsdutil.cpp @@ -214,6 +214,8 @@ BOOL compare_llsd_with_template( const LLSD& template_llsd, LLSD& resultant_llsd) { + LL_PROFILE_ZONE_SCOPED + if ( llsd_to_test.isUndefined() && template_llsd.isDefined() ) @@ -335,6 +337,8 @@ bool filter_llsd_with_template( const LLSD & template_llsd, LLSD & resultant_llsd) { + LL_PROFILE_ZONE_SCOPED + if (llsd_to_test.isUndefined() && template_llsd.isDefined()) { resultant_llsd = template_llsd; @@ -529,6 +533,8 @@ class TypeLookup public: TypeLookup() { + LL_PROFILE_ZONE_SCOPED + for (const Data *di(boost::begin(typedata)), *dend(boost::end(typedata)); di != dend; ++di) { mMap[di->type] = di->name; @@ -537,6 +543,8 @@ public: std::string lookup(LLSD::Type type) const { + LL_PROFILE_ZONE_SCOPED + MapType::const_iterator found = mMap.find(type); if (found != mMap.end()) { @@ -587,6 +595,8 @@ static std::string match_types(LLSD::Type expect, // prototype.type() LLSD::Type actual, // type we're checking const std::string& pfx) // as for llsd_matches { + LL_PROFILE_ZONE_SCOPED + // Trivial case: if the actual type is exactly what we expect, we're good. if (actual == expect) return ""; @@ -624,6 +634,8 @@ static std::string match_types(LLSD::Type expect, // prototype.type() // see docstring in .h file std::string llsd_matches(const LLSD& prototype, const LLSD& data, const std::string& pfx) { + LL_PROFILE_ZONE_SCOPED + // An undefined prototype means that any data is valid. // An undefined slot in an array or map prototype means that any data // may fill that slot. @@ -756,6 +768,8 @@ std::string llsd_matches(const LLSD& prototype, const LLSD& data, const std::str bool llsd_equals(const LLSD& lhs, const LLSD& rhs, int bits) { + LL_PROFILE_ZONE_SCOPED + // We're comparing strict equality of LLSD representation rather than // performing any conversions. So if the types aren't equal, the LLSD // values aren't equal. @@ -864,6 +878,8 @@ namespace llsd LLSD& drill(LLSD& blob, const LLSD& rawPath) { + LL_PROFILE_ZONE_SCOPED + // Treat rawPath uniformly as an array. If it's not already an array, // store it as the only entry in one. (But let's say Undefined means an // empty array.) @@ -889,6 +905,8 @@ LLSD& drill(LLSD& blob, const LLSD& rawPath) // path entry that's bad. for (LLSD::Integer i = 0; i < path.size(); ++i) { + LL_PROFILE_ZONE_NUM( i ) + const LLSD& key{path[i]}; if (key.isString()) { @@ -917,6 +935,8 @@ LLSD& drill(LLSD& blob, const LLSD& rawPath) LLSD drill(const LLSD& blob, const LLSD& path) { + LL_PROFILE_ZONE_SCOPED + // non-const drill() does exactly what we want. Temporarily cast away // const-ness and use that. return drill(const_cast(blob), path); @@ -929,6 +949,8 @@ LLSD drill(const LLSD& blob, const LLSD& path) // filter may be include to exclude/include keys in a map. LLSD llsd_clone(LLSD value, LLSD filter) { + LL_PROFILE_ZONE_SCOPED + LLSD clone; bool has_filter(filter.isMap()); -- cgit v1.2.3 From ed456eca5f0464c3e8036283864676f87ed16c22 Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Mon, 20 Sep 2021 09:47:26 -0700 Subject: SL-16014: Add Tracy markup for LLVolumeFace --- indra/llmath/llvolume.cpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index e085fa6ada..130f30bedc 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -383,6 +383,7 @@ public: virtual void visit(const LLOctreeNode* branch) { //this is a depth first traversal, so it's safe to assum all children have complete //bounding data + LL_PROFILE_ZONE_SCOPED LLVolumeOctreeListener* node = (LLVolumeOctreeListener*) branch->getListener(0); @@ -822,6 +823,8 @@ S32 LLProfile::getNumPoints(const LLProfileParams& params, BOOL path_open,F32 de BOOL LLProfile::generate(const LLProfileParams& params, BOOL path_open,F32 detail, S32 split, BOOL is_sculpted, S32 sculpt_size) { + LL_PROFILE_ZONE_SCOPED + if ((!mDirty) && (!is_sculpted)) { return FALSE; @@ -1302,6 +1305,8 @@ S32 LLPath::getNumNGonPoints(const LLPathParams& params, S32 sides, F32 startOff void LLPath::genNGon(const LLPathParams& params, S32 sides, F32 startOff, F32 end_scale, F32 twist_scale) { + LL_PROFILE_ZONE_SCOPED + // Generates a circular path, starting at (1, 0, 0), counterclockwise along the xz plane. static const F32 tableScale[] = { 1, 1, 1, 0.5f, 0.707107f, 0.53f, 0.525f, 0.5f }; @@ -1536,6 +1541,8 @@ S32 LLPath::getNumPoints(const LLPathParams& params, F32 detail) BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split, BOOL is_sculpted, S32 sculpt_size) { + LL_PROFILE_ZONE_SCOPED + if ((!mDirty) && (!is_sculpted)) { return FALSE; @@ -2112,6 +2119,8 @@ LLVolume::~LLVolume() BOOL LLVolume::generate() { + LL_PROFILE_ZONE_SCOPED + LL_CHECK_MEMORY llassert_always(mProfilep); @@ -2370,6 +2379,8 @@ bool LLVolumeFace::VertexData::compareNormal(const LLVolumeFace::VertexData& rhs bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) { + LL_PROFILE_ZONE_SCOPED + //input stream is now pointing at a zlib compressed block of LLSD //decompress block LLSD mdl; @@ -2755,6 +2766,8 @@ S32 LLVolume::getNumFaces() const void LLVolume::createVolumeFaces() { + LL_PROFILE_ZONE_SCOPED + if (mGenerateSingleFace) { // do nothing @@ -3720,6 +3733,8 @@ void LLVolume::generateSilhouetteVertices(std::vector &vertices, const LLMatrix3& norm_mat_in, S32 face_mask) { + LL_PROFILE_ZONE_SCOPED + LLMatrix4a mat; mat.loadu(mat_in); @@ -4846,6 +4861,8 @@ void LLVolumeFace::freeData() BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build) { + LL_PROFILE_ZONE_SCOPED + //tree for this face is no longer valid delete mOctree; mOctree = NULL; @@ -5514,6 +5531,8 @@ bool LLVolumeFace::cacheOptimize() void LLVolumeFace::createOctree(F32 scaler, const LLVector4a& center, const LLVector4a& size) { + LL_PROFILE_ZONE_SCOPED + if (mOctree) { return; @@ -6287,6 +6306,8 @@ void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVe void LLVolumeFace::createTangents() { + LL_PROFILE_ZONE_SCOPED + if (!mTangents) { allocateTangents(mNumVertices); @@ -6482,6 +6503,8 @@ void LLVolumeFace::fillFromLegacyData(std::vector& v, BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) { + LL_PROFILE_ZONE_SCOPED + LL_CHECK_MEMORY BOOL flat = mTypeMask & FLAT_MASK; @@ -6974,6 +6997,8 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal, const LLVector2 *texcoord, U32 triangleCount, const U16* index_array, LLVector4a *tangent) { + LL_PROFILE_ZONE_SCOPED + //LLVector4a *tan1 = new LLVector4a[vertexCount * 2]; LLVector4a* tan1 = (LLVector4a*) ll_aligned_malloc_16(vertexCount*2*sizeof(LLVector4a)); // new(tan1) LLVector4a; -- cgit v1.2.3 From 53853cf96469912e51a7262521feb4c76e125969 Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Mon, 20 Sep 2021 09:48:16 -0700 Subject: SL-16014: Add Tracy markup for LLEventFilter --- indra/llcommon/lleventfilter.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/indra/llcommon/lleventfilter.h b/indra/llcommon/lleventfilter.h index 48c2570732..7613850fb2 100644 --- a/indra/llcommon/lleventfilter.h +++ b/indra/llcommon/lleventfilter.h @@ -429,6 +429,8 @@ public: // path, then stores it to mTarget. virtual bool post(const LLSD& event) { + LL_PROFILE_ZONE_SCOPED + // Extract the element specified by 'mPath' from 'event'. To perform a // generic type-appropriate store through mTarget, construct an // LLSDParam and store that, thus engaging LLSDParam's custom -- cgit v1.2.3 From fff9b8dff20a1a5f4ce4371b027bcdef2d0dc6ed Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Mon, 20 Sep 2021 09:54:32 -0700 Subject: SL-16014: Add Tracy markup to doFrame() --- indra/newview/llappviewer.cpp | 48 ++++++++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index ab2b846c09..879cc6fc85 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1358,7 +1358,8 @@ void LLAppViewer::initMaxHeapSize() } static LLTrace::BlockTimerStatHandle FTM_MESSAGES("System Messages"); -static LLTrace::BlockTimerStatHandle FTM_SLEEP("Sleep"); +static LLTrace::BlockTimerStatHandle FTM_SLEEP1("Sleep1"); +static LLTrace::BlockTimerStatHandle FTM_SLEEP2("Sleep2"); static LLTrace::BlockTimerStatHandle FTM_YIELD("Yield"); static LLTrace::BlockTimerStatHandle FTM_TEXTURE_CACHE("Texture Cache"); @@ -1420,13 +1421,13 @@ bool LLAppViewer::frame() bool LLAppViewer::doFrame() { + LL_RECORD_BLOCK_TIME(FTM_FRAME); + LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop")); LLSD newFrame; - LL_RECORD_BLOCK_TIME(FTM_FRAME); - { - LL_PROFILE_ZONE_NAMED( ":blocktimer" ) + LL_PROFILE_ZONE_NAMED( "df blocktimer" ) LLTrace::BlockTimer::processTimes(); LLTrace::get_frame_recording().nextPeriod(); LLTrace::BlockTimer::logStats(); @@ -1438,7 +1439,7 @@ bool LLAppViewer::doFrame() LL_CLEAR_CALLSTACKS(); { - LL_PROFILE_ZONE_NAMED( ":processMiscNativeEvents" ) + LL_PROFILE_ZONE_NAMED( "df processMiscNativeEvents" ) pingMainloopTimeout("Main:MiscNativeWindowEvents"); if (gViewerWindow) @@ -1448,7 +1449,7 @@ bool LLAppViewer::doFrame() } { - LL_PROFILE_ZONE_NAMED( ":gatherInput" ) + LL_PROFILE_ZONE_NAMED( "df gatherInput" ) pingMainloopTimeout("Main:GatherInput"); } @@ -1475,20 +1476,20 @@ bool LLAppViewer::doFrame() } { - LL_PROFILE_ZONE_NAMED( ":mainloop" ) + LL_PROFILE_ZONE_NAMED( "df mainloop" ) // canonical per-frame event mainloop.post(newFrame); } { - LL_PROFILE_ZONE_NAMED( ":suspend" ) + LL_PROFILE_ZONE_NAMED( "df suspend" ) // give listeners a chance to run llcoro::suspend(); } if (!LLApp::isExiting()) { - LL_PROFILE_ZONE_NAMED( ":JoystickKeyboard" ) + LL_PROFILE_ZONE_NAMED( "df JoystickKeyboard" ) pingMainloopTimeout("Main:JoystickKeyboard"); // Scan keyboard for movement keys. Command keys and typing @@ -1510,7 +1511,7 @@ bool LLAppViewer::doFrame() // Update state based on messages, user input, object idle. { { - LL_PROFILE_ZONE_NAMED( ":pauseMainloopTimeout" ) + LL_PROFILE_ZONE_NAMED( "df pauseMainloopTimeout" ) pauseMainloopTimeout(); // *TODO: Remove. Messages shouldn't be stalling for 20+ seconds! } @@ -1518,7 +1519,7 @@ bool LLAppViewer::doFrame() idle(); { - LL_PROFILE_ZONE_NAMED( ":resumeMainloopTimeout" ) + LL_PROFILE_ZONE_NAMED( "df resumeMainloopTimeout" ) resumeMainloopTimeout(); } } @@ -1535,7 +1536,7 @@ bool LLAppViewer::doFrame() // *TODO: Should we run display() even during gHeadlessClient? DK 2011-02-18 if (!LLApp::isExiting() && !gHeadlessClient && gViewerWindow) { - LL_PROFILE_ZONE_NAMED( ":Display" ) + LL_PROFILE_ZONE_NAMED( "df Display" ) pingMainloopTimeout("Main:Display"); gGLActive = TRUE; @@ -1548,16 +1549,19 @@ bool LLAppViewer::doFrame() U64 elapsed_time = LLTimer::getTotalTime() - last_call; if (elapsed_time < mMinMicroSecPerFrame) { - LL_RECORD_BLOCK_TIME(FTM_SLEEP); + //LL_RECORD_BLOCK_TIME(FTM_SLEEP1); + LL_PROFILE_ZONE_WARN( "Sleep1" ) // llclamp for when time function gets funky U64 sleep_time = llclamp(mMinMicroSecPerFrame - elapsed_time, (U64)1, (U64)1e6); + + LL_PROFILE_ZONE_NUM( sleep_time ) micro_sleep(sleep_time, 0); } } last_call = LLTimer::getTotalTime(); { - LL_PROFILE_ZONE_NAMED( ":Snapshot" ) + LL_PROFILE_ZONE_NAMED( "df Snapshot" ) pingMainloopTimeout("Main:Snapshot"); LLFloaterSnapshot::update(); // take snapshots LLFloaterOutfitSnapshot::update(); @@ -1567,7 +1571,7 @@ bool LLAppViewer::doFrame() } { - LL_PROFILE_ZONE_NAMED( ":pauseMainloopTimeout" ) + LL_PROFILE_ZONE_NAMED( "df pauseMainloopTimeout" ) pingMainloopTimeout("Main:Sleep"); pauseMainloopTimeout(); @@ -1575,13 +1579,15 @@ bool LLAppViewer::doFrame() // Sleep and run background threads { - LL_RECORD_BLOCK_TIME(FTM_SLEEP); + //LL_RECORD_BLOCK_TIME(SLEEP2); + LL_PROFILE_ZONE_WARN( "Sleep2" ) // yield some time to the os based on command line option static LLCachedControl yield_time(gSavedSettings, "YieldTime", -1); if(yield_time >= 0) { LL_RECORD_BLOCK_TIME(FTM_YIELD); + LL_PROFILE_ZONE_NUM( yield_time ) ms_sleep(yield_time); } @@ -1646,20 +1652,20 @@ bool LLAppViewer::doFrame() } { - LL_PROFILE_ZONE_NAMED( ":gMeshRepo" ) + LL_PROFILE_ZONE_NAMED( "df gMeshRepo" ) gMeshRepo.update() ; } if(!total_work_pending) //pause texture fetching threads if nothing to process. { - LL_PROFILE_ZONE_NAMED( ":getTextureCache" ) + LL_PROFILE_ZONE_NAMED( "df getTextureCache" ) LLAppViewer::getTextureCache()->pause(); LLAppViewer::getImageDecodeThread()->pause(); LLAppViewer::getTextureFetch()->pause(); } if(!total_io_pending) //pause file threads if nothing to process. { - LL_PROFILE_ZONE_NAMED( ":LLVFSThread" ) + LL_PROFILE_ZONE_NAMED( "df LLVFSThread" ) LLVFSThread::sLocal->pause(); LLLFSThread::sLocal->pause(); } @@ -1667,7 +1673,7 @@ bool LLAppViewer::doFrame() //texture fetching debugger if(LLTextureFetchDebugger::isEnabled()) { - LL_PROFILE_ZONE_NAMED( ":tex_fetch_debugger_instance" ) + LL_PROFILE_ZONE_NAMED( "df tex_fetch_debugger_instance" ) LLFloaterTextureFetchDebugger* tex_fetch_debugger_instance = LLFloaterReg::findTypedInstance("tex_fetch_debugger"); if(tex_fetch_debugger_instance) @@ -1677,7 +1683,7 @@ bool LLAppViewer::doFrame() } { - LL_PROFILE_ZONE_NAMED( ":resumeMainloopTimeout" ) + LL_PROFILE_ZONE_NAMED( "df resumeMainloopTimeout" ) resumeMainloopTimeout(); } pingMainloopTimeout("Main:End"); -- cgit v1.2.3 From f79890669dcf8e44b5ec3ce1abbd1d1fdd34eb3b Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 20 Sep 2021 18:58:09 +0000 Subject: SL-16006 and SL-16009 Rigged mesh rendering optimization pass --- indra/llcharacter/lljoint.cpp | 8 + indra/llcharacter/lljoint.h | 4 + indra/llmath/llmatrix4a.h | 41 ++- indra/llmath/llvector4a.h | 7 +- indra/llmath/llvector4a.inl | 4 +- indra/llmath/m4math.cpp | 9 +- indra/llmath/m4math.h | 2 + indra/llmath/v3math.cpp | 6 + indra/llmath/v3math.h | 5 +- indra/llprimitive/lldaeloader.cpp | 16 +- indra/llprimitive/llmodel.cpp | 8 +- indra/llprimitive/llmodel.h | 9 +- indra/llrender/llglslshader.cpp | 1 + indra/newview/llcontrolavatar.cpp | 2 +- indra/newview/lldrawpoolavatar.cpp | 508 ++++++++++++++++++-------------- indra/newview/lldrawpoolavatar.h | 27 +- indra/newview/llfloatermodelpreview.cpp | 88 +++--- indra/newview/llmodelpreview.cpp | 9 +- indra/newview/llskinningutil.cpp | 62 ++-- indra/newview/llskinningutil.h | 4 +- indra/newview/llviewertexture.cpp | 1 + indra/newview/llviewertexturelist.cpp | 1 + indra/newview/llvoavatar.cpp | 43 +-- indra/newview/llvoavatar.h | 5 + indra/newview/llvovolume.cpp | 5 +- 25 files changed, 521 insertions(+), 354 deletions(-) diff --git a/indra/llcharacter/lljoint.cpp b/indra/llcharacter/lljoint.cpp index dee642310e..d72282ab42 100644 --- a/indra/llcharacter/lljoint.cpp +++ b/indra/llcharacter/lljoint.cpp @@ -922,6 +922,13 @@ const LLMatrix4 &LLJoint::getWorldMatrix() return mXform.getWorldMatrix(); } +const LLMatrix4a& LLJoint::getWorldMatrix4a() +{ + updateWorldMatrixParent(); + + return mWorldMatrix; +} + //-------------------------------------------------------------------- // setWorldMatrix() @@ -1003,6 +1010,7 @@ void LLJoint::updateWorldMatrix() { sNumUpdates++; mXform.updateMatrix(FALSE); + mWorldMatrix.loadu(mXform.getWorldMatrix()); mDirtyFlags = 0x0; } } diff --git a/indra/llcharacter/lljoint.h b/indra/llcharacter/lljoint.h index 1b646b641f..ba821667c7 100644 --- a/indra/llcharacter/lljoint.h +++ b/indra/llcharacter/lljoint.h @@ -38,6 +38,7 @@ #include "m4math.h" #include "llquaternion.h" #include "xform.h" +#include "llmatrix4a.h" const S32 LL_CHARACTER_MAX_JOINTS_PER_MESH = 15; // Need to set this to count of animate-able joints, @@ -123,6 +124,7 @@ protected: // explicit transformation members LLXformMatrix mXform; + LLMatrix4a mWorldMatrix; LLVector3 mDefaultPosition; LLVector3 mDefaultScale; @@ -259,6 +261,8 @@ public: const LLMatrix4 &getWorldMatrix(); void setWorldMatrix( const LLMatrix4& mat ); + const LLMatrix4a& getWorldMatrix4a(); + void updateWorldMatrixChildren(); void updateWorldMatrixParent(); diff --git a/indra/llmath/llmatrix4a.h b/indra/llmath/llmatrix4a.h index 7ba347062f..5291a05607 100644 --- a/indra/llmath/llmatrix4a.h +++ b/indra/llmath/llmatrix4a.h @@ -36,6 +36,26 @@ class LLMatrix4a public: LL_ALIGN_16(LLVector4a mMatrix[4]); + LLMatrix4a() + { + + } + + explicit LLMatrix4a(const LLMatrix4& val) + { + loadu(val); + } + + inline F32* getF32ptr() + { + return (F32*) &mMatrix; + } + + inline const F32* getF32ptr() const + { + return (F32*)&mMatrix; + } + inline void clear() { mMatrix[0].clear(); @@ -44,6 +64,14 @@ public: mMatrix[3].clear(); } + inline void setIdentity() + { + mMatrix[0].set(1.f, 0.f, 0.f, 0.f); + mMatrix[1].set(0.f, 1.f, 0.f, 0.f); + mMatrix[2].set(0.f, 0.f, 1.f, 0.f); + mMatrix[3].set(0.f, 0.f, 0.f, 1.f); + } + inline void loadu(const LLMatrix4& src) { mMatrix[0] = _mm_loadu_ps(src.mMatrix[0]); @@ -105,7 +133,7 @@ public: mMatrix[3].setAdd(a.mMatrix[3],d3); } - inline void rotate(const LLVector4a& v, LLVector4a& res) + inline void rotate(const LLVector4a& v, LLVector4a& res) const { LLVector4a y,z; @@ -151,6 +179,8 @@ public: { affineTransformSSE(v,res); } + + const LLVector4a& getTranslation() const { return mMatrix[3]; } }; inline LLVector4a rowMul(const LLVector4a &row, const LLMatrix4a &mat) @@ -176,6 +206,15 @@ inline void matMul(const LLMatrix4a &a, const LLMatrix4a &b, LLMatrix4a &res) res.mMatrix[3] = row3; } +//Faster version of matMul wehere res must not be a or b +inline void matMulUnsafe(const LLMatrix4a &a, const LLMatrix4a &b, LLMatrix4a &res) +{ + res.mMatrix[0] = rowMul(a.mMatrix[0], b); + res.mMatrix[1] = rowMul(a.mMatrix[1], b); + res.mMatrix[2] = rowMul(a.mMatrix[2], b); + res.mMatrix[3] = rowMul(a.mMatrix[3], b); +} + inline std::ostream& operator<<(std::ostream& s, const LLMatrix4a& m) { s << "[" << m.mMatrix[0] << ", " << m.mMatrix[1] << ", " << m.mMatrix[2] << ", " << m.mMatrix[3] << "]"; diff --git a/indra/llmath/llvector4a.h b/indra/llmath/llvector4a.h index 27abf39537..5a02928374 100644 --- a/indra/llmath/llvector4a.h +++ b/indra/llmath/llvector4a.h @@ -46,10 +46,9 @@ class LLRotation; // of this writing, July 08, 2010) about getting it implemented before you resort to // LLVector3/LLVector4. ///////////////////////////////// -struct LLVector4a; LL_ALIGN_PREFIX(16) -struct LLVector4a +class LLVector4a { public: @@ -138,10 +137,10 @@ public: // BASIC GET/SET //////////////////////////////////// - // Return a "this" as an F32 pointer. Do not use unless you have a very good reason. (Not sure? Ask Falcon) + // Return a "this" as an F32 pointer. inline F32* getF32ptr(); - // Return a "this" as a const F32 pointer. Do not use unless you have a very good reason. (Not sure? Ask Falcon) + // Return a "this" as a const F32 pointer. inline const F32* const getF32ptr() const; // Read-only access a single float in this vector. Do not use in proximity to any function call that manipulates diff --git a/indra/llmath/llvector4a.inl b/indra/llmath/llvector4a.inl index 69d3d01efe..8be1c1b114 100644 --- a/indra/llmath/llvector4a.inl +++ b/indra/llmath/llvector4a.inl @@ -58,13 +58,13 @@ inline void LLVector4a::store4a(F32* dst) const // BASIC GET/SET //////////////////////////////////// -// Return a "this" as an F32 pointer. Do not use unless you have a very good reason. (Not sure? Ask Falcon) +// Return a "this" as an F32 pointer. F32* LLVector4a::getF32ptr() { return (F32*) &mQ; } -// Return a "this" as a const F32 pointer. Do not use unless you have a very good reason. (Not sure? Ask Falcon) +// Return a "this" as a const F32 pointer. const F32* const LLVector4a::getF32ptr() const { return (const F32* const) &mQ; diff --git a/indra/llmath/m4math.cpp b/indra/llmath/m4math.cpp index 3baf1bad18..6e40dae30b 100644 --- a/indra/llmath/m4math.cpp +++ b/indra/llmath/m4math.cpp @@ -32,8 +32,7 @@ #include "m4math.h" #include "m3math.h" #include "llquaternion.h" - - +#include "llmatrix4a.h" // LLMatrix4 @@ -115,6 +114,12 @@ LLMatrix4::LLMatrix4(const LLQuaternion &q) *this = initRotation(q); } +LLMatrix4::LLMatrix4(const LLMatrix4a& mat) + : LLMatrix4(mat.getF32ptr()) +{ + +} + LLMatrix4::LLMatrix4(const LLQuaternion &q, const LLVector4 &pos) { *this = initRotTrans(q, pos); diff --git a/indra/llmath/m4math.h b/indra/llmath/m4math.h index bf60adb9b6..b9da970cde 100644 --- a/indra/llmath/m4math.h +++ b/indra/llmath/m4math.h @@ -32,6 +32,7 @@ class LLVector4; class LLMatrix3; class LLQuaternion; +class LLMatrix4a; // NOTA BENE: Currently assuming a right-handed, x-forward, y-left, z-up universe @@ -104,6 +105,7 @@ public: explicit LLMatrix4(const F32 *mat); // Initializes Matrix to values in mat explicit LLMatrix4(const LLMatrix3 &mat); // Initializes Matrix to values in mat and sets position to (0,0,0) explicit LLMatrix4(const LLQuaternion &q); // Initializes Matrix with rotation q and sets position to (0,0,0) + explicit LLMatrix4(const LLMatrix4a& mat); LLMatrix4(const LLMatrix3 &mat, const LLVector4 &pos); // Initializes Matrix to values in mat and pos diff --git a/indra/llmath/v3math.cpp b/indra/llmath/v3math.cpp index b04c67d926..93010d2250 100644 --- a/indra/llmath/v3math.cpp +++ b/indra/llmath/v3math.cpp @@ -316,6 +316,12 @@ LLVector3::LLVector3(const LLVector4 &vec) mV[VZ] = (F32)vec.mV[VZ]; } +LLVector3::LLVector3(const LLVector4a& vec) + : LLVector3(vec.getF32ptr()) +{ + +} + LLVector3::LLVector3(const LLSD& sd) { setValue(sd); diff --git a/indra/llmath/v3math.h b/indra/llmath/v3math.h index 6f857d7061..068f489020 100644 --- a/indra/llmath/v3math.h +++ b/indra/llmath/v3math.h @@ -33,6 +33,7 @@ #include "llsd.h" class LLVector2; class LLVector4; +class LLVector4a; class LLMatrix3; class LLMatrix4; class LLVector3d; @@ -62,7 +63,9 @@ class LLVector3 explicit LLVector3(const LLVector2 &vec); // Initializes LLVector3 to (vec[0]. vec[1], 0) explicit LLVector3(const LLVector3d &vec); // Initializes LLVector3 to (vec[0]. vec[1], vec[2]) explicit LLVector3(const LLVector4 &vec); // Initializes LLVector4 to (vec[0]. vec[1], vec[2]) - explicit LLVector3(const LLSD& sd); + explicit LLVector3(const LLVector4a& vec); // Initializes LLVector4 to (vec[0]. vec[1], vec[2]) + explicit LLVector3(const LLSD& sd); + LLSD getValue() const; diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp index dfa29fb539..8343de0cbc 100644 --- a/indra/llprimitive/lldaeloader.cpp +++ b/indra/llprimitive/lldaeloader.cpp @@ -1173,17 +1173,19 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do LLMeshSkinInfo& skin_info = model->mSkinInfo; + LLMatrix4 mat; for (int i = 0; i < 4; i++) { for(int j = 0; j < 4; j++) { - skin_info.mBindShapeMatrix.mMatrix[i][j] = dom_value[i + j*4]; + mat.mMatrix[i][j] = dom_value[i + j*4]; } } - LLMatrix4 trans = normalized_transformation; - trans *= skin_info.mBindShapeMatrix; - skin_info.mBindShapeMatrix = trans; + skin_info.mBindShapeMatrix.loadu(mat); + + LLMatrix4a trans(normalized_transformation); + matMul(trans, skin_info.mBindShapeMatrix, skin_info.mBindShapeMatrix); } @@ -1401,7 +1403,7 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do mat.mMatrix[i][j] = transform[k*16 + i + j*4]; } } - model->mSkinInfo.mInvBindMatrix.push_back(mat); + model->mSkinInfo.mInvBindMatrix.push_back(LLMatrix4a(mat)); } } } @@ -1475,9 +1477,9 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do if (mJointMap.find(lookingForJoint) != mJointMap.end() && model->mSkinInfo.mInvBindMatrix.size() > i) { - LLMatrix4 newInverse = model->mSkinInfo.mInvBindMatrix[i]; + LLMatrix4 newInverse = LLMatrix4(model->mSkinInfo.mInvBindMatrix[i].getF32ptr()); newInverse.setTranslation( mJointList[lookingForJoint].getTranslation() ); - model->mSkinInfo.mAlternateBindMatrix.push_back( newInverse ); + model->mSkinInfo.mAlternateBindMatrix.push_back( LLMatrix4a(newInverse) ); } else { diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index 702a1b5238..a23b991f1d 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -1396,7 +1396,7 @@ void LLMeshSkinInfo::fromLLSD(LLSD& skin) } } - mInvBindMatrix.push_back(mat); + mInvBindMatrix.push_back(LLMatrix4a(mat)); } if (mJointNames.size() != mInvBindMatrix.size()) @@ -1410,13 +1410,15 @@ void LLMeshSkinInfo::fromLLSD(LLSD& skin) if (skin.has("bind_shape_matrix")) { + LLMatrix4 mat; for (U32 j = 0; j < 4; j++) { for (U32 k = 0; k < 4; k++) { - mBindShapeMatrix.mMatrix[j][k] = skin["bind_shape_matrix"][j*4+k].asReal(); + mat.mMatrix[j][k] = skin["bind_shape_matrix"][j*4+k].asReal(); } } + mBindShapeMatrix.loadu(mat); } if (skin.has("alt_inverse_bind_matrix")) @@ -1432,7 +1434,7 @@ void LLMeshSkinInfo::fromLLSD(LLSD& skin) } } - mAlternateBindMatrix.push_back(mat); + mAlternateBindMatrix.push_back(LLMatrix4a(mat)); } } diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index 51fa2f8079..96d4582b4f 100644 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -33,6 +33,8 @@ #include "m4math.h" #include +#include + class daeElement; class domMesh; @@ -49,10 +51,11 @@ public: LLUUID mMeshID; std::vector mJointNames; mutable std::vector mJointNums; - std::vector mInvBindMatrix; - std::vector mAlternateBindMatrix; + typedef std::vector> matrix_list_t; + matrix_list_t mInvBindMatrix; + matrix_list_t mAlternateBindMatrix; - LLMatrix4 mBindShapeMatrix; + LLMatrix4a mBindShapeMatrix; float mPelvisOffset; bool mLockScaleIfJointPosition; bool mInvalidJointsScrubbed; diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index 4351f6e2c8..8bd9dbf9b8 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -1346,6 +1346,7 @@ void LLGLSLShader::uniformMatrix3fv(U32 index, U32 count, GLboolean transpose, c void LLGLSLShader::uniformMatrix3x4fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v) { + LL_PROFILE_ZONE_SCOPED; if (mProgramObject) { if (mUniform.size() <= index) diff --git a/indra/newview/llcontrolavatar.cpp b/indra/newview/llcontrolavatar.cpp index fab249f988..606e670805 100644 --- a/indra/newview/llcontrolavatar.cpp +++ b/indra/newview/llcontrolavatar.cpp @@ -241,7 +241,7 @@ void LLControlAvatar::matchVolumeTransform() if (skin_info) { LL_DEBUGS("BindShape") << getFullname() << " bind shape " << skin_info->mBindShapeMatrix << LL_ENDL; - bind_rot = LLSkinningUtil::getUnscaledQuaternion(skin_info->mBindShapeMatrix); + bind_rot = LLSkinningUtil::getUnscaledQuaternion(LLMatrix4(skin_info->mBindShapeMatrix)); } #endif setRotation(bind_rot*obj_rot); diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 6c4844f9ee..c7aa104ca5 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -163,6 +163,7 @@ void LLDrawPoolAvatar::prerender() { LLVOAvatar* avatarp = (LLVOAvatar *)facep->getDrawable()->getVObj().get(); updateRiggedVertexBuffers(avatarp); + updateSkinInfoMatrixPalettes(avatarp); } } } @@ -428,221 +429,230 @@ S32 LLDrawPoolAvatar::getNumShadowPasses() void LLDrawPoolAvatar::beginShadowPass(S32 pass) { LL_RECORD_BLOCK_TIME(FTM_SHADOW_AVATAR); + { + LL_PROFILE_ZONE_SCOPED; - if (pass == SHADOW_PASS_AVATAR_OPAQUE) - { - sVertexProgram = &gDeferredAvatarShadowProgram; - - if ((sShaderLevel > 0)) // for hardware blending - { - sRenderingSkinned = TRUE; - sVertexProgram->bind(); - } + if (pass == SHADOW_PASS_AVATAR_OPAQUE) + { + sVertexProgram = &gDeferredAvatarShadowProgram; - gGL.diffuseColor4f(1,1,1,1); - } - else if (pass == SHADOW_PASS_AVATAR_ALPHA_BLEND) - { - sVertexProgram = &gDeferredAvatarAlphaShadowProgram; + if ((sShaderLevel > 0)) // for hardware blending + { + sRenderingSkinned = TRUE; + sVertexProgram->bind(); + } - // bind diffuse tex so we can reference the alpha channel... - S32 loc = sVertexProgram->getUniformLocation(LLViewerShaderMgr::DIFFUSE_MAP); - sDiffuseChannel = 0; - if (loc != -1) + gGL.diffuseColor4f(1, 1, 1, 1); + } + else if (pass == SHADOW_PASS_AVATAR_ALPHA_BLEND) { - sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); - } + sVertexProgram = &gDeferredAvatarAlphaShadowProgram; - if ((sShaderLevel > 0)) // for hardware blending - { - sRenderingSkinned = TRUE; - sVertexProgram->bind(); - } + // bind diffuse tex so we can reference the alpha channel... + S32 loc = sVertexProgram->getUniformLocation(LLViewerShaderMgr::DIFFUSE_MAP); + sDiffuseChannel = 0; + if (loc != -1) + { + sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); + } - gGL.diffuseColor4f(1,1,1,1); - } - else if (pass == SHADOW_PASS_AVATAR_ALPHA_MASK) - { - sVertexProgram = &gDeferredAvatarAlphaMaskShadowProgram; + if ((sShaderLevel > 0)) // for hardware blending + { + sRenderingSkinned = TRUE; + sVertexProgram->bind(); + } - // bind diffuse tex so we can reference the alpha channel... - S32 loc = sVertexProgram->getUniformLocation(LLViewerShaderMgr::DIFFUSE_MAP); - sDiffuseChannel = 0; - if (loc != -1) + gGL.diffuseColor4f(1, 1, 1, 1); + } + else if (pass == SHADOW_PASS_AVATAR_ALPHA_MASK) { - sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); - } + sVertexProgram = &gDeferredAvatarAlphaMaskShadowProgram; - if ((sShaderLevel > 0)) // for hardware blending - { - sRenderingSkinned = TRUE; - sVertexProgram->bind(); - } + // bind diffuse tex so we can reference the alpha channel... + S32 loc = sVertexProgram->getUniformLocation(LLViewerShaderMgr::DIFFUSE_MAP); + sDiffuseChannel = 0; + if (loc != -1) + { + sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); + } - gGL.diffuseColor4f(1,1,1,1); - } - else if (pass == SHADOW_PASS_ATTACHMENT_ALPHA_BLEND) - { - sVertexProgram = &gDeferredAttachmentAlphaShadowProgram; + if ((sShaderLevel > 0)) // for hardware blending + { + sRenderingSkinned = TRUE; + sVertexProgram->bind(); + } - // bind diffuse tex so we can reference the alpha channel... - S32 loc = sVertexProgram->getUniformLocation(LLViewerShaderMgr::DIFFUSE_MAP); - sDiffuseChannel = 0; - if (loc != -1) + gGL.diffuseColor4f(1, 1, 1, 1); + } + else if (pass == SHADOW_PASS_ATTACHMENT_ALPHA_BLEND) { - sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); - } - - if ((sShaderLevel > 0)) // for hardware blending - { - sRenderingSkinned = TRUE; - sVertexProgram->bind(); - } + sVertexProgram = &gDeferredAttachmentAlphaShadowProgram; - gGL.diffuseColor4f(1,1,1,1); - } - else if (pass == SHADOW_PASS_ATTACHMENT_ALPHA_MASK) - { - sVertexProgram = &gDeferredAttachmentAlphaMaskShadowProgram; + // bind diffuse tex so we can reference the alpha channel... + S32 loc = sVertexProgram->getUniformLocation(LLViewerShaderMgr::DIFFUSE_MAP); + sDiffuseChannel = 0; + if (loc != -1) + { + sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); + } + + if ((sShaderLevel > 0)) // for hardware blending + { + sRenderingSkinned = TRUE; + sVertexProgram->bind(); + } - // bind diffuse tex so we can reference the alpha channel... - S32 loc = sVertexProgram->getUniformLocation(LLViewerShaderMgr::DIFFUSE_MAP); - sDiffuseChannel = 0; - if (loc != -1) + gGL.diffuseColor4f(1, 1, 1, 1); + } + else if (pass == SHADOW_PASS_ATTACHMENT_ALPHA_MASK) { - sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); - } + sVertexProgram = &gDeferredAttachmentAlphaMaskShadowProgram; - if ((sShaderLevel > 0)) // for hardware blending - { - sRenderingSkinned = TRUE; - sVertexProgram->bind(); - } + // bind diffuse tex so we can reference the alpha channel... + S32 loc = sVertexProgram->getUniformLocation(LLViewerShaderMgr::DIFFUSE_MAP); + sDiffuseChannel = 0; + if (loc != -1) + { + sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); + } - gGL.diffuseColor4f(1,1,1,1); - } - else // SHADOW_PASS_ATTACHMENT_OPAQUE - { - sVertexProgram = &gDeferredAttachmentShadowProgram; - S32 loc = sVertexProgram->getUniformLocation(LLViewerShaderMgr::DIFFUSE_MAP); - sDiffuseChannel = 0; - if (loc != -1) + if ((sShaderLevel > 0)) // for hardware blending + { + sRenderingSkinned = TRUE; + sVertexProgram->bind(); + } + + gGL.diffuseColor4f(1, 1, 1, 1); + } + else // SHADOW_PASS_ATTACHMENT_OPAQUE { - sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); - } - sVertexProgram->bind(); - } + sVertexProgram = &gDeferredAttachmentShadowProgram; + S32 loc = sVertexProgram->getUniformLocation(LLViewerShaderMgr::DIFFUSE_MAP); + sDiffuseChannel = 0; + if (loc != -1) + { + sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); + } + sVertexProgram->bind(); + } + } } void LLDrawPoolAvatar::endShadowPass(S32 pass) { LL_RECORD_BLOCK_TIME(FTM_SHADOW_AVATAR); + { + LL_PROFILE_ZONE_SCOPED; - if (pass == SHADOW_PASS_ATTACHMENT_OPAQUE) - { - LLVertexBuffer::unbind(); - } + if (pass == SHADOW_PASS_ATTACHMENT_OPAQUE) + { + LLVertexBuffer::unbind(); + } - if (sShaderLevel > 0) - { - sVertexProgram->unbind(); - } - sVertexProgram = NULL; - sRenderingSkinned = FALSE; - LLDrawPoolAvatar::sShadowPass = -1; + if (sShaderLevel > 0) + { + sVertexProgram->unbind(); + } + sVertexProgram = NULL; + sRenderingSkinned = FALSE; + LLDrawPoolAvatar::sShadowPass = -1; + } } void LLDrawPoolAvatar::renderShadow(S32 pass) { - LL_RECORD_BLOCK_TIME(FTM_SHADOW_AVATAR); + LL_RECORD_BLOCK_TIME(FTM_SHADOW_AVATAR); + { + LL_PROFILE_ZONE_SCOPED; - if (mDrawFace.empty()) - { - return; - } + if (mDrawFace.empty()) + { + return; + } - const LLFace *facep = mDrawFace[0]; - if (!facep->getDrawable()) - { - return; - } - LLVOAvatar *avatarp = (LLVOAvatar *)facep->getDrawable()->getVObj().get(); + const LLFace *facep = mDrawFace[0]; + if (!facep->getDrawable()) + { + return; + } + LLVOAvatar *avatarp = (LLVOAvatar *)facep->getDrawable()->getVObj().get(); - if (avatarp->isDead() || avatarp->isUIAvatar() || avatarp->mDrawable.isNull()) - { - return; - } - LLVOAvatar::AvatarOverallAppearance oa = avatarp->getOverallAppearance(); - BOOL impostor = !LLPipeline::sImpostorRender && avatarp->isImpostor(); - if (oa == LLVOAvatar::AOA_INVISIBLE || - (impostor && oa == LLVOAvatar::AOA_JELLYDOLL)) - { - // No shadows for jellydolled or invisible avs. - return; - } - - LLDrawPoolAvatar::sShadowPass = pass; + if (avatarp->isDead() || avatarp->isUIAvatar() || avatarp->mDrawable.isNull()) + { + return; + } + LLVOAvatar::AvatarOverallAppearance oa = avatarp->getOverallAppearance(); + BOOL impostor = !LLPipeline::sImpostorRender && avatarp->isImpostor(); + if (oa == LLVOAvatar::AOA_INVISIBLE || + (impostor && oa == LLVOAvatar::AOA_JELLYDOLL)) + { + // No shadows for jellydolled or invisible avs. + return; + } - if (pass == SHADOW_PASS_AVATAR_OPAQUE) - { - LLDrawPoolAvatar::sSkipTransparent = true; - avatarp->renderSkinned(); - LLDrawPoolAvatar::sSkipTransparent = false; - } - else if (pass == SHADOW_PASS_AVATAR_ALPHA_BLEND) - { - LLDrawPoolAvatar::sSkipOpaque = true; - avatarp->renderSkinned(); - LLDrawPoolAvatar::sSkipOpaque = false; - } - else if (pass == SHADOW_PASS_AVATAR_ALPHA_MASK) - { - LLDrawPoolAvatar::sSkipOpaque = true; - avatarp->renderSkinned(); - LLDrawPoolAvatar::sSkipOpaque = false; - } - else if (pass == SHADOW_PASS_ATTACHMENT_ALPHA_BLEND) // rigged alpha - { - LLDrawPoolAvatar::sSkipOpaque = true; - renderRigged(avatarp, RIGGED_MATERIAL_ALPHA); - renderRigged(avatarp, RIGGED_MATERIAL_ALPHA_EMISSIVE); - renderRigged(avatarp, RIGGED_ALPHA); - renderRigged(avatarp, RIGGED_FULLBRIGHT_ALPHA); - renderRigged(avatarp, RIGGED_GLOW); - renderRigged(avatarp, RIGGED_SPECMAP_BLEND); - renderRigged(avatarp, RIGGED_NORMMAP_BLEND); - renderRigged(avatarp, RIGGED_NORMSPEC_BLEND); - LLDrawPoolAvatar::sSkipOpaque = false; - } - else if (pass == SHADOW_PASS_ATTACHMENT_ALPHA_MASK) // rigged alpha mask - { - LLDrawPoolAvatar::sSkipOpaque = true; - renderRigged(avatarp, RIGGED_MATERIAL_ALPHA_MASK); - renderRigged(avatarp, RIGGED_NORMMAP_MASK); - renderRigged(avatarp, RIGGED_SPECMAP_MASK); - renderRigged(avatarp, RIGGED_NORMSPEC_MASK); - renderRigged(avatarp, RIGGED_GLOW); - LLDrawPoolAvatar::sSkipOpaque = false; - } - else // rigged opaque (SHADOW_PASS_ATTACHMENT_OPAQUE - { - LLDrawPoolAvatar::sSkipTransparent = true; - renderRigged(avatarp, RIGGED_MATERIAL); - renderRigged(avatarp, RIGGED_SPECMAP); - renderRigged(avatarp, RIGGED_SPECMAP_EMISSIVE); - renderRigged(avatarp, RIGGED_NORMMAP); - renderRigged(avatarp, RIGGED_NORMMAP_EMISSIVE); - renderRigged(avatarp, RIGGED_NORMSPEC); - renderRigged(avatarp, RIGGED_NORMSPEC_EMISSIVE); - renderRigged(avatarp, RIGGED_SIMPLE); - renderRigged(avatarp, RIGGED_FULLBRIGHT); - renderRigged(avatarp, RIGGED_SHINY); - renderRigged(avatarp, RIGGED_FULLBRIGHT_SHINY); - renderRigged(avatarp, RIGGED_GLOW); - renderRigged(avatarp, RIGGED_DEFERRED_BUMP); - renderRigged(avatarp, RIGGED_DEFERRED_SIMPLE); - LLDrawPoolAvatar::sSkipTransparent = false; - } + LLDrawPoolAvatar::sShadowPass = pass; + + if (pass == SHADOW_PASS_AVATAR_OPAQUE) + { + LLDrawPoolAvatar::sSkipTransparent = true; + avatarp->renderSkinned(); + LLDrawPoolAvatar::sSkipTransparent = false; + } + else if (pass == SHADOW_PASS_AVATAR_ALPHA_BLEND) + { + LLDrawPoolAvatar::sSkipOpaque = true; + avatarp->renderSkinned(); + LLDrawPoolAvatar::sSkipOpaque = false; + } + else if (pass == SHADOW_PASS_AVATAR_ALPHA_MASK) + { + LLDrawPoolAvatar::sSkipOpaque = true; + avatarp->renderSkinned(); + LLDrawPoolAvatar::sSkipOpaque = false; + } + else if (pass == SHADOW_PASS_ATTACHMENT_ALPHA_BLEND) // rigged alpha + { + LLDrawPoolAvatar::sSkipOpaque = true; + renderRigged(avatarp, RIGGED_MATERIAL_ALPHA); + renderRigged(avatarp, RIGGED_MATERIAL_ALPHA_EMISSIVE); + renderRigged(avatarp, RIGGED_ALPHA); + renderRigged(avatarp, RIGGED_FULLBRIGHT_ALPHA); + renderRigged(avatarp, RIGGED_GLOW); + renderRigged(avatarp, RIGGED_SPECMAP_BLEND); + renderRigged(avatarp, RIGGED_NORMMAP_BLEND); + renderRigged(avatarp, RIGGED_NORMSPEC_BLEND); + LLDrawPoolAvatar::sSkipOpaque = false; + } + else if (pass == SHADOW_PASS_ATTACHMENT_ALPHA_MASK) // rigged alpha mask + { + LLDrawPoolAvatar::sSkipOpaque = true; + renderRigged(avatarp, RIGGED_MATERIAL_ALPHA_MASK); + renderRigged(avatarp, RIGGED_NORMMAP_MASK); + renderRigged(avatarp, RIGGED_SPECMAP_MASK); + renderRigged(avatarp, RIGGED_NORMSPEC_MASK); + renderRigged(avatarp, RIGGED_GLOW); + LLDrawPoolAvatar::sSkipOpaque = false; + } + else // rigged opaque (SHADOW_PASS_ATTACHMENT_OPAQUE + { + LLDrawPoolAvatar::sSkipTransparent = true; + renderRigged(avatarp, RIGGED_MATERIAL); + renderRigged(avatarp, RIGGED_SPECMAP); + renderRigged(avatarp, RIGGED_SPECMAP_EMISSIVE); + renderRigged(avatarp, RIGGED_NORMMAP); + renderRigged(avatarp, RIGGED_NORMMAP_EMISSIVE); + renderRigged(avatarp, RIGGED_NORMSPEC); + renderRigged(avatarp, RIGGED_NORMSPEC_EMISSIVE); + renderRigged(avatarp, RIGGED_SIMPLE); + renderRigged(avatarp, RIGGED_FULLBRIGHT); + renderRigged(avatarp, RIGGED_SHINY); + renderRigged(avatarp, RIGGED_FULLBRIGHT_SHINY); + renderRigged(avatarp, RIGGED_GLOW); + renderRigged(avatarp, RIGGED_DEFERRED_BUMP); + renderRigged(avatarp, RIGGED_DEFERRED_SIMPLE); + LLDrawPoolAvatar::sSkipTransparent = false; + } + } } S32 LLDrawPoolAvatar::getNumPasses() @@ -1794,7 +1804,7 @@ void LLDrawPoolAvatar::getRiggedGeometry( U16 offset = 0; - LLMatrix4 mat_vert = skin->mBindShapeMatrix; + LLMatrix4 mat_vert = LLMatrix4(skin->mBindShapeMatrix); glh::matrix4f m((F32*) mat_vert.mMatrix); m = m.inverse().transpose(); @@ -1968,14 +1978,11 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( skin = vobj->getSkinInfo(); } - //build matrix palette - LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT]; - U32 count = LLSkinningUtil::getMeshJointCount(skin); - LLSkinningUtil::initSkinningMatrixPalette((LLMatrix4*)mat, count, skin, avatar); - LLSkinningUtil::checkSkinWeights(weights, buffer->getNumVerts(), skin); + const MatrixPaletteCache& mpc = updateSkinInfoMatrixPalette(avatar, skin); + const LLMatrix4a* mat = &(mpc.mMatrixPalette[0]); - LLMatrix4a bind_shape_matrix; - bind_shape_matrix.loadu(skin->mBindShapeMatrix); + LLSkinningUtil::checkSkinWeights(weights, buffer->getNumVerts(), skin); + const LLMatrix4a& bind_shape_matrix = skin->mBindShapeMatrix; #if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS U8* joint_indices_cursor = vol_face.mJointIndices; @@ -2043,6 +2050,8 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) { + LL_PROFILE_ZONE_SCOPED; + if (!avatar->shouldRenderRigged()) { return; @@ -2050,15 +2059,18 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) stop_glerror(); + const LLMeshSkinInfo* lastSkin = nullptr; + for (U32 i = 0; i < mRiggedFace[type].size(); ++i) { + LL_PROFILE_ZONE_NAMED("Render Rigged Face"); LLFace* face = mRiggedFace[type][i]; S32 offset = face->getIndicesStart(); U32 count = face->getIndicesCount(); U16 start = face->getGeomStart(); - U16 end = start + face->getGeomCount()-1; + U16 end = start + face->getGeomCount()-1; LLDrawable* drawable = face->getDrawable(); if (!drawable) @@ -2180,52 +2192,32 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) } if (buff) - { + { if (sShaderLevel > 0) { - // upload matrix palette to shader - LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT]; - U32 count = LLSkinningUtil::getMeshJointCount(skin); - LLSkinningUtil::initSkinningMatrixPalette((LLMatrix4*)mat, count, skin, avatar); - - stop_glerror(); - - F32 mp[LL_MAX_JOINTS_PER_MESH_OBJECT*12]; - - for (U32 i = 0; i < count; ++i) - { - F32* m = (F32*) mat[i].mMatrix[0].getF32ptr(); - - U32 idx = i*12; - - mp[idx+0] = m[0]; - mp[idx+1] = m[1]; - mp[idx+2] = m[2]; - mp[idx+3] = m[12]; - - mp[idx+4] = m[4]; - mp[idx+5] = m[5]; - mp[idx+6] = m[6]; - mp[idx+7] = m[13]; + if (lastSkin != skin) // <== only upload matrix palette to GL if the skininfo changed + { + // upload matrix palette to shader + const MatrixPaletteCache& mpc = updateSkinInfoMatrixPalette(avatar, skin); + U32 count = mpc.mMatrixPalette.size(); - mp[idx+8] = m[8]; - mp[idx+9] = m[9]; - mp[idx+10] = m[10]; - mp[idx+11] = m[14]; - } + stop_glerror(); - LLDrawPoolAvatar::sVertexProgram->uniformMatrix3x4fv(LLViewerShaderMgr::AVATAR_MATRIX, - count, - FALSE, - (GLfloat*) mp); + LLDrawPoolAvatar::sVertexProgram->uniformMatrix3x4fv(LLViewerShaderMgr::AVATAR_MATRIX, + count, + FALSE, + (GLfloat*) &(mpc.mGLMp[0])); - stop_glerror(); + stop_glerror(); + } } else { data_mask &= ~LLVertexBuffer::MAP_WEIGHT4; } + lastSkin = skin; + /*if (glow) { gGL.diffuseColor4f(0,0,0,face->getTextureEntry()->getGlow()); @@ -2391,6 +2383,70 @@ void LLDrawPoolAvatar::updateRiggedVertexBuffers(LLVOAvatar* avatar) } } +void LLDrawPoolAvatar::updateSkinInfoMatrixPalettes(LLVOAvatar* avatarp) +{ + LL_PROFILE_ZONE_SCOPED; + //evict matrix palettes from the cache that haven't been updated in 10 frames + for (matrix_palette_cache_t::iterator iter = mMatrixPaletteCache.begin(); iter != mMatrixPaletteCache.end(); ) + { + if (gFrameCount - iter->second.mFrame > 10) + { + iter = mMatrixPaletteCache.erase(iter); + } + else + { + ++iter; + } + } +} + +const LLDrawPoolAvatar::MatrixPaletteCache& LLDrawPoolAvatar::updateSkinInfoMatrixPalette(LLVOAvatar * avatarp, const LLMeshSkinInfo* skin) +{ + MatrixPaletteCache& entry = mMatrixPaletteCache[skin]; + + if (entry.mFrame != gFrameCount) + { + LL_PROFILE_ZONE_SCOPED; + entry.mFrame = gFrameCount; + //build matrix palette + U32 count = LLSkinningUtil::getMeshJointCount(skin); + entry.mMatrixPalette.resize(count); + LLSkinningUtil::initSkinningMatrixPalette(&(entry.mMatrixPalette[0]), count, skin, avatarp); + + const LLMatrix4a* mat = &(entry.mMatrixPalette[0]); + + stop_glerror(); + + entry.mGLMp.resize(count * 12); + + F32* mp = &(entry.mGLMp[0]); + + for (U32 i = 0; i < count; ++i) + { + F32* m = (F32*)mat[i].mMatrix[0].getF32ptr(); + + U32 idx = i * 12; + + mp[idx + 0] = m[0]; + mp[idx + 1] = m[1]; + mp[idx + 2] = m[2]; + mp[idx + 3] = m[12]; + + mp[idx + 4] = m[4]; + mp[idx + 5] = m[5]; + mp[idx + 6] = m[6]; + mp[idx + 7] = m[13]; + + mp[idx + 8] = m[8]; + mp[idx + 9] = m[9]; + mp[idx + 10] = m[10]; + mp[idx + 11] = m[14]; + } + } + + return entry; +} + void LLDrawPoolAvatar::renderRiggedSimple(LLVOAvatar* avatar) { renderRigged(avatar, RIGGED_SIMPLE); diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h index 9b26266ced..0c1ee2cced 100644 --- a/indra/newview/lldrawpoolavatar.h +++ b/indra/newview/lldrawpoolavatar.h @@ -28,15 +28,18 @@ #define LL_LLDRAWPOOLAVATAR_H #include "lldrawpool.h" +#include "llmodel.h" + +#include class LLVOAvatar; class LLVOVolume; class LLGLSLShader; class LLFace; -class LLMeshSkinInfo; class LLVolume; class LLVolumeFace; +extern U32 gFrameCount; class LLDrawPoolAvatar : public LLFacePool { @@ -259,6 +262,8 @@ typedef enum LLVolumeFace& vol_face); void updateRiggedVertexBuffers(LLVOAvatar* avatar); + void updateSkinInfoMatrixPalettes(LLVOAvatar* avatarp); + void renderRigged(LLVOAvatar* avatar, U32 type, bool glow = false); void renderRiggedSimple(LLVOAvatar* avatar); void renderRiggedAlpha(LLVOAvatar* avatar); @@ -278,6 +283,26 @@ typedef enum std::vector mRiggedFace[NUM_RIGGED_PASSES]; + class MatrixPaletteCache + { + public: + U32 mFrame; + LLMeshSkinInfo::matrix_list_t mMatrixPalette; + + // Float array ready to be sent to GL + std::vector mGLMp; + + MatrixPaletteCache() : + mFrame(gFrameCount-1) + { + } + }; + + const MatrixPaletteCache& updateSkinInfoMatrixPalette(LLVOAvatar* avatarp, const LLMeshSkinInfo* skin); + + typedef std::unordered_map matrix_palette_cache_t; + matrix_palette_cache_t mMatrixPaletteCache; + /*virtual*/ LLViewerTexture *getDebugTexture(); /*virtual*/ LLColor3 getDebugColor() const; // For AGP debug display diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index d9edd4dc30..0e54b66ea9 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -1357,31 +1357,31 @@ void LLFloaterModelPreview::clearAvatarTab() } void LLFloaterModelPreview::updateAvatarTab(bool highlight_overrides) - { +{ S32 display_lod = mModelPreview->mPreviewLOD; if (mModelPreview->mModel[display_lod].empty()) - { + { mSelectedJointName.clear(); return; - } + } // Joints will be listed as long as they are listed in mAlternateBindMatrix // even if they are for some reason identical to defaults. // Todo: Are overrides always identical for all lods? They normally are, but there might be situations where they aren't. if (mJointOverrides[display_lod].empty()) - { + { // populate map for (LLModelLoader::scene::iterator iter = mModelPreview->mScene[display_lod].begin(); iter != mModelPreview->mScene[display_lod].end(); ++iter) - { + { for (LLModelLoader::model_instance_list::iterator model_iter = iter->second.begin(); model_iter != iter->second.end(); ++model_iter) - { + { LLModelInstance& instance = *model_iter; LLModel* model = instance.mModel; const LLMeshSkinInfo *skin = &model->mSkinInfo; U32 joint_count = LLSkinningUtil::getMeshJointCount(skin); U32 bind_count = highlight_overrides ? skin->mAlternateBindMatrix.size() : 0; // simply do not include overrides if data is not needed if (bind_count > 0 && bind_count != joint_count) - { + { std::ostringstream out; out << "Invalid joint overrides for model " << model->getName(); out << ". Amount of joints " << joint_count; @@ -1390,68 +1390,68 @@ void LLFloaterModelPreview::updateAvatarTab(bool highlight_overrides) addStringToLog(out.str(), true); // Disable overrides for this model bind_count = 0; - } + } if (bind_count > 0) - { + { for (U32 j = 0; j < joint_count; ++j) - { - const LLVector3& joint_pos = skin->mAlternateBindMatrix[j].getTranslation(); + { + const LLVector3& joint_pos = LLVector3(skin->mAlternateBindMatrix[j].getTranslation()); LLJointOverrideData &data = mJointOverrides[display_lod][skin->mJointNames[j]]; LLJoint* pJoint = LLModelPreview::lookupJointByName(skin->mJointNames[j], mModelPreview); if (pJoint) - { + { // see how voavatar uses aboveJointPosThreshold if (pJoint->aboveJointPosThreshold(joint_pos)) - { + { // valid override if (data.mPosOverrides.size() > 0 && (data.mPosOverrides.begin()->second - joint_pos).lengthSquared() > (LL_JOINT_TRESHOLD_POS_OFFSET * LL_JOINT_TRESHOLD_POS_OFFSET)) - { + { // File contains multiple meshes with conflicting joint offsets // preview may be incorrect, upload result might wary (depends onto // mesh_id that hasn't been generated yet). data.mHasConflicts = true; - } + } data.mPosOverrides[model->getName()] = joint_pos; - } - else - { + } + else + { // default value, it won't be accounted for by avatar data.mModelsNoOverrides.insert(model->getName()); - } - } - } - } - else - { + } + } + } + } + else + { for (U32 j = 0; j < joint_count; ++j) - { + { LLJointOverrideData &data = mJointOverrides[display_lod][skin->mJointNames[j]]; data.mModelsNoOverrides.insert(model->getName()); } } - } - } - } + } + } + } LLPanel *panel = mTabContainer->getPanelByName("rigging_panel"); LLScrollListCtrl *joints_list = panel->getChild("joints_list"); if (joints_list->isEmpty()) - { + { // Populate table - std::map joint_alias_map; + std::map joint_alias_map; mModelPreview->getJointAliases(joint_alias_map); - + S32 conflicts = 0; joint_override_data_map_t::iterator joint_iter = mJointOverrides[display_lod].begin(); joint_override_data_map_t::iterator joint_end = mJointOverrides[display_lod].end(); while (joint_iter != joint_end) - { + { const std::string& listName = joint_iter->first; - + LLScrollListItem::Params item_params; item_params.value(listName); @@ -1459,38 +1459,38 @@ void LLFloaterModelPreview::updateAvatarTab(bool highlight_overrides) cell_params.font = LLFontGL::getFontSansSerif(); cell_params.value = listName; if (joint_alias_map.find(listName) == joint_alias_map.end()) - { + { // Missing names cell_params.color = LLColor4::red; - } + } if (joint_iter->second.mHasConflicts) - { + { // Conflicts cell_params.color = LLColor4::orange; conflicts++; - } + } if (highlight_overrides && joint_iter->second.mPosOverrides.size() > 0) - { + { cell_params.font.style = "BOLD"; - } + } item_params.columns.add(cell_params); joints_list->addRow(item_params, ADD_BOTTOM); joint_iter++; - } + } joints_list->selectFirstItem(); LLScrollListItem *selected = joints_list->getFirstSelected(); if (selected) -{ + { mSelectedJointName = selected->getValue().asString(); - } + } LLTextBox *joint_conf_descr = panel->getChild("conflicts_description"); joint_conf_descr->setTextArg("[CONFLICTS]", llformat("%d", conflicts)); joint_conf_descr->setTextArg("[JOINTS_COUNT]", llformat("%d", mJointOverrides[display_lod].size())); - } - } + } +} //----------------------------------------------------------------------------- // addStringToLogTab() diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index a9e80ab5da..01bddd781d 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -591,7 +591,7 @@ void LLModelPreview::rebuildUploadData() bool upload_skinweights = fmp && fmp->childGetValue("upload_skin").asBoolean(); if (upload_skinweights && high_lod_model->mSkinInfo.mJointNames.size() > 0) { - LLQuaternion bind_rot = LLSkinningUtil::getUnscaledQuaternion(high_lod_model->mSkinInfo.mBindShapeMatrix); + LLQuaternion bind_rot = LLSkinningUtil::getUnscaledQuaternion(LLMatrix4(high_lod_model->mSkinInfo.mBindShapeMatrix)); LLQuaternion identity; if (!bind_rot.isEqualEps(identity, 0.01)) { @@ -3298,7 +3298,7 @@ BOOL LLModelPreview::render() LLJoint *joint = getPreviewAvatar()->getJoint(skin->mJointNums[j]); if (joint) { - const LLVector3& jointPos = skin->mAlternateBindMatrix[j].getTranslation(); + const LLVector3& jointPos = LLVector3(skin->mAlternateBindMatrix[j].getTranslation()); if (joint->aboveJointPosThreshold(jointPos)) { bool override_changed; @@ -3340,11 +3340,10 @@ BOOL LLModelPreview::render() //build matrix palette LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT]; - LLSkinningUtil::initSkinningMatrixPalette((LLMatrix4*)mat, joint_count, + LLSkinningUtil::initSkinningMatrixPalette(mat, joint_count, skin, getPreviewAvatar()); - LLMatrix4a bind_shape_matrix; - bind_shape_matrix.loadu(skin->mBindShapeMatrix); + const LLMatrix4a& bind_shape_matrix = skin->mBindShapeMatrix; U32 max_joints = LLSkinningUtil::getMaxJointCount(); for (U32 j = 0; j < buffer->getNumVerts(); ++j) { diff --git a/indra/newview/llskinningutil.cpp b/indra/newview/llskinningutil.cpp index e02b21f036..dc12de29fb 100644 --- a/indra/newview/llskinningutil.cpp +++ b/indra/newview/llskinningutil.cpp @@ -35,7 +35,6 @@ #include "llrigginginfo.h" #define DEBUG_SKINNING LL_DEBUG -#define MAT_USE_SSE 1 void dump_avatar_and_skin_state(const std::string& reason, LLVOAvatar *avatar, const LLMeshSkinInfo *skin) { @@ -120,36 +119,26 @@ void LLSkinningUtil::scrubInvalidJoints(LLVOAvatar *avatar, LLMeshSkinInfo* skin skin->mInvalidJointsScrubbed = true; } -#define MAT_USE_SSE 1 - void LLSkinningUtil::initSkinningMatrixPalette( - LLMatrix4* mat, + LLMatrix4a* mat, S32 count, const LLMeshSkinInfo* skin, LLVOAvatar *avatar) { + LL_PROFILE_ZONE_SCOPED; + initJointNums(const_cast(skin), avatar); + + LLMatrix4a world[LL_CHARACTER_MAX_ANIMATED_JOINTS]; + for (U32 j = 0; j < count; ++j) { S32 joint_num = skin->mJointNums[j]; - LLJoint *joint = NULL; - if (joint_num >= 0 && joint_num < LL_CHARACTER_MAX_ANIMATED_JOINTS) - { - joint = avatar->getJoint(joint_num); - } - llassert(joint); + LLJoint *joint = avatar->getJoint(joint_num); + if (joint) { -#ifdef MAT_USE_SSE - LLMatrix4a bind, world, res; - bind.loadu(skin->mInvBindMatrix[j]); - world.loadu(joint->getWorldMatrix()); - matMul(bind,world,res); - memcpy(mat[j].mMatrix,res.mMatrix,16*sizeof(float)); -#else - mat[j] = skin->mInvBindMatrix[j]; - mat[j] *= joint->getWorldMatrix(); -#endif + world[j] = joint->getWorldMatrix4a(); } else { @@ -159,16 +148,27 @@ void LLSkinningUtil::initSkinningMatrixPalette( // rendering should be disabled unless all joints are // valid. In other cases of skinned rendering, invalid // joints should already have been removed during scrubInvalidJoints(). - LL_WARNS_ONCE("Avatar") << avatar->getFullname() - << " rigged to invalid joint name " << skin->mJointNames[j] - << " num " << skin->mJointNums[j] << LL_ENDL; - LL_WARNS_ONCE("Avatar") << avatar->getFullname() - << " avatar build state: isBuilt() " << avatar->isBuilt() - << " mInitFlags " << avatar->mInitFlags << LL_ENDL; + LL_WARNS_ONCE("Avatar") << avatar->getFullname() + << " rigged to invalid joint name " << skin->mJointNames[j] + << " num " << skin->mJointNums[j] << LL_ENDL; + LL_WARNS_ONCE("Avatar") << avatar->getFullname() + << " avatar build state: isBuilt() " << avatar->isBuilt() + << " mInitFlags " << avatar->mInitFlags << LL_ENDL; #endif dump_avatar_and_skin_state("initSkinningMatrixPalette joint not found", avatar, skin); } } + + //NOTE: pointer striders used here as a micro-optimization over vector/array lookups + const LLMatrix4a* invBind = &(skin->mInvBindMatrix[0]); + const LLMatrix4a* w = world; + LLMatrix4a* m = mat; + LLMatrix4a* end = m + count; + + while (m < end) + { + matMulUnsafe(*(invBind++), *(w++), *(m++)); + } } void LLSkinningUtil::checkSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin) @@ -212,7 +212,7 @@ void LLSkinningUtil::scrubSkinWeights(LLVector4a* weights, U32 num_vertices, con void LLSkinningUtil::getPerVertexSkinMatrix( F32* weights, - LLMatrix4a* mat, + const LLMatrix4a* mat, bool handle_bad_scale, LLMatrix4a& final_mat, U32 max_joints) @@ -270,6 +270,7 @@ void LLSkinningUtil::initJointNums(LLMeshSkinInfo* skin, LLVOAvatar *avatar) { if (!skin->mJointNumsInitialized) { + LL_PROFILE_ZONE_SCOPED; for (U32 j = 0; j < skin->mJointNames.size(); ++j) { #if DEBUG_SKINNING @@ -357,13 +358,11 @@ void LLSkinningUtil::updateRiggingInfo(const LLMeshSkinInfo* skin, LLVOAvatar *a rig_info_tab[joint_num].setIsRiggedTo(true); // FIXME could precompute these matMuls. - LLMatrix4a bind_shape; - LLMatrix4a inv_bind; + const LLMatrix4a& bind_shape = skin->mBindShapeMatrix; + const LLMatrix4a& inv_bind = skin->mInvBindMatrix[joint_index]; LLMatrix4a mat; LLVector4a pos_joint_space; - bind_shape.loadu(skin->mBindShapeMatrix); - inv_bind.loadu(skin->mInvBindMatrix[joint_index]); matMul(bind_shape, inv_bind, mat); mat.affineTransform(pos, pos_joint_space); @@ -426,3 +425,4 @@ LLQuaternion LLSkinningUtil::getUnscaledQuaternion(const LLMatrix4& mat4) bind_rot.normalize(); return bind_rot; } + diff --git a/indra/newview/llskinningutil.h b/indra/newview/llskinningutil.h index efe7c85997..807418f983 100644 --- a/indra/newview/llskinningutil.h +++ b/indra/newview/llskinningutil.h @@ -42,10 +42,10 @@ namespace LLSkinningUtil S32 getMaxJointCount(); U32 getMeshJointCount(const LLMeshSkinInfo *skin); void scrubInvalidJoints(LLVOAvatar *avatar, LLMeshSkinInfo* skin); - void initSkinningMatrixPalette(LLMatrix4* mat, S32 count, const LLMeshSkinInfo* skin, LLVOAvatar *avatar); + void initSkinningMatrixPalette(LLMatrix4a* mat, S32 count, const LLMeshSkinInfo* skin, LLVOAvatar *avatar); void checkSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin); void scrubSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin); - void getPerVertexSkinMatrix(F32* weights, LLMatrix4a* mat, bool handle_bad_scale, LLMatrix4a& final_mat, U32 max_joints); + void getPerVertexSkinMatrix(F32* weights, const LLMatrix4a* mat, bool handle_bad_scale, LLMatrix4a& final_mat, U32 max_joints); LL_FORCE_INLINE void getPerVertexSkinMatrixWithIndices( F32* weights, diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index ca01bb46aa..af55f68cd2 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -208,6 +208,7 @@ void LLViewerTextureManager::findTextures(const LLUUID& id, std::vector=attachment_start) + if (joint_num >= 0) { - // Attachment IDs start at 1 - S32 attachment_id = joint_num - attachment_start + 1; - attachment_map_t::iterator iter = mAttachmentPoints.find(attachment_id); - if (iter != mAttachmentPoints.end()) + if (joint_num < mNumBones) { - pJoint = iter->second; + pJoint = mSkeleton[joint_num]; + } + else if (joint_num < mNumBones + mNumCollisionVolumes) + { + S32 collision_id = joint_num - mNumBones; + pJoint = &mCollisionVolumes[collision_id]; + } + else + { + // Attachment IDs start at 1 + S32 attachment_id = joint_num - (mNumBones + mNumCollisionVolumes) + 1; + attachment_map_t::iterator iter = mAttachmentPoints.find(attachment_id); + if (iter != mAttachmentPoints.end()) + { + pJoint = iter->second; + } } } - else if (joint_num>=collision_start) - { - S32 collision_id = joint_num-collision_start; - pJoint = &mCollisionVolumes[collision_id]; - } - else if (joint_num>=0) - { - pJoint = mSkeleton[joint_num]; - } + llassert(!pJoint || pJoint->getJointNum() == joint_num); return pJoint; } @@ -6515,7 +6519,7 @@ void LLVOAvatar::addAttachmentOverridesForObject(LLViewerObject *vo, std::setmAlternateBindMatrix[i].getTranslation(); + const LLVector3& jointPos = LLVector3(pSkinData->mAlternateBindMatrix[i].getTranslation()); if (pJoint->aboveJointPosThreshold(jointPos)) { bool override_changed; @@ -7864,6 +7868,8 @@ void LLVOAvatar::onGlobalColorChanged(const LLTexGlobalColor* global_color) // Do rigged mesh attachments display with this av? bool LLVOAvatar::shouldRenderRigged() const { + LL_PROFILE_ZONE_SCOPED; + if (getOverallAppearance() == AOA_NORMAL) { return true; @@ -10951,6 +10957,7 @@ void LLVOAvatar::updateOverallAppearanceAnimations() // Based on isVisuallyMuted(), but has 3 possible results. LLVOAvatar::AvatarOverallAppearance LLVOAvatar::getOverallAppearance() const { + LL_PROFILE_ZONE_SCOPED; AvatarOverallAppearance result = AOA_NORMAL; // Priority order (highest priority first) diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 74ef589ca4..39adaab8ca 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -209,6 +209,11 @@ public: virtual LLJoint* getJoint(const std::string &name); LLJoint* getJoint(S32 num); + //if you KNOW joint_num is a valid animated joint index, use getSkeletonJoint for efficiency + inline LLJoint* getSkeletonJoint(S32 joint_num) { return mSkeleton[joint_num]; } + inline size_t getSkeletonJointCount() const { return mSkeleton.size(); } + + void addAttachmentOverridesForObject(LLViewerObject *vo, std::set* meshes_seen = NULL, bool recursive = true); void removeAttachmentOverridesForObject(const LLUUID& mesh_id); void removeAttachmentOverridesForObject(LLViewerObject *vo); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index f9b2285989..e5a4b0f374 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -4807,7 +4807,7 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons LLMatrix4a mat[kMaxJoints]; U32 maxJoints = LLSkinningUtil::getMeshJointCount(skin); - LLSkinningUtil::initSkinningMatrixPalette((LLMatrix4*)mat, maxJoints, skin, avatar); + LLSkinningUtil::initSkinningMatrixPalette(mat, maxJoints, skin, avatar); S32 rigged_vert_count = 0; S32 rigged_face_count = 0; @@ -4823,8 +4823,7 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons if ( weight ) { LLSkinningUtil::checkSkinWeights(weight, dst_face.mNumVertices, skin); - LLMatrix4a bind_shape_matrix; - bind_shape_matrix.loadu(skin->mBindShapeMatrix); + const LLMatrix4a& bind_shape_matrix = skin->mBindShapeMatrix; LLVector4a* pos = dst_face.mPositions; -- cgit v1.2.3 From 014dd037dde0a93f6c591618e4c111c6b598b60e Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 20 Sep 2021 21:22:17 +0000 Subject: SL-16043 Fix DisableVerticalSync, default DisableVerticalSync to off, remove broken frame limiter code (use vsync if you want to limit framerate). --- indra/llwindow/llwindowwin32.cpp | 3 ++- indra/newview/app_settings/settings.xml | 15 ++------------ indra/newview/llappviewer.cpp | 35 +-------------------------------- indra/newview/llappviewer.h | 7 +------ 4 files changed, 6 insertions(+), 54 deletions(-) diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index b2b123f0da..585905893b 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -784,7 +784,7 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks, LLCoordScreen windowPos(x,y); LLCoordScreen windowSize(window_rect.right - window_rect.left, window_rect.bottom - window_rect.top); - if (!switchContext(mFullscreen, windowSize, TRUE, &windowPos)) + if (!switchContext(mFullscreen, windowSize, disable_vsync, &windowPos)) { return; } @@ -1764,6 +1764,7 @@ const S32 max_format = (S32)num_formats - 1; else { LL_DEBUGS("Window") << "Keeping vertical sync" << LL_ENDL; + wglSwapIntervalEXT(1); } SetWindowLongPtr(mWindowHandle, GWLP_USERDATA, (LONG_PTR)this); diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index b1120c18b2..05c3fc3bfe 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -812,17 +812,6 @@ Value 0 - FramePerSecondLimit - - Comment - Controls upper limit of frames per second - Persist - 1 - Type - U32 - Value - 120 - BackgroundYieldTime Comment @@ -3366,13 +3355,13 @@ DisableVerticalSync Comment - Update frames as fast as possible (FALSE = update frames between display scans) + Update frames as fast as possible (FALSE = update frames between display scans). Requires restart. Persist 1 Type Boolean Value - 1 + 0 EnableGroupChatPopups diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 94f0b31ecd..a71ef69512 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -694,8 +694,7 @@ LLAppViewer::LLAppViewer() mPeriodicSlowFrame(LLCachedControl(gSavedSettings,"Periodic Slow Frame", FALSE)), mFastTimerLogThread(NULL), mSettingsLocationList(NULL), - mIsFirstRun(false), - mMinMicroSecPerFrame(0.f) + mIsFirstRun(false) { if(NULL != sInstance) { @@ -1326,10 +1325,6 @@ bool LLAppViewer::init() joystick = LLViewerJoystick::getInstance(); joystick->setNeedsReset(true); /*----------------------------------------------------------------------*/ - - gSavedSettings.getControl("FramePerSecondLimit")->getSignal()->connect(boost::bind(&LLAppViewer::onChangeFrameLimit, this, _2)); - onChangeFrameLimit(gSavedSettings.getLLSD("FramePerSecondLimit")); - // Load User's bindings loadKeyBindings(); @@ -1518,21 +1513,6 @@ bool LLAppViewer::doFrame() display(); - static U64 last_call = 0; - if (!gTeleportDisplay) - { - // Frame/draw throttling, controlled by FramePerSecondLimit - U64 elapsed_time = LLTimer::getTotalTime() - last_call; - if (elapsed_time < mMinMicroSecPerFrame) - { - LL_RECORD_BLOCK_TIME(FTM_SLEEP); - // llclamp for when time function gets funky - U64 sleep_time = llclamp(mMinMicroSecPerFrame - elapsed_time, (U64)1, (U64)1e6); - micro_sleep(sleep_time, 0); - } - } - last_call = LLTimer::getTotalTime(); - pingMainloopTimeout("Main:Snapshot"); LLFloaterSnapshot::update(); // take snapshots LLFloaterOutfitSnapshot::update(); @@ -5613,19 +5593,6 @@ void LLAppViewer::disconnectViewer() LLUrlEntryParcel::setDisconnected(gDisconnected); } -bool LLAppViewer::onChangeFrameLimit(LLSD const & evt) -{ - if (evt.asInteger() > 0) - { - mMinMicroSecPerFrame = (U64)(1000000.0f / F32(evt.asInteger())); - } - else - { - mMinMicroSecPerFrame = 0; - } - return false; -} - void LLAppViewer::forceErrorLLError() { LL_ERRS() << "This is a deliberate llerror" << LL_ENDL; diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index 0afb70958c..64e7caa36b 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -262,8 +262,6 @@ private: void sendLogoutRequest(); void disconnectViewer(); - bool onChangeFrameLimit(LLSD const & evt); - // *FIX: the app viewer class should be some sort of singleton, no? // Perhaps its child class is the singleton and this should be an abstract base. static LLAppViewer* sInstance; @@ -319,10 +317,7 @@ private: // llcorehttp library init/shutdown helper LLAppCoreHttp mAppCoreHttp; - bool mIsFirstRun; - U64 mMinMicroSecPerFrame; // frame throttling - - + bool mIsFirstRun; }; // consts from viewer.h -- cgit v1.2.3 From 316753352eaf5e1d555116f2f0f149c19521830f Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Tue, 21 Sep 2021 12:34:45 +0300 Subject: SL-15903 Restored the lost code --- indra/newview/viewer_manifest.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index ce7df2ccb5..55d1edb151 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -1064,15 +1064,19 @@ class DarwinManifest(ViewerManifest): # our apps executable_path = {} - self.path2basename(os.path.join(os.pardir, os.path.join("llplugin", "slplugin"), self.args['configuration']), "SLPlugin.app") - executable_path["SLPlugin.app"] = \ - self.dst_path_of(os.path.join("SLPlugin.app", "Contents", "MacOS")) - - # our apps dependencies on shared libs - # for each app, for each dylib we collected in dylibs, - # create a symlink to the real copy of the dylib. - with self.prefix(dst=os.path.join("SLPlugin.app", "Contents", "Resources")): - for libfile in dylibs: + embedded_apps = [ (os.path.join("llplugin", "slplugin"), "SLPlugin.app") ] + for app_bld_dir, app in embedded_apps: + self.path2basename(os.path.join(os.pardir, + app_bld_dir, self.args['configuration']), + app) + executable_path[app] = \ + self.dst_path_of(os.path.join(app, "Contents", "MacOS")) + + # our apps dependencies on shared libs + # for each app, for each dylib we collected in dylibs, + # create a symlink to the real copy of the dylib. + with self.prefix(dst=os.path.join(app, "Contents", "Resources")): + for libfile in dylibs: self.relsymlinkf(os.path.join(libfile_parent, libfile)) # Dullahan helper apps go inside SLPlugin.app -- cgit v1.2.3 From 4a411d98960c29925c8979e656d940b1af666db9 Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Tue, 21 Sep 2021 19:31:04 +0300 Subject: Revert "DRTVWR-520 Updated dullahan to codeticket build 562751" This reverts commit adb724564da73a4b2d1ebf7835ce628448048d87. --- autobuild.xml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 365311f369..b01ee685f7 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -580,9 +580,9 @@ archive hash - 499ae3458342185b47e6f1261d71891f + 49fff41e17e06cdf9eb0c737d20df52f url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/86091/796295/dullahan-1.12.2.202108121937_91.1.21_g9dd45fe_chromium-91.0.4472.114-darwin64-562751.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/83411/779825/dullahan-1.12.2.202106220202_91.1.21_g9dd45fe_chromium-91.0.4472.114-darwin64-560751.tar.bz2 name darwin64 @@ -592,9 +592,9 @@ archive hash - 4fa5ded4475264305a058423e553e6ad + f51f324d50a2461cda273e84fa65e0ad url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/86096/796319/dullahan-1.12.2.202108121946_91.1.21_g9dd45fe_chromium-91.0.4472.114-windows-562751.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/83413/779836/dullahan-1.12.2.202106220213_91.1.21_g9dd45fe_chromium-91.0.4472.114-windows-560751.tar.bz2 name windows @@ -604,16 +604,16 @@ archive hash - d4c5214819c901afc916e47f8715f3a7 + d3df46f6592715c75df2bf520c1ad68b url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/86095/796323/dullahan-1.12.2.202108121946_91.1.21_g9dd45fe_chromium-91.0.4472.114-windows64-562751.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/83412/779840/dullahan-1.12.2.202106220213_91.1.21_g9dd45fe_chromium-91.0.4472.114-windows64-560751.tar.bz2 name windows64 version - 1.12.2.202108121946_91.1.21_g9dd45fe_chromium-91.0.4472.114 + 1.12.2.202106220213_91.1.21_g9dd45fe_chromium-91.0.4472.114 elfio -- cgit v1.2.3 From 30c0043ba3171726d008f2f573fc90107e612c73 Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Tue, 21 Sep 2021 19:37:15 +0300 Subject: SL-15612 Check for SKIP_NOTARIZATION evn. variable --- indra/newview/installers/darwin/apple-notarize.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/indra/newview/installers/darwin/apple-notarize.sh b/indra/newview/installers/darwin/apple-notarize.sh index ecf5bd158a..2213914e6d 100755 --- a/indra/newview/installers/darwin/apple-notarize.sh +++ b/indra/newview/installers/darwin/apple-notarize.sh @@ -1,4 +1,9 @@ #!/bin/sh +if [ -n $SKIP_NOTARIZATION ]; then + echo "Skipping notarization" + exit 0 +fi + CONFIG_FILE="$build_secrets_checkout/code-signing-osx/notarize_creds.sh" if [ -f "$CONFIG_FILE" ]; then source $CONFIG_FILE -- cgit v1.2.3 From f2582cacf7746f42736d683eed8cad69f4cff6d7 Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Tue, 21 Sep 2021 19:42:43 +0300 Subject: SL-15612 Value fix --- indra/newview/installers/darwin/apple-notarize.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/installers/darwin/apple-notarize.sh b/indra/newview/installers/darwin/apple-notarize.sh index 2213914e6d..466898ecda 100755 --- a/indra/newview/installers/darwin/apple-notarize.sh +++ b/indra/newview/installers/darwin/apple-notarize.sh @@ -1,5 +1,5 @@ #!/bin/sh -if [ -n $SKIP_NOTARIZATION ]; then +if [[ $SKIP_NOTARIZATION == "true" ]]; then echo "Skipping notarization" exit 0 fi -- cgit v1.2.3 From a35544c701b223ba08f0607c872d8afbb08114f5 Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Tue, 21 Sep 2021 15:56:18 -0700 Subject: SL-16027: Add Tracy OpenGL support --- indra/llcommon/linden_common.h | 4 +--- indra/llcommon/llprofiler.h | 3 +++ indra/llrender/llglheaders.h | 19 +++++++++++++++++++ indra/llrender/llrendertarget.cpp | 2 ++ indra/llrender/llvertexbuffer.cpp | 5 +++++ indra/llwindow/llwindowwin32.cpp | 4 ++++ indra/newview/llappviewerwin32.cpp | 4 ++++ indra/newview/llface.cpp | 1 + indra/newview/llspatialpartition.cpp | 11 +++++++++-- indra/newview/pipeline.cpp | 1 + 10 files changed, 49 insertions(+), 5 deletions(-) diff --git a/indra/llcommon/linden_common.h b/indra/llcommon/linden_common.h index b2c5be6b76..a228fd22be 100644 --- a/indra/llcommon/linden_common.h +++ b/indra/llcommon/linden_common.h @@ -28,7 +28,7 @@ #define LL_LINDEN_COMMON_H #include "llprofiler.h" -#if (TRACY_ENABLE) // hooks for memory profiling +#if TRACY_ENABLE && !defined(LL_PROFILER_ENABLE_TRACY_OPENGL) // hooks for memory profiling void *tracy_aligned_malloc(size_t size, size_t alignment); void tracy_aligned_free(void *memblock); #define _aligned_malloc(X, Y) tracy_aligned_malloc((X), (Y)) @@ -68,6 +68,4 @@ void tracy_aligned_free(void *memblock); #include "llerror.h" #include "llfile.h" -#include "llprofiler.h" // must be before fast timer; needed due to LLThreads potentially needing access to tracy - #endif diff --git a/indra/llcommon/llprofiler.h b/indra/llcommon/llprofiler.h index 62e649913b..62ec20fa44 100644 --- a/indra/llcommon/llprofiler.h +++ b/indra/llcommon/llprofiler.h @@ -45,6 +45,9 @@ // #define TRACY_ONLY_LOCALHOST 1 #define TRACY_ONLY_IPV4 1 #include "Tracy.hpp" + + // Mutually exclusive with detailed memory tracing + #define LL_PROFILER_ENABLE_TRACY_OPENGL 0 #endif #if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h index 6bca3623e0..e7f9315d11 100644 --- a/indra/llrender/llglheaders.h +++ b/indra/llrender/llglheaders.h @@ -812,4 +812,23 @@ extern void glGetBufferPointervARB (GLenum, GLenum, GLvoid* *); #define GL_RENDERBUFFER_FREE_MEMORY_ATI 0x87FD #endif +#if LL_PROFILER_ENABLE_TRACY_OPENGL + // Tracy uses the following: + // glGenQueries + // glGetQueryiv + // glGetQueryObjectiv + #define glGenQueries glGenQueriesARB + #define glGetQueryiv glGetQueryivARB + #define glGetQueryObjectiv glGetQueryObjectivARB + #include + + #define LL_PROFILER_GPU_ZONEC(name,color) TracyGpuZoneC(name,color); + #define LL_PROFILER_GPU_COLLECT TracyGpuCollect + #define LL_PROFILER_GPU_CONTEXT TracyGpuContext +#else + #define LL_PROFILER_GPU_ZONEC(name,color) (void)name;(void)color; + #define LL_PROFILER_GPU_COLLECT + #define LL_PROFILER_GPU_CONTEXT +#endif + #endif // LL_LLGLHEADERS_H diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp index e3c0255290..401085a00b 100644 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -437,11 +437,13 @@ void LLRenderTarget::bindTarget() GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3}; + LL_PROFILER_GPU_ZONEC( "gl.DrawBuffersARB", 0x4000FF ) glDrawBuffersARB(mTex.size(), drawbuffers); } if (mTex.empty()) { //no color buffer to draw to + LL_PROFILER_GPU_ZONEC( "gl.DrawBuffer", 0x0000FF ) glDrawBuffer(GL_NONE); glReadBuffer(GL_NONE); } diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 7d2b09ca4a..b69b644ebc 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -615,6 +615,7 @@ void LLVertexBuffer::drawArrays(U32 mode, const std::vector& pos, con glNormalPointer(GL_FLOAT, 0, norm[0].mV); } LLGLSLShader::startProfile(); + LL_PROFILER_GPU_ZONEC( "gl.DrawArrays", 0xFF0000 ) glDrawArrays(sGLMode[mode], 0, count); LLGLSLShader::stopProfile(count, mode); } @@ -654,6 +655,7 @@ void LLVertexBuffer::drawElements(U32 mode, const LLVector4a* pos, const LLVecto } LLGLSLShader::startProfile(); + LL_PROFILER_GPU_ZONEC( "gl.DrawElements", 0x80FF80 ) glDrawElements(sGLMode[mode], num_indices, GL_UNSIGNED_SHORT, indicesp); LLGLSLShader::stopProfile(num_indices, mode); } @@ -763,6 +765,7 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi stop_glerror(); LLGLSLShader::startProfile(); + LL_PROFILER_GPU_ZONEC( "gl.DrawRangeElements", 0xFFFF00 ) glDrawRangeElements(sGLMode[mode], start, end, count, GL_UNSIGNED_SHORT, idx); LLGLSLShader::stopProfile(count, mode); @@ -814,6 +817,7 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const stop_glerror(); LLGLSLShader::startProfile(); + LL_PROFILER_GPU_ZONEC( "gl.DrawElements", 0xA0FFA0 ) glDrawElements(sGLMode[mode], count, GL_UNSIGNED_SHORT, ((U16*) getIndicesPointer()) + indices_offset); LLGLSLShader::stopProfile(count, mode); @@ -861,6 +865,7 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const stop_glerror(); LLGLSLShader::startProfile(); stop_glerror(); + LL_PROFILER_GPU_ZONEC( "gl.DrawArrays", 0xFF4040 ) glDrawArrays(sGLMode[mode], first, count); stop_glerror(); LLGLSLShader::stopProfile(count, mode); diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index b2b123f0da..1b8881cc86 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -1748,6 +1748,8 @@ const S32 max_format = (S32)num_formats - 1; return FALSE; } + LL_PROFILER_GPU_CONTEXT + if (!gGLManager.initGL()) { close(); @@ -3474,6 +3476,8 @@ BOOL LLWindowWin32::resetDisplayResolution() void LLWindowWin32::swapBuffers() { SwapBuffers(mhDC); + + LL_PROFILER_GPU_COLLECT } diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index 9daea515e5..fb53a7648d 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -323,6 +323,10 @@ int APIENTRY WINMAIN(HINSTANCE hInstance, PWSTR pCmdLine, int nCmdShow) { + // Call Tracy first thing to have it allocate memory + // https://github.com/wolfpld/tracy/issues/196 + LL_PROFILER_FRAME_END + const S32 MAX_HEAPS = 255; DWORD heap_enable_lfh_error[MAX_HEAPS]; S32 num_heaps = 0; diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 4a802ad9aa..6e55d8f66a 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -585,6 +585,7 @@ void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color) glTexCoordPointer(2, GL_FLOAT, 8, vol_face.mTexCoords); } gGL.syncMatrices(); + LL_PROFILER_GPU_ZONEC( "gl.DrawElements", 0x00FF00 ); glDrawElements(GL_TRIANGLES, vol_face.mNumIndices, GL_UNSIGNED_SHORT, vol_face.mIndices); glDisableClientState(GL_TEXTURE_COORD_ARRAY); } diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index efa4a7fd66..0adf58a0bf 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -2700,11 +2700,17 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume) glVertexPointer(3, GL_FLOAT, 16, phys_volume->mHullPoints); gGL.diffuseColor4fv(line_color.mV); gGL.syncMatrices(); - glDrawElements(GL_TRIANGLES, phys_volume->mNumHullIndices, GL_UNSIGNED_SHORT, phys_volume->mHullIndices); + { + LL_PROFILER_GPU_ZONEC( "gl.DrawElements", 0x20FF20 ) + glDrawElements(GL_TRIANGLES, phys_volume->mNumHullIndices, GL_UNSIGNED_SHORT, phys_volume->mHullIndices); + } gGL.diffuseColor4fv(color.mV); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - glDrawElements(GL_TRIANGLES, phys_volume->mNumHullIndices, GL_UNSIGNED_SHORT, phys_volume->mHullIndices); + { + LL_PROFILER_GPU_ZONEC( "gl.DrawElements", 0x40FF40 ) + glDrawElements(GL_TRIANGLES, phys_volume->mNumHullIndices, GL_UNSIGNED_SHORT, phys_volume->mHullIndices); + } } else { @@ -3222,6 +3228,7 @@ void renderRaycast(LLDrawable* drawablep) gGL.diffuseColor4f(0,1,1,0.5f); glVertexPointer(3, GL_FLOAT, sizeof(LLVector4a), face.mPositions); gGL.syncMatrices(); + LL_PROFILER_GPU_ZONEC( "gl.DrawElements", 0x60FF60 ); glDrawElements(GL_TRIANGLES, face.mNumIndices, GL_UNSIGNED_SHORT, face.mIndices); } diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index e7c2d4db39..4e28c8c493 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -11146,6 +11146,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) if (LLPipeline::sRenderDeferred) { GLuint buff = GL_COLOR_ATTACHMENT0; + LL_PROFILER_GPU_ZONEC( "gl.DrawBuffersARB", 0x8000FF ); glDrawBuffersARB(1, &buff); } -- cgit v1.2.3 From d03ade68d36525a8b7abc0a783636cebda006ef4 Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Tue, 21 Sep 2021 17:46:11 -0700 Subject: SL-16027: Only enable Tracy OpengL macros if Tracy is enabled --- indra/llrender/llglheaders.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h index e7f9315d11..3d93cc0762 100644 --- a/indra/llrender/llglheaders.h +++ b/indra/llrender/llglheaders.h @@ -812,7 +812,7 @@ extern void glGetBufferPointervARB (GLenum, GLenum, GLvoid* *); #define GL_RENDERBUFFER_FREE_MEMORY_ATI 0x87FD #endif -#if LL_PROFILER_ENABLE_TRACY_OPENGL +#if defined(TRACY_ENABLE) && LL_PROFILER_ENABLE_TRACY_OPENGL // Tracy uses the following: // glGenQueries // glGetQueryiv -- cgit v1.2.3 From a68ca665ade56d21a8c939a7e26332f1de413698 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Fri, 17 Sep 2021 15:29:00 +0300 Subject: SL-15958 Stop impostored avatars from casting shadows --- doc/contributions.txt | 1 + indra/newview/lldrawpoolavatar.cpp | 5 ++--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/contributions.txt b/doc/contributions.txt index a8deb9c2ae..537df59c8c 100755 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -271,6 +271,7 @@ Beq Janus SL-14766 SL-14927 SL-15709 + SL-16021 Beth Walcher Bezilon Kasei Biancaluce Robbiani diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index c7aa104ca5..d8491d60ee 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -583,10 +583,9 @@ void LLDrawPoolAvatar::renderShadow(S32 pass) } LLVOAvatar::AvatarOverallAppearance oa = avatarp->getOverallAppearance(); BOOL impostor = !LLPipeline::sImpostorRender && avatarp->isImpostor(); - if (oa == LLVOAvatar::AOA_INVISIBLE || - (impostor && oa == LLVOAvatar::AOA_JELLYDOLL)) + if (impostor || (oa == LLVOAvatar::AOA_INVISIBLE)) { - // No shadows for jellydolled or invisible avs. + // No shadows for impostored (including jellydolled) or invisible avs. return; } -- cgit v1.2.3 From b4bb74c5def3175d99d672b0b26f941b756f5f45 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 22 Sep 2021 21:37:01 +0000 Subject: SL-16031 Add support for VS 2019 (requires autobuild 1.2-alpha) --- indra/cmake/Copy3rdPartyLibs.cmake | 2 ++ indra/newview/llexperiencelog.cpp | 4 ---- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index 46ddb9d15b..75601ddfcb 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -97,6 +97,8 @@ if(WINDOWS) set(MSVC_VER 120) elseif (MSVC_VERSION GREATER_EQUAL 1910 AND MSVC_VERSION LESS 1920) # Visual Studio 2017 set(MSVC_VER 140) + elseif (MSVC_VERSION GREATER_EQUAL 1920 AND MSVC_VERSION LESS 1930) # Visual Studio 2019 + set(MSVC_VER 140) else (MSVC80) MESSAGE(WARNING "New MSVC_VERSION ${MSVC_VERSION} of MSVC: adapt Copy3rdPartyLibs.cmake") endif (MSVC80) diff --git a/indra/newview/llexperiencelog.cpp b/indra/newview/llexperiencelog.cpp index ee5d561927..c441fbc09f 100644 --- a/indra/newview/llexperiencelog.cpp +++ b/indra/newview/llexperiencelog.cpp @@ -149,10 +149,6 @@ std::string LLExperienceLog::getPermissionString( const LLSD& message, const std { buf.str(entry); } - else - { - buf.str(); - } } if(buf.str().empty()) -- cgit v1.2.3 From 25089265699afe6c2a035f81259e8fd1e4b7008f Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Wed, 15 Sep 2021 15:39:48 -0700 Subject: SL-16014 Add Tracy logging to lldrawpoolavatar.cpp --- indra/newview/lldrawpoolavatar.cpp | 126 ++++++++++++++++++++++++++++++++++++- 1 file changed, 125 insertions(+), 1 deletion(-) diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index c04142ab47..4f615d6107 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -121,6 +121,8 @@ LLDrawPoolAvatar::~LLDrawPoolAvatar() // virtual BOOL LLDrawPoolAvatar::isDead() { + LL_PROFILE_ZONE_SCOPED + if (!LLFacePool::isDead()) { return FALSE; @@ -138,11 +140,15 @@ BOOL LLDrawPoolAvatar::isDead() S32 LLDrawPoolAvatar::getShaderLevel() const { + LL_PROFILE_ZONE_SCOPED + return (S32) LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR); } void LLDrawPoolAvatar::prerender() { + LL_PROFILE_ZONE_SCOPED + mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR); sShaderLevel = mShaderLevel; @@ -169,6 +175,8 @@ void LLDrawPoolAvatar::prerender() LLMatrix4& LLDrawPoolAvatar::getModelView() { + LL_PROFILE_ZONE_SCOPED + static LLMatrix4 ret; ret.initRows(LLVector4(gGLModelView+0), @@ -257,6 +265,8 @@ void LLDrawPoolAvatar::endDeferredPass(S32 pass) void LLDrawPoolAvatar::renderDeferred(S32 pass) { + LL_PROFILE_ZONE_SCOPED + render(pass); } @@ -267,6 +277,8 @@ S32 LLDrawPoolAvatar::getNumPostDeferredPasses() void LLDrawPoolAvatar::beginPostDeferredPass(S32 pass) { + LL_PROFILE_ZONE_SCOPED + switch (pass) { case 0: @@ -295,6 +307,8 @@ void LLDrawPoolAvatar::beginPostDeferredPass(S32 pass) void LLDrawPoolAvatar::beginPostDeferredAlpha() { + LL_PROFILE_ZONE_SCOPED + sSkipOpaque = TRUE; sShaderLevel = mShaderLevel; sVertexProgram = &gDeferredAvatarAlphaProgram; @@ -309,6 +323,8 @@ void LLDrawPoolAvatar::beginPostDeferredAlpha() void LLDrawPoolAvatar::beginDeferredRiggedAlpha() { + LL_PROFILE_ZONE_SCOPED + sVertexProgram = &gDeferredSkinnedAlphaProgram; gPipeline.bindDeferredShader(*sVertexProgram); sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); @@ -317,6 +333,8 @@ void LLDrawPoolAvatar::beginDeferredRiggedAlpha() void LLDrawPoolAvatar::beginDeferredRiggedMaterialAlpha(S32 pass) { + LL_PROFILE_ZONE_SCOPED + switch (pass) { case 0: pass = 1; break; @@ -343,6 +361,8 @@ void LLDrawPoolAvatar::beginDeferredRiggedMaterialAlpha(S32 pass) void LLDrawPoolAvatar::endDeferredRiggedAlpha() { + LL_PROFILE_ZONE_SCOPED + LLVertexBuffer::unbind(); gPipeline.unbindDeferredShader(*sVertexProgram); sDiffuseChannel = 0; @@ -353,6 +373,8 @@ void LLDrawPoolAvatar::endDeferredRiggedAlpha() void LLDrawPoolAvatar::endPostDeferredPass(S32 pass) { + LL_PROFILE_ZONE_SCOPED + switch (pass) { case 0: @@ -381,6 +403,8 @@ void LLDrawPoolAvatar::endPostDeferredPass(S32 pass) void LLDrawPoolAvatar::endPostDeferredAlpha() { + LL_PROFILE_ZONE_SCOPED + // if we're in software-blending, remember to set the fence _after_ we draw so we wait till this rendering is done sRenderingSkinned = FALSE; sSkipOpaque = FALSE; @@ -392,6 +416,8 @@ void LLDrawPoolAvatar::endPostDeferredAlpha() void LLDrawPoolAvatar::renderPostDeferred(S32 pass) { + LL_PROFILE_ZONE_SCOPED + static const S32 actual_pass[] = { //map post deferred pass numbers to what render() expects 2, //skinned @@ -647,6 +673,8 @@ void LLDrawPoolAvatar::renderShadow(S32 pass) S32 LLDrawPoolAvatar::getNumPasses() { + LL_PROFILE_ZONE_SCOPED + if (LLPipeline::sImpostorRender) { return 8; @@ -660,6 +688,8 @@ S32 LLDrawPoolAvatar::getNumPasses() S32 LLDrawPoolAvatar::getNumDeferredPasses() { + LL_PROFILE_ZONE_SCOPED + if (LLPipeline::sImpostorRender) { return 19; @@ -780,6 +810,8 @@ void LLDrawPoolAvatar::endRenderPass(S32 pass) void LLDrawPoolAvatar::beginImpostor() { + LL_PROFILE_ZONE_SCOPED + if (!LLPipeline::sReflectionRender) { LLVOAvatar::sRenderDistance = llclamp(LLVOAvatar::sRenderDistance, 16.f, 256.f); @@ -798,6 +830,8 @@ void LLDrawPoolAvatar::beginImpostor() void LLDrawPoolAvatar::endImpostor() { + LL_PROFILE_ZONE_SCOPED + if (LLGLSLShader::sNoFixedFunction) { gImpostorProgram.unbind(); @@ -807,6 +841,8 @@ void LLDrawPoolAvatar::endImpostor() void LLDrawPoolAvatar::beginRigid() { + LL_PROFILE_ZONE_SCOPED + if (gPipeline.canUseVertexShaders()) { if (LLPipeline::sUnderWaterRender) @@ -840,6 +876,8 @@ void LLDrawPoolAvatar::beginRigid() void LLDrawPoolAvatar::endRigid() { + LL_PROFILE_ZONE_SCOPED + sShaderLevel = mShaderLevel; if (sVertexProgram != NULL) { @@ -849,6 +887,8 @@ void LLDrawPoolAvatar::endRigid() void LLDrawPoolAvatar::beginDeferredImpostor() { + LL_PROFILE_ZONE_SCOPED + if (!LLPipeline::sReflectionRender) { LLVOAvatar::sRenderDistance = llclamp(LLVOAvatar::sRenderDistance, 16.f, 256.f); @@ -865,6 +905,8 @@ void LLDrawPoolAvatar::beginDeferredImpostor() void LLDrawPoolAvatar::endDeferredImpostor() { + LL_PROFILE_ZONE_SCOPED + sShaderLevel = mShaderLevel; sVertexProgram->disableTexture(LLViewerShaderMgr::DEFERRED_NORMAL); sVertexProgram->disableTexture(LLViewerShaderMgr::SPECULAR_MAP); @@ -876,6 +918,8 @@ void LLDrawPoolAvatar::endDeferredImpostor() void LLDrawPoolAvatar::beginDeferredRigid() { + LL_PROFILE_ZONE_SCOPED + sVertexProgram = &gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram; sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); sVertexProgram->bind(); @@ -892,6 +936,8 @@ void LLDrawPoolAvatar::beginDeferredRigid() void LLDrawPoolAvatar::endDeferredRigid() { + LL_PROFILE_ZONE_SCOPED + sShaderLevel = mShaderLevel; sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP); sVertexProgram->unbind(); @@ -901,6 +947,8 @@ void LLDrawPoolAvatar::endDeferredRigid() void LLDrawPoolAvatar::beginSkinned() { + LL_PROFILE_ZONE_SCOPED + if (sShaderLevel > 0) { if (LLPipeline::sUnderWaterRender) @@ -967,6 +1015,8 @@ void LLDrawPoolAvatar::beginSkinned() void LLDrawPoolAvatar::endSkinned() { + LL_PROFILE_ZONE_SCOPED + // if we're in software-blending, remember to set the fence _after_ we draw so we wait till this rendering is done if (sShaderLevel > 0) { @@ -991,6 +1041,8 @@ void LLDrawPoolAvatar::endSkinned() void LLDrawPoolAvatar::beginRiggedSimple() { + LL_PROFILE_ZONE_SCOPED + if (sShaderLevel > 0) { if (LLPipeline::sUnderWaterRender) @@ -1031,6 +1083,8 @@ void LLDrawPoolAvatar::beginRiggedSimple() void LLDrawPoolAvatar::endRiggedSimple() { + LL_PROFILE_ZONE_SCOPED + LLVertexBuffer::unbind(); if (sShaderLevel > 0 || gPipeline.canUseVertexShaders()) { @@ -1041,27 +1095,37 @@ void LLDrawPoolAvatar::endRiggedSimple() void LLDrawPoolAvatar::beginRiggedAlpha() { + LL_PROFILE_ZONE_SCOPED + beginRiggedSimple(); } void LLDrawPoolAvatar::endRiggedAlpha() { + LL_PROFILE_ZONE_SCOPED + endRiggedSimple(); } void LLDrawPoolAvatar::beginRiggedFullbrightAlpha() { + LL_PROFILE_ZONE_SCOPED + beginRiggedFullbright(); } void LLDrawPoolAvatar::endRiggedFullbrightAlpha() { + LL_PROFILE_ZONE_SCOPED + endRiggedFullbright(); } void LLDrawPoolAvatar::beginRiggedGlow() { + LL_PROFILE_ZONE_SCOPED + if (sShaderLevel > 0) { if (LLPipeline::sUnderWaterRender) @@ -1108,11 +1172,15 @@ void LLDrawPoolAvatar::beginRiggedGlow() void LLDrawPoolAvatar::endRiggedGlow() { + LL_PROFILE_ZONE_SCOPED + endRiggedFullbright(); } void LLDrawPoolAvatar::beginRiggedFullbright() { + LL_PROFILE_ZONE_SCOPED + if (sShaderLevel > 0) { if (LLPipeline::sUnderWaterRender) @@ -1170,6 +1238,8 @@ void LLDrawPoolAvatar::beginRiggedFullbright() void LLDrawPoolAvatar::endRiggedFullbright() { + LL_PROFILE_ZONE_SCOPED + LLVertexBuffer::unbind(); if (sShaderLevel > 0 || gPipeline.canUseVertexShaders()) { @@ -1180,6 +1250,8 @@ void LLDrawPoolAvatar::endRiggedFullbright() void LLDrawPoolAvatar::beginRiggedShinySimple() { + LL_PROFILE_ZONE_SCOPED + if (sShaderLevel > 0) { if (LLPipeline::sUnderWaterRender) @@ -1220,6 +1292,8 @@ void LLDrawPoolAvatar::beginRiggedShinySimple() void LLDrawPoolAvatar::endRiggedShinySimple() { + LL_PROFILE_ZONE_SCOPED + LLVertexBuffer::unbind(); if (sShaderLevel > 0 || gPipeline.canUseVertexShaders()) { @@ -1231,6 +1305,8 @@ void LLDrawPoolAvatar::endRiggedShinySimple() void LLDrawPoolAvatar::beginRiggedFullbrightShiny() { + LL_PROFILE_ZONE_SCOPED + if (sShaderLevel > 0) { if (LLPipeline::sUnderWaterRender) @@ -1296,6 +1372,8 @@ void LLDrawPoolAvatar::beginRiggedFullbrightShiny() void LLDrawPoolAvatar::endRiggedFullbrightShiny() { + LL_PROFILE_ZONE_SCOPED + LLVertexBuffer::unbind(); if (sShaderLevel > 0 || gPipeline.canUseVertexShaders()) { @@ -1308,6 +1386,8 @@ void LLDrawPoolAvatar::endRiggedFullbrightShiny() void LLDrawPoolAvatar::beginDeferredRiggedSimple() { + LL_PROFILE_ZONE_SCOPED + sVertexProgram = &gDeferredSkinnedDiffuseProgram; sDiffuseChannel = 0; sVertexProgram->bind(); @@ -1323,6 +1403,8 @@ void LLDrawPoolAvatar::beginDeferredRiggedSimple() void LLDrawPoolAvatar::endDeferredRiggedSimple() { + LL_PROFILE_ZONE_SCOPED + LLVertexBuffer::unbind(); sVertexProgram->unbind(); sVertexProgram = NULL; @@ -1330,6 +1412,8 @@ void LLDrawPoolAvatar::endDeferredRiggedSimple() void LLDrawPoolAvatar::beginDeferredRiggedBump() { + LL_PROFILE_ZONE_SCOPED + sVertexProgram = &gDeferredSkinnedBumpProgram; sVertexProgram->bind(); if (LLPipeline::sRenderingHUDs) @@ -1346,6 +1430,8 @@ void LLDrawPoolAvatar::beginDeferredRiggedBump() void LLDrawPoolAvatar::endDeferredRiggedBump() { + LL_PROFILE_ZONE_SCOPED + LLVertexBuffer::unbind(); sVertexProgram->disableTexture(LLViewerShaderMgr::BUMP_MAP); sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP); @@ -1357,6 +1443,8 @@ void LLDrawPoolAvatar::endDeferredRiggedBump() void LLDrawPoolAvatar::beginDeferredRiggedMaterial(S32 pass) { + LL_PROFILE_ZONE_SCOPED + if (pass == 1 || pass == 5 || pass == 9 || @@ -1387,6 +1475,8 @@ void LLDrawPoolAvatar::beginDeferredRiggedMaterial(S32 pass) void LLDrawPoolAvatar::endDeferredRiggedMaterial(S32 pass) { + LL_PROFILE_ZONE_SCOPED + if (pass == 1 || pass == 5 || pass == 9 || @@ -1407,6 +1497,8 @@ void LLDrawPoolAvatar::endDeferredRiggedMaterial(S32 pass) void LLDrawPoolAvatar::beginDeferredSkinned() { + LL_PROFILE_ZONE_SCOPED + sShaderLevel = mShaderLevel; sVertexProgram = &gDeferredAvatarProgram; sRenderingSkinned = TRUE; @@ -1428,6 +1520,8 @@ void LLDrawPoolAvatar::beginDeferredSkinned() void LLDrawPoolAvatar::endDeferredSkinned() { + LL_PROFILE_ZONE_SCOPED + // if we're in software-blending, remember to set the fence _after_ we draw so we wait till this rendering is done sRenderingSkinned = FALSE; sVertexProgram->unbind(); @@ -1740,6 +1834,8 @@ void LLDrawPoolAvatar::getRiggedGeometry( LLVolume* volume, const LLVolumeFace& vol_face) { + LL_PROFILE_ZONE_SCOPED + face->setGeomIndex(0); face->setIndicesIndex(0); @@ -2040,6 +2136,8 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) { + LL_PROFILE_ZONE_SCOPED + if (!avatar->shouldRenderRigged()) { return; @@ -2332,16 +2430,22 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) void LLDrawPoolAvatar::renderDeferredRiggedSimple(LLVOAvatar* avatar) { + LL_PROFILE_ZONE_SCOPED + renderRigged(avatar, RIGGED_DEFERRED_SIMPLE); } void LLDrawPoolAvatar::renderDeferredRiggedBump(LLVOAvatar* avatar) { + LL_PROFILE_ZONE_SCOPED + renderRigged(avatar, RIGGED_DEFERRED_BUMP); } void LLDrawPoolAvatar::renderDeferredRiggedMaterial(LLVOAvatar* avatar, S32 pass) { + LL_PROFILE_ZONE_SCOPED + renderRigged(avatar, pass); } @@ -2396,27 +2500,37 @@ void LLDrawPoolAvatar::updateRiggedVertexBuffers(LLVOAvatar* avatar) void LLDrawPoolAvatar::renderRiggedSimple(LLVOAvatar* avatar) { + LL_PROFILE_ZONE_SCOPED + renderRigged(avatar, RIGGED_SIMPLE); } void LLDrawPoolAvatar::renderRiggedFullbright(LLVOAvatar* avatar) { + LL_PROFILE_ZONE_SCOPED + renderRigged(avatar, RIGGED_FULLBRIGHT); } void LLDrawPoolAvatar::renderRiggedShinySimple(LLVOAvatar* avatar) { + LL_PROFILE_ZONE_SCOPED + renderRigged(avatar, RIGGED_SHINY); } void LLDrawPoolAvatar::renderRiggedFullbrightShiny(LLVOAvatar* avatar) { + LL_PROFILE_ZONE_SCOPED + renderRigged(avatar, RIGGED_FULLBRIGHT_SHINY); } void LLDrawPoolAvatar::renderRiggedAlpha(LLVOAvatar* avatar) { + LL_PROFILE_ZONE_SCOPED + if (!mRiggedFace[RIGGED_ALPHA].empty()) { LLGLEnable blend(GL_BLEND); @@ -2434,6 +2548,8 @@ void LLDrawPoolAvatar::renderRiggedAlpha(LLVOAvatar* avatar) void LLDrawPoolAvatar::renderRiggedFullbrightAlpha(LLVOAvatar* avatar) { + LL_PROFILE_ZONE_SCOPED + if (!mRiggedFace[RIGGED_FULLBRIGHT_ALPHA].empty()) { LLGLEnable blend(GL_BLEND); @@ -2451,6 +2567,8 @@ void LLDrawPoolAvatar::renderRiggedFullbrightAlpha(LLVOAvatar* avatar) void LLDrawPoolAvatar::renderRiggedGlow(LLVOAvatar* avatar) { + LL_PROFILE_ZONE_SCOPED + if (!mRiggedFace[RIGGED_GLOW].empty()) { LLGLEnable blend(GL_BLEND); @@ -2478,6 +2596,8 @@ void LLDrawPoolAvatar::renderRiggedGlow(LLVOAvatar* avatar) //----------------------------------------------------------------------------- LLViewerTexture *LLDrawPoolAvatar::getDebugTexture() { + LL_PROFILE_ZONE_SCOPED + if (mReferences.empty()) { return NULL; @@ -2501,6 +2621,8 @@ LLColor3 LLDrawPoolAvatar::getDebugColor() const void LLDrawPoolAvatar::addRiggedFace(LLFace* facep, U32 type) { + LL_PROFILE_ZONE_SCOPED + llassert (facep->isState(LLFace::RIGGED)); llassert(getType() == LLDrawPool::POOL_AVATAR || getType() == LLDrawPool::POOL_CONTROL_AV); if (facep->getPool() && facep->getPool() != this) @@ -2523,6 +2645,8 @@ void LLDrawPoolAvatar::addRiggedFace(LLFace* facep, U32 type) void LLDrawPoolAvatar::removeRiggedFace(LLFace* facep) { + LL_PROFILE_ZONE_SCOPED + llassert (facep->isState(LLFace::RIGGED)); llassert(getType() == LLDrawPool::POOL_AVATAR || getType() == LLDrawPool::POOL_CONTROL_AV); if (facep->getPool() != this) @@ -2560,7 +2684,7 @@ LLVertexBufferAvatar::LLVertexBufferAvatar() : LLVertexBuffer(sDataMask, GL_STREAM_DRAW_ARB) //avatars are always stream draw due to morph targets { - + LL_PROFILE_ZONE_SCOPED } -- cgit v1.2.3 From c0eadc87e8bc8ce5658f49a960af4868a0865ddc Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Wed, 15 Sep 2021 17:44:09 -0700 Subject: SL-16014: Add Tracy logging to doFrame() --- indra/newview/llappviewer.cpp | 74 ++++++++++++++++++++++++++++++++----------- 1 file changed, 56 insertions(+), 18 deletions(-) diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 94f0b31ecd..ab2b846c09 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1424,9 +1424,13 @@ bool LLAppViewer::doFrame() LLSD newFrame; LL_RECORD_BLOCK_TIME(FTM_FRAME); - LLTrace::BlockTimer::processTimes(); - LLTrace::get_frame_recording().nextPeriod(); - LLTrace::BlockTimer::logStats(); + + { + LL_PROFILE_ZONE_NAMED( ":blocktimer" ) + LLTrace::BlockTimer::processTimes(); + LLTrace::get_frame_recording().nextPeriod(); + LLTrace::BlockTimer::logStats(); + } LLTrace::get_thread_recorder()->pullFromChildren(); @@ -1434,6 +1438,7 @@ bool LLAppViewer::doFrame() LL_CLEAR_CALLSTACKS(); { + LL_PROFILE_ZONE_NAMED( ":processMiscNativeEvents" ) pingMainloopTimeout("Main:MiscNativeWindowEvents"); if (gViewerWindow) @@ -1442,7 +1447,10 @@ bool LLAppViewer::doFrame() gViewerWindow->getWindow()->processMiscNativeEvents(); } - pingMainloopTimeout("Main:GatherInput"); + { + LL_PROFILE_ZONE_NAMED( ":gatherInput" ) + pingMainloopTimeout("Main:GatherInput"); + } if (gViewerWindow) { @@ -1466,13 +1474,21 @@ bool LLAppViewer::doFrame() } } - // canonical per-frame event - mainloop.post(newFrame); - // give listeners a chance to run - llcoro::suspend(); + { + LL_PROFILE_ZONE_NAMED( ":mainloop" ) + // canonical per-frame event + mainloop.post(newFrame); + } + + { + LL_PROFILE_ZONE_NAMED( ":suspend" ) + // give listeners a chance to run + llcoro::suspend(); + } if (!LLApp::isExiting()) { + LL_PROFILE_ZONE_NAMED( ":JoystickKeyboard" ) pingMainloopTimeout("Main:JoystickKeyboard"); // Scan keyboard for movement keys. Command keys and typing @@ -1493,12 +1509,18 @@ bool LLAppViewer::doFrame() // Update state based on messages, user input, object idle. { - pauseMainloopTimeout(); // *TODO: Remove. Messages shouldn't be stalling for 20+ seconds! + { + LL_PROFILE_ZONE_NAMED( ":pauseMainloopTimeout" ) + pauseMainloopTimeout(); // *TODO: Remove. Messages shouldn't be stalling for 20+ seconds! + } LL_RECORD_BLOCK_TIME(FTM_IDLE); idle(); - resumeMainloopTimeout(); + { + LL_PROFILE_ZONE_NAMED( ":resumeMainloopTimeout" ) + resumeMainloopTimeout(); + } } if (gDoDisconnect && (LLStartUp::getStartupState() == STATE_STARTED)) @@ -1513,6 +1535,7 @@ bool LLAppViewer::doFrame() // *TODO: Should we run display() even during gHeadlessClient? DK 2011-02-18 if (!LLApp::isExiting() && !gHeadlessClient && gViewerWindow) { + LL_PROFILE_ZONE_NAMED( ":Display" ) pingMainloopTimeout("Main:Display"); gGLActive = TRUE; @@ -1533,16 +1556,22 @@ bool LLAppViewer::doFrame() } last_call = LLTimer::getTotalTime(); - pingMainloopTimeout("Main:Snapshot"); - LLFloaterSnapshot::update(); // take snapshots + { + LL_PROFILE_ZONE_NAMED( ":Snapshot" ) + pingMainloopTimeout("Main:Snapshot"); + LLFloaterSnapshot::update(); // take snapshots LLFloaterOutfitSnapshot::update(); - gGLActive = FALSE; + gGLActive = FALSE; + } } } - pingMainloopTimeout("Main:Sleep"); + { + LL_PROFILE_ZONE_NAMED( ":pauseMainloopTimeout" ) + pingMainloopTimeout("Main:Sleep"); - pauseMainloopTimeout(); + pauseMainloopTimeout(); + } // Sleep and run background threads { @@ -1615,16 +1644,22 @@ bool LLAppViewer::doFrame() total_io_pending += io_pending ; } - gMeshRepo.update() ; + + { + LL_PROFILE_ZONE_NAMED( ":gMeshRepo" ) + gMeshRepo.update() ; + } if(!total_work_pending) //pause texture fetching threads if nothing to process. { + LL_PROFILE_ZONE_NAMED( ":getTextureCache" ) LLAppViewer::getTextureCache()->pause(); LLAppViewer::getImageDecodeThread()->pause(); LLAppViewer::getTextureFetch()->pause(); } if(!total_io_pending) //pause file threads if nothing to process. { + LL_PROFILE_ZONE_NAMED( ":LLVFSThread" ) LLVFSThread::sLocal->pause(); LLLFSThread::sLocal->pause(); } @@ -1632,6 +1667,7 @@ bool LLAppViewer::doFrame() //texture fetching debugger if(LLTextureFetchDebugger::isEnabled()) { + LL_PROFILE_ZONE_NAMED( ":tex_fetch_debugger_instance" ) LLFloaterTextureFetchDebugger* tex_fetch_debugger_instance = LLFloaterReg::findTypedInstance("tex_fetch_debugger"); if(tex_fetch_debugger_instance) @@ -1640,8 +1676,10 @@ bool LLAppViewer::doFrame() } } - resumeMainloopTimeout(); - + { + LL_PROFILE_ZONE_NAMED( ":resumeMainloopTimeout" ) + resumeMainloopTimeout(); + } pingMainloopTimeout("Main:End"); } } -- cgit v1.2.3 From b9ad51981eb992ebe77b8ffbde48b2797ff55cef Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Mon, 20 Sep 2021 08:33:41 -0700 Subject: SL-16014: Add macros for better markup in Tracy --- indra/llcommon/llprofiler.h | 50 +++++++++++++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/indra/llcommon/llprofiler.h b/indra/llcommon/llprofiler.h index 62ec20fa44..59e7dc02c6 100644 --- a/indra/llcommon/llprofiler.h +++ b/indra/llcommon/llprofiler.h @@ -51,25 +51,49 @@ #endif #if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY - #define LL_PROFILER_FRAME_END FrameMark - #define LL_PROFILER_SET_THREAD_NAME( name ) tracy::SetThreadName( name ) - #define LL_RECORD_BLOCK_TIME(name) ZoneNamedN( ___tracy_scoped_zone, #name, true ); - #define LL_PROFILE_ZONE_NAMED(name) ZoneNamedN( ___tracy_scoped_zone, name, true ); - #define LL_PROFILE_ZONE_SCOPED ZoneScoped + #define LL_PROFILER_FRAME_END FrameMark + #define LL_PROFILER_SET_THREAD_NAME( name ) tracy::SetThreadName( name ) + #define LL_RECORD_BLOCK_TIME(name) ZoneScoped // Want descriptive names; was: ZoneNamedN( ___tracy_scoped_zone, #name, true ); + #define LL_PROFILE_ZONE_NAMED(name) ZoneNamedN( ___tracy_scoped_zone, name, true ); + #define LL_PROFILE_ZONE_NAMED_COLOR(name,color) ZoneNamedNC( ___tracy_scopped_zone, name, color, true ) // RGB + #define LL_PROFILE_ZONE_SCOPED ZoneScoped + + #define LL_PROFILE_ZONE_NUM( val ) ZoneValue( val ) + #define LL_PROFILE_ZONE_TEXT( text, size ) ZoneText( text, size ) + + #define LL_PROFILE_ZONE_ERR(name) LL_PROFILE_ZONE_NAMED_COLOR( name, 0XFF0000 ) // RGB yellow + #define LL_PROFILE_ZONE_INFO(name) LL_PROFILE_ZONE_NAMED_COLOR( name, 0X00FFFF ) // RGB cyan + #define LL_PROFILE_ZONE_WARN(name) LL_PROFILE_ZONE_NAMED_COLOR( name, 0x0FFFF00 ) // RGB red #endif #if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_FAST_TIMER #define LL_PROFILER_FRAME_END - #define LL_PROFILER_SET_THREAD_NAME( name ) (void)(name) + #define LL_PROFILER_SET_THREAD_NAME( name ) (void)(name) #define LL_RECORD_BLOCK_TIME(name) const LLTrace::BlockTimer& LL_GLUE_TOKENS(block_time_recorder, __LINE__)(LLTrace::timeThisBlock(name)); (void)LL_GLUE_TOKENS(block_time_recorder, __LINE__); - #define LL_PROFILE_ZONE_NAMED(name) // LL_PROFILE_ZONE_NAMED is a no-op when Tracy is disabled - #define LL_PROFILE_ZONE_SCOPED // LL_PROFILE_ZONE_SCOPED is a no-op when Tracy is disabled + #define LL_PROFILE_ZONE_NAMED(name) // LL_PROFILE_ZONE_NAMED is a no-op when Tracy is disabled + #define LL_PROFILE_ZONE_SCOPED // LL_PROFILE_ZONE_SCOPED is a no-op when Tracy is disabled + #define LL_PRPFILE_ZONE_COLOR(name,color) // LL_RECORD_BLOCK_TIME(name) + + #define LL_PROFILE_ZONE_NUM( val ) (void)( val ); // Not supported + #define LL_PROFILE_ZONE_TEXT( text, size ) (void)( text ); void( size ); // Not supported + + #define LL_PROFILE_ZONE_ERR(name) (void)(name); // Not supported + #define LL_PROFILE_ZONE_INFO(name) (void)(name); // Not supported + #define LL_PROFILE_ZONE_WARN(name) (void)(name); // Not supported #endif #if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY_FAST_TIMER - #define LL_PROFILER_FRAME_END FrameMark - #define LL_PROFILER_SET_THREAD_NAME( name ) tracy::SetThreadName( name ) - #define LL_RECORD_BLOCK_TIME(name) ZoneNamedN( ___tracy_scoped_zone, #timer_stat, true ) const LLTrace::BlockTimer& LL_GLUE_TOKENS(block_time_recorder, __LINE__)(LLTrace::timeThisBlock(name)); (void)LL_GLUE_TOKENS(block_time_recorder, __LINE__); - #define LL_PROFILE_ZONE_NAMED(name) ZoneNamedN( ___tracy_scoped_zone, #name, true ); - #define LL_PROFILE_ZONE_SCOPED ZoneScoped + #define LL_PROFILER_FRAME_END FrameMark + #define LL_PROFILER_SET_THREAD_NAME( name ) tracy::SetThreadName( name ) + #define LL_RECORD_BLOCK_TIME(name) ZoneScoped const LLTrace::BlockTimer& LL_GLUE_TOKENS(block_time_recorder, __LINE__)(LLTrace::timeThisBlock(name)); (void)LL_GLUE_TOKENS(block_time_recorder, __LINE__); + #define LL_PROFILE_ZONE_NAMED(name) ZoneNamedN( ___tracy_scoped_zone, #name, true ); + #define LL_PROFILE_ZONE_NAMED_COLOR(name,color) ZoneNamedNC( ___tracy_scopped_zone, name, color, true ) // RGB + #define LL_PROFILE_ZONE_SCOPED ZoneScoped + + #define LL_PROFILE_ZONE_NUM( val ) ZoneValue( val ) + #define LL_PROFILE_ZONE_TEXT( text, size ) ZoneText( text, size ) + + #define LL_PROFILE_ZONE_ERR(name) LL_PROFILE_ZONE_NAMED_COLOR( name, 0XFF0000 ) // RGB yellow + #define LL_PROFILE_ZONE_INFO(name) LL_PROFILE_ZONE_NAMED_COLOR( name, 0X00FFFF ) // RGB cyan + #define LL_PROFILE_ZONE_WARN(name) LL_PROFILE_ZONE_NAMED_COLOR( name, 0x0FFFF00 ) // RGB red #endif #else #define LL_PROFILER_FRAME_END -- cgit v1.2.3 From 6c53fbfb4700b40893cd69377999d29c7ba96099 Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Mon, 20 Sep 2021 09:43:38 -0700 Subject: SL-16014: Add Tracy markup for lldrawable --- indra/newview/lldrawable.cpp | 45 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 507af56cb0..30c4a21e1c 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -101,6 +101,8 @@ LLDrawable::LLDrawable(LLViewerObject *vobj, bool new_entry) void LLDrawable::init(bool new_entry) { + LL_PROFILE_ZONE_SCOPED + // mXform mParent = NULL; mRenderType = 0; @@ -232,6 +234,8 @@ void LLDrawable::markDead() LLVOVolume* LLDrawable::getVOVolume() const { + LL_PROFILE_ZONE_SCOPED + LLViewerObject* objectp = mVObjp; if ( !isDead() && objectp && (objectp->getPCode() == LL_PCODE_VOLUME)) { @@ -335,6 +339,7 @@ static LLTrace::BlockTimerStatHandle FTM_ALLOCATE_FACE("Allocate Face"); LLFace* LLDrawable::addFace(LLFacePool *poolp, LLViewerTexture *texturep) { + LL_PROFILE_ZONE_SCOPED LLFace *face; { @@ -363,6 +368,8 @@ LLFace* LLDrawable::addFace(LLFacePool *poolp, LLViewerTexture *texturep) LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep) { + LL_PROFILE_ZONE_SCOPED + LLFace *face; { @@ -387,6 +394,8 @@ LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep) LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep, LLViewerTexture *normalp) { + LL_PROFILE_ZONE_SCOPED + LLFace *face; face = new LLFace(this, mVObjp); @@ -408,6 +417,8 @@ LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep, LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep, LLViewerTexture *normalp, LLViewerTexture *specularp) { + LL_PROFILE_ZONE_SCOPED + LLFace *face; face = new LLFace(this, mVObjp); @@ -430,6 +441,8 @@ LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep, void LLDrawable::setNumFaces(const S32 newFaces, LLFacePool *poolp, LLViewerTexture *texturep) { + LL_PROFILE_ZONE_SCOPED + if (newFaces == (S32)mFaces.size()) { return; @@ -453,6 +466,8 @@ void LLDrawable::setNumFaces(const S32 newFaces, LLFacePool *poolp, LLViewerText void LLDrawable::setNumFacesFast(const S32 newFaces, LLFacePool *poolp, LLViewerTexture *texturep) { + LL_PROFILE_ZONE_SCOPED + if (newFaces <= (S32)mFaces.size() && newFaces >= (S32)mFaces.size()/2) { return; @@ -476,6 +491,8 @@ void LLDrawable::setNumFacesFast(const S32 newFaces, LLFacePool *poolp, LLViewer void LLDrawable::mergeFaces(LLDrawable* src) { + LL_PROFILE_ZONE_SCOPED + U32 face_count = mFaces.size() + src->mFaces.size(); mFaces.reserve(face_count); @@ -509,6 +526,8 @@ void LLDrawable::updateMaterial() void LLDrawable::makeActive() { + LL_PROFILE_ZONE_SCOPED + #if !LL_RELEASE_FOR_DOWNLOAD if (mVObjp.notNull()) { @@ -572,6 +591,8 @@ void LLDrawable::makeActive() void LLDrawable::makeStatic(BOOL warning_enabled) { + LL_PROFILE_ZONE_SCOPED + if (isState(ACTIVE) && !isState(ACTIVE_CHILD) && !mVObjp->isAttachment() && @@ -618,6 +639,8 @@ void LLDrawable::makeStatic(BOOL warning_enabled) // Returns "distance" between target destination and resulting xfrom F32 LLDrawable::updateXform(BOOL undamped) { + LL_PROFILE_ZONE_SCOPED + BOOL damped = !undamped; // Position @@ -769,6 +792,8 @@ void LLDrawable::moveUpdatePipeline(BOOL moved) void LLDrawable::movePartition() { + LL_PROFILE_ZONE_SCOPED + LLSpatialPartition* part = getSpatialPartition(); if (part) { @@ -813,6 +838,8 @@ BOOL LLDrawable::updateMoveUndamped() void LLDrawable::updatePartition() { + LL_PROFILE_ZONE_SCOPED + if (!getVOVolume()) { movePartition(); @@ -830,6 +857,8 @@ void LLDrawable::updatePartition() BOOL LLDrawable::updateMoveDamped() { + LL_PROFILE_ZONE_SCOPED + F32 dist_squared = updateXform(FALSE); mGeneration++; @@ -853,6 +882,8 @@ BOOL LLDrawable::updateMoveDamped() void LLDrawable::updateDistance(LLCamera& camera, bool force_update) { + LL_PROFILE_ZONE_SCOPED + if (LLViewerCamera::sCurCameraID != LLViewerCamera::CAMERA_WORLD) { LL_WARNS() << "Attempted to update distance for non-world camera." << LL_ENDL; @@ -957,6 +988,8 @@ void LLDrawable::updateTexture() BOOL LLDrawable::updateGeometry(BOOL priority) { + LL_PROFILE_ZONE_SCOPED + llassert(mVObjp.notNull()); BOOL res = mVObjp->updateGeometry(this); return res; @@ -1034,6 +1067,8 @@ const LLVector3& LLDrawable::getBounds(LLVector3& min, LLVector3& max) const void LLDrawable::updateSpatialExtents() { + LL_PROFILE_ZONE_SCOPED + if (mVObjp) { const LLVector4a* exts = getSpatialExtents(); @@ -1164,6 +1199,8 @@ void LLDrawable::setGroup(LLViewerOctreeGroup *groupp) LLSpatialPartition* LLDrawable::getSpatialPartition() { + LL_PROFILE_ZONE_SCOPED + LLSpatialPartition* retval = NULL; if (!mVObjp || @@ -1247,6 +1284,8 @@ LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 dat LLDrawable(root->getVObj(), true), LLSpatialPartition(data_mask, render_by_group, GL_STREAM_DRAW_ARB, regionp) { + LL_PROFILE_ZONE_SCOPED + mBridge = this; mDrawable = root; root->setSpatialBridge(this); @@ -1292,6 +1331,8 @@ void LLSpatialBridge::destroyTree() void LLSpatialBridge::updateSpatialExtents() { + LL_PROFILE_ZONE_SCOPED + LLSpatialGroup* root = (LLSpatialGroup*) mOctree->getListener(0); { @@ -1455,6 +1496,8 @@ public: void LLSpatialBridge::setVisible(LLCamera& camera_in, std::vector* results, BOOL for_select) { + LL_PROFILE_ZONE_SCOPED + if (!gPipeline.hasRenderType(mDrawableType)) { return; @@ -1552,6 +1595,8 @@ void LLSpatialBridge::setVisible(LLCamera& camera_in, std::vector* void LLSpatialBridge::updateDistance(LLCamera& camera_in, bool force_update) { + LL_PROFILE_ZONE_SCOPED + if (mDrawable == NULL) { markDead(); -- cgit v1.2.3 From dd3fc66b51e8a979a6f6bf8f7e1cfedb952d0d49 Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Mon, 20 Sep 2021 09:44:34 -0700 Subject: SL-16014: Add Tracy markup to LLFace --- indra/newview/llface.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 6e55d8f66a..34448a780d 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -241,6 +241,8 @@ void LLFace::setPool(LLFacePool* pool) void LLFace::setPool(LLFacePool* new_pool, LLViewerTexture *texturep) { + LL_PROFILE_ZONE_SCOPED + if (!new_pool) { LL_ERRS() << "Setting pool to null!" << LL_ENDL; @@ -320,6 +322,8 @@ void LLFace::setSpecularMap(LLViewerTexture* tex) void LLFace::dirtyTexture() { + LL_PROFILE_ZONE_SCOPED + LLDrawable* drawablep = getDrawable(); if (mVObjp.notNull() && mVObjp->getVolume()) @@ -535,6 +539,8 @@ void LLFace::updateCenterAgent() void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color) { + LL_PROFILE_ZONE_SCOPED + if (mDrawablep == NULL || mDrawablep->getSpatialGroup() == NULL) { return; @@ -606,6 +612,8 @@ void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color) void renderFace(LLDrawable* drawable, LLFace *face) { + LL_PROFILE_ZONE_SCOPED + LLVOVolume* vobj = drawable->getVOVolume(); if (vobj) { @@ -892,6 +900,8 @@ bool less_than_max_mag(const LLVector4a& vec) BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f, const LLMatrix4& mat_vert_in, BOOL global_volume) { + LL_PROFILE_ZONE_SCOPED + //get bounding box if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION | LLDrawable::REBUILD_RIGGED)) { @@ -2376,6 +2386,8 @@ F32 LLFace::getTextureVirtualSize() BOOL LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius) { + LL_PROFILE_ZONE_SCOPED + //VECTORIZE THIS //get area of circle around face LLVector4a center; @@ -2655,6 +2667,8 @@ const LLMatrix4& LLFace::getRenderMatrix() const S32 LLFace::renderElements(const U16 *index_array) const { + LL_PROFILE_ZONE_SCOPED + S32 ret = 0; if (isState(GLOBAL)) @@ -2674,6 +2688,8 @@ S32 LLFace::renderElements(const U16 *index_array) const S32 LLFace::renderIndexed() { + LL_PROFILE_ZONE_SCOPED + if(mDrawablep == NULL || mDrawPoolp == NULL) { return 0; @@ -2684,6 +2700,8 @@ S32 LLFace::renderIndexed() S32 LLFace::renderIndexed(U32 mask) { + LL_PROFILE_ZONE_SCOPED + if (mVertexBuffer.isNull()) { return 0; -- cgit v1.2.3 From 584a7f05df9b067c3e57b52c61d5e94fcfce6a19 Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Mon, 20 Sep 2021 09:45:17 -0700 Subject: SL-16014: Add Tracy markup to LLSpatialGroup --- indra/newview/llspatialpartition.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 0adf58a0bf..253b6b9953 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -503,7 +503,9 @@ LLSpatialGroup* LLSpatialGroup::getParent() } BOOL LLSpatialGroup::removeObject(LLDrawable *drawablep, BOOL from_octree) - { +{ + LL_PROFILE_ZONE_SCOPED + if(!drawablep) { return FALSE; @@ -591,6 +593,8 @@ public: void LLSpatialGroup::setState(U32 state, S32 mode) { + LL_PROFILE_ZONE_SCOPED + llassert(state <= LLSpatialGroup::STATE_MASK); if (mode > STATE_MODE_SINGLE) @@ -638,6 +642,8 @@ public: void LLSpatialGroup::clearState(U32 state, S32 mode) { + LL_PROFILE_ZONE_SCOPED + llassert(state <= LLSpatialGroup::STATE_MASK); if (mode > STATE_MODE_SINGLE) @@ -724,6 +730,8 @@ void LLSpatialGroup::updateDistance(LLCamera &camera) F32 LLSpatialPartition::calcDistance(LLSpatialGroup* group, LLCamera& camera) { + LL_PROFILE_ZONE_SCOPED + LLVector4a eye; LLVector4a origin; origin.load3(camera.getOrigin().mV); @@ -815,6 +823,8 @@ F32 LLSpatialGroup::getUpdateUrgency() const BOOL LLSpatialGroup::changeLOD() { + LL_PROFILE_ZONE_SCOPED + if (hasState(ALPHA_DIRTY | OBJECT_DIRTY)) { //a rebuild is going to happen, update distance and LoD @@ -907,6 +917,8 @@ void LLSpatialGroup::handleDestruction(const TreeNode* node) void LLSpatialGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* child) { + LL_PROFILE_ZONE_SCOPED + if (child->getListenerCount() == 0) { new LLSpatialGroup(child, getSpatialPartition()); -- cgit v1.2.3 From b78db5ae5c308f3a895e15a109d2814ca7f9ea94 Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Mon, 20 Sep 2021 09:45:52 -0700 Subject: SL-16014: Add Tracy markup to LLViewerObjectList --- indra/newview/llviewerobjectlist.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 63e48d1dd0..0b20556104 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -168,6 +168,8 @@ U64 LLViewerObjectList::getIndex(const U32 local_id, BOOL LLViewerObjectList::removeFromLocalIDTable(const LLViewerObject* objectp) { + LL_PROFILE_ZONE_SCOPED + if(objectp && objectp->getRegion()) { U32 local_id = objectp->mLocalID; @@ -303,6 +305,8 @@ static LLTrace::BlockTimerStatHandle FTM_PROCESS_OBJECTS("Process Objects"); LLViewerObject* LLViewerObjectList::processObjectUpdateFromCache(LLVOCacheEntry* entry, LLViewerRegion* regionp) { + LL_PROFILE_ZONE_SCOPED + LLDataPacker *cached_dpp = entry->getDP(); if (!cached_dpp) @@ -848,6 +852,8 @@ static LLTrace::BlockTimerStatHandle FTM_IDLE_COPY("Idle Copy"); void LLViewerObjectList::update(LLAgent &agent) { + LL_PROFILE_ZONE_SCOPED + // Update globals LLViewerObject::setVelocityInterpolate( gSavedSettings.getBOOL("VelocityInterpolate") ); LLViewerObject::setPingInterpolate( gSavedSettings.getBOOL("PingInterpolate") ); @@ -1293,6 +1299,8 @@ void LLViewerObjectList::clearDebugText() void LLViewerObjectList::cleanupReferences(LLViewerObject *objectp) { + LL_PROFILE_ZONE_SCOPED + bool new_dead_object = true; if (mDeadObjects.find(objectp->mID) != mDeadObjects.end()) { @@ -1523,6 +1531,8 @@ void LLViewerObjectList::removeFromActiveList(LLViewerObject* objectp) void LLViewerObjectList::updateActive(LLViewerObject *objectp) { + LL_PROFILE_ZONE_SCOPED + if (objectp->isDead()) { return; // We don't update dead objects! @@ -1843,6 +1853,8 @@ void LLViewerObjectList::renderObjectBounds(const LLVector3 ¢er) void LLViewerObjectList::generatePickList(LLCamera &camera) { + LL_PROFILE_ZONE_SCOPED + LLViewerObject *objectp; S32 i; // Reset all of the GL names to zero. @@ -2104,6 +2116,8 @@ LLViewerObject *LLViewerObjectList::replaceObject(const LLUUID &id, const LLPCod S32 LLViewerObjectList::findReferences(LLDrawable *drawablep) const { + LL_PROFILE_ZONE_SCOPED + LLViewerObject *objectp; S32 num_refs = 0; @@ -2167,6 +2181,8 @@ void LLViewerObjectList::orphanize(LLViewerObject *childp, U32 parent_id, U32 ip void LLViewerObjectList::findOrphans(LLViewerObject* objectp, U32 ip, U32 port) { + LL_PROFILE_ZONE_SCOPED + if (objectp->isDead()) { LL_WARNS() << "Trying to find orphans for dead obj " << objectp->mID -- cgit v1.2.3 From 51a887a51c4d86775006fea1d9522031142ec79d Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Mon, 20 Sep 2021 09:46:43 -0700 Subject: SL-16014: Add Tracy markup for LLSD --- indra/llcommon/llsdutil.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/indra/llcommon/llsdutil.cpp b/indra/llcommon/llsdutil.cpp index eb3a96b133..c2fe15e9b7 100644 --- a/indra/llcommon/llsdutil.cpp +++ b/indra/llcommon/llsdutil.cpp @@ -214,6 +214,8 @@ BOOL compare_llsd_with_template( const LLSD& template_llsd, LLSD& resultant_llsd) { + LL_PROFILE_ZONE_SCOPED + if ( llsd_to_test.isUndefined() && template_llsd.isDefined() ) @@ -335,6 +337,8 @@ bool filter_llsd_with_template( const LLSD & template_llsd, LLSD & resultant_llsd) { + LL_PROFILE_ZONE_SCOPED + if (llsd_to_test.isUndefined() && template_llsd.isDefined()) { resultant_llsd = template_llsd; @@ -529,6 +533,8 @@ class TypeLookup public: TypeLookup() { + LL_PROFILE_ZONE_SCOPED + for (const Data *di(boost::begin(typedata)), *dend(boost::end(typedata)); di != dend; ++di) { mMap[di->type] = di->name; @@ -537,6 +543,8 @@ public: std::string lookup(LLSD::Type type) const { + LL_PROFILE_ZONE_SCOPED + MapType::const_iterator found = mMap.find(type); if (found != mMap.end()) { @@ -587,6 +595,8 @@ static std::string match_types(LLSD::Type expect, // prototype.type() LLSD::Type actual, // type we're checking const std::string& pfx) // as for llsd_matches { + LL_PROFILE_ZONE_SCOPED + // Trivial case: if the actual type is exactly what we expect, we're good. if (actual == expect) return ""; @@ -624,6 +634,8 @@ static std::string match_types(LLSD::Type expect, // prototype.type() // see docstring in .h file std::string llsd_matches(const LLSD& prototype, const LLSD& data, const std::string& pfx) { + LL_PROFILE_ZONE_SCOPED + // An undefined prototype means that any data is valid. // An undefined slot in an array or map prototype means that any data // may fill that slot. @@ -756,6 +768,8 @@ std::string llsd_matches(const LLSD& prototype, const LLSD& data, const std::str bool llsd_equals(const LLSD& lhs, const LLSD& rhs, int bits) { + LL_PROFILE_ZONE_SCOPED + // We're comparing strict equality of LLSD representation rather than // performing any conversions. So if the types aren't equal, the LLSD // values aren't equal. @@ -864,6 +878,8 @@ namespace llsd LLSD& drill(LLSD& blob, const LLSD& rawPath) { + LL_PROFILE_ZONE_SCOPED + // Treat rawPath uniformly as an array. If it's not already an array, // store it as the only entry in one. (But let's say Undefined means an // empty array.) @@ -889,6 +905,8 @@ LLSD& drill(LLSD& blob, const LLSD& rawPath) // path entry that's bad. for (LLSD::Integer i = 0; i < path.size(); ++i) { + LL_PROFILE_ZONE_NUM( i ) + const LLSD& key{path[i]}; if (key.isString()) { @@ -917,6 +935,8 @@ LLSD& drill(LLSD& blob, const LLSD& rawPath) LLSD drill(const LLSD& blob, const LLSD& path) { + LL_PROFILE_ZONE_SCOPED + // non-const drill() does exactly what we want. Temporarily cast away // const-ness and use that. return drill(const_cast(blob), path); @@ -929,6 +949,8 @@ LLSD drill(const LLSD& blob, const LLSD& path) // filter may be include to exclude/include keys in a map. LLSD llsd_clone(LLSD value, LLSD filter) { + LL_PROFILE_ZONE_SCOPED + LLSD clone; bool has_filter(filter.isMap()); -- cgit v1.2.3 From 8e4907beeea1ca0474dd124c7f6b4bf5dba45c3e Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Mon, 20 Sep 2021 09:47:26 -0700 Subject: SL-16014: Add Tracy markup for LLVolumeFace --- indra/llmath/llvolume.cpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index e085fa6ada..130f30bedc 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -383,6 +383,7 @@ public: virtual void visit(const LLOctreeNode* branch) { //this is a depth first traversal, so it's safe to assum all children have complete //bounding data + LL_PROFILE_ZONE_SCOPED LLVolumeOctreeListener* node = (LLVolumeOctreeListener*) branch->getListener(0); @@ -822,6 +823,8 @@ S32 LLProfile::getNumPoints(const LLProfileParams& params, BOOL path_open,F32 de BOOL LLProfile::generate(const LLProfileParams& params, BOOL path_open,F32 detail, S32 split, BOOL is_sculpted, S32 sculpt_size) { + LL_PROFILE_ZONE_SCOPED + if ((!mDirty) && (!is_sculpted)) { return FALSE; @@ -1302,6 +1305,8 @@ S32 LLPath::getNumNGonPoints(const LLPathParams& params, S32 sides, F32 startOff void LLPath::genNGon(const LLPathParams& params, S32 sides, F32 startOff, F32 end_scale, F32 twist_scale) { + LL_PROFILE_ZONE_SCOPED + // Generates a circular path, starting at (1, 0, 0), counterclockwise along the xz plane. static const F32 tableScale[] = { 1, 1, 1, 0.5f, 0.707107f, 0.53f, 0.525f, 0.5f }; @@ -1536,6 +1541,8 @@ S32 LLPath::getNumPoints(const LLPathParams& params, F32 detail) BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split, BOOL is_sculpted, S32 sculpt_size) { + LL_PROFILE_ZONE_SCOPED + if ((!mDirty) && (!is_sculpted)) { return FALSE; @@ -2112,6 +2119,8 @@ LLVolume::~LLVolume() BOOL LLVolume::generate() { + LL_PROFILE_ZONE_SCOPED + LL_CHECK_MEMORY llassert_always(mProfilep); @@ -2370,6 +2379,8 @@ bool LLVolumeFace::VertexData::compareNormal(const LLVolumeFace::VertexData& rhs bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) { + LL_PROFILE_ZONE_SCOPED + //input stream is now pointing at a zlib compressed block of LLSD //decompress block LLSD mdl; @@ -2755,6 +2766,8 @@ S32 LLVolume::getNumFaces() const void LLVolume::createVolumeFaces() { + LL_PROFILE_ZONE_SCOPED + if (mGenerateSingleFace) { // do nothing @@ -3720,6 +3733,8 @@ void LLVolume::generateSilhouetteVertices(std::vector &vertices, const LLMatrix3& norm_mat_in, S32 face_mask) { + LL_PROFILE_ZONE_SCOPED + LLMatrix4a mat; mat.loadu(mat_in); @@ -4846,6 +4861,8 @@ void LLVolumeFace::freeData() BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build) { + LL_PROFILE_ZONE_SCOPED + //tree for this face is no longer valid delete mOctree; mOctree = NULL; @@ -5514,6 +5531,8 @@ bool LLVolumeFace::cacheOptimize() void LLVolumeFace::createOctree(F32 scaler, const LLVector4a& center, const LLVector4a& size) { + LL_PROFILE_ZONE_SCOPED + if (mOctree) { return; @@ -6287,6 +6306,8 @@ void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVe void LLVolumeFace::createTangents() { + LL_PROFILE_ZONE_SCOPED + if (!mTangents) { allocateTangents(mNumVertices); @@ -6482,6 +6503,8 @@ void LLVolumeFace::fillFromLegacyData(std::vector& v, BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) { + LL_PROFILE_ZONE_SCOPED + LL_CHECK_MEMORY BOOL flat = mTypeMask & FLAT_MASK; @@ -6974,6 +6997,8 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal, const LLVector2 *texcoord, U32 triangleCount, const U16* index_array, LLVector4a *tangent) { + LL_PROFILE_ZONE_SCOPED + //LLVector4a *tan1 = new LLVector4a[vertexCount * 2]; LLVector4a* tan1 = (LLVector4a*) ll_aligned_malloc_16(vertexCount*2*sizeof(LLVector4a)); // new(tan1) LLVector4a; -- cgit v1.2.3 From 2b19015f4394de59244c78f88c5c5df172632de6 Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Mon, 20 Sep 2021 09:48:16 -0700 Subject: SL-16014: Add Tracy markup for LLEventFilter --- indra/llcommon/lleventfilter.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/indra/llcommon/lleventfilter.h b/indra/llcommon/lleventfilter.h index 48c2570732..7613850fb2 100644 --- a/indra/llcommon/lleventfilter.h +++ b/indra/llcommon/lleventfilter.h @@ -429,6 +429,8 @@ public: // path, then stores it to mTarget. virtual bool post(const LLSD& event) { + LL_PROFILE_ZONE_SCOPED + // Extract the element specified by 'mPath' from 'event'. To perform a // generic type-appropriate store through mTarget, construct an // LLSDParam and store that, thus engaging LLSDParam's custom -- cgit v1.2.3 From 5fa9b510293fc3a36776f75fa6e88aefe3233a94 Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Mon, 20 Sep 2021 09:54:32 -0700 Subject: SL-16014: Add Tracy markup to doFrame() --- indra/newview/llappviewer.cpp | 48 ++++++++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index ab2b846c09..879cc6fc85 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1358,7 +1358,8 @@ void LLAppViewer::initMaxHeapSize() } static LLTrace::BlockTimerStatHandle FTM_MESSAGES("System Messages"); -static LLTrace::BlockTimerStatHandle FTM_SLEEP("Sleep"); +static LLTrace::BlockTimerStatHandle FTM_SLEEP1("Sleep1"); +static LLTrace::BlockTimerStatHandle FTM_SLEEP2("Sleep2"); static LLTrace::BlockTimerStatHandle FTM_YIELD("Yield"); static LLTrace::BlockTimerStatHandle FTM_TEXTURE_CACHE("Texture Cache"); @@ -1420,13 +1421,13 @@ bool LLAppViewer::frame() bool LLAppViewer::doFrame() { + LL_RECORD_BLOCK_TIME(FTM_FRAME); + LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop")); LLSD newFrame; - LL_RECORD_BLOCK_TIME(FTM_FRAME); - { - LL_PROFILE_ZONE_NAMED( ":blocktimer" ) + LL_PROFILE_ZONE_NAMED( "df blocktimer" ) LLTrace::BlockTimer::processTimes(); LLTrace::get_frame_recording().nextPeriod(); LLTrace::BlockTimer::logStats(); @@ -1438,7 +1439,7 @@ bool LLAppViewer::doFrame() LL_CLEAR_CALLSTACKS(); { - LL_PROFILE_ZONE_NAMED( ":processMiscNativeEvents" ) + LL_PROFILE_ZONE_NAMED( "df processMiscNativeEvents" ) pingMainloopTimeout("Main:MiscNativeWindowEvents"); if (gViewerWindow) @@ -1448,7 +1449,7 @@ bool LLAppViewer::doFrame() } { - LL_PROFILE_ZONE_NAMED( ":gatherInput" ) + LL_PROFILE_ZONE_NAMED( "df gatherInput" ) pingMainloopTimeout("Main:GatherInput"); } @@ -1475,20 +1476,20 @@ bool LLAppViewer::doFrame() } { - LL_PROFILE_ZONE_NAMED( ":mainloop" ) + LL_PROFILE_ZONE_NAMED( "df mainloop" ) // canonical per-frame event mainloop.post(newFrame); } { - LL_PROFILE_ZONE_NAMED( ":suspend" ) + LL_PROFILE_ZONE_NAMED( "df suspend" ) // give listeners a chance to run llcoro::suspend(); } if (!LLApp::isExiting()) { - LL_PROFILE_ZONE_NAMED( ":JoystickKeyboard" ) + LL_PROFILE_ZONE_NAMED( "df JoystickKeyboard" ) pingMainloopTimeout("Main:JoystickKeyboard"); // Scan keyboard for movement keys. Command keys and typing @@ -1510,7 +1511,7 @@ bool LLAppViewer::doFrame() // Update state based on messages, user input, object idle. { { - LL_PROFILE_ZONE_NAMED( ":pauseMainloopTimeout" ) + LL_PROFILE_ZONE_NAMED( "df pauseMainloopTimeout" ) pauseMainloopTimeout(); // *TODO: Remove. Messages shouldn't be stalling for 20+ seconds! } @@ -1518,7 +1519,7 @@ bool LLAppViewer::doFrame() idle(); { - LL_PROFILE_ZONE_NAMED( ":resumeMainloopTimeout" ) + LL_PROFILE_ZONE_NAMED( "df resumeMainloopTimeout" ) resumeMainloopTimeout(); } } @@ -1535,7 +1536,7 @@ bool LLAppViewer::doFrame() // *TODO: Should we run display() even during gHeadlessClient? DK 2011-02-18 if (!LLApp::isExiting() && !gHeadlessClient && gViewerWindow) { - LL_PROFILE_ZONE_NAMED( ":Display" ) + LL_PROFILE_ZONE_NAMED( "df Display" ) pingMainloopTimeout("Main:Display"); gGLActive = TRUE; @@ -1548,16 +1549,19 @@ bool LLAppViewer::doFrame() U64 elapsed_time = LLTimer::getTotalTime() - last_call; if (elapsed_time < mMinMicroSecPerFrame) { - LL_RECORD_BLOCK_TIME(FTM_SLEEP); + //LL_RECORD_BLOCK_TIME(FTM_SLEEP1); + LL_PROFILE_ZONE_WARN( "Sleep1" ) // llclamp for when time function gets funky U64 sleep_time = llclamp(mMinMicroSecPerFrame - elapsed_time, (U64)1, (U64)1e6); + + LL_PROFILE_ZONE_NUM( sleep_time ) micro_sleep(sleep_time, 0); } } last_call = LLTimer::getTotalTime(); { - LL_PROFILE_ZONE_NAMED( ":Snapshot" ) + LL_PROFILE_ZONE_NAMED( "df Snapshot" ) pingMainloopTimeout("Main:Snapshot"); LLFloaterSnapshot::update(); // take snapshots LLFloaterOutfitSnapshot::update(); @@ -1567,7 +1571,7 @@ bool LLAppViewer::doFrame() } { - LL_PROFILE_ZONE_NAMED( ":pauseMainloopTimeout" ) + LL_PROFILE_ZONE_NAMED( "df pauseMainloopTimeout" ) pingMainloopTimeout("Main:Sleep"); pauseMainloopTimeout(); @@ -1575,13 +1579,15 @@ bool LLAppViewer::doFrame() // Sleep and run background threads { - LL_RECORD_BLOCK_TIME(FTM_SLEEP); + //LL_RECORD_BLOCK_TIME(SLEEP2); + LL_PROFILE_ZONE_WARN( "Sleep2" ) // yield some time to the os based on command line option static LLCachedControl yield_time(gSavedSettings, "YieldTime", -1); if(yield_time >= 0) { LL_RECORD_BLOCK_TIME(FTM_YIELD); + LL_PROFILE_ZONE_NUM( yield_time ) ms_sleep(yield_time); } @@ -1646,20 +1652,20 @@ bool LLAppViewer::doFrame() } { - LL_PROFILE_ZONE_NAMED( ":gMeshRepo" ) + LL_PROFILE_ZONE_NAMED( "df gMeshRepo" ) gMeshRepo.update() ; } if(!total_work_pending) //pause texture fetching threads if nothing to process. { - LL_PROFILE_ZONE_NAMED( ":getTextureCache" ) + LL_PROFILE_ZONE_NAMED( "df getTextureCache" ) LLAppViewer::getTextureCache()->pause(); LLAppViewer::getImageDecodeThread()->pause(); LLAppViewer::getTextureFetch()->pause(); } if(!total_io_pending) //pause file threads if nothing to process. { - LL_PROFILE_ZONE_NAMED( ":LLVFSThread" ) + LL_PROFILE_ZONE_NAMED( "df LLVFSThread" ) LLVFSThread::sLocal->pause(); LLLFSThread::sLocal->pause(); } @@ -1667,7 +1673,7 @@ bool LLAppViewer::doFrame() //texture fetching debugger if(LLTextureFetchDebugger::isEnabled()) { - LL_PROFILE_ZONE_NAMED( ":tex_fetch_debugger_instance" ) + LL_PROFILE_ZONE_NAMED( "df tex_fetch_debugger_instance" ) LLFloaterTextureFetchDebugger* tex_fetch_debugger_instance = LLFloaterReg::findTypedInstance("tex_fetch_debugger"); if(tex_fetch_debugger_instance) @@ -1677,7 +1683,7 @@ bool LLAppViewer::doFrame() } { - LL_PROFILE_ZONE_NAMED( ":resumeMainloopTimeout" ) + LL_PROFILE_ZONE_NAMED( "df resumeMainloopTimeout" ) resumeMainloopTimeout(); } pingMainloopTimeout("Main:End"); -- cgit v1.2.3 From 43bca9e85d7fb1e6907fbe17f527e5bc8f543411 Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Wed, 22 Sep 2021 14:58:36 -0700 Subject: SL-16014: Fix typo --- indra/llcommon/llprofiler.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/llcommon/llprofiler.h b/indra/llcommon/llprofiler.h index 59e7dc02c6..49510df913 100644 --- a/indra/llcommon/llprofiler.h +++ b/indra/llcommon/llprofiler.h @@ -71,7 +71,7 @@ #define LL_RECORD_BLOCK_TIME(name) const LLTrace::BlockTimer& LL_GLUE_TOKENS(block_time_recorder, __LINE__)(LLTrace::timeThisBlock(name)); (void)LL_GLUE_TOKENS(block_time_recorder, __LINE__); #define LL_PROFILE_ZONE_NAMED(name) // LL_PROFILE_ZONE_NAMED is a no-op when Tracy is disabled #define LL_PROFILE_ZONE_SCOPED // LL_PROFILE_ZONE_SCOPED is a no-op when Tracy is disabled - #define LL_PRPFILE_ZONE_COLOR(name,color) // LL_RECORD_BLOCK_TIME(name) + #define LL_PROFILE_ZONE_COLOR(name,color) // LL_RECORD_BLOCK_TIME(name) #define LL_PROFILE_ZONE_NUM( val ) (void)( val ); // Not supported #define LL_PROFILE_ZONE_TEXT( text, size ) (void)( text ); void( size ); // Not supported -- cgit v1.2.3 From 9bcd860f53902a41adf14486d0d32966d410d404 Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Thu, 23 Sep 2021 01:50:05 +0300 Subject: SL-15903 SLPlugin entitlements fix --- indra/newview/slplugin.entitlements | 8 ++++++++ indra/newview/viewer_manifest.py | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 indra/newview/slplugin.entitlements diff --git a/indra/newview/slplugin.entitlements b/indra/newview/slplugin.entitlements new file mode 100644 index 0000000000..a1c430a57a --- /dev/null +++ b/indra/newview/slplugin.entitlements @@ -0,0 +1,8 @@ + + + + + com.apple.security.cs.allow-unsigned-executable-memory + + + diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 55d1edb151..b932f43141 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -1308,7 +1308,7 @@ class DarwinManifest(ViewerManifest): self.run_command(['codesign', '--force', '--timestamp','--keychain', viewer_keychain, '--sign', identity, libvlc_path]) self.run_command(['codesign', '--force', '--timestamp', '--keychain', viewer_keychain, '--sign', identity, cef_path]) self.run_command(['codesign', '--force', '--timestamp', '--keychain', viewer_keychain, '--sign', identity, greenlet_path]) - self.run_command(['codesign', '--verbose', '--deep', '--force', '--options', 'runtime', '--keychain', viewer_keychain, '--sign', identity, slplugin_path]) + self.run_command(['codesign', '--verbose', '--deep', '--force', '--entitlements', self.src_path_of("slplugin.entitlements"), '--options', 'runtime', '--keychain', viewer_keychain, '--sign', identity, slplugin_path]) self.run_command(['codesign', '--verbose', '--deep', '--force', '--options', 'runtime', '--keychain', viewer_keychain, '--sign', identity, app_in_dmg]) signed=True # if no exception was raised, the codesign worked except ManifestError as err: -- cgit v1.2.3 From 717fe2cc5c35151f4712519f649276d4877d09a3 Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Thu, 23 Sep 2021 10:57:37 +0300 Subject: DRTVWR-520 Updated dullahan to codeticket build 563968 --- autobuild.xml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index b01ee685f7..5424e0629a 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -580,9 +580,9 @@ archive hash - 49fff41e17e06cdf9eb0c737d20df52f + 45dedb5b09995cd794304150e94fcf21 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/83411/779825/dullahan-1.12.2.202106220202_91.1.21_g9dd45fe_chromium-91.0.4472.114-darwin64-560751.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87950/806969/dullahan-1.12.2.202109170444_91.1.21_g9dd45fe_chromium-91.0.4472.114-darwin64-563968.tar.bz2 name darwin64 @@ -592,9 +592,9 @@ archive hash - f51f324d50a2461cda273e84fa65e0ad + d0fd9d7086699da4bb5ccc935622a717 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/83413/779836/dullahan-1.12.2.202106220213_91.1.21_g9dd45fe_chromium-91.0.4472.114-windows-560751.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/88276/809277/dullahan-1.12.2.202109230751_91.1.21_g9dd45fe_chromium-91.0.4472.114-windows-563968.tar.bz2 name windows @@ -604,16 +604,16 @@ archive hash - d3df46f6592715c75df2bf520c1ad68b + 7e8c3ccd420ff5aef24ff72d609ba394 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/83412/779840/dullahan-1.12.2.202106220213_91.1.21_g9dd45fe_chromium-91.0.4472.114-windows64-560751.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/88275/809281/dullahan-1.12.2.202109230751_91.1.21_g9dd45fe_chromium-91.0.4472.114-windows64-563968.tar.bz2 name windows64 version - 1.12.2.202106220213_91.1.21_g9dd45fe_chromium-91.0.4472.114 + 1.12.2.202109230751_91.1.21_g9dd45fe_chromium-91.0.4472.114 elfio -- cgit v1.2.3 From d7dea2dd7a312001c9ad4593871ec938aa9ad586 Mon Sep 17 00:00:00 2001 From: Runitai Linden Date: Fri, 24 Sep 2021 15:21:35 -0500 Subject: Ignore build-vc160-64 --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 4af34870cf..3619681d82 100755 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,7 @@ build-vc120-32/ build-vc120-64/ build-vc150-32/ build-vc150-64/ +build-vc160-64/ indra/CMakeFiles indra/build-vc[0-9]* indra/lib/mono/1.0/*.dll -- cgit v1.2.3 From 78007d2592290582e3b3fbff002376ad0561779f Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 27 Sep 2021 22:35:50 +0000 Subject: SL-16088 Fix for stall from many calls to glGenBuffers. --- indra/llrender/llvertexbuffer.cpp | 19 +++++++++++++++---- indra/llrender/llvertexbuffer.h | 5 ++++- indra/newview/llsurface.cpp | 1 + indra/newview/llsurfacepatch.cpp | 1 + indra/newview/llviewerparceloverlay.cpp | 1 + indra/newview/llvlcomposition.cpp | 1 + indra/newview/llvoavatar.cpp | 2 ++ indra/newview/llvosurfacepatch.cpp | 1 + 8 files changed, 26 insertions(+), 5 deletions(-) diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index b69b644ebc..0449ac392c 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -91,6 +91,8 @@ LLVBOPool LLVertexBuffer::sDynamicIBOPool(GL_DYNAMIC_DRAW_ARB, GL_ELEMENT_ARRAY_ U32 LLVBOPool::sBytesPooled = 0; U32 LLVBOPool::sIndexBytesPooled = 0; +U32 LLVBOPool::sNameIdx = 0; +U32 LLVBOPool::sNamePool[1024]; std::list LLVertexBuffer::sAvailableVAOName; U32 LLVertexBuffer::sCurVAOName = 1; @@ -121,15 +123,20 @@ bool LLVertexBuffer::sPreferStreamDraw = false; U32 LLVBOPool::genBuffer() { - U32 ret = 0; + LL_PROFILE_ZONE_SCOPED - glGenBuffersARB(1, &ret); - - return ret; + if (sNameIdx == 0) + { + glGenBuffersARB(1024, sNamePool); + sNameIdx = 1024; + } + + return sNamePool[--sNameIdx]; } void LLVBOPool::deleteBuffer(U32 name) { + LL_PROFILE_ZONE_SCOPED if (gGLManager.mInited) { LLVertexBuffer::unbind(); @@ -152,6 +159,7 @@ LLVBOPool::LLVBOPool(U32 vboUsage, U32 vboType) volatile U8* LLVBOPool::allocate(U32& name, U32 size, bool for_seed) { + LL_PROFILE_ZONE_SCOPED llassert(vbo_block_size(size) == size); volatile U8* ret = NULL; @@ -267,10 +275,12 @@ void LLVBOPool::release(U32 name, volatile U8* buffer, U32 size) void LLVBOPool::seedPool() { + LL_PROFILE_ZONE_SCOPED U32 dummy_name = 0; if (mFreeList.size() < LL_VBO_POOL_SEED_COUNT) { + LL_PROFILE_ZONE_NAMED("VBOPool Resize"); mFreeList.resize(LL_VBO_POOL_SEED_COUNT); } @@ -411,6 +421,7 @@ void LLVertexBuffer::releaseVAOName(U32 name) //static void LLVertexBuffer::seedPools() { + LL_PROFILE_ZONE_SCOPED sStreamVBOPool.seedPool(); sDynamicVBOPool.seedPool(); sDynamicCopyVBOPool.seedPool(); diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index dbe1a3687f..1d60970df4 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -89,6 +89,9 @@ public: std::vector mFreeList; std::vector mMissCount; + //used to avoid calling glGenBuffers for every VBO creation + static U32 sNamePool[1024]; + static U32 sNameIdx; }; @@ -127,7 +130,7 @@ public: static LLVBOPool sDynamicCopyVBOPool; static LLVBOPool sStreamIBOPool; static LLVBOPool sDynamicIBOPool; - + static std::list sAvailableVAOName; static U32 sCurVAOName; diff --git a/indra/newview/llsurface.cpp b/indra/newview/llsurface.cpp index cb356726e6..ea36e1d7be 100644 --- a/indra/newview/llsurface.cpp +++ b/indra/newview/llsurface.cpp @@ -1214,6 +1214,7 @@ F32 LLSurface::getWaterHeight() const BOOL LLSurface::generateWaterTexture(const F32 x, const F32 y, const F32 width, const F32 height) { + LL_PROFILE_ZONE_SCOPED if (!getWaterTexture()) { return FALSE; diff --git a/indra/newview/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp index 5e056944e9..aeefcd6fb8 100644 --- a/indra/newview/llsurfacepatch.cpp +++ b/indra/newview/llsurfacepatch.cpp @@ -728,6 +728,7 @@ BOOL LLSurfacePatch::updateTexture() void LLSurfacePatch::updateGL() { + LL_PROFILE_ZONE_SCOPED F32 meters_per_grid = getSurface()->getMetersPerGrid(); F32 grids_per_patch_edge = (F32)getSurface()->getGridsPerPatchEdge(); diff --git a/indra/newview/llviewerparceloverlay.cpp b/indra/newview/llviewerparceloverlay.cpp index 7c3dd00e1a..02f7bbeed8 100644 --- a/indra/newview/llviewerparceloverlay.cpp +++ b/indra/newview/llviewerparceloverlay.cpp @@ -847,6 +847,7 @@ void LLViewerParcelOverlay::setDirty() void LLViewerParcelOverlay::updateGL() { + LL_PROFILE_ZONE_SCOPED updateOverlayTexture(); } diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index c63c5f6b23..46beac8255 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -254,6 +254,7 @@ BOOL LLVLComposition::generateComposition() BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, const F32 width, const F32 height) { + LL_PROFILE_ZONE_SCOPED llassert(mSurfacep); llassert(x >= 0.f); llassert(y >= 0.f); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index f260e4f750..a588d05ff7 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -7123,6 +7123,7 @@ void LLVOAvatar::updateGL() { if (mMeshTexturesDirty) { + LL_PROFILE_ZONE_SCOPED updateMeshTextures(); mMeshTexturesDirty = FALSE; } @@ -8361,6 +8362,7 @@ void LLVOAvatar::updateMeshVisibility() // virtual void LLVOAvatar::updateMeshTextures() { + LL_PROFILE_ZONE_SCOPED static S32 update_counter = 0; mBakedTextureDebugText.clear(); diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index 897bace4e1..b5560d3d79 100644 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -218,6 +218,7 @@ void LLVOSurfacePatch::updateGL() { if (mPatchp) { + LL_PROFILE_ZONE_SCOPED mPatchp->updateGL(); } } -- cgit v1.2.3 From 675514bdb372c25b50dd2c42b06633895c86b8ce Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 27 Sep 2021 23:56:06 +0000 Subject: SL-16093 Don't force the console window to be open on developer builds because it causes frame stalls while logging. --- indra/llcommon/llerror.cpp | 12 +++++++++++- indra/llcommon/llerror.h | 5 ++++- indra/llcommon/llerrorcontrol.h | 1 + indra/llcommon/llmemory.cpp | 2 ++ indra/llcommon/llmutex.cpp | 12 ++++++++++++ indra/llcommon/llsys.cpp | 1 + indra/llcommon/llthread.cpp | 7 +++++++ indra/llrender/llglslshader.cpp | 1 + indra/llrender/llimagegl.cpp | 5 ++++- indra/llrender/llrender.cpp | 1 + indra/newview/llappviewer.cpp | 7 +------ indra/newview/llviewerdisplay.cpp | 11 ++++++++++- indra/newview/llviewerwindow.cpp | 1 + indra/newview/llworld.cpp | 1 + indra/newview/pipeline.cpp | 2 ++ indra/test/test.cpp | 1 + 16 files changed, 60 insertions(+), 10 deletions(-) diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index 8355df9045..f7af181927 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -109,6 +109,7 @@ namespace { virtual void recordMessage(LLError::ELevel level, const std::string& message) override { + LL_PROFILE_ZONE_SCOPED int syslogPriority = LOG_CRIT; switch (level) { case LLError::LEVEL_DEBUG: syslogPriority = LOG_DEBUG; break; @@ -166,6 +167,7 @@ namespace { virtual void recordMessage(LLError::ELevel level, const std::string& message) override { + LL_PROFILE_ZONE_SCOPED if (LLError::getAlwaysFlush()) { mFile << message << std::endl; @@ -208,6 +210,7 @@ namespace { virtual void recordMessage(LLError::ELevel level, const std::string& message) override { + LL_PROFILE_ZONE_SCOPED static std::string s_ansi_error = createANSI("31"); // red static std::string s_ansi_warn = createANSI("34"); // blue static std::string s_ansi_debug = createANSI("35"); // magenta @@ -220,7 +223,8 @@ namespace { } else { - fprintf(stderr, "%s\n", message.c_str()); + LL_PROFILE_ZONE_NAMED("fprintf"); + fprintf(stderr, "%s\n", message.c_str()); } } @@ -229,6 +233,7 @@ namespace { LL_FORCE_INLINE void writeANSI(const std::string& ansi_code, const std::string& message) { + LL_PROFILE_ZONE_SCOPED static std::string s_ansi_bold = createANSI("1"); // bold static std::string s_ansi_reset = createANSI("0"); // reset // ANSI color code escape sequence, message, and reset in one fprintf call @@ -265,6 +270,7 @@ namespace { virtual void recordMessage(LLError::ELevel level, const std::string& message) override { + LL_PROFILE_ZONE_SCOPED mBuffer->addLine(message); } @@ -291,6 +297,7 @@ namespace { virtual void recordMessage(LLError::ELevel level, const std::string& message) override { + LL_PROFILE_ZONE_SCOPED debugger_print(message); } }; @@ -1178,6 +1185,7 @@ namespace void writeToRecorders(const LLError::CallSite& site, const std::string& message) { + LL_PROFILE_ZONE_SCOPED LLError::ELevel level = site.mLevel; LLError::SettingsConfigPtr s = LLError::Settings::getInstance()->getSettingsConfig(); @@ -1311,6 +1319,7 @@ namespace LLError bool Log::shouldLog(CallSite& site) { + LL_PROFILE_ZONE_SCOPED LLMutexTrylock lock(getMutex(), 5); if (!lock.isLocked()) { @@ -1354,6 +1363,7 @@ namespace LLError void Log::flush(const std::ostringstream& out, const CallSite& site) { + LL_PROFILE_ZONE_SCOPED LLMutexTrylock lock(getMutex(),5); if (!lock.isLocked()) { diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h index d439136ca8..d06c0e2132 100644 --- a/indra/llcommon/llerror.h +++ b/indra/llcommon/llerror.h @@ -35,7 +35,9 @@ #include "stdtypes.h" +#include "llprofiler.h" #include "llpreprocessor.h" + #include const int LL_ERR_NOERR = 0; @@ -348,7 +350,8 @@ typedef LLError::NoClassInfo _LL_CLASS_TO_LOG; // if (condition) LL_INFOS() << "True" << LL_ENDL; else LL_INFOS()() << "False" << LL_ENDL; #define lllog(level, once, ...) \ - do { \ + do { \ + LL_PROFILE_ZONE_NAMED("lllog"); \ const char* tags[] = {"", ##__VA_ARGS__}; \ static LLError::CallSite _site(lllog_site_args_(level, once, tags)); \ lllog_test_() diff --git a/indra/llcommon/llerrorcontrol.h b/indra/llcommon/llerrorcontrol.h index e87bb7bf35..57f10b7895 100644 --- a/indra/llcommon/llerrorcontrol.h +++ b/indra/llcommon/llerrorcontrol.h @@ -190,6 +190,7 @@ namespace LLError {} void recordMessage(LLError::ELevel level, const std::string& message) override { + LL_PROFILE_ZONE_SCOPED mCallable(level, message); } private: diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp index ea84e4c1ea..849867586a 100644 --- a/indra/llcommon/llmemory.cpp +++ b/indra/llcommon/llmemory.cpp @@ -82,6 +82,7 @@ void LLMemory::initMaxHeapSizeGB(F32Gigabytes max_heap_size) //static void LLMemory::updateMemoryInfo() { + LL_PROFILE_ZONE_SCOPED #if LL_WINDOWS PROCESS_MEMORY_COUNTERS counters; @@ -145,6 +146,7 @@ void* LLMemory::tryToAlloc(void* address, U32 size) //static void LLMemory::logMemoryInfo(BOOL update) { + LL_PROFILE_ZONE_SCOPED if(update) { updateMemoryInfo() ; diff --git a/indra/llcommon/llmutex.cpp b/indra/llcommon/llmutex.cpp index 4d73c04d07..a49002b5dc 100644 --- a/indra/llcommon/llmutex.cpp +++ b/indra/llcommon/llmutex.cpp @@ -44,6 +44,7 @@ LLMutex::~LLMutex() void LLMutex::lock() { + LL_PROFILE_ZONE_SCOPED if(isSelfLocked()) { //redundant lock mCount++; @@ -65,6 +66,7 @@ void LLMutex::lock() void LLMutex::unlock() { + LL_PROFILE_ZONE_SCOPED if (mCount > 0) { //not the root unlock mCount--; @@ -85,6 +87,7 @@ void LLMutex::unlock() bool LLMutex::isLocked() { + LL_PROFILE_ZONE_SCOPED if (!mMutex.try_lock()) { return true; @@ -108,6 +111,7 @@ LLThread::id_t LLMutex::lockingThread() const bool LLMutex::trylock() { + LL_PROFILE_ZONE_SCOPED if(isSelfLocked()) { //redundant lock mCount++; @@ -146,17 +150,20 @@ LLCondition::~LLCondition() void LLCondition::wait() { + LL_PROFILE_ZONE_SCOPED std::unique_lock< std::mutex > lock(mMutex); mCond.wait(lock); } void LLCondition::signal() { + LL_PROFILE_ZONE_SCOPED mCond.notify_one(); } void LLCondition::broadcast() { + LL_PROFILE_ZONE_SCOPED mCond.notify_all(); } @@ -166,6 +173,7 @@ LLMutexTrylock::LLMutexTrylock(LLMutex* mutex) : mMutex(mutex), mLocked(false) { + LL_PROFILE_ZONE_SCOPED if (mMutex) mLocked = mMutex->trylock(); } @@ -174,6 +182,7 @@ LLMutexTrylock::LLMutexTrylock(LLMutex* mutex, U32 aTries, U32 delay_ms) : mMutex(mutex), mLocked(false) { + LL_PROFILE_ZONE_SCOPED if (!mMutex) return; @@ -188,6 +197,7 @@ LLMutexTrylock::LLMutexTrylock(LLMutex* mutex, U32 aTries, U32 delay_ms) LLMutexTrylock::~LLMutexTrylock() { + LL_PROFILE_ZONE_SCOPED if (mMutex && mLocked) mMutex->unlock(); } @@ -199,6 +209,7 @@ LLMutexTrylock::~LLMutexTrylock() // LLScopedLock::LLScopedLock(std::mutex* mutex) : mMutex(mutex) { + LL_PROFILE_ZONE_SCOPED if(mutex) { mutex->lock(); @@ -217,6 +228,7 @@ LLScopedLock::~LLScopedLock() void LLScopedLock::unlock() { + LL_PROFILE_ZONE_SCOPED if(mLocked) { mMutex->unlock(); diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp index 4e61fb8a58..6d5d043e8d 100644 --- a/indra/llcommon/llsys.cpp +++ b/indra/llcommon/llsys.cpp @@ -861,6 +861,7 @@ LLSD LLMemoryInfo::getStatsMap() const LLMemoryInfo& LLMemoryInfo::refresh() { + LL_PROFILE_ZONE_SCOPED mStatsMap = loadStatsMap(); LL_DEBUGS("LLMemoryInfo") << "Populated mStatsMap:\n"; diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index a8cc750437..11f5a015f1 100644 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -333,6 +333,7 @@ bool LLThread::runCondition(void) // Stop thread execution if requested until unpaused. void LLThread::checkPause() { + LL_PROFILE_ZONE_SCOPED mDataLock->lock(); // This is in a while loop because the pthread API allows for spurious wakeups. @@ -364,17 +365,20 @@ void LLThread::setQuitting() // static LLThread::id_t LLThread::currentID() { + LL_PROFILE_ZONE_SCOPED return std::this_thread::get_id(); } // static void LLThread::yield() { + LL_PROFILE_ZONE_SCOPED std::this_thread::yield(); } void LLThread::wake() { + LL_PROFILE_ZONE_SCOPED mDataLock->lock(); if(!shouldSleep()) { @@ -385,6 +389,7 @@ void LLThread::wake() void LLThread::wakeLocked() { + LL_PROFILE_ZONE_SCOPED if(!shouldSleep()) { mRunCondition->signal(); @@ -393,11 +398,13 @@ void LLThread::wakeLocked() void LLThread::lockData() { + LL_PROFILE_ZONE_SCOPED mDataLock->lock(); } void LLThread::unlockData() { + LL_PROFILE_ZONE_SCOPED mDataLock->unlock(); } diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index 8bd9dbf9b8..9ab38d25a9 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -126,6 +126,7 @@ struct LLGLSLShaderCompareTimeElapsed //static void LLGLSLShader::finishProfile(bool emit_report) { + LL_PROFILE_ZONE_SCOPED sProfileEnabled = false; if (emit_report) diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 0151d20128..276fa55e15 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -1304,7 +1304,10 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt } stop_glerror(); - glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, use_scratch ? scratch : pixels); + { + LL_PROFILE_ZONE_NAMED("glTexImage2D"); + glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, use_scratch ? scratch : pixels); + } stop_glerror(); if (use_scratch) diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 03b6aac20c..43b4441ea8 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -1848,6 +1848,7 @@ LLLightState* LLRender::getLight(U32 index) void LLRender::setAmbientLightColor(const LLColor4& color) { + LL_PROFILE_ZONE_SCOPED if (color != mAmbientLightColor) { ++mLightHash; diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index fc35590667..3d49a9eb78 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -2501,12 +2501,7 @@ bool LLAppViewer::initConfiguration() #ifndef LL_RELEASE_FOR_DOWNLOAD // provide developer build only overrides for these control variables that are not // persisted to settings.xml - LLControlVariable* c = gSavedSettings.getControl("ShowConsoleWindow"); - if (c) - { - c->setValue(true, false); - } - c = gSavedSettings.getControl("AllowMultipleViewers"); + LLControlVariable* c = gSavedSettings.getControl("AllowMultipleViewers"); if (c) { c->setValue(true, false); diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index a590237440..33842497d1 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -208,9 +208,11 @@ void display_update_camera() // Write some stats to LL_INFOS() void display_stats() { + LL_PROFILE_ZONE_SCOPED F32 fps_log_freq = gSavedSettings.getF32("FPSLogFrequency"); if (fps_log_freq > 0.f && gRecentFPSTime.getElapsedTimeF32() >= fps_log_freq) { + LL_PROFILE_ZONE_NAMED("DS - FPS"); F32 fps = gRecentFrameCount / fps_log_freq; LL_INFOS() << llformat("FPS: %.02f", fps) << LL_ENDL; gRecentFrameCount = 0; @@ -219,6 +221,7 @@ void display_stats() F32 mem_log_freq = gSavedSettings.getF32("MemoryLogFrequency"); if (mem_log_freq > 0.f && gRecentMemoryTime.getElapsedTimeF32() >= mem_log_freq) { + LL_PROFILE_ZONE_NAMED("DS - Memory"); gMemoryAllocated = U64Bytes(LLMemory::getCurrentRSS()); U32Megabytes memory = gMemoryAllocated; LL_INFOS() << "MEMORY: " << memory << LL_ENDL; @@ -228,6 +231,7 @@ void display_stats() F32 asset_storage_log_freq = gSavedSettings.getF32("AssetStorageLogFrequency"); if (asset_storage_log_freq > 0.f && gAssetStorageLogTime.getElapsedTimeF32() >= asset_storage_log_freq) { + LL_PROFILE_ZONE_NAMED("DS - Asset Storage"); gAssetStorageLogTime.reset(); gAssetStorage->logAssetStorageInfo(); } @@ -630,6 +634,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) if (!gDisconnected) { + LL_PROFILE_ZONE_NAMED("display - 1"); LLAppViewer::instance()->pingMainloopTimeout("Display:Update"); if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) { //don't draw hud objects in this frame @@ -722,6 +727,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) LLAppViewer::instance()->pingMainloopTimeout("Display:Swap"); { + LL_PROFILE_ZONE_NAMED("display - 2") if (gResizeScreenTexture) { gResizeScreenTexture = FALSE; @@ -777,6 +783,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) //if (!for_snapshot) { + LL_PROFILE_ZONE_NAMED("display - 3") LLAppViewer::instance()->pingMainloopTimeout("Display:Imagery"); gPipeline.generateWaterReflection(*LLViewerCamera::getInstance()); gPipeline.generateHighlight(*LLViewerCamera::getInstance()); @@ -825,7 +832,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) LLImageGL::deleteDeadTextures(); stop_glerror(); }*/ - } + } LLGLState::checkStates(); LLGLState::checkClientArrays(); @@ -840,6 +847,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) // LLAppViewer::instance()->pingMainloopTimeout("Display:StateSort"); { + LL_PROFILE_ZONE_NAMED("display - 3") LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; gPipeline.stateSort(*LLViewerCamera::getInstance(), result); stop_glerror(); @@ -948,6 +956,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) if (!(LLAppViewer::instance()->logoutRequestSent() && LLAppViewer::instance()->hasSavedFinalSnapshot()) && !gRestoreGL) { + LL_PROFILE_ZONE_NAMED("display - 4") LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; if (gSavedSettings.getBOOL("RenderDepthPrePass") && LLGLSLShader::sNoFixedFunction) diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 1d13a306ef..2157585364 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -5280,6 +5280,7 @@ void LLViewerWindow::setup3DRender() void LLViewerWindow::setup3DViewport(S32 x_offset, S32 y_offset) { + LL_PROFILE_ZONE_SCOPED gGLViewport[0] = mWorldViewRectRaw.mLeft + x_offset; gGLViewport[1] = mWorldViewRectRaw.mBottom + y_offset; gGLViewport[2] = mWorldViewRectRaw.getWidth(); diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index a1a1db35d6..c7b0a2bfb4 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -1284,6 +1284,7 @@ void send_agent_pause() void send_agent_resume() { + LL_PROFILE_ZONE_SCOPED // Note: used to check for LLWorld initialization before it became a singleton. // Rather than just remove this check I'm changing it to assure that the message // system has been initialized. -MG diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 4e28c8c493..d7acf2ec0e 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -1897,6 +1897,7 @@ void LLPipeline::createObject(LLViewerObject* vobj) void LLPipeline::resetFrameStats() { + LL_PROFILE_ZONE_SCOPED assertInitialized(); sCompiles = 0; @@ -2125,6 +2126,7 @@ void LLPipeline::grabReferences(LLCullResult& result) void LLPipeline::clearReferences() { + LL_PROFILE_ZONE_SCOPED sCull = NULL; mGroupSaveQ1.clear(); } diff --git a/indra/test/test.cpp b/indra/test/test.cpp index 87c4a8d8a3..bb48216b2b 100644 --- a/indra/test/test.cpp +++ b/indra/test/test.cpp @@ -112,6 +112,7 @@ public: virtual void recordMessage(LLError::ELevel level, const std::string& message) { + LL_PROFILE_ZONE_SCOPED mFile << message << std::endl; } -- cgit v1.2.3 From 3e12a97a7f0dfa951c3997dd2117d2418fe21ce6 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Tue, 28 Sep 2021 16:40:33 -0400 Subject: SL-16040: Honor autobuild_{configure,build}_parameters variables. The generic build.sh script honors these environment variables to specify parameters to the autobuild configure and autobuild build steps, respectively. Support them in the viewer-specific build.sh too. In the generic build.sh, autobuild_configure_parameters allows specifying command-line switches either for autobuild or, following --, for the underlying tool (in our case, CMake). In order to support that variable the same way here, we insert -- (as before) when autobuild_configure_parameters is unset or empty, since the rest of the switches *we* specify are for CMake. That means that, as with the generic build.sh, a non-empty autobuild_configure_parameters override must precede any switches intended for CMake with the -- separator. --- build.sh | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/build.sh b/build.sh index 96bcff0e8e..3291039856 100755 --- a/build.sh +++ b/build.sh @@ -132,7 +132,11 @@ pre_build() fi set -x - "$autobuild" configure --quiet -c $variant -- \ + # honor autobuild_configure_parameters same as sling-buildscripts + eval_autobuild_configure_parameters=$(eval $(echo echo $autobuild_configure_parameters)) + + "$autobuild" configure --quiet -c $variant \ + ${eval_autobuild_configure_parameters:---} \ -DPACKAGE:BOOL=ON \ -DHAVOK:BOOL="$HAVOK" \ -DRELEASE_CRASH_REPORTING:BOOL="$RELEASE_CRASH_REPORTING" \ @@ -182,7 +186,11 @@ build() if $build_viewer then begin_section "autobuild $variant" - "$autobuild" build --no-configure -c $variant || fatal "failed building $variant" + # honor autobuild_build_parameters same as sling-buildscripts + eval_autobuild_build_parameters=$(eval $(echo echo $autobuild_build_parameters)) + "$autobuild" build --no-configure -c $variant \ + $eval_autobuild_build_parameters \ + || fatal "failed building $variant" echo true >"$build_dir"/build_ok end_section "autobuild $variant" -- cgit v1.2.3 From 548bfda290b556d3ab29cc8c2f810f4cc349c9d8 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Tue, 28 Sep 2021 16:53:04 -0400 Subject: SL-16040: operator new() must never return nullptr. --- indra/llcommon/llcommon.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/indra/llcommon/llcommon.cpp b/indra/llcommon/llcommon.cpp index da61e7539a..92f4d569b1 100644 --- a/indra/llcommon/llcommon.cpp +++ b/indra/llcommon/llcommon.cpp @@ -34,14 +34,13 @@ #include "llcleanup.h" #if (TRACY_ENABLE) -// Override new/delet for tracy memory profiling +// Override new/delete for tracy memory profiling void *operator new(size_t size) { auto ptr = (malloc) (size); if (!ptr) { throw std::bad_alloc(); - return nullptr; } TracyAlloc(ptr, size); return ptr; -- cgit v1.2.3 From db86ec9176dcbfabe5fddb3603da4132443f8b7f Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Tue, 28 Sep 2021 22:09:02 -0400 Subject: SL-16040: _aligned_malloc() and _aligned_free() are Microsoft only. Fortunately we already have platform-independent wrappers in llmemory.h. --- indra/llcommon/llcommon.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indra/llcommon/llcommon.cpp b/indra/llcommon/llcommon.cpp index 92f4d569b1..5d4a623bf6 100644 --- a/indra/llcommon/llcommon.cpp +++ b/indra/llcommon/llcommon.cpp @@ -61,7 +61,7 @@ void operator delete(void *ptr) noexcept void *tracy_aligned_malloc(size_t size, size_t alignment) { - auto ptr = (_aligned_malloc) (size, alignment); + auto ptr = ll_aligned_malloc_fallback(size, alignment); if (ptr) TracyAlloc(ptr, size); return ptr; } @@ -69,7 +69,7 @@ void *tracy_aligned_malloc(size_t size, size_t alignment) void tracy_aligned_free(void *memblock) { TracyFree(memblock); - (_aligned_free)(memblock); + ll_aligned_free_fallback(memblock); } #endif -- cgit v1.2.3 From 2148e4c731e1c0926c32fedb3e7047c96cd9eebf Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 1 Oct 2021 15:51:12 +0000 Subject: SL-16094 Move LLWindowWin32::mainWindowProc and Windows message handling to a background thread to prevent frame stalls in LLWindowWin32::gatherInput --- indra/llwindow/llwindowwin32.cpp | 2580 +++++++++++++++++++++----------------- indra/llwindow/llwindowwin32.h | 46 +- 2 files changed, 1495 insertions(+), 1131 deletions(-) diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 714e07da31..4ce7c30bef 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -28,6 +28,8 @@ #if LL_WINDOWS && !LL_MESA_HEADLESS +#define LL_WINDOW_SINGLE_THREADED 0 + #include "llwindowwin32.h" // LLWindow library includes @@ -45,6 +47,7 @@ #include "lldir.h" #include "llsdutil.h" #include "llglslshader.h" +#include "llthreadsafequeue.h" // System includes #include @@ -79,6 +82,18 @@ const F32 ICON_FLASH_TIME = 0.5f; extern BOOL gDebugWindowProc; +static std::thread::id sWindowThreadId; +static std::thread::id sMainThreadId; + +#if 1 || LL_WINDOW_SINGLE_THREADED +#define ASSERT_MAIN_THREAD() +#define ASSERT_WINDOW_THREAD() +#else +#define ASSERT_MAIN_THREAD() llassert(LLThread::currentID() == sMainThreadId) +#define ASSERT_WINDOW_THREAD() llassert(LLThread::currentID() == sWindowThreadId) +#endif + + LPWSTR gIconResource = IDI_APPLICATION; LPDIRECTINPUT8 gDirectInput8; @@ -294,7 +309,7 @@ LLWinImm::LLWinImm() : mHImmDll(NULL) // static -BOOL LLWinImm::isIME(HKL hkl) +BOOL LLWinImm::isIME(HKL hkl) { if ( sTheInstance.mImmIsIME ) return sTheInstance.mImmIsIME(hkl); @@ -326,7 +341,7 @@ BOOL LLWinImm::getOpenStatus(HIMC himc) } // static -BOOL LLWinImm::setOpenStatus(HIMC himc, BOOL status) +BOOL LLWinImm::setOpenStatus(HIMC himc, BOOL status) { if ( sTheInstance.mImmSetOpenStatus ) return sTheInstance.mImmSetOpenStatus(himc, status); @@ -454,6 +469,8 @@ private: static LLMonitorInfo sMonitorInfo; + + LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks, const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height, U32 flags, @@ -463,7 +480,11 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks, U32 fsaa_samples) : LLWindow(callbacks, fullscreen, flags) { - + sMainThreadId = LLThread::currentID(); + mWindowThread = new LLWindowWin32Thread(this); +#if !LL_WINDOW_SINGLE_THREADED + mWindowThread->start(); +#endif //MAINT-516 -- force a load of opengl32.dll just in case windows went sideways LoadLibrary(L"opengl32.dll"); @@ -811,6 +832,8 @@ LLWindowWin32::~LLWindowWin32() delete [] mWindowClassName; mWindowClassName = NULL; + + delete mWindowThread; } void LLWindowWin32::show() @@ -930,26 +953,35 @@ void LLWindowWin32::close() LL_DEBUGS("Window") << "Destroying Window" << LL_ENDL; - if (IsWindow(mWindowHandle)) - { - // Make sure we don't leave a blank toolbar button. - ShowWindow(mWindowHandle, SW_HIDE); - - // This causes WM_DESTROY to be sent *immediately* - if (!destroy_window_handler(mWindowHandle)) + mWindowThread->post([=]() { - OSMessageBox(mCallbacks->translateString("MBDestroyWinFailed"), - mCallbacks->translateString("MBShutdownErr"), - OSMB_OK); - } - } - else + if (IsWindow(mWindowHandle)) + { + // Make sure we don't leave a blank toolbar button. + ShowWindow(mWindowHandle, SW_HIDE); + + // This causes WM_DESTROY to be sent *immediately* + if (!destroy_window_handler(mWindowHandle)) + { + OSMessageBox(mCallbacks->translateString("MBDestroyWinFailed"), + mCallbacks->translateString("MBShutdownErr"), + OSMB_OK); + } + } + else + { + // Something killed the window while we were busy destroying gl or handle somehow got broken + LL_WARNS("Window") << "Failed to destroy Window, invalid handle!" << LL_ENDL; + } + mWindowHandle = NULL; + + mWindowThread->mFinished = true; + }); + + while (!mWindowThread->isStopped()) { - // Something killed the window while we were busy destroying gl or handle somehow got broken - LL_WARNS("Window") << "Failed to destroy Window, invalid handle!" << LL_ENDL; + std::this_thread::sleep_for(std::chrono::milliseconds(1)); } - - mWindowHandle = NULL; } BOOL LLWindowWin32::isValid() @@ -1090,171 +1122,203 @@ BOOL LLWindowWin32::setSizeImpl(const LLCoordWindow size) } // changing fullscreen resolution -BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp) +BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen& size, BOOL disable_vsync, const LLCoordScreen* const posp) { - GLuint pixel_format; - DEVMODE dev_mode; - ::ZeroMemory(&dev_mode, sizeof(DEVMODE)); - dev_mode.dmSize = sizeof(DEVMODE); - DWORD current_refresh; - DWORD dw_ex_style; - DWORD dw_style; - RECT window_rect = {0, 0, 0, 0}; - S32 width = size.mX; - S32 height = size.mY; - BOOL auto_show = FALSE; - - if (mhRC) - { - auto_show = TRUE; - resetDisplayResolution(); - } - - if (EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dev_mode)) - { - current_refresh = dev_mode.dmDisplayFrequency; - } - else - { - current_refresh = 60; - } - - gGLManager.shutdownGL(); - //destroy gl context - if (mhRC) - { - if (!wglMakeCurrent(NULL, NULL)) - { - LL_WARNS("Window") << "Release of DC and RC failed" << LL_ENDL; - } + //called from main thread + GLuint pixel_format; + DEVMODE dev_mode; + ::ZeroMemory(&dev_mode, sizeof(DEVMODE)); + dev_mode.dmSize = sizeof(DEVMODE); + DWORD current_refresh; + DWORD dw_ex_style; + DWORD dw_style; + RECT window_rect = { 0, 0, 0, 0 }; + S32 width = size.mX; + S32 height = size.mY; + BOOL auto_show = FALSE; + + if (mhRC) + { + auto_show = TRUE; + resetDisplayResolution(); + } - if (!wglDeleteContext(mhRC)) - { - LL_WARNS("Window") << "Release of rendering context failed" << LL_ENDL; - } + if (EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dev_mode)) + { + current_refresh = dev_mode.dmDisplayFrequency; + } + else + { + current_refresh = 60; + } - mhRC = NULL; - } + gGLManager.shutdownGL(); + //destroy gl context + if (mhRC) + { + if (!wglMakeCurrent(NULL, NULL)) + { + LL_WARNS("Window") << "Release of DC and RC failed" << LL_ENDL; + } - if (fullscreen) - { - mFullscreen = TRUE; - BOOL success = FALSE; - DWORD closest_refresh = 0; + if (!wglDeleteContext(mhRC)) + { + LL_WARNS("Window") << "Release of rendering context failed" << LL_ENDL; + } - for (S32 mode_num = 0;; mode_num++) - { - if (!EnumDisplaySettings(NULL, mode_num, &dev_mode)) - { - break; - } + mhRC = NULL; + } - if (dev_mode.dmPelsWidth == width && - dev_mode.dmPelsHeight == height && - dev_mode.dmBitsPerPel == BITS_PER_PIXEL) - { - success = TRUE; - if ((dev_mode.dmDisplayFrequency - current_refresh) - < (closest_refresh - current_refresh)) - { - closest_refresh = dev_mode.dmDisplayFrequency; - } - } - } + if (fullscreen) + { + mFullscreen = TRUE; + BOOL success = FALSE; + DWORD closest_refresh = 0; - if (closest_refresh == 0) - { - LL_WARNS("Window") << "Couldn't find display mode " << width << " by " << height << " at " << BITS_PER_PIXEL << " bits per pixel" << LL_ENDL; - return FALSE; - } + for (S32 mode_num = 0;; mode_num++) + { + if (!EnumDisplaySettings(NULL, mode_num, &dev_mode)) + { + break; + } - // If we found a good resolution, use it. - if (success) - { - success = setDisplayResolution(width, height, BITS_PER_PIXEL, closest_refresh); - } + if (dev_mode.dmPelsWidth == width && + dev_mode.dmPelsHeight == height && + dev_mode.dmBitsPerPel == BITS_PER_PIXEL) + { + success = TRUE; + if ((dev_mode.dmDisplayFrequency - current_refresh) + < (closest_refresh - current_refresh)) + { + closest_refresh = dev_mode.dmDisplayFrequency; + } + } + } - // Keep a copy of the actual current device mode in case we minimize - // and change the screen resolution. JC - EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dev_mode); + if (closest_refresh == 0) + { + LL_WARNS("Window") << "Couldn't find display mode " << width << " by " << height << " at " << BITS_PER_PIXEL << " bits per pixel" << LL_ENDL; + return FALSE; + } - if (success) - { - mFullscreen = TRUE; - mFullscreenWidth = dev_mode.dmPelsWidth; - mFullscreenHeight = dev_mode.dmPelsHeight; - mFullscreenBits = dev_mode.dmBitsPerPel; - mFullscreenRefresh = dev_mode.dmDisplayFrequency; + // If we found a good resolution, use it. + if (success) + { + success = setDisplayResolution(width, height, BITS_PER_PIXEL, closest_refresh); + } - LL_INFOS("Window") << "Running at " << dev_mode.dmPelsWidth - << "x" << dev_mode.dmPelsHeight - << "x" << dev_mode.dmBitsPerPel - << " @ " << dev_mode.dmDisplayFrequency - << LL_ENDL; + // Keep a copy of the actual current device mode in case we minimize + // and change the screen resolution. JC + EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dev_mode); - window_rect.left = (long) 0; - window_rect.right = (long) width; // Windows GDI rects don't include rightmost pixel - window_rect.top = (long) 0; - window_rect.bottom = (long) height; - dw_ex_style = WS_EX_APPWINDOW; - dw_style = WS_POPUP; + if (success) + { + mFullscreen = TRUE; + mFullscreenWidth = dev_mode.dmPelsWidth; + mFullscreenHeight = dev_mode.dmPelsHeight; + mFullscreenBits = dev_mode.dmBitsPerPel; + mFullscreenRefresh = dev_mode.dmDisplayFrequency; + + LL_INFOS("Window") << "Running at " << dev_mode.dmPelsWidth + << "x" << dev_mode.dmPelsHeight + << "x" << dev_mode.dmBitsPerPel + << " @ " << dev_mode.dmDisplayFrequency + << LL_ENDL; + + window_rect.left = (long)0; + window_rect.right = (long)width; // Windows GDI rects don't include rightmost pixel + window_rect.top = (long)0; + window_rect.bottom = (long)height; + dw_ex_style = WS_EX_APPWINDOW; + dw_style = WS_POPUP; + + // Move window borders out not to cover window contents. + // This converts client rect to window rect, i.e. expands it by the window border size. + AdjustWindowRectEx(&window_rect, dw_style, FALSE, dw_ex_style); + } + // If it failed, we don't want to run fullscreen + else + { + mFullscreen = FALSE; + mFullscreenWidth = -1; + mFullscreenHeight = -1; + mFullscreenBits = -1; + mFullscreenRefresh = -1; - // Move window borders out not to cover window contents. - // This converts client rect to window rect, i.e. expands it by the window border size. - AdjustWindowRectEx(&window_rect, dw_style, FALSE, dw_ex_style); - } - // If it failed, we don't want to run fullscreen - else - { - mFullscreen = FALSE; - mFullscreenWidth = -1; - mFullscreenHeight = -1; - mFullscreenBits = -1; - mFullscreenRefresh = -1; + LL_INFOS("Window") << "Unable to run fullscreen at " << width << "x" << height << LL_ENDL; + return FALSE; + } + } + else + { + mFullscreen = FALSE; + window_rect.left = (long)(posp ? posp->mX : 0); + window_rect.right = (long)width + window_rect.left; // Windows GDI rects don't include rightmost pixel + window_rect.top = (long)(posp ? posp->mY : 0); + window_rect.bottom = (long)height + window_rect.top; + // Window with an edge + dw_ex_style = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; + dw_style = WS_OVERLAPPEDWINDOW; + } - LL_INFOS("Window") << "Unable to run fullscreen at " << width << "x" << height << LL_ENDL; - return FALSE; - } - } - else - { - mFullscreen = FALSE; - window_rect.left = (long) (posp ? posp->mX : 0); - window_rect.right = (long) width + window_rect.left; // Windows GDI rects don't include rightmost pixel - window_rect.top = (long) (posp ? posp->mY : 0); - window_rect.bottom = (long) height + window_rect.top; - // Window with an edge - dw_ex_style = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; - dw_style = WS_OVERLAPPEDWINDOW; - } + // don't post quit messages when destroying old windows + mPostQuit = FALSE; - // don't post quit messages when destroying old windows - mPostQuit = FALSE; - // create window + // create window LL_DEBUGS("Window") << "Creating window with X: " << window_rect.left << " Y: " << window_rect.top << " Width: " << (window_rect.right - window_rect.left) << " Height: " << (window_rect.bottom - window_rect.top) << " Fullscreen: " << mFullscreen << LL_ENDL; - if (mWindowHandle && !destroy_window_handler(mWindowHandle)) + + auto oldHandle = mWindowHandle; + + //zero out mWindowHandle and mhDC before destroying window so window thread falls back to peekmessage + mWindowHandle = 0; + mhDC = 0; + + if (oldHandle && !destroy_window_handler(oldHandle)) { LL_WARNS("Window") << "Failed to properly close window before recreating it!" << LL_ENDL; - } - mWindowHandle = CreateWindowEx(dw_ex_style, - mWindowClassName, - mWindowTitle, - WS_CLIPSIBLINGS | WS_CLIPCHILDREN | dw_style, - window_rect.left, // x pos - window_rect.top, // y pos - window_rect.right - window_rect.left, // width - window_rect.bottom - window_rect.top, // height - NULL, - NULL, - mhInstance, - NULL); + } + + mWindowHandle = NULL; + mhDC = 0; + + mWindowThread->post( + [this, window_rect, dw_ex_style, dw_style]() + { + mWindowHandle = CreateWindowEx(dw_ex_style, + mWindowClassName, + mWindowTitle, + WS_CLIPSIBLINGS | WS_CLIPCHILDREN | dw_style, + window_rect.left, // x pos + window_rect.top, // y pos + window_rect.right - window_rect.left, // width + window_rect.bottom - window_rect.top, // height + NULL, + NULL, + mhInstance, + NULL); + + if (mWindowHandle) + { + mhDC = GetDC(mWindowHandle); + } + } + ); + + // HACK wait for above handle to become populated + // TODO: use a future + int count = 1024; + while (!mhDC && count > 0) + { + Sleep(10); + --count; + } if (mWindowHandle) { @@ -1288,7 +1352,7 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO 0, 0, 0 }; - if (!(mhDC = GetDC(mWindowHandle))) + if (!mhDC) { close(); OSMessageBox(mCallbacks->translateString("MBDevContextErr"), @@ -1582,25 +1646,48 @@ const S32 max_format = (S32)num_formats - 1; mhDC = 0; // Zero The Device Context } + auto oldHandle = mWindowHandle; + mWindowHandle = NULL; + mhDC = 0; + // Destroy The Window - if (mWindowHandle && !destroy_window_handler(mWindowHandle)) + if (oldHandle && !destroy_window_handler(oldHandle)) { LL_WARNS("Window") << "Failed to properly close window!" << LL_ENDL; } - mWindowHandle = CreateWindowEx(dw_ex_style, - mWindowClassName, - mWindowTitle, - WS_CLIPSIBLINGS | WS_CLIPCHILDREN | dw_style, - window_rect.left, // x pos - window_rect.top, // y pos - window_rect.right - window_rect.left, // width - window_rect.bottom - window_rect.top, // height - NULL, - NULL, - mhInstance, - NULL); + mWindowThread->post( + [this, window_rect, dw_ex_style, dw_style]() + { + mWindowHandle = CreateWindowEx(dw_ex_style, + mWindowClassName, + mWindowTitle, + WS_CLIPSIBLINGS | WS_CLIPCHILDREN | dw_style, + window_rect.left, // x pos + window_rect.top, // y pos + window_rect.right - window_rect.left, // width + window_rect.bottom - window_rect.top, // height + NULL, + NULL, + mhInstance, + NULL); + + if (mWindowHandle) + { + mhDC = GetDC(mWindowHandle); + } + } + ); + // HACK wait for above handle to become populated + // TODO: use a future + int count = 1024; + while (!mhDC && count > 0) + { + PostMessage(oldHandle, WM_USER + 8, 0x1717, 0x3b3b); + Sleep(10); + --count; + } if (mWindowHandle) { @@ -1612,7 +1699,7 @@ const S32 max_format = (S32)num_formats - 1; LL_WARNS("Window") << "Window recreation failed, code: " << GetLastError() << LL_ENDL; } - if (!(mhDC = GetDC(mWindowHandle))) + if (!mhDC) { close(); OSMessageBox(mCallbacks->translateString("MBDevContextErr"), mCallbacks->translateString("MBError"), OSMB_OK); @@ -1816,31 +1903,41 @@ void LLWindowWin32::moveWindow( const LLCoordScreen& position, const LLCoordScre BOOL LLWindowWin32::setCursorPosition(const LLCoordWindow position) { - mMousePositionModified = TRUE; + ASSERT_MAIN_THREAD(); + if (!mWindowHandle) { return FALSE; } - - // Inform the application of the new mouse position (needed for per-frame + // Inform the application of the new mouse position (needed for per-frame // hover/picking to function). mCallbacks->handleMouseMove(this, position.convert(), (MASK)0); - // DEV-18951 VWR-8524 Camera moves wildly when alt-clicking. - // Because we have preemptively notified the application of the new - // mouse position via handleMouseMove() above, we need to clear out - // any stale mouse move events. RN/JC - MSG msg; - while (PeekMessage(&msg, NULL, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE)) - { } - - LLCoordScreen screen_pos(position.convert()); - return ::SetCursorPos(screen_pos.mX, screen_pos.mY); + mMousePositionModified = TRUE; + LLCoordScreen screen_pos(position.convert()); + + mWindowThread->post([=] + { + SetCursorPos(screen_pos.mX, screen_pos.mY); + // DEV-18951 VWR-8524 Camera moves wildly when alt-clicking. + // Because we have preemptively notified the application of the new + // mouse position via handleMouseMove() above, we need to clear out + // any stale mouse move events. RN/JC + MSG msg; + while (PeekMessage(&msg, NULL, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE)) + { + } + + mMousePositionModified = FALSE; + }); + + return TRUE; } BOOL LLWindowWin32::getCursorPosition(LLCoordWindow *position) { + ASSERT_MAIN_THREAD(); POINT cursor_point; if (!mWindowHandle @@ -1856,21 +1953,35 @@ BOOL LLWindowWin32::getCursorPosition(LLCoordWindow *position) void LLWindowWin32::hideCursor() { - while (ShowCursor(FALSE) >= 0) - { - // nothing, wait for cursor to push down - } + ASSERT_MAIN_THREAD(); + + mWindowThread->post([=]() + { + while (ShowCursor(FALSE) >= 0) + { + // nothing, wait for cursor to push down + } + }); + mCursorHidden = TRUE; mHideCursorPermanent = TRUE; } void LLWindowWin32::showCursor() { - // makes sure the cursor shows up - while (ShowCursor(TRUE) < 0) - { - // do nothing, wait for cursor to pop out - } + LL_PROFILE_ZONE_SCOPED; + + ASSERT_MAIN_THREAD(); + + mWindowThread->post([=]() + { + // makes sure the cursor shows up + while (ShowCursor(TRUE) < 0) + { + // do nothing, wait for cursor to pop out + } + }); + mCursorHidden = FALSE; mHideCursorPermanent = FALSE; } @@ -1972,6 +2083,8 @@ void LLWindowWin32::initCursors() void LLWindowWin32::updateCursor() { + ASSERT_MAIN_THREAD(); + LL_PROFILE_ZONE_SCOPED if (mNextCursor == UI_CURSOR_ARROW && mBusyCount > 0) { @@ -1981,7 +2094,11 @@ void LLWindowWin32::updateCursor() if( mCurrentCursor != mNextCursor ) { mCurrentCursor = mNextCursor; - SetCursor( mCursor[mNextCursor] ); + auto nextCursor = mCursor[mNextCursor]; + mWindowThread->post([=]() + { + SetCursor(nextCursor); + }); } } @@ -1997,13 +2114,8 @@ void LLWindowWin32::captureMouse() void LLWindowWin32::releaseMouse() { - // *NOTE:Mani ReleaseCapture will spawn new windows messages... - // which will in turn call our MainWindowProc. It therefore requires - // pausing *and more importantly resumption* of the mainlooptimeout... - // just like DispatchMessage below. - mCallbacks->handlePauseWatchdog(this); + LL_PROFILE_ZONE_SCOPED; ReleaseCapture(); - mCallbacks->handleResumeWatchdog(this); } @@ -2012,1003 +2124,1129 @@ void LLWindowWin32::delayInputProcessing() mInputProcessingPaused = TRUE; } + void LLWindowWin32::gatherInput() { - MSG msg; - int msg_count = 0; + ASSERT_MAIN_THREAD(); + LL_PROFILE_ZONE_SCOPED + MSG msg; - while ((msg_count < MAX_MESSAGE_PER_UPDATE) && PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) - { - mCallbacks->handlePingWatchdog(this, "Main:TranslateGatherInput"); - TranslateMessage(&msg); +#if LL_WINDOW_SINGLE_THREADED + int msg_count = 0; + + while ((msg_count < MAX_MESSAGE_PER_UPDATE)) + { + LL_PROFILE_ZONE_NAMED("gi - loop"); + ++msg_count; + { + LL_PROFILE_ZONE_NAMED("gi - PeekMessage"); + if (!PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + { + break; + } + } - // turn watchdog off in here to not fail if windows is doing something wacky - mCallbacks->handlePauseWatchdog(this); - DispatchMessage(&msg); - mCallbacks->handleResumeWatchdog(this); - msg_count++; + { + LL_PROFILE_ZONE_NAMED("gi - translate"); + TranslateMessage(&msg); + } - if ( mInputProcessingPaused ) - { - break; - } - /* Attempted workaround for problem where typing fast and hitting - return would result in only part of the text being sent. JC + { + LL_PROFILE_ZONE_NAMED("gi - dispatch"); + DispatchMessage(&msg); + } - BOOL key_posted = TranslateMessage(&msg); - DispatchMessage(&msg); - msg_count++; + if (mInputProcessingPaused) + { + break; + } - // If a key was translated, a WM_CHAR might have been posted to the end - // of the event queue. We need it immediately. - if (key_posted && msg.message == WM_KEYDOWN) - { - if (PeekMessage(&msg, NULL, WM_CHAR, WM_CHAR, PM_REMOVE)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - msg_count++; - } - } - */ - mCallbacks->handlePingWatchdog(this, "Main:AsyncCallbackGatherInput"); - // For async host by name support. Really hacky. - if (gAsyncMsgCallback && (LL_WM_HOST_RESOLVED == msg.message)) - { - gAsyncMsgCallback(msg); - } - } + // For async host by name support. Really hacky. + if (gAsyncMsgCallback && (LL_WM_HOST_RESOLVED == msg.message)) + { + LL_PROFILE_ZONE_NAMED("gi - callback"); + gAsyncMsgCallback(msg); + } + } +#else //multi-threaded window impl + { + if (mWindowThread->mFunctionQueue.size() > 0) + { + LL_PROFILE_ZONE_NAMED("gi - PostMessage"); + if (mWindowHandle) + { // post a nonsense user message to wake up the Window Thread in case any functions are pending + // and no windows events came through this frame + PostMessage(mWindowHandle, WM_USER + 0x0017, 0xB0B0, 0x1337); + } + } + + while (mWindowThread->mMessageQueue.tryPopBack(msg)) + { + LL_PROFILE_ZONE_NAMED("gi - message queue"); + if (mInputProcessingPaused) + { + continue; + } + + // For async host by name support. Really hacky. + if (gAsyncMsgCallback && (LL_WM_HOST_RESOLVED == msg.message)) + { + LL_PROFILE_ZONE_NAMED("gi - callback"); + gAsyncMsgCallback(msg); + } + } + } + + { + LL_PROFILE_ZONE_NAMED("gi - function queue"); + //process any pending functions + std::function curFunc; + while (mFunctionQueue.tryPopBack(curFunc)) + { + curFunc(); + } + } +#endif mInputProcessingPaused = FALSE; updateCursor(); - - // clear this once we've processed all mouse messages that might have occurred after - // we slammed the mouse position - mMousePositionModified = FALSE; } static LLTrace::BlockTimerStatHandle FTM_KEYHANDLER("Handle Keyboard"); static LLTrace::BlockTimerStatHandle FTM_MOUSEHANDLER("Handle Mouse"); +#if LL_WINDOW_SINGLE_THREADED +#define WINDOW_IMP_POST(x) x +#else +#define WINDOW_IMP_POST(x) window_imp->post([=]() { x; }) +#endif + LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_param, LPARAM l_param) { - // Ignore clicks not originated in the client area, i.e. mouse-up events not preceded with a WM_LBUTTONDOWN. - // This helps prevent avatar walking after maximizing the window by double-clicking the title bar. - static bool sHandleLeftMouseUp = true; + ASSERT_WINDOW_THREAD(); + LL_PROFILE_ZONE_SCOPED; - // Ignore the double click received right after activating app. - // This is to avoid triggering double click teleport after returning focus (see MAINT-3786). - static bool sHandleDoubleClick = true; + // Ignore clicks not originated in the client area, i.e. mouse-up events not preceded with a WM_LBUTTONDOWN. + // This helps prevent avatar walking after maximizing the window by double-clicking the title bar. + static bool sHandleLeftMouseUp = true; - LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLongPtr( h_wnd, GWLP_USERDATA ); + // Ignore the double click received right after activating app. + // This is to avoid triggering double click teleport after returning focus (see MAINT-3786). + static bool sHandleDoubleClick = true; - bool debug_window_proc = gDebugWindowProc || debugLoggingEnabled("Window"); + LLWindowWin32* window_imp = (LLWindowWin32*)GetWindowLongPtr(h_wnd, GWLP_USERDATA); + bool debug_window_proc = false; // gDebugWindowProc || debugLoggingEnabled("Window"); - if (NULL != window_imp) - { - window_imp->mCallbacks->handleResumeWatchdog(window_imp); - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:StartWndProc"); - // Has user provided their own window callback? - if (NULL != window_imp->mWndProc) - { - if (!window_imp->mWndProc(h_wnd, u_msg, w_param, l_param)) - { - // user has handled window message - return 0; - } - } + if (NULL != window_imp) + { + // Has user provided their own window callback? + if (NULL != window_imp->mWndProc) + { + LL_PROFILE_ZONE_NAMED("mwp - WndProc"); + if (!window_imp->mWndProc(h_wnd, u_msg, w_param, l_param)) + { + // user has handled window message + return 0; + } + } - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:PreSwitchWndProc"); - - // Juggle to make sure we can get negative positions for when - // mouse is outside window. - LLCoordWindow window_coord((S32)(S16)LOWORD(l_param), (S32)(S16)HIWORD(l_param)); + // Juggle to make sure we can get negative positions for when + // mouse is outside window. + LLCoordWindow window_coord((S32)(S16)LOWORD(l_param), (S32)(S16)HIWORD(l_param)); - // This doesn't work, as LOWORD returns unsigned short. - //LLCoordWindow window_coord(LOWORD(l_param), HIWORD(l_param)); - LLCoordGL gl_coord; + // This doesn't work, as LOWORD returns unsigned short. + //LLCoordWindow window_coord(LOWORD(l_param), HIWORD(l_param)); + LLCoordGL gl_coord; - // pass along extended flag in mask - MASK mask = (l_param>>16 & KF_EXTENDED) ? MASK_EXTENDED : 0x0; - BOOL eat_keystroke = TRUE; + // pass along extended flag in mask + MASK mask = (l_param >> 16 & KF_EXTENDED) ? MASK_EXTENDED : 0x0; + BOOL eat_keystroke = TRUE; - switch(u_msg) - { - RECT update_rect; - S32 update_width; - S32 update_height; + switch (u_msg) + { + RECT update_rect; + S32 update_width; + S32 update_height; - case WM_TIMER: - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_TIMER"); - window_imp->mCallbacks->handleTimerEvent(window_imp); - break; + case WM_TIMER: + { + LL_PROFILE_ZONE_NAMED("mwp - WM_TIMER"); + WINDOW_IMP_POST(window_imp->mCallbacks->handleTimerEvent(window_imp)); + break; + } - case WM_DEVICECHANGE: - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_DEVICECHANGE"); - if (debug_window_proc) - { - LL_INFOS("Window") << " WM_DEVICECHANGE: wParam=" << w_param - << "; lParam=" << l_param << LL_ENDL; - } - if (w_param == DBT_DEVNODES_CHANGED || w_param == DBT_DEVICEARRIVAL) - { - if (window_imp->mCallbacks->handleDeviceChange(window_imp)) - { - return 0; - } - } - break; - - case WM_PAINT: - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_PAINT"); - GetUpdateRect(window_imp->mWindowHandle, &update_rect, FALSE); - update_width = update_rect.right - update_rect.left + 1; - update_height = update_rect.bottom - update_rect.top + 1; - window_imp->mCallbacks->handlePaint(window_imp, update_rect.left, update_rect.top, - update_width, update_height); - break; - case WM_PARENTNOTIFY: - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_PARENTNOTIFY"); - u_msg = u_msg; - break; - - case WM_SETCURSOR: - // This message is sent whenever the cursor is moved in a window. - // You need to set the appropriate cursor appearance. - - // Only take control of cursor over client region of window - // This allows Windows(tm) to handle resize cursors, etc. - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_SETCURSOR"); - if (LOWORD(l_param) == HTCLIENT) - { - SetCursor(window_imp->mCursor[ window_imp->mCurrentCursor] ); - return 0; - } - break; - - case WM_ENTERMENULOOP: - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_ENTERMENULOOP"); - window_imp->mCallbacks->handleWindowBlock(window_imp); - break; - - case WM_EXITMENULOOP: - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_EXITMENULOOP"); - window_imp->mCallbacks->handleWindowUnblock(window_imp); - break; - - case WM_ACTIVATEAPP: - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_ACTIVATEAPP"); - { - // This message should be sent whenever the app gains or loses focus. - BOOL activating = (BOOL) w_param; - BOOL minimized = window_imp->getMinimized(); - - if (debug_window_proc) - { - LL_INFOS("Window") << "WINDOWPROC ActivateApp " - << " activating " << S32(activating) - << " minimized " << S32(minimized) - << " fullscreen " << S32(window_imp->mFullscreen) - << LL_ENDL; - } - - if (window_imp->mFullscreen) - { - // When we run fullscreen, restoring or minimizing the app needs - // to switch the screen resolution - if (activating) - { - window_imp->setFullscreenResolution(); - window_imp->restore(); - } - else - { - window_imp->minimize(); - window_imp->resetDisplayResolution(); - } - } - - if (!activating) - { - sHandleDoubleClick = false; - } - - window_imp->mCallbacks->handleActivateApp(window_imp, activating); - - break; - } - - case WM_ACTIVATE: - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_ACTIVATE"); - { - // Can be one of WA_ACTIVE, WA_CLICKACTIVE, or WA_INACTIVE - BOOL activating = (LOWORD(w_param) != WA_INACTIVE); - - BOOL minimized = BOOL(HIWORD(w_param)); - - if (!activating && LLWinImm::isAvailable() && window_imp->mPreeditor) - { - window_imp->interruptLanguageTextInput(); - } - - // JC - I'm not sure why, but if we don't report that we handled the - // WM_ACTIVATE message, the WM_ACTIVATEAPP messages don't work - // properly when we run fullscreen. - if (debug_window_proc) - { - LL_INFOS("Window") << "WINDOWPROC Activate " - << " activating " << S32(activating) - << " minimized " << S32(minimized) - << LL_ENDL; - } - - // Don't handle this. - break; - } - - case WM_QUERYOPEN: - // TODO: use this to return a nice icon - break; - - case WM_SYSCOMMAND: - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_SYSCOMMAND"); - switch(w_param) - { - case SC_KEYMENU: - // Disallow the ALT key from triggering the default system menu. - return 0; - - case SC_SCREENSAVE: - case SC_MONITORPOWER: - // eat screen save messages and prevent them! - return 0; - } - break; - - case WM_CLOSE: - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_CLOSE"); - // Will the app allow the window to close? - if (window_imp->mCallbacks->handleCloseRequest(window_imp)) - { - // Get the app to initiate cleanup. - window_imp->mCallbacks->handleQuit(window_imp); - // The app is responsible for calling destroyWindow when done with GL - } - return 0; - - case WM_DESTROY: - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_DESTROY"); - if (window_imp->shouldPostQuit()) - { - PostQuitMessage(0); // Posts WM_QUIT with an exit code of 0 - } - return 0; - - case WM_COMMAND: - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_COMMAND"); - if (!HIWORD(w_param)) // this message is from a menu - { - window_imp->mCallbacks->handleMenuSelect(window_imp, LOWORD(w_param)); - } - break; - - case WM_SYSKEYDOWN: - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_SYSKEYDOWN"); - // allow system keys, such as ALT-F4 to be processed by Windows - eat_keystroke = FALSE; - case WM_KEYDOWN: - window_imp->mKeyCharCode = 0; // don't know until wm_char comes in next - window_imp->mKeyScanCode = ( l_param >> 16 ) & 0xff; - window_imp->mKeyVirtualKey = w_param; - window_imp->mRawMsg = u_msg; - window_imp->mRawWParam = w_param; - window_imp->mRawLParam = l_param; - - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_KEYDOWN"); - { - if (debug_window_proc) - { - LL_INFOS("Window") << "Debug WindowProc WM_KEYDOWN " - << " key " << S32(w_param) - << LL_ENDL; - } - if(gKeyboard->handleKeyDown(w_param, mask) && eat_keystroke) - { - return 0; - } - // pass on to windows if we didn't handle it - break; - } - case WM_SYSKEYUP: - eat_keystroke = FALSE; - case WM_KEYUP: - { - window_imp->mKeyScanCode = ( l_param >> 16 ) & 0xff; - window_imp->mKeyVirtualKey = w_param; - window_imp->mRawMsg = u_msg; - window_imp->mRawWParam = w_param; - window_imp->mRawLParam = l_param; - - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_KEYUP"); - LL_RECORD_BLOCK_TIME(FTM_KEYHANDLER); - - if (debug_window_proc) - { - LL_INFOS("Window") << "Debug WindowProc WM_KEYUP " - << " key " << S32(w_param) - << LL_ENDL; - } - if (gKeyboard->handleKeyUp(w_param, mask) && eat_keystroke) - { - return 0; - } - - // pass on to windows - break; - } - case WM_IME_SETCONTEXT: - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_IME_SETCONTEXT"); - if (debug_window_proc) - { - LL_INFOS("Window") << "WM_IME_SETCONTEXT" << LL_ENDL; - } - if (LLWinImm::isAvailable() && window_imp->mPreeditor) - { - l_param &= ~ISC_SHOWUICOMPOSITIONWINDOW; - // Invoke DefWinProc with the modified LPARAM. - } - break; - - case WM_IME_STARTCOMPOSITION: - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_IME_STARTCOMPOSITION"); - if (debug_window_proc) - { - LL_INFOS() << "WM_IME_STARTCOMPOSITION" << LL_ENDL; - } - if (LLWinImm::isAvailable() && window_imp->mPreeditor) - { - window_imp->handleStartCompositionMessage(); - return 0; - } - break; - - case WM_IME_ENDCOMPOSITION: - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_IME_ENDCOMPOSITION"); - if (debug_window_proc) - { - LL_INFOS() << "WM_IME_ENDCOMPOSITION" << LL_ENDL; - } - if (LLWinImm::isAvailable() && window_imp->mPreeditor) - { - return 0; - } - break; - - case WM_IME_COMPOSITION: - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_IME_COMPOSITION"); - if (debug_window_proc) - { - LL_INFOS() << "WM_IME_COMPOSITION" << LL_ENDL; - } - if (LLWinImm::isAvailable() && window_imp->mPreeditor) - { - window_imp->handleCompositionMessage(l_param); - return 0; - } - break; - - case WM_IME_REQUEST: - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_IME_REQUEST"); - if (debug_window_proc) - { - LL_INFOS() << "WM_IME_REQUEST" << LL_ENDL; - } - if (LLWinImm::isAvailable() && window_imp->mPreeditor) - { - LRESULT result = 0; - if (window_imp->handleImeRequests(w_param, l_param, &result)) - { - return result; - } - } - break; - - case WM_CHAR: - window_imp->mKeyCharCode = w_param; - window_imp->mRawMsg = u_msg; - window_imp->mRawWParam = w_param; - window_imp->mRawLParam = l_param; - - // Should really use WM_UNICHAR eventually, but it requires a specific Windows version and I need - // to figure out how that works. - Doug - // - // ... Well, I don't think so. - // How it works is explained in Win32 API document, but WM_UNICHAR didn't work - // as specified at least on Windows XP SP1 Japanese version. I have never used - // it since then, and I'm not sure whether it has been fixed now, but I don't think - // it is worth trying. The good old WM_CHAR works just fine even for supplementary - // characters. We just need to take care of surrogate pairs sent as two WM_CHAR's - // by ourselves. It is not that tough. -- Alissa Sabre @ SL - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_CHAR"); - if (debug_window_proc) - { - LL_INFOS("Window") << "Debug WindowProc WM_CHAR " - << " key " << S32(w_param) - << LL_ENDL; - } - // Even if LLWindowCallbacks::handleUnicodeChar(llwchar, BOOL) returned FALSE, - // we *did* processed the event, so I believe we should not pass it to DefWindowProc... - window_imp->handleUnicodeUTF16((U16)w_param, gKeyboard->currentMask(FALSE)); - return 0; + case WM_DEVICECHANGE: + { + LL_PROFILE_ZONE_NAMED("mwp - WM_DEVICECHANGE"); + if (debug_window_proc) + { + LL_INFOS("Window") << " WM_DEVICECHANGE: wParam=" << w_param + << "; lParam=" << l_param << LL_ENDL; + } + if (w_param == DBT_DEVNODES_CHANGED || w_param == DBT_DEVICEARRIVAL) + { + WINDOW_IMP_POST(window_imp->mCallbacks->handleDeviceChange(window_imp)); + + return TRUE; + } + break; + } - case WM_NCLBUTTONDOWN: - { - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_NCLBUTTONDOWN"); - // A click in a non-client area, e.g. title bar or window border. - sHandleLeftMouseUp = false; - sHandleDoubleClick = true; - } - break; + case WM_PAINT: + { + LL_PROFILE_ZONE_NAMED("mwp - WM_PAINT"); + GetUpdateRect(window_imp->mWindowHandle, &update_rect, FALSE); + update_width = update_rect.right - update_rect.left + 1; + update_height = update_rect.bottom - update_rect.top + 1; + + WINDOW_IMP_POST(window_imp->mCallbacks->handlePaint(window_imp, update_rect.left, update_rect.top, + update_width, update_height)); + break; + } + case WM_PARENTNOTIFY: + { + break; + } - case WM_LBUTTONDOWN: - { - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_LBUTTONDOWN"); - LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); - sHandleLeftMouseUp = true; + case WM_SETCURSOR: + { + LL_PROFILE_ZONE_NAMED("mwp - WM_SETCURSOR"); + // This message is sent whenever the cursor is moved in a window. + // You need to set the appropriate cursor appearance. - if (LLWinImm::isAvailable() && window_imp->mPreeditor) - { - window_imp->interruptLanguageTextInput(); - } + // Only take control of cursor over client region of window + // This allows Windows(tm) to handle resize cursors, etc. + if (LOWORD(l_param) == HTCLIENT) + { + SetCursor(window_imp->mCursor[window_imp->mCurrentCursor]); + return 0; + } + break; + } + case WM_ENTERMENULOOP: + { + LL_PROFILE_ZONE_NAMED("mwp - WM_ENTERMENULOOP"); + WINDOW_IMP_POST(window_imp->mCallbacks->handleWindowBlock(window_imp)); + break; + } - // Because we move the cursor position in the app, we need to query - // to find out where the cursor at the time the event is handled. - // If we don't do this, many clicks could get buffered up, and if the - // first click changes the cursor position, all subsequent clicks - // will occur at the wrong location. JC - if (window_imp->mMousePositionModified) - { - LLCoordWindow cursor_coord_window; - window_imp->getCursorPosition(&cursor_coord_window); - gl_coord = cursor_coord_window.convert(); - } - else - { - gl_coord = window_coord.convert(); - } - MASK mask = gKeyboard->currentMask(TRUE); - // generate move event to update mouse coordinates - window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask); - if (window_imp->mCallbacks->handleMouseDown(window_imp, gl_coord, mask)) - { - return 0; - } - } - break; + case WM_EXITMENULOOP: + { + LL_PROFILE_ZONE_NAMED("mwp - WM_EXITMENULOOP"); + WINDOW_IMP_POST(window_imp->mCallbacks->handleWindowUnblock(window_imp)); + break; + } - case WM_LBUTTONDBLCLK: - //RN: ignore right button double clicks for now - //case WM_RBUTTONDBLCLK: - { - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_LBUTTONDBLCLK"); + case WM_ACTIVATEAPP: + { + LL_PROFILE_ZONE_NAMED("mwp - WM_ACTIVATEAPP"); + window_imp->post([=]() + { + // This message should be sent whenever the app gains or loses focus. + BOOL activating = (BOOL)w_param; + BOOL minimized = window_imp->getMinimized(); + + if (debug_window_proc) + { + LL_INFOS("Window") << "WINDOWPROC ActivateApp " + << " activating " << S32(activating) + << " minimized " << S32(minimized) + << " fullscreen " << S32(window_imp->mFullscreen) + << LL_ENDL; + } + + if (window_imp->mFullscreen) + { + // When we run fullscreen, restoring or minimizing the app needs + // to switch the screen resolution + if (activating) + { + window_imp->setFullscreenResolution(); + window_imp->restore(); + } + else + { + window_imp->minimize(); + window_imp->resetDisplayResolution(); + } + } + + if (!activating) + { + sHandleDoubleClick = false; + } + + window_imp->mCallbacks->handleActivateApp(window_imp, activating); + }); + break; + } + case WM_ACTIVATE: + { + LL_PROFILE_ZONE_NAMED("mwp - WM_ACTIVATE"); + window_imp->post([=]() + { + // Can be one of WA_ACTIVE, WA_CLICKACTIVE, or WA_INACTIVE + BOOL activating = (LOWORD(w_param) != WA_INACTIVE); + + BOOL minimized = BOOL(HIWORD(w_param)); + + if (!activating && LLWinImm::isAvailable() && window_imp->mPreeditor) + { + window_imp->interruptLanguageTextInput(); + } + + // JC - I'm not sure why, but if we don't report that we handled the + // WM_ACTIVATE message, the WM_ACTIVATEAPP messages don't work + // properly when we run fullscreen. + if (debug_window_proc) + { + LL_INFOS("Window") << "WINDOWPROC Activate " + << " activating " << S32(activating) + << " minimized " << S32(minimized) + << LL_ENDL; + } + }); + + break; + } - if (!sHandleDoubleClick) - { - sHandleDoubleClick = true; - break; - } + case WM_QUERYOPEN: + // TODO: use this to return a nice icon + break; - // Because we move the cursor position in the app, we need to query - // to find out where the cursor at the time the event is handled. - // If we don't do this, many clicks could get buffered up, and if the - // first click changes the cursor position, all subsequent clicks - // will occur at the wrong location. JC - if (window_imp->mMousePositionModified) - { - LLCoordWindow cursor_coord_window; - window_imp->getCursorPosition(&cursor_coord_window); - gl_coord = cursor_coord_window.convert(); - } - else - { - gl_coord = window_coord.convert(); - } - MASK mask = gKeyboard->currentMask(TRUE); - // generate move event to update mouse coordinates - window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask); - if (window_imp->mCallbacks->handleDoubleClick(window_imp, gl_coord, mask) ) - { - return 0; - } - } - break; + case WM_SYSCOMMAND: + { + LL_PROFILE_ZONE_NAMED("mwp - WM_SYSCOMMAND"); + switch (w_param) + { + case SC_KEYMENU: + // Disallow the ALT key from triggering the default system menu. + return 0; + + case SC_SCREENSAVE: + case SC_MONITORPOWER: + // eat screen save messages and prevent them! + return 0; + } + break; + } + case WM_CLOSE: + { + LL_PROFILE_ZONE_NAMED("mwp - WM_CLOSE"); + window_imp->post([=]() + { + // Will the app allow the window to close? + if (window_imp->mCallbacks->handleCloseRequest(window_imp)) + { + // Get the app to initiate cleanup. + window_imp->mCallbacks->handleQuit(window_imp); + // The app is responsible for calling destroyWindow when done with GL + } + }); + return 0; + } + case WM_DESTROY: + { + LL_PROFILE_ZONE_NAMED("mwp - WM_DESTROY"); + if (window_imp->shouldPostQuit()) + { + PostQuitMessage(0); // Posts WM_QUIT with an exit code of 0 + } + return 0; + } + case WM_COMMAND: + { + LL_PROFILE_ZONE_NAMED("mwp - WM_COMMAND"); + if (!HIWORD(w_param)) // this message is from a menu + { + WINDOW_IMP_POST(window_imp->mCallbacks->handleMenuSelect(window_imp, LOWORD(w_param))); + } + break; + } + case WM_SYSKEYDOWN: + { + LL_PROFILE_ZONE_NAMED("mwp - WM_SYSKEYDOWN"); + // allow system keys, such as ALT-F4 to be processed by Windows + eat_keystroke = FALSE; + } + case WM_KEYDOWN: + { + LL_PROFILE_ZONE_NAMED("mwp - WM_KEYDOWN"); + window_imp->post([=]() + { + window_imp->mKeyCharCode = 0; // don't know until wm_char comes in next + window_imp->mKeyScanCode = (l_param >> 16) & 0xff; + window_imp->mKeyVirtualKey = w_param; + window_imp->mRawMsg = u_msg; + window_imp->mRawWParam = w_param; + window_imp->mRawLParam = l_param; + + { + if (debug_window_proc) + { + LL_INFOS("Window") << "Debug WindowProc WM_KEYDOWN " + << " key " << S32(w_param) + << LL_ENDL; + } + + gKeyboard->handleKeyDown(w_param, mask); + } + }); + return eat_keystroke; + } + case WM_SYSKEYUP: + eat_keystroke = FALSE; + case WM_KEYUP: + { + LL_PROFILE_ZONE_NAMED("mwp - WM_KEYUP"); + window_imp->post([=]() + { + window_imp->mKeyScanCode = (l_param >> 16) & 0xff; + window_imp->mKeyVirtualKey = w_param; + window_imp->mRawMsg = u_msg; + window_imp->mRawWParam = w_param; + window_imp->mRawLParam = l_param; + + { + LL_RECORD_BLOCK_TIME(FTM_KEYHANDLER); + + if (debug_window_proc) + { + LL_INFOS("Window") << "Debug WindowProc WM_KEYUP " + << " key " << S32(w_param) + << LL_ENDL; + } + gKeyboard->handleKeyUp(w_param, mask); + } + }); + return eat_keystroke; + } + case WM_IME_SETCONTEXT: + { + LL_PROFILE_ZONE_NAMED("mwp - WM_IME_SETCONTEXT"); + if (debug_window_proc) + { + LL_INFOS("Window") << "WM_IME_SETCONTEXT" << LL_ENDL; + } + if (LLWinImm::isAvailable() && window_imp->mPreeditor) + { + l_param &= ~ISC_SHOWUICOMPOSITIONWINDOW; + // Invoke DefWinProc with the modified LPARAM. + } + break; + } + case WM_IME_STARTCOMPOSITION: + { + LL_PROFILE_ZONE_NAMED("mwp - WM_IME_STARTCOMPOSITION"); + if (debug_window_proc) + { + LL_INFOS() << "WM_IME_STARTCOMPOSITION" << LL_ENDL; + } + if (LLWinImm::isAvailable() && window_imp->mPreeditor) + { + WINDOW_IMP_POST(window_imp->handleStartCompositionMessage()); + return 0; + } + break; + } + case WM_IME_ENDCOMPOSITION: + { + LL_PROFILE_ZONE_NAMED("mwp - WM_IME_ENDCOMPOSITION"); + if (debug_window_proc) + { + LL_INFOS() << "WM_IME_ENDCOMPOSITION" << LL_ENDL; + } + if (LLWinImm::isAvailable() && window_imp->mPreeditor) + { + return 0; + } + break; + } + case WM_IME_COMPOSITION: + { + LL_PROFILE_ZONE_NAMED("mwp - WM_IME_COMPOSITION"); + if (debug_window_proc) + { + LL_INFOS() << "WM_IME_COMPOSITION" << LL_ENDL; + } + if (LLWinImm::isAvailable() && window_imp->mPreeditor) + { + WINDOW_IMP_POST(window_imp->handleCompositionMessage(l_param)); + return 0; + } + break; + } + case WM_IME_REQUEST: + { + LL_PROFILE_ZONE_NAMED("mwp - WM_IME_REQUEST"); + if (debug_window_proc) + { + LL_INFOS() << "WM_IME_REQUEST" << LL_ENDL; + } + if (LLWinImm::isAvailable() && window_imp->mPreeditor) + { + LRESULT result; + window_imp->handleImeRequests(w_param, l_param, &result); + return result; + } + break; + } + case WM_CHAR: + { + LL_PROFILE_ZONE_NAMED("mwp - WM_CHAR"); + window_imp->post([=]() + { + window_imp->mKeyCharCode = w_param; + window_imp->mRawMsg = u_msg; + window_imp->mRawWParam = w_param; + window_imp->mRawLParam = l_param; + + // Should really use WM_UNICHAR eventually, but it requires a specific Windows version and I need + // to figure out how that works. - Doug + // + // ... Well, I don't think so. + // How it works is explained in Win32 API document, but WM_UNICHAR didn't work + // as specified at least on Windows XP SP1 Japanese version. I have never used + // it since then, and I'm not sure whether it has been fixed now, but I don't think + // it is worth trying. The good old WM_CHAR works just fine even for supplementary + // characters. We just need to take care of surrogate pairs sent as two WM_CHAR's + // by ourselves. It is not that tough. -- Alissa Sabre @ SL + if (debug_window_proc) + { + LL_INFOS("Window") << "Debug WindowProc WM_CHAR " + << " key " << S32(w_param) + << LL_ENDL; + } + // Even if LLWindowCallbacks::handleUnicodeChar(llwchar, BOOL) returned FALSE, + // we *did* processed the event, so I believe we should not pass it to DefWindowProc... + window_imp->handleUnicodeUTF16((U16)w_param, gKeyboard->currentMask(FALSE)); + }); + return 0; + } + case WM_NCLBUTTONDOWN: + { + LL_PROFILE_ZONE_NAMED("mwp - WM_NCLBUTTONDOWN"); + { + // A click in a non-client area, e.g. title bar or window border. + window_imp->post([=]() + { + sHandleLeftMouseUp = false; + sHandleDoubleClick = true; + }); + } + break; + } + case WM_LBUTTONDOWN: + { + LL_PROFILE_ZONE_NAMED("mwp - WM_LBUTTONDOWN"); + { + LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); + window_imp->post([=]() + { + auto glc = gl_coord; + sHandleLeftMouseUp = true; + + if (LLWinImm::isAvailable() && window_imp->mPreeditor) + { + window_imp->interruptLanguageTextInput(); + } + + // Because we move the cursor position in the app, we need to query + // to find out where the cursor at the time the event is handled. + // If we don't do this, many clicks could get buffered up, and if the + // first click changes the cursor position, all subsequent clicks + // will occur at the wrong location. JC + if (window_imp->mMousePositionModified) + { + LLCoordWindow cursor_coord_window; + window_imp->getCursorPosition(&cursor_coord_window); + glc = cursor_coord_window.convert(); + } + else + { + glc = window_coord.convert(); + } + MASK mask = gKeyboard->currentMask(TRUE); + // generate move event to update mouse coordinates + window_imp->mCallbacks->handleMouseMove(window_imp, glc, mask); + window_imp->mCallbacks->handleMouseDown(window_imp, glc, mask); + }); + + return 0; + } + break; + } - case WM_LBUTTONUP: - { - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_LBUTTONUP"); - LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); + case WM_LBUTTONDBLCLK: + { + LL_PROFILE_ZONE_NAMED("mwp - WM_LBUTTONDBLCLK"); + //RN: ignore right button double clicks for now + //case WM_RBUTTONDBLCLK: + if (!sHandleDoubleClick) + { + sHandleDoubleClick = true; + return 0; + } - if (!sHandleLeftMouseUp) - { - sHandleLeftMouseUp = true; - break; - } - sHandleDoubleClick = true; - - //if (gDebugClicks) - //{ - // LL_INFOS("Window") << "WndProc left button up" << LL_ENDL; - //} - // Because we move the cursor position in the app, we need to query - // to find out where the cursor at the time the event is handled. - // If we don't do this, many clicks could get buffered up, and if the - // first click changes the cursor position, all subsequent clicks - // will occur at the wrong location. JC - if (window_imp->mMousePositionModified) - { - LLCoordWindow cursor_coord_window; - window_imp->getCursorPosition(&cursor_coord_window); - gl_coord = cursor_coord_window.convert(); - } - else - { - gl_coord = window_coord.convert(); - } - MASK mask = gKeyboard->currentMask(TRUE); - // generate move event to update mouse coordinates - window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask); - if (window_imp->mCallbacks->handleMouseUp(window_imp, gl_coord, mask)) - { - return 0; - } - } - break; + // Because we move the cursor position in the app, we need to query + // to find out where the cursor at the time the event is handled. + // If we don't do this, many clicks could get buffered up, and if the + // first click changes the cursor position, all subsequent clicks + // will occur at the wrong location. JC + if (window_imp->mMousePositionModified) + { + LLCoordWindow cursor_coord_window; + window_imp->getCursorPosition(&cursor_coord_window); + gl_coord = cursor_coord_window.convert(); + } + else + { + gl_coord = window_coord.convert(); + } + MASK mask = gKeyboard->currentMask(TRUE); + // generate move event to update mouse coordinates + window_imp->post([=]() + { + window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask); + window_imp->mCallbacks->handleDoubleClick(window_imp, gl_coord, mask); + }); + return 0; + } + case WM_LBUTTONUP: + { + LL_PROFILE_ZONE_NAMED("mwp - WM_LBUTTONUP"); + { + LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); + + if (!sHandleLeftMouseUp) + { + sHandleLeftMouseUp = true; + return 0; + } + sHandleDoubleClick = true; + window_imp->post([=]() + { + auto glc = gl_coord; + + //if (gDebugClicks) + //{ + // LL_INFOS("Window") << "WndProc left button up" << LL_ENDL; + //} + // Because we move the cursor position in the app, we need to query + // to find out where the cursor at the time the event is handled. + // If we don't do this, many clicks could get buffered up, and if the + // first click changes the cursor position, all subsequent clicks + // will occur at the wrong location. JC + if (window_imp->mMousePositionModified) + { + LLCoordWindow cursor_coord_window; + window_imp->getCursorPosition(&cursor_coord_window); + glc = cursor_coord_window.convert(); + } + else + { + glc = window_coord.convert(); + } + MASK mask = gKeyboard->currentMask(TRUE); + // generate move event to update mouse coordinates + window_imp->mCallbacks->handleMouseMove(window_imp, glc, mask); + window_imp->mCallbacks->handleMouseUp(window_imp, glc, mask); + }); + } + return 0; + } + case WM_RBUTTONDBLCLK: + case WM_RBUTTONDOWN: + { + LL_PROFILE_ZONE_NAMED("mwp - WM_RBUTTONDOWN"); + { + LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); + if (LLWinImm::isAvailable() && window_imp->mPreeditor) + { + WINDOW_IMP_POST(window_imp->interruptLanguageTextInput()); + } + + // Because we move the cursor position in the llviewerapp, we need to query + // to find out where the cursor at the time the event is handled. + // If we don't do this, many clicks could get buffered up, and if the + // first click changes the cursor position, all subsequent clicks + // will occur at the wrong location. JC + if (window_imp->mMousePositionModified) + { + LLCoordWindow cursor_coord_window; + window_imp->getCursorPosition(&cursor_coord_window); + gl_coord = cursor_coord_window.convert(); + } + else + { + gl_coord = window_coord.convert(); + } + MASK mask = gKeyboard->currentMask(TRUE); + // generate move event to update mouse coordinates + window_imp->post([=]() + { + window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask); + window_imp->mCallbacks->handleRightMouseDown(window_imp, gl_coord, mask); + }); + } + return 0; + } + break; - case WM_RBUTTONDBLCLK: - case WM_RBUTTONDOWN: - { - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_RBUTTONDOWN"); - LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); - if (LLWinImm::isAvailable() && window_imp->mPreeditor) - { - window_imp->interruptLanguageTextInput(); - } + case WM_RBUTTONUP: + { + LL_PROFILE_ZONE_NAMED("mwp - WM_RBUTTONUP"); + { + LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); + // Because we move the cursor position in the app, we need to query + // to find out where the cursor at the time the event is handled. + // If we don't do this, many clicks could get buffered up, and if the + // first click changes the cursor position, all subsequent clicks + // will occur at the wrong location. JC + if (window_imp->mMousePositionModified) + { + LLCoordWindow cursor_coord_window; + window_imp->getCursorPosition(&cursor_coord_window); + gl_coord = cursor_coord_window.convert(); + } + else + { + gl_coord = window_coord.convert(); + } + MASK mask = gKeyboard->currentMask(TRUE); + // generate move event to update mouse coordinates + window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask); + if (window_imp->mCallbacks->handleRightMouseUp(window_imp, gl_coord, mask)) + { + return 0; + } + } + } + break; - // Because we move the cursor position in the llviewerapp, we need to query - // to find out where the cursor at the time the event is handled. - // If we don't do this, many clicks could get buffered up, and if the - // first click changes the cursor position, all subsequent clicks - // will occur at the wrong location. JC - if (window_imp->mMousePositionModified) - { - LLCoordWindow cursor_coord_window; - window_imp->getCursorPosition(&cursor_coord_window); - gl_coord = cursor_coord_window.convert(); - } - else - { - gl_coord = window_coord.convert(); - } - MASK mask = gKeyboard->currentMask(TRUE); - // generate move event to update mouse coordinates - window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask); - if (window_imp->mCallbacks->handleRightMouseDown(window_imp, gl_coord, mask)) - { - return 0; - } - } - break; + case WM_MBUTTONDOWN: + // case WM_MBUTTONDBLCLK: + { + LL_PROFILE_ZONE_NAMED("mwp - WM_MBUTTONDOWN"); + { + LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); + if (LLWinImm::isAvailable() && window_imp->mPreeditor) + { + window_imp->interruptLanguageTextInput(); + } + + // Because we move the cursor position in tllviewerhe app, we need to query + // to find out where the cursor at the time the event is handled. + // If we don't do this, many clicks could get buffered up, and if the + // first click changes the cursor position, all subsequent clicks + // will occur at the wrong location. JC + if (window_imp->mMousePositionModified) + { + LLCoordWindow cursor_coord_window; + window_imp->getCursorPosition(&cursor_coord_window); + gl_coord = cursor_coord_window.convert(); + } + else + { + gl_coord = window_coord.convert(); + } + MASK mask = gKeyboard->currentMask(TRUE); + // generate move event to update mouse coordinates + window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask); + if (window_imp->mCallbacks->handleMiddleMouseDown(window_imp, gl_coord, mask)) + { + return 0; + } + } + } + break; - case WM_RBUTTONUP: - { - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_RBUTTONUP"); - LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); - // Because we move the cursor position in the app, we need to query - // to find out where the cursor at the time the event is handled. - // If we don't do this, many clicks could get buffered up, and if the - // first click changes the cursor position, all subsequent clicks - // will occur at the wrong location. JC - if (window_imp->mMousePositionModified) - { - LLCoordWindow cursor_coord_window; - window_imp->getCursorPosition(&cursor_coord_window); - gl_coord = cursor_coord_window.convert(); - } - else - { - gl_coord = window_coord.convert(); - } - MASK mask = gKeyboard->currentMask(TRUE); - // generate move event to update mouse coordinates - window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask); - if (window_imp->mCallbacks->handleRightMouseUp(window_imp, gl_coord, mask)) - { - return 0; - } - } - break; + case WM_MBUTTONUP: + { + LL_PROFILE_ZONE_NAMED("mwp - WM_MBUTTONUP"); + { + LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); + // Because we move the cursor position in the llviewer app, we need to query + // to find out where the cursor at the time the event is handled. + // If we don't do this, many clicks could get buffered up, and if the + // first click changes the cursor position, all subsequent clicks + // will occur at the wrong location. JC + if (window_imp->mMousePositionModified) + { + LLCoordWindow cursor_coord_window; + window_imp->getCursorPosition(&cursor_coord_window); + gl_coord = cursor_coord_window.convert(); + } + else + { + gl_coord = window_coord.convert(); + } + MASK mask = gKeyboard->currentMask(TRUE); + // generate move event to update mouse coordinates + window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask); + if (window_imp->mCallbacks->handleMiddleMouseUp(window_imp, gl_coord, mask)) + { + return 0; + } + } + } + break; + case WM_XBUTTONDOWN: + { + LL_PROFILE_ZONE_NAMED("mwp - WM_XBUTTONDOWN"); + { + LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); + S32 button = GET_XBUTTON_WPARAM(w_param); + if (LLWinImm::isAvailable() && window_imp->mPreeditor) + { + window_imp->interruptLanguageTextInput(); + } + + // Because we move the cursor position in tllviewerhe app, we need to query + // to find out where the cursor at the time the event is handled. + // If we don't do this, many clicks could get buffered up, and if the + // first click changes the cursor position, all subsequent clicks + // will occur at the wrong location. JC + if (window_imp->mMousePositionModified) + { + LLCoordWindow cursor_coord_window; + window_imp->getCursorPosition(&cursor_coord_window); + gl_coord = cursor_coord_window.convert(); + } + else + { + gl_coord = window_coord.convert(); + } + MASK mask = gKeyboard->currentMask(TRUE); + // generate move event to update mouse coordinates + window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask); + // Windows uses numbers 1 and 2 for buttons, remap to 4, 5 + if (window_imp->mCallbacks->handleOtherMouseDown(window_imp, gl_coord, mask, button + 3)) + { + return 0; + } + } + } + break; - case WM_MBUTTONDOWN: -// case WM_MBUTTONDBLCLK: - { - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_MBUTTONDOWN"); - LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); - if (LLWinImm::isAvailable() && window_imp->mPreeditor) - { - window_imp->interruptLanguageTextInput(); - } + case WM_XBUTTONUP: + { + LL_PROFILE_ZONE_NAMED("mwp - WM_XBUTTONUP"); + { + LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); + S32 button = GET_XBUTTON_WPARAM(w_param); + // Because we move the cursor position in the llviewer app, we need to query + // to find out where the cursor at the time the event is handled. + // If we don't do this, many clicks could get buffered up, and if the + // first click changes the cursor position, all subsequent clicks + // will occur at the wrong location. JC + if (window_imp->mMousePositionModified) + { + LLCoordWindow cursor_coord_window; + window_imp->getCursorPosition(&cursor_coord_window); + gl_coord = cursor_coord_window.convert(); + } + else + { + gl_coord = window_coord.convert(); + } + MASK mask = gKeyboard->currentMask(TRUE); + // generate move event to update mouse coordinates + window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask); + // Windows uses numbers 1 and 2 for buttons, remap to 4, 5 + if (window_imp->mCallbacks->handleOtherMouseUp(window_imp, gl_coord, mask, button + 3)) + { + return 0; + } + } + } + break; - // Because we move the cursor position in tllviewerhe app, we need to query - // to find out where the cursor at the time the event is handled. - // If we don't do this, many clicks could get buffered up, and if the - // first click changes the cursor position, all subsequent clicks - // will occur at the wrong location. JC - if (window_imp->mMousePositionModified) - { - LLCoordWindow cursor_coord_window; - window_imp->getCursorPosition(&cursor_coord_window); - gl_coord = cursor_coord_window.convert(); - } - else - { - gl_coord = window_coord.convert(); - } - MASK mask = gKeyboard->currentMask(TRUE); - // generate move event to update mouse coordinates - window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask); - if (window_imp->mCallbacks->handleMiddleMouseDown(window_imp, gl_coord, mask)) - { - return 0; - } - } - break; + case WM_MOUSEWHEEL: + { + LL_PROFILE_ZONE_NAMED("mwp - WM_MOUSEWHEEL"); + static short z_delta = 0; - case WM_MBUTTONUP: - { - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_MBUTTONUP"); - LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); - // Because we move the cursor position in the llviewer app, we need to query - // to find out where the cursor at the time the event is handled. - // If we don't do this, many clicks could get buffered up, and if the - // first click changes the cursor position, all subsequent clicks - // will occur at the wrong location. JC - if (window_imp->mMousePositionModified) - { - LLCoordWindow cursor_coord_window; - window_imp->getCursorPosition(&cursor_coord_window); - gl_coord = cursor_coord_window.convert(); - } - else - { - gl_coord = window_coord.convert(); - } - MASK mask = gKeyboard->currentMask(TRUE); - // generate move event to update mouse coordinates - window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask); - if (window_imp->mCallbacks->handleMiddleMouseUp(window_imp, gl_coord, mask)) - { - return 0; - } - } - break; - case WM_XBUTTONDOWN: - { - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_MBUTTONDOWN"); - LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); - S32 button = GET_XBUTTON_WPARAM(w_param); - if (LLWinImm::isAvailable() && window_imp->mPreeditor) - { - window_imp->interruptLanguageTextInput(); - } + RECT client_rect; - // Because we move the cursor position in tllviewerhe app, we need to query - // to find out where the cursor at the time the event is handled. - // If we don't do this, many clicks could get buffered up, and if the - // first click changes the cursor position, all subsequent clicks - // will occur at the wrong location. JC - if (window_imp->mMousePositionModified) - { - LLCoordWindow cursor_coord_window; - window_imp->getCursorPosition(&cursor_coord_window); - gl_coord = cursor_coord_window.convert(); - } - else - { - gl_coord = window_coord.convert(); - } - MASK mask = gKeyboard->currentMask(TRUE); - // generate move event to update mouse coordinates - window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask); - // Windows uses numbers 1 and 2 for buttons, remap to 4, 5 - if (window_imp->mCallbacks->handleOtherMouseDown(window_imp, gl_coord, mask, button + 3)) - { - return 0; - } - } - break; + // eat scroll events that occur outside our window, since we use mouse position to direct scroll + // instead of keyboard focus + // NOTE: mouse_coord is in *window* coordinates for scroll events + POINT mouse_coord = { (S32)(S16)LOWORD(l_param), (S32)(S16)HIWORD(l_param) }; - case WM_XBUTTONUP: - { - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_MBUTTONUP"); - LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); - S32 button = GET_XBUTTON_WPARAM(w_param); - // Because we move the cursor position in the llviewer app, we need to query - // to find out where the cursor at the time the event is handled. - // If we don't do this, many clicks could get buffered up, and if the - // first click changes the cursor position, all subsequent clicks - // will occur at the wrong location. JC - if (window_imp->mMousePositionModified) - { - LLCoordWindow cursor_coord_window; - window_imp->getCursorPosition(&cursor_coord_window); - gl_coord = cursor_coord_window.convert(); - } - else - { - gl_coord = window_coord.convert(); - } - MASK mask = gKeyboard->currentMask(TRUE); - // generate move event to update mouse coordinates - window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask); - // Windows uses numbers 1 and 2 for buttons, remap to 4, 5 - if (window_imp->mCallbacks->handleOtherMouseUp(window_imp, gl_coord, mask, button + 3)) - { - return 0; - } - } - break; + if (ScreenToClient(window_imp->mWindowHandle, &mouse_coord) + && GetClientRect(window_imp->mWindowHandle, &client_rect)) + { + // we have a valid mouse point and client rect + if (mouse_coord.x < client_rect.left || client_rect.right < mouse_coord.x + || mouse_coord.y < client_rect.top || client_rect.bottom < mouse_coord.y) + { + // mouse is outside of client rect, so don't do anything + return 0; + } + } - case WM_MOUSEWHEEL: - { - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_MOUSEWHEEL"); - static short z_delta = 0; + S16 incoming_z_delta = HIWORD(w_param); + z_delta += incoming_z_delta; + // cout << "z_delta " << z_delta << endl; + + // current mouse wheels report changes in increments of zDelta (+120, -120) + // Future, higher resolution mouse wheels may report smaller deltas. + // So we sum the deltas and only act when we've exceeded WHEEL_DELTA + // + // If the user rapidly spins the wheel, we can get messages with + // large deltas, like 480 or so. Thus we need to scroll more quickly. + if (z_delta <= -WHEEL_DELTA || WHEEL_DELTA <= z_delta) + { + window_imp->mCallbacks->handleScrollWheel(window_imp, -z_delta / WHEEL_DELTA); + z_delta = 0; + } + return 0; + } + /* + // TODO: add this after resolving _WIN32_WINNT issue + case WM_MOUSELEAVE: + { + window_imp->mCallbacks->handleMouseLeave(window_imp); + + // TRACKMOUSEEVENT track_mouse_event; + // track_mouse_event.cbSize = sizeof( TRACKMOUSEEVENT ); + // track_mouse_event.dwFlags = TME_LEAVE; + // track_mouse_event.hwndTrack = h_wnd; + // track_mouse_event.dwHoverTime = HOVER_DEFAULT; + // TrackMouseEvent( &track_mouse_event ); + return 0; + } + */ + case WM_MOUSEHWHEEL: + { + LL_PROFILE_ZONE_NAMED("mwp - WM_MOUSEHWHEEL"); + static short h_delta = 0; - RECT client_rect; + RECT client_rect; - // eat scroll events that occur outside our window, since we use mouse position to direct scroll - // instead of keyboard focus - // NOTE: mouse_coord is in *window* coordinates for scroll events - POINT mouse_coord = {(S32)(S16)LOWORD(l_param), (S32)(S16)HIWORD(l_param)}; + // eat scroll events that occur outside our window, since we use mouse position to direct scroll + // instead of keyboard focus + // NOTE: mouse_coord is in *window* coordinates for scroll events + POINT mouse_coord = { (S32)(S16)LOWORD(l_param), (S32)(S16)HIWORD(l_param) }; - if (ScreenToClient(window_imp->mWindowHandle, &mouse_coord) - && GetClientRect(window_imp->mWindowHandle, &client_rect)) - { - // we have a valid mouse point and client rect - if (mouse_coord.x < client_rect.left || client_rect.right < mouse_coord.x - || mouse_coord.y < client_rect.top || client_rect.bottom < mouse_coord.y) - { - // mouse is outside of client rect, so don't do anything - return 0; - } - } + if (ScreenToClient(window_imp->mWindowHandle, &mouse_coord) + && GetClientRect(window_imp->mWindowHandle, &client_rect)) + { + // we have a valid mouse point and client rect + if (mouse_coord.x < client_rect.left || client_rect.right < mouse_coord.x + || mouse_coord.y < client_rect.top || client_rect.bottom < mouse_coord.y) + { + // mouse is outside of client rect, so don't do anything + return 0; + } + } - S16 incoming_z_delta = HIWORD(w_param); - z_delta += incoming_z_delta; - // cout << "z_delta " << z_delta << endl; - - // current mouse wheels report changes in increments of zDelta (+120, -120) - // Future, higher resolution mouse wheels may report smaller deltas. - // So we sum the deltas and only act when we've exceeded WHEEL_DELTA - // - // If the user rapidly spins the wheel, we can get messages with - // large deltas, like 480 or so. Thus we need to scroll more quickly. - if (z_delta <= -WHEEL_DELTA || WHEEL_DELTA <= z_delta) - { - window_imp->mCallbacks->handleScrollWheel(window_imp, -z_delta / WHEEL_DELTA); - z_delta = 0; - } - return 0; - } - /* - // TODO: add this after resolving _WIN32_WINNT issue - case WM_MOUSELEAVE: - { - window_imp->mCallbacks->handleMouseLeave(window_imp); - - // TRACKMOUSEEVENT track_mouse_event; - // track_mouse_event.cbSize = sizeof( TRACKMOUSEEVENT ); - // track_mouse_event.dwFlags = TME_LEAVE; - // track_mouse_event.hwndTrack = h_wnd; - // track_mouse_event.dwHoverTime = HOVER_DEFAULT; - // TrackMouseEvent( &track_mouse_event ); - return 0; - } - */ - case WM_MOUSEHWHEEL: - { - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_MOUSEHWHEEL"); - static short h_delta = 0; + S16 incoming_h_delta = HIWORD(w_param); + h_delta += incoming_h_delta; - RECT client_rect; + // If the user rapidly spins the wheel, we can get messages with + // large deltas, like 480 or so. Thus we need to scroll more quickly. + if (h_delta <= -WHEEL_DELTA || WHEEL_DELTA <= h_delta) + { + WINDOW_IMP_POST(window_imp->mCallbacks->handleScrollHWheel(window_imp, h_delta / WHEEL_DELTA)); + h_delta = 0; + } + return 0; + } + // Handle mouse movement within the window + case WM_MOUSEMOVE: + { + LL_PROFILE_ZONE_NAMED("mwp - WM_MOUSEMOVE"); + if (!window_imp->mMousePositionModified) + { + MASK mask = gKeyboard->currentMask(TRUE); + WINDOW_IMP_POST(window_imp->mCallbacks->handleMouseMove(window_imp, window_coord.convert(), mask)); + } + return 0; + } - // eat scroll events that occur outside our window, since we use mouse position to direct scroll - // instead of keyboard focus - // NOTE: mouse_coord is in *window* coordinates for scroll events - POINT mouse_coord = {(S32)(S16)LOWORD(l_param), (S32)(S16)HIWORD(l_param)}; + case WM_GETMINMAXINFO: + { + LL_PROFILE_ZONE_NAMED("mwp - WM_GETMINMAXINFO"); + LPMINMAXINFO min_max = (LPMINMAXINFO)l_param; + min_max->ptMinTrackSize.x = window_imp->mMinWindowWidth; + min_max->ptMinTrackSize.y = window_imp->mMinWindowHeight; + return 0; + } - if (ScreenToClient(window_imp->mWindowHandle, &mouse_coord) - && GetClientRect(window_imp->mWindowHandle, &client_rect)) - { - // we have a valid mouse point and client rect - if (mouse_coord.x < client_rect.left || client_rect.right < mouse_coord.x - || mouse_coord.y < client_rect.top || client_rect.bottom < mouse_coord.y) - { - // mouse is outside of client rect, so don't do anything - return 0; - } - } + case WM_SIZE: + { + LL_PROFILE_ZONE_NAMED("mwp - WM_SIZE"); + S32 width = S32(LOWORD(l_param)); + S32 height = S32(HIWORD(l_param)); - S16 incoming_h_delta = HIWORD(w_param); - h_delta += incoming_h_delta; + if (debug_window_proc) + { + BOOL maximized = (w_param == SIZE_MAXIMIZED); + BOOL restored = (w_param == SIZE_RESTORED); + BOOL minimized = (w_param == SIZE_MINIMIZED); + + LL_INFOS("Window") << "WINDOWPROC Size " + << width << "x" << height + << " max " << S32(maximized) + << " min " << S32(minimized) + << " rest " << S32(restored) + << LL_ENDL; + } - // If the user rapidly spins the wheel, we can get messages with - // large deltas, like 480 or so. Thus we need to scroll more quickly. - if (h_delta <= -WHEEL_DELTA || WHEEL_DELTA <= h_delta) - { - window_imp->mCallbacks->handleScrollHWheel(window_imp, h_delta / WHEEL_DELTA); - h_delta = 0; - } - return 0; - } - // Handle mouse movement within the window - case WM_MOUSEMOVE: - { - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_MOUSEMOVE"); - MASK mask = gKeyboard->currentMask(TRUE); - window_imp->mCallbacks->handleMouseMove(window_imp, window_coord.convert(), mask); - return 0; - } + // There's an odd behavior with WM_SIZE that I would call a bug. If + // the window is maximized, and you call MoveWindow() with a size smaller + // than a maximized window, it ends up sending WM_SIZE with w_param set + // to SIZE_MAXIMIZED -- which isn't true. So the logic below doesn't work. + // (SL-44655). Fixed it by calling ShowWindow(SW_RESTORE) first (see + // LLWindowWin32::moveWindow in this file). - case WM_GETMINMAXINFO: - { - LPMINMAXINFO min_max = (LPMINMAXINFO)l_param; - min_max->ptMinTrackSize.x = window_imp->mMinWindowWidth; - min_max->ptMinTrackSize.y = window_imp->mMinWindowHeight; - return 0; - } + // If we are now restored, but we weren't before, this + // means that the window was un-minimized. + if (w_param == SIZE_RESTORED && window_imp->mLastSizeWParam != SIZE_RESTORED) + { + WINDOW_IMP_POST(window_imp->mCallbacks->handleActivate(window_imp, TRUE)); + } - case WM_SIZE: - { - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_SIZE"); - S32 width = S32( LOWORD(l_param) ); - S32 height = S32( HIWORD(l_param) ); + // handle case of window being maximized from fully minimized state + if (w_param == SIZE_MAXIMIZED && window_imp->mLastSizeWParam != SIZE_MAXIMIZED) + { + WINDOW_IMP_POST(window_imp->mCallbacks->handleActivate(window_imp, TRUE)); + } - if (debug_window_proc) - { - BOOL maximized = ( w_param == SIZE_MAXIMIZED ); - BOOL restored = ( w_param == SIZE_RESTORED ); - BOOL minimized = ( w_param == SIZE_MINIMIZED ); - - LL_INFOS("Window") << "WINDOWPROC Size " - << width << "x" << height - << " max " << S32(maximized) - << " min " << S32(minimized) - << " rest " << S32(restored) - << LL_ENDL; - } + // Also handle the minimization case + if (w_param == SIZE_MINIMIZED && window_imp->mLastSizeWParam != SIZE_MINIMIZED) + { + WINDOW_IMP_POST(window_imp->mCallbacks->handleActivate(window_imp, FALSE)); + } - // There's an odd behavior with WM_SIZE that I would call a bug. If - // the window is maximized, and you call MoveWindow() with a size smaller - // than a maximized window, it ends up sending WM_SIZE with w_param set - // to SIZE_MAXIMIZED -- which isn't true. So the logic below doesn't work. - // (SL-44655). Fixed it by calling ShowWindow(SW_RESTORE) first (see - // LLWindowWin32::moveWindow in this file). + // Actually resize all of our views + if (w_param != SIZE_MINIMIZED) + { + // Ignore updates for minimizing and minimized "windows" + WINDOW_IMP_POST(window_imp->mCallbacks->handleResize(window_imp, + LOWORD(l_param), + HIWORD(l_param))); + } - // If we are now restored, but we weren't before, this - // means that the window was un-minimized. - if (w_param == SIZE_RESTORED && window_imp->mLastSizeWParam != SIZE_RESTORED) - { - window_imp->mCallbacks->handleActivate(window_imp, TRUE); - } + window_imp->mLastSizeWParam = w_param; - // handle case of window being maximized from fully minimized state - if (w_param == SIZE_MAXIMIZED && window_imp->mLastSizeWParam != SIZE_MAXIMIZED) - { - window_imp->mCallbacks->handleActivate(window_imp, TRUE); - } + return 0; + } - // Also handle the minimization case - if (w_param == SIZE_MINIMIZED && window_imp->mLastSizeWParam != SIZE_MINIMIZED) - { - window_imp->mCallbacks->handleActivate(window_imp, FALSE); - } + case WM_DPICHANGED: + { + LL_PROFILE_ZONE_NAMED("mwp - WM_DPICHANGED"); + LPRECT lprc_new_scale; + F32 new_scale = F32(LOWORD(w_param)) / F32(USER_DEFAULT_SCREEN_DPI); + lprc_new_scale = (LPRECT)l_param; + S32 new_width = lprc_new_scale->right - lprc_new_scale->left; + S32 new_height = lprc_new_scale->bottom - lprc_new_scale->top; + WINDOW_IMP_POST(window_imp->mCallbacks->handleDPIChanged(window_imp, new_scale, new_width, new_height)); + + SetWindowPos(h_wnd, + HWND_TOP, + lprc_new_scale->left, + lprc_new_scale->top, + new_width, + new_height, + SWP_NOZORDER | SWP_NOACTIVATE); + + return 0; + } - // Actually resize all of our views - if (w_param != SIZE_MINIMIZED) - { - // Ignore updates for minimizing and minimized "windows" - window_imp->mCallbacks->handleResize( window_imp, - LOWORD(l_param), - HIWORD(l_param) ); - } + case WM_SETFOCUS: + { + LL_PROFILE_ZONE_NAMED("mwp - WM_SETFOCUS"); + if (debug_window_proc) + { + LL_INFOS("Window") << "WINDOWPROC SetFocus" << LL_ENDL; + } + WINDOW_IMP_POST(window_imp->mCallbacks->handleFocus(window_imp)); + return 0; + } - window_imp->mLastSizeWParam = w_param; + case WM_KILLFOCUS: + { + LL_PROFILE_ZONE_NAMED("mwp - WM_KILLFOCUS"); + if (debug_window_proc) + { + LL_INFOS("Window") << "WINDOWPROC KillFocus" << LL_ENDL; + } + WINDOW_IMP_POST(window_imp->mCallbacks->handleFocusLost(window_imp)); + return 0; + } - return 0; - } + case WM_COPYDATA: + { + LL_PROFILE_ZONE_NAMED("mwp - WM_COPYDATA"); + { + // received a URL + PCOPYDATASTRUCT myCDS = (PCOPYDATASTRUCT)l_param; + void* data = new U8[myCDS->cbData]; + memcpy(data, myCDS->lpData, myCDS->cbData); + auto myType = myCDS->dwData; + + window_imp->post([=]() + { + window_imp->mCallbacks->handleDataCopy(window_imp, myType, data); + delete[] data; + }); + }; + return 0; + + break; + } + case WM_SETTINGCHANGE: + { + LL_PROFILE_ZONE_NAMED("mwp - WM_SETTINGCHANGE"); + if (w_param == SPI_SETMOUSEVANISH) + { + if (!SystemParametersInfo(SPI_GETMOUSEVANISH, 0, &window_imp->mMouseVanish, 0)) + { + WINDOW_IMP_POST(window_imp->mMouseVanish = TRUE); + } + } + } + break; - case WM_DPICHANGED: - { - LPRECT lprc_new_scale; - F32 new_scale = F32(LOWORD(w_param)) / F32(USER_DEFAULT_SCREEN_DPI); - lprc_new_scale = (LPRECT)l_param; - S32 new_width = lprc_new_scale->right - lprc_new_scale->left; - S32 new_height = lprc_new_scale->bottom - lprc_new_scale->top; - if (window_imp->mCallbacks->handleDPIChanged(window_imp, new_scale, new_width, new_height)) - { - SetWindowPos(h_wnd, - HWND_TOP, - lprc_new_scale->left, - lprc_new_scale->top, - new_width, - new_height, - SWP_NOZORDER | SWP_NOACTIVATE); - } - return 0; - } - - case WM_SETFOCUS: - if (debug_window_proc) - { - LL_INFOS("Window") << "WINDOWPROC SetFocus" << LL_ENDL; - } - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_SETFOCUS"); - window_imp->mCallbacks->handleFocus(window_imp); - return 0; - - case WM_KILLFOCUS: - if (debug_window_proc) - { - LL_INFOS("Window") << "WINDOWPROC KillFocus" << LL_ENDL; - } - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_KILLFOCUS"); - window_imp->mCallbacks->handleFocusLost(window_imp); - return 0; - - case WM_COPYDATA: - { - window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_COPYDATA"); - // received a URL - PCOPYDATASTRUCT myCDS = (PCOPYDATASTRUCT) l_param; - window_imp->mCallbacks->handleDataCopy(window_imp, myCDS->dwData, myCDS->lpData); - }; - return 0; - - break; - - case WM_SETTINGCHANGE: - { - if (w_param == SPI_SETMOUSEVANISH) - { - if (!SystemParametersInfo(SPI_GETMOUSEVANISH, 0, &window_imp->mMouseVanish, 0)) - { - window_imp->mMouseVanish = TRUE; - } - } - } - break; - default: - { - if (debug_window_proc) - { - LL_INFOS("Window") << "Unhandled windows message code: " << U32(u_msg) << LL_ENDL; - } - } - break; - } - - window_imp->mCallbacks->handlePauseWatchdog(window_imp); - } + //list of messages we get often that we don't care to log about + case WM_NCHITTEST: + case WM_NCMOUSEMOVE: + case WM_NCMOUSELEAVE: + case WM_MOVING: + case WM_MOVE: + case WM_WINDOWPOSCHANGING: + case WM_WINDOWPOSCHANGED: + break; + + default: + { + LL_PROFILE_ZONE_NAMED("mwp - default"); + if (debug_window_proc) + { + LL_INFOS("Window") << "Unhandled windows message code: 0x" << std::hex << U32(u_msg) << LL_ENDL; + } + } + break; + } + } else { // (NULL == window_imp) LL_DEBUGS("Window") << "No window implementation to handle message with, message code: " << U32(u_msg) << LL_ENDL; } - // pass unhandled messages down to Windows - return DefWindowProc(h_wnd, u_msg, w_param, l_param); + // pass unhandled messages down to Windows + LRESULT ret; + { + LL_PROFILE_ZONE_NAMED("mwp - DefWindowProc"); + ret = DefWindowProc(h_wnd, u_msg, w_param, l_param); + } + return ret; } BOOL LLWindowWin32::convertCoords(LLCoordGL from, LLCoordWindow *to) @@ -3187,6 +3425,8 @@ BOOL LLWindowWin32::copyTextToClipboard(const LLWString& wstr) // Constrains the mouse to the window. void LLWindowWin32::setMouseClipping( BOOL b ) { + LL_PROFILE_ZONE_SCOPED; + ASSERT_MAIN_THREAD(); if( b != mIsMouseClipping ) { BOOL success = FALSE; @@ -3263,6 +3503,7 @@ F32 LLWindowWin32::getGamma() BOOL LLWindowWin32::restoreGamma() { + ASSERT_MAIN_THREAD(); if (mCustomGammaSet != FALSE) { LL_DEBUGS("Window") << "Restoring gamma" << LL_ENDL; @@ -3274,6 +3515,7 @@ BOOL LLWindowWin32::restoreGamma() BOOL LLWindowWin32::setGamma(const F32 gamma) { + ASSERT_MAIN_THREAD(); mCurrentGamma = gamma; //Get the previous gamma ramp to restore later. @@ -3312,6 +3554,7 @@ BOOL LLWindowWin32::setGamma(const F32 gamma) void LLWindowWin32::setFSAASamples(const U32 fsaa_samples) { + ASSERT_MAIN_THREAD(); mFSAASamples = fsaa_samples; } @@ -3322,6 +3565,7 @@ U32 LLWindowWin32::getFSAASamples() LLWindow::LLWindowResolution* LLWindowWin32::getSupportedResolutions(S32 &num_resolutions) { + ASSERT_MAIN_THREAD(); if (!mSupportedResolutions) { mSupportedResolutions = new LLWindowResolution[MAX_NUM_RESOLUTIONS]; @@ -3476,6 +3720,7 @@ BOOL LLWindowWin32::resetDisplayResolution() void LLWindowWin32::swapBuffers() { + ASSERT_MAIN_THREAD(); SwapBuffers(mhDC); LL_PROFILER_GPU_COLLECT @@ -3951,6 +4196,7 @@ void LLWindowWin32::updateLanguageTextInputArea() void LLWindowWin32::interruptLanguageTextInput() { + ASSERT_MAIN_THREAD(); if (mPreeditor && LLWinImm::isAvailable()) { HIMC himc = LLWinImm::getContext(mWindowHandle); @@ -4153,6 +4399,7 @@ static LLWString find_context(const LLWString & wtext, S32 focus, S32 focus_leng // for files and via IDropTarget interface requests. LLWindowCallbacks::DragNDropResult LLWindowWin32::completeDragNDropRequest( const LLCoordGL gl_coord, const MASK mask, LLWindowCallbacks::DragNDropAction action, const std::string url ) { + ASSERT_MAIN_THREAD(); return mCallbacks->handleDragNDrop( this, gl_coord, mask, action, url ); } @@ -4201,6 +4448,7 @@ BOOL LLWindowWin32::handleImeRequests(WPARAM request, LPARAM param, LRESULT *res LL_WARNS("Window") << "*** IMR_QUERYCHARPOSITON called but getPreeditLocation failed." << LL_ENDL; return FALSE; } + fillCharPosition(caret_coord, preedit_bounds, text_control, char_position); *result = 1; @@ -4408,3 +4656,79 @@ std::vector LLWindowWin32::getDynamicFallbackFontList() #endif // LL_WINDOWS + +inline LLWindowWin32Thread::LLWindowWin32Thread(LLWindowWin32* window) + : LLThread("Window Thread"), + mWindow(window), + mFunctionQueue(MAX_QUEUE_SIZE) +{ + +} + +inline void LLWindowWin32Thread::run() +{ + sWindowThreadId = getID(); + while (!mFinished) + { + LL_PROFILE_ZONE_SCOPED; + + + if (mWindow && mWindow->mWindowHandle != 0) + { + MSG msg; + BOOL status; + if (mWindow->mhDC == 0) + { + LL_PROFILE_ZONE_NAMED("w32t - PeekMessage"); + status = PeekMessage(&msg, mWindow->mWindowHandle, 0, 0, PM_REMOVE); + } + else + { + LL_PROFILE_ZONE_NAMED("w32t - GetMessage"); + status = GetMessage(&msg, mWindow->mWindowHandle, 0, 0); + } + if (status > 0) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + + mMessageQueue.pushFront(msg); + } + } + + { + LL_PROFILE_ZONE_NAMED("w32t - Function Queue"); + //process any pending functions + std::function curFunc; + while (mFunctionQueue.tryPopBack(curFunc)) + { + curFunc(); + } + } + +#if 0 + { + LL_PROFILE_ZONE_NAMED("w32t - Sleep"); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } +#endif + } +} + +void LLWindowWin32Thread::post(const std::function& func) +{ +#if LL_WINDOW_SINGLE_THREADED + func(); +#else + mFunctionQueue.pushFront(func); +#endif +} + +void LLWindowWin32::post(const std::function& func) +{ +#if LL_WINDOW_SINGLE_THREADED + func(); +#else + mFunctionQueue.pushFront(func); +#endif +} \ No newline at end of file diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h index 0b3d14fb16..66647459b2 100644 --- a/indra/llwindow/llwindowwin32.h +++ b/indra/llwindow/llwindowwin32.h @@ -33,11 +33,46 @@ #include "llwindow.h" #include "llwindowcallbacks.h" #include "lldragdropwin32.h" +#include "llthread.h" +#include "llthreadsafequeue.h" // Hack for async host by name #define LL_WM_HOST_RESOLVED (WM_APP + 1) typedef void (*LLW32MsgCallback)(const MSG &msg); +class LLWindowWin32; + +// Thread that owns the Window Handle +class LLWindowWin32Thread : public LLThread +{ +public: + class Message + { + public: + LRESULT mMsg; + }; + + static const int MAX_QUEUE_SIZE = 2048; + + LLThreadSafeQueue mMessageQueue; + LLThreadSafeQueue> mFunctionQueue; + + bool mFinished = false; + + LLWindowWin32Thread(LLWindowWin32* window); + + void run() override; + + void post(const std::function& func); + +private: + + // call PeekMessage and pull enqueue messages for later processing + void gatherInput(); + LLWindowWin32* mWindow = nullptr; + +}; + class LLWindowWin32 : public LLWindow { public: @@ -172,9 +207,9 @@ protected: WCHAR *mWindowTitle; WCHAR *mWindowClassName; - HWND mWindowHandle; // window handle - HGLRC mhRC; // OpenGL rendering context - HDC mhDC; // Windows Device context handle + HWND mWindowHandle = 0; // window handle + HGLRC mhRC = 0; // OpenGL rendering context + HDC mhDC = 0; // Windows Device context handle HINSTANCE mhInstance; // handle to application instance WNDPROC mWndProc; // user-installable window proc RECT mOldMouseClip; // Screen rect to which the mouse cursor was globally constrained before we changed it in clipMouse() @@ -221,7 +256,12 @@ protected: BOOL mMouseVanish; + LLWindowWin32Thread* mWindowThread = nullptr; + LLThreadSafeQueue> mFunctionQueue; + void post(const std::function& func); + friend class LLWindowManager; + friend class LLWindowWin32Thread; }; class LLSplashScreenWin32 : public LLSplashScreen -- cgit v1.2.3 From 7c9aeed97d4ba3641971b9a1a92d334ec0adbb09 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Fri, 1 Oct 2021 16:05:23 -0400 Subject: SL-16024: Enhance LLThreadSafeQueue for use with WorkQueue. First, parameterize LLThreadSafeQueue's queue type. This allows us to substitute (e.g.) a std::priority_queue for a particular instance. Use std::queue for the default queue type, changing the operations invoked on the queue type from std::deque methods to std::queue methods. Rename published methods from (e.g.) pushFront() and popBack() to simple push() and pop(), retaining legacy names as aliases. Not only are the overt Front and Back unnecessary; they're the opposite of how std::queue uses std::deque or std::list, so they only confuse the reader. Break out tryPushUntil() method. We already use that logic internally to tryPushFor(), so it's just as easy to publish it as its own entry point. Add tryPopFor() and tryPopUntil() to allow limiting the time we'll wait for a queue item to become available. --- indra/llcommon/llthreadsafequeue.h | 229 ++++++++++++++++++++++++++----------- 1 file changed, 163 insertions(+), 66 deletions(-) diff --git a/indra/llcommon/llthreadsafequeue.h b/indra/llcommon/llthreadsafequeue.h index 26e0d71d31..04f51816d7 100644 --- a/indra/llcommon/llthreadsafequeue.h +++ b/indra/llcommon/llthreadsafequeue.h @@ -1,6 +1,6 @@ /** * @file llthreadsafequeue.h - * @brief Base classes for thread, mutex and condition handling. + * @brief Queue protected with mutexes for cross-thread use * * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code @@ -27,15 +27,15 @@ #ifndef LL_LLTHREADSAFEQUEUE_H #define LL_LLTHREADSAFEQUEUE_H -#include "llexception.h" -#include -#include -#include -#include "mutex.h" #include "llcoros.h" #include LLCOROS_MUTEX_HEADER #include #include LLCOROS_CONDVAR_HEADER +#include "llexception.h" +#include "mutex.h" +#include +#include +#include // // A general queue exception. @@ -66,61 +66,95 @@ public: } }; -// -// Implements a thread safe FIFO. -// -template +/** + * Implements a thread safe FIFO. + */ +// Let the default std::queue default to underlying std::deque. Override if +// desired. +template> class LLThreadSafeQueue { public: typedef ElementT value_type; - + // If the pool is set to NULL one will be allocated and managed by this // queue. LLThreadSafeQueue(U32 capacity = 1024); - - // Add an element to the front of queue (will block if the queue has + + // Add an element to the queue (will block if the queue has // reached capacity). // // This call will raise an interrupt error if the queue is closed while // the caller is blocked. - void pushFront(ElementT const & element); - - // Try to add an element to the front of queue without blocking. Returns + void push(ElementT const& element); + // legacy name + void pushFront(ElementT const & element) { return push(element); } + + // Try to add an element to the queue without blocking. Returns // true only if the element was actually added. - bool tryPushFront(ElementT const & element); + bool tryPush(ElementT const& element); + // legacy name + bool tryPushFront(ElementT const & element) { return tryPush(element); } - // Try to add an element to the front of queue, blocking if full but with - // timeout. Returns true if the element was added. + // Try to add an element to the queue, blocking if full but with timeout + // after specified duration. Returns true if the element was added. // There are potentially two different timeouts involved: how long to try // to lock the mutex, versus how long to wait for the queue to stop being // full. Careful settings for each timeout might be orders of magnitude // apart. However, this method conflates them. template + bool tryPushFor(const std::chrono::duration& timeout, + ElementT const & element); + // legacy name + template bool tryPushFrontFor(const std::chrono::duration& timeout, - ElementT const & element); + ElementT const & element) { return tryPushFor(timeout, element); } + + // Try to add an element to the queue, blocking if full but with + // timeout at specified time_point. Returns true if the element was added. + template + bool tryPushUntil(const std::chrono::time_point& timeout, + ElementT const& element); + // no legacy name because this is a newer method - // Pop the element at the end of the queue (will block if the queue is + // Pop the element at the head of the queue (will block if the queue is // empty). // // This call will raise an interrupt error if the queue is closed while // the caller is blocked. - ElementT popBack(void); - - // Pop an element from the end of the queue if there is one available. + ElementT pop(void); + // legacy name + ElementT popBack(void) { return pop(); } + + // Pop an element from the head of the queue if there is one available. // Returns true only if an element was popped. - bool tryPopBack(ElementT & element); - + bool tryPop(ElementT & element); + // legacy name + bool tryPopBack(ElementT & element) { return tryPop(element); } + + // Pop the element at the head of the queue, blocking if empty, with + // timeout after specified duration. Returns true if an element was popped. + template + bool tryPopFor(const std::chrono::duration& timeout, ElementT& element); + // no legacy name because this is a newer method + + // Pop the element at the head of the queue, blocking if empty, with + // timeout at specified time_point. Returns true if an element was popped. + template + bool tryPopUntil(const std::chrono::time_point& timeout, + ElementT& element); + // no legacy name because this is a newer method + // Returns the size of the queue. size_t size(); // closes the queue: - // - every subsequent pushFront() call will throw LLThreadSafeQueueInterrupt - // - every subsequent tryPushFront() call will return false - // - popBack() calls will return normally until the queue is drained, then - // every subsequent popBack() will throw LLThreadSafeQueueInterrupt - // - tryPopBack() calls will return normally until the queue is drained, - // then every subsequent tryPopBack() call will return false + // - every subsequent push() call will throw LLThreadSafeQueueInterrupt + // - every subsequent tryPush() call will return false + // - pop() calls will return normally until the queue is drained, then + // every subsequent pop() will throw LLThreadSafeQueueInterrupt + // - tryPop() calls will return normally until the queue is drained, + // then every subsequent tryPop() call will return false void close(); // detect closed state @@ -128,8 +162,9 @@ public: // inverse of isClosed() explicit operator bool(); -private: - std::deque< ElementT > mStorage; +protected: + typedef QueueT queue_type; + QueueT mStorage; U32 mCapacity; bool mClosed; @@ -142,16 +177,16 @@ private: // LLThreadSafeQueue //----------------------------------------------------------------------------- -template -LLThreadSafeQueue::LLThreadSafeQueue(U32 capacity) : +template +LLThreadSafeQueue::LLThreadSafeQueue(U32 capacity) : mCapacity(capacity), mClosed(false) { } -template -void LLThreadSafeQueue::pushFront(ElementT const & element) +template +void LLThreadSafeQueue::push(ElementT const & element) { lock_t lock1(mLock); while (true) @@ -163,7 +198,7 @@ void LLThreadSafeQueue::pushFront(ElementT const & element) if (mStorage.size() < mCapacity) { - mStorage.push_front(element); + mStorage.push(element); lock1.unlock(); mEmptyCond.notify_one(); return; @@ -175,15 +210,24 @@ void LLThreadSafeQueue::pushFront(ElementT const & element) } -template +template template -bool LLThreadSafeQueue::tryPushFrontFor(const std::chrono::duration& timeout, - ElementT const & element) +bool LLThreadSafeQueue::tryPushFor( + const std::chrono::duration& timeout, + ElementT const & element) { // Convert duration to time_point: passing the same timeout duration to // each of multiple calls is wrong. - auto endpoint = std::chrono::steady_clock::now() + timeout; + return tryPushUntil(std::chrono::steady_clock::now() + timeout, element); +} + +template +template +bool LLThreadSafeQueue::tryPushUntil( + const std::chrono::time_point& endpoint, + ElementT const& element) +{ lock_t lock1(mLock, std::defer_lock); if (!lock1.try_lock_until(endpoint)) return false; @@ -197,7 +241,7 @@ bool LLThreadSafeQueue::tryPushFrontFor(const std::chrono::duration::tryPushFrontFor(const std::chrono::duration -bool LLThreadSafeQueue::tryPushFront(ElementT const & element) +template +bool LLThreadSafeQueue::tryPush(ElementT const & element) { lock_t lock1(mLock, std::defer_lock); if (!lock1.try_lock()) @@ -228,23 +272,24 @@ bool LLThreadSafeQueue::tryPushFront(ElementT const & element) if (mStorage.size() >= mCapacity) return false; - mStorage.push_front(element); + mStorage.push(element); lock1.unlock(); mEmptyCond.notify_one(); return true; } -template -ElementT LLThreadSafeQueue::popBack(void) +template +ElementT LLThreadSafeQueue::pop(void) { lock_t lock1(mLock); while (true) { if (!mStorage.empty()) { - ElementT value = mStorage.back(); - mStorage.pop_back(); + // std::queue::front() is the element about to pop() + ElementT value = mStorage.front(); + mStorage.pop(); lock1.unlock(); mCapacityCond.notify_one(); return value; @@ -261,54 +306,106 @@ ElementT LLThreadSafeQueue::popBack(void) } -template -bool LLThreadSafeQueue::tryPopBack(ElementT & element) +template +bool LLThreadSafeQueue::tryPop(ElementT & element) { lock_t lock1(mLock, std::defer_lock); if (!lock1.try_lock()) return false; - // no need to check mClosed: tryPopBack() behavior when the queue is + // no need to check mClosed: tryPop() behavior when the queue is // closed is implemented by simple inability to push any new elements if (mStorage.empty()) return false; - element = mStorage.back(); - mStorage.pop_back(); + // std::queue::front() is the element about to pop() + element = mStorage.front(); + mStorage.pop(); lock1.unlock(); mCapacityCond.notify_one(); return true; } -template -size_t LLThreadSafeQueue::size(void) +template +template +bool LLThreadSafeQueue::tryPopFor( + const std::chrono::duration& timeout, + ElementT& element) +{ + // Convert duration to time_point: passing the same timeout duration to + // each of multiple calls is wrong. + return tryPopUntil(std::chrono::steady_clock::now() + timeout, element); +} + + +template +template +bool LLThreadSafeQueue::tryPopUntil( + const std::chrono::time_point& endpoint, + ElementT& element) +{ + lock_t lock1(mLock, std::defer_lock); + if (!lock1.try_lock_until(endpoint)) + return false; + + while (true) + { + if (!mStorage.empty()) + { + // std::queue::front() is the element about to pop() + element = mStorage.front(); + mStorage.pop(); + lock1.unlock(); + mCapacityCond.notify_one(); + return true; + } + + if (mClosed) + { + return false; + } + + // Storage empty. Wait for signal. + if (LLCoros::cv_status::timeout == mEmptyCond.wait_until(lock1, endpoint)) + { + // timed out -- formally we might recheck both conditions above + return false; + } + // If we didn't time out, we were notified for some reason. Loop back + // to check. + } +} + + +template +size_t LLThreadSafeQueue::size(void) { lock_t lock(mLock); return mStorage.size(); } -template -void LLThreadSafeQueue::close() +template +void LLThreadSafeQueue::close() { lock_t lock(mLock); mClosed = true; lock.unlock(); - // wake up any blocked popBack() calls + // wake up any blocked pop() calls mEmptyCond.notify_all(); - // wake up any blocked pushFront() calls + // wake up any blocked push() calls mCapacityCond.notify_all(); } -template -bool LLThreadSafeQueue::isClosed() +template +bool LLThreadSafeQueue::isClosed() { lock_t lock(mLock); return mClosed && mStorage.size() == 0; } -template -LLThreadSafeQueue::operator bool() +template +LLThreadSafeQueue::operator bool() { return ! isClosed(); } -- cgit v1.2.3 From 1b1ebdf183e50c6a751493570ee6e643c33c4eda Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Mon, 4 Oct 2021 11:48:58 -0400 Subject: SL-16024: Introduce tuple.h with tuple_cons(), tuple_cdr(). These functions allow prepending or removing an item at the left end of an arbitrary tuple -- for instance, to add a sequence key to a caller's data, then remove it again when delivering the original tuple. --- indra/llcommon/CMakeLists.txt | 2 + indra/llcommon/tests/tuple_test.cpp | 47 +++++++++++++++++++++ indra/llcommon/tuple.h | 84 +++++++++++++++++++++++++++++++++++++ 3 files changed, 133 insertions(+) create mode 100644 indra/llcommon/tests/tuple_test.cpp create mode 100644 indra/llcommon/tuple.h diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index dd266630ea..6558219462 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -254,6 +254,7 @@ set(llcommon_HEADER_FILES stdtypes.h stringize.h timer.h + tuple.h u64.h StackWalker.h ) @@ -358,6 +359,7 @@ if (LL_TESTS) LL_ADD_INTEGRATION_TEST(lluri "" "${test_libs}") LL_ADD_INTEGRATION_TEST(llunits "" "${test_libs}") LL_ADD_INTEGRATION_TEST(stringize "" "${test_libs}") + LL_ADD_INTEGRATION_TEST(tuple "" "${test_libs}") ## llexception_test.cpp isn't a regression test, and doesn't need to be run ## every build. It's to help a developer make implementation choices about diff --git a/indra/llcommon/tests/tuple_test.cpp b/indra/llcommon/tests/tuple_test.cpp new file mode 100644 index 0000000000..af94e2086c --- /dev/null +++ b/indra/llcommon/tests/tuple_test.cpp @@ -0,0 +1,47 @@ +/** + * @file tuple_test.cpp + * @author Nat Goodspeed + * @date 2021-10-04 + * @brief Test for tuple. + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$ + * Copyright (c) 2021, Linden Research, Inc. + * $/LicenseInfo$ + */ + +// Precompiled header +#include "linden_common.h" +// associated header +#include "tuple.h" +// STL headers +// std headers +// external library headers +// other Linden headers +#include "../test/lltut.h" + +/***************************************************************************** +* TUT +*****************************************************************************/ +namespace tut +{ + struct tuple_data + { + }; + typedef test_group tuple_group; + typedef tuple_group::object object; + tuple_group tuplegrp("tuple"); + + template<> template<> + void object::test<1>() + { + set_test_name("tuple"); + std::tuple tup{ "abc", 17 }; + std::tuple ptup{ tuple_cons(34, tup) }; + std::tuple tup2; + int i; + std::tie(i, tup2) = tuple_split(ptup); + ensure_equals("tuple_car() fail", i, 34); + ensure_equals("tuple_cdr() (0) fail", std::get<0>(tup2), "abc"); + ensure_equals("tuple_cdr() (1) fail", std::get<1>(tup2), 17); + } +} // namespace tut diff --git a/indra/llcommon/tuple.h b/indra/llcommon/tuple.h new file mode 100644 index 0000000000..bfe7e3c2ba --- /dev/null +++ b/indra/llcommon/tuple.h @@ -0,0 +1,84 @@ +/** + * @file tuple.h + * @author Nat Goodspeed + * @date 2021-10-04 + * @brief A couple tuple utilities + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$ + * Copyright (c) 2021, Linden Research, Inc. + * $/LicenseInfo$ + */ + +#if ! defined(LL_TUPLE_H) +#define LL_TUPLE_H + +#include +#include // std::remove_reference +#include // std::pair + +/** + * tuple_cons() behaves like LISP cons: it uses std::tuple_cat() to prepend a + * new item of arbitrary type to an existing std::tuple. + */ +template > +auto tuple_cons(First&& first, Tuple_&& rest) +{ + // All we need to do is make a tuple containing 'first', and let + // tuple_cat() do the hard part. + return std::tuple_cat(std::tuple(std::forward(first)), + std::forward(rest)); +} + +/** + * tuple_car() behaves like LISP car: it extracts the first item from a + * std::tuple. + */ +template > +auto tuple_car(Tuple_&& tuple) +{ + return std::get<0>(std::forward(tuple)); +} + +/** + * tuple_cdr() behaves like LISP cdr: it returns a new tuple containing + * everything BUT the first item. + */ +// derived from https://stackoverflow.com/a/24046437 +template +auto tuple_cdr_(Tuple&& tuple, const std::index_sequence) +{ + // Given an index sequence from [0..N-1), extract tuple items [1..N) + return std::make_tuple(std::get(std::forward(tuple))...); +} + +template +auto tuple_cdr(Tuple&& tuple) +{ + return tuple_cdr_( + std::forward(tuple), + // Pass helper function an index sequence one item shorter than tuple + std::make_index_sequence< + std::tuple_size< + // tuple_size doesn't like reference types + typename std::remove_reference::type + >::value - 1u> + ()); +} + +/** + * tuple_split(), the opposite of tuple_cons(), has no direct analog in LISP. + * It returns a std::pair of tuple_car(), tuple_cdr(). We could call this + * function tuple_car_cdr(), or tuple_slice() or some such. But tuple_split() + * feels more descriptive. + */ +template > +auto tuple_split(Tuple_&& tuple) +{ + // We're not really worried about forwarding multiple times a tuple that + // might contain move-only items, because the implementation above only + // applies std::get() exactly once to each item. + return std::make_pair(tuple_car(std::forward(tuple)), + tuple_cdr(std::forward(tuple))); +} + +#endif /* ! defined(LL_TUPLE_H) */ -- cgit v1.2.3 From ca60fbe72ce086fbdf0821043ad3be6aad06857c Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Mon, 4 Oct 2021 16:19:59 -0400 Subject: SL-16024: LLThreadSafeQueue enhancements Add LL::PriorityQueueAdapter, a wrapper for std::priority_queue to make its API more closely resemble std::queue for drop-in use as LLThreadSafeQueue's underlying QueueT container. Support move-only element types. Factor out some implementation redundancy: wrap actual push semantics as push_(), actual pop semantics as pop_(). push(), tryPush() and tryPushUntil() now call push_(); pop(), tryPop() and tryPopUntil() now call pop_(). Break out tryLock() and tryLockUntil() methods that, if they can lock, run the passed callable. Then tryPush(), tryPushUntil(), tryPop() and tryPopUntil() pass lambdas containing the meat of the original method body to tryLock() or tryLockUntil(), as appropriate. --- indra/llcommon/llthreadsafequeue.h | 358 ++++++++++++++++++++++++------------- 1 file changed, 235 insertions(+), 123 deletions(-) diff --git a/indra/llcommon/llthreadsafequeue.h b/indra/llcommon/llthreadsafequeue.h index 04f51816d7..c57520c01f 100644 --- a/indra/llcommon/llthreadsafequeue.h +++ b/indra/llcommon/llthreadsafequeue.h @@ -37,6 +37,9 @@ #include #include +/***************************************************************************** +* LLThreadSafeQueue +*****************************************************************************/ // // A general queue exception. // @@ -77,8 +80,8 @@ class LLThreadSafeQueue public: typedef ElementT value_type; - // If the pool is set to NULL one will be allocated and managed by this - // queue. + // Limiting the number of pending items prevents unbounded growth of the + // underlying queue. LLThreadSafeQueue(U32 capacity = 1024); // Add an element to the queue (will block if the queue has @@ -86,13 +89,15 @@ public: // // This call will raise an interrupt error if the queue is closed while // the caller is blocked. - void push(ElementT const& element); + template + void push(T&& element); // legacy name void pushFront(ElementT const & element) { return push(element); } // Try to add an element to the queue without blocking. Returns // true only if the element was actually added. - bool tryPush(ElementT const& element); + template + bool tryPush(T&& element); // legacy name bool tryPushFront(ElementT const & element) { return tryPush(element); } @@ -102,9 +107,9 @@ public: // to lock the mutex, versus how long to wait for the queue to stop being // full. Careful settings for each timeout might be orders of magnitude // apart. However, this method conflates them. - template + template bool tryPushFor(const std::chrono::duration& timeout, - ElementT const & element); + T&& element); // legacy name template bool tryPushFrontFor(const std::chrono::duration& timeout, @@ -112,9 +117,9 @@ public: // Try to add an element to the queue, blocking if full but with // timeout at specified time_point. Returns true if the element was added. - template - bool tryPushUntil(const std::chrono::time_point& timeout, - ElementT const& element); + template + bool tryPushUntil(const std::chrono::time_point& until, + T&& element); // no legacy name because this is a newer method // Pop the element at the head of the queue (will block if the queue is @@ -141,7 +146,7 @@ public: // Pop the element at the head of the queue, blocking if empty, with // timeout at specified time_point. Returns true if an element was popped. template - bool tryPopUntil(const std::chrono::time_point& timeout, + bool tryPopUntil(const std::chrono::time_point& until, ElementT& element); // no legacy name because this is a newer method @@ -172,11 +177,74 @@ protected: typedef std::unique_lock lock_t; boost::fibers::condition_variable_any mCapacityCond; boost::fibers::condition_variable_any mEmptyCond; -}; -// LLThreadSafeQueue -//----------------------------------------------------------------------------- + // if we're able to lock immediately, do so and run the passed callable, + // which must accept lock_t& and return bool + template + bool tryLock(CALLABLE&& callable); + // if we're able to lock before the passed time_point, do so and run the + // passed callable, which must accept lock_t& and return bool + template + bool tryLockUntil(const std::chrono::time_point& until, + CALLABLE&& callable); + // while lock is locked, really push the passed element, if we can + template + bool push_(lock_t& lock, T&& element); + // while lock is locked, really pop the head element, if we can + template + bool pop_(lock_t& lock, ElementT& element, + PRED&& pred=[](const ElementT&){ return true; }); +}; +/***************************************************************************** +* PriorityQueueAdapter +*****************************************************************************/ +namespace LL +{ + /** + * std::priority_queue's API is almost like std::queue, intentionally of + * course, but you must access the element about to pop() as top() rather + * than as front(). Make an adapter for use with LLThreadSafeQueue. + */ + template , + typename Compare=std::less> + class PriorityQueueAdapter + { + public: + // publish all the same types + typedef std::priority_queue queue_type; + typedef typename queue_type::container_type container_type; + typedef typename queue_type::value_compare value_compare; + typedef typename queue_type::value_type value_type; + typedef typename queue_type::size_type size_type; + typedef typename queue_type::reference reference; + typedef typename queue_type::const_reference const_reference; + + // Although std::queue defines both const and non-const front() + // methods, std::priority_queue defines only const top(). + const_reference front() const { return mQ.top(); } + // std::priority_queue has no equivalent to back(), so it's good that + // LLThreadSafeQueue doesn't use it. + + // All the rest of these merely forward to the corresponding + // queue_type methods. + bool empty() const { return mQ.empty(); } + size_type size() const { return mQ.size(); } + void push(const value_type& value) { mQ.push(value); } + void push(value_type&& value) { mQ.push(std::move(value)); } + template + void emplace(Args&&... args) { mQ.emplace(std::forward(args)...); } + void pop() { mQ.pop(); } + + private: + queue_type mQ; + }; +} // namespace LL + + +/***************************************************************************** +* LLThreadSafeQueue implementation +*****************************************************************************/ template LLThreadSafeQueue::LLThreadSafeQueue(U32 capacity) : mCapacity(capacity), @@ -185,24 +253,69 @@ LLThreadSafeQueue::LLThreadSafeQueue(U32 capacity) : } -template -void LLThreadSafeQueue::push(ElementT const & element) +// if we're able to lock immediately, do so and run the passed callable, which +// must accept lock_t& and return bool +template +template +bool LLThreadSafeQueue::tryLock(CALLABLE&& callable) +{ + lock_t lock1(mLock, std::defer_lock); + if (!lock1.try_lock()) + return false; + + return std::forward(callable)(lock1); +} + + +// if we're able to lock before the passed time_point, do so and run the +// passed callable, which must accept lock_t& and return bool +template +template +bool LLThreadSafeQueue::tryLockUntil( + const std::chrono::time_point& until, + CALLABLE&& callable) +{ + lock_t lock1(mLock, std::defer_lock); + if (!lock1.try_lock_until(until)) + return false; + + return std::forward(callable)(lock1); +} + + +// while lock is locked, really push the passed element, if we can +template +template +bool LLThreadSafeQueue::push_(lock_t& lock, T&& element) +{ + if (mStorage.size() >= mCapacity) + return false; + + mStorage.push(std::forward(element)); + lock.unlock(); + // now that we've pushed, if somebody's been waiting to pop, signal them + mEmptyCond.notify_one(); + return true; +} + + +template +template +void LLThreadSafeQueue::push(T&& element) { lock_t lock1(mLock); while (true) { + // On the producer side, it doesn't matter whether the queue has been + // drained or not: the moment either end calls close(), further push() + // operations will fail. if (mClosed) { LLTHROW(LLThreadSafeQueueInterrupt()); } - if (mStorage.size() < mCapacity) - { - mStorage.push(element); - lock1.unlock(); - mEmptyCond.notify_one(); + if (push_(lock1, std::forward(element))) return; - } // Storage Full. Wait for signal. mCapacityCond.wait(lock1); @@ -210,71 +323,85 @@ void LLThreadSafeQueue::push(ElementT const & element) } +template +template +bool LLThreadSafeQueue::tryPush(T&& element) +{ + return tryLock( + [this, element=std::move(element)](lock_t& lock) + { + if (mClosed) + return false; + return push_(lock, std::move(element)); + }); +} + + template -template +template bool LLThreadSafeQueue::tryPushFor( const std::chrono::duration& timeout, - ElementT const & element) + T&& element) { // Convert duration to time_point: passing the same timeout duration to // each of multiple calls is wrong. - return tryPushUntil(std::chrono::steady_clock::now() + timeout, element); + return tryPushUntil(std::chrono::steady_clock::now() + timeout, + std::forward(element)); } template -template +template bool LLThreadSafeQueue::tryPushUntil( - const std::chrono::time_point& endpoint, - ElementT const& element) + const std::chrono::time_point& until, + T&& element) { - lock_t lock1(mLock, std::defer_lock); - if (!lock1.try_lock_until(endpoint)) - return false; - - while (true) - { - if (mClosed) + return tryLockUntil( + until, + [this, until, element=std::move(element)](lock_t& lock) { - return false; - } - - if (mStorage.size() < mCapacity) - { - mStorage.push(element); - lock1.unlock(); - mEmptyCond.notify_one(); - return true; - } - - // Storage Full. Wait for signal. - if (LLCoros::cv_status::timeout == mCapacityCond.wait_until(lock1, endpoint)) - { - // timed out -- formally we might recheck both conditions above - return false; - } - // If we didn't time out, we were notified for some reason. Loop back - // to check. - } + while (true) + { + if (mClosed) + { + return false; + } + + if (push_(lock, std::move(element))) + return true; + + // Storage Full. Wait for signal. + if (LLCoros::cv_status::timeout == mCapacityCond.wait_until(lock, until)) + { + // timed out -- formally we might recheck both conditions above + return false; + } + // If we didn't time out, we were notified for some reason. Loop back + // to check. + } + }); } -template -bool LLThreadSafeQueue::tryPush(ElementT const & element) +// while lock is locked, really pop the head element, if we can +template +template +bool LLThreadSafeQueue::pop_( + lock_t& lock, ElementT& element, PRED&& pred) { - lock_t lock1(mLock, std::defer_lock); - if (!lock1.try_lock()) - return false; - - if (mClosed) - return false; - - if (mStorage.size() >= mCapacity) + // If mStorage is empty, there's no head element. + // If there's a head element, pass it to the predicate to see if caller + // considers it ready to pop. + // Unless both are satisfied, no point in continuing. + if (mStorage.empty() || ! std::forward(pred)(mStorage.front())) return false; - mStorage.push(element); - lock1.unlock(); - mEmptyCond.notify_one(); + // std::queue::front() is the element about to pop() + element = mStorage.front(); + mStorage.pop(); + lock.unlock(); + // now that we've popped, if somebody's been waiting to push, signal them + mCapacityCond.notify_one(); return true; } @@ -285,22 +412,20 @@ ElementT LLThreadSafeQueue::pop(void) lock_t lock1(mLock); while (true) { - if (!mStorage.empty()) - { - // std::queue::front() is the element about to pop() - ElementT value = mStorage.front(); - mStorage.pop(); - lock1.unlock(); - mCapacityCond.notify_one(); - return value; - } - + // On the consumer side, we always try to pop before checking mClosed + // so we can finish draining the queue. + ElementT value; + if (pop_(lock1, value)) + return std::move(value); + + // Once the queue is empty, mClosed lets us know if there will ever be + // any more coming. if (mClosed) { LLTHROW(LLThreadSafeQueueInterrupt()); } - // Storage empty. Wait for signal. + // Storage empty, queue still open. Wait for signal. mEmptyCond.wait(lock1); } } @@ -309,21 +434,14 @@ ElementT LLThreadSafeQueue::pop(void) template bool LLThreadSafeQueue::tryPop(ElementT & element) { - lock_t lock1(mLock, std::defer_lock); - if (!lock1.try_lock()) - return false; - - // no need to check mClosed: tryPop() behavior when the queue is - // closed is implemented by simple inability to push any new elements - if (mStorage.empty()) - return false; - - // std::queue::front() is the element about to pop() - element = mStorage.front(); - mStorage.pop(); - lock1.unlock(); - mCapacityCond.notify_one(); - return true; + return tryLock( + [this, &element](lock_t& lock) + { + // no need to check mClosed: tryPop() behavior when the queue is + // closed is implemented by simple inability to push any new + // elements + return pop_(lock, element); + }); } @@ -342,39 +460,33 @@ bool LLThreadSafeQueue::tryPopFor( template template bool LLThreadSafeQueue::tryPopUntil( - const std::chrono::time_point& endpoint, + const std::chrono::time_point& until, ElementT& element) { - lock_t lock1(mLock, std::defer_lock); - if (!lock1.try_lock_until(endpoint)) - return false; - - while (true) - { - if (!mStorage.empty()) + return tryLockUntil( + until, + [this, until, &element](lock_t& lock) { - // std::queue::front() is the element about to pop() - element = mStorage.front(); - mStorage.pop(); - lock1.unlock(); - mCapacityCond.notify_one(); - return true; - } - - if (mClosed) - { - return false; - } - - // Storage empty. Wait for signal. - if (LLCoros::cv_status::timeout == mEmptyCond.wait_until(lock1, endpoint)) - { - // timed out -- formally we might recheck both conditions above - return false; - } - // If we didn't time out, we were notified for some reason. Loop back - // to check. - } + while (true) + { + if (pop_(lock, element)) + return true; + + if (mClosed) + { + return false; + } + + // Storage empty. Wait for signal. + if (LLCoros::cv_status::timeout == mEmptyCond.wait_until(lock, until)) + { + // timed out -- formally we might recheck both conditions above + return false; + } + // If we didn't time out, we were notified for some reason. Loop back + // to check. + } + }); } -- cgit v1.2.3 From a35e266547e4d2c8dbd6b003c64b719d91eaaf87 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Mon, 4 Oct 2021 17:21:39 -0400 Subject: SL-16024: Don't use a lambda as default arg for universal reference. Instead, break out a separate pop_() method that explicitly provides the lambda to the real pop_() implementation. --- indra/llcommon/llthreadsafequeue.h | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/indra/llcommon/llthreadsafequeue.h b/indra/llcommon/llthreadsafequeue.h index c57520c01f..1dffad6b89 100644 --- a/indra/llcommon/llthreadsafequeue.h +++ b/indra/llcommon/llthreadsafequeue.h @@ -191,9 +191,11 @@ protected: template bool push_(lock_t& lock, T&& element); // while lock is locked, really pop the head element, if we can + bool pop_(lock_t& lock, ElementT& element); + // pop_() with an explicit predicate indicating whether the head element + // is ready to be popped template - bool pop_(lock_t& lock, ElementT& element, - PRED&& pred=[](const ElementT&){ return true; }); + bool pop_(lock_t& lock, ElementT& element, PRED&& pred); }; /***************************************************************************** @@ -385,6 +387,16 @@ bool LLThreadSafeQueue::tryPushUntil( // while lock is locked, really pop the head element, if we can template +bool LLThreadSafeQueue::pop_(lock_t& lock, ElementT& element) +{ + // default predicate: head element, if present, is always ready to pop + return pop_(lock, element, [](const ElementT&){ return true; }); +} + + +// pop_() with an explicit predicate indicating whether the head element +// is ready to be popped +template template bool LLThreadSafeQueue::pop_( lock_t& lock, ElementT& element, PRED&& pred) -- cgit v1.2.3 From 4778f9497ec8b871c297b4efc4c0a44ee5726af1 Mon Sep 17 00:00:00 2001 From: Dave Houlton Date: Tue, 5 Oct 2021 10:05:22 -0600 Subject: DRTVWR-546 trigger --- indra/edit-me-to-trigger-new-build.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/indra/edit-me-to-trigger-new-build.txt b/indra/edit-me-to-trigger-new-build.txt index 5366987cff..eab7c17b71 100644 --- a/indra/edit-me-to-trigger-new-build.txt +++ b/indra/edit-me-to-trigger-new-build.txt @@ -1,3 +1,4 @@ euclid 5/29/2020 euclid 7/23/2020 -euclid 4/29/2021 \ No newline at end of file +euclid 4/29/2021 +euclid 10/5/2021 DRTVWR-546 -- cgit v1.2.3 From f0e31b6c82d38706acbad22abc3946c2579870cd Mon Sep 17 00:00:00 2001 From: Dave Houlton Date: Tue, 5 Oct 2021 13:29:46 -0600 Subject: SL-16138 Avoid re-binding a shader which is already bound --- indra/llrender/llglslshader.cpp | 53 ++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 30 deletions(-) diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index 9ab38d25a9..46b9c69faa 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -938,52 +938,45 @@ BOOL LLGLSLShader::link(BOOL suppress_errors) void LLGLSLShader::bind() { - gGL.flush(); - if (gGLManager.mHasShaderObjects) + LL_PROFILE_ZONE_SCOPED; + + if (sCurBoundShader != mProgramObject) // Don't re-bind current shader { + gGL.flush(); LLVertexBuffer::unbind(); glUseProgramObjectARB(mProgramObject); sCurBoundShader = mProgramObject; sCurBoundShaderPtr = this; - if (mUniformsDirty) - { - LLShaderMgr::instance()->updateShaderUniforms(this); - mUniformsDirty = FALSE; - } + } + + if (mUniformsDirty) + { + LLShaderMgr::instance()->updateShaderUniforms(this); + mUniformsDirty = FALSE; } } void LLGLSLShader::unbind() { + LL_PROFILE_ZONE_SCOPED; + gGL.flush(); - if (gGLManager.mHasShaderObjects) - { - stop_glerror(); - if (gGLManager.mIsNVIDIA) - { - for (U32 i = 0; i < mAttribute.size(); ++i) - { - vertexAttrib4f(i, 0,0,0,1); - stop_glerror(); - } - } - LLVertexBuffer::unbind(); - glUseProgramObjectARB(0); - sCurBoundShader = 0; - sCurBoundShaderPtr = NULL; - stop_glerror(); - } + stop_glerror(); + LLVertexBuffer::unbind(); + glUseProgramObjectARB(0); + sCurBoundShader = 0; + sCurBoundShaderPtr = NULL; + stop_glerror(); } void LLGLSLShader::bindNoShader(void) { + LL_PROFILE_ZONE_SCOPED; + LLVertexBuffer::unbind(); - if (gGLManager.mHasShaderObjects) - { - glUseProgramObjectARB(0); - sCurBoundShader = 0; - sCurBoundShaderPtr = NULL; - } + glUseProgramObjectARB(0); + sCurBoundShader = 0; + sCurBoundShaderPtr = NULL; } S32 LLGLSLShader::bindTexture(const std::string &uniform, LLTexture *texture, LLTexUnit::eTextureType mode, LLTexUnit::eTextureColorSpace colorspace) -- cgit v1.2.3 From 955b967623983cb50ba09f7b82e5f01f2c6bcebb Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Tue, 5 Oct 2021 17:31:53 -0400 Subject: SL-16024: Add ThreadSafeSchedule, a timestamped LLThreadSafeQueue. ThreadSafeSchedule orders its items by timestamp, which can be passed either implicitly or explicitly. The timestamp specifies earliest delivery time: an item cannot be popped until that time. Add initial tests. Tweak the LLThreadSafeQueue base class to support ThreadSafeSchedule: introduce virtual canPop() method to report whether the current head item is available to pop. The base class unconditionally says yes, ThreadSafeSchedule says it depends on whether its timestamp is still in the future. This replaces the protected pop_() overload accepting a predicate. Rather than explicitly passing a predicate through a couple levels of function call, use canPop() at the level it matters. Runtime behavior that varies depending on an object's leaf class is what virtual functions were invented for. Give pop_() a three-state enum return so pop() can distinguish between "closed and empty" (throws exception) versus "closed, not yet drained because we're not yet ready to pop the head item" (waits). Also break out protected tryPopUntil_() method, the body logic of tryPopUntil(). The public method locks the data structure, the protected method requires that its caller has already done so. Add chrono.h with a more full-featured LL::time_point_cast() function than the one found in , which only converts between time_point durations, not between time_points based on different clocks. --- indra/llcommon/CMakeLists.txt | 3 + indra/llcommon/chrono.h | 65 +++++ indra/llcommon/llthreadsafequeue.h | 121 ++++---- indra/llcommon/tests/threadsafeschedule_test.cpp | 65 +++++ indra/llcommon/threadsafeschedule.h | 334 +++++++++++++++++++++++ 5 files changed, 535 insertions(+), 53 deletions(-) create mode 100644 indra/llcommon/chrono.h create mode 100644 indra/llcommon/tests/threadsafeschedule_test.cpp create mode 100644 indra/llcommon/threadsafeschedule.h diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 6558219462..5efcfabf24 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -127,6 +127,7 @@ set(llcommon_SOURCE_FILES set(llcommon_HEADER_FILES CMakeLists.txt + chrono.h ctype_workaround.h fix_macros.h indra_constants.h @@ -253,6 +254,7 @@ set(llcommon_HEADER_FILES lockstatic.h stdtypes.h stringize.h + threadsafeschedule.h timer.h tuple.h u64.h @@ -359,6 +361,7 @@ if (LL_TESTS) LL_ADD_INTEGRATION_TEST(lluri "" "${test_libs}") LL_ADD_INTEGRATION_TEST(llunits "" "${test_libs}") LL_ADD_INTEGRATION_TEST(stringize "" "${test_libs}") + LL_ADD_INTEGRATION_TEST(threadsafeschedule "" "${test_libs}") LL_ADD_INTEGRATION_TEST(tuple "" "${test_libs}") ## llexception_test.cpp isn't a regression test, and doesn't need to be run diff --git a/indra/llcommon/chrono.h b/indra/llcommon/chrono.h new file mode 100644 index 0000000000..806e871892 --- /dev/null +++ b/indra/llcommon/chrono.h @@ -0,0 +1,65 @@ +/** + * @file chrono.h + * @author Nat Goodspeed + * @date 2021-10-05 + * @brief supplement with utility functions + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$ + * Copyright (c) 2021, Linden Research, Inc. + * $/LicenseInfo$ + */ + +#if ! defined(LL_CHRONO_H) +#define LL_CHRONO_H + +#include +#include // std::enable_if + +namespace LL +{ + +// time_point_cast() is derived from https://stackoverflow.com/a/35293183 +// without the iteration: we think errors in the ~1 microsecond range are +// probably acceptable. + +// This variant is for the optimal case when the source and dest use the same +// clock: that case is handled by std::chrono. +template ::value, + bool>::type = true> +DestTimePoint time_point_cast(const SrcTimePoint& time) +{ + return std::chrono::time_point_cast(time); +} + +// This variant is for when the source and dest use different clocks -- see +// the linked StackOverflow answer, also Howard Hinnant's, for more context. +template ::value, + bool>::type = true> +DestTimePoint time_point_cast(const SrcTimePoint& time) +{ + // The basic idea is that we must adjust the passed time_point by the + // difference between the clocks' epochs. But since time_point doesn't + // expose its epoch, we fall back on what each of them thinks is now(). + // However, since we necessarily make sequential calls to those now() + // functions, the answers differ not only by the cycles spent executing + // those calls, but by potential OS interruptions between them. Try to + // reduce that error by capturing the source clock time both before and + // after the dest clock, and splitting the difference. Of course an + // interruption between two of these now() calls without a comparable + // interruption between the other two will skew the result, but better is + // more expensive. + const auto src_before = typename SrcTimePoint::clock::now(); + const auto dest_now = typename DestTimePoint::clock::now(); + const auto src_after = typename SrcTimePoint::clock::now(); + const auto src_diff = src_after - src_before; + const auto src_now = src_before + src_diff / 2; + return dest_now + (time - src_now); +} + +} // namespace LL + +#endif /* ! defined(LL_CHRONO_H) */ diff --git a/indra/llcommon/llthreadsafequeue.h b/indra/llcommon/llthreadsafequeue.h index 1dffad6b89..bd2d82d4c3 100644 --- a/indra/llcommon/llthreadsafequeue.h +++ b/indra/llcommon/llthreadsafequeue.h @@ -83,6 +83,7 @@ public: // Limiting the number of pending items prevents unbounded growth of the // underlying queue. LLThreadSafeQueue(U32 capacity = 1024); + virtual ~LLThreadSafeQueue() {} // Add an element to the queue (will block if the queue has // reached capacity). @@ -162,10 +163,10 @@ public: // then every subsequent tryPop() call will return false void close(); - // detect closed state + // producer end: are we prevented from pushing any additional items? bool isClosed(); - // inverse of isClosed() - explicit operator bool(); + // consumer end: are we done, is the queue entirely drained? + bool done(); protected: typedef QueueT queue_type; @@ -178,6 +179,11 @@ protected: boost::fibers::condition_variable_any mCapacityCond; boost::fibers::condition_variable_any mEmptyCond; + // implementation logic, suitable for passing to tryLockUntil() + template + bool tryPopUntil_(lock_t& lock, + const std::chrono::time_point& until, + ElementT& element); // if we're able to lock immediately, do so and run the passed callable, // which must accept lock_t& and return bool template @@ -191,11 +197,11 @@ protected: template bool push_(lock_t& lock, T&& element); // while lock is locked, really pop the head element, if we can - bool pop_(lock_t& lock, ElementT& element); - // pop_() with an explicit predicate indicating whether the head element - // is ready to be popped - template - bool pop_(lock_t& lock, ElementT& element, PRED&& pred); + enum pop_result { EMPTY, WAITING, POPPED }; + pop_result pop_(lock_t& lock, ElementT& element); + // Is the current head element ready to pop? We say yes; subclass can + // override as needed. + virtual bool canPop(const ElementT& head) const { return true; } }; /***************************************************************************** @@ -387,26 +393,16 @@ bool LLThreadSafeQueue::tryPushUntil( // while lock is locked, really pop the head element, if we can template -bool LLThreadSafeQueue::pop_(lock_t& lock, ElementT& element) -{ - // default predicate: head element, if present, is always ready to pop - return pop_(lock, element, [](const ElementT&){ return true; }); -} - - -// pop_() with an explicit predicate indicating whether the head element -// is ready to be popped -template -template -bool LLThreadSafeQueue::pop_( - lock_t& lock, ElementT& element, PRED&& pred) +typename LLThreadSafeQueue::pop_result +LLThreadSafeQueue::pop_(lock_t& lock, ElementT& element) { // If mStorage is empty, there's no head element. - // If there's a head element, pass it to the predicate to see if caller - // considers it ready to pop. - // Unless both are satisfied, no point in continuing. - if (mStorage.empty() || ! std::forward(pred)(mStorage.front())) - return false; + if (mStorage.empty()) + return EMPTY; + + // If there's a head element, pass it to canPop() to see if it's ready to pop. + if (! canPop(mStorage.front())) + return WAITING; // std::queue::front() is the element about to pop() element = mStorage.front(); @@ -414,7 +410,7 @@ bool LLThreadSafeQueue::pop_( lock.unlock(); // now that we've popped, if somebody's been waiting to push, signal them mCapacityCond.notify_one(); - return true; + return POPPED; } @@ -422,17 +418,20 @@ template ElementT LLThreadSafeQueue::pop(void) { lock_t lock1(mLock); + ElementT value; while (true) { // On the consumer side, we always try to pop before checking mClosed // so we can finish draining the queue. - ElementT value; - if (pop_(lock1, value)) + pop_result popped = pop_(lock1, value); + if (popped == POPPED) return std::move(value); // Once the queue is empty, mClosed lets us know if there will ever be - // any more coming. - if (mClosed) + // any more coming. If we didn't pop because WAITING, i.e. canPop() + // returned false, then even if the producer end has been closed, + // there's still at least one item to drain: wait for it. + if (popped == EMPTY && mClosed) { LLTHROW(LLThreadSafeQueueInterrupt()); } @@ -452,7 +451,7 @@ bool LLThreadSafeQueue::tryPop(ElementT & element) // no need to check mClosed: tryPop() behavior when the queue is // closed is implemented by simple inability to push any new // elements - return pop_(lock, element); + return pop_(lock, element) == POPPED; }); } @@ -479,26 +478,38 @@ bool LLThreadSafeQueue::tryPopUntil( until, [this, until, &element](lock_t& lock) { - while (true) - { - if (pop_(lock, element)) - return true; + return tryPopUntil_(lock, until, element); + }); +} - if (mClosed) - { - return false; - } - // Storage empty. Wait for signal. - if (LLCoros::cv_status::timeout == mEmptyCond.wait_until(lock, until)) - { - // timed out -- formally we might recheck both conditions above - return false; - } - // If we didn't time out, we were notified for some reason. Loop back - // to check. - } - }); +// body of tryPopUntil(), called once we have the lock +template +template +bool LLThreadSafeQueue::tryPopUntil_( + lock_t& lock, + const std::chrono::time_point& until, + ElementT& element) +{ + while (true) + { + if (pop_(lock, element) == POPPED) + return true; + + if (mClosed) + { + return false; + } + + // Storage empty. Wait for signal. + if (LLCoros::cv_status::timeout == mEmptyCond.wait_until(lock, until)) + { + // timed out -- formally we might recheck both conditions above + return false; + } + // If we didn't time out, we were notified for some reason. Loop back + // to check. + } } @@ -509,6 +520,7 @@ size_t LLThreadSafeQueue::size(void) return mStorage.size(); } + template void LLThreadSafeQueue::close() { @@ -521,17 +533,20 @@ void LLThreadSafeQueue::close() mCapacityCond.notify_all(); } + template bool LLThreadSafeQueue::isClosed() { lock_t lock(mLock); - return mClosed && mStorage.size() == 0; + return mClosed; } + template -LLThreadSafeQueue::operator bool() +bool LLThreadSafeQueue::done() { - return ! isClosed(); + lock_t lock(mLock); + return mClosed && mStorage.size() == 0; } #endif diff --git a/indra/llcommon/tests/threadsafeschedule_test.cpp b/indra/llcommon/tests/threadsafeschedule_test.cpp new file mode 100644 index 0000000000..ec0fa0c928 --- /dev/null +++ b/indra/llcommon/tests/threadsafeschedule_test.cpp @@ -0,0 +1,65 @@ +/** + * @file threadsafeschedule_test.cpp + * @author Nat Goodspeed + * @date 2021-10-04 + * @brief Test for threadsafeschedule. + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$ + * Copyright (c) 2021, Linden Research, Inc. + * $/LicenseInfo$ + */ + +// Precompiled header +#include "linden_common.h" +// associated header +#include "threadsafeschedule.h" +// STL headers +// std headers +#include +// external library headers +// other Linden headers +#include "../test/lltut.h" + +using namespace std::literals::chrono_literals; // ms suffix +using namespace std::literals::string_literals; // s suffix +using Queue = LL::ThreadSafeSchedule; + +/***************************************************************************** +* TUT +*****************************************************************************/ +namespace tut +{ + struct threadsafeschedule_data + { + Queue queue; + }; + typedef test_group threadsafeschedule_group; + typedef threadsafeschedule_group::object object; + threadsafeschedule_group threadsafeschedulegrp("threadsafeschedule"); + + template<> template<> + void object::test<1>() + { + set_test_name("push"); + // Simply calling push() a few times might result in indeterminate + // delivery order if the resolution of steady_clock is coarser than + // the real time required for each push() call. Explicitly increment + // the timestamp for each one -- but since we're passing explicit + // timestamps, make the queue reorder them. + queue.push(Queue::TimeTuple(Queue::Clock::now() + 20ms, "ghi")); + queue.push("abc"s); + queue.push(Queue::Clock::now() + 10ms, "def"); + queue.close(); + auto entry = queue.pop(); + ensure_equals("failed to pop first", std::get<0>(entry), "abc"s); + entry = queue.pop(); + ensure_equals("failed to pop second", std::get<0>(entry), "def"s); + ensure("queue not closed", queue.isClosed()); + ensure("queue prematurely done", ! queue.done()); + entry = queue.pop(); + ensure_equals("failed to pop third", std::get<0>(entry), "ghi"s); + bool popped = queue.tryPop(entry); + ensure("queue not empty", ! popped); + ensure("queue not done", queue.done()); + } +} // namespace tut diff --git a/indra/llcommon/threadsafeschedule.h b/indra/llcommon/threadsafeschedule.h new file mode 100644 index 0000000000..545c820f53 --- /dev/null +++ b/indra/llcommon/threadsafeschedule.h @@ -0,0 +1,334 @@ +/** + * @file threadsafeschedule.h + * @author Nat Goodspeed + * @date 2021-10-02 + * @brief ThreadSafeSchedule is an ordered queue in which every item has an + * associated timestamp. + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$ + * Copyright (c) 2021, Linden Research, Inc. + * $/LicenseInfo$ + */ + +#if ! defined(LL_THREADSAFESCHEDULE_H) +#define LL_THREADSAFESCHEDULE_H + +#include "chrono.h" +#include "llexception.h" +#include "llthreadsafequeue.h" +#include "tuple.h" +#include +#include + +namespace LL +{ + namespace ThreadSafeSchedulePrivate + { + using TimePoint = std::chrono::steady_clock::time_point; + // Bundle consumer's data with a TimePoint to order items by timestamp. + template + using TimestampedTuple = std::tuple; + + // comparison functor for TimedTuples -- see TimedQueue comments + struct ReverseTupleOrder + { + template + bool operator()(const Tuple& left, const Tuple& right) const + { + return std::get<0>(left) > std::get<0>(right); + } + }; + + template + using TimedQueue = PriorityQueueAdapter< + TimestampedTuple, + // std::vector is the default storage for std::priority_queue, + // have to restate to specify comparison template parameter + std::vector>, + // std::priority_queue uses a counterintuitive comparison + // behavior: the default std::less comparator is used to present + // the *highest* value as top(). So to sort by earliest timestamp, + // we must invert by using >. + ReverseTupleOrder>; + } // namespace ThreadSafeSchedulePrivate + + /** + * ThreadSafeSchedule is an ordered LLThreadSafeQueue in which every item + * is given an associated timestamp. That is, TimePoint is implicitly + * prepended to the std::tuple with the specified types. + * + * Items are popped in increasing chronological order. Moreover, any item + * with a timestamp in the future is held back until + * std::chrono::steady_clock reaches that timestamp. + */ + template + class ThreadSafeSchedule: + public LLThreadSafeQueue, + ThreadSafeSchedulePrivate::TimedQueue> + { + public: + using DataTuple = std::tuple; + using TimeTuple = ThreadSafeSchedulePrivate::TimestampedTuple; + + private: + using super = LLThreadSafeQueue>; + using lock_t = typename super::lock_t; + using super::pop_; + using super::push_; + using super::mClosed; + using super::mEmptyCond; + using super::mCapacityCond; + + public: + using TimePoint = ThreadSafeSchedulePrivate::TimePoint; + using Clock = TimePoint::clock; + + ThreadSafeSchedule(U32 capacity=1024): + super(capacity) + {} + + /*----------------------------- push() -----------------------------*/ + /// explicitly pass TimeTuple + using super::push; + + /// pass DataTuple with implicit now + void push(const DataTuple& tuple) + { + push(tuple_cons(Clock::now(), tuple)); + } + + /// individually pass each component of the TimeTuple + void push(const TimePoint& time, Args&&... args) + { + push(TimeTuple(time, std::forward(args)...)); + } + + /// individually pass every component except the TimePoint (implies + /// now) -- could be ambiguous if the first specified template + /// parameter type is also TimePoint -- we could try to disambiguate, + /// but a simpler approach would be for the caller to explicitly + /// construct DataTuple and call that overload + void push(Args&&... args) + { + push(Clock::now(), std::forward(args)...); + } + + /*--------------------------- tryPush() ----------------------------*/ + /// explicit TimeTuple + using super::tryPush; + + /// DataTuple with implicit now + bool tryPush(const DataTuple& tuple) + { + return tryPush(tuple_cons(Clock::now(), tuple)); + } + + /// individually pass components + bool tryPush(const TimePoint& time, Args&&... args) + { + return tryPush(TimeTuple(time, std::forward(args)...)); + } + + /// individually pass components with implicit now + bool tryPush(Args&&... args) + { + return tryPush(Clock::now(), std::forward(args)...); + } + + /*-------------------------- tryPushFor() --------------------------*/ + /// explicit TimeTuple + using super::tryPushFor; + + /// DataTuple with implicit now + template + bool tryPushFor(const std::chrono::duration& timeout, + const DataTuple& tuple) + { + return tryPushFor(timeout, tuple_cons(Clock::now(), tuple)); + } + + /// individually pass components + template + bool tryPushFor(const std::chrono::duration& timeout, + const TimePoint& time, Args&&... args) + { + return tryPushFor(TimeTuple(time, std::forward(args)...)); + } + + /// individually pass components with implicit now + template + bool tryPushFor(const std::chrono::duration& timeout, + Args&&... args) + { + return tryPushFor(Clock::now(), std::forward(args)...); + } + + /*------------------------- tryPushUntil() -------------------------*/ + /// explicit TimeTuple + using super::tryPushUntil; + + /// DataTuple with implicit now + template + bool tryPushUntil(const std::chrono::time_point& until, + const DataTuple& tuple) + { + return tryPushUntil(until, tuple_cons(Clock::now(), tuple)); + } + + /// individually pass components + template + bool tryPushUntil(const std::chrono::time_point& until, + const TimePoint& time, Args&&... args) + { + return tryPushUntil(until, TimeTuple(time, std::forward(args)...)); + } + + /// individually pass components with implicit now + template + bool tryPushUntil(const std::chrono::time_point& until, + Args&&... args) + { + return tryPushUntil(until, Clock::now(), std::forward(args)...); + } + + /*----------------------------- pop() ------------------------------*/ + // Our consumer may or may not care about the timestamp associated + // with each popped item, so we allow retrieving either DataTuple or + // TimeTuple. One potential use would be to observe, and possibly + // adjust for, the time lag between the item time and the actual + // current time. + + /// pop DataTuple by value + DataTuple pop() + { + return tuple_cdr(popWithTime()); + } + + /// pop TimeTuple by value + TimeTuple popWithTime() + { + lock_t lock(super::mLock); + // We can't just sit around waiting forever, given that there may + // be items in the queue that are not yet ready but will *become* + // ready in the near future. So in fact, with this class, every + // pop() becomes a tryPopUntil(), constrained to the timestamp of + // the head item. It almost doesn't matter what we specify for the + // caller's time constraint -- all we really care about is the + // head item's timestamp. Since pop() and popWithTime() are + // defined to wait until either an item becomes available or the + // queue is closed, loop until one of those things happens. The + // constraint we pass just determines how often we'll loop while + // waiting. + TimeTuple tt; + while (true) + { + // Pick a point suitably far into the future. + TimePoint until = TimePoint::clock::now() + std::chrono::hours(24); + if (tryPopUntil_(lock, until, tt)) + return std::move(tt); + + // empty and closed: throw, just as super::pop() does + if (super::mStorage.empty() && super::mClosed) + { + LLTHROW(LLThreadSafeQueueInterrupt()); + } + // If not empty, we've still got items to drain. + // If not closed, it's worth waiting for more items. + // Either way, loop back to wait. + } + } + + // We can use tryPop(TimeTuple&) just as it stands; the only behavior + // difference is in our canPop() override method. + using super::tryPop; + + /// tryPop(DataTuple&) + bool tryPop(DataTuple& tuple) + { + TimeTuple tt; + if (! super::tryPop(tt)) + return false; + tuple = tuple_cdr(std::move(tt)); + return true; + } + + /// tryPopFor() + template + bool tryPopFor(const std::chrono::duration& timeout, Tuple& tuple) + { + // It's important to use OUR tryPopUntil() implementation, rather + // than delegating immediately to our base class. + return tryPopUntil(Clock::now() + timeout, tuple); + } + + /// tryPopUntil(TimeTuple&) + template + bool tryPopUntil(const std::chrono::time_point& until, + TimeTuple& tuple) + { + // super::tryPopUntil() wakes up when an item becomes available or + // we hit 'until', whichever comes first. Thing is, the current + // head of the queue could become ready sooner than either of + // those events, and we need to deliver it as soon as it does. + // Don't wait past the TimePoint of the head item. + // Naturally, lock the queue before peeking at mStorage. + return super::tryLockUntil( + until, + [this, until, &tuple](lock_t& lock) + { + // Use our time_point_cast to allow for 'until' that's a + // time_point type other than TimePoint. + return tryPopUntil_(lock, time_point_cast(until), tuple); + }); + } + + bool tryPopUntil_(lock_t& lock, const TimePoint& until, TimeTuple& tuple) + { + TimePoint adjusted = until; + if (! super::mStorage.empty()) + { + // use whichever is earlier: the head item's timestamp, or + // the caller's limit + adjusted = min(std::get<0>(super::mStorage.front()), adjusted); + } + // now delegate to base-class tryPopUntil_() + return super::tryPopUntil_(lock, adjusted, tuple); + } + + /// tryPopUntil(DataTuple&) + template + bool tryPopUntil(const std::chrono::time_point& until, + DataTuple& tuple) + { + TimeTuple tt; + if (! tryPopUntil(until, tt)) + return false; + tuple = tuple_cdr(std::move(tt)); + return true; + } + + /*------------------------------ etc. ------------------------------*/ + // We can't hide items that aren't yet ready because we can't traverse + // the underlying priority_queue: it has no iterators, only top(). So + // a consumer could observe size() > 0 and yet tryPop() returns false. + // Shrug, in a multi-consumer scenario that would be expected behavior. + using super::size; + // open/closed state + using super::close; + using super::isClosed; + using super::done; + + private: + // this method is called by base class pop_() every time we're + // considering whether to deliver the current head element + bool canPop(const TimeTuple& head) const override + { + // an item with a future timestamp isn't yet ready to pop + // (should we add some slop for overhead?) + return std::get<0>(head) <= Clock::now(); + } + }; + +} // namespace LL + +#endif /* ! defined(LL_THREADSAFESCHEDULE_H) */ -- cgit v1.2.3 From cf70766b4504f7ee745822926c526ed9c86c9339 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 6 Oct 2021 12:54:29 -0400 Subject: SL-16024: Fix ThreadSafeSchedule::tryPopFor(), tryPopUntil(). ThreadSafeSchedule::tryPopUntil() (and therefore tryPopFor()) was simply delegating to LLThreadSafeQueue::tryPopUntil(), with an adjusted timeout since we want to wake up as soon as the head item, if any, becomes ready. But then we have to loop back to retry the pop to actually deal with that head item. In addition, ThreadSafeSchedule::popWithTime() was spinning rather than properly blocking on a timed condition variable. Fixed. --- indra/llcommon/llthreadsafequeue.h | 51 +++++++++-------- indra/llcommon/tests/threadsafeschedule_test.cpp | 10 +++- indra/llcommon/threadsafeschedule.h | 72 ++++++++++++++++++------ 3 files changed, 88 insertions(+), 45 deletions(-) diff --git a/indra/llcommon/llthreadsafequeue.h b/indra/llcommon/llthreadsafequeue.h index bd2d82d4c3..719edcd579 100644 --- a/indra/llcommon/llthreadsafequeue.h +++ b/indra/llcommon/llthreadsafequeue.h @@ -179,11 +179,12 @@ protected: boost::fibers::condition_variable_any mCapacityCond; boost::fibers::condition_variable_any mEmptyCond; + enum pop_result { EMPTY, DONE, WAITING, POPPED }; // implementation logic, suitable for passing to tryLockUntil() template - bool tryPopUntil_(lock_t& lock, - const std::chrono::time_point& until, - ElementT& element); + pop_result tryPopUntil_(lock_t& lock, + const std::chrono::time_point& until, + ElementT& element); // if we're able to lock immediately, do so and run the passed callable, // which must accept lock_t& and return bool template @@ -197,7 +198,6 @@ protected: template bool push_(lock_t& lock, T&& element); // while lock is locked, really pop the head element, if we can - enum pop_result { EMPTY, WAITING, POPPED }; pop_result pop_(lock_t& lock, ElementT& element); // Is the current head element ready to pop? We say yes; subclass can // override as needed. @@ -398,7 +398,7 @@ LLThreadSafeQueue::pop_(lock_t& lock, ElementT& element) { // If mStorage is empty, there's no head element. if (mStorage.empty()) - return EMPTY; + return mClosed? DONE : EMPTY; // If there's a head element, pass it to canPop() to see if it's ready to pop. if (! canPop(mStorage.front())) @@ -427,16 +427,16 @@ ElementT LLThreadSafeQueue::pop(void) if (popped == POPPED) return std::move(value); - // Once the queue is empty, mClosed lets us know if there will ever be - // any more coming. If we didn't pop because WAITING, i.e. canPop() - // returned false, then even if the producer end has been closed, - // there's still at least one item to drain: wait for it. - if (popped == EMPTY && mClosed) + // Once the queue is DONE, there will never be any more coming. + if (popped == DONE) { LLTHROW(LLThreadSafeQueueInterrupt()); } - // Storage empty, queue still open. Wait for signal. + // If we didn't pop because WAITING, i.e. canPop() returned false, + // then even if the producer end has been closed, there's still at + // least one item to drain: wait for it. Or we might be EMPTY, with + // the queue still open. Either way, wait for signal. mEmptyCond.wait(lock1); } } @@ -448,8 +448,8 @@ bool LLThreadSafeQueue::tryPop(ElementT & element) return tryLock( [this, &element](lock_t& lock) { - // no need to check mClosed: tryPop() behavior when the queue is - // closed is implemented by simple inability to push any new + // conflate EMPTY, DONE, WAITING: tryPop() behavior when the queue + // is closed is implemented by simple inability to push any new // elements return pop_(lock, element) == POPPED; }); @@ -478,7 +478,8 @@ bool LLThreadSafeQueue::tryPopUntil( until, [this, until, &element](lock_t& lock) { - return tryPopUntil_(lock, until, element); + // conflate EMPTY, DONE, WAITING + return tryPopUntil_(lock, until, element) == POPPED; }); } @@ -486,26 +487,28 @@ bool LLThreadSafeQueue::tryPopUntil( // body of tryPopUntil(), called once we have the lock template template -bool LLThreadSafeQueue::tryPopUntil_( +typename LLThreadSafeQueue::pop_result +LLThreadSafeQueue::tryPopUntil_( lock_t& lock, const std::chrono::time_point& until, ElementT& element) { while (true) { - if (pop_(lock, element) == POPPED) - return true; - - if (mClosed) + pop_result popped = pop_(lock, element); + if (popped == POPPED || popped == DONE) { - return false; + // If we succeeded, great! If we've drained the last item, so be + // it. Either way, break the loop and tell caller. + return popped; } - // Storage empty. Wait for signal. + // EMPTY or WAITING: wait for signal. if (LLCoros::cv_status::timeout == mEmptyCond.wait_until(lock, until)) { - // timed out -- formally we might recheck both conditions above - return false; + // timed out -- formally we might recheck + // as it is, break loop + return popped; } // If we didn't time out, we were notified for some reason. Loop back // to check. @@ -546,7 +549,7 @@ template bool LLThreadSafeQueue::done() { lock_t lock(mLock); - return mClosed && mStorage.size() == 0; + return mClosed && mStorage.empty(); } #endif diff --git a/indra/llcommon/tests/threadsafeschedule_test.cpp b/indra/llcommon/tests/threadsafeschedule_test.cpp index ec0fa0c928..af67b9f492 100644 --- a/indra/llcommon/tests/threadsafeschedule_test.cpp +++ b/indra/llcommon/tests/threadsafeschedule_test.cpp @@ -47,6 +47,8 @@ namespace tut // the timestamp for each one -- but since we're passing explicit // timestamps, make the queue reorder them. queue.push(Queue::TimeTuple(Queue::Clock::now() + 20ms, "ghi")); + // Given the various push() overloads, you have to match the type + // exactly: conversions are ambiguous. queue.push("abc"s); queue.push(Queue::Clock::now() + 10ms, "def"); queue.close(); @@ -56,9 +58,11 @@ namespace tut ensure_equals("failed to pop second", std::get<0>(entry), "def"s); ensure("queue not closed", queue.isClosed()); ensure("queue prematurely done", ! queue.done()); - entry = queue.pop(); - ensure_equals("failed to pop third", std::get<0>(entry), "ghi"s); - bool popped = queue.tryPop(entry); + std::string s; + bool popped = queue.tryPopFor(1s, s); + ensure("failed to pop third", popped); + ensure_equals("third is wrong", s, "ghi"s); + popped = queue.tryPop(s); ensure("queue not empty", ! popped); ensure("queue not done", queue.done()); } diff --git a/indra/llcommon/threadsafeschedule.h b/indra/llcommon/threadsafeschedule.h index 545c820f53..8ab4311ca1 100644 --- a/indra/llcommon/threadsafeschedule.h +++ b/indra/llcommon/threadsafeschedule.h @@ -73,11 +73,7 @@ namespace LL private: using super = LLThreadSafeQueue>; using lock_t = typename super::lock_t; - using super::pop_; - using super::push_; - using super::mClosed; - using super::mEmptyCond; - using super::mCapacityCond; + using pop_result = typename super::pop_result; public: using TimePoint = ThreadSafeSchedulePrivate::TimePoint; @@ -92,6 +88,11 @@ namespace LL using super::push; /// pass DataTuple with implicit now + // This could be ambiguous for Args with a single type. Unfortunately + // we can't enable_if an individual method with a condition based on + // the *class* template arguments, only on that method's template + // arguments. We could specialize this class for the single-Args case; + // we could minimize redundancy by breaking out a common base class... void push(const DataTuple& tuple) { push(tuple_cons(Clock::now(), tuple)); @@ -103,11 +104,11 @@ namespace LL push(TimeTuple(time, std::forward(args)...)); } - /// individually pass every component except the TimePoint (implies - /// now) -- could be ambiguous if the first specified template - /// parameter type is also TimePoint -- we could try to disambiguate, - /// but a simpler approach would be for the caller to explicitly - /// construct DataTuple and call that overload + /// individually pass every component except the TimePoint (implies now) + // This could be ambiguous if the first specified template parameter + // type is also TimePoint. We could try to disambiguate, but a simpler + // approach would be for the caller to explicitly construct DataTuple + // and call that overload. void push(Args&&... args) { push(Clock::now(), std::forward(args)...); @@ -199,6 +200,10 @@ namespace LL // current time. /// pop DataTuple by value + // It would be great to notice when sizeof...(Args) == 1 and directly + // return the first (only) value, instead of making pop()'s caller + // call std::get<0>(value). See push(DataTuple) remarks for why we + // haven't yet jumped through those hoops. DataTuple pop() { return tuple_cdr(popWithTime()); @@ -224,16 +229,17 @@ namespace LL { // Pick a point suitably far into the future. TimePoint until = TimePoint::clock::now() + std::chrono::hours(24); - if (tryPopUntil_(lock, until, tt)) + pop_result popped = tryPopUntil_(lock, until, tt); + if (popped == super::POPPED) return std::move(tt); - // empty and closed: throw, just as super::pop() does - if (super::mStorage.empty() && super::mClosed) + // DONE: throw, just as super::pop() does + if (popped == super::DONE) { LLTHROW(LLThreadSafeQueueInterrupt()); } - // If not empty, we've still got items to drain. - // If not closed, it's worth waiting for more items. + // WAITING: we've still got items to drain. + // EMPTY: not closed, so it's worth waiting for more items. // Either way, loop back to wait. } } @@ -252,6 +258,16 @@ namespace LL return true; } + /// for when Args has exactly one type + bool tryPop(typename std::tuple_element<1, TimeTuple>::type& value) + { + TimeTuple tt; + if (! super::tryPop(tt)) + return false; + value = std::get<1>(std::move(tt)); + return true; + } + /// tryPopFor() template bool tryPopFor(const std::chrono::duration& timeout, Tuple& tuple) @@ -278,11 +294,12 @@ namespace LL { // Use our time_point_cast to allow for 'until' that's a // time_point type other than TimePoint. - return tryPopUntil_(lock, time_point_cast(until), tuple); + return super::POPPED == + tryPopUntil_(lock, LL::time_point_cast(until), tuple); }); } - bool tryPopUntil_(lock_t& lock, const TimePoint& until, TimeTuple& tuple) + pop_result tryPopUntil_(lock_t& lock, const TimePoint& until, TimeTuple& tuple) { TimePoint adjusted = until; if (! super::mStorage.empty()) @@ -292,7 +309,14 @@ namespace LL adjusted = min(std::get<0>(super::mStorage.front()), adjusted); } // now delegate to base-class tryPopUntil_() - return super::tryPopUntil_(lock, adjusted, tuple); + pop_result popped; + while ((popped = super::tryPopUntil_(lock, adjusted, tuple)) == super::WAITING) + { + // If super::tryPopUntil_() returns WAITING, it means there's + // a head item, but it's not yet time. But it's worth looping + // back to recheck. + } + return popped; } /// tryPopUntil(DataTuple&) @@ -307,6 +331,18 @@ namespace LL return true; } + /// for when Args has exactly one type + template + bool tryPopUntil(const std::chrono::time_point& until, + typename std::tuple_element<1, TimeTuple>::type& value) + { + TimeTuple tt; + if (! tryPopUntil(until, tt)) + return false; + value = std::get<1>(std::move(tt)); + return true; + } + /*------------------------------ etc. ------------------------------*/ // We can't hide items that aren't yet ready because we can't traverse // the underlying priority_queue: it has no iterators, only top(). So -- cgit v1.2.3 From 4c07eaa560c24303126057b7cf43441d87d520e5 Mon Sep 17 00:00:00 2001 From: Dave Houlton Date: Tue, 5 Oct 2021 14:11:29 -0600 Subject: SL-16138 Add timing mark-up to shader fxns --- indra/llrender/llglslshader.cpp | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index 46b9c69faa..2fb3b8257d 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -126,7 +126,6 @@ struct LLGLSLShaderCompareTimeElapsed //static void LLGLSLShader::finishProfile(bool emit_report) { - LL_PROFILE_ZONE_SCOPED sProfileEnabled = false; if (emit_report) @@ -385,6 +384,8 @@ BOOL LLGLSLShader::createShader(std::vector * attributes, U32 varying_count, const char** varyings) { + LL_PROFILE_ZONE_SCOPED; + unloadInternal(); sInstances.insert(this); @@ -589,6 +590,8 @@ void LLGLSLShader::attachObjects(GLhandleARB* objects, S32 count) BOOL LLGLSLShader::mapAttributes(const std::vector * attributes) { + LL_PROFILE_ZONE_SCOPED; + //before linking, make sure reserved attributes always have consistent locations for (U32 i = 0; i < LLShaderMgr::instance()->mReservedAttribs.size(); i++) { @@ -650,6 +653,8 @@ BOOL LLGLSLShader::mapAttributes(const std::vector * attri void LLGLSLShader::mapUniform(GLint index, const vector * uniforms) { + LL_PROFILE_ZONE_SCOPED; + if (index == -1) { return; @@ -771,6 +776,8 @@ void LLGLSLShader::removePermutation(std::string name) GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type) { + LL_PROFILE_ZONE_SCOPED; + if ((type >= GL_SAMPLER_1D_ARB && type <= GL_SAMPLER_2D_RECT_SHADOW_ARB) || type == GL_SAMPLER_2D_MULTISAMPLE) { //this here is a texture @@ -783,7 +790,9 @@ GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type) BOOL LLGLSLShader::mapUniforms(const vector * uniforms) { - BOOL res = TRUE; + LL_PROFILE_ZONE_SCOPED; + + BOOL res = TRUE; mTotalUniformSize = 0; mActiveTextureChannels = 0; @@ -926,6 +935,8 @@ BOOL LLGLSLShader::mapUniforms(const vector * uniforms) BOOL LLGLSLShader::link(BOOL suppress_errors) { + LL_PROFILE_ZONE_SCOPED; + BOOL success = LLShaderMgr::instance()->linkProgramObject(mProgramObject, suppress_errors); if (!success && !suppress_errors) @@ -940,9 +951,10 @@ void LLGLSLShader::bind() { LL_PROFILE_ZONE_SCOPED; + gGL.flush(); + if (sCurBoundShader != mProgramObject) // Don't re-bind current shader { - gGL.flush(); LLVertexBuffer::unbind(); glUseProgramObjectARB(mProgramObject); sCurBoundShader = mProgramObject; @@ -981,6 +993,8 @@ void LLGLSLShader::bindNoShader(void) S32 LLGLSLShader::bindTexture(const std::string &uniform, LLTexture *texture, LLTexUnit::eTextureType mode, LLTexUnit::eTextureColorSpace colorspace) { + LL_PROFILE_ZONE_SCOPED; + S32 channel = 0; channel = getUniformLocation(uniform); @@ -989,6 +1003,8 @@ S32 LLGLSLShader::bindTexture(const std::string &uniform, LLTexture *texture, LL S32 LLGLSLShader::bindTexture(S32 uniform, LLTexture *texture, LLTexUnit::eTextureType mode, LLTexUnit::eTextureColorSpace colorspace) { + LL_PROFILE_ZONE_SCOPED; + if (uniform < 0 || uniform >= (S32)mTexture.size()) { LL_SHADER_UNIFORM_ERRS() << "Uniform out of range: " << uniform << LL_ENDL; @@ -1008,6 +1024,8 @@ S32 LLGLSLShader::bindTexture(S32 uniform, LLTexture *texture, LLTexUnit::eTextu S32 LLGLSLShader::unbindTexture(const std::string &uniform, LLTexUnit::eTextureType mode) { + LL_PROFILE_ZONE_SCOPED; + S32 channel = 0; channel = getUniformLocation(uniform); @@ -1016,6 +1034,8 @@ S32 LLGLSLShader::unbindTexture(const std::string &uniform, LLTexUnit::eTextureT S32 LLGLSLShader::unbindTexture(S32 uniform, LLTexUnit::eTextureType mode) { + LL_PROFILE_ZONE_SCOPED; + if (uniform < 0 || uniform >= (S32)mTexture.size()) { LL_SHADER_UNIFORM_ERRS() << "Uniform out of range: " << uniform << LL_ENDL; @@ -1034,6 +1054,8 @@ S32 LLGLSLShader::unbindTexture(S32 uniform, LLTexUnit::eTextureType mode) S32 LLGLSLShader::enableTexture(S32 uniform, LLTexUnit::eTextureType mode, LLTexUnit::eTextureColorSpace space) { + LL_PROFILE_ZONE_SCOPED; + if (uniform < 0 || uniform >= (S32)mTexture.size()) { LL_SHADER_UNIFORM_ERRS() << "Uniform out of range: " << uniform << LL_ENDL; @@ -1051,6 +1073,8 @@ S32 LLGLSLShader::enableTexture(S32 uniform, LLTexUnit::eTextureType mode, LLTex S32 LLGLSLShader::disableTexture(S32 uniform, LLTexUnit::eTextureType mode, LLTexUnit::eTextureColorSpace space) { + LL_PROFILE_ZONE_SCOPED; + if (uniform < 0 || uniform >= (S32)mTexture.size()) { LL_SHADER_UNIFORM_ERRS() << "Uniform out of range: " << uniform << LL_ENDL; @@ -1341,6 +1365,7 @@ void LLGLSLShader::uniformMatrix3fv(U32 index, U32 count, GLboolean transpose, c void LLGLSLShader::uniformMatrix3x4fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v) { LL_PROFILE_ZONE_SCOPED; + if (mProgramObject) { if (mUniform.size() <= index) @@ -1375,6 +1400,8 @@ void LLGLSLShader::uniformMatrix4fv(U32 index, U32 count, GLboolean transpose, c GLint LLGLSLShader::getUniformLocation(const LLStaticHashedString& uniform) { + LL_PROFILE_ZONE_SCOPED; + GLint ret = -1; if (mProgramObject) { @@ -1399,6 +1426,8 @@ GLint LLGLSLShader::getUniformLocation(const LLStaticHashedString& uniform) GLint LLGLSLShader::getUniformLocation(U32 index) { + LL_PROFILE_ZONE_SCOPED; + GLint ret = -1; if (mProgramObject) { @@ -1411,6 +1440,8 @@ GLint LLGLSLShader::getUniformLocation(U32 index) GLint LLGLSLShader::getAttribLocation(U32 attrib) { + LL_PROFILE_ZONE_SCOPED; + if (attrib < mAttribute.size()) { return mAttribute[attrib]; -- cgit v1.2.3 From 3e99853b2984a40093ff6b504abfcabe065b251b Mon Sep 17 00:00:00 2001 From: Dave Houlton Date: Tue, 5 Oct 2021 15:59:21 -0600 Subject: SL-16138 remove checks for now-mandatory capabilities --- indra/llrender/llgl.cpp | 300 ++++++++++++++++-------------------- indra/llrender/llgl.h | 3 - indra/newview/llappviewer.cpp | 13 -- indra/newview/lldrawpoolsimple.cpp | 24 +-- indra/newview/lldrawpoolsky.cpp | 8 +- indra/newview/llfeaturemanager.cpp | 6 +- indra/newview/llglsandbox.cpp | 5 +- indra/newview/llviewershadermgr.cpp | 11 +- indra/newview/pipeline.cpp | 9 +- indra/newview/pipeline.h | 1 - 10 files changed, 142 insertions(+), 238 deletions(-) diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index 43fedeca64..673f6cb6df 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -434,9 +434,6 @@ LLGLManager::LLGLManager() : mHasMapBufferRange(FALSE), mHasFlushBufferRange(FALSE), mHasPBuffer(FALSE), - mHasShaderObjects(FALSE), - mHasVertexShader(FALSE), - mHasFragmentShader(FALSE), mNumTextureImageUnits(0), mHasOcclusionQuery(FALSE), mHasTimerQuery(FALSE), @@ -775,14 +772,9 @@ bool LLGLManager::initGL() stop_glerror(); - stop_glerror(); - - if (mHasFragmentShader) - { - GLint num_tex_image_units; - glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &num_tex_image_units); - mNumTextureImageUnits = llmin(num_tex_image_units, 32); - } + GLint num_tex_image_units; + glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &num_tex_image_units); + mNumTextureImageUnits = llmin(num_tex_image_units, 32); if (LLRender::sGLCoreProfile) { @@ -975,9 +967,9 @@ void LLGLManager::asLLSD(LLSD& info) info["has_map_buffer_range"] = mHasMapBufferRange; info["has_flush_buffer_range"] = mHasFlushBufferRange; info["has_pbuffer"] = mHasPBuffer; - info["has_shader_objects"] = mHasShaderObjects; - info["has_vertex_shader"] = mHasVertexShader; - info["has_fragment_shader"] = mHasFragmentShader; + info["has_shader_objects"] = std::string("Assumed TRUE"); // was mHasShaderObjects; + info["has_vertex_shader"] = std::string("Assumed TRUE"); // was mHasVertexShader; + info["has_fragment_shader"] = std::string("Assumed TRUE"); // was mHasFragmentShader; info["num_texture_image_units"] = mNumTextureImageUnits; info["has_occlusion_query"] = mHasOcclusionQuery; info["has_timer_query"] = mHasTimerQuery; @@ -1083,9 +1075,6 @@ void LLGLManager::initExtensions() mHasCubeMap = FALSE; mHasOcclusionQuery = FALSE; mHasPointParameters = FALSE; - mHasShaderObjects = FALSE; - mHasVertexShader = FALSE; - mHasFragmentShader = FALSE; mHasTextureRectangle = FALSE; #else // LL_MESA_HEADLESS //important, gGLHExts.mSysExts is uninitialized until after glh_init_extensions is called mHasMultitexture = glh_init_extensions("GL_ARB_multitexture"); @@ -1143,10 +1132,6 @@ void LLGLManager::initExtensions() #if !LL_DARWIN mHasPointParameters = !mIsATI && ExtensionExists("GL_ARB_point_parameters", gGLHExts.mSysExts); #endif - mHasShaderObjects = ExtensionExists("GL_ARB_shader_objects", gGLHExts.mSysExts) && (LLRender::sGLCoreProfile || ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts)); - mHasVertexShader = ExtensionExists("GL_ARB_vertex_program", gGLHExts.mSysExts) && ExtensionExists("GL_ARB_vertex_shader", gGLHExts.mSysExts) - && (LLRender::sGLCoreProfile || ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts)); - mHasFragmentShader = ExtensionExists("GL_ARB_fragment_shader", gGLHExts.mSysExts) && (LLRender::sGLCoreProfile || ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts)); #endif #if LL_LINUX @@ -1169,9 +1154,6 @@ void LLGLManager::initExtensions() mHasCubeMap = FALSE; mHasOcclusionQuery = FALSE; mHasPointParameters = FALSE; - mHasShaderObjects = FALSE; - mHasVertexShader = FALSE; - mHasFragmentShader = FALSE; LL_WARNS("RenderInit") << "GL extension support DISABLED via LL_GL_NOEXT" << LL_ENDL; } else if (getenv("LL_GL_BASICEXT")) /* Flawfinder: ignore */ @@ -1184,9 +1166,6 @@ void LLGLManager::initExtensions() mHasAnisotropic = FALSE; //mHasCubeMap = FALSE; // apparently fatal on Intel 915 & similar //mHasOcclusionQuery = FALSE; // source of many ATI system hangs - mHasShaderObjects = FALSE; - mHasVertexShader = FALSE; - mHasFragmentShader = FALSE; mHasBlendFuncSeparate = FALSE; LL_WARNS("RenderInit") << "GL extension support forced to SIMPLE level via LL_GL_BASICEXT" << LL_ENDL; } @@ -1208,9 +1187,6 @@ void LLGLManager::initExtensions() if (strchr(blacklist,'j')) mHasCubeMap = FALSE;//S // if (strchr(blacklist,'k')) mHasATIVAO = FALSE;//S if (strchr(blacklist,'l')) mHasOcclusionQuery = FALSE; - if (strchr(blacklist,'m')) mHasShaderObjects = FALSE;//S - if (strchr(blacklist,'n')) mHasVertexShader = FALSE;//S - if (strchr(blacklist,'o')) mHasFragmentShader = FALSE;//S if (strchr(blacklist,'p')) mHasPointParameters = FALSE;//S if (strchr(blacklist,'q')) mHasFramebufferObject = FALSE;//S if (strchr(blacklist,'r')) mHasDrawBuffers = FALSE;//S @@ -1257,18 +1233,6 @@ void LLGLManager::initExtensions() { LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_point_parameters" << LL_ENDL; } - if (!mHasShaderObjects) - { - LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_shader_objects" << LL_ENDL; - } - if (!mHasVertexShader) - { - LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_vertex_shader" << LL_ENDL; - } - if (!mHasFragmentShader) - { - LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_fragment_shader" << LL_ENDL; - } if (!mHasBlendFuncSeparate) { LL_INFOS("RenderInit") << "Couldn't initialize GL_EXT_blend_func_separate" << LL_ENDL; @@ -1436,134 +1400,132 @@ void LLGLManager::initExtensions() glPointParameterfARB = (PFNGLPOINTPARAMETERFARBPROC)GLH_EXT_GET_PROC_ADDRESS("glPointParameterfARB"); glPointParameterfvARB = (PFNGLPOINTPARAMETERFVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glPointParameterfvARB"); } - if (mHasShaderObjects) - { - glDeleteObjectARB = (PFNGLDELETEOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDeleteObjectARB"); - glGetHandleARB = (PFNGLGETHANDLEARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetHandleARB"); - glDetachObjectARB = (PFNGLDETACHOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDetachObjectARB"); - glCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glCreateShaderObjectARB"); - glShaderSourceARB = (PFNGLSHADERSOURCEARBPROC) GLH_EXT_GET_PROC_ADDRESS("glShaderSourceARB"); - glCompileShaderARB = (PFNGLCOMPILESHADERARBPROC) GLH_EXT_GET_PROC_ADDRESS("glCompileShaderARB"); - glCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glCreateProgramObjectARB"); - glAttachObjectARB = (PFNGLATTACHOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glAttachObjectARB"); - glLinkProgramARB = (PFNGLLINKPROGRAMARBPROC) GLH_EXT_GET_PROC_ADDRESS("glLinkProgramARB"); - glUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUseProgramObjectARB"); - glValidateProgramARB = (PFNGLVALIDATEPROGRAMARBPROC) GLH_EXT_GET_PROC_ADDRESS("glValidateProgramARB"); - glUniform1fARB = (PFNGLUNIFORM1FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform1fARB"); - glUniform2fARB = (PFNGLUNIFORM2FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform2fARB"); - glUniform3fARB = (PFNGLUNIFORM3FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform3fARB"); - glUniform4fARB = (PFNGLUNIFORM4FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform4fARB"); - glUniform1iARB = (PFNGLUNIFORM1IARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform1iARB"); - glUniform2iARB = (PFNGLUNIFORM2IARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform2iARB"); - glUniform3iARB = (PFNGLUNIFORM3IARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform3iARB"); - glUniform4iARB = (PFNGLUNIFORM4IARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform4iARB"); - glUniform1fvARB = (PFNGLUNIFORM1FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform1fvARB"); - glUniform2fvARB = (PFNGLUNIFORM2FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform2fvARB"); - glUniform3fvARB = (PFNGLUNIFORM3FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform3fvARB"); - glUniform4fvARB = (PFNGLUNIFORM4FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform4fvARB"); - glUniform1ivARB = (PFNGLUNIFORM1IVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform1ivARB"); - glUniform2ivARB = (PFNGLUNIFORM2IVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform2ivARB"); - glUniform3ivARB = (PFNGLUNIFORM3IVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform3ivARB"); - glUniform4ivARB = (PFNGLUNIFORM4IVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform4ivARB"); - glUniformMatrix2fvARB = (PFNGLUNIFORMMATRIX2FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix2fvARB"); - glUniformMatrix3fvARB = (PFNGLUNIFORMMATRIX3FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix3fvARB"); - glUniformMatrix3x4fv = (PFNGLUNIFORMMATRIX3X4FVPROC) GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix3x4fv"); - glUniformMatrix4fvARB = (PFNGLUNIFORMMATRIX4FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix4fvARB"); - glGetObjectParameterfvARB = (PFNGLGETOBJECTPARAMETERFVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetObjectParameterfvARB"); - glGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetObjectParameterivARB"); - glGetInfoLogARB = (PFNGLGETINFOLOGARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetInfoLogARB"); - glGetAttachedObjectsARB = (PFNGLGETATTACHEDOBJECTSARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetAttachedObjectsARB"); - glGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetUniformLocationARB"); - glGetActiveUniformARB = (PFNGLGETACTIVEUNIFORMARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetActiveUniformARB"); - glGetUniformfvARB = (PFNGLGETUNIFORMFVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetUniformfvARB"); - glGetUniformivARB = (PFNGLGETUNIFORMIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetUniformivARB"); - glGetShaderSourceARB = (PFNGLGETSHADERSOURCEARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetShaderSourceARB"); - } - if (mHasVertexShader) - { - LL_INFOS() << "initExtensions() VertexShader-related procs..." << LL_ENDL; - - // nSight doesn't support use of ARB funcs that have been normalized in the API - if (!LLRender::sNsightDebugSupport) - { - glGetAttribLocationARB = (PFNGLGETATTRIBLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetAttribLocationARB"); - glBindAttribLocationARB = (PFNGLBINDATTRIBLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glBindAttribLocationARB"); - } - else - { - glGetAttribLocationARB = (PFNGLGETATTRIBLOCATIONARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetAttribLocation"); - glBindAttribLocationARB = (PFNGLBINDATTRIBLOCATIONARBPROC)GLH_EXT_GET_PROC_ADDRESS("glBindAttribLocation"); - } - - glGetActiveAttribARB = (PFNGLGETACTIVEATTRIBARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetActiveAttribARB"); - glVertexAttrib1dARB = (PFNGLVERTEXATTRIB1DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1dARB"); - glVertexAttrib1dvARB = (PFNGLVERTEXATTRIB1DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1dvARB"); - glVertexAttrib1fARB = (PFNGLVERTEXATTRIB1FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1fARB"); - glVertexAttrib1fvARB = (PFNGLVERTEXATTRIB1FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1fvARB"); - glVertexAttrib1sARB = (PFNGLVERTEXATTRIB1SARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1sARB"); - glVertexAttrib1svARB = (PFNGLVERTEXATTRIB1SVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1svARB"); - glVertexAttrib2dARB = (PFNGLVERTEXATTRIB2DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2dARB"); - glVertexAttrib2dvARB = (PFNGLVERTEXATTRIB2DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2dvARB"); - glVertexAttrib2fARB = (PFNGLVERTEXATTRIB2FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2fARB"); - glVertexAttrib2fvARB = (PFNGLVERTEXATTRIB2FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2fvARB"); - glVertexAttrib2sARB = (PFNGLVERTEXATTRIB2SARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2sARB"); - glVertexAttrib2svARB = (PFNGLVERTEXATTRIB2SVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2svARB"); - glVertexAttrib3dARB = (PFNGLVERTEXATTRIB3DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3dARB"); - glVertexAttrib3dvARB = (PFNGLVERTEXATTRIB3DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3dvARB"); - glVertexAttrib3fARB = (PFNGLVERTEXATTRIB3FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3fARB"); - glVertexAttrib3fvARB = (PFNGLVERTEXATTRIB3FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3fvARB"); - glVertexAttrib3sARB = (PFNGLVERTEXATTRIB3SARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3sARB"); - glVertexAttrib3svARB = (PFNGLVERTEXATTRIB3SVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3svARB"); - glVertexAttrib4nbvARB = (PFNGLVERTEXATTRIB4NBVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nbvARB"); - glVertexAttrib4nivARB = (PFNGLVERTEXATTRIB4NIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nivARB"); - glVertexAttrib4nsvARB = (PFNGLVERTEXATTRIB4NSVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nsvARB"); - glVertexAttrib4nubARB = (PFNGLVERTEXATTRIB4NUBARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nubARB"); - glVertexAttrib4nubvARB = (PFNGLVERTEXATTRIB4NUBVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nubvARB"); - glVertexAttrib4nuivARB = (PFNGLVERTEXATTRIB4NUIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nuivARB"); - glVertexAttrib4nusvARB = (PFNGLVERTEXATTRIB4NUSVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nusvARB"); - glVertexAttrib4bvARB = (PFNGLVERTEXATTRIB4BVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4bvARB"); - glVertexAttrib4dARB = (PFNGLVERTEXATTRIB4DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4dARB"); - glVertexAttrib4dvARB = (PFNGLVERTEXATTRIB4DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4dvARB"); - glVertexAttrib4fARB = (PFNGLVERTEXATTRIB4FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4fARB"); - glVertexAttrib4fvARB = (PFNGLVERTEXATTRIB4FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4fvARB"); - glVertexAttrib4ivARB = (PFNGLVERTEXATTRIB4IVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4ivARB"); - glVertexAttrib4sARB = (PFNGLVERTEXATTRIB4SARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4sARB"); - glVertexAttrib4svARB = (PFNGLVERTEXATTRIB4SVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4svARB"); - glVertexAttrib4ubvARB = (PFNGLVERTEXATTRIB4UBVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4ubvARB"); - glVertexAttrib4uivARB = (PFNGLVERTEXATTRIB4UIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4uivARB"); - glVertexAttrib4usvARB = (PFNGLVERTEXATTRIB4USVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4usvARB"); - glVertexAttribPointerARB = (PFNGLVERTEXATTRIBPOINTERARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttribPointerARB"); - glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttribIPointer"); - glEnableVertexAttribArrayARB = (PFNGLENABLEVERTEXATTRIBARRAYARBPROC) GLH_EXT_GET_PROC_ADDRESS("glEnableVertexAttribArrayARB"); - glDisableVertexAttribArrayARB = (PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDisableVertexAttribArrayARB"); - glProgramStringARB = (PFNGLPROGRAMSTRINGARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramStringARB"); - glBindProgramARB = (PFNGLBINDPROGRAMARBPROC) GLH_EXT_GET_PROC_ADDRESS("glBindProgramARB"); - glDeleteProgramsARB = (PFNGLDELETEPROGRAMSARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDeleteProgramsARB"); - glGenProgramsARB = (PFNGLGENPROGRAMSARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGenProgramsARB"); - glProgramEnvParameter4dARB = (PFNGLPROGRAMENVPARAMETER4DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramEnvParameter4dARB"); - glProgramEnvParameter4dvARB = (PFNGLPROGRAMENVPARAMETER4DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramEnvParameter4dvARB"); - glProgramEnvParameter4fARB = (PFNGLPROGRAMENVPARAMETER4FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramEnvParameter4fARB"); - glProgramEnvParameter4fvARB = (PFNGLPROGRAMENVPARAMETER4FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramEnvParameter4fvARB"); - glProgramLocalParameter4dARB = (PFNGLPROGRAMLOCALPARAMETER4DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramLocalParameter4dARB"); - glProgramLocalParameter4dvARB = (PFNGLPROGRAMLOCALPARAMETER4DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramLocalParameter4dvARB"); - glProgramLocalParameter4fARB = (PFNGLPROGRAMLOCALPARAMETER4FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramLocalParameter4fARB"); - glProgramLocalParameter4fvARB = (PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramLocalParameter4fvARB"); - glGetProgramEnvParameterdvARB = (PFNGLGETPROGRAMENVPARAMETERDVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramEnvParameterdvARB"); - glGetProgramEnvParameterfvARB = (PFNGLGETPROGRAMENVPARAMETERFVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramEnvParameterfvARB"); - glGetProgramLocalParameterdvARB = (PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramLocalParameterdvARB"); - glGetProgramLocalParameterfvARB = (PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramLocalParameterfvARB"); - glGetProgramivARB = (PFNGLGETPROGRAMIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramivARB"); - glGetProgramStringARB = (PFNGLGETPROGRAMSTRINGARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramStringARB"); - glGetVertexAttribdvARB = (PFNGLGETVERTEXATTRIBDVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetVertexAttribdvARB"); - glGetVertexAttribfvARB = (PFNGLGETVERTEXATTRIBFVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetVertexAttribfvARB"); - glGetVertexAttribivARB = (PFNGLGETVERTEXATTRIBIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetVertexAttribivARB"); - glGetVertexAttribPointervARB = (PFNGLGETVERTEXATTRIBPOINTERVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glgetVertexAttribPointervARB"); - glIsProgramARB = (PFNGLISPROGRAMARBPROC) GLH_EXT_GET_PROC_ADDRESS("glIsProgramARB"); - } - LL_DEBUGS("RenderInit") << "GL Probe: Got symbols" << LL_ENDL; + + // Assume shader capabilities + glDeleteObjectARB = (PFNGLDELETEOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDeleteObjectARB"); + glGetHandleARB = (PFNGLGETHANDLEARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetHandleARB"); + glDetachObjectARB = (PFNGLDETACHOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDetachObjectARB"); + glCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glCreateShaderObjectARB"); + glShaderSourceARB = (PFNGLSHADERSOURCEARBPROC) GLH_EXT_GET_PROC_ADDRESS("glShaderSourceARB"); + glCompileShaderARB = (PFNGLCOMPILESHADERARBPROC) GLH_EXT_GET_PROC_ADDRESS("glCompileShaderARB"); + glCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glCreateProgramObjectARB"); + glAttachObjectARB = (PFNGLATTACHOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glAttachObjectARB"); + glLinkProgramARB = (PFNGLLINKPROGRAMARBPROC) GLH_EXT_GET_PROC_ADDRESS("glLinkProgramARB"); + glUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUseProgramObjectARB"); + glValidateProgramARB = (PFNGLVALIDATEPROGRAMARBPROC) GLH_EXT_GET_PROC_ADDRESS("glValidateProgramARB"); + glUniform1fARB = (PFNGLUNIFORM1FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform1fARB"); + glUniform2fARB = (PFNGLUNIFORM2FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform2fARB"); + glUniform3fARB = (PFNGLUNIFORM3FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform3fARB"); + glUniform4fARB = (PFNGLUNIFORM4FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform4fARB"); + glUniform1iARB = (PFNGLUNIFORM1IARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform1iARB"); + glUniform2iARB = (PFNGLUNIFORM2IARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform2iARB"); + glUniform3iARB = (PFNGLUNIFORM3IARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform3iARB"); + glUniform4iARB = (PFNGLUNIFORM4IARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform4iARB"); + glUniform1fvARB = (PFNGLUNIFORM1FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform1fvARB"); + glUniform2fvARB = (PFNGLUNIFORM2FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform2fvARB"); + glUniform3fvARB = (PFNGLUNIFORM3FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform3fvARB"); + glUniform4fvARB = (PFNGLUNIFORM4FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform4fvARB"); + glUniform1ivARB = (PFNGLUNIFORM1IVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform1ivARB"); + glUniform2ivARB = (PFNGLUNIFORM2IVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform2ivARB"); + glUniform3ivARB = (PFNGLUNIFORM3IVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform3ivARB"); + glUniform4ivARB = (PFNGLUNIFORM4IVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform4ivARB"); + glUniformMatrix2fvARB = (PFNGLUNIFORMMATRIX2FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix2fvARB"); + glUniformMatrix3fvARB = (PFNGLUNIFORMMATRIX3FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix3fvARB"); + glUniformMatrix3x4fv = (PFNGLUNIFORMMATRIX3X4FVPROC) GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix3x4fv"); + glUniformMatrix4fvARB = (PFNGLUNIFORMMATRIX4FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix4fvARB"); + glGetObjectParameterfvARB = (PFNGLGETOBJECTPARAMETERFVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetObjectParameterfvARB"); + glGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetObjectParameterivARB"); + glGetInfoLogARB = (PFNGLGETINFOLOGARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetInfoLogARB"); + glGetAttachedObjectsARB = (PFNGLGETATTACHEDOBJECTSARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetAttachedObjectsARB"); + glGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetUniformLocationARB"); + glGetActiveUniformARB = (PFNGLGETACTIVEUNIFORMARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetActiveUniformARB"); + glGetUniformfvARB = (PFNGLGETUNIFORMFVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetUniformfvARB"); + glGetUniformivARB = (PFNGLGETUNIFORMIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetUniformivARB"); + glGetShaderSourceARB = (PFNGLGETSHADERSOURCEARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetShaderSourceARB"); + + LL_INFOS() << "initExtensions() VertexShader-related procs..." << LL_ENDL; + + // nSight doesn't support use of ARB funcs that have been normalized in the API + if (!LLRender::sNsightDebugSupport) + { + glGetAttribLocationARB = (PFNGLGETATTRIBLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetAttribLocationARB"); + glBindAttribLocationARB = (PFNGLBINDATTRIBLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glBindAttribLocationARB"); + } + else + { + glGetAttribLocationARB = (PFNGLGETATTRIBLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetAttribLocation"); + glBindAttribLocationARB = (PFNGLBINDATTRIBLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glBindAttribLocation"); + } + + glGetActiveAttribARB = (PFNGLGETACTIVEATTRIBARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetActiveAttribARB"); + glVertexAttrib1dARB = (PFNGLVERTEXATTRIB1DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1dARB"); + glVertexAttrib1dvARB = (PFNGLVERTEXATTRIB1DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1dvARB"); + glVertexAttrib1fARB = (PFNGLVERTEXATTRIB1FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1fARB"); + glVertexAttrib1fvARB = (PFNGLVERTEXATTRIB1FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1fvARB"); + glVertexAttrib1sARB = (PFNGLVERTEXATTRIB1SARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1sARB"); + glVertexAttrib1svARB = (PFNGLVERTEXATTRIB1SVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1svARB"); + glVertexAttrib2dARB = (PFNGLVERTEXATTRIB2DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2dARB"); + glVertexAttrib2dvARB = (PFNGLVERTEXATTRIB2DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2dvARB"); + glVertexAttrib2fARB = (PFNGLVERTEXATTRIB2FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2fARB"); + glVertexAttrib2fvARB = (PFNGLVERTEXATTRIB2FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2fvARB"); + glVertexAttrib2sARB = (PFNGLVERTEXATTRIB2SARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2sARB"); + glVertexAttrib2svARB = (PFNGLVERTEXATTRIB2SVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2svARB"); + glVertexAttrib3dARB = (PFNGLVERTEXATTRIB3DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3dARB"); + glVertexAttrib3dvARB = (PFNGLVERTEXATTRIB3DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3dvARB"); + glVertexAttrib3fARB = (PFNGLVERTEXATTRIB3FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3fARB"); + glVertexAttrib3fvARB = (PFNGLVERTEXATTRIB3FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3fvARB"); + glVertexAttrib3sARB = (PFNGLVERTEXATTRIB3SARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3sARB"); + glVertexAttrib3svARB = (PFNGLVERTEXATTRIB3SVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3svARB"); + glVertexAttrib4nbvARB = (PFNGLVERTEXATTRIB4NBVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nbvARB"); + glVertexAttrib4nivARB = (PFNGLVERTEXATTRIB4NIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nivARB"); + glVertexAttrib4nsvARB = (PFNGLVERTEXATTRIB4NSVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nsvARB"); + glVertexAttrib4nubARB = (PFNGLVERTEXATTRIB4NUBARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nubARB"); + glVertexAttrib4nubvARB = (PFNGLVERTEXATTRIB4NUBVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nubvARB"); + glVertexAttrib4nuivARB = (PFNGLVERTEXATTRIB4NUIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nuivARB"); + glVertexAttrib4nusvARB = (PFNGLVERTEXATTRIB4NUSVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nusvARB"); + glVertexAttrib4bvARB = (PFNGLVERTEXATTRIB4BVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4bvARB"); + glVertexAttrib4dARB = (PFNGLVERTEXATTRIB4DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4dARB"); + glVertexAttrib4dvARB = (PFNGLVERTEXATTRIB4DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4dvARB"); + glVertexAttrib4fARB = (PFNGLVERTEXATTRIB4FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4fARB"); + glVertexAttrib4fvARB = (PFNGLVERTEXATTRIB4FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4fvARB"); + glVertexAttrib4ivARB = (PFNGLVERTEXATTRIB4IVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4ivARB"); + glVertexAttrib4sARB = (PFNGLVERTEXATTRIB4SARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4sARB"); + glVertexAttrib4svARB = (PFNGLVERTEXATTRIB4SVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4svARB"); + glVertexAttrib4ubvARB = (PFNGLVERTEXATTRIB4UBVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4ubvARB"); + glVertexAttrib4uivARB = (PFNGLVERTEXATTRIB4UIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4uivARB"); + glVertexAttrib4usvARB = (PFNGLVERTEXATTRIB4USVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4usvARB"); + glVertexAttribPointerARB = (PFNGLVERTEXATTRIBPOINTERARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttribPointerARB"); + glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttribIPointer"); + glEnableVertexAttribArrayARB = (PFNGLENABLEVERTEXATTRIBARRAYARBPROC) GLH_EXT_GET_PROC_ADDRESS("glEnableVertexAttribArrayARB"); + glDisableVertexAttribArrayARB = (PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDisableVertexAttribArrayARB"); + glProgramStringARB = (PFNGLPROGRAMSTRINGARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramStringARB"); + glBindProgramARB = (PFNGLBINDPROGRAMARBPROC) GLH_EXT_GET_PROC_ADDRESS("glBindProgramARB"); + glDeleteProgramsARB = (PFNGLDELETEPROGRAMSARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDeleteProgramsARB"); + glGenProgramsARB = (PFNGLGENPROGRAMSARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGenProgramsARB"); + glProgramEnvParameter4dARB = (PFNGLPROGRAMENVPARAMETER4DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramEnvParameter4dARB"); + glProgramEnvParameter4dvARB = (PFNGLPROGRAMENVPARAMETER4DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramEnvParameter4dvARB"); + glProgramEnvParameter4fARB = (PFNGLPROGRAMENVPARAMETER4FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramEnvParameter4fARB"); + glProgramEnvParameter4fvARB = (PFNGLPROGRAMENVPARAMETER4FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramEnvParameter4fvARB"); + glProgramLocalParameter4dARB = (PFNGLPROGRAMLOCALPARAMETER4DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramLocalParameter4dARB"); + glProgramLocalParameter4dvARB = (PFNGLPROGRAMLOCALPARAMETER4DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramLocalParameter4dvARB"); + glProgramLocalParameter4fARB = (PFNGLPROGRAMLOCALPARAMETER4FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramLocalParameter4fARB"); + glProgramLocalParameter4fvARB = (PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramLocalParameter4fvARB"); + glGetProgramEnvParameterdvARB = (PFNGLGETPROGRAMENVPARAMETERDVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramEnvParameterdvARB"); + glGetProgramEnvParameterfvARB = (PFNGLGETPROGRAMENVPARAMETERFVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramEnvParameterfvARB"); + glGetProgramLocalParameterdvARB = (PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramLocalParameterdvARB"); + glGetProgramLocalParameterfvARB = (PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramLocalParameterfvARB"); + glGetProgramivARB = (PFNGLGETPROGRAMIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramivARB"); + glGetProgramStringARB = (PFNGLGETPROGRAMSTRINGARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramStringARB"); + glGetVertexAttribdvARB = (PFNGLGETVERTEXATTRIBDVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetVertexAttribdvARB"); + glGetVertexAttribfvARB = (PFNGLGETVERTEXATTRIBFVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetVertexAttribfvARB"); + glGetVertexAttribivARB = (PFNGLGETVERTEXATTRIBIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetVertexAttribivARB"); + glGetVertexAttribPointervARB = (PFNGLGETVERTEXATTRIBPOINTERVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glgetVertexAttribPointervARB"); + glIsProgramARB = (PFNGLISPROGRAMARBPROC) GLH_EXT_GET_PROC_ADDRESS("glIsProgramARB"); + + LL_DEBUGS("RenderInit") << "GL Probe: Got symbols" << LL_ENDL; #endif - mInited = TRUE; + mInited = TRUE; } void rotate_quat(LLQuaternion& rotation) @@ -2116,7 +2078,7 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask) glClientActiveTextureARB(GL_TEXTURE0_ARB); gGL.getTexUnit(0)->activate(); - if (gGLManager.mHasVertexShader && LLGLSLShader::sNoFixedFunction) + if (LLGLSLShader::sNoFixedFunction) { //make sure vertex attribs are all disabled GLint count; glGetIntegerv(GL_MAX_VERTEX_ATTRIBS_ARB, &count); diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h index a07e2d9bb0..a03d5352be 100644 --- a/indra/llrender/llgl.h +++ b/indra/llrender/llgl.h @@ -94,9 +94,6 @@ public: BOOL mHasMapBufferRange; BOOL mHasFlushBufferRange; BOOL mHasPBuffer; - BOOL mHasShaderObjects; - BOOL mHasVertexShader; - BOOL mHasFragmentShader; S32 mNumTextureImageUnits; BOOL mHasOcclusionQuery; BOOL mHasTimerQuery; diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 3d49a9eb78..98409106a1 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1010,19 +1010,6 @@ bool LLAppViewer::init() return 0; } - // If we don't have the right shader requirements. - if (!gGLManager.mHasShaderObjects - || !gGLManager.mHasVertexShader - || !gGLManager.mHasFragmentShader) - { - LLUIString details = LLNotifications::instance().getGlobalString("UnsupportedShaderRequirements"); - OSMessageBox( - details.getString(), - LLStringUtil::null, - OSMB_OK); - return 0; - } - // Without SSE2 support we will crash almost immediately, warn here. if (!gSysCPU.hasSSE2()) { diff --git a/indra/newview/lldrawpoolsimple.cpp b/indra/newview/lldrawpoolsimple.cpp index f211cf6e27..74e6665a96 100644 --- a/indra/newview/lldrawpoolsimple.cpp +++ b/indra/newview/lldrawpoolsimple.cpp @@ -199,11 +199,7 @@ void LLDrawPoolSimple::beginRenderPass(S32 pass) } else { - // don't use shaders! - if (gGLManager.mHasShaderObjects) - { - LLGLSLShader::bindNoShader(); - } + LLGLSLShader::bindNoShader(); } } @@ -301,11 +297,7 @@ void LLDrawPoolAlphaMask::beginRenderPass(S32 pass) } else { - // don't use shaders! - if (gGLManager.mHasShaderObjects) - { - LLGLSLShader::bindNoShader(); - } + LLGLSLShader::bindNoShader(); } } @@ -392,11 +384,7 @@ void LLDrawPoolFullbrightAlphaMask::beginRenderPass(S32 pass) } else { - // don't use shaders! - if (gGLManager.mHasShaderObjects) - { - LLGLSLShader::bindNoShader(); - } + LLGLSLShader::bindNoShader(); } } @@ -567,11 +555,7 @@ void LLDrawPoolGrass::beginRenderPass(S32 pass) else { gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); - // don't use shaders! - if (gGLManager.mHasShaderObjects) - { - LLGLSLShader::bindNoShader(); - } + LLGLSLShader::bindNoShader(); } } diff --git a/indra/newview/lldrawpoolsky.cpp b/indra/newview/lldrawpoolsky.cpp index b6f55e800a..b1eefaab81 100644 --- a/indra/newview/lldrawpoolsky.cpp +++ b/indra/newview/lldrawpoolsky.cpp @@ -82,13 +82,7 @@ void LLDrawPoolSky::render(S32 pass) } else { - // don't use shaders! - if (gGLManager.mHasShaderObjects) - { - // Ironically, we must support shader objects to be - // able to use this call. - LLGLSLShader::bindNoShader(); - } + LLGLSLShader::bindNoShader(); mShader = NULL; } diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp index e6bbe234b3..98c8531cd6 100644 --- a/indra/newview/llfeaturemanager.cpp +++ b/indra/newview/llfeaturemanager.cpp @@ -670,11 +670,7 @@ void LLFeatureManager::applyBaseMasks() } // now all those wacky ones - if (!gGLManager.mHasFragmentShader) - { - maskFeatures("NoPixelShaders"); - } - if (!gGLManager.mHasVertexShader || !mGPUSupported) + if (!mGPUSupported) { maskFeatures("NoVertexShaders"); } diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp index 698c15bd2d..0f288e05ca 100644 --- a/indra/newview/llglsandbox.cpp +++ b/indra/newview/llglsandbox.cpp @@ -993,9 +993,8 @@ private: //----------------------------------------------------------------------------- F32 gpu_benchmark() { - if (!gGLManager.mHasShaderObjects || !gGLManager.mHasTimerQuery) - { // don't bother benchmarking the fixed function - // or venerable drivers which don't support accurate timing anyway + if (!gGLManager.mHasTimerQuery) + { // don't bother benchmarking venerable drivers which don't support accurate timing anyway // and are likely to be correctly identified by the GPU table already. return -1.f; } diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index be5c22e7c3..7dcf29eb75 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -384,7 +384,7 @@ void LLViewerShaderMgr::initAttribsAndUniforms(void) S32 LLViewerShaderMgr::getShaderLevel(S32 type) { - return LLPipeline::sDisableShaders ? 0 : mShaderLevel[type]; + return mShaderLevel[type]; } //============================================================================ @@ -400,15 +400,6 @@ void LLViewerShaderMgr::setShaders() return; } - if (!gGLManager.mHasShaderObjects - || !gGLManager.mHasVertexShader - || !gGLManager.mHasFragmentShader) - { - // Viewer will show 'hardware requirements' warning later - LL_INFOS("ShaderLoading") << "Shaders not supported" << LL_ENDL; - return; - } - static LLCachedControl max_texture_index(gSavedSettings, "RenderMaxTextureIndex", 16); LLGLSLShader::sIndexedTextureChannels = llmax(llmin(gGLManager.mNumTextureImageUnits, (S32) max_texture_index), 1); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index d7acf2ec0e..c0b469af81 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -338,7 +338,6 @@ S32 LLPipeline::sUseOcclusion = 0; bool LLPipeline::sDelayVBUpdate = true; bool LLPipeline::sAutoMaskAlphaDeferred = true; bool LLPipeline::sAutoMaskAlphaNonDeferred = false; -bool LLPipeline::sDisableShaders = false; bool LLPipeline::sRenderTransparentWater = true; bool LLPipeline::sRenderBump = true; bool LLPipeline::sBakeSunlight = false; @@ -1393,10 +1392,7 @@ void LLPipeline::restoreGL() bool LLPipeline::canUseVertexShaders() { - if (sDisableShaders || - !gGLManager.mHasVertexShader || - !gGLManager.mHasFragmentShader || - (assertInitialized() && mVertexShadersLoaded != 1) ) + if ((assertInitialized() && mVertexShadersLoaded != 1) ) { return false; } @@ -1408,8 +1404,7 @@ bool LLPipeline::canUseVertexShaders() bool LLPipeline::canUseWindLightShaders() const { - return (!LLPipeline::sDisableShaders && - gWLSkyProgram.mProgramObject != 0 && + return (gWLSkyProgram.mProgramObject != 0 && LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1); } diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 0eaa6b141d..5605d26410 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -574,7 +574,6 @@ public: static bool sDelayVBUpdate; static bool sAutoMaskAlphaDeferred; static bool sAutoMaskAlphaNonDeferred; - static bool sDisableShaders; // if true, rendering will be done without shaders static bool sRenderTransparentWater; static bool sRenderBump; static bool sBakeSunlight; -- cgit v1.2.3 From 1ef78e2afa9e8424dd5d84b2b104b31e72e9e95a Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 6 Oct 2021 15:28:58 -0400 Subject: SL-16024: Work around VS bug regarding base-class enum. --- indra/llcommon/threadsafeschedule.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/indra/llcommon/threadsafeschedule.h b/indra/llcommon/threadsafeschedule.h index 8ab4311ca1..0e70d30714 100644 --- a/indra/llcommon/threadsafeschedule.h +++ b/indra/llcommon/threadsafeschedule.h @@ -73,7 +73,9 @@ namespace LL private: using super = LLThreadSafeQueue>; using lock_t = typename super::lock_t; - using pop_result = typename super::pop_result; + // VS 2017 needs this due to a bug: + // https://developercommunity.visualstudio.com/t/cannot-access-protected-enumerator-of-enclosing-cl/203430 + enum pop_result { EMPTY=super::EMPTY, DONE=super::DONE, WAITING=super::WAITING, POPPED=super::POPPED }; public: using TimePoint = ThreadSafeSchedulePrivate::TimePoint; @@ -230,11 +232,11 @@ namespace LL // Pick a point suitably far into the future. TimePoint until = TimePoint::clock::now() + std::chrono::hours(24); pop_result popped = tryPopUntil_(lock, until, tt); - if (popped == super::POPPED) + if (popped == POPPED) return std::move(tt); // DONE: throw, just as super::pop() does - if (popped == super::DONE) + if (popped == DONE) { LLTHROW(LLThreadSafeQueueInterrupt()); } @@ -294,7 +296,7 @@ namespace LL { // Use our time_point_cast to allow for 'until' that's a // time_point type other than TimePoint. - return super::POPPED == + return POPPED == tryPopUntil_(lock, LL::time_point_cast(until), tuple); }); } @@ -310,7 +312,7 @@ namespace LL } // now delegate to base-class tryPopUntil_() pop_result popped; - while ((popped = super::tryPopUntil_(lock, adjusted, tuple)) == super::WAITING) + while ((popped = pop_result(super::tryPopUntil_(lock, adjusted, tuple))) == WAITING) { // If super::tryPopUntil_() returns WAITING, it means there's // a head item, but it's not yet time. But it's worth looping -- cgit v1.2.3 From 2cb09dd4a828756dce6180505c63851aa9875187 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 7 Oct 2021 11:53:45 -0400 Subject: SL-16024: Return shared_ptr from LLInstanceTracker::getInstance(). It feels wrong to return a dumb LLInstanceTracker subclass* from getInstance() when we use std::shared_ptr and std::weak_ptr internally. But tweak consumers to use 'auto' or LLInstanceTracker::ptr_t in case we later revisit this decision. We did add a couple get() calls where it's important to obtain a dumb pointer. --- indra/llcommon/llinstancetracker.h | 59 ++++++++++++++++++++-------- indra/llcommon/llleaplistener.cpp | 2 +- indra/llui/llnotifications.cpp | 2 +- indra/llui/llstatbar.cpp | 20 ++++------ indra/llxml/llcontrol.h | 8 ++-- indra/newview/llappviewer.cpp | 4 +- indra/newview/llbrowsernotification.cpp | 4 +- indra/newview/llfloaterwebcontent.cpp | 4 +- indra/newview/llnotificationofferhandler.cpp | 4 +- indra/newview/llviewercontrollistener.cpp | 8 ++-- indra/newview/llviewermessage.cpp | 4 +- 11 files changed, 71 insertions(+), 48 deletions(-) diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h index 402333cca7..02535a59e7 100644 --- a/indra/llcommon/llinstancetracker.h +++ b/indra/llcommon/llinstancetracker.h @@ -83,13 +83,34 @@ class LLInstanceTracker typedef llthread::LockStatic LockStatic; public: + using ptr_t = std::shared_ptr; + using weak_t = std::weak_ptr; + + /** + * Storing a dumb T* somewhere external is a bad idea, since + * LLInstanceTracker subclasses are explicitly destroyed rather than + * managed by smart pointers. It's legal to declare stack instances of an + * LLInstanceTracker subclass. But it's reasonable to store a + * std::weak_ptr, which will become invalid when the T instance is + * destroyed. + */ + weak_t getWeak() + { + return mSelf; + } + + static S32 instanceCount() + { + return LockStatic()->mMap.size(); + } + // snapshot of std::pair> pairs class snapshot { // It's very important that what we store in this snapshot are // weak_ptrs, NOT shared_ptrs. That's how we discover whether any // instance has been deleted during the lifespan of a snapshot. - typedef std::vector>> VectorType; + typedef std::vector> VectorType; // Dereferencing our iterator produces a std::shared_ptr for each // instance that still exists. Since we store weak_ptrs, that involves // two chained transformations: @@ -98,7 +119,7 @@ public: // It is very important that we filter lazily, that is, during // traversal. Any one of our stored weak_ptrs might expire during // traversal. - typedef std::pair> strong_pair; + typedef std::pair strong_pair; // Note for future reference: nat has not yet had any luck (up to // Boost 1.67) trying to use boost::transform_iterator with a hand- // coded functor, only with actual functions. In my experience, an @@ -202,17 +223,12 @@ public: iterator end() { return iterator(snapshot::end(), key_getter); } }; - static T* getInstance(const KEY& k) + static ptr_t getInstance(const KEY& k) { LockStatic lock; const InstanceMap& map(lock->mMap); typename InstanceMap::const_iterator found = map.find(k); - return (found == map.end()) ? NULL : found->second.get(); - } - - static S32 instanceCount() - { - return LockStatic()->mMap.size(); + return (found == map.end()) ? NULL : found->second; } protected: @@ -222,7 +238,9 @@ protected: // shared_ptr, so give it a no-op deleter. We store shared_ptrs in our // InstanceMap specifically so snapshot can store weak_ptrs so we can // detect deletions during traversals. - std::shared_ptr ptr(static_cast(this), [](T*){}); + ptr_t ptr(static_cast(this), [](T*){}); + // save corresponding weak_ptr for future reference + mSelf = ptr; LockStatic lock; add_(lock, key, ptr); } @@ -257,7 +275,7 @@ private: static std::string report(const char* key) { return report(std::string(key)); } // caller must instantiate LockStatic - void add_(LockStatic& lock, const KEY& key, const std::shared_ptr& ptr) + void add_(LockStatic& lock, const KEY& key, const ptr_t& ptr) { mInstanceKey = key; InstanceMap& map = lock->mMap; @@ -281,7 +299,7 @@ private: break; } } - std::shared_ptr remove_(LockStatic& lock) + ptr_t remove_(LockStatic& lock) { InstanceMap& map = lock->mMap; typename InstanceMap::iterator iter = map.find(mInstanceKey); @@ -295,6 +313,9 @@ private: } private: + // Storing a weak_ptr to self is a bit like deriving from + // std::enable_shared_from_this(), except more explicit. + weak_t mSelf; KEY mInstanceKey; }; @@ -326,6 +347,9 @@ class LLInstanceTracker typedef llthread::LockStatic LockStatic; public: + using ptr_t = std::shared_ptr; + using weak_t = std::weak_ptr; + /** * Storing a dumb T* somewhere external is a bad idea, since * LLInstanceTracker subclasses are explicitly destroyed rather than @@ -334,12 +358,15 @@ public: * std::weak_ptr, which will become invalid when the T instance is * destroyed. */ - std::weak_ptr getWeak() + weak_t getWeak() { return mSelf; } - static S32 instanceCount() { return LockStatic()->mSet.size(); } + static S32 instanceCount() + { + return LockStatic()->mSet.size(); + } // snapshot of std::shared_ptr pointers class snapshot @@ -347,7 +374,7 @@ public: // It's very important that what we store in this snapshot are // weak_ptrs, NOT shared_ptrs. That's how we discover whether any // instance has been deleted during the lifespan of a snapshot. - typedef std::vector> VectorType; + typedef std::vector VectorType; // Dereferencing our iterator produces a std::shared_ptr for each // instance that still exists. Since we store weak_ptrs, that involves // two chained transformations: @@ -453,7 +480,7 @@ protected: private: // Storing a weak_ptr to self is a bit like deriving from // std::enable_shared_from_this(), except more explicit. - std::weak_ptr mSelf; + weak_t mSelf; }; #endif diff --git a/indra/llcommon/llleaplistener.cpp b/indra/llcommon/llleaplistener.cpp index 3e6ce9092c..11bfec1b31 100644 --- a/indra/llcommon/llleaplistener.cpp +++ b/indra/llcommon/llleaplistener.cpp @@ -220,7 +220,7 @@ void LLLeapListener::getAPI(const LLSD& request) const { Response reply(LLSD(), request); - LLEventAPI* found = LLEventAPI::getInstance(request["api"]); + auto found = LLEventAPI::getInstance(request["api"]); if (found) { reply["name"] = found->getName(); diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index b791a19c2b..88eda1c172 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -1387,7 +1387,7 @@ bool LLNotifications::failedUniquenessTest(const LLSD& payload) LLNotificationChannelPtr LLNotifications::getChannel(const std::string& channelName) { - return LLNotificationChannelPtr(LLNotificationChannel::getInstance(channelName)); + return LLNotificationChannelPtr(LLNotificationChannel::getInstance(channelName).get()); } diff --git a/indra/llui/llstatbar.cpp b/indra/llui/llstatbar.cpp index 6c8e63442b..8adcd664df 100644 --- a/indra/llui/llstatbar.cpp +++ b/indra/llui/llstatbar.cpp @@ -554,29 +554,25 @@ void LLStatBar::draw() void LLStatBar::setStat(const std::string& stat_name) { using namespace LLTrace; - const StatType* count_stat; - const StatType* event_stat; - const StatType* sample_stat; - const StatType* mem_stat; - if ((count_stat = StatType::getInstance(stat_name))) + if (auto count_stat = StatType::getInstance(stat_name)) { - mStat.countStatp = count_stat; + mStat.countStatp = count_stat.get(); mStatType = STAT_COUNT; } - else if ((event_stat = StatType::getInstance(stat_name))) + else if (auto event_stat = StatType::getInstance(stat_name)) { - mStat.eventStatp = event_stat; + mStat.eventStatp = event_stat.get(); mStatType = STAT_EVENT; } - else if ((sample_stat = StatType::getInstance(stat_name))) + else if (auto sample_stat = StatType::getInstance(stat_name)) { - mStat.sampleStatp = sample_stat; + mStat.sampleStatp = sample_stat.get(); mStatType = STAT_SAMPLE; } - else if ((mem_stat = StatType::getInstance(stat_name))) + else if (auto mem_stat = StatType::getInstance(stat_name)) { - mStat.memStatp = mem_stat; + mStat.memStatp = mem_stat.get(); mStatType = STAT_MEM; } } diff --git a/indra/llxml/llcontrol.h b/indra/llxml/llcontrol.h index 19508becc3..5da13f5010 100644 --- a/indra/llxml/llcontrol.h +++ b/indra/llxml/llcontrol.h @@ -405,8 +405,8 @@ public: const T& default_value, const std::string& comment = "Declared In Code") { - mCachedControlPtr = LLControlCache::getInstance(name); - if (mCachedControlPtr.isNull()) + mCachedControlPtr = LLControlCache::getInstance(name).get(); + if (! mCachedControlPtr) { mCachedControlPtr = new LLControlCache(group, name, default_value, comment); } @@ -415,8 +415,8 @@ public: LLCachedControl(LLControlGroup& group, const std::string& name) { - mCachedControlPtr = LLControlCache::getInstance(name); - if (mCachedControlPtr.isNull()) + mCachedControlPtr = LLControlCache::getInstance(name).get(); + if (! mCachedControlPtr) { mCachedControlPtr = new LLControlCache(group, name); } diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 891722e1bd..4a9a1ad0d4 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -2336,7 +2336,7 @@ bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key, LL_INFOS("Settings") << "Attempting to load settings for the group " << file.name() << " - from location " << location_key << LL_ENDL; - LLControlGroup* settings_group = LLControlGroup::getInstance(file.name); + auto settings_group = LLControlGroup::getInstance(file.name); if(!settings_group) { LL_WARNS("Settings") << "No matching settings group for name " << file.name() << LL_ENDL; @@ -2638,7 +2638,7 @@ bool LLAppViewer::initConfiguration() group_part = name.substr(0, pos); name_part = name.substr(pos+1); LL_INFOS() << "Setting " << group_part << "." << name_part << " to " << value << LL_ENDL; - LLControlGroup* g = LLControlGroup::getInstance(group_part); + auto g = LLControlGroup::getInstance(group_part); if (g) control = g->getControl(name_part); } else diff --git a/indra/newview/llbrowsernotification.cpp b/indra/newview/llbrowsernotification.cpp index 0460bff1b4..30ac35fff7 100644 --- a/indra/newview/llbrowsernotification.cpp +++ b/indra/newview/llbrowsernotification.cpp @@ -43,14 +43,14 @@ LLBrowserNotification::LLBrowserNotification() bool LLBrowserNotification::processNotification(const LLNotificationPtr& notification) { LLUUID media_id = notification->getPayload()["media_id"].asUUID(); - LLMediaCtrl* media_instance = LLMediaCtrl::getInstance(media_id); + auto media_instance = LLMediaCtrl::getInstance(media_id); if (media_instance) { media_instance->showNotification(notification); } else if (LLViewerMediaFocus::instance().getControlsMediaID() == media_id) { - LLViewerMediaImpl* impl = LLViewerMedia::getInstance()->getMediaImplFromTextureID(media_id); + auto impl = LLViewerMedia::getInstance()->getMediaImplFromTextureID(media_id); if (impl) { impl->showNotification(notification); diff --git a/indra/newview/llfloaterwebcontent.cpp b/indra/newview/llfloaterwebcontent.cpp index 23fd6d9c8e..ceab472c55 100644 --- a/indra/newview/llfloaterwebcontent.cpp +++ b/indra/newview/llfloaterwebcontent.cpp @@ -159,7 +159,7 @@ LLFloater* LLFloaterWebContent::create( Params p) //static void LLFloaterWebContent::closeRequest(const std::string &uuid) { - LLFloaterWebContent* floaterp = instance_tracker_t::getInstance(uuid); + auto floaterp = instance_tracker_t::getInstance(uuid); if (floaterp) { floaterp->closeFloater(false); @@ -169,7 +169,7 @@ void LLFloaterWebContent::closeRequest(const std::string &uuid) //static void LLFloaterWebContent::geometryChanged(const std::string &uuid, S32 x, S32 y, S32 width, S32 height) { - LLFloaterWebContent* floaterp = instance_tracker_t::getInstance(uuid); + auto floaterp = instance_tracker_t::getInstance(uuid); if (floaterp) { floaterp->geometryChanged(x, y, width, height); diff --git a/indra/newview/llnotificationofferhandler.cpp b/indra/newview/llnotificationofferhandler.cpp index a9678b1e93..d9359d20cf 100644 --- a/indra/newview/llnotificationofferhandler.cpp +++ b/indra/newview/llnotificationofferhandler.cpp @@ -166,14 +166,14 @@ bool LLOfferHandler::processNotification(const LLNotificationPtr& notification) /*virtual*/ void LLOfferHandler::onChange(LLNotificationPtr p) { - LLToastNotifyPanel* panelp = LLToastNotifyPanel::getInstance(p->getID()); + auto panelp = LLToastNotifyPanel::getInstance(p->getID()); if (panelp) { // // HACK: if we're dealing with a notification embedded in IM, update it // otherwise remove its toast // - if (dynamic_cast(panelp)) + if (dynamic_cast(panelp.get())) { panelp->updateNotification(); } diff --git a/indra/newview/llviewercontrollistener.cpp b/indra/newview/llviewercontrollistener.cpp index 3443bb644a..8820f9ec56 100644 --- a/indra/newview/llviewercontrollistener.cpp +++ b/indra/newview/llviewercontrollistener.cpp @@ -127,7 +127,7 @@ struct Info LLEventAPI::Response response; std::string groupname; - LLControlGroup* group; + LLControlGroup::ptr_t group; std::string key; LLControlVariable* control; }; @@ -187,7 +187,7 @@ void LLViewerControlListener::groups(LLSD const & request) struct CollectVars: public LLControlGroup::ApplyFunctor { - CollectVars(LLControlGroup* g): + CollectVars(LLControlGroup::ptr_t g): mGroup(g) {} @@ -200,7 +200,7 @@ struct CollectVars: public LLControlGroup::ApplyFunctor ("comment", control->getComment())); } - LLControlGroup* mGroup; + LLControlGroup::ptr_t mGroup; LLSD vars; }; @@ -210,7 +210,7 @@ void LLViewerControlListener::vars(LLSD const & request) // control name. Response response(LLSD(), request); std::string groupname(request["group"]); - LLControlGroup* group(LLControlGroup::getInstance(groupname)); + auto group(LLControlGroup::getInstance(groupname)); if (! group) { return response.error(STRINGIZE("Unrecognized group '" << groupname << "'")); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 39c891c9c1..94d2d216b9 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -3978,8 +3978,8 @@ void process_sim_stats(LLMessageSystem *msg, void **user_data) F32 stat_value; msg->getU32("Stat", "StatID", stat_id, i); msg->getF32("Stat", "StatValue", stat_value, i); - LLStatViewer::SimMeasurementSampler* measurementp = LLStatViewer::SimMeasurementSampler::getInstance((ESimStatID)stat_id); - + auto measurementp = LLStatViewer::SimMeasurementSampler::getInstance((ESimStatID)stat_id); + if (measurementp ) { measurementp->sample(stat_value); -- cgit v1.2.3 From b554c9eaf45c83500e6b65e295cc507b9a3d537b Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 7 Oct 2021 14:00:39 -0400 Subject: SL-16024: Adapt llinstancetracker_test.cpp to getInstance() change. --- indra/llcommon/tests/llinstancetracker_test.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/indra/llcommon/tests/llinstancetracker_test.cpp b/indra/llcommon/tests/llinstancetracker_test.cpp index 9b89159625..5daa29adf4 100644 --- a/indra/llcommon/tests/llinstancetracker_test.cpp +++ b/indra/llcommon/tests/llinstancetracker_test.cpp @@ -90,19 +90,19 @@ namespace tut { Keyed one("one"); ensure_equals(Keyed::instanceCount(), 1); - Keyed* found = Keyed::getInstance("one"); - ensure("couldn't find stack Keyed", found); - ensure_equals("found wrong Keyed instance", found, &one); + auto found = Keyed::getInstance("one"); + ensure("couldn't find stack Keyed", bool(found)); + ensure_equals("found wrong Keyed instance", found.get(), &one); { boost::scoped_ptr two(new Keyed("two")); ensure_equals(Keyed::instanceCount(), 2); - Keyed* found = Keyed::getInstance("two"); - ensure("couldn't find heap Keyed", found); - ensure_equals("found wrong Keyed instance", found, two.get()); + auto found = Keyed::getInstance("two"); + ensure("couldn't find heap Keyed", bool(found)); + ensure_equals("found wrong Keyed instance", found.get(), two.get()); } ensure_equals(Keyed::instanceCount(), 1); } - Keyed* found = Keyed::getInstance("one"); + auto found = Keyed::getInstance("one"); ensure("Keyed key lives too long", ! found); ensure_equals(Keyed::instanceCount(), 0); } -- cgit v1.2.3 From 6e06d1db6045df2e4961243f379c4d7695a8190d Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 7 Oct 2021 15:32:19 -0400 Subject: SL-16024: Make LLCond::get() lock and return by value. Its previous behavior, returning a const reference without locking, was wrong: it could return a reference to an object in an inconsistent state if it was concurrently being modified on another thread. Locking the mutex and returning a copy by value is the correct behavior. --- indra/llcommon/llcond.h | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/indra/llcommon/llcond.h b/indra/llcommon/llcond.h index e31b67d893..c08acb66a1 100644 --- a/indra/llcommon/llcond.h +++ b/indra/llcommon/llcond.h @@ -53,6 +53,8 @@ private: LLCoros::Mutex mMutex; // Use LLCoros::ConditionVariable for the same reason. LLCoros::ConditionVariable mCond; + using LockType = LLCoros::LockType; + using cv_status = LLCoros::cv_status; public: /// LLCond can be explicitly initialized with a specific value for mData if @@ -65,10 +67,14 @@ public: LLCond(const LLCond&) = delete; LLCond& operator=(const LLCond&) = delete; - /// get() returns a const reference to the stored DATA. The only way to - /// get a non-const reference -- to modify the stored DATA -- is via - /// update_one() or update_all(). - const value_type& get() const { return mData; } + /// get() returns the stored DATA by value -- so to use get(), DATA must + /// be copyable. The only way to get a non-const reference -- to modify + /// the stored DATA -- is via update_one() or update_all(). + value_type get() + { + LockType lk(mMutex); + return mData; + } /** * Pass update_one() an invocable accepting non-const (DATA&). The @@ -83,7 +89,7 @@ public: void update_one(MODIFY modify) { { // scope of lock can/should end before notify_one() - LLCoros::LockType lk(mMutex); + LockType lk(mMutex); modify(mData); } mCond.notify_one(); @@ -102,7 +108,7 @@ public: void update_all(MODIFY modify) { { // scope of lock can/should end before notify_all() - LLCoros::LockType lk(mMutex); + LockType lk(mMutex); modify(mData); } mCond.notify_all(); @@ -118,7 +124,7 @@ public: template void wait(Pred pred) { - LLCoros::LockType lk(mMutex); + LockType lk(mMutex); // We must iterate explicitly since the predicate accepted by // condition_variable::wait() requires a different signature: // condition_variable::wait() calls its predicate with no arguments. @@ -205,14 +211,14 @@ private: template bool wait_until(const std::chrono::time_point& timeout_time, Pred pred) { - LLCoros::LockType lk(mMutex); + LockType lk(mMutex); // We advise the caller to pass a predicate accepting (const DATA&). // But what if they instead pass a predicate accepting non-const // (DATA&)? Such a predicate could modify mData, which would be Bad. // Forbid that. while (! pred(const_cast(mData))) { - if (LLCoros::cv_status::timeout == mCond.wait_until(lk, timeout_time)) + if (cv_status::timeout == mCond.wait_until(lk, timeout_time)) { // It's possible that wait_until() timed out AND the predicate // became true more or less simultaneously. Even though -- cgit v1.2.3 From 623ac79120a417ec445ce5c106a907fe46734309 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 7 Oct 2021 15:32:51 -0400 Subject: SL-16024: Add LL::WorkQueue for passing work items between threads. A typical WorkQueue has a string name, which can be used to find it to post work to it. "Work" is a nullary callable. WorkQueue is a multi-producer, multi-consumer thread-safe queue: multiple threads can service the WorkQueue, multiple threads can post work to it. Work can be scheduled in the future by submitting with a timestamp. In addition, a given work item can be scheduled to run on a recurring basis. A requesting thread servicing a WorkQueue of its own, such as the viewer's main thread, can submit work to another WorkQueue along with a callback to be passed the result (of arbitrary type) of the first work item. The callback is posted to the originating WorkQueue, permitting safe data exchange between participating threads. Methods are provided for different kinds of servicing threads. runUntilClose() is useful for a simple worker thread. runFor(duration) devotes no more than a specified time slice to that WorkQueue, e.g. for use by the main thread. --- indra/llcommon/CMakeLists.txt | 3 + indra/llcommon/tests/workqueue_test.cpp | 158 ++++++++++++++++ indra/llcommon/threadsafeschedule.h | 1 + indra/llcommon/workqueue.cpp | 114 +++++++++++ indra/llcommon/workqueue.h | 325 ++++++++++++++++++++++++++++++++ 5 files changed, 601 insertions(+) create mode 100644 indra/llcommon/tests/workqueue_test.cpp create mode 100644 indra/llcommon/workqueue.cpp create mode 100644 indra/llcommon/workqueue.h diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 5efcfabf24..a3dbb6d9d0 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -121,6 +121,7 @@ set(llcommon_SOURCE_FILES llworkerthread.cpp timing.cpp u64.cpp + workqueue.cpp StackWalker.cpp ) @@ -258,6 +259,7 @@ set(llcommon_HEADER_FILES timer.h tuple.h u64.h + workqueue.h StackWalker.h ) @@ -363,6 +365,7 @@ if (LL_TESTS) LL_ADD_INTEGRATION_TEST(stringize "" "${test_libs}") LL_ADD_INTEGRATION_TEST(threadsafeschedule "" "${test_libs}") LL_ADD_INTEGRATION_TEST(tuple "" "${test_libs}") + LL_ADD_INTEGRATION_TEST(workqueue "" "${test_libs}") ## llexception_test.cpp isn't a regression test, and doesn't need to be run ## every build. It's to help a developer make implementation choices about diff --git a/indra/llcommon/tests/workqueue_test.cpp b/indra/llcommon/tests/workqueue_test.cpp new file mode 100644 index 0000000000..ab1cae6c14 --- /dev/null +++ b/indra/llcommon/tests/workqueue_test.cpp @@ -0,0 +1,158 @@ +/** + * @file workqueue_test.cpp + * @author Nat Goodspeed + * @date 2021-10-07 + * @brief Test for workqueue. + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$ + * Copyright (c) 2021, Linden Research, Inc. + * $/LicenseInfo$ + */ + +// Precompiled header +#include "linden_common.h" +// associated header +#include "workqueue.h" +// STL headers +// std headers +#include +#include +// external library headers +// other Linden headers +#include "../test/lltut.h" +#include "llcond.h" +#include "llstring.h" +#include "stringize.h" + +using namespace LL; +using namespace std::literals::chrono_literals; // ms suffix +using namespace std::literals::string_literals; // s suffix + +/***************************************************************************** +* TUT +*****************************************************************************/ +namespace tut +{ + struct workqueue_data + { + WorkQueue queue{"queue"}; + }; + typedef test_group workqueue_group; + typedef workqueue_group::object object; + workqueue_group workqueuegrp("workqueue"); + + template<> template<> + void object::test<1>() + { + set_test_name("name"); + ensure_equals("didn't capture name", queue.getKey(), "queue"); + ensure("not findable", WorkQueue::getInstance("queue") == queue.getWeak().lock()); + WorkQueue q2; + ensure("has no name", LLStringUtil::startsWith(q2.getKey(), "WorkQueue")); + } + + template<> template<> + void object::test<2>() + { + set_test_name("post"); + bool wasRun{ false }; + // We only get away with binding a simple bool because we're running + // the work on the same thread. + queue.post([&wasRun](){ wasRun = true; }); + queue.close(); + ensure("ran too soon", ! wasRun); + queue.runUntilClose(); + ensure("didn't run", wasRun); + } + + template<> template<> + void object::test<3>() + { + set_test_name("postEvery"); + // record of runs + using Shared = std::deque; + // This is an example of how to share data between the originator of + // postEvery(work) and the work item itself, since usually a WorkQueue + // is used to dispatch work to a different thread. Neither of them + // should call any of LLCond's wait methods: you don't want to stall + // either the worker thread or the originating thread (conventionally + // main). Use LLCond or a subclass even if all you want to do is + // signal the work item that it can quit; consider LLOneShotCond. + LLCond data; + auto start = WorkQueue::TimePoint::clock::now(); + auto interval = 100ms; + queue.postEvery( + interval, + [&data, count = 0] + () mutable + { + // record the timestamp at which this instance is running + data.update_one( + [](Shared& data) + { + data.push_back(WorkQueue::TimePoint::clock::now()); + }); + // by the 3rd call, return false to stop + return (++count < 3); + }); + // no convenient way to close() our queue while we've got a + // postEvery() running, so run until we think we should have exhausted + // the iterations + queue.runFor(10*interval); + // Take a copy of the captured deque. + Shared result = data.get(); + ensure_equals("called wrong number of times", result.size(), 3); + // postEvery() assumes you want the first call to happen right away. + // Inject a fake start time that's (interval) earlier than that, to + // make our too early/too late tests uniform for all entries. + result.push_front(start - interval); + for (size_t i = 1; i < result.size(); ++i) + { + auto diff = (result[i] - result[i-1]); + try + { + ensure(STRINGIZE("call " << i << " too soon"), diff >= interval); + ensure(STRINGIZE("call " << i << " too late"), diff < interval*1.5); + } + catch (const tut::failure&) + { + auto interval_ms = interval / 1ms; + auto diff_ms = diff / 1ms; + std::cerr << "interval " << interval_ms + << "ms; diff " << diff_ms << "ms" << std::endl; + throw; + } + } + } + + template<> template<> + void object::test<4>() + { + set_test_name("postTo"); + WorkQueue main("main"); + auto qptr = WorkQueue::getInstance("queue"); + int result = 0; + main.postTo( + qptr, + [](){ return 17; }, + // Note that a postTo() *callback* can safely bind a reference to + // a variable on the invoking thread, because the callback is run + // on the invoking thread. + [&result](int i){ result = i; }); + // this should post the callback to main + qptr->runOne(); + // this should run the callback + main.runOne(); + ensure_equals("failed to run int callback", result, 17); + + std::string alpha; + // postTo() handles arbitrary return types + main.postTo( + qptr, + [](){ return "abc"s; }, + [&alpha](const std::string& s){ alpha = s; }); + qptr->runPending(); + main.runPending(); + ensure_equals("failed to run string callback", alpha, "abc"); + } +} // namespace tut diff --git a/indra/llcommon/threadsafeschedule.h b/indra/llcommon/threadsafeschedule.h index 0e70d30714..c8ad23532b 100644 --- a/indra/llcommon/threadsafeschedule.h +++ b/indra/llcommon/threadsafeschedule.h @@ -78,6 +78,7 @@ namespace LL enum pop_result { EMPTY=super::EMPTY, DONE=super::DONE, WAITING=super::WAITING, POPPED=super::POPPED }; public: + using Closed = LLThreadSafeQueueInterrupt; using TimePoint = ThreadSafeSchedulePrivate::TimePoint; using Clock = TimePoint::clock; diff --git a/indra/llcommon/workqueue.cpp b/indra/llcommon/workqueue.cpp new file mode 100644 index 0000000000..15e292fb43 --- /dev/null +++ b/indra/llcommon/workqueue.cpp @@ -0,0 +1,114 @@ +/** + * @file workqueue.cpp + * @author Nat Goodspeed + * @date 2021-10-06 + * @brief Implementation for WorkQueue. + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$ + * Copyright (c) 2021, Linden Research, Inc. + * $/LicenseInfo$ + */ + +// Precompiled header +#include "linden_common.h" +// associated header +#include "workqueue.h" +// STL headers +// std headers +// external library headers +// other Linden headers +#include "llerror.h" +#include "llexception.h" +#include "stringize.h" + +LL::WorkQueue::WorkQueue(const std::string& name): + super(makeName(name)) +{ + // TODO: register for "LLApp" events so we can implicitly close() on + // viewer shutdown. +} + +void LL::WorkQueue::close() +{ + mQueue.close(); +} + +void LL::WorkQueue::runUntilClose() +{ + try + { + for (;;) + { + callWork(mQueue.pop()); + } + } + catch (const Queue::Closed&) + { + } +} + +bool LL::WorkQueue::runPending() +{ + for (Work work; mQueue.tryPop(work); ) + { + callWork(work); + } + return ! mQueue.done(); +} + +bool LL::WorkQueue::runOne() +{ + Work work; + if (mQueue.tryPop(work)) + { + callWork(work); + } + return ! mQueue.done(); +} + +bool LL::WorkQueue::runUntil(const TimePoint& until) +{ + // Should we subtract some slop to allow for typical Work execution time? + // How much slop? + Work work; + while (TimePoint::clock::now() < until && mQueue.tryPopUntil(until, work)) + { + callWork(work); + } + return ! mQueue.done(); +} + +std::string LL::WorkQueue::makeName(const std::string& name) +{ + if (! name.empty()) + return name; + + static thread_local U32 discriminator = 0; + return STRINGIZE("WorkQueue" << discriminator++); +} + +void LL::WorkQueue::callWork(const Queue::DataTuple& work) +{ + // ThreadSafeSchedule::pop() always delivers a tuple, even when + // there's only one data field per item, as for us. + callWork(std::get<0>(work)); +} + +void LL::WorkQueue::callWork(const Work& work) +{ + try + { + work(); + } + catch (...) + { + // No matter what goes wrong with any individual work item, the worker + // thread must go on! Log our own instance name with the exception. + LOG_UNHANDLED_EXCEPTION(getKey()); + } +} + +void LL::WorkQueue::error(const std::string& msg) +{ + LL_ERRS("WorkQueue") << msg << LL_ENDL; +} diff --git a/indra/llcommon/workqueue.h b/indra/llcommon/workqueue.h new file mode 100644 index 0000000000..a52f7b0e26 --- /dev/null +++ b/indra/llcommon/workqueue.h @@ -0,0 +1,325 @@ +/** + * @file workqueue.h + * @author Nat Goodspeed + * @date 2021-09-30 + * @brief Queue used for inter-thread work passing. + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$ + * Copyright (c) 2021, Linden Research, Inc. + * $/LicenseInfo$ + */ + +#if ! defined(LL_WORKQUEUE_H) +#define LL_WORKQUEUE_H + +#include "llinstancetracker.h" +#include "threadsafeschedule.h" +#include +#include // std::function +#include +#include +#include // std::pair +#include + +namespace LL +{ + /** + * A typical WorkQueue has a string name that can be used to find it. + */ + class WorkQueue: public LLInstanceTracker + { + private: + using super = LLInstanceTracker; + + public: + using Work = std::function; + + private: + using Queue = ThreadSafeSchedule; + // helper for postEvery() + template + class BackJack; + + public: + using TimePoint = Queue::TimePoint; + using TimedWork = Queue::TimeTuple; + using Closed = Queue::Closed; + + /** + * You may omit the WorkQueue name, in which case a unique name is + * synthesized; for practical purposes that makes it anonymous. + */ + WorkQueue(const std::string& name = std::string()); + + /** + * Since the point of WorkQueue is to pass work to some other worker + * thread(s) asynchronously, it's important that the WorkQueue continue + * to exist until the worker thread(s) have drained it. To communicate + * that it's time for them to quit, close() the queue. + */ + void close(); + + /*---------------------- fire and forget API -----------------------*/ + + /// fire-and-forget, but at a particular (future?) time + template + void post(const TimePoint& time, CALLABLE&& callable) + { + // Defer reifying an arbitrary CALLABLE until we hit this method. + // All other methods should accept CALLABLEs of arbitrary type to + // avoid multiple levels of std::function indirection. + mQueue.push(TimedWork(time, std::move(callable))); + } + + /// fire-and-forget + template + void post(CALLABLE&& callable) + { + // We use TimePoint::clock::now() instead of TimePoint's + // representation of the epoch because this WorkQueue may contain + // a mix of past-due TimedWork items and TimedWork items scheduled + // for the future. Sift this new item into the correct place. + post(TimePoint::clock::now(), std::move(callable)); + } + + /** + * Launch a callable returning bool that will trigger repeatedly at + * specified interval, until the callable returns false. + * + * If you need to signal that callable from outside, DO NOT bind a + * reference to a simple bool! That's not thread-safe. Instead, bind + * an LLCond variant, e.g. LLOneShotCond or LLBoolCond. + */ + template + void postEvery(const std::chrono::duration& interval, + CALLABLE&& callable); + + /*------------------------- handshake API --------------------------*/ + + /** + * Post work to another WorkQueue to be run at a specified time, + * requesting a specific callback to be run on this WorkQueue on + * completion. + * + * Returns true if able to post, false if the other WorkQueue is + * inaccessible. + */ + template + bool postTo(std::weak_ptr target, + const TimePoint& time, CALLABLE&& callable, CALLBACK&& callback) + { + // We're being asked to post to the WorkQueue at target. + // target is a weak_ptr: have to lock it to check it. + auto tptr = target.lock(); + if (! tptr) + // can't post() if the target WorkQueue has been destroyed + return false; + + // Here we believe target WorkQueue still exists. Post to it a + // lambda that packages our callable, our callback and a weak_ptr + // to this originating WorkQueue. + tptr->post( + time, + [reply = super::getWeak(), + callable = std::move(callable), + callback = std::move(callback)] + () + { + // Call the callable in any case -- but to minimize + // copying the result, immediately bind it into a reply + // lambda. The reply lambda also binds the original + // callback, so that when we, the originating WorkQueue, + // finally receive and process the reply lambda, we'll + // call the bound callback with the bound result -- on the + // same thread that originally called postTo(). + auto rlambda = + [result = callable(), + callback = std::move(callback)] + () + { callback(std::move(result)); }; + // Check if this originating WorkQueue still exists. + // Remember, the outer lambda is now running on a thread + // servicing the target WorkQueue, and real time has + // elapsed since postTo()'s tptr->post() call. + // reply is a weak_ptr: have to lock it to check it. + auto rptr = reply.lock(); + if (rptr) + { + // Only post reply lambda if the originating WorkQueue + // still exists. If not -- who would we tell? Log it? + try + { + rptr->post(std::move(rlambda)); + } + catch (const Closed&) + { + // Originating WorkQueue might still exist, but + // might be Closed. Same thing: just discard the + // callback. + } + } + }); + // looks like we were able to post() + return true; + } + + /** + * Post work to another WorkQueue, requesting a specific callback to + * be run on this WorkQueue on completion. + * + * Returns true if able to post, false if the other WorkQueue is + * inaccessible. + */ + template + bool postTo(std::weak_ptr target, + CALLABLE&& callable, CALLBACK&& callback) + { + return postTo(target, TimePoint::clock::now(), std::move(callable), std::move(callback)); + } + + /*--------------------------- worker API ---------------------------*/ + + /** + * runUntilClose() pulls TimedWork items off this WorkQueue until the + * queue is closed, at which point it returns. This would be the + * typical entry point for a simple worker thread. + */ + void runUntilClose(); + + /** + * runPending() runs all TimedWork items that are ready to run. It + * returns true if the queue remains open, false if the queue has been + * closed. This could be used by a thread whose primary purpose is to + * serve the queue, but also wants to do other things with its idle time. + */ + bool runPending(); + + /** + * runOne() runs at most one ready TimedWork item -- zero if none are + * ready. It returns true if the queue remains open, false if the + * queue has been closed. + */ + bool runOne(); + + /** + * runFor() runs a subset of ready TimedWork items, until the + * timeslice has been exceeded. It returns true if the queue remains + * open, false if the queue has been closed. This could be used by a + * busy main thread to lend a bounded few CPU cycles to this WorkQueue + * without risking the WorkQueue blowing out the length of any one + * frame. + */ + template + bool runFor(const std::chrono::duration& timeslice) + { + return runUntil(TimePoint::clock::now() + timeslice); + } + + /** + * runUntil() is just like runFor(), only with a specific end time + * instead of a timeslice duration. + */ + bool runUntil(const TimePoint& until); + + private: + static void error(const std::string& msg); + static std::string makeName(const std::string& name); + void callWork(const Queue::DataTuple& work); + void callWork(const Work& work); + Queue mQueue; + }; + + /** + * BackJack is, in effect, a hand-rolled lambda, binding a WorkQueue, a + * CALLABLE that returns bool, a TimePoint and an interval at which to + * relaunch it. As long as the callable continues returning true, BackJack + * keeps resubmitting it to the target WorkQueue. + */ + // Why is BackJack a class and not a lambda? Because, unlike a lambda, a + // class method gets its own 'this' pointer -- which we need to resubmit + // the whole BackJack callable. + template + class WorkQueue::BackJack + { + public: + // bind the desired data + BackJack(std::weak_ptr target, + const WorkQueue::TimePoint& start, + const std::chrono::duration& interval, + CALLABLE&& callable): + mTarget(target), + mStart(start), + mInterval(interval), + mCallable(std::move(callable)) + {} + + // Call by target WorkQueue -- note that although WE require a + // callable returning bool, WorkQueue wants a void callable. We + // consume the bool. + void operator()() + { + // If mCallable() throws an exception, don't catch it here: if it + // throws once, it's likely to throw every time, so it's a waste + // of time to arrange to call it again. + if (mCallable()) + { + // Modify mStart to the new start time we desire. If we simply + // added mInterval to now, we'd get actual timings of + // (mInterval + slop), where 'slop' is the latency between the + // previous mStart and the WorkQueue actually calling us. + // Instead, add mInterval to mStart so that at least we + // register our intent to fire at exact mIntervals. + mStart += mInterval; + + // We're being called at this moment by the target WorkQueue. + // Assume it still exists, rather than checking the result of + // lock(). + // Resubmit the whole *this callable: that's why we're a class + // rather than a lambda. Allow moving *this so we can carry a + // move-only callable; but naturally this statement must be + // the last time we reference this instance, which may become + // moved-from. + try + { + mTarget.lock()->post(mStart, std::move(*this)); + } + catch (const Closed&) + { + // Once this queue is closed, oh well, just stop + } + } + } + + private: + std::weak_ptr mTarget; + WorkQueue::TimePoint mStart; + std::chrono::duration mInterval; + CALLABLE mCallable; + }; + + template + void WorkQueue::postEvery(const std::chrono::duration& interval, + CALLABLE&& callable) + { + if (interval.count() <= 0) + { + // It's essential that postEvery() be called with a positive + // interval, since each call to BackJack posts another instance of + // itself at (start + interval) and we order by target time. A + // zero or negative interval would result in that BackJack + // instance going to the head of the queue every time, immediately + // ready to run. Effectively that would produce an infinite loop, + // a denial of service on this WorkQueue. + error("postEvery(interval) may not be 0"); + } + // Instantiate and post a suitable BackJack, binding a weak_ptr to + // self, the current time, the desired interval and the desired + // callable. + post( + BackJack( + getWeak(), TimePoint::clock::now(), interval, std::move(callable))); + } + +} // namespace LL + +#endif /* ! defined(LL_WORKQUEUE_H) */ -- cgit v1.2.3 From c585ddb75e383cdd994d0d99fed8f2de8f955e3c Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 7 Oct 2021 16:45:15 -0400 Subject: SL-16024: Defend against two threads making "anonymous" WorkQueues. Also make workqueue_test.cpp more robust. --- indra/llcommon/tests/workqueue_test.cpp | 11 ++++++----- indra/llcommon/workqueue.cpp | 18 ++++++++++++++++-- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/indra/llcommon/tests/workqueue_test.cpp b/indra/llcommon/tests/workqueue_test.cpp index ab1cae6c14..d5405400fd 100644 --- a/indra/llcommon/tests/workqueue_test.cpp +++ b/indra/llcommon/tests/workqueue_test.cpp @@ -103,12 +103,13 @@ namespace tut Shared result = data.get(); ensure_equals("called wrong number of times", result.size(), 3); // postEvery() assumes you want the first call to happen right away. - // Inject a fake start time that's (interval) earlier than that, to - // make our too early/too late tests uniform for all entries. - result.push_front(start - interval); - for (size_t i = 1; i < result.size(); ++i) + // Pretend our start time was (interval) earlier than that, to make + // our too early/too late tests uniform for all entries. + start -= interval; + for (size_t i = 0; i < result.size(); ++i) { - auto diff = (result[i] - result[i-1]); + auto diff = result[i] - start; + start += interval; try { ensure(STRINGIZE("call " << i << " too soon"), diff >= interval); diff --git a/indra/llcommon/workqueue.cpp b/indra/llcommon/workqueue.cpp index 15e292fb43..ffc9a97dc0 100644 --- a/indra/llcommon/workqueue.cpp +++ b/indra/llcommon/workqueue.cpp @@ -17,10 +17,15 @@ // std headers // external library headers // other Linden headers +#include "llcoros.h" +#include LLCOROS_MUTEX_HEADER #include "llerror.h" #include "llexception.h" #include "stringize.h" +using Mutex = LLCoros::Mutex; +using Lock = LLCoros::LockType; + LL::WorkQueue::WorkQueue(const std::string& name): super(makeName(name)) { @@ -83,8 +88,17 @@ std::string LL::WorkQueue::makeName(const std::string& name) if (! name.empty()) return name; - static thread_local U32 discriminator = 0; - return STRINGIZE("WorkQueue" << discriminator++); + static U32 discriminator = 0; + static Mutex mutex; + U32 num; + { + // Protect discriminator from concurrent access by different threads. + // It can't be thread_local, else two racing threads will come up with + // the same name. + Lock lk(mutex); + num = discriminator++; + } + return STRINGIZE("WorkQueue" << num); } void LL::WorkQueue::callWork(const Queue::DataTuple& work) -- cgit v1.2.3 From 54d874b1233586844f87e79ae8f211af0a1cb7a6 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Fri, 8 Oct 2021 11:52:09 -0400 Subject: SL-16024: Resolve bizarre VS compile error. Thanks Callum! It seems CALLBACK is a macro in some Microsoft header file. Bleah. --- indra/llcommon/workqueue.h | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/indra/llcommon/workqueue.h b/indra/llcommon/workqueue.h index a52f7b0e26..b88aef989a 100644 --- a/indra/llcommon/workqueue.h +++ b/indra/llcommon/workqueue.h @@ -104,9 +104,13 @@ namespace LL * Returns true if able to post, false if the other WorkQueue is * inaccessible. */ - template - bool postTo(std::weak_ptr target, - const TimePoint& time, CALLABLE&& callable, CALLBACK&& callback) + // Apparently some Microsoft header file defines a macro CALLBACK? The + // natural template argument name CALLBACK produces very weird Visual + // Studio compile errors that seem utterly unrelated to this source + // code. + template + bool postTo(WorkQueue::weak_t target, + const TimePoint& time, CALLABLE&& callable, FOLLOWUP&& callback) { // We're being asked to post to the WorkQueue at target. // target is a weak_ptr: have to lock it to check it. @@ -170,9 +174,9 @@ namespace LL * Returns true if able to post, false if the other WorkQueue is * inaccessible. */ - template - bool postTo(std::weak_ptr target, - CALLABLE&& callable, CALLBACK&& callback) + template + bool postTo(WorkQueue::weak_t target, + CALLABLE&& callable, FOLLOWUP&& callback) { return postTo(target, TimePoint::clock::now(), std::move(callable), std::move(callback)); } @@ -243,7 +247,7 @@ namespace LL { public: // bind the desired data - BackJack(std::weak_ptr target, + BackJack(WorkQueue::weak_t target, const WorkQueue::TimePoint& start, const std::chrono::duration& interval, CALLABLE&& callable): @@ -291,7 +295,7 @@ namespace LL } private: - std::weak_ptr mTarget; + WorkQueue::weak_t mTarget; WorkQueue::TimePoint mStart; std::chrono::duration mInterval; CALLABLE mCallable; -- cgit v1.2.3 From 2238f89db70a754614b01bb85adc5f16a63e7eb4 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Mon, 11 Oct 2021 18:05:27 +0300 Subject: SL-16141 Load fonts and generate glyphs on startup --- indra/llrender/llfontgl.cpp | 31 +++++++++++++++++++++++-------- indra/llrender/llfontgl.h | 4 +++- indra/llrender/llfontregistry.cpp | 5 +++++ indra/newview/llviewerwindow.cpp | 19 +++++++++---------- 4 files changed, 40 insertions(+), 19 deletions(-) diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index 86a4c35e6d..266399d212 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -547,9 +547,19 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars, S32 begin_offset, S32 max_chars return cur_x / sScaleX; } +void LLFontGL::generateASCIIglyphs() +{ + LL_PROFILE_ZONE_SCOPED + for (U32 i = 32; (i < 127); i++) + { + mFontFreetype->getGlyphInfo(i); + } +} + // Returns the max number of complete characters from text (up to max_chars) that can be drawn in max_pixels S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_chars, EWordWrapStyle end_on_word_boundary) const { + LL_PROFILE_ZONE_SCOPED if (!wchars || !wchars[0] || max_chars == 0) { return 0; @@ -829,6 +839,8 @@ void LLFontGL::initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, const std::st { sFontRegistry->reset(); } + + LLFontGL::loadDefaultFonts(); } // Force standard fonts to get generated up front. @@ -838,6 +850,7 @@ void LLFontGL::initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, const std::st // static bool LLFontGL::loadDefaultFonts() { + LL_PROFILE_ZONE_SCOPED bool succ = true; succ &= (NULL != getFontSansSerifSmall()); succ &= (NULL != getFontSansSerif()); @@ -845,10 +858,18 @@ bool LLFontGL::loadDefaultFonts() succ &= (NULL != getFontSansSerifHuge()); succ &= (NULL != getFontSansSerifBold()); succ &= (NULL != getFontMonospace()); - succ &= (NULL != getFontExtChar()); return succ; } +void LLFontGL::loadCommonFonts() +{ + LL_PROFILE_ZONE_SCOPED + getFont(LLFontDescriptor("SansSerif", "Small", BOLD)); + getFont(LLFontDescriptor("SansSerif", "Large", BOLD)); + getFont(LLFontDescriptor("SansSerif", "Huge", BOLD)); + getFont(LLFontDescriptor("Monospace", "Medium", 0)); +} + // static void LLFontGL::destroyDefaultFonts() { @@ -1015,7 +1036,7 @@ LLFontGL* LLFontGL::getFontSansSerifBig() //static LLFontGL* LLFontGL::getFontSansSerifHuge() { - static LLFontGL* fontp = getFont(LLFontDescriptor("SansSerif","Large",0)); + static LLFontGL* fontp = getFont(LLFontDescriptor("SansSerif","Huge",0)); return fontp; } @@ -1026,12 +1047,6 @@ LLFontGL* LLFontGL::getFontSansSerifBold() return fontp; } -//static -LLFontGL* LLFontGL::getFontExtChar() -{ - return getFontSansSerif(); -} - //static LLFontGL* LLFontGL::getFont(const LLFontDescriptor& desc) { diff --git a/indra/llrender/llfontgl.h b/indra/llrender/llfontgl.h index 10891faed9..3b58a37d33 100644 --- a/indra/llrender/llfontgl.h +++ b/indra/llrender/llfontgl.h @@ -160,12 +160,15 @@ public: const LLFontDescriptor& getFontDesc() const; + void generateASCIIglyphs(); + static void initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, const std::string& app_dir, bool create_gl_textures = true); // Load sans-serif, sans-serif-small, etc. // Slow, requires multiple seconds to load fonts. static bool loadDefaultFonts(); + static void loadCommonFonts(); static void destroyDefaultFonts(); static void destroyAllGL(); @@ -190,7 +193,6 @@ public: static LLFontGL* getFontSansSerifBig(); static LLFontGL* getFontSansSerifHuge(); static LLFontGL* getFontSansSerifBold(); - static LLFontGL* getFontExtChar(); static LLFontGL* getFont(const LLFontDescriptor& desc); // Use with legacy names like "SANSSERIF_SMALL" or "OCRA" static LLFontGL* getFontByName(const std::string& name); diff --git a/indra/llrender/llfontregistry.cpp b/indra/llrender/llfontregistry.cpp index 33a33af160..bc1a2f8887 100644 --- a/indra/llrender/llfontregistry.cpp +++ b/indra/llrender/llfontregistry.cpp @@ -597,6 +597,11 @@ LLFontGL *LLFontRegistry::getFont(const LLFontDescriptor& desc) <<" style=[" << ((S32) desc.getStyle()) << "]" << " size=[" << desc.getSize() << "]" << LL_ENDL; } + else + { + //generate glyphs for ASCII chars to avoid stalls later + fontp->generateASCIIglyphs(); + } return fontp; } } diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 2157585364..c52a4e98d3 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1963,6 +1963,13 @@ LLViewerWindow::LLViewerWindow(const Params& p) } LLFontManager::initClass(); + // Init font system, load default fonts and generate basic glyphs + // currently it takes aprox. 0.5 sec and we would load these fonts anyway + // before login screen. + LLFontGL::initClass( gSavedSettings.getF32("FontScreenDPI"), + mDisplayScale.mV[VX], + mDisplayScale.mV[VY], + gDirUtilp->getAppRODataDir()); // // We want to set this stuff up BEFORE we initialize the pipeline, so we can turn off @@ -2009,14 +2016,6 @@ LLViewerWindow::LLViewerWindow(const Params& p) LLViewerTextureManager::init() ; gBumpImageList.init(); - // Init font system, but don't actually load the fonts yet - // because our window isn't onscreen and they take several - // seconds to parse. - LLFontGL::initClass( gSavedSettings.getF32("FontScreenDPI"), - mDisplayScale.mV[VX], - mDisplayScale.mV[VY], - gDirUtilp->getAppRODataDir()); - // Create container for all sub-views LLView::Params rvp; rvp.name("root"); @@ -2102,6 +2101,8 @@ void LLViewerWindow::initBase() LL_DEBUGS("AppInit") << "initializing edit menu" << LL_ENDL; initialize_edit_menu(); + LLFontGL::loadCommonFonts(); + // Create the floater view at the start so that other views can add children to it. // (But wait to add it as a child of the root view so that it will be in front of the // other views.) @@ -5499,8 +5500,6 @@ void LLViewerWindow::initFonts(F32 zoom_factor) mDisplayScale.mV[VX] * zoom_factor, mDisplayScale.mV[VY] * zoom_factor, gDirUtilp->getAppRODataDir()); - // Force font reloads, which can be very slow - LLFontGL::loadDefaultFonts(); } void LLViewerWindow::requestResolutionUpdate() -- cgit v1.2.3 From d00272e0cc9974f35a46f0c313ee2c0e11cddbda Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 11 Oct 2021 16:03:40 +0000 Subject: SL-16099 Multi-threaded OpenGL usage on Windows, enable Core Profile and VAOs by default. --- indra/llcommon/llthreadsafequeue.h | 3 + indra/llimage/llimageworker.cpp | 4 + indra/llrender/llcubemap.cpp | 2 + indra/llrender/llfontfreetype.cpp | 1 + indra/llrender/llglslshader.cpp | 2 + indra/llrender/llgltexture.cpp | 2 + indra/llrender/llimagegl.cpp | 330 +++++++++++++++++++++----------- indra/llrender/llimagegl.h | 35 +++- indra/llrender/llrender.cpp | 2 +- indra/llrender/llrender.h | 2 +- indra/llwindow/llopenglview-objc.mm | 3 +- indra/llwindow/llwindow.h | 12 +- indra/llwindow/llwindowheadless.h | 3 + indra/llwindow/llwindowmacosx.cpp | 28 +++ indra/llwindow/llwindowmacosx.h | 144 +++++++------- indra/llwindow/llwindowwin32.cpp | 129 ++++++++----- indra/llwindow/llwindowwin32.h | 3 + indra/newview/app_settings/settings.xml | 4 +- indra/newview/llappviewer.cpp | 3 +- indra/newview/llnetmap.cpp | 1 + indra/newview/lltexturefetch.cpp | 4 + indra/newview/llviewertexture.cpp | 311 +++++++++++++++++++----------- indra/newview/llviewertexture.h | 8 +- indra/newview/llviewertexturelist.cpp | 36 ++++ indra/newview/llviewerwindow.cpp | 2 +- 25 files changed, 718 insertions(+), 356 deletions(-) diff --git a/indra/llcommon/llthreadsafequeue.h b/indra/llcommon/llthreadsafequeue.h index 719edcd579..06e8d8f609 100644 --- a/indra/llcommon/llthreadsafequeue.h +++ b/indra/llcommon/llthreadsafequeue.h @@ -154,6 +154,9 @@ public: // Returns the size of the queue. size_t size(); + //Returns the capacity of the queue. + U32 capacity() { return mCapacity; } + // closes the queue: // - every subsequent push() call will throw LLThreadSafeQueueInterrupt // - every subsequent tryPush() call will return false diff --git a/indra/llimage/llimageworker.cpp b/indra/llimage/llimageworker.cpp index 5f42fba866..33f8dce6ee 100644 --- a/indra/llimage/llimageworker.cpp +++ b/indra/llimage/llimageworker.cpp @@ -48,6 +48,7 @@ LLImageDecodeThread::~LLImageDecodeThread() // virtual S32 LLImageDecodeThread::update(F32 max_time_ms) { + LL_PROFILE_ZONE_SCOPED; LLMutexLock lock(mCreationMutex); for (creation_list_t::iterator iter = mCreationList.begin(); iter != mCreationList.end(); ++iter) @@ -71,6 +72,7 @@ S32 LLImageDecodeThread::update(F32 max_time_ms) LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(LLImageFormatted* image, U32 priority, S32 discard, BOOL needs_aux, Responder* responder) { + LL_PROFILE_ZONE_SCOPED; LLMutexLock lock(mCreationMutex); handle_t handle = generateHandle(); mCreationList.push_back(creation_info(handle, image, priority, discard, needs_aux, responder)); @@ -118,6 +120,7 @@ LLImageDecodeThread::ImageRequest::~ImageRequest() // Returns true when done, whether or not decode was successful. bool LLImageDecodeThread::ImageRequest::processRequest() { + LL_PROFILE_ZONE_SCOPED; const F32 decode_time_slice = .1f; bool done = true; if (!mDecodedRaw && mFormattedImage.notNull()) @@ -164,6 +167,7 @@ bool LLImageDecodeThread::ImageRequest::processRequest() void LLImageDecodeThread::ImageRequest::finishRequest(bool completed) { + LL_PROFILE_ZONE_SCOPED; if (mResponder.notNull()) { bool success = completed && mDecodedRaw && (!mNeedsAux || mDecodedAux); diff --git a/indra/llrender/llcubemap.cpp b/indra/llrender/llcubemap.cpp index 5947bca670..d7f7b2f58e 100644 --- a/indra/llrender/llcubemap.cpp +++ b/indra/llrender/llcubemap.cpp @@ -150,6 +150,7 @@ void LLCubeMap::initRawData(const std::vector >& rawimages void LLCubeMap::initGLData() { + LL_PROFILE_ZONE_SCOPED; for (int i = 0; i < 6; i++) { mImages[i]->setSubImage(mRawImages[i], 0, 0, RESOLUTION, RESOLUTION); @@ -453,6 +454,7 @@ BOOL LLCubeMap::project(F32& v_min, F32& v_max, F32& h_min, F32& h_max, void LLCubeMap::paintIn(LLVector3 dir[4], const LLColor4U& col) { + LL_PROFILE_ZONE_SCOPED; F32 v_min, v_max, h_min, h_max; LLVector3 center = dir[0] + dir[1] + dir[2] + dir[3]; center.normVec(); diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp index c41730ebaa..e18161e53c 100644 --- a/indra/llrender/llfontfreetype.cpp +++ b/indra/llrender/llfontfreetype.cpp @@ -460,6 +460,7 @@ LLFontGlyphInfo* LLFontFreetype::addGlyph(llwchar wch) const LLFontGlyphInfo* LLFontFreetype::addGlyphFromFont(const LLFontFreetype *fontp, llwchar wch, U32 glyph_index) const { + LL_PROFILE_ZONE_SCOPED; if (mFTFace == NULL) return NULL; diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index 2fb3b8257d..394fcd2b2f 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -208,6 +208,7 @@ void LLGLSLShader::dumpStats() //static void LLGLSLShader::startProfile() { + LL_PROFILE_ZONE_SCOPED; if (sProfileEnabled && sCurBoundShaderPtr) { sCurBoundShaderPtr->placeProfileQuery(); @@ -218,6 +219,7 @@ void LLGLSLShader::startProfile() //static void LLGLSLShader::stopProfile(U32 count, U32 mode) { + LL_PROFILE_ZONE_SCOPED; if (sProfileEnabled && sCurBoundShaderPtr) { sCurBoundShaderPtr->readProfileQuery(count, mode); diff --git a/indra/llrender/llgltexture.cpp b/indra/llrender/llgltexture.cpp index ad501687ed..a279e85bae 100644 --- a/indra/llrender/llgltexture.cpp +++ b/indra/llrender/llgltexture.cpp @@ -262,6 +262,7 @@ LLTexUnit::eTextureType LLGLTexture::getTarget(void) const BOOL LLGLTexture::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height) { + LL_PROFILE_ZONE_SCOPED; llassert(mGLTexturep.notNull()) ; return mGLTexturep->setSubImage(imageraw, x_pos, y_pos, width, height) ; @@ -269,6 +270,7 @@ BOOL LLGLTexture::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, BOOL LLGLTexture::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height) { + LL_PROFILE_ZONE_SCOPED; llassert(mGLTexturep.notNull()) ; return mGLTexturep->setSubImage(datap, data_width, data_height, x_pos, y_pos, width, height) ; diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 276fa55e15..aff29bd857 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -39,6 +39,7 @@ #include "llgl.h" #include "llglslshader.h" #include "llrender.h" +#include "llwindow.h" //---------------------------------------------------------------------------- const F32 MIN_TEXTURE_LIFETIME = 10.f; @@ -170,15 +171,32 @@ BOOL is_little_endian() return (*c == 0x78) ; } + +LLImageGLThread* LLImageGLThread::sInstance = nullptr; + //static -void LLImageGL::initClass(S32 num_catagories, BOOL skip_analyze_alpha /* = false */) +void LLImageGL::initClass(LLWindow* window, S32 num_catagories, BOOL skip_analyze_alpha /* = false */) { + LL_PROFILE_ZONE_SCOPED; sSkipAnalyzeAlpha = skip_analyze_alpha; + LLImageGLThread::sInstance = new LLImageGLThread(window); + LLImageGLThread::sInstance->start(); +} + +//static +void LLImageGL::updateClass() +{ + LL_PROFILE_ZONE_SCOPED; + LLImageGLThread::sInstance->executeCallbacks(); } //static void LLImageGL::cleanupClass() -{ +{ + LL_PROFILE_ZONE_SCOPED; + LLImageGLThread::sInstance->mFunctionQueue.close(); + delete LLImageGLThread::sInstance; + LLImageGLThread::sInstance = nullptr; } //static @@ -656,6 +674,7 @@ void LLImageGL::setExplicitFormat( LLGLint internal_format, LLGLenum primary_for void LLImageGL::setImage(const LLImageRaw* imageraw) { + LL_PROFILE_ZONE_SCOPED; llassert((imageraw->getWidth() == getWidth(mCurrentDiscardLevel)) && (imageraw->getHeight() == getHeight(mCurrentDiscardLevel)) && (imageraw->getComponents() == getComponents())); @@ -699,9 +718,8 @@ BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) } llverify(gGL.getTexUnit(0)->bind(this)); - - - if (mUseMipMaps) + + if (mUseMipMaps) { if (data_hasmips) { @@ -781,7 +799,7 @@ BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) glTexParameteri(mTarget, GL_GENERATE_MIPMAP, GL_TRUE); } - LLImageGL::setManualImage(mTarget, 0, mFormatInternal, + LLImageGL::setManualImage(mTarget, 0, mFormatInternal, w, h, mFormatPrimary, mFormatType, data_in, mAllowCompression); @@ -878,7 +896,7 @@ BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) stop_glerror(); } - LLImageGL::setManualImage(mTarget, m, mFormatInternal, w, h, mFormatPrimary, mFormatType, cur_mip_data, mAllowCompression); + LLImageGL::setManualImage(mTarget, m, mFormatInternal, w, h, mFormatPrimary, mFormatType, cur_mip_data, mAllowCompression); if (m == 0) { analyzeAlpha(data_in, w, h); @@ -1067,6 +1085,7 @@ void LLImageGL::postAddToAtlas() BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update) { + LL_PROFILE_ZONE_SCOPED; if (!width || !height) { return TRUE; @@ -1163,6 +1182,7 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3 BOOL LLImageGL::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update) { + LL_PROFILE_ZONE_SCOPED; return setSubImage(imageraw->getData(), imageraw->getWidth(), imageraw->getHeight(), x_pos, y_pos, width, height, force_fast_update); } @@ -1201,119 +1221,119 @@ void LLImageGL::deleteTextures(S32 numTextures, U32 *textures) // static static LLTrace::BlockTimerStatHandle FTM_SET_MANUAL_IMAGE("setManualImage"); -void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels, bool allow_compression) +void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void* pixels, bool allow_compression) { - LL_RECORD_BLOCK_TIME(FTM_SET_MANUAL_IMAGE); - bool use_scratch = false; - U32* scratch = NULL; - if (LLRender::sGLCoreProfile) - { - if (pixformat == GL_ALPHA && pixtype == GL_UNSIGNED_BYTE) - { //GL_ALPHA is deprecated, convert to RGBA - use_scratch = true; - scratch = new U32[width*height]; + LL_RECORD_BLOCK_TIME(FTM_SET_MANUAL_IMAGE); + bool use_scratch = false; + U32* scratch = NULL; + if (LLRender::sGLCoreProfile) + { + if (pixformat == GL_ALPHA && pixtype == GL_UNSIGNED_BYTE) + { //GL_ALPHA is deprecated, convert to RGBA + use_scratch = true; + scratch = new U32[width * height]; - U32 pixel_count = (U32) (width*height); - for (U32 i = 0; i < pixel_count; i++) - { - U8* pix = (U8*) &scratch[i]; - pix[0] = pix[1] = pix[2] = 0; - pix[3] = ((U8*) pixels)[i]; - } - - pixformat = GL_RGBA; - intformat = GL_RGBA8; - } + U32 pixel_count = (U32)(width * height); + for (U32 i = 0; i < pixel_count; i++) + { + U8* pix = (U8*)&scratch[i]; + pix[0] = pix[1] = pix[2] = 0; + pix[3] = ((U8*)pixels)[i]; + } - if (pixformat == GL_LUMINANCE_ALPHA && pixtype == GL_UNSIGNED_BYTE) - { //GL_LUMINANCE_ALPHA is deprecated, convert to RGBA - use_scratch = true; - scratch = new U32[width*height]; + pixformat = GL_RGBA; + intformat = GL_RGBA8; + } - U32 pixel_count = (U32) (width*height); - for (U32 i = 0; i < pixel_count; i++) - { - U8 lum = ((U8*) pixels)[i*2+0]; - U8 alpha = ((U8*) pixels)[i*2+1]; + if (pixformat == GL_LUMINANCE_ALPHA && pixtype == GL_UNSIGNED_BYTE) + { //GL_LUMINANCE_ALPHA is deprecated, convert to RGBA + use_scratch = true; + scratch = new U32[width * height]; - U8* pix = (U8*) &scratch[i]; - pix[0] = pix[1] = pix[2] = lum; - pix[3] = alpha; - } - - pixformat = GL_RGBA; - intformat = GL_RGBA8; - } + U32 pixel_count = (U32)(width * height); + for (U32 i = 0; i < pixel_count; i++) + { + U8 lum = ((U8*)pixels)[i * 2 + 0]; + U8 alpha = ((U8*)pixels)[i * 2 + 1]; - if (pixformat == GL_LUMINANCE && pixtype == GL_UNSIGNED_BYTE) - { //GL_LUMINANCE_ALPHA is deprecated, convert to RGB - use_scratch = true; - scratch = new U32[width*height]; + U8* pix = (U8*)&scratch[i]; + pix[0] = pix[1] = pix[2] = lum; + pix[3] = alpha; + } - U32 pixel_count = (U32) (width*height); - for (U32 i = 0; i < pixel_count; i++) - { - U8 lum = ((U8*) pixels)[i]; - - U8* pix = (U8*) &scratch[i]; - pix[0] = pix[1] = pix[2] = lum; - pix[3] = 255; - } - - pixformat = GL_RGBA; - intformat = GL_RGB8; - } - } + pixformat = GL_RGBA; + intformat = GL_RGBA8; + } - if (LLImageGL::sCompressTextures && allow_compression) - { - switch (intformat) - { - case GL_RGB: - case GL_RGB8: - intformat = GL_COMPRESSED_RGB; - break; - case GL_SRGB: - case GL_SRGB8: - intformat = GL_COMPRESSED_SRGB; - break; - case GL_RGBA: - case GL_RGBA8: - intformat = GL_COMPRESSED_RGBA; - break; - case GL_SRGB_ALPHA: - case GL_SRGB8_ALPHA8: - intformat = GL_COMPRESSED_SRGB_ALPHA; - break; - case GL_LUMINANCE: - case GL_LUMINANCE8: - intformat = GL_COMPRESSED_LUMINANCE; - break; - case GL_LUMINANCE_ALPHA: - case GL_LUMINANCE8_ALPHA8: - intformat = GL_COMPRESSED_LUMINANCE_ALPHA; - break; - case GL_ALPHA: - case GL_ALPHA8: - intformat = GL_COMPRESSED_ALPHA; - break; - default: - LL_WARNS() << "Could not compress format: " << std::hex << intformat << LL_ENDL; - break; - } - } + if (pixformat == GL_LUMINANCE && pixtype == GL_UNSIGNED_BYTE) + { //GL_LUMINANCE_ALPHA is deprecated, convert to RGB + use_scratch = true; + scratch = new U32[width * height]; - stop_glerror(); - { - LL_PROFILE_ZONE_NAMED("glTexImage2D"); - glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, use_scratch ? scratch : pixels); - } - stop_glerror(); + U32 pixel_count = (U32)(width * height); + for (U32 i = 0; i < pixel_count; i++) + { + U8 lum = ((U8*)pixels)[i]; - if (use_scratch) - { - delete [] scratch; - } + U8* pix = (U8*)&scratch[i]; + pix[0] = pix[1] = pix[2] = lum; + pix[3] = 255; + } + + pixformat = GL_RGBA; + intformat = GL_RGB8; + } + } + + if (LLImageGL::sCompressTextures && allow_compression) + { + switch (intformat) + { + case GL_RGB: + case GL_RGB8: + intformat = GL_COMPRESSED_RGB; + break; + case GL_SRGB: + case GL_SRGB8: + intformat = GL_COMPRESSED_SRGB; + break; + case GL_RGBA: + case GL_RGBA8: + intformat = GL_COMPRESSED_RGBA; + break; + case GL_SRGB_ALPHA: + case GL_SRGB8_ALPHA8: + intformat = GL_COMPRESSED_SRGB_ALPHA; + break; + case GL_LUMINANCE: + case GL_LUMINANCE8: + intformat = GL_COMPRESSED_LUMINANCE; + break; + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE8_ALPHA8: + intformat = GL_COMPRESSED_LUMINANCE_ALPHA; + break; + case GL_ALPHA: + case GL_ALPHA8: + intformat = GL_COMPRESSED_ALPHA; + break; + default: + LL_WARNS() << "Could not compress format: " << std::hex << intformat << LL_ENDL; + break; + } + } + + stop_glerror(); + { + LL_PROFILE_ZONE_NAMED("glTexImage2D"); + glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, use_scratch ? scratch : pixels); + } + stop_glerror(); + + if (use_scratch) + { + delete[] scratch; + } } //create an empty GL texture: just create a texture name @@ -1336,6 +1356,7 @@ BOOL LLImageGL::createGLTexture() if(mTexName) { LLImageGL::deleteTextures(1, (reinterpret_cast(&mTexName))) ; + mTexName = 0; } @@ -1697,7 +1718,7 @@ void LLImageGL::destroyGLTexture() mTextureMemory = (S32Bytes)0; } - LLImageGL::deleteTextures(1, &mTexName); + LLImageGL::deleteTextures(1, &mTexName); mCurrentDiscardLevel = -1 ; //invalidate mCurrentDiscardLevel. mTexName = 0; mGLTextureCreated = FALSE ; @@ -2238,3 +2259,90 @@ void LLImageGL::resetCurTexSizebar() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, nummips); */ + +LLImageGLThread::LLImageGLThread(LLWindow* window) + : LLThread("LLImageGL"), mWindow(window) +{ + mFinished = false; + + mContext = mWindow->createSharedContext(); +} + +// post a function to be executed on the LLImageGL background thread + +bool LLImageGLThread::post(const std::function& func) +{ + try + { + if (mFunctionQueue.size() < mFunctionQueue.capacity()) + { + //NOTE: tryPushFront will return immediately if the lock is held + // desired behavior here is to push and return true unless the + // queue is full or closed + mFunctionQueue.pushFront(func); + } + else + { + return false; + } + } + catch (LLThreadSafeQueueInterrupt e) + { + return false; + } + + return true; +} + +//post a callback to be executed on the main thread + +bool LLImageGLThread::postCallback(const std::function& callback) +{ + try + { + mCallbackQueue.pushFront(callback); + } + catch (LLThreadSafeQueueInterrupt e) + { + //thread is closing, drop request + return false; + } + + return true; +} + +void LLImageGLThread::executeCallbacks() +{ + LL_PROFILE_ZONE_SCOPED; + //executed from main thread + std::function callback; + while (mCallbackQueue.tryPopBack(callback)) + { + LL_PROFILE_ZONE_NAMED("iglt - callback"); + callback(); + } +} + +void LLImageGLThread::run() +{ + mWindow->makeContextCurrent(mContext); + gGL.init(); + try + { + while (true) + { + LL_PROFILE_ZONE_SCOPED; + std::function curFunc = mFunctionQueue.popBack(); + { + LL_PROFILE_ZONE_NAMED("iglt - function") + curFunc(); + } + } + } + catch (LLThreadSafeQueueInterrupt e) + { + //queue is closed, fall out of run loop + } + gGL.shutdown(); + mWindow->destroySharedContext(mContext); +} diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index 61ddc8d59b..8e9b483c2d 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -35,9 +35,11 @@ #include "llrefcount.h" #include "v2math.h" #include "llunits.h" - +#include "llthreadsafequeue.h" #include "llrender.h" class LLTextureAtlas ; +class LLWindow; + #define BYTES_TO_MEGA_BYTES(x) ((x) >> 20) #define MEGA_BYTES_TO_BYTES(x) ((x) << 20) @@ -102,7 +104,7 @@ public: void setAllowCompression(bool allow) { mAllowCompression = allow; } static void setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels, bool allow_compression = true); - + BOOL createGLTexture() ; BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0, BOOL to_create = TRUE, S32 category = sMaxCategories-1); @@ -265,7 +267,8 @@ public: #endif public: - static void initClass(S32 num_catagories, BOOL skip_analyze_alpha = false); + static void initClass(LLWindow* window, S32 num_catagories, BOOL skip_analyze_alpha = false); + static void updateClass(); static void cleanupClass() ; private: @@ -301,4 +304,30 @@ public: }; +class LLImageGLThread : public LLThread +{ +public: + LLImageGLThread(LLWindow* window); + + // post a function to be executed on the LLImageGL background thread + bool post(const std::function& func); + + //post a callback to be executed on the main thread + bool postCallback(const std::function& callback); + + void executeCallbacks(); + + void run() override; + + LLThreadSafeQueue> mFunctionQueue; + LLThreadSafeQueue> mCallbackQueue; + + LLWindow* mWindow; + void* mContext; + LLAtomicBool mFinished; + + static LLImageGLThread* sInstance; +}; + + #endif // LL_LLIMAGEGL_H diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 43b4441ea8..b6711e44e3 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -36,7 +36,7 @@ #include "lltexture.h" #include "llshadermgr.h" -LLRender gGL; +thread_local LLRender gGL; // Handy copies of last good GL matrices F32 gGLModelView[16]; diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index af8568f8a3..c08c2d6881 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -511,7 +511,7 @@ extern F32 gGLLastProjection[16]; extern F32 gGLProjection[16]; extern S32 gGLViewport[4]; -extern LLRender gGL; +extern thread_local LLRender gGL; // This rotation matrix moves the default OpenGL reference frame // (-Z at, Y up) to Cory's favorite reference frame (X at, Z up) diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm index d2c5b11c3d..b647085b7e 100644 --- a/indra/llwindow/llopenglview-objc.mm +++ b/indra/llwindow/llopenglview-objc.mm @@ -288,7 +288,8 @@ attributedStringInfo getSegments(NSAttributedString *str) if (vsync) { - [glContext setValues:(const GLint*)1 forParameter:NSOpenGLCPSwapInterval]; + GLint value = 1; + [glContext setValues:&value forParameter:NSOpenGLCPSwapInterval]; } else { // supress this error after move to Xcode 7: // error: null passed to a callee that requires a non-null argument [-Werror,-Wnonnull] diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h index d4d5b76937..10c0b6a424 100644 --- a/indra/llwindow/llwindow.h +++ b/indra/llwindow/llwindow.h @@ -78,7 +78,17 @@ public: BOOL setSize(LLCoordWindow size); virtual void setMinSize(U32 min_width, U32 min_height, bool enforce_immediately = true); virtual BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp = NULL) = 0; - virtual BOOL setCursorPosition(LLCoordWindow position) = 0; + + //create a new GL context that shares a namespace with this Window's main GL context and make it current on the current thread + // returns a pointer to be handed back to destroySharedConext/makeContextCurrent + virtual void* createSharedContext() = 0; + //make the given context current on the current thread + virtual void makeContextCurrent(void* context) = 0; + //destroy the given context that was retrieved by createSharedContext() + //Must be called on the same thread that called createSharedContext() + virtual void destroySharedContext(void* context) = 0; + + virtual BOOL setCursorPosition(LLCoordWindow position) = 0; virtual BOOL getCursorPosition(LLCoordWindow *position) = 0; virtual void showCursor() = 0; virtual void hideCursor() = 0; diff --git a/indra/llwindow/llwindowheadless.h b/indra/llwindow/llwindowheadless.h index c692666df1..a7ae28aa24 100644 --- a/indra/llwindow/llwindowheadless.h +++ b/indra/llwindow/llwindowheadless.h @@ -49,6 +49,9 @@ public: /*virtual*/ BOOL setSizeImpl(LLCoordScreen size) {return FALSE;}; /*virtual*/ BOOL setSizeImpl(LLCoordWindow size) {return FALSE;}; /*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp = NULL) {return FALSE;}; + void* createSharedContext() { return nullptr; } + void makeContextCurrent(void*) {} + void destroySharedContext(void*) {} /*virtual*/ BOOL setCursorPosition(LLCoordWindow position) {return FALSE;}; /*virtual*/ BOOL getCursorPosition(LLCoordWindow *position) {return FALSE;}; /*virtual*/ void showCursor() {}; diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 0d0607a0bb..23830dd24e 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -1907,6 +1907,34 @@ void LLWindowMacOSX::allowLanguageTextInput(LLPreeditor *preeditor, BOOL b) allowDirectMarkedTextInput(b, mGLView); // mLanguageTextInputAllowed and mMarkedTextAllowed should be updated at once (by Pell Smit } +class sharedContext +{ +public: + CGLContextObj mContext; +}; + +void* LLWindowMacOSX::createSharedContext() +{ + sharedContext* sc = new sharedContext(); + CGLCreateContext(mPixelFormat, mContext, &(sc->mContext)); + + return (void *)sc; +} + +void LLWindowMacOSX::makeContextCurrent(void* context) +{ + CGLSetCurrentContext(((sharedContext*)context)->mContext); +} + +void LLWindowMacOSX::destroySharedContext(void* context) +{ + sharedContext* sc = (sharedContext*)context; + + CGLDestroyContext(sc->mContext); + + delete sc; +} + void LLWindowMacOSX::interruptLanguageTextInput() { commitCurrentPreedit(mGLView); diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h index bf45238c8d..ede2b453d5 100644 --- a/indra/llwindow/llwindowmacosx.h +++ b/indra/llwindow/llwindowmacosx.h @@ -41,85 +41,84 @@ #undef verify #undef require - class LLWindowMacOSX : public LLWindow { public: - /*virtual*/ void show(); - /*virtual*/ void hide(); - /*virtual*/ void close(); - /*virtual*/ BOOL getVisible(); - /*virtual*/ BOOL getMinimized(); - /*virtual*/ BOOL getMaximized(); - /*virtual*/ BOOL maximize(); - /*virtual*/ void minimize(); - /*virtual*/ void restore(); - /*virtual*/ BOOL getFullscreen(); - /*virtual*/ BOOL getPosition(LLCoordScreen *position); - /*virtual*/ BOOL getSize(LLCoordScreen *size); - /*virtual*/ BOOL getSize(LLCoordWindow *size); - /*virtual*/ BOOL setPosition(LLCoordScreen position); - /*virtual*/ BOOL setSizeImpl(LLCoordScreen size); - /*virtual*/ BOOL setSizeImpl(LLCoordWindow size); - /*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp = NULL); - /*virtual*/ BOOL setCursorPosition(LLCoordWindow position); - /*virtual*/ BOOL getCursorPosition(LLCoordWindow *position); - /*virtual*/ void showCursor(); - /*virtual*/ void hideCursor(); - /*virtual*/ void showCursorFromMouseMove(); - /*virtual*/ void hideCursorUntilMouseMove(); - /*virtual*/ BOOL isCursorHidden(); - /*virtual*/ void updateCursor(); - /*virtual*/ ECursorType getCursor() const; - /*virtual*/ void captureMouse(); - /*virtual*/ void releaseMouse(); - /*virtual*/ void setMouseClipping( BOOL b ); - /*virtual*/ BOOL isClipboardTextAvailable(); - /*virtual*/ BOOL pasteTextFromClipboard(LLWString &dst); - /*virtual*/ BOOL copyTextToClipboard(const LLWString & src); - /*virtual*/ void flashIcon(F32 seconds); - /*virtual*/ F32 getGamma(); - /*virtual*/ BOOL setGamma(const F32 gamma); // Set the gamma - /*virtual*/ U32 getFSAASamples(); - /*virtual*/ void setFSAASamples(const U32 fsaa_samples); - /*virtual*/ BOOL restoreGamma(); // Restore original gamma table (before updating gamma) - /*virtual*/ ESwapMethod getSwapMethod() { return mSwapMethod; } - /*virtual*/ void gatherInput(); - /*virtual*/ void delayInputProcessing() {}; - /*virtual*/ void swapBuffers(); + void show() override; + void hide() override; + void close() override; + BOOL getVisible() override; + BOOL getMinimized() override; + BOOL getMaximized() override; + BOOL maximize() override; + void minimize() override; + void restore() override; + BOOL getFullscreen(); + BOOL getPosition(LLCoordScreen *position) override; + BOOL getSize(LLCoordScreen *size) override; + BOOL getSize(LLCoordWindow *size) override; + BOOL setPosition(LLCoordScreen position) override; + BOOL setSizeImpl(LLCoordScreen size) override; + BOOL setSizeImpl(LLCoordWindow size) override; + BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp = NULL) override; + BOOL setCursorPosition(LLCoordWindow position) override; + BOOL getCursorPosition(LLCoordWindow *position) override; + void showCursor() override; + void hideCursor() override; + void showCursorFromMouseMove() override; + void hideCursorUntilMouseMove() override; + BOOL isCursorHidden() override; + void updateCursor() override; + ECursorType getCursor() const override; + void captureMouse() override; + void releaseMouse() override; + void setMouseClipping( BOOL b ) override; + BOOL isClipboardTextAvailable() override; + BOOL pasteTextFromClipboard(LLWString &dst) override; + BOOL copyTextToClipboard(const LLWString & src) override; + void flashIcon(F32 seconds) override; + F32 getGamma() override; + BOOL setGamma(const F32 gamma) override; // Set the gamma + U32 getFSAASamples() override; + void setFSAASamples(const U32 fsaa_samples) override; + BOOL restoreGamma() override; // Restore original gamma table (before updating gamma) + ESwapMethod getSwapMethod() override { return mSwapMethod; } + void gatherInput() override; + void delayInputProcessing() override {}; + void swapBuffers() override; // handy coordinate space conversion routines - /*virtual*/ BOOL convertCoords(LLCoordScreen from, LLCoordWindow *to); - /*virtual*/ BOOL convertCoords(LLCoordWindow from, LLCoordScreen *to); - /*virtual*/ BOOL convertCoords(LLCoordWindow from, LLCoordGL *to); - /*virtual*/ BOOL convertCoords(LLCoordGL from, LLCoordWindow *to); - /*virtual*/ BOOL convertCoords(LLCoordScreen from, LLCoordGL *to); - /*virtual*/ BOOL convertCoords(LLCoordGL from, LLCoordScreen *to); + BOOL convertCoords(LLCoordScreen from, LLCoordWindow *to) override; + BOOL convertCoords(LLCoordWindow from, LLCoordScreen *to) override; + BOOL convertCoords(LLCoordWindow from, LLCoordGL *to) override; + BOOL convertCoords(LLCoordGL from, LLCoordWindow *to) override; + BOOL convertCoords(LLCoordScreen from, LLCoordGL *to) override; + BOOL convertCoords(LLCoordGL from, LLCoordScreen *to) override; - /*virtual*/ LLWindowResolution* getSupportedResolutions(S32 &num_resolutions); - /*virtual*/ F32 getNativeAspectRatio(); - /*virtual*/ F32 getPixelAspectRatio(); - /*virtual*/ void setNativeAspectRatio(F32 ratio) { mOverrideAspectRatio = ratio; } + LLWindowResolution* getSupportedResolutions(S32 &num_resolutions) override; + F32 getNativeAspectRatio() override; + F32 getPixelAspectRatio() override; + void setNativeAspectRatio(F32 ratio) override { mOverrideAspectRatio = ratio; } - /*virtual*/ void beforeDialog(); - /*virtual*/ void afterDialog(); + void beforeDialog() override; + void afterDialog() override; - /*virtual*/ BOOL dialogColorPicker(F32 *r, F32 *g, F32 *b); + BOOL dialogColorPicker(F32 *r, F32 *g, F32 *b) override; - /*virtual*/ void *getPlatformWindow(); - /*virtual*/ void bringToFront() {}; + void *getPlatformWindow() override; + void bringToFront() override {}; - /*virtual*/ void allowLanguageTextInput(LLPreeditor *preeditor, BOOL b); - /*virtual*/ void interruptLanguageTextInput(); - /*virtual*/ void spawnWebBrowser(const std::string& escaped_url, bool async); - /*virtual*/ F32 getSystemUISize(); + void allowLanguageTextInput(LLPreeditor *preeditor, BOOL b) override; + void interruptLanguageTextInput() override; + void spawnWebBrowser(const std::string& escaped_url, bool async) override; + F32 getSystemUISize() override; static std::vector getDisplaysResolutionList(); static std::vector getDynamicFallbackFontList(); // Provide native key event data - /*virtual*/ LLSD getNativeKeyData(); + LLSD getNativeKeyData() override; void* getWindow() { return mWindow; } LLWindowCallbacks* getCallbacks() { return mCallbacks; } @@ -132,6 +131,15 @@ public: bool allowsLanguageInput() { return mLanguageTextInputAllowed; } + //create a new GL context that shares a namespace with this Window's main GL context and make it current on the current thread + // returns a pointer to be handed back to destroySharedConext/makeContextCurrent + void* createSharedContext() override; + //make the given context current on the current thread + void makeContextCurrent(void* context) override; + //destroy the given context that was retrieved by createSharedContext() + //Must be called on the same thread that called createSharedContext() + void destroySharedContext(void* context) override; + protected: LLWindowMacOSX(LLWindowCallbacks* callbacks, const std::string& title, const std::string& name, int x, int y, int width, int height, U32 flags, @@ -141,7 +149,7 @@ protected: ~LLWindowMacOSX(); void initCursors(); - BOOL isValid(); + BOOL isValid() override; void moveWindow(const LLCoordScreen& position,const LLCoordScreen& size); @@ -157,7 +165,7 @@ protected: BOOL shouldPostQuit() { return mPostQuit; } //Satisfy MAINT-3135 and MAINT-3288 with a flag. - /*virtual */ void setOldResize(bool oldresize) {setResizeMode(oldresize, mGLView); } + /*virtual */ void setOldResize(bool oldresize) override {setResizeMode(oldresize, mGLView); } private: void restoreGLContext(); @@ -231,9 +239,9 @@ public: LLSplashScreenMacOSX(); virtual ~LLSplashScreenMacOSX(); - /*virtual*/ void showImpl(); - /*virtual*/ void updateImpl(const std::string& mesg); - /*virtual*/ void hideImpl(); + void showImpl(); + void updateImpl(const std::string& mesg); + void hideImpl(); private: WindowRef mWindow; diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 4ce7c30bef..12d4c6c30e 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -1774,58 +1774,11 @@ const S32 max_format = (S32)num_formats - 1; mhRC = 0; if (wglCreateContextAttribsARB) { //attempt to create a specific versioned context - S32 attribs[] = - { //start at 4.2 - WGL_CONTEXT_MAJOR_VERSION_ARB, 4, - WGL_CONTEXT_MINOR_VERSION_ARB, 2, - WGL_CONTEXT_PROFILE_MASK_ARB, LLRender::sGLCoreProfile ? WGL_CONTEXT_CORE_PROFILE_BIT_ARB : WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, - WGL_CONTEXT_FLAGS_ARB, gDebugGL ? WGL_CONTEXT_DEBUG_BIT_ARB : 0, - 0 - }; - - bool done = false; - while (!done) - { - mhRC = wglCreateContextAttribsARB(mhDC, mhRC, attribs); - - if (!mhRC) - { - if (attribs[3] > 0) - { //decrement minor version - attribs[3]--; - } - else if (attribs[1] > 3) - { //decrement major version and start minor version over at 3 - attribs[1]--; - attribs[3] = 3; - } - else - { //we reached 3.0 and still failed, bail out - done = true; - } - } - else - { - LL_INFOS() << "Created OpenGL " << llformat("%d.%d", attribs[1], attribs[3]) << - (LLRender::sGLCoreProfile ? " core" : " compatibility") << " context." << LL_ENDL; - done = true; - - // force sNoFixedFunction iff we're trying to use nsight debugging which does not support many legacy API uses - - // nSight doesn't support use of legacy API funcs in the fixed function pipe - if (LLRender::sGLCoreProfile || LLRender::sNsightDebugSupport) - { - LLGLSLShader::sNoFixedFunction = true; - } - } - } - } - - if (!mhRC && !(mhRC = wglCreateContext(mhDC))) - { - close(); - OSMessageBox(mCallbacks->translateString("MBGLContextErr"), mCallbacks->translateString("MBError"), OSMB_OK); - return FALSE; + mhRC = (HGLRC) createSharedContext(); + if (!mhRC) + { + return FALSE; + } } if (!wglMakeCurrent(mhDC, mhRC)) @@ -1880,6 +1833,75 @@ const S32 max_format = (S32)num_formats - 1; return TRUE; } +void* LLWindowWin32::createSharedContext() +{ + S32 attribs[] = + { + WGL_CONTEXT_MAJOR_VERSION_ARB, 4, + WGL_CONTEXT_MINOR_VERSION_ARB, 2, + WGL_CONTEXT_PROFILE_MASK_ARB, LLRender::sGLCoreProfile ? WGL_CONTEXT_CORE_PROFILE_BIT_ARB : WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, + WGL_CONTEXT_FLAGS_ARB, gDebugGL ? WGL_CONTEXT_DEBUG_BIT_ARB : 0, + 0 + }; + + HGLRC rc = wglCreateContextAttribsARB(mhDC, mhRC, attribs); + + bool done = false; + while (!done) + { + rc = wglCreateContextAttribsARB(mhDC, mhRC, attribs); + + if (!rc) + { + if (attribs[3] > 0) + { //decrement minor version + attribs[3]--; + } + else if (attribs[1] > 3) + { //decrement major version and start minor version over at 3 + attribs[1]--; + attribs[3] = 3; + } + else + { //we reached 3.0 and still failed, bail out + done = true; + } + } + else + { + LL_INFOS() << "Created OpenGL " << llformat("%d.%d", attribs[1], attribs[3]) << + (LLRender::sGLCoreProfile ? " core" : " compatibility") << " context." << LL_ENDL; + done = true; + + // force sNoFixedFunction iff we're trying to use nsight debugging which does not support many legacy API uses + + // nSight doesn't support use of legacy API funcs in the fixed function pipe + if (LLRender::sGLCoreProfile || LLRender::sNsightDebugSupport) + { + LLGLSLShader::sNoFixedFunction = true; + } + } + } + + if (!rc && !(rc = wglCreateContext(mhDC))) + { + close(); + OSMessageBox(mCallbacks->translateString("MBGLContextErr"), mCallbacks->translateString("MBError"), OSMB_OK); + } + + return rc; +} + +void LLWindowWin32::makeContextCurrent(void* contextPtr) +{ + wglMakeCurrent(mhDC, (HGLRC) contextPtr); +} + +void LLWindowWin32::destroySharedContext(void* contextPtr) +{ + wglDeleteContext((HGLRC)contextPtr); +} + void LLWindowWin32::moveWindow( const LLCoordScreen& position, const LLCoordScreen& size ) { if( mIsMouseClipping ) @@ -3720,6 +3742,7 @@ BOOL LLWindowWin32::resetDisplayResolution() void LLWindowWin32::swapBuffers() { + LL_PROFILE_ZONE_SCOPED; ASSERT_MAIN_THREAD(); SwapBuffers(mhDC); @@ -4731,4 +4754,4 @@ void LLWindowWin32::post(const std::function& func) #else mFunctionQueue.pushFront(func); #endif -} \ No newline at end of file +} diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h index 66647459b2..5f253b5df3 100644 --- a/indra/llwindow/llwindowwin32.h +++ b/indra/llwindow/llwindowwin32.h @@ -93,6 +93,9 @@ public: /*virtual*/ BOOL setSizeImpl(LLCoordScreen size); /*virtual*/ BOOL setSizeImpl(LLCoordWindow size); /*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp = NULL); + void* createSharedContext() override; + void makeContextCurrent(void* context) override; + void destroySharedContext(void* context) override; /*virtual*/ BOOL setCursorPosition(LLCoordWindow position); /*virtual*/ BOOL getCursorPosition(LLCoordWindow *position); /*virtual*/ void showCursor(); diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 05c3fc3bfe..d05d100ddf 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -9814,7 +9814,7 @@ Type Boolean Value - 0 + 1 RenderGlow @@ -10599,7 +10599,7 @@ Type Boolean Value - 0 + 1 RenderUseTransformFeedback diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 722a6caa65..e46e8feb14 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -613,7 +613,7 @@ static void settings_modify() LLPipeline::sRenderDeferred = LLPipeline::sRenderTransparentWater && LLPipeline::sRenderBump && gSavedSettings.getBOOL("RenderDeferred"); LLVOSurfacePatch::sLODFactor = gSavedSettings.getF32("RenderTerrainLODFactor"); LLVOSurfacePatch::sLODFactor *= LLVOSurfacePatch::sLODFactor; //square lod factor to get exponential range of [1,4] - gDebugGL = gSavedSettings.getBOOL("RenderDebugGL") || gDebugSession; + gDebugGL = gSavedSettings.getBOOL("RenderDebugGL") || gDebugSession; gDebugPipeline = gSavedSettings.getBOOL("RenderDebugPipeline"); } @@ -4831,6 +4831,7 @@ void LLAppViewer::idle() LLNotificationsUI::LLToast::updateClass(); LLSmoothInterpolation::updateInterpolants(); LLMortician::updateClass(); + LLImageGL::updateClass(); LLFilePickerThread::clearDead(); //calls LLFilePickerThread::notify() LLDirPickerThread::clearDead(); F32 dt_raw = idle_timer.getElapsedTimeAndResetF32(); diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index 112da55682..111b45612e 100644 --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -147,6 +147,7 @@ void LLNetMap::setScale( F32 scale ) void LLNetMap::draw() { + LL_PROFILE_ZONE_SCOPED; static LLFrameTimer map_timer; static LLUIColor map_avatar_color = LLUIColorTable::instance().getColor("MapAvatarColor", LLColor4::white); static LLUIColor map_avatar_friend_color = LLUIColorTable::instance().getColor("MapAvatarFriendColor", LLColor4::white); diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index f64db7beb5..63e561147d 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -314,6 +314,7 @@ private: // Threads: Ttc virtual void completed(bool success) { + LL_PROFILE_ZONE_SCOPED; LLTextureFetchWorker* worker = mFetcher->getWorker(mID); if (worker) { @@ -338,6 +339,7 @@ private: // Threads: Ttc virtual void completed(bool success) { + LL_PROFILE_ZONE_SCOPED; LLTextureFetchWorker* worker = mFetcher->getWorker(mID); if (worker) { @@ -362,6 +364,7 @@ private: // Threads: Tid virtual void completed(bool success, LLImageRaw* raw, LLImageRaw* aux) { + LL_PROFILE_ZONE_SCOPED; LLTextureFetchWorker* worker = mFetcher->getWorker(mID); if (worker) { @@ -1139,6 +1142,7 @@ void LLTextureFetchWorker::startWork(S32 param) // Threads: Ttf bool LLTextureFetchWorker::doWork(S32 param) { + LL_PROFILE_ZONE_SCOPED; static const LLCore::HttpStatus http_not_found(HTTP_NOT_FOUND); // 404 static const LLCore::HttpStatus http_service_unavail(HTTP_SERVICE_UNAVAILABLE); // 503 static const LLCore::HttpStatus http_not_sat(HTTP_REQUESTED_RANGE_NOT_SATISFIABLE); // 416; diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index af55f68cd2..274f53a160 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -184,6 +184,7 @@ void LLViewerTextureManager::findFetchedTextures(const LLUUID& id, std::vector &output) { + LL_PROFILE_ZONE_SCOPED; std::vector fetched_output; gTextureList.findTexturesByID(id, fetched_output); std::vector::iterator iter = fetched_output.begin(); @@ -485,6 +486,7 @@ static LLTrace::BlockTimerStatHandle FTM_TEXTURE_MEMORY_CHECK("Memory Check"); //static bool LLViewerTexture::isMemoryForTextureLow() { + LL_PROFILE_ZONE_SCOPED; // Note: we need to figure out a better source for 'min' values, // what is free for low end at minimal settings is 'nothing left' // for higher end gpus at high settings. @@ -501,6 +503,7 @@ bool LLViewerTexture::isMemoryForTextureLow() //static bool LLViewerTexture::isMemoryForTextureSuficientlyFree() { + LL_PROFILE_ZONE_SCOPED; const S32Megabytes DESIRED_FREE_TEXTURE_MEMORY(50); const S32Megabytes DESIRED_FREE_MAIN_MEMORY(200); @@ -514,6 +517,7 @@ bool LLViewerTexture::isMemoryForTextureSuficientlyFree() //static void LLViewerTexture::getGPUMemoryForTextures(S32Megabytes &gpu, S32Megabytes &physical) { + LL_PROFILE_ZONE_SCOPED; static LLFrameTimer timer; static S32Megabytes gpu_res = S32Megabytes(S32_MAX); static S32Megabytes physical_res = S32Megabytes(S32_MAX); @@ -526,27 +530,29 @@ void LLViewerTexture::getGPUMemoryForTextures(S32Megabytes &gpu, S32Megabytes &p } timer.reset(); - LL_RECORD_BLOCK_TIME(FTM_TEXTURE_MEMORY_CHECK); - - if (gGLManager.mHasATIMemInfo) { - S32 meminfo[4]; - glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, meminfo); - gpu_res = (S32Megabytes)meminfo[0]; + LL_RECORD_BLOCK_TIME(FTM_TEXTURE_MEMORY_CHECK); - //check main memory, only works for windows. - LLMemory::updateMemoryInfo(); - physical_res = LLMemory::getAvailableMemKB(); - } - else if (gGLManager.mHasNVXMemInfo) - { - S32 free_memory; - glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &free_memory); - gpu_res = (S32Megabytes)(free_memory / 1024); - } + if (gGLManager.mHasATIMemInfo) + { + S32 meminfo[4]; + glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, meminfo); + gpu_res = (S32Megabytes)meminfo[0]; - gpu = gpu_res; - physical = physical_res; + //check main memory, only works for windows. + LLMemory::updateMemoryInfo(); + physical_res = LLMemory::getAvailableMemKB(); + } + else if (gGLManager.mHasNVXMemInfo) + { + S32 free_memory; + glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &free_memory); + gpu_res = (S32Megabytes)(free_memory / 1024); + } + + gpu = gpu_res; + physical = physical_res; + } } static LLTrace::BlockTimerStatHandle FTM_TEXTURE_UPDATE_MEDIA("Media"); @@ -555,6 +561,7 @@ static LLTrace::BlockTimerStatHandle FTM_TEXTURE_UPDATE_TEST("Test"); //static void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity) { + LL_PROFILE_ZONE_SCOPED; sCurrentTime = gFrameTimeSeconds; LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName); @@ -704,6 +711,7 @@ void LLViewerTexture::cleanup() void LLViewerTexture::notifyAboutCreatingTexture() { + LL_PROFILE_ZONE_SCOPED; for(U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch) { for(U32 f = 0; f < mNumFaces[ch]; f++) @@ -715,6 +723,7 @@ void LLViewerTexture::notifyAboutCreatingTexture() void LLViewerTexture::notifyAboutMissingAsset() { + LL_PROFILE_ZONE_SCOPED; for(U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch) { for(U32 f = 0; f < mNumFaces[ch]; f++) @@ -727,6 +736,7 @@ void LLViewerTexture::notifyAboutMissingAsset() // virtual void LLViewerTexture::dump() { + LL_PROFILE_ZONE_SCOPED; LLGLTexture::dump(); LL_INFOS() << "LLViewerTexture" @@ -762,6 +772,7 @@ bool LLViewerTexture::isActiveFetching() bool LLViewerTexture::bindDebugImage(const S32 stage) { + LL_PROFILE_ZONE_SCOPED; if (stage < 0) return false; bool res = true; @@ -780,6 +791,7 @@ bool LLViewerTexture::bindDebugImage(const S32 stage) bool LLViewerTexture::bindDefaultImage(S32 stage) { + LL_PROFILE_ZONE_SCOPED; if (stage < 0) return false; bool res = true; @@ -822,6 +834,7 @@ void LLViewerTexture::forceImmediateUpdate() void LLViewerTexture::addTextureStats(F32 virtual_size, BOOL needs_gltexture) const { + LL_PROFILE_ZONE_SCOPED; if(needs_gltexture) { mNeedsGLTexture = TRUE; @@ -864,6 +877,7 @@ void LLViewerTexture::setKnownDrawSize(S32 width, S32 height) //virtual void LLViewerTexture::addFace(U32 ch, LLFace* facep) { + LL_PROFILE_ZONE_SCOPED; llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); if(mNumFaces[ch] >= mFaceList[ch].size()) @@ -879,6 +893,7 @@ void LLViewerTexture::addFace(U32 ch, LLFace* facep) //virtual void LLViewerTexture::removeFace(U32 ch, LLFace* facep) { + LL_PROFILE_ZONE_SCOPED; llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); if(mNumFaces[ch] > 1) @@ -919,6 +934,7 @@ S32 LLViewerTexture::getNumFaces(U32 ch) const //virtual void LLViewerTexture::addVolume(U32 ch, LLVOVolume* volumep) { + LL_PROFILE_ZONE_SCOPED; if (mNumVolumes[ch] >= mVolumeList[ch].size()) { mVolumeList[ch].resize(2 * mNumVolumes[ch] + 1); @@ -932,6 +948,7 @@ void LLViewerTexture::addVolume(U32 ch, LLVOVolume* volumep) //virtual void LLViewerTexture::removeVolume(U32 ch, LLVOVolume* volumep) { + LL_PROFILE_ZONE_SCOPED; if (mNumVolumes[ch] > 1) { S32 index = volumep->getIndexInTex(ch); @@ -955,6 +972,7 @@ S32 LLViewerTexture::getNumVolumes(U32 ch) const void LLViewerTexture::reorganizeFaceList() { + LL_PROFILE_ZONE_SCOPED; static const F32 MAX_WAIT_TIME = 20.f; // seconds static const U32 MAX_EXTRA_BUFFER_SIZE = 4; @@ -978,6 +996,7 @@ void LLViewerTexture::reorganizeFaceList() void LLViewerTexture::reorganizeVolumeList() { + LL_PROFILE_ZONE_SCOPED; static const F32 MAX_WAIT_TIME = 20.f; // seconds static const U32 MAX_EXTRA_BUFFER_SIZE = 4; @@ -1180,6 +1199,7 @@ FTType LLViewerFetchedTexture::getFTType() const void LLViewerFetchedTexture::cleanup() { + LL_PROFILE_ZONE_SCOPED; for(callback_list_t::iterator iter = mLoadedCallbackList.begin(); iter != mLoadedCallbackList.end(); ) { @@ -1205,6 +1225,7 @@ void LLViewerFetchedTexture::cleanup() //access the fast cache void LLViewerFetchedTexture::loadFromFastCache() { + LL_PROFILE_ZONE_SCOPED; if(!mInFastCacheList) { return; //no need to access the fast cache. @@ -1350,6 +1371,7 @@ void LLViewerFetchedTexture::dump() // ONLY called from LLViewerFetchedTextureList void LLViewerFetchedTexture::destroyTexture() { + LL_PROFILE_ZONE_SCOPED; if(LLImageGL::sGlobalTextureMemory < sMaxDesiredTextureMem * 0.95f)//not ready to release unused memory. { return ; @@ -1366,6 +1388,7 @@ void LLViewerFetchedTexture::destroyTexture() void LLViewerFetchedTexture::addToCreateTexture() { + LL_PROFILE_ZONE_SCOPED; bool force_update = false; if (getComponents() != mRawImage->getComponents()) { @@ -1407,6 +1430,7 @@ void LLViewerFetchedTexture::addToCreateTexture() } else { + LL_PROFILE_ZONE_SCOPED; #if 1 // //if mRequestedDiscardLevel > mDesiredDiscardLevel, we assume the required image res keep going up, @@ -1451,99 +1475,100 @@ void LLViewerFetchedTexture::addToCreateTexture() } } #endif - mNeedsCreateTexture = TRUE; - gTextureList.mCreateTextureList.insert(this); - } + scheduleCreateTexture(); + } return; } // ONLY called from LLViewerTextureList -BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/) +BOOL LLViewerFetchedTexture::preCreateTexture(S32 usename/*= 0*/) { - if (!mNeedsCreateTexture) - { - destroyRawImage(); - return FALSE; - } - mNeedsCreateTexture = FALSE; - if (mRawImage.isNull()) - { - LL_ERRS() << "LLViewerTexture trying to create texture with no Raw Image" << LL_ENDL; - } - if (mRawImage->isBufferInvalid()) - { - LL_WARNS() << "Can't create a texture: invalid image data" << LL_ENDL; - destroyRawImage(); - return FALSE; - } -// LL_INFOS() << llformat("IMAGE Creating (%d) [%d x %d] Bytes: %d ", -// mRawDiscardLevel, -// mRawImage->getWidth(), mRawImage->getHeight(),mRawImage->getDataSize()) -// << mID.getString() << LL_ENDL; - BOOL res = TRUE; + LL_PROFILE_ZONE_SCOPED; + if (!mNeedsCreateTexture) + { + destroyRawImage(); + return FALSE; + } + mNeedsCreateTexture = FALSE; - // store original size only for locally-sourced images - if (mUrl.compare(0, 7, "file://") == 0) - { - mOrigWidth = mRawImage->getWidth(); - mOrigHeight = mRawImage->getHeight(); + if (mRawImage.isNull()) + { + LL_ERRS() << "LLViewerTexture trying to create texture with no Raw Image" << LL_ENDL; + } + if (mRawImage->isBufferInvalid()) + { + LL_WARNS() << "Can't create a texture: invalid image data" << LL_ENDL; + destroyRawImage(); + return FALSE; + } + // LL_INFOS() << llformat("IMAGE Creating (%d) [%d x %d] Bytes: %d ", + // mRawDiscardLevel, + // mRawImage->getWidth(), mRawImage->getHeight(),mRawImage->getDataSize()) + // << mID.getString() << LL_ENDL; + BOOL res = TRUE; + + // store original size only for locally-sourced images + if (mUrl.compare(0, 7, "file://") == 0) + { + mOrigWidth = mRawImage->getWidth(); + mOrigHeight = mRawImage->getHeight(); // This is only safe because it's a local image and fetcher doesn't use raw data // from local images, but this might become unsafe in case of changes to fetcher - if (mBoostLevel == BOOST_PREVIEW) - { - mRawImage->biasedScaleToPowerOfTwo(1024); - } - else - { // leave black border, do not scale image content - mRawImage->expandToPowerOfTwo(MAX_IMAGE_SIZE, FALSE); - } - - mFullWidth = mRawImage->getWidth(); - mFullHeight = mRawImage->getHeight(); - setTexelsPerImage(); - } - else - { - mOrigWidth = mFullWidth; - mOrigHeight = mFullHeight; - } + if (mBoostLevel == BOOST_PREVIEW) + { + mRawImage->biasedScaleToPowerOfTwo(1024); + } + else + { // leave black border, do not scale image content + mRawImage->expandToPowerOfTwo(MAX_IMAGE_SIZE, FALSE); + } - bool size_okay = true; + mFullWidth = mRawImage->getWidth(); + mFullHeight = mRawImage->getHeight(); + setTexelsPerImage(); + } + else + { + mOrigWidth = mFullWidth; + mOrigHeight = mFullHeight; + } - S32 discard_level = mRawDiscardLevel; - if (mRawDiscardLevel < 0) - { - LL_DEBUGS() << "Negative raw discard level when creating image: " << mRawDiscardLevel << LL_ENDL; - discard_level = 0; - } + bool size_okay = true; - U32 raw_width = mRawImage->getWidth() << discard_level; - U32 raw_height = mRawImage->getHeight() << discard_level; + S32 discard_level = mRawDiscardLevel; + if (mRawDiscardLevel < 0) + { + LL_DEBUGS() << "Negative raw discard level when creating image: " << mRawDiscardLevel << LL_ENDL; + discard_level = 0; + } - if( raw_width > MAX_IMAGE_SIZE || raw_height > MAX_IMAGE_SIZE ) - { - LL_INFOS() << "Width or height is greater than " << MAX_IMAGE_SIZE << ": (" << raw_width << "," << raw_height << ")" << LL_ENDL; - size_okay = false; - } - - if (!LLImageGL::checkSize(mRawImage->getWidth(), mRawImage->getHeight())) - { - // A non power-of-two image was uploaded (through a non standard client) - LL_INFOS() << "Non power of two width or height: (" << mRawImage->getWidth() << "," << mRawImage->getHeight() << ")" << LL_ENDL; - size_okay = false; - } - - if( !size_okay ) - { - // An inappropriately-sized image was uploaded (through a non standard client) - // We treat these images as missing assets which causes them to - // be renderd as 'missing image' and to stop requesting data - LL_WARNS() << "!size_ok, setting as missing" << LL_ENDL; - setIsMissingAsset(); - destroyRawImage(); - return FALSE; - } + U32 raw_width = mRawImage->getWidth() << discard_level; + U32 raw_height = mRawImage->getHeight() << discard_level; + + if (raw_width > MAX_IMAGE_SIZE || raw_height > MAX_IMAGE_SIZE) + { + LL_INFOS() << "Width or height is greater than " << MAX_IMAGE_SIZE << ": (" << raw_width << "," << raw_height << ")" << LL_ENDL; + size_okay = false; + } + + if (!LLImageGL::checkSize(mRawImage->getWidth(), mRawImage->getHeight())) + { + // A non power-of-two image was uploaded (through a non standard client) + LL_INFOS() << "Non power of two width or height: (" << mRawImage->getWidth() << "," << mRawImage->getHeight() << ")" << LL_ENDL; + size_okay = false; + } + + if (!size_okay) + { + // An inappropriately-sized image was uploaded (through a non standard client) + // We treat these images as missing assets which causes them to + // be renderd as 'missing image' and to stop requesting data + LL_WARNS() << "!size_ok, setting as missing" << LL_ENDL; + setIsMissingAsset(); + destroyRawImage(); + return FALSE; + } if (mGLTexturep->getHasExplicitFormat()) { @@ -1565,19 +1590,79 @@ BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/) } } - res = mGLTexturep->createGLTexture(mRawDiscardLevel, mRawImage, usename, TRUE, mBoostLevel); + return res; +} - notifyAboutCreatingTexture(); +BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/) +{ + if (!mNeedsCreateTexture) + { + return FALSE; + } - setActive(); + BOOL res = mGLTexturep->createGLTexture(mRawDiscardLevel, mRawImage, usename, TRUE, mBoostLevel); + + return res; +} - if (!needsToSaveRawImage()) - { - mNeedsAux = FALSE; - destroyRawImage(); - } +void LLViewerFetchedTexture::postCreateTexture() +{ + if (!mNeedsCreateTexture) + { + return; + } - return res; + notifyAboutCreatingTexture(); + + setActive(); + + if (!needsToSaveRawImage()) + { + mNeedsAux = FALSE; + destroyRawImage(); + } + + mNeedsCreateTexture = FALSE; +} + +void LLViewerFetchedTexture::scheduleCreateTexture() +{ + ref(); + mNeedsCreateTexture = TRUE; + if (preCreateTexture()) + { + mNeedsCreateTexture = TRUE; +#if LL_WINDOWS //flip to 0 to revert to single-threaded OpenGL texture uploads + if (!LLImageGLThread::sInstance->post([this]() + { + //actually create the texture on a background thread + createTexture(); + { + LL_PROFILE_ZONE_NAMED("iglt - sync"); + if (gGLManager.mHasSync) + { + auto sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + glClientWaitSync(sync, 0, 0); + glDeleteSync(sync); + } + else + { + glFinish(); + } + } + LLImageGLThread::sInstance->postCallback([this]() + { + //finalize on main thread + postCreateTexture(); + unref(); + }); + })) +#endif + { + gTextureList.mCreateTextureList.insert(this); + unref(); + } + } } // Call with 0,0 to turn this feature off. @@ -1869,6 +1954,7 @@ void LLViewerFetchedTexture::setAdditionalDecodePriority(F32 priority) void LLViewerFetchedTexture::updateVirtualSize() { + LL_PROFILE_ZONE_SCOPED; if(!mMaxVirtualSizeResetCounter) { addTextureStats(0.f, FALSE);//reset @@ -1960,6 +2046,7 @@ bool LLViewerFetchedTexture::isActiveFetching() bool LLViewerFetchedTexture::updateFetch() { + LL_PROFILE_ZONE_SCOPED; static LLCachedControl textures_decode_disabled(gSavedSettings,"TextureDecodeDisabled", false); static LLCachedControl sCameraMotionThreshold(gSavedSettings,"TextureCameraMotionThreshold", 0.2); static LLCachedControl sCameraMotionBoost(gSavedSettings,"TextureCameraMotionBoost", 3); @@ -2062,7 +2149,7 @@ bool LLViewerFetchedTexture::updateFetch() } else { - mIsRawImageValid = TRUE; + mIsRawImageValid = TRUE; addToCreateTexture(); } @@ -2890,6 +2977,7 @@ void LLViewerFetchedTexture::destroyRawImage() //virtual void LLViewerFetchedTexture::switchToCachedImage() { + LL_PROFILE_ZONE_SCOPED; if(mCachedRawImage.notNull()) { mRawImage = mCachedRawImage; @@ -2901,12 +2989,12 @@ void LLViewerFetchedTexture::switchToCachedImage() mComponents = mRawImage->getComponents(); mGLTexturep->setComponents(mComponents); gTextureList.dirtyImage(this); - } + } mIsRawImageValid = TRUE; mRawDiscardLevel = mCachedRawDiscardLevel; - gTextureList.mCreateTextureList.insert(this); - mNeedsCreateTexture = TRUE; + + scheduleCreateTexture(); } } @@ -3180,6 +3268,7 @@ bool LLViewerLODTexture::isUpdateFrozen() //virtual void LLViewerLODTexture::processTextureStats() { + LL_PROFILE_ZONE_SCOPED; updateVirtualSize(); static LLCachedControl textures_fullres(gSavedSettings,"TextureLoadFullRes", false); diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index 69568cc825..a5a1fb2c16 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -321,9 +321,13 @@ public: void addToCreateTexture(); - - // ONLY call from LLViewerTextureList + //call to determine if createTexture is necessary + BOOL preCreateTexture(S32 usename = 0); + // ONLY call from LLViewerTextureList or ImageGL background thread BOOL createTexture(S32 usename = 0); + void postCreateTexture(); + void scheduleCreateTexture(); + void destroyTexture() ; virtual void processTextureStats() ; diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 12495078e9..db740b69e9 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -114,6 +114,7 @@ void LLViewerTextureList::init() void LLViewerTextureList::doPreloadImages() { + LL_PROFILE_ZONE_SCOPED; LL_DEBUGS("ViewerImages") << "Preloading images..." << LL_ENDL; llassert_always(mInitialized) ; @@ -205,6 +206,7 @@ static std::string get_texture_list_name() void LLViewerTextureList::doPrefetchImages() { + LL_PROFILE_ZONE_SCOPED; if (LLAppViewer::instance()->getPurgeCache()) { // cache was purged, no point @@ -258,6 +260,7 @@ LLViewerTextureList::~LLViewerTextureList() void LLViewerTextureList::shutdown() { + LL_PROFILE_ZONE_SCOPED; // clear out preloads mImagePreloads.clear(); @@ -333,6 +336,7 @@ void LLViewerTextureList::shutdown() void LLViewerTextureList::dump() { + LL_PROFILE_ZONE_SCOPED; LL_INFOS() << "LLViewerTextureList::dump()" << LL_ENDL; for (image_priority_list_t::iterator it = mImageList.begin(); it != mImageList.end(); ++it) { @@ -377,6 +381,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromFile(const std::string& LLGLenum primary_format, const LLUUID& force_id) { + LL_PROFILE_ZONE_SCOPED; if(!mInitialized) { return NULL ; @@ -404,6 +409,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromUrl(const std::string& LLGLenum primary_format, const LLUUID& force_id) { + LL_PROFILE_ZONE_SCOPED; if(!mInitialized) { return NULL ; @@ -492,6 +498,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id, LLGLenum primary_format, LLHost request_from_host) { + LL_PROFILE_ZONE_SCOPED; if(!mInitialized) { return NULL ; @@ -554,6 +561,7 @@ LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id, LLGLenum primary_format, LLHost request_from_host) { + LL_PROFILE_ZONE_SCOPED; static LLCachedControl fast_cache_fetching_enabled(gSavedSettings, "FastCacheFetchEnabled", true); LLPointer imagep ; @@ -609,6 +617,7 @@ LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id, void LLViewerTextureList::findTexturesByID(const LLUUID &image_id, std::vector &output) { + LL_PROFILE_ZONE_SCOPED; LLTextureKey search_key(image_id, TEX_LIST_STANDARD); uuid_map_t::iterator iter = mUUIDMap.lower_bound(search_key); while (iter != mUUIDMap.end() && iter->first.textureId == image_id) @@ -634,6 +643,7 @@ LLViewerFetchedTexture *LLViewerTextureList::findImage(const LLUUID &image_id, E void LLViewerTextureList::addImageToList(LLViewerFetchedTexture *image) { + LL_PROFILE_ZONE_SCOPED; assert_main_thread(); llassert_always(mInitialized) ; llassert(image); @@ -653,6 +663,7 @@ void LLViewerTextureList::addImageToList(LLViewerFetchedTexture *image) void LLViewerTextureList::removeImageFromList(LLViewerFetchedTexture *image) { + LL_PROFILE_ZONE_SCOPED; assert_main_thread(); llassert_always(mInitialized) ; llassert(image); @@ -701,6 +712,7 @@ void LLViewerTextureList::removeImageFromList(LLViewerFetchedTexture *image) void LLViewerTextureList::addImage(LLViewerFetchedTexture *new_image, ETexListType tex_type) { + LL_PROFILE_ZONE_SCOPED; if (!new_image) { return; @@ -724,6 +736,7 @@ void LLViewerTextureList::addImage(LLViewerFetchedTexture *new_image, ETexListTy void LLViewerTextureList::deleteImage(LLViewerFetchedTexture *image) { + LL_PROFILE_ZONE_SCOPED; if( image) { if (image->hasCallbacks()) @@ -845,6 +858,7 @@ void LLViewerTextureList::updateImages(F32 max_time) void LLViewerTextureList::clearFetchingRequests() { + LL_PROFILE_ZONE_SCOPED; if (LLAppViewer::getTextureFetch()->getNumRequests() == 0) { return; @@ -862,6 +876,7 @@ void LLViewerTextureList::clearFetchingRequests() void LLViewerTextureList::updateImagesDecodePriorities() { + LL_PROFILE_ZONE_SCOPED; // Update the decode priority for N images each frame { F32 lazy_flush_timeout = 30.f; // stop decoding @@ -977,6 +992,7 @@ void LLViewerTextureList::updateImagesDecodePriorities() void LLViewerTextureList::setDebugFetching(LLViewerFetchedTexture* tex, S32 debug_level) { + LL_PROFILE_ZONE_SCOPED; if(!tex->setDebugFetching(debug_level)) { return; @@ -1025,6 +1041,7 @@ void LLViewerTextureList::setDebugFetching(LLViewerFetchedTexture* tex, S32 debu F32 LLViewerTextureList::updateImagesCreateTextures(F32 max_time) { + LL_PROFILE_ZONE_SCOPED; if (gGLManager.mIsDisabled) return 0.0f; // @@ -1041,6 +1058,7 @@ F32 LLViewerTextureList::updateImagesCreateTextures(F32 max_time) enditer = iter; LLViewerFetchedTexture *imagep = *curiter; imagep->createTexture(); + imagep->postCreateTexture(); if (create_timer.getElapsedTimeF32() > max_time) { break; @@ -1052,6 +1070,7 @@ F32 LLViewerTextureList::updateImagesCreateTextures(F32 max_time) F32 LLViewerTextureList::updateImagesLoadingFastCache(F32 max_time) { + LL_PROFILE_ZONE_SCOPED; if (gGLManager.mIsDisabled) return 0.0f; if(mFastCacheList.empty()) { @@ -1082,6 +1101,7 @@ F32 LLViewerTextureList::updateImagesLoadingFastCache(F32 max_time) void LLViewerTextureList::forceImmediateUpdate(LLViewerFetchedTexture* imagep) { + LL_PROFILE_ZONE_SCOPED; if(!imagep) { return ; @@ -1101,6 +1121,7 @@ void LLViewerTextureList::forceImmediateUpdate(LLViewerFetchedTexture* imagep) F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time) { + LL_PROFILE_ZONE_SCOPED; LLTimer image_op_timer; // Update fetch for N images each frame @@ -1176,6 +1197,7 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time) void LLViewerTextureList::updateImagesUpdateStats() { + LL_PROFILE_ZONE_SCOPED; if (mForceResetTextureStats) { for (image_priority_list_t::iterator iter = mImageList.begin(); @@ -1190,6 +1212,7 @@ void LLViewerTextureList::updateImagesUpdateStats() void LLViewerTextureList::decodeAllImages(F32 max_time) { + LL_PROFILE_ZONE_SCOPED; LLTimer timer; //loading from fast cache @@ -1259,6 +1282,7 @@ BOOL LLViewerTextureList::createUploadFile(const std::string& filename, const std::string& out_filename, const U8 codec) { + LL_PROFILE_ZONE_SCOPED; // Load the image LLPointer image = LLImageFormatted::createFromType(codec); if (image.isNull()) @@ -1312,6 +1336,7 @@ BOOL LLViewerTextureList::createUploadFile(const std::string& filename, // note: modifies the argument raw_image!!!! LLPointer LLViewerTextureList::convertToUploadFile(LLPointer raw_image) { + LL_PROFILE_ZONE_SCOPED; raw_image->biasedScaleToPowerOfTwo(LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); LLPointer compressedImage = new LLImageJ2C(); @@ -1345,6 +1370,7 @@ LLPointer LLViewerTextureList::convertToUploadFile(LLPointer U32Megabytes(1500)) ? S32Megabytes(64) : gMinVideoRam ; @@ -1354,6 +1380,7 @@ S32Megabytes LLViewerTextureList::getMinVideoRamSetting() // Returns max setting for TextureMemory (in MB) S32Megabytes LLViewerTextureList::getMaxVideoRamSetting(bool get_recommended, float mem_multiplier) { + LL_PROFILE_ZONE_SCOPED; S32Megabytes max_texmem; if (gGLManager.mVRAM != 0) { @@ -1407,6 +1434,7 @@ const S32Megabytes VIDEO_CARD_FRAMEBUFFER_MEM(12); const S32Megabytes MIN_MEM_FOR_NON_TEXTURE(512); void LLViewerTextureList::updateMaxResidentTexMem(S32Megabytes mem) { + LL_PROFILE_ZONE_SCOPED; // Initialize the image pipeline VRAM settings S32Megabytes cur_mem(gSavedSettings.getS32("TextureMemory")); F32 mem_multiplier = gSavedSettings.getF32("RenderTextureMemoryMultiple"); @@ -1647,6 +1675,7 @@ void LLUIImageList::cleanUp() LLUIImagePtr LLUIImageList::getUIImageByID(const LLUUID& image_id, S32 priority) { + LL_PROFILE_ZONE_SCOPED; // use id as image name std::string image_name = image_id.asString(); @@ -1665,6 +1694,7 @@ LLUIImagePtr LLUIImageList::getUIImageByID(const LLUUID& image_id, S32 priority) LLUIImagePtr LLUIImageList::getUIImage(const std::string& image_name, S32 priority) { + LL_PROFILE_ZONE_SCOPED; // look for existing image uuid_ui_image_map_t::iterator found_it = mUIImages.find(image_name); if (found_it != mUIImages.end()) @@ -1682,6 +1712,7 @@ LLUIImagePtr LLUIImageList::loadUIImageByName(const std::string& name, const std BOOL use_mips, const LLRect& scale_rect, const LLRect& clip_rect, LLViewerTexture::EBoostLevel boost_priority, LLUIImage::EScaleStyle scale_style) { + LL_PROFILE_ZONE_SCOPED; if (boost_priority == LLGLTexture::BOOST_NONE) { boost_priority = LLGLTexture::BOOST_UI; @@ -1694,6 +1725,7 @@ LLUIImagePtr LLUIImageList::loadUIImageByID(const LLUUID& id, BOOL use_mips, const LLRect& scale_rect, const LLRect& clip_rect, LLViewerTexture::EBoostLevel boost_priority, LLUIImage::EScaleStyle scale_style) { + LL_PROFILE_ZONE_SCOPED; if (boost_priority == LLGLTexture::BOOST_NONE) { boost_priority = LLGLTexture::BOOST_UI; @@ -1705,6 +1737,7 @@ LLUIImagePtr LLUIImageList::loadUIImageByID(const LLUUID& id, LLUIImagePtr LLUIImageList::loadUIImage(LLViewerFetchedTexture* imagep, const std::string& name, BOOL use_mips, const LLRect& scale_rect, const LLRect& clip_rect, LLUIImage::EScaleStyle scale_style) { + LL_PROFILE_ZONE_SCOPED; if (!imagep) return NULL; imagep->setAddressMode(LLTexUnit::TAM_CLAMP); @@ -1742,6 +1775,7 @@ LLUIImagePtr LLUIImageList::loadUIImage(LLViewerFetchedTexture* imagep, const st LLUIImagePtr LLUIImageList::preloadUIImage(const std::string& name, const std::string& filename, BOOL use_mips, const LLRect& scale_rect, const LLRect& clip_rect, LLUIImage::EScaleStyle scale_style) { + LL_PROFILE_ZONE_SCOPED; // look for existing image uuid_ui_image_map_t::iterator found_it = mUIImages.find(name); if (found_it != mUIImages.end()) @@ -1756,6 +1790,7 @@ LLUIImagePtr LLUIImageList::preloadUIImage(const std::string& name, const std::s //static void LLUIImageList::onUIImageLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* user_data ) { + LL_PROFILE_ZONE_SCOPED; if(!success || !user_data) { return; @@ -1857,6 +1892,7 @@ struct UIImageDeclarations : public LLInitParam::Block bool LLUIImageList::initFromFile() { + LL_PROFILE_ZONE_SCOPED; // Look for textures.xml in all the right places. Pass // constraint=LLDir::ALL_SKINS because we want to overlay textures.xml // from all the skins directories. diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index c52a4e98d3..82ece85c1b 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -2011,7 +2011,7 @@ LLViewerWindow::LLViewerWindow(const Params& p) // Init the image list. Must happen after GL is initialized and before the images that // LLViewerWindow needs are requested. - LLImageGL::initClass(LLViewerTexture::MAX_GL_IMAGE_CATEGORY) ; + LLImageGL::initClass(mWindow, LLViewerTexture::MAX_GL_IMAGE_CATEGORY) ; gTextureList.init(); LLViewerTextureManager::init() ; gBumpImageList.init(); -- cgit v1.2.3 From 75cf90723f63d1d80b2a3b4b8aa9536cadcda8cb Mon Sep 17 00:00:00 2001 From: Runitai Linden Date: Mon, 11 Oct 2021 11:48:43 -0500 Subject: SL-16099 Followup -- disable VAOs since they still run like garbage in busy scenes. --- indra/newview/app_settings/settings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index d05d100ddf..eeadea76a2 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10599,7 +10599,7 @@ Type Boolean Value - 1 + 0 RenderUseTransformFeedback -- cgit v1.2.3 From 52e1a45659341df68eca01822f189e0883afe66d Mon Sep 17 00:00:00 2001 From: Runitai Linden Date: Tue, 12 Oct 2021 14:46:19 -0500 Subject: SL-16166 Optimization pass on LLRenderPass::pushBatch --- indra/llrender/llgltexture.h | 2 +- indra/llrender/llrender.cpp | 18 +++- indra/llrender/llrender.h | 11 +++ indra/llrender/lltexture.h | 4 +- indra/llrender/llvertexbuffer.cpp | 155 ++++++++++++++++++++++++++++++++++ indra/llrender/llvertexbuffer.h | 11 ++- indra/newview/lldrawpool.cpp | 29 +++---- indra/newview/lldrawpoolmaterials.cpp | 1 + indra/newview/lldrawpoolsimple.cpp | 1 + indra/newview/lldrawpooltree.cpp | 1 + indra/newview/llspatialpartition.h | 7 +- indra/newview/llviewertexture.cpp | 6 +- indra/newview/pipeline.cpp | 52 +++++++----- indra/newview/pipeline.h | 3 +- 14 files changed, 247 insertions(+), 54 deletions(-) diff --git a/indra/llrender/llgltexture.h b/indra/llrender/llgltexture.h index 071912c2c2..028457c510 100644 --- a/indra/llrender/llgltexture.h +++ b/indra/llrender/llgltexture.h @@ -176,7 +176,7 @@ private: protected: void setTexelsPerImage(); - //note: do not make this function public. +public: /*virtual*/ LLImageGL* getGLTexture() const ; protected: diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index b6711e44e3..34c5b77944 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -169,6 +169,7 @@ void LLTexUnit::refreshState(void) void LLTexUnit::activate(void) { + LL_PROFILE_ZONE_SCOPED; if (mIndex < 0) return; if ((S32)gGL.mCurrTextureUnitIndex != mIndex || gGL.mDirty) @@ -229,8 +230,20 @@ void LLTexUnit::disable(void) } } +void LLTexUnit::bindFast(LLTexture* texture) +{ + LLImageGL* gl_tex = texture->getGLTexture(); + + glActiveTextureARB(GL_TEXTURE0_ARB + mIndex); + gGL.mCurrTextureUnitIndex = mIndex; + mCurrTexture = gl_tex->getTexName(); + glBindTexture(sGLTextureType[gl_tex->getTarget()], mCurrTexture); + mHasMipMaps = gl_tex->mHasMipMaps; +} + bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind) { + LL_PROFILE_ZONE_SCOPED; stop_glerror(); if (mIndex >= 0) { @@ -1243,8 +1256,6 @@ void LLRender::syncLightState() void LLRender::syncMatrices() { - stop_glerror(); - static const U32 name[] = { LLShaderMgr::MODELVIEW_MATRIX, @@ -1415,8 +1426,6 @@ void LLRender::syncMatrices() } } } - - stop_glerror(); } void LLRender::translatef(const GLfloat& x, const GLfloat& y, const GLfloat& z) @@ -1925,6 +1934,7 @@ void LLRender::end() } void LLRender::flush() { + LL_PROFILE_ZONE_SCOPED; if (mCount > 0) { if (!mUIOffset.empty()) diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index c08c2d6881..658cdda504 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -161,6 +161,17 @@ public: bool bind(LLImageGL* texture, bool for_rendering = false, bool forceBind = false); bool bind(LLTexture* texture, bool for_rendering = false, bool forceBind = false); + // bind implementation for inner loops + // makes the following assumptions: + // - No need for gGL.flush() + // - texture is not null + // - gl_tex->getTexName() is not zero + // - This texture is not being bound redundantly + // - USE_SRGB_DECODE is disabled + // - mTexOptionsDirty is false + // - + void bindFast(LLTexture* texture); + // Binds a cubemap to this texture unit // (automatically enables the texture unit for cubemaps) bool bind(LLCubeMap* cubeMap); diff --git a/indra/llrender/lltexture.h b/indra/llrender/lltexture.h index 41481fb8a7..256d85ce5a 100644 --- a/indra/llrender/lltexture.h +++ b/indra/llrender/lltexture.h @@ -67,11 +67,9 @@ public: virtual S32 getWidth(S32 discard_level = -1) const; virtual S32 getHeight(S32 discard_level = -1) const; virtual bool isActiveFetching(); + virtual LLImageGL* getGLTexture() const; private: - //note: do not make this function public. - virtual LLImageGL* getGLTexture() const; - virtual void updateBindStatsForTester(); }; #endif diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 0449ac392c..7b9388123f 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -787,6 +787,18 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi placeFence(); } +void LLVertexBuffer::drawRangeFast(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const +{ + mMappable = false; + gGL.syncMatrices(); + + U16* idx = ((U16*)(U8*)mAlignedIndexOffset) + indices_offset; + + LL_PROFILER_GPU_ZONEC("gl.DrawRangeElements", 0xFFFF00) + glDrawRangeElements(sGLMode[mode], start, end, count, GL_UNSIGNED_SHORT, + idx); +} + void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const { llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL); @@ -2272,6 +2284,21 @@ bool LLVertexBuffer::bindGLBuffer(bool force_bind) return ret; } +bool LLVertexBuffer::bindGLBufferFast() +{ + if (mGLBuffer != sGLRenderBuffer || !sVBOActive) + { + glBindBufferARB(GL_ARRAY_BUFFER_ARB, mGLBuffer); + sGLRenderBuffer = mGLBuffer; + sBindCount++; + sVBOActive = true; + + return true; + } + + return false; +} + static LLTrace::BlockTimerStatHandle FTM_BIND_GL_INDICES("Bind Indices"); bool LLVertexBuffer::bindGLIndices(bool force_bind) @@ -2297,6 +2324,21 @@ bool LLVertexBuffer::bindGLIndices(bool force_bind) return ret; } +bool LLVertexBuffer::bindGLIndicesFast() +{ + if (mGLIndices != sGLRenderIndices || !sIBOActive) + { + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mGLIndices); + sGLRenderIndices = mGLIndices; + sBindCount++; + sIBOActive = true; + + return true; + } + + return false; +} + void LLVertexBuffer::flush() { if (useVBOs()) @@ -2487,6 +2529,26 @@ void LLVertexBuffer::setBuffer(U32 data_mask) } } +void LLVertexBuffer::setBufferFast(U32 data_mask) +{ + //set up pointers if the data mask is different ... + bool setup = (sLastMask != data_mask); + + + const bool bindBuffer = bindGLBufferFast(); + const bool bindIndices = bindGLIndicesFast(); + + setup = setup || bindBuffer || bindIndices; + + setupClientArrays(data_mask); + + if (data_mask && setup) + { + setupVertexBuffer(data_mask); // subclass specific setup (virtual function) + sSetCount++; + } +} + // virtual (default) void LLVertexBuffer::setupVertexBuffer(U32 data_mask) { @@ -2644,6 +2706,99 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) llglassertok(); } +void LLVertexBuffer::setupVertexBufferFast(U32 data_mask) +{ + U8* base = (U8*)mAlignedOffset; + + if (data_mask & MAP_NORMAL) + { + S32 loc = TYPE_NORMAL; + void* ptr = (void*)(base + mOffsets[TYPE_NORMAL]); + glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_NORMAL], ptr); + } + if (data_mask & MAP_TEXCOORD3) + { + S32 loc = TYPE_TEXCOORD3; + void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD3]); + glVertexAttribPointerARB(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], ptr); + } + if (data_mask & MAP_TEXCOORD2) + { + S32 loc = TYPE_TEXCOORD2; + void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD2]); + glVertexAttribPointerARB(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], ptr); + } + if (data_mask & MAP_TEXCOORD1) + { + S32 loc = TYPE_TEXCOORD1; + void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD1]); + glVertexAttribPointerARB(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], ptr); + } + if (data_mask & MAP_TANGENT) + { + S32 loc = TYPE_TANGENT; + void* ptr = (void*)(base + mOffsets[TYPE_TANGENT]); + glVertexAttribPointerARB(loc, 4, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TANGENT], ptr); + } + if (data_mask & MAP_TEXCOORD0) + { + S32 loc = TYPE_TEXCOORD0; + void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD0]); + glVertexAttribPointerARB(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], ptr); + } + if (data_mask & MAP_COLOR) + { + S32 loc = TYPE_COLOR; + //bind emissive instead of color pointer if emissive is present + void* ptr = (data_mask & MAP_EMISSIVE) ? (void*)(base + mOffsets[TYPE_EMISSIVE]) : (void*)(base + mOffsets[TYPE_COLOR]); + glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_COLOR], ptr); + } + if (data_mask & MAP_EMISSIVE) + { + S32 loc = TYPE_EMISSIVE; + void* ptr = (void*)(base + mOffsets[TYPE_EMISSIVE]); + glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr); + + if (!(data_mask & MAP_COLOR)) + { //map emissive to color channel when color is not also being bound to avoid unnecessary shader swaps + loc = TYPE_COLOR; + glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr); + } + } + if (data_mask & MAP_WEIGHT) + { + S32 loc = TYPE_WEIGHT; + void* ptr = (void*)(base + mOffsets[TYPE_WEIGHT]); + glVertexAttribPointerARB(loc, 1, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT], ptr); + } + if (data_mask & MAP_WEIGHT4) + { + S32 loc = TYPE_WEIGHT4; + void* ptr = (void*)(base + mOffsets[TYPE_WEIGHT4]); + glVertexAttribPointerARB(loc, 4, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT4], ptr); + } + if (data_mask & MAP_CLOTHWEIGHT) + { + S32 loc = TYPE_CLOTHWEIGHT; + void* ptr = (void*)(base + mOffsets[TYPE_CLOTHWEIGHT]); + glVertexAttribPointerARB(loc, 4, GL_FLOAT, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_CLOTHWEIGHT], ptr); + } + if (data_mask & MAP_TEXTURE_INDEX) + { +#if !LL_DARWIN + S32 loc = TYPE_TEXTURE_INDEX; + void* ptr = (void*)(base + mOffsets[TYPE_VERTEX] + 12); + glVertexAttribIPointer(loc, 1, GL_UNSIGNED_INT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr); +#endif + } + if (data_mask & MAP_VERTEX) + { + S32 loc = TYPE_VERTEX; + void* ptr = (void*)(base + mOffsets[TYPE_VERTEX]); + glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr); + } +} + LLVertexBuffer::MappedRegion::MappedRegion(S32 type, S32 index, S32 count) : mType(type), mIndex(index), mCount(count) { diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index 1d60970df4..51ed85510e 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -210,13 +210,17 @@ protected: virtual ~LLVertexBuffer(); // use unref() - virtual void setupVertexBuffer(U32 data_mask); // pure virtual, called from mapBuffer() + virtual void setupVertexBuffer(U32 data_mask); + void setupVertexBufferFast(U32 data_mask); + void setupVertexArray(); void genBuffer(U32 size); void genIndices(U32 size); bool bindGLBuffer(bool force_bind = false); + bool bindGLBufferFast(); bool bindGLIndices(bool force_bind = false); + bool bindGLIndicesFast(); bool bindGLArray(); void releaseBuffer(); void releaseIndices(); @@ -239,6 +243,8 @@ public: // set for rendering virtual void setBuffer(U32 data_mask); // calls setupVertexBuffer() if data_mask is not 0 + void setBufferFast(U32 data_mask); // calls setupVertexBufferFast(), assumes data_mask is not 0 among other assumptions + void flush(); //flush pending data to GL memory // allocate buffer bool allocateBuffer(S32 nverts, S32 nindices, bool create); @@ -290,6 +296,9 @@ public: void drawArrays(U32 mode, U32 offset, U32 count) const; void drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const; + //implementation for inner loops that does no safety checking + void drawRangeFast(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const; + //for debugging, validate data in given range is valid void validateRange(U32 start, U32 end, U32 count, U32 offset) const; diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index d583a692f9..01dd307187 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -404,6 +404,7 @@ void LLRenderPass::renderTexture(U32 type, U32 mask, BOOL batch_textures) void LLRenderPass::pushBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures) { + LL_PROFILE_ZONE_SCOPED; for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i) { LLDrawInfo* pparams = *i; @@ -452,6 +453,7 @@ void LLRenderPass::applyModelMatrix(const LLDrawInfo& params) void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures) { + LL_PROFILE_ZONE_SCOPED; if (!params.mCount) { return; @@ -469,7 +471,7 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL ba { if (params.mTextureList[i].notNull()) { - gGL.getTexUnit(i)->bind(params.mTextureList[i], TRUE); + gGL.getTexUnit(i)->bindFast(params.mTextureList[i]); } } } @@ -477,8 +479,7 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL ba { //not batching textures or batch has only 1 texture -- might need a texture matrix if (params.mTexture.notNull()) { - params.mTexture->addTextureStats(params.mVSize); - gGL.getTexUnit(0)->bind(params.mTexture, TRUE) ; + gGL.getTexUnit(0)->bindFast(params.mTexture); if (params.mTextureMatrix) { tex_setup = true; @@ -495,19 +496,17 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL ba } } - if (params.mVertexBuffer.notNull()) - { - if (params.mGroup) - { - params.mGroup->rebuildMesh(); - } + { + if (params.mGroup) + { + params.mGroup->rebuildMesh(); + } - LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test); - - params.mVertexBuffer->setBuffer(mask); - params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); - gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode); - } + LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test); + + params.mVertexBuffer->setBufferFast(mask); + params.mVertexBuffer->drawRangeFast(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); + } if (tex_setup) { diff --git a/indra/newview/lldrawpoolmaterials.cpp b/indra/newview/lldrawpoolmaterials.cpp index 05b0c1f1a9..d45e387e10 100644 --- a/indra/newview/lldrawpoolmaterials.cpp +++ b/indra/newview/lldrawpoolmaterials.cpp @@ -106,6 +106,7 @@ void LLDrawPoolMaterials::endDeferredPass(S32 pass) void LLDrawPoolMaterials::renderDeferred(S32 pass) { + LL_PROFILE_ZONE_SCOPED; static const U32 type_list[] = { LLRenderPass::PASS_MATERIAL, diff --git a/indra/newview/lldrawpoolsimple.cpp b/indra/newview/lldrawpoolsimple.cpp index 74e6665a96..ba8549904b 100644 --- a/indra/newview/lldrawpoolsimple.cpp +++ b/indra/newview/lldrawpoolsimple.cpp @@ -471,6 +471,7 @@ void LLDrawPoolSimple::endDeferredPass(S32 pass) void LLDrawPoolSimple::renderDeferred(S32 pass) { + LL_PROFILE_ZONE_SCOPED; LLGLDisable blend(GL_BLEND); LLGLDisable alpha_test(GL_ALPHA_TEST); diff --git a/indra/newview/lldrawpooltree.cpp b/indra/newview/lldrawpooltree.cpp index 0d5195bdbf..a1ff020068 100644 --- a/indra/newview/lldrawpooltree.cpp +++ b/indra/newview/lldrawpooltree.cpp @@ -153,6 +153,7 @@ void LLDrawPoolTree::beginDeferredPass(S32 pass) void LLDrawPoolTree::renderDeferred(S32 pass) { + LL_PROFILE_ZONE_SCOPED; render(pass); } diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index 919f386d29..6ef82fac9c 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -41,6 +41,7 @@ #include "llviewercamera.h" #include "llvector4a.h" #include +#include #define SG_STATE_INHERIT_MASK (OCCLUDED) #define SG_INITIAL_STATE_MASK (DIRTY | GEOM_DIRTY) @@ -216,10 +217,10 @@ public: typedef std::vector > sg_vector_t; typedef std::vector > bridge_list_t; typedef std::vector > drawmap_elem_t; - typedef std::map draw_map_t; + typedef std::unordered_map draw_map_t; typedef std::vector > buffer_list_t; - typedef std::map buffer_texture_map_t; - typedef std::map buffer_map_t; + typedef std::unordered_map buffer_texture_map_t; + typedef std::unordered_map buffer_map_t; struct CompareDistanceGreater { diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 274f53a160..949e71a4c9 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -845,14 +845,14 @@ void LLViewerTexture::addTextureStats(F32 virtual_size, BOOL needs_gltexture) co { //flag to reset the values because the old values are used. resetMaxVirtualSizeResetCounter(); - mMaxVirtualSize = virtual_size; - mAdditionalDecodePriority = 0.f; + mMaxVirtualSize = virtual_size; + mAdditionalDecodePriority = 0.f; mNeedsGLTexture = needs_gltexture; } else if (virtual_size > mMaxVirtualSize) { mMaxVirtualSize = virtual_size; - } + } } void LLViewerTexture::resetTextureStats() diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index c0b469af81..5ef3819de4 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -358,7 +358,6 @@ bool LLPipeline::sRenderAttachedLights = true; bool LLPipeline::sRenderAttachedParticles = true; bool LLPipeline::sRenderDeferred = false; S32 LLPipeline::sVisibleLightCount = 0; -F32 LLPipeline::sMinRenderSize = 0.f; bool LLPipeline::sRenderingHUDs; F32 LLPipeline::sDistortionWaterClipPlaneMargin = 1.0125f; @@ -2550,13 +2549,6 @@ void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera) return; } - const LLVector4a* bounds = group->getBounds(); - if (sMinRenderSize > 0.f && - llmax(llmax(bounds[1][0], bounds[1][1]), bounds[1][2]) < sMinRenderSize) - { - return; - } - assertInitialized(); if (!group->getSpatialPartition()->mRenderByGroup) @@ -3480,7 +3472,6 @@ void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera) group->mLastUpdateDistance = group->mDistance; } } - } void LLPipeline::stateSort(LLSpatialBridge* bridge, LLCamera& camera, BOOL fov_changed) @@ -3787,6 +3778,27 @@ void renderSoundHighlights(LLDrawable* drawablep) } } +void LLPipeline::touchTextures(LLDrawInfo* info) +{ + LL_PROFILE_ZONE_SCOPED; + for (auto& tex : info->mTextureList) + { + if (tex.notNull()) + { + LLImageGL* gl_tex = tex->getGLTexture(); + if (gl_tex && gl_tex->updateBindStats(gl_tex->mTextureMemory)) + { + tex->setActive(); + } + } + } + + if (info->mTexture.notNull()) + { + info->mTexture->addTextureStats(info->mVSize); + } +} + void LLPipeline::postSort(LLCamera& camera) { LL_RECORD_BLOCK_TIME(FTM_STATESORT_POSTSORT); @@ -3839,20 +3851,14 @@ void LLPipeline::postSort(LLCamera& camera) for (LLSpatialGroup::drawmap_elem_t::iterator k = src_vec.begin(); k != src_vec.end(); ++k) { - if (sMinRenderSize > 0.f) - { - LLVector4a bounds; - bounds.setSub((*k)->mExtents[1],(*k)->mExtents[0]); - - if (llmax(llmax(bounds[0], bounds[1]), bounds[2]) > sMinRenderSize) - { - sCull->pushDrawInfo(j->first, *k); - } - } - else - { - sCull->pushDrawInfo(j->first, *k); - } + LLDrawInfo* info = *k; + + sCull->pushDrawInfo(j->first, info); + if (!sShadowRender && !sReflectionRender) + { + touchTextures(info); + addTrianglesDrawn(info->mCount, info->mDrawMode); + } } } diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 5605d26410..8ffbddca21 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -265,6 +265,8 @@ public: void stateSort(LLSpatialBridge* bridge, LLCamera& camera, BOOL fov_changed = FALSE); void stateSort(LLDrawable* drawablep, LLCamera& camera); void postSort(LLCamera& camera); + //update stats for textures in given DrawInfo + void touchTextures(LLDrawInfo* info); void forAllVisibleDrawables(void (*func)(LLDrawable*)); void renderObjects(U32 type, U32 mask, bool texture = true, bool batch_texture = false); @@ -596,7 +598,6 @@ public: static bool sRenderAttachedParticles; static bool sRenderDeferred; static S32 sVisibleLightCount; - static F32 sMinRenderSize; static bool sRenderingHUDs; static F32 sDistortionWaterClipPlaneMargin; -- cgit v1.2.3 From 74a2354353813db529ae123858bafba86cd12110 Mon Sep 17 00:00:00 2001 From: Runitai Linden Date: Wed, 13 Oct 2021 09:37:04 -0500 Subject: SL-16166 Don't use setupVertexBuffer where setupVertexBufferFast is called for (thank you, Henri!) --- indra/llrender/llvertexbuffer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 7b9388123f..103d5388d3 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -2544,7 +2544,7 @@ void LLVertexBuffer::setBufferFast(U32 data_mask) if (data_mask && setup) { - setupVertexBuffer(data_mask); // subclass specific setup (virtual function) + setupVertexBufferFast(data_mask); sSetCount++; } } -- cgit v1.2.3 From a1e6cbe4a802f92182163171e6743e7f63d89ace Mon Sep 17 00:00:00 2001 From: Runitai Linden Date: Wed, 13 Oct 2021 10:35:39 -0500 Subject: SL-16166 Apply LLRenderPass::pushBatch optimizations to LLDrawPoolBump::pushBatch --- indra/llrender/llrender.cpp | 22 ++++++++++++++++++++++ indra/llrender/llrender.h | 3 +++ indra/newview/lldrawpool.cpp | 14 ++++++-------- indra/newview/lldrawpoolbump.cpp | 28 ++++++++-------------------- 4 files changed, 39 insertions(+), 28 deletions(-) diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 34c5b77944..91d3c96fbe 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -472,6 +472,28 @@ void LLTexUnit::unbind(eTextureType type) } } +void LLTexUnit::unbindFast(eTextureType type) +{ + activate(); + + // Disabled caching of binding state. + if (mCurrTexType == type) + { + mCurrTexture = 0; + + // Always make sure our texture color space is reset to linear. SRGB sampling should be opt-in in the vast majority of cases. Also prevents color space "popping". + mTexColorSpace = TCS_LINEAR; + if (type == LLTexUnit::TT_TEXTURE) + { + glBindTexture(sGLTextureType[type], sWhiteTexture); + } + else + { + glBindTexture(sGLTextureType[type], 0); + } + } +} + void LLTexUnit::setTextureAddressMode(eTextureAddressMode mode) { if (mIndex < 0 || mCurrTexture == 0) return; diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index 658cdda504..6e2647a16b 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -188,6 +188,9 @@ public: // (only if there's a texture of the given type currently bound) void unbind(eTextureType type); + // Fast but unsafe version of unbind + void unbindFast(eTextureType type); + // Sets the addressing mode used to sample the texture // Warning: this stays set for the bound texture forever, // make sure you want to permanently change the address mode for the bound texture. diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index 01dd307187..75d569ffbb 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -496,17 +496,15 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL ba } } + if (params.mGroup) { - if (params.mGroup) - { - params.mGroup->rebuildMesh(); - } + params.mGroup->rebuildMesh(); + } - LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test); + LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test); - params.mVertexBuffer->setBufferFast(mask); - params.mVertexBuffer->drawRangeFast(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); - } + params.mVertexBuffer->setBufferFast(mask); + params.mVertexBuffer->drawRangeFast(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); if (tex_setup) { diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index 14069fa6c2..7e2dfbfda1 100644 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -677,6 +677,7 @@ BOOL LLDrawPoolBump::bindBumpMap(LLFace* face, S32 channel) //static BOOL LLDrawPoolBump::bindBumpMap(U8 bump_code, LLViewerTexture* texture, F32 vsize, S32 channel) { + LL_PROFILE_ZONE_SCOPED; //Note: texture atlas does not support bump texture now. LLViewerFetchedTexture* tex = LLViewerTextureManager::staticCastToFetchedTexture(texture) ; if(!tex) @@ -1497,6 +1498,7 @@ void LLDrawPoolBump::renderBump(U32 type, U32 mask) void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures) { + LL_PROFILE_ZONE_SCOPED; applyModelMatrix(params); bool tex_setup = false; @@ -1507,7 +1509,7 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL { if (params.mTextureList[i].notNull()) { - gGL.getTexUnit(i)->bind(params.mTextureList[i], TRUE); + gGL.getTexUnit(i)->bindFast(params.mTextureList[i]); } } } @@ -1522,13 +1524,6 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL } else { - if (!LLGLSLShader::sNoFixedFunction) - { - gGL.getTexUnit(1)->activate(); - gGL.matrixMode(LLRender::MM_TEXTURE); - gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix); - } - gGL.getTexUnit(0)->activate(); gGL.matrixMode(LLRender::MM_TEXTURE); gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix); @@ -1545,8 +1540,7 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL { if (params.mTexture.notNull()) { - gGL.getTexUnit(diffuse_channel)->bind(params.mTexture); - params.mTexture->addTextureStats(params.mVSize); + gGL.getTexUnit(diffuse_channel)->bindFast(params.mTexture); } else { @@ -1559,10 +1553,10 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL { params.mGroup->rebuildMesh(); } - params.mVertexBuffer->setBuffer(mask); - params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); - gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode); - if (tex_setup) + params.mVertexBuffer->setBufferFast(mask); + params.mVertexBuffer->drawRangeFast(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); + + if (tex_setup) { if (mShiny) { @@ -1570,12 +1564,6 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL } else { - if (!LLGLSLShader::sNoFixedFunction) - { - gGL.getTexUnit(1)->activate(); - gGL.matrixMode(LLRender::MM_TEXTURE); - gGL.loadIdentity(); - } gGL.getTexUnit(0)->activate(); gGL.matrixMode(LLRender::MM_TEXTURE); } -- cgit v1.2.3 From 4dedd706ae07c4a1aeedfe9ca0c03b7c905d0b57 Mon Sep 17 00:00:00 2001 From: Runitai Linden Date: Wed, 13 Oct 2021 11:02:00 -0500 Subject: SL-16189 Optimize bindBumpMap --- indra/newview/lldrawpoolbump.cpp | 8 ++++---- indra/newview/lldrawpoolbump.h | 4 +++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index 7e2dfbfda1..f316d121ab 100644 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -694,7 +694,7 @@ BOOL LLDrawPoolBump::bindBumpMap(U8 bump_code, LLViewerTexture* texture, F32 vsi break; case BE_BRIGHTNESS: case BE_DARKNESS: - bump = gBumpImageList.getBrightnessDarknessImage( tex, bump_code ); + bump = gBumpImageList.getBrightnessDarknessImage( tex, bump_code ); break; default: @@ -710,12 +710,12 @@ BOOL LLDrawPoolBump::bindBumpMap(U8 bump_code, LLViewerTexture* texture, F32 vsi { if (channel == -2) { - gGL.getTexUnit(1)->bind(bump); - gGL.getTexUnit(0)->bind(bump); + gGL.getTexUnit(1)->bindFast(bump); + gGL.getTexUnit(0)->bindFast(bump); } else { - gGL.getTexUnit(channel)->bind(bump); + gGL.getTexUnit(channel)->bindFast(bump); } return TRUE; diff --git a/indra/newview/lldrawpoolbump.h b/indra/newview/lldrawpoolbump.h index 476b1d41b7..bab160c34d 100644 --- a/indra/newview/lldrawpoolbump.h +++ b/indra/newview/lldrawpoolbump.h @@ -32,6 +32,8 @@ #include "lltextureentry.h" #include "lluuid.h" +#include + class LLImageRaw; class LLSpatialGroup; class LLDrawInfo; @@ -161,7 +163,7 @@ private: static void onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLImageRaw* src, LLUUID& source_asset_id, EBumpEffect bump ); private: - typedef std::map > bump_image_map_t; + typedef std::unordered_map > bump_image_map_t; bump_image_map_t mBrightnessEntries; bump_image_map_t mDarknessEntries; }; -- cgit v1.2.3 From 6a0b728bd9e75cbee62752033e6460a76e8b0ed6 Mon Sep 17 00:00:00 2001 From: Runitai Linden Date: Wed, 13 Oct 2021 13:49:24 -0500 Subject: SL-16166 Optimize LLDrawPoolMaterials::pushBatch --- indra/newview/lldrawpool.cpp | 2 +- indra/newview/lldrawpoolmaterials.cpp | 61 +++++++++++++++-------------------- indra/newview/lldrawpoolmaterials.h | 2 +- 3 files changed, 28 insertions(+), 37 deletions(-) diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index 75d569ffbb..3e4f97e494 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -491,7 +491,7 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL ba } else { - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(0)->unbindFast(LLTexUnit::TT_TEXTURE); } } } diff --git a/indra/newview/lldrawpoolmaterials.cpp b/indra/newview/lldrawpoolmaterials.cpp index d45e387e10..d2a8757379 100644 --- a/indra/newview/lldrawpoolmaterials.cpp +++ b/indra/newview/lldrawpoolmaterials.cpp @@ -158,7 +158,10 @@ void LLDrawPoolMaterials::renderDeferred(S32 pass) mShader->setMinimumAlpha(params.mAlphaMaskCutoff); mShader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, params.mFullbright ? 1.f : 0.f); - pushBatch(params, mask, TRUE); + { + LL_PROFILE_ZONE_SCOPED; + pushMaterialsBatch(params, mask); + } } } @@ -172,49 +175,37 @@ void LLDrawPoolMaterials::bindNormalMap(LLViewerTexture* tex) mShader->bindTexture(LLShaderMgr::BUMP_MAP, tex); } -void LLDrawPoolMaterials::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures) +void LLDrawPoolMaterials::pushMaterialsBatch(LLDrawInfo& params, U32 mask) { + LL_PROFILE_ZONE_SCOPED; applyModelMatrix(params); bool tex_setup = false; - if (batch_textures && params.mTextureList.size() > 1) + //not batching textures or batch has only 1 texture -- might need a texture matrix + if (params.mTextureMatrix) { - for (U32 i = 0; i < params.mTextureList.size(); ++i) + //if (mShiny) { - if (params.mTextureList[i].notNull()) - { - gGL.getTexUnit(i)->bind(params.mTextureList[i], TRUE); - } + gGL.getTexUnit(0)->activate(); + gGL.matrixMode(LLRender::MM_TEXTURE); } - } - else - { //not batching textures or batch has only 1 texture -- might need a texture matrix - if (params.mTextureMatrix) - { - //if (mShiny) - { - gGL.getTexUnit(0)->activate(); - gGL.matrixMode(LLRender::MM_TEXTURE); - } - gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix); - gPipeline.mTextureMatrixOps++; + gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix); + gPipeline.mTextureMatrixOps++; - tex_setup = true; - } + tex_setup = true; + } - if (mShaderLevel > 1 && texture) + if (mShaderLevel > 1) + { + if (params.mTexture.notNull()) + { + gGL.getTexUnit(diffuse_channel)->bindFast(params.mTexture); + } + else { - if (params.mTexture.notNull()) - { - gGL.getTexUnit(diffuse_channel)->bind(params.mTexture); - params.mTexture->addTextureStats(params.mVSize); - } - else - { - gGL.getTexUnit(diffuse_channel)->unbind(LLTexUnit::TT_TEXTURE); - } + gGL.getTexUnit(diffuse_channel)->unbindFast(LLTexUnit::TT_TEXTURE); } } @@ -225,9 +216,9 @@ void LLDrawPoolMaterials::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test); - params.mVertexBuffer->setBuffer(mask); - params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); - gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode); + params.mVertexBuffer->setBufferFast(mask); + params.mVertexBuffer->drawRangeFast(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); + if (tex_setup) { gGL.getTexUnit(0)->activate(); diff --git a/indra/newview/lldrawpoolmaterials.h b/indra/newview/lldrawpoolmaterials.h index eae1aba87c..6e39821b07 100644 --- a/indra/newview/lldrawpoolmaterials.h +++ b/indra/newview/lldrawpoolmaterials.h @@ -69,7 +69,7 @@ public: void bindSpecularMap(LLViewerTexture* tex); void bindNormalMap(LLViewerTexture* tex); - /*virtual*/ void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures = FALSE); + /*virtual*/ void pushMaterialsBatch(LLDrawInfo& params, U32 mask); }; #endif //LL_LLDRAWPOOLMATERIALS_H -- cgit v1.2.3 From aa2169aa372492b3a5367997536fb6dfa89b74cf Mon Sep 17 00:00:00 2001 From: Runitai Linden Date: Wed, 13 Oct 2021 13:57:56 -0500 Subject: SL-16166 Remove LLDrawPoolGlow::pushBatch non-specialization --- indra/newview/lldrawpoolsimple.cpp | 7 ------- indra/newview/lldrawpoolsimple.h | 1 - 2 files changed, 8 deletions(-) diff --git a/indra/newview/lldrawpoolsimple.cpp b/indra/newview/lldrawpoolsimple.cpp index ba8549904b..843288cfb0 100644 --- a/indra/newview/lldrawpoolsimple.cpp +++ b/indra/newview/lldrawpoolsimple.cpp @@ -150,13 +150,6 @@ void LLDrawPoolGlow::render(S32 pass) } } -void LLDrawPoolGlow::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures) -{ - //gGL.diffuseColor4ubv(params.mGlowColor.mV); - LLRenderPass::pushBatch(params, mask, texture, batch_textures); -} - - LLDrawPoolSimple::LLDrawPoolSimple() : LLRenderPass(POOL_SIMPLE) { diff --git a/indra/newview/lldrawpoolsimple.h b/indra/newview/lldrawpoolsimple.h index 608ad9e1eb..b27cc4babc 100644 --- a/indra/newview/lldrawpoolsimple.h +++ b/indra/newview/lldrawpoolsimple.h @@ -187,7 +187,6 @@ public: /*virtual*/ S32 getNumPasses(); void render(S32 pass = 0); - void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture = TRUE, BOOL batch_textures = FALSE); }; -- cgit v1.2.3 From cbaba2df56c66926e051d50b6cb02955c81c2a6c Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 13 Oct 2021 16:52:44 -0400 Subject: Increment viewer version to 6.4.24 following promotion of DRTVWR-520 --- indra/newview/VIEWER_VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index 4c8366c864..f186cd8874 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -6.4.23 +6.4.24 -- cgit v1.2.3 From 851767b808c3cb05d718538389ccc1ed3c95d1a1 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 14 Oct 2021 17:41:38 +0000 Subject: SL-16131 Fix for alignment warnings on Win32 builds. --- indra/llcharacter/lleditingmotion.h | 18 +- indra/llcharacter/lljoint.h | 14 +- indra/llcharacter/llkeyframestandmotion.h | 28 +- indra/llcharacter/llpose.h | 6 +- indra/llcommon/llmemory.h | 13 + indra/llprimitive/llmodel.h | 10 +- indra/llwindow/llwindow.h | 1 + indra/media_plugins/cef/CMakeLists.txt | 3 - indra/newview/llviewertexture.h | 1592 ++++++++++++++--------------- 9 files changed, 854 insertions(+), 831 deletions(-) diff --git a/indra/llcharacter/lleditingmotion.h b/indra/llcharacter/lleditingmotion.h index 7b1c8bb059..80c1717a70 100644 --- a/indra/llcharacter/lleditingmotion.h +++ b/indra/llcharacter/lleditingmotion.h @@ -42,9 +42,11 @@ //----------------------------------------------------------------------------- // class LLEditingMotion //----------------------------------------------------------------------------- +LL_ALIGN_PREFIX(16) class LLEditingMotion : public LLMotion { + LL_ALIGN_NEW public: // Constructor LLEditingMotion(const LLUUID &id); @@ -108,6 +110,13 @@ public: //------------------------------------------------------------------------- // joint states to be animated //------------------------------------------------------------------------- + LL_ALIGN_16(LLJoint mParentJoint); + LL_ALIGN_16(LLJoint mShoulderJoint); + LL_ALIGN_16(LLJoint mElbowJoint); + LL_ALIGN_16(LLJoint mWristJoint); + LL_ALIGN_16(LLJoint mTarget); + LLJointSolverRP3 mIKSolver; + LLCharacter *mCharacter; LLVector3 mWristOffset; @@ -117,17 +126,10 @@ public: LLPointer mWristState; LLPointer mTorsoState; - LLJoint mParentJoint; - LLJoint mShoulderJoint; - LLJoint mElbowJoint; - LLJoint mWristJoint; - LLJoint mTarget; - LLJointSolverRP3 mIKSolver; - static S32 sHandPose; static S32 sHandPosePriority; LLVector3 mLastSelectPt; -}; +} LL_ALIGN_POSTFIX(16); #endif // LL_LLKEYFRAMEMOTION_H diff --git a/indra/llcharacter/lljoint.h b/indra/llcharacter/lljoint.h index ba821667c7..63d99b9209 100644 --- a/indra/llcharacter/lljoint.h +++ b/indra/llcharacter/lljoint.h @@ -86,8 +86,10 @@ inline bool operator!=(const LLVector3OverrideMap& a, const LLVector3OverrideMap //----------------------------------------------------------------------------- // class LLJoint //----------------------------------------------------------------------------- +LL_ALIGN_PREFIX(16) class LLJoint { + LL_ALIGN_NEW public: // priority levels, from highest to lowest enum JointPriority @@ -115,17 +117,17 @@ public: SUPPORT_EXTENDED }; protected: - std::string mName; + // explicit transformation members + LL_ALIGN_16(LLMatrix4a mWorldMatrix); + LLXformMatrix mXform; + + std::string mName; SupportCategory mSupport; // parent joint LLJoint *mParent; - // explicit transformation members - LLXformMatrix mXform; - LLMatrix4a mWorldMatrix; - LLVector3 mDefaultPosition; LLVector3 mDefaultScale; @@ -300,6 +302,6 @@ public: // These are used in checks of whether a pos/scale override is considered significant. bool aboveJointPosThreshold(const LLVector3& pos) const; bool aboveJointScaleThreshold(const LLVector3& scale) const; -}; +} LL_ALIGN_POSTFIX(16); #endif // LL_LLJOINT_H diff --git a/indra/llcharacter/llkeyframestandmotion.h b/indra/llcharacter/llkeyframestandmotion.h index c2634ecd6d..1aa5b187ba 100644 --- a/indra/llcharacter/llkeyframestandmotion.h +++ b/indra/llcharacter/llkeyframestandmotion.h @@ -37,9 +37,11 @@ //----------------------------------------------------------------------------- // class LLKeyframeStandMotion //----------------------------------------------------------------------------- +LL_ALIGN_PREFIX(16) class LLKeyframeStandMotion : public LLKeyframeMotion { + LL_ALIGN_NEW public: // Constructor LLKeyframeStandMotion(const LLUUID &id); @@ -69,6 +71,18 @@ public: //------------------------------------------------------------------------- // Member Data //------------------------------------------------------------------------- + LLJoint mPelvisJoint; + + LLJoint mHipLeftJoint; + LLJoint mKneeLeftJoint; + LLJoint mAnkleLeftJoint; + LLJoint mTargetLeft; + + LLJoint mHipRightJoint; + LLJoint mKneeRightJoint; + LLJoint mAnkleRightJoint; + LLJoint mTargetRight; + LLCharacter *mCharacter; BOOL mFlipFeet; @@ -83,18 +97,6 @@ public: LLPointer mKneeRightState; LLPointer mAnkleRightState; - LLJoint mPelvisJoint; - - LLJoint mHipLeftJoint; - LLJoint mKneeLeftJoint; - LLJoint mAnkleLeftJoint; - LLJoint mTargetLeft; - - LLJoint mHipRightJoint; - LLJoint mKneeRightJoint; - LLJoint mAnkleRightJoint; - LLJoint mTargetRight; - LLJointSolverRP3 mIKLeft; LLJointSolverRP3 mIKRight; @@ -110,7 +112,7 @@ public: BOOL mTrackAnkles; S32 mFrameNum; -}; +} LL_ALIGN_POSTFIX(16); #endif // LL_LLKEYFRAMESTANDMOTION_H diff --git a/indra/llcharacter/llpose.h b/indra/llcharacter/llpose.h index c004a0f3b7..1405f1e053 100644 --- a/indra/llcharacter/llpose.h +++ b/indra/llcharacter/llpose.h @@ -80,8 +80,10 @@ public: const S32 JSB_NUM_JOINT_STATES = 6; +LL_ALIGN_PREFIX(16) class LLJointStateBlender { + LL_ALIGN_NEW protected: LLPointer mJointStates[JSB_NUM_JOINT_STATES]; S32 mPriorities[JSB_NUM_JOINT_STATES]; @@ -96,8 +98,8 @@ public: void resetCachedJoint(); public: - LLJoint mJointCache; -}; + LL_ALIGN_16(LLJoint mJointCache); +} LL_ALIGN_POSTFIX(16); class LLMotion; diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h index 24f86cc11e..2704a495e0 100644 --- a/indra/llcommon/llmemory.h +++ b/indra/llcommon/llmemory.h @@ -101,6 +101,19 @@ template T* LL_NEXT_ALIGNED_ADDRESS_64(T* address) #define LL_ALIGN_16(var) LL_ALIGN_PREFIX(16) var LL_ALIGN_POSTFIX(16) +#define LL_ALIGN_NEW \ +public: \ + void* operator new(size_t size) \ + { \ + return ll_aligned_malloc_16(size); \ + } \ + \ + void operator delete(void* ptr) \ + { \ + ll_aligned_free_16(ptr); \ + } + + //------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------ // for enable buffer overrun detection predefine LL_DEBUG_BUFFER_OVERRUN in current library diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index 96d4582b4f..cd2b6c6728 100644 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -40,8 +40,10 @@ class domMesh; #define MAX_MODEL_FACES 8 +LL_ALIGN_PREFIX(16) class LLMeshSkinInfo { + LL_ALIGN_NEW public: LLMeshSkinInfo(); LLMeshSkinInfo(LLSD& data); @@ -55,15 +57,17 @@ public: matrix_list_t mInvBindMatrix; matrix_list_t mAlternateBindMatrix; - LLMatrix4a mBindShapeMatrix; + LL_ALIGN_16(LLMatrix4a mBindShapeMatrix); float mPelvisOffset; bool mLockScaleIfJointPosition; bool mInvalidJointsScrubbed; bool mJointNumsInitialized; -}; +} LL_ALIGN_POSTFIX(16); +LL_ALIGN_PREFIX(16) class LLModel : public LLVolume { + LL_ALIGN_NEW public: enum @@ -285,7 +289,7 @@ public: EModelStatus mStatus ; int mSubmodelID; -}; +} LL_ALIGN_POSTFIX(16); typedef std::vector > model_list; typedef std::queue > model_queue; diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h index 10c0b6a424..0100c3bf0a 100644 --- a/indra/llwindow/llwindow.h +++ b/indra/llwindow/llwindow.h @@ -88,6 +88,7 @@ public: //Must be called on the same thread that called createSharedContext() virtual void destroySharedContext(void* context) = 0; + virtual BOOL setCursorPosition(LLCoordWindow position) = 0; virtual BOOL getCursorPosition(LLCoordWindow *position) = 0; virtual void showCursor() = 0; diff --git a/indra/media_plugins/cef/CMakeLists.txt b/indra/media_plugins/cef/CMakeLists.txt index ce6278963d..76d398576c 100644 --- a/indra/media_plugins/cef/CMakeLists.txt +++ b/indra/media_plugins/cef/CMakeLists.txt @@ -111,9 +111,6 @@ if (DARWIN) LINK_FLAGS "-exported_symbols_list ${CMAKE_CURRENT_SOURCE_DIR}/../base/media_plugin_base.exp" ) - ## turns on C++11 using Cmake - target_compile_features(media_plugin_cef PRIVATE cxx_range_for) - add_custom_command(TARGET media_plugin_cef POST_BUILD COMMAND ${CMAKE_INSTALL_NAME_TOOL} -change "@executable_path/Chromium Embedded Framework" "@executable_path/../../../../Frameworks/Chromium Embedded Framework.framework/Chromium Embedded Framework" diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index a5a1fb2c16..b6b4d1e41f 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -1,796 +1,796 @@ -/** - * @file llviewertexture.h - * @brief Object for managing images and their textures - * - * $LicenseInfo:firstyear=2000&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_LLVIEWERTEXTURE_H -#define LL_LLVIEWERTEXTURE_H - -#include "llgltexture.h" -#include "lltimer.h" -#include "llframetimer.h" -#include "llhost.h" -#include "llgltypes.h" -#include "llrender.h" -#include "llmetricperformancetester.h" -#include "httpcommon.h" - -#include -#include - -extern const S32Megabytes gMinVideoRam; -extern const S32Megabytes gMaxVideoRam; - -class LLFace; -class LLImageGL ; -class LLImageRaw; -class LLViewerObject; -class LLViewerTexture; -class LLViewerFetchedTexture ; -class LLViewerMediaTexture ; -class LLTexturePipelineTester ; - - -typedef void (*loaded_callback_func)( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata ); - -class LLVFile; -class LLMessageSystem; -class LLViewerMediaImpl ; -class LLVOVolume ; -struct LLTextureKey; - -class LLLoadedCallbackEntry -{ -public: - typedef std::set< LLTextureKey > source_callback_list_t; - -public: - LLLoadedCallbackEntry(loaded_callback_func cb, - S32 discard_level, - BOOL need_imageraw, // Needs image raw for the callback - void* userdata, - source_callback_list_t* src_callback_list, - LLViewerFetchedTexture* target, - BOOL pause); - ~LLLoadedCallbackEntry(); - void removeTexture(LLViewerFetchedTexture* tex) ; - - loaded_callback_func mCallback; - S32 mLastUsedDiscard; - S32 mDesiredDiscard; - BOOL mNeedsImageRaw; - BOOL mPaused; - void* mUserData; - source_callback_list_t* mSourceCallbackList; - -public: - static void cleanUpCallbackList(LLLoadedCallbackEntry::source_callback_list_t* callback_list) ; -}; - -class LLTextureBar; - -class LLViewerTexture : public LLGLTexture -{ -public: - enum - { - LOCAL_TEXTURE, - MEDIA_TEXTURE, - DYNAMIC_TEXTURE, - FETCHED_TEXTURE, - LOD_TEXTURE, - ATLAS_TEXTURE, - INVALID_TEXTURE_TYPE - }; - - typedef std::vector ll_face_list_t; - typedef std::vector ll_volume_list_t; - - -protected: - virtual ~LLViewerTexture(); - LOG_CLASS(LLViewerTexture); - -public: - static void initClass(); - static void updateClass(const F32 velocity, const F32 angular_velocity) ; - - LLViewerTexture(BOOL usemipmaps = TRUE); - LLViewerTexture(const LLUUID& id, BOOL usemipmaps) ; - LLViewerTexture(const LLImageRaw* raw, BOOL usemipmaps) ; - LLViewerTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps) ; - - virtual S8 getType() const; - virtual BOOL isMissingAsset() const ; - virtual void dump(); // debug info to LL_INFOS() - - virtual bool isViewerMediaTexture() const { return false; } - - /*virtual*/ bool bindDefaultImage(const S32 stage = 0) ; - /*virtual*/ bool bindDebugImage(const S32 stage = 0) ; - /*virtual*/ void forceImmediateUpdate() ; - /*virtual*/ bool isActiveFetching(); - - /*virtual*/ const LLUUID& getID() const { return mID; } - void setBoostLevel(S32 level); - S32 getBoostLevel() { return mBoostLevel; } - void setTextureListType(S32 tex_type) { mTextureListType = tex_type; } - S32 getTextureListType() { return mTextureListType; } - - void addTextureStats(F32 virtual_size, BOOL needs_gltexture = TRUE) const; - void resetTextureStats(); - void setMaxVirtualSizeResetInterval(S32 interval)const {mMaxVirtualSizeResetInterval = interval;} - void resetMaxVirtualSizeResetCounter()const {mMaxVirtualSizeResetCounter = mMaxVirtualSizeResetInterval;} - S32 getMaxVirtualSizeResetCounter() const { return mMaxVirtualSizeResetCounter; } - - virtual F32 getMaxVirtualSize() ; - - LLFrameTimer* getLastReferencedTimer() {return &mLastReferencedTimer ;} - - S32 getFullWidth() const { return mFullWidth; } - S32 getFullHeight() const { return mFullHeight; } - /*virtual*/ void setKnownDrawSize(S32 width, S32 height); - - virtual void addFace(U32 channel, LLFace* facep) ; - virtual void removeFace(U32 channel, LLFace* facep) ; - S32 getTotalNumFaces() const; - S32 getNumFaces(U32 ch) const; - const ll_face_list_t* getFaceList(U32 channel) const {llassert(channel < LLRender::NUM_TEXTURE_CHANNELS); return &mFaceList[channel];} - - virtual void addVolume(U32 channel, LLVOVolume* volumep); - virtual void removeVolume(U32 channel, LLVOVolume* volumep); - S32 getNumVolumes(U32 channel) const; - const ll_volume_list_t* getVolumeList(U32 channel) const { return &mVolumeList[channel]; } - - - virtual void setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) ; - BOOL isLargeImage() ; - - void setParcelMedia(LLViewerMediaTexture* media) {mParcelMedia = media;} - BOOL hasParcelMedia() const { return mParcelMedia != NULL;} - LLViewerMediaTexture* getParcelMedia() const { return mParcelMedia;} - - /*virtual*/ void updateBindStatsForTester() ; -protected: - void cleanup() ; - void init(bool firstinit) ; - void reorganizeFaceList() ; - void reorganizeVolumeList() ; - - void notifyAboutMissingAsset(); - void notifyAboutCreatingTexture(); - -private: - friend class LLBumpImageList; - friend class LLUIImageList; - - virtual void switchToCachedImage(); - - static bool isMemoryForTextureLow() ; - static bool isMemoryForTextureSuficientlyFree(); - static void getGPUMemoryForTextures(S32Megabytes &gpu, S32Megabytes &physical); - -protected: - LLUUID mID; - S32 mTextureListType; // along with mID identifies where to search for this texture in TextureList - - F32 mSelectedTime; // time texture was last selected - mutable F32 mMaxVirtualSize; // The largest virtual size of the image, in pixels - how much data to we need? - mutable S32 mMaxVirtualSizeResetCounter ; - mutable S32 mMaxVirtualSizeResetInterval; - mutable F32 mAdditionalDecodePriority; // priority add to mDecodePriority. - LLFrameTimer mLastReferencedTimer; - - ll_face_list_t mFaceList[LLRender::NUM_TEXTURE_CHANNELS]; //reverse pointer pointing to the faces using this image as texture - U32 mNumFaces[LLRender::NUM_TEXTURE_CHANNELS]; - LLFrameTimer mLastFaceListUpdateTimer ; - - ll_volume_list_t mVolumeList[LLRender::NUM_VOLUME_TEXTURE_CHANNELS]; - U32 mNumVolumes[LLRender::NUM_VOLUME_TEXTURE_CHANNELS]; - LLFrameTimer mLastVolumeListUpdateTimer; - - //do not use LLPointer here. - LLViewerMediaTexture* mParcelMedia ; - - static F32 sTexelPixelRatio; -public: - static const U32 sCurrentFileVersion; - static S32 sImageCount; - static S32 sRawCount; - static S32 sAuxCount; - static LLFrameTimer sEvaluationTimer; - static F32 sDesiredDiscardBias; - static F32 sDesiredDiscardScale; - static S32Bytes sBoundTextureMemory; - static S32Bytes sTotalTextureMemory; - static S32Megabytes sMaxBoundTextureMemory; - static S32Megabytes sMaxTotalTextureMem; - static S32Bytes sMaxDesiredTextureMem ; - static S8 sCameraMovingDiscardBias; - static F32 sCameraMovingBias; - static S32 sMaxSculptRez ; - static U32 sMinLargeImageSize ; - static U32 sMaxSmallImageSize ; - static bool sFreezeImageUpdates; - static F32 sCurrentTime ; - - enum EDebugTexels - { - DEBUG_TEXELS_OFF, - DEBUG_TEXELS_CURRENT, - DEBUG_TEXELS_DESIRED, - DEBUG_TEXELS_FULL - }; - - static EDebugTexels sDebugTexelsMode; - - static LLPointer sNullImagep; // Null texture for non-textured objects. - static LLPointer sBlackImagep; // Texture to show NOTHING (pure black) - static LLPointer sCheckerBoardImagep; // Texture to show NOTHING (pure black) -}; - - -enum FTType -{ - FTT_UNKNOWN = -1, - FTT_DEFAULT = 0, // standard texture fetched by id. - FTT_SERVER_BAKE, // texture produced by appearance service and fetched from there. - FTT_HOST_BAKE, // old-style baked texture uploaded by viewer and fetched from avatar's host. - FTT_MAP_TILE, // tiles are fetched from map server directly. - FTT_LOCAL_FILE // fetch directly from a local file. -}; - -const std::string& fttype_to_string(const FTType& fttype); - -// -//textures are managed in gTextureList. -//raw image data is fetched from remote or local cache -//but the raw image this texture pointing to is fixed. -// -class LLViewerFetchedTexture : public LLViewerTexture -{ - friend class LLTextureBar; // debug info only - friend class LLTextureView; // debug info only - -protected: - /*virtual*/ ~LLViewerFetchedTexture(); -public: - LLViewerFetchedTexture(const LLUUID& id, FTType f_type, const LLHost& host = LLHost(), BOOL usemipmaps = TRUE); - LLViewerFetchedTexture(const LLImageRaw* raw, FTType f_type, BOOL usemipmaps); - LLViewerFetchedTexture(const std::string& url, FTType f_type, const LLUUID& id, BOOL usemipmaps = TRUE); - -public: - static F32 maxDecodePriority(); - - struct Compare - { - // lhs < rhs - bool operator()(const LLPointer &lhs, const LLPointer &rhs) const - { - const LLViewerFetchedTexture* lhsp = (const LLViewerFetchedTexture*)lhs; - const LLViewerFetchedTexture* rhsp = (const LLViewerFetchedTexture*)rhs; - // greater priority is "less" - const F32 lpriority = lhsp->getDecodePriority(); - const F32 rpriority = rhsp->getDecodePriority(); - if (lpriority > rpriority) // higher priority - return true; - if (lpriority < rpriority) - return false; - return lhsp < rhsp; - } - }; - -public: - /*virtual*/ S8 getType() const ; - FTType getFTType() const; - /*virtual*/ void forceImmediateUpdate() ; - /*virtual*/ void dump() ; - - // Set callbacks to get called when the image gets updated with higher - // resolution versions. - void setLoadedCallback(loaded_callback_func cb, - S32 discard_level, BOOL keep_imageraw, BOOL needs_aux, - void* userdata, LLLoadedCallbackEntry::source_callback_list_t* src_callback_list, BOOL pause = FALSE); - bool hasCallbacks() { return mLoadedCallbackList.empty() ? false : true; } - void pauseLoadedCallbacks(const LLLoadedCallbackEntry::source_callback_list_t* callback_list); - void unpauseLoadedCallbacks(const LLLoadedCallbackEntry::source_callback_list_t* callback_list); - bool doLoadedCallbacks(); - void deleteCallbackEntry(const LLLoadedCallbackEntry::source_callback_list_t* callback_list); - void clearCallbackEntryList() ; - - void addToCreateTexture(); - - //call to determine if createTexture is necessary - BOOL preCreateTexture(S32 usename = 0); - // ONLY call from LLViewerTextureList or ImageGL background thread - BOOL createTexture(S32 usename = 0); - void postCreateTexture(); - void scheduleCreateTexture(); - - void destroyTexture() ; - - virtual void processTextureStats() ; - F32 calcDecodePriority() ; - - BOOL needsAux() const { return mNeedsAux; } - - // Host we think might have this image, used for baked av textures. - void setTargetHost(LLHost host) { mTargetHost = host; } - LLHost getTargetHost() const { return mTargetHost; } - - // Set the decode priority for this image... - // DON'T CALL THIS UNLESS YOU KNOW WHAT YOU'RE DOING, it can mess up - // the priority list, and cause horrible things to happen. - void setDecodePriority(F32 priority = -1.0f); - F32 getDecodePriority() const { return mDecodePriority; }; - F32 getAdditionalDecodePriority() const { return mAdditionalDecodePriority; }; - - void setAdditionalDecodePriority(F32 priority) ; - - void updateVirtualSize() ; - - S32 getDesiredDiscardLevel() { return mDesiredDiscardLevel; } - void setMinDiscardLevel(S32 discard) { mMinDesiredDiscardLevel = llmin(mMinDesiredDiscardLevel,(S8)discard); } - - bool updateFetch(); - bool setDebugFetching(S32 debug_level); - bool isInDebug() const { return mInDebug; } - - void setUnremovable(BOOL value) { mUnremovable = value; } - bool isUnremovable() const { return mUnremovable; } - - void clearFetchedResults(); //clear all fetched results, for debug use. - - // Override the computation of discard levels if we know the exact output - // size of the image. Used for UI textures to not decode, even if we have - // more data. - /*virtual*/ void setKnownDrawSize(S32 width, S32 height); - - void setIsMissingAsset(BOOL is_missing = true); - /*virtual*/ BOOL isMissingAsset() const { return mIsMissingAsset; } - - // returns dimensions of original image for local files (before power of two scaling) - // and returns 0 for all asset system images - S32 getOriginalWidth() { return mOrigWidth; } - S32 getOriginalHeight() { return mOrigHeight; } - - BOOL isInImageList() const {return mInImageList ;} - void setInImageList(BOOL flag) {mInImageList = flag ;} - - LLFrameTimer* getLastPacketTimer() {return &mLastPacketTimer;} - - U32 getFetchPriority() const { return mFetchPriority ;} - F32 getDownloadProgress() const {return mDownloadProgress ;} - - LLImageRaw* reloadRawImage(S8 discard_level) ; - void destroyRawImage(); - bool needsToSaveRawImage(); - - const std::string& getUrl() const {return mUrl;} - //--------------- - BOOL isDeleted() ; - BOOL isInactive() ; - BOOL isDeletionCandidate(); - void setDeletionCandidate() ; - void setInactive() ; - BOOL getUseDiscard() const { return mUseMipMaps && !mDontDiscard; } - //--------------- - - void setForSculpt(); - BOOL forSculpt() const {return mForSculpt;} - BOOL isForSculptOnly() const; - - //raw image management - void checkCachedRawSculptImage() ; - LLImageRaw* getRawImage()const { return mRawImage ;} - S32 getRawImageLevel() const {return mRawDiscardLevel;} - LLImageRaw* getCachedRawImage() const { return mCachedRawImage ;} - S32 getCachedRawImageLevel() const {return mCachedRawDiscardLevel;} - BOOL isCachedRawImageReady() const {return mCachedRawImageReady ;} - BOOL isRawImageValid()const { return mIsRawImageValid ; } - void forceToSaveRawImage(S32 desired_discard = 0, F32 kept_time = 0.f) ; - void forceToRefetchTexture(S32 desired_discard = 0, F32 kept_time = 60.f); - /*virtual*/ void setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) ; - void destroySavedRawImage() ; - LLImageRaw* getSavedRawImage() ; - BOOL hasSavedRawImage() const ; - F32 getElapsedLastReferencedSavedRawImageTime() const ; - BOOL isFullyLoaded() const; - - BOOL hasFetcher() const { return mHasFetcher;} - void setCanUseHTTP(bool can_use_http) {mCanUseHTTP = can_use_http;} - - void forceToDeleteRequest(); - void loadFromFastCache(); - void setInFastCacheList(bool in_list) { mInFastCacheList = in_list; } - bool isInFastCacheList() { return mInFastCacheList; } - - /*virtual*/bool isActiveFetching(); //is actively in fetching by the fetching pipeline. - -protected: - /*virtual*/ void switchToCachedImage(); - S32 getCurrentDiscardLevelForFetching() ; - -private: - void init(bool firstinit) ; - void cleanup() ; - - void saveRawImage() ; - void setCachedRawImage() ; - - //for atlas - void resetFaceAtlas() ; - void invalidateAtlas(BOOL rebuild_geom) ; - BOOL insertToAtlas() ; - -private: - BOOL mFullyLoaded; - BOOL mInDebug; - BOOL mUnremovable; - BOOL mInFastCacheList; - BOOL mForceCallbackFetch; - -protected: - std::string mLocalFileName; - - S32 mOrigWidth; - S32 mOrigHeight; - - // Override the computation of discard levels if we know the exact output size of the image. - // Used for UI textures to not decode, even if we have more data. - S32 mKnownDrawWidth; - S32 mKnownDrawHeight; - BOOL mKnownDrawSizeChanged ; - std::string mUrl; - - S32 mRequestedDiscardLevel; - F32 mRequestedDownloadPriority; - S32 mFetchState; - U32 mFetchPriority; - F32 mDownloadProgress; - F32 mFetchDeltaTime; - F32 mRequestDeltaTime; - F32 mDecodePriority; // The priority for decoding this image. - S32 mMinDiscardLevel; - S8 mDesiredDiscardLevel; // The discard level we'd LIKE to have - if we have it and there's space - S8 mMinDesiredDiscardLevel; // The minimum discard level we'd like to have - - S8 mNeedsAux; // We need to decode the auxiliary channels - S8 mHasAux; // We have aux channels - S8 mDecodingAux; // Are we decoding high components - S8 mIsRawImageValid; - S8 mHasFetcher; // We've made a fecth request - S8 mIsFetching; // Fetch request is active - bool mCanUseHTTP; //This texture can be fetched through http if true. - LLCore::HttpStatus mLastHttpGetStatus; // Result of the most recently completed http request for this texture. - - FTType mFTType; // What category of image is this - map tile, server bake, etc? - mutable S8 mIsMissingAsset; // True if we know that there is no image asset with this image id in the database. - - typedef std::list callback_list_t; - S8 mLoadedCallbackDesiredDiscardLevel; - BOOL mPauseLoadedCallBacks; - callback_list_t mLoadedCallbackList; - F32 mLastCallBackActiveTime; - - LLPointer mRawImage; - S32 mRawDiscardLevel; - - // Used ONLY for cloth meshes right now. Make SURE you know what you're - // doing if you use it for anything else! - djs - LLPointer mAuxRawImage; - - //keep a copy of mRawImage for some special purposes - //when mForceToSaveRawImage is set. - BOOL mForceToSaveRawImage ; - BOOL mSaveRawImage; - LLPointer mSavedRawImage; - S32 mSavedRawDiscardLevel; - S32 mDesiredSavedRawDiscardLevel; - F32 mLastReferencedSavedRawImageTime ; - F32 mKeptSavedRawImageTime ; - - //a small version of the copy of the raw image (<= 64 * 64) - LLPointer mCachedRawImage; - S32 mCachedRawDiscardLevel; - BOOL mCachedRawImageReady; //the rez of the mCachedRawImage reaches the upper limit. - - LLHost mTargetHost; // if invalid, just request from agent's simulator - - // Timers - LLFrameTimer mLastPacketTimer; // Time since last packet. - LLFrameTimer mStopFetchingTimer; // Time since mDecodePriority == 0.f. - - BOOL mInImageList; // TRUE if image is in list (in which case don't reset priority!) - BOOL mNeedsCreateTexture; - - BOOL mForSculpt ; //a flag if the texture is used as sculpt data. - BOOL mIsFetched ; //is loaded from remote or from cache, not generated locally. - -public: - static LLPointer sMissingAssetImagep; // Texture to show for an image asset that is not in the database - static LLPointer sWhiteImagep; // Texture to show NOTHING (whiteness) - static LLPointer sDefaultImagep; // "Default" texture for error cases, the only case of fetched texture which is generated in local. - static LLPointer sSmokeImagep; // Old "Default" translucent texture - static LLPointer sFlatNormalImagep; // Flat normal map denoting no bumpiness on a surface -}; - -// -//the image data is fetched from remote or from local cache -//the resolution of the texture is adjustable: depends on the view-dependent parameters. -// -class LLViewerLODTexture : public LLViewerFetchedTexture -{ -protected: - /*virtual*/ ~LLViewerLODTexture(){} - -public: - LLViewerLODTexture(const LLUUID& id, FTType f_type, const LLHost& host = LLHost(), BOOL usemipmaps = TRUE); - LLViewerLODTexture(const std::string& url, FTType f_type, const LLUUID& id, BOOL usemipmaps = TRUE); - - /*virtual*/ S8 getType() const; - // Process image stats to determine priority/quality requirements. - /*virtual*/ void processTextureStats(); - bool isUpdateFrozen() ; - -private: - void init(bool firstinit) ; - bool scaleDown() ; - -private: - F32 mDiscardVirtualSize; // Virtual size used to calculate desired discard - F32 mCalculatedDiscardLevel; // Last calculated discard level -}; - -// -//the image data is fetched from the media pipeline periodically -//the resolution of the texture is also adjusted by the media pipeline -// -class LLViewerMediaTexture : public LLViewerTexture -{ -protected: - /*virtual*/ ~LLViewerMediaTexture() ; - -public: - LLViewerMediaTexture(const LLUUID& id, BOOL usemipmaps = TRUE, LLImageGL* gl_image = NULL) ; - - /*virtual*/ S8 getType() const; - void reinit(BOOL usemipmaps = TRUE); - - BOOL getUseMipMaps() {return mUseMipMaps ; } - void setUseMipMaps(BOOL mipmap) ; - - void setPlaying(BOOL playing) ; - BOOL isPlaying() const {return mIsPlaying;} - void setMediaImpl() ; - - virtual bool isViewerMediaTexture() const { return true; } - - void initVirtualSize() ; - void invalidateMediaImpl() ; - - void addMediaToFace(LLFace* facep) ; - void removeMediaFromFace(LLFace* facep) ; - - /*virtual*/ void addFace(U32 ch, LLFace* facep) ; - /*virtual*/ void removeFace(U32 ch, LLFace* facep) ; - - /*virtual*/ F32 getMaxVirtualSize() ; -private: - void switchTexture(U32 ch, LLFace* facep) ; - BOOL findFaces() ; - void stopPlaying() ; - -private: - // - //an instant list, recording all faces referencing or can reference to this media texture. - //NOTE: it is NOT thread safe. - // - std::list< LLFace* > mMediaFaceList ; - - //an instant list keeping all textures which are replaced by the current media texture, - //is only used to avoid the removal of those textures from memory. - std::list< LLPointer > mTextureList ; - - LLViewerMediaImpl* mMediaImplp ; - BOOL mIsPlaying ; - U32 mUpdateVirtualSizeTime ; - -public: - static void updateClass() ; - static void cleanUpClass() ; - - static LLViewerMediaTexture* findMediaTexture(const LLUUID& media_id) ; - static void removeMediaImplFromTexture(const LLUUID& media_id) ; - -private: - typedef std::map< LLUUID, LLPointer > media_map_t ; - static media_map_t sMediaMap ; -}; - -//just an interface class, do not create instance from this class. -class LLViewerTextureManager -{ -private: - //make the constructor private to preclude creating instances from this class. - LLViewerTextureManager(){} - -public: - //texture pipeline tester - static LLTexturePipelineTester* sTesterp ; - - //returns NULL if tex is not a LLViewerFetchedTexture nor derived from LLViewerFetchedTexture. - static LLViewerFetchedTexture* staticCastToFetchedTexture(LLTexture* tex, BOOL report_error = FALSE) ; - - // - //"find-texture" just check if the texture exists, if yes, return it, otherwise return null. - // - static void findFetchedTextures(const LLUUID& id, std::vector &output); - static void findTextures(const LLUUID& id, std::vector &output); - static LLViewerFetchedTexture* findFetchedTexture(const LLUUID& id, S32 tex_type); - static LLViewerMediaTexture* findMediaTexture(const LLUUID& id) ; - - static LLViewerMediaTexture* createMediaTexture(const LLUUID& id, BOOL usemipmaps = TRUE, LLImageGL* gl_image = NULL) ; - - // - //"get-texture" will create a new texture if the texture does not exist. - // - static LLViewerMediaTexture* getMediaTexture(const LLUUID& id, BOOL usemipmaps = TRUE, LLImageGL* gl_image = NULL) ; - - static LLPointer getLocalTexture(BOOL usemipmaps = TRUE, BOOL generate_gl_tex = TRUE); - static LLPointer getLocalTexture(const LLUUID& id, BOOL usemipmaps, BOOL generate_gl_tex = TRUE) ; - static LLPointer getLocalTexture(const LLImageRaw* raw, BOOL usemipmaps) ; - static LLPointer getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex = TRUE) ; - - static LLViewerFetchedTexture* getFetchedTexture(const LLUUID &image_id, - FTType f_type = FTT_DEFAULT, - BOOL usemipmap = TRUE, - LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE, // Get the requested level immediately upon creation. - S8 texture_type = LLViewerTexture::FETCHED_TEXTURE, - LLGLint internal_format = 0, - LLGLenum primary_format = 0, - LLHost request_from_host = LLHost() - ); - - static LLViewerFetchedTexture* getFetchedTextureFromFile(const std::string& filename, - FTType f_type = FTT_LOCAL_FILE, - BOOL usemipmap = TRUE, - LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE, - S8 texture_type = LLViewerTexture::FETCHED_TEXTURE, - LLGLint internal_format = 0, - LLGLenum primary_format = 0, - const LLUUID& force_id = LLUUID::null - ); - - static LLViewerFetchedTexture* getFetchedTextureFromUrl(const std::string& url, - FTType f_type, - BOOL usemipmap = TRUE, - LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE, - S8 texture_type = LLViewerTexture::FETCHED_TEXTURE, - LLGLint internal_format = 0, - LLGLenum primary_format = 0, - const LLUUID& force_id = LLUUID::null - ); - - static LLViewerFetchedTexture* getFetchedTextureFromHost(const LLUUID& image_id, FTType f_type, LLHost host) ; - - static void init() ; - static void cleanup() ; -}; -// -//this class is used for test/debug only -//it tracks the activities of the texture pipeline -//records them, and outputs them to log files -// -class LLTexturePipelineTester : public LLMetricPerformanceTesterWithSession -{ - enum - { - MIN_LARGE_IMAGE_AREA = 262144 //512 * 512 - }; -public: - LLTexturePipelineTester() ; - ~LLTexturePipelineTester() ; - - void update(); - void updateTextureBindingStats(const LLViewerTexture* imagep) ; - void updateTextureLoadingStats(const LLViewerFetchedTexture* imagep, const LLImageRaw* raw_imagep, BOOL from_cache) ; - void updateGrayTextureBinding() ; - void setStablizingTime() ; - -private: - void reset() ; - void updateStablizingTime() ; - - /*virtual*/ void outputTestRecord(LLSD* sd) ; - -private: - BOOL mPause ; -private: - BOOL mUsingDefaultTexture; //if set, some textures are still gray. - - U32Bytes mTotalBytesUsed ; //total bytes of textures bound/used for the current frame. - U32Bytes mTotalBytesUsedForLargeImage ; //total bytes of textures bound/used for the current frame for images larger than 256 * 256. - U32Bytes mLastTotalBytesUsed ; //total bytes of textures bound/used for the previous frame. - U32Bytes mLastTotalBytesUsedForLargeImage ; //total bytes of textures bound/used for the previous frame for images larger than 256 * 256. - - // - //data size - // - U32Bytes mTotalBytesLoaded ; //total bytes fetched by texture pipeline - U32Bytes mTotalBytesLoadedFromCache ; //total bytes fetched by texture pipeline from local cache - U32Bytes mTotalBytesLoadedForLargeImage ; //total bytes fetched by texture pipeline for images larger than 256 * 256. - U32Bytes mTotalBytesLoadedForSculpties ; //total bytes fetched by texture pipeline for sculpties - - // - //time - //NOTE: the error tolerances of the following timers is one frame time. - // - F32 mStartFetchingTime ; - F32 mTotalGrayTime ; //total loading time when no gray textures. - F32 mTotalStablizingTime ; //total stablizing time when texture memory overflows - F32 mStartTimeLoadingSculpties ; //the start moment of loading sculpty images. - F32 mEndTimeLoadingSculpties ; //the end moment of loading sculpty images. - F32 mStartStablizingTime ; - F32 mEndStablizingTime ; - -private: - // - //The following members are used for performance analyzing - // - class LLTextureTestSession : public LLTestSession - { - public: - LLTextureTestSession() ; - /*virtual*/ ~LLTextureTestSession() ; - - void reset() ; - - F32 mTotalFetchingTime ; - F32 mTotalGrayTime ; - F32 mTotalStablizingTime ; - F32 mStartTimeLoadingSculpties ; - F32 mTotalTimeLoadingSculpties ; - - S32 mTotalBytesLoaded ; - S32 mTotalBytesLoadedFromCache ; - S32 mTotalBytesLoadedForLargeImage ; - S32 mTotalBytesLoadedForSculpties ; - - typedef struct _texture_instant_preformance_t - { - S32 mAverageBytesUsedPerSecond ; - S32 mAverageBytesUsedForLargeImagePerSecond ; - F32 mAveragePercentageBytesUsedPerSecond ; - F32 mTime ; - }texture_instant_preformance_t ; - std::vector mInstantPerformanceList ; - S32 mInstantPerformanceListCounter ; - }; - - /*virtual*/ LLMetricPerformanceTesterWithSession::LLTestSession* loadTestSession(LLSD* log) ; - /*virtual*/ void compareTestSessions(llofstream* os) ; -}; - -#endif +/** + * @file llviewertexture.h + * @brief Object for managing images and their textures + * + * $LicenseInfo:firstyear=2000&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_LLVIEWERTEXTURE_H +#define LL_LLVIEWERTEXTURE_H + +#include "llgltexture.h" +#include "lltimer.h" +#include "llframetimer.h" +#include "llhost.h" +#include "llgltypes.h" +#include "llrender.h" +#include "llmetricperformancetester.h" +#include "httpcommon.h" + +#include +#include + +extern const S32Megabytes gMinVideoRam; +extern const S32Megabytes gMaxVideoRam; + +class LLFace; +class LLImageGL ; +class LLImageRaw; +class LLViewerObject; +class LLViewerTexture; +class LLViewerFetchedTexture ; +class LLViewerMediaTexture ; +class LLTexturePipelineTester ; + + +typedef void (*loaded_callback_func)( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata ); + +class LLVFile; +class LLMessageSystem; +class LLViewerMediaImpl ; +class LLVOVolume ; +struct LLTextureKey; + +class LLLoadedCallbackEntry +{ +public: + typedef std::set< LLTextureKey > source_callback_list_t; + +public: + LLLoadedCallbackEntry(loaded_callback_func cb, + S32 discard_level, + BOOL need_imageraw, // Needs image raw for the callback + void* userdata, + source_callback_list_t* src_callback_list, + LLViewerFetchedTexture* target, + BOOL pause); + ~LLLoadedCallbackEntry(); + void removeTexture(LLViewerFetchedTexture* tex) ; + + loaded_callback_func mCallback; + S32 mLastUsedDiscard; + S32 mDesiredDiscard; + BOOL mNeedsImageRaw; + BOOL mPaused; + void* mUserData; + source_callback_list_t* mSourceCallbackList; + +public: + static void cleanUpCallbackList(LLLoadedCallbackEntry::source_callback_list_t* callback_list) ; +}; + +class LLTextureBar; + +class LLViewerTexture : public LLGLTexture +{ +public: + enum + { + LOCAL_TEXTURE, + MEDIA_TEXTURE, + DYNAMIC_TEXTURE, + FETCHED_TEXTURE, + LOD_TEXTURE, + ATLAS_TEXTURE, + INVALID_TEXTURE_TYPE + }; + + typedef std::vector ll_face_list_t; + typedef std::vector ll_volume_list_t; + + +protected: + virtual ~LLViewerTexture(); + LOG_CLASS(LLViewerTexture); + +public: + static void initClass(); + static void updateClass(const F32 velocity, const F32 angular_velocity) ; + + LLViewerTexture(BOOL usemipmaps = TRUE); + LLViewerTexture(const LLUUID& id, BOOL usemipmaps) ; + LLViewerTexture(const LLImageRaw* raw, BOOL usemipmaps) ; + LLViewerTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps) ; + + virtual S8 getType() const; + virtual BOOL isMissingAsset() const ; + virtual void dump(); // debug info to LL_INFOS() + + virtual bool isViewerMediaTexture() const { return false; } + + /*virtual*/ bool bindDefaultImage(const S32 stage = 0) ; + /*virtual*/ bool bindDebugImage(const S32 stage = 0) ; + /*virtual*/ void forceImmediateUpdate() ; + /*virtual*/ bool isActiveFetching(); + + /*virtual*/ const LLUUID& getID() const { return mID; } + void setBoostLevel(S32 level); + S32 getBoostLevel() { return mBoostLevel; } + void setTextureListType(S32 tex_type) { mTextureListType = tex_type; } + S32 getTextureListType() { return mTextureListType; } + + void addTextureStats(F32 virtual_size, BOOL needs_gltexture = TRUE) const; + void resetTextureStats(); + void setMaxVirtualSizeResetInterval(S32 interval)const {mMaxVirtualSizeResetInterval = interval;} + void resetMaxVirtualSizeResetCounter()const {mMaxVirtualSizeResetCounter = mMaxVirtualSizeResetInterval;} + S32 getMaxVirtualSizeResetCounter() const { return mMaxVirtualSizeResetCounter; } + + virtual F32 getMaxVirtualSize() ; + + LLFrameTimer* getLastReferencedTimer() {return &mLastReferencedTimer ;} + + S32 getFullWidth() const { return mFullWidth; } + S32 getFullHeight() const { return mFullHeight; } + /*virtual*/ void setKnownDrawSize(S32 width, S32 height); + + virtual void addFace(U32 channel, LLFace* facep) ; + virtual void removeFace(U32 channel, LLFace* facep) ; + S32 getTotalNumFaces() const; + S32 getNumFaces(U32 ch) const; + const ll_face_list_t* getFaceList(U32 channel) const {llassert(channel < LLRender::NUM_TEXTURE_CHANNELS); return &mFaceList[channel];} + + virtual void addVolume(U32 channel, LLVOVolume* volumep); + virtual void removeVolume(U32 channel, LLVOVolume* volumep); + S32 getNumVolumes(U32 channel) const; + const ll_volume_list_t* getVolumeList(U32 channel) const { return &mVolumeList[channel]; } + + + virtual void setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) ; + BOOL isLargeImage() ; + + void setParcelMedia(LLViewerMediaTexture* media) {mParcelMedia = media;} + BOOL hasParcelMedia() const { return mParcelMedia != NULL;} + LLViewerMediaTexture* getParcelMedia() const { return mParcelMedia;} + + /*virtual*/ void updateBindStatsForTester() ; +protected: + void cleanup() ; + void init(bool firstinit) ; + void reorganizeFaceList() ; + void reorganizeVolumeList() ; + + void notifyAboutMissingAsset(); + void notifyAboutCreatingTexture(); + +private: + friend class LLBumpImageList; + friend class LLUIImageList; + + virtual void switchToCachedImage(); + + static bool isMemoryForTextureLow() ; + static bool isMemoryForTextureSuficientlyFree(); + static void getGPUMemoryForTextures(S32Megabytes &gpu, S32Megabytes &physical); + +protected: + LLUUID mID; + S32 mTextureListType; // along with mID identifies where to search for this texture in TextureList + + F32 mSelectedTime; // time texture was last selected + mutable F32 mMaxVirtualSize; // The largest virtual size of the image, in pixels - how much data to we need? + mutable S32 mMaxVirtualSizeResetCounter ; + mutable S32 mMaxVirtualSizeResetInterval; + mutable F32 mAdditionalDecodePriority; // priority add to mDecodePriority. + LLFrameTimer mLastReferencedTimer; + + ll_face_list_t mFaceList[LLRender::NUM_TEXTURE_CHANNELS]; //reverse pointer pointing to the faces using this image as texture + U32 mNumFaces[LLRender::NUM_TEXTURE_CHANNELS]; + LLFrameTimer mLastFaceListUpdateTimer ; + + ll_volume_list_t mVolumeList[LLRender::NUM_VOLUME_TEXTURE_CHANNELS]; + U32 mNumVolumes[LLRender::NUM_VOLUME_TEXTURE_CHANNELS]; + LLFrameTimer mLastVolumeListUpdateTimer; + + //do not use LLPointer here. + LLViewerMediaTexture* mParcelMedia ; + + static F32 sTexelPixelRatio; +public: + static const U32 sCurrentFileVersion; + static S32 sImageCount; + static S32 sRawCount; + static S32 sAuxCount; + static LLFrameTimer sEvaluationTimer; + static F32 sDesiredDiscardBias; + static F32 sDesiredDiscardScale; + static S32Bytes sBoundTextureMemory; + static S32Bytes sTotalTextureMemory; + static S32Megabytes sMaxBoundTextureMemory; + static S32Megabytes sMaxTotalTextureMem; + static S32Bytes sMaxDesiredTextureMem ; + static S8 sCameraMovingDiscardBias; + static F32 sCameraMovingBias; + static S32 sMaxSculptRez ; + static U32 sMinLargeImageSize ; + static U32 sMaxSmallImageSize ; + static bool sFreezeImageUpdates; + static F32 sCurrentTime ; + + enum EDebugTexels + { + DEBUG_TEXELS_OFF, + DEBUG_TEXELS_CURRENT, + DEBUG_TEXELS_DESIRED, + DEBUG_TEXELS_FULL + }; + + static EDebugTexels sDebugTexelsMode; + + static LLPointer sNullImagep; // Null texture for non-textured objects. + static LLPointer sBlackImagep; // Texture to show NOTHING (pure black) + static LLPointer sCheckerBoardImagep; // Texture to show NOTHING (pure black) +}; + + +enum FTType +{ + FTT_UNKNOWN = -1, + FTT_DEFAULT = 0, // standard texture fetched by id. + FTT_SERVER_BAKE, // texture produced by appearance service and fetched from there. + FTT_HOST_BAKE, // old-style baked texture uploaded by viewer and fetched from avatar's host. + FTT_MAP_TILE, // tiles are fetched from map server directly. + FTT_LOCAL_FILE // fetch directly from a local file. +}; + +const std::string& fttype_to_string(const FTType& fttype); + +// +//textures are managed in gTextureList. +//raw image data is fetched from remote or local cache +//but the raw image this texture pointing to is fixed. +// +class LLViewerFetchedTexture : public LLViewerTexture +{ + friend class LLTextureBar; // debug info only + friend class LLTextureView; // debug info only + +protected: + /*virtual*/ ~LLViewerFetchedTexture(); +public: + LLViewerFetchedTexture(const LLUUID& id, FTType f_type, const LLHost& host = LLHost(), BOOL usemipmaps = TRUE); + LLViewerFetchedTexture(const LLImageRaw* raw, FTType f_type, BOOL usemipmaps); + LLViewerFetchedTexture(const std::string& url, FTType f_type, const LLUUID& id, BOOL usemipmaps = TRUE); + +public: + static F32 maxDecodePriority(); + + struct Compare + { + // lhs < rhs + bool operator()(const LLPointer &lhs, const LLPointer &rhs) const + { + const LLViewerFetchedTexture* lhsp = (const LLViewerFetchedTexture*)lhs; + const LLViewerFetchedTexture* rhsp = (const LLViewerFetchedTexture*)rhs; + // greater priority is "less" + const F32 lpriority = lhsp->getDecodePriority(); + const F32 rpriority = rhsp->getDecodePriority(); + if (lpriority > rpriority) // higher priority + return true; + if (lpriority < rpriority) + return false; + return lhsp < rhsp; + } + }; + +public: + /*virtual*/ S8 getType() const ; + FTType getFTType() const; + /*virtual*/ void forceImmediateUpdate() ; + /*virtual*/ void dump() ; + + // Set callbacks to get called when the image gets updated with higher + // resolution versions. + void setLoadedCallback(loaded_callback_func cb, + S32 discard_level, BOOL keep_imageraw, BOOL needs_aux, + void* userdata, LLLoadedCallbackEntry::source_callback_list_t* src_callback_list, BOOL pause = FALSE); + bool hasCallbacks() { return mLoadedCallbackList.empty() ? false : true; } + void pauseLoadedCallbacks(const LLLoadedCallbackEntry::source_callback_list_t* callback_list); + void unpauseLoadedCallbacks(const LLLoadedCallbackEntry::source_callback_list_t* callback_list); + bool doLoadedCallbacks(); + void deleteCallbackEntry(const LLLoadedCallbackEntry::source_callback_list_t* callback_list); + void clearCallbackEntryList() ; + + void addToCreateTexture(); + + //call to determine if createTexture is necessary + BOOL preCreateTexture(S32 usename = 0); + // ONLY call from LLViewerTextureList or ImageGL background thread + BOOL createTexture(S32 usename = 0); + void postCreateTexture(); + void scheduleCreateTexture(); + + void destroyTexture() ; + + virtual void processTextureStats() ; + F32 calcDecodePriority() ; + + BOOL needsAux() const { return mNeedsAux; } + + // Host we think might have this image, used for baked av textures. + void setTargetHost(LLHost host) { mTargetHost = host; } + LLHost getTargetHost() const { return mTargetHost; } + + // Set the decode priority for this image... + // DON'T CALL THIS UNLESS YOU KNOW WHAT YOU'RE DOING, it can mess up + // the priority list, and cause horrible things to happen. + void setDecodePriority(F32 priority = -1.0f); + F32 getDecodePriority() const { return mDecodePriority; }; + F32 getAdditionalDecodePriority() const { return mAdditionalDecodePriority; }; + + void setAdditionalDecodePriority(F32 priority) ; + + void updateVirtualSize() ; + + S32 getDesiredDiscardLevel() { return mDesiredDiscardLevel; } + void setMinDiscardLevel(S32 discard) { mMinDesiredDiscardLevel = llmin(mMinDesiredDiscardLevel,(S8)discard); } + + bool updateFetch(); + bool setDebugFetching(S32 debug_level); + bool isInDebug() const { return mInDebug; } + + void setUnremovable(BOOL value) { mUnremovable = value; } + bool isUnremovable() const { return mUnremovable; } + + void clearFetchedResults(); //clear all fetched results, for debug use. + + // Override the computation of discard levels if we know the exact output + // size of the image. Used for UI textures to not decode, even if we have + // more data. + /*virtual*/ void setKnownDrawSize(S32 width, S32 height); + + void setIsMissingAsset(BOOL is_missing = true); + /*virtual*/ BOOL isMissingAsset() const { return mIsMissingAsset; } + + // returns dimensions of original image for local files (before power of two scaling) + // and returns 0 for all asset system images + S32 getOriginalWidth() { return mOrigWidth; } + S32 getOriginalHeight() { return mOrigHeight; } + + BOOL isInImageList() const {return mInImageList ;} + void setInImageList(BOOL flag) {mInImageList = flag ;} + + LLFrameTimer* getLastPacketTimer() {return &mLastPacketTimer;} + + U32 getFetchPriority() const { return mFetchPriority ;} + F32 getDownloadProgress() const {return mDownloadProgress ;} + + LLImageRaw* reloadRawImage(S8 discard_level) ; + void destroyRawImage(); + bool needsToSaveRawImage(); + + const std::string& getUrl() const {return mUrl;} + //--------------- + BOOL isDeleted() ; + BOOL isInactive() ; + BOOL isDeletionCandidate(); + void setDeletionCandidate() ; + void setInactive() ; + BOOL getUseDiscard() const { return mUseMipMaps && !mDontDiscard; } + //--------------- + + void setForSculpt(); + BOOL forSculpt() const {return mForSculpt;} + BOOL isForSculptOnly() const; + + //raw image management + void checkCachedRawSculptImage() ; + LLImageRaw* getRawImage()const { return mRawImage ;} + S32 getRawImageLevel() const {return mRawDiscardLevel;} + LLImageRaw* getCachedRawImage() const { return mCachedRawImage ;} + S32 getCachedRawImageLevel() const {return mCachedRawDiscardLevel;} + BOOL isCachedRawImageReady() const {return mCachedRawImageReady ;} + BOOL isRawImageValid()const { return mIsRawImageValid ; } + void forceToSaveRawImage(S32 desired_discard = 0, F32 kept_time = 0.f) ; + void forceToRefetchTexture(S32 desired_discard = 0, F32 kept_time = 60.f); + /*virtual*/ void setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) ; + void destroySavedRawImage() ; + LLImageRaw* getSavedRawImage() ; + BOOL hasSavedRawImage() const ; + F32 getElapsedLastReferencedSavedRawImageTime() const ; + BOOL isFullyLoaded() const; + + BOOL hasFetcher() const { return mHasFetcher;} + void setCanUseHTTP(bool can_use_http) {mCanUseHTTP = can_use_http;} + + void forceToDeleteRequest(); + void loadFromFastCache(); + void setInFastCacheList(bool in_list) { mInFastCacheList = in_list; } + bool isInFastCacheList() { return mInFastCacheList; } + + /*virtual*/bool isActiveFetching(); //is actively in fetching by the fetching pipeline. + +protected: + /*virtual*/ void switchToCachedImage(); + S32 getCurrentDiscardLevelForFetching() ; + +private: + void init(bool firstinit) ; + void cleanup() ; + + void saveRawImage() ; + void setCachedRawImage() ; + + //for atlas + void resetFaceAtlas() ; + void invalidateAtlas(BOOL rebuild_geom) ; + BOOL insertToAtlas() ; + +private: + BOOL mFullyLoaded; + BOOL mInDebug; + BOOL mUnremovable; + BOOL mInFastCacheList; + BOOL mForceCallbackFetch; + +protected: + std::string mLocalFileName; + + S32 mOrigWidth; + S32 mOrigHeight; + + // Override the computation of discard levels if we know the exact output size of the image. + // Used for UI textures to not decode, even if we have more data. + S32 mKnownDrawWidth; + S32 mKnownDrawHeight; + BOOL mKnownDrawSizeChanged ; + std::string mUrl; + + S32 mRequestedDiscardLevel; + F32 mRequestedDownloadPriority; + S32 mFetchState; + U32 mFetchPriority; + F32 mDownloadProgress; + F32 mFetchDeltaTime; + F32 mRequestDeltaTime; + F32 mDecodePriority; // The priority for decoding this image. + S32 mMinDiscardLevel; + S8 mDesiredDiscardLevel; // The discard level we'd LIKE to have - if we have it and there's space + S8 mMinDesiredDiscardLevel; // The minimum discard level we'd like to have + + S8 mNeedsAux; // We need to decode the auxiliary channels + S8 mHasAux; // We have aux channels + S8 mDecodingAux; // Are we decoding high components + S8 mIsRawImageValid; + S8 mHasFetcher; // We've made a fecth request + S8 mIsFetching; // Fetch request is active + bool mCanUseHTTP; //This texture can be fetched through http if true. + LLCore::HttpStatus mLastHttpGetStatus; // Result of the most recently completed http request for this texture. + + FTType mFTType; // What category of image is this - map tile, server bake, etc? + mutable S8 mIsMissingAsset; // True if we know that there is no image asset with this image id in the database. + + typedef std::list callback_list_t; + S8 mLoadedCallbackDesiredDiscardLevel; + BOOL mPauseLoadedCallBacks; + callback_list_t mLoadedCallbackList; + F32 mLastCallBackActiveTime; + + LLPointer mRawImage; + S32 mRawDiscardLevel; + + // Used ONLY for cloth meshes right now. Make SURE you know what you're + // doing if you use it for anything else! - djs + LLPointer mAuxRawImage; + + //keep a copy of mRawImage for some special purposes + //when mForceToSaveRawImage is set. + BOOL mForceToSaveRawImage ; + BOOL mSaveRawImage; + LLPointer mSavedRawImage; + S32 mSavedRawDiscardLevel; + S32 mDesiredSavedRawDiscardLevel; + F32 mLastReferencedSavedRawImageTime ; + F32 mKeptSavedRawImageTime ; + + //a small version of the copy of the raw image (<= 64 * 64) + LLPointer mCachedRawImage; + S32 mCachedRawDiscardLevel; + BOOL mCachedRawImageReady; //the rez of the mCachedRawImage reaches the upper limit. + + LLHost mTargetHost; // if invalid, just request from agent's simulator + + // Timers + LLFrameTimer mLastPacketTimer; // Time since last packet. + LLFrameTimer mStopFetchingTimer; // Time since mDecodePriority == 0.f. + + BOOL mInImageList; // TRUE if image is in list (in which case don't reset priority!) + BOOL mNeedsCreateTexture; + + BOOL mForSculpt ; //a flag if the texture is used as sculpt data. + BOOL mIsFetched ; //is loaded from remote or from cache, not generated locally. + +public: + static LLPointer sMissingAssetImagep; // Texture to show for an image asset that is not in the database + static LLPointer sWhiteImagep; // Texture to show NOTHING (whiteness) + static LLPointer sDefaultImagep; // "Default" texture for error cases, the only case of fetched texture which is generated in local. + static LLPointer sSmokeImagep; // Old "Default" translucent texture + static LLPointer sFlatNormalImagep; // Flat normal map denoting no bumpiness on a surface +}; + +// +//the image data is fetched from remote or from local cache +//the resolution of the texture is adjustable: depends on the view-dependent parameters. +// +class LLViewerLODTexture : public LLViewerFetchedTexture +{ +protected: + /*virtual*/ ~LLViewerLODTexture(){} + +public: + LLViewerLODTexture(const LLUUID& id, FTType f_type, const LLHost& host = LLHost(), BOOL usemipmaps = TRUE); + LLViewerLODTexture(const std::string& url, FTType f_type, const LLUUID& id, BOOL usemipmaps = TRUE); + + /*virtual*/ S8 getType() const; + // Process image stats to determine priority/quality requirements. + /*virtual*/ void processTextureStats(); + bool isUpdateFrozen() ; + +private: + void init(bool firstinit) ; + bool scaleDown() ; + +private: + F32 mDiscardVirtualSize; // Virtual size used to calculate desired discard + F32 mCalculatedDiscardLevel; // Last calculated discard level +}; + +// +//the image data is fetched from the media pipeline periodically +//the resolution of the texture is also adjusted by the media pipeline +// +class LLViewerMediaTexture : public LLViewerTexture +{ +protected: + /*virtual*/ ~LLViewerMediaTexture() ; + +public: + LLViewerMediaTexture(const LLUUID& id, BOOL usemipmaps = TRUE, LLImageGL* gl_image = NULL) ; + + /*virtual*/ S8 getType() const; + void reinit(BOOL usemipmaps = TRUE); + + BOOL getUseMipMaps() {return mUseMipMaps ; } + void setUseMipMaps(BOOL mipmap) ; + + void setPlaying(BOOL playing) ; + BOOL isPlaying() const {return mIsPlaying;} + void setMediaImpl() ; + + virtual bool isViewerMediaTexture() const { return true; } + + void initVirtualSize() ; + void invalidateMediaImpl() ; + + void addMediaToFace(LLFace* facep) ; + void removeMediaFromFace(LLFace* facep) ; + + /*virtual*/ void addFace(U32 ch, LLFace* facep) ; + /*virtual*/ void removeFace(U32 ch, LLFace* facep) ; + + /*virtual*/ F32 getMaxVirtualSize() ; +private: + void switchTexture(U32 ch, LLFace* facep) ; + BOOL findFaces() ; + void stopPlaying() ; + +private: + // + //an instant list, recording all faces referencing or can reference to this media texture. + //NOTE: it is NOT thread safe. + // + std::list< LLFace* > mMediaFaceList ; + + //an instant list keeping all textures which are replaced by the current media texture, + //is only used to avoid the removal of those textures from memory. + std::list< LLPointer > mTextureList ; + + LLViewerMediaImpl* mMediaImplp ; + BOOL mIsPlaying ; + U32 mUpdateVirtualSizeTime ; + +public: + static void updateClass() ; + static void cleanUpClass() ; + + static LLViewerMediaTexture* findMediaTexture(const LLUUID& media_id) ; + static void removeMediaImplFromTexture(const LLUUID& media_id) ; + +private: + typedef std::map< LLUUID, LLPointer > media_map_t ; + static media_map_t sMediaMap ; +}; + +//just an interface class, do not create instance from this class. +class LLViewerTextureManager +{ +private: + //make the constructor private to preclude creating instances from this class. + LLViewerTextureManager(){} + +public: + //texture pipeline tester + static LLTexturePipelineTester* sTesterp ; + + //returns NULL if tex is not a LLViewerFetchedTexture nor derived from LLViewerFetchedTexture. + static LLViewerFetchedTexture* staticCastToFetchedTexture(LLTexture* tex, BOOL report_error = FALSE) ; + + // + //"find-texture" just check if the texture exists, if yes, return it, otherwise return null. + // + static void findFetchedTextures(const LLUUID& id, std::vector &output); + static void findTextures(const LLUUID& id, std::vector &output); + static LLViewerFetchedTexture* findFetchedTexture(const LLUUID& id, S32 tex_type); + static LLViewerMediaTexture* findMediaTexture(const LLUUID& id) ; + + static LLViewerMediaTexture* createMediaTexture(const LLUUID& id, BOOL usemipmaps = TRUE, LLImageGL* gl_image = NULL) ; + + // + //"get-texture" will create a new texture if the texture does not exist. + // + static LLViewerMediaTexture* getMediaTexture(const LLUUID& id, BOOL usemipmaps = TRUE, LLImageGL* gl_image = NULL) ; + + static LLPointer getLocalTexture(BOOL usemipmaps = TRUE, BOOL generate_gl_tex = TRUE); + static LLPointer getLocalTexture(const LLUUID& id, BOOL usemipmaps, BOOL generate_gl_tex = TRUE) ; + static LLPointer getLocalTexture(const LLImageRaw* raw, BOOL usemipmaps) ; + static LLPointer getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex = TRUE) ; + + static LLViewerFetchedTexture* getFetchedTexture(const LLUUID &image_id, + FTType f_type = FTT_DEFAULT, + BOOL usemipmap = TRUE, + LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE, // Get the requested level immediately upon creation. + S8 texture_type = LLViewerTexture::FETCHED_TEXTURE, + LLGLint internal_format = 0, + LLGLenum primary_format = 0, + LLHost request_from_host = LLHost() + ); + + static LLViewerFetchedTexture* getFetchedTextureFromFile(const std::string& filename, + FTType f_type = FTT_LOCAL_FILE, + BOOL usemipmap = TRUE, + LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE, + S8 texture_type = LLViewerTexture::FETCHED_TEXTURE, + LLGLint internal_format = 0, + LLGLenum primary_format = 0, + const LLUUID& force_id = LLUUID::null + ); + + static LLViewerFetchedTexture* getFetchedTextureFromUrl(const std::string& url, + FTType f_type, + BOOL usemipmap = TRUE, + LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE, + S8 texture_type = LLViewerTexture::FETCHED_TEXTURE, + LLGLint internal_format = 0, + LLGLenum primary_format = 0, + const LLUUID& force_id = LLUUID::null + ); + + static LLViewerFetchedTexture* getFetchedTextureFromHost(const LLUUID& image_id, FTType f_type, LLHost host) ; + + static void init() ; + static void cleanup() ; +}; +// +//this class is used for test/debug only +//it tracks the activities of the texture pipeline +//records them, and outputs them to log files +// +class LLTexturePipelineTester : public LLMetricPerformanceTesterWithSession +{ + enum + { + MIN_LARGE_IMAGE_AREA = 262144 //512 * 512 + }; +public: + LLTexturePipelineTester() ; + ~LLTexturePipelineTester() ; + + void update(); + void updateTextureBindingStats(const LLViewerTexture* imagep) ; + void updateTextureLoadingStats(const LLViewerFetchedTexture* imagep, const LLImageRaw* raw_imagep, BOOL from_cache) ; + void updateGrayTextureBinding() ; + void setStablizingTime() ; + +private: + void reset() ; + void updateStablizingTime() ; + + /*virtual*/ void outputTestRecord(LLSD* sd) ; + +private: + BOOL mPause ; +private: + BOOL mUsingDefaultTexture; //if set, some textures are still gray. + + U32Bytes mTotalBytesUsed ; //total bytes of textures bound/used for the current frame. + U32Bytes mTotalBytesUsedForLargeImage ; //total bytes of textures bound/used for the current frame for images larger than 256 * 256. + U32Bytes mLastTotalBytesUsed ; //total bytes of textures bound/used for the previous frame. + U32Bytes mLastTotalBytesUsedForLargeImage ; //total bytes of textures bound/used for the previous frame for images larger than 256 * 256. + + // + //data size + // + U32Bytes mTotalBytesLoaded ; //total bytes fetched by texture pipeline + U32Bytes mTotalBytesLoadedFromCache ; //total bytes fetched by texture pipeline from local cache + U32Bytes mTotalBytesLoadedForLargeImage ; //total bytes fetched by texture pipeline for images larger than 256 * 256. + U32Bytes mTotalBytesLoadedForSculpties ; //total bytes fetched by texture pipeline for sculpties + + // + //time + //NOTE: the error tolerances of the following timers is one frame time. + // + F32 mStartFetchingTime ; + F32 mTotalGrayTime ; //total loading time when no gray textures. + F32 mTotalStablizingTime ; //total stablizing time when texture memory overflows + F32 mStartTimeLoadingSculpties ; //the start moment of loading sculpty images. + F32 mEndTimeLoadingSculpties ; //the end moment of loading sculpty images. + F32 mStartStablizingTime ; + F32 mEndStablizingTime ; + +private: + // + //The following members are used for performance analyzing + // + class LLTextureTestSession : public LLTestSession + { + public: + LLTextureTestSession() ; + /*virtual*/ ~LLTextureTestSession() ; + + void reset() ; + + F32 mTotalFetchingTime ; + F32 mTotalGrayTime ; + F32 mTotalStablizingTime ; + F32 mStartTimeLoadingSculpties ; + F32 mTotalTimeLoadingSculpties ; + + S32 mTotalBytesLoaded ; + S32 mTotalBytesLoadedFromCache ; + S32 mTotalBytesLoadedForLargeImage ; + S32 mTotalBytesLoadedForSculpties ; + + typedef struct _texture_instant_preformance_t + { + S32 mAverageBytesUsedPerSecond ; + S32 mAverageBytesUsedForLargeImagePerSecond ; + F32 mAveragePercentageBytesUsedPerSecond ; + F32 mTime ; + }texture_instant_preformance_t ; + std::vector mInstantPerformanceList ; + S32 mInstantPerformanceListCounter ; + }; + + /*virtual*/ LLMetricPerformanceTesterWithSession::LLTestSession* loadTestSession(LLSD* log) ; + /*virtual*/ void compareTestSessions(llofstream* os) ; +}; + +#endif -- cgit v1.2.3 From e7227afe0249806ceb1c8eef2dd6ca909eb394d3 Mon Sep 17 00:00:00 2001 From: Runitai Linden Date: Thu, 14 Oct 2021 13:02:40 -0500 Subject: SL-16166 Apply optimizations from pushBatch to other render call sites. Optimize out a map lookup in rigged face rendering. --- indra/llrender/llglslshader.cpp | 4 +- indra/llrender/llrender.cpp | 3 +- indra/newview/lldrawable.cpp | 2 - indra/newview/lldrawpoolalpha.cpp | 218 +++++++++---------------------------- indra/newview/lldrawpoolalpha.h | 4 +- indra/newview/lldrawpoolavatar.cpp | 206 ++++++++++++++--------------------- indra/newview/lldrawpoolavatar.h | 9 +- indra/newview/llmeshrepository.cpp | 3 +- indra/newview/llmeshrepository.h | 2 +- indra/newview/llvovolume.cpp | 2 +- indra/newview/llvovolume.h | 3 + 11 files changed, 150 insertions(+), 306 deletions(-) diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index 394fcd2b2f..84eac00c65 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -1017,7 +1017,7 @@ S32 LLGLSLShader::bindTexture(S32 uniform, LLTexture *texture, LLTexUnit::eTextu if (uniform > -1) { - gGL.getTexUnit(uniform)->bind(texture, mode); + gGL.getTexUnit(uniform)->bindFast(texture); gGL.getTexUnit(uniform)->setTextureColorSpace(colorspace); } @@ -1048,7 +1048,7 @@ S32 LLGLSLShader::unbindTexture(S32 uniform, LLTexUnit::eTextureType mode) if (uniform > -1) { - gGL.getTexUnit(uniform)->unbind(mode); + gGL.getTexUnit(uniform)->unbindFast(mode); } return uniform; diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 91d3c96fbe..669a09d3ce 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -169,7 +169,6 @@ void LLTexUnit::refreshState(void) void LLTexUnit::activate(void) { - LL_PROFILE_ZONE_SCOPED; if (mIndex < 0) return; if ((S32)gGL.mCurrTextureUnitIndex != mIndex || gGL.mDirty) @@ -1956,9 +1955,9 @@ void LLRender::end() } void LLRender::flush() { - LL_PROFILE_ZONE_SCOPED; if (mCount > 0) { + LL_PROFILE_ZONE_SCOPED; if (!mUIOffset.empty()) { sUICalls++; diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 30c4a21e1c..495e06b6f7 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -234,8 +234,6 @@ void LLDrawable::markDead() LLVOVolume* LLDrawable::getVOVolume() const { - LL_PROFILE_ZONE_SCOPED - LLViewerObject* objectp = mVObjp; if ( !isDead() && objectp && (objectp->getPCode() == LL_PCODE_VOLUME)) { diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 4ee08e869a..369d7a6bb8 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -55,19 +55,7 @@ static BOOL deferred_render = FALSE; static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_SETUP("Alpha Setup"); static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_GROUP_LOOP("Alpha Group"); -static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_PUSH("Alpha Push Verts"); static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_DEFERRED("Alpha Deferred"); -static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_SETBUFFER("Alpha SetBuffer"); -static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_DRAW("Alpha Draw"); -static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_TEX_BINDS("Alpha Tex Binds"); -static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_MATS("Alpha Mat Tex Binds"); -static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_GLOW("Alpha Glow Binds"); -static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_SHADER_BINDS("Alpha Shader Binds"); -static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_DEFERRED_SHADER_BINDS("Alpha Def Binds"); -static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_DEFERRED_TEX_BINDS("Alpha Def Tex Binds"); -static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_MESH_REBUILD("Alpha Mesh Rebuild"); -static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_EMISSIVE("Alpha Emissive"); -static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_LIGHT_SETUP("Alpha Light Setup"); LLDrawPoolAlpha::LLDrawPoolAlpha(U32 type) : LLRenderPass(type), current_shader(NULL), target_shader(NULL), @@ -86,6 +74,10 @@ LLDrawPoolAlpha::~LLDrawPoolAlpha() void LLDrawPoolAlpha::prerender() { mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT); + + // TODO: is this even necessay? These are probably set to never discard + LLViewerFetchedTexture::sFlatNormalImagep->addTextureStats(1024.f*1024.f); + LLViewerFetchedTexture::sWhiteImagep->addTextureStats(1024.f * 1024.f); } S32 LLDrawPoolAlpha::getNumPostDeferredPasses() @@ -309,7 +301,7 @@ void LLDrawPoolAlpha::render(S32 pass) gGL.diffuseColor4f(1,0,0,1); LLViewerFetchedTexture::sSmokeImagep->addTextureStats(1024.f*1024.f); - gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sSmokeImagep, TRUE) ; + gGL.getTexUnit(0)->bindFast(LLViewerFetchedTexture::sSmokeImagep); renderAlphaHighlight(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0); @@ -358,9 +350,8 @@ void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask) { params.mGroup->rebuildMesh(); } - params.mVertexBuffer->setBuffer(mask); - params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); - gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode); + params.mVertexBuffer->setBufferFast(mask); + params.mVertexBuffer->drawRangeFast(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); } } } @@ -383,27 +374,23 @@ inline bool IsEmissive(LLDrawInfo& params) inline void Draw(LLDrawInfo* draw, U32 mask) { - draw->mVertexBuffer->setBuffer(mask); + draw->mVertexBuffer->setBufferFast(mask); LLRenderPass::applyModelMatrix(*draw); - draw->mVertexBuffer->drawRange(draw->mDrawMode, draw->mStart, draw->mEnd, draw->mCount, draw->mOffset); - gPipeline.addTrianglesDrawn(draw->mCount, draw->mDrawMode); + draw->mVertexBuffer->drawRangeFast(draw->mDrawMode, draw->mStart, draw->mEnd, draw->mCount, draw->mOffset); } -bool LLDrawPoolAlpha::TexSetup(LLDrawInfo* draw, bool use_shaders, bool use_material, LLGLSLShader* current_shader) +bool LLDrawPoolAlpha::TexSetup(LLDrawInfo* draw, bool use_material, LLGLSLShader* current_shader) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_TEX_BINDS); - bool tex_setup = false; if (deferred_render && use_material && current_shader) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DEFERRED_TEX_BINDS); if (draw->mNormalMap) - { + { draw->mNormalMap->addTextureStats(draw->mVSize); current_shader->bindTexture(LLShaderMgr::BUMP_MAP, draw->mNormalMap); } - + if (draw->mSpecularMap) { draw->mSpecularMap->addTextureStats(draw->mVSize); @@ -412,18 +399,16 @@ bool LLDrawPoolAlpha::TexSetup(LLDrawInfo* draw, bool use_shaders, bool use_mate } else if (current_shader == simple_shader) { - LLViewerFetchedTexture::sFlatNormalImagep->addTextureStats(draw->mVSize); - LLViewerFetchedTexture::sWhiteImagep->addTextureStats(draw->mVSize); - current_shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep); + current_shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep); current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep); } - if (use_shaders && draw->mTextureList.size() > 1) + if (draw->mTextureList.size() > 1) { for (U32 i = 0; i < draw->mTextureList.size(); ++i) { if (draw->mTextureList[i].notNull()) { - gGL.getTexUnit(i)->bind(draw->mTextureList[i], TRUE); + gGL.getTexUnit(i)->bindFast(draw->mTextureList[i]); } } } @@ -431,16 +416,15 @@ bool LLDrawPoolAlpha::TexSetup(LLDrawInfo* draw, bool use_shaders, bool use_mate { //not batching textures or batch has only 1 texture -- might need a texture matrix if (draw->mTexture.notNull()) { - draw->mTexture->addTextureStats(draw->mVSize); - if (use_shaders && use_material) + if (use_material) { current_shader->bindTexture(LLShaderMgr::DIFFUSE_MAP, draw->mTexture); } else { - gGL.getTexUnit(0)->bind(draw->mTexture, TRUE) ; + gGL.getTexUnit(0)->bindFast(draw->mTexture); } - + if (draw->mTextureMatrix) { tex_setup = true; @@ -452,7 +436,7 @@ bool LLDrawPoolAlpha::TexSetup(LLDrawInfo* draw, bool use_shaders, bool use_mate } else { - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(0)->unbindFast(LLTexUnit::TT_TEXTURE); } } @@ -470,37 +454,15 @@ void LLDrawPoolAlpha::RestoreTexSetup(bool tex_setup) } } -void LLDrawPoolAlpha::renderSimples(U32 mask, std::vector& simples) -{ - gPipeline.enableLightsDynamic(); - simple_shader->bind(); - simple_shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep); - simple_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep); - simple_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, 1.0f, 1.0f, 1.0f, 1.0f); - simple_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, 0.0f); - simple_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 0.0f); - bool use_shaders = gPipeline.canUseVertexShaders(); - for (LLDrawInfo* draw : simples) - { - bool tex_setup = TexSetup(draw, use_shaders, false, simple_shader); - LLGLEnableFunc stencil_test(GL_STENCIL_TEST, draw->mSelected, &LLGLCommonFunc::selected_stencil_test); - gGL.blendFunc((LLRender::eBlendFactor) draw->mBlendFuncSrc, (LLRender::eBlendFactor) draw->mBlendFuncDst, mAlphaSFactor, mAlphaDFactor); - - Draw(draw, mask); - RestoreTexSetup(tex_setup); - } - simple_shader->unbind(); -} - void LLDrawPoolAlpha::renderFullbrights(U32 mask, std::vector& fullbrights) { gPipeline.enableLightsFullbright(); fullbright_shader->bind(); fullbright_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 1.0f); - bool use_shaders = gPipeline.canUseVertexShaders(); + for (LLDrawInfo* draw : fullbrights) { - bool tex_setup = TexSetup(draw, use_shaders, false, fullbright_shader); + bool tex_setup = TexSetup(draw, false, fullbright_shader); LLGLEnableFunc stencil_test(GL_STENCIL_TEST, draw->mSelected, &LLGLCommonFunc::selected_stencil_test); gGL.blendFunc((LLRender::eBlendFactor) draw->mBlendFuncSrc, (LLRender::eBlendFactor) draw->mBlendFuncDst, mAlphaSFactor, mAlphaDFactor); @@ -511,65 +473,10 @@ void LLDrawPoolAlpha::renderFullbrights(U32 mask, std::vector& full fullbright_shader->unbind(); } -void LLDrawPoolAlpha::renderMaterials(U32 mask, std::vector& materials) -{ - LLGLSLShader::bindNoShader(); - current_shader = NULL; - - gPipeline.enableLightsDynamic(); - bool use_shaders = gPipeline.canUseVertexShaders(); - for (LLDrawInfo* draw : materials) - { - U32 mask = draw->mShaderMask; - - llassert(mask < LLMaterial::SHADER_COUNT); - target_shader = (LLPipeline::sUnderWaterRender) ? &(gDeferredMaterialWaterProgram[mask]) : &(gDeferredMaterialProgram[mask]); - - if (current_shader != target_shader) - { - LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DEFERRED_SHADER_BINDS); - if (current_shader) - { - gPipeline.unbindDeferredShader(*current_shader); - } - gPipeline.bindDeferredShader(*target_shader); - current_shader = target_shader; - } - - bool tex_setup = TexSetup(draw, use_shaders, true, current_shader); - - current_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, draw->mSpecColor.mV[0], draw->mSpecColor.mV[1], draw->mSpecColor.mV[2], draw->mSpecColor.mV[3]); - current_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, draw->mEnvIntensity); - current_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, draw->mFullbright ? 1.f : 0.f); - - { - LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DEFERRED_TEX_BINDS); - if (draw->mNormalMap) - { - draw->mNormalMap->addTextureStats(draw->mVSize); - current_shader->bindTexture(LLShaderMgr::BUMP_MAP, draw->mNormalMap); - } - - if (draw->mSpecularMap) - { - draw->mSpecularMap->addTextureStats(draw->mVSize); - current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, draw->mSpecularMap); - } - } - - LLGLEnableFunc stencil_test(GL_STENCIL_TEST, draw->mSelected, &LLGLCommonFunc::selected_stencil_test); - gGL.blendFunc((LLRender::eBlendFactor) draw->mBlendFuncSrc, (LLRender::eBlendFactor) draw->mBlendFuncDst, mAlphaSFactor, mAlphaDFactor); - - Draw(draw, mask); - RestoreTexSetup(tex_setup); - } -} - void LLDrawPoolAlpha::drawEmissive(U32 mask, LLDrawInfo* draw) { - draw->mVertexBuffer->setBuffer((mask & ~LLVertexBuffer::MAP_COLOR) | LLVertexBuffer::MAP_EMISSIVE); - draw->mVertexBuffer->drawRange(draw->mDrawMode, draw->mStart, draw->mEnd, draw->mCount, draw->mOffset); - gPipeline.addTrianglesDrawn(draw->mCount, draw->mDrawMode); + draw->mVertexBuffer->setBufferFast((mask & ~LLVertexBuffer::MAP_COLOR) | LLVertexBuffer::MAP_EMISSIVE); + draw->mVertexBuffer->drawRangeFast(draw->mDrawMode, draw->mStart, draw->mEnd, draw->mCount, draw->mOffset); } void LLDrawPoolAlpha::drawEmissiveInline(U32 mask, LLDrawInfo* draw) @@ -599,10 +506,10 @@ void LLDrawPoolAlpha::renderEmissives(U32 mask, std::vector& emissi // install glow-accumulating blend mode // don't touch color, add to alpha (glow) gGL.blendFunc(LLRender::BF_ZERO, LLRender::BF_ONE, LLRender::BF_ONE, LLRender::BF_ONE); - bool use_shaders = gPipeline.canUseVertexShaders(); + for (LLDrawInfo* draw : emissives) { - bool tex_setup = TexSetup(draw, use_shaders, false, emissive_shader); + bool tex_setup = TexSetup(draw, false, emissive_shader); drawEmissive(mask, draw); RestoreTexSetup(tex_setup); } @@ -620,8 +527,6 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) BOOL initialized_lighting = FALSE; BOOL light_enabled = TRUE; - BOOL use_shaders = gPipeline.canUseVertexShaders(); - for (LLCullResult::sg_iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i) { LLSpatialGroup* group = *i; @@ -631,8 +536,10 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) if (group->getSpatialPartition()->mRenderByGroup && !group->isDead()) { - std::vector emissives; - std::vector fullbrights; + static std::vector emissives; + static std::vector fullbrights; + emissives.resize(0); + fullbrights.resize(0); bool is_particle_or_hud_particle = group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_PARTICLE || group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_HUD_PARTICLE; @@ -649,6 +556,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k) { + LL_PROFILE_ZONE_NAMED("ra - push batch") LLDrawInfo& params = **k; U32 have_mask = params.mVertexBuffer->getTypeMask() & mask; if (have_mask != mask) @@ -696,34 +604,17 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) // Turn off lighting if it hasn't already been so. if (light_enabled || !initialized_lighting) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_LIGHT_SETUP); - initialized_lighting = TRUE; - if (use_shaders) - { - target_shader = fullbright_shader; - } - else - { - gPipeline.enableLightsFullbright(); - } + target_shader = fullbright_shader; + light_enabled = FALSE; } } // Turn on lighting if it isn't already. else if (!light_enabled || !initialized_lighting) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_LIGHT_SETUP); - initialized_lighting = TRUE; - if (use_shaders) - { - target_shader = simple_shader; - } - else - { - gPipeline.enableLightsDynamic(); - } + target_shader = simple_shader; light_enabled = TRUE; } @@ -741,7 +632,6 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) if (current_shader != target_shader) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DEFERRED_SHADER_BINDS); gPipeline.bindDeferredShader(*target_shader); current_shader = target_shader; } @@ -755,25 +645,19 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) target_shader = fullbright_shader; } - if(use_shaders && (current_shader != target_shader)) + if(current_shader != target_shader) {// If we need shaders, and we're not ALREADY using the proper shader, then bind it // (this way we won't rebind shaders unnecessarily). - LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_SHADER_BINDS); current_shader = target_shader; current_shader->bind(); } - else if (!use_shaders && current_shader != NULL) - { - LLGLSLShader::bindNoShader(); - current_shader = NULL; - } LLVector4 spec_color(1, 1, 1, 1); F32 env_intensity = 0.0f; F32 brightness = 1.0f; // We have a material. Supply the appropriate data here. - if (use_shaders && mat && deferred_render) + if (mat && deferred_render) { spec_color = params.mSpecColor; env_intensity = params.mEnvIntensity; @@ -792,20 +676,16 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) params.mGroup->rebuildMesh(); } - bool tex_setup = TexSetup(¶ms, use_shaders, use_shaders && (mat != nullptr), current_shader); + bool tex_setup = TexSetup(¶ms, (mat != nullptr), current_shader); { - LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_PUSH); - LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test); gGL.blendFunc((LLRender::eBlendFactor) params.mBlendFuncSrc, (LLRender::eBlendFactor) params.mBlendFuncDst, mAlphaSFactor, mAlphaDFactor); - params.mVertexBuffer->setBuffer(mask & ~(params.mFullbright ? (LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2) : 0)); + params.mVertexBuffer->setBufferFast(mask & ~(params.mFullbright ? (LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2) : 0)); { - LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DRAW); - params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); - gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode); + params.mVertexBuffer->drawRangeFast(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); } } @@ -814,8 +694,6 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) draw_glow_for_this_partition && params.mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_EMISSIVE)) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_EMISSIVE); - if (batch_emissives) { emissives.push_back(¶ms); @@ -835,19 +713,29 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) } } + + bool rebind = false; if (batch_fullbrights) { - light_enabled = false; - renderFullbrights(mask, fullbrights); + if (!fullbrights.empty()) + { + light_enabled = false; + renderFullbrights(mask, fullbrights); + rebind = true; + } } if (batch_emissives) { - light_enabled = true; - renderEmissives(mask, emissives); + if (!emissives.empty()) + { + light_enabled = true; + renderEmissives(mask, emissives); + rebind = true; + } } - if (current_shader) + if (current_shader && rebind) { current_shader->bind(); } diff --git a/indra/newview/lldrawpoolalpha.h b/indra/newview/lldrawpoolalpha.h index a069f805e8..a50b1d929e 100644 --- a/indra/newview/lldrawpoolalpha.h +++ b/indra/newview/lldrawpoolalpha.h @@ -75,15 +75,13 @@ private: LLGLSLShader* fullbright_shader; LLGLSLShader* emissive_shader; - void renderSimples(U32 mask, std::vector& simples); void renderFullbrights(U32 mask, std::vector& fullbrights); - void renderMaterials(U32 mask, std::vector& fullbrights); void renderEmissives(U32 mask, std::vector& emissives); void drawEmissive(U32 mask, LLDrawInfo* draw); void drawEmissiveInline(U32 mask, LLDrawInfo* draw); - bool TexSetup(LLDrawInfo* draw, bool use_shaders, bool use_material, LLGLSLShader* current_shader); + bool TexSetup(LLDrawInfo* draw, bool use_material, LLGLSLShader* current_shader); void RestoreTexSetup(bool tex_setup); // our 'normal' alpha blend function for this pass diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 02ab316256..8dd8c15b87 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1685,7 +1685,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) renderRigged(avatarp, RIGGED_MATERIAL_ALPHA_EMISSIVE); renderRigged(avatarp, RIGGED_NORMMAP); renderRigged(avatarp, RIGGED_NORMMAP_MASK); - renderRigged(avatarp, RIGGED_NORMMAP_EMISSIVE); + renderRigged(avatarp, RIGGED_NORMMAP_EMISSIVE); renderRigged(avatarp, RIGGED_SPECMAP); renderRigged(avatarp, RIGGED_SPECMAP_MASK); renderRigged(avatarp, RIGGED_SPECMAP_EMISSIVE); @@ -2067,56 +2067,12 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( LLVector4a* pos = (LLVector4a*) position.get(); LLVector4a* norm = has_normal ? (LLVector4a*) normal.get() : NULL; - - if (skin == nullptr) - { - skin = vobj->getSkinInfo(); - } - const MatrixPaletteCache& mpc = updateSkinInfoMatrixPalette(avatar, skin); + const MatrixPaletteCache& mpc = updateSkinInfoMatrixPalette(avatar, vobj->getMeshID()); const LLMatrix4a* mat = &(mpc.mMatrixPalette[0]); + const LLMatrix4a& bind_shape_matrix = mpc.mBindShapeMatrix; - LLSkinningUtil::checkSkinWeights(weights, buffer->getNumVerts(), skin); - const LLMatrix4a& bind_shape_matrix = skin->mBindShapeMatrix; - -#if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS - U8* joint_indices_cursor = vol_face.mJointIndices; - // fast path with joint indices separate from weights - if (joint_indices_cursor) - { - LLMatrix4a src[4]; - for (U32 j = 0; j < buffer->getNumVerts(); ++j) - { - LLMatrix4a final_mat; - //LLMatrix4a final_mat_correct; - - F32* jw = just_weights[j].getF32ptr(); - - LLSkinningUtil::getPerVertexSkinMatrixWithIndices(jw, joint_indices_cursor, mat, final_mat, src); - - joint_indices_cursor += 4; - - LLVector4a& v = vol_face.mPositions[j]; - - LLVector4a t; - LLVector4a dst; - bind_shape_matrix.affineTransform(v, t); - final_mat.affineTransform(t, dst); - pos[j] = dst; - - if (norm) - { - LLVector4a& n = vol_face.mNormals[j]; - bind_shape_matrix.rotate(n, t); - final_mat.rotate(t, dst); - dst.normalize3fast(); - norm[j] = dst; - } - } - } - // slow path with joint indices calculated from weights - else -#endif + if (!mpc.mMatrixPalette.empty()) { for (U32 j = 0; j < buffer->getNumVerts(); ++j) { @@ -2152,9 +2108,7 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) return; } - stop_glerror(); - - const LLMeshSkinInfo* lastSkin = nullptr; + LLUUID lastMeshId; for (U32 i = 0; i < mRiggedFace[type].size(); ++i) { @@ -2188,19 +2142,6 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) continue; } - const LLMeshSkinInfo* skin = vobj->getSkinInfo(); - if (!skin) - { - continue; - } - - //stop_glerror(); - - //const LLVolumeFace& vol_face = volume->getVolumeFace(te); - //updateRiggedFaceVertexBuffer(avatar, face, skin, volume, vol_face); - - //stop_glerror(); - U32 data_mask = LLFace::getRiggedDataMask(type); LLVertexBuffer* buff = face->getVertexBuffer(); @@ -2290,34 +2231,33 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) { if (sShaderLevel > 0) { - if (lastSkin != skin) // <== only upload matrix palette to GL if the skininfo changed + auto& meshId = vobj->getMeshID(); + + if (lastMeshId != meshId) // <== only upload matrix palette to GL if the skininfo changed { // upload matrix palette to shader - const MatrixPaletteCache& mpc = updateSkinInfoMatrixPalette(avatar, skin); + const MatrixPaletteCache& mpc = updateSkinInfoMatrixPalette(avatar, meshId); U32 count = mpc.mMatrixPalette.size(); - stop_glerror(); + if (count == 0) + { + //skin info not loaded yet, don't render + continue; + } LLDrawPoolAvatar::sVertexProgram->uniformMatrix3x4fv(LLViewerShaderMgr::AVATAR_MATRIX, count, FALSE, (GLfloat*) &(mpc.mGLMp[0])); - - stop_glerror(); } + + lastMeshId = meshId; } else { data_mask &= ~LLVertexBuffer::MAP_WEIGHT4; } - lastSkin = skin; - - /*if (glow) - { - gGL.diffuseColor4f(0,0,0,face->getTextureEntry()->getGlow()); - }*/ - if (mat) { //order is important here LLRender::DIFFUSE_MAP should be last, becouse it change @@ -2332,13 +2272,17 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) { specular = face->getTexture(LLRender::SPECULAR_MAP); } - if (specular) + if (specular && specular_channel >= 0) { - gGL.getTexUnit(specular_channel)->bind(specular); + gGL.getTexUnit(specular_channel)->bindFast(specular); } - gGL.getTexUnit(normal_channel)->bind(face->getTexture(LLRender::NORMAL_MAP)); - gGL.getTexUnit(sDiffuseChannel)->bind(face->getTexture(LLRender::DIFFUSE_MAP), false, true); + if (normal_channel >= 0) + { + gGL.getTexUnit(normal_channel)->bindFast(face->getTexture(LLRender::NORMAL_MAP)); + } + + gGL.getTexUnit(sDiffuseChannel)->bindFast(face->getTexture(LLRender::DIFFUSE_MAP)); LLColor4 col = mat->getSpecularLightColor(); @@ -2369,23 +2313,28 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) sVertexProgram->setMinimumAlpha(0.f); } - for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i) - { - LLViewerTexture* tex = face->getTexture(i); - if (tex) - { - tex->addTextureStats(avatar->getPixelArea()); - } - } + if (!LLPipeline::sShadowRender && !LLPipeline::sReflectionRender) + { + for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i) + { + LLViewerTexture* tex = face->getTexture(i); + if (tex) + { + tex->addTextureStats(avatar->getPixelArea()); + } + } + } } else { - gGL.getTexUnit(sDiffuseChannel)->bind(face->getTexture()); sVertexProgram->setMinimumAlpha(0.f); if (normal_channel > -1) { LLDrawPoolBump::bindBumpMap(face, normal_channel); } + + gGL.getTexUnit(sDiffuseChannel)->bindFast(face->getTexture()); + } if (face->mTextureMatrix && vobj->mTexAnimMode) @@ -2399,8 +2348,8 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) gGL.loadMatrix((F32*) face->mTextureMatrix->mMatrix); } - buff->setBuffer(data_mask); - buff->drawRange(LLRender::TRIANGLES, start, end, count, offset); + buff->setBufferFast(data_mask); + buff->drawRangeFast(LLRender::TRIANGLES, start, end, count, offset); if (tex_index <= 1) { @@ -2411,11 +2360,9 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) } else { - buff->setBuffer(data_mask); - buff->drawRange(LLRender::TRIANGLES, start, end, count, offset); + buff->setBufferFast(data_mask); + buff->drawRangeFast(LLRender::TRIANGLES, start, end, count, offset); } - - gPipeline.addTrianglesDrawn(count, LLRender::TRIANGLES); } } } @@ -2476,8 +2423,6 @@ void LLDrawPoolAvatar::updateRiggedVertexBuffers(LLVOAvatar* avatar) continue; } - stop_glerror(); - LLVolumeFace& vol_face = volume->getVolumeFace(te); updateRiggedFaceVertexBuffer(avatar, face, vobj, volume, vol_face); } @@ -2501,47 +2446,58 @@ void LLDrawPoolAvatar::updateSkinInfoMatrixPalettes(LLVOAvatar* avatarp) } } -const LLDrawPoolAvatar::MatrixPaletteCache& LLDrawPoolAvatar::updateSkinInfoMatrixPalette(LLVOAvatar * avatarp, const LLMeshSkinInfo* skin) +const LLDrawPoolAvatar::MatrixPaletteCache& LLDrawPoolAvatar::updateSkinInfoMatrixPalette(LLVOAvatar * avatarp, const LLUUID& meshId) { - MatrixPaletteCache& entry = mMatrixPaletteCache[skin]; + MatrixPaletteCache& entry = mMatrixPaletteCache[meshId]; if (entry.mFrame != gFrameCount) { LL_PROFILE_ZONE_SCOPED; + + const LLMeshSkinInfo* skin = gMeshRepo.getSkinInfo(meshId); entry.mFrame = gFrameCount; - //build matrix palette - U32 count = LLSkinningUtil::getMeshJointCount(skin); - entry.mMatrixPalette.resize(count); - LLSkinningUtil::initSkinningMatrixPalette(&(entry.mMatrixPalette[0]), count, skin, avatarp); - const LLMatrix4a* mat = &(entry.mMatrixPalette[0]); + if (skin != nullptr) + { + entry.mBindShapeMatrix = skin->mBindShapeMatrix; + + //build matrix palette + U32 count = LLSkinningUtil::getMeshJointCount(skin); + entry.mMatrixPalette.resize(count); + LLSkinningUtil::initSkinningMatrixPalette(&(entry.mMatrixPalette[0]), count, skin, avatarp); - stop_glerror(); - - entry.mGLMp.resize(count * 12); + const LLMatrix4a* mat = &(entry.mMatrixPalette[0]); - F32* mp = &(entry.mGLMp[0]); - - for (U32 i = 0; i < count; ++i) - { - F32* m = (F32*)mat[i].mMatrix[0].getF32ptr(); + entry.mGLMp.resize(count * 12); + + F32* mp = &(entry.mGLMp[0]); + + for (U32 i = 0; i < count; ++i) + { + F32* m = (F32*)mat[i].mMatrix[0].getF32ptr(); - U32 idx = i * 12; + U32 idx = i * 12; - mp[idx + 0] = m[0]; - mp[idx + 1] = m[1]; - mp[idx + 2] = m[2]; - mp[idx + 3] = m[12]; + mp[idx + 0] = m[0]; + mp[idx + 1] = m[1]; + mp[idx + 2] = m[2]; + mp[idx + 3] = m[12]; - mp[idx + 4] = m[4]; - mp[idx + 5] = m[5]; - mp[idx + 6] = m[6]; - mp[idx + 7] = m[13]; + mp[idx + 4] = m[4]; + mp[idx + 5] = m[5]; + mp[idx + 6] = m[6]; + mp[idx + 7] = m[13]; - mp[idx + 8] = m[8]; - mp[idx + 9] = m[9]; - mp[idx + 10] = m[10]; - mp[idx + 11] = m[14]; + mp[idx + 8] = m[8]; + mp[idx + 9] = m[9]; + mp[idx + 10] = m[10]; + mp[idx + 11] = m[14]; + } + } + else + { + entry.mMatrixPalette.resize(0); + entry.mGLMp.resize(0); } } diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h index 0c1ee2cced..800bbc5f62 100644 --- a/indra/newview/lldrawpoolavatar.h +++ b/indra/newview/lldrawpoolavatar.h @@ -283,12 +283,13 @@ typedef enum std::vector mRiggedFace[NUM_RIGGED_PASSES]; + LL_ALIGN_PREFIX(16) class MatrixPaletteCache { public: U32 mFrame; LLMeshSkinInfo::matrix_list_t mMatrixPalette; - + LL_ALIGN_16(LLMatrix4a mBindShapeMatrix); // Float array ready to be sent to GL std::vector mGLMp; @@ -296,11 +297,11 @@ typedef enum mFrame(gFrameCount-1) { } - }; + } LL_ALIGN_POSTFIX(16); - const MatrixPaletteCache& updateSkinInfoMatrixPalette(LLVOAvatar* avatarp, const LLMeshSkinInfo* skin); + const MatrixPaletteCache& updateSkinInfoMatrixPalette(LLVOAvatar* avatarp, const LLUUID& meshId); - typedef std::unordered_map matrix_palette_cache_t; + typedef std::unordered_map matrix_palette_cache_t; matrix_palette_cache_t mMatrixPaletteCache; /*virtual*/ LLViewerTexture *getDebugTexture(); diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 8ac64dbd15..a19d6d0b19 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -4045,7 +4045,7 @@ S32 LLMeshRepository::getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lo const LLMeshSkinInfo* LLMeshRepository::getSkinInfo(const LLUUID& mesh_id, const LLVOVolume* requesting_obj) { - LL_RECORD_BLOCK_TIME(FTM_MESH_FETCH); + LL_PROFILE_ZONE_SCOPED; if (mesh_id.notNull()) { skin_map::iterator iter = mSkinMap.find(mesh_id); @@ -4055,6 +4055,7 @@ const LLMeshSkinInfo* LLMeshRepository::getSkinInfo(const LLUUID& mesh_id, const } //no skin info known about given mesh, try to fetch it + if (requesting_obj != nullptr) { LLMutexLock lock(mMeshMutex); //add volume to list of loading meshes diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index c1698194cb..c0e894fda4 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -586,7 +586,7 @@ public: S32 getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod); static S32 getActualMeshLOD(LLSD& header, S32 lod); - const LLMeshSkinInfo* getSkinInfo(const LLUUID& mesh_id, const LLVOVolume* requesting_obj); + const LLMeshSkinInfo* getSkinInfo(const LLUUID& mesh_id, const LLVOVolume* requesting_obj = nullptr); LLModel::Decomposition* getDecomposition(const LLUUID& mesh_id); void fetchPhysicsShape(const LLUUID& mesh_id); bool hasPhysicsShape(const LLUUID& mesh_id); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index e5a4b0f374..b86935b081 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -3555,7 +3555,7 @@ const LLMeshSkinInfo* LLVOVolume::getSkinInfo() const { if (getVolume()) { - return gMeshRepo.getSkinInfo(getVolume()->getParams().getSculptID(), this); + return gMeshRepo.getSkinInfo(getMeshID(), this); } else { diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index ce400a3498..b8c6f47bbd 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -296,6 +296,9 @@ public: BOOL setIsFlexible(BOOL is_flexible); const LLMeshSkinInfo* getSkinInfo() const; + + //convenience accessor for mesh ID (which is stored in sculpt id for legacy reasons) + const LLUUID& getMeshID() const { return getVolume()->getParams().getSculptID(); } // Extended Mesh Properties U32 getExtendedMeshFlags() const; -- cgit v1.2.3 From d2dce17803a545378407d6b7c62fdcd3007a92bc Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 19 Oct 2021 02:26:41 +0000 Subject: SL-16197 Optimize LLEnvironment handling of shader uniforms. Instrument LLSD. Enable Fast Timers when Tracy is enabled to catch Fast Timer overhead. --- indra/cmake/Tracy.cmake | 2 +- indra/llcommon/llsd.cpp | 32 +++++++++++--- indra/llcommon/llsd.h | 12 +++++- indra/llinventory/llsettingsbase.cpp | 4 ++ indra/llinventory/llsettingssky.cpp | 3 ++ indra/llrender/llglslshader.cpp | 68 +++++++++++++++++++++--------- indra/llrender/llglslshader.h | 82 ++++++++++++++++++++++++++++++++---- indra/newview/lldrawpoolbump.cpp | 1 + indra/newview/lldrawpoolterrain.cpp | 2 - indra/newview/lldrawpoolwlsky.cpp | 6 --- indra/newview/llenvironment.cpp | 39 ++++++++++++++--- indra/newview/llenvironment.h | 18 ++++++-- indra/newview/llsettingsvo.cpp | 68 +++++++++++++++--------------- indra/newview/llsettingsvo.h | 4 -- indra/newview/pipeline.cpp | 2 - 15 files changed, 247 insertions(+), 96 deletions(-) diff --git a/indra/cmake/Tracy.cmake b/indra/cmake/Tracy.cmake index 1b8c3db2e2..cfff956bcf 100644 --- a/indra/cmake/Tracy.cmake +++ b/indra/cmake/Tracy.cmake @@ -7,7 +7,7 @@ if (USE_TRACY) set(TRACY_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/tracy) # See: indra/llcommon/llprofiler.h - add_definitions(-DLL_PROFILER_CONFIGURATION=2) + add_definitions(-DLL_PROFILER_CONFIGURATION=3) use_prebuilt_binary(tracy) if (WINDOWS) diff --git a/indra/llcommon/llsd.cpp b/indra/llcommon/llsd.cpp index 57b746889d..605f6bf0e3 100644 --- a/indra/llcommon/llsd.cpp +++ b/indra/llcommon/llsd.cpp @@ -400,6 +400,7 @@ namespace ImplMap& ImplMap::makeMap(LLSD::Impl*& var) { + LL_PROFILE_ZONE_SCOPED; if (shared()) { ImplMap* i = new ImplMap(mData); @@ -414,18 +415,21 @@ namespace bool ImplMap::has(const LLSD::String& k) const { + LL_PROFILE_ZONE_SCOPED; DataMap::const_iterator i = mData.find(k); return i != mData.end(); } LLSD ImplMap::get(const LLSD::String& k) const { + LL_PROFILE_ZONE_SCOPED; DataMap::const_iterator i = mData.find(k); return (i != mData.end()) ? i->second : LLSD(); } LLSD ImplMap::getKeys() const { + LL_PROFILE_ZONE_SCOPED; LLSD keys = LLSD::emptyArray(); DataMap::const_iterator iter = mData.begin(); while (iter != mData.end()) @@ -438,11 +442,13 @@ namespace void ImplMap::insert(const LLSD::String& k, const LLSD& v) { + LL_PROFILE_ZONE_SCOPED; mData.insert(DataMap::value_type(k, v)); } void ImplMap::erase(const LLSD::String& k) { + LL_PROFILE_ZONE_SCOPED; mData.erase(k); } @@ -684,6 +690,7 @@ const LLSD::Impl& LLSD::Impl::safe(const Impl* impl) ImplMap& LLSD::Impl::makeMap(Impl*& var) { + LL_PROFILE_ZONE_SCOPED; ImplMap* im = new ImplMap; reset(var, im); return *im; @@ -887,11 +894,16 @@ LLSD& LLSD::with(const String& k, const LLSD& v) } void LLSD::erase(const String& k) { makeMap(impl).erase(k); } -LLSD& LLSD::operator[](const String& k) - { return makeMap(impl).ref(k); } +LLSD& LLSD::operator[](const String& k) +{ + LL_PROFILE_ZONE_SCOPED; + return makeMap(impl).ref(k); +} const LLSD& LLSD::operator[](const String& k) const - { return safe(impl).ref(k); } - +{ + LL_PROFILE_ZONE_SCOPED; + return safe(impl).ref(k); +} LLSD LLSD::emptyArray() { @@ -914,10 +926,16 @@ LLSD& LLSD::with(Integer i, const LLSD& v) LLSD& LLSD::append(const LLSD& v) { return makeArray(impl).append(v); } void LLSD::erase(Integer i) { makeArray(impl).erase(i); } -LLSD& LLSD::operator[](Integer i) - { return makeArray(impl).ref(i); } +LLSD& LLSD::operator[](Integer i) +{ + LL_PROFILE_ZONE_SCOPED; + return makeArray(impl).ref(i); +} const LLSD& LLSD::operator[](Integer i) const - { return safe(impl).ref(i); } +{ + LL_PROFILE_ZONE_SCOPED; + return safe(impl).ref(i); +} static const char *llsd_dump(const LLSD &llsd, bool useXMLFormat) { diff --git a/indra/llcommon/llsd.h b/indra/llcommon/llsd.h index 5b6d5545af..b8ddf21596 100644 --- a/indra/llcommon/llsd.h +++ b/indra/llcommon/llsd.h @@ -290,9 +290,17 @@ public: LLSD& with(const String&, const LLSD&); LLSD& operator[](const String&); - LLSD& operator[](const char* c) { return (*this)[String(c)]; } + LLSD& operator[](const char* c) + { + LL_PROFILE_ZONE_SCOPED; + return (*this)[String(c)]; + } const LLSD& operator[](const String&) const; - const LLSD& operator[](const char* c) const { return (*this)[String(c)]; } + const LLSD& operator[](const char* c) const + { + LL_PROFILE_ZONE_SCOPED; + return (*this)[String(c)]; + } //@} /** @name Array Values */ diff --git a/indra/llinventory/llsettingsbase.cpp b/indra/llinventory/llsettingsbase.cpp index 61b59e35aa..89a4eebf26 100644 --- a/indra/llinventory/llsettingsbase.cpp +++ b/indra/llinventory/llsettingsbase.cpp @@ -683,6 +683,7 @@ bool LLSettingsBase::Validator::verifyStringLength(LLSD &value, S32 length) //========================================================================= void LLSettingsBlender::update(const LLSettingsBase::BlendFactor& blendf) { + LL_PROFILE_ZONE_SCOPED; F64 res = setBlendFactor(blendf); llassert(res >= 0.0 && res <= 1.0); (void)res; @@ -713,6 +714,7 @@ F64 LLSettingsBlender::setBlendFactor(const LLSettingsBase::BlendFactor& blendf_ void LLSettingsBlender::triggerComplete() { + LL_PROFILE_ZONE_SCOPED; if (mTarget) mTarget->replaceSettings(mFinal->getSettings()); LLSettingsBlender::ptr_t hold = shared_from_this(); // prevents this from deleting too soon @@ -725,11 +727,13 @@ const LLSettingsBase::BlendFactor LLSettingsBlenderTimeDelta::MIN_BLEND_DELTA(FL LLSettingsBase::BlendFactor LLSettingsBlenderTimeDelta::calculateBlend(const LLSettingsBase::TrackPosition& spanpos, const LLSettingsBase::TrackPosition& spanlen) const { + LL_PROFILE_ZONE_SCOPED; return LLSettingsBase::BlendFactor(fmod((F64)spanpos, (F64)spanlen) / (F64)spanlen); } bool LLSettingsBlenderTimeDelta::applyTimeDelta(const LLSettingsBase::Seconds& timedelta) { + LL_PROFILE_ZONE_SCOPED; mTimeSpent += timedelta; if (mTimeSpent > mBlendSpan) diff --git a/indra/llinventory/llsettingssky.cpp b/indra/llinventory/llsettingssky.cpp index 81937dbda5..00c1edb55a 100644 --- a/indra/llinventory/llsettingssky.cpp +++ b/indra/llinventory/llsettingssky.cpp @@ -444,6 +444,7 @@ void LLSettingsSky::replaceWithSky(LLSettingsSky::ptr_t pother) void LLSettingsSky::blend(const LLSettingsBase::ptr_t &end, F64 blendf) { + LL_PROFILE_ZONE_SCOPED; llassert(getSettingsType() == end->getSettingsType()); LLSettingsSky::ptr_t other = PTR_NAMESPACE::dynamic_pointer_cast(end); @@ -1022,6 +1023,7 @@ LLColor3 LLSettingsSky::getLightDiffuse() const LLColor3 LLSettingsSky::getColor(const std::string& key, const LLColor3& default_value) const { + LL_PROFILE_ZONE_SCOPED; if (mSettings.has(SETTING_LEGACY_HAZE) && mSettings[SETTING_LEGACY_HAZE].has(key)) { return LLColor3(mSettings[SETTING_LEGACY_HAZE][key]); @@ -1035,6 +1037,7 @@ LLColor3 LLSettingsSky::getColor(const std::string& key, const LLColor3& default F32 LLSettingsSky::getFloat(const std::string& key, F32 default_value) const { + LL_PROFILE_ZONE_SCOPED; if (mSettings.has(SETTING_LEGACY_HAZE) && mSettings[SETTING_LEGACY_HAZE].has(key)) { return mSettings[SETTING_LEGACY_HAZE][key].asReal(); diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index 84eac00c65..0e4753fcc6 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -1104,6 +1104,7 @@ S32 LLGLSLShader::disableTexture(S32 uniform, LLTexUnit::eTextureType mode, LLTe void LLGLSLShader::uniform1i(U32 index, GLint x) { + LL_PROFILE_ZONE_SCOPED if (mProgramObject) { if (mUniform.size() <= index) @@ -1114,7 +1115,7 @@ void LLGLSLShader::uniform1i(U32 index, GLint x) if (mUniform[index] >= 0) { - std::map::iterator iter = mValue.find(mUniform[index]); + const auto& iter = mValue.find(mUniform[index]); if (iter == mValue.end() || iter->second.mV[0] != x) { glUniform1iARB(mUniform[index], x); @@ -1126,6 +1127,7 @@ void LLGLSLShader::uniform1i(U32 index, GLint x) void LLGLSLShader::uniform1f(U32 index, GLfloat x) { + LL_PROFILE_ZONE_SCOPED if (mProgramObject) { if (mUniform.size() <= index) @@ -1136,7 +1138,7 @@ void LLGLSLShader::uniform1f(U32 index, GLfloat x) if (mUniform[index] >= 0) { - std::map::iterator iter = mValue.find(mUniform[index]); + const auto& iter = mValue.find(mUniform[index]); if (iter == mValue.end() || iter->second.mV[0] != x) { glUniform1fARB(mUniform[index], x); @@ -1158,7 +1160,7 @@ void LLGLSLShader::uniform2f(U32 index, GLfloat x, GLfloat y) if (mUniform[index] >= 0) { - std::map::iterator iter = mValue.find(mUniform[index]); + const auto& iter = mValue.find(mUniform[index]); LLVector4 vec(x,y,0.f,0.f); if (iter == mValue.end() || shouldChange(iter->second,vec)) { @@ -1181,7 +1183,7 @@ void LLGLSLShader::uniform3f(U32 index, GLfloat x, GLfloat y, GLfloat z) if (mUniform[index] >= 0) { - std::map::iterator iter = mValue.find(mUniform[index]); + const auto& iter = mValue.find(mUniform[index]); LLVector4 vec(x,y,z,0.f); if (iter == mValue.end() || shouldChange(iter->second,vec)) { @@ -1204,7 +1206,7 @@ void LLGLSLShader::uniform4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat if (mUniform[index] >= 0) { - std::map::iterator iter = mValue.find(mUniform[index]); + const auto& iter = mValue.find(mUniform[index]); LLVector4 vec(x,y,z,w); if (iter == mValue.end() || shouldChange(iter->second,vec)) { @@ -1227,7 +1229,7 @@ void LLGLSLShader::uniform1iv(U32 index, U32 count, const GLint* v) if (mUniform[index] >= 0) { - std::map::iterator iter = mValue.find(mUniform[index]); + const auto& iter = mValue.find(mUniform[index]); LLVector4 vec(v[0],0.f,0.f,0.f); if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) { @@ -1250,7 +1252,7 @@ void LLGLSLShader::uniform1fv(U32 index, U32 count, const GLfloat* v) if (mUniform[index] >= 0) { - std::map::iterator iter = mValue.find(mUniform[index]); + const auto& iter = mValue.find(mUniform[index]); LLVector4 vec(v[0],0.f,0.f,0.f); if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) { @@ -1273,7 +1275,7 @@ void LLGLSLShader::uniform2fv(U32 index, U32 count, const GLfloat* v) if (mUniform[index] >= 0) { - std::map::iterator iter = mValue.find(mUniform[index]); + const auto& iter = mValue.find(mUniform[index]); LLVector4 vec(v[0],v[1],0.f,0.f); if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) { @@ -1296,7 +1298,7 @@ void LLGLSLShader::uniform3fv(U32 index, U32 count, const GLfloat* v) if (mUniform[index] >= 0) { - std::map::iterator iter = mValue.find(mUniform[index]); + const auto& iter = mValue.find(mUniform[index]); LLVector4 vec(v[0],v[1],v[2],0.f); if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) { @@ -1319,10 +1321,11 @@ void LLGLSLShader::uniform4fv(U32 index, U32 count, const GLfloat* v) if (mUniform[index] >= 0) { - std::map::iterator iter = mValue.find(mUniform[index]); + const auto& iter = mValue.find(mUniform[index]); LLVector4 vec(v[0],v[1],v[2],v[3]); if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) { + LL_PROFILE_ZONE_SCOPED; glUniform4fvARB(mUniform[index], count, v); mValue[mUniform[index]] = vec; } @@ -1460,7 +1463,7 @@ void LLGLSLShader::uniform1i(const LLStaticHashedString& uniform, GLint v) if (location >= 0) { - std::map::iterator iter = mValue.find(location); + const auto& iter = mValue.find(location); LLVector4 vec(v,0.f,0.f,0.f); if (iter == mValue.end() || shouldChange(iter->second,vec)) { @@ -1476,7 +1479,7 @@ void LLGLSLShader::uniform2i(const LLStaticHashedString& uniform, GLint i, GLint if (location >= 0) { - std::map::iterator iter = mValue.find(location); + const auto& iter = mValue.find(location); LLVector4 vec(i,j,0.f,0.f); if (iter == mValue.end() || shouldChange(iter->second,vec)) { @@ -1493,7 +1496,7 @@ void LLGLSLShader::uniform1f(const LLStaticHashedString& uniform, GLfloat v) if (location >= 0) { - std::map::iterator iter = mValue.find(location); + const auto& iter = mValue.find(location); LLVector4 vec(v,0.f,0.f,0.f); if (iter == mValue.end() || shouldChange(iter->second,vec)) { @@ -1509,7 +1512,7 @@ void LLGLSLShader::uniform2f(const LLStaticHashedString& uniform, GLfloat x, GLf if (location >= 0) { - std::map::iterator iter = mValue.find(location); + const auto& iter = mValue.find(location); LLVector4 vec(x,y,0.f,0.f); if (iter == mValue.end() || shouldChange(iter->second,vec)) { @@ -1526,7 +1529,7 @@ void LLGLSLShader::uniform3f(const LLStaticHashedString& uniform, GLfloat x, GLf if (location >= 0) { - std::map::iterator iter = mValue.find(location); + const auto& iter = mValue.find(location); LLVector4 vec(x,y,z,0.f); if (iter == mValue.end() || shouldChange(iter->second,vec)) { @@ -1542,7 +1545,7 @@ void LLGLSLShader::uniform1fv(const LLStaticHashedString& uniform, U32 count, co if (location >= 0) { - std::map::iterator iter = mValue.find(location); + const auto& iter = mValue.find(location); LLVector4 vec(v[0],0.f,0.f,0.f); if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) { @@ -1558,7 +1561,7 @@ void LLGLSLShader::uniform2fv(const LLStaticHashedString& uniform, U32 count, co if (location >= 0) { - std::map::iterator iter = mValue.find(location); + const auto& iter = mValue.find(location); LLVector4 vec(v[0],v[1],0.f,0.f); if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) { @@ -1574,7 +1577,7 @@ void LLGLSLShader::uniform3fv(const LLStaticHashedString& uniform, U32 count, co if (location >= 0) { - std::map::iterator iter = mValue.find(location); + const auto& iter = mValue.find(location); LLVector4 vec(v[0],v[1],v[2],0.f); if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) { @@ -1591,12 +1594,11 @@ void LLGLSLShader::uniform4fv(const LLStaticHashedString& uniform, U32 count, co if (location >= 0) { LLVector4 vec(v); - std::map::iterator iter = mValue.find(location); + const auto& iter = mValue.find(location); if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) { - stop_glerror(); + LL_PROFILE_ZONE_SCOPED; glUniform4fvARB(location, count, v); - stop_glerror(); mValue[location] = vec; } } @@ -1636,3 +1638,27 @@ void LLGLSLShader::setMinimumAlpha(F32 minimum) gGL.flush(); uniform1f(LLShaderMgr::MINIMUM_ALPHA, minimum); } + +void LLShaderUniforms::apply(LLGLSLShader* shader) +{ + LL_PROFILE_ZONE_SCOPED; + for (auto& uniform : mIntegers) + { + shader->uniform1i(uniform.mUniform, uniform.mValue); + } + + for (auto& uniform : mFloats) + { + shader->uniform1f(uniform.mUniform, uniform.mValue); + } + + for (auto& uniform : mVectors) + { + shader->uniform4fv(uniform.mUniform, 1, uniform.mValue.mV); + } + + for (auto& uniform : mVector3s) + { + shader->uniform3fv(uniform.mUniform, 1, uniform.mValue.mV); + } +} diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h index 7cf6d3c941..3b23cf1b28 100644 --- a/indra/llrender/llglslshader.h +++ b/indra/llrender/llglslshader.h @@ -30,6 +30,7 @@ #include "llgl.h" #include "llrender.h" #include "llstaticstringtable.h" +#include class LLShaderFeatures { @@ -64,16 +65,79 @@ public: LLShaderFeatures(); }; +// ============= Structure for caching shader uniforms =============== +class LLGLSLShader; + +class LLShaderUniforms +{ +public: + + template + struct UniformSetting + { + S32 mUniform; + T mValue; + }; + + typedef UniformSetting IntSetting; + typedef UniformSetting FloatSetting; + typedef UniformSetting VectorSetting; + typedef UniformSetting Vector3Setting; + + void clear() + { + mIntegers.resize(0); + mFloats.resize(0); + mVectors.resize(0); + mVector3s.resize(0); + } + + void uniform1i(S32 index, S32 value) + { + mIntegers.push_back({ index, value }); + } + + void uniform1f(S32 index, F32 value) + { + mFloats.push_back({ index, value }); + } + + void uniform4fv(S32 index, const LLVector4& value) + { + mVectors.push_back({ index, value }); + } + + void uniform4fv(S32 index, const F32* value) + { + mVectors.push_back({ index, LLVector4(value) }); + } + + void uniform3fv(S32 index, const LLVector3& value) + { + mVector3s.push_back({ index, value }); + } + + void apply(LLGLSLShader* shader); + + + std::vector mIntegers; + std::vector mFloats; + std::vector mVectors; + std::vector mVector3s; +}; class LLGLSLShader { public: - enum + // enum primarily used to control application sky settings uniforms + typedef enum { - SG_DEFAULT = 0, - SG_SKY, - SG_WATER - }; + SG_DEFAULT = 0, // not sky or water specific + SG_SKY, // + SG_WATER, + SG_ANY, + SG_COUNT + } eGroup; static std::set sInstances; static bool sProfileEnabled; @@ -190,13 +254,15 @@ public: U32 mAttributeMask; //mask of which reserved attributes are set (lines up with LLVertexBuffer::getTypeMask()) std::vector mUniform; //lookup table of uniform enum to uniform location LLStaticStringTable mUniformMap; //lookup map of uniform name to uniform location - std::map mUniformNameMap; //lookup map of uniform location to uniform name - std::map mValue; //lookup map of uniform location to last known value + typedef std::unordered_map uniform_name_map_t; + typedef std::unordered_map uniform_value_map_t; + uniform_name_map_t mUniformNameMap; //lookup map of uniform location to uniform name + uniform_value_map_t mValue; //lookup map of uniform location to last known value std::vector mTexture; S32 mTotalUniformSize; S32 mActiveTextureChannels; S32 mShaderLevel; - S32 mShaderGroup; + S32 mShaderGroup; // see LLGLSLShader::eGroup BOOL mUniformsDirty; LLShaderFeatures mFeatures; std::vector< std::pair< std::string, GLenum > > mShaderFiles; diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index f316d121ab..d75884cc16 100644 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -1062,6 +1062,7 @@ void LLBumpImageList::updateImages() // Note: the caller SHOULD NOT keep the pointer that this function returns. It may be updated as more data arrives. LLViewerTexture* LLBumpImageList::getBrightnessDarknessImage(LLViewerFetchedTexture* src_image, U8 bump_code ) { + LL_PROFILE_ZONE_SCOPED; llassert( (bump_code == BE_BRIGHTNESS) || (bump_code == BE_DARKNESS) ); LLViewerTexture* bump = NULL; diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index 37dc80e2b7..34a8b6b2cc 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -343,8 +343,6 @@ void LLDrawPoolTerrain::renderFullShader() LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater(); - ((LLSettingsVOWater*)pwater.get())->updateShader(shader); - // // detail texture 1 // diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp index 0c3d8f3098..8c8dc3f3d2 100644 --- a/indra/newview/lldrawpoolwlsky.cpp +++ b/indra/newview/lldrawpoolwlsky.cpp @@ -182,8 +182,6 @@ void LLDrawPoolWLSky::renderSkyHazeDeferred(const LLVector3& camPosLocal, F32 ca sky_shader->bindTexture(LLShaderMgr::RAINBOW_MAP, rainbow_tex); sky_shader->bindTexture(LLShaderMgr::HALO_MAP, halo_tex); - ((LLSettingsVOSky*)psky.get())->updateShader(sky_shader); - F32 moisture_level = (float)psky->getSkyMoistureLevel(); F32 droplet_radius = (float)psky->getSkyDropletRadius(); F32 ice_level = (float)psky->getSkyIceLevel(); @@ -406,8 +404,6 @@ void LLDrawPoolWLSky::renderSkyCloudsDeferred(const LLVector3& camPosLocal, F32 cloudshader->uniform1f(LLShaderMgr::CLOUD_VARIANCE, cloud_variance); cloudshader->uniform1f(LLShaderMgr::SUN_MOON_GLOW_FACTOR, psky->getSunMoonGlowFactor()); - ((LLSettingsVOSky*)psky.get())->updateShader(cloudshader); - /// Render the skydome renderDome(camPosLocal, camHeightLocal, cloudshader); @@ -462,8 +458,6 @@ void LLDrawPoolWLSky::renderSkyClouds(const LLVector3& camPosLocal, F32 camHeigh cloudshader->uniform1f(LLShaderMgr::CLOUD_VARIANCE, cloud_variance); cloudshader->uniform1f(LLShaderMgr::SUN_MOON_GLOW_FACTOR, psky->getSunMoonGlowFactor()); - ((LLSettingsVOSky*)psky.get())->updateShader(cloudshader); - /// Render the skydome renderDome(camPosLocal, camHeightLocal, cloudshader); diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp index 8881d11802..69d3075928 100644 --- a/indra/newview/llenvironment.cpp +++ b/indra/newview/llenvironment.cpp @@ -1471,6 +1471,7 @@ LLEnvironment::DayInstance::ptr_t LLEnvironment::getSharedEnvironmentInstance() void LLEnvironment::updateEnvironment(LLSettingsBase::Seconds transition, bool forced) { + LL_PROFILE_ZONE_SCOPED; DayInstance::ptr_t pinstance = getSelectedEnvironmentInstance(); if ((mCurrentEnvironment != pinstance) || forced) @@ -1488,6 +1489,8 @@ void LLEnvironment::updateEnvironment(LLSettingsBase::Seconds transition, bool f { mCurrentEnvironment = pinstance; } + + updateSettingsUniforms(); } } @@ -1614,6 +1617,8 @@ void LLEnvironment::update(const LLViewerCamera * cam) stop_glerror(); + updateSettingsUniforms(); + // *TODO: potential optimization - this block may only need to be // executed some of the time. For example for water shaders only. { @@ -1648,10 +1653,16 @@ void LLEnvironment::updateCloudScroll() } // static -void LLEnvironment::updateGLVariablesForSettings(LLGLSLShader *shader, const LLSettingsBase::ptr_t &psetting) +void LLEnvironment::updateGLVariablesForSettings(LLShaderUniforms* uniforms, const LLSettingsBase::ptr_t &psetting) { LL_RECORD_BLOCK_TIME(FTM_SHADER_PARAM_UPDATE); + for (int i = 0; i < LLGLSLShader::SG_COUNT; ++i) + { + uniforms[i].clear(); + } + + LLShaderUniforms* shader = &uniforms[LLGLSLShader::SG_ANY]; //_WARNS("RIDER") << "----------------------------------------------------------------" << LL_ENDL; LLSettingsBase::parammapping_t params = psetting->getParameterMap(); for (auto &it: params) @@ -1694,7 +1705,7 @@ void LLEnvironment::updateGLVariablesForSettings(LLGLSLShader *shader, const LLS { LLVector4 vect4(value); //_WARNS("RIDER") << "pushing '" << (*it).first << "' as " << vect4 << LL_ENDL; - shader->uniform4fv(it.second.getShaderKey(), 1, vect4.mV); + shader->uniform4fv(it.second.getShaderKey(), vect4 ); break; } @@ -1707,17 +1718,30 @@ void LLEnvironment::updateGLVariablesForSettings(LLGLSLShader *shader, const LLS default: break; } - stop_glerror(); } //_WARNS("RIDER") << "----------------------------------------------------------------" << LL_ENDL; - psetting->applySpecial(shader); + psetting->applySpecial(uniforms); +} + +void LLEnvironment::updateShaderUniforms(LLGLSLShader* shader) +{ + LL_PROFILE_ZONE_SCOPED; + + // apply uniforms that should be applied to all shaders + mSkyUniforms[LLGLSLShader::SG_ANY].apply(shader); + mWaterUniforms[LLGLSLShader::SG_ANY].apply(shader); + + // apply uniforms specific to the given shader's shader group + auto group = shader->mShaderGroup; + mSkyUniforms[group].apply(shader); + mWaterUniforms[group].apply(shader); } -void LLEnvironment::updateShaderUniforms(LLGLSLShader *shader) +void LLEnvironment::updateSettingsUniforms() { - updateGLVariablesForSettings(shader, mCurrentEnvironment->getWater()); - updateGLVariablesForSettings(shader, mCurrentEnvironment->getSky()); + updateGLVariablesForSettings(mWaterUniforms, mCurrentEnvironment->getWater()); + updateGLVariablesForSettings(mSkyUniforms, mCurrentEnvironment->getSky()); } void LLEnvironment::recordEnvironment(S32 parcel_id, LLEnvironment::EnvironmentInfo::ptr_t envinfo, LLSettingsBase::Seconds transition) @@ -2618,6 +2642,7 @@ LLEnvironment::DayInstance::ptr_t LLEnvironment::DayInstance::clone() const bool LLEnvironment::DayInstance::applyTimeDelta(const LLSettingsBase::Seconds& delta) { + LL_PROFILE_ZONE_SCOPED; ptr_t keeper(shared_from_this()); // makes sure that this does not go away while it is being worked on. bool changed(false); diff --git a/indra/newview/llenvironment.h b/indra/newview/llenvironment.h index 7cbf2d25bb..3568fbcfd1 100644 --- a/indra/newview/llenvironment.h +++ b/indra/newview/llenvironment.h @@ -38,11 +38,12 @@ #include "llatmosphere.h" +#include "llglslshader.h" + #include //------------------------------------------------------------------------- class LLViewerCamera; -class LLGLSLShader; class LLParcel; //------------------------------------------------------------------------- @@ -50,8 +51,8 @@ class LLEnvironment : public LLSingleton { LLSINGLETON_C11(LLEnvironment); LOG_CLASS(LLEnvironment); - public: + static const F64Seconds TRANSITION_INSTANT; static const F64Seconds TRANSITION_FAST; static const F64Seconds TRANSITION_DEFAULT; @@ -131,9 +132,14 @@ public: void update(const LLViewerCamera * cam); - static void updateGLVariablesForSettings(LLGLSLShader *shader, const LLSettingsBase::ptr_t &psetting); + static void updateGLVariablesForSettings(LLShaderUniforms* uniforms, const LLSettingsBase::ptr_t &psetting); + + // apply current sky settings to given shader void updateShaderUniforms(LLGLSLShader *shader); + // prepare settings to be applied to shaders (call whenever settings are updated) + void updateSettingsUniforms(); + void setSelectedEnvironment(EnvSelection_t env, LLSettingsBase::Seconds transition = TRANSITION_DEFAULT, bool forced = false); EnvSelection_t getSelectedEnvironment() const { return mSelectedEnvironment; } @@ -234,6 +240,11 @@ public: void handleEnvironmentPush(LLSD &message); + //cached uniform values from LLSD values + LLShaderUniforms mWaterUniforms[LLGLSLShader::SG_COUNT]; + LLShaderUniforms mSkyUniforms[LLGLSLShader::SG_COUNT]; + // ======================================================================================= + class DayInstance: public std::enable_shared_from_this { public: @@ -288,6 +299,7 @@ public: LLSettingsDay::ptr_t mDayCycle; LLSettingsSky::ptr_t mSky; LLSettingsWater::ptr_t mWater; + S32 mSkyTrack; bool mInitialized; diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp index 1e5b893cbc..6a88a8ef2c 100644 --- a/indra/newview/llsettingsvo.cpp +++ b/indra/newview/llsettingsvo.cpp @@ -637,6 +637,7 @@ LLSD LLSettingsVOSky::convertToLegacy(const LLSettingsSky::ptr_t &psky, bool isA //------------------------------------------------------------------------- void LLSettingsVOSky::updateSettings() { + LL_PROFILE_ZONE_SCOPED; LLSettingsSky::updateSettings(); LLVector3 sun_direction = getSunDirection(); LLVector3 moon_direction = getMoonDirection(); @@ -665,55 +666,55 @@ void LLSettingsVOSky::updateSettings() void LLSettingsVOSky::applySpecial(void *ptarget, bool force) { - LLGLSLShader *shader = (LLGLSLShader *)ptarget; - LLVector4 light_direction = LLEnvironment::instance().getClampedLightNorm(); - if (shader->mShaderGroup == LLGLSLShader::SG_DEFAULT) + LLShaderUniforms* shader = &((LLShaderUniforms*)ptarget)[LLGLSLShader::SG_DEFAULT]; { - shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, light_direction.mV); - shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, 1, LLViewerCamera::getInstance()->getOrigin().mV); + shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, light_direction); + shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, LLViewerCamera::getInstance()->getOrigin()); } - else if (shader->mShaderGroup == LLGLSLShader::SG_SKY) + + shader = &((LLShaderUniforms*)ptarget)[LLGLSLShader::SG_SKY]; { - shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, light_direction.mV); + shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, light_direction); - // Legacy? SETTING_CLOUD_SCROLL_RATE("cloud_scroll_rate") - LLVector4 vect_c_p_d1(mSettings[SETTING_CLOUD_POS_DENSITY1]); - LLVector4 cloud_scroll( LLEnvironment::instance().getCloudScrollDelta() ); + // Legacy? SETTING_CLOUD_SCROLL_RATE("cloud_scroll_rate") + LLVector4 vect_c_p_d1(mSettings[SETTING_CLOUD_POS_DENSITY1]); + LLVector4 cloud_scroll( LLEnvironment::instance().getCloudScrollDelta() ); - // SL-13084 EEP added support for custom cloud textures -- flip them horizontally to match the preview of Clouds > Cloud Scroll - // Keep in Sync! - // * indra\newview\llsettingsvo.cpp - // * indra\newview\app_settings\shaders\class2\windlight\cloudsV.glsl - // * indra\newview\app_settings\shaders\class1\deferred\cloudsV.glsl - cloud_scroll[0] = -cloud_scroll[0]; - vect_c_p_d1 += cloud_scroll; - shader->uniform4fv(LLShaderMgr::CLOUD_POS_DENSITY1, 1, vect_c_p_d1.mV); + // SL-13084 EEP added support for custom cloud textures -- flip them horizontally to match the preview of Clouds > Cloud Scroll + // Keep in Sync! + // * indra\newview\llsettingsvo.cpp + // * indra\newview\app_settings\shaders\class2\windlight\cloudsV.glsl + // * indra\newview\app_settings\shaders\class1\deferred\cloudsV.glsl + cloud_scroll[0] = -cloud_scroll[0]; + vect_c_p_d1 += cloud_scroll; + shader->uniform4fv(LLShaderMgr::CLOUD_POS_DENSITY1, vect_c_p_d1); - LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); + LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); - LLColor4 sunDiffuse = psky->getSunlightColor(); - LLColor4 moonDiffuse = psky->getMoonlightColor(); + LLVector4 sunDiffuse = LLVector4(psky->getSunlightColor().mV); + LLVector4 moonDiffuse = LLVector4(psky->getMoonlightColor().mV); - shader->uniform4fv(LLShaderMgr::SUNLIGHT_COLOR, 1, sunDiffuse.mV); - shader->uniform4fv(LLShaderMgr::MOONLIGHT_COLOR, 1, moonDiffuse.mV); + shader->uniform4fv(LLShaderMgr::SUNLIGHT_COLOR, sunDiffuse); + shader->uniform4fv(LLShaderMgr::MOONLIGHT_COLOR, moonDiffuse); - LLColor4 cloud_color(psky->getCloudColor(), 1.0); - shader->uniform4fv(LLShaderMgr::CLOUD_COLOR, 1, cloud_color.mV); + LLVector4 cloud_color(LLVector3(psky->getCloudColor().mV), 1.0); + shader->uniform4fv(LLShaderMgr::CLOUD_COLOR, cloud_color); } + shader = &((LLShaderUniforms*)ptarget)[LLGLSLShader::SG_ANY]; shader->uniform1f(LLShaderMgr::SCENE_LIGHT_STRENGTH, mSceneLightStrength); LLColor4 ambient(getTotalAmbient()); - shader->uniform4fv(LLShaderMgr::AMBIENT, 1, ambient.mV); + shader->uniform4fv(LLShaderMgr::AMBIENT, LLVector4(ambient.mV)); shader->uniform1i(LLShaderMgr::SUN_UP_FACTOR, getIsSunUp() ? 1 : 0); shader->uniform1f(LLShaderMgr::SUN_MOON_GLOW_FACTOR, getSunMoonGlowFactor()); shader->uniform1f(LLShaderMgr::DENSITY_MULTIPLIER, getDensityMultiplier()); shader->uniform1f(LLShaderMgr::DISTANCE_MULTIPLIER, getDistanceMultiplier()); - F32 g = getGamma(); + F32 g = getGamma(); F32 display_gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma"); shader->uniform1f(LLShaderMgr::GAMMA, g); @@ -907,11 +908,11 @@ LLSD LLSettingsVOWater::convertToLegacy(const LLSettingsWater::ptr_t &pwater) //------------------------------------------------------------------------- void LLSettingsVOWater::applySpecial(void *ptarget, bool force) { - LLGLSLShader *shader = (LLGLSLShader *)ptarget; - LLEnvironment& env = LLEnvironment::instance(); - if (force || (shader->mShaderGroup == LLGLSLShader::SG_WATER)) + auto group = LLGLSLShader::SG_WATER; + LLShaderUniforms* shader = &((LLShaderUniforms*)ptarget)[group]; + { F32 water_height = env.getWaterHeight(); @@ -935,7 +936,7 @@ void LLSettingsVOWater::applySpecial(void *ptarget, bool force) LLVector4 waterPlane(enorm.v[0], enorm.v[1], enorm.v[2], -ep.dot(enorm)); - shader->uniform4fv(LLShaderMgr::WATER_WATERPLANE, 1, waterPlane.mV); + shader->uniform4fv(LLShaderMgr::WATER_WATERPLANE, waterPlane.mV); LLVector4 light_direction = env.getClampedLightNorm(); @@ -950,18 +951,19 @@ void LLSettingsVOWater::applySpecial(void *ptarget, bool force) shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY, waterFogDensity); LLColor4 fog_color(env.getCurrentWater()->getWaterFogColor(), 0.0f); - shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, fog_color.mV); + shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, fog_color.mV); F32 blend_factor = env.getCurrentWater()->getBlendFactor(); shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor); // update to normal lightnorm, water shader itself will use rotated lightnorm as necessary - shader->uniform4fv(LLShaderMgr::LIGHTNORM, 1, light_direction.mV); + shader->uniform4fv(LLShaderMgr::LIGHTNORM, light_direction.mV); } } void LLSettingsVOWater::updateSettings() { + LL_PROFILE_ZONE_SCOPED; // base class clears dirty flag so as to not trigger recursive update LLSettingsBase::updateSettings(); diff --git a/indra/newview/llsettingsvo.h b/indra/newview/llsettingsvo.h index 65136ad2f5..caa3ac18d3 100644 --- a/indra/newview/llsettingsvo.h +++ b/indra/newview/llsettingsvo.h @@ -102,8 +102,6 @@ public: bool isAdvanced() const { return m_isAdvanced; } - virtual void updateShader(LLGLSLShader* shader) { applySpecial(shader, true); } - protected: LLSettingsVOSky(); @@ -136,8 +134,6 @@ public: static LLSD convertToLegacy(const ptr_t &); - virtual void updateShader(LLGLSLShader* shader) { applySpecial(shader, true); } - protected: LLSettingsVOWater(); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 5ef3819de4..c4976c4bbc 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -8427,8 +8427,6 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_ LLEnvironment& environment = LLEnvironment::instance(); LLSettingsSky::ptr_t sky = environment.getCurrentSky(); - - static_cast(sky.get())->updateShader(&shader); } LLColor3 pow3f(LLColor3 v, F32 f) -- cgit v1.2.3