Newer
Older
Steven Bennetts
committed
/**
* @file llappviewer.cpp
* @brief The LLAppViewer class definitions
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
Steven Bennetts
committed
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
Steven Bennetts
committed
*
* 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.
Steven Bennetts
committed
*
* 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
Steven Bennetts
committed
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
Steven Bennetts
committed
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
Steven Bennetts
committed
#include "llappviewer.h"
// Viewer includes
Steven Bennetts
committed
#include "llfeaturemanager.h"
#include "lluictrlfactory.h"
#include "lltexteditor.h"
Steven Bennetts
committed
#include "llerrorcontrol.h"
Tofu Linden
committed
#include "lleventtimer.h"
Steven Bennetts
committed
#include "llgroupmgr.h"
#include "llagent.h"
#include "llagentcamera.h"
Vadim Savchuk
committed
#include "llagentlanguage.h"
#include "llagentwearables.h"
Steven Bennetts
committed
#include "llwindow.h"
#include "llviewerstats.h"
#include "llmd5.h"
#include "llpumpio.h"
#include "llslurl.h"
Steven Bennetts
committed
#include "llstartup.h"
#include "llfocusmgr.h"
#include "llviewerjoystick.h"
#include "llallocator.h"
Steven Bennetts
committed
#include "llcurl.h"
#include "lltexturestats.h"
#include "lltexturestats.h"
Steven Bennetts
committed
#include "llviewerwindow.h"
#include "llviewerdisplay.h"
#include "llviewerparcelmedia.h"
#include "llviewermediafocus.h"
Steven Bennetts
committed
#include "llviewermessage.h"
#include "llviewerobjectlist.h"
#include "llworldmap.h"
#include "llmutelist.h"
#include "llviewerhelp.h"
#include "lluicolortable.h"
#include "llurldispatcher.h"
//#include "llfirstuse.h"
#include "llrender.h"
#include "llteleporthistory.h"
#include "lllocationhistory.h"
#include "llfasttimerview.h"
#include "llvoicechannel.h"
Yuri Chebotarev
committed
#include "llsidetray.h"
Andrew A. de Laix
committed
#include "llfeaturemanager.h"
Yuri Chebotarev
committed
#include "llurlmatch.h"
#include "lltextutil.h"
Steven Bennetts
committed
#include "llweb.h"
#include "llsecondlifeurls.h"
// Linden library includes
brad kittenbrink
committed
#include "llimagej2c.h"
#include "llmemory.h"
#include "llprimitive.h"
#include "llurlaction.h"
brad kittenbrink
committed
#include "llvfile.h"
#include "llvfsthread.h"
#include "llvolumemgr.h"
brad kittenbrink
committed
#include "llxfermanager.h"
Alexei Arabadji
committed
#include "llnotificationmanager.h"
#include "llnotifications.h"
#include "llnotificationsutil.h"
Alexei Arabadji
committed
// Third party library includes
#include <boost/bind.hpp>
Steven Bennetts
committed
#if LL_WINDOWS
# include <share.h> // For _SH_DENYWR in initMarkerFile
#else
# include <sys/file.h> // For initMarkerFile support
#endif
#include "llapr.h"
#include "apr_dso.h"
#include <boost/lexical_cast.hpp>
Steven Bennetts
committed
#include "llviewerkeyboard.h"
#include "lllfsthread.h"
#include "llworkerthread.h"
#include "lltexturecache.h"
#include "lltexturefetch.h"
#include "llimageworker.h"
Steven Bennetts
committed
// The files below handle dependencies from cleanup.
#include "llkeyframemotion.h"
#include "llworldmap.h"
#include "llhudmanager.h"
#include "lltoolmgr.h"
#include "llassetstorage.h"
#include "llpolymesh.h"
#include "llcachename.h"
#include "llaudioengine.h"
#include "llstreamingaudio.h"
Steven Bennetts
committed
#include "llviewermenu.h"
#include "llselectmgr.h"
James Cook
committed
#include "lltrans.h"
Adam Moss
committed
#include "lltransutil.h"
Steven Bennetts
committed
#include "lltracker.h"
#include "llviewerparcelmgr.h"
#include "llworldmapview.h"
#include "llpostprocess.h"
#include "llwlparammanager.h"
#include "llwaterparammanager.h"
Steven Bennetts
committed
#include "lldebugview.h"
#include "llconsole.h"
#include "llcontainerview.h"
Richard Nelson
committed
#include "lltooltip.h"
Steven Bennetts
committed
Kyle Machulis
committed
#include "llsdserialize.h"
Steven Bennetts
committed
#include "llworld.h"
#include "llhudeffecttrail.h"
#include "llvectorperfoptions.h"
#include "llwatchdog.h"
Steven Bennetts
committed
// Included so that constants/settings might be initialized
// in save_settings_to_globals()
#include "llbutton.h"
#include "llcombobox.h"
#include "llstatusbar.h"
#include "llsurface.h"
#include "llvosky.h"
#include "llvotree.h"
#include "llvoavatar.h"
#include "llfolderview.h"
#include "llagentpilot.h"
#include "llvovolume.h"
#include "llflexibleobject.h"
#include "llvosurfacepatch.h"
#include "llviewerfloaterreg.h"
#include "llcommandlineparser.h"
#include "llfloatermemleak.h"
James Cook
committed
#include "llfloaterreg.h"
#include "llfloatersnapshot.h"
James Cook
committed
#include "llfloaterinventory.h"
Steven Bennetts
committed
// includes for idle() idleShutdown()
#include "llviewercontrol.h"
#include "lleventnotifier.h"
#include "llcallbacklist.h"
#include "pipeline.h"
#include "llgesturemgr.h"
#include "llsky.h"
#include "llvlmanager.h"
#include "llviewercamera.h"
#include "lldrawpoolbump.h"
#include "llvieweraudio.h"
#include "llimview.h"
#include "llviewerthrottle.h"
Steven Bennetts
committed
#include "llavatariconctrl.h"
Yuri Chebotarev
committed
#include "llgroupiconctrl.h"
// Include for security api initialization
#include "llsecapi.h"
Steven Bennetts
committed
// *FIX: These extern globals should be cleaned up.
// The globals either represent state/config/resource-storage of either
// this app, or another 'component' of the viewer. App globals should be
// moved into the app class, where as the other globals should be
// moved out of here.
// If a global symbol reference seems valid, it will be included
// via header files above.
//----------------------------------------------------------------------------
// llviewernetwork.h
#include "llviewernetwork.h"
// define a self-registering event API object
#include "llappviewerlistener.h"
Steven Bennetts
committed
#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
Steven Bennetts
committed
static LLAppViewerListener sAppViewerListener(LLAppViewer::instance);
////// Windows-specific includes to the bottom - nasty defines in these pollute the preprocessor
//
Steven Bennetts
committed
//----------------------------------------------------------------------------
// viewer.cpp - these are only used in viewer, should be easily moved.
#if LL_DARWIN
extern void init_apple_menu(const char* product);
#endif // LL_DARWIN
extern BOOL gRandomizeFramerate;
extern BOOL gPeriodicSlowFrame;
Steven Bennetts
committed
////////////////////////////////////////////////////////////
// All from the last globals push...
const F32 DEFAULT_AFK_TIMEOUT = 5.f * 60.f; // time with no input before user flagged as Away From Keyboard
F32 gSimLastTime; // Used in LLAppViewer::init and send_stats()
F32 gSimFrames;
BOOL gShowObjectUpdates = FALSE;
Steven Bennetts
committed
eLastExecEvent gLastExecEvent = LAST_EXEC_NORMAL;
Steven Bennetts
committed
Kyle Machulis
committed
LLSD gDebugInfo;
Steven Bennetts
committed
U32 gFrameCount = 0;
U32 gForegroundFrameCount = 0; // number of frames that app window was in foreground
LLPumpIO* gServicePump = NULL;
Steven Bennetts
committed
U64 gFrameTime = 0;
F32 gFrameTimeSeconds = 0.f;
F32 gFrameIntervalSeconds = 0.f;
F32 gFPSClamped = 10.f; // Pretend we start at target rate.
F32 gFrameDTClamped = 0.f; // Time between adjacent checks to network for packets
Steven Bennetts
committed
U64 gStartTime = 0; // gStartTime is "private", used only to calculate gFrameTimeSeconds
const F64 FRAME_STALL_THRESHOLD = 1.0;
Steven Bennetts
committed
LLTimer gRenderStartTime;
LLFrameTimer gForegroundTime;
LLFrameTimer gLoggedInTime;
LLTimer gLogoutTimer;
static const F32 LOGOUT_REQUEST_TIME = 6.f; // this will be cut short by the LogoutReply msg.
F32 gLogoutMaxTime = LOGOUT_REQUEST_TIME;
Steven Bennetts
committed
BOOL gDisconnected = FALSE;
// used to restore texture state after a mode switch
LLFrameTimer gRestoreGLTimer;
BOOL gRestoreGL = FALSE;
BOOL gUseWireframe = FALSE;
// VFS globals - see llappviewer.h
LLVFS* gStaticVFS = NULL;
LLMemoryInfo gSysMemory;
U64 gMemoryAllocated = 0; // updated in display_stats() in llviewerdisplay.cpp
Steven Bennetts
committed
std::string gLastVersionChannel;
Steven Bennetts
committed
LLVector3 gWindVec(3.0, 3.0, 0.0);
LLVector3 gRelativeWindVec(0.0, 0.0, 0.0);
U32 gPacketsIn = 0;
BOOL gPrintMessagesThisFrame = FALSE;
BOOL gRandomizeFramerate = FALSE;
BOOL gPeriodicSlowFrame = FALSE;
BOOL gCrashOnStartup = FALSE;
BOOL gLLErrorActivated = FALSE;
BOOL gLogoutInProgress = FALSE;
Steven Bennetts
committed
////////////////////////////////////////////////////////////
// Internal globals... that should be removed.
static std::string gArgs;
Steven Bennetts
committed
const std::string MARKER_FILE_NAME("SecondLife.exec_marker");
const std::string ERROR_MARKER_FILE_NAME("SecondLife.error_marker");
const std::string LLERROR_MARKER_FILE_NAME("SecondLife.llerror_marker");
const std::string LOGOUT_MARKER_FILE_NAME("SecondLife.logout_marker");
Steven Bennetts
committed
static BOOL gDoDisconnect = FALSE;
static std::string gLaunchFileOnQuit;
Steven Bennetts
committed
// Used on Win32 for other apps to identify our window (eg, win_setup)
const char* const VIEWER_WINDOW_CLASSNAME = "Second Life";
//----------------------------------------------------------------------------
// List of entries from strings.xml to always replace
static std::set<std::string> default_trans_args;
void init_default_trans_args()
{
default_trans_args.insert("SECOND_LIFE"); // World
default_trans_args.insert("APP_NAME");
Tofu Linden
committed
default_trans_args.insert("CAPITALIZED_APP_NAME");
default_trans_args.insert("SECOND_LIFE_GRID");
default_trans_args.insert("SUPPORT_SITE");
Steven Bennetts
committed
//----------------------------------------------------------------------------
// File scope definitons
const char *VFS_DATA_FILE_BASE = "data.db2.x.";
const char *VFS_INDEX_FILE_BASE = "index.db2.x.";
static std::string gWindowTitle;
Steven Bennetts
committed
LLAppViewer::LLUpdaterInfo *LLAppViewer::sUpdaterInfo = NULL ;
//----------------------------------------------------------------------------
// Metrics logging control constants
//----------------------------------------------------------------------------
static const F32 METRICS_INTERVAL_MIN = 300.0;
static const F32 METRICS_INTERVAL_MAX = 3600.0;
static const F32 METRICS_INTERVAL_DEFAULT = 600.0;
Steven Bennetts
committed
void idle_afk_check()
{
// check idle timers
Leyla Farazha
committed
if (gSavedSettings.getS32("AFKTimeout") && (gAwayTriggerTimer.getElapsedTimeF32() > gSavedSettings.getS32("AFKTimeout")))
Steven Bennetts
committed
{
gAgent.setAFK();
}
}
// A callback set in LLAppViewer::init()
static void ui_audio_callback(const LLUUID& uuid)
{
if (gAudiop)
{
gAudiop->triggerSound(uuid, gAgent.getID(), 1.0f, LLAudioEngine::AUDIO_TYPE_UI);
Steven Bennetts
committed
}
}
Yuri Chebotarev
committed
bool create_text_segment_icon_from_url_match(LLUrlMatch* match,LLTextBase* base)
{
if(!match || !base || base->getPlainText())
Yuri Chebotarev
committed
return false;
LLUUID match_id = match->getID();
LLIconCtrl* icon;
if(gAgent.isInGroup(match_id, TRUE))
{
Yuri Chebotarev
committed
icon_params.group_id = match_id;
icon_params.rect = LLRect(0, 16, 16, 0);
icon_params.visible = true;
icon = LLUICtrlFactory::instance().create<LLGroupIconCtrl>(icon_params);
Yuri Chebotarev
committed
}
else
{
Yuri Chebotarev
committed
icon_params.avatar_id = match_id;
icon_params.rect = LLRect(0, 16, 16, 0);
icon_params.visible = true;
icon = LLUICtrlFactory::instance().create<LLAvatarIconCtrl>(icon_params);
Yuri Chebotarev
committed
}
LLInlineViewSegment::Params params;
params.force_newline = false;
params.view = icon;
params.left_pad = 4;
params.right_pad = 4;
Richard Linden
committed
params.top_pad = -2;
Yuri Chebotarev
committed
params.bottom_pad = 2;
base->appendWidget(params," ",false);
return true;
}
Steven Bennetts
committed
void request_initial_instant_messages()
{
static BOOL requested = FALSE;
if (!requested
&& gMessageSystem
&& LLMuteList::getInstance()->isLoaded()
Steven Bennetts
committed
{
// Auto-accepted inventory items may require the avatar object
// to build a correct name. Likewise, inventory offers from
// muted avatars require the mute list to properly mute.
LLMessageSystem* msg = gMessageSystem;
msg->newMessageFast(_PREHASH_RetrieveInstantMessages);
msg->nextBlockFast(_PREHASH_AgentData);
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
gAgent.sendReliableMessage();
requested = TRUE;
}
}
// A settings system callback for CrashSubmitBehavior
bool handleCrashSubmitBehaviorChanged(const LLSD& newvalue)
{
S32 cb = newvalue.asInteger();
const S32 NEVER_SUBMIT_REPORT = 2;
if(cb == NEVER_SUBMIT_REPORT)
{
LLAppViewer::instance()->destroyMainloopTimeout();
}
return true;
}
Steven Bennetts
committed
// Use these strictly for things that are constructed at startup,
// or for things that are performance critical. JC
static void settings_to_globals()
Steven Bennetts
committed
{
LLBUTTON_H_PAD = gSavedSettings.getS32("ButtonHPad");
BTN_HEIGHT_SMALL = gSavedSettings.getS32("ButtonHeightSmall");
BTN_HEIGHT = gSavedSettings.getS32("ButtonHeight");
MENU_BAR_HEIGHT = gSavedSettings.getS32("MenuBarHeight");
MENU_BAR_WIDTH = gSavedSettings.getS32("MenuBarWidth");
LLCOMBOBOX_HEIGHT = BTN_HEIGHT - 2;
LLCOMBOBOX_WIDTH = 128;
LLSurface::setTextureSize(gSavedSettings.getU32("RegionTextureSize"));
LLImageGL::sGlobalUseAnisotropic = gSavedSettings.getBOOL("RenderAnisotropic");
LLVOVolume::sLODFactor = gSavedSettings.getF32("RenderVolumeLODFactor");
LLVOVolume::sDistanceFactor = 1.f-LLVOVolume::sLODFactor * 0.1f;
LLVolumeImplFlexible::sUpdateFactor = gSavedSettings.getF32("RenderFlexTimeFactor");
LLVOTree::sTreeFactor = gSavedSettings.getF32("RenderTreeLODFactor");
LLVOAvatar::sLODFactor = gSavedSettings.getF32("RenderAvatarLODFactor");
LLVOAvatar::sMaxVisible = (U32)gSavedSettings.getS32("RenderAvatarMaxVisible");
Steven Bennetts
committed
LLVOAvatar::sVisibleInFirstPerson = gSavedSettings.getBOOL("FirstPersonAvatarVisible");
// clamp auto-open time to some minimum usable value
LLFolderView::sAutoOpenTime = llmax(0.25f, gSavedSettings.getF32("FolderAutoOpenDelay"));
LLSelectMgr::sRectSelectInclusive = gSavedSettings.getBOOL("RectangleSelectInclusive");
LLSelectMgr::sRenderHiddenSelections = gSavedSettings.getBOOL("RenderHiddenSelections");
LLSelectMgr::sRenderLightRadius = gSavedSettings.getBOOL("RenderLightRadius");
gAgentPilot.mNumRuns = gSavedSettings.getS32("StatsNumRuns");
gAgentPilot.mQuitAfterRuns = gSavedSettings.getBOOL("StatsQuitAfterRuns");
gAgent.setHideGroupTitle(gSavedSettings.getBOOL("RenderHideGroupTitle"));
Steven Bennetts
committed
gDebugWindowProc = gSavedSettings.getBOOL("DebugWindowProc");
gShowObjectUpdates = gSavedSettings.getBOOL("ShowObjectUpdates");
LLWorldMapView::sMapScale = gSavedSettings.getF32("MapScale");
LLCubeMap::sUseCubeMaps = LLFeatureManager::getInstance()->isFeatureAvailable("RenderCubeMap");
Steven Bennetts
committed
static void settings_modify()
{
LLRenderTarget::sUseFBO = gSavedSettings.getBOOL("RenderUseFBO");
LLVOAvatar::sUseImpostors = gSavedSettings.getBOOL("RenderUseImpostors");
LLVOSurfacePatch::sLODFactor = gSavedSettings.getF32("RenderTerrainLODFactor");
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");
Steven Bennetts
committed
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
#if LL_VECTORIZE
if (gSysCPU.hasAltivec())
{
gSavedSettings.setBOOL("VectorizeEnable", TRUE );
gSavedSettings.setU32("VectorizeProcessor", 0 );
}
else
if (gSysCPU.hasSSE2())
{
gSavedSettings.setBOOL("VectorizeEnable", TRUE );
gSavedSettings.setU32("VectorizeProcessor", 2 );
}
else
if (gSysCPU.hasSSE())
{
gSavedSettings.setBOOL("VectorizeEnable", TRUE );
gSavedSettings.setU32("VectorizeProcessor", 1 );
}
else
{
// Don't bother testing or running if CPU doesn't support it. JC
gSavedSettings.setBOOL("VectorizePerfTest", FALSE );
gSavedSettings.setBOOL("VectorizeEnable", FALSE );
gSavedSettings.setU32("VectorizeProcessor", 0 );
gSavedSettings.setBOOL("VectorizeSkin", FALSE);
}
#else
// This build target doesn't support SSE, don't test/run.
gSavedSettings.setBOOL("VectorizePerfTest", FALSE );
gSavedSettings.setBOOL("VectorizeEnable", FALSE );
gSavedSettings.setU32("VectorizeProcessor", 0 );
gSavedSettings.setBOOL("VectorizeSkin", FALSE);
#endif
}
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
class LLFastTimerLogThread : public LLThread
{
public:
std::string mFile;
LLFastTimerLogThread() : LLThread("fast timer log")
{
if(LLFastTimer::sLog)
{
mFile = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "performance.slp");
}
if(LLFastTimer::sMetricLog)
{
mFile = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "metric.slp");
}
}
void run()
{
std::ofstream os(mFile.c_str());
while (!LLAppViewer::instance()->isQuitting())
{
LLFastTimer::writeLog(os);
os.flush();
ms_sleep(32);
}
os.close();
}
};
//virtual
bool LLAppViewer::initSLURLHandler()
Steven Bennetts
committed
{
// does nothing unless subclassed
return false;
}
//virtual
bool LLAppViewer::sendURLToOtherInstance(const std::string& url)
{
// does nothing unless subclassed
Steven Bennetts
committed
return false;
}
//----------------------------------------------------------------------------
// LLAppViewer definition
// Static members.
// The single viewer app.
LLAppViewer* LLAppViewer::sInstance = NULL;
const std::string LLAppViewer::sGlobalSettingsName = "Global";
Steven Bennetts
committed
LLTextureCache* LLAppViewer::sTextureCache = NULL;
LLImageDecodeThread* LLAppViewer::sImageDecodeThread = NULL;
Steven Bennetts
committed
LLTextureFetch* LLAppViewer::sTextureFetch = NULL;
LLAppViewer::LLAppViewer() :
mMarkerFile(),
Steven Bennetts
committed
mReportedCrash(false),
mNumSessions(0),
mPurgeCache(false),
mPurgeOnExit(false),
mSecondInstance(false),
Steven Bennetts
committed
mSavedFinalSnapshot(false),
mForceGraphicsDetail(false),
mQuitRequested(false),
mLogoutRequestSent(false),
mMainloopTimeout(NULL),
mAgentRegionLastAlive(false),
mRandomizeFramerate(LLCachedControl<bool>(gSavedSettings,"Randomize Framerate", FALSE)),
mPeriodicSlowFrame(LLCachedControl<bool>(gSavedSettings,"Periodic Slow Frame", FALSE)),
mFastTimerLogThread(NULL)
Steven Bennetts
committed
{
if(NULL != sInstance)
{
llerrs << "Oh no! An instance of LLAppViewer already exists! LLAppViewer is sort of like a singleton." << llendl;
}
Steven Bennetts
committed
sInstance = this;
gLoggedInTime.stop();
Steven Bennetts
committed
}
LLAppViewer::~LLAppViewer()
{
destroyMainloopTimeout();
Steven Bennetts
committed
// If we got to this destructor somehow, the app didn't hang.
removeMarkerFile();
}
bool LLAppViewer::init()
{
//
// Start of the application
//
// IMPORTANT! Do NOT put anything that will write
// into the log files during normal startup until AFTER
// we run the "program crashed last time" error handler below.
//
Richard Nelson
committed
LLFastTimer::reset();
Steven Bennetts
committed
// 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");
// set skin search path to default, will be overridden later
// this allows simple skinned file lookups to work
gDirUtilp->setSkinFolder("default");
Steven Bennetts
committed
initLogging();
//
// OK to write stuff to logs now, we've now crash reported if necessary
//
init_default_trans_args();
if (!initConfiguration())
// 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();
writeSystemInfo();
// Build a string representing the current version number.
gCurrentVersion = llformat("%s %s",
gSavedSettings.getString("VersionChannelName").c_str(),
LLVersionInfo::getVersion().c_str());
Steven Bennetts
committed
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// *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.
LL_INFOS("InitInfo") << "J2C Engine is: " << LLImageJ2C::getEngineInfo() << LL_ENDL;
LL_INFOS("InitInfo") << "libcurl version is: " << LLCurl::getVersionString() << LL_ENDL;
Steven Bennetts
committed
// 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);
}
Steven Bennetts
committed
/////////////////////////////////////////////////
// OS-specific login dialogs
/////////////////////////////////////////////////
//test_cached_control();
Steven Bennetts
committed
// track number of times that app has run
mNumSessions = gSavedSettings.getS32("NumSessions");
mNumSessions++;
gSavedSettings.setS32("NumSessions", mNumSessions);
if (gSavedSettings.getBOOL("VerboseLogs"))
{
LLError::setPrintLocation(true);
}
// Widget construction depends on LLUI being initialized
LLUI::settings_map_t settings_map;
settings_map["config"] = &gSavedSettings;
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);
// Setup paths and LLTrans after LLUI::initClass has been called
LLUI::setupPaths();
Adam Moss
committed
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
// 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();
/////////////////////////////////////////////////
LLToolMgr::getInstance(); // Initialize tool manager if not already instantiated
LLViewerFloaterReg::registerFloaters();
Steven Bennetts
committed
/////////////////////////////////////////////////
//
// Load settings files
//
//
LLGroupMgr::parseRoleActions("role_actions.xml");
LLAgent::parseTeleportMessages("teleport_strings.xml");
LLViewerJointMesh::updateVectorize();
Monroe Linden
committed
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
// Setup settings listeners
settings_setup_listeners();
// Modify settings based on system configuration and compile options
settings_modify();
Steven Bennetts
committed
// Find partition serial number (Windows) or hardware serial (Mac)
mSerialNumber = generateSerialNumber();
// do any necessary set-up for accepting incoming SLURLs from apps
initSLURLHandler();
Steven Bennetts
committed
if(false == initHardwareTest())
{
// Early out from user choice.
return false;
}
// 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
MemSetErrorHandler(first_mem_error_handler);
#endif // LL_WINDOWS && LL_RELEASE_FOR_DOWNLOAD && LL_USE_SMARTHEAP
// *Note: this is where gViewerStats used to be created.
Steven Bennetts
committed
//
// Initialize the VFS, and gracefully handle initialization errors
//
if (!initCache())
{
std::ostringstream msg;
msg << LLTrans::getString("MBUnableToAccessFile");
OSMessageBox(msg.str(),LLStringUtil::null,OSMB_OK);
Steven Bennetts
committed
return 1;
}
//
// Initialize the window
//
Steven Bennetts
committed
initWindow();
// call all self-registered classes
LLInitClassList::instance().fireCallbacks();
LLFolderViewItem::initClass(); // SJB: Needs to happen after initWindow(), not sure why but related to fonts
Kyle Machulis
committed
gGLManager.getGLInfo(gDebugInfo);
gGLManager.printGLInfoString();
Steven Bennetts
committed
//load key settings
bind_keyboard_functions();
// Load Default bindings
if (!gViewerKeyboard.loadBindings(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"keys.ini")))
Steven Bennetts
committed
{
LL_ERRS("InitInfo") << "Unable to open keys.ini" << LL_ENDL;
Steven Bennetts
committed
}
// Load Custom bindings (override defaults)
gViewerKeyboard.loadBindings(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"custom_keys.ini"));
Steven Bennetts
committed
// If we don't have the right GL requirements, exit.
if (!gGLManager.mHasRequirements && !gNoRender)
{
// can't use an alert here since we're exiting and
// all hell breaks lose.
Steven Bennetts
committed
OSMessageBox(
LLNotifications::instance().getGlobalString("UnsupportedGLRequirements"),
LLStringUtil::null,
Steven Bennetts
committed
OSMB_OK);
return 0;
}
// alert the user if they are using unsupported hardware
if(!gSavedSettings.getBOOL("AlertedUnsupportedHardware"))
bool unsupported = false;
LLSD args;
std::string minSpecs;
// get cpu data from xml
std::stringstream minCPUString(LLNotifications::instance().getGlobalString("UnsupportedCPUAmount"));
S32 minCPU = 0;
minCPUString >> minCPU;
// get RAM data from XML
std::stringstream minRAMString(LLNotifications::instance().getGlobalString("UnsupportedRAMAmount"));
U64 minRAM = 0;
minRAMString >> minRAM;
minRAM = minRAM * 1024 * 1024;
if(!LLFeatureManager::getInstance()->isGPUSupported() && LLFeatureManager::getInstance()->getGPUClass() != GPU_CLASS_UNKNOWN)
{
minSpecs += LLNotifications::instance().getGlobalString("UnsupportedGPU");
minSpecs += "\n";
unsupported = true;
}
Tofu Linden
committed
if(gSysCPU.getMHz() < minCPU)
{
minSpecs += LLNotifications::instance().getGlobalString("UnsupportedCPU");
minSpecs += "\n";
unsupported = true;
}
if(gSysMemory.getPhysicalMemoryClamped() < minRAM)
{
minSpecs += LLNotifications::instance().getGlobalString("UnsupportedRAM");
minSpecs += "\n";
unsupported = true;
}
if (LLFeatureManager::getInstance()->getGPUClass() == GPU_CLASS_UNKNOWN)
{
LLNotificationsUtil::add("UnknownGPU");
}
if(unsupported)
{
if(!gSavedSettings.controlExists("WarnUnsupportedHardware")
|| gSavedSettings.getBOOL("WarnUnsupportedHardware"))
{
args["MINSPECS"] = minSpecs;
LLNotificationsUtil::add("UnsupportedHardware", args );
}
// save the graphics card
gDebugInfo["GraphicsCard"] = LLFeatureManager::getInstance()->getGPUString();
Steven Bennetts
committed
// Save the current version to the prefs file
gSavedSettings.setString("LastRunVersion", gCurrentVersion);
gSimLastTime = gRenderStartTime.getElapsedTimeF32();
gSimFrames = (F32)gFrameCount;
LLViewerJoystick::getInstance()->init(false);
try {
initializeSecHandler();
}
catch (LLProtectedDataException ex)
{
LLNotificationsUtil::add("CorruptedProtectedDataStore");
}
LLHTTPClient::setCertVerifyCallback(secapiSSLCertVerifyCallback);
if (gSavedSettings.getBOOL("QAMode") && gSavedSettings.getS32("QAModeEventHostPort") > 0)
{
loadEventHostModule(gSavedSettings.getS32("QAModeEventHostPort"));
}
LLViewerMedia::initClass();
Yuri Chebotarev
committed
LLTextUtil::TextHelpers::iconCallbackCreationFunction = create_text_segment_icon_from_url_match;
Yuri Chebotarev
committed
Yuri Chebotarev
committed
//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).
Yuri Chebotarev
committed
std::string language = LLControlGroup::getInstance(sGlobalSettingsName)->getString("Language");
if(language == "ja" || language == "pl")
Yuri Chebotarev
committed
{
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");
}
Yuri Chebotarev
committed
Vadim Savchuk
committed
LLAgentLanguage::init();
Steven Bennetts
committed
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");
Steve Bennetts
committed
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");
Steven Bennetts
committed
bool LLAppViewer::mainLoop()
{
LLMemType mt1(LLMemType::MTYPE_MAIN);
mMainloopTimeout = new LLWatchdogTimeout();
Steven Bennetts
committed
//-------------------------------------------
// Run main loop until time to quit
//-------------------------------------------
// Create IO Pump to use for HTTP Requests.
gServicePump = new LLPumpIO(gAPRPoolp);
LLHTTPClient::setPump(*gServicePump);
// Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be instantiated.
Steven Bennetts
committed
LLVoiceChannel::initClass();
LLVoiceClient::getInstance()->init(gServicePump);
Steven Bennetts
committed
LLTimer frameTimer,idleTimer;
LLTimer debugTime;
LLViewerJoystick* joystick(LLViewerJoystick::getInstance());
joystick->setNeedsReset(true);