aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/viewer.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:50 -0500
committerJacek Antonelli2008-08-15 23:44:50 -0500
commit89fe5dab825a62a0e3fd8d248cbc91c65eb2a426 (patch)
treebcff14b7888d04a2fec799c59369f6095224bd08 /linden/indra/newview/viewer.cpp
parentSecond Life viewer sources 1.13.3.2 (diff)
downloadmeta-impy-89fe5dab825a62a0e3fd8d248cbc91c65eb2a426.zip
meta-impy-89fe5dab825a62a0e3fd8d248cbc91c65eb2a426.tar.gz
meta-impy-89fe5dab825a62a0e3fd8d248cbc91c65eb2a426.tar.bz2
meta-impy-89fe5dab825a62a0e3fd8d248cbc91c65eb2a426.tar.xz
Second Life viewer sources 1.14.0.0
Diffstat (limited to 'linden/indra/newview/viewer.cpp')
-rw-r--r--linden/indra/newview/viewer.cpp825
1 files changed, 438 insertions, 387 deletions
diff --git a/linden/indra/newview/viewer.cpp b/linden/indra/newview/viewer.cpp
index 19b5260..181e446 100644
--- a/linden/indra/newview/viewer.cpp
+++ b/linden/indra/newview/viewer.cpp
@@ -56,7 +56,12 @@
56#include <process.h> // _spawnl() 56#include <process.h> // _spawnl()
57#include <tchar.h> // For TCHAR support 57#include <tchar.h> // For TCHAR support
58 58
59#if LL_WINDOWS && _MSC_VER < 1400
59//#define LL_USE_SMARTHEAP 0 60//#define LL_USE_SMARTHEAP 0
61#else
62#define LL_USE_SMARTHEAP 0
63#endif
64
60#if LL_WINDOWS && LL_RELEASE_FOR_DOWNLOAD && LL_USE_SMARTHEAP 65#if LL_WINDOWS && LL_RELEASE_FOR_DOWNLOAD && LL_USE_SMARTHEAP
61#include "smrtheap/smrtheap.h" 66#include "smrtheap/smrtheap.h"
62#endif // LL_WINDOWS && LL_RELEASE_FOR_DOWNLOAD && LL_USE_SMARTHEAP 67#endif // LL_WINDOWS && LL_RELEASE_FOR_DOWNLOAD && LL_USE_SMARTHEAP
@@ -103,19 +108,23 @@
103// Linden library headers 108// Linden library headers
104// 109//
105 110
111#include "audioengine.h"
106#include "llcommon.h" 112#include "llcommon.h"
107#include "llapr.h" 113#include "llapr.h"
108#include "audioengine.h"
109#include "llcachename.h" 114#include "llcachename.h"
110#include "llviewercontrol.h" 115#include "llcurl.h"
111#include "llcriticaldamp.h" 116#include "llcriticaldamp.h"
112#include "lldir.h" 117#include "lldir.h"
113#include "lleconomy.h" 118#include "lleconomy.h"
119#include "llerrorcontrol.h"
114#include "llflexibleobject.h" 120#include "llflexibleobject.h"
115#include "llfasttimer.h" 121#include "llfasttimer.h"
116#include "llfocusmgr.h" 122#include "llfocusmgr.h"
117#include "llgroupmgr.h" 123#include "llgroupmgr.h"
124#include "llimage.h"
125#include "llimageworker.h"
118#include "lllfsthread.h" 126#include "lllfsthread.h"
127#include "llmemtype.h"
119#include "llmd5.h" 128#include "llmd5.h"
120#include "llsecondlifeurls.h" 129#include "llsecondlifeurls.h"
121#include "llversion.h" 130#include "llversion.h"
@@ -180,12 +189,15 @@
180#include "llstatusbar.h" 189#include "llstatusbar.h"
181#include "llsurface.h" 190#include "llsurface.h"
182#include "lltexlayer.h" 191#include "lltexlayer.h"
192#include "lltexturecache.h"
193#include "lltexturefetch.h"
183#include "lltoolbar.h" 194#include "lltoolbar.h"
184#include "lltoolmgr.h" 195#include "lltoolmgr.h"
185#include "lltracker.h" 196#include "lltracker.h"
186#include "llurlwhitelist.h" 197#include "llurlwhitelist.h"
187#include "llviewerbuild.h" 198#include "llviewerbuild.h"
188#include "llviewercamera.h" 199#include "llviewercamera.h"
200#include "llviewercontrol.h"
189#include "llviewerimagelist.h" 201#include "llviewerimagelist.h"
190#include "llviewerkeyboard.h" 202#include "llviewerkeyboard.h"
191#include "llviewermenu.h" 203#include "llviewermenu.h"
@@ -202,7 +214,6 @@
202#include "llvoavatar.h" 214#include "llvoavatar.h"
203#include "llvograss.h" 215#include "llvograss.h"
204#include "llvotree.h" 216#include "llvotree.h"
205#include "llvotreenew.h"
206#include "llvovolume.h" // To set a static member. 217#include "llvovolume.h" // To set a static member.
207#include "llvowater.h" 218#include "llvowater.h"
208#include "llvolume.h" 219#include "llvolume.h"
@@ -236,11 +247,15 @@
236#endif 247#endif
237 248
238#include "llmediaengine.h" 249#include "llmediaengine.h"
239#include "llmozlib.h"
240 250
241extern LLErrorBuffer gErrorBuffer; 251#if LL_LIBXUL_ENABLED
252#include "llmozlib.h"
253#endif // LL_LIBXUL_ENABLED
242 254
255/////////////////////////////////////////////////////////////////////////////////
243// Support for crash handling. 256// Support for crash handling.
257/////////////////////////////////////////////////////////////////////////////////
258
244void errorCallback(const std::string &error_string); 259void errorCallback(const std::string &error_string);
245S32 gCrashBehavior = CRASH_BEHAVIOR_ASK; 260S32 gCrashBehavior = CRASH_BEHAVIOR_ASK;
246void (*gCrashCallback)(void) = NULL; 261void (*gCrashCallback)(void) = NULL;
@@ -253,9 +268,10 @@ BOOL gHandleKeysAsync = FALSE;
253BOOL gProbeHardware = TRUE; 268BOOL gProbeHardware = TRUE;
254std::string gSerialNumber; 269std::string gSerialNumber;
255 270
256// 271/////////////////////////////////////////////////////////////////////////////////
257// Application constants 272// Application constants
258// 273/////////////////////////////////////////////////////////////////////////////////
274
259S32 gStartupState = STATE_FIRST; 275S32 gStartupState = STATE_FIRST;
260 276
261BOOL gHaveSavedSnapshot = FALSE; 277BOOL gHaveSavedSnapshot = FALSE;
@@ -270,7 +286,6 @@ const F32 DEFAULT_AFK_TIMEOUT = 5.f * 60.f; // time with no input before user fl
270 286
271const char *VFS_DATA_FILE_BASE = "data.db2.x."; 287const char *VFS_DATA_FILE_BASE = "data.db2.x.";
272const char *VFS_INDEX_FILE_BASE = "index.db2.x."; 288const char *VFS_INDEX_FILE_BASE = "index.db2.x.";
273const U32 VFS_SIZE_MAP[4] = {52428800, 209715200, 524288000, 1048576000};
274 289
275const F32 MAX_USER_FOG_RATIO = 4.f; 290const F32 MAX_USER_FOG_RATIO = 4.f;
276const F32 MIN_USER_FOG_RATIO = 0.5f; 291const F32 MIN_USER_FOG_RATIO = 0.5f;
@@ -333,6 +348,7 @@ BOOL gDisconnected = FALSE;
333 348
334// Tells us to clean up the cache directory in the case of network corruption 349// Tells us to clean up the cache directory in the case of network corruption
335BOOL gPurgeOnExit = FALSE; 350BOOL gPurgeOnExit = FALSE;
351BOOL gPurgeCache = FALSE;
336 352
337// Allow multiple viewers in ReleaseForDownload 353// Allow multiple viewers in ReleaseForDownload
338#if LL_RELEASE_FOR_DOWNLOAD 354#if LL_RELEASE_FOR_DOWNLOAD
@@ -340,6 +356,7 @@ BOOL gMultipleViewersOK = FALSE;
340#else 356#else
341BOOL gMultipleViewersOK = TRUE; 357BOOL gMultipleViewersOK = TRUE;
342#endif 358#endif
359BOOL gSecondInstance = FALSE;
343 360
344LLString gArgs; 361LLString gArgs;
345 362
@@ -356,7 +373,6 @@ LLString gOldSettingsFileName;
356BOOL gPrintMessagesThisFrame = FALSE; 373BOOL gPrintMessagesThisFrame = FALSE;
357const char* DEFAULT_SETTINGS_FILE = "settings.xml"; 374const char* DEFAULT_SETTINGS_FILE = "settings.xml";
358const char* LEGACY_DEFAULT_SETTINGS_FILE = "settings.ini"; 375const char* LEGACY_DEFAULT_SETTINGS_FILE = "settings.ini";
359BOOL gRenderLightGlows = FALSE; // off by default for speed
360BOOL gUseWireframe = FALSE; 376BOOL gUseWireframe = FALSE;
361BOOL gRunLocal = FALSE; 377BOOL gRunLocal = FALSE;
362LLUUID gViewerDigest; // MD5 digest of the viewer's executable file. 378LLUUID gViewerDigest; // MD5 digest of the viewer's executable file.
@@ -374,14 +390,8 @@ const F32 LOGOUT_REQUEST_TIME = 6.f; // this will be cut short by the LogoutR
374F32 gLogoutMaxTime = LOGOUT_REQUEST_TIME; 390F32 gLogoutMaxTime = LOGOUT_REQUEST_TIME;
375 391
376// Map scale in pixels per region 392// Map scale in pixels per region
377F32 gMapScale = 128.f; 393F32 gMapScale = 128.f;
378F32 gMiniMapScale = 128.f; 394F32 gMiniMapScale = 128.f;
379
380// User interface/rendering globals
381
382extern LLPointer<LLImageGL> gStartImageGL;
383extern BOOL gDebugWindowProc;
384extern BOOL gAvatarBacklight;
385 395
386// Sky object, globals 396// Sky object, globals
387LLSky gSky; 397LLSky gSky;
@@ -401,7 +411,12 @@ BOOL gRestoreGL = FALSE;
401LLGlobalEconomy *gGlobalEconomy = NULL; 411LLGlobalEconomy *gGlobalEconomy = NULL;
402 412
403// VFS globals - see viewer.h 413// VFS globals - see viewer.h
404LLVFS *gStaticVFS = NULL; 414LLVFS* gStaticVFS = NULL;
415
416// Threads
417LLTextureCache* gTextureCache = NULL;
418LLWorkerThread* gImageDecodeThread = NULL;
419LLTextureFetch* gTextureFetch = NULL;
405 420
406// Debugging 421// Debugging
407FILE *gDebugFile = NULL; // File pointer used by the function which writes debug data. 422FILE *gDebugFile = NULL; // File pointer used by the function which writes debug data.
@@ -481,13 +496,6 @@ static const char USAGE[] = "\n"
481#if !LL_RELEASE_FOR_DOWNLOAD 496#if !LL_RELEASE_FOR_DOWNLOAD
482" -sim <simulator_ip> specify the simulator ip address\n" 497" -sim <simulator_ip> specify the simulator ip address\n"
483" -local run without simulator\n" 498" -local run without simulator\n"
484" -debugst <value> debug mask |= 1<<value (e.g. 1=LLERR_IMAGE, 2=LLERR_MESSAGE)\n"
485" -errmask <mask> 32 bit bitmask for error type mask\n"
486" -logcontrol <control> <level> <mask> specify admin logging control\n"
487" <time> <location> control: 0=replace, 1=merge\n"
488" level: 0=debug, 1=inf, 2=wrn, 3=err\n"
489" mask: 32 bit bitmask\n"
490" time,location: 0=no, 1=yes\n"
491#endif 499#endif
492" -god log in as god if you have god access\n" 500" -god log in as god if you have god access\n"
493" -purge delete files in cache\n" 501" -purge delete files in cache\n"
@@ -516,7 +524,6 @@ BOOL gUseAudio = TRUE;
516BOOL gUseFMOD = TRUE; 524BOOL gUseFMOD = TRUE;
517BOOL gConnectToSomething = TRUE; 525BOOL gConnectToSomething = TRUE;
518BOOL gLogMessages = FALSE; 526BOOL gLogMessages = FALSE;
519BOOL gLogUTC = TRUE;
520BOOL gRequestInventoryLibrary = TRUE; 527BOOL gRequestInventoryLibrary = TRUE;
521BOOL gAcceptTOS = FALSE; 528BOOL gAcceptTOS = FALSE;
522BOOL gAcceptCriticalMessage = FALSE; 529BOOL gAcceptCriticalMessage = FALSE;
@@ -558,12 +565,13 @@ protected:
558// Application initialization and cleanup 565// Application initialization and cleanup
559// 566//
560void init_marker_file(); 567void init_marker_file();
561void init_crash_logging(); 568void init_crash_handler();
569void init_logging();
562void create_console(); 570void create_console();
563void write_system_info(); 571void write_system_info();
564int parse_args(int argc, char **argv); 572int parse_args(int argc, char **argv);
565void saved_settings_to_globals(); 573void saved_settings_to_globals();
566BOOL init_vfs_viewer(); 574BOOL init_cache();
567void purge_cache(); 575void purge_cache();
568void cleanup_app(); 576void cleanup_app();
569void disconnect_viewer(void *); // Don't use directly - use do_disconnect() 577void disconnect_viewer(void *); // Don't use directly - use do_disconnect()
@@ -609,10 +617,6 @@ OSStatus simpleDialogHandler(EventHandlerCallRef handler, EventRef event, void *
609OSStatus DisplayReleaseNotes(void); 617OSStatus DisplayReleaseNotes(void);
610#endif // LL_DARWIN 618#endif // LL_DARWIN
611 619
612#ifdef LL_WINDOWS
613extern LPWSTR gIconResource;
614#endif
615
616void ui_audio_callback(const LLUUID& uuid, F32 volume) 620void ui_audio_callback(const LLUUID& uuid, F32 volume)
617{ 621{
618 if (gAudiop) 622 if (gAudiop)
@@ -624,7 +628,7 @@ void ui_audio_callback(const LLUUID& uuid, F32 volume)
624#if LL_WINDOWS 628#if LL_WINDOWS
625BOOL CALLBACK login_dialog_func(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lparam) 629BOOL CALLBACK login_dialog_func(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lparam)
626{ 630{
627 char buffer[MAX_STRING]; 631 char buffer[MAX_STRING]; /* Flawfinder: ignore */
628 switch(msg) 632 switch(msg)
629 { 633 {
630 case WM_INITDIALOG: 634 case WM_INITDIALOG:
@@ -755,7 +759,7 @@ MEM_BOOL MEM_CALLBACK first_mem_error_handler(MEM_ERROR_INFO *errorInfo)
755MEM_BOOL MEM_CALLBACK second_mem_error_handler(MEM_ERROR_INFO *errorInfo) 759MEM_BOOL MEM_CALLBACK second_mem_error_handler(MEM_ERROR_INFO *errorInfo)
756{ 760{
757 // Just in case "llerrs" and "llendl" cause another out-of-memory. 761 // Just in case "llerrs" and "llendl" cause another out-of-memory.
758 _llcrash_and_loop(); 762 LLError::crashAndLoop("");
759 // NOTREACHED better not be! 763 // NOTREACHED better not be!
760 return 0; 764 return 0;
761} 765}
@@ -778,10 +782,18 @@ int main( int argc, char **argv )
778 // This will eventually be done in LLApp 782 // This will eventually be done in LLApp
779 LLCommon::initClass(); 783 LLCommon::initClass();
780 // This should eventually be done in LLAppViewer 784 // This should eventually be done in LLAppViewer
781 LLWorkerThread::initClass(); 785# if MEM_TRACK_MEM
782 LLVFSThread::initClass(true, true); 786 static const bool enable_threads = false;
783 LLLFSThread::initClass(true, true); 787# else
784 LLImageFormatted::initClass(true, true); 788 static const bool enable_threads = true;
789# endif
790 LLVFSThread::initClass(enable_threads && true);
791 LLLFSThread::initClass(enable_threads && true);
792 // Image decoding
793 gImageDecodeThread = new LLWorkerThread("ImageDecode", enable_threads && true);
794 gTextureCache = new LLTextureCache(enable_threads && true);
795 gTextureFetch = new LLTextureFetch(gTextureCache, enable_threads && false);
796 LLImageWorker::initClass(gImageDecodeThread);
785 LLImageJ2C::openDSO(); 797 LLImageJ2C::openDSO();
786#endif 798#endif
787 799
@@ -798,7 +810,7 @@ int main( int argc, char **argv )
798 810
799 const S32 MAX_ARGS = 100; 811 const S32 MAX_ARGS = 100;
800 int argc = 0; 812 int argc = 0;
801 char *argv[MAX_ARGS]; 813 char* argv[MAX_ARGS]; /* Flawfinder: ignore */
802 814
803 char *token = NULL; 815 char *token = NULL;
804 if( cmd_line_including_exe_name[0] == '\"' ) 816 if( cmd_line_including_exe_name[0] == '\"' )
@@ -818,7 +830,7 @@ int main( int argc, char **argv )
818 { 830 {
819 argv[argc++] = token; 831 argv[argc++] = token;
820 /* Get next token: */ 832 /* Get next token: */
821 if (*(token + strlen(token) + 1) == '\"') 833 if (*(token + strlen(token) + 1) == '\"') /* Flawfinder: ignore*/
822 { 834 {
823 token = strtok( NULL, "\""); 835 token = strtok( NULL, "\"");
824 } 836 }
@@ -836,25 +848,25 @@ int main( int argc, char **argv )
836 // the gUserServerName (which gets passed to the crash reporter). 848 // the gUserServerName (which gets passed to the crash reporter).
837 // We're assuming that they're trying to log into the same grid as last 849 // We're assuming that they're trying to log into the same grid as last
838 // time, which seems fairly reasonable. 850 // time, which seems fairly reasonable.
839 sprintf(gUserServerName,"%s", gUserServerDomainName[UserServerDefaultChoice].mName); 851 snprintf(gUserServerName, MAX_STRING, "%s", gUserServerDomainName[UserServerDefaultChoice].mName); /* Flawfinder: ignore */
840 S32 j; 852 S32 j;
841 for (j = 1; j < argc; j++) 853 for (j = 1; j < argc; j++)
842 { 854 {
843 if (!strcmp(argv[j], "--aditi")) 855 if (!strcmp(argv[j], "--aditi"))
844 { 856 {
845 sprintf(gUserServerName,"%s", gUserServerDomainName[USERSERVER_ADITI].mName); 857 snprintf(gUserServerName, MAX_STRING, "%s", gUserServerDomainName[USERSERVER_ADITI].mName); /* Flawfinder: ignore */
846 } 858 }
847 else if (!strcmp(argv[j], "--agni")) 859 else if (!strcmp(argv[j], "--agni"))
848 { 860 {
849 sprintf(gUserServerName,"%s", gUserServerDomainName[USERSERVER_AGNI].mName); 861 snprintf(gUserServerName, MAX_STRING, "%s", gUserServerDomainName[USERSERVER_AGNI].mName); /* Flawfinder: ignore */
850 } 862 }
851 else if (!strcmp(argv[j], "--dmz")) 863 else if (!strcmp(argv[j], "--dmz"))
852 { 864 {
853 sprintf(gUserServerName,"%s", gUserServerDomainName[USERSERVER_DMZ].mName); 865 snprintf(gUserServerName, MAX_STRING, "%s", gUserServerDomainName[USERSERVER_DMZ].mName); /* Flawfinder: ignore */
854 } 866 }
855 else if (!strcmp(argv[j], "--siva")) 867 else if (!strcmp(argv[j], "--siva"))
856 { 868 {
857 sprintf(gUserServerName,"%s", gUserServerDomainName[USERSERVER_SIVA].mName); 869 snprintf(gUserServerName, MAX_STRING, "%s", gUserServerDomainName[USERSERVER_SIVA].mName); /* Flawfinder: ignore */
858 } 870 }
859 else if (!strcmp(argv[j], "--shakti")) 871 else if (!strcmp(argv[j], "--shakti"))
860 { 872 {
@@ -862,15 +874,19 @@ int main( int argc, char **argv )
862 } 874 }
863 else if (!strcmp(argv[j], "--durga")) 875 else if (!strcmp(argv[j], "--durga"))
864 { 876 {
865 sprintf(gUserServerName,"%s", gUserServerDomainName[USERSERVER_DURGA].mName); 877 snprintf(gUserServerName, MAX_STRING, "%s", gUserServerDomainName[USERSERVER_DURGA].mName); /* Flawfinder: ignore */
866 } 878 }
867 else if (!strcmp(argv[j], "--soma")) 879 else if (!strcmp(argv[j], "--soma"))
868 { 880 {
869 sprintf(gUserServerName,"%s", gUserServerDomainName[USERSERVER_SOMA].mName); 881 snprintf(gUserServerName, MAX_STRING, "%s", gUserServerDomainName[USERSERVER_SOMA].mName); /* Flawfinder: ignore */
870 } 882 }
871 else if (!strcmp(argv[j], "--ganga")) 883 else if (!strcmp(argv[j], "--ganga"))
872 { 884 {
873 sprintf(gUserServerName,"%s", gUserServerDomainName[USERSERVER_GANGA].mName); 885 snprintf(gUserServerName, MAX_STRING, "%s", gUserServerDomainName[USERSERVER_GANGA].mName); /* Flawfinder: ignore */
886 }
887 else if (!strcmp(argv[j], "--vaak"))
888 {
889 sprintf(gUserServerName,"%s", gUserServerDomainName[USERSERVER_VAAK].mName);
874 } 890 }
875 else if (!strcmp(argv[j], "--uma")) 891 else if (!strcmp(argv[j], "--uma"))
876 { 892 {
@@ -880,11 +896,11 @@ int main( int argc, char **argv )
880 { 896 {
881 if (!strcmp(argv[j], "-")) 897 if (!strcmp(argv[j], "-"))
882 { 898 {
883 sprintf(gUserServerName,"%s", LOOPBACK_ADDRESS_STRING); 899 snprintf(gUserServerName, MAX_STRING, "%s", LOOPBACK_ADDRESS_STRING); /* Flawfinder: ignore */
884 } 900 }
885 else 901 else
886 { 902 {
887 snprintf(gUserServerName, MAX_STRING, "%s", argv[j]); 903 snprintf(gUserServerName, MAX_STRING, "%s", argv[j]); /* Flawfinder: ignore */
888 } 904 }
889 } 905 }
890 else if (!strcmp(argv[j], "-multiple")) 906 else if (!strcmp(argv[j], "-multiple"))
@@ -911,15 +927,24 @@ int main( int argc, char **argv )
911 // that touches files should really go through the lldir API 927 // that touches files should really go through the lldir API
912 gDirUtilp->initAppDirs("SecondLife"); 928 gDirUtilp->initAppDirs("SecondLife");
913 929
930 //
931 // Set up logging defaults for the viewer
932 //
933 LLError::initForApplication(
934 gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, ""));
935 LLError::setFatalFunction(errorCallback);
936
937
914#if LL_RELEASE_FOR_DOWNLOAD && LL_SEND_CRASH_REPORTS 938#if LL_RELEASE_FOR_DOWNLOAD && LL_SEND_CRASH_REPORTS
915 // 939 //
916 // Crash log if we hard crashed. 940 // Crash log if we hard crashed.
917 // Initialize crash logging 941 // Initialize crash logging
918 // Set up SecondLife.log
919 // 942 //
920 init_crash_logging(); 943 init_crash_handler();
921#endif 944#endif
922 945 // Set up SecondLife.log
946 init_logging();
947
923 // 948 //
924 // OK to write stuff to logs now, we've now crash reported if necessary 949 // OK to write stuff to logs now, we've now crash reported if necessary
925 // 950 //
@@ -939,7 +964,7 @@ int main( int argc, char **argv )
939 { 964 {
940 // On the Mac, read in arguments.txt (if it exists) and process it for additional arguments. 965 // On the Mac, read in arguments.txt (if it exists) and process it for additional arguments.
941 LLString args; 966 LLString args;
942 if(LLString::read(args, "arguments.txt")) 967 if(LLString::read(args, "arguments.txt")) /* Flawfinder: ignore*/
943 { 968 {
944 // The arguments file exists. 969 // The arguments file exists.
945 // It should consist of command line arguments separated by newlines. 970 // It should consist of command line arguments separated by newlines.
@@ -1051,35 +1076,6 @@ int main( int argc, char **argv )
1051 gStartTime = totalTime(); 1076 gStartTime = totalTime();
1052 1077
1053 1078
1054 //
1055 // Set up logging defaults for the viewer
1056 //
1057#if 0 // This is bad... it disables lldebugs... if some spam is annoying, use lldebugst or comment it out.
1058 // Reduced spam diet for the viewer
1059 gErrorStream.setLevel( LLErrorStream::INFO );
1060#endif
1061 //gErrorStream.setLevel( LLErrorStream::WARN );
1062 gErrorStream.setTime(FALSE);
1063 gErrorStream.setPrintLocation(FALSE);
1064 gErrorStream.setErrorCallback(errorCallback);
1065
1066#if LL_DARWIN || LL_LINUX
1067 // Disable syslogging - the viewer shouldn't spam there
1068 gErrorBuffer.enableSyslog(FALSE);
1069#endif
1070
1071#if LL_DARWIN
1072 // On Mac OS X, stderr from apps launched from the Finder goes to the console log.
1073 // It's generally considered bad form to spam too much there.
1074
1075 // If stdin is a tty, assume the user launched from the command line and therefore wants to see stderr.
1076 // Otherwise, assume we've been launched from the finder and shouldn't spam stderr.
1077 if(!isatty(0))
1078 {
1079 gErrorBuffer.enableError(FALSE);
1080 }
1081#endif
1082
1083 //////////////////////////////////////// 1079 ////////////////////////////////////////
1084 // 1080 //
1085 // Process ini files 1081 // Process ini files
@@ -1119,7 +1115,10 @@ int main( int argc, char **argv )
1119 // successfully handed off URL to existing instance, exit 1115 // successfully handed off URL to existing instance, exit
1120 return 1; 1116 return 1;
1121 } 1117 }
1122 else if (another_instance_running()) 1118
1119 gSecondInstance = another_instance_running();
1120
1121 if (gSecondInstance)
1123 { 1122 {
1124 std::ostringstream msg; 1123 std::ostringstream msg;
1125 msg << 1124 msg <<
@@ -1178,7 +1177,7 @@ int main( int argc, char **argv )
1178 command_str += gUserServerName; 1177 command_str += gUserServerName;
1179 // XXX -- We need to exit fullscreen mode for this to work. 1178 // XXX -- We need to exit fullscreen mode for this to work.
1180 // XXX -- system() also doesn't wait for completion. Hmm... 1179 // XXX -- system() also doesn't wait for completion. Hmm...
1181 system(command_str.c_str()); 1180 system(command_str.c_str()); /* Flawfinder: Ignore */
1182#elif LL_LINUX 1181#elif LL_LINUX
1183 std::string cmd =gDirUtilp->getAppRODataDir(); 1182 std::string cmd =gDirUtilp->getAppRODataDir();
1184 cmd += gDirUtilp->getDirDelimiter(); 1183 cmd += gDirUtilp->getDirDelimiter();
@@ -1194,7 +1193,7 @@ int main( int argc, char **argv )
1194 pid_t pid = fork(); 1193 pid_t pid = fork();
1195 if (pid == 0) 1194 if (pid == 0)
1196 { // child 1195 { // child
1197 execv(cmd.c_str(), cmdargv); 1196 execv(cmd.c_str(), cmdargv); /* Flawfinder: Ignore */
1198 llwarns << "execv failure when trying to start " << cmd << llendl; 1197 llwarns << "execv failure when trying to start " << cmd << llendl;
1199 _exit(1); // avoid atexit() 1198 _exit(1); // avoid atexit()
1200 } else { 1199 } else {
@@ -1218,8 +1217,10 @@ int main( int argc, char **argv )
1218 } 1217 }
1219 else 1218 else
1220 { 1219 {
1220 gSecondInstance = another_instance_running();
1221
1221 /* Don't start another instance if using -multiple 1222 /* Don't start another instance if using -multiple
1222 if (another_instance_running()) 1223 if (gSecondInstance)
1223 { 1224 {
1224 //RN: if we received a URL, hand it off to the existing instance 1225 //RN: if we received a URL, hand it off to the existing instance
1225 if (LLURLSimString::parse()) 1226 if (LLURLSimString::parse())
@@ -1262,6 +1263,13 @@ int main( int argc, char **argv )
1262 // Merge with the command line overrides 1263 // Merge with the command line overrides
1263 gSavedSettings.applyOverrides(gCommandLineSettings); 1264 gSavedSettings.applyOverrides(gCommandLineSettings);
1264 1265
1266 // Need to do this before calling parseAlerts
1267 gUICtrlFactory = new LLViewerUICtrlFactory();
1268
1269 // Pre-load alerts.xml to define the warnings settings (always loads from skins/xui/en-us/)
1270 // Do this *before* loading the settings file
1271 LLAlertDialog::parseAlerts("alerts.xml", &gSavedSettings, TRUE);
1272
1265 // Overwrite default settings with user settings 1273 // Overwrite default settings with user settings
1266 llinfos << "Loading configuration file " << gSettingsFileName << llendl; 1274 llinfos << "Loading configuration file " << gSettingsFileName << llendl;
1267 if (0 == gSavedSettings.loadFromFile(gSettingsFileName)) 1275 if (0 == gSavedSettings.loadFromFile(gSettingsFileName))
@@ -1283,19 +1291,13 @@ int main( int argc, char **argv )
1283 gSavedSettings.applyOverrides(gCommandLineForcedSettings); 1291 gSavedSettings.applyOverrides(gCommandLineForcedSettings);
1284 1292
1285 gLastRunVersion = gSavedSettings.getString("LastRunVersion"); 1293 gLastRunVersion = gSavedSettings.getString("LastRunVersion");
1294
1295 settings_version_fixup();
1286 1296
1287 // Get the single value from the crash settings file, if it exists 1297 // Get the single value from the crash settings file, if it exists
1288 std::string crash_settings_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, CRASH_SETTINGS_FILE); 1298 std::string crash_settings_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, CRASH_SETTINGS_FILE);
1289 gCrashSettings.loadFromFile(crash_settings_filename.c_str()); 1299 gCrashSettings.loadFromFile(crash_settings_filename.c_str());
1290 1300
1291 // Purge cache if user requested it
1292 if (gSavedSettings.getBOOL("PurgeCacheOnStartup") ||
1293 gSavedSettings.getBOOL("PurgeCacheOnNextStartup"))
1294 {
1295 gSavedSettings.setBOOL("PurgeCacheOnNextStartup", FALSE);
1296 purge_cache();
1297 }
1298
1299 ///////////////////////////////////////////////// 1301 /////////////////////////////////////////////////
1300 // OS-specific login dialogs 1302 // OS-specific login dialogs
1301 ///////////////////////////////////////////////// 1303 /////////////////////////////////////////////////
@@ -1328,7 +1330,7 @@ int main( int argc, char **argv )
1328 1330
1329 if (gSavedSettings.getBOOL("VerboseLogs")) 1331 if (gSavedSettings.getBOOL("VerboseLogs"))
1330 { 1332 {
1331 gErrorStream.setPrintLocation(TRUE); 1333 LLError::setPrintLocation(true);
1332 } 1334 }
1333 1335
1334#if !LL_RELEASE_FOR_DOWNLOAD 1336#if !LL_RELEASE_FOR_DOWNLOAD
@@ -1345,11 +1347,11 @@ int main( int argc, char **argv )
1345 LLString custom_server = gSavedSettings.getString("CustomServer"); 1347 LLString custom_server = gSavedSettings.getString("CustomServer");
1346 if (custom_server.empty()) 1348 if (custom_server.empty())
1347 { 1349 {
1348 sprintf(gUserServerName,"none"); 1350 snprintf(gUserServerName, MAX_STRING, "none"); /* Flawfinder: ignore */
1349 } 1351 }
1350 else 1352 else
1351 { 1353 {
1352 sprintf(gUserServerName,"%s", custom_server.c_str()); 1354 snprintf(gUserServerName, MAX_STRING, "%s", custom_server.c_str()); /* Flawfinder: ignore */
1353 } 1355 }
1354 } 1356 }
1355 } 1357 }
@@ -1365,6 +1367,9 @@ int main( int argc, char **argv )
1365 LLString viewer_art_filename = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"viewerart.xml"); 1367 LLString viewer_art_filename = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"viewerart.xml");
1366 llinfos << "Loading art table from " << viewer_art_filename << llendl; 1368 llinfos << "Loading art table from " << viewer_art_filename << llendl;
1367 gViewerArt.loadFromFile(viewer_art_filename.c_str(), FALSE); 1369 gViewerArt.loadFromFile(viewer_art_filename.c_str(), FALSE);
1370 LLString textures_filename = gDirUtilp->getExpandedFilename(LL_PATH_SKINS, "textures", "textures.xml");
1371 llinfos << "Loading art table from " << textures_filename << llendl;
1372 gViewerArt.loadFromFile(textures_filename.c_str(), FALSE);
1368 1373
1369 LLString colors_base_filename = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "colors_base.xml"); 1374 LLString colors_base_filename = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "colors_base.xml");
1370 llinfos << "Loading base colors from " << colors_base_filename << llendl; 1375 llinfos << "Loading base colors from " << colors_base_filename << llendl;
@@ -1388,19 +1393,14 @@ int main( int argc, char **argv )
1388 &gImageList, 1393 &gImageList,
1389 ui_audio_callback, 1394 ui_audio_callback,
1390 &LLUI::sGLScaleFactor); 1395 &LLUI::sGLScaleFactor);
1391
1392 gUICtrlFactory = new LLViewerUICtrlFactory();
1393 1396
1397 gUICtrlFactory->setupPaths(); // update paths with correct language set
1394 1398
1395 ///////////////////////////////////////////////// 1399 /////////////////////////////////////////////////
1396 // 1400 //
1397 // Load settings files 1401 // Load settings files
1398 // 1402 //
1399 // 1403 //
1400 // XUI:translate? Should be OK to get the controldef first
1401 // Pre-load alerts.xml to define the warnings settings (always loads from skins/xui/en-us/)
1402 LLAlertDialog::parseAlerts("alerts.xml", &gSavedSettings, TRUE);
1403
1404 LLGroupMgr::parseRoleActions("role_actions.xml"); 1404 LLGroupMgr::parseRoleActions("role_actions.xml");
1405 1405
1406 // Move certain saved settings into global variables for speed 1406 // Move certain saved settings into global variables for speed
@@ -1500,11 +1500,6 @@ int main( int argc, char **argv )
1500 llwarns << " Someone took over my exception handler (post hardware probe)!" << llendl; 1500 llwarns << " Someone took over my exception handler (post hardware probe)!" << llendl;
1501 } 1501 }
1502 1502
1503 if (gFeatureManagerp->initPCIFeatureMasks())
1504 {
1505 // User is looking at "bad device" web pages, exit
1506 return 0;
1507 }
1508 gGLManager.mVRAM = gDXHardware.getVRAM(); 1503 gGLManager.mVRAM = gDXHardware.getVRAM();
1509 llinfos << "Detected VRAM: " << gGLManager.mVRAM << llendl; 1504 llinfos << "Detected VRAM: " << gGLManager.mVRAM << llendl;
1510#endif 1505#endif
@@ -1524,7 +1519,8 @@ int main( int argc, char **argv )
1524 // 1519 //
1525 // Initialize the VFS, and gracefully handle initialization errors 1520 // Initialize the VFS, and gracefully handle initialization errors
1526 // 1521 //
1527 if (!init_vfs_viewer()) 1522
1523 if (!init_cache())
1528 { 1524 {
1529 std::ostringstream msg; 1525 std::ostringstream msg;
1530 msg << 1526 msg <<
@@ -1541,7 +1537,7 @@ int main( int argc, char **argv )
1541 OSMB_OK); 1537 OSMB_OK);
1542 return 1; 1538 return 1;
1543 } 1539 }
1544 1540
1545#if LL_DARWIN 1541#if LL_DARWIN
1546 // Display the release notes for the current version 1542 // Display the release notes for the current version
1547 if(!gHideLinks && gCurrentVersion != gLastRunVersion) 1543 if(!gHideLinks && gCurrentVersion != gLastRunVersion)
@@ -1572,8 +1568,9 @@ int main( int argc, char **argv )
1572 LLSplashScreen::hide(); 1568 LLSplashScreen::hide();
1573 1569
1574 // HACK: Need a non-const char * for stupid window name (propagated deep down) 1570 // HACK: Need a non-const char * for stupid window name (propagated deep down)
1575 char window_title_str[256]; 1571 char window_title_str[256]; /* Flawfinder: ignore */
1576 strcpy(window_title_str, gWindowTitle.c_str()); 1572 strncpy(window_title_str, gWindowTitle.c_str(), sizeof(window_title_str) - 1); /* Flawfinder: ignore */
1573 window_title_str[sizeof(window_title_str) - 1] = '\0';
1577 1574
1578 // always start windowed 1575 // always start windowed
1579 gViewerWindow = new LLViewerWindow(window_title_str, "Second Life", 1576 gViewerWindow = new LLViewerWindow(window_title_str, "Second Life",
@@ -1618,10 +1615,6 @@ int main( int argc, char **argv )
1618 write_debug(gGLManager.getGLInfoString()); 1615 write_debug(gGLManager.getGLInfoString());
1619 llinfos << gGLManager.getGLInfoString() << llendl; 1616 llinfos << gGLManager.getGLInfoString() << llendl;
1620 1617
1621 char tmp_str[256];
1622 sprintf(tmp_str, "Allocated %d bytes of AGP memory\n", gPipeline.getAGPMemUsage());
1623 write_debug(tmp_str);
1624
1625 //load key settings 1618 //load key settings
1626 bind_keyboard_functions(); 1619 bind_keyboard_functions();
1627 1620
@@ -1634,7 +1627,7 @@ int main( int argc, char **argv )
1634 gViewerKeyboard.loadBindings(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"custom_keys.ini").c_str()); 1627 gViewerKeyboard.loadBindings(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"custom_keys.ini").c_str());
1635 1628
1636 // Calculate the digest for the executable (takes < 90ms on a fast machine). 1629 // Calculate the digest for the executable (takes < 90ms on a fast machine).
1637 FILE* app_file = LLFile::fopen( gDirUtilp->getExecutablePathAndName().c_str(), "rb" ); 1630 FILE* app_file = LLFile::fopen( gDirUtilp->getExecutablePathAndName().c_str(), "rb" ); /* Flawfinder: ignore */
1638 if( app_file ) 1631 if( app_file )
1639 { 1632 {
1640 LLMD5 app_md5; 1633 LLMD5 app_md5;
@@ -1711,12 +1704,12 @@ BOOL another_instance_running()
1711 1704
1712 // If file doesn't exist, we create it 1705 // If file doesn't exist, we create it
1713 // If file does exist, try to get writing privilages 1706 // If file does exist, try to get writing privilages
1714 FILE *fMarker = LLFile::fopen(marker_file.c_str(), "rb"); 1707 FILE* fMarker = LLFile::fopen(marker_file.c_str(), "rb"); /* Flawfinder: ignore */
1715 if (fMarker != NULL) 1708 if (fMarker != NULL)
1716 { 1709 {
1717 // File exists, try opening with write permissions 1710 // File exists, try opening with write permissions
1718 fclose(fMarker); 1711 fclose(fMarker);
1719 fMarker = LLFile::fopen(marker_file.c_str(), "wb"); 1712 fMarker = LLFile::fopen(marker_file.c_str(), "wb"); /* Flawfinder: ignore */
1720 if (fMarker == NULL) 1713 if (fMarker == NULL)
1721 { 1714 {
1722 llinfos << "Marker file is locked." << llendl; 1715 llinfos << "Marker file is locked." << llendl;
@@ -1780,7 +1773,6 @@ void main_loop()
1780 // once per second debug info 1773 // once per second debug info
1781 if (debugTime.getElapsedTimeF32() > 1.f) 1774 if (debugTime.getElapsedTimeF32() > 1.f)
1782 { 1775 {
1783// llinfos << "AGP Byte mem: " << LLAGPArray<U8>::sBytesPad << llendl;
1784 debugTime.reset(); 1776 debugTime.reset();
1785 } 1777 }
1786#endif 1778#endif
@@ -1803,6 +1795,7 @@ void main_loop()
1803 { 1795 {
1804 LLFastTimer t3(LLFastTimer::FTM_IDLE); 1796 LLFastTimer t3(LLFastTimer::FTM_IDLE);
1805 idle(); 1797 idle();
1798 LLCurl::process();
1806 io_pump->pump(); 1799 io_pump->pump();
1807 io_pump->callback(); 1800 io_pump->callback();
1808 } 1801 }
@@ -1831,18 +1824,24 @@ void main_loop()
1831 // Sleep and run background threads 1824 // Sleep and run background threads
1832 { 1825 {
1833 LLFastTimer t2(LLFastTimer::FTM_SLEEP); 1826 LLFastTimer t2(LLFastTimer::FTM_SLEEP);
1834 1827 bool run_multiple_threads = gSavedSettings.getBOOL("RunMultipleThreads");
1828
1835 const F64 min_frame_time = 0.0; //(.0333 - .0010); // max video frame rate = 30 fps 1829 const F64 min_frame_time = 0.0; //(.0333 - .0010); // max video frame rate = 30 fps
1836 const F64 min_idle_time = 0.0; //(.0010); // min idle time = 1 ms 1830 const F64 min_idle_time = 0.0; //(.0010); // min idle time = 1 ms
1831 const F64 max_idle_time = run_multiple_threads ? min_idle_time : .005; // 5 ms
1837 idleTimer.reset(); 1832 idleTimer.reset();
1838 while(1) 1833 while(1)
1839 { 1834 {
1840 LLWorkerThread::updateClass(0); // unpauses the worker threads 1835 S32 work_pending = 0;
1841 S32 vfs_pending = LLVFSThread::updateClass(0); 1836 S32 io_pending = 0;
1842 S32 lfs_pending = LLLFSThread::updateClass(0); 1837 work_pending += gTextureCache->update(1); // unpauses the texture cache thread
1843 if (vfs_pending > 1000 || lfs_pending > 100) 1838 work_pending += gImageDecodeThread->update(1); // unpauses the image thread
1839 work_pending += gTextureFetch->update(1); // unpauses the texture fetch thread
1840 io_pending += LLVFSThread::updateClass(1);
1841 io_pending += LLLFSThread::updateClass(1);
1842 if (io_pending > 1000)
1844 { 1843 {
1845 ms_sleep(llmin(vfs_pending/100,100)); // give the vfs some time to catch up 1844 ms_sleep(llmin(io_pending/100,100)); // give the vfs some time to catch up
1846 } 1845 }
1847 if ( gNoRender 1846 if ( gNoRender
1848 || !gViewerWindow->mWindow->getVisible() 1847 || !gViewerWindow->mWindow->getVisible()
@@ -1871,15 +1870,23 @@ void main_loop()
1871 1870
1872 F64 frame_time = frameTimer.getElapsedTimeF64(); 1871 F64 frame_time = frameTimer.getElapsedTimeF64();
1873 F64 idle_time = idleTimer.getElapsedTimeF64(); 1872 F64 idle_time = idleTimer.getElapsedTimeF64();
1874 if (frame_time >= min_frame_time && idle_time >= min_idle_time) 1873 if (frame_time >= min_frame_time &&
1874 idle_time >= min_idle_time &&
1875 (!work_pending || idle_time >= max_idle_time))
1875 { 1876 {
1876 break; 1877 break;
1877 } 1878 }
1878 } 1879 }
1879 frameTimer.reset(); 1880 frameTimer.reset();
1880 1881
1881 // if (LLWorkerThread::threadCount()==1) //pauseALl() should only be required when on a single threaded client... 1882 // Prevent the worker threads from running while rendering.
1882 LLWorkerThread::pauseAll(); // Prevent the worker thread from running while rendering. 1883 // if (LLThread::processorCount()==1) //pause() should only be required when on a single processor client...
1884 if (run_multiple_threads == FALSE)
1885 {
1886 gTextureCache->pause();
1887 gImageDecodeThread->pause();
1888 // gTextureFetch->pause(); // Don't pause the fetch (IO) thread
1889 }
1883 //LLVFSThread::sLocal->pause(); // Prevent the VFS thread from running while rendering. 1890 //LLVFSThread::sLocal->pause(); // Prevent the VFS thread from running while rendering.
1884 //LLLFSThread::sLocal->pause(); // Prevent the LFS thread from running while rendering. 1891 //LLLFSThread::sLocal->pause(); // Prevent the LFS thread from running while rendering.
1885 } 1892 }
@@ -1970,12 +1977,12 @@ void init_marker_file()
1970 std::string marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.exec_marker"); 1977 std::string marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.exec_marker");
1971 llinfos << "Checking marker file for lock..." << llendl; 1978 llinfos << "Checking marker file for lock..." << llendl;
1972 1979
1973 FILE *fMarker = LLFile::fopen(marker_file.c_str(), "rb"); 1980 FILE* fMarker = LLFile::fopen(marker_file.c_str(), "rb"); /* Flawfinder: ignore */
1974 if (fMarker != NULL) 1981 if (fMarker != NULL)
1975 { 1982 {
1976 // File exists, try opening with write permissions 1983 // File exists, try opening with write permissions
1977 fclose(fMarker); 1984 fclose(fMarker);
1978 fMarker = LLFile::fopen(marker_file.c_str(), "wb"); 1985 fMarker = LLFile::fopen(marker_file.c_str(), "wb"); /* Flawfinder: ignore */
1979 if (fMarker == NULL) 1986 if (fMarker == NULL)
1980 { 1987 {
1981 // Another instance is running. Skip the rest of these operations. 1988 // Another instance is running. Skip the rest of these operations.
@@ -2004,7 +2011,7 @@ void init_marker_file()
2004#if LL_WINDOWS 2011#if LL_WINDOWS
2005 gMarkerFile = LLFile::_fsopen(marker_file.c_str(), "w", _SH_DENYWR); 2012 gMarkerFile = LLFile::_fsopen(marker_file.c_str(), "w", _SH_DENYWR);
2006#else 2013#else
2007 gMarkerFile = LLFile::fopen(marker_file.c_str(), "w"); 2014 gMarkerFile = LLFile::fopen(marker_file.c_str(), "w"); /* Flawfinder: ignore */
2008 if (gMarkerFile) 2015 if (gMarkerFile)
2009 { 2016 {
2010 int fd = fileno(gMarkerFile); 2017 int fd = fileno(gMarkerFile);
@@ -2040,7 +2047,7 @@ void init_marker_file()
2040 llinfos << "Exiting init_marker_file()." << llendl; 2047 llinfos << "Exiting init_marker_file()." << llendl;
2041} 2048}
2042 2049
2043void init_crash_logging() 2050void init_crash_handler()
2044{ 2051{
2045 ////////////////////////////////////////// 2052 //////////////////////////////////////////
2046 // 2053 //
@@ -2052,7 +2059,10 @@ void init_crash_logging()
2052 2059
2053 // Set the crash callback for the viewer 2060 // Set the crash callback for the viewer
2054 gCrashCallback = viewer_crash_callback; 2061 gCrashCallback = viewer_crash_callback;
2062}
2055 2063
2064void init_logging()
2065{
2056 // Remove the last ".old" log file. 2066 // Remove the last ".old" log file.
2057 std::string old_log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, 2067 std::string old_log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
2058 "SecondLife.old"); 2068 "SecondLife.old");
@@ -2072,16 +2082,13 @@ void init_crash_logging()
2072 2082
2073 // Set the log file to SecondLife.log 2083 // Set the log file to SecondLife.log
2074 2084
2075 if (!gErrorStream.setFile(log_file.c_str())) 2085 LLError::logToFile(log_file);
2076 {
2077 llinfos << "Error setting log file to " << log_file << llendl;
2078 }
2079} 2086}
2080 2087
2081void write_system_info() 2088void write_system_info()
2082{ 2089{
2083 write_debug("SL Log: "); 2090 write_debug("SL Log: ");
2084 write_debug(gErrorStream.getFilename()); 2091 write_debug(LLError::logFileName());
2085 write_debug("\n"); 2092 write_debug("\n");
2086 2093
2087 std::string tmp_str = gSecondLife 2094 std::string tmp_str = gSecondLife
@@ -2108,7 +2115,7 @@ void write_system_info()
2108 // Dump the local time and time zone 2115 // Dump the local time and time zone
2109 time_t now; 2116 time_t now;
2110 time(&now); 2117 time(&now);
2111 char tbuffer[256]; 2118 char tbuffer[256]; /* Flawfinder: ignore */
2112 strftime(tbuffer, 256, "%Y-%m-%dT%H:%M:%S %Z", localtime(&now)); 2119 strftime(tbuffer, 256, "%Y-%m-%dT%H:%M:%S %Z", localtime(&now));
2113 llinfos << "Local time: " << tbuffer << llendl; 2120 llinfos << "Local time: " << tbuffer << llendl;
2114 2121
@@ -2122,12 +2129,12 @@ void write_system_info()
2122void disable_win_error_reporting() 2129void disable_win_error_reporting()
2123{ 2130{
2124 const char win_xp_string[] = "Microsoft Windows XP"; 2131 const char win_xp_string[] = "Microsoft Windows XP";
2125 BOOL is_win_xp = ( gSysOS.getOSString().substr(0, strlen(win_xp_string) ) == win_xp_string ); 2132 BOOL is_win_xp = ( gSysOS.getOSString().substr(0, strlen(win_xp_string) ) == win_xp_string ); /* Flawfinder: ignore*/
2126 if( is_win_xp ) 2133 if( is_win_xp )
2127 { 2134 {
2128 // Note: we need to use run-time dynamic linking, because load-time dynamic linking will fail 2135 // Note: we need to use run-time dynamic linking, because load-time dynamic linking will fail
2129 // on systems that don't have the library installed (all non-Windows XP systems) 2136 // on systems that don't have the library installed (all non-Windows XP systems)
2130 HINSTANCE fault_rep_dll_handle = LoadLibrary(L"faultrep.dll"); 2137 HINSTANCE fault_rep_dll_handle = LoadLibrary(L"faultrep.dll"); /* Flawfinder: ignore */
2131 if( fault_rep_dll_handle ) 2138 if( fault_rep_dll_handle )
2132 { 2139 {
2133 pfn_ADDEREXCLUDEDAPPLICATIONA pAddERExcludedApplicationA = (pfn_ADDEREXCLUDEDAPPLICATIONA) GetProcAddress(fault_rep_dll_handle, "AddERExcludedApplicationA"); 2140 pfn_ADDEREXCLUDEDAPPLICATIONA pAddERExcludedApplicationA = (pfn_ADDEREXCLUDEDAPPLICATIONA) GetProcAddress(fault_rep_dll_handle, "AddERExcludedApplicationA");
@@ -2157,7 +2164,7 @@ void disable_win_error_reporting()
2157// On Mac, return the hardware serial number. 2164// On Mac, return the hardware serial number.
2158std::string get_serial_number() 2165std::string get_serial_number()
2159{ 2166{
2160 char serial_md5[MD5HEX_STR_SIZE]; 2167 char serial_md5[MD5HEX_STR_SIZE]; /* Flawfinder: ignore */
2161 serial_md5[0] = 0; 2168 serial_md5[0] = 0;
2162 2169
2163#if LL_WINDOWS 2170#if LL_WINDOWS
@@ -2199,7 +2206,7 @@ std::string get_serial_number()
2199 2206
2200 if (serialNumber) 2207 if (serialNumber)
2201 { 2208 {
2202 char buffer[MAX_STRING]; 2209 char buffer[MAX_STRING]; /* Flawfinder: ignore */
2203 if (CFStringGetCString(serialNumber, buffer, MAX_STRING, kCFStringEncodingASCII)) 2210 if (CFStringGetCString(serialNumber, buffer, MAX_STRING, kCFStringEncodingASCII))
2204 { 2211 {
2205 LLMD5 md5( (unsigned char*)buffer ); 2212 LLMD5 md5( (unsigned char*)buffer );
@@ -2234,7 +2241,7 @@ static inline BOOL do_basic_glibc_backtrace()
2234 2241
2235 std::string strace_filename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"stack_trace.log"); 2242 std::string strace_filename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"stack_trace.log");
2236 llinfos << "Opening stack trace file " << strace_filename << llendl; 2243 llinfos << "Opening stack trace file " << strace_filename << llendl;
2237 FILE* StraceFile = LLFile::fopen(strace_filename.c_str(), "w"); 2244 FILE* StraceFile = LLFile::fopen(strace_filename.c_str(), "w"); /* Flawfinder: ignore */
2238 if (!StraceFile) 2245 if (!StraceFile)
2239 { 2246 {
2240 llinfos << "Opening stack trace file " << strace_filename << " failed. Using stderr." << llendl; 2247 llinfos << "Opening stack trace file " << strace_filename << " failed. Using stderr." << llendl;
@@ -2272,7 +2279,7 @@ static inline BOOL do_elfio_glibc_backtrace()
2272 2279
2273 std::string strace_filename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"stack_trace.log"); 2280 std::string strace_filename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"stack_trace.log");
2274 llinfos << "Opening stack trace file " << strace_filename << llendl; 2281 llinfos << "Opening stack trace file " << strace_filename << llendl;
2275 FILE* StraceFile = LLFile::fopen(strace_filename.c_str(), "w"); 2282 FILE* StraceFile = LLFile::fopen(strace_filename.c_str(), "w"); /* Flawfinder: ignore */
2276 if (!StraceFile) 2283 if (!StraceFile)
2277 { 2284 {
2278 llinfos << "Opening stack trace file " << strace_filename << " failed. Using stderr." << llendl; 2285 llinfos << "Opening stack trace file " << strace_filename << " failed. Using stderr." << llendl;
@@ -2423,7 +2430,7 @@ void viewer_crash_callback()
2423 2430
2424 // Close the debug file 2431 // Close the debug file
2425 close_debug(); 2432 close_debug();
2426 gErrorBuffer.closeFile(); 2433 LLError::logToFile("");
2427 2434
2428 // Close the SecondLife.log 2435 // Close the SecondLife.log
2429 2436
@@ -2461,7 +2468,7 @@ void viewer_crash_callback()
2461 command_str += "-user "; 2468 command_str += "-user ";
2462 command_str += gUserServerName; 2469 command_str += gUserServerName;
2463 command_str += " &"; // This backgrounds the command so system() doesn't block until the crashreporter exits. 2470 command_str += " &"; // This backgrounds the command so system() doesn't block until the crashreporter exits.
2464 system(command_str.c_str()); 2471 system(command_str.c_str()); /* Flawfinder: ignore */
2465 2472
2466 // Sometimes signals don't seem to quit the viewer. 2473 // Sometimes signals don't seem to quit the viewer.
2467 // Make sure we exit so as to not totally confuse the user. 2474 // Make sure we exit so as to not totally confuse the user.
@@ -2495,7 +2502,7 @@ void viewer_crash_callback()
2495 pid_t pid = fork(); 2502 pid_t pid = fork();
2496 if (pid == 0) 2503 if (pid == 0)
2497 { // child 2504 { // child
2498 execv(cmd.c_str(), cmdargv); 2505 execv(cmd.c_str(), cmdargv); /* Flawfinder: ignore */
2499 llwarns << "execv failure when trying to start " << cmd << llendl; 2506 llwarns << "execv failure when trying to start " << cmd << llendl;
2500 _exit(1); // avoid atexit() 2507 _exit(1); // avoid atexit()
2501 } else { 2508 } else {
@@ -2523,19 +2530,89 @@ void viewer_crash_callback()
2523 2530
2524 2531
2525 2532
2526BOOL init_vfs_viewer() 2533BOOL init_cache()
2527{ 2534{
2535 gPurgeCache = FALSE;
2536 // Purge cache if user requested it
2537 if (gSavedSettings.getBOOL("PurgeCacheOnStartup") ||
2538 gSavedSettings.getBOOL("PurgeCacheOnNextStartup"))
2539 {
2540 gSavedSettings.setBOOL("PurgeCacheOnNextStartup", FALSE);
2541 gPurgeCache = TRUE;
2542 }
2543 // Purge cache if it belongs to an old version
2544 else
2545 {
2546 static const S32 cache_version = 5;
2547 if (gSavedSettings.getS32("LocalCacheVersion") != cache_version)
2548 {
2549 gPurgeCache = TRUE;
2550 gSavedSettings.setS32("LocalCacheVersion", cache_version);
2551 }
2552 }
2553
2554 // Setup and verify the cache location
2555 LLString cache_location = gSavedSettings.getString("CacheLocation");
2556 LLString new_cache_location = gSavedSettings.getString("NewCacheLocation");
2557 if (new_cache_location != cache_location)
2558 {
2559 gDirUtilp->setCacheDir(gSavedSettings.getString("CacheLocation"));
2560 purge_cache(); // purge old cache
2561 gSavedSettings.setString("CacheLocation", new_cache_location);
2562 }
2563
2564 if (!gDirUtilp->setCacheDir(gSavedSettings.getString("CacheLocation")))
2565 {
2566 llwarns << "Unable to set cache location" << llendl;
2567 gSavedSettings.setString("CacheLocation", "");
2568 }
2569
2570 if (gPurgeCache)
2571 {
2572 LLSplashScreen::update("Clearing cache...");
2573 purge_cache();
2574 }
2575
2576 LLSplashScreen::update("Initializing Texture Cache...");
2577
2578 // Init the texture cache
2579 // Allocate 80% of the cache size for textures
2580 BOOL read_only = gSecondInstance ? TRUE : FALSE;
2581 const S32 MB = 1024*1024;
2582 S64 cache_size = (S64)(gSavedSettings.getU32("CacheSize")) * MB;
2583 const S64 MAX_CACHE_SIZE = 1024*MB;
2584 cache_size = llmin(cache_size, MAX_CACHE_SIZE);
2585 S64 texture_cache_size = ((cache_size * 8)/10);
2586 S64 extra = gTextureCache->initCache(LL_PATH_CACHE, texture_cache_size, read_only);
2587 texture_cache_size -= extra;
2588
2589 LLSplashScreen::update("Initializing VFS...");
2590
2591 // Init the VFS
2592 S64 vfs_size = cache_size - texture_cache_size;
2593 const S64 MAX_VFS_SIZE = 1024 * MB; // 1 GB
2594 vfs_size = llmin(vfs_size, MAX_VFS_SIZE);
2595 vfs_size = (vfs_size / MB) * MB; // make sure it is MB aligned
2596 U32 vfs_size_u32 = (U32)vfs_size;
2597 U32 old_vfs_size = gSavedSettings.getU32("VFSOldSize") * MB;
2598 bool resize_vfs = (vfs_size_u32 != old_vfs_size);
2599 if (resize_vfs)
2600 {
2601 gSavedSettings.setU32("VFSOldSize", vfs_size_u32/MB);
2602 }
2603 llinfos << "VFS CACHE SIZE: " << vfs_size/(1024*1024) << " MB" << llendl;
2604
2528 // This has to happen BEFORE starting the vfs 2605 // This has to happen BEFORE starting the vfs
2529 //time_t ltime; 2606 //time_t ltime;
2530 srand(time(NULL)); 2607 srand(time(NULL)); /* Flawfinder: ignore */
2531 U32 old_salt = gSavedSettings.getU32("VFSSalt"); 2608 U32 old_salt = gSavedSettings.getU32("VFSSalt");
2532 U32 new_salt; 2609 U32 new_salt;
2533 char old_vfs_data_file[LL_MAX_PATH]; 2610 char old_vfs_data_file[LL_MAX_PATH]; /* Flawfinder: ignore */
2534 char old_vfs_index_file[LL_MAX_PATH]; 2611 char old_vfs_index_file[LL_MAX_PATH]; /* Flawfinder: ignore */
2535 char new_vfs_data_file[LL_MAX_PATH]; 2612 char new_vfs_data_file[LL_MAX_PATH]; /* Flawfinder: ignore */
2536 char new_vfs_index_file[LL_MAX_PATH]; 2613 char new_vfs_index_file[LL_MAX_PATH]; /* Flawfinder: ignore */
2537 char static_vfs_index_file[LL_MAX_PATH]; 2614 char static_vfs_index_file[LL_MAX_PATH]; /* Flawfinder: ignore */
2538 char static_vfs_data_file[LL_MAX_PATH]; 2615 char static_vfs_data_file[LL_MAX_PATH]; /* Flawfinder: ignore */
2539 2616
2540 if (gMultipleViewersOK) 2617 if (gMultipleViewersOK)
2541 { 2618 {
@@ -2550,7 +2627,7 @@ BOOL init_vfs_viewer()
2550 } while( new_salt == old_salt ); 2627 } while( new_salt == old_salt );
2551 } 2628 }
2552 2629
2553 sprintf(old_vfs_data_file, "%s%u", 2630 snprintf(old_vfs_data_file, LL_MAX_PATH, "%s%u", /* Flawfinder: ignore */
2554 gDirUtilp->getExpandedFilename(LL_PATH_CACHE,VFS_DATA_FILE_BASE).c_str(), 2631 gDirUtilp->getExpandedFilename(LL_PATH_CACHE,VFS_DATA_FILE_BASE).c_str(),
2555 old_salt); 2632 old_salt);
2556 2633
@@ -2571,10 +2648,10 @@ BOOL init_vfs_viewer()
2571 std::string found_file; 2648 std::string found_file;
2572 if (gDirUtilp->getNextFileInDir(dir, mask, found_file, FALSE)) 2649 if (gDirUtilp->getNextFileInDir(dir, mask, found_file, FALSE))
2573 { 2650 {
2574 sprintf(old_vfs_data_file, "%s%s%s", dir.c_str(), gDirUtilp->getDirDelimiter().c_str(), found_file.c_str()); 2651 snprintf(old_vfs_data_file, LL_MAX_PATH, "%s%s%s", dir.c_str(), gDirUtilp->getDirDelimiter().c_str(), found_file.c_str()); /* Flawfinder: ignore */
2575 2652
2576 S32 start_pos; 2653 S32 start_pos;
2577 S32 length = strlen(found_file.c_str()); 2654 S32 length = strlen(found_file.c_str()); /* Flawfinder: ignore*/
2578 for (start_pos = length - 1; start_pos >= 0; start_pos--) 2655 for (start_pos = length - 1; start_pos >= 0; start_pos--)
2579 { 2656 {
2580 if (found_file[start_pos] == '.') 2657 if (found_file[start_pos] == '.')
@@ -2592,7 +2669,7 @@ BOOL init_vfs_viewer()
2592 } 2669 }
2593 } 2670 }
2594 2671
2595 sprintf(old_vfs_index_file, "%s%u", 2672 snprintf(old_vfs_index_file, LL_MAX_PATH, "%s%u", /* Flawfinder: ignore */
2596 gDirUtilp->getExpandedFilename(LL_PATH_CACHE,VFS_INDEX_FILE_BASE).c_str(), 2673 gDirUtilp->getExpandedFilename(LL_PATH_CACHE,VFS_INDEX_FILE_BASE).c_str(),
2597 old_salt); 2674 old_salt);
2598 2675
@@ -2623,32 +2700,25 @@ BOOL init_vfs_viewer()
2623 gDirUtilp->deleteFilesInDir(dir, mask); 2700 gDirUtilp->deleteFilesInDir(dir, mask);
2624 } 2701 }
2625 2702
2626 sprintf(new_vfs_data_file, "%s%u", 2703 snprintf(new_vfs_data_file, LL_MAX_PATH, "%s%u", /* Flawfinder: ignore */
2627 gDirUtilp->getExpandedFilename(LL_PATH_CACHE,VFS_DATA_FILE_BASE).c_str(), 2704 gDirUtilp->getExpandedFilename(LL_PATH_CACHE,VFS_DATA_FILE_BASE).c_str(),
2628 new_salt); 2705 new_salt);
2629 2706
2630 sprintf(new_vfs_index_file, "%s%u", gDirUtilp->getExpandedFilename(LL_PATH_CACHE, VFS_INDEX_FILE_BASE).c_str(), 2707 snprintf(new_vfs_index_file, LL_MAX_PATH, "%s%u", gDirUtilp->getExpandedFilename(LL_PATH_CACHE, VFS_INDEX_FILE_BASE).c_str(), /* Flawfinder: ignore */
2631 new_salt); 2708 new_salt);
2632 2709
2633 2710
2634 strcpy(static_vfs_data_file, gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"static_data.db2").c_str()); 2711 strncpy(static_vfs_data_file, gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"static_data.db2").c_str(), LL_MAX_PATH -1); /* Flawfinder: ignore */
2635 strcpy(static_vfs_index_file, gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"static_index.db2").c_str()); 2712 static_vfs_data_file[LL_MAX_PATH -1] = '\0';
2636 2713 strncpy(static_vfs_index_file, gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"static_index.db2").c_str(), LL_MAX_PATH -1); /* Flawfinder: ignore */
2637 U32 vfs_size = gSavedSettings.getU32("VFSSize"); 2714 static_vfs_index_file[LL_MAX_PATH -1] = '\0';
2638 if (vfs_size > 4)
2639 {
2640 llwarns << "Invalid VFS size" << llendl;
2641 gSavedSettings.setU32("VFSSize", 2);
2642 vfs_size = 2;
2643 }
2644 2715
2645 if (gSavedSettings.getU32("VFSOldSize") != vfs_size) 2716 if (resize_vfs)
2646 { 2717 {
2647 llinfos << "Removing old vfs and re-sizing" << llendl; 2718 llinfos << "Removing old vfs and re-sizing" << llendl;
2648 2719
2649 LLFile::remove(old_vfs_data_file); 2720 LLFile::remove(old_vfs_data_file);
2650 LLFile::remove(old_vfs_index_file); 2721 LLFile::remove(old_vfs_index_file);
2651 gSavedSettings.setU32("VFSOldSize", vfs_size);
2652 } 2722 }
2653 else if (old_salt != new_salt) 2723 else if (old_salt != new_salt)
2654 { 2724 {
@@ -2662,16 +2732,15 @@ BOOL init_vfs_viewer()
2662 // Startup the VFS... 2732 // Startup the VFS...
2663 gSavedSettings.setU32("VFSSalt", new_salt); 2733 gSavedSettings.setU32("VFSSalt", new_salt);
2664 2734
2665 U32 presize = VFS_SIZE_MAP[gSavedSettings.getU32("VFSSize")];
2666 // Don't remove VFS after viewer crashes. If user has corrupt data, they can reinstall. JC 2735 // Don't remove VFS after viewer crashes. If user has corrupt data, they can reinstall. JC
2667 gVFS = new LLVFS(new_vfs_index_file, new_vfs_data_file, FALSE, presize, FALSE); 2736 gVFS = new LLVFS(new_vfs_index_file, new_vfs_data_file, FALSE, vfs_size_u32, FALSE);
2668 if( VFSVALID_BAD_CORRUPT == gVFS->getValidState() ) 2737 if( VFSVALID_BAD_CORRUPT == gVFS->getValidState() )
2669 { 2738 {
2670 // Try again with fresh files 2739 // Try again with fresh files
2671 // (The constructor deletes corrupt files when it finds them.) 2740 // (The constructor deletes corrupt files when it finds them.)
2672 llwarns << "VFS corrupt, deleted. Making new VFS." << llendl; 2741 llwarns << "VFS corrupt, deleted. Making new VFS." << llendl;
2673 delete gVFS; 2742 delete gVFS;
2674 gVFS = new LLVFS(new_vfs_index_file, new_vfs_data_file, FALSE, presize, FALSE); 2743 gVFS = new LLVFS(new_vfs_index_file, new_vfs_data_file, FALSE, vfs_size_u32, FALSE);
2675 } 2744 }
2676 2745
2677 gStaticVFS = new LLVFS(static_vfs_index_file, static_vfs_data_file, TRUE, 0, FALSE); 2746 gStaticVFS = new LLVFS(static_vfs_index_file, static_vfs_data_file, TRUE, 0, FALSE);
@@ -2694,7 +2763,7 @@ OSErr AEGURLHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn)
2694{ 2763{
2695 OSErr result = noErr; 2764 OSErr result = noErr;
2696 DescType actualType; 2765 DescType actualType;
2697 char buffer[1024]; 2766 char buffer[1024]; /* Flawfinder: ignore */
2698 Size size; 2767 Size size;
2699 2768
2700 result = AEGetParamPtr ( 2769 result = AEGetParamPtr (
@@ -2797,7 +2866,7 @@ OSStatus DisplayReleaseNotes(void)
2797 2866
2798 LLString releaseNotesText; 2867 LLString releaseNotesText;
2799 2868
2800 LLString::read(releaseNotesText, "releasenotes.txt"); 2869 LLString::read(releaseNotesText, "releasenotes.txt"); /* Flawfinder: ignore*/
2801 2870
2802 err = HIViewFindByID(HIViewGetRoot(window), id, &textView); 2871 err = HIViewFindByID(HIViewGetRoot(window), id, &textView);
2803 2872
@@ -2982,10 +3051,11 @@ void save_final_snapshot(void*)
2982 gAgent.changeCameraToThirdPerson( FALSE ); // don't animate, need immediate switch 3051 gAgent.changeCameraToThirdPerson( FALSE ); // don't animate, need immediate switch
2983 gSavedSettings.setBOOL("ShowParcelOwners", FALSE); 3052 gSavedSettings.setBOOL("ShowParcelOwners", FALSE);
2984 idle(); 3053 idle();
2985 char temp_str[MAX_PATH]; 3054 char temp_str[MAX_PATH]; /* Flawfinder: ignore */
2986 strcpy (temp_str,gDirUtilp->getLindenUserDir().c_str()); 3055 strncpy (temp_str,gDirUtilp->getLindenUserDir().c_str(), MAX_PATH -1); /* Flawfinder: ignore */
2987 strcat (temp_str,"/"); 3056 temp_str[MAX_PATH -1] = '\0';
2988 strcat (temp_str,SCREEN_LAST_FILENAME); 3057 strcat (temp_str,"/"); /* Flawfinder: ignore */
3058 strcat (temp_str,SCREEN_LAST_FILENAME); /* Flawfinder: ignore */
2989 gViewerWindow->saveSnapshot(temp_str, gViewerWindow->getWindowWidth(), gViewerWindow->getWindowHeight(), FALSE, TRUE); 3059 gViewerWindow->saveSnapshot(temp_str, gViewerWindow->getWindowWidth(), gViewerWindow->getWindowHeight(), FALSE, TRUE);
2990 gHaveSavedSnapshot = TRUE; 3060 gHaveSavedSnapshot = TRUE;
2991 } 3061 }
@@ -3089,8 +3159,8 @@ void idle_shutdown()
3089 S32 finished_uploads = total_uploads - pending_uploads; 3159 S32 finished_uploads = total_uploads - pending_uploads;
3090 F32 percent = 100.f * finished_uploads / total_uploads; 3160 F32 percent = 100.f * finished_uploads / total_uploads;
3091 gViewerWindow->setProgressPercent(percent); 3161 gViewerWindow->setProgressPercent(percent);
3092 char buffer[MAX_STRING]; 3162 char buffer[MAX_STRING]; /* Flawfinder: ignore */
3093 sprintf(buffer, "Saving final data..."); 3163 snprintf(buffer, MAX_STRING, "Saving final data..."); /* Flawfinder: ignore */
3094 gViewerWindow->setProgressString(buffer); 3164 gViewerWindow->setProgressString(buffer);
3095 return; 3165 return;
3096 } 3166 }
@@ -3164,6 +3234,7 @@ void update_statistics(U32 frame_count)
3164 gViewerStats->incStat(LLViewerStats::ST_TOOLBOX_SECONDS, gFrameIntervalSeconds); 3234 gViewerStats->incStat(LLViewerStats::ST_TOOLBOX_SECONDS, gFrameIntervalSeconds);
3165 } 3235 }
3166 } 3236 }
3237 gViewerStats->setStat(LLViewerStats::ST_ENABLE_VBO, (F64)gSavedSettings.getBOOL("RenderVBOEnable"));
3167 gViewerStats->setStat(LLViewerStats::ST_LIGHTING_DETAIL, (F64)gSavedSettings.getS32("RenderLightingDetail")); 3238 gViewerStats->setStat(LLViewerStats::ST_LIGHTING_DETAIL, (F64)gSavedSettings.getS32("RenderLightingDetail"));
3168 gViewerStats->setStat(LLViewerStats::ST_DRAW_DIST, (F64)gSavedSettings.getF32("RenderFarClip")); 3239 gViewerStats->setStat(LLViewerStats::ST_DRAW_DIST, (F64)gSavedSettings.getF32("RenderFarClip"));
3169 gViewerStats->setStat(LLViewerStats::ST_CHAT_BUBBLES, (F64)gSavedSettings.getBOOL("UseChatBubbles")); 3240 gViewerStats->setStat(LLViewerStats::ST_CHAT_BUBBLES, (F64)gSavedSettings.getBOOL("UseChatBubbles"));
@@ -3193,10 +3264,7 @@ void update_statistics(U32 frame_count)
3193 gViewerStats->mSimPingStat.addValue(10000); 3264 gViewerStats->mSimPingStat.addValue(10000);
3194 } 3265 }
3195 3266
3196 if (!gViewerWindow->renderingFastFrame()) 3267 gViewerStats->mFPSStat.addValue(1);
3197 {
3198 gViewerStats->mFPSStat.addValue(1);
3199 }
3200 F32 layer_bits = (F32)(gVLManager.getLandBits() + gVLManager.getWindBits() + gVLManager.getCloudBits()); 3268 F32 layer_bits = (F32)(gVLManager.getLandBits() + gVLManager.getWindBits() + gVLManager.getCloudBits());
3201 gViewerStats->mLayersKBitStat.addValue(layer_bits/1024.f); 3269 gViewerStats->mLayersKBitStat.addValue(layer_bits/1024.f);
3202 gViewerStats->mObjectKBitStat.addValue(gObjectBits/1024.f); 3270 gViewerStats->mObjectKBitStat.addValue(gObjectBits/1024.f);
@@ -3249,11 +3317,11 @@ void update_statistics(U32 frame_count)
3249 3317
3250 // Argh! Shouldn't be doing the rendering here, it should be in a UI class! 3318 // Argh! Shouldn't be doing the rendering here, it should be in a UI class!
3251 3319
3252 static char wind_vel_text[MAX_TEXT_LENGTH]; 3320 static char wind_vel_text[MAX_TEXT_LENGTH]; /* Flawfinder: ignore */
3253 static char wind_vector_text[MAX_TEXT_LENGTH]; 3321 static char wind_vector_text[MAX_TEXT_LENGTH]; /* Flawfinder: ignore */
3254 static char rwind_vel_text[MAX_TEXT_LENGTH]; 3322 static char rwind_vel_text[MAX_TEXT_LENGTH]; /* Flawfinder: ignore */
3255 static char rwind_vector_text[MAX_TEXT_LENGTH]; 3323 static char rwind_vector_text[MAX_TEXT_LENGTH]; /* Flawfinder: ignore */
3256 static char audio_text[MAX_TEXT_LENGTH]; 3324 static char audio_text[MAX_TEXT_LENGTH]; /* Flawfinder: ignore */
3257 3325
3258 // Now draw the text 3326 // Now draw the text
3259 LLGLSUIDefault gls_ui; 3327 LLGLSUIDefault gls_ui;
@@ -3269,46 +3337,46 @@ void update_statistics(U32 frame_count)
3269 3337
3270 if (gDisplayCameraPos) 3338 if (gDisplayCameraPos)
3271 { 3339 {
3272 char camera_view_text[MAX_TEXT_LENGTH]; 3340 char camera_view_text[MAX_TEXT_LENGTH]; /* Flawfinder: ignore */
3273 char camera_center_text[MAX_TEXT_LENGTH]; 3341 char camera_center_text[MAX_TEXT_LENGTH]; /* Flawfinder: ignore */
3274 char agent_view_text[MAX_TEXT_LENGTH]; 3342 char agent_view_text[MAX_TEXT_LENGTH]; /* Flawfinder: ignore */
3275 char agent_left_text[MAX_TEXT_LENGTH]; 3343 char agent_left_text[MAX_TEXT_LENGTH]; /* Flawfinder: ignore */
3276 char agent_center_text[MAX_TEXT_LENGTH]; 3344 char agent_center_text[MAX_TEXT_LENGTH]; /* Flawfinder: ignore */
3277 char agent_root_center_text[MAX_TEXT_LENGTH]; 3345 char agent_root_center_text[MAX_TEXT_LENGTH]; /* Flawfinder: ignore */
3278 3346
3279 LLVector3d tvector; // Temporary vector to hold data for printing. 3347 LLVector3d tvector; // Temporary vector to hold data for printing.
3280 3348
3281 // Update camera center, camera view, wind info every other frame 3349 // Update camera center, camera view, wind info every other frame
3282 tvector = gAgent.getPositionGlobal(); 3350 tvector = gAgent.getPositionGlobal();
3283 sprintf(agent_center_text, "AgentCenter %f %f %f", 3351 snprintf(agent_center_text, MAX_TEXT_LENGTH, "AgentCenter %f %f %f", /* Flawfinder: ignore */
3284 (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ])); 3352 (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ]));
3285 3353
3286 if (gAgent.getAvatarObject()) 3354 if (gAgent.getAvatarObject())
3287 { 3355 {
3288 tvector = gAgent.getPosGlobalFromAgent(gAgent.getAvatarObject()->mRoot.getWorldPosition()); 3356 tvector = gAgent.getPosGlobalFromAgent(gAgent.getAvatarObject()->mRoot.getWorldPosition());
3289 sprintf(agent_root_center_text, "AgentRootCenter %f %f %f", 3357 snprintf(agent_root_center_text, MAX_TEXT_LENGTH, "AgentRootCenter %f %f %f", /* Flawfinder: ignore */
3290 (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ])); 3358 (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ]));
3291 } 3359 }
3292 else 3360 else
3293 { 3361 {
3294 sprintf(agent_root_center_text, "---"); 3362 snprintf(agent_root_center_text, MAX_TEXT_LENGTH, "---"); /* Flawfinder: ignore */
3295 } 3363 }
3296 3364
3297 3365
3298 tvector = LLVector4(gAgent.getFrameAgent().getAtAxis()); 3366 tvector = LLVector4(gAgent.getFrameAgent().getAtAxis());
3299 sprintf(agent_view_text, "AgentAtAxis %f %f %f", 3367 snprintf(agent_view_text, MAX_TEXT_LENGTH, "AgentAtAxis %f %f %f", /* Flawfinder: ignore */
3300 (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ])); 3368 (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ]));
3301 3369
3302 tvector = LLVector4(gAgent.getFrameAgent().getLeftAxis()); 3370 tvector = LLVector4(gAgent.getFrameAgent().getLeftAxis());
3303 sprintf(agent_left_text, "AgentLeftAxis %f %f %f", 3371 snprintf(agent_left_text, MAX_TEXT_LENGTH, "AgentLeftAxis %f %f %f", /* Flawfinder: ignore */
3304 (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ])); 3372 (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ]));
3305 3373
3306 tvector = gAgent.getCameraPositionGlobal(); 3374 tvector = gAgent.getCameraPositionGlobal();
3307 sprintf(camera_center_text, "CameraCenter %f %f %f", 3375 snprintf(camera_center_text, MAX_TEXT_LENGTH, "CameraCenter %f %f %f", /* Flawfinder: ignore */
3308 (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ])); 3376 (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ]));
3309 3377
3310 tvector = LLVector4(gCamera->getAtAxis()); 3378 tvector = LLVector4(gCamera->getAtAxis());
3311 sprintf(camera_view_text, "CameraAtAxis %f %f %f", 3379 snprintf(camera_view_text, MAX_TEXT_LENGTH, "CameraAtAxis %f %f %f", /* Flawfinder: ignore */
3312 (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ])); 3380 (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ]));
3313 3381
3314 add_text(xpos, ypos, agent_center_text); ypos += y_inc; 3382 add_text(xpos, ypos, agent_center_text); ypos += y_inc;
@@ -3321,10 +3389,10 @@ void update_statistics(U32 frame_count)
3321 3389
3322 if (gDisplayWindInfo) 3390 if (gDisplayWindInfo)
3323 { 3391 {
3324 sprintf(wind_vel_text, "Wind velocity %.2f m/s", gWindVec.magVec()); 3392 snprintf(wind_vel_text, MAX_TEXT_LENGTH, "Wind velocity %.2f m/s", gWindVec.magVec()); /* Flawfinder: ignore */
3325 sprintf(wind_vector_text, "Wind vector %.2f %.2f %.2f", gWindVec.mV[0], gWindVec.mV[1], gWindVec.mV[2]); 3393 snprintf(wind_vector_text, MAX_TEXT_LENGTH, "Wind vector %.2f %.2f %.2f", gWindVec.mV[0], gWindVec.mV[1], gWindVec.mV[2]); /* Flawfinder: ignore */
3326 sprintf(rwind_vel_text, "RWind vel %.2f m/s", gRelativeWindVec.magVec()); 3394 snprintf(rwind_vel_text, MAX_TEXT_LENGTH, "RWind vel %.2f m/s", gRelativeWindVec.magVec()); /* Flawfinder: ignore */
3327 sprintf(rwind_vector_text, "RWind vec %.2f %.2f %.2f", gRelativeWindVec.mV[0], gRelativeWindVec.mV[1], gRelativeWindVec.mV[2]); 3395 snprintf(rwind_vector_text, MAX_TEXT_LENGTH, "RWind vec %.2f %.2f %.2f", gRelativeWindVec.mV[0], gRelativeWindVec.mV[1], gRelativeWindVec.mV[2]); /* Flawfinder: ignore */
3328 3396
3329 add_text(xpos, ypos, wind_vel_text); ypos += y_inc; 3397 add_text(xpos, ypos, wind_vel_text); ypos += y_inc;
3330 add_text(xpos, ypos, wind_vector_text); ypos += y_inc; 3398 add_text(xpos, ypos, wind_vector_text); ypos += y_inc;
@@ -3335,14 +3403,14 @@ void update_statistics(U32 frame_count)
3335 { 3403 {
3336 if (gAudiop) 3404 if (gAudiop)
3337 { 3405 {
3338 sprintf(audio_text, "Audio for wind: %d", gAudiop->isWindEnabled()); 3406 snprintf(audio_text, MAX_TEXT_LENGTH, "Audio for wind: %d", gAudiop->isWindEnabled()); /* Flawfinder: ignore */
3339 } 3407 }
3340 add_text(xpos, ypos, audio_text); ypos += y_inc; 3408 add_text(xpos, ypos, audio_text); ypos += y_inc;
3341 } 3409 }
3342 if (gDisplayFOV) 3410 if (gDisplayFOV)
3343 { 3411 {
3344 char fov_string[MAX_TEXT_LENGTH]; 3412 char fov_string[MAX_TEXT_LENGTH]; /* Flawfinder: ignore */
3345 sprintf(fov_string, "FOV: %2.1f deg", RAD_TO_DEG * gCamera->getView()); 3413 snprintf(fov_string, MAX_TEXT_LENGTH, "FOV: %2.1f deg", RAD_TO_DEG * gCamera->getView()); /* Flawfinder: ignore */
3346 add_text(xpos, ypos, fov_string); 3414 add_text(xpos, ypos, fov_string);
3347 ypos += y_inc; 3415 ypos += y_inc;
3348 } 3416 }
@@ -3352,6 +3420,14 @@ void update_statistics(U32 frame_count)
3352 add_text(xpos, ypos, "Shaders Disabled"); 3420 add_text(xpos, ypos, "Shaders Disabled");
3353 ypos += y_inc; 3421 ypos += y_inc;
3354 } 3422 }
3423 add_text(xpos, ypos, (char*) llformat("%d MB Vertex Data", LLVertexBuffer::sAllocatedBytes/(1024*1024)).c_str());
3424 ypos += y_inc;
3425
3426 add_text(xpos, ypos, (char*) llformat("%d Pending Lock", LLVertexBuffer::sLockedList.size()).c_str());
3427 ypos += y_inc;
3428
3429 add_text(xpos, ypos, (char*) llformat("%d Vertex Buffers", LLVertexBuffer::sGLCount).c_str());
3430 ypos += y_inc;
3355#endif 3431#endif
3356 if (LLPipeline::getRenderParticleBeacons(NULL)) 3432 if (LLPipeline::getRenderParticleBeacons(NULL))
3357 { 3433 {
@@ -3471,8 +3547,7 @@ void idle_network()
3471 3547
3472 if (gPrintMessagesThisFrame) 3548 if (gPrintMessagesThisFrame)
3473 { 3549 {
3474 llinfos << "Decoded " << total_decoded 3550 llinfos << "Decoded " << total_decoded << " msgs this frame!" << llendl;
3475 << " msgs this frame!" << llendl;
3476 gPrintMessagesThisFrame = FALSE; 3551 gPrintMessagesThisFrame = FALSE;
3477 } 3552 }
3478 } 3553 }
@@ -3530,9 +3605,9 @@ void idle()
3530 LLControlBase::updateAllListeners(); 3605 LLControlBase::updateAllListeners();
3531 3606
3532 LLFrameTimer::updateFrameTime(); 3607 LLFrameTimer::updateFrameTime();
3608 LLEventTimer::updateClass();
3533 LLCriticalDamp::updateInterpolants(); 3609 LLCriticalDamp::updateInterpolants();
3534 LLMortician::updateClass(); 3610 LLMortician::updateClass();
3535
3536 F32 dt_raw = idle_timer.getElapsedTimeAndResetF32(); 3611 F32 dt_raw = idle_timer.getElapsedTimeAndResetF32();
3537 3612
3538 // Cap out-of-control frame times 3613 // Cap out-of-control frame times
@@ -3693,7 +3768,6 @@ void idle()
3693 { 3768 {
3694// LLFastTimer t(LLFastTimer::FTM_IDLE_CB); 3769// LLFastTimer t(LLFastTimer::FTM_IDLE_CB);
3695 3770
3696 LLEventTimer::updateClass();
3697 // Do event notifications if necessary. Yes, we may want to move this elsewhere. 3771 // Do event notifications if necessary. Yes, we may want to move this elsewhere.
3698 gEventNotifier.update(); 3772 gEventNotifier.update();
3699 3773
@@ -3737,8 +3811,6 @@ void idle()
3737 gPipeline.resetDrawOrders(); 3811 gPipeline.resetDrawOrders();
3738 } 3812 }
3739 { 3813 {
3740 //LLFastTimer t(LLFastTimer::FTM_TEMP1);
3741
3742 // Handle pending gesture processing 3814 // Handle pending gesture processing
3743 gGestureManager.update(); 3815 gGestureManager.update();
3744 3816
@@ -3749,8 +3821,6 @@ void idle()
3749 LLFastTimer t(LLFastTimer::FTM_OBJECTLIST_UPDATE); // Actually "object update" 3821 LLFastTimer t(LLFastTimer::FTM_OBJECTLIST_UPDATE); // Actually "object update"
3750 gFrameStats.start(LLFrameStats::OBJECT_UPDATE); 3822 gFrameStats.start(LLFrameStats::OBJECT_UPDATE);
3751 3823
3752 LLVolumeImplFlexible::resetUpdateBins();
3753
3754 if (!(gLogoutRequestSent && gHaveSavedSnapshot)) 3824 if (!(gLogoutRequestSent && gHaveSavedSnapshot))
3755 { 3825 {
3756 gObjectList.update(gAgent, *gWorldp); 3826 gObjectList.update(gAgent, *gWorldp);
@@ -3816,8 +3886,9 @@ void idle()
3816 3886
3817 gWorldp->updateVisibilities(); 3887 gWorldp->updateVisibilities();
3818 { 3888 {
3889 const F32 max_region_update_time = .001f; // 1ms
3819 LLFastTimer t(LLFastTimer::FTM_REGION_UPDATE); 3890 LLFastTimer t(LLFastTimer::FTM_REGION_UPDATE);
3820 gWorldp->updateRegions(); 3891 gWorldp->updateRegions(max_region_update_time);
3821 } 3892 }
3822 3893
3823 ///////////////////////// 3894 /////////////////////////
@@ -3827,8 +3898,6 @@ void idle()
3827 3898
3828 if (!gNoRender) 3899 if (!gNoRender)
3829 { 3900 {
3830 gSky.updateFog(gCamera->getFar());
3831
3832 gWorldp->updateClouds(gFrameDTClamped); 3901 gWorldp->updateClouds(gFrameDTClamped);
3833 gSky.propagateHeavenlyBodies(gFrameDTClamped); // moves sun, moon, and planets 3902 gSky.propagateHeavenlyBodies(gFrameDTClamped); // moves sun, moon, and planets
3834 3903
@@ -3866,31 +3935,22 @@ void idle()
3866 // 3935 //
3867 gFrameStats.start(LLFrameStats::IMAGE_UPDATE); 3936 gFrameStats.start(LLFrameStats::IMAGE_UPDATE);
3868 3937
3869 if (!gViewerWindow->renderingFastFrame()) 3938 LLFastTimer t(LLFastTimer::FTM_IMAGE_UPDATE);
3870 { 3939
3871 LLFastTimer t(LLFastTimer::FTM_IMAGE_UPDATE); 3940 LLViewerImage::updateClass(gCamera->getVelocityStat()->getMean(),
3872 3941 gCamera->getAngularVelocityStat()->getMean());
3873 LLViewerImage::updateClass(gCamera->getVelocityStat()->getMean(),
3874 gCamera->getAngularVelocityStat()->getMean());
3875 3942
3876 gBumpImageList.updateImages(); // must be called before gImageList version so that it's textures are thrown out first. 3943 gBumpImageList.updateImages(); // must be called before gImageList version so that it's textures are thrown out first.
3877 3944
3878 const F32 max_image_decode_time = 0.005f; // 5 ms decode time 3945 const F32 max_image_decode_time = 0.005f; // 5 ms decode time
3879 gImageList.updateImages(max_image_decode_time); 3946 gImageList.updateImages(max_image_decode_time);
3880 stop_glerror(); 3947 stop_glerror();
3881 }
3882 3948
3883 ////////////////////////////////////// 3949 //////////////////////////////////////
3884 // 3950 //
3885 // Sort and cull in the new renderer are moved to pipeline.cpp 3951 // Sort and cull in the new renderer are moved to pipeline.cpp
3886 // Here, particles are updated and drawables are moved. 3952 // Here, particles are updated and drawables are moved.
3887 // 3953 //
3888 if (gViewerWindow->renderingFastFrame() || gViewerWindow->firstFastFrame())
3889 {
3890 gFrameStats.start(LLFrameStats::UPDATE_MOVE);
3891 gFrameStats.start(LLFrameStats::UPDATE_CULL);
3892 gFrameStats.start(LLFrameStats::UPDATE_GEOM);
3893 }
3894 3954
3895 if (!gNoRender) 3955 if (!gNoRender)
3896 { 3956 {
@@ -3899,9 +3959,6 @@ void idle()
3899 3959
3900 gFrameStats.start(LLFrameStats::UPDATE_PARTICLES); 3960 gFrameStats.start(LLFrameStats::UPDATE_PARTICLES);
3901 gWorldp->updateParticles(); 3961 gWorldp->updateParticles();
3902
3903 //now that transforms are updated, update flexible objects
3904 LLVolumeImplFlexible::doFlexibleUpdateBins();
3905 } 3962 }
3906 stop_glerror(); 3963 stop_glerror();
3907 3964
@@ -3909,7 +3966,6 @@ void idle()
3909 3966
3910 // objects and camera should be in sync, do LOD calculations now 3967 // objects and camera should be in sync, do LOD calculations now
3911 { 3968 {
3912// LLFastTimer t(LLFastTimer::FTM_OBJECTLIST_UPDATE); // Actually "object update"
3913 LLFastTimer t(LLFastTimer::FTM_LOD_UPDATE); 3969 LLFastTimer t(LLFastTimer::FTM_LOD_UPDATE);
3914 gObjectList.updateApparentAngles(gAgent); 3970 gObjectList.updateApparentAngles(gAgent);
3915 } 3971 }
@@ -4018,6 +4074,35 @@ F32 mouse_y_from_center(S32 y)
4018 4074
4019///////////////////////////////////////////////////////// 4075/////////////////////////////////////////////////////////
4020 4076
4077class AudioSettingsListener: public LLSimpleListener
4078{
4079 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4080 {
4081 // Note: Ignore the specific event value, look up the ones we want
4082 if (!gAudiop) return true;
4083 gAudiop->setDopplerFactor(gSavedSettings.getF32("AudioLevelDoppler"));
4084 gAudiop->setDistanceFactor(gSavedSettings.getF32("AudioLevelDistance"));
4085#ifdef kAUDIO_ENABLE_WIND
4086 // Wind Gain
4087 gAudiop->mMaxWindGain = gSavedSettings.getF32("AudioLevelWind");
4088 // Rolloff
4089 LLVector3 camera_pos = gAgent.getCameraPositionAgent();
4090 LLViewerRegion* region = gAgent.getRegion();
4091 F32 camera_water_height = region ? camera_pos.mV[VZ] - region->getWaterHeight() : 0.f;
4092 if (camera_water_height < 0.f)
4093 {
4094 gAudiop->setRolloffFactor(gSavedSettings.getF32("AudioLevelRolloff") * LL_ROLLOFF_MULTIPLIER_UNDER_WATER);
4095 }
4096 else
4097 {
4098 gAudiop->setRolloffFactor(gSavedSettings.getF32("AudioLevelRolloff"));
4099 }
4100#endif
4101 return true;
4102 }
4103};
4104static AudioSettingsListener audio_settings_listener;
4105
4021void init_audio() 4106void init_audio()
4022{ 4107{
4023 if (!gAudiop) 4108 if (!gAudiop)
@@ -4086,6 +4171,8 @@ void init_audio()
4086#ifdef kAUDIO_ENABLE_WIND 4171#ifdef kAUDIO_ENABLE_WIND
4087 gAudiop->enableWind(!mute_audio); 4172 gAudiop->enableWind(!mute_audio);
4088 gAudiop->mMaxWindGain = gSavedSettings.getF32("AudioLevelWind"); 4173 gAudiop->mMaxWindGain = gSavedSettings.getF32("AudioLevelWind");
4174 gSavedSettings.getControl("AudioLevelWind")->addListener(&audio_settings_listener);
4175 gSavedSettings.getControl("AudioLevelRolloff")->addListener(&audio_settings_listener);
4089 // don't use the setter setMaxWindGain() because we don't 4176 // don't use the setter setMaxWindGain() because we don't
4090 // want to screw up the fade-in on startup by setting actual source gain 4177 // want to screw up the fade-in on startup by setting actual source gain
4091 // outside the fade-in. 4178 // outside the fade-in.
@@ -4094,8 +4181,10 @@ void init_audio()
4094 gAudiop->setMasterGain ( gSavedSettings.getF32 ( "AudioLevelMaster" ) ); 4181 gAudiop->setMasterGain ( gSavedSettings.getF32 ( "AudioLevelMaster" ) );
4095 4182
4096 gAudiop->setDopplerFactor(gSavedSettings.getF32("AudioLevelDoppler")); 4183 gAudiop->setDopplerFactor(gSavedSettings.getF32("AudioLevelDoppler"));
4097 gAudiop->setDistanceFactor(gSavedSettings.getF32("AudioLevelDistance")); 4184 gSavedSettings.getControl("AudioLevelDoppler")->addListener(&audio_settings_listener);
4098 gAudiop->setRolloffFactor(gSavedSettings.getF32("AudioLevelRolloff")); 4185 gAudiop->setDistanceFactor(gSavedSettings.getF32("AudioLevelDistance"));
4186 gSavedSettings.getControl("AudioLevelDistance")->addListener(&audio_settings_listener);
4187 gAudiop->setRolloffFactor(gSavedSettings.getF32("AudioLevelRolloff"));
4099 gAudiop->setMuted(mute_audio); 4188 gAudiop->setMuted(mute_audio);
4100} 4189}
4101 4190
@@ -4647,16 +4736,6 @@ class LLNightBrightnessListener: public LLSimpleListener
4647}; 4736};
4648static LLNightBrightnessListener night_brightness_listener; 4737static LLNightBrightnessListener night_brightness_listener;
4649 4738
4650class LLUseAGPListener: public LLSimpleListener
4651{
4652 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4653 {
4654 gPipeline.setUseAGP(event->getValue().asBoolean() && gGLManager.mHasAnyAGP);
4655 return true;
4656 }
4657};
4658static LLUseAGPListener use_agp_listener;
4659
4660class LLFogRatioListener: public LLSimpleListener 4739class LLFogRatioListener: public LLSimpleListener
4661{ 4740{
4662 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) 4741 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
@@ -4858,6 +4937,16 @@ class LLAudioMuteListener: public LLSimpleListener
4858 4937
4859static LLAudioMuteListener audio_mute_listener; 4938static LLAudioMuteListener audio_mute_listener;
4860 4939
4940class LLUseOcclusionListener: public LLSimpleListener
4941{
4942 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4943 {
4944 LLPipeline::sUseOcclusion = (event->getValue().asBoolean() && gGLManager.mHasOcclusionQuery &&
4945 !gUseWireframe);
4946 return true;
4947 }
4948};
4949static LLUseOcclusionListener use_occlusion_listener;
4861 4950
4862class LLNumpadControlListener: public LLSimpleListener 4951class LLNumpadControlListener: public LLSimpleListener
4863{ 4952{
@@ -4873,6 +4962,26 @@ class LLNumpadControlListener: public LLSimpleListener
4873 4962
4874static LLNumpadControlListener numpad_control_listener; 4963static LLNumpadControlListener numpad_control_listener;
4875 4964
4965class LLRenderUseVBOListener: public LLSimpleListener
4966{
4967 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4968 {
4969 gPipeline.setUseVBO(event->getValue().asBoolean());
4970 return true;
4971 }
4972};
4973static LLRenderUseVBOListener render_use_vbo_listener;
4974
4975class LLRenderLightingDetailListener: public LLSimpleListener
4976{
4977 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4978 {
4979 gPipeline.setLightingDetail(event->getValue().asInteger());
4980 return true;
4981 }
4982};
4983static LLRenderLightingDetailListener render_lighting_detail_listener;
4984
4876// Use these strictly for things that are constructed at startup, 4985// Use these strictly for things that are constructed at startup,
4877// or for things that are performance critical. JC 4986// or for things that are performance critical. JC
4878void saved_settings_to_globals() 4987void saved_settings_to_globals()
@@ -4894,7 +5003,6 @@ void saved_settings_to_globals()
4894 LLVOSky::sNighttimeBrightness = gSavedSettings.getF32("RenderNightBrightness"); 5003 LLVOSky::sNighttimeBrightness = gSavedSettings.getF32("RenderNightBrightness");
4895 5004
4896 LLImageGL::sGlobalUseAnisotropic = gSavedSettings.getBOOL("RenderAnisotropic"); 5005 LLImageGL::sGlobalUseAnisotropic = gSavedSettings.getBOOL("RenderAnisotropic");
4897 gRenderLightGlows = gSavedSettings.getBOOL("RenderLightGlows");
4898 LLVOVolume::sLODFactor = gSavedSettings.getF32("RenderVolumeLODFactor"); 5006 LLVOVolume::sLODFactor = gSavedSettings.getF32("RenderVolumeLODFactor");
4899 LLVOVolume::sDistanceFactor = 1.f-LLVOVolume::sLODFactor * 0.1f; 5007 LLVOVolume::sDistanceFactor = 1.f-LLVOVolume::sLODFactor * 0.1f;
4900 LLVolumeImplFlexible::sUpdateFactor = gSavedSettings.getF32("RenderFlexTimeFactor"); 5008 LLVolumeImplFlexible::sUpdateFactor = gSavedSettings.getF32("RenderFlexTimeFactor");
@@ -4908,9 +5016,6 @@ void saved_settings_to_globals()
4908 LLSelectMgr::sRectSelectInclusive = gSavedSettings.getBOOL("RectangleSelectInclusive"); 5016 LLSelectMgr::sRectSelectInclusive = gSavedSettings.getBOOL("RectangleSelectInclusive");
4909 LLSelectMgr::sRenderHiddenSelections = gSavedSettings.getBOOL("RenderHiddenSelections"); 5017 LLSelectMgr::sRenderHiddenSelections = gSavedSettings.getBOOL("RenderHiddenSelections");
4910 LLSelectMgr::sRenderLightRadius = gSavedSettings.getBOOL("RenderLightRadius"); 5018 LLSelectMgr::sRenderLightRadius = gSavedSettings.getBOOL("RenderLightRadius");
4911// LLViewerObject::sUseSharedDrawables = gSavedSettings.getBOOL("RenderUseSharedDrawables");
4912 BOOL use_occlusion = gSavedSettings.getBOOL("UseOcclusion");
4913 gPipeline.setUseOcclusionCulling( use_occlusion );
4914 5019
4915 gFrameStats.setTrackStats(gSavedSettings.getBOOL("StatsSessionTrackFrameStats")); 5020 gFrameStats.setTrackStats(gSavedSettings.getBOOL("StatsSessionTrackFrameStats"));
4916 gAgentPilot.mNumRuns = gSavedSettings.getS32("StatsNumRuns"); 5021 gAgentPilot.mNumRuns = gSavedSettings.getS32("StatsNumRuns");
@@ -4922,7 +5027,6 @@ void saved_settings_to_globals()
4922 gAFKTimeout = gSavedSettings.getF32("AFKTimeout"); 5027 gAFKTimeout = gSavedSettings.getF32("AFKTimeout");
4923 gMouseSensitivity = gSavedSettings.getF32("MouseSensitivity"); 5028 gMouseSensitivity = gSavedSettings.getF32("MouseSensitivity");
4924 gInvertMouse = gSavedSettings.getBOOL("InvertMouse"); 5029 gInvertMouse = gSavedSettings.getBOOL("InvertMouse");
4925 gAvatarBacklight = gSavedSettings.getBOOL("AvatarBacklight");
4926 gShowObjectUpdates = gSavedSettings.getBOOL("ShowObjectUpdates"); 5030 gShowObjectUpdates = gSavedSettings.getBOOL("ShowObjectUpdates");
4927 gMapScale = gSavedSettings.getF32("MapScale"); 5031 gMapScale = gSavedSettings.getF32("MapScale");
4928 gMiniMapScale = gSavedSettings.getF32("MiniMapScale"); 5032 gMiniMapScale = gSavedSettings.getF32("MiniMapScale");
@@ -4941,6 +5045,7 @@ void saved_settings_to_globals()
4941 gSavedSettings.getControl("RenderTerrainDetail")->addListener(&terrain_detail_listener); 5045 gSavedSettings.getControl("RenderTerrainDetail")->addListener(&terrain_detail_listener);
4942 gSavedSettings.getControl("RenderRippleWater")->addListener(&set_shader_listener); 5046 gSavedSettings.getControl("RenderRippleWater")->addListener(&set_shader_listener);
4943 gSavedSettings.getControl("RenderAvatarVP")->addListener(&set_shader_listener); 5047 gSavedSettings.getControl("RenderAvatarVP")->addListener(&set_shader_listener);
5048 gSavedSettings.getControl("RenderDynamicReflections")->addListener(&set_shader_listener);
4944 gSavedSettings.getControl("RenderAvatarMode")->addListener(&set_shader_listener); 5049 gSavedSettings.getControl("RenderAvatarMode")->addListener(&set_shader_listener);
4945 gSavedSettings.getControl("RenderVolumeLODFactor")->addListener(&volume_lod_listener); 5050 gSavedSettings.getControl("RenderVolumeLODFactor")->addListener(&volume_lod_listener);
4946 gSavedSettings.getControl("RenderAvatarLODFactor")->addListener(&avatar_lod_listener); 5051 gSavedSettings.getControl("RenderAvatarLODFactor")->addListener(&avatar_lod_listener);
@@ -4949,7 +5054,6 @@ void saved_settings_to_globals()
4949 gSavedSettings.getControl("ThrottleBandwidthKBPS")->addListener(&bandwidth_listener); 5054 gSavedSettings.getControl("ThrottleBandwidthKBPS")->addListener(&bandwidth_listener);
4950 gSavedSettings.getControl("RenderGamma")->addListener(&gamma_listener); 5055 gSavedSettings.getControl("RenderGamma")->addListener(&gamma_listener);
4951 gSavedSettings.getControl("RenderNightBrightness")->addListener(&night_brightness_listener); 5056 gSavedSettings.getControl("RenderNightBrightness")->addListener(&night_brightness_listener);
4952 gSavedSettings.getControl("RenderUseAGP")->addListener(&use_agp_listener);
4953 gSavedSettings.getControl("RenderFogRatio")->addListener(&fog_ratio_listener); 5057 gSavedSettings.getControl("RenderFogRatio")->addListener(&fog_ratio_listener);
4954 gSavedSettings.getControl("RenderMaxPartCount")->addListener(&max_partCount_listener); 5058 gSavedSettings.getControl("RenderMaxPartCount")->addListener(&max_partCount_listener);
4955 gSavedSettings.getControl("AvatarCompositeLimit")->addListener(&composite_limit_listener); 5059 gSavedSettings.getControl("AvatarCompositeLimit")->addListener(&composite_limit_listener);
@@ -4957,12 +5061,13 @@ void saved_settings_to_globals()
4957 gSavedSettings.getControl("ChatFontSize")->addListener(&chat_font_size_listener); 5061 gSavedSettings.getControl("ChatFontSize")->addListener(&chat_font_size_listener);
4958 gSavedSettings.getControl("ChatPersistTime")->addListener(&chat_persist_time_listener); 5062 gSavedSettings.getControl("ChatPersistTime")->addListener(&chat_persist_time_listener);
4959 gSavedSettings.getControl("ConsoleMaxLines")->addListener(&console_max_lines_listener); 5063 gSavedSettings.getControl("ConsoleMaxLines")->addListener(&console_max_lines_listener);
4960 5064 gSavedSettings.getControl("UseOcclusion")->addListener(&use_occlusion_listener);
4961 gSavedSettings.getControl("AudioLevelMaster")->addListener(&master_audio_listener); 5065 gSavedSettings.getControl("AudioLevelMaster")->addListener(&master_audio_listener);
4962 gSavedSettings.getControl("AudioStreamingMusic")->addListener(&audio_stream_music_listener); 5066 gSavedSettings.getControl("AudioStreamingMusic")->addListener(&audio_stream_music_listener);
4963 gSavedSettings.getControl("AudioStreamingVideo")->addListener(&audio_stream_media_listener); 5067 gSavedSettings.getControl("AudioStreamingVideo")->addListener(&audio_stream_media_listener);
4964 gSavedSettings.getControl("MuteAudio")->addListener(&audio_mute_listener); 5068 gSavedSettings.getControl("MuteAudio")->addListener(&audio_mute_listener);
4965 5069 gSavedSettings.getControl("RenderVBOEnable")->addListener(&render_use_vbo_listener);
5070 gSavedSettings.getControl("RenderLightingDetail")->addListener(&render_lighting_detail_listener);
4966 gSavedSettings.getControl("NumpadControl")->addListener(&numpad_control_listener); 5071 gSavedSettings.getControl("NumpadControl")->addListener(&numpad_control_listener);
4967 5072
4968 // gAgent.init() also loads from saved settings. 5073 // gAgent.init() also loads from saved settings.
@@ -4970,7 +5075,6 @@ void saved_settings_to_globals()
4970 5075
4971void cleanup_saved_settings() 5076void cleanup_saved_settings()
4972{ 5077{
4973 gSavedSettings.setBOOL("RenderLightGlows", gRenderLightGlows);
4974 gSavedSettings.setBOOL("MouseSun", FALSE); 5078 gSavedSettings.setBOOL("MouseSun", FALSE);
4975 5079
4976 gSavedSettings.setBOOL("FlyBtnState", FALSE); 5080 gSavedSettings.setBOOL("FlyBtnState", FALSE);
@@ -4985,9 +5089,7 @@ void cleanup_saved_settings()
4985 5089
4986 gSavedSettings.setBOOL("AllowAFK", gAllowAFK); 5090 gSavedSettings.setBOOL("AllowAFK", gAllowAFK);
4987 gSavedSettings.setBOOL("ShowObjectUpdates", gShowObjectUpdates); 5091 gSavedSettings.setBOOL("ShowObjectUpdates", gShowObjectUpdates);
4988 BOOL use_occlusion = gPipeline.getUseOcclusionCulling(); 5092
4989 gSavedSettings.setBOOL( "UseOcclusion", use_occlusion );
4990
4991 if (!gNoRender) 5093 if (!gNoRender)
4992 { 5094 {
4993 if (gDebugView) 5095 if (gDebugView)
@@ -5050,7 +5152,7 @@ void write_debug(const char *str)
5050 { 5152 {
5051 std::string debug_filename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"debug_info.log"); 5153 std::string debug_filename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"debug_info.log");
5052 llinfos << "Opening debug file " << debug_filename << llendl; 5154 llinfos << "Opening debug file " << debug_filename << llendl;
5053 gDebugFile = LLFile::fopen(debug_filename.c_str(), "w"); 5155 gDebugFile = LLFile::fopen(debug_filename.c_str(), "w"); /* Flawfinder: ignore */
5054 if (!gDebugFile) 5156 if (!gDebugFile)
5055 { 5157 {
5056 llinfos << "Opening debug file " << debug_filename << " failed. Using stderr." << llendl; 5158 llinfos << "Opening debug file " << debug_filename << " failed. Using stderr." << llendl;
@@ -5117,8 +5219,6 @@ void output_statistics(void*)
5117 llinfos << "Memory Usage:" << llendl; 5219 llinfos << "Memory Usage:" << llendl;
5118 llinfos << "--------------------------------" << llendl; 5220 llinfos << "--------------------------------" << llendl;
5119 llinfos << "Pipeline:" << llendl; 5221 llinfos << "Pipeline:" << llendl;
5120 S32 total_usage = 0;
5121 total_usage += gPipeline.getMemUsage(TRUE);
5122 llinfos << llendl; 5222 llinfos << llendl;
5123 5223
5124#if LL_SMARTHEAP 5224#if LL_SMARTHEAP
@@ -5464,8 +5564,10 @@ void release_signals()
5464 5564
5465void purge_cache() 5565void purge_cache()
5466{ 5566{
5467 char mask[LL_MAX_PATH]; 5567 llinfos << "Purging Texture Cache..." << llendl;
5468 sprintf(mask, "%s*.*", gDirUtilp->getDirDelimiter().c_str()); 5568 gTextureCache->purgeCache(LL_PATH_CACHE);
5569 llinfos << "Purging Cache..." << llendl;
5570 std::string mask = gDirUtilp->getDirDelimiter() + "*.*";
5469 gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,"").c_str(),mask); 5571 gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,"").c_str(),mask);
5470} 5572}
5471 5573
@@ -5506,43 +5608,43 @@ int parse_args(int argc, char **argv)
5506 else if (!strcmp(argv[j], "--aditi")) 5608 else if (!strcmp(argv[j], "--aditi"))
5507 { 5609 {
5508 gUserServerChoice = USERSERVER_ADITI; 5610 gUserServerChoice = USERSERVER_ADITI;
5509 sprintf(gUserServerName,"%s", gUserServerDomainName[gUserServerChoice].mName); 5611 snprintf(gUserServerName, MAX_STRING, "%s", gUserServerDomainName[gUserServerChoice].mName); /* Flawfinder: ignore */
5510 gConnectToSomething = TRUE; 5612 gConnectToSomething = TRUE;
5511 } 5613 }
5512 else if (!strcmp(argv[j], "--agni")) 5614 else if (!strcmp(argv[j], "--agni"))
5513 { 5615 {
5514 gUserServerChoice = USERSERVER_AGNI; 5616 gUserServerChoice = USERSERVER_AGNI;
5515 sprintf(gUserServerName,"%s", gUserServerDomainName[gUserServerChoice].mName); 5617 snprintf(gUserServerName, MAX_STRING, "%s", gUserServerDomainName[gUserServerChoice].mName); /* Flawfinder: ignore */
5516 gConnectToSomething = TRUE; 5618 gConnectToSomething = TRUE;
5517 } 5619 }
5518 else if (!strcmp(argv[j], "--dmz")) 5620 else if (!strcmp(argv[j], "--dmz"))
5519 { 5621 {
5520 gUserServerChoice = USERSERVER_DMZ; 5622 gUserServerChoice = USERSERVER_DMZ;
5521 sprintf(gUserServerName,"%s", gUserServerDomainName[gUserServerChoice].mName); 5623 snprintf(gUserServerName, MAX_STRING, "%s", gUserServerDomainName[gUserServerChoice].mName); /* Flawfinder: ignore */
5522 gConnectToSomething = TRUE; 5624 gConnectToSomething = TRUE;
5523 } 5625 }
5524 else if (!strcmp(argv[j], "--siva")) 5626 else if (!strcmp(argv[j], "--siva"))
5525 { 5627 {
5526 gUserServerChoice = USERSERVER_SIVA; 5628 gUserServerChoice = USERSERVER_SIVA;
5527 sprintf(gUserServerName,"%s", gUserServerDomainName[gUserServerChoice].mName); 5629 snprintf(gUserServerName, MAX_STRING, "%s", gUserServerDomainName[gUserServerChoice].mName); /* Flawfinder: ignore */
5528 gConnectToSomething = TRUE; 5630 gConnectToSomething = TRUE;
5529 } 5631 }
5530 else if (!strcmp(argv[j], "--shakti")) 5632 else if (!strcmp(argv[j], "--shakti"))
5531 { 5633 {
5532 gUserServerChoice = USERSERVER_SHAKTI; 5634 gUserServerChoice = USERSERVER_SHAKTI;
5533 sprintf(gUserServerName,"%s", gUserServerDomainName[gUserServerChoice].mName); 5635 snprintf(gUserServerName, MAX_STRING, "%s", gUserServerDomainName[gUserServerChoice].mName); /* Flawfinder: ignore */
5534 gConnectToSomething = TRUE; 5636 gConnectToSomething = TRUE;
5535 } 5637 }
5536 else if (!strcmp(argv[j], "--durga")) 5638 else if (!strcmp(argv[j], "--durga"))
5537 { 5639 {
5538 gUserServerChoice = USERSERVER_DURGA; 5640 gUserServerChoice = USERSERVER_DURGA;
5539 sprintf(gUserServerName,"%s", gUserServerDomainName[gUserServerChoice].mName); 5641 snprintf(gUserServerName, MAX_STRING, "%s", gUserServerDomainName[gUserServerChoice].mName); /* Flawfinder: ignore */
5540 gConnectToSomething = TRUE; 5642 gConnectToSomething = TRUE;
5541 } 5643 }
5542 else if (!strcmp(argv[j], "--soma")) 5644 else if (!strcmp(argv[j], "--soma"))
5543 { 5645 {
5544 gUserServerChoice = USERSERVER_SOMA; 5646 gUserServerChoice = USERSERVER_SOMA;
5545 sprintf(gUserServerName,"%s", gUserServerDomainName[gUserServerChoice].mName); 5647 snprintf(gUserServerName, MAX_STRING, "%s", gUserServerDomainName[gUserServerChoice].mName); /* Flawfinder: ignore */
5546 gConnectToSomething = TRUE; 5648 gConnectToSomething = TRUE;
5547 } 5649 }
5548 else if (!strcmp(argv[j], "--ganga")) 5650 else if (!strcmp(argv[j], "--ganga"))
@@ -5551,6 +5653,12 @@ int parse_args(int argc, char **argv)
5551 sprintf(gUserServerName,"%s", gUserServerDomainName[gUserServerChoice].mName); 5653 sprintf(gUserServerName,"%s", gUserServerDomainName[gUserServerChoice].mName);
5552 gConnectToSomething = TRUE; 5654 gConnectToSomething = TRUE;
5553 } 5655 }
5656 else if (!strcmp(argv[j], "--vaak"))
5657 {
5658 gUserServerChoice = USERSERVER_VAAK;
5659 sprintf(gUserServerName,"%s", gUserServerDomainName[gUserServerChoice].mName);
5660 gConnectToSomething = TRUE;
5661 }
5554 else if (!strcmp(argv[j], "--uma")) 5662 else if (!strcmp(argv[j], "--uma"))
5555 { 5663 {
5556 gUserServerChoice = USERSERVER_UMA; 5664 gUserServerChoice = USERSERVER_UMA;
@@ -5562,7 +5670,7 @@ int parse_args(int argc, char **argv)
5562 if (!strcmp(argv[j], "-")) 5670 if (!strcmp(argv[j], "-"))
5563 { 5671 {
5564 gUserServerChoice = USERSERVER_LOCAL; 5672 gUserServerChoice = USERSERVER_LOCAL;
5565 sprintf(gUserServerName,"%s", LOOPBACK_ADDRESS_STRING); 5673 snprintf(gUserServerName, MAX_STRING, "%s", LOOPBACK_ADDRESS_STRING); /* Flawfinder: ignore */
5566 } 5674 }
5567 else 5675 else
5568 { 5676 {
@@ -5570,7 +5678,7 @@ int parse_args(int argc, char **argv)
5570 ip_string.assign( argv[j] ); 5678 ip_string.assign( argv[j] );
5571 LLString::trim(ip_string); 5679 LLString::trim(ip_string);
5572 gUserServer.setHostByName( ip_string.c_str() ); 5680 gUserServer.setHostByName( ip_string.c_str() );
5573 snprintf(gUserServerName, MAX_STRING, "%s", ip_string.c_str()); 5681 snprintf(gUserServerName, MAX_STRING, "%s", ip_string.c_str()); /* Flawfinder: ignore */
5574 } 5682 }
5575 gConnectToSomething = TRUE; 5683 gConnectToSomething = TRUE;
5576 } 5684 }
@@ -5653,91 +5761,10 @@ int parse_args(int argc, char **argv)
5653 gUserServer.invalidate(); 5761 gUserServer.invalidate();
5654 gRunLocal = TRUE; 5762 gRunLocal = TRUE;
5655 } 5763 }
5656 else if (!strcmp(argv[j], "-debugst") && (++j < argc))
5657 {
5658 U32 err_val;
5659 sscanf(argv[j], "%d", &err_val);
5660 llinfos << "Enabling debug mask " << err_val << " (0x" << (1<<err_val) << ")" << llendl;
5661 gErrorStream.setDebugMask( 1<<err_val );
5662 gErrorStream.setLevel( LLErrorStream::DEBUG );
5663 }
5664 else if (!strcmp(argv[j], "-errmask") && (++j < argc))
5665 {
5666 U32 err_mask;
5667 sscanf(argv[j], "%d", &err_mask);
5668 llinfos << "Setting error mask to " << err_mask << llendl;
5669 gErrorStream.setDebugMask( err_mask );
5670 gErrorStream.setLevel( LLErrorStream::DEBUG );
5671 }
5672 else if(!strcmp(argv[j], "-noutc"))
5673 {
5674 gLogUTC = FALSE;
5675 }
5676 else if(!strcmp(argv[j], "-noinvlib")) 5764 else if(!strcmp(argv[j], "-noinvlib"))
5677 { 5765 {
5678 gRequestInventoryLibrary = FALSE; 5766 gRequestInventoryLibrary = FALSE;
5679 } 5767 }
5680#if !LL_RELEASE_FOR_DOWNLOAD
5681 else if(!strcmp(argv[j], "-logcontrol"))
5682 {
5683 S32 control;
5684 S32 level;
5685 U32 debugmask;
5686 S32 time;
5687 S32 location;
5688
5689 if (++j >= argc)
5690 {
5691 llwarns << "Missing <control> after -logcontrol" << llendl;
5692 return 1;
5693 }
5694 sscanf(argv[j], "%d", &control);
5695
5696 if (++j >= argc)
5697 {
5698 llwarns << "Missing <level> after -logcontrol" << llendl;
5699 return 1;
5700 }
5701 sscanf(argv[j], "%d", &level);
5702
5703 if (++j >= argc)
5704 {
5705 llwarns << "Missing <mask> after -logcontrol" << llendl;
5706 return 1;
5707 }
5708 sscanf(argv[j], "%u", &debugmask);
5709
5710 if (++j >= argc)
5711 {
5712 llwarns << "Missing <time> after -logcontrol" << llendl;
5713 return 1;
5714 }
5715 sscanf(argv[j], "%d", &time);
5716
5717 if (++j >= argc)
5718 {
5719 llwarns << "Missing <location> after -logcontrol" << llendl;
5720 return 1;
5721 }
5722 sscanf(argv[j], "%d", &location);
5723
5724 if (LLErrorStream::MERGE == control)
5725 {
5726 gErrorStream.mergeLevel( LLErrorStream::ELevel(level) );
5727 gErrorStream.mergeDebugMask(debugmask);
5728 gErrorStream.mergeTime( BOOL(time) );
5729 gErrorStream.mergeLocation( BOOL(location) );
5730 }
5731 else
5732 {
5733 gErrorStream.setLevel( LLErrorStream::ELevel(level) );
5734 gErrorStream.setDebugMask(debugmask);
5735 gErrorStream.setTime( BOOL(time) );
5736 gErrorStream.setPrintLocation( BOOL(location) );
5737 }
5738 continue;
5739 }
5740#endif
5741 else if (!strcmp(argv[j], "-log")) 5768 else if (!strcmp(argv[j], "-log"))
5742 { 5769 {
5743 gLogMessages = TRUE; 5770 gLogMessages = TRUE;
@@ -5746,14 +5773,11 @@ int parse_args(int argc, char **argv)
5746 else if (!strcmp(argv[j], "-logfile") && (++j < argc)) 5773 else if (!strcmp(argv[j], "-logfile") && (++j < argc))
5747 { 5774 {
5748 // *NOTE: This buffer size is hard coded into scanf() below. 5775 // *NOTE: This buffer size is hard coded into scanf() below.
5749 char logfile[256]; 5776 char logfile[256]; /* Flawfinder: ignore */
5750 sscanf(argv[j], "%255s", logfile); 5777 sscanf(argv[j], "%255s", logfile); /* Flawfinder: ignore */
5751 llinfos << "Setting log file to " << logfile << llendl; 5778 llinfos << "Setting log file to " << logfile << llendl;
5752 LLFile::remove(logfile); 5779 LLFile::remove(logfile);
5753 if (!gErrorStream.setFile(logfile)) 5780 LLError::logToFile(logfile);
5754 {
5755 llinfos << "Error setting log file to " << logfile << llendl;
5756 }
5757 } 5781 }
5758 else if (!strcmp(argv[j], "-settings") && (++j < argc)) 5782 else if (!strcmp(argv[j], "-settings") && (++j < argc))
5759 { 5783 {
@@ -6022,7 +6046,7 @@ bool LLURLSimString::send_to_other_instance()
6022 return false; 6046 return false;
6023 } 6047 }
6024#if LL_WINDOWS 6048#if LL_WINDOWS
6025 wchar_t window_class[256]; // Assume max length < 255 chars. 6049 wchar_t window_class[256]; /* Flawfinder: ignore */ // Assume max length < 255 chars.
6026 mbstowcs(window_class, gWindowName.c_str(), 255); 6050 mbstowcs(window_class, gWindowName.c_str(), 255);
6027 window_class[255] = 0; 6051 window_class[255] = 0;
6028 // Use the class instead of the window name. 6052 // Use the class instead of the window name.
@@ -6031,7 +6055,7 @@ bool LLURLSimString::send_to_other_instance()
6031 { 6055 {
6032 lldebugs << "Found other window with the name '" << gWindowTitle << "'" << llendl; 6056 lldebugs << "Found other window with the name '" << gWindowTitle << "'" << llendl;
6033 llurl_data url_data; 6057 llurl_data url_data;
6034 strncpy(url_data.mSimName, sInstance.mSimName.c_str(), DB_SIM_NAME_BUF_SIZE); 6058 strncpy(url_data.mSimName, sInstance.mSimName.c_str(), DB_SIM_NAME_BUF_SIZE); /* Flawfinder: ignore*/
6035 url_data.mSimName[DB_SIM_NAME_BUF_SIZE - 1] = '\0'; 6059 url_data.mSimName[DB_SIM_NAME_BUF_SIZE - 1] = '\0';
6036 url_data.mSimX = sInstance.mX; 6060 url_data.mSimX = sInstance.mX;
6037 url_data.mSimY = sInstance.mY; 6061 url_data.mSimY = sInstance.mY;
@@ -6059,7 +6083,7 @@ void load_name_cache()
6059 6083
6060 std::string name_cache; 6084 std::string name_cache;
6061 name_cache = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "name.cache"); 6085 name_cache = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "name.cache");
6062 FILE* name_cache_fp = LLFile::fopen(name_cache.c_str(), "r"); 6086 FILE* name_cache_fp = LLFile::fopen(name_cache.c_str(), "r"); /* Flawfinder: ignore*/
6063 if (name_cache_fp) 6087 if (name_cache_fp)
6064 { 6088 {
6065 gCacheName->importFile(name_cache_fp); 6089 gCacheName->importFile(name_cache_fp);
@@ -6073,7 +6097,7 @@ void save_name_cache()
6073 6097
6074 std::string name_cache; 6098 std::string name_cache;
6075 name_cache = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "name.cache"); 6099 name_cache = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "name.cache");
6076 FILE* name_cache_fp = LLFile::fopen(name_cache.c_str(), "w"); 6100 FILE* name_cache_fp = LLFile::fopen(name_cache.c_str(), "w"); /* Flawfinder: ignore*/
6077 if (name_cache_fp) 6101 if (name_cache_fp)
6078 { 6102 {
6079 gCacheName->exportFile(name_cache_fp); 6103 gCacheName->exportFile(name_cache_fp);
@@ -6167,8 +6191,8 @@ void disconnect_viewer(void *)
6167// helper function for cleanup_app 6191// helper function for cleanup_app
6168void remove_cache_files(const char* file_mask) 6192void remove_cache_files(const char* file_mask)
6169{ 6193{
6170 char mask[LL_MAX_PATH]; 6194 char mask[LL_MAX_PATH]; /* Flawfinder: ignore */
6171 sprintf(mask, "%s%s", gDirUtilp->getDirDelimiter().c_str(), file_mask); 6195 snprintf(mask, LL_MAX_PATH, "%s%s", gDirUtilp->getDirDelimiter().c_str(), file_mask); /* Flawfinder: ignore */
6172 gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "").c_str(), mask); 6196 gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "").c_str(), mask);
6173} 6197}
6174 6198
@@ -6311,9 +6335,9 @@ void cleanup_app()
6311 llinfos << "Viewer disconnected" << llendflush; 6335 llinfos << "Viewer disconnected" << llendflush;
6312 6336
6313 gDisconnectedImagep = NULL; 6337 gDisconnectedImagep = NULL;
6314 gStartImageGL = NULL; 6338 release_start_screen(); // just in case
6315 6339
6316 gErrorStream.setFixedBuffer(NULL); 6340 LLError::logToFixedBuffer(NULL);
6317 6341
6318 llinfos << "Cleaning Up" << llendflush; 6342 llinfos << "Cleaning Up" << llendflush;
6319 6343
@@ -6323,9 +6347,6 @@ void cleanup_app()
6323 LLHUDObject::cleanupHUDObjects(); 6347 LLHUDObject::cleanupHUDObjects();
6324 llinfos << "HUD Objects cleaned up" << llendflush; 6348 llinfos << "HUD Objects cleaned up" << llendflush;
6325 6349
6326 LLVOTreeNew::cleanupTextures();
6327 llinfos << "Textures cleaned up" << llendflush;
6328
6329 // End TransferManager before deleting systems it depends on (Audio, VFS, AssetStorage) 6350 // End TransferManager before deleting systems it depends on (Audio, VFS, AssetStorage)
6330#if 0 // this seems to get us stuck in an infinite loop... 6351#if 0 // this seems to get us stuck in an infinite loop...
6331 gTransferManager.cleanup(); 6352 gTransferManager.cleanup();
@@ -6520,8 +6541,8 @@ void cleanup_app()
6520 if (gPurgeOnExit) 6541 if (gPurgeOnExit)
6521 { 6542 {
6522 llinfos << "Purging all cache files on exit" << llendflush; 6543 llinfos << "Purging all cache files on exit" << llendflush;
6523 char mask[LL_MAX_PATH]; 6544 char mask[LL_MAX_PATH]; /* Flawfinder: ignore */
6524 sprintf(mask, "%s*.*", gDirUtilp->getDirDelimiter().c_str()); 6545 snprintf(mask, LL_MAX_PATH, "%s*.*", gDirUtilp->getDirDelimiter().c_str()); /* Flawfinder: ignore */
6525 gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,"").c_str(),mask); 6546 gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,"").c_str(),mask);
6526 } 6547 }
6527 6548
@@ -6529,6 +6550,37 @@ void cleanup_app()
6529 6550
6530 close_debug(); 6551 close_debug();
6531 6552
6553 // Let threads finish
6554 LLTimer idleTimer;
6555 idleTimer.reset();
6556 const F64 max_idle_time = 5.f; // 5 seconds
6557 while(1)
6558 {
6559 S32 pending = 0;
6560 pending += gTextureCache->update(1); // unpauses the worker thread
6561 pending += gImageDecodeThread->update(1); // unpauses the image thread
6562 pending += gTextureFetch->update(1); // unpauses the texture fetch thread
6563 pending += LLVFSThread::updateClass(0);
6564 pending += LLLFSThread::updateClass(0);
6565 F64 idle_time = idleTimer.getElapsedTimeF64();
6566 if (!pending || idle_time >= max_idle_time)
6567 {
6568 llwarns << "Quitting with pending background tasks." << llendl;
6569 break;
6570 }
6571 }
6572
6573 // Delete workers first
6574 // shotdown all worker threads before deleting them in case of co-dependencies
6575 gTextureCache->shutdown();
6576 gTextureFetch->shutdown();
6577 gImageDecodeThread->shutdown();
6578 delete gTextureCache;
6579 delete gTextureFetch;
6580 delete gImageDecodeThread;
6581
6582 gImageList.shutdown(); // shutdown again in case a callback added something
6583
6532 // This should eventually be done in LLAppViewer 6584 // This should eventually be done in LLAppViewer
6533 LLImageJ2C::closeDSO(); 6585 LLImageJ2C::closeDSO();
6534 LLImageFormatted::cleanupClass(); 6586 LLImageFormatted::cleanupClass();
@@ -6549,8 +6601,6 @@ void cleanup_app()
6549 delete gVFS; 6601 delete gVFS;
6550 gVFS = NULL; 6602 gVFS = NULL;
6551 6603
6552 LLWorkerThread::cleanupClass();
6553
6554 // This will eventually be done in LLApp 6604 // This will eventually be done in LLApp
6555 LLCommon::cleanupClass(); 6605 LLCommon::cleanupClass();
6556} 6606}
@@ -6580,6 +6630,7 @@ void errorCallback(const std::string &error_string)
6580#ifndef LL_RELEASE_FOR_DOWNLOAD 6630#ifndef LL_RELEASE_FOR_DOWNLOAD
6581 OSMessageBox(error_string.c_str(), "Fatal Error", OSMB_OK); 6631 OSMessageBox(error_string.c_str(), "Fatal Error", OSMB_OK);
6582#endif 6632#endif
6633 LLError::crashAndLoop(error_string);
6583} 6634}
6584// JC - Please don't put code here. Find the right file, perhaps 6635// JC - Please don't put code here. Find the right file, perhaps
6585// llviewermessage.cpp, and put it there. Thanks! 6636// llviewermessage.cpp, and put it there. Thanks!