diff options
Diffstat (limited to 'linden/indra/newview/llappviewer.cpp')
-rw-r--r-- | linden/indra/newview/llappviewer.cpp | 299 |
1 files changed, 155 insertions, 144 deletions
diff --git a/linden/indra/newview/llappviewer.cpp b/linden/indra/newview/llappviewer.cpp index b2bfccf..4d53c88 100644 --- a/linden/indra/newview/llappviewer.cpp +++ b/linden/indra/newview/llappviewer.cpp | |||
@@ -4,7 +4,7 @@ | |||
4 | * | 4 | * |
5 | * $LicenseInfo:firstyear=2007&license=viewergpl$ | 5 | * $LicenseInfo:firstyear=2007&license=viewergpl$ |
6 | * | 6 | * |
7 | * Copyright (c) 2007-2008, Linden Research, Inc. | 7 | * Copyright (c) 2007-2009, Linden Research, Inc. |
8 | * | 8 | * |
9 | * Second Life Viewer Source Code | 9 | * Second Life Viewer Source Code |
10 | * The source code in this file ("Source Code") is provided by Linden Lab | 10 | * The source code in this file ("Source Code") is provided by Linden Lab |
@@ -192,35 +192,22 @@ | |||
192 | 192 | ||
193 | //---------------------------------------------------------------------------- | 193 | //---------------------------------------------------------------------------- |
194 | // viewer.cpp - these are only used in viewer, should be easily moved. | 194 | // viewer.cpp - these are only used in viewer, should be easily moved. |
195 | extern void disable_win_error_reporting(); | ||
196 | 195 | ||
197 | #if LL_DARWIN | 196 | #if LL_DARWIN |
198 | #include <Carbon/Carbon.h> | ||
199 | extern void init_apple_menu(const char* product); | 197 | extern void init_apple_menu(const char* product); |
200 | extern OSErr AEGURLHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn); | ||
201 | extern OSErr AEQuitHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn); | ||
202 | extern OSStatus simpleDialogHandler(EventHandlerCallRef handler, EventRef event, void *userdata); | ||
203 | #include <boost/tokenizer.hpp> | ||
204 | #endif // LL_DARWIN | 198 | #endif // LL_DARWIN |
205 | 199 | ||
206 | |||
207 | extern BOOL gRandomizeFramerate; | 200 | extern BOOL gRandomizeFramerate; |
208 | extern BOOL gPeriodicSlowFrame; | 201 | extern BOOL gPeriodicSlowFrame; |
209 | extern BOOL gDebugGL; | 202 | extern BOOL gDebugGL; |
210 | 203 | ||
211 | //////////////////////////////////////////////////////////// | 204 | //////////////////////////////////////////////////////////// |
212 | // All from the last globals push... | 205 | // All from the last globals push... |
213 | BOOL gHandleKeysAsync = FALSE; | ||
214 | |||
215 | const F32 DEFAULT_AFK_TIMEOUT = 5.f * 60.f; // time with no input before user flagged as Away From Keyboard | 206 | const F32 DEFAULT_AFK_TIMEOUT = 5.f * 60.f; // time with no input before user flagged as Away From Keyboard |
216 | 207 | ||
217 | F32 gSimLastTime; // Used in LLAppViewer::init and send_stats() | 208 | F32 gSimLastTime; // Used in LLAppViewer::init and send_stats() |
218 | F32 gSimFrames; | 209 | F32 gSimFrames; |
219 | 210 | ||
220 | std::string gDisabledMessage; // Set in LLAppViewer::initConfiguration used in idle_startup | ||
221 | |||
222 | BOOL gHideLinks = FALSE; // Set in LLAppViewer::initConfiguration, used externally | ||
223 | |||
224 | BOOL gAllowIdleAFK = TRUE; | 211 | BOOL gAllowIdleAFK = TRUE; |
225 | BOOL gAllowTapTapHoldRun = TRUE; | 212 | BOOL gAllowTapTapHoldRun = TRUE; |
226 | BOOL gShowObjectUpdates = FALSE; | 213 | BOOL gShowObjectUpdates = FALSE; |
@@ -246,7 +233,7 @@ F32 gFPSClamped = 10.f; // Pretend we start at target rate. | |||
246 | F32 gFrameDTClamped = 0.f; // Time between adjacent checks to network for packets | 233 | F32 gFrameDTClamped = 0.f; // Time between adjacent checks to network for packets |
247 | U64 gStartTime = 0; // gStartTime is "private", used only to calculate gFrameTimeSeconds | 234 | U64 gStartTime = 0; // gStartTime is "private", used only to calculate gFrameTimeSeconds |
248 | U32 gFrameStalls = 0; | 235 | U32 gFrameStalls = 0; |
249 | const F64 FRAME_STALL_THRESHOLD = 5.0; | 236 | const F64 FRAME_STALL_THRESHOLD = 1.0; |
250 | 237 | ||
251 | LLTimer gRenderStartTime; | 238 | LLTimer gRenderStartTime; |
252 | LLFrameTimer gForegroundTime; | 239 | LLFrameTimer gForegroundTime; |
@@ -261,7 +248,6 @@ BOOL gDisconnected = FALSE; | |||
261 | 248 | ||
262 | // Map scale in pixels per region | 249 | // Map scale in pixels per region |
263 | F32 gMapScale = 128.f; | 250 | F32 gMapScale = 128.f; |
264 | F32 gMiniMapScale = 128.f; | ||
265 | 251 | ||
266 | // used to restore texture state after a mode switch | 252 | // used to restore texture state after a mode switch |
267 | LLFrameTimer gRestoreGLTimer; | 253 | LLFrameTimer gRestoreGLTimer; |
@@ -316,6 +302,7 @@ std::string gLoginPage; | |||
316 | std::vector<std::string> gLoginURIs; | 302 | std::vector<std::string> gLoginURIs; |
317 | static std::string gHelperURI; | 303 | static std::string gHelperURI; |
318 | 304 | ||
305 | LLAppViewer::LLUpdaterInfo *LLAppViewer::sUpdaterInfo = NULL ; | ||
319 | 306 | ||
320 | void idle_afk_check() | 307 | void idle_afk_check() |
321 | { | 308 | { |
@@ -331,8 +318,7 @@ static void ui_audio_callback(const LLUUID& uuid) | |||
331 | { | 318 | { |
332 | if (gAudiop) | 319 | if (gAudiop) |
333 | { | 320 | { |
334 | F32 volume = gSavedSettings.getBOOL("MuteUI") ? 0.f : gSavedSettings.getF32("AudioLevelUI"); | 321 | gAudiop->triggerSound(uuid, gAgent.getID(), 1.0f, LLAudioEngine::AUDIO_TYPE_UI); |
335 | gAudiop->triggerSound(uuid, gAgent.getID(), volume); | ||
336 | } | 322 | } |
337 | } | 323 | } |
338 | 324 | ||
@@ -405,6 +391,7 @@ static void settings_to_globals() | |||
405 | LLFolderView::sAutoOpenTime = llmax(0.25f, gSavedSettings.getF32("FolderAutoOpenDelay")); | 391 | LLFolderView::sAutoOpenTime = llmax(0.25f, gSavedSettings.getF32("FolderAutoOpenDelay")); |
406 | LLToolBar::sInventoryAutoOpenTime = gSavedSettings.getF32("InventoryAutoOpenDelay"); | 392 | LLToolBar::sInventoryAutoOpenTime = gSavedSettings.getF32("InventoryAutoOpenDelay"); |
407 | LLSelectMgr::sRectSelectInclusive = gSavedSettings.getBOOL("RectangleSelectInclusive"); | 393 | LLSelectMgr::sRectSelectInclusive = gSavedSettings.getBOOL("RectangleSelectInclusive"); |
394 | LLSelectMgr::sRenderSelectionHighlights = gSavedSettings.getBOOL("RenderHighlightSelections"); | ||
408 | LLSelectMgr::sRenderHiddenSelections = gSavedSettings.getBOOL("RenderHiddenSelections"); | 395 | LLSelectMgr::sRenderHiddenSelections = gSavedSettings.getBOOL("RenderHiddenSelections"); |
409 | LLSelectMgr::sRenderLightRadius = gSavedSettings.getBOOL("RenderLightRadius"); | 396 | LLSelectMgr::sRenderLightRadius = gSavedSettings.getBOOL("RenderLightRadius"); |
410 | 397 | ||
@@ -418,8 +405,6 @@ static void settings_to_globals() | |||
418 | gAllowTapTapHoldRun = gSavedSettings.getBOOL("AllowTapTapHoldRun"); | 405 | gAllowTapTapHoldRun = gSavedSettings.getBOOL("AllowTapTapHoldRun"); |
419 | gShowObjectUpdates = gSavedSettings.getBOOL("ShowObjectUpdates"); | 406 | gShowObjectUpdates = gSavedSettings.getBOOL("ShowObjectUpdates"); |
420 | gMapScale = gSavedSettings.getF32("MapScale"); | 407 | gMapScale = gSavedSettings.getF32("MapScale"); |
421 | gMiniMapScale = gSavedSettings.getF32("MiniMapScale"); | ||
422 | gHandleKeysAsync = gSavedSettings.getBOOL("AsyncKeyboard"); | ||
423 | LLHoverView::sShowHoverTips = gSavedSettings.getBOOL("ShowHoverTips"); | 408 | LLHoverView::sShowHoverTips = gSavedSettings.getBOOL("ShowHoverTips"); |
424 | 409 | ||
425 | LLCubeMap::sUseCubeMaps = LLFeatureManager::getInstance()->isFeatureAvailable("RenderCubeMap"); | 410 | LLCubeMap::sUseCubeMaps = LLFeatureManager::getInstance()->isFeatureAvailable("RenderCubeMap"); |
@@ -498,30 +483,17 @@ void LLAppViewer::initGridChoice() | |||
498 | } | 483 | } |
499 | } | 484 | } |
500 | 485 | ||
501 | bool send_url_to_other_instance(const std::string& url) | 486 | //virtual |
487 | bool LLAppViewer::initSLURLHandler() | ||
502 | { | 488 | { |
503 | #if LL_WINDOWS | 489 | // does nothing unless subclassed |
504 | wchar_t window_class[256]; /* Flawfinder: ignore */ // Assume max length < 255 chars. | 490 | return false; |
505 | mbstowcs(window_class, sWindowClass, 255); | 491 | } |
506 | window_class[255] = 0; | 492 | |
507 | // Use the class instead of the window name. | 493 | //virtual |
508 | HWND other_window = FindWindow(window_class, NULL); | 494 | bool LLAppViewer::sendURLToOtherInstance(const std::string& url) |
509 | 495 | { | |
510 | if (other_window != NULL) | 496 | // does nothing unless subclassed |
511 | { | ||
512 | lldebugs << "Found other window with the name '" << gWindowTitle << "'" << llendl; | ||
513 | COPYDATASTRUCT cds; | ||
514 | const S32 SLURL_MESSAGE_TYPE = 0; | ||
515 | cds.dwData = SLURL_MESSAGE_TYPE; | ||
516 | cds.cbData = url.length() + 1; | ||
517 | cds.lpData = (void*)url.c_str(); | ||
518 | |||
519 | LRESULT msg_result = SendMessage(other_window, WM_COPYDATA, NULL, (LPARAM)&cds); | ||
520 | lldebugs << "SendMessage(WM_COPYDATA) to other window '" | ||
521 | << gWindowTitle << "' returned " << msg_result << llendl; | ||
522 | return true; | ||
523 | } | ||
524 | #endif | ||
525 | return false; | 497 | return false; |
526 | } | 498 | } |
527 | 499 | ||
@@ -690,6 +662,7 @@ bool LLAppViewer::init() | |||
690 | ui_audio_callback, | 662 | ui_audio_callback, |
691 | &LLUI::sGLScaleFactor); | 663 | &LLUI::sGLScaleFactor); |
692 | LLWeb::initClass(); // do this after LLUI | 664 | LLWeb::initClass(); // do this after LLUI |
665 | |||
693 | LLTextEditor::setURLCallbacks(&LLWeb::loadURL, | 666 | LLTextEditor::setURLCallbacks(&LLWeb::loadURL, |
694 | &LLURLDispatcher::dispatchFromTextEditor, | 667 | &LLURLDispatcher::dispatchFromTextEditor, |
695 | &LLURLDispatcher::dispatchFromTextEditor); | 668 | &LLURLDispatcher::dispatchFromTextEditor); |
@@ -710,7 +683,6 @@ bool LLAppViewer::init() | |||
710 | // load MIME type -> media impl mappings | 683 | // load MIME type -> media impl mappings |
711 | LLMIMETypes::parseMIMETypes( std::string("mime_types.xml") ); | 684 | LLMIMETypes::parseMIMETypes( std::string("mime_types.xml") ); |
712 | 685 | ||
713 | |||
714 | // Copy settings to globals. *TODO: Remove or move to appropriage class initializers | 686 | // Copy settings to globals. *TODO: Remove or move to appropriage class initializers |
715 | settings_to_globals(); | 687 | settings_to_globals(); |
716 | // Setup settings listeners | 688 | // Setup settings listeners |
@@ -721,6 +693,9 @@ bool LLAppViewer::init() | |||
721 | // Find partition serial number (Windows) or hardware serial (Mac) | 693 | // Find partition serial number (Windows) or hardware serial (Mac) |
722 | mSerialNumber = generateSerialNumber(); | 694 | mSerialNumber = generateSerialNumber(); |
723 | 695 | ||
696 | // do any necessary set-up for accepting incoming SLURLs from apps | ||
697 | initSLURLHandler(); | ||
698 | |||
724 | if(false == initHardwareTest()) | 699 | if(false == initHardwareTest()) |
725 | { | 700 | { |
726 | // Early out from user choice. | 701 | // Early out from user choice. |
@@ -851,7 +826,10 @@ bool LLAppViewer::init() | |||
851 | } | 826 | } |
852 | 827 | ||
853 | } | 828 | } |
854 | 829 | ||
830 | // save the graphics card | ||
831 | gDebugInfo["GraphicsCard"] = LLFeatureManager::getInstance()->getGPUString(); | ||
832 | |||
855 | // Save the current version to the prefs file | 833 | // Save the current version to the prefs file |
856 | gSavedSettings.setString("LastRunVersion", gCurrentVersion); | 834 | gSavedSettings.setString("LastRunVersion", gCurrentVersion); |
857 | 835 | ||
@@ -896,16 +874,21 @@ bool LLAppViewer::mainLoop() | |||
896 | { | 874 | { |
897 | LLFastTimer t(LLFastTimer::FTM_FRAME); | 875 | LLFastTimer t(LLFastTimer::FTM_FRAME); |
898 | 876 | ||
877 | pingMainloopTimeout("Main:MiscNativeWindowEvents"); | ||
878 | |||
879 | { | ||
880 | LLFastTimer t2(LLFastTimer::FTM_MESSAGES); | ||
881 | gViewerWindow->mWindow->processMiscNativeEvents(); | ||
882 | } | ||
883 | |||
899 | pingMainloopTimeout("Main:GatherInput"); | 884 | pingMainloopTimeout("Main:GatherInput"); |
900 | 885 | ||
901 | { | 886 | { |
902 | LLFastTimer t2(LLFastTimer::FTM_MESSAGES); | 887 | LLFastTimer t2(LLFastTimer::FTM_MESSAGES); |
903 | #if LL_WINDOWS | 888 | if (!restoreErrorTrap()) |
904 | if (!LLWinDebug::checkExceptionHandler()) | ||
905 | { | 889 | { |
906 | llwarns << " Someone took over my exception handler (post messagehandling)!" << llendl; | 890 | llwarns << " Someone took over my signal/exception handler (post messagehandling)!" << llendl; |
907 | } | 891 | } |
908 | #endif | ||
909 | 892 | ||
910 | gViewerWindow->mWindow->gatherInput(); | 893 | gViewerWindow->mWindow->gatherInput(); |
911 | } | 894 | } |
@@ -961,7 +944,7 @@ bool LLAppViewer::mainLoop() | |||
961 | 944 | ||
962 | resumeMainloopTimeout(); | 945 | resumeMainloopTimeout(); |
963 | } | 946 | } |
964 | 947 | ||
965 | if (gDoDisconnect && (LLStartUp::getStartupState() == STATE_STARTED)) | 948 | if (gDoDisconnect && (LLStartUp::getStartupState() == STATE_STARTED)) |
966 | { | 949 | { |
967 | pauseMainloopTimeout(); | 950 | pauseMainloopTimeout(); |
@@ -1183,17 +1166,24 @@ bool LLAppViewer::cleanup() | |||
1183 | 1166 | ||
1184 | llinfos << "Global stuff deleted" << llendflush; | 1167 | llinfos << "Global stuff deleted" << llendflush; |
1185 | 1168 | ||
1186 | #if (!defined(LL_FMOD)) || (!LL_RELEASE_FOR_DOWNLOAD) | ||
1187 | // OpenAL likes to crash on exit if we *don't* explicitly shut it down. | ||
1188 | if (gAudiop) | 1169 | if (gAudiop) |
1189 | { | 1170 | { |
1190 | gAudiop->shutdown(); | 1171 | bool want_longname = false; |
1172 | if (gAudiop->getDriverName(want_longname) == "FMOD") | ||
1173 | { | ||
1174 | // This hack exists because fmod likes to occasionally | ||
1175 | // hang forever when shutting down, for no apparent | ||
1176 | // reason. | ||
1177 | llwarns << "Hack, skipping FMOD audio engine cleanup" << llendflush; | ||
1178 | } | ||
1179 | else | ||
1180 | { | ||
1181 | gAudiop->shutdown(); | ||
1182 | } | ||
1183 | |||
1184 | delete gAudiop; | ||
1185 | gAudiop = NULL; | ||
1191 | } | 1186 | } |
1192 | #else | ||
1193 | // This hack exists because fmod likes to occasionally hang forever | ||
1194 | // when shutting down for no apparent reason. | ||
1195 | llwarns << "Hack, skipping audio engine cleanup" << llendflush; | ||
1196 | #endif | ||
1197 | 1187 | ||
1198 | // Note: this is where LLFeatureManager::getInstance()-> used to be deleted. | 1188 | // Note: this is where LLFeatureManager::getInstance()-> used to be deleted. |
1199 | 1189 | ||
@@ -1204,9 +1194,6 @@ bool LLAppViewer::cleanup() | |||
1204 | cleanupSavedSettings(); | 1194 | cleanupSavedSettings(); |
1205 | llinfos << "Settings patched up" << llendflush; | 1195 | llinfos << "Settings patched up" << llendflush; |
1206 | 1196 | ||
1207 | delete gAudiop; | ||
1208 | gAudiop = NULL; | ||
1209 | |||
1210 | // delete some of the files left around in the cache. | 1197 | // delete some of the files left around in the cache. |
1211 | removeCacheFiles("*.wav"); | 1198 | removeCacheFiles("*.wav"); |
1212 | removeCacheFiles("*.tmp"); | 1199 | removeCacheFiles("*.tmp"); |
@@ -1375,12 +1362,15 @@ bool LLAppViewer::cleanup() | |||
1375 | delete sImageDecodeThread; | 1362 | delete sImageDecodeThread; |
1376 | sImageDecodeThread = NULL; | 1363 | sImageDecodeThread = NULL; |
1377 | 1364 | ||
1365 | //Note: | ||
1366 | //LLViewerMedia::cleanupClass() has to be put before gImageList.shutdown() | ||
1367 | //because some new image might be generated during cleaning up media. --bao | ||
1368 | LLViewerMedia::cleanupClass(); | ||
1378 | gImageList.shutdown(); // shutdown again in case a callback added something | 1369 | gImageList.shutdown(); // shutdown again in case a callback added something |
1379 | LLUIImageList::getInstance()->cleanUp(); | 1370 | LLUIImageList::getInstance()->cleanUp(); |
1380 | 1371 | ||
1381 | // This should eventually be done in LLAppViewer | 1372 | // This should eventually be done in LLAppViewer |
1382 | LLImageJ2C::closeDSO(); | 1373 | LLImage::cleanupClass(); |
1383 | LLImageFormatted::cleanupClass(); | ||
1384 | LLVFSThread::cleanupClass(); | 1374 | LLVFSThread::cleanupClass(); |
1385 | LLLFSThread::cleanupClass(); | 1375 | LLLFSThread::cleanupClass(); |
1386 | 1376 | ||
@@ -1401,14 +1391,17 @@ bool LLAppViewer::cleanup() | |||
1401 | LLWatchdog::getInstance()->cleanup(); | 1391 | LLWatchdog::getInstance()->cleanup(); |
1402 | 1392 | ||
1403 | end_messaging_system(); | 1393 | end_messaging_system(); |
1394 | llinfos << "Message system deleted." << llendflush; | ||
1404 | 1395 | ||
1405 | // *NOTE:Mani - The following call is not thread safe. | 1396 | // *NOTE:Mani - The following call is not thread safe. |
1406 | LLCurl::cleanupClass(); | 1397 | LLCurl::cleanupClass(); |
1398 | llinfos << "LLCurl cleaned up." << llendflush; | ||
1407 | 1399 | ||
1408 | // If we're exiting to launch an URL, do that here so the screen | 1400 | // If we're exiting to launch an URL, do that here so the screen |
1409 | // is at the right resolution before we launch IE. | 1401 | // is at the right resolution before we launch IE. |
1410 | if (!gLaunchFileOnQuit.empty()) | 1402 | if (!gLaunchFileOnQuit.empty()) |
1411 | { | 1403 | { |
1404 | llinfos << "Launch file on quit." << llendflush; | ||
1412 | #if LL_WINDOWS | 1405 | #if LL_WINDOWS |
1413 | // Indicate an application is starting. | 1406 | // Indicate an application is starting. |
1414 | SetCursor(LoadCursor(NULL, IDC_WAIT)); | 1407 | SetCursor(LoadCursor(NULL, IDC_WAIT)); |
@@ -1418,9 +1411,8 @@ bool LLAppViewer::cleanup() | |||
1418 | ms_sleep(1000); | 1411 | ms_sleep(1000); |
1419 | 1412 | ||
1420 | LLWeb::loadURLExternal( gLaunchFileOnQuit ); | 1413 | LLWeb::loadURLExternal( gLaunchFileOnQuit ); |
1414 | llinfos << "File launched." << llendflush; | ||
1421 | } | 1415 | } |
1422 | |||
1423 | LLViewerMedia::cleanupClass(); | ||
1424 | 1416 | ||
1425 | llinfos << "Goodbye" << llendflush; | 1417 | llinfos << "Goodbye" << llendflush; |
1426 | 1418 | ||
@@ -1428,6 +1420,25 @@ bool LLAppViewer::cleanup() | |||
1428 | return true; | 1420 | return true; |
1429 | } | 1421 | } |
1430 | 1422 | ||
1423 | // A callback for llerrs to call during the watchdog error. | ||
1424 | void watchdog_llerrs_callback(const std::string &error_string) | ||
1425 | { | ||
1426 | gLLErrorActivated = true; | ||
1427 | |||
1428 | #ifdef LL_WINDOWS | ||
1429 | RaiseException(0,0,0,0); | ||
1430 | #else | ||
1431 | raise(SIGQUIT); | ||
1432 | #endif | ||
1433 | } | ||
1434 | |||
1435 | // A callback for the watchdog to call. | ||
1436 | void watchdog_killer_callback() | ||
1437 | { | ||
1438 | LLError::setFatalFunction(watchdog_llerrs_callback); | ||
1439 | llerrs << "Watchdog killer event" << llendl; | ||
1440 | } | ||
1441 | |||
1431 | bool LLAppViewer::initThreads() | 1442 | bool LLAppViewer::initThreads() |
1432 | { | 1443 | { |
1433 | #if MEM_TRACK_MEM | 1444 | #if MEM_TRACK_MEM |
@@ -1437,10 +1448,11 @@ bool LLAppViewer::initThreads() | |||
1437 | #endif | 1448 | #endif |
1438 | 1449 | ||
1439 | const S32 NEVER_SUBMIT_REPORT = 2; | 1450 | const S32 NEVER_SUBMIT_REPORT = 2; |
1440 | if(TRUE == gSavedSettings.getBOOL("WatchdogEnabled") | 1451 | bool use_watchdog = gSavedSettings.getBOOL("WatchdogEnabled"); |
1441 | && (gCrashSettings.getS32(CRASH_BEHAVIOR_SETTING) != NEVER_SUBMIT_REPORT)) | 1452 | bool send_reports = gCrashSettings.getS32(CRASH_BEHAVIOR_SETTING) != NEVER_SUBMIT_REPORT; |
1453 | if(use_watchdog && send_reports) | ||
1442 | { | 1454 | { |
1443 | LLWatchdog::getInstance()->init(); | 1455 | LLWatchdog::getInstance()->init(watchdog_killer_callback); |
1444 | } | 1456 | } |
1445 | 1457 | ||
1446 | LLVFSThread::initClass(enable_threads && true); | 1458 | LLVFSThread::initClass(enable_threads && true); |
@@ -1450,8 +1462,7 @@ bool LLAppViewer::initThreads() | |||
1450 | LLAppViewer::sImageDecodeThread = new LLWorkerThread("ImageDecode", enable_threads && true); | 1462 | LLAppViewer::sImageDecodeThread = new LLWorkerThread("ImageDecode", enable_threads && true); |
1451 | LLAppViewer::sTextureCache = new LLTextureCache(enable_threads && true); | 1463 | LLAppViewer::sTextureCache = new LLTextureCache(enable_threads && true); |
1452 | LLAppViewer::sTextureFetch = new LLTextureFetch(LLAppViewer::getTextureCache(), enable_threads && false); | 1464 | LLAppViewer::sTextureFetch = new LLTextureFetch(LLAppViewer::getTextureCache(), enable_threads && false); |
1453 | LLImageWorker::initClass(LLAppViewer::getImageDecodeThread()); | 1465 | LLImage::initClass(LLAppViewer::getImageDecodeThread()); |
1454 | LLImageJ2C::openDSO(); | ||
1455 | 1466 | ||
1456 | // *FIX: no error handling here! | 1467 | // *FIX: no error handling here! |
1457 | return true; | 1468 | return true; |
@@ -1883,22 +1894,6 @@ bool LLAppViewer::initConfiguration() | |||
1883 | // llerrs << "Failed to parse skin definition." << llendl; | 1894 | // llerrs << "Failed to parse skin definition." << llendl; |
1884 | // } | 1895 | // } |
1885 | 1896 | ||
1886 | // LLXmlTreeNode* rootp = skin_def_tree.getRoot(); | ||
1887 | // LLXmlTreeNode* disabled_message_node = rootp->getChildByName("disabled_message"); | ||
1888 | // if (disabled_message_node) | ||
1889 | // { | ||
1890 | // gDisabledMessage = disabled_message_node->getContents(); | ||
1891 | // } | ||
1892 | |||
1893 | // static LLStdStringHandle hide_links_string = LLXmlTree::addAttributeString("hide_links"); | ||
1894 | // rootp->getFastAttributeBOOL(hide_links_string, gHideLinks); | ||
1895 | |||
1896 | // // Legacy string. This flag really meant we didn't want to expose references to "Second Life". | ||
1897 | // // Just set gHideLinks instead. | ||
1898 | // static LLStdStringHandle silent_string = LLXmlTree::addAttributeString("silent_update"); | ||
1899 | // BOOL silent_update; | ||
1900 | // rootp->getFastAttributeBOOL(silent_string, silent_update); | ||
1901 | // gHideLinks = (gHideLinks || silent_update); | ||
1902 | //} | 1897 | //} |
1903 | 1898 | ||
1904 | #if LL_DARWIN | 1899 | #if LL_DARWIN |
@@ -1951,7 +1946,7 @@ bool LLAppViewer::initConfiguration() | |||
1951 | #endif | 1946 | #endif |
1952 | LLStringUtil::truncate(gWindowTitle, 255); | 1947 | LLStringUtil::truncate(gWindowTitle, 255); |
1953 | 1948 | ||
1954 | //RN: if we received a URL, hand it off to the existing instance | 1949 | //RN: if we received a URL, hand it off to the existing instance. |
1955 | // don't call anotherInstanceRunning() when doing URL handoff, as | 1950 | // don't call anotherInstanceRunning() when doing URL handoff, as |
1956 | // it relies on checking a marker file which will not work when running | 1951 | // it relies on checking a marker file which will not work when running |
1957 | // out of different directories | 1952 | // out of different directories |
@@ -1966,7 +1961,7 @@ bool LLAppViewer::initConfiguration() | |||
1966 | } | 1961 | } |
1967 | if (!slurl.empty()) | 1962 | if (!slurl.empty()) |
1968 | { | 1963 | { |
1969 | if (send_url_to_other_instance(slurl)) | 1964 | if (sendURLToOtherInstance(slurl)) |
1970 | { | 1965 | { |
1971 | // successfully handed off URL to existing instance, exit | 1966 | // successfully handed off URL to existing instance, exit |
1972 | return false; | 1967 | return false; |
@@ -1997,7 +1992,7 @@ bool LLAppViewer::initConfiguration() | |||
1997 | } | 1992 | } |
1998 | 1993 | ||
1999 | initMarkerFile(); | 1994 | initMarkerFile(); |
2000 | 1995 | ||
2001 | #if LL_SEND_CRASH_REPORTS | 1996 | #if LL_SEND_CRASH_REPORTS |
2002 | if (gLastExecEvent == LAST_EXEC_FROZE) | 1997 | if (gLastExecEvent == LAST_EXEC_FROZE) |
2003 | { | 1998 | { |
@@ -2019,52 +2014,8 @@ bool LLAppViewer::initConfiguration() | |||
2019 | { | 2014 | { |
2020 | llinfos << "Sending crash report." << llendl; | 2015 | llinfos << "Sending crash report." << llendl; |
2021 | 2016 | ||
2022 | #if LL_WINDOWS | 2017 | bool report_freeze = true; |
2023 | std::string exe_path = gDirUtilp->getAppRODataDir(); | 2018 | handleCrashReporting(report_freeze); |
2024 | exe_path += gDirUtilp->getDirDelimiter(); | ||
2025 | exe_path += "win_crash_logger.exe"; | ||
2026 | |||
2027 | std::string arg_string = "-previous "; | ||
2028 | // Spawn crash logger. | ||
2029 | // NEEDS to wait until completion, otherwise log files will get smashed. | ||
2030 | _spawnl(_P_WAIT, exe_path.c_str(), exe_path.c_str(), arg_string.c_str(), NULL); | ||
2031 | #elif LL_DARWIN | ||
2032 | std::string command_str; | ||
2033 | command_str = "mac-crash-logger.app/Contents/MacOS/mac-crash-logger "; | ||
2034 | command_str += "-previous"; | ||
2035 | // XXX -- We need to exit fullscreen mode for this to work. | ||
2036 | // XXX -- system() also doesn't wait for completion. Hmm... | ||
2037 | system(command_str.c_str()); /* Flawfinder: Ignore */ | ||
2038 | #elif LL_LINUX || LL_SOLARIS | ||
2039 | std::string cmd =gDirUtilp->getAppRODataDir(); | ||
2040 | cmd += gDirUtilp->getDirDelimiter(); | ||
2041 | #if LL_LINUX | ||
2042 | cmd += "linux-crash-logger.bin"; | ||
2043 | #else // LL_SOLARIS | ||
2044 | cmd += "bin/solaris-crash-logger"; | ||
2045 | #endif // LL_LINUX | ||
2046 | char* const cmdargv[] = | ||
2047 | {(char*)cmd.c_str(), | ||
2048 | (char*)"-previous", | ||
2049 | NULL}; | ||
2050 | fflush(NULL); // flush all buffers before the child inherits them | ||
2051 | pid_t pid = fork(); | ||
2052 | if (pid == 0) | ||
2053 | { // child | ||
2054 | execv(cmd.c_str(), cmdargv); /* Flawfinder: Ignore */ | ||
2055 | llwarns << "execv failure when trying to start " << cmd << llendl; | ||
2056 | _exit(1); // avoid atexit() | ||
2057 | } else { | ||
2058 | if (pid > 0) | ||
2059 | { | ||
2060 | // wait for child proc to die | ||
2061 | int childExitStatus; | ||
2062 | waitpid(pid, &childExitStatus, 0); | ||
2063 | } else { | ||
2064 | llwarns << "fork failure." << llendl; | ||
2065 | } | ||
2066 | } | ||
2067 | #endif | ||
2068 | } | 2019 | } |
2069 | else | 2020 | else |
2070 | { | 2021 | { |
@@ -2228,8 +2179,6 @@ void LLAppViewer::cleanupSavedSettings() | |||
2228 | } | 2179 | } |
2229 | 2180 | ||
2230 | gSavedSettings.setF32("MapScale", gMapScale ); | 2181 | gSavedSettings.setF32("MapScale", gMapScale ); |
2231 | gSavedSettings.setF32("MiniMapScale", gMiniMapScale ); | ||
2232 | gSavedSettings.setBOOL("AsyncKeyboard", gHandleKeysAsync); | ||
2233 | gSavedSettings.setBOOL("ShowHoverTips", LLHoverView::sShowHoverTips); | 2182 | gSavedSettings.setBOOL("ShowHoverTips", LLHoverView::sShowHoverTips); |
2234 | 2183 | ||
2235 | // Some things are cached in LLAgent. | 2184 | // Some things are cached in LLAgent. |
@@ -2271,7 +2220,7 @@ void LLAppViewer::writeSystemInfo() | |||
2271 | gDebugInfo["RAMInfo"]["Physical"] = (LLSD::Integer)(gSysMemory.getPhysicalMemoryKB()); | 2220 | gDebugInfo["RAMInfo"]["Physical"] = (LLSD::Integer)(gSysMemory.getPhysicalMemoryKB()); |
2272 | gDebugInfo["RAMInfo"]["Allocated"] = (LLSD::Integer)(gMemoryAllocated>>10); // MB -> KB | 2221 | gDebugInfo["RAMInfo"]["Allocated"] = (LLSD::Integer)(gMemoryAllocated>>10); // MB -> KB |
2273 | gDebugInfo["OSInfo"] = getOSInfo().getOSStringSimple(); | 2222 | gDebugInfo["OSInfo"] = getOSInfo().getOSStringSimple(); |
2274 | 2223 | ||
2275 | // The user is not logged on yet, but record the current grid choice login url | 2224 | // The user is not logged on yet, but record the current grid choice login url |
2276 | // which may have been the intended grid. This can b | 2225 | // which may have been the intended grid. This can b |
2277 | gDebugInfo["GridName"] = LLViewerLogin::getInstance()->getGridLabel(); | 2226 | gDebugInfo["GridName"] = LLViewerLogin::getInstance()->getGridLabel(); |
@@ -2282,6 +2231,13 @@ void LLAppViewer::writeSystemInfo() | |||
2282 | gDebugInfo["MainloopThreadID"] = (S32)thread_id; | 2231 | gDebugInfo["MainloopThreadID"] = (S32)thread_id; |
2283 | #endif | 2232 | #endif |
2284 | 2233 | ||
2234 | // "CrashNotHandled" is set here, while things are running well, | ||
2235 | // in case of a freeze. If there is a freeze, the crash logger will be launched | ||
2236 | // and can read this value from the debug_info.log. | ||
2237 | // If the crash is handled by LLAppViewer::handleViewerCrash, ie not a freeze, | ||
2238 | // then the value of "CrashNotHandled" will be set to true. | ||
2239 | gDebugInfo["CrashNotHandled"] = (LLSD::Boolean)true; | ||
2240 | |||
2285 | // Dump some debugging info | 2241 | // Dump some debugging info |
2286 | LL_INFOS("SystemInfo") << gCurrentVersion << LL_ENDL; | 2242 | LL_INFOS("SystemInfo") << gCurrentVersion << LL_ENDL; |
2287 | 2243 | ||
@@ -2358,6 +2314,10 @@ void LLAppViewer::handleViewerCrash() | |||
2358 | gDebugInfo["CAFilename"] = gDirUtilp->getCAFile(); | 2314 | gDebugInfo["CAFilename"] = gDirUtilp->getCAFile(); |
2359 | gDebugInfo["ViewerExePath"] = gDirUtilp->getExecutablePathAndName(); | 2315 | gDebugInfo["ViewerExePath"] = gDirUtilp->getExecutablePathAndName(); |
2360 | gDebugInfo["CurrentPath"] = gDirUtilp->getCurPath(); | 2316 | gDebugInfo["CurrentPath"] = gDirUtilp->getCurPath(); |
2317 | gDebugInfo["SessionLength"] = F32(LLFrameTimer::getElapsedSeconds()); | ||
2318 | gDebugInfo["StartupState"] = LLStartUp::getStartupStateString(); | ||
2319 | gDebugInfo["RAMInfo"]["Allocated"] = (LLSD::Integer) getCurrentRSS() >> 10; | ||
2320 | |||
2361 | if(gLogoutInProgress) | 2321 | if(gLogoutInProgress) |
2362 | { | 2322 | { |
2363 | gDebugInfo["LastExecEvent"] = LAST_EXEC_LOGOUT_CRASH; | 2323 | gDebugInfo["LastExecEvent"] = LAST_EXEC_LOGOUT_CRASH; |
@@ -2383,6 +2343,9 @@ void LLAppViewer::handleViewerCrash() | |||
2383 | gDebugInfo["MainloopTimeoutState"] = LLAppViewer::instance()->mMainloopTimeout->getState(); | 2343 | gDebugInfo["MainloopTimeoutState"] = LLAppViewer::instance()->mMainloopTimeout->getState(); |
2384 | } | 2344 | } |
2385 | 2345 | ||
2346 | // The crash is being handled here so set this value to false. | ||
2347 | // Otherwise the crash logger will think this crash was a freeze. | ||
2348 | gDebugInfo["CrashNotHandled"] = (LLSD::Boolean)false; | ||
2386 | 2349 | ||
2387 | //Write out the crash status file | 2350 | //Write out the crash status file |
2388 | //Use marker file style setup, as that's the simplest, especially since | 2351 | //Use marker file style setup, as that's the simplest, especially since |
@@ -2466,24 +2429,23 @@ bool LLAppViewer::anotherInstanceRunning() | |||
2466 | { | 2429 | { |
2467 | // Another instance is running. Skip the rest of these operations. | 2430 | // Another instance is running. Skip the rest of these operations. |
2468 | LL_INFOS("MarkerFile") << "Marker file is locked." << LL_ENDL; | 2431 | LL_INFOS("MarkerFile") << "Marker file is locked." << LL_ENDL; |
2469 | return TRUE; | 2432 | return true; |
2470 | } | 2433 | } |
2471 | if (apr_file_lock(fMarker, APR_FLOCK_NONBLOCK | APR_FLOCK_EXCLUSIVE) != APR_SUCCESS) //flock(fileno(fMarker), LOCK_EX | LOCK_NB) == -1) | 2434 | if (apr_file_lock(fMarker, APR_FLOCK_NONBLOCK | APR_FLOCK_EXCLUSIVE) != APR_SUCCESS) //flock(fileno(fMarker), LOCK_EX | LOCK_NB) == -1) |
2472 | { | 2435 | { |
2473 | apr_file_close(fMarker); | 2436 | apr_file_close(fMarker); |
2474 | LL_INFOS("MarkerFile") << "Marker file is locked." << LL_ENDL; | 2437 | LL_INFOS("MarkerFile") << "Marker file is locked." << LL_ENDL; |
2475 | return TRUE; | 2438 | return true; |
2476 | } | 2439 | } |
2477 | // No other instances; we'll lock this file now & delete on quit. | 2440 | // No other instances; we'll lock this file now & delete on quit. |
2478 | apr_file_close(fMarker); | 2441 | apr_file_close(fMarker); |
2479 | } | 2442 | } |
2480 | LL_DEBUGS("MarkerFile") << "Marker file isn't locked." << LL_ENDL; | 2443 | LL_DEBUGS("MarkerFile") << "Marker file isn't locked." << LL_ENDL; |
2481 | return FALSE; | 2444 | return false; |
2482 | } | 2445 | } |
2483 | 2446 | ||
2484 | void LLAppViewer::initMarkerFile() | 2447 | void LLAppViewer::initMarkerFile() |
2485 | { | 2448 | { |
2486 | |||
2487 | //First, check for the existence of other files. | 2449 | //First, check for the existence of other files. |
2488 | //There are marker files for two different types of crashes | 2450 | //There are marker files for two different types of crashes |
2489 | 2451 | ||
@@ -2738,7 +2700,7 @@ bool LLAppViewer::initCache() | |||
2738 | 2700 | ||
2739 | // Init the texture cache | 2701 | // Init the texture cache |
2740 | // Allocate 80% of the cache size for textures | 2702 | // Allocate 80% of the cache size for textures |
2741 | BOOL read_only = mSecondInstance ? true : false; | 2703 | BOOL read_only = mSecondInstance ? TRUE : FALSE; |
2742 | const S32 MB = 1024*1024; | 2704 | const S32 MB = 1024*1024; |
2743 | S64 cache_size = (S64)(gSavedSettings.getU32("CacheSize")) * MB; | 2705 | S64 cache_size = (S64)(gSavedSettings.getU32("CacheSize")) * MB; |
2744 | const S64 MAX_CACHE_SIZE = 1024*MB; | 2706 | const S64 MAX_CACHE_SIZE = 1024*MB; |
@@ -3539,12 +3501,12 @@ void LLAppViewer::sendLogoutRequest() | |||
3539 | if (mLogoutMarkerFile) | 3501 | if (mLogoutMarkerFile) |
3540 | { | 3502 | { |
3541 | llinfos << "Created logout marker file " << mLogoutMarkerFileName << llendl; | 3503 | llinfos << "Created logout marker file " << mLogoutMarkerFileName << llendl; |
3504 | apr_file_close(mLogoutMarkerFile); | ||
3542 | } | 3505 | } |
3543 | else | 3506 | else |
3544 | { | 3507 | { |
3545 | llwarns << "Cannot create logout marker file " << mLogoutMarkerFileName << llendl; | 3508 | llwarns << "Cannot create logout marker file " << mLogoutMarkerFileName << llendl; |
3546 | } | 3509 | } |
3547 | apr_file_close(mLogoutMarkerFile); | ||
3548 | } | 3510 | } |
3549 | } | 3511 | } |
3550 | 3512 | ||
@@ -3765,6 +3727,11 @@ void LLAppViewer::forceErrorSoftwareException() | |||
3765 | throw; | 3727 | throw; |
3766 | } | 3728 | } |
3767 | 3729 | ||
3730 | void LLAppViewer::forceErrorDriverCrash() | ||
3731 | { | ||
3732 | glDeleteTextures(1, NULL); | ||
3733 | } | ||
3734 | |||
3768 | void LLAppViewer::initMainloopTimeout(const std::string& state, F32 secs) | 3735 | void LLAppViewer::initMainloopTimeout(const std::string& state, F32 secs) |
3769 | { | 3736 | { |
3770 | if(!mMainloopTimeout) | 3737 | if(!mMainloopTimeout) |
@@ -3807,6 +3774,11 @@ void LLAppViewer::pauseMainloopTimeout() | |||
3807 | 3774 | ||
3808 | void LLAppViewer::pingMainloopTimeout(const std::string& state, F32 secs) | 3775 | void LLAppViewer::pingMainloopTimeout(const std::string& state, F32 secs) |
3809 | { | 3776 | { |
3777 | // if(!restoreErrorTrap()) | ||
3778 | // { | ||
3779 | // llwarns << "!!!!!!!!!!!!! Its an error trap!!!!" << state << llendl; | ||
3780 | // } | ||
3781 | |||
3810 | if(mMainloopTimeout) | 3782 | if(mMainloopTimeout) |
3811 | { | 3783 | { |
3812 | if(secs < 0.0f) | 3784 | if(secs < 0.0f) |
@@ -3819,3 +3791,42 @@ void LLAppViewer::pingMainloopTimeout(const std::string& state, F32 secs) | |||
3819 | } | 3791 | } |
3820 | } | 3792 | } |
3821 | 3793 | ||
3794 | void LLAppViewer::handleLoginComplete() | ||
3795 | { | ||
3796 | initMainloopTimeout("Mainloop Init"); | ||
3797 | |||
3798 | // Store some data to DebugInfo in case of a freeze. | ||
3799 | gDebugInfo["ClientInfo"]["Name"] = gSavedSettings.getString("VersionChannelName"); | ||
3800 | |||
3801 | gDebugInfo["ClientInfo"]["MajorVersion"] = LL_VERSION_MAJOR; | ||
3802 | gDebugInfo["ClientInfo"]["MinorVersion"] = LL_VERSION_MINOR; | ||
3803 | gDebugInfo["ClientInfo"]["PatchVersion"] = LL_VERSION_PATCH; | ||
3804 | gDebugInfo["ClientInfo"]["BuildVersion"] = LL_VERSION_BUILD; | ||
3805 | |||
3806 | LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); | ||
3807 | if ( parcel && parcel->getMusicURL()[0]) | ||
3808 | { | ||
3809 | gDebugInfo["ParcelMusicURL"] = parcel->getMusicURL(); | ||
3810 | } | ||
3811 | if ( parcel && parcel->getMediaURL()[0]) | ||
3812 | { | ||
3813 | gDebugInfo["ParcelMediaURL"] = parcel->getMediaURL(); | ||
3814 | } | ||
3815 | |||
3816 | gDebugInfo["SettingsFilename"] = gSavedSettings.getString("ClientSettingsFile"); | ||
3817 | gDebugInfo["CAFilename"] = gDirUtilp->getCAFile(); | ||
3818 | gDebugInfo["ViewerExePath"] = gDirUtilp->getExecutablePathAndName(); | ||
3819 | gDebugInfo["CurrentPath"] = gDirUtilp->getCurPath(); | ||
3820 | |||
3821 | if(gAgent.getRegion()) | ||
3822 | { | ||
3823 | gDebugInfo["CurrentSimHost"] = gAgent.getRegionHost().getHostName(); | ||
3824 | gDebugInfo["CurrentRegion"] = gAgent.getRegion()->getName(); | ||
3825 | } | ||
3826 | |||
3827 | if(LLAppViewer::instance()->mMainloopTimeout) | ||
3828 | { | ||
3829 | gDebugInfo["MainloopTimeoutState"] = LLAppViewer::instance()->mMainloopTimeout->getState(); | ||
3830 | } | ||
3831 | writeDebugInfo(); | ||
3832 | } | ||