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.cpp234
1 files changed, 153 insertions, 81 deletions
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 4e6200e8af..297925d0f0 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -287,7 +287,7 @@ extern BOOL gHiDPISupport;
////////////////////////////////////////////////////////////
// All from the last globals push...
-F32 gSimLastTime; // Used in LLAppViewer::init and send_stats()
+F32 gSimLastTime; // Used in LLAppViewer::init and send_viewer_stats()
F32 gSimFrames;
BOOL gShowObjectUpdates = FALSE;
@@ -680,6 +680,7 @@ LLAppViewer::LLAppViewer()
mPurgeCacheOnExit(false),
mPurgeUserDataOnExit(false),
mSecondInstance(false),
+ mUpdaterNotFound(false),
mSavedFinalSnapshot(false),
mSavePerAccountSettings(false), // don't save settings on logout unless login succeeded.
mQuitRequested(false),
@@ -692,7 +693,8 @@ LLAppViewer::LLAppViewer()
mPeriodicSlowFrame(LLCachedControl<bool>(gSavedSettings,"Periodic Slow Frame", FALSE)),
mFastTimerLogThread(NULL),
mSettingsLocationList(NULL),
- mIsFirstRun(false)
+ mIsFirstRun(false),
+ mMinMicroSecPerFrame(0.f)
{
if(NULL != sInstance)
{
@@ -1163,7 +1165,7 @@ bool LLAppViewer::init()
gGLActive = FALSE;
-#if LL_RELEASE_FOR_DOWNLOAD
+#if LL_RELEASE_FOR_DOWNLOAD
if (!gSavedSettings.getBOOL("CmdLineSkipUpdater"))
{
LLProcess::Params updater;
@@ -1171,14 +1173,18 @@ bool LLAppViewer::init()
// Because it's the updater, it MUST persist beyond the lifespan of the
// viewer itself.
updater.autokill = false;
+ std::string updater_file;
#if LL_WINDOWS
- updater.executable = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "SLVersionChecker.exe");
+ updater_file = "SLVersionChecker.exe";
+ updater.executable = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, updater_file);
#elif LL_DARWIN
// explicitly run the system Python interpreter on SLVersionChecker.py
updater.executable = "python";
- updater.args.add(gDirUtilp->add(gDirUtilp->getAppRODataDir(), "updater", "SLVersionChecker.py"));
+ updater_file = "SLVersionChecker.py";
+ updater.args.add(gDirUtilp->add(gDirUtilp->getAppRODataDir(), "updater", updater_file));
#else
- updater.executable = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "SLVersionChecker");
+ updater_file = "SLVersionChecker";
+ updater.executable = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, updater_file);
#endif
// add LEAP mode command-line argument to whichever of these we selected
updater.args.add("leap");
@@ -1191,37 +1197,58 @@ bool LLAppViewer::init()
// ForceAddressSize
updater.args.add(stringize(gSavedSettings.getU32("ForceAddressSize")));
- // Run the updater. An exception from launching the updater should bother us.
- LLLeap::create(updater, true);
+ try
+ {
+ // Run the updater. An exception from launching the updater should bother us.
+ LLLeap::create(updater, true);
+ mUpdaterNotFound = false;
+ }
+ catch (...)
+ {
+ LLUIString details = LLNotifications::instance().getGlobalString("LLLeapUpdaterFailure");
+ details.setArg("[UPDATER_APP]", updater_file);
+ OSMessageBox(
+ details.getString(),
+ LLStringUtil::null,
+ OSMB_OK);
+ mUpdaterNotFound = true;
+ }
}
else
{
LL_WARNS("InitInfo") << "Skipping updater check." << LL_ENDL;
}
- // Iterate over --leap command-line options. But this is a bit tricky: if
- // there's only one, it won't be an array at all.
- LLSD LeapCommand(gSavedSettings.getLLSD("LeapCommand"));
- LL_DEBUGS("InitInfo") << "LeapCommand: " << LeapCommand << LL_ENDL;
- if (LeapCommand.isDefined() && ! LeapCommand.isArray())
- {
- // If LeapCommand is actually a scalar value, make an array of it.
- // Have to do it in two steps because LeapCommand.append(LeapCommand)
- // trashes content! :-P
- LLSD item(LeapCommand);
- LeapCommand.append(item);
- }
- BOOST_FOREACH(const std::string& leap, llsd::inArray(LeapCommand))
- {
- LL_INFOS("InitInfo") << "processing --leap \"" << leap << '"' << LL_ENDL;
- // We don't have any better description of this plugin than the
- // user-specified command line. Passing "" causes LLLeap to derive a
- // description from the command line itself.
- // Suppress LLLeap::Error exception: trust LLLeap's own logging. We
- // don't consider any one --leap command mission-critical, so if one
- // fails, log it, shrug and carry on.
- LLLeap::create("", leap, false); // exception=false
- }
+ if (mUpdaterNotFound)
+ {
+ LL_WARNS("InitInfo") << "Failed to launch updater. Skipping Leap commands." << LL_ENDL;
+ }
+ else
+ {
+ // Iterate over --leap command-line options. But this is a bit tricky: if
+ // there's only one, it won't be an array at all.
+ LLSD LeapCommand(gSavedSettings.getLLSD("LeapCommand"));
+ LL_DEBUGS("InitInfo") << "LeapCommand: " << LeapCommand << LL_ENDL;
+ if (LeapCommand.isDefined() && !LeapCommand.isArray())
+ {
+ // If LeapCommand is actually a scalar value, make an array of it.
+ // Have to do it in two steps because LeapCommand.append(LeapCommand)
+ // trashes content! :-P
+ LLSD item(LeapCommand);
+ LeapCommand.append(item);
+ }
+ BOOST_FOREACH(const std::string& leap, llsd::inArray(LeapCommand))
+ {
+ LL_INFOS("InitInfo") << "processing --leap \"" << leap << '"' << LL_ENDL;
+ // We don't have any better description of this plugin than the
+ // user-specified command line. Passing "" causes LLLeap to derive a
+ // description from the command line itself.
+ // Suppress LLLeap::Error exception: trust LLLeap's own logging. We
+ // don't consider any one --leap command mission-critical, so if one
+ // fails, log it, shrug and carry on.
+ LLLeap::create("", leap, false); // exception=false
+ }
+ }
if (gSavedSettings.getBOOL("QAMode") && gSavedSettings.getS32("QAModeEventHostPort") > 0)
{
@@ -1229,7 +1256,7 @@ bool LLAppViewer::init()
<< "lleventhost no longer supported as a dynamic library"
<< LL_ENDL;
}
-#endif
+#endif //LL_RELEASE_FOR_DOWNLOAD
LLTextUtil::TextHelpers::iconCallbackCreationFunction = create_text_segment_icon_from_url_match;
@@ -1275,6 +1302,10 @@ bool LLAppViewer::init()
joystick = LLViewerJoystick::getInstance();
joystick->setNeedsReset(true);
+ /*----------------------------------------------------------------------*/
+
+ gSavedSettings.getControl("FramePerSecondLimit")->getSignal()->connect(boost::bind(&LLAppViewer::onChangeFrameLimit, this, _2));
+ onChangeFrameLimit(gSavedSettings.getLLSD("FramePerSecondLimit"));
return true;
}
@@ -1460,6 +1491,21 @@ bool LLAppViewer::doFrame()
display();
+ static U64 last_call = 0;
+ if (!gTeleportDisplay)
+ {
+ // Frame/draw throttling, controlled by FramePerSecondLimit
+ U64 elapsed_time = LLTimer::getTotalTime() - last_call;
+ if (elapsed_time < mMinMicroSecPerFrame)
+ {
+ LL_RECORD_BLOCK_TIME(FTM_SLEEP);
+ // llclamp for when time function gets funky
+ U64 sleep_time = llclamp(mMinMicroSecPerFrame - elapsed_time, (U64)1, (U64)1e6);
+ micro_sleep(sleep_time, 0);
+ }
+ }
+ last_call = LLTimer::getTotalTime();
+
pingMainloopTimeout("Main:Snapshot");
LLFloaterSnapshot::update(); // take snapshots
LLFloaterOutfitSnapshot::update();
@@ -1831,8 +1877,6 @@ bool LLAppViewer::cleanup()
SUBSYSTEM_CLEANUP(LLAvatarAppearance);
- SUBSYSTEM_CLEANUP(LLAvatarAppearance);
-
SUBSYSTEM_CLEANUP(LLPostProcess);
LLTracker::cleanupInstance();
@@ -2034,6 +2078,7 @@ bool LLAppViewer::cleanup()
LLUIImageList::getInstance()->cleanUp();
// This should eventually be done in LLAppViewer
+ SUBSYSTEM_CLEANUP(LLImage);
SUBSYSTEM_CLEANUP(LLVFSThread);
SUBSYSTEM_CLEANUP(LLLFSThread);
@@ -2077,6 +2122,7 @@ bool LLAppViewer::cleanup()
LLWeb::loadURLExternal( gLaunchFileOnQuit, false );
LL_INFOS() << "File launched." << LL_ENDL;
}
+ // make sure nothing uses applyProxySettings by this point.
LL_INFOS() << "Cleaning up LLProxy." << LL_ENDL;
SUBSYSTEM_CLEANUP(LLProxy);
LLCore::LLHttp::cleanup();
@@ -2132,7 +2178,7 @@ bool LLAppViewer::initThreads()
{
static const bool enable_threads = true;
- LLImage::initParamSingleton(gSavedSettings.getBOOL("TextureNewByteRange"),gSavedSettings.getS32("TextureReverseByteRange"));
+ LLImage::initClass(gSavedSettings.getBOOL("TextureNewByteRange"),gSavedSettings.getS32("TextureReverseByteRange"));
LLVFSThread::initClass(enable_threads && false);
LLLFSThread::initClass(enable_threads && false);
@@ -3088,7 +3134,7 @@ LLSD LLAppViewer::getViewerInfo() const
info["REGION"] = gAgent.getRegion()->getName();
boost::regex regex("\\.(secondlife|lindenlab)\\..*");
- info["HOSTNAME"] = boost::regex_replace(gAgent.getRegion()->getHost().getHostName(), regex, "");
+ info["HOSTNAME"] = boost::regex_replace(gAgent.getRegion()->getSimHostName(), regex, "");
info["SERVER_VERSION"] = gLastVersionChannel;
LLSLURL slurl;
LLAgentUI::buildSLURL(slurl);
@@ -3544,7 +3590,7 @@ void LLAppViewer::handleViewerCrash()
if(gAgent.getRegion())
{
- gDebugInfo["Dynamic"]["CurrentSimHost"] = gAgent.getRegionHost().getHostName();
+ gDebugInfo["Dynamic"]["CurrentSimHost"] = gAgent.getRegion()->getSimHostName();
gDebugInfo["Dynamic"]["CurrentRegion"] = gAgent.getRegion()->getName();
const LLVector3& loc = gAgent.getPositionAgent();
@@ -3936,7 +3982,9 @@ void LLAppViewer::requestQuit()
gFloaterView->closeAllChildren(true);
}
- send_stats();
+ // Send preferences once, when exiting
+ bool include_preferences = true;
+ send_viewer_stats(include_preferences);
gLogoutTimer.reset();
mQuitRequested = true;
@@ -4735,7 +4783,8 @@ void LLAppViewer::idle()
if (viewer_stats_timer.getElapsedTimeF32() >= SEND_STATS_PERIOD && !gDisconnected)
{
LL_INFOS() << "Transmitting sessions stats" << LL_ENDL;
- send_stats();
+ bool include_preferences = false;
+ send_viewer_stats(include_preferences);
viewer_stats_timer.reset();
}
@@ -5146,11 +5195,56 @@ void LLAppViewer::sendLogoutRequest()
}
}
+void LLAppViewer::updateNameLookupUrl()
+{
+ LLViewerRegion* region = gAgent.getRegion();
+ if (!region || !region->capabilitiesReceived())
+ {
+ return;
+ }
+
+ LLAvatarNameCache *name_cache = LLAvatarNameCache::getInstance();
+ bool had_capability = LLAvatarNameCache::getInstance()->hasNameLookupURL();
+ std::string name_lookup_url;
+ name_lookup_url.reserve(128); // avoid a memory allocation below
+ name_lookup_url = region->getCapability("GetDisplayNames");
+ bool have_capability = !name_lookup_url.empty();
+ if (have_capability)
+ {
+ // we have support for display names, use it
+ U32 url_size = name_lookup_url.size();
+ // capabilities require URLs with slashes before query params:
+ // https://<host>:<port>/cap/<uuid>/?ids=<blah>
+ // but the caps are granted like:
+ // https://<host>:<port>/cap/<uuid>
+ if (url_size > 0 && name_lookup_url[url_size - 1] != '/')
+ {
+ name_lookup_url += '/';
+ }
+ name_cache->setNameLookupURL(name_lookup_url);
+ }
+ else
+ {
+ // Display names not available on this region
+ name_cache->setNameLookupURL(std::string());
+ }
+
+ // Error recovery - did we change state?
+ if (had_capability != have_capability)
+ {
+ // name tags are persistant on screen, so make sure they refresh
+ LLVOAvatar::invalidateNameTags();
+ }
+}
+
void LLAppViewer::idleNameCache()
{
// Neither old nor new name cache can function before agent has a region
LLViewerRegion* region = gAgent.getRegion();
- if (!region) return;
+ if (!region)
+ {
+ return;
+ }
// deal with any queued name requests and replies.
gCacheName->processPending();
@@ -5158,47 +5252,12 @@ void LLAppViewer::idleNameCache()
// Can't run the new cache until we have the list of capabilities
// for the agent region, and can therefore decide whether to use
// display names or fall back to the old name system.
- if (!region->capabilitiesReceived()) return;
-
- // Agent may have moved to a different region, so need to update cap URL
- // for name lookups. Can't do this in the cap grant code, as caps are
- // granted to neighbor regions before the main agent gets there. Can't
- // do it in the move-into-region code because cap not guaranteed to be
- // granted yet, for example on teleport.
- LLAvatarNameCache *name_cache = LLAvatarNameCache::getInstance();
- bool had_capability = LLAvatarNameCache::getInstance()->hasNameLookupURL();
- std::string name_lookup_url;
- name_lookup_url.reserve(128); // avoid a memory allocation below
- name_lookup_url = region->getCapability("GetDisplayNames");
- bool have_capability = !name_lookup_url.empty();
- if (have_capability)
- {
- // we have support for display names, use it
- U32 url_size = name_lookup_url.size();
- // capabilities require URLs with slashes before query params:
- // https://<host>:<port>/cap/<uuid>/?ids=<blah>
- // but the caps are granted like:
- // https://<host>:<port>/cap/<uuid>
- if (url_size > 0 && name_lookup_url[url_size-1] != '/')
- {
- name_lookup_url += '/';
- }
- name_cache->setNameLookupURL(name_lookup_url);
- }
- else
- {
- // Display names not available on this region
- name_cache->setNameLookupURL( std::string() );
- }
-
- // Error recovery - did we change state?
- if (had_capability != have_capability)
- {
- // name tags are persistant on screen, so make sure they refresh
- LLVOAvatar::invalidateNameTags();
- }
+ if (!region->capabilitiesReceived())
+ {
+ return;
+ }
- name_cache->idle();
+ LLAvatarNameCache::getInstance()->idle();
}
//
@@ -5400,6 +5459,19 @@ void LLAppViewer::disconnectViewer()
LLUrlEntryParcel::setDisconnected(gDisconnected);
}
+bool LLAppViewer::onChangeFrameLimit(LLSD const & evt)
+{
+ if (evt.asInteger() > 0)
+ {
+ mMinMicroSecPerFrame = (U64)(1000000.0f / F32(evt.asInteger()));
+ }
+ else
+ {
+ mMinMicroSecPerFrame = 0;
+ }
+ return false;
+}
+
void LLAppViewer::forceErrorLLError()
{
LL_ERRS() << "This is a deliberate llerror" << LL_ENDL;
@@ -5537,7 +5609,7 @@ void LLAppViewer::handleLoginComplete()
if(gAgent.getRegion())
{
- gDebugInfo["CurrentSimHost"] = gAgent.getRegionHost().getHostName();
+ gDebugInfo["CurrentSimHost"] = gAgent.getRegion()->getSimHostName();
gDebugInfo["CurrentRegion"] = gAgent.getRegion()->getName();
}