summaryrefslogtreecommitdiff
path: root/indra/newview/llappviewer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llappviewer.cpp')
-rw-r--r--indra/newview/llappviewer.cpp1512
1 files changed, 985 insertions, 527 deletions
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index ce66bb6180..92a9b83bc5 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -2,31 +2,25 @@
* @file llappviewer.cpp
* @brief The LLAppViewer class definitions
*
- * $LicenseInfo:firstyear=2007&license=viewergpl$
- *
- * Copyright (c) 2007-2009, Linden Research, Inc.
- *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * Copyright (C) 2010, Linden Research, Inc.
*
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
*
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -34,23 +28,23 @@
#include "llappviewer.h"
-#include "llprimitive.h"
-
-#include "llversionviewer.h"
+// Viewer includes
+#include "llversioninfo.h"
#include "llfeaturemanager.h"
#include "lluictrlfactory.h"
#include "lltexteditor.h"
-#include "llalertdialog.h"
#include "llerrorcontrol.h"
-#include "llviewerimagelist.h"
+#include "lleventtimer.h"
+#include "llviewertexturelist.h"
#include "llgroupmgr.h"
#include "llagent.h"
+#include "llagentcamera.h"
+#include "llagentlanguage.h"
#include "llagentwearables.h"
#include "llwindow.h"
#include "llviewerstats.h"
#include "llmd5.h"
#include "llpumpio.h"
-#include "llimpanel.h"
#include "llmimetypes.h"
#include "llslurl.h"
#include "llstartup.h"
@@ -59,32 +53,53 @@
#include "llallocator.h"
#include "llares.h"
#include "llcurl.h"
+#include "lltexturestats.h"
+#include "lltexturestats.h"
#include "llviewerwindow.h"
#include "llviewerdisplay.h"
#include "llviewermedia.h"
+#include "llviewerparcelmedia.h"
+#include "llviewermediafocus.h"
#include "llviewermessage.h"
#include "llviewerobjectlist.h"
#include "llworldmap.h"
#include "llmutelist.h"
+#include "llviewerhelp.h"
#include "lluicolortable.h"
#include "llurldispatcher.h"
#include "llurlhistory.h"
-#include "llfirstuse.h"
+//#include "llfirstuse.h"
#include "llrender.h"
+#include "llteleporthistory.h"
#include "lllocationhistory.h"
#include "llfasttimerview.h"
+#include "llvoicechannel.h"
+#include "llvoavatarself.h"
+#include "llsidetray.h"
+#include "llfeaturemanager.h"
+#include "llurlmatch.h"
+#include "lltextutil.h"
+
#include "llweb.h"
#include "llsecondlifeurls.h"
// Linden library includes
+#include "llimagej2c.h"
#include "llmemory.h"
+#include "llprimitive.h"
+#include "llurlaction.h"
+#include "llvfile.h"
+#include "llvfsthread.h"
+#include "llvolumemgr.h"
+#include "llxfermanager.h"
+
+#include "llnotificationmanager.h"
+#include "llnotifications.h"
+#include "llnotificationsutil.h"
// Third party library includes
#include <boost/bind.hpp>
-#if LL_WINDOWS
- #include "llwindebug.h"
-#endif
#if LL_WINDOWS
# include <share.h> // For _SH_DENYWR in initMarkerFile
@@ -92,7 +107,10 @@
# include <sys/file.h> // For initMarkerFile support
#endif
-#include "llnotify.h"
+#include "llapr.h"
+#include "apr_dso.h"
+#include <boost/lexical_cast.hpp>
+
#include "llviewerkeyboard.h"
#include "lllfsthread.h"
#include "llworkerthread.h"
@@ -109,10 +127,12 @@
#include "llassetstorage.h"
#include "llpolymesh.h"
#include "llcachename.h"
-#include "audioengine.h"
+#include "llaudioengine.h"
+#include "llstreamingaudio.h"
#include "llviewermenu.h"
#include "llselectmgr.h"
#include "lltrans.h"
+#include "lltransutil.h"
#include "lltracker.h"
#include "llviewerparcelmgr.h"
#include "llworldmapview.h"
@@ -123,14 +143,14 @@
#include "lldebugview.h"
#include "llconsole.h"
#include "llcontainerview.h"
-#include "llhoverview.h"
+#include "lltooltip.h"
#include "llsdserialize.h"
#include "llworld.h"
#include "llhudeffecttrail.h"
#include "llvectorperfoptions.h"
-#include "llurlsimstring.h"
+#include "llslurl.h"
#include "llwatchdog.h"
// Included so that constants/settings might be initialized
@@ -143,17 +163,16 @@
#include "llvotree.h"
#include "llvoavatar.h"
#include "llfolderview.h"
-#include "lltoolbar.h"
#include "llagentpilot.h"
-#include "llsrv.h"
#include "llvovolume.h"
#include "llflexibleobject.h"
#include "llvosurfacepatch.h"
#include "llviewerfloaterreg.h"
#include "llcommandlineparser.h"
#include "llfloatermemleak.h"
+#include "llfloaterreg.h"
#include "llfloatersnapshot.h"
-#include "llinventoryview.h"
+#include "llfloaterinventory.h"
// includes for idle() idleShutdown()
#include "llviewercontrol.h"
@@ -169,6 +188,12 @@
#include "llimview.h"
#include "llviewerthrottle.h"
#include "llparcel.h"
+#include "llavatariconctrl.h"
+#include "llgroupiconctrl.h"
+
+// Include for security api initialization
+#include "llsecapi.h"
+#include "llmachineid.h"
// *FIX: These extern globals should be cleaned up.
// The globals either represent state/config/resource-storage of either
@@ -181,7 +206,19 @@
//----------------------------------------------------------------------------
// llviewernetwork.h
#include "llviewernetwork.h"
+// define a self-registering event API object
+#include "llappviewerlistener.h"
+#if (LL_LINUX || LL_SOLARIS) && LL_GTK
+#include "glib.h"
+#endif // (LL_LINUX || LL_SOLARIS) && LL_GTK
+
+#if LL_MSVC
+// disable boost::lexical_cast warning
+#pragma warning (disable:4702)
+#endif
+
+static LLAppViewerListener sAppViewerListener(LLAppViewer::instance);
////// Windows-specific includes to the bottom - nasty defines in these pollute the preprocessor
//
@@ -203,13 +240,9 @@ const F32 DEFAULT_AFK_TIMEOUT = 5.f * 60.f; // time with no input before user fl
F32 gSimLastTime; // Used in LLAppViewer::init and send_stats()
F32 gSimFrames;
-BOOL gAllowTapTapHoldRun = TRUE;
BOOL gShowObjectUpdates = FALSE;
BOOL gUseQuickTime = TRUE;
-BOOL gAcceptTOS = FALSE;
-BOOL gAcceptCriticalMessage = FALSE;
-
eLastExecEvent gLastExecEvent = LAST_EXEC_NORMAL;
LLSD gDebugInfo;
@@ -218,8 +251,6 @@ U32 gFrameCount = 0;
U32 gForegroundFrameCount = 0; // number of frames that app window was in foreground
LLPumpIO* gServicePump = NULL;
-BOOL gPacificDaylightTime = FALSE;
-
U64 gFrameTime = 0;
F32 gFrameTimeSeconds = 0.f;
F32 gFrameIntervalSeconds = 0.f;
@@ -235,14 +266,8 @@ LLTimer gLogoutTimer;
static const F32 LOGOUT_REQUEST_TIME = 6.f; // this will be cut short by the LogoutReply msg.
F32 gLogoutMaxTime = LOGOUT_REQUEST_TIME;
-LLUUID gInventoryLibraryOwner;
-LLUUID gInventoryLibraryRoot;
-
BOOL gDisconnected = FALSE;
-// Map scale in pixels per region
-F32 gMapScale = 128.f;
-
// used to restore texture state after a mode switch
LLFrameTimer gRestoreGLTimer;
BOOL gRestoreGL = FALSE;
@@ -291,9 +316,10 @@ static std::set<std::string> default_trans_args;
void init_default_trans_args()
{
default_trans_args.insert("SECOND_LIFE"); // World
- default_trans_args.insert("SECOND_LIFE_VIEWER");
+ default_trans_args.insert("APP_NAME");
+ default_trans_args.insert("CAPITALIZED_APP_NAME");
default_trans_args.insert("SECOND_LIFE_GRID");
- default_trans_args.insert("SECOND_LIFE_SUPPORT");
+ default_trans_args.insert("SUPPORT_SITE");
}
//----------------------------------------------------------------------------
@@ -303,16 +329,12 @@ const char *VFS_INDEX_FILE_BASE = "index.db2.x.";
static std::string gWindowTitle;
-std::string gLoginPage;
-std::vector<std::string> gLoginURIs;
-static std::string gHelperURI;
-
LLAppViewer::LLUpdaterInfo *LLAppViewer::sUpdaterInfo = NULL ;
void idle_afk_check()
{
// check idle timers
- if (gSavedSettings.getBOOL("AllowIdleAFK") && (gAwayTriggerTimer.getElapsedTimeF32() > gSavedSettings.getF32("AFKTimeout")))
+ if (gSavedSettings.getS32("AFKTimeout") && (gAwayTriggerTimer.getElapsedTimeF32() > gSavedSettings.getS32("AFKTimeout")))
{
gAgent.setAFK();
}
@@ -327,13 +349,52 @@ static void ui_audio_callback(const LLUUID& uuid)
}
}
+bool create_text_segment_icon_from_url_match(LLUrlMatch* match,LLTextBase* base)
+{
+ if(!match || !base || base->getPlainText())
+ return false;
+
+ LLUUID match_id = match->getID();
+
+ LLIconCtrl* icon;
+
+ if(gAgent.isInGroup(match_id, TRUE))
+ {
+ LLGroupIconCtrl::Params icon_params = LLUICtrlFactory::instance().getDefaultParams<LLGroupIconCtrl>();
+ icon_params.group_id = match_id;
+ icon_params.rect = LLRect(0, 16, 16, 0);
+ icon_params.visible = true;
+ icon = LLUICtrlFactory::instance().createWidget<LLGroupIconCtrl>(icon_params);
+ }
+ else
+ {
+ LLAvatarIconCtrl::Params icon_params = LLUICtrlFactory::instance().getDefaultParams<LLAvatarIconCtrl>();
+ icon_params.avatar_id = match_id;
+ icon_params.rect = LLRect(0, 16, 16, 0);
+ icon_params.visible = true;
+ icon = LLUICtrlFactory::instance().createWidget<LLAvatarIconCtrl>(icon_params);
+ }
+
+ LLInlineViewSegment::Params params;
+ params.force_newline = false;
+ params.view = icon;
+ params.left_pad = 4;
+ params.right_pad = 4;
+ params.top_pad = -2;
+ params.bottom_pad = 2;
+
+ base->appendWidget(params," ",false);
+
+ return true;
+}
+
void request_initial_instant_messages()
{
static BOOL requested = FALSE;
if (!requested
&& gMessageSystem
&& LLMuteList::getInstance()->isLoaded()
- && gAgent.getAvatarObject())
+ && isAgentAvatarValid())
{
// Auto-accepted inventory items may require the avatar object
// to build a correct name. Likewise, inventory offers from
@@ -355,14 +416,8 @@ bool handleCrashSubmitBehaviorChanged(const LLSD& newvalue)
const S32 NEVER_SUBMIT_REPORT = 2;
if(cb == NEVER_SUBMIT_REPORT)
{
-// LLWatchdog::getInstance()->cleanup(); // SJB: cleaning up a running watchdog thread is unsafe
LLAppViewer::instance()->destroyMainloopTimeout();
}
- else if(gSavedSettings.getBOOL("WatchdogEnabled") == TRUE)
- {
- // Don't re-enable the watchdog when we change the setting; this may get called before it's started
-// LLWatchdog::getInstance()->init();
- }
return true;
}
@@ -371,7 +426,6 @@ bool handleCrashSubmitBehaviorChanged(const LLSD& newvalue)
static void settings_to_globals()
{
LLBUTTON_H_PAD = gSavedSettings.getS32("ButtonHPad");
- LLBUTTON_V_PAD = gSavedSettings.getS32("ButtonVPad");
BTN_HEIGHT_SMALL = gSavedSettings.getS32("ButtonHeightSmall");
BTN_HEIGHT = gSavedSettings.getS32("ButtonHeight");
@@ -389,11 +443,10 @@ static void settings_to_globals()
LLVolumeImplFlexible::sUpdateFactor = gSavedSettings.getF32("RenderFlexTimeFactor");
LLVOTree::sTreeFactor = gSavedSettings.getF32("RenderTreeLODFactor");
LLVOAvatar::sLODFactor = gSavedSettings.getF32("RenderAvatarLODFactor");
- LLVOAvatar::sMaxVisible = gSavedSettings.getS32("RenderAvatarMaxVisible");
+ LLVOAvatar::sMaxVisible = (U32)gSavedSettings.getS32("RenderAvatarMaxVisible");
LLVOAvatar::sVisibleInFirstPerson = gSavedSettings.getBOOL("FirstPersonAvatarVisible");
// clamp auto-open time to some minimum usable value
LLFolderView::sAutoOpenTime = llmax(0.25f, gSavedSettings.getF32("FolderAutoOpenDelay"));
- LLToolBar::sInventoryAutoOpenTime = gSavedSettings.getF32("InventoryAutoOpenDelay");
LLSelectMgr::sRectSelectInclusive = gSavedSettings.getBOOL("RectangleSelectInclusive");
LLSelectMgr::sRenderHiddenSelections = gSavedSettings.getBOOL("RenderHiddenSelections");
LLSelectMgr::sRenderLightRadius = gSavedSettings.getBOOL("RenderLightRadius");
@@ -403,10 +456,8 @@ static void settings_to_globals()
gAgent.setHideGroupTitle(gSavedSettings.getBOOL("RenderHideGroupTitle"));
gDebugWindowProc = gSavedSettings.getBOOL("DebugWindowProc");
- gAllowTapTapHoldRun = gSavedSettings.getBOOL("AllowTapTapHoldRun");
gShowObjectUpdates = gSavedSettings.getBOOL("ShowObjectUpdates");
- gMapScale = gSavedSettings.getF32("MapScale");
- LLHoverView::sShowHoverTips = gSavedSettings.getBOOL("ShowHoverTips");
+ LLWorldMapView::sMapScale = gSavedSettings.getF32("MapScale");
LLCubeMap::sUseCubeMaps = LLFeatureManager::getInstance()->isFeatureAvailable("RenderCubeMap");
}
@@ -419,7 +470,7 @@ static void settings_modify()
LLVOSurfacePatch::sLODFactor *= LLVOSurfacePatch::sLODFactor; //square lod factor to get exponential range of [1,4]
gDebugGL = gSavedSettings.getBOOL("RenderDebugGL") || gDebugSession;
gDebugPipeline = gSavedSettings.getBOOL("RenderDebugPipeline");
-
+ gAuditTexture = gSavedSettings.getBOOL("AuditTexture");
#if LL_VECTORIZE
if (gSysCPU.hasAltivec())
{
@@ -487,35 +538,6 @@ public:
}
};
-void LLAppViewer::initGridChoice()
-{
- // Load up the initial grid choice from:
- // - hard coded defaults...
- // - command line settings...
- // - if dev build, persisted settings...
-
- // Set the "grid choice", this is specified by command line.
- std::string grid_choice = gSavedSettings.getString("CmdLineGridChoice");
- LLViewerLogin::getInstance()->setGridChoice(grid_choice);
-
- // Load last server choice by default
- // ignored if the command line grid choice has been set
- if(grid_choice.empty())
- {
- S32 server = gSavedSettings.getS32("ServerChoice");
- server = llclamp(server, 0, (S32)GRID_INFO_COUNT - 1);
- if(server == GRID_INFO_OTHER)
- {
- std::string custom_server = gSavedSettings.getString("CustomServer");
- LLViewerLogin::getInstance()->setGridChoice(custom_server);
- }
- else if(server != (S32)GRID_INFO_NONE)
- {
- LLViewerLogin::getInstance()->setGridChoice((EGridInfo)server);
- }
- }
-}
-
//virtual
bool LLAppViewer::initSLURLHandler()
{
@@ -540,7 +562,7 @@ LLAppViewer* LLAppViewer::sInstance = NULL;
const std::string LLAppViewer::sGlobalSettingsName = "Global";
LLTextureCache* LLAppViewer::sTextureCache = NULL;
-LLWorkerThread* LLAppViewer::sImageDecodeThread = NULL;
+LLImageDecodeThread* LLAppViewer::sImageDecodeThread = NULL;
LLTextureFetch* LLAppViewer::sTextureFetch = NULL;
LLAppViewer::LLAppViewer() :
@@ -558,9 +580,9 @@ LLAppViewer::LLAppViewer() :
mYieldTime(-1),
mMainloopTimeout(NULL),
mAgentRegionLastAlive(false),
- mFastTimerLogThread(NULL),
mRandomizeFramerate(LLCachedControl<bool>(gSavedSettings,"Randomize Framerate", FALSE)),
- mPeriodicSlowFrame(LLCachedControl<bool>(gSavedSettings,"Periodic Slow Frame", FALSE))
+ mPeriodicSlowFrame(LLCachedControl<bool>(gSavedSettings,"Periodic Slow Frame", FALSE)),
+ mFastTimerLogThread(NULL)
{
if(NULL != sInstance)
{
@@ -588,7 +610,8 @@ bool LLAppViewer::init()
// into the log files during normal startup until AFTER
// we run the "program crashed last time" error handler below.
//
-
+ LLFastTimer::reset();
+
// Need to do this initialization before we do anything else, since anything
// that touches files should really go through the lldir API
gDirUtilp->initAppDirs("SecondLife");
@@ -606,24 +629,38 @@ bool LLAppViewer::init()
if (!initConfiguration())
return false;
-
+
+ // write Google Breakpad minidump files to our log directory
+ std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "");
+ logdir += gDirUtilp->getDirDelimiter();
+ setMiniDumpDir(logdir);
+
+ // Although initLogging() is the right place to mess with
+ // setFatalFunction(), we can't query gSavedSettings until after
+ // initConfiguration().
+ S32 rc(gSavedSettings.getS32("QAModeTermCode"));
+ if (rc >= 0)
+ {
+ // QAModeTermCode set, terminate with that rc on LL_ERRS. Use _exit()
+ // rather than exit() because normal cleanup depends too much on
+ // successful startup!
+ LLError::setFatalFunction(boost::bind(_exit, rc));
+ }
+
mAlloc.setProfilingEnabled(gSavedSettings.getBOOL("MemProfiling"));
// *NOTE:Mani - LLCurl::initClass is not thread safe.
// Called before threads are created.
LLCurl::initClass();
+ LLMachineID::init();
initThreads();
-
writeSystemInfo();
// Build a string representing the current version number.
- gCurrentVersion = llformat("%s %d.%d.%d.%d",
- gSavedSettings.getString("VersionChannelName").c_str(),
- LL_VERSION_MAJOR,
- LL_VERSION_MINOR,
- LL_VERSION_PATCH,
- LL_VERSION_BUILD );
+ gCurrentVersion = llformat("%s %s",
+ gSavedSettings.getString("VersionChannelName").c_str(),
+ LLVersionInfo::getVersion().c_str());
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
@@ -631,6 +668,9 @@ bool LLAppViewer::init()
//////////////////////////////////////////////////////////////////////////////
// *FIX: The following code isn't grouped into functions yet.
+ // Statistics / debug timer initialization
+ init_statistics();
+
//
// Various introspection concerning the libs we're using - particularly
// the libs involved in getting to a full login screen.
@@ -641,6 +681,11 @@ bool LLAppViewer::init()
// Get the single value from the crash settings file, if it exists
std::string crash_settings_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, CRASH_SETTINGS_FILE);
gCrashSettings.loadFromFile(crash_settings_filename);
+ if(gSavedSettings.getBOOL("IgnoreAllNotifications"))
+ {
+ gCrashSettings.setS32(CRASH_BEHAVIOR_SETTING, CRASH_BEHAVIOR_ALWAYS_SEND);
+ gCrashSettings.saveToFile(crash_settings_filename, FALSE);
+ }
/////////////////////////////////////////////////
// OS-specific login dialogs
@@ -653,8 +698,6 @@ bool LLAppViewer::init()
mNumSessions++;
gSavedSettings.setS32("NumSessions", mNumSessions);
- gSavedSettings.setString("HelpLastVisitedURL",gSavedSettings.getString("HelpHomeURL"));
-
if (gSavedSettings.getBOOL("VerboseLogs"))
{
LLError::setPrintLocation(true);
@@ -663,26 +706,36 @@ bool LLAppViewer::init()
// Widget construction depends on LLUI being initialized
LLUI::settings_map_t settings_map;
settings_map["config"] = &gSavedSettings;
- settings_map["color"] = &gSavedSkinSettings;
settings_map["ignores"] = &gWarningSettings;
settings_map["floater"] = &gSavedSettings; // *TODO: New settings file
settings_map["account"] = &gSavedPerAccountSettings;
LLUI::initClass(settings_map,
- LLUIImageList::getInstance(),
- ui_audio_callback,
- &LLUI::sGLScaleFactor);
+ LLUIImageList::getInstance(),
+ ui_audio_callback,
+ &LLUI::sGLScaleFactor);
// Setup paths and LLTrans after LLUI::initClass has been called
LLUI::setupPaths();
- LLTrans::parseStrings("strings.xml", default_trans_args);
+ LLTransUtil::parseStrings("strings.xml", default_trans_args);
+ LLTransUtil::parseLanguageStrings("language_settings.xml");
+
+ // LLKeyboard relies on LLUI to know what some accelerator keys are called.
+ LLKeyboard::setStringTranslatorFunc( LLTrans::getKeyboardString );
LLWeb::initClass(); // do this after LLUI
-
- LLTextEditor::setURLCallbacks(&LLWeb::loadURL,
- &LLURLDispatcher::dispatchFromTextEditor,
- &LLURLDispatcher::dispatchFromTextEditor);
+ // Provide the text fields with callbacks for opening Urls
+ LLUrlAction::setOpenURLCallback(&LLWeb::loadURL);
+ LLUrlAction::setOpenURLInternalCallback(&LLWeb::loadURLInternal);
+ LLUrlAction::setOpenURLExternalCallback(&LLWeb::loadURLExternal);
+ LLUrlAction::setExecuteSLURLCallback(&LLURLDispatcher::dispatchFromTextEditor);
+
+ // Let code in llui access the viewer help floater
+ LLUI::sHelpImpl = LLViewerHelp::getInstance();
+
+ // Load translations for tooltips
+ LLFloater::initClass();
/////////////////////////////////////////////////
@@ -702,7 +755,15 @@ bool LLAppViewer::init()
LLViewerJointMesh::updateVectorize();
// load MIME type -> media impl mappings
- LLMIMETypes::parseMIMETypes( std::string("mime_types.xml") );
+ std::string mime_types_name;
+#if LL_DARWIN
+ mime_types_name = "mime_types_mac.xml";
+#elif LL_LINUX
+ mime_types_name = "mime_types_linux.xml";
+#else
+ mime_types_name = "mime_types.xml";
+#endif
+ LLMIMETypes::parseMIMETypes( mime_types_name );
// Copy settings to globals. *TODO: Remove or move to appropriage class initializers
settings_to_globals();
@@ -723,10 +784,6 @@ bool LLAppViewer::init()
return false;
}
- // Always fetch the Ethernet MAC address, needed both for login
- // and password load.
- LLUUID::getNodeID(gMACAddress);
-
// Prepare for out-of-memory situations, during which we will crash on
// purpose and save a dump.
#if LL_WINDOWS && LL_RELEASE_FOR_DOWNLOAD && LL_USE_SMARTHEAP
@@ -750,18 +807,12 @@ bool LLAppViewer::init()
//
// Initialize the window
//
+ gGLActive = TRUE;
initWindow();
// call all self-registered classes
LLInitClassList::instance().fireCallbacks();
- #if LL_LCD_COMPILE
- // start up an LCD window on a logitech keyboard, if there is one
- HINSTANCE hInstance = GetModuleHandle(NULL);
- gLcdScreen = new LLLCD(hInstance);
- CreateLCDDebugWindows();
-#endif
-
LLFolderViewItem::initClass(); // SJB: Needs to happen after initWindow(), not sure why but related to fonts
gGLManager.getGLInfo(gDebugInfo);
@@ -814,7 +865,7 @@ bool LLAppViewer::init()
minSpecs += "\n";
unsupported = true;
}
- if(gSysCPU.getMhz() < minCPU)
+ if(gSysCPU.getMHz() < minCPU)
{
minSpecs += LLNotifications::instance().getGlobalString("UnsupportedCPU");
minSpecs += "\n";
@@ -829,7 +880,7 @@ bool LLAppViewer::init()
if (LLFeatureManager::getInstance()->getGPUClass() == GPU_CLASS_UNKNOWN)
{
- LLNotifications::instance().add("UnknownGPU");
+ LLNotificationsUtil::add("UnknownGPU");
}
if(unsupported)
@@ -838,12 +889,13 @@ bool LLAppViewer::init()
|| gSavedSettings.getBOOL("WarnUnsupportedHardware"))
{
args["MINSPECS"] = minSpecs;
- LLNotifications::instance().add("UnsupportedHardware", args );
+ LLNotificationsUtil::add("UnsupportedHardware", args );
}
}
}
+
// save the graphics card
gDebugInfo["GraphicsCard"] = LLFeatureManager::getInstance()->getGPUString();
@@ -855,14 +907,65 @@ bool LLAppViewer::init()
LLViewerJoystick::getInstance()->init(false);
+ try {
+ initializeSecHandler();
+ }
+ catch (LLProtectedDataException ex)
+ {
+ LLNotificationsUtil::add("CorruptedProtectedDataStore");
+ }
+ LLHTTPClient::setCertVerifyCallback(secapiSSLCertVerifyCallback);
+
+
+ gGLActive = FALSE;
+ if (gSavedSettings.getBOOL("QAMode") && gSavedSettings.getS32("QAModeEventHostPort") > 0)
+ {
+ loadEventHostModule(gSavedSettings.getS32("QAModeEventHostPort"));
+ }
+
+ LLViewerMedia::initClass();
+ LLTextUtil::TextHelpers::iconCallbackCreationFunction = create_text_segment_icon_from_url_match;
+
+ //EXT-7013 - On windows for some locale (Japanese) standard
+ //datetime formatting functions didn't support some parameters such as "weekday".
+ //Names for days and months localized in xml are also useful for Polish locale(STORM-107).
+ std::string language = LLControlGroup::getInstance(sGlobalSettingsName)->getString("Language");
+ if(language == "ja" || language == "pl")
+ {
+ LLStringOps::setupWeekDaysNames(LLTrans::getString("dateTimeWeekdaysNames"));
+ LLStringOps::setupWeekDaysShortNames(LLTrans::getString("dateTimeWeekdaysShortNames"));
+ LLStringOps::setupMonthNames(LLTrans::getString("dateTimeMonthNames"));
+ LLStringOps::setupMonthShortNames(LLTrans::getString("dateTimeMonthShortNames"));
+ LLStringOps::setupDayFormat(LLTrans::getString("dateTimeDayFormat"));
+
+ LLStringOps::sAM = LLTrans::getString("dateTimeAM");
+ LLStringOps::sPM = LLTrans::getString("dateTimePM");
+ }
+
+ LLAgentLanguage::init();
+
return true;
}
+static LLFastTimer::DeclareTimer FTM_MESSAGES("System Messages");
+static LLFastTimer::DeclareTimer FTM_SLEEP("Sleep");
+static LLFastTimer::DeclareTimer FTM_TEXTURE_CACHE("Texture Cache");
+static LLFastTimer::DeclareTimer FTM_DECODE("Image Decode");
+static LLFastTimer::DeclareTimer FTM_VFS("VFS Thread");
+static LLFastTimer::DeclareTimer FTM_LFS("LFS Thread");
+static LLFastTimer::DeclareTimer FTM_PAUSE_THREADS("Pause Threads");
+static LLFastTimer::DeclareTimer FTM_IDLE("Idle");
+static LLFastTimer::DeclareTimer FTM_PUMP("Pump");
+static LLFastTimer::DeclareTimer FTM_PUMP_ARES("Ares");
+static LLFastTimer::DeclareTimer FTM_PUMP_SERVICE("Service");
+static LLFastTimer::DeclareTimer FTM_SERVICE_CALLBACK("Callback");
+static LLFastTimer::DeclareTimer FTM_AGENT_AUTOPILOT("Autopilot");
+static LLFastTimer::DeclareTimer FTM_AGENT_UPDATE("Update");
+
bool LLAppViewer::mainLoop()
{
LLMemType mt1(LLMemType::MTYPE_MAIN);
mMainloopTimeout = new LLWatchdogTimeout();
- // *FIX:Mani - Make this a setting, once new settings exist in this branch.
//-------------------------------------------
// Run main loop until time to quit
@@ -872,12 +975,11 @@ bool LLAppViewer::mainLoop()
gServicePump = new LLPumpIO(gAPRPoolp);
LLHTTPClient::setPump(*gServicePump);
LLCurl::setCAFile(gDirUtilp->getCAFile());
-
+
// Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be instantiated.
LLVoiceChannel::initClass();
- LLVoiceClient::init(gServicePump);
-
+ LLVoiceClient::getInstance()->init(gServicePump);
LLTimer frameTimer,idleTimer;
LLTimer debugTime;
LLViewerJoystick* joystick(LLViewerJoystick::getInstance());
@@ -894,21 +996,22 @@ bool LLAppViewer::mainLoop()
while (!LLApp::isExiting())
{
LLFastTimer::nextFrame(); // Should be outside of any timer instances
+
try
{
pingMainloopTimeout("Main:MiscNativeWindowEvents");
if (gViewerWindow)
{
- LLFastTimer t2(LLFastTimer::FTM_MESSAGES);
+ LLFastTimer t2(FTM_MESSAGES);
gViewerWindow->mWindow->processMiscNativeEvents();
}
-
+
pingMainloopTimeout("Main:GatherInput");
if (gViewerWindow)
{
- LLFastTimer t2(LLFastTimer::FTM_MESSAGES);
+ LLFastTimer t2(FTM_MESSAGES);
if (!restoreErrorTrap())
{
llwarns << " Someone took over my signal/exception handler (post messagehandling)!" << llendl;
@@ -926,9 +1029,11 @@ bool LLAppViewer::mainLoop()
#endif
//memory leaking simulation
- if(LLFloaterMemLeak::getInstance())
+ LLFloaterMemLeak* mem_leak_instance =
+ LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking");
+ if(mem_leak_instance)
{
- LLFloaterMemLeak::getInstance()->idle() ;
+ mem_leak_instance->idle() ;
}
// canonical per-frame event
@@ -957,18 +1062,28 @@ bool LLAppViewer::mainLoop()
{
pauseMainloopTimeout(); // *TODO: Remove. Messages shouldn't be stalling for 20+ seconds!
- LLFastTimer t3(LLFastTimer::FTM_IDLE);
+ LLFastTimer t3(FTM_IDLE);
idle();
if (gAres != NULL && gAres->isInitialized())
{
LLMemType mt_ip(LLMemType::MTYPE_IDLE_PUMP);
pingMainloopTimeout("Main:ServicePump");
- LLFastTimer t4(LLFastTimer::FTM_PUMP);
- gAres->process();
- // this pump is necessary to make the login screen show up
- gServicePump->pump();
- gServicePump->callback();
+ LLFastTimer t4(FTM_PUMP);
+ {
+ LLFastTimer t(FTM_PUMP_ARES);
+ gAres->process();
+ }
+ {
+ LLFastTimer t(FTM_PUMP_SERVICE);
+ // this pump is necessary to make the login screen show up
+ gServicePump->pump();
+
+ {
+ LLFastTimer t(FTM_SERVICE_CALLBACK);
+ gServicePump->callback();
+ }
+ }
}
resumeMainloopTimeout();
@@ -986,10 +1101,11 @@ bool LLAppViewer::mainLoop()
if (!LLApp::isExiting())
{
pingMainloopTimeout("Main:Display");
+ gGLActive = TRUE;
display();
-
pingMainloopTimeout("Main:Snapshot");
LLFloaterSnapshot::update(); // take snapshots
+ gGLActive = FALSE;
}
}
@@ -1001,9 +1117,8 @@ bool LLAppViewer::mainLoop()
// Sleep and run background threads
{
LLMemType mt_sleep(LLMemType::MTYPE_SLEEP);
- LLFastTimer t2(LLFastTimer::FTM_SLEEP);
- bool run_multiple_threads = gSavedSettings.getBOOL("RunMultipleThreads");
-
+ LLFastTimer t2(FTM_SLEEP);
+
// yield some time to the os based on command line option
if(mYieldTime >= 0)
{
@@ -1040,34 +1155,64 @@ bool LLAppViewer::mainLoop()
ms_sleep(500);
}
-
- const F64 min_frame_time = 0.0; //(.0333 - .0010); // max video frame rate = 30 fps
- const F64 min_idle_time = 0.0; //(.0010); // min idle time = 1 ms
- const F64 max_idle_time = run_multiple_threads ? min_idle_time : llmin(.005*10.0*gFrameTimeSeconds, 0.005); // 5 ms a second
+ static const F64 FRAME_SLOW_THRESHOLD = 0.5; //2 frames per seconds
+ const F64 max_idle_time = llmin(.005*10.0*gFrameTimeSeconds, 0.005); // 5 ms a second
idleTimer.reset();
- while(1)
+ bool is_slow = (frameTimer.getElapsedTimeF64() > FRAME_SLOW_THRESHOLD) ;
+ S32 total_work_pending = 0;
+ S32 total_io_pending = 0;
+ while(!is_slow)//do not unpause threads if the frame rates are very low.
{
S32 work_pending = 0;
S32 io_pending = 0;
- work_pending += LLAppViewer::getTextureCache()->update(1); // unpauses the texture cache thread
- work_pending += LLAppViewer::getImageDecodeThread()->update(1); // unpauses the image thread
- work_pending += LLAppViewer::getTextureFetch()->update(1); // unpauses the texture fetch thread
- io_pending += LLVFSThread::updateClass(1);
- io_pending += LLLFSThread::updateClass(1);
+ {
+ LLFastTimer ftm(FTM_TEXTURE_CACHE);
+ work_pending += LLAppViewer::getTextureCache()->update(1); // unpauses the texture cache thread
+ }
+ {
+ LLFastTimer ftm(FTM_DECODE);
+ work_pending += LLAppViewer::getImageDecodeThread()->update(1); // unpauses the image thread
+ }
+ {
+ LLFastTimer ftm(FTM_DECODE);
+ work_pending += LLAppViewer::getTextureFetch()->update(1); // unpauses the texture fetch thread
+ }
+
+ {
+ LLFastTimer ftm(FTM_VFS);
+ io_pending += LLVFSThread::updateClass(1);
+ }
+ {
+ LLFastTimer ftm(FTM_LFS);
+ io_pending += LLLFSThread::updateClass(1);
+ }
+
if (io_pending > 1000)
{
ms_sleep(llmin(io_pending/100,100)); // give the vfs some time to catch up
}
- F64 frame_time = frameTimer.getElapsedTimeF64();
- F64 idle_time = idleTimer.getElapsedTimeF64();
- if (frame_time >= min_frame_time &&
- idle_time >= min_idle_time &&
- (!work_pending || idle_time >= max_idle_time))
+ total_work_pending += work_pending ;
+ total_io_pending += io_pending ;
+
+ if (!work_pending || idleTimer.getElapsedTimeF64() >= max_idle_time)
{
break;
}
}
+
+ if(!total_work_pending) //pause texture fetching threads if nothing to process.
+ {
+ LLAppViewer::getTextureCache()->pause();
+ LLAppViewer::getImageDecodeThread()->pause();
+ LLAppViewer::getTextureFetch()->pause();
+ }
+ if(!total_io_pending) //pause file threads if nothing to process.
+ {
+ LLVFSThread::sLocal->pause();
+ LLLFSThread::sLocal->pause();
+ }
+
if ((LLStartUp::getStartupState() >= STATE_CLEANUP) &&
(frameTimer.getElapsedTimeF64() > FRAME_STALL_THRESHOLD))
{
@@ -1075,17 +1220,6 @@ bool LLAppViewer::mainLoop()
}
frameTimer.reset();
- // Prevent the worker threads from running while rendering.
- // if (LLThread::processorCount()==1) //pause() should only be required when on a single processor client...
- if (run_multiple_threads == FALSE)
- {
- LLAppViewer::getTextureCache()->pause();
- LLAppViewer::getImageDecodeThread()->pause();
- // LLAppViewer::getTextureFetch()->pause(); // Don't pause the fetch (IO) thread
- }
- //LLVFSThread::sLocal->pause(); // Prevent the VFS thread from running while rendering.
- //LLLFSThread::sLocal->pause(); // Prevent the LFS thread from running while rendering.
-
resumeMainloopTimeout();
pingMainloopTimeout("Main:End");
@@ -1095,9 +1229,11 @@ bool LLAppViewer::mainLoop()
catch(std::bad_alloc)
{
//stop memory leaking simulation
- if(LLFloaterMemLeak::getInstance())
+ LLFloaterMemLeak* mem_leak_instance =
+ LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking");
+ if(mem_leak_instance)
{
- LLFloaterMemLeak::getInstance()->stop() ;
+ mem_leak_instance->stop() ;
llwarns << "Bad memory allocation in LLAppViewer::mainLoop()!" << llendl ;
}
else
@@ -1122,9 +1258,11 @@ bool LLAppViewer::mainLoop()
llwarns << "Bad memory allocation when saveFinalSnapshot() is called!" << llendl ;
//stop memory leaking simulation
- if(LLFloaterMemLeak::getInstance())
+ LLFloaterMemLeak* mem_leak_instance =
+ LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking");
+ if(mem_leak_instance)
{
- LLFloaterMemLeak::getInstance()->stop() ;
+ mem_leak_instance->stop() ;
}
}
}
@@ -1140,6 +1278,29 @@ bool LLAppViewer::mainLoop()
bool LLAppViewer::cleanup()
{
+ // workaround for DEV-35406 crash on shutdown
+ LLEventPumps::instance().reset();
+
+ // remove any old breakpad minidump files from the log directory
+ if (! isError())
+ {
+ std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "");
+ logdir += gDirUtilp->getDirDelimiter();
+ gDirUtilp->deleteFilesInDir(logdir, "*-*-*-*-*.dmp");
+ }
+
+ // *TODO - generalize this and move DSO wrangling to a helper class -brad
+ std::set<struct apr_dso_handle_t *>::const_iterator i;
+ for(i = mPlugins.begin(); i != mPlugins.end(); ++i)
+ {
+ int (*ll_plugin_stop_func)(void) = NULL;
+ apr_status_t rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll_plugin_stop_func, *i, "ll_plugin_stop");
+ ll_plugin_stop_func();
+
+ rv = apr_dso_unload(*i);
+ }
+ mPlugins.clear();
+
//----------------------------------------------
//this test code will be removed after the test
//test manual call stack tracer
@@ -1154,7 +1315,7 @@ bool LLAppViewer::cleanup()
// to ensure shutdown order
LLMortician::setZealous(TRUE);
- LLVoiceClient::terminate();
+ LLVoiceClient::getInstance()->terminate();
disconnectViewer();
@@ -1204,6 +1365,14 @@ bool LLAppViewer::cleanup()
if (gAudiop)
{
+ // shut down the streaming audio sub-subsystem first, in case it relies on not outliving the general audio subsystem.
+
+ LLStreamingAudioInterface *sai = gAudiop->getStreamingAudioImpl();
+ delete sai;
+ gAudiop->setStreamingAudioImpl(NULL);
+
+ // shut down the audio subsystem
+
bool want_longname = false;
if (gAudiop->getDriverName(want_longname) == "FMOD")
{
@@ -1241,9 +1410,6 @@ bool LLAppViewer::cleanup()
llinfos << "Cache files removed" << llendflush;
-
- cleanup_menus();
-
// Wait for any pending VFS IO
while (1)
{
@@ -1256,15 +1422,25 @@ bool LLAppViewer::cleanup()
llinfos << "Waiting for pending IO to finish: " << pending << llendflush;
ms_sleep(100);
}
- llinfos << "Shutting down." << llendflush;
+ llinfos << "Shutting down Views" << llendflush;
// Destroy the UI
if( gViewerWindow)
gViewerWindow->shutdownViews();
+ llinfos << "Cleaning up Inventory" << llendflush;
+
+ // Cleanup Inventory after the UI since it will delete any remaining observers
+ // (Deleted observers should have already removed themselves)
+ gInventory.cleanupInventory();
+
+ llinfos << "Cleaning up Selections" << llendflush;
+
// Clean up selection managers after UI is destroyed, as UI may be observing them.
// Clean up before GL is shut down because we might be holding on to objects with texture references
LLSelectMgr::cleanupGlobals();
+
+ llinfos << "Shutting down OpenGL" << llendflush;
// Shut down OpenGL
if( gViewerWindow)
@@ -1278,11 +1454,18 @@ bool LLAppViewer::cleanup()
gViewerWindow = NULL;
llinfos << "ViewerWindow deleted" << llendflush;
}
+
+ llinfos << "Cleaning up Keyboard & Joystick" << llendflush;
// viewer UI relies on keyboard so keep it aound until viewer UI isa gone
delete gKeyboard;
gKeyboard = NULL;
+ // Turn off Space Navigator and similar devices
+ LLViewerJoystick::getInstance()->terminate();
+
+ llinfos << "Cleaning up Objects" << llendflush;
+
LLViewerObject::cleanupVOClasses();
LLWaterParamManager::cleanupClass();
@@ -1305,6 +1488,8 @@ bool LLAppViewer::cleanup()
}
LLPrimitive::cleanupVolumeManager();
+ llinfos << "Additional Cleanup..." << llendflush;
+
LLViewerParcelMgr::cleanupGlobals();
// *Note: this is where gViewerStats used to be deleted.
@@ -1324,15 +1509,10 @@ bool LLAppViewer::cleanup()
// Also after shutting down the messaging system since it has VFS dependencies
//
+ llinfos << "Cleaning up VFS" << llendflush;
LLVFile::cleanupClass();
- llinfos << "VFS cleaned up" << llendflush;
- // Quitting with "Remember Password" turned off should always stomp your
- // saved password, whether or not you successfully logged in. JC
- if (!gSavedSettings.getBOOL("RememberPassword"))
- {
- LLStartUp::deletePasswordFromDisk();
- }
+ llinfos << "Saving Data" << llendflush;
// Store the time of our current logoff
gSavedPerAccountSettings.setU32("LastLogoff", time_corrected());
@@ -1341,12 +1521,19 @@ bool LLAppViewer::cleanup()
// save their rects on delete.
gSavedSettings.saveToFile(gSavedSettings.getString("ClientSettingsFile"), TRUE);
- //*FIX: don't overwrite user color tweaks with *all* colors
- gSavedSkinSettings.saveToFile(gSavedSettings.getString("SkinningSettingsFile"), TRUE);
- // PerAccountSettingsFile should be empty if no use has been logged on.
+ LLUIColorTable::instance().saveUserSettings();
+
+ // PerAccountSettingsFile should be empty if no user has been logged on.
// *FIX:Mani This should get really saved in a "logoff" mode.
- gSavedPerAccountSettings.saveToFile(gSavedSettings.getString("PerAccountSettingsFile"), TRUE);
- llinfos << "Saved settings" << llendflush;
+ if (gSavedSettings.getString("PerAccountSettingsFile").empty())
+ {
+ llinfos << "Not saving per-account settings; don't know the account name yet." << llendl;
+ }
+ else
+ {
+ gSavedPerAccountSettings.saveToFile(gSavedSettings.getString("PerAccountSettingsFile"), TRUE);
+ llinfos << "Saved settings" << llendflush;
+ }
std::string crash_settings_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, CRASH_SETTINGS_FILE);
// save all settings, even if equals defaults
@@ -1355,10 +1542,6 @@ bool LLAppViewer::cleanup()
std::string warnings_settings_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, getSettingsFilename("Default", "Warnings"));
gWarningSettings.saveToFile(warnings_settings_filename, TRUE);
- gSavedSettings.cleanup();
- gSavedSkinSettings.cleanup();
- gCrashSettings.cleanup();
-
// Save URL history file
LLURLHistory::saveFile("url_history.xml");
@@ -1376,6 +1559,17 @@ bool LLAppViewer::cleanup()
writeDebugInfo();
+ LLLocationHistory::getInstance()->save();
+
+ LLAvatarIconIDCache::getInstance()->save();
+
+ LLViewerMedia::saveCookieFile();
+
+ // Stop the plugin read thread if it's running.
+ LLPluginProcessParent::setUseReadThread(false);
+
+ llinfos << "Shutting down Threads" << llendflush;
+
// Let threads finish
LLTimer idleTimer;
idleTimer.reset();
@@ -1389,30 +1583,35 @@ bool LLAppViewer::cleanup()
pending += LLVFSThread::updateClass(0);
pending += LLLFSThread::updateClass(0);
F64 idle_time = idleTimer.getElapsedTimeF64();
- if (!pending || idle_time >= max_idle_time)
+ if(!pending)
+ {
+ break ; //done
+ }
+ else if(idle_time >= max_idle_time)
{
llwarns << "Quitting with pending background tasks." << llendl;
break;
}
}
-
+
// Delete workers first
// shotdown all worker threads before deleting them in case of co-dependencies
sTextureCache->shutdown();
sTextureFetch->shutdown();
sImageDecodeThread->shutdown();
+ sTextureFetch->shutDownTextureCacheThread() ;
+ sTextureFetch->shutDownImageDecodeThread() ;
+
delete sTextureCache;
sTextureCache = NULL;
delete sTextureFetch;
sTextureFetch = NULL;
delete sImageDecodeThread;
sImageDecodeThread = NULL;
-
- LLLocationHistory::getInstance()->save();
delete mFastTimerLogThread;
mFastTimerLogThread = NULL;
-
+
if (LLFastTimerView::sAnalyzePerformance)
{
llinfos << "Analyzing performance" << llendl;
@@ -1434,11 +1633,14 @@ bool LLAppViewer::cleanup()
}
LLMetricPerformanceTester::cleanClass() ;
+ llinfos << "Cleaning up Media and Textures" << llendflush;
+
//Note:
- //LLViewerMedia::cleanupClass() has to be put before gImageList.shutdown()
+ //LLViewerMedia::cleanupClass() has to be put before gTextureList.shutdown()
//because some new image might be generated during cleaning up media. --bao
LLViewerMedia::cleanupClass();
- gImageList.shutdown(); // shutdown again in case a callback added something
+ LLViewerParcelMedia::cleanupClass();
+ gTextureList.shutdown(); // shutdown again in case a callback added something
LLUIImageList::getInstance()->cleanUp();
// This should eventually be done in LLAppViewer
@@ -1446,28 +1648,31 @@ bool LLAppViewer::cleanup()
LLVFSThread::cleanupClass();
LLLFSThread::cleanupClass();
- llinfos << "VFS Thread finished" << llendflush;
-
#ifndef LL_RELEASE_FOR_DOWNLOAD
llinfos << "Auditing VFS" << llendl;
gVFS->audit();
#endif
+ llinfos << "Misc Cleanup" << llendflush;
+
// For safety, the LLVFS has to be deleted *after* LLVFSThread. This should be cleaned up.
// (LLVFS doesn't know about LLVFSThread so can't kill pending requests) -Steve
delete gStaticVFS;
gStaticVFS = NULL;
delete gVFS;
gVFS = NULL;
+
+ gSavedSettings.cleanup();
+ LLUIColorTable::instance().clear();
+ gCrashSettings.cleanup();
LLWatchdog::getInstance()->cleanup();
+ llinfos << "Shutting down message system" << llendflush;
end_messaging_system();
- llinfos << "Message system deleted." << llendflush;
// *NOTE:Mani - The following call is not thread safe.
LLCurl::cleanupClass();
- llinfos << "LLCurl cleaned up." << llendflush;
// If we're exiting to launch an URL, do that here so the screen
// is at the right resolution before we launch IE.
@@ -1482,13 +1687,13 @@ bool LLAppViewer::cleanup()
// HACK: Attempt to wait until the screen res. switch is complete.
ms_sleep(1000);
- LLWeb::loadURLExternal( gLaunchFileOnQuit );
+ LLWeb::loadURLExternal( gLaunchFileOnQuit, false );
llinfos << "File launched." << llendflush;
}
ll_close_fail_log();
- llinfos << "Goodbye" << llendflush;
+ llinfos << "Goodbye!" << llendflush;
// return 0;
return true;
@@ -1521,22 +1726,14 @@ bool LLAppViewer::initThreads()
static const bool enable_threads = true;
#endif
- const S32 NEVER_SUBMIT_REPORT = 2;
- bool use_watchdog = gSavedSettings.getBOOL("WatchdogEnabled");
- bool send_reports = gCrashSettings.getS32(CRASH_BEHAVIOR_SETTING) != NEVER_SUBMIT_REPORT;
- if(use_watchdog && send_reports)
- {
- LLWatchdog::getInstance()->init(watchdog_killer_callback);
- }
-
- LLVFSThread::initClass(enable_threads && true);
- LLLFSThread::initClass(enable_threads && true);
+ LLVFSThread::initClass(enable_threads && false);
+ LLLFSThread::initClass(enable_threads && false);
// Image decoding
- LLAppViewer::sImageDecodeThread = new LLWorkerThread("ImageDecode", enable_threads && true);
+ LLAppViewer::sImageDecodeThread = new LLImageDecodeThread(enable_threads && true);
LLAppViewer::sTextureCache = new LLTextureCache(enable_threads && true);
- LLAppViewer::sTextureFetch = new LLTextureFetch(LLAppViewer::getTextureCache(), enable_threads && false);
- LLImage::initClass(LLAppViewer::getImageDecodeThread());
+ LLAppViewer::sTextureFetch = new LLTextureFetch(LLAppViewer::getTextureCache(), sImageDecodeThread, enable_threads && true);
+ LLImage::initClass();
if (LLFastTimer::sLog || LLFastTimer::sMetricLog)
{
@@ -1569,7 +1766,7 @@ bool LLAppViewer::initLogging()
LLError::initForApplication(
gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, ""));
LLError::setFatalFunction(errorCallback);
-
+
// Remove the last ".old" log file.
std::string old_log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
"SecondLife.old");
@@ -1664,7 +1861,7 @@ bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key,
}
else
{
- llwarns << "Cannot load " << full_settings_path << " - No settings found." << llendl;
+ llinfos << "Cannot load " << full_settings_path << " - No settings found." << llendl;
}
}
else
@@ -1696,43 +1893,7 @@ std::string LLAppViewer::getSettingsFilename(const std::string& location_key,
void LLAppViewer::loadColorSettings()
{
- gSavedSkinSettings.cleanup();
-
- loadSettingsFromDirectory("DefaultSkin");
- loadSettingsFromDirectory("CurrentSkin", true);
- loadSettingsFromDirectory("UserSkin");
-
- class ColorConverterFunctor : public LLControlGroup::ApplyFunctor
- {
- public:
- explicit ColorConverterFunctor(LLUIColorTable::Params& result)
- :mResult(result)
- {
- }
-
- void apply(const std::string& name, LLControlVariable* control)
- {
- if(control->isType(TYPE_COL4))
- {
- LLUIColorTable::ColorParams color;
- color.value = control->getValue();
-
- LLUIColorTable::ColorEntryParams color_entry;
- color_entry.name = name;
- color_entry.color = color;
-
- mResult.color_entries.add(color_entry);
- }
- }
-
- private:
- LLUIColorTable::Params& mResult;
- };
-
- LLUIColorTable::Params params;
- ColorConverterFunctor ccf(params);
- LLControlGroup::getInstance("Skinning")->applyToAll(&ccf);
- LLUIColorTable::instance().init(params);
+ LLUIColorTable::instance().loadFromSettings();
}
bool LLAppViewer::initConfiguration()
@@ -1769,65 +1930,64 @@ bool LLAppViewer::initConfiguration()
}
LLUI::setupPaths(); // setup paths for LLTrans based on settings files only
- LLTrans::parseStrings("strings.xml", default_trans_args);
-
+ LLTransUtil::parseStrings("strings.xml", default_trans_args);
+ LLTransUtil::parseLanguageStrings("language_settings.xml");
// - set procedural settings
// Note: can't use LL_PATH_PER_SL_ACCOUNT for any of these since we haven't logged in yet
gSavedSettings.setString("ClientSettingsFile",
gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, getSettingsFilename("Default", "Global")));
- gSavedSettings.setString("SkinningSettingsFile",
- gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, getSettingsFilename("UserSkin", "Skinning")));
-
- gSavedSettings.setString("VersionChannelName", LL_CHANNEL);
+ gSavedSettings.setString("VersionChannelName", LLVersionInfo::getChannel());
#ifndef LL_RELEASE_FOR_DOWNLOAD
- gSavedSettings.setBOOL("ShowConsoleWindow", TRUE);
- gSavedSettings.setBOOL("AllowMultipleViewers", TRUE);
+ // provide developer build only overrides for these control variables that are not
+ // persisted to settings.xml
+ LLControlVariable* c = gSavedSettings.getControl("ShowConsoleWindow");
+ if (c)
+ {
+ c->setValue(true, false);
+ }
+ c = gSavedSettings.getControl("AllowMultipleViewers");
+ if (c)
+ {
+ c->setValue(true, false);
+ }
#endif
- //*FIX:Mani - Set default to disabling watchdog mainloop
- // timeout for mac and linux. There is no call stack info
- // on these platform to help debug.
#ifndef LL_RELEASE_FOR_DOWNLOAD
- gSavedSettings.setBOOL("WatchdogEnabled", FALSE);
gSavedSettings.setBOOL("QAMode", TRUE );
+ gSavedSettings.setS32("WatchdogEnabled", 0);
#endif
-
-#ifndef LL_WINDOWS
- gSavedSettings.setBOOL("WatchdogEnabled", FALSE);
-#endif
-
+
gCrashSettings.getControl(CRASH_BEHAVIOR_SETTING)->getSignal()->connect(boost::bind(&handleCrashSubmitBehaviorChanged, _2));
// These are warnings that appear on the first experience of that condition.
// They are already set in the settings_default.xml file, but still need to be added to LLFirstUse
// for disable/reset ability
- LLFirstUse::addConfigVariable("FirstBalanceIncrease");
- LLFirstUse::addConfigVariable("FirstBalanceDecrease");
- LLFirstUse::addConfigVariable("FirstSit");
- LLFirstUse::addConfigVariable("FirstMap");
- LLFirstUse::addConfigVariable("FirstGoTo");
- LLFirstUse::addConfigVariable("FirstBuild");
- LLFirstUse::addConfigVariable("FirstLeftClickNoHit");
- LLFirstUse::addConfigVariable("FirstTeleport");
- LLFirstUse::addConfigVariable("FirstOverrideKeys");
- LLFirstUse::addConfigVariable("FirstAttach");
- LLFirstUse::addConfigVariable("FirstAppearance");
- LLFirstUse::addConfigVariable("FirstInventory");
- LLFirstUse::addConfigVariable("FirstSandbox");
- LLFirstUse::addConfigVariable("FirstFlexible");
- LLFirstUse::addConfigVariable("FirstDebugMenus");
- LLFirstUse::addConfigVariable("FirstStreamingMusic");
- LLFirstUse::addConfigVariable("FirstStreamingVideo");
- LLFirstUse::addConfigVariable("FirstSculptedPrim");
- LLFirstUse::addConfigVariable("FirstVoice");
- LLFirstUse::addConfigVariable("FirstMedia");
+// LLFirstUse::addConfigVariable("FirstBalanceIncrease");
+// LLFirstUse::addConfigVariable("FirstBalanceDecrease");
+// LLFirstUse::addConfigVariable("FirstSit");
+// LLFirstUse::addConfigVariable("FirstMap");
+// LLFirstUse::addConfigVariable("FirstGoTo");
+// LLFirstUse::addConfigVariable("FirstBuild");
+// LLFirstUse::addConfigVariable("FirstLeftClickNoHit");
+// LLFirstUse::addConfigVariable("FirstTeleport");
+// LLFirstUse::addConfigVariable("FirstOverrideKeys");
+// LLFirstUse::addConfigVariable("FirstAttach");
+// LLFirstUse::addConfigVariable("FirstAppearance");
+// LLFirstUse::addConfigVariable("FirstInventory");
+// LLFirstUse::addConfigVariable("FirstSandbox");
+// LLFirstUse::addConfigVariable("FirstFlexible");
+// LLFirstUse::addConfigVariable("FirstDebugMenus");
+// LLFirstUse::addConfigVariable("FirstSculptedPrim");
+// LLFirstUse::addConfigVariable("FirstVoice");
+// LLFirstUse::addConfigVariable("FirstMedia");
// - read command line settings.
LLControlGroupCLP clp;
std::string cmd_line_config = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,
"cmd_line.xml");
+
clp.configure(cmd_line_config, &gSavedSettings);
if(!initParseCommandLine(clp))
@@ -1910,7 +2070,6 @@ bool LLAppViewer::initConfiguration()
}
}
- initGridChoice();
// If we have specified crash on startup, set the global so we'll trigger the crash at the right time
if(clp.hasOption("crashonstartup"))
@@ -1971,6 +2130,11 @@ bool LLAppViewer::initConfiguration()
{
LLAgentPilot::sReplaySession = TRUE;
}
+
+ if (clp.hasOption("nonotifications"))
+ {
+ gSavedSettings.setBOOL("IgnoreAllNotifications", TRUE);
+ }
if (clp.hasOption("debugsession"))
{
@@ -1999,39 +2163,25 @@ bool LLAppViewer::initConfiguration()
// injection and steal passwords. Phoenix. SL-55321
if(clp.hasOption("url"))
{
- std::string slurl = clp.getOption("url")[0];
- if (LLSLURL::isSLURLCommand(slurl))
- {
- LLStartUp::sSLURLCommand = slurl;
- }
- else
- {
- LLURLSimString::setString(slurl);
- }
+ LLStartUp::setStartSLURL(LLSLURL(clp.getOption("url")[0]));
+ if(LLStartUp::getStartSLURL().getType() == LLSLURL::LOCATION)
+ {
+ LLGridManager::getInstance()->setGridChoice(LLStartUp::getStartSLURL().getGrid());
+
+ }
}
else if(clp.hasOption("slurl"))
{
- std::string slurl = clp.getOption("slurl")[0];
- if(LLSLURL::isSLURL(slurl))
- {
- if (LLSLURL::isSLURLCommand(slurl))
- {
- LLStartUp::sSLURLCommand = slurl;
- }
- else
- {
- LLURLSimString::setString(slurl);
- }
- }
+ LLSLURL start_slurl(clp.getOption("slurl")[0]);
+ LLStartUp::setStartSLURL(start_slurl);
}
const LLControlVariable* skinfolder = gSavedSettings.getControl("SkinCurrent");
if(skinfolder && LLStringUtil::null != skinfolder->getValue().asString())
{
- gDirUtilp->setSkinFolder(skinfolder->getValue().asString());
-
- gSavedSettings.setString("SkinningSettingsFile",
- gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, getSettingsFilename("UserSkin", "Skinning")));
+ // hack to force the skin to default.
+ //gDirUtilp->setSkinFolder(skinfolder->getValue().asString());
+ gDirUtilp->setSkinFolder("default");
}
mYieldTime = gSavedSettings.getS32("YieldTime");
@@ -2051,7 +2201,7 @@ bool LLAppViewer::initConfiguration()
#if LL_DARWIN
// Initialize apple menubar and various callbacks
- init_apple_menu(LLTrans::getString("SECOND_LIFE_VIEWER").c_str());
+ init_apple_menu(LLTrans::getString("APP_NAME").c_str());
#if __ppc__
// If the CPU doesn't have Altivec (i.e. it's not at least a G4), don't go any further.
@@ -2073,10 +2223,12 @@ bool LLAppViewer::initConfiguration()
// Display splash screen. Must be after above check for previous
// crash as this dialog is always frontmost.
- std::ostringstream splash_msg;
- splash_msg << "Loading " << LLTrans::getString("SECOND_LIFE") << "...";
+ std::string splash_msg;
+ LLStringUtil::format_map_t args;
+ args["[APP_NAME]"] = LLTrans::getString("SECOND_LIFE");
+ splash_msg = LLTrans::getString("StartupLoading", args);
LLSplashScreen::show();
- LLSplashScreen::update(splash_msg.str());
+ LLSplashScreen::update(splash_msg);
//LLVolumeMgr::initClass();
LLVolumeMgr* volume_manager = new LLVolumeMgr();
@@ -2090,7 +2242,7 @@ bool LLAppViewer::initConfiguration()
//
// Set the name of the window
//
- gWindowTitle = LLTrans::getString("SECOND_LIFE_VIEWER");
+ gWindowTitle = LLTrans::getString("APP_NAME");
#if LL_DEBUG
gWindowTitle += std::string(" [DEBUG] ") + gArgs;
#else
@@ -2102,18 +2254,10 @@ bool LLAppViewer::initConfiguration()
// don't call anotherInstanceRunning() when doing URL handoff, as
// it relies on checking a marker file which will not work when running
// out of different directories
- std::string slurl;
- if (!LLStartUp::sSLURLCommand.empty())
- {
- slurl = LLStartUp::sSLURLCommand;
- }
- else if (LLURLSimString::parse())
- {
- slurl = LLURLSimString::getURL();
- }
- if (!slurl.empty())
+
+ if (LLStartUp::getStartSLURL().isValid())
{
- if (sendURLToOtherInstance(slurl))
+ if (sendURLToOtherInstance(LLStartUp::getStartSLURL().getSLURLString()))
{
// successfully handed off URL to existing instance, exit
return false;
@@ -2169,9 +2313,9 @@ bool LLAppViewer::initConfiguration()
// need to do this here - need to have initialized global settings first
std::string nextLoginLocation = gSavedSettings.getString( "NextLoginLocation" );
- if ( nextLoginLocation.length() )
+ if ( !nextLoginLocation.empty() )
{
- LLURLSimString::setString( nextLoginLocation );
+ LLStartUp::setStartSLURL(LLSLURL(nextLoginLocation));
};
gLastRunVersion = gSavedSettings.getString("LastRunVersion");
@@ -2186,17 +2330,7 @@ void LLAppViewer::checkForCrash(void)
{
#if LL_SEND_CRASH_REPORTS
- //*NOTE:Mani The current state of the crash handler has the MacOSX
- // sending all crash reports as freezes, in order to let
- // the MacOSX CrashRepoter generate stacks before spawning the
- // SL crash logger.
- // The Linux and Windows clients generate their own stacks and
- // spawn the SL crash logger immediately. This may change in the future.
-#if LL_DARWIN
- if(gLastExecEvent != LAST_EXEC_NORMAL)
-#else
if (gLastExecEvent == LAST_EXEC_FROZE)
-#endif
{
llinfos << "Last execution froze, requesting to send crash report." << llendl;
//
@@ -2207,7 +2341,7 @@ void LLAppViewer::checkForCrash(void)
{
std::ostringstream msg;
msg << LLTrans::getString("MBFrozenCrashed");
- std::string alert = LLTrans::getString("SECOND_LIFE_VIEWER") + " " + LLTrans::getString("MBAlert");
+ std::string alert = LLTrans::getString("APP_NAME") + " " + LLTrans::getString("MBAlert");
choice = OSMessageBox(msg.str(),
alert,
OSMB_YESNO);
@@ -2244,9 +2378,6 @@ bool LLAppViewer::initWindow()
// store setting in a global for easy access and modification
gNoRender = gSavedSettings.getBOOL("DisableRendering");
- // Hide the splash screen
- LLSplashScreen::hide();
-
// always start windowed
BOOL ignorePixelDepth = gSavedSettings.getBOOL("IgnorePixelDepth");
gViewerWindow = new LLViewerWindow(gWindowTitle,
@@ -2254,17 +2385,31 @@ bool LLAppViewer::initWindow()
gSavedSettings.getS32("WindowX"), gSavedSettings.getS32("WindowY"),
gSavedSettings.getS32("WindowWidth"), gSavedSettings.getS32("WindowHeight"),
FALSE, ignorePixelDepth);
-
- if (!gSavedSettings.getBOOL("NotFullScreen"))
+
+ // Need to load feature table before cheking to start watchdog.
+ const S32 NEVER_SUBMIT_REPORT = 2;
+ bool use_watchdog = false;
+ int watchdog_enabled_setting = gSavedSettings.getS32("WatchdogEnabled");
+ if(watchdog_enabled_setting == -1){
+ use_watchdog = !LLFeatureManager::getInstance()->isFeatureAvailable("WatchdogDisabled");
+ }
+ else
{
- gViewerWindow->toggleFullscreen(FALSE);
- // request to go full screen... which will be delayed until login
+ // The user has explicitly set this setting; always use that value.
+ use_watchdog = bool(watchdog_enabled_setting);
}
-
+
+ bool send_reports = gCrashSettings.getS32(CRASH_BEHAVIOR_SETTING) != NEVER_SUBMIT_REPORT;
+ if(use_watchdog && send_reports)
+ {
+ LLWatchdog::getInstance()->init(watchdog_killer_callback);
+ }
+
+ LLNotificationsUI::LLNotificationManager::getInstance();
+
if (gSavedSettings.getBOOL("WindowMaximized"))
{
gViewerWindow->mWindow->maximize();
- gViewerWindow->getWindow()->setNativeAspectRatio(gSavedSettings.getF32("FullScreenAspectRatio"));
}
if (!gNoRender)
@@ -2324,17 +2469,10 @@ void LLAppViewer::cleanupSavedSettings()
{
gSavedSettings.setBOOL("MouseSun", FALSE);
- gSavedSettings.setBOOL("FlyBtnState", FALSE);
-
- gSavedSettings.setBOOL("FirstPersonBtnState", FALSE);
- gSavedSettings.setBOOL("ThirdPersonBtnState", TRUE);
- gSavedSettings.setBOOL("BuildBtnState", FALSE);
-
gSavedSettings.setBOOL("UseEnergy", TRUE); // force toggle to turn off, since sends message to simulator
gSavedSettings.setBOOL("DebugWindowProc", gDebugWindowProc);
- gSavedSettings.setBOOL("AllowTapTapHoldRun", gAllowTapTapHoldRun);
gSavedSettings.setBOOL("ShowObjectUpdates", gShowObjectUpdates);
if (!gNoRender)
@@ -2345,11 +2483,10 @@ void LLAppViewer::cleanupSavedSettings()
}
}
- // save window position if not fullscreen
+ // save window position if not maximized
// as we don't track it in callbacks
- BOOL fullscreen = gViewerWindow->mWindow->getFullscreen();
BOOL maximized = gViewerWindow->mWindow->getMaximized();
- if (!fullscreen && !maximized)
+ if (!maximized)
{
LLCoordScreen window_pos;
@@ -2360,13 +2497,12 @@ void LLAppViewer::cleanupSavedSettings()
}
}
- gSavedSettings.setF32("MapScale", gMapScale );
- gSavedSettings.setBOOL("ShowHoverTips", LLHoverView::sShowHoverTips);
+ gSavedSettings.setF32("MapScale", LLWorldMapView::sMapScale );
// Some things are cached in LLAgent.
- if (gAgent.mInitialized)
+ if (gAgent.isInitialized())
{
- gSavedSettings.setF32("RenderFarClip", gAgent.mDrawDistance);
+ gSavedSettings.setF32("RenderFarClip", gAgentCamera.mDrawDistance);
}
}
@@ -2381,16 +2517,16 @@ void LLAppViewer::writeSystemInfo()
gDebugInfo["SLLog"] = LLError::logFileName();
gDebugInfo["ClientInfo"]["Name"] = gSavedSettings.getString("VersionChannelName");
- gDebugInfo["ClientInfo"]["MajorVersion"] = LL_VERSION_MAJOR;
- gDebugInfo["ClientInfo"]["MinorVersion"] = LL_VERSION_MINOR;
- gDebugInfo["ClientInfo"]["PatchVersion"] = LL_VERSION_PATCH;
- gDebugInfo["ClientInfo"]["BuildVersion"] = LL_VERSION_BUILD;
+ gDebugInfo["ClientInfo"]["MajorVersion"] = LLVersionInfo::getMajor();
+ gDebugInfo["ClientInfo"]["MinorVersion"] = LLVersionInfo::getMinor();
+ gDebugInfo["ClientInfo"]["PatchVersion"] = LLVersionInfo::getPatch();
+ gDebugInfo["ClientInfo"]["BuildVersion"] = LLVersionInfo::getBuild();
gDebugInfo["CAFilename"] = gDirUtilp->getCAFile();
gDebugInfo["CPUInfo"]["CPUString"] = gSysCPU.getCPUString();
gDebugInfo["CPUInfo"]["CPUFamily"] = gSysCPU.getFamily();
- gDebugInfo["CPUInfo"]["CPUMhz"] = gSysCPU.getMhz();
+ gDebugInfo["CPUInfo"]["CPUMhz"] = (S32)gSysCPU.getMHz();
gDebugInfo["CPUInfo"]["CPUAltivec"] = gSysCPU.hasAltivec();
gDebugInfo["CPUInfo"]["CPUSSE"] = gSysCPU.hasSSE();
gDebugInfo["CPUInfo"]["CPUSSE2"] = gSysCPU.hasSSE2();
@@ -2401,9 +2537,9 @@ void LLAppViewer::writeSystemInfo()
// The user is not logged on yet, but record the current grid choice login url
// which may have been the intended grid. This can b
- gDebugInfo["GridName"] = LLViewerLogin::getInstance()->getGridLabel();
+ gDebugInfo["GridName"] = LLGridManager::getInstance()->getGridLabel();
- // *FIX:Mani - move this ddown in llappviewerwin32
+ // *FIX:Mani - move this down in llappviewerwin32
#ifdef LL_WINDOWS
DWORD thread_id = GetCurrentThreadId();
gDebugInfo["MainloopThreadID"] = (S32)thread_id;
@@ -2415,11 +2551,19 @@ void LLAppViewer::writeSystemInfo()
// If the crash is handled by LLAppViewer::handleViewerCrash, ie not a freeze,
// then the value of "CrashNotHandled" will be set to true.
gDebugInfo["CrashNotHandled"] = (LLSD::Boolean)true;
+
+ // Insert crash host url (url to post crash log to) if configured. This insures
+ // that the crash report will go to the proper location in the case of a
+ // prior freeze.
+ std::string crashHostUrl = gSavedSettings.get<std::string>("CrashHostUrl");
+ if(crashHostUrl != "")
+ {
+ gDebugInfo["CrashHostUrl"] = crashHostUrl;
+ }
// Dump some debugging info
- LL_INFOS("SystemInfo") << LLTrans::getString("SECOND_LIFE_VIEWER")
- << " version " << LL_VERSION_MAJOR << "." << LL_VERSION_MINOR << "." << LL_VERSION_PATCH
- << LL_ENDL;
+ LL_INFOS("SystemInfo") << LLTrans::getString("APP_NAME")
+ << " version " << LLVersionInfo::getShortVersion() << LL_ENDL;
// Dump the local time and time zone
time_t now;
@@ -2437,17 +2581,12 @@ void LLAppViewer::writeSystemInfo()
writeDebugInfo(); // Save out debug_info.log early, in case of crash.
}
-void LLAppViewer::handleSyncViewerCrash()
-{
- LLAppViewer* pApp = LLAppViewer::instance();
- // Call to pure virtual, handled by platform specific llappviewer instance.
- pApp->handleSyncCrashTrace();
-}
-
void LLAppViewer::handleViewerCrash()
{
llinfos << "Handle viewer crash entry." << llendl;
+ llinfos << "Last render pool type: " << LLPipeline::sCurRenderPoolType << llendl ;
+
//print out recorded call stacks if there are any.
LLError::LLCallStacks::print();
@@ -2465,18 +2604,22 @@ void LLAppViewer::handleViewerCrash()
return;
}
pApp->mReportedCrash = TRUE;
-
- // Make sure the watchdog gets turned off...
-// pApp->destroyMainloopTimeout(); // SJB: Bah. This causes the crash handler to hang, not sure why.
+
+ // Insert crash host url (url to post crash log to) if configured.
+ std::string crashHostUrl = gSavedSettings.get<std::string>("CrashHostUrl");
+ if(crashHostUrl != "")
+ {
+ gDebugInfo["CrashHostUrl"] = crashHostUrl;
+ }
//We already do this in writeSystemInfo(), but we do it again here to make /sure/ we have a version
//to check against no matter what
gDebugInfo["ClientInfo"]["Name"] = gSavedSettings.getString("VersionChannelName");
- gDebugInfo["ClientInfo"]["MajorVersion"] = LL_VERSION_MAJOR;
- gDebugInfo["ClientInfo"]["MinorVersion"] = LL_VERSION_MINOR;
- gDebugInfo["ClientInfo"]["PatchVersion"] = LL_VERSION_PATCH;
- gDebugInfo["ClientInfo"]["BuildVersion"] = LL_VERSION_BUILD;
+ gDebugInfo["ClientInfo"]["MajorVersion"] = LLVersionInfo::getMajor();
+ gDebugInfo["ClientInfo"]["MinorVersion"] = LLVersionInfo::getMinor();
+ gDebugInfo["ClientInfo"]["PatchVersion"] = LLVersionInfo::getPatch();
+ gDebugInfo["ClientInfo"]["BuildVersion"] = LLVersionInfo::getBuild();
LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
if ( parcel && parcel->getMusicURL()[0])
@@ -2499,6 +2642,12 @@ void LLAppViewer::handleViewerCrash()
gDebugInfo["FirstLogin"] = (LLSD::Boolean) gAgent.isFirstLogin();
gDebugInfo["FirstRunThisInstall"] = gSavedSettings.getBOOL("FirstRunThisInstall");
+ char *minidump_file = pApp->getMiniDumpFilename();
+ if(minidump_file && minidump_file[0] != 0)
+ {
+ gDebugInfo["MinidumpPath"] = minidump_file;
+ }
+
if(gLogoutInProgress)
{
gDebugInfo["LastExecEvent"] = LAST_EXEC_LOGOUT_CRASH;
@@ -2569,17 +2718,13 @@ void LLAppViewer::handleViewerCrash()
gMessageSystem->stopLogging();
}
- LLWorld::getInstance()->getInfo(gDebugInfo);
+ if (LLWorld::instanceExists()) LLWorld::getInstance()->getInfo(gDebugInfo);
// Close the debug file
pApp->writeDebugInfo();
LLError::logToFile("");
-// On Mac, we send the report on the next run, since we need macs crash report
-// for a stack trace, so we have to let it the app fail.
-#if !LL_DARWIN
-
// Remove the marker file, since otherwise we'll spawn a process that'll keep it locked
if(gDebugInfo["LastExecEvent"].asInteger() == LAST_EXEC_LOGOUT_CRASH)
{
@@ -2592,8 +2737,6 @@ void LLAppViewer::handleViewerCrash()
// Call to pure virtual, handled by platform specific llappviewer instance.
pApp->handleCrashReporting();
-
-#endif //!LL_DARWIN
return;
}
@@ -2687,7 +2830,7 @@ void LLAppViewer::initMarkerFile()
// Create the marker file for this execution & lock it
apr_status_t s;
- s = mMarkerFile.open(mMarkerFileName, LL_APR_W, gAPRPoolp);
+ s = mMarkerFile.open(mMarkerFileName, LL_APR_W, TRUE);
if (s == APR_SUCCESS && mMarkerFile.getFileHandle())
{
@@ -2755,6 +2898,8 @@ void LLAppViewer::requestQuit()
gFloaterView->closeAllChildren(true);
}
+ LLSideTray::getInstance()->notifyChildren(LLSD().with("request","quit"));
+
send_stats();
gLogoutTimer.reset();
@@ -2763,7 +2908,7 @@ void LLAppViewer::requestQuit()
static bool finish_quit(const LLSD& notification, const LLSD& response)
{
- S32 option = LLNotification::getSelectedOption(notification, response);
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
if (option == 0)
{
@@ -2775,7 +2920,14 @@ static LLNotificationFunctorRegistration finish_quit_reg("ConfirmQuit", finish_q
void LLAppViewer::userQuit()
{
- LLNotifications::instance().add("ConfirmQuit");
+ if (gDisconnected)
+ {
+ requestQuit();
+ }
+ else
+ {
+ LLNotificationsUtil::add("ConfirmQuit");
+ }
}
static bool finish_early_exit(const LLSD& notification, const LLSD& response)
@@ -2788,7 +2940,7 @@ void LLAppViewer::earlyExit(const std::string& name, const LLSD& substitutions)
{
llwarns << "app_early_exit: " << name << llendl;
gDoDisconnect = TRUE;
- LLNotifications::instance().add(name, substitutions, LLSD(), finish_early_exit);
+ LLNotificationsUtil::add(name, substitutions, LLSD(), finish_early_exit);
}
void LLAppViewer::forceExit(S32 arg)
@@ -2874,66 +3026,134 @@ void LLAppViewer::migrateCacheDirectory()
#endif // LL_WINDOWS || LL_DARWIN
}
-bool LLAppViewer::initCache()
+void dumpVFSCaches()
{
- mPurgeCache = false;
- // Purge cache if user requested it
- if (gSavedSettings.getBOOL("PurgeCacheOnStartup") ||
- gSavedSettings.getBOOL("PurgeCacheOnNextStartup"))
+ llinfos << "======= Static VFS ========" << llendl;
+ gStaticVFS->listFiles();
+#if LL_WINDOWS
+ llinfos << "======= Dumping static VFS to StaticVFSDump ========" << llendl;
+ WCHAR w_str[MAX_PATH];
+ GetCurrentDirectory(MAX_PATH, w_str);
+ S32 res = LLFile::mkdir("StaticVFSDump");
+ if (res == -1)
{
- gSavedSettings.setBOOL("PurgeCacheOnNextStartup", false);
- mPurgeCache = true;
+ if (errno != EEXIST)
+ {
+ llwarns << "Couldn't create dir StaticVFSDump" << llendl;
+ }
}
- // Purge cache if it belongs to an old version
- else
+ SetCurrentDirectory(utf8str_to_utf16str("StaticVFSDump").c_str());
+ gStaticVFS->dumpFiles();
+ SetCurrentDirectory(w_str);
+#endif
+
+ llinfos << "========= Dynamic VFS ====" << llendl;
+ gVFS->listFiles();
+#if LL_WINDOWS
+ llinfos << "========= Dumping dynamic VFS to VFSDump ====" << llendl;
+ res = LLFile::mkdir("VFSDump");
+ if (res == -1)
{
- static const S32 cache_version = 5;
- if (gSavedSettings.getS32("LocalCacheVersion") != cache_version)
+ if (errno != EEXIST)
{
- mPurgeCache = true;
- gSavedSettings.setS32("LocalCacheVersion", cache_version);
+ llwarns << "Couldn't create dir VFSDump" << llendl;
}
}
-
- // We have moved the location of the cache directory over time.
- migrateCacheDirectory();
+ SetCurrentDirectory(utf8str_to_utf16str("VFSDump").c_str());
+ gVFS->dumpFiles();
+ SetCurrentDirectory(w_str);
+#endif
+}
+
+//static
+U32 LLAppViewer::getTextureCacheVersion()
+{
+ //viewer texture cache version, change if the texture cache format changes.
+ const U32 TEXTURE_CACHE_VERSION = 7;
+
+ return TEXTURE_CACHE_VERSION ;
+}
+
+//static
+U32 LLAppViewer::getObjectCacheVersion()
+{
+ // Viewer object cache version, change if object update
+ // format changes. JC
+ const U32 INDRA_OBJECT_CACHE_VERSION = 14;
+
+ return INDRA_OBJECT_CACHE_VERSION;
+}
+
+bool LLAppViewer::initCache()
+{
+ mPurgeCache = false;
+ BOOL read_only = mSecondInstance ? TRUE : FALSE;
+ LLAppViewer::getTextureCache()->setReadOnly(read_only) ;
+ LLVOCache::getInstance()->setReadOnly(read_only);
- // Setup and verify the cache location
- std::string cache_location = gSavedSettings.getString("CacheLocation");
- std::string new_cache_location = gSavedSettings.getString("NewCacheLocation");
- if (new_cache_location != cache_location)
+ BOOL texture_cache_mismatch = FALSE ;
+ if (gSavedSettings.getS32("LocalCacheVersion") != LLAppViewer::getTextureCacheVersion())
{
- gDirUtilp->setCacheDir(gSavedSettings.getString("CacheLocation"));
- purgeCache(); // purge old cache
- gSavedSettings.setString("CacheLocation", new_cache_location);
+ texture_cache_mismatch = TRUE ;
+ if(!read_only)
+ {
+ gSavedSettings.setS32("LocalCacheVersion", LLAppViewer::getTextureCacheVersion());
+ }
}
+
+ if(!read_only)
+ {
+ // Purge cache if user requested it
+ if (gSavedSettings.getBOOL("PurgeCacheOnStartup") ||
+ gSavedSettings.getBOOL("PurgeCacheOnNextStartup"))
+ {
+ gSavedSettings.setBOOL("PurgeCacheOnNextStartup", false);
+ mPurgeCache = true;
+ }
+
+ // We have moved the location of the cache directory over time.
+ migrateCacheDirectory();
+ // Setup and verify the cache location
+ std::string cache_location = gSavedSettings.getString("CacheLocation");
+ std::string new_cache_location = gSavedSettings.getString("NewCacheLocation");
+ if (new_cache_location != cache_location)
+ {
+ gDirUtilp->setCacheDir(gSavedSettings.getString("CacheLocation"));
+ purgeCache(); // purge old cache
+ gSavedSettings.setString("CacheLocation", new_cache_location);
+ gSavedSettings.setString("CacheLocationTopFolder", gDirUtilp->getBaseFileName(new_cache_location));
+ }
+ }
+
if (!gDirUtilp->setCacheDir(gSavedSettings.getString("CacheLocation")))
{
LL_WARNS("AppCache") << "Unable to set cache location" << LL_ENDL;
gSavedSettings.setString("CacheLocation", "");
+ gSavedSettings.setString("CacheLocationTopFolder", "");
}
- if (mPurgeCache)
+ if (mPurgeCache && !read_only)
{
- LLSplashScreen::update("Clearing cache...");
+ LLSplashScreen::update(LLTrans::getString("StartupClearingCache"));
purgeCache();
}
- LLSplashScreen::update("Initializing Texture Cache...");
+ LLSplashScreen::update(LLTrans::getString("StartupInitializingTextureCache"));
// Init the texture cache
- // Allocate 80% of the cache size for textures
- BOOL read_only = mSecondInstance ? TRUE : FALSE;
+ // Allocate 80% of the cache size for textures
const S32 MB = 1024*1024;
S64 cache_size = (S64)(gSavedSettings.getU32("CacheSize")) * MB;
const S64 MAX_CACHE_SIZE = 1024*MB;
cache_size = llmin(cache_size, MAX_CACHE_SIZE);
S64 texture_cache_size = ((cache_size * 8)/10);
- S64 extra = LLAppViewer::getTextureCache()->initCache(LL_PATH_CACHE, texture_cache_size, read_only);
+ S64 extra = LLAppViewer::getTextureCache()->initCache(LL_PATH_CACHE, texture_cache_size, texture_cache_mismatch);
texture_cache_size -= extra;
- LLSplashScreen::update("Initializing VFS...");
+ LLVOCache::getInstance()->initCache(LL_PATH_CACHE, gSavedSettings.getU32("CacheNumberOfRegionsForObjects"), getObjectCacheVersion()) ;
+
+ LLSplashScreen::update(LLTrans::getString("StartupInitializingVFS"));
// Init the VFS
S64 vfs_size = cache_size - texture_cache_size;
@@ -3079,6 +3299,14 @@ bool LLAppViewer::initCache()
else
{
LLVFile::initClass();
+
+#ifndef LL_RELEASE_FOR_DOWNLOAD
+ if (gSavedSettings.getBOOL("DumpVFSCaches"))
+ {
+ dumpVFSCaches();
+ }
+#endif
+
return true;
}
}
@@ -3087,13 +3315,14 @@ void LLAppViewer::purgeCache()
{
LL_INFOS("AppCache") << "Purging Cache and Texture Cache..." << llendl;
LLAppViewer::getTextureCache()->purgeCache(LL_PATH_CACHE);
+ LLVOCache::getInstance()->removeCache(LL_PATH_CACHE);
std::string mask = gDirUtilp->getDirDelimiter() + "*.*";
gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""),mask);
}
std::string LLAppViewer::getSecondLifeTitle() const
{
- return LLTrans::getString("SECOND_LIFE_VIEWER");
+ return LLTrans::getString("APP_NAME");
}
std::string LLAppViewer::getWindowTitle() const
@@ -3104,7 +3333,7 @@ std::string LLAppViewer::getWindowTitle() const
// Callback from a dialog indicating user was logged out.
bool finish_disconnect(const LLSD& notification, const LLSD& response)
{
- S32 option = LLNotification::getSelectedOption(notification, response);
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
if (1 == option)
{
@@ -3144,12 +3373,12 @@ void LLAppViewer::forceDisconnect(const std::string& mesg)
{
// Tell users what happened
args["ERROR_MESSAGE"] = big_reason;
- LLNotifications::instance().add("ErrorMessage", args, LLSD(), &finish_forced_disconnect);
+ LLNotificationsUtil::add("ErrorMessage", args, LLSD(), &finish_forced_disconnect);
}
else
{
args["MESSAGE"] = big_reason;
- LLNotifications::instance().add("YouHaveBeenLoggedOut", args, LLSD(), &finish_disconnect );
+ LLNotificationsUtil::add("YouHaveBeenLoggedOut", args, LLSD(), &finish_disconnect );
}
}
@@ -3163,13 +3392,6 @@ void LLAppViewer::badNetworkHandler()
mPurgeOnExit = TRUE;
-#if LL_WINDOWS
- // Generates the minidump.
- LLWinDebug::generateCrashStacks(NULL);
-#endif
- LLAppViewer::handleSyncViewerCrash();
- LLAppViewer::handleViewerCrash();
-
std::ostringstream message;
message <<
"The viewer has detected mangled network data indicative\n"
@@ -3182,6 +3404,8 @@ void LLAppViewer::badNetworkHandler()
"If the problem continues, see the Tech Support FAQ at: \n"
"www.secondlife.com/support";
forceDisconnect(message.str());
+
+ LLApp::instance()->writeMiniDump();
}
// This routine may get called more than once during the shutdown process.
@@ -3191,10 +3415,10 @@ void LLAppViewer::saveFinalSnapshot()
{
if (!mSavedFinalSnapshot && !gNoRender)
{
- gSavedSettings.setVector3d("FocusPosOnLogout", gAgent.calcFocusPositionTargetGlobal());
- gSavedSettings.setVector3d("CameraPosOnLogout", gAgent.calcCameraPositionTargetGlobal());
+ gSavedSettings.setVector3d("FocusPosOnLogout", gAgentCamera.calcFocusPositionTargetGlobal());
+ gSavedSettings.setVector3d("CameraPosOnLogout", gAgentCamera.calcCameraPositionTargetGlobal());
gViewerWindow->setCursor(UI_CURSOR_WAIT);
- gAgent.changeCameraToThirdPerson( FALSE ); // don't animate, need immediate switch
+ gAgentCamera.changeCameraToThirdPerson( FALSE ); // don't animate, need immediate switch
gSavedSettings.setBOOL("ShowParcelOwners", FALSE);
idle();
@@ -3202,7 +3426,7 @@ void LLAppViewer::saveFinalSnapshot()
snap_filename += gDirUtilp->getDirDelimiter();
snap_filename += SCREEN_LAST_FILENAME;
// use full pixel dimensions of viewer window (not post-scale dimensions)
- gViewerWindow->saveSnapshot(snap_filename, gViewerWindow->getWindowDisplayWidth(), gViewerWindow->getWindowDisplayHeight(), FALSE, TRUE);
+ gViewerWindow->saveSnapshot(snap_filename, gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw(), FALSE, TRUE);
mSavedFinalSnapshot = TRUE;
}
}
@@ -3258,6 +3482,15 @@ public:
}
};
+static LLFastTimer::DeclareTimer FTM_AUDIO_UPDATE("Update Audio");
+static LLFastTimer::DeclareTimer FTM_CLEANUP("Cleanup");
+static LLFastTimer::DeclareTimer FTM_IDLE_CB("Idle Callbacks");
+static LLFastTimer::DeclareTimer FTM_LOD_UPDATE("Update LOD");
+static LLFastTimer::DeclareTimer FTM_OBJECTLIST_UPDATE("Update Objectlist");
+static LLFastTimer::DeclareTimer FTM_REGION_UPDATE("Update Region");
+static LLFastTimer::DeclareTimer FTM_WORLD_UPDATE("Update World");
+static LLFastTimer::DeclareTimer FTM_NETWORK("Network");
+
///////////////////////////////////////////////////////
// idle()
//
@@ -3313,10 +3546,13 @@ void LLAppViewer::idle()
if (LLStartUp::getStartupState() < STATE_STARTED)
{
// Skip rest if idle startup returns false (essentially, no world yet)
+ gGLActive = TRUE;
if (!idle_startup())
{
+ gGLActive = FALSE;
return;
}
+ gGLActive = FALSE;
}
@@ -3324,7 +3560,7 @@ void LLAppViewer::idle()
if (!gDisconnected)
{
- LLFastTimer t(LLFastTimer::FTM_NETWORK);
+ LLFastTimer t(FTM_NETWORK);
// Update spaceserver timeinfo
LLWorld::getInstance()->setSpaceTimeUSec(LLWorld::getInstance()->getSpaceTimeUSec() + (U32)(dt_raw * SEC_TO_MICROSEC));
@@ -3339,9 +3575,12 @@ void LLAppViewer::idle()
gAgent.moveYaw(-1.f);
}
- // Handle automatic walking towards points
- gAgentPilot.updateTarget();
- gAgent.autoPilot(&yaw);
+ {
+ LLFastTimer t(FTM_AGENT_AUTOPILOT);
+ // Handle automatic walking towards points
+ gAgentPilot.updateTarget();
+ gAgent.autoPilot(&yaw);
+ }
static LLFrameTimer agent_update_timer;
static U32 last_control_flags;
@@ -3352,6 +3591,7 @@ void LLAppViewer::idle()
if (flags_changed || (agent_update_time > (1.0f / (F32) AGENT_UPDATES_PER_SECOND)))
{
+ LLFastTimer t(FTM_AGENT_UPDATE);
// Send avatar and camera info
last_control_flags = gAgent.getControlFlags();
send_agent_update(TRUE);
@@ -3405,7 +3645,7 @@ void LLAppViewer::idle()
if (!gDisconnected)
{
- LLFastTimer t(LLFastTimer::FTM_NETWORK);
+ LLFastTimer t(FTM_NETWORK);
////////////////////////////////////////////////
//
@@ -3415,10 +3655,8 @@ void LLAppViewer::idle()
// floating throughout the various object lists.
//
- stop_glerror();
idleNetwork();
- stop_glerror();
-
+
// Check for away from keyboard, kick idle agents.
idle_afk_check();
@@ -3434,12 +3672,13 @@ void LLAppViewer::idle()
//
{
-// LLFastTimer t(LLFastTimer::FTM_IDLE_CB);
+// LLFastTimer t(FTM_IDLE_CB);
// Do event notifications if necessary. Yes, we may want to move this elsewhere.
gEventNotifier.update();
gIdleCallbacks.callFunctions();
+ gInventory.idleNotifyObservers();
}
if (gDisconnected)
@@ -3463,13 +3702,15 @@ void LLAppViewer::idle()
{
// Handle pending gesture processing
- gGestureManager.update();
+ static LLFastTimer::DeclareTimer ftm("Agent Position");
+ LLFastTimer t(ftm);
+ LLGestureMgr::instance().update();
gAgent.updateAgentPosition(gFrameDTClamped, yaw, current_mouse.mX, current_mouse.mY);
}
{
- LLFastTimer t(LLFastTimer::FTM_OBJECTLIST_UPDATE); // Actually "object update"
+ LLFastTimer t(FTM_OBJECTLIST_UPDATE);
if (!(logoutRequestSent() && hasSavedFinalSnapshot()))
{
@@ -3484,7 +3725,7 @@ void LLAppViewer::idle()
//
{
- LLFastTimer t(LLFastTimer::FTM_CLEANUP);
+ LLFastTimer t(FTM_CLEANUP);
gObjectList.cleanDeadObjects();
LLDrawable::cleanupDeadDrawables();
}
@@ -3503,20 +3744,20 @@ void LLAppViewer::idle()
//
{
+ static LLFastTimer::DeclareTimer ftm("HUD Effects");
+ LLFastTimer t(ftm);
LLSelectMgr::getInstance()->updateEffects();
LLHUDManager::getInstance()->cleanupEffects();
LLHUDManager::getInstance()->sendEffects();
}
- stop_glerror();
-
////////////////////////////////////////
//
// Unpack layer data that we've received
//
{
- LLFastTimer t(LLFastTimer::FTM_NETWORK);
+ LLFastTimer t(FTM_NETWORK);
gVLManager.unpackData();
}
@@ -3528,7 +3769,7 @@ void LLAppViewer::idle()
LLWorld::getInstance()->updateVisibilities();
{
const F32 max_region_update_time = .001f; // 1ms
- LLFastTimer t(LLFastTimer::FTM_REGION_UPDATE);
+ LLFastTimer t(FTM_REGION_UPDATE);
LLWorld::getInstance()->updateRegions(max_region_update_time);
}
@@ -3565,7 +3806,6 @@ void LLAppViewer::idle()
gWindVec.setVec(0.0f, 0.0f, 0.0f);
}
}
- stop_glerror();
//////////////////////////////////////
//
@@ -3575,12 +3815,11 @@ void LLAppViewer::idle()
if (!gNoRender)
{
- LLFastTimer t(LLFastTimer::FTM_WORLD_UPDATE);
+ LLFastTimer t(FTM_WORLD_UPDATE);
gPipeline.updateMove();
LLWorld::getInstance()->updateParticles();
}
- stop_glerror();
if (LLViewerJoystick::getInstance()->getOverrideCamera())
{
@@ -3593,17 +3832,20 @@ void LLAppViewer::idle()
LLViewerJoystick::getInstance()->moveObjects();
}
- gAgent.updateCamera();
+ gAgentCamera.updateCamera();
}
+ // update media focus
+ LLViewerMediaFocus::getInstance()->update();
+
// objects and camera should be in sync, do LOD calculations now
{
- LLFastTimer t(LLFastTimer::FTM_LOD_UPDATE);
+ LLFastTimer t(FTM_LOD_UPDATE);
gObjectList.updateApparentAngles(gAgent);
}
{
- LLFastTimer t(LLFastTimer::FTM_AUDIO_UPDATE);
+ LLFastTimer t(FTM_AUDIO_UPDATE);
if (gAudiop)
{
@@ -3622,10 +3864,9 @@ void LLAppViewer::idle()
// forcibly quit if it has taken too long
if (mQuitRequested)
{
+ gGLActive = TRUE;
idleShutdown();
}
-
- stop_glerror();
}
void LLAppViewer::idleShutdown()
@@ -3649,6 +3890,24 @@ void LLAppViewer::idleShutdown()
return;
}
+ if (LLSideTray::getInstance()->notifyChildren(LLSD().with("request","wait_quit")))
+ {
+ return;
+ }
+
+
+
+ // ProductEngine: Try moving this code to where we shut down sTextureCache in cleanup()
+ // *TODO: ugly
+ static bool saved_teleport_history = false;
+ if (!saved_teleport_history)
+ {
+ saved_teleport_history = true;
+ LLTeleportHistory::getInstance()->dump();
+ LLLocationHistory::getInstance()->save(); // *TODO: find a better place for doing this
+ return;
+ }
+
static bool saved_snapshot = false;
if (!saved_snapshot)
{
@@ -3671,7 +3930,7 @@ void LLAppViewer::idleShutdown()
S32 finished_uploads = total_uploads - pending_uploads;
F32 percent = 100.f * finished_uploads / total_uploads;
gViewerWindow->setProgressPercent(percent);
- gViewerWindow->setProgressString("Saving your settings...");
+ gViewerWindow->setProgressString(LLTrans::getString("SavingSettings"));
return;
}
@@ -3683,7 +3942,7 @@ void LLAppViewer::idleShutdown()
// Wait for a LogoutReply message
gViewerWindow->setShowProgress(TRUE);
gViewerWindow->setProgressPercent(100.f);
- gViewerWindow->setProgressString("Logging out...");
+ gViewerWindow->setProgressString(LLTrans::getString("LoggingOut"));
return;
}
@@ -3711,7 +3970,7 @@ void LLAppViewer::sendLogoutRequest()
gLogoutMaxTime = LOGOUT_REQUEST_TIME;
mLogoutRequestSent = TRUE;
- gVoiceClient->leaveChannel();
+ LLVoiceClient::getInstance()->leaveChannel();
//Set internal status variables and marker files
gLogoutInProgress = TRUE;
@@ -3743,26 +4002,24 @@ void LLAppViewer::sendLogoutRequest()
static F32 CheckMessagesMaxTime = CHECK_MESSAGES_DEFAULT_MAX_TIME;
#endif
+static LLFastTimer::DeclareTimer FTM_IDLE_NETWORK("Idle Network");
+
void LLAppViewer::idleNetwork()
{
LLMemType mt_in(LLMemType::MTYPE_IDLE_NETWORK);
pingMainloopTimeout("idleNetwork");
- LLError::LLCallStacks::clear() ;
- llpushcallstacks ;
-
+
gObjectList.mNumNewObjects = 0;
S32 total_decoded = 0;
if (!gSavedSettings.getBOOL("SpeedTest"))
{
- LLFastTimer t(LLFastTimer::FTM_IDLE_NETWORK); // decode
+ LLFastTimer t(FTM_IDLE_NETWORK); // decode
// deal with any queued name requests and replies.
gCacheName->processPending();
- llpushcallstacks ;
LLTimer check_message_timer;
// Read all available packets from network
- stop_glerror();
const S64 frame_count = gFrameCount; // U32->S64
F32 total_time = 0.0f;
@@ -3775,8 +4032,7 @@ void LLAppViewer::idleNetwork()
// server going down, so this is OK.
break;
}
- stop_glerror();
-
+
total_decoded++;
gPacketsIn++;
@@ -3816,9 +4072,7 @@ void LLAppViewer::idleNetwork()
// we want to clear the control after sending out all necessary agent updates
gAgent.resetControlFlags();
- stop_glerror();
-
-
+
// Decode enqueued messages...
S32 remaining_possible_decodes = MESSAGE_MAX_PER_FRAME - total_decoded;
@@ -3833,16 +4087,13 @@ void LLAppViewer::idleNetwork()
gPrintMessagesThisFrame = FALSE;
}
}
- llpushcallstacks ;
LLViewerStats::getInstance()->mNumNewObjectsStat.addValue(gObjectList.mNumNewObjects);
// Retransmit unacknowledged packets.
gXferManager->retransmitUnackedPackets();
gAssetStorage->checkForTimeouts();
- llpushcallstacks ;
gViewerThrottle.updateDynamicThrottle();
- llpushcallstacks ;
// Check that the circuit between the viewer and the agent's current
// region is still alive
LLViewerRegion *agent_region = gAgent.getRegion();
@@ -3858,7 +4109,6 @@ void LLAppViewer::idleNetwork()
mAgentRegionLastID = this_region_id;
mAgentRegionLastAlive = this_region_alive;
}
- llpushcallstacks ;
}
void LLAppViewer::disconnectViewer()
@@ -3893,23 +4143,23 @@ void LLAppViewer::disconnectViewer()
LLSelectMgr::getInstance()->deselectAll();
}
- if (!gNoRender)
+ // save inventory if appropriate
+ gInventory.cache(gInventory.getRootFolderID(), gAgent.getID());
+ if (gInventory.getLibraryRootFolderID().notNull()
+ && gInventory.getLibraryOwnerID().notNull())
{
- // save inventory if appropriate
- gInventory.cache(gAgent.getInventoryRootID(), gAgent.getID());
- if(gInventoryLibraryRoot.notNull() && gInventoryLibraryOwner.notNull())
- {
- gInventory.cache(gInventoryLibraryRoot, gInventoryLibraryOwner);
- }
+ gInventory.cache(
+ gInventory.getLibraryRootFolderID(),
+ gInventory.getLibraryOwnerID());
}
saveNameCache();
// close inventory interface, close all windows
- LLInventoryView::cleanup();
+ LLFloaterInventory::cleanup();
gAgentWearables.cleanup();
-
+ gAgentCamera.cleanup();
// Also writes cached agent settings to gSavedSettings
gAgent.cleanup();
@@ -3940,11 +4190,11 @@ void LLAppViewer::forceErrorBreakpoint()
void LLAppViewer::forceErrorBadMemoryAccess()
{
S32* crash = NULL;
- *crash = 0xDEADBEEF;
+ *crash = 0xDEADBEEF;
return;
}
-void LLAppViewer::forceErrorInifiniteLoop()
+void LLAppViewer::forceErrorInfiniteLoop()
{
while(true)
{
@@ -4025,17 +4275,15 @@ void LLAppViewer::pingMainloopTimeout(const std::string& state, F32 secs)
void LLAppViewer::handleLoginComplete()
{
- gViewerWindow->handleLoginComplete();
-
initMainloopTimeout("Mainloop Init");
// Store some data to DebugInfo in case of a freeze.
gDebugInfo["ClientInfo"]["Name"] = gSavedSettings.getString("VersionChannelName");
- gDebugInfo["ClientInfo"]["MajorVersion"] = LL_VERSION_MAJOR;
- gDebugInfo["ClientInfo"]["MinorVersion"] = LL_VERSION_MINOR;
- gDebugInfo["ClientInfo"]["PatchVersion"] = LL_VERSION_PATCH;
- gDebugInfo["ClientInfo"]["BuildVersion"] = LL_VERSION_BUILD;
+ gDebugInfo["ClientInfo"]["MajorVersion"] = LLVersionInfo::getMajor();
+ gDebugInfo["ClientInfo"]["MinorVersion"] = LLVersionInfo::getMinor();
+ gDebugInfo["ClientInfo"]["PatchVersion"] = LLVersionInfo::getPatch();
+ gDebugInfo["ClientInfo"]["BuildVersion"] = LLVersionInfo::getBuild();
LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
if ( parcel && parcel->getMusicURL()[0])
@@ -4062,5 +4310,215 @@ void LLAppViewer::handleLoginComplete()
{
gDebugInfo["MainloopTimeoutState"] = LLAppViewer::instance()->mMainloopTimeout->getState();
}
+
+ mOnLoginCompleted();
+
writeDebugInfo();
}
+
+// *TODO - generalize this and move DSO wrangling to a helper class -brad
+void LLAppViewer::loadEventHostModule(S32 listen_port)
+{
+ std::string dso_name =
+#if LL_WINDOWS
+ "lleventhost.dll";
+#elif LL_DARWIN
+ "liblleventhost.dylib";
+#else
+ "liblleventhost.so";
+#endif
+
+ std::string dso_path = gDirUtilp->findFile(dso_name,
+ gDirUtilp->getAppRODataDir(),
+ gDirUtilp->getExecutableDir());
+
+ if(dso_path == "")
+ {
+ llerrs << "QAModeEventHost requested but module \"" << dso_name << "\" not found!" << llendl;
+ return;
+ }
+
+ apr_dso_handle_t * eventhost_dso_handle = NULL;
+ apr_pool_t * eventhost_dso_memory_pool = NULL;
+
+ //attempt to load the shared library
+ apr_pool_create(&eventhost_dso_memory_pool, NULL);
+ apr_status_t rv = apr_dso_load(&eventhost_dso_handle,
+ dso_path.c_str(),
+ eventhost_dso_memory_pool);
+ ll_apr_assert_status(rv);
+ llassert_always(eventhost_dso_handle != NULL);
+
+ int (*ll_plugin_start_func)(LLSD const &) = NULL;
+ rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll_plugin_start_func, eventhost_dso_handle, "ll_plugin_start");
+
+ ll_apr_assert_status(rv);
+ llassert_always(ll_plugin_start_func != NULL);
+
+ LLSD args;
+ args["listen_port"] = listen_port;
+
+ int status = ll_plugin_start_func(args);
+
+ if(status != 0)
+ {
+ llerrs << "problem loading eventhost plugin, status: " << status << llendl;
+ }
+
+ mPlugins.insert(eventhost_dso_handle);
+}
+
+void LLAppViewer::launchUpdater()
+{
+ LLSD query_map = LLSD::emptyMap();
+ // *TODO place os string in a global constant
+#if LL_WINDOWS
+ query_map["os"] = "win";
+#elif LL_DARWIN
+ query_map["os"] = "mac";
+#elif LL_LINUX
+ query_map["os"] = "lnx";
+#elif LL_SOLARIS
+ query_map["os"] = "sol";
+#endif
+ // *TODO change userserver to be grid on both viewer and sim, since
+ // userserver no longer exists.
+ query_map["userserver"] = LLGridManager::getInstance()->getGridLabel();
+ query_map["channel"] = gSavedSettings.getString("VersionChannelName");
+ // *TODO constantize this guy
+ // *NOTE: This URL is also used in win_setup/lldownloader.cpp
+ LLURI update_url = LLURI::buildHTTP("secondlife.com", 80, "update.php", query_map);
+
+ if(LLAppViewer::sUpdaterInfo)
+ {
+ delete LLAppViewer::sUpdaterInfo;
+ }
+ LLAppViewer::sUpdaterInfo = new LLAppViewer::LLUpdaterInfo() ;
+
+ // if a sim name was passed in via command line parameter (typically through a SLURL)
+ if ( LLStartUp::getStartSLURL().getType() == LLSLURL::LOCATION )
+ {
+ // record the location to start at next time
+ gSavedSettings.setString( "NextLoginLocation", LLStartUp::getStartSLURL().getSLURLString());
+ };
+
+#if LL_WINDOWS
+ LLAppViewer::sUpdaterInfo->mUpdateExePath = gDirUtilp->getTempFilename();
+ if (LLAppViewer::sUpdaterInfo->mUpdateExePath.empty())
+ {
+ delete LLAppViewer::sUpdaterInfo ;
+ LLAppViewer::sUpdaterInfo = NULL ;
+
+ // We're hosed, bail
+ LL_WARNS("AppInit") << "LLDir::getTempFilename() failed" << LL_ENDL;
+ return;
+ }
+
+ LLAppViewer::sUpdaterInfo->mUpdateExePath += ".exe";
+
+ std::string updater_source = gDirUtilp->getAppRODataDir();
+ updater_source += gDirUtilp->getDirDelimiter();
+ updater_source += "updater.exe";
+
+ LL_DEBUGS("AppInit") << "Calling CopyFile source: " << updater_source
+ << " dest: " << LLAppViewer::sUpdaterInfo->mUpdateExePath
+ << LL_ENDL;
+
+
+ if (!CopyFileA(updater_source.c_str(), LLAppViewer::sUpdaterInfo->mUpdateExePath.c_str(), FALSE))
+ {
+ delete LLAppViewer::sUpdaterInfo ;
+ LLAppViewer::sUpdaterInfo = NULL ;
+
+ LL_WARNS("AppInit") << "Unable to copy the updater!" << LL_ENDL;
+
+ return;
+ }
+
+ LLAppViewer::sUpdaterInfo->mParams << "-url \"" << update_url.asString() << "\"";
+
+ LL_DEBUGS("AppInit") << "Calling updater: " << LLAppViewer::sUpdaterInfo->mUpdateExePath << " " << LLAppViewer::sUpdaterInfo->mParams.str() << LL_ENDL;
+
+ //Explicitly remove the marker file, otherwise we pass the lock onto the child process and things get weird.
+ LLAppViewer::instance()->removeMarkerFile(); // In case updater fails
+
+ // *NOTE:Mani The updater is spawned as the last thing before the WinMain exit.
+ // see LLAppViewerWin32.cpp
+
+#elif LL_DARWIN
+ LLAppViewer::sUpdaterInfo->mUpdateExePath = "'";
+ LLAppViewer::sUpdaterInfo->mUpdateExePath += gDirUtilp->getAppRODataDir();
+ LLAppViewer::sUpdaterInfo->mUpdateExePath += "/mac-updater.app/Contents/MacOS/mac-updater' -url \"";
+ LLAppViewer::sUpdaterInfo->mUpdateExePath += update_url.asString();
+ LLAppViewer::sUpdaterInfo->mUpdateExePath += "\" -name \"";
+ LLAppViewer::sUpdaterInfo->mUpdateExePath += LLAppViewer::instance()->getSecondLifeTitle();
+ LLAppViewer::sUpdaterInfo->mUpdateExePath += "\" &";
+
+ LL_DEBUGS("AppInit") << "Calling updater: " << LLAppViewer::sUpdaterInfo->mUpdateExePath << LL_ENDL;
+
+ // Run the auto-updater.
+ system(LLAppViewer::sUpdaterInfo->mUpdateExePath.c_str()); /* Flawfinder: ignore */
+
+#elif (LL_LINUX || LL_SOLARIS) && LL_GTK
+ // we tell the updater where to find the xml containing string
+ // translations which it can use for its own UI
+ std::string xml_strings_file = "strings.xml";
+ std::vector<std::string> xui_path_vec = LLUI::getXUIPaths();
+ std::string xml_search_paths;
+ std::vector<std::string>::const_iterator iter;
+ // build comma-delimited list of xml paths to pass to updater
+ for (iter = xui_path_vec.begin(); iter != xui_path_vec.end(); )
+ {
+ std::string this_skin_dir = gDirUtilp->getDefaultSkinDir()
+ + gDirUtilp->getDirDelimiter()
+ + (*iter);
+ llinfos << "Got a XUI path: " << this_skin_dir << llendl;
+ xml_search_paths.append(this_skin_dir);
+ ++iter;
+ if (iter != xui_path_vec.end())
+ xml_search_paths.append(","); // comma-delimit
+ }
+ // build the overall command-line to run the updater correctly
+ LLAppViewer::sUpdaterInfo->mUpdateExePath =
+ gDirUtilp->getExecutableDir() + "/" + "linux-updater.bin" +
+ " --url \"" + update_url.asString() + "\"" +
+ " --name \"" + LLAppViewer::instance()->getSecondLifeTitle() + "\"" +
+ " --dest \"" + gDirUtilp->getAppRODataDir() + "\"" +
+ " --stringsdir \"" + xml_search_paths + "\"" +
+ " --stringsfile \"" + xml_strings_file + "\"";
+
+ LL_INFOS("AppInit") << "Calling updater: "
+ << LLAppViewer::sUpdaterInfo->mUpdateExePath << LL_ENDL;
+
+ // *TODO: we could use the gdk equivalent to ensure the updater
+ // gets started on the same screen.
+ GError *error = NULL;
+ if (!g_spawn_command_line_async(LLAppViewer::sUpdaterInfo->mUpdateExePath.c_str(), &error))
+ {
+ llerrs << "Failed to launch updater: "
+ << error->message
+ << llendl;
+ }
+ if (error) {
+ g_error_free(error);
+ }
+#else
+ OSMessageBox(LLTrans::getString("MBNoAutoUpdate"), LLStringUtil::null, OSMB_OK);
+#endif
+
+ // *REMOVE:Mani - Saving for reference...
+ // LLAppViewer::instance()->forceQuit();
+}
+
+
+//virtual
+void LLAppViewer::setMasterSystemAudioMute(bool mute)
+{
+ gSavedSettings.setBOOL("MuteAudio", mute);
+}
+
+//virtual
+bool LLAppViewer::getMasterSystemAudioMute()
+{
+ return gSavedSettings.getBOOL("MuteAudio");
+}