diff options
59 files changed, 3575 insertions, 1206 deletions
@@ -67,3 +67,6 @@ db0fe9bb65187f365e58a717dd23d0f4754a9c1d DRTVWR-17_2.3.0-beta2 54d772d8687c69b1d773f6ce14bbc7bdc9d6c05f DRTVWR-33_2.5.0-beta2 b723921b5c711bd24dbe77dc76ef488b544dac78 2.5.0-beta3 b723921b5c711bd24dbe77dc76ef488b544dac78 DRTVWR-34_2.5.0-beta3 +b723921b5c711bd24dbe77dc76ef488b544dac78 2.5.0-release +b723921b5c711bd24dbe77dc76ef488b544dac78 DRTVWR-31_2.5.0-release +92e58e51776a4f8c29069b1a62ff21454d2085f0 2.6.0-start diff --git a/doc/contributions.txt b/doc/contributions.txt index 03e4978dd0..16615ab220 100644 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -1,842 +1,850 @@ -Linden Lab would like to acknowledge source code contributions from the -following residents. The Second Life resident name is given below, -along with the issue identifier corresponding to the patches we've -received from them. To see more about these contributions, visit the -browsable version: http://wiki.secondlife.com/wiki/Source_contributions - -Able Whitman - VWR-650 - VWR-1460 - VWR-1691 - VWR-1735 - VWR-1813 -Adam Marker - VWR-2755 -Agathos Frascati - CT-246 - CT-317 - CT-352 -Aimee Trescothick - SNOW-227 - SNOW-570 - SNOW-572 - SNOW-575 - VWR-3321 - VWR-3336 - VWR-3903 - VWR-4083 - VWR-4106 - VWR-5308 - VWR-6348 - VWR-6358 - VWR-6360 - VWR-6432 - VWR-6550 - VWR-6583 - VWR-6482 - VWR-6918 - VWR-7109 - VWR-7383 - VWR-7800 - VWR-8008 - VWR-8341 - VWR-8430 - VWR-8482 - VWR-9255 - VWR-10717 - VWR-10990 - VWR-11100 - VWR-11111 - VWR-11844 - VWR-12631 - VWR-12696 - VWR-12748 - VWR-13221 - VWR-14087 - VWR-14267 - VWR-14278 - VWR-14711 - VWR-14712 - VWR-15454 -Alejandro Rosenthal - VWR-1184 -Aleric Inglewood - SNOW-84 - SNOW-240 - SNOW-477 - SNOW-522 - SNOW-626 - SNOW-744 - SNOW-756 - SNOW-764 - SNOW-766 - VWR-10001 - VWR-10579 - VWR-10759 - VWR-10837 - VWR-12691 - VWR-12984 - VWR-13040 - VWR-13996 - VWR-14426 - VWR-24247 - VWR-24251 - VWR-24252 - VWR-24254 - VWR-24261 - VWR-24315 - VWR-24317 - VWR-24320 - VWR-24321 - VWR-24354 - VWR-24519 - STORM-163 - STORM-864 -Ales Beaumont - VWR-9352 - SNOW-240 -Alexandrea Fride - STORM-255 -Alissa Sabre - VWR-81 - VWR-83 - VWR-109 - VWR-157 - VWR-171 - VWR-177 - VWR-213 - VWR-250 - VWR-251 - VWR-286 - VWR-414 - VWR-415 - VWR-459 - VWR-606 - VWR-652 - VWR-738 - VWR-1109 - VWR-1351 - VWR-1353 - VWR-1410 - VWR-1843 - VWR-2116 - VWR-2826 - VWR-3290 - VWR-3410 - VWR-3857 - VWR-4010 - VWR-5575 - VWR-5717 - VWR-5929 - VWR-6384 - VWR-6385 - VWR-6386 - VWR-6430 - VWR-6858 - VWR-6668 - VWR-7086 - VWR-7087 - VWR-7153 - VWR-7168 - VWR-9190 - VWR-10728 - VWR-11172 - VWR-12569 - VWR-12617 - VWR-12620 - VWR-12789 - SNOW-322 -Angus Boyd - VWR-592 -Ann Congrejo - CT-193 -Ardy Lay - VWR-19499 -Argent Stonecutter - VWR-68 -Armin Weatherwax - VWR-8436 -Asuka Neely - VWR-3434 - VWR-8179 -Balp Allen - VWR-4157 -Be Holder - SNOW-322 - SNOW-397 -Benja Kepler - VWR-746 -Biancaluce Robbiani - CT-225 - CT-226 - CT-227 - CT-228 - CT-229 - CT-230 - CT-231 - CT-321 - CT-352 -Blakar Ogre - VWR-418 - VWR-881 - VWR-983 - VWR-1612 - VWR-1613 - VWR-2164 -blino Nakamura - VWR-17 -Boroondas Gupte - SNOW-278 - SNOW-503 - SNOW-510 - SNOW-527 - SNOW-610 - SNOW-624 - SNOW-737 - STORM-318 - VWR-233 - VWR-20583 - VWR-20891 - VWR-23455 - WEB-262 -Bulli Schumann - CT-218 - CT-219 - CT-220 - CT-221 - CT-222 - CT-223 - CT-224 - CT-319 - CT-350 - CT-352 -bushing Spatula - VWR-119 - VWR-424 -Carjay McGinnis - VWR-3737 - VWR-4070 - VWR-4212 - VWR-6154 - VWR-9400 - VWR-9620 -Catherine Pfeffer - VWR-1282 - VWR-8624 - VWR-10854 -Celierra Darling - VWR-1274 - VWR-6975 -Coaldust Numbers - VWR-1095 -Cron Stardust - VWR-10579 -Cypren Christenson - STORM-417 -Dale Glass - VWR-120 - VWR-560 - VWR-2502 - VWR-1358 - VWR-2041 -Drew Dri - VWR-19683 -Drewan Keats - VWR-28 - VWR-248 - VWR-412 - VWR-638 - VWR-660 -Dylan Haskell - VWR-72 -Dzonatas Sol - VWR-187 - VWR-198 - VWR-777 - VWR-878 - VWR-962 - VWR-975 - VWR-1061 - VWR-1062 - VWR-1704 - VWR-1705 - VWR-1729 - VWR-1812 -Eddi Decosta - SNOW-586 -Eddy Stryker - VWR-15 - VWR-23 - VWR-1468 - VWR-1475 -EponymousDylan Ra - VWR-1289 - VWR-1465 -Eva Nowicka - CT-324 - CT-352 -Farallon Greyskin - VWR-2036 -Feep Larsson - VWR-447 - VWR-1314 - VWR-4444 -Flemming Congrejo - CT-193 - CT-318 -Fluf Fredriksson - VWR-3450 -Fremont Cunningham - VWR-1147 -Geneko Nemeth - CT-117 - VWR-11069 -Gigs Taggart - SVC-493 - VWR-6 - VWR-38 - VWR-71 - VWR-101 - VWR-166 - VWR-234 - VWR-315 - VWR-326 - VWR-442 - VWR-493 - VWR-1203 - VWR-1217 - VWR-1434 - VWR-1987 - VWR-2065 - VWR-2491 - VWR-2502 - VWR-2331 - VWR-5308 - VWR-8781 - VWR-8783 -Ginko Bayliss - VWR-4 -Grazer Kline - VWR-1092 - VWR-2113 -Gudmund Shepherd - VWR-1594 - VWR-1873 -Hamncheese Omlet - VWR-333 -HappySmurf Papp - CT-193 -Henri Beauchamp - VWR-1320 - VWR-1406 - VWR-4157 -Hikkoshi Sakai - VWR-429 -Hiro Sommambulist - VWR-66 - VWR-67 - VWR-97 - VWR-100 - VWR-105 - VWR-118 - VWR-132 - VWR-136 - VWR-143 -Hoze Menges - VWR-255 -Ian Kas - VWR-8780 (Russian localization) - [NO JIRA] (Ukranian localization) - CT-322 - CT-325 -Irene Muni - CT-324 - CT-352 -Iskar Ariantho - VWR-1223 - VWR-11759 -Jacek Antonelli - SNOW-388 - VWR-165 - VWR-188 - VWR-427 - VWR-597 - VWR-2054 - VWR-2448 - VWR-2896 - VWR-2947 - VWR-2948 - VWR-3605 - VWR-8617 -JB Kraft - VWR-5283 - VWR-7802 -Joghert LeSabre - VWR-64 -Jonathan Yap - STORM-435 - STORM-523 - STORM-596 - STORM-615 - STORM-616 - STORM-643 - STORM-679 - STORM-723 - STORM-726 - STORM-737 - STORM-785 - STORM-812 - STORM-829 - STORM-844 - STORM-869 - VWR-17801 - VWR-24347 -Kage Pixel - VWR-11 -Ken March - CT-245 -Kerutsen Sellery - VWR-1350 -Khyota Wulluf - VWR-2085 - VWR-8885 - VWR-9256 - VWR-9966 -Kitty Barnett - VWR-19699 - STORM-288 - STORM-799 - STORM-800 - VWR-24217 -Kunnis Basiat - VWR-82 - VWR-102 -Latif Khalifa - VWR-5370 -Lisa Lowe - CT-218 - CT-219 - CT-220 - CT-221 - CT-222 - CT-223 - CT-224 - CT-319 -Lockhart Cordoso - VWR-108 -maciek marksman - CT-86 -Magnus Balczo - CT-138 -Malwina Dollinger - CT-138 -march Korda - SVC-1020 -Marine Kelley - STORM-281 -Matthew Dowd - VWR-1344 - VWR-1651 - VWR-1736 - VWR-1737 - VWR-1761 - VWR-2681 -McCabe Maxsted - SNOW-387 - VWR-1318 - VWR-4065 - VWR-4826 - VWR-6518 - VWR-7827 - VWR-7877 - VWR-7893 - VWR-8080 - VWR-8454 - VWR-8689 - VWR-9007 -Michelle2 Zenovka - STORM-477 - VWR-2652 - VWR-2662 - VWR-2834 - VWR-3749 - VWR-4022 - VWR-4331 - VWR-4506 - VWR-4981 - VWR-5082 - VWR-5659 - VWR-7831 - VWR-8885 - VWR-8889 - VWR-8310 - VWR-9499 -Mm Alder - SNOW-376 - VWR-197 - VWR-3777 - VWR-4232 - VWR-4794 - VWR-13578 -Mr Greggan - VWR-445 -Nicholaz Beresford - VWR-132 - VWR-176 - VWR-193 - VWR-349 - VWR-353 - VWR-364 - VWR-374 - VWR-546 - VWR-691 - VWR-727 - VWR-793 - VWR-794 - VWR-802 - VWR-803 - VWR-804 - VWR-805 - VWR-807 - VWR-808 - VWR-809 - VWR-810 - VWR-823 - VWR-849 - VWR-856 - VWR-865 - VWR-869 - VWR-870 - VWR-871 - VWR-873 - VWR-908 - VWR-966 - VWR-1105 - VWR-1221 - VWR-1230 - VWR-1270 - VWR-1294 - VWR-1296 - VWR-1354 - VWR-1410 - VWR-1418 - VWR-1436 - VWR-1453 - VWR-1455 - VWR-1470 - VWR-1471 - VWR-1566 - VWR-1578 - VWR-1626 - VWR-1646 - VWR-1655 - VWR-1698 - VWR-1706 - VWR-1721 - VWR-1723 - VWR-1732 - VWR-1754 - VWR-1769 - VWR-1808 - VWR-1826 - VWR-1861 - VWR-1872 - VWR-1968 - VWR-2046 - VWR-2142 - VWR-2152 - VWR-2614 - VWR-2411 - VWR-2412 - VWR-2682 - VWR-2684 -Nounouch Hapmouche - VWR-238 -Patric Mills - VWR-2645 -Paul Churchill - VWR-20 - VWR-493 - VWR-749 - VWR-1567 - VWR-1647 - VWR-1880 - VWR-2072 -Paula Innis - VWR-30 - VWR-293 - VWR-1049 - VWR-1562 -Peekay Semyorka - VWR-7 - VWR-19 - VWR-49 - VWR-79 -Peter Lameth - VWR-7331 -Pf Shan - CT-225 - CT-226 - CT-227 - CT-228 - CT-229 - CT-230 - CT-231 - CT-321 - SNOW-422 -princess niven - VWR-5733 - CT-85 - CT-320 - CT-352 -Renault Clio - VWR-1976 -resu Ampan - SNOW-93 -Ringo Tuxing - CT-225 - CT-226 - CT-227 - CT-228 - CT-229 - CT-230 - CT-231 - CT-321 -Robin Cornelius - SNOW-108 - SNOW-204 - SNOW-287 - SNOW-484 - SNOW-504 - SNOW-506 - SNOW-507 - SNOW-511 - SNOW-512 - SNOW-514 - SNOW-520 - SNOW-585 - SNOW-599 - SNOW-747 - STORM-422 - VWR-2488 - VWR-9557 - VWR-10579 - VWR-11128 - VWR-12533 - VWR-12587 - VWR-12758 - VWR-12763 - VWR-12995 - VWR-20911 -Ryozu Kojima - VWR-53 - VWR-287 -Salahzar Stenvaag - CT-225 - CT-226 - CT-227 - CT-228 - CT-229 - CT-230 - CT-231 - CT-321 -Sammy Frederix - VWR-6186 -Satomi Ahn - STORM-501 - STORM-229 -Scrippy Scofield - VWR-3748 -Seg Baphomet - VWR-1475 - VWR-1525 - VWR-1585 - VWR-1586 - VWR-2662 - VWR-3206 - VWR-2488 -Sergen Davies - CT-225 - CT-226 - CT-227 - CT-228 - CT-229 - CT-230 - CT-231 - CT-321 -Shawn Kaufmat - SNOW-240 -SignpostMarv Martin - VWR-153 - VWR-154 - VWR-155 - VWR-218 - VWR-373 - VWR-8357 -Simon Nolan - VWR-409 -SpacedOut Frye - VWR-34 - VWR-45 - VWR-57 - VWR-94 - VWR-113 - VWR-121 - VWR-123 - VWR-130 - VWR-1823 -Sporked Friis - VWR-4903 -Stevex Janus - VWR-1182 -Still Defiant - VWR-207 - VWR-227 - VWR-446 -Strife Onizuka - SVC-9 - VWR-14 - VWR-74 - VWR-85 - VWR-148 - WEB-164 - VWR-183 - VWR-2265 - VWR-4111 - SNOW-691 -Tayra Dagostino - SNOW-517 - SNOW-543 - VWR-13947 -TBBle Kurosawa - VWR-938 - VWR-941 - VWR-942 - VWR-944 - VWR-945 - SNOW-543 - VWR-1891 - VWR-1892 -Teardrops Fall - VWR-5366 -Techwolf Lupindo - SNOW-92 - SNOW-592 - SNOW-649 - SNOW-650 - SNOW-651 - SNOW-654 - SNOW-687 - SNOW-680 - SNOW-681 - SNOW-685 - SNOW-690 - SNOW-746 - VWR-12385 - VWR-20893 -tenebrous pau - VWR-247 -Tharax Ferraris - VWR-605 -Thickbrick Sleaford - SNOW-207 - SNOW-390 - SNOW-421 - SNOW-462 - SNOW-586 - SNOW-592 - SNOW-635 - SNOW-743 - VWR-7109 - VWR-9287 - VWR-13483 - VWR-13947 - VWR-24420 -Thraxis Epsilon - SVC-371 - VWR-383 -tiamat bingyi - CT-246 -Tofu Buzzard - STORM-546 -TraductoresAnonimos Alter - CT-324 -Tue Torok - CT-68 - CT-69 - CT-70 - CT-72 - CT-73 - CT-74 -Twisted Laws - SNOW-352 - STORM-466 - STORM-467 - STORM-844 - STORM-643 -Vadim Bigbear - VWR-2681 -Vector Hastings - VWR-8726 -Vixen Heron - VWR-2710 - CT-88 -Whoops Babii - VWR-631 - VWR-1640 - VWR-3340 - SNOW-667 - VWR-4800 - VWR-4802 - VWR-4804 - VWR-4805 - VWR-4806 - VWR-4808 - VWR-4809 - VWR-4811 - VWR-4815 - VWR-4816 - VWR-4818 - VWR-5659 - VWR-8291 - VWR-8292 - VWR-8293 - VWR-8294 - VWR-8295 - VWR-8296 - VWR-8297 - VWR-8298 -Wilton Lundquist - VWR-7682 -WolfPup Lowenhar - SNOW-622 - SNOW-772 - STORM-102 - STORM-103 - STORM-143 - STORM-255 - STORM-256 - STORM-288 - STORM-535 - STORM-544 - STORM-654 - STORM-674 - STORM-776 - STORM-825 - VWR-20741 - VWR-20933 -Zai Lynch - VWR-19505 -Zarkonnen Decosta - VWR-253 -Zi Ree - VWR-423 - VWR-671 - VWR-682 - VWR-684 - VWR-9127 - VWR-1140 -Zipherius Turas - VWR-76 - VWR-77 - +Linden Lab would like to acknowledge source code contributions from the
+following residents. The Second Life resident name is given below,
+along with the issue identifier corresponding to the patches we've
+received from them. To see more about these contributions, visit the
+browsable version: http://wiki.secondlife.com/wiki/Source_contributions
+
+Able Whitman
+ VWR-650
+ VWR-1460
+ VWR-1691
+ VWR-1735
+ VWR-1813
+Adam Marker
+ VWR-2755
+Agathos Frascati
+ CT-246
+ CT-317
+ CT-352
+Aimee Trescothick
+ SNOW-227
+ SNOW-570
+ SNOW-572
+ SNOW-575
+ VWR-3321
+ VWR-3336
+ VWR-3903
+ VWR-4083
+ VWR-4106
+ VWR-5308
+ VWR-6348
+ VWR-6358
+ VWR-6360
+ VWR-6432
+ VWR-6550
+ VWR-6583
+ VWR-6482
+ VWR-6918
+ VWR-7109
+ VWR-7383
+ VWR-7800
+ VWR-8008
+ VWR-8341
+ VWR-8430
+ VWR-8482
+ VWR-9255
+ VWR-10717
+ VWR-10990
+ VWR-11100
+ VWR-11111
+ VWR-11844
+ VWR-12631
+ VWR-12696
+ VWR-12748
+ VWR-13221
+ VWR-14087
+ VWR-14267
+ VWR-14278
+ VWR-14711
+ VWR-14712
+ VWR-15454
+Alejandro Rosenthal
+ VWR-1184
+Aleric Inglewood
+ SNOW-84
+ SNOW-240
+ SNOW-477
+ SNOW-522
+ SNOW-626
+ SNOW-744
+ SNOW-756
+ SNOW-764
+ SNOW-766
+ SNOW-800
+ VWR-10001
+ VWR-10579
+ VWR-10759
+ VWR-10837
+ VWR-12691
+ VWR-12984
+ VWR-13040
+ VWR-13996
+ VWR-14426
+ VWR-24247
+ VWR-24251
+ VWR-24252
+ VWR-24254
+ VWR-24261
+ VWR-24315
+ VWR-24317
+ VWR-24320
+ VWR-24321
+ VWR-24354
+ VWR-24519
+ STORM-163
+ STORM-864
+ STORM-955
+ STORM-960
+Ales Beaumont
+ VWR-9352
+ SNOW-240
+Alexandrea Fride
+ STORM-255
+ STORM-960
+Alissa Sabre
+ VWR-81
+ VWR-83
+ VWR-109
+ VWR-157
+ VWR-171
+ VWR-177
+ VWR-213
+ VWR-250
+ VWR-251
+ VWR-286
+ VWR-414
+ VWR-415
+ VWR-459
+ VWR-606
+ VWR-652
+ VWR-738
+ VWR-1109
+ VWR-1351
+ VWR-1353
+ VWR-1410
+ VWR-1843
+ VWR-2116
+ VWR-2826
+ VWR-3290
+ VWR-3410
+ VWR-3857
+ VWR-4010
+ VWR-5575
+ VWR-5717
+ VWR-5929
+ VWR-6384
+ VWR-6385
+ VWR-6386
+ VWR-6430
+ VWR-6858
+ VWR-6668
+ VWR-7086
+ VWR-7087
+ VWR-7153
+ VWR-7168
+ VWR-9190
+ VWR-10728
+ VWR-11172
+ VWR-12569
+ VWR-12617
+ VWR-12620
+ VWR-12789
+ SNOW-322
+Angus Boyd
+ VWR-592
+Ann Congrejo
+ CT-193
+Ardy Lay
+ VWR-19499
+Argent Stonecutter
+ VWR-68
+Armin Weatherwax
+ VWR-8436
+Asuka Neely
+ VWR-3434
+ VWR-8179
+Balp Allen
+ VWR-4157
+Be Holder
+ SNOW-322
+ SNOW-397
+Benja Kepler
+ VWR-746
+Biancaluce Robbiani
+ CT-225
+ CT-226
+ CT-227
+ CT-228
+ CT-229
+ CT-230
+ CT-231
+ CT-321
+ CT-352
+Blakar Ogre
+ VWR-418
+ VWR-881
+ VWR-983
+ VWR-1612
+ VWR-1613
+ VWR-2164
+blino Nakamura
+ VWR-17
+Boroondas Gupte
+ SNOW-278
+ SNOW-503
+ SNOW-510
+ SNOW-527
+ SNOW-610
+ SNOW-624
+ SNOW-737
+ STORM-318
+ VWR-233
+ VWR-20583
+ VWR-20891
+ VWR-23455
+ WEB-262
+Bulli Schumann
+ CT-218
+ CT-219
+ CT-220
+ CT-221
+ CT-222
+ CT-223
+ CT-224
+ CT-319
+ CT-350
+ CT-352
+bushing Spatula
+ VWR-119
+ VWR-424
+Carjay McGinnis
+ VWR-3737
+ VWR-4070
+ VWR-4212
+ VWR-6154
+ VWR-9400
+ VWR-9620
+Catherine Pfeffer
+ VWR-1282
+ VWR-8624
+ VWR-10854
+Celierra Darling
+ VWR-1274
+ VWR-6975
+Coaldust Numbers
+ VWR-1095
+Cron Stardust
+ VWR-10579
+Cypren Christenson
+ STORM-417
+Dale Glass
+ VWR-120
+ VWR-560
+ VWR-2502
+ VWR-1358
+ VWR-2041
+Drew Dri
+ VWR-19683
+Drewan Keats
+ VWR-28
+ VWR-248
+ VWR-412
+ VWR-638
+ VWR-660
+Dylan Haskell
+ VWR-72
+Dzonatas Sol
+ VWR-187
+ VWR-198
+ VWR-777
+ VWR-878
+ VWR-962
+ VWR-975
+ VWR-1061
+ VWR-1062
+ VWR-1704
+ VWR-1705
+ VWR-1729
+ VWR-1812
+Eddi Decosta
+ SNOW-586
+Eddy Stryker
+ VWR-15
+ VWR-23
+ VWR-1468
+ VWR-1475
+EponymousDylan Ra
+ VWR-1289
+ VWR-1465
+Eva Nowicka
+ CT-324
+ CT-352
+Farallon Greyskin
+ VWR-2036
+Feep Larsson
+ VWR-447
+ VWR-1314
+ VWR-4444
+Flemming Congrejo
+ CT-193
+ CT-318
+Fluf Fredriksson
+ VWR-3450
+Fremont Cunningham
+ VWR-1147
+Geneko Nemeth
+ CT-117
+ VWR-11069
+Gigs Taggart
+ SVC-493
+ VWR-6
+ VWR-38
+ VWR-71
+ VWR-101
+ VWR-166
+ VWR-234
+ VWR-315
+ VWR-326
+ VWR-442
+ VWR-493
+ VWR-1203
+ VWR-1217
+ VWR-1434
+ VWR-1987
+ VWR-2065
+ VWR-2491
+ VWR-2502
+ VWR-2331
+ VWR-5308
+ VWR-8781
+ VWR-8783
+Ginko Bayliss
+ VWR-4
+Grazer Kline
+ VWR-1092
+ VWR-2113
+Gudmund Shepherd
+ VWR-1594
+ VWR-1873
+Hamncheese Omlet
+ VWR-333
+HappySmurf Papp
+ CT-193
+Henri Beauchamp
+ VWR-1320
+ VWR-1406
+ VWR-4157
+Hikkoshi Sakai
+ VWR-429
+Hiro Sommambulist
+ VWR-66
+ VWR-67
+ VWR-97
+ VWR-100
+ VWR-105
+ VWR-118
+ VWR-132
+ VWR-136
+ VWR-143
+Hoze Menges
+ VWR-255
+Ian Kas
+ VWR-8780 (Russian localization)
+ [NO JIRA] (Ukranian localization)
+ CT-322
+ CT-325
+Irene Muni
+ CT-324
+ CT-352
+Iskar Ariantho
+ VWR-1223
+ VWR-11759
+Jacek Antonelli
+ SNOW-388
+ VWR-165
+ VWR-188
+ VWR-427
+ VWR-597
+ VWR-2054
+ VWR-2448
+ VWR-2896
+ VWR-2947
+ VWR-2948
+ VWR-3605
+ VWR-8617
+JB Kraft
+ VWR-5283
+ VWR-7802
+Joghert LeSabre
+ VWR-64
+Jonathan Yap
+ STORM-435
+ STORM-523
+ STORM-596
+ STORM-615
+ STORM-616
+ STORM-643
+ STORM-679
+ STORM-723
+ STORM-726
+ STORM-737
+ STORM-785
+ STORM-812
+ STORM-829
+ STORM-844
+ STORM-869
+ VWR-17801
+ VWR-24347
+ STORM-975
+Kage Pixel
+ VWR-11
+Ken March
+ CT-245
+Kerutsen Sellery
+ VWR-1350
+Khyota Wulluf
+ VWR-2085
+ VWR-8885
+ VWR-9256
+ VWR-9966
+Kitty Barnett
+ VWR-19699
+ STORM-288
+ STORM-799
+ STORM-800
+ VWR-24217
+Kunnis Basiat
+ VWR-82
+ VWR-102
+Latif Khalifa
+ VWR-5370
+Lisa Lowe
+ CT-218
+ CT-219
+ CT-220
+ CT-221
+ CT-222
+ CT-223
+ CT-224
+ CT-319
+Lockhart Cordoso
+ VWR-108
+maciek marksman
+ CT-86
+Magnus Balczo
+ CT-138
+Malwina Dollinger
+ CT-138
+march Korda
+ SVC-1020
+Marine Kelley
+ STORM-281
+Matthew Dowd
+ VWR-1344
+ VWR-1651
+ VWR-1736
+ VWR-1737
+ VWR-1761
+ VWR-2681
+McCabe Maxsted
+ SNOW-387
+ VWR-1318
+ VWR-4065
+ VWR-4826
+ VWR-6518
+ VWR-7827
+ VWR-7877
+ VWR-7893
+ VWR-8080
+ VWR-8454
+ VWR-8689
+ VWR-9007
+Michelle2 Zenovka
+ STORM-477
+ VWR-2652
+ VWR-2662
+ VWR-2834
+ VWR-3749
+ VWR-4022
+ VWR-4331
+ VWR-4506
+ VWR-4981
+ VWR-5082
+ VWR-5659
+ VWR-7831
+ VWR-8885
+ VWR-8889
+ VWR-8310
+ VWR-9499
+Mm Alder
+ SNOW-376
+ VWR-197
+ VWR-3777
+ VWR-4232
+ VWR-4794
+ VWR-13578
+Mr Greggan
+ VWR-445
+Nicholaz Beresford
+ VWR-132
+ VWR-176
+ VWR-193
+ VWR-349
+ VWR-353
+ VWR-364
+ VWR-374
+ VWR-546
+ VWR-691
+ VWR-727
+ VWR-793
+ VWR-794
+ VWR-802
+ VWR-803
+ VWR-804
+ VWR-805
+ VWR-807
+ VWR-808
+ VWR-809
+ VWR-810
+ VWR-823
+ VWR-849
+ VWR-856
+ VWR-865
+ VWR-869
+ VWR-870
+ VWR-871
+ VWR-873
+ VWR-908
+ VWR-966
+ VWR-1105
+ VWR-1221
+ VWR-1230
+ VWR-1270
+ VWR-1294
+ VWR-1296
+ VWR-1354
+ VWR-1410
+ VWR-1418
+ VWR-1436
+ VWR-1453
+ VWR-1455
+ VWR-1470
+ VWR-1471
+ VWR-1566
+ VWR-1578
+ VWR-1626
+ VWR-1646
+ VWR-1655
+ VWR-1698
+ VWR-1706
+ VWR-1721
+ VWR-1723
+ VWR-1732
+ VWR-1754
+ VWR-1769
+ VWR-1808
+ VWR-1826
+ VWR-1861
+ VWR-1872
+ VWR-1968
+ VWR-2046
+ VWR-2142
+ VWR-2152
+ VWR-2614
+ VWR-2411
+ VWR-2412
+ VWR-2682
+ VWR-2684
+Nounouch Hapmouche
+ VWR-238
+Patric Mills
+ VWR-2645
+Paul Churchill
+ VWR-20
+ VWR-493
+ VWR-749
+ VWR-1567
+ VWR-1647
+ VWR-1880
+ VWR-2072
+Paula Innis
+ VWR-30
+ VWR-293
+ VWR-1049
+ VWR-1562
+Peekay Semyorka
+ VWR-7
+ VWR-19
+ VWR-49
+ VWR-79
+Peter Lameth
+ VWR-7331
+Pf Shan
+ CT-225
+ CT-226
+ CT-227
+ CT-228
+ CT-229
+ CT-230
+ CT-231
+ CT-321
+ SNOW-422
+princess niven
+ VWR-5733
+ CT-85
+ CT-320
+ CT-352
+Renault Clio
+ VWR-1976
+resu Ampan
+ SNOW-93
+Ringo Tuxing
+ CT-225
+ CT-226
+ CT-227
+ CT-228
+ CT-229
+ CT-230
+ CT-231
+ CT-321
+Robin Cornelius
+ SNOW-108
+ SNOW-204
+ SNOW-287
+ SNOW-484
+ SNOW-504
+ SNOW-506
+ SNOW-507
+ SNOW-511
+ SNOW-512
+ SNOW-514
+ SNOW-520
+ SNOW-585
+ SNOW-599
+ SNOW-747
+ STORM-422
+ STORM-960
+ VWR-2488
+ VWR-9557
+ VWR-10579
+ VWR-11128
+ VWR-12533
+ VWR-12587
+ VWR-12758
+ VWR-12763
+ VWR-12995
+ VWR-20911
+Ryozu Kojima
+ VWR-53
+ VWR-287
+Salahzar Stenvaag
+ CT-225
+ CT-226
+ CT-227
+ CT-228
+ CT-229
+ CT-230
+ CT-231
+ CT-321
+Sammy Frederix
+ VWR-6186
+Satomi Ahn
+ STORM-501
+ STORM-229
+Scrippy Scofield
+ VWR-3748
+Seg Baphomet
+ VWR-1475
+ VWR-1525
+ VWR-1585
+ VWR-1586
+ VWR-2662
+ VWR-3206
+ VWR-2488
+Sergen Davies
+ CT-225
+ CT-226
+ CT-227
+ CT-228
+ CT-229
+ CT-230
+ CT-231
+ CT-321
+Shawn Kaufmat
+ SNOW-240
+Siana Gearz
+ STORM-960
+SignpostMarv Martin
+ VWR-153
+ VWR-154
+ VWR-155
+ VWR-218
+ VWR-373
+ VWR-8357
+Simon Nolan
+ VWR-409
+SpacedOut Frye
+ VWR-34
+ VWR-45
+ VWR-57
+ VWR-94
+ VWR-113
+ VWR-121
+ VWR-123
+ VWR-130
+ VWR-1823
+Sporked Friis
+ VWR-4903
+Stevex Janus
+ VWR-1182
+Still Defiant
+ VWR-207
+ VWR-227
+ VWR-446
+Strife Onizuka
+ SVC-9
+ VWR-14
+ VWR-74
+ VWR-85
+ VWR-148
+ WEB-164
+ VWR-183
+ VWR-2265
+ VWR-4111
+ SNOW-691
+Tayra Dagostino
+ SNOW-517
+ SNOW-543
+ VWR-13947
+TBBle Kurosawa
+ VWR-938
+ VWR-941
+ VWR-942
+ VWR-944
+ VWR-945
+ SNOW-543
+ VWR-1891
+ VWR-1892
+Teardrops Fall
+ VWR-5366
+Techwolf Lupindo
+ SNOW-92
+ SNOW-592
+ SNOW-649
+ SNOW-650
+ SNOW-651
+ SNOW-654
+ SNOW-687
+ SNOW-680
+ SNOW-681
+ SNOW-685
+ SNOW-690
+ SNOW-746
+ VWR-12385
+ VWR-20893
+tenebrous pau
+ VWR-247
+Tharax Ferraris
+ VWR-605
+Thickbrick Sleaford
+ SNOW-207
+ SNOW-390
+ SNOW-421
+ SNOW-462
+ SNOW-586
+ SNOW-592
+ SNOW-635
+ SNOW-743
+ VWR-7109
+ VWR-9287
+ VWR-13483
+ VWR-13947
+ VWR-24420
+Thraxis Epsilon
+ SVC-371
+ VWR-383
+tiamat bingyi
+ CT-246
+Tofu Buzzard
+ STORM-546
+TraductoresAnonimos Alter
+ CT-324
+Tue Torok
+ CT-68
+ CT-69
+ CT-70
+ CT-72
+ CT-73
+ CT-74
+Twisted Laws
+ SNOW-352
+ STORM-466
+ STORM-467
+ STORM-844
+ STORM-643
+Vadim Bigbear
+ VWR-2681
+Vector Hastings
+ VWR-8726
+Vixen Heron
+ VWR-2710
+ CT-88
+Whoops Babii
+ VWR-631
+ VWR-1640
+ VWR-3340
+ SNOW-667
+ VWR-4800
+ VWR-4802
+ VWR-4804
+ VWR-4805
+ VWR-4806
+ VWR-4808
+ VWR-4809
+ VWR-4811
+ VWR-4815
+ VWR-4816
+ VWR-4818
+ VWR-5659
+ VWR-8291
+ VWR-8292
+ VWR-8293
+ VWR-8294
+ VWR-8295
+ VWR-8296
+ VWR-8297
+ VWR-8298
+Wilton Lundquist
+ VWR-7682
+WolfPup Lowenhar
+ SNOW-622
+ SNOW-772
+ STORM-102
+ STORM-103
+ STORM-143
+ STORM-255
+ STORM-256
+ STORM-288
+ STORM-535
+ STORM-544
+ STORM-654
+ STORM-674
+ STORM-776
+ STORM-825
+ VWR-20741
+ VWR-20933
+Zai Lynch
+ VWR-19505
+Zarkonnen Decosta
+ VWR-253
+Zi Ree
+ VWR-423
+ VWR-671
+ VWR-682
+ VWR-684
+ VWR-9127
+ VWR-1140
+Zipherius Turas
+ VWR-76
+ VWR-77
+
diff --git a/indra/llcharacter/llanimationstates.cpp b/indra/llcharacter/llanimationstates.cpp index a30113a478..155226cf17 100644 --- a/indra/llcharacter/llanimationstates.cpp +++ b/indra/llcharacter/llanimationstates.cpp @@ -33,145 +33,145 @@ #include "llanimationstates.h" #include "llstring.h" -const LLUUID ANIM_AGENT_AFRAID = LLUUID("6b61c8e8-4747-0d75-12d7-e49ff207a4ca"); -const LLUUID ANIM_AGENT_AIM_BAZOOKA_R = LLUUID("b5b4a67d-0aee-30d2-72cd-77b333e932ef"); -const LLUUID ANIM_AGENT_AIM_BOW_L = LLUUID("46bb4359-de38-4ed8-6a22-f1f52fe8f506"); -const LLUUID ANIM_AGENT_AIM_HANDGUN_R = LLUUID("3147d815-6338-b932-f011-16b56d9ac18b"); -const LLUUID ANIM_AGENT_AIM_RIFLE_R = LLUUID("ea633413-8006-180a-c3ba-96dd1d756720"); -const LLUUID ANIM_AGENT_ANGRY = LLUUID("5747a48e-073e-c331-f6f3-7c2149613d3e"); -const LLUUID ANIM_AGENT_AWAY = LLUUID("fd037134-85d4-f241-72c6-4f42164fedee"); -const LLUUID ANIM_AGENT_BACKFLIP = LLUUID("c4ca6188-9127-4f31-0158-23c4e2f93304"); -const LLUUID ANIM_AGENT_BELLY_LAUGH = LLUUID("18b3a4b5-b463-bd48-e4b6-71eaac76c515"); -const LLUUID ANIM_AGENT_BLOW_KISS = LLUUID("db84829b-462c-ee83-1e27-9bbee66bd624"); -const LLUUID ANIM_AGENT_BORED = LLUUID("b906c4ba-703b-1940-32a3-0c7f7d791510"); -const LLUUID ANIM_AGENT_BOW = LLUUID("82e99230-c906-1403-4d9c-3889dd98daba"); -const LLUUID ANIM_AGENT_BRUSH = LLUUID("349a3801-54f9-bf2c-3bd0-1ac89772af01"); -const LLUUID ANIM_AGENT_BUSY = LLUUID("efcf670c-2d18-8128-973a-034ebc806b67"); -const LLUUID ANIM_AGENT_CLAP = LLUUID("9b0c1c4e-8ac7-7969-1494-28c874c4f668"); -const LLUUID ANIM_AGENT_COURTBOW = LLUUID("9ba1c942-08be-e43a-fb29-16ad440efc50"); -const LLUUID ANIM_AGENT_CROUCH = LLUUID("201f3fdf-cb1f-dbec-201f-7333e328ae7c"); -const LLUUID ANIM_AGENT_CROUCHWALK = LLUUID("47f5f6fb-22e5-ae44-f871-73aaaf4a6022"); -const LLUUID ANIM_AGENT_CRY = LLUUID("92624d3e-1068-f1aa-a5ec-8244585193ed"); -const LLUUID ANIM_AGENT_CUSTOMIZE = LLUUID("038fcec9-5ebd-8a8e-0e2e-6e71a0a1ac53"); -const LLUUID ANIM_AGENT_CUSTOMIZE_DONE = LLUUID("6883a61a-b27b-5914-a61e-dda118a9ee2c"); -const LLUUID ANIM_AGENT_DANCE1 = LLUUID("b68a3d7c-de9e-fc87-eec8-543d787e5b0d"); -const LLUUID ANIM_AGENT_DANCE2 = LLUUID("928cae18-e31d-76fd-9cc9-2f55160ff818"); -const LLUUID ANIM_AGENT_DANCE3 = LLUUID("30047778-10ea-1af7-6881-4db7a3a5a114"); -const LLUUID ANIM_AGENT_DANCE4 = LLUUID("951469f4-c7b2-c818-9dee-ad7eea8c30b7"); -const LLUUID ANIM_AGENT_DANCE5 = LLUUID("4bd69a1d-1114-a0b4-625f-84e0a5237155"); -const LLUUID ANIM_AGENT_DANCE6 = LLUUID("cd28b69b-9c95-bb78-3f94-8d605ff1bb12"); -const LLUUID ANIM_AGENT_DANCE7 = LLUUID("a54d8ee2-28bb-80a9-7f0c-7afbbe24a5d6"); -const LLUUID ANIM_AGENT_DANCE8 = LLUUID("b0dc417c-1f11-af36-2e80-7e7489fa7cdc"); -const LLUUID ANIM_AGENT_DEAD = LLUUID("57abaae6-1d17-7b1b-5f98-6d11a6411276"); -const LLUUID ANIM_AGENT_DRINK = LLUUID("0f86e355-dd31-a61c-fdb0-3a96b9aad05f"); -const LLUUID ANIM_AGENT_EMBARRASSED = LLUUID("514af488-9051-044a-b3fc-d4dbf76377c6"); -const LLUUID ANIM_AGENT_EXPRESS_AFRAID = LLUUID("aa2df84d-cf8f-7218-527b-424a52de766e"); -const LLUUID ANIM_AGENT_EXPRESS_ANGER = LLUUID("1a03b575-9634-b62a-5767-3a679e81f4de"); -const LLUUID ANIM_AGENT_EXPRESS_BORED = LLUUID("214aa6c1-ba6a-4578-f27c-ce7688f61d0d"); -const LLUUID ANIM_AGENT_EXPRESS_CRY = LLUUID("d535471b-85bf-3b4d-a542-93bea4f59d33"); -const LLUUID ANIM_AGENT_EXPRESS_DISDAIN = LLUUID("d4416ff1-09d3-300f-4183-1b68a19b9fc1"); -const LLUUID ANIM_AGENT_EXPRESS_EMBARRASSED = LLUUID("0b8c8211-d78c-33e8-fa28-c51a9594e424"); -const LLUUID ANIM_AGENT_EXPRESS_FROWN = LLUUID("fee3df48-fa3d-1015-1e26-a205810e3001"); -const LLUUID ANIM_AGENT_EXPRESS_KISS = LLUUID("1e8d90cc-a84e-e135-884c-7c82c8b03a14"); -const LLUUID ANIM_AGENT_EXPRESS_LAUGH = LLUUID("62570842-0950-96f8-341c-809e65110823"); -const LLUUID ANIM_AGENT_EXPRESS_OPEN_MOUTH = LLUUID("d63bc1f9-fc81-9625-a0c6-007176d82eb7"); -const LLUUID ANIM_AGENT_EXPRESS_REPULSED = LLUUID("f76cda94-41d4-a229-2872-e0296e58afe1"); -const LLUUID ANIM_AGENT_EXPRESS_SAD = LLUUID("eb6ebfb2-a4b3-a19c-d388-4dd5c03823f7"); -const LLUUID ANIM_AGENT_EXPRESS_SHRUG = LLUUID("a351b1bc-cc94-aac2-7bea-a7e6ebad15ef"); -const LLUUID ANIM_AGENT_EXPRESS_SMILE = LLUUID("b7c7c833-e3d3-c4e3-9fc0-131237446312"); -const LLUUID ANIM_AGENT_EXPRESS_SURPRISE = LLUUID("728646d9-cc79-08b2-32d6-937f0a835c24"); -const LLUUID ANIM_AGENT_EXPRESS_TONGUE_OUT = LLUUID("835965c6-7f2f-bda2-5deb-2478737f91bf"); -const LLUUID ANIM_AGENT_EXPRESS_TOOTHSMILE = LLUUID("b92ec1a5-e7ce-a76b-2b05-bcdb9311417e"); -const LLUUID ANIM_AGENT_EXPRESS_WINK = LLUUID("da020525-4d94-59d6-23d7-81fdebf33148"); -const LLUUID ANIM_AGENT_EXPRESS_WORRY = LLUUID("9c05e5c7-6f07-6ca4-ed5a-b230390c3950"); -const LLUUID ANIM_AGENT_FALLDOWN = LLUUID("666307d9-a860-572d-6fd4-c3ab8865c094"); -const LLUUID ANIM_AGENT_FEMALE_RUN_NEW = LLUUID("85995026-eade-5d78-d364-94a64512cb66"); -const LLUUID ANIM_AGENT_FEMALE_WALK = LLUUID("f5fc7433-043d-e819-8298-f519a119b688"); -const LLUUID ANIM_AGENT_FEMALE_WALK_NEW = LLUUID("d60c41d2-7c24-7074-d3fa-6101cea22a51"); -const LLUUID ANIM_AGENT_FINGER_WAG = LLUUID("c1bc7f36-3ba0-d844-f93c-93be945d644f"); -const LLUUID ANIM_AGENT_FIST_PUMP = LLUUID("7db00ccd-f380-f3ee-439d-61968ec69c8a"); -const LLUUID ANIM_AGENT_FLY = LLUUID("aec4610c-757f-bc4e-c092-c6e9caf18daf"); -const LLUUID ANIM_AGENT_FLYSLOW = LLUUID("2b5a38b2-5e00-3a97-a495-4c826bc443e6"); -const LLUUID ANIM_AGENT_HELLO = LLUUID("9b29cd61-c45b-5689-ded2-91756b8d76a9"); -const LLUUID ANIM_AGENT_HOLD_BAZOOKA_R = LLUUID("ef62d355-c815-4816-2474-b1acc21094a6"); -const LLUUID ANIM_AGENT_HOLD_BOW_L = LLUUID("8b102617-bcba-037b-86c1-b76219f90c88"); -const LLUUID ANIM_AGENT_HOLD_HANDGUN_R = LLUUID("efdc1727-8b8a-c800-4077-975fc27ee2f2"); -const LLUUID ANIM_AGENT_HOLD_RIFLE_R = LLUUID("3d94bad0-c55b-7dcc-8763-033c59405d33"); -const LLUUID ANIM_AGENT_HOLD_THROW_R = LLUUID("7570c7b5-1f22-56dd-56ef-a9168241bbb6"); -const LLUUID ANIM_AGENT_HOVER = LLUUID("4ae8016b-31b9-03bb-c401-b1ea941db41d"); -const LLUUID ANIM_AGENT_HOVER_DOWN = LLUUID("20f063ea-8306-2562-0b07-5c853b37b31e"); -const LLUUID ANIM_AGENT_HOVER_UP = LLUUID("62c5de58-cb33-5743-3d07-9e4cd4352864"); -const LLUUID ANIM_AGENT_IMPATIENT = LLUUID("5ea3991f-c293-392e-6860-91dfa01278a3"); -const LLUUID ANIM_AGENT_JUMP = LLUUID("2305bd75-1ca9-b03b-1faa-b176b8a8c49e"); -const LLUUID ANIM_AGENT_JUMP_FOR_JOY = LLUUID("709ea28e-1573-c023-8bf8-520c8bc637fa"); -const LLUUID ANIM_AGENT_KISS_MY_BUTT = LLUUID("19999406-3a3a-d58c-a2ac-d72e555dcf51"); -const LLUUID ANIM_AGENT_LAND = LLUUID("7a17b059-12b2-41b1-570a-186368b6aa6f"); -const LLUUID ANIM_AGENT_LAUGH_SHORT = LLUUID("ca5b3f14-3194-7a2b-c894-aa699b718d1f"); -const LLUUID ANIM_AGENT_MEDIUM_LAND = LLUUID("f4f00d6e-b9fe-9292-f4cb-0ae06ea58d57"); -const LLUUID ANIM_AGENT_MOTORCYCLE_SIT = LLUUID("08464f78-3a8e-2944-cba5-0c94aff3af29"); -const LLUUID ANIM_AGENT_MUSCLE_BEACH = LLUUID("315c3a41-a5f3-0ba4-27da-f893f769e69b"); -const LLUUID ANIM_AGENT_NO = LLUUID("5a977ed9-7f72-44e9-4c4c-6e913df8ae74"); -const LLUUID ANIM_AGENT_NO_UNHAPPY = LLUUID("d83fa0e5-97ed-7eb2-e798-7bd006215cb4"); -const LLUUID ANIM_AGENT_NYAH_NYAH = LLUUID("f061723d-0a18-754f-66ee-29a44795a32f"); -const LLUUID ANIM_AGENT_ONETWO_PUNCH = LLUUID("eefc79be-daae-a239-8c04-890f5d23654a"); -const LLUUID ANIM_AGENT_PEACE = LLUUID("b312b10e-65ab-a0a4-8b3c-1326ea8e3ed9"); -const LLUUID ANIM_AGENT_POINT_ME = LLUUID("17c024cc-eef2-f6a0-3527-9869876d7752"); -const LLUUID ANIM_AGENT_POINT_YOU = LLUUID("ec952cca-61ef-aa3b-2789-4d1344f016de"); -const LLUUID ANIM_AGENT_PRE_JUMP = LLUUID("7a4e87fe-de39-6fcb-6223-024b00893244"); -const LLUUID ANIM_AGENT_PUNCH_LEFT = LLUUID("f3300ad9-3462-1d07-2044-0fef80062da0"); -const LLUUID ANIM_AGENT_PUNCH_RIGHT = LLUUID("c8e42d32-7310-6906-c903-cab5d4a34656"); -const LLUUID ANIM_AGENT_REPULSED = LLUUID("36f81a92-f076-5893-dc4b-7c3795e487cf"); -const LLUUID ANIM_AGENT_ROUNDHOUSE_KICK = LLUUID("49aea43b-5ac3-8a44-b595-96100af0beda"); -const LLUUID ANIM_AGENT_RPS_COUNTDOWN = LLUUID("35db4f7e-28c2-6679-cea9-3ee108f7fc7f"); -const LLUUID ANIM_AGENT_RPS_PAPER = LLUUID("0836b67f-7f7b-f37b-c00a-460dc1521f5a"); -const LLUUID ANIM_AGENT_RPS_ROCK = LLUUID("42dd95d5-0bc6-6392-f650-777304946c0f"); -const LLUUID ANIM_AGENT_RPS_SCISSORS = LLUUID("16803a9f-5140-e042-4d7b-d28ba247c325"); -const LLUUID ANIM_AGENT_RUN = LLUUID("05ddbff8-aaa9-92a1-2b74-8fe77a29b445"); -const LLUUID ANIM_AGENT_RUN_NEW = LLUUID("1ab1b236-cd08-21e6-0cbc-0d923fc6eca2"); -const LLUUID ANIM_AGENT_SAD = LLUUID("0eb702e2-cc5a-9a88-56a5-661a55c0676a"); -const LLUUID ANIM_AGENT_SALUTE = LLUUID("cd7668a6-7011-d7e2-ead8-fc69eff1a104"); -const LLUUID ANIM_AGENT_SHOOT_BOW_L = LLUUID("e04d450d-fdb5-0432-fd68-818aaf5935f8"); -const LLUUID ANIM_AGENT_SHOUT = LLUUID("6bd01860-4ebd-127a-bb3d-d1427e8e0c42"); -const LLUUID ANIM_AGENT_SHRUG = LLUUID("70ea714f-3a97-d742-1b01-590a8fcd1db5"); -const LLUUID ANIM_AGENT_SIT = LLUUID("1a5fe8ac-a804-8a5d-7cbd-56bd83184568"); -const LLUUID ANIM_AGENT_SIT_FEMALE = LLUUID("b1709c8d-ecd3-54a1-4f28-d55ac0840782"); -const LLUUID ANIM_AGENT_SIT_GENERIC = LLUUID("245f3c54-f1c0-bf2e-811f-46d8eeb386e7"); -const LLUUID ANIM_AGENT_SIT_GROUND = LLUUID("1c7600d6-661f-b87b-efe2-d7421eb93c86"); -const LLUUID ANIM_AGENT_SIT_GROUND_CONSTRAINED = LLUUID("1a2bd58e-87ff-0df8-0b4c-53e047b0bb6e"); -const LLUUID ANIM_AGENT_SIT_TO_STAND = LLUUID("a8dee56f-2eae-9e7a-05a2-6fb92b97e21e"); -const LLUUID ANIM_AGENT_SLEEP = LLUUID("f2bed5f9-9d44-39af-b0cd-257b2a17fe40"); -const LLUUID ANIM_AGENT_SMOKE_IDLE = LLUUID("d2f2ee58-8ad1-06c9-d8d3-3827ba31567a"); -const LLUUID ANIM_AGENT_SMOKE_INHALE = LLUUID("6802d553-49da-0778-9f85-1599a2266526"); -const LLUUID ANIM_AGENT_SMOKE_THROW_DOWN = LLUUID("0a9fb970-8b44-9114-d3a9-bf69cfe804d6"); -const LLUUID ANIM_AGENT_SNAPSHOT = LLUUID("eae8905b-271a-99e2-4c0e-31106afd100c"); -const LLUUID ANIM_AGENT_STAND = LLUUID("2408fe9e-df1d-1d7d-f4ff-1384fa7b350f"); -const LLUUID ANIM_AGENT_STANDUP = LLUUID("3da1d753-028a-5446-24f3-9c9b856d9422"); -const LLUUID ANIM_AGENT_STAND_1 = LLUUID("15468e00-3400-bb66-cecc-646d7c14458e"); -const LLUUID ANIM_AGENT_STAND_2 = LLUUID("370f3a20-6ca6-9971-848c-9a01bc42ae3c"); -const LLUUID ANIM_AGENT_STAND_3 = LLUUID("42b46214-4b44-79ae-deb8-0df61424ff4b"); -const LLUUID ANIM_AGENT_STAND_4 = LLUUID("f22fed8b-a5ed-2c93-64d5-bdd8b93c889f"); -const LLUUID ANIM_AGENT_STRETCH = LLUUID("80700431-74ec-a008-14f8-77575e73693f"); -const LLUUID ANIM_AGENT_STRIDE = LLUUID("1cb562b0-ba21-2202-efb3-30f82cdf9595"); -const LLUUID ANIM_AGENT_SURF = LLUUID("41426836-7437-7e89-025d-0aa4d10f1d69"); -const LLUUID ANIM_AGENT_SURPRISE = LLUUID("313b9881-4302-73c0-c7d0-0e7a36b6c224"); -const LLUUID ANIM_AGENT_SWORD_STRIKE = LLUUID("85428680-6bf9-3e64-b489-6f81087c24bd"); -const LLUUID ANIM_AGENT_TALK = LLUUID("5c682a95-6da4-a463-0bf6-0f5b7be129d1"); -const LLUUID ANIM_AGENT_TANTRUM = LLUUID("11000694-3f41-adc2-606b-eee1d66f3724"); -const LLUUID ANIM_AGENT_THROW_R = LLUUID("aa134404-7dac-7aca-2cba-435f9db875ca"); -const LLUUID ANIM_AGENT_TRYON_SHIRT = LLUUID("83ff59fe-2346-f236-9009-4e3608af64c1"); -const LLUUID ANIM_AGENT_TURNLEFT = LLUUID("56e0ba0d-4a9f-7f27-6117-32f2ebbf6135"); -const LLUUID ANIM_AGENT_TURNRIGHT = LLUUID("2d6daa51-3192-6794-8e2e-a15f8338ec30"); -const LLUUID ANIM_AGENT_TYPE = LLUUID("c541c47f-e0c0-058b-ad1a-d6ae3a4584d9"); -const LLUUID ANIM_AGENT_WALK = LLUUID("6ed24bd8-91aa-4b12-ccc7-c97c857ab4e0"); -const LLUUID ANIM_AGENT_WALK_NEW = LLUUID("33339176-7ddc-9397-94a4-bf3403cbc8f5"); -const LLUUID ANIM_AGENT_WHISPER = LLUUID("7693f268-06c7-ea71-fa21-2b30d6533f8f"); -const LLUUID ANIM_AGENT_WHISTLE = LLUUID("b1ed7982-c68e-a982-7561-52a88a5298c0"); -const LLUUID ANIM_AGENT_WINK = LLUUID("869ecdad-a44b-671e-3266-56aef2e3ac2e"); -const LLUUID ANIM_AGENT_WINK_HOLLYWOOD = LLUUID("c0c4030f-c02b-49de-24ba-2331f43fe41c"); -const LLUUID ANIM_AGENT_WORRY = LLUUID("9f496bd2-589a-709f-16cc-69bf7df1d36c"); -const LLUUID ANIM_AGENT_YES = LLUUID("15dd911d-be82-2856-26db-27659b142875"); -const LLUUID ANIM_AGENT_YES_HAPPY = LLUUID("b8c8b2a3-9008-1771-3bfc-90924955ab2d"); -const LLUUID ANIM_AGENT_YOGA_FLOAT = LLUUID("42ecd00b-9947-a97c-400a-bbc9174c7aeb"); +LLUUID const ANIM_AGENT_AFRAID ("6b61c8e8-4747-0d75-12d7-e49ff207a4ca"); +LLUUID const ANIM_AGENT_AIM_BAZOOKA_R ("b5b4a67d-0aee-30d2-72cd-77b333e932ef"); +LLUUID const ANIM_AGENT_AIM_BOW_L ("46bb4359-de38-4ed8-6a22-f1f52fe8f506"); +LLUUID const ANIM_AGENT_AIM_HANDGUN_R ("3147d815-6338-b932-f011-16b56d9ac18b"); +LLUUID const ANIM_AGENT_AIM_RIFLE_R ("ea633413-8006-180a-c3ba-96dd1d756720"); +LLUUID const ANIM_AGENT_ANGRY ("5747a48e-073e-c331-f6f3-7c2149613d3e"); +LLUUID const ANIM_AGENT_AWAY ("fd037134-85d4-f241-72c6-4f42164fedee"); +LLUUID const ANIM_AGENT_BACKFLIP ("c4ca6188-9127-4f31-0158-23c4e2f93304"); +LLUUID const ANIM_AGENT_BELLY_LAUGH ("18b3a4b5-b463-bd48-e4b6-71eaac76c515"); +LLUUID const ANIM_AGENT_BLOW_KISS ("db84829b-462c-ee83-1e27-9bbee66bd624"); +LLUUID const ANIM_AGENT_BORED ("b906c4ba-703b-1940-32a3-0c7f7d791510"); +LLUUID const ANIM_AGENT_BOW ("82e99230-c906-1403-4d9c-3889dd98daba"); +LLUUID const ANIM_AGENT_BRUSH ("349a3801-54f9-bf2c-3bd0-1ac89772af01"); +LLUUID const ANIM_AGENT_BUSY ("efcf670c-2d18-8128-973a-034ebc806b67"); +LLUUID const ANIM_AGENT_CLAP ("9b0c1c4e-8ac7-7969-1494-28c874c4f668"); +LLUUID const ANIM_AGENT_COURTBOW ("9ba1c942-08be-e43a-fb29-16ad440efc50"); +LLUUID const ANIM_AGENT_CROUCH ("201f3fdf-cb1f-dbec-201f-7333e328ae7c"); +LLUUID const ANIM_AGENT_CROUCHWALK ("47f5f6fb-22e5-ae44-f871-73aaaf4a6022"); +LLUUID const ANIM_AGENT_CRY ("92624d3e-1068-f1aa-a5ec-8244585193ed"); +LLUUID const ANIM_AGENT_CUSTOMIZE ("038fcec9-5ebd-8a8e-0e2e-6e71a0a1ac53"); +LLUUID const ANIM_AGENT_CUSTOMIZE_DONE ("6883a61a-b27b-5914-a61e-dda118a9ee2c"); +LLUUID const ANIM_AGENT_DANCE1 ("b68a3d7c-de9e-fc87-eec8-543d787e5b0d"); +LLUUID const ANIM_AGENT_DANCE2 ("928cae18-e31d-76fd-9cc9-2f55160ff818"); +LLUUID const ANIM_AGENT_DANCE3 ("30047778-10ea-1af7-6881-4db7a3a5a114"); +LLUUID const ANIM_AGENT_DANCE4 ("951469f4-c7b2-c818-9dee-ad7eea8c30b7"); +LLUUID const ANIM_AGENT_DANCE5 ("4bd69a1d-1114-a0b4-625f-84e0a5237155"); +LLUUID const ANIM_AGENT_DANCE6 ("cd28b69b-9c95-bb78-3f94-8d605ff1bb12"); +LLUUID const ANIM_AGENT_DANCE7 ("a54d8ee2-28bb-80a9-7f0c-7afbbe24a5d6"); +LLUUID const ANIM_AGENT_DANCE8 ("b0dc417c-1f11-af36-2e80-7e7489fa7cdc"); +LLUUID const ANIM_AGENT_DEAD ("57abaae6-1d17-7b1b-5f98-6d11a6411276"); +LLUUID const ANIM_AGENT_DRINK ("0f86e355-dd31-a61c-fdb0-3a96b9aad05f"); +LLUUID const ANIM_AGENT_EMBARRASSED ("514af488-9051-044a-b3fc-d4dbf76377c6"); +LLUUID const ANIM_AGENT_EXPRESS_AFRAID ("aa2df84d-cf8f-7218-527b-424a52de766e"); +LLUUID const ANIM_AGENT_EXPRESS_ANGER ("1a03b575-9634-b62a-5767-3a679e81f4de"); +LLUUID const ANIM_AGENT_EXPRESS_BORED ("214aa6c1-ba6a-4578-f27c-ce7688f61d0d"); +LLUUID const ANIM_AGENT_EXPRESS_CRY ("d535471b-85bf-3b4d-a542-93bea4f59d33"); +LLUUID const ANIM_AGENT_EXPRESS_DISDAIN ("d4416ff1-09d3-300f-4183-1b68a19b9fc1"); +LLUUID const ANIM_AGENT_EXPRESS_EMBARRASSED ("0b8c8211-d78c-33e8-fa28-c51a9594e424"); +LLUUID const ANIM_AGENT_EXPRESS_FROWN ("fee3df48-fa3d-1015-1e26-a205810e3001"); +LLUUID const ANIM_AGENT_EXPRESS_KISS ("1e8d90cc-a84e-e135-884c-7c82c8b03a14"); +LLUUID const ANIM_AGENT_EXPRESS_LAUGH ("62570842-0950-96f8-341c-809e65110823"); +LLUUID const ANIM_AGENT_EXPRESS_OPEN_MOUTH ("d63bc1f9-fc81-9625-a0c6-007176d82eb7"); +LLUUID const ANIM_AGENT_EXPRESS_REPULSED ("f76cda94-41d4-a229-2872-e0296e58afe1"); +LLUUID const ANIM_AGENT_EXPRESS_SAD ("eb6ebfb2-a4b3-a19c-d388-4dd5c03823f7"); +LLUUID const ANIM_AGENT_EXPRESS_SHRUG ("a351b1bc-cc94-aac2-7bea-a7e6ebad15ef"); +LLUUID const ANIM_AGENT_EXPRESS_SMILE ("b7c7c833-e3d3-c4e3-9fc0-131237446312"); +LLUUID const ANIM_AGENT_EXPRESS_SURPRISE ("728646d9-cc79-08b2-32d6-937f0a835c24"); +LLUUID const ANIM_AGENT_EXPRESS_TONGUE_OUT ("835965c6-7f2f-bda2-5deb-2478737f91bf"); +LLUUID const ANIM_AGENT_EXPRESS_TOOTHSMILE ("b92ec1a5-e7ce-a76b-2b05-bcdb9311417e"); +LLUUID const ANIM_AGENT_EXPRESS_WINK ("da020525-4d94-59d6-23d7-81fdebf33148"); +LLUUID const ANIM_AGENT_EXPRESS_WORRY ("9c05e5c7-6f07-6ca4-ed5a-b230390c3950"); +LLUUID const ANIM_AGENT_FALLDOWN ("666307d9-a860-572d-6fd4-c3ab8865c094"); +LLUUID const ANIM_AGENT_FEMALE_RUN_NEW ("85995026-eade-5d78-d364-94a64512cb66"); +LLUUID const ANIM_AGENT_FEMALE_WALK ("f5fc7433-043d-e819-8298-f519a119b688"); +LLUUID const ANIM_AGENT_FEMALE_WALK_NEW ("d60c41d2-7c24-7074-d3fa-6101cea22a51"); +LLUUID const ANIM_AGENT_FINGER_WAG ("c1bc7f36-3ba0-d844-f93c-93be945d644f"); +LLUUID const ANIM_AGENT_FIST_PUMP ("7db00ccd-f380-f3ee-439d-61968ec69c8a"); +LLUUID const ANIM_AGENT_FLY ("aec4610c-757f-bc4e-c092-c6e9caf18daf"); +LLUUID const ANIM_AGENT_FLYSLOW ("2b5a38b2-5e00-3a97-a495-4c826bc443e6"); +LLUUID const ANIM_AGENT_HELLO ("9b29cd61-c45b-5689-ded2-91756b8d76a9"); +LLUUID const ANIM_AGENT_HOLD_BAZOOKA_R ("ef62d355-c815-4816-2474-b1acc21094a6"); +LLUUID const ANIM_AGENT_HOLD_BOW_L ("8b102617-bcba-037b-86c1-b76219f90c88"); +LLUUID const ANIM_AGENT_HOLD_HANDGUN_R ("efdc1727-8b8a-c800-4077-975fc27ee2f2"); +LLUUID const ANIM_AGENT_HOLD_RIFLE_R ("3d94bad0-c55b-7dcc-8763-033c59405d33"); +LLUUID const ANIM_AGENT_HOLD_THROW_R ("7570c7b5-1f22-56dd-56ef-a9168241bbb6"); +LLUUID const ANIM_AGENT_HOVER ("4ae8016b-31b9-03bb-c401-b1ea941db41d"); +LLUUID const ANIM_AGENT_HOVER_DOWN ("20f063ea-8306-2562-0b07-5c853b37b31e"); +LLUUID const ANIM_AGENT_HOVER_UP ("62c5de58-cb33-5743-3d07-9e4cd4352864"); +LLUUID const ANIM_AGENT_IMPATIENT ("5ea3991f-c293-392e-6860-91dfa01278a3"); +LLUUID const ANIM_AGENT_JUMP ("2305bd75-1ca9-b03b-1faa-b176b8a8c49e"); +LLUUID const ANIM_AGENT_JUMP_FOR_JOY ("709ea28e-1573-c023-8bf8-520c8bc637fa"); +LLUUID const ANIM_AGENT_KISS_MY_BUTT ("19999406-3a3a-d58c-a2ac-d72e555dcf51"); +LLUUID const ANIM_AGENT_LAND ("7a17b059-12b2-41b1-570a-186368b6aa6f"); +LLUUID const ANIM_AGENT_LAUGH_SHORT ("ca5b3f14-3194-7a2b-c894-aa699b718d1f"); +LLUUID const ANIM_AGENT_MEDIUM_LAND ("f4f00d6e-b9fe-9292-f4cb-0ae06ea58d57"); +LLUUID const ANIM_AGENT_MOTORCYCLE_SIT ("08464f78-3a8e-2944-cba5-0c94aff3af29"); +LLUUID const ANIM_AGENT_MUSCLE_BEACH ("315c3a41-a5f3-0ba4-27da-f893f769e69b"); +LLUUID const ANIM_AGENT_NO ("5a977ed9-7f72-44e9-4c4c-6e913df8ae74"); +LLUUID const ANIM_AGENT_NO_UNHAPPY ("d83fa0e5-97ed-7eb2-e798-7bd006215cb4"); +LLUUID const ANIM_AGENT_NYAH_NYAH ("f061723d-0a18-754f-66ee-29a44795a32f"); +LLUUID const ANIM_AGENT_ONETWO_PUNCH ("eefc79be-daae-a239-8c04-890f5d23654a"); +LLUUID const ANIM_AGENT_PEACE ("b312b10e-65ab-a0a4-8b3c-1326ea8e3ed9"); +LLUUID const ANIM_AGENT_POINT_ME ("17c024cc-eef2-f6a0-3527-9869876d7752"); +LLUUID const ANIM_AGENT_POINT_YOU ("ec952cca-61ef-aa3b-2789-4d1344f016de"); +LLUUID const ANIM_AGENT_PRE_JUMP ("7a4e87fe-de39-6fcb-6223-024b00893244"); +LLUUID const ANIM_AGENT_PUNCH_LEFT ("f3300ad9-3462-1d07-2044-0fef80062da0"); +LLUUID const ANIM_AGENT_PUNCH_RIGHT ("c8e42d32-7310-6906-c903-cab5d4a34656"); +LLUUID const ANIM_AGENT_REPULSED ("36f81a92-f076-5893-dc4b-7c3795e487cf"); +LLUUID const ANIM_AGENT_ROUNDHOUSE_KICK ("49aea43b-5ac3-8a44-b595-96100af0beda"); +LLUUID const ANIM_AGENT_RPS_COUNTDOWN ("35db4f7e-28c2-6679-cea9-3ee108f7fc7f"); +LLUUID const ANIM_AGENT_RPS_PAPER ("0836b67f-7f7b-f37b-c00a-460dc1521f5a"); +LLUUID const ANIM_AGENT_RPS_ROCK ("42dd95d5-0bc6-6392-f650-777304946c0f"); +LLUUID const ANIM_AGENT_RPS_SCISSORS ("16803a9f-5140-e042-4d7b-d28ba247c325"); +LLUUID const ANIM_AGENT_RUN ("05ddbff8-aaa9-92a1-2b74-8fe77a29b445"); +LLUUID const ANIM_AGENT_RUN_NEW ("1ab1b236-cd08-21e6-0cbc-0d923fc6eca2"); +LLUUID const ANIM_AGENT_SAD ("0eb702e2-cc5a-9a88-56a5-661a55c0676a"); +LLUUID const ANIM_AGENT_SALUTE ("cd7668a6-7011-d7e2-ead8-fc69eff1a104"); +LLUUID const ANIM_AGENT_SHOOT_BOW_L ("e04d450d-fdb5-0432-fd68-818aaf5935f8"); +LLUUID const ANIM_AGENT_SHOUT ("6bd01860-4ebd-127a-bb3d-d1427e8e0c42"); +LLUUID const ANIM_AGENT_SHRUG ("70ea714f-3a97-d742-1b01-590a8fcd1db5"); +LLUUID const ANIM_AGENT_SIT ("1a5fe8ac-a804-8a5d-7cbd-56bd83184568"); +LLUUID const ANIM_AGENT_SIT_FEMALE ("b1709c8d-ecd3-54a1-4f28-d55ac0840782"); +LLUUID const ANIM_AGENT_SIT_GENERIC ("245f3c54-f1c0-bf2e-811f-46d8eeb386e7"); +LLUUID const ANIM_AGENT_SIT_GROUND ("1c7600d6-661f-b87b-efe2-d7421eb93c86"); +LLUUID const ANIM_AGENT_SIT_GROUND_CONSTRAINED("1a2bd58e-87ff-0df8-0b4c-53e047b0bb6e"); +LLUUID const ANIM_AGENT_SIT_TO_STAND ("a8dee56f-2eae-9e7a-05a2-6fb92b97e21e"); +LLUUID const ANIM_AGENT_SLEEP ("f2bed5f9-9d44-39af-b0cd-257b2a17fe40"); +LLUUID const ANIM_AGENT_SMOKE_IDLE ("d2f2ee58-8ad1-06c9-d8d3-3827ba31567a"); +LLUUID const ANIM_AGENT_SMOKE_INHALE ("6802d553-49da-0778-9f85-1599a2266526"); +LLUUID const ANIM_AGENT_SMOKE_THROW_DOWN ("0a9fb970-8b44-9114-d3a9-bf69cfe804d6"); +LLUUID const ANIM_AGENT_SNAPSHOT ("eae8905b-271a-99e2-4c0e-31106afd100c"); +LLUUID const ANIM_AGENT_STAND ("2408fe9e-df1d-1d7d-f4ff-1384fa7b350f"); +LLUUID const ANIM_AGENT_STANDUP ("3da1d753-028a-5446-24f3-9c9b856d9422"); +LLUUID const ANIM_AGENT_STAND_1 ("15468e00-3400-bb66-cecc-646d7c14458e"); +LLUUID const ANIM_AGENT_STAND_2 ("370f3a20-6ca6-9971-848c-9a01bc42ae3c"); +LLUUID const ANIM_AGENT_STAND_3 ("42b46214-4b44-79ae-deb8-0df61424ff4b"); +LLUUID const ANIM_AGENT_STAND_4 ("f22fed8b-a5ed-2c93-64d5-bdd8b93c889f"); +LLUUID const ANIM_AGENT_STRETCH ("80700431-74ec-a008-14f8-77575e73693f"); +LLUUID const ANIM_AGENT_STRIDE ("1cb562b0-ba21-2202-efb3-30f82cdf9595"); +LLUUID const ANIM_AGENT_SURF ("41426836-7437-7e89-025d-0aa4d10f1d69"); +LLUUID const ANIM_AGENT_SURPRISE ("313b9881-4302-73c0-c7d0-0e7a36b6c224"); +LLUUID const ANIM_AGENT_SWORD_STRIKE ("85428680-6bf9-3e64-b489-6f81087c24bd"); +LLUUID const ANIM_AGENT_TALK ("5c682a95-6da4-a463-0bf6-0f5b7be129d1"); +LLUUID const ANIM_AGENT_TANTRUM ("11000694-3f41-adc2-606b-eee1d66f3724"); +LLUUID const ANIM_AGENT_THROW_R ("aa134404-7dac-7aca-2cba-435f9db875ca"); +LLUUID const ANIM_AGENT_TRYON_SHIRT ("83ff59fe-2346-f236-9009-4e3608af64c1"); +LLUUID const ANIM_AGENT_TURNLEFT ("56e0ba0d-4a9f-7f27-6117-32f2ebbf6135"); +LLUUID const ANIM_AGENT_TURNRIGHT ("2d6daa51-3192-6794-8e2e-a15f8338ec30"); +LLUUID const ANIM_AGENT_TYPE ("c541c47f-e0c0-058b-ad1a-d6ae3a4584d9"); +LLUUID const ANIM_AGENT_WALK ("6ed24bd8-91aa-4b12-ccc7-c97c857ab4e0"); +LLUUID const ANIM_AGENT_WALK_NEW ("33339176-7ddc-9397-94a4-bf3403cbc8f5"); +LLUUID const ANIM_AGENT_WHISPER ("7693f268-06c7-ea71-fa21-2b30d6533f8f"); +LLUUID const ANIM_AGENT_WHISTLE ("b1ed7982-c68e-a982-7561-52a88a5298c0"); +LLUUID const ANIM_AGENT_WINK ("869ecdad-a44b-671e-3266-56aef2e3ac2e"); +LLUUID const ANIM_AGENT_WINK_HOLLYWOOD ("c0c4030f-c02b-49de-24ba-2331f43fe41c"); +LLUUID const ANIM_AGENT_WORRY ("9f496bd2-589a-709f-16cc-69bf7df1d36c"); +LLUUID const ANIM_AGENT_YES ("15dd911d-be82-2856-26db-27659b142875"); +LLUUID const ANIM_AGENT_YES_HAPPY ("b8c8b2a3-9008-1771-3bfc-90924955ab2d"); +LLUUID const ANIM_AGENT_YOGA_FLOAT ("42ecd00b-9947-a97c-400a-bbc9174c7aeb"); LLUUID AGENT_WALK_ANIMS[] = {ANIM_AGENT_WALK, ANIM_AGENT_RUN, ANIM_AGENT_CROUCHWALK, ANIM_AGENT_TURNLEFT, ANIM_AGENT_TURNRIGHT}; S32 NUM_AGENT_WALK_ANIMS = LL_ARRAY_SIZE(AGENT_WALK_ANIMS); diff --git a/indra/llcommon/llavatarconstants.h b/indra/llcommon/llavatarconstants.h index 596b0643ef..f47f447b45 100644 --- a/indra/llcommon/llavatarconstants.h +++ b/indra/llcommon/llavatarconstants.h @@ -46,10 +46,10 @@ const U32 AVATAR_TRANSACTED = 0x1 << 3; // whether avatar has actively used p const U32 AVATAR_ONLINE = 0x1 << 4; // the online status of this avatar, if known. const U32 AVATAR_AGEVERIFIED = 0x1 << 5; // whether avatar has been age-verified -static const std::string VISIBILITY_DEFAULT("default"); -static const std::string VISIBILITY_HIDDEN("hidden"); -static const std::string VISIBILITY_VISIBLE("visible"); -static const std::string VISIBILITY_INVISIBLE("invisible"); +char const* const VISIBILITY_DEFAULT = "default"; +char const* const VISIBILITY_HIDDEN = "hidden"; +char const* const VISIBILITY_VISIBLE = "visible"; +char const* const VISIBILITY_INVISIBLE = "invisible"; #endif diff --git a/indra/llcommon/lllslconstants.h b/indra/llcommon/lllslconstants.h index 539c807020..9f32598e61 100644 --- a/indra/llcommon/lllslconstants.h +++ b/indra/llcommon/lllslconstants.h @@ -181,7 +181,7 @@ const S32 OBJECT_GROUP = 7; const S32 OBJECT_CREATOR = 8; // llTextBox() magic token string - yes this is a hack. sue me. -const std::string TEXTBOX_MAGIC_TOKEN = "!!llTextBox!!"; +char const* const TEXTBOX_MAGIC_TOKEN = "!!llTextBox!!"; // changed() event flags const U32 CHANGED_NONE = 0x0; diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp index 51fcd5b717..08fc1ddfe5 100644 --- a/indra/llcommon/llmemory.cpp +++ b/indra/llcommon/llmemory.cpp @@ -26,14 +26,13 @@ #include "linden_common.h" -#include "llmemory.h" -#if MEM_TRACK_MEM +//#if MEM_TRACK_MEM #include "llthread.h" -#endif +//#endif #if defined(LL_WINDOWS) -# include <windows.h> +//# include <windows.h> # include <psapi.h> #elif defined(LL_DARWIN) # include <sys/types.h> @@ -43,10 +42,20 @@ # include <unistd.h> #endif +#include "llmemory.h" + +#include "llsys.h" +#include "llframetimer.h" //---------------------------------------------------------------------------- //static char* LLMemory::reserveMem = 0; +U32 LLMemory::sAvailPhysicalMemInKB = U32_MAX ; +U32 LLMemory::sMaxPhysicalMemInKB = 0; +U32 LLMemory::sAllocatedMemInKB = 0; +U32 LLMemory::sAllocatedPageSizeInKB = 0 ; +U32 LLMemory::sMaxHeapSizeInKB = U32_MAX ; +BOOL LLMemory::sEnableMemoryFailurePrevention = FALSE; //static void LLMemory::initClass() @@ -71,6 +80,131 @@ void LLMemory::freeReserve() reserveMem = NULL; } +//static +void LLMemory::initMaxHeapSizeGB(F32 max_heap_size_gb, BOOL prevent_heap_failure) +{ + sMaxHeapSizeInKB = (U32)(max_heap_size_gb * 1024 * 1024) ; + sEnableMemoryFailurePrevention = prevent_heap_failure ; +} + +//static +void LLMemory::updateMemoryInfo() +{ +#if LL_WINDOWS + HANDLE self = GetCurrentProcess(); + PROCESS_MEMORY_COUNTERS counters; + + if (!GetProcessMemoryInfo(self, &counters, sizeof(counters))) + { + llwarns << "GetProcessMemoryInfo failed" << llendl; + return ; + } + + sAllocatedMemInKB = (U32)(counters.WorkingSetSize / 1024) ; + sAllocatedPageSizeInKB = (U32)(counters.PagefileUsage / 1024) ; + sMaxPhysicalMemInKB = llmin(LLMemoryInfo::getAvailableMemoryKB() + sAllocatedMemInKB, sMaxHeapSizeInKB); + + if(sMaxPhysicalMemInKB > sAllocatedMemInKB) + { + sAvailPhysicalMemInKB = sMaxPhysicalMemInKB - sAllocatedMemInKB ; + } + else + { + sAvailPhysicalMemInKB = 0 ; + } +#else + //not valid for other systems for now. + sAllocatedMemInKB = (U32)(LLMemory::getCurrentRSS() / 1024) ; + sMaxPhysicalMemInKB = U32_MAX ; + sAvailPhysicalMemInKB = U32_MAX ; +#endif + + return ; +} + +// +//this function is to test if there is enough space with the size in the virtual address space. +//it does not do any real allocation +//if success, it returns the address where the memory chunk can fit in; +//otherwise it returns NULL. +// +//static +void* LLMemory::tryToAlloc(void* address, U32 size) +{ +#if LL_WINDOWS + address = VirtualAlloc(address, size, MEM_RESERVE | MEM_TOP_DOWN, PAGE_NOACCESS) ; + if(address) + { + if(!VirtualFree(address, 0, MEM_RELEASE)) + { + llerrs << "error happens when free some memory reservation." << llendl ; + } + } +#else +#endif + + return address ; +} + +//static +void LLMemory::logMemoryInfo(BOOL update) +{ + if(update) + { + updateMemoryInfo() ; + } + + llinfos << "Current allocated physical memory(KB): " << sAllocatedMemInKB << llendl ; + llinfos << "Current allocated page size (KB): " << sAllocatedPageSizeInKB << llendl ; + llinfos << "Current availabe physical memory(KB): " << sAvailPhysicalMemInKB << llendl ; + llinfos << "Current max usable memory(KB): " << sMaxPhysicalMemInKB << llendl ; +} + +//return 0: everything is normal; +//return 1: the memory pool is low, but not in danger; +//return -1: the memory pool is in danger, is about to crash. +//static +S32 LLMemory::isMemoryPoolLow() +{ + static const U32 LOW_MEMEOY_POOL_THRESHOLD_KB = 64 * 1024 ; //64 MB for emergency use + + if(!sEnableMemoryFailurePrevention) + { + return 0 ; //no memory failure prevention. + } + + if(sAvailPhysicalMemInKB < (LOW_MEMEOY_POOL_THRESHOLD_KB >> 2)) //out of physical memory + { + return -1 ; + } + + if(sAllocatedPageSizeInKB + (LOW_MEMEOY_POOL_THRESHOLD_KB >> 2) > sMaxHeapSizeInKB) //out of virtual address space. + { + return -1 ; + } + + return (S32)(sAvailPhysicalMemInKB < LOW_MEMEOY_POOL_THRESHOLD_KB || + sAllocatedPageSizeInKB + LOW_MEMEOY_POOL_THRESHOLD_KB > sMaxHeapSizeInKB) ; +} + +//static +U32 LLMemory::getAvailableMemKB() +{ + return sAvailPhysicalMemInKB ; +} + +//static +U32 LLMemory::getMaxMemKB() +{ + return sMaxPhysicalMemInKB ; +} + +//static +U32 LLMemory::getAllocatedMemKB() +{ + return sAllocatedMemInKB ; +} + void* ll_allocate (size_t size) { if (size == 0) @@ -256,7 +390,7 @@ U64 LLMemory::getCurrentRSS() U32 LLMemory::getWorkingSetSize() { - return 0 ; + return 0; } #endif @@ -395,3 +529,1508 @@ const char* LLMemTracker::getNextLine() #endif //MEM_TRACK_MEM //-------------------------------------------------------------------------------------------------- + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +//minimum block sizes (page size) for small allocation, medium allocation, large allocation +const U32 MIN_BLOCK_SIZES[LLPrivateMemoryPool::SUPER_ALLOCATION] = {2 << 10, 4 << 10, 16 << 10} ; // + +//maximum block sizes for small allocation, medium allocation, large allocation +const U32 MAX_BLOCK_SIZES[LLPrivateMemoryPool::SUPER_ALLOCATION] = {64 << 10, 1 << 20, 4 << 20} ; + +//minimum slot sizes for small allocation, medium allocation, large allocation +const U32 MIN_SLOT_SIZES[LLPrivateMemoryPool::SUPER_ALLOCATION] = {8, 2 << 10, 512 << 10}; + +//maximum slot sizes for small allocation, medium allocation, large allocation +const U32 MAX_SLOT_SIZES[LLPrivateMemoryPool::SUPER_ALLOCATION] = {(2 << 10) - 8, (512 - 2) << 10, 4 << 20}; + +//size of a block with multiple slots can not exceed CUT_OFF_SIZE +const U32 CUT_OFF_SIZE = (64 << 10) ; //64 KB + +//------------------------------------------------------------- +//class LLPrivateMemoryPool::LLMemoryBlock +//------------------------------------------------------------- +// +//each memory block could fit for two page sizes: 0.75 * mSlotSize, which starts from the beginning of the memory chunk and grow towards the end of the +//the block; another is mSlotSize, which starts from the end of the block and grows towards the beginning of the block. +// +LLPrivateMemoryPool::LLMemoryBlock::LLMemoryBlock() +{ + //empty +} + +LLPrivateMemoryPool::LLMemoryBlock::~LLMemoryBlock() +{ + //empty +} + +//create and initialize a memory block +void LLPrivateMemoryPool::LLMemoryBlock::init(char* buffer, U32 buffer_size, U32 slot_size) +{ + mBuffer = buffer ; + mBufferSize = buffer_size ; + mSlotSize = slot_size ; + mTotalSlots = buffer_size / mSlotSize ; + + llassert_always(mTotalSlots <= 256) ; //max number is 256 + + mAllocatedSlots = 0 ; + + //init the bit map. + //mark free bits + S32 usage_bit_len = (mTotalSlots + 31) / 32 ; + mDummySize = usage_bit_len - 1 ; //if the mTotalSlots more than 32, needs extra space for bit map + if(mDummySize > 0) //reserve extra space from mBuffer to store bitmap if needed. + { + mTotalSlots -= (mDummySize * sizeof(mUsageBits) + mSlotSize - 1) / mSlotSize ; + usage_bit_len = (mTotalSlots + 31) / 32 ; + mDummySize = usage_bit_len - 1 ;//number of 32bits reserved from mBuffer for bitmap + + if(mDummySize > 0) + { + mUsageBits = 0 ; + for(S32 i = 0 ; i < mDummySize ; i++) + { + *((U32*)mBuffer + i) = 0 ; + } + if(mTotalSlots & 31) + { + *((U32*)mBuffer + mDummySize - 1) = (0xffffffff << (mTotalSlots & 31)) ; + } + } + } + + if(mDummySize < 1)//no extra bitmap space reserved + { + mUsageBits = 0 ; + if(mTotalSlots & 31) + { + mUsageBits = (0xffffffff << (mTotalSlots & 31)) ; + } + } + + mSelf = this ; + mNext = NULL ; + mPrev = NULL ; + + llassert_always(mTotalSlots > 0) ; +} + +//mark this block to be free with the memory [mBuffer, mBuffer + mBufferSize). +void LLPrivateMemoryPool::LLMemoryBlock::setBuffer(char* buffer, U32 buffer_size) +{ + mBuffer = buffer ; + mBufferSize = buffer_size ; + mSelf = NULL ; + mTotalSlots = 0 ; //set the block is free. +} + +//reserve a slot +char* LLPrivateMemoryPool::LLMemoryBlock::allocate() +{ + llassert_always(mAllocatedSlots < mTotalSlots) ; + + //find a free slot + U32* bits = NULL ; + U32 k = 0 ; + if(mUsageBits != 0xffffffff) + { + bits = &mUsageBits ; + } + else if(mDummySize > 0)//go to extra space + { + for(S32 i = 0 ; i < mDummySize; i++) + { + if(*((U32*)mBuffer + i) != 0xffffffff) + { + bits = (U32*)mBuffer + i ; + k = i + 1 ; + break ; + } + } + } + S32 idx = 0 ; + U32 tmp = *bits ; + for(; tmp & 1 ; tmp >>= 1, idx++) ; + + //set the slot reserved + if(!idx) + { + *bits |= 1 ; + } + else + { + *bits |= (1 << idx) ; + } + + mAllocatedSlots++ ; + + return mBuffer + mDummySize * sizeof(U32) + (k * 32 + idx) * mSlotSize ; +} + +//free a slot +void LLPrivateMemoryPool::LLMemoryBlock::free(void* addr) +{ + //bit index + U32 idx = ((U32)addr - (U32)mBuffer - mDummySize * sizeof(U32)) / mSlotSize ; + + U32* bits = &mUsageBits ; + if(idx >= 32) + { + bits = (U32*)mBuffer + (idx - 32) / 32 ; + } + + //reset the bit + if(idx & 31) + { + *bits &= ~(1 << (idx & 31)) ; + } + else + { + *bits &= ~1 ; + } + + mAllocatedSlots-- ; +} + +//for debug use: reset the entire bitmap. +void LLPrivateMemoryPool::LLMemoryBlock::resetBitMap() +{ + for(S32 i = 0 ; i < mDummySize ; i++) + { + *((U32*)mBuffer + i) = 0 ; + } + mUsageBits = 0 ; +} +//------------------------------------------------------------------- +//class LLMemoryChunk +//-------------------------------------------------------------------- +LLPrivateMemoryPool::LLMemoryChunk::LLMemoryChunk() +{ + //empty +} + +LLPrivateMemoryPool::LLMemoryChunk::~LLMemoryChunk() +{ + //empty +} + +//create and init a memory chunk +void LLPrivateMemoryPool::LLMemoryChunk::init(char* buffer, U32 buffer_size, U32 min_slot_size, U32 max_slot_size, U32 min_block_size, U32 max_block_size) +{ + mBuffer = buffer ; + mBufferSize = buffer_size ; + mAlloatedSize = 0 ; + + mMetaBuffer = mBuffer + sizeof(LLMemoryChunk) ; + + mMinBlockSize = min_block_size; //page size + mMinSlotSize = min_slot_size; + mMaxSlotSize = max_slot_size ; + mBlockLevels = mMaxSlotSize / mMinSlotSize ; + mPartitionLevels = max_block_size / mMinBlockSize + 1 ; + + S32 max_num_blocks = (buffer_size - sizeof(LLMemoryChunk) - mBlockLevels * sizeof(LLMemoryBlock*) - mPartitionLevels * sizeof(LLMemoryBlock*)) / + (mMinBlockSize + sizeof(LLMemoryBlock)) ; + //meta data space + mBlocks = (LLMemoryBlock*)mMetaBuffer ; //space reserved for all memory blocks. + mAvailBlockList = (LLMemoryBlock**)((char*)mBlocks + sizeof(LLMemoryBlock) * max_num_blocks) ; + mFreeSpaceList = (LLMemoryBlock**)((char*)mAvailBlockList + sizeof(LLMemoryBlock*) * mBlockLevels) ; + + //data buffer, which can be used for allocation + mDataBuffer = (char*)mFreeSpaceList + sizeof(LLMemoryBlock*) * mPartitionLevels ; + + //init + for(U32 i = 0 ; i < mBlockLevels; i++) + { + mAvailBlockList[i] = NULL ; + } + for(U32 i = 0 ; i < mPartitionLevels ; i++) + { + mFreeSpaceList[i] = NULL ; + } + + //assign the entire chunk to the first block + mBlocks[0].mPrev = NULL ; + mBlocks[0].mNext = NULL ; + mBlocks[0].setBuffer(mDataBuffer, buffer_size - (mDataBuffer - mBuffer)) ; + addToFreeSpace(&mBlocks[0]) ; + + mHashNext = NULL ; + mNext = NULL ; + mPrev = NULL ; +} + +//static +U32 LLPrivateMemoryPool::LLMemoryChunk::getMaxOverhead(U32 data_buffer_size, U32 min_slot_size, + U32 max_slot_size, U32 min_block_size, U32 max_block_size) +{ + //for large allocations, reserve some extra memory for meta data to avoid wasting much + if(data_buffer_size / min_slot_size < 64) //large allocations + { + U32 overhead = sizeof(LLMemoryChunk) + (data_buffer_size / min_block_size) * sizeof(LLMemoryBlock) + + sizeof(LLMemoryBlock*) * (max_slot_size / min_slot_size) + sizeof(LLMemoryBlock*) * (max_block_size / min_block_size + 1) ; + + //round to integer times of min_block_size + overhead = ((overhead + min_block_size - 1) / min_block_size) * min_block_size ; + return overhead ; + } + else + { + return 0 ; //do not reserve extra overhead if for small allocations + } +} + +char* LLPrivateMemoryPool::LLMemoryChunk::allocate(U32 size) +{ + if(mMinSlotSize > size) + { + size = mMinSlotSize ; + } + if(mAlloatedSize + size > mBufferSize - (mDataBuffer - mBuffer)) + { + return NULL ; //no enough space in this chunk. + } + + char* p = NULL ; + U32 blk_idx = getBlockLevel(size); + + LLMemoryBlock* blk = NULL ; + + //check if there is free block available + if(mAvailBlockList[blk_idx]) + { + blk = mAvailBlockList[blk_idx] ; + p = blk->allocate() ; + + if(blk->isFull()) + { + popAvailBlockList(blk_idx) ; + } + } + + //ask for a new block + if(!p) + { + blk = addBlock(blk_idx) ; + if(blk) + { + p = blk->allocate() ; + + if(blk->isFull()) + { + popAvailBlockList(blk_idx) ; + } + } + } + + //ask for space from larger blocks + if(!p) + { + for(S32 i = blk_idx + 1 ; i < mBlockLevels; i++) + { + if(mAvailBlockList[i]) + { + blk = mAvailBlockList[i] ; + p = blk->allocate() ; + + if(blk->isFull()) + { + popAvailBlockList(i) ; + } + break ; + } + } + } + + if(p && blk) + { + mAlloatedSize += blk->getSlotSize() ; + } + return p ; +} + +void LLPrivateMemoryPool::LLMemoryChunk::free(void* addr) +{ + U32 blk_idx = getPageIndex((U32)addr) ; + LLMemoryBlock* blk = (LLMemoryBlock*)(mMetaBuffer + blk_idx * sizeof(LLMemoryBlock)) ; + blk = blk->mSelf ; + + bool was_full = blk->isFull() ; + blk->free(addr) ; + mAlloatedSize -= blk->getSlotSize() ; + + if(blk->empty()) + { + removeBlock(blk) ; + } + else if(was_full) + { + addToAvailBlockList(blk) ; + } +} + +bool LLPrivateMemoryPool::LLMemoryChunk::empty() +{ + return !mAlloatedSize ; +} + +bool LLPrivateMemoryPool::LLMemoryChunk::containsAddress(const char* addr) const +{ + return (U32)mBuffer <= (U32)addr && (U32)mBuffer + mBufferSize > (U32)addr ; +} + +//debug use +void LLPrivateMemoryPool::LLMemoryChunk::dump() +{ +#if 0 + //sanity check + //for(S32 i = 0 ; i < mBlockLevels ; i++) + //{ + // LLMemoryBlock* blk = mAvailBlockList[i] ; + // while(blk) + // { + // blk_list.push_back(blk) ; + // blk = blk->mNext ; + // } + //} + for(S32 i = 0 ; i < mPartitionLevels ; i++) + { + LLMemoryBlock* blk = mFreeSpaceList[i] ; + while(blk) + { + blk_list.push_back(blk) ; + blk = blk->mNext ; + } + } + + std::sort(blk_list.begin(), blk_list.end(), LLMemoryBlock::CompareAddress()); + + U32 total_size = blk_list[0]->getBufferSize() ; + for(U32 i = 1 ; i < blk_list.size(); i++) + { + total_size += blk_list[i]->getBufferSize() ; + if((U32)blk_list[i]->getBuffer() < (U32)blk_list[i-1]->getBuffer() + blk_list[i-1]->getBufferSize()) + { + llerrs << "buffer corrupted." << llendl ; + } + } + + llassert_always(total_size + mMinBlockSize >= mBufferSize - ((U32)mDataBuffer - (U32)mBuffer)) ; + + U32 blk_num = (mBufferSize - (mDataBuffer - mBuffer)) / mMinBlockSize ; + for(U32 i = 0 ; i < blk_num ; ) + { + LLMemoryBlock* blk = &mBlocks[i] ; + if(blk->mSelf) + { + U32 end = blk->getBufferSize() / mMinBlockSize ; + for(U32 j = 0 ; j < end ; j++) + { + llassert_always(blk->mSelf == blk || !blk->mSelf) ; + } + i += end ; + } + else + { + llerrs << "gap happens" << llendl ; + } + } +#endif +#if 0 + llinfos << "---------------------------" << llendl ; + llinfos << "Chunk buffer: " << (U32)getBuffer() << " size: " << getBufferSize() << llendl ; + + llinfos << "available blocks ... " << llendl ; + for(S32 i = 0 ; i < mBlockLevels ; i++) + { + LLMemoryBlock* blk = mAvailBlockList[i] ; + while(blk) + { + llinfos << "blk buffer " << (U32)blk->getBuffer() << " size: " << blk->getBufferSize() << llendl ; + blk = blk->mNext ; + } + } + + llinfos << "free blocks ... " << llendl ; + for(S32 i = 0 ; i < mPartitionLevels ; i++) + { + LLMemoryBlock* blk = mFreeSpaceList[i] ; + while(blk) + { + llinfos << "blk buffer " << (U32)blk->getBuffer() << " size: " << blk->getBufferSize() << llendl ; + blk = blk->mNext ; + } + } +#endif +} + +//compute the size for a block, the size is round to integer times of mMinBlockSize. +U32 LLPrivateMemoryPool::LLMemoryChunk::calcBlockSize(U32 slot_size) +{ + // + //Note: we try to make a block to have 32 slots if the size is not over 32 pages + //32 is the number of bits of an integer in a 32-bit system + // + + U32 block_size; + U32 cut_off_size = llmin(CUT_OFF_SIZE, (U32)(mMinBlockSize << 5)) ; + + if((slot_size << 5) <= mMinBlockSize)//for small allocations, return one page + { + block_size = mMinBlockSize ; + } + else if(slot_size >= cut_off_size)//for large allocations, return one-slot block + { + block_size = (slot_size / mMinBlockSize) * mMinBlockSize ; + if(block_size < slot_size) + { + block_size += mMinBlockSize ; + } + } + else //medium allocations + { + if((slot_size << 5) >= cut_off_size) + { + block_size = cut_off_size ; + } + else + { + block_size = ((slot_size << 5) / mMinBlockSize) * mMinBlockSize ; + } + } + + llassert_always(block_size >= slot_size) ; + + return block_size ; +} + +//create a new block in the chunk +LLPrivateMemoryPool::LLMemoryBlock* LLPrivateMemoryPool::LLMemoryChunk::addBlock(U32 blk_idx) +{ + U32 slot_size = mMinSlotSize * (blk_idx + 1) ; + U32 preferred_block_size = calcBlockSize(slot_size) ; + U16 idx = getPageLevel(preferred_block_size); + LLMemoryBlock* blk = NULL ; + + if(mFreeSpaceList[idx])//if there is free slot for blk_idx + { + blk = createNewBlock(mFreeSpaceList[idx], preferred_block_size, slot_size, blk_idx) ; + } + else if(mFreeSpaceList[mPartitionLevels - 1]) //search free pool + { + blk = createNewBlock(mFreeSpaceList[mPartitionLevels - 1], preferred_block_size, slot_size, blk_idx) ; + } + else //search for other non-preferred but enough space slot. + { + S32 min_idx = 0 ; + if(slot_size > mMinBlockSize) + { + min_idx = getPageLevel(slot_size) ; + } + for(S32 i = (S32)idx - 1 ; i >= min_idx ; i--) //search the small slots first + { + if(mFreeSpaceList[i]) + { + U32 new_preferred_block_size = mFreeSpaceList[i]->getBufferSize(); + new_preferred_block_size = (new_preferred_block_size / mMinBlockSize) * mMinBlockSize ; //round to integer times of mMinBlockSize. + + //create a NEW BLOCK THERE. + if(new_preferred_block_size >= slot_size) //at least there is space for one slot. + { + + blk = createNewBlock(mFreeSpaceList[i], new_preferred_block_size, slot_size, blk_idx) ; + } + break ; + } + } + + if(!blk) + { + for(U16 i = idx + 1 ; i < mPartitionLevels - 1; i++) //search the large slots + { + if(mFreeSpaceList[i]) + { + //create a NEW BLOCK THERE. + blk = createNewBlock(mFreeSpaceList[i], preferred_block_size, slot_size, blk_idx) ; + break ; + } + } + } + } + + return blk ; +} + +//create a new block at the designed location +LLPrivateMemoryPool::LLMemoryBlock* LLPrivateMemoryPool::LLMemoryChunk::createNewBlock(LLMemoryBlock* blk, U32 buffer_size, U32 slot_size, U32 blk_idx) +{ + //unlink from the free space + removeFromFreeSpace(blk) ; + + //check the rest space + U32 new_free_blk_size = blk->getBufferSize() - buffer_size ; + if(new_free_blk_size < mMinBlockSize) //can not partition the memory into size smaller than mMinBlockSize + { + new_free_blk_size = 0 ; //discard the last small extra space. + } + + //add the rest space back to the free list + if(new_free_blk_size > 0) //blk still has free space + { + LLMemoryBlock* next_blk = blk + (buffer_size / mMinBlockSize) ; + next_blk->setBuffer(blk->getBuffer() + buffer_size, new_free_blk_size) ; + addToFreeSpace(next_blk) ; + } + + blk->init(blk->getBuffer(), buffer_size, slot_size) ; + //insert to the available block list... + mAvailBlockList[blk_idx] = blk ; + + //mark the address map: all blocks covered by this block space pointing back to this block. + U32 end = (buffer_size / mMinBlockSize) ; + for(U32 i = 1 ; i < end ; i++) + { + (blk + i)->mSelf = blk ; + } + + return blk ; +} + +//delete a block, release the block to the free pool. +void LLPrivateMemoryPool::LLMemoryChunk::removeBlock(LLMemoryBlock* blk) +{ + //remove from the available block list + if(blk->mPrev) + { + blk->mPrev->mNext = blk->mNext ; + } + if(blk->mNext) + { + blk->mNext->mPrev = blk->mPrev ; + } + U32 blk_idx = getBlockLevel(blk->getSlotSize()); + if(mAvailBlockList[blk_idx] == blk) + { + mAvailBlockList[blk_idx] = blk->mNext ; + } + + blk->mNext = NULL ; + blk->mPrev = NULL ; + + //mark it free + blk->setBuffer(blk->getBuffer(), blk->getBufferSize()) ; + +#if 1 + //merge blk with neighbors if possible + if(blk->getBuffer() > mDataBuffer) //has the left neighbor + { + if((blk - 1)->mSelf->isFree()) + { + LLMemoryBlock* left_blk = (blk - 1)->mSelf ; + removeFromFreeSpace((blk - 1)->mSelf); + left_blk->setBuffer(left_blk->getBuffer(), left_blk->getBufferSize() + blk->getBufferSize()) ; + blk = left_blk ; + } + } + if(blk->getBuffer() + blk->getBufferSize() <= mBuffer + mBufferSize - mMinBlockSize) //has the right neighbor + { + U32 d = blk->getBufferSize() / mMinBlockSize ; + if((blk + d)->isFree()) + { + LLMemoryBlock* right_blk = blk + d ; + removeFromFreeSpace(blk + d) ; + blk->setBuffer(blk->getBuffer(), blk->getBufferSize() + right_blk->getBufferSize()) ; + } + } +#endif + + addToFreeSpace(blk) ; + + return ; +} + +//the top block in the list is full, pop it out of the list +void LLPrivateMemoryPool::LLMemoryChunk::popAvailBlockList(U32 blk_idx) +{ + if(mAvailBlockList[blk_idx]) + { + LLMemoryBlock* next = mAvailBlockList[blk_idx]->mNext ; + if(next) + { + next->mPrev = NULL ; + } + mAvailBlockList[blk_idx]->mPrev = NULL ; + mAvailBlockList[blk_idx]->mNext = NULL ; + mAvailBlockList[blk_idx] = next ; + } +} + +//add the block back to the free pool +void LLPrivateMemoryPool::LLMemoryChunk::addToFreeSpace(LLMemoryBlock* blk) +{ + llassert_always(!blk->mPrev) ; + llassert_always(!blk->mNext) ; + + U16 free_idx = blk->getBufferSize() / mMinBlockSize - 1; + + (blk + free_idx)->mSelf = blk ; //mark the end pointing back to the head. + free_idx = llmin(free_idx, (U16)(mPartitionLevels - 1)) ; + + blk->mNext = mFreeSpaceList[free_idx] ; + if(mFreeSpaceList[free_idx]) + { + mFreeSpaceList[free_idx]->mPrev = blk ; + } + mFreeSpaceList[free_idx] = blk ; + blk->mPrev = NULL ; + blk->mSelf = blk ; + + return ; +} + +//remove the space from the free pool +void LLPrivateMemoryPool::LLMemoryChunk::removeFromFreeSpace(LLMemoryBlock* blk) +{ + U16 free_idx = blk->getBufferSize() / mMinBlockSize - 1; + free_idx = llmin(free_idx, (U16)(mPartitionLevels - 1)) ; + + if(mFreeSpaceList[free_idx] == blk) + { + mFreeSpaceList[free_idx] = blk->mNext ; + } + if(blk->mPrev) + { + blk->mPrev->mNext = blk->mNext ; + } + if(blk->mNext) + { + blk->mNext->mPrev = blk->mPrev ; + } + blk->mNext = NULL ; + blk->mPrev = NULL ; + blk->mSelf = NULL ; + + return ; +} + +void LLPrivateMemoryPool::LLMemoryChunk::addToAvailBlockList(LLMemoryBlock* blk) +{ + llassert_always(!blk->mPrev) ; + llassert_always(!blk->mNext) ; + + U32 blk_idx = getBlockLevel(blk->getSlotSize()); + + blk->mNext = mAvailBlockList[blk_idx] ; + if(blk->mNext) + { + blk->mNext->mPrev = blk ; + } + blk->mPrev = NULL ; + mAvailBlockList[blk_idx] = blk ; + + return ; +} + +U32 LLPrivateMemoryPool::LLMemoryChunk::getPageIndex(U32 addr) +{ + return (addr - (U32)mDataBuffer) / mMinBlockSize ; +} + +//for mAvailBlockList +U32 LLPrivateMemoryPool::LLMemoryChunk::getBlockLevel(U32 size) +{ + llassert(size >= mMinSlotSize && size <= mMaxSlotSize) ; + + //start from 0 + return (size + mMinSlotSize - 1) / mMinSlotSize - 1 ; +} + +//for mFreeSpaceList +U16 LLPrivateMemoryPool::LLMemoryChunk::getPageLevel(U32 size) +{ + //start from 0 + U16 level = size / mMinBlockSize - 1 ; + if(level >= mPartitionLevels) + { + level = mPartitionLevels - 1 ; + } + return level ; +} + +//------------------------------------------------------------------- +//class LLPrivateMemoryPool +//-------------------------------------------------------------------- +const U32 CHUNK_SIZE = 4 << 20 ; //4 MB +const U32 LARGE_CHUNK_SIZE = 4 * CHUNK_SIZE ; //16 MB +LLPrivateMemoryPool::LLPrivateMemoryPool(U32 max_size, bool threaded) : + mMutexp(NULL), + mMaxPoolSize(max_size), + mReservedPoolSize(0), + mHashFactor(1) +{ + if(threaded) + { + mMutexp = new LLMutex(NULL) ; + } + + for(S32 i = 0 ; i < SUPER_ALLOCATION ; i++) + { + mChunkList[i] = NULL ; + } + + mNumOfChunks = 0 ; +} + +LLPrivateMemoryPool::~LLPrivateMemoryPool() +{ + destroyPool(); + delete mMutexp ; +} + +char* LLPrivateMemoryPool::allocate(U32 size) +{ + if(!size) + { + return NULL ; + } + + //if the asked size larger than MAX_BLOCK_SIZE, fetch from heap directly, the pool does not manage it + if(size >= CHUNK_SIZE) + { + return new char[size] ; + } + + char* p = NULL ; + + //find the appropriate chunk + S32 chunk_idx = getChunkIndex(size) ; + + lock() ; + + LLMemoryChunk* chunk = mChunkList[chunk_idx]; + while(chunk) + { + if((p = chunk->allocate(size))) + { + break ; + } + chunk = chunk->mNext ; + } + + //fetch new memory chunk + if(!p) + { + if(mReservedPoolSize + CHUNK_SIZE > mMaxPoolSize) + { + chunk = mChunkList[chunk_idx]; + while(chunk) + { + if((p = chunk->allocate(size))) + { + break ; + } + chunk = chunk->mNext ; + } + } + + chunk = addChunk(chunk_idx) ; + if(chunk) + { + p = chunk->allocate(size) ; + } + } + + unlock() ; + + return p ; +} + +void LLPrivateMemoryPool::free(void* addr) +{ + if(!addr) + { + return ; + } + + lock() ; + + LLMemoryChunk* chunk = findChunk((char*)addr) ; + + if(!chunk) + { + delete[] (char*)addr ; //release from heap + } + else + { + chunk->free(addr) ; + + if(chunk->empty()) + { + removeChunk(chunk) ; + } + } + + unlock() ; +} + +void LLPrivateMemoryPool::dump() +{ +} + +U32 LLPrivateMemoryPool::getTotalAllocatedSize() +{ + U32 total_allocated = 0 ; + + LLMemoryChunk* chunk ; + for(S32 i = 0 ; i < SUPER_ALLOCATION ; i++) + { + chunk = mChunkList[i]; + while(chunk) + { + total_allocated += chunk->getAllocatedSize() ; + chunk = chunk->mNext ; + } + } + + return total_allocated ; +} + +void LLPrivateMemoryPool::lock() +{ + if(mMutexp) + { + mMutexp->lock() ; + } +} + +void LLPrivateMemoryPool::unlock() +{ + if(mMutexp) + { + mMutexp->unlock() ; + } +} + +S32 LLPrivateMemoryPool::getChunkIndex(U32 size) +{ + S32 i ; + for(i = 0 ; size > MAX_SLOT_SIZES[i]; i++); + + llassert_always(i < SUPER_ALLOCATION); + + return i ; +} + +//destroy the entire pool +void LLPrivateMemoryPool::destroyPool() +{ + lock() ; + if(mNumOfChunks > 0) + { + for(U32 i = 0 ; i < mHashFactor; i++) + { + while(mChunkHashList[i]) + { + removeChunk(mChunkHashList[i]) ; + } + } + } + mChunkHashList.clear() ; + mHashFactor = 1 ; + llassert_always(mNumOfChunks == 0) ; + llassert_always(mReservedPoolSize == 0) ; + + for(S32 i = 0 ; i < SUPER_ALLOCATION ; i++) + { + mChunkList[i] = NULL ; + } + + unlock() ; +} + +void LLPrivateMemoryPool::checkSize(U32 asked_size) +{ + if(mReservedPoolSize + asked_size > mMaxPoolSize) + { + llinfos << "Max pool size: " << mMaxPoolSize << llendl ; + llinfos << "Total reserved size: " << mReservedPoolSize + asked_size << llendl ; + llinfos << "Total_allocated Size: " << getTotalAllocatedSize() << llendl ; + + llerrs << "The pool is overflowing..." << llendl ; + } +} + +LLPrivateMemoryPool::LLMemoryChunk* LLPrivateMemoryPool::addChunk(S32 chunk_index) +{ + U32 preferred_size ; + U32 overhead ; + if(chunk_index < LARGE_ALLOCATION) + { + preferred_size = CHUNK_SIZE ; //4MB + overhead = LLMemoryChunk::getMaxOverhead(preferred_size, MIN_SLOT_SIZES[chunk_index], + MAX_SLOT_SIZES[chunk_index], MIN_BLOCK_SIZES[chunk_index], MAX_BLOCK_SIZES[chunk_index]) ; + } + else + { + preferred_size = LARGE_CHUNK_SIZE ; //16MB + overhead = LLMemoryChunk::getMaxOverhead(preferred_size, MIN_SLOT_SIZES[chunk_index], + MAX_SLOT_SIZES[chunk_index], MIN_BLOCK_SIZES[chunk_index], MAX_BLOCK_SIZES[chunk_index]) ; + } + + checkSize(preferred_size + overhead) ; + mReservedPoolSize += preferred_size + overhead ; + + char* buffer = new(std::nothrow) char[preferred_size + overhead] ; + if(!buffer) + { + return NULL ; + } + + LLMemoryChunk* chunk = new (buffer) LLMemoryChunk() ; + chunk->init(buffer, preferred_size + overhead, MIN_SLOT_SIZES[chunk_index], + MAX_SLOT_SIZES[chunk_index], MIN_BLOCK_SIZES[chunk_index], MAX_BLOCK_SIZES[chunk_index]) ; + + //add to the tail of the linked list + { + if(!mChunkList[chunk_index]) + { + mChunkList[chunk_index] = chunk ; + } + else + { + LLMemoryChunk* cur = mChunkList[chunk_index] ; + while(cur->mNext) + { + cur = cur->mNext ; + } + cur->mNext = chunk ; + chunk->mPrev = cur ; + } + } + + //insert into the hash table + addToHashTable(chunk) ; + + mNumOfChunks++; + + return chunk ; +} + +void LLPrivateMemoryPool::removeChunk(LLMemoryChunk* chunk) +{ + if(!chunk) + { + return ; + } + + //remove from the linked list + for(S32 i = 0 ; i < SUPER_ALLOCATION ; i++) + { + if(mChunkList[i] == chunk) + { + mChunkList[i] = chunk->mNext ; + } + } + + if(chunk->mPrev) + { + chunk->mPrev->mNext = chunk->mNext ; + } + if(chunk->mNext) + { + chunk->mNext->mPrev = chunk->mPrev ; + } + + //remove from the hash table + removeFromHashTable(chunk) ; + + mNumOfChunks--; + mReservedPoolSize -= chunk->getBufferSize() ; + + //release memory + delete[] chunk->getBuffer() ; +} + +U16 LLPrivateMemoryPool::findHashKey(const char* addr) +{ + return (((U32)addr) / CHUNK_SIZE) % mHashFactor ; +} + +LLPrivateMemoryPool::LLMemoryChunk* LLPrivateMemoryPool::findChunk(const char* addr) +{ + U16 key = findHashKey(addr) ; + if(mChunkHashList.size() <= key) + { + return NULL ; + } + + //check the hash value "key" + LLMemoryChunk* chunk = mChunkHashList[key] ; + while(chunk && !chunk->containsAddress(addr)) + { + chunk = chunk->mHashNext ; + } + + return chunk ; +} + +void LLPrivateMemoryPool::addToHashTable(LLMemoryChunk* chunk) +{ + static const U16 HASH_FACTORS[] = {41, 83, 193, 317, 419, 523, 0xFFFF}; + + U16 i ; + if(mChunkHashList.empty()) + { + mHashFactor = HASH_FACTORS[0] ; + rehash() ; + } + + U16 start_key = findHashKey(chunk->getBuffer()) ; + U16 end_key = findHashKey(chunk->getBuffer() + chunk->getBufferSize() - 1) ; + bool need_rehash = false ; + + if(mChunkHashList[start_key]) + { + if(mChunkHashList[start_key] == chunk) + { + return; //already inserted. + } + + llassert_always(!chunk->mHashNext) ; + + chunk->mHashNext = mChunkHashList[start_key] ; + mChunkHashList[start_key] = chunk ; + } + else + { + mChunkHashList[start_key] = chunk ; + } + + if(!need_rehash) + { + if(mChunkHashList[end_key]) + { + llassert_always(mChunkHashList[end_key] != chunk) + + need_rehash = mChunkHashList[end_key]->mHashNext != NULL || mChunkHashList[end_key] == chunk->mHashNext; + if(!need_rehash) + { + mChunkHashList[end_key]->mHashNext = chunk ; + } + } + else + { + mChunkHashList[end_key] = chunk ; + } + } + + if(!need_rehash) + { + if(end_key < start_key) + { + need_rehash = fillHashTable(start_key + 1, mHashFactor, chunk) ; + if(!need_rehash) + { + need_rehash = fillHashTable(0, end_key, chunk) ; + } + } + else + { + need_rehash = fillHashTable(start_key + 1, end_key, chunk) ; + } + } + + if(need_rehash) + { + i = 0 ; + while(HASH_FACTORS[i] <= mHashFactor) i++; + + mHashFactor = HASH_FACTORS[i] ; + llassert_always(mHashFactor != 0xFFFF) ;//stop point to prevent endlessly recursive calls + + rehash() ; + } +} + +void LLPrivateMemoryPool::removeFromHashTable(LLMemoryChunk* chunk) +{ + U16 start_key = findHashKey(chunk->getBuffer()) ; + U16 end_key = findHashKey(chunk->getBuffer() + chunk->getBufferSize() - 1) ; + + mChunkHashList[start_key] = chunk->mHashNext ; + chunk->mHashNext = NULL ; + + if(mChunkHashList[end_key] != chunk) + { + mChunkHashList[end_key]->mHashNext = NULL ; + } + else + { + mChunkHashList[end_key] = NULL ; + } + + if(end_key < start_key) + { + for(U16 i = start_key + 1 ; i < mHashFactor; i++) + { + mChunkHashList[i] = NULL ; + } + for(U16 i = 0 ; i < end_key; i++) + { + mChunkHashList[i] = NULL ; + } + } + else + { + for(U16 i = start_key + 1 ; i < end_key; i++) + { + mChunkHashList[i] = NULL ; + } + } +} + +void LLPrivateMemoryPool::rehash() +{ + llinfos << "new hash factor: " << mHashFactor << llendl ; + + mChunkHashList.clear() ; + mChunkHashList.resize(mHashFactor, NULL) ; + + LLMemoryChunk* chunk ; + for(U16 i = 0 ; i < SUPER_ALLOCATION ; i++) + { + chunk = mChunkList[i] ; + while(chunk) + { + chunk->mHashNext = NULL ; + addToHashTable(chunk) ; + chunk = chunk->mNext ; + } + } +} + +bool LLPrivateMemoryPool::fillHashTable(U16 start, U16 end, LLMemoryChunk* chunk) +{ + for(U16 i = start; i < end; i++) + { + if(mChunkHashList[i]) //the slot is occupied. + { + llassert_always(mChunkHashList[i] != chunk) ; + return true ; + } + else + { + mChunkHashList[i] = chunk ; + } + } + + return false ; +} + +//-------------------------------------------------------------------- +//class LLPrivateMemoryPoolManager +//-------------------------------------------------------------------- +LLPrivateMemoryPoolManager* LLPrivateMemoryPoolManager::sInstance = NULL ; + +LLPrivateMemoryPoolManager::LLPrivateMemoryPoolManager() +{ +} + +LLPrivateMemoryPoolManager::~LLPrivateMemoryPoolManager() +{ + //all private pools should be released by their owners before reaching here. + llassert_always(mPoolList.empty()) ; + +#if 0 + if(!mPoolList.empty()) + { + for(std::set<LLPrivateMemoryPool*>::iterator iter = mPoolList.begin(); iter != mPoolList.end(); ++iter) + { + delete *iter; + } + mPoolList.clear() ; + } +#endif +} + +//static +LLPrivateMemoryPoolManager* LLPrivateMemoryPoolManager::getInstance() +{ + if(!sInstance) + { + sInstance = new LLPrivateMemoryPoolManager() ; + } + return sInstance ; +} + +//static +void LLPrivateMemoryPoolManager::destroyClass() +{ + if(sInstance) + { + delete sInstance ; + sInstance = NULL ; + } +} + +LLPrivateMemoryPool* LLPrivateMemoryPoolManager::newPool(U32 max_size, bool threaded) +{ + LLPrivateMemoryPool* pool = new LLPrivateMemoryPool(max_size, threaded) ; + mPoolList.insert(pool) ; + + return pool ; +} + +void LLPrivateMemoryPoolManager::deletePool(LLPrivateMemoryPool* pool) +{ + mPoolList.erase(pool) ; + delete pool; +} + +//debug +void LLPrivateMemoryPoolManager::updateStatistics() +{ + mTotalReservedSize = 0 ; + mTotalAllocatedSize = 0 ; + + for(std::set<LLPrivateMemoryPool*>::iterator iter = mPoolList.begin(); iter != mPoolList.end(); ++iter) + { + mTotalReservedSize += (*iter)->getTotalReservedSize() ; + mTotalAllocatedSize += (*iter)->getTotalAllocatedSize() ; + } +} + +//-------------------------------------------------------------------- +//class LLPrivateMemoryPoolTester +//-------------------------------------------------------------------- +LLPrivateMemoryPoolTester* LLPrivateMemoryPoolTester::sInstance = NULL ; +LLPrivateMemoryPool* LLPrivateMemoryPoolTester::sPool = NULL ; +LLPrivateMemoryPoolTester::LLPrivateMemoryPoolTester() +{ +} + +LLPrivateMemoryPoolTester::~LLPrivateMemoryPoolTester() +{ +} + +//static +LLPrivateMemoryPoolTester* LLPrivateMemoryPoolTester::getInstance() +{ + if(!sInstance) + { + sInstance = ::new LLPrivateMemoryPoolTester() ; + } + return sInstance ; +} + +//static +void LLPrivateMemoryPoolTester::destroy() +{ + if(sInstance) + { + ::delete sInstance ; + sInstance = NULL ; + } + + if(sPool) + { + LLPrivateMemoryPoolManager::getInstance()->deletePool(sPool) ; + sPool = NULL ; + } +} + +void LLPrivateMemoryPoolTester::run(bool threaded) +{ + const U32 max_pool_size = 1024 << 20 ; + + if(sPool) + { + LLPrivateMemoryPoolManager::getInstance()->deletePool(sPool) ; + } + sPool = LLPrivateMemoryPoolManager::getInstance()->newPool(max_pool_size, threaded) ; + + //run the test + correctnessTest() ; + performanceTest() ; + //fragmentationtest() ; + + //release pool. + LLPrivateMemoryPoolManager::getInstance()->deletePool(sPool) ; + sPool = NULL ; +} + +void LLPrivateMemoryPoolTester::test(U32 min_size, U32 max_size, U32 stride, U32 times, + bool random_deletion, bool output_statistics) +{ + U32 levels = (max_size - min_size) / stride + 1 ; + char*** p ; + U32 i, j ; + U32 total_allocated_size = 0 ; + + //allocate space for p ; + if(!(p = ::new char**[times]) || !(*p = ::new char*[times * levels])) + { + llerrs << "memory initialization for p failed" << llendl ; + } + + //init + for(i = 0 ; i < times; i++) + { + p[i] = *p + i * levels ; + for(j = 0 ; j < levels; j++) + { + p[i][j] = NULL ; + } + } + + //allocation + U32 size ; + for(i = 0 ; i < times ; i++) + { + for(j = 0 ; j < levels; j++) + { + size = min_size + j * stride ; + p[i][j] = sPool->allocate(size) ; + + total_allocated_size+= size ; + + *(U32*)p[i][j] = i ; + *((U32*)p[i][j] + 1) = j ; + //p[i][j][size - 1] = '\0' ; //access the last element to verify the success of the allocation. + + //randomly release memory + if(random_deletion) + { + S32 k = rand() % levels ; + + if(p[i][k]) + { + llassert_always(*(U32*)p[i][k] == i && *((U32*)p[i][k] + 1) == k) ; + sPool->free(p[i][k]) ; + total_allocated_size -= min_size + k * stride ; + p[i][k] = NULL ; + } + } + } + } + + //output pool allocation statistics + if(output_statistics) + { + } + + //release all memory allocations + for(i = 0 ; i < times; i++) + { + for(j = 0 ; j < levels; j++) + { + if(p[i][j]) + { + llassert_always(*(U32*)p[i][j] == i && *((U32*)p[i][j] + 1) == j) ; + sPool->free(p[i][j]) ; + total_allocated_size -= min_size + j * stride ; + p[i][j] = NULL ; + } + } + } + + ::delete[] *p ; + ::delete[] p ; +} + +void LLPrivateMemoryPoolTester::testAndTime(U32 size, U32 times) +{ + LLTimer timer ; + + llinfos << " -**********************- " << llendl ; + llinfos << "test size: " << size << " test times: " << times << llendl ; + + timer.reset() ; + char** p = new char*[times] ; + + //using the customized memory pool + //allocation + for(U32 i = 0 ; i < times; i++) + { + p[i] = sPool->allocate(size) ; + if(!p[i]) + { + llerrs << "allocation failed" << llendl ; + } + } + //de-allocation + for(U32 i = 0 ; i < times; i++) + { + sPool->free(p[i]) ; + p[i] = NULL ; + } + llinfos << "time spent using customized memory pool: " << timer.getElapsedTimeF32() << llendl ; + + timer.reset() ; + + //using the standard allocator/de-allocator: + //allocation + for(U32 i = 0 ; i < times; i++) + { + p[i] = ::new char[size] ; + if(!p[i]) + { + llerrs << "allocation failed" << llendl ; + } + } + //de-allocation + for(U32 i = 0 ; i < times; i++) + { + ::delete[] p[i] ; + p[i] = NULL ; + } + llinfos << "time spent using standard allocator/de-allocator: " << timer.getElapsedTimeF32() << llendl ; + + delete[] p; +} + +void LLPrivateMemoryPoolTester::correctnessTest() +{ + //try many different sized allocation, and all kinds of edge cases, access the allocated memory + //to see if allocation is right. + + //edge case + char* p = sPool->allocate(0) ; + sPool->free(p) ; + + //small sized + // [8 bytes, 2KB), each asks for 256 allocations and deallocations + test(8, 2040, 8, 256, true, true) ; + + //medium sized + //[2KB, 512KB), each asks for 16 allocations and deallocations + test(2048, 512 * 1024 - 2048, 2048, 16, true, true) ; + + //large sized + //[512KB, 4MB], each asks for 8 allocations and deallocations + test(512 * 1024, 4 * 1024 * 1024, 64 * 1024, 6, true, true) ; +} + +void LLPrivateMemoryPoolTester::performanceTest() +{ + U32 test_size[3] = {768, 3* 1024, 3* 1024 * 1024}; + + //small sized + testAndTime(test_size[0], 8) ; + + //medium sized + testAndTime(test_size[1], 8) ; + + //large sized + testAndTime(test_size[2], 8) ; +} + +void LLPrivateMemoryPoolTester::fragmentationtest() +{ + //for internal fragmentation statistics: + //every time when asking for a new chunk during correctness test, and performance test, + //print out the chunk usage statistices. +} + +//-------------------------------------------------------------------- diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h index 11406f59b0..4474df6f86 100644 --- a/indra/llcommon/llmemory.h +++ b/indra/llcommon/llmemory.h @@ -27,7 +27,6 @@ #define LLMEMORY_H #include "llmemtype.h" - extern S32 gTotalDAlloc; extern S32 gTotalDAUse; extern S32 gDACount; @@ -45,8 +44,24 @@ public: // Return value is zero if not known. static U64 getCurrentRSS(); static U32 getWorkingSetSize(); + static void* tryToAlloc(void* address, U32 size); + static void initMaxHeapSizeGB(F32 max_heap_size_gb, BOOL prevent_heap_failure); + static void updateMemoryInfo() ; + static void logMemoryInfo(BOOL update = FALSE); + static S32 isMemoryPoolLow(); + + static U32 getAvailableMemKB() ; + static U32 getMaxMemKB() ; + static U32 getAllocatedMemKB() ; private: static char* reserveMem; + static U32 sAvailPhysicalMemInKB ; + static U32 sMaxPhysicalMemInKB ; + static U32 sAllocatedMemInKB; + static U32 sAllocatedPageSizeInKB ; + + static U32 sMaxHeapSizeInKB; + static BOOL sEnableMemoryFailurePrevention; }; //---------------------------------------------------------------------------- @@ -93,6 +108,272 @@ private: //---------------------------------------------------------------------------- + +// +//class LLPrivateMemoryPool defines a private memory pool for an application to use, so the application does not +//need to access the heap directly fro each memory allocation. Throught this, the allocation speed is faster, +//and reduces virtaul address space gragmentation problem. +//Note: this class is thread-safe by passing true to the constructor function. However, you do not need to do this unless +//you are sure the memory allocation and de-allocation will happen in different threads. To make the pool thread safe +//increases allocation and deallocation cost. +// +class LL_COMMON_API LLPrivateMemoryPool +{ + friend class LLPrivateMemoryPoolManager ; + +public: + class LL_COMMON_API LLMemoryBlock //each block is devided into slots uniformly + { + public: + LLMemoryBlock() ; + ~LLMemoryBlock() ; + + void init(char* buffer, U32 buffer_size, U32 slot_size) ; + void setBuffer(char* buffer, U32 buffer_size) ; + + char* allocate() ; + void free(void* addr) ; + + bool empty() {return !mAllocatedSlots;} + bool isFull() {return mAllocatedSlots == mTotalSlots;} + bool isFree() {return !mTotalSlots;} + + U32 getSlotSize()const {return mSlotSize;} + U32 getTotalSlots()const {return mTotalSlots;} + U32 getBufferSize()const {return mBufferSize;} + char* getBuffer() const {return mBuffer;} + + //debug use + void resetBitMap() ; + private: + char* mBuffer; + U32 mSlotSize ; //when the block is not initialized, it is the buffer size. + U32 mBufferSize ; + U32 mUsageBits ; + U8 mTotalSlots ; + U8 mAllocatedSlots ; + U8 mDummySize ; //size of extra U32 reserved for mUsageBits. + + public: + LLMemoryBlock* mPrev ; + LLMemoryBlock* mNext ; + LLMemoryBlock* mSelf ; + + struct CompareAddress + { + bool operator()(const LLMemoryBlock* const& lhs, const LLMemoryBlock* const& rhs) + { + return (U32)lhs->getBuffer() < (U32)rhs->getBuffer(); + } + }; + }; + + class LL_COMMON_API LLMemoryChunk //is divided into memory blocks. + { + public: + LLMemoryChunk() ; + ~LLMemoryChunk() ; + + void init(char* buffer, U32 buffer_size, U32 min_slot_size, U32 max_slot_size, U32 min_block_size, U32 max_block_size) ; + void setBuffer(char* buffer, U32 buffer_size) ; + + bool empty() ; + + char* allocate(U32 size) ; + void free(void* addr) ; + + const char* getBuffer() const {return mBuffer;} + U32 getBufferSize() const {return mBufferSize;} + U32 getAllocatedSize() const {return mAlloatedSize;} + + bool containsAddress(const char* addr) const; + + static U32 getMaxOverhead(U32 data_buffer_size, U32 min_slot_size, + U32 max_slot_size, U32 min_block_size, U32 max_block_size) ; + + void dump() ; + + private: + U32 getPageIndex(U32 addr) ; + U32 getBlockLevel(U32 size) ; + U16 getPageLevel(U32 size) ; + LLMemoryBlock* addBlock(U32 blk_idx) ; + void popAvailBlockList(U32 blk_idx) ; + void addToFreeSpace(LLMemoryBlock* blk) ; + void removeFromFreeSpace(LLMemoryBlock* blk) ; + void removeBlock(LLMemoryBlock* blk) ; + void addToAvailBlockList(LLMemoryBlock* blk) ; + U32 calcBlockSize(U32 slot_size); + LLMemoryBlock* createNewBlock(LLMemoryBlock* blk, U32 buffer_size, U32 slot_size, U32 blk_idx) ; + + private: + LLMemoryBlock** mAvailBlockList ;//256 by mMinSlotSize + LLMemoryBlock** mFreeSpaceList; + LLMemoryBlock* mBlocks ; //index of blocks by address. + + char* mBuffer ; + U32 mBufferSize ; + char* mDataBuffer ; + char* mMetaBuffer ; + U32 mMinBlockSize ; + U32 mMinSlotSize ; + U32 mMaxSlotSize ; + U32 mAlloatedSize ; + U16 mBlockLevels; + U16 mPartitionLevels; + + public: + //form a linked list + LLMemoryChunk* mNext ; + LLMemoryChunk* mPrev ; + + LLMemoryChunk* mHashNext ; + } ; + +private: + LLPrivateMemoryPool(U32 max_size, bool threaded) ; + ~LLPrivateMemoryPool() ; + +public: + char *allocate(U32 size) ; + void free(void* addr) ; + + void dump() ; + U32 getTotalAllocatedSize() ; + U32 getTotalReservedSize() {return mReservedPoolSize;} + +private: + void lock() ; + void unlock() ; + S32 getChunkIndex(U32 size) ; + LLMemoryChunk* addChunk(S32 chunk_index) ; + void checkSize(U32 asked_size) ; + void removeChunk(LLMemoryChunk* chunk) ; + U16 findHashKey(const char* addr); + void addToHashTable(LLMemoryChunk* chunk) ; + void removeFromHashTable(LLMemoryChunk* chunk) ; + void rehash() ; + bool fillHashTable(U16 start, U16 end, LLMemoryChunk* chunk) ; + LLMemoryChunk* findChunk(const char* addr) ; + + void destroyPool() ; + +public: + enum + { + SMALL_ALLOCATION = 0, //from 8 bytes to 2KB(exclusive), page size 2KB, max chunk size is 4MB. + MEDIUM_ALLOCATION, //from 2KB to 512KB(exclusive), page size 32KB, max chunk size 4MB + LARGE_ALLOCATION, //from 512KB to 4MB(inclusive), page size 64KB, max chunk size 16MB + SUPER_ALLOCATION //allocation larger than 4MB. + }; + +private: + LLMutex* mMutexp ; + U32 mMaxPoolSize; + U32 mReservedPoolSize ; + + LLMemoryChunk* mChunkList[SUPER_ALLOCATION] ; //all memory chunks reserved by this pool, sorted by address + std::vector<LLMemoryChunk*> mChunkHashList ; + U16 mNumOfChunks ; + U16 mHashFactor ; +}; + +class LL_COMMON_API LLPrivateMemoryPoolManager +{ +private: + LLPrivateMemoryPoolManager() ; + ~LLPrivateMemoryPoolManager() ; + +public: + static LLPrivateMemoryPoolManager* getInstance() ; + static void destroyClass() ; + + LLPrivateMemoryPool* newPool(U32 max_size, bool threaded) ; + void deletePool(LLPrivateMemoryPool* pool) ; + +private: + static LLPrivateMemoryPoolManager* sInstance ; + std::set<LLPrivateMemoryPool*> mPoolList ; + +public: + //debug and statistics info. + void updateStatistics() ; + + U32 mTotalReservedSize ; + U32 mTotalAllocatedSize ; +}; + +// +//the below singleton is used to test the private memory pool. +// +class LL_COMMON_API LLPrivateMemoryPoolTester +{ +private: + LLPrivateMemoryPoolTester() ; + ~LLPrivateMemoryPoolTester() ; + +public: + static LLPrivateMemoryPoolTester* getInstance() ; + static void destroy() ; + + void run(bool threaded) ; + +private: + void correctnessTest() ; + void performanceTest() ; + void fragmentationtest() ; + + void test(U32 min_size, U32 max_size, U32 stride, U32 times, bool random_deletion, bool output_statistics) ; + void testAndTime(U32 size, U32 times) ; + +public: + void* operator new(size_t size) + { + return (void*)sPool->allocate(size) ; + } + void operator delete(void* addr) + { + sPool->free(addr) ; + } + void* operator new[](size_t size) + { + return (void*)sPool->allocate(size) ; + } + void operator delete[](void* addr) + { + sPool->free(addr) ; + } + +private: + static LLPrivateMemoryPoolTester* sInstance; + static LLPrivateMemoryPool* sPool ; + static LLPrivateMemoryPool* sThreadedPool ; +}; +#if 0 +//static +void* LLPrivateMemoryPoolTester::operator new(size_t size) +{ + return (void*)sPool->allocate(size) ; +} + +//static +void LLPrivateMemoryPoolTester::operator delete(void* addr) +{ + sPool->free(addr) ; +} + +//static +void* LLPrivateMemoryPoolTester::operator new[](size_t size) +{ + return (void*)sPool->allocate(size) ; +} + +//static +void LLPrivateMemoryPoolTester::operator delete[](void* addr) +{ + sPool->free(addr) ; +} +#endif // LLRefCount moved to llrefcount.h // LLPointer moved to llpointer.h diff --git a/indra/llcommon/llmetricperformancetester.h b/indra/llcommon/llmetricperformancetester.h index 925010ac96..1372f48dcf 100644 --- a/indra/llcommon/llmetricperformancetester.h +++ b/indra/llcommon/llmetricperformancetester.h @@ -27,7 +27,7 @@ #ifndef LL_METRICPERFORMANCETESTER_H #define LL_METRICPERFORMANCETESTER_H -const std::string DEFAULT_METRIC_NAME("metric"); +char const* const DEFAULT_METRIC_NAME = "metric"; /** * @class LLMetricPerformanceTesterBasic diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp index 10cdc7087b..7968e53c13 100644 --- a/indra/llcommon/llsys.cpp +++ b/indra/llcommon/llsys.cpp @@ -636,22 +636,20 @@ U32 LLMemoryInfo::getPhysicalMemoryClamped() const } //static -void LLMemoryInfo::getAvailableMemoryKB(U32& avail_physical_mem_kb, U32& avail_virtual_mem_kb) +U32 LLMemoryInfo::getAvailableMemoryKB() { #if LL_WINDOWS MEMORYSTATUSEX state; state.dwLength = sizeof(state); GlobalMemoryStatusEx(&state); - avail_physical_mem_kb = (U32)(state.ullAvailPhys/1024) ; - avail_virtual_mem_kb = (U32)(state.ullAvailVirtual/1024) ; + return (U32)(state.ullAvailPhys/1024) ; #else //do not know how to collect available memory info for other systems. //leave it blank here for now. - avail_physical_mem_kb = -1 ; - avail_virtual_mem_kb = -1 ; + return -1; #endif } diff --git a/indra/llcommon/llsys.h b/indra/llcommon/llsys.h index 41a4f25000..580eee4e8d 100644 --- a/indra/llcommon/llsys.h +++ b/indra/llcommon/llsys.h @@ -116,7 +116,7 @@ public: U32 getPhysicalMemoryClamped() const; ///< Memory size in clamped bytes //get the available memory infomation in KiloBytes. - static void getAvailableMemoryKB(U32& avail_physical_mem_kb, U32& avail_virtual_mem_kb); + static U32 getAvailableMemoryKB(); }; diff --git a/indra/llcommon/llversionviewer.h b/indra/llcommon/llversionviewer.h index 7d5afe92dc..7703132d90 100644 --- a/indra/llcommon/llversionviewer.h +++ b/indra/llcommon/llversionviewer.h @@ -28,7 +28,7 @@ #define LL_LLVERSIONVIEWER_H const S32 LL_VERSION_MAJOR = 2; -const S32 LL_VERSION_MINOR = 6; +const S32 LL_VERSION_MINOR = 7; const S32 LL_VERSION_PATCH = 0; const S32 LL_VERSION_BUILD = 0; diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp index f4399d4ed4..706231307d 100644 --- a/indra/llimage/llimage.cpp +++ b/indra/llimage/llimage.cpp @@ -39,6 +39,7 @@ #include "llimagepng.h" #include "llimagedxt.h" #include "llimageworker.h" +#include "llmemory.h" //--------------------------------------------------------------------------- // LLImage @@ -47,11 +48,14 @@ //static std::string LLImage::sLastErrorMessage; LLMutex* LLImage::sMutex = NULL; +LLPrivateMemoryPool* LLImageBase::sPrivatePoolp = NULL ; //static void LLImage::initClass() { sMutex = new LLMutex; + + LLImageBase::createPrivatePool() ; } //static @@ -59,6 +63,8 @@ void LLImage::cleanupClass() { delete sMutex; sMutex = NULL; + + LLImageBase::destroyPrivatePool() ; } //static @@ -97,6 +103,53 @@ LLImageBase::~LLImageBase() deleteData(); // virtual } +//static +void LLImageBase::createPrivatePool() +{ + const U32 MAX_POOL_SIZE = 512 * 1024 * 1024 ; //512 MB + + if(!sPrivatePoolp) + { + sPrivatePoolp = LLPrivateMemoryPoolManager::getInstance()->newPool(MAX_POOL_SIZE, true) ; + } +} + +//static +void LLImageBase::destroyPrivatePool() +{ + if(sPrivatePoolp) + { + LLPrivateMemoryPoolManager::getInstance()->deletePool(sPrivatePoolp) ; + sPrivatePoolp = NULL ; + } +} + +//static +char* LLImageBase::allocateMemory(S32 size) +{ + if(sPrivatePoolp) + { + return sPrivatePoolp->allocate(size) ; + } + else + { + return new char[size]; + } +} + +//static +void LLImageBase::deleteMemory(void* p) +{ + if(sPrivatePoolp) + { + sPrivatePoolp->free(p) ; + } + else + { + delete[] (char*)p ; + } +} + // virtual void LLImageBase::dump() { @@ -130,7 +183,7 @@ void LLImageBase::sanityCheck() // virtual void LLImageBase::deleteData() { - delete[] mData; + deleteMemory(mData) ; mData = NULL; mDataSize = 0; } @@ -167,7 +220,7 @@ U8* LLImageBase::allocateData(S32 size) { deleteData(); // virtual mBadBufferAllocation = false ; - mData = new U8[size]; + mData = (U8*)allocateMemory(size); if (!mData) { llwarns << "allocate image data: " << size << llendl; @@ -185,7 +238,7 @@ U8* LLImageBase::allocateData(S32 size) U8* LLImageBase::reallocateData(S32 size) { LLMemType mt1(mMemType); - U8 *new_datap = new U8[size]; + U8 *new_datap = (U8*)allocateMemory(size); if (!new_datap) { llwarns << "Out of memory in LLImageBase::reallocateData" << llendl; @@ -195,7 +248,7 @@ U8* LLImageBase::reallocateData(S32 size) { S32 bytes = llmin(mDataSize, size); memcpy(new_datap, mData, bytes); /* Flawfinder: ignore */ - delete[] mData; + deleteMemory(mData) ; } mData = new_datap; mDataSize = size; @@ -341,6 +394,7 @@ BOOL LLImageRaw::resize(U16 width, U16 height, S8 components) return TRUE; } +#if 0 U8 * LLImageRaw::getSubImage(U32 x_pos, U32 y_pos, U32 width, U32 height) const { LLMemType mt1(mMemType); @@ -361,6 +415,7 @@ U8 * LLImageRaw::getSubImage(U32 x_pos, U32 y_pos, U32 width, U32 height) const } return data; } +#endif BOOL LLImageRaw::setSubImage(U32 x_pos, U32 y_pos, U32 width, U32 height, const U8 *data, U32 stride, BOOL reverse_y) @@ -830,6 +885,7 @@ void LLImageRaw::copyScaled( LLImageRaw* src ) } } +#if 0 //scale down image by not blending a pixel with its neighbors. BOOL LLImageRaw::scaleDownWithoutBlending( S32 new_width, S32 new_height) { @@ -853,7 +909,7 @@ BOOL LLImageRaw::scaleDownWithoutBlending( S32 new_width, S32 new_height) ratio_x -= 1.0f ; ratio_y -= 1.0f ; - U8* new_data = new U8[new_data_size] ; + U8* new_data = allocateMemory(new_data_size) ; llassert_always(new_data != NULL) ; U8* old_data = getData() ; @@ -875,6 +931,7 @@ BOOL LLImageRaw::scaleDownWithoutBlending( S32 new_width, S32 new_height) return TRUE ; } +#endif BOOL LLImageRaw::scale( S32 new_width, S32 new_height, BOOL scale_image_data ) { @@ -1527,6 +1584,7 @@ void LLImageFormatted::setData(U8 *data, S32 size) { deleteData(); setDataAndSize(data, size); // Access private LLImageBase members + sGlobalFormattedMemory += getDataSize(); } } @@ -1545,7 +1603,7 @@ void LLImageFormatted::appendData(U8 *data, S32 size) S32 newsize = cursize + size; reallocateData(newsize); memcpy(getData() + cursize, data, size); - delete[] data; + deleteMemory(data); } } } diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h index 825b9aab1a..ab20ccda9e 100644 --- a/indra/llimage/llimage.h +++ b/indra/llimage/llimage.h @@ -29,7 +29,6 @@ #include "lluuid.h" #include "llstring.h" -//#include "llmemory.h" #include "llthread.h" #include "llmemtype.h" @@ -56,6 +55,7 @@ const S32 MAX_IMG_PACKET_SIZE = 1000; class LLImageFormatted; class LLImageRaw; class LLColor4U; +class LLPrivateMemoryPool; typedef enum e_image_codec { @@ -127,7 +127,7 @@ public: protected: // special accessor to allow direct setting of mData and mDataSize by LLImageFormatted - void setDataAndSize(U8 *data, S32 size) { mData = data; mDataSize = size; } + void setDataAndSize(U8 *data, S32 size) { mData = data; mDataSize = size; } public: static void generateMip(const U8 *indata, U8* mipdata, int width, int height, S32 nchannels); @@ -138,6 +138,11 @@ public: static EImageCodec getCodecFromExtension(const std::string& exten); + static void createPrivatePool() ; + static void destroyPrivatePool() ; + static char* allocateMemory(S32 size) ; + static void deleteMemory(void* p) ; + private: U8 *mData; S32 mDataSize; @@ -149,6 +154,8 @@ private: bool mBadBufferAllocation ; bool mAllowOverSize ; + + static LLPrivateMemoryPool* sPrivatePoolp ; public: LLMemType::DeclareMemType& mMemType; // debug }; @@ -172,7 +179,7 @@ public: BOOL resize(U16 width, U16 height, S8 components); - U8 * getSubImage(U32 x_pos, U32 y_pos, U32 width, U32 height) const; + //U8 * getSubImage(U32 x_pos, U32 y_pos, U32 width, U32 height) const; BOOL setSubImage(U32 x_pos, U32 y_pos, U32 width, U32 height, const U8 *data, U32 stride = 0, BOOL reverse_y = FALSE); @@ -184,7 +191,7 @@ public: void contractToPowerOfTwo(S32 max_dim = MAX_IMAGE_SIZE, BOOL scale_image = TRUE); void biasedScaleToPowerOfTwo(S32 max_dim = MAX_IMAGE_SIZE); BOOL scale( S32 new_width, S32 new_height, BOOL scale_image = TRUE ); - BOOL scaleDownWithoutBlending( S32 new_width, S32 new_height) ; + //BOOL scaleDownWithoutBlending( S32 new_width, S32 new_height) ; // Fill the buffer with a constant color void fill( const LLColor4U& color ); diff --git a/indra/llimage/llimagedxt.cpp b/indra/llimage/llimagedxt.cpp index 4bd3efddaa..81be09a412 100644 --- a/indra/llimage/llimagedxt.cpp +++ b/indra/llimage/llimagedxt.cpp @@ -429,7 +429,7 @@ bool LLImageDXT::convertToDXR() S32 nmips = calcNumMips(width,height); S32 total_bytes = getDataSize(); U8* olddata = getData(); - U8* newdata = new U8[total_bytes]; + U8* newdata = (U8*)allocateMemory(total_bytes); if (!newdata) { llerrs << "Out of memory in LLImageDXT::convertToDXR()" << llendl; diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp index 5f488a6764..1bdcba6eb5 100644 --- a/indra/llimage/llimagej2c.cpp +++ b/indra/llimage/llimagej2c.cpp @@ -372,14 +372,14 @@ BOOL LLImageJ2C::loadAndValidate(const std::string &filename) } else { - U8 *data = new U8[file_size]; + U8 *data = (U8*)allocateMemory(file_size); apr_size_t bytes_read = file_size; apr_status_t s = apr_file_read(apr_file, data, &bytes_read); // modifies bytes_read infile.close() ; if (s != APR_SUCCESS || (S32)bytes_read != file_size) { - delete[] data; + deleteMemory(data); setLastError("Unable to read entire file"); res = FALSE; } diff --git a/indra/llmath/llcamera.cpp b/indra/llmath/llcamera.cpp index bad4d00fd6..687c1a7d45 100644 --- a/indra/llmath/llcamera.cpp +++ b/indra/llmath/llcamera.cpp @@ -703,6 +703,7 @@ void LLCamera::calculateFrustumPlanes(F32 left, F32 right, F32 top, F32 bottom) mLocalPlanes[PLANE_BOTTOM].setVec( a, c, b); //calculate center and radius squared of frustum in world absolute coordinates + static LLVector3 const X_AXIS(1.f, 0.f, 0.f); mFrustCenter = X_AXIS*mFarPlane*0.5f; mFrustCenter = transformToAbsolute(mFrustCenter); mFrustRadiusSquared = mFarPlane*0.5f; diff --git a/indra/llmath/llcamera.h b/indra/llmath/llcamera.h index 922d6f9fac..531144db39 100644 --- a/indra/llmath/llcamera.h +++ b/indra/llmath/llcamera.h @@ -50,15 +50,6 @@ const F32 MIN_FAR_PLANE = 0.2f; static const F32 MIN_FIELD_OF_VIEW = 5.0f * DEG_TO_RAD; static const F32 MAX_FIELD_OF_VIEW = 175.f * DEG_TO_RAD; -static const LLVector3 X_AXIS(1.f,0.f,0.f); -static const LLVector3 Y_AXIS(0.f,1.f,0.f); -static const LLVector3 Z_AXIS(0.f,0.f,1.f); - -static const LLVector3 NEG_X_AXIS(-1.f,0.f,0.f); -static const LLVector3 NEG_Y_AXIS(0.f,-1.f,0.f); -static const LLVector3 NEG_Z_AXIS(0.f,0.f,-1.f); - - // An LLCamera is an LLCoorFrame with a view frustum. // This means that it has several methods for moving it around // that are inherited from the LLCoordFrame() class : diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp index 595c470a19..26a20cede8 100644 --- a/indra/llplugin/llpluginclassmedia.cpp +++ b/indra/llplugin/llpluginclassmedia.cpp @@ -64,9 +64,10 @@ LLPluginClassMedia::~LLPluginClassMedia() reset(); } -bool LLPluginClassMedia::init(const std::string &launcher_filename, const std::string &plugin_filename, bool debug) +bool LLPluginClassMedia::init(const std::string &launcher_filename, const std::string &plugin_dir, const std::string &plugin_filename, bool debug) { LL_DEBUGS("Plugin") << "launcher: " << launcher_filename << LL_ENDL; + LL_DEBUGS("Plugin") << "dir: " << plugin_dir << LL_ENDL; LL_DEBUGS("Plugin") << "plugin: " << plugin_filename << LL_ENDL; mPlugin = new LLPluginProcessParent(this); @@ -77,7 +78,7 @@ bool LLPluginClassMedia::init(const std::string &launcher_filename, const std::s message.setValue("target", mTarget); sendMessage(message); - mPlugin->init(launcher_filename, plugin_filename, debug); + mPlugin->init(launcher_filename, plugin_dir, plugin_filename, debug); return true; } diff --git a/indra/llplugin/llpluginclassmedia.h b/indra/llplugin/llpluginclassmedia.h index c826e13c40..618e928a08 100644 --- a/indra/llplugin/llpluginclassmedia.h +++ b/indra/llplugin/llpluginclassmedia.h @@ -45,6 +45,7 @@ public: // local initialization, called by the media manager when creating a source virtual bool init(const std::string &launcher_filename, + const std::string &plugin_dir, const std::string &plugin_filename, bool debug); diff --git a/indra/llplugin/llplugininstance.cpp b/indra/llplugin/llplugininstance.cpp index 9c9909a017..e8efb233ff 100644 --- a/indra/llplugin/llplugininstance.cpp +++ b/indra/llplugin/llplugininstance.cpp @@ -31,6 +31,10 @@ #include "llplugininstance.h" #include "llthread.h" // Needed for LLThread::tldata().mRootPool +#if LL_WINDOWS +#include "direct.h" // needed for _chdir() +#endif + /** Virtual destructor. */ LLPluginInstanceMessageListener::~LLPluginInstanceMessageListener() { @@ -73,10 +77,24 @@ LLPluginInstance::~LLPluginInstance() * @param[in] plugin_file Name of plugin dll/dylib/so. TODO:DOC is this correct? see .h * @return 0 if successful, APR error code or error code from the plugin's init function on failure. */ -int LLPluginInstance::load(std::string &plugin_file) +int LLPluginInstance::load(const std::string& plugin_dir, std::string &plugin_file) { pluginInitFunction init_function = NULL; + if ( plugin_dir.length() ) + { +#if LL_WINDOWS + // VWR-21275: + // *SOME* Windows systems fail to load the Qt plugins if the current working + // directory is not the same as the directory with the Qt DLLs in. + // This should not cause any run time issues since we are changing the cwd for the + // plugin shell process and not the viewer. + // Changing back to the previous directory is not necessary since the plugin shell + // quits once the plugin exits. + _chdir( plugin_dir.c_str() ); +#endif + }; + int result = apr_dso_load(&mDSOHandle, plugin_file.c_str(), mDSOHandlePool()); diff --git a/indra/llplugin/llplugininstance.h b/indra/llplugin/llplugininstance.h index 1c3898e2e7..3c1cd12546 100644 --- a/indra/llplugin/llplugininstance.h +++ b/indra/llplugin/llplugininstance.h @@ -57,7 +57,7 @@ public: // Load a plugin dll/dylib/so // Returns 0 if successful, APR error code or error code returned from the plugin's init function on failure. - int load(std::string &plugin_file); + int load(const std::string& plugin_dir, std::string &plugin_file); // Sends a message to the plugin. void sendMessage(const std::string &message); diff --git a/indra/llplugin/llpluginprocesschild.cpp b/indra/llplugin/llpluginprocesschild.cpp index 2fa5dcdd01..a7cdf14f0d 100644 --- a/indra/llplugin/llpluginprocesschild.cpp +++ b/indra/llplugin/llpluginprocesschild.cpp @@ -139,7 +139,7 @@ void LLPluginProcessChild::idle(void) if(!mPluginFile.empty()) { mInstance = new LLPluginInstance(this); - if(mInstance->load(mPluginFile) == 0) + if(mInstance->load(mPluginDir, mPluginFile) == 0) { mHeartbeat.start(); mHeartbeat.setTimerExpirySec(HEARTBEAT_SECONDS); @@ -348,6 +348,7 @@ void LLPluginProcessChild::receiveMessageRaw(const std::string &message) if(message_name == "load_plugin") { mPluginFile = parsed.getValue("file"); + mPluginDir = parsed.getValue("dir"); } else if(message_name == "shm_add") { diff --git a/indra/llplugin/llpluginprocesschild.h b/indra/llplugin/llpluginprocesschild.h index 22ff403ad6..a9d6794e40 100644 --- a/indra/llplugin/llpluginprocesschild.h +++ b/indra/llplugin/llpluginprocesschild.h @@ -92,6 +92,7 @@ private: LLSocket::ptr_t mSocket; std::string mPluginFile; + std::string mPluginDir; LLPluginInstance *mInstance; diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp index eaf7ec4bf3..8b7e8635cf 100644 --- a/indra/llplugin/llpluginprocessparent.cpp +++ b/indra/llplugin/llpluginprocessparent.cpp @@ -159,10 +159,11 @@ void LLPluginProcessParent::errorState(void) setState(STATE_ERROR); } -void LLPluginProcessParent::init(const std::string &launcher_filename, const std::string &plugin_filename, bool debug) +void LLPluginProcessParent::init(const std::string &launcher_filename, const std::string &plugin_dir, const std::string &plugin_filename, bool debug) { mProcess.setExecutable(launcher_filename); mPluginFile = plugin_filename; + mPluginDir = plugin_dir; mCPUUsage = 0.0f; mDebug = debug; setState(STATE_INITIALIZED); @@ -431,6 +432,7 @@ void LLPluginProcessParent::idle(void) { LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "load_plugin"); message.setValue("file", mPluginFile); + message.setValue("dir", mPluginDir); sendMessage(message); } diff --git a/indra/llplugin/llpluginprocessparent.h b/indra/llplugin/llpluginprocessparent.h index 6beeb64c7e..29995647d5 100644 --- a/indra/llplugin/llpluginprocessparent.h +++ b/indra/llplugin/llpluginprocessparent.h @@ -57,6 +57,7 @@ public: ~LLPluginProcessParent(); void init(const std::string &launcher_filename, + const std::string &plugin_dir, const std::string &plugin_filename, bool debug); @@ -151,6 +152,7 @@ private: LLProcessLauncher mProcess; std::string mPluginFile; + std::string mPluginDir; LLPluginProcessParentOwner *mOwner; diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 02160b09c4..03befe6818 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -33,6 +33,7 @@ #include "llglheaders.h" #include "llmemtype.h" #include "llrender.h" +#include "llmemory.h" //============================================================================ @@ -47,6 +48,7 @@ U32 LLVertexBuffer::sSetCount = 0; S32 LLVertexBuffer::sCount = 0; S32 LLVertexBuffer::sGLCount = 0; S32 LLVertexBuffer::sMappedCount = 0; +BOOL LLVertexBuffer::sDisableVBOMapping = FALSE ; BOOL LLVertexBuffer::sEnableVBOs = TRUE; U32 LLVertexBuffer::sGLRenderBuffer = 0; U32 LLVertexBuffer::sGLRenderIndices = 0; @@ -212,6 +214,11 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi { llassert(mRequestedNumVerts >= 0); + if(mDirty) + { + postUpdate() ; + } + if (start >= (U32) mRequestedNumVerts || end >= (U32) mRequestedNumVerts) { @@ -251,6 +258,12 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const { llassert(mRequestedNumIndices >= 0); + + if(mDirty) + { + postUpdate() ; + } + if (indices_offset >= (U32) mRequestedNumIndices || indices_offset + count > (U32) mRequestedNumIndices) { @@ -282,6 +295,12 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const { llassert(mRequestedNumVerts >= 0); + + if(mDirty) + { + postUpdate() ; + } + if (first >= (U32) mRequestedNumVerts || first + count > (U32) mRequestedNumVerts) { @@ -305,9 +324,10 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const } //static -void LLVertexBuffer::initClass(bool use_vbo) +void LLVertexBuffer::initClass(bool use_vbo, bool no_vbo_mapping) { sEnableVBOs = use_vbo; + sDisableVBOMapping = no_vbo_mapping ; LLGLNamePool::registerPool(&sDynamicVBOPool); LLGLNamePool::registerPool(&sDynamicIBOPool); LLGLNamePool::registerPool(&sStreamVBOPool); @@ -369,7 +389,8 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) : mFilthy(FALSE), mEmpty(TRUE), mResized(FALSE), - mDynamicSize(FALSE) + mDynamicSize(FALSE), + mDirty(FALSE) { LLMemType mt2(LLMemType::MTYPE_VERTEX_CONSTRUCTOR); if (!sEnableVBOs) @@ -567,6 +588,8 @@ void LLVertexBuffer::destroyGLBuffer() { if (useVBOs()) { + freeClientBuffer() ; + if (mMappedData || mMappedIndexData) { llerrs << "Vertex buffer destroyed while mapped!" << llendl; @@ -594,11 +617,13 @@ void LLVertexBuffer::destroyGLIndices() { if (useVBOs()) { + freeClientBuffer() ; + if (mMappedData || mMappedIndexData) { llerrs << "Vertex buffer destroyed while mapped." << llendl; } - releaseIndices(); + releaseIndices(); } else { @@ -799,6 +824,7 @@ void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices) if (mResized && useVBOs()) { + freeClientBuffer() ; setBuffer(0); } } @@ -822,6 +848,60 @@ BOOL LLVertexBuffer::useVBOs() const } //---------------------------------------------------------------------------- +void LLVertexBuffer::freeClientBuffer() +{ + if(useVBOs() && sDisableVBOMapping && (mMappedData || mMappedIndexData)) + { + delete[] mMappedData ; + delete[] mMappedIndexData ; + mMappedData = NULL ; + mMappedIndexData = NULL ; + } +} + +void LLVertexBuffer::preUpdate() +{ + if(!useVBOs() || !sDisableVBOMapping) + { + return ; + } + + if(!mMappedData) + { + U32 size = getSize() ; + mMappedData = new U8[size]; + memset(mMappedData, 0, size); + } + + if(!mMappedIndexData) + { + U32 size = getIndicesSize(); + mMappedIndexData = new U8[size]; + memset(mMappedIndexData, 0, size); + } + + mDirty = TRUE ; +} + +void LLVertexBuffer::postUpdate() const +{ + if(!useVBOs() || !sDisableVBOMapping) + { + return ; + } + + llassert_always(mMappedData && mMappedIndexData) ; + + //release the existing buffers + glBufferDataARB(GL_ARRAY_BUFFER_ARB, 0, NULL, mUsage); + glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, NULL, mUsage); + + //update to the new buffers + glBufferDataARB(GL_ARRAY_BUFFER_ARB, getSize(), mMappedData, mUsage); + glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, getIndicesSize(), mMappedIndexData, mUsage); + + mDirty = FALSE ; +} // Map for data access U8* LLVertexBuffer::mapBuffer(S32 access) @@ -836,6 +916,12 @@ U8* LLVertexBuffer::mapBuffer(S32 access) llerrs << "LLVertexBuffer::mapBuffer() called on unallocated buffer." << llendl; } + if(useVBOs() && sDisableVBOMapping) + { + preUpdate() ; + return mMappedData ; + } + if (!mLocked && useVBOs()) { { @@ -857,11 +943,8 @@ U8* LLVertexBuffer::mapBuffer(S32 access) log_glerror(); //check the availability of memory - U32 avail_phy_mem, avail_vir_mem; - LLMemoryInfo::getAvailableMemoryKB(avail_phy_mem, avail_vir_mem) ; - llinfos << "Available physical mwmory(KB): " << avail_phy_mem << llendl ; - llinfos << "Available virtual memory(KB): " << avail_vir_mem << llendl; - + LLMemory::logMemoryInfo(TRUE) ; + //-------------------- //print out more debug info before crash llinfos << "vertex buffer size: (num verts : num indices) = " << getNumVerts() << " : " << getNumIndices() << llendl ; @@ -884,6 +967,7 @@ U8* LLVertexBuffer::mapBuffer(S32 access) if (!mMappedIndexData) { log_glerror(); + LLMemory::logMemoryInfo(TRUE) ; GLint buff; glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff); @@ -906,7 +990,11 @@ void LLVertexBuffer::unmapBuffer() LLMemType mt2(LLMemType::MTYPE_VERTEX_UNMAP_BUFFER); if (mMappedData || mMappedIndexData) { - if (useVBOs() && mLocked) + if(sDisableVBOMapping && useVBOs()) + { + return ; + } + else if (useVBOs() && mLocked) { stop_glerror(); glUnmapBufferARB(GL_ARRAY_BUFFER_ARB); @@ -1152,13 +1240,13 @@ void LLVertexBuffer::setBuffer(U32 data_mask) } } - if (mGLBuffer) + if (mGLBuffer && !sDisableVBOMapping) { stop_glerror(); glBufferDataARB(GL_ARRAY_BUFFER_ARB, getSize(), NULL, mUsage); stop_glerror(); } - if (mGLIndices) + if (mGLIndices && !sDisableVBOMapping) { stop_glerror(); glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, getIndicesSize(), NULL, mUsage); diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index 94fa790957..18d50c87bb 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -80,7 +80,7 @@ public: static BOOL sUseStreamDraw; - static void initClass(bool use_vbo); + static void initClass(bool use_vbo, bool no_vbo_mapping); static void cleanupClass(); static void setupClientArrays(U32 data_mask); static void clientCopy(F64 max_time = 0.005); //copy data from client to GL @@ -152,6 +152,11 @@ public: void allocateBuffer(S32 nverts, S32 nindices, bool create); virtual void resizeBuffer(S32 newnverts, S32 newnindices); + void preUpdate() ; + void postUpdate() const ; + void freeClientBuffer() ; + void dirty() {mDirty = TRUE;} + // Only call each getVertexPointer, etc, once before calling unmapBuffer() // call unmapBuffer() after calls to getXXXStrider() before any cals to setBuffer() // example: @@ -216,6 +221,7 @@ protected: S32 mOffsets[TYPE_MAX]; BOOL mResized; // if TRUE, client buffer has been resized and GL buffer has not BOOL mDynamicSize; // if TRUE, buffer has been resized at least once (and should be padded) + mutable BOOL mDirty ; class DirtyRegion { @@ -240,13 +246,14 @@ public: static std::vector<U32> sDeleteList; typedef std::list<LLVertexBuffer*> buffer_list_t; + static BOOL sDisableVBOMapping; //disable glMapBufferARB static BOOL sEnableVBOs; + static BOOL sVBOActive; + static BOOL sIBOActive; static S32 sTypeOffsets[TYPE_MAX]; static U32 sGLMode[LLRender::NUM_MODES]; static U32 sGLRenderBuffer; - static U32 sGLRenderIndices; - static BOOL sVBOActive; - static BOOL sIBOActive; + static U32 sGLRenderIndices; static U32 sLastMask; static U32 sAllocatedBytes; static U32 sBindCount; diff --git a/indra/llxml/llcontrol.h b/indra/llxml/llcontrol.h index 93975579cc..70749b8ee9 100644 --- a/indra/llxml/llcontrol.h +++ b/indra/llxml/llcontrol.h @@ -385,7 +385,8 @@ class LLCachedControl { public: LLCachedControl(LLControlGroup& group, - const std::string& name, + const std::string& name, + const T& default_value, const std::string& comment = "Declared In Code") { diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 6630d8f400..fac4cfbef9 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -1841,6 +1841,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>DebugShowPrivateMem</key> + <map> + <key>Comment</key> + <string>Show Private Mem Info</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>DebugShowRenderInfo</key> <map> <key>Comment</key> @@ -5220,6 +5231,17 @@ <key>Value</key> <real>48.0</real> </map> + <key>MaxHeapSize</key> + <map> + <key>Comment</key> + <string>Maximum heap size (GB)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>1.6</real> + </map> <key>MaxSelectDistance</key> <map> <key>Comment</key> @@ -5341,6 +5363,17 @@ <key>Value</key> <integer>1</integer> </map> + <key>MemeoyFailurePreventionEnabled</key> + <map> + <key>Comment</key> + <string>If set, the viewer will quit to avoid crash when memory failure happens</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> <key>MemoryLogFrequency</key> <map> <key>Comment</key> @@ -8451,6 +8484,17 @@ <key>Value</key> <integer>1</integer> </map> + <key>RenderVBOMappingDisable</key> + <map> + <key>Comment</key> + <string>Disable VBO glMapBufferARB</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>RenderUseStreamVBO</key> <map> <key>Comment</key> diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 1f76e2af40..e29588214d 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -619,7 +619,7 @@ LLAppViewer::~LLAppViewer() } bool LLAppViewer::init() -{ +{ // // Start of the application // @@ -647,6 +647,9 @@ bool LLAppViewer::init() if (!initConfiguration()) return false; + //set the max heap size. + initMaxHeapSize() ; + // write Google Breakpad minidump files to our log directory std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ""); logdir += gDirUtilp->getDirDelimiter(); @@ -996,9 +999,97 @@ bool LLAppViewer::init() LLAgentLanguage::init(); + return true; +} +void LLAppViewer::initMaxHeapSize() +{ + //set the max heap size. + //here is some info regarding to the max heap size: + //------------------------------------------------------------------------------------------ + // OS | setting | SL address bits | max manageable memory space | max heap size + // Win 32 | default | 32-bit | 2GB | < 1.7GB + // Win 32 | /3G | 32-bit | 3GB | < 1.7GB or 2.7GB + //Linux 32 | default | 32-bit | 3GB | < 2.7GB + //Linux 32 |HUGEMEM | 32-bit | 4GB | < 3.7GB + //64-bit OS |default | 32-bit | 4GB | < 3.7GB + //64-bit OS |default | 64-bit | N/A (> 4GB) | N/A (> 4GB) + //------------------------------------------------------------------------------------------ + //currently SL is built under 32-bit setting, we set its max heap size no more than 1.6 GB. + + //F32 max_heap_size_gb = llmin(1.6f, (F32)gSavedSettings.getF32("MaxHeapSize")) ; + F32 max_heap_size_gb = gSavedSettings.getF32("MaxHeapSize") ; + BOOL enable_mem_failure_prevention = (BOOL)gSavedSettings.getBOOL("MemeoyFailurePreventionEnabled") ; + + LLMemory::initMaxHeapSizeGB(max_heap_size_gb, enable_mem_failure_prevention) ; +} - return true; +void LLAppViewer::checkMemory() +{ + const static F32 MEMORY_CHECK_INTERVAL = 1.0f ; //second + //const static F32 MAX_QUIT_WAIT_TIME = 30.0f ; //seconds + const static U32 MAX_SIZE_CHECKED_MEMORY_BLOCK = 64 * 1024 * 1024 ; //64 MB + //static F32 force_quit_timer = MAX_QUIT_WAIT_TIME + MEMORY_CHECK_INTERVAL ; + static void* last_reserved_address = NULL ; + + if(MEMORY_CHECK_INTERVAL > mMemCheckTimer.getElapsedTimeF32()) + { + return ; + } + mMemCheckTimer.reset() ; + + if(gGLManager.mDebugGPU) + { + //update the availability of memory + LLMemory::updateMemoryInfo() ; + } + + //check the virtual address space fragmentation + if(!last_reserved_address) + { + last_reserved_address = LLMemory::tryToAlloc(last_reserved_address, MAX_SIZE_CHECKED_MEMORY_BLOCK) ; + } + else + { + last_reserved_address = LLMemory::tryToAlloc(last_reserved_address, MAX_SIZE_CHECKED_MEMORY_BLOCK) ; + if(!last_reserved_address) //failed, try once more + { + last_reserved_address = LLMemory::tryToAlloc(last_reserved_address, MAX_SIZE_CHECKED_MEMORY_BLOCK) ; + } + } + + S32 is_low = !last_reserved_address || LLMemory::isMemoryPoolLow() ; + + //if(is_low < 0) //to force quit + //{ + // if(force_quit_timer > MAX_QUIT_WAIT_TIME) //just hit the limit for the first time + // { + // //send out the notification to tell the viewer is about to quit in 30 seconds. + // LLNotification::Params params("ForceQuitDueToLowMemory"); + // LLNotifications::instance().add(params); + + // force_quit_timer = MAX_QUIT_WAIT_TIME - MEMORY_CHECK_INTERVAL ; + // } + // else + // { + // force_quit_timer -= MEMORY_CHECK_INTERVAL ; + // if(force_quit_timer < 0.f) + // { + // forceQuit() ; //quit + // } + // } + //} + //else + //{ + // force_quit_timer = MAX_QUIT_WAIT_TIME + MEMORY_CHECK_INTERVAL ; + //} + + LLPipeline::throttleNewMemoryAllocation(!is_low ? FALSE : TRUE) ; + + if(is_low) + { + LLMemory::logMemoryInfo() ; + } } static LLFastTimer::DeclareTimer FTM_MESSAGES("System Messages"); @@ -1036,7 +1127,6 @@ bool LLAppViewer::mainLoop() LLVoiceClient::getInstance()->init(gServicePump); LLTimer frameTimer,idleTimer; LLTimer debugTime; - LLFrameTimer memCheckTimer; LLViewerJoystick* joystick(LLViewerJoystick::getInstance()); joystick->setNeedsReset(true); @@ -1047,7 +1137,9 @@ bool LLAppViewer::mainLoop() // point of posting. LLSD newFrame; - const F32 memory_check_interval = 1.0f ; //second + //LLPrivateMemoryPoolTester::getInstance()->run(false) ; + //LLPrivateMemoryPoolTester::getInstance()->run(true) ; + //LLPrivateMemoryPoolTester::destroy() ; // Handle messages while (!LLApp::isExiting()) @@ -1058,18 +1150,8 @@ bool LLAppViewer::mainLoop() llclearcallstacks; //check memory availability information - { - if(memory_check_interval < memCheckTimer.getElapsedTimeF32()) - { - memCheckTimer.reset() ; - - //update the availability of memory - LLMemoryInfo::getAvailableMemoryKB(mAvailPhysicalMemInKB, mAvailVirtualMemInKB) ; - } - llcallstacks << "Available physical mem(KB): " << mAvailPhysicalMemInKB << llcallstacksendl ; - llcallstacks << "Available virtual mem(KB): " << mAvailVirtualMemInKB << llcallstacksendl ; - } - + checkMemory() ; + try { pingMainloopTimeout("Main:MiscNativeWindowEvents"); @@ -1233,7 +1315,7 @@ bool LLAppViewer::mainLoop() idleTimer.reset(); bool is_slow = (frameTimer.getElapsedTimeF64() > FRAME_SLOW_THRESHOLD) ; S32 total_work_pending = 0; - S32 total_io_pending = 0; + S32 total_io_pending = 0; while(!is_slow)//do not unpause threads if the frame rates are very low. { S32 work_pending = 0; @@ -1300,15 +1382,7 @@ bool LLAppViewer::mainLoop() } catch(std::bad_alloc) { - { - llinfos << "Availabe physical memory(KB) at the beginning of the frame: " << mAvailPhysicalMemInKB << llendl ; - llinfos << "Availabe virtual memory(KB) at the beginning of the frame: " << mAvailVirtualMemInKB << llendl ; - - LLMemoryInfo::getAvailableMemoryKB(mAvailPhysicalMemInKB, mAvailVirtualMemInKB) ; - - llinfos << "Current availabe physical memory(KB): " << mAvailPhysicalMemInKB << llendl ; - llinfos << "Current availabe virtual memory(KB): " << mAvailVirtualMemInKB << llendl ; - } + LLMemory::logMemoryInfo(TRUE) ; //stop memory leaking simulation LLFloaterMemLeak* mem_leak_instance = @@ -1777,6 +1851,9 @@ bool LLAppViewer::cleanup() LLMainLoopRepeater::instance().stop(); + //release all private memory pools. + LLPrivateMemoryPoolManager::destroyClass() ; + ll_close_fail_log(); MEM_TRACK_RELEASE diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index 00b12d50ae..512887cb1a 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -168,7 +168,7 @@ public: // mute/unmute the system's master audio virtual void setMasterSystemAudioMute(bool mute); - virtual bool getMasterSystemAudioMute(); + virtual bool getMasterSystemAudioMute(); // Metrics policy helper statics. static void metricsUpdateRegion(U64 region_handle); @@ -190,11 +190,12 @@ protected: private: + void initMaxHeapSize(); bool initThreads(); // Initialize viewer threads, return false on failure. bool initConfiguration(); // Initialize settings from the command line/config file. void initUpdater(); // Initialize the updater service. bool initCache(); // Initialize local client cache. - + void checkMemory() ; // We have switched locations of both Mac and Windows cache, make sure // files migrate and old cache is cleared out. @@ -268,8 +269,7 @@ private: std::map<apr_dso_handle_t*, boost::shared_ptr<LLAPRPool> > mPlugins; - U32 mAvailPhysicalMemInKB ; - U32 mAvailVirtualMemInKB ; + LLFrameTimer mMemCheckTimer; boost::scoped_ptr<LLUpdaterService> mUpdater; diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index c98bcbda45..5ff22f89ab 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -899,31 +899,14 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL } } - LLTextEditor* text_editor = notify_box->getChild<LLTextEditor>("text_editor_box", TRUE); - S32 text_heigth = 0; - if(text_editor != NULL) - { - text_heigth = text_editor->getTextBoundingRect().getHeight(); - } - //Prepare the rect for the view LLRect target_rect = mEditor->getDocumentView()->getRect(); // squeeze down the widget by subtracting padding off left and right target_rect.mLeft += mLeftWidgetPad + mEditor->getHPad(); target_rect.mRight -= mRightWidgetPad; - notify_box->reshape(target_rect.getWidth(), - notify_box->getRect().getHeight()); + notify_box->reshape(target_rect.getWidth(), notify_box->getRect().getHeight()); notify_box->setOrigin(target_rect.mLeft, notify_box->getRect().mBottom); - if (text_editor != NULL) - { - S32 text_heigth_delta = - text_editor->getTextBoundingRect().getHeight() - - text_heigth; - notify_box->reshape(target_rect.getWidth(), - notify_box->getRect().getHeight() + text_heigth_delta); - } - LLInlineViewSegment::Params params; params.view = notify_box; params.left_pad = mLeftWidgetPad; diff --git a/indra/newview/llcolorswatch.cpp b/indra/newview/llcolorswatch.cpp index 6f02192d0a..d77ebc5367 100644 --- a/indra/newview/llcolorswatch.cpp +++ b/indra/newview/llcolorswatch.cpp @@ -185,6 +185,10 @@ BOOL LLColorSwatchCtrl::handleMouseUp(S32 x, S32 y, MASK mask) llassert(getEnabled()); llassert(getVisible()); + // Focus the widget now in order to return the focus + // after the color picker is closed. + setFocus(TRUE); + showPicker(FALSE); } } diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp index f781d5f3ff..fb9958ee9d 100644 --- a/indra/newview/lldynamictexture.cpp +++ b/indra/newview/lldynamictexture.cpp @@ -40,6 +40,7 @@ #include "llvertexbuffer.h" #include "llviewerdisplay.h" #include "llrender.h" +#include "pipeline.h" // static LLViewerDynamicTexture::instance_list_t LLViewerDynamicTexture::sInstances[ LLViewerDynamicTexture::ORDER_COUNT ]; @@ -201,7 +202,7 @@ void LLViewerDynamicTexture::postRender(BOOL success) BOOL LLViewerDynamicTexture::updateAllInstances() { sNumRenders = 0; - if (gGLManager.mIsDisabled) + if (gGLManager.mIsDisabled || LLPipeline::sMemAllocationThrottled) { return TRUE; } diff --git a/indra/newview/llfloatermemleak.cpp b/indra/newview/llfloatermemleak.cpp index 58931d112e..9edfe1e354 100644 --- a/indra/newview/llfloatermemleak.cpp +++ b/indra/newview/llfloatermemleak.cpp @@ -90,6 +90,11 @@ LLFloaterMemLeak::~LLFloaterMemLeak() void LLFloaterMemLeak::release() { + if(mLeakedMem.empty()) + { + return ; + } + for(S32 i = 0 ; i < (S32)mLeakedMem.size() ; i++) { delete[] mLeakedMem[i] ; diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 9623554200..0ef502b81b 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -2719,6 +2719,15 @@ void LLIMMgr::inviteToSession( { LLFloaterReg::showInstance("incoming_call", payload, FALSE); } + + // Add the caller to the Recent List here (at this point + // "incoming_call" floater is shown and the recipient can + // reject the call), because even if a recipient will reject + // the call, the caller should be added to the recent list + // anyway. STORM-507. + if(type == IM_SESSION_P2P_INVITE) + LLRecentPeople::instance().add(caller_id); + mPendingInvitations[session_id.asString()] = LLSD(); } } diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp index 38100aa6c5..afceb58ccf 100644 --- a/indra/newview/llnamelistctrl.cpp +++ b/indra/newview/llnamelistctrl.cpp @@ -143,6 +143,30 @@ void LLNameListCtrl::mouseOverHighlightNthItem( S32 target_index ) S32 cur_index = getHighlightedItemInx(); if (cur_index != target_index) { + bool is_mouse_over_name_cell = false; + + S32 mouse_x, mouse_y; + LLUI::getMousePositionLocal(this, &mouse_x, &mouse_y); + + S32 column_index = getColumnIndexFromOffset(mouse_x); + LLScrollListItem* hit_item = hitItem(mouse_x, mouse_y); + if (hit_item && column_index == mNameColumnIndex) + { + // Get the name cell which is currently under the mouse pointer. + LLScrollListCell* hit_cell = hit_item->getColumn(column_index); + if (hit_cell) + { + is_mouse_over_name_cell = getCellRect(cur_index, column_index).pointInRect(mouse_x, mouse_y); + } + } + + // If the tool tip is visible and the mouse is over the currently highlighted item's name cell, + // we should not reset the highlighted item index i.e. set mHighlightedItem = -1 + // and should not increase the width of the text inside the cell because it may + // overlap the tool tip icon. + if (LLToolTipMgr::getInstance()->toolTipVisible() && is_mouse_over_name_cell) + return; + if(0 <= cur_index && cur_index < (S32)getItemList().size()) { LLScrollListItem* item = getItemList()[cur_index]; diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index a47ea8581a..11dff69e0c 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -113,7 +113,7 @@ public: ~LLTextureCacheWorker() { llassert_always(!haveWork()); - delete[] mReadData; + LLImageBase::deleteMemory(mReadData); } // override this interface @@ -215,7 +215,7 @@ bool LLTextureCacheLocalFileWorker::doRead() mDataSize = 0; return true; } - mReadData = new U8[mDataSize]; + mReadData = (U8*)LLImageBase::allocateMemory(mDataSize); mBytesRead = -1; mBytesToRead = mDataSize; setPriority(LLWorkerThread::PRIORITY_LOW | mPriority); @@ -233,7 +233,7 @@ bool LLTextureCacheLocalFileWorker::doRead() // << " Bytes: " << mDataSize << " Offset: " << mOffset // << " / " << mDataSize << llendl; mDataSize = 0; // failed - delete[] mReadData; + LLImageBase::deleteMemory(mReadData); mReadData = NULL; } return true; @@ -248,7 +248,7 @@ bool LLTextureCacheLocalFileWorker::doRead() { mDataSize = local_size; } - mReadData = new U8[mDataSize]; + mReadData = (U8*)LLImageBase::allocateMemory(mDataSize); S32 bytes_read = LLAPRFile::readEx(mFileName, mReadData, mOffset, mDataSize); @@ -258,7 +258,7 @@ bool LLTextureCacheLocalFileWorker::doRead() // << " Bytes: " << mDataSize << " Offset: " << mOffset // << " / " << mDataSize << llendl; mDataSize = 0; - delete[] mReadData; + LLImageBase::deleteMemory(mReadData); mReadData = NULL; } else @@ -377,7 +377,7 @@ bool LLTextureCacheRemoteWorker::doRead() mDataSize = local_size; } // Allocate read buffer - mReadData = new U8[mDataSize]; + mReadData = (U8*)LLImageBase::allocateMemory(mDataSize); S32 bytes_read = LLAPRFile::readEx(local_filename, mReadData, mOffset, mDataSize); if (bytes_read != mDataSize) { @@ -385,7 +385,7 @@ bool LLTextureCacheRemoteWorker::doRead() << " Bytes: " << mDataSize << " Offset: " << mOffset << " / " << mDataSize << llendl; mDataSize = 0; - delete[] mReadData; + LLImageBase::deleteMemory(mReadData); mReadData = NULL; } else @@ -428,14 +428,14 @@ bool LLTextureCacheRemoteWorker::doRead() S32 size = TEXTURE_CACHE_ENTRY_SIZE - mOffset; size = llmin(size, mDataSize); // Allocate the read buffer - mReadData = new U8[size]; + mReadData = (U8*)LLImageBase::allocateMemory(size); S32 bytes_read = LLAPRFile::readEx(mCache->mHeaderDataFileName, mReadData, offset, size); if (bytes_read != size) { llwarns << "LLTextureCacheWorker: " << mID << " incorrect number of bytes read from header: " << bytes_read << " / " << size << llendl; - delete[] mReadData; + LLImageBase::deleteMemory(mReadData); mReadData = NULL; mDataSize = -1; // failed done = true; @@ -465,7 +465,7 @@ bool LLTextureCacheRemoteWorker::doRead() S32 data_offset, file_size, file_offset; // Reserve the whole data buffer first - U8* data = new U8[mDataSize]; + U8* data = (U8*)LLImageBase::allocateMemory(mDataSize); // Set the data file pointers taking the read offset into account. 2 cases: if (mOffset < TEXTURE_CACHE_ENTRY_SIZE) @@ -478,7 +478,7 @@ bool LLTextureCacheRemoteWorker::doRead() // Copy the raw data we've been holding from the header cache into the new sized buffer llassert_always(mReadData); memcpy(data, mReadData, data_offset); - delete[] mReadData; + LLImageBase::deleteMemory(mReadData); mReadData = NULL; } else @@ -503,7 +503,7 @@ bool LLTextureCacheRemoteWorker::doRead() llwarns << "LLTextureCacheWorker: " << mID << " incorrect number of bytes read from body: " << bytes_read << " / " << file_size << llendl; - delete[] mReadData; + LLImageBase::deleteMemory(mReadData); mReadData = NULL; mDataSize = -1; // failed done = true; @@ -595,11 +595,11 @@ bool LLTextureCacheRemoteWorker::doWrite() { // We need to write a full record in the header cache so, if the amount of data is smaller // than a record, we need to transfer the data to a buffer padded with 0 and write that - U8* padBuffer = new U8[TEXTURE_CACHE_ENTRY_SIZE]; + U8* padBuffer = (U8*)LLImageBase::allocateMemory(TEXTURE_CACHE_ENTRY_SIZE); memset(padBuffer, 0, TEXTURE_CACHE_ENTRY_SIZE); // Init with zeros memcpy(padBuffer, mWriteData, mDataSize); // Copy the write buffer bytes_written = LLAPRFile::writeEx(mCache->mHeaderDataFileName, padBuffer, offset, size); - delete [] padBuffer; + LLImageBase::deleteMemory(padBuffer); } else { @@ -694,7 +694,7 @@ void LLTextureCacheWorker::finishWork(S32 param, bool completed) } else { - delete[] mReadData; + LLImageBase::deleteMemory(mReadData); mReadData = NULL; } } diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 139b434aeb..806f130486 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -816,7 +816,7 @@ void LLTextureFetchWorker::setImagePriority(F32 priority) void LLTextureFetchWorker::resetFormattedData() { - delete[] mBuffer; + LLImageBase::deleteMemory(mBuffer); mBuffer = NULL; mBufferSize = 0; if (mFormattedImage.notNull()) @@ -887,7 +887,7 @@ bool LLTextureFetchWorker::doWork(S32 param) mSentRequest = UNSENT; mDecoded = FALSE; mWritten = FALSE; - delete[] mBuffer; + LLImageBase::deleteMemory(mBuffer); mBuffer = NULL; mBufferSize = 0; mHaveAllData = FALSE; @@ -1283,7 +1283,7 @@ bool LLTextureFetchWorker::doWork(S32 param) llassert_always(mBufferSize == cur_size + mRequestedSize); if(!mBufferSize)//no data received. { - delete[] mBuffer; + LLImageBase::deleteMemory(mBuffer); mBuffer = NULL; //abort. @@ -1311,7 +1311,7 @@ bool LLTextureFetchWorker::doWork(S32 param) mFileSize = mBufferSize + 1 ; //flag the file is not fully loaded. } - U8* buffer = new U8[mBufferSize]; + U8* buffer = (U8*)LLImageBase::allocateMemory(mBufferSize); if (cur_size > 0) { memcpy(buffer, mFormattedImage->getData(), cur_size); @@ -1320,7 +1320,7 @@ bool LLTextureFetchWorker::doWork(S32 param) // NOTE: setData releases current data and owns new data (buffer) mFormattedImage->setData(buffer, mBufferSize); // delete temp data - delete[] mBuffer; // Note: not 'buffer' (assigned in setData()) + LLImageBase::deleteMemory(mBuffer); // Note: not 'buffer' (assigned in setData()) mBuffer = NULL; mBufferSize = 0; mLoadedDiscard = mRequestedDiscard; @@ -1617,7 +1617,7 @@ bool LLTextureFetchWorker::processSimulatorPackets() if (buffer_size > cur_size) { /// We have new data - U8* buffer = new U8[buffer_size]; + U8* buffer = (U8*)LLImageBase::allocateMemory(buffer_size); S32 offset = 0; if (cur_size > 0 && mFirstPacket > 0) { @@ -1669,7 +1669,7 @@ S32 LLTextureFetchWorker::callbackHttpGet(const LLChannelDescriptors& channels, if (data_size > 0) { // *TODO: set the formatted image data here directly to avoid the copy - mBuffer = new U8[data_size]; + mBuffer = (U8*)LLImageBase::allocateMemory(data_size); buffer->readAfter(channels.in(), NULL, mBuffer, data_size); mBufferSize += data_size; if (data_size < mRequestedSize && mRequestedDiscard == 0) diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp index 3f7dc24ade..fa91f129b8 100644 --- a/indra/newview/lltoastnotifypanel.cpp +++ b/indra/newview/lltoastnotifypanel.cpp @@ -563,7 +563,17 @@ void LLIMToastNotifyPanel::reshape(S32 width, S32 height, BOOL called_from_paren height = rc.getHeight(); width = rc.getWidth(); + bool is_width_changed = width != getRect().getWidth(); + LLToastPanel::reshape(width, height, called_from_parent); + + // Notification height required to display the text message depends on + // the width of the text box thus if panel width is changed the text box + // width is also changed then reshape() is called to adjust proper height. + if (is_width_changed) + { + reshape(width, height, called_from_parent); + } } // EOF diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 8c5a52c187..3c53e54203 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -309,6 +309,15 @@ static bool handleRenderUseVBOChanged(const LLSD& newvalue) return true; } +static bool handleRenderUseVBOMappingChanged(const LLSD& newvalue) +{ + if (gPipeline.isInit()) + { + gPipeline.setDisableVBOMapping(newvalue.asBoolean()); + } + return true; +} + static bool handleWLSkyDetailChanged(const LLSD&) { if (gSky.mVOWLSkyp.notNull()) @@ -589,6 +598,7 @@ void settings_setup_listeners() gSavedSettings.getControl("MuteAmbient")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); gSavedSettings.getControl("MuteUI")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); gSavedSettings.getControl("RenderVBOEnable")->getSignal()->connect(boost::bind(&handleRenderUseVBOChanged, _2)); + gSavedSettings.getControl("RenderVBOMappingDisable")->getSignal()->connect(boost::bind(&handleRenderUseVBOMappingChanged, _2)); gSavedSettings.getControl("RenderUseStreamVBO")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); gSavedSettings.getControl("WLSkyDetail")->getSignal()->connect(boost::bind(&handleWLSkyDetailChanged, _2)); gSavedSettings.getControl("NumpadControl")->getSignal()->connect(boost::bind(&handleNumpadControlChanged, _2)); diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 41b7c13826..b9d81a76ff 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -203,6 +203,7 @@ void display_stats() gMemoryAllocated = LLMemory::getCurrentRSS(); U32 memory = (U32)(gMemoryAllocated / (1024*1024)); llinfos << llformat("MEMORY: %d MB", memory) << llendl; + LLMemory::logMemoryInfo() ; gRecentMemoryTime.reset(); } } @@ -690,7 +691,11 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) glh::matrix4f mod = glh_get_current_modelview(); glViewport(0,0,512,512); LLVOAvatar::updateFreezeCounter() ; - LLVOAvatar::updateImpostors(); + + if(!LLPipeline::sMemAllocationThrottled) + { + LLVOAvatar::updateImpostors(); + } glh_set_current_projection(proj); glh_set_current_modelview(mod); diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index f16d8814dd..900081b8c6 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -53,7 +53,7 @@ #include "llwebsharing.h" // For LLWebSharing::setOpenIDCookie(), *TODO: find a better way to do this! #include "llfilepicker.h" #include "llnotifications.h" - +#include "lldir.h" #include "llevent.h" // LLSimpleListener #include "llnotificationsutil.h" #include "lluuid.h" @@ -1766,7 +1766,8 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_ media_source->setTarget(target); - if (media_source->init(launcher_name, plugin_name, gSavedSettings.getBOOL("PluginAttachDebuggerToPlugins"))) + const std::string plugin_dir = gDirUtilp->getLLPluginDir(); + if (media_source->init(launcher_name, plugin_dir, plugin_name, gSavedSettings.getBOOL("PluginAttachDebuggerToPlugins"))) { return media_source; } diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 090d3cadd4..32cd8dbb39 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -477,7 +477,6 @@ void LLViewerObject::initVOClasses() llinfos << "Viewer Object size: " << sizeof(LLViewerObject) << llendl; LLVOGrass::initClass(); LLVOWater::initClass(); - LLVOSky::initClass(); LLVOVolume::initClass(); } @@ -3009,6 +3008,8 @@ void LLViewerObject::setScale(const LLVector3 &scale, BOOL damped) { if (!mOnMap) { + llassert_always(LLWorld::getInstance()->getRegionFromHandle(getRegion()->getHandle())); + gObjectList.addToMap(this); mOnMap = TRUE; } @@ -3536,8 +3537,8 @@ void LLViewerObject::setPositionParent(const LLVector3 &pos_parent, BOOL damped) // Set position relative to parent, if no parent, relative to region if (!isRoot()) { - LLViewerObject::setPosition(pos_parent); - updateDrawable(damped); + LLViewerObject::setPosition(pos_parent, damped); + //updateDrawable(damped); } else { @@ -3578,6 +3579,7 @@ void LLViewerObject::setPositionEdit(const LLVector3 &pos_edit, BOOL damped) LLVector3 position_offset = getPosition() * getParent()->getRotation(); ((LLViewerObject *)getParent())->setPositionEdit(pos_edit - position_offset); + updateDrawable(damped); } else if (isJointChild()) { @@ -3586,15 +3588,14 @@ void LLViewerObject::setPositionEdit(const LLVector3 &pos_edit, BOOL damped) LLQuaternion inv_parent_rot = parent->getRotation(); inv_parent_rot.transQuat(); LLVector3 pos_parent = (pos_edit - parent->getPositionRegion()) * inv_parent_rot; - LLViewerObject::setPosition(pos_parent); + LLViewerObject::setPosition(pos_parent, damped); } else { - LLViewerObject::setPosition(pos_edit); + LLViewerObject::setPosition(pos_edit, damped); mPositionRegion = pos_edit; mPositionAgent = mRegionp->getPosAgentFromRegion(mPositionRegion); - } - updateDrawable(damped); + } } diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 970cc2e2a7..82bc164021 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -1124,6 +1124,22 @@ void LLViewerObjectList::shiftObjects(const LLVector3 &offset) LLWorld::getInstance()->shiftRegions(offset); } +//debug code +bool LLViewerObjectList::hasMapObjectInRegion(LLViewerRegion* regionp) +{ + for (vobj_list_t::iterator iter = mMapObjects.begin(); iter != mMapObjects.end(); ++iter) + { + LLViewerObject* objectp = *iter; + + if(objectp->isDead() || objectp->getRegion() == regionp) + { + return true ; + } + } + + return false ; +} + void LLViewerObjectList::renderObjectsForMap(LLNetMap &netmap) { LLColor4 above_water_color = LLUIColorTable::instance().getColor( "NetMapOtherOwnAboveWater" ); @@ -1142,6 +1158,9 @@ void LLViewerObjectList::renderObjectsForMap(LLNetMap &netmap) for (vobj_list_t::iterator iter = mMapObjects.begin(); iter != mMapObjects.end(); ++iter) { LLViewerObject* objectp = *iter; + + llassert_always(!objectp->isDead()); + if (!objectp->getRegion() || objectp->isOrphaned() || objectp->isAttachment()) { continue; @@ -1429,7 +1448,7 @@ LLViewerObject *LLViewerObjectList::replaceObject(const LLUUID &id, const LLPCod LLViewerObject *old_instance = findObject(id); if (old_instance) { - cleanupReferences(old_instance); + //cleanupReferences(old_instance); old_instance->markDead(); return createObject(pcode, regionp, id, old_instance->getLocalID(), LLHost()); diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h index fda3d6899d..8cff8e988a 100644 --- a/indra/newview/llviewerobjectlist.h +++ b/indra/newview/llviewerobjectlist.h @@ -87,6 +87,7 @@ public: void shiftObjects(const LLVector3 &offset); + bool hasMapObjectInRegion(LLViewerRegion* regionp) ; void renderObjectsForMap(LLNetMap &netmap); void renderObjectBounds(const LLVector3 ¢er); diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index cd16b15e3e..23d6ca1ae2 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -3080,9 +3080,16 @@ void LLViewerLODTexture::processTextureStats() { mDesiredDiscardLevel = llmin(mDesiredDiscardLevel, (S8)mDesiredSavedRawDiscardLevel) ; } + else if(LLPipeline::sMemAllocationThrottled)//release memory of large textures by decrease their resolutions. + { + if(scaleDown()) + { + mDesiredDiscardLevel = mCachedRawDiscardLevel ; + } + } } -void LLViewerLODTexture::scaleDown() +bool LLViewerLODTexture::scaleDown() { if(hasGLTexture() && mCachedRawDiscardLevel > getDiscardLevel()) { @@ -3093,7 +3100,10 @@ void LLViewerLODTexture::scaleDown() { tester->setStablizingTime() ; } + + return true ; } + return false ; } //---------------------------------------------------------------------------------------------- //end of LLViewerLODTexture diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index b5636bbdc7..07b91c2071 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -595,7 +595,7 @@ public: private: void init(bool firstinit) ; - void scaleDown() ; + bool scaleDown() ; private: F32 mDiscardVirtualSize; // Virtual size used to calculate desired discard diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 274dbe2cc8..dfdf429455 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -561,6 +561,17 @@ public: addText(xpos, ypos, llformat("%d %d %d %d", color[0], color[1], color[2], color[3])); ypos += y_inc; } + + if (gSavedSettings.getBOOL("DebugShowPrivateMem")) + { + LLPrivateMemoryPoolManager::getInstance()->updateStatistics() ; + addText(xpos, ypos, llformat("Total Reserved(KB): %d", LLPrivateMemoryPoolManager::getInstance()->mTotalReservedSize / 1024)); + ypos += y_inc; + + addText(xpos, ypos, llformat("Total Allocated(KB): %d", LLPrivateMemoryPoolManager::getInstance()->mTotalAllocatedSize / 1024)); + ypos += y_inc; + } + // only display these messages if we are actually rendering beacons at this moment if (LLPipeline::getRenderBeacons(NULL) && LLFloaterReg::instanceVisible("beacons")) { @@ -1477,7 +1488,7 @@ LLViewerWindow::LLViewerWindow( { gSavedSettings.setBOOL("RenderVBOEnable", FALSE); } - LLVertexBuffer::initClass(gSavedSettings.getBOOL("RenderVBOEnable")); + LLVertexBuffer::initClass(gSavedSettings.getBOOL("RenderVBOEnable"), gSavedSettings.getBOOL("RenderVBOMappingDisable")); if (LLFeatureManager::getInstance()->isSafe() || (gSavedSettings.getS32("LastFeatureVersion") != LLFeatureManager::getInstance()->getVersion()) @@ -3978,6 +3989,19 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei { return FALSE; } + //check if there is enough memory for the snapshot image + if(LLPipeline::sMemAllocationThrottled) + { + return FALSE ; //snapshot taking is disabled due to memory restriction. + } + if(image_width * image_height > (1 << 22)) //if snapshot image is larger than 2K by 2K + { + if(!LLMemory::tryToAlloc(NULL, image_width * image_height * 3)) + { + llwarns << "No enough memory to take the snapshot with size (w : h): " << image_width << " : " << image_height << llendl ; + return FALSE ; //there is no enough memory for taking this snapshot. + } + } // PRE SNAPSHOT gDisplaySwapBuffers = FALSE; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 2cd9b09932..d58628942e 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -599,16 +599,16 @@ F32 LLVOAvatar::sRenderDistance = 256.f; S32 LLVOAvatar::sNumVisibleAvatars = 0; S32 LLVOAvatar::sNumLODChangesThisFrame = 0; -const LLUUID LLVOAvatar::sStepSoundOnLand = LLUUID("e8af4a28-aa83-4310-a7c4-c047e15ea0df"); +const LLUUID LLVOAvatar::sStepSoundOnLand("e8af4a28-aa83-4310-a7c4-c047e15ea0df"); const LLUUID LLVOAvatar::sStepSounds[LL_MCODE_END] = { - LLUUID(SND_STONE_RUBBER), - LLUUID(SND_METAL_RUBBER), - LLUUID(SND_GLASS_RUBBER), - LLUUID(SND_WOOD_RUBBER), - LLUUID(SND_FLESH_RUBBER), - LLUUID(SND_RUBBER_PLASTIC), - LLUUID(SND_RUBBER_RUBBER) + SND_STONE_RUBBER, + SND_METAL_RUBBER, + SND_GLASS_RUBBER, + SND_WOOD_RUBBER, + SND_FLESH_RUBBER, + SND_RUBBER_PLASTIC, + SND_RUBBER_RUBBER }; S32 LLVOAvatar::sRenderName = RENDER_NAME_ALWAYS; diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp index 7ae8c2c07d..80f43e51d2 100644 --- a/indra/newview/llvosky.cpp +++ b/indra/newview/llvosky.cpp @@ -77,9 +77,6 @@ static const LLVector2 TEX11 = LLVector2(1.f, 1.f); LLUUID gSunTextureID = IMG_SUN; LLUUID gMoonTextureID = IMG_MOON; -//static -LLColor3 LLHaze::sAirScaSeaLevel; - class LLFastLn { public: @@ -182,6 +179,23 @@ inline void color_gamma_correct(LLColor3 &col) } } +static LLColor3 calc_air_sca_sea_level() +{ + static LLColor3 WAVE_LEN(675, 520, 445); + static LLColor3 refr_ind = refr_ind_calc(WAVE_LEN); + static LLColor3 n21 = refr_ind * refr_ind - LLColor3(1, 1, 1); + static LLColor3 n4 = n21 * n21; + static LLColor3 wl2 = WAVE_LEN * WAVE_LEN * 1e-6f; + static LLColor3 wl4 = wl2 * wl2; + static LLColor3 mult_const = fsigma * 2.0f/ 3.0f * 1e24f * (F_PI * F_PI) * n4; + static F32 dens_div_N = F32( ATM_SEA_LEVEL_NDENS / Ndens2); + return dens_div_N * color_div ( mult_const, wl4 ); +} + +// static constants. +LLColor3 const LLHaze::sAirScaSeaLevel = calc_air_sca_sea_level(); +F32 const LLHaze::sAirScaIntense = color_intens(LLHaze::sAirScaSeaLevel); +F32 const LLHaze::sAirScaAvg = LLHaze::sAirScaIntense / 3.f; /*************************************** @@ -394,12 +408,6 @@ LLVOSky::~LLVOSky() mCubeMap = NULL; } -void LLVOSky::initClass() -{ - LLHaze::initClass(); -} - - void LLVOSky::init() { const F32 haze_int = color_intens(mHaze.calcSigSca(0)); @@ -2147,17 +2155,8 @@ void LLVOSky::updateFog(const F32 distance) stop_glerror(); } -// static -void LLHaze::initClass() -{ - sAirScaSeaLevel = LLHaze::calcAirScaSeaLevel(); -} - - // Functions used a lot. - - F32 color_norm_pow(LLColor3& col, F32 e, BOOL postmultiply) { F32 mv = color_max(col); diff --git a/indra/newview/llvosky.h b/indra/newview/llvosky.h index 6b3e7873a1..d3a42583ea 100644 --- a/indra/newview/llvosky.h +++ b/indra/newview/llvosky.h @@ -292,23 +292,6 @@ LL_FORCE_INLINE LLColor3 refr_ind_calc(const LLColor3 &wave_length) } -LL_FORCE_INLINE LLColor3 calc_air_sca_sea_level() -{ - const static LLColor3 WAVE_LEN(675, 520, 445); - const static LLColor3 refr_ind = refr_ind_calc(WAVE_LEN); - const static LLColor3 n21 = refr_ind * refr_ind - LLColor3(1, 1, 1); - const static LLColor3 n4 = n21 * n21; - const static LLColor3 wl2 = WAVE_LEN * WAVE_LEN * 1e-6f; - const static LLColor3 wl4 = wl2 * wl2; - const static LLColor3 mult_const = fsigma * 2.0f/ 3.0f * 1e24f * (F_PI * F_PI) * n4; - const static F32 dens_div_N = F32( ATM_SEA_LEVEL_NDENS / Ndens2); - return dens_div_N * color_div ( mult_const, wl4 ); -} - -const LLColor3 gAirScaSeaLevel = calc_air_sca_sea_level(); -const F32 AIR_SCA_INTENS = color_intens(gAirScaSeaLevel); -const F32 AIR_SCA_AVG = AIR_SCA_INTENS / 3.f; - class LLHaze { public: @@ -316,18 +299,15 @@ public: LLHaze(const F32 g, const LLColor3& sca, const F32 fo = 2.f) : mG(g), mSigSca(0.25f/F_PI * sca), mFalloff(fo), mAbsCoef(0.f) { - mAbsCoef = color_intens(mSigSca) / AIR_SCA_INTENS; + mAbsCoef = color_intens(mSigSca) / sAirScaIntense; } LLHaze(const F32 g, const F32 sca, const F32 fo = 2.f) : mG(g), mSigSca(0.25f/F_PI * LLColor3(sca, sca, sca)), mFalloff(fo) { - mAbsCoef = 0.01f * sca / AIR_SCA_AVG; + mAbsCoef = 0.01f * sca / sAirScaAvg; } - static void initClass(); - - F32 getG() const { return mG; } void setG(const F32 g) @@ -343,12 +323,12 @@ public: void setSigSca(const LLColor3& s) { mSigSca = s; - mAbsCoef = 0.01f * color_intens(mSigSca) / AIR_SCA_INTENS; + mAbsCoef = 0.01f * color_intens(mSigSca) / sAirScaIntense; } void setSigSca(const F32 s0, const F32 s1, const F32 s2) { - mSigSca = AIR_SCA_AVG * LLColor3 (s0, s1, s2); + mSigSca = sAirScaAvg * LLColor3 (s0, s1, s2); mAbsCoef = 0.01f * (s0 + s1 + s2) / 3; } @@ -392,10 +372,11 @@ public: static inline LLColor3 calcAirSca(const F32 h); static inline void calcAirSca(const F32 h, LLColor3 &result); - static LLColor3 calcAirScaSeaLevel() { return gAirScaSeaLevel; } - static const LLColor3 &getAirScaSeaLevel() { return sAirScaSeaLevel; } -public: - static LLColor3 sAirScaSeaLevel; + +private: + static LLColor3 const sAirScaSeaLevel; + static F32 const sAirScaIntense; + static F32 const sAirScaAvg; protected: F32 mG; @@ -473,7 +454,6 @@ public: LLVOSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp); // Initialize/delete data that's only inited once per class. - static void initClass(); void init(); void initCubeMap(); void initEmpty(); @@ -654,14 +634,12 @@ F32 color_norm_pow(LLColor3& col, F32 e, BOOL postmultiply = FALSE); inline LLColor3 LLHaze::calcAirSca(const F32 h) { - static const LLColor3 air_sca_sea_level = calcAirScaSeaLevel(); - return calcFalloff(h) * air_sca_sea_level; + return calcFalloff(h) * sAirScaSeaLevel; } inline void LLHaze::calcAirSca(const F32 h, LLColor3 &result) { - static const LLColor3 air_sca_sea_level = calcAirScaSeaLevel(); - result = air_sca_sea_level; + result = sAirScaSeaLevel; result *= calcFalloff(h); } diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index 399442e5c4..9db6d5e08c 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -281,6 +281,8 @@ void LLWorld::removeRegion(const LLHost &host) delete regionp; updateWaterObjects(); + + llassert_always(!gObjectList.hasMapObjectInRegion(regionp)) ; } diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 39bc354250..53564ec0f8 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -100,6 +100,7 @@ #include "llspatialpartition.h" #include "llmutelist.h" #include "lltoolpie.h" +#include "llnotifications.h" #ifdef _DEBUG @@ -281,6 +282,7 @@ BOOL LLPipeline::sRenderAttachedLights = TRUE; BOOL LLPipeline::sRenderAttachedParticles = TRUE; BOOL LLPipeline::sRenderDeferred = FALSE; BOOL LLPipeline::sAllowRebuildPriorityGroup = FALSE ; +BOOL LLPipeline::sMemAllocationThrottled = FALSE; S32 LLPipeline::sVisibleLightCount = 0; F32 LLPipeline::sMinRenderSize = 0.f; @@ -513,6 +515,24 @@ void LLPipeline::destroyGL() static LLFastTimer::DeclareTimer FTM_RESIZE_SCREEN_TEXTURE("Resize Screen Texture"); +//static +void LLPipeline::throttleNewMemoryAllocation(BOOL disable) +{ + if(sMemAllocationThrottled != disable) + { + sMemAllocationThrottled = disable ; + + if(sMemAllocationThrottled) + { + //send out notification + LLNotification::Params params("LowMemory"); + LLNotifications::instance().add(params); + + //release some memory. + } + } +} + void LLPipeline::resizeScreenTexture() { LLFastTimer ft(FTM_RESIZE_SCREEN_TEXTURE); @@ -5313,7 +5333,25 @@ void LLPipeline::setUseVBO(BOOL use_vbo) } resetVertexBuffers(); - LLVertexBuffer::initClass(use_vbo); + LLVertexBuffer::initClass(use_vbo, gSavedSettings.getBOOL("RenderVBOMappingDisable")); + } +} + +void LLPipeline::setDisableVBOMapping(BOOL no_vbo_mapping) +{ + if (LLVertexBuffer::sEnableVBOs && no_vbo_mapping != LLVertexBuffer::sDisableVBOMapping) + { + if (no_vbo_mapping) + { + llinfos << "Disabling VBO glMapBufferARB." << llendl; + } + else + { + llinfos << "Enabling VBO glMapBufferARB." << llendl; + } + + resetVertexBuffers(); + LLVertexBuffer::initClass(true, no_vbo_mapping); } } diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index cef3d87f36..4a7cc77bde 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -111,6 +111,7 @@ public: void resetVertexBuffers(LLDrawable* drawable); void setUseVBO(BOOL use_vbo); + void setDisableVBOMapping(BOOL no_vbo_mapping); void generateImpostor(LLVOAvatar* avatar); void bindScreenToTexture(); void renderBloom(BOOL for_snapshot, F32 zoom_factor = 1.f, int subfield = 0); @@ -333,6 +334,8 @@ public: static void updateRenderDeferred(); + static void throttleNewMemoryAllocation(BOOL disable); + private: void unloadShaders(); void addToQuickLookup( LLDrawPool* new_poolp ); @@ -478,8 +481,9 @@ public: static BOOL sRenderAttachedParticles; static BOOL sRenderDeferred; static BOOL sAllowRebuildPriorityGroup; + static BOOL sMemAllocationThrottled; static S32 sVisibleLightCount; - static F32 sMinRenderSize; + static F32 sMinRenderSize; //screen texture U32 mScreenWidth; diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml index 3dd6c60095..937a97797d 100644 --- a/indra/newview/skins/default/xui/en/floater_about_land.xml +++ b/indra/newview/skins/default/xui/en/floater_about_land.xml @@ -1905,7 +1905,7 @@ Only large parcels can be listed in search. </panel.string> <panel.string name="allow_public_access"> - Allow Public Access ([MATURITY]) + Allow Public Access ([MATURITY]) (Note: Unchecking this will create ban lines) </panel.string> <panel.string name="estate_override"> @@ -1932,7 +1932,7 @@ Only large parcels can be listed in search. name="public_access" top_pad="5" label_text.valign="center" - label_text.v_pad="-7" + label_text.v_pad="-2" width="278" /> <text type="string" diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 08ae0c233e..6963b5bb45 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -2000,6 +2000,16 @@ function="ToggleControl" parameter="DebugShowMemory" /> </menu_item_check> + <menu_item_check + label="Show Private Mem Info" + name="Show Private Mem Info"> + <menu_item_check.on_check + function="CheckControl" + parameter="DebugShowPrivateMem" /> + <menu_item_check.on_click + function="ToggleControl" + parameter="DebugShowPrivateMem" /> + </menu_item_check> <menu_item_separator/> @@ -2747,18 +2757,6 @@ function="Floater.Toggle" parameter="region_debug_console" /> </menu_item_check> - <menu_item_check - label="Region Debug Console" - name="Region Debug Console" - shortcut="control|shift|`" - use_mac_ctrl="true"> - <menu_item_check.on_check - function="Floater.Visible" - parameter="region_debug_console" /> - <menu_item_check.on_click - function="Floater.Toggle" - parameter="region_debug_console" /> - </menu_item_check> <menu_item_separator /> diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index f008042a81..fcb4123b2e 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -6680,6 +6680,20 @@ Mute everyone? Here's your current balance of L$. Click Buy L$ to purchase more Linden Dollars. </notification> + <notification + icon="alertmodal.tga" + name="LowMemory" + type="alertmodal"> + Your memory pool is low. Some functions of SL are disabled to avoid crash. Please close other applications. Restart SL if this persists. + </notification> + + <notification + icon="alertmodal.tga" + name="ForceQuitDueToLowMemory" + type="alertmodal"> + SL will quit in 30 seconds due to out of memory. + </notification> + <notification name="PopupAttempt" icon="Popup_Caution" diff --git a/indra/test_apps/llplugintest/llmediaplugintest.cpp b/indra/test_apps/llplugintest/llmediaplugintest.cpp index fd46626ff1..30fa832c7d 100644 --- a/indra/test_apps/llplugintest/llmediaplugintest.cpp +++ b/indra/test_apps/llplugintest/llmediaplugintest.cpp @@ -1616,7 +1616,7 @@ mediaPanel* LLMediaPluginTest::addMediaPanel( std::string url ) std::string user_data_path = std::string( cwd ) + "/"; #endif media_source->setUserDataPath(user_data_path); - media_source->init( launcher_name, plugin_name, false ); + media_source->init( launcher_name, user_data_path, plugin_name, false ); media_source->setDisableTimeout(mDisableTimeout); // make a new panel and save parameters @@ -1856,7 +1856,7 @@ mediaPanel* LLMediaPluginTest::replaceMediaPanel( mediaPanel* panel, std::string #endif media_source->setUserDataPath(user_data_path); - media_source->init( launcher_name, plugin_name, false ); + media_source->init( launcher_name, user_data_path, plugin_name, false ); media_source->setDisableTimeout(mDisableTimeout); // make a new panel and save parameters |