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.cpp323
1 files changed, 175 insertions, 148 deletions
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index c9d852686e..89e0da3ea7 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -91,7 +91,6 @@
#include "llsdutil_math.h"
#include "lllocationhistory.h"
#include "llfasttimerview.h"
-#include "lltelemetry.h"
#include "llvector4a.h"
#include "llviewermenufile.h"
#include "llvoicechannel.h"
@@ -233,11 +232,12 @@
#include "llavatariconctrl.h"
#include "llgroupiconctrl.h"
#include "llviewerassetstats.h"
+#include "workqueue.h"
+using namespace LL;
// Include for security api initialization
#include "llsecapi.h"
#include "llmachineid.h"
-#include "llmainlooprepeater.h"
#include "llcleanup.h"
#include "llcoproceduremanager.h"
@@ -363,6 +363,10 @@ BOOL gLogoutInProgress = FALSE;
BOOL gSimulateMemLeak = FALSE;
+// We don't want anyone, especially threads working on the graphics pipeline,
+// to have to block due to this WorkQueue being full.
+WorkQueue gMainloopWork("mainloop", 1024*1024);
+
////////////////////////////////////////////////////////////
// Internal globals... that should be removed.
static std::string gArgs;
@@ -378,42 +382,6 @@ static std::string gLaunchFileOnQuit;
// Used on Win32 for other apps to identify our window (eg, win_setup)
const char* const VIEWER_WINDOW_CLASSNAME = "Second Life";
-//-- LLDeferredTaskList ------------------------------------------------------
-
-/**
- * A list of deferred tasks.
- *
- * We sometimes need to defer execution of some code until the viewer gets idle,
- * e.g. removing an inventory item from within notifyObservers() may not work out.
- *
- * Tasks added to this list will be executed in the next LLAppViewer::idle() iteration.
- * All tasks are executed only once.
- */
-class LLDeferredTaskList: public LLSingleton<LLDeferredTaskList>
-{
- LLSINGLETON_EMPTY_CTOR(LLDeferredTaskList);
- LOG_CLASS(LLDeferredTaskList);
-
- friend class LLAppViewer;
- typedef boost::signals2::signal<void()> signal_t;
-
- void addTask(const signal_t::slot_type& cb)
- {
- mSignal.connect(cb);
- }
-
- void run()
- {
- if (!mSignal.empty())
- {
- mSignal();
- mSignal.disconnect_all_slots();
- }
- }
-
- signal_t mSignal;
-};
-
//----------------------------------------------------------------------------
// List of entries from strings.xml to always replace
@@ -598,14 +566,14 @@ static void settings_to_globals()
static void settings_modify()
{
- LLPipeline::sRenderTransparentWater = gSavedSettings.getBOOL("RenderTransparentWater");
- LLPipeline::sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
- LLPipeline::sRenderDeferred = LLPipeline::sRenderTransparentWater && LLPipeline::sRenderBump && gSavedSettings.getBOOL("RenderDeferred");
- LLRenderTarget::sUseFBO = LLPipeline::sRenderDeferred && gSavedSettings.getBOOL("RenderAvatarVP");
- 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");
+ LLPipeline::sRenderTransparentWater = gSavedSettings.getBOOL("RenderTransparentWater");
+ LLPipeline::sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
+ LLPipeline::sRenderDeferred = LLPipeline::sRenderBump && gSavedSettings.getBOOL("RenderDeferred");
+ LLRenderTarget::sUseFBO = LLPipeline::sRenderDeferred;
+ 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");
}
class LLFastTimerLogThread : public LLThread
@@ -686,8 +654,7 @@ LLAppViewer::LLAppViewer()
mPeriodicSlowFrame(LLCachedControl<bool>(gSavedSettings,"Periodic Slow Frame", FALSE)),
mFastTimerLogThread(NULL),
mSettingsLocationList(NULL),
- mIsFirstRun(false),
- mMinMicroSecPerFrame(0.f)
+ mIsFirstRun(false)
{
if(NULL != sInstance)
{
@@ -856,8 +823,6 @@ bool LLAppViewer::init()
LLNotifications::instance();
LL_INFOS("InitInfo") << "Notifications initialized." << LL_ENDL ;
- writeSystemInfo();
-
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
@@ -964,8 +929,8 @@ bool LLAppViewer::init()
}
LL_INFOS("InitInfo") << "Cache initialization is done." << LL_ENDL ;
- // Initialize the repeater service.
- LLMainLoopRepeater::instance().start();
+ // Initialize event recorder
+ LLViewerEventRecorder::createInstance();
//
// Initialize the window
@@ -974,6 +939,9 @@ bool LLAppViewer::init()
initWindow();
LL_INFOS("InitInfo") << "Window is initialized." << LL_ENDL ;
+ // writeSystemInfo can be called after window is initialized (gViewerWindow non-null)
+ writeSystemInfo();
+
// initWindow also initializes the Feature List, so now we can initialize this global.
LLCubeMap::sUseCubeMaps = LLFeatureManager::getInstance()->isFeatureAvailable("RenderCubeMap");
@@ -998,19 +966,6 @@ bool LLAppViewer::init()
return 0;
}
- // If we don't have the right shader requirements.
- if (!gGLManager.mHasShaderObjects
- || !gGLManager.mHasVertexShader
- || !gGLManager.mHasFragmentShader)
- {
- LLUIString details = LLNotifications::instance().getGlobalString("UnsupportedShaderRequirements");
- OSMessageBox(
- details.getString(),
- LLStringUtil::null,
- OSMB_OK);
- return 0;
- }
-
// Without SSE2 support we will crash almost immediately, warn here.
if (!gSysCPU.hasSSE2())
{
@@ -1136,7 +1091,7 @@ bool LLAppViewer::init()
{
url = LLTrans::getString("NvidiaDriverPage");
}
- else if (gGLManager.mIsATI)
+ else if (gGLManager.mIsAMD)
{
url = LLTrans::getString("AMDDriverPage");
}
@@ -1321,13 +1276,16 @@ bool LLAppViewer::init()
joystick = LLViewerJoystick::getInstance();
joystick->setNeedsReset(true);
/*----------------------------------------------------------------------*/
-
- gSavedSettings.getControl("FramePerSecondLimit")->getSignal()->connect(boost::bind(&LLAppViewer::onChangeFrameLimit, this, _2));
- onChangeFrameLimit(gSavedSettings.getLLSD("FramePerSecondLimit"));
-
// Load User's bindings
loadKeyBindings();
+ //LLSimpleton creations
+ LLEnvironment::createInstance();
+ LLEnvironment::getInstance()->initSingleton();
+ LLWorld::createInstance();
+ LLSelectMgr::createInstance();
+ LLViewerCamera::createInstance();
+
#if LL_WINDOWS
if (!mSecondInstance)
{
@@ -1360,7 +1318,8 @@ void LLAppViewer::initMaxHeapSize()
}
static LLTrace::BlockTimerStatHandle FTM_MESSAGES("System Messages");
-static LLTrace::BlockTimerStatHandle FTM_SLEEP("Sleep");
+static LLTrace::BlockTimerStatHandle FTM_SLEEP1("Sleep1");
+static LLTrace::BlockTimerStatHandle FTM_SLEEP2("Sleep2");
static LLTrace::BlockTimerStatHandle FTM_YIELD("Yield");
static LLTrace::BlockTimerStatHandle FTM_TEXTURE_CACHE("Texture Cache");
@@ -1421,13 +1380,26 @@ bool LLAppViewer::frame()
bool LLAppViewer::doFrame()
{
+ LL_RECORD_BLOCK_TIME(FTM_FRAME);
+
+ if (!LLWorld::instanceExists())
+ {
+ LLWorld::createInstance();
+ }
+
LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop"));
LLSD newFrame;
- LL_RECORD_BLOCK_TIME(FTM_FRAME);
+ {
+ LL_PROFILE_ZONE_NAMED("df LLTrace");
+ if (LLFloaterReg::instanceVisible("block_timers"))
+ {
LLTrace::BlockTimer::processTimes();
+ }
+
LLTrace::get_frame_recording().nextPeriod();
LLTrace::BlockTimer::logStats();
+ }
LLTrace::get_thread_recorder()->pullFromChildren();
@@ -1435,6 +1407,7 @@ bool LLAppViewer::doFrame()
LL_CLEAR_CALLSTACKS();
{
+ LL_PROFILE_ZONE_NAMED( "df processMiscNativeEvents" )
pingMainloopTimeout("Main:MiscNativeWindowEvents");
if (gViewerWindow)
@@ -1443,7 +1416,10 @@ bool LLAppViewer::doFrame()
gViewerWindow->getWindow()->processMiscNativeEvents();
}
+ {
+ LL_PROFILE_ZONE_NAMED( "df gatherInput" )
pingMainloopTimeout("Main:GatherInput");
+ }
if (gViewerWindow)
{
@@ -1467,13 +1443,21 @@ bool LLAppViewer::doFrame()
}
}
+ {
+ LL_PROFILE_ZONE_NAMED( "df mainloop" )
// canonical per-frame event
mainloop.post(newFrame);
+ }
+
+ {
+ LL_PROFILE_ZONE_NAMED( "df suspend" )
// give listeners a chance to run
llcoro::suspend();
+ }
if (!LLApp::isExiting())
{
+ LL_PROFILE_ZONE_NAMED( "df JoystickKeyboard" )
pingMainloopTimeout("Main:JoystickKeyboard");
// Scan keyboard for movement keys. Command keys and typing
@@ -1494,13 +1478,19 @@ bool LLAppViewer::doFrame()
// Update state based on messages, user input, object idle.
{
+ {
+ LL_PROFILE_ZONE_NAMED( "df pauseMainloopTimeout" )
pauseMainloopTimeout(); // *TODO: Remove. Messages shouldn't be stalling for 20+ seconds!
+ }
LL_RECORD_BLOCK_TIME(FTM_IDLE);
idle();
+ {
+ LL_PROFILE_ZONE_NAMED( "df resumeMainloopTimeout" )
resumeMainloopTimeout();
}
+ }
if (gDoDisconnect && (LLStartUp::getStartupState() == STATE_STARTED))
{
@@ -1520,49 +1510,51 @@ bool LLAppViewer::doFrame()
// *TODO: Should we run display() even during gHeadlessClient? DK 2011-02-18
if (!LLApp::isExiting() && !gHeadlessClient && gViewerWindow)
{
+ LL_PROFILE_ZONE_NAMED( "df Display" )
pingMainloopTimeout("Main:Display");
gGLActive = TRUE;
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();
-
+ LL_PROFILE_ZONE_NAMED( "df Snapshot" )
pingMainloopTimeout("Main:Snapshot");
LLFloaterSnapshot::update(); // take snapshots
LLFloaterOutfitSnapshot::update();
gGLActive = FALSE;
}
}
+ }
+ {
+ LL_PROFILE_ZONE_NAMED( "df pauseMainloopTimeout" )
pingMainloopTimeout("Main:Sleep");
pauseMainloopTimeout();
+ }
// Sleep and run background threads
{
- LL_RECORD_BLOCK_TIME(FTM_SLEEP);
+ //LL_RECORD_BLOCK_TIME(SLEEP2);
+ LL_PROFILE_ZONE_WARN( "Sleep2" )
// yield some time to the os based on command line option
static LLCachedControl<S32> yield_time(gSavedSettings, "YieldTime", -1);
if(yield_time >= 0)
{
LL_RECORD_BLOCK_TIME(FTM_YIELD);
+ LL_PROFILE_ZONE_NUM( yield_time )
ms_sleep(yield_time);
}
+ if (gNonInteractive)
+ {
+ S32 non_interactive_ms_sleep_time = 100;
+ LLAppViewer::getTextureCache()->pause();
+ LLAppViewer::getImageDecodeThread()->pause();
+ ms_sleep(non_interactive_ms_sleep_time);
+ }
+
// yield cooperatively when not running as foreground window
// and when not quiting (causes trouble at mac's cleanup stage)
if (!LLApp::isExiting()
@@ -1570,8 +1562,8 @@ bool LLAppViewer::doFrame()
|| !gFocusMgr.getAppHasFocus()))
{
// Sleep if we're not rendering, or the window is minimized.
- static LLCachedControl<S32> s_bacground_yeild_time(gSavedSettings, "BackgroundYieldTime", 40);
- S32 milliseconds_to_sleep = llclamp((S32)s_bacground_yeild_time, 0, 1000);
+ static LLCachedControl<S32> s_background_yield_time(gSavedSettings, "BackgroundYieldTime", 40);
+ S32 milliseconds_to_sleep = llclamp((S32)s_background_yield_time, 0, 1000);
// don't sleep when BackgroundYieldTime set to 0, since this will still yield to other threads
// of equal priority on Windows
if (milliseconds_to_sleep > 0)
@@ -1618,22 +1610,29 @@ bool LLAppViewer::doFrame()
total_io_pending += io_pending ;
}
+
+ {
+ LL_PROFILE_ZONE_NAMED( "df gMeshRepo" )
gMeshRepo.update() ;
+ }
if(!total_work_pending) //pause texture fetching threads if nothing to process.
{
+ LL_PROFILE_ZONE_NAMED( "df getTextureCache" )
LLAppViewer::getTextureCache()->pause();
LLAppViewer::getImageDecodeThread()->pause();
LLAppViewer::getTextureFetch()->pause();
}
if(!total_io_pending) //pause file threads if nothing to process.
{
+ LL_PROFILE_ZONE_NAMED( "df LLVFSThread" )
LLLFSThread::sLocal->pause();
}
//texture fetching debugger
if(LLTextureFetchDebugger::isEnabled())
{
+ LL_PROFILE_ZONE_NAMED( "df tex_fetch_debugger_instance" )
LLFloaterTextureFetchDebugger* tex_fetch_debugger_instance =
LLFloaterReg::findTypedInstance<LLFloaterTextureFetchDebugger>("tex_fetch_debugger");
if(tex_fetch_debugger_instance)
@@ -1642,8 +1641,10 @@ bool LLAppViewer::doFrame()
}
}
+ {
+ LL_PROFILE_ZONE_NAMED( "df resumeMainloopTimeout" )
resumeMainloopTimeout();
-
+ }
pingMainloopTimeout("Main:End");
}
}
@@ -1669,7 +1670,7 @@ bool LLAppViewer::doFrame()
LL_INFOS() << "Exiting main_loop" << LL_ENDL;
}
- LLPROFILE_UPDATE();
+ LL_PROFILER_FRAME_END
return ! LLApp::isRunning();
}
@@ -1708,6 +1709,11 @@ void LLAppViewer::flushLFSIO()
bool LLAppViewer::cleanup()
{
+ // Since we don't know what functions are going to be queued by
+ // onCleanup(), we have to assume they might rely on some of the things
+ // we're about to destroy below. Run them first.
+ mOnCleanup();
+
LLAtmosphere::cleanupClass();
//ditch LLVOAvatarSelf instance
@@ -1754,6 +1760,7 @@ bool LLAppViewer::cleanup()
LLPluginProcessParent::shutdown();
disconnectViewer();
+ LLViewerCamera::deleteSingleton();
LL_INFOS() << "Viewer disconnected" << LL_ENDL;
@@ -1947,7 +1954,7 @@ bool LLAppViewer::cleanup()
if (LLEnvironment::instanceExists())
{
- //Store environment settings if nessesary
+ //Store environment settings if necessary
LLEnvironment::getInstance()->saveToSettings();
}
@@ -2138,12 +2145,14 @@ bool LLAppViewer::cleanup()
SUBSYSTEM_CLEANUP(LLProxy);
LLCore::LLHttp::cleanup();
- LLMainLoopRepeater::instance().stop();
-
ll_close_fail_log();
LLError::LLCallStacks::cleanup();
+ LLEnvironment::deleteSingleton();
+ LLSelectMgr::deleteSingleton();
+ LLViewerEventRecorder::deleteSingleton();
+
// It's not at first obvious where, in this long sequence, a generic cleanup
// call OUGHT to go. So let's say this: as we migrate cleanup from
// explicit hand-placed calls into the generic mechanism, eventually
@@ -2326,7 +2335,7 @@ bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key,
LL_INFOS("Settings") << "Attempting to load settings for the group " << file.name()
<< " - from location " << location_key << LL_ENDL;
- LLControlGroup* settings_group = LLControlGroup::getInstance(file.name);
+ auto settings_group = LLControlGroup::getInstance(file.name);
if(!settings_group)
{
LL_WARNS("Settings") << "No matching settings group for name " << file.name() << LL_ENDL;
@@ -2421,6 +2430,38 @@ namespace
}
} // anonymous namespace
+// Set a named control temporarily for this session, as when set via the command line --set option.
+// Name can be specified as "<control_group>.<control_name>", with default group being Global.
+bool tempSetControl(const std::string& name, const std::string& value)
+{
+ std::string name_part;
+ std::string group_part;
+ LLControlVariable* control = NULL;
+
+ // Name can be further split into ControlGroup.Name, with the default control group being Global
+ size_t pos = name.find('.');
+ if (pos != std::string::npos)
+ {
+ group_part = name.substr(0, pos);
+ name_part = name.substr(pos+1);
+ LL_INFOS() << "Setting " << group_part << "." << name_part << " to " << value << LL_ENDL;
+ auto g = LLControlGroup::getInstance(group_part);
+ if (g) control = g->getControl(name_part);
+ }
+ else
+ {
+ LL_INFOS() << "Setting Global." << name << " to " << value << LL_ENDL;
+ control = gSavedSettings.getControl(name);
+ }
+
+ if (control)
+ {
+ control->setValue(value, false);
+ return true;
+ }
+ return false;
+}
+
bool LLAppViewer::initConfiguration()
{
//Load settings files list
@@ -2471,12 +2512,7 @@ bool LLAppViewer::initConfiguration()
#ifndef LL_RELEASE_FOR_DOWNLOAD
// 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");
+ LLControlVariable* c = gSavedSettings.getControl("AllowMultipleViewers");
if (c)
{
c->setValue(true, false);
@@ -2582,9 +2618,10 @@ bool LLAppViewer::initConfiguration()
disableCrashlogger();
}
+ gNonInteractive = gSavedSettings.getBOOL("NonInteractive");
// Handle initialization from settings.
// Start up the debugging console before handling other options.
- if (gSavedSettings.getBOOL("ShowConsoleWindow"))
+ if (gSavedSettings.getBOOL("ShowConsoleWindow") && !gNonInteractive)
{
initConsole();
}
@@ -2617,31 +2654,7 @@ bool LLAppViewer::initConfiguration()
{
const std::string& name = *itr;
const std::string& value = *(++itr);
- std::string name_part;
- std::string group_part;
- LLControlVariable* control = NULL;
-
- // Name can be further split into ControlGroup.Name, with the default control group being Global
- size_t pos = name.find('.');
- if (pos != std::string::npos)
- {
- group_part = name.substr(0, pos);
- name_part = name.substr(pos+1);
- LL_INFOS() << "Setting " << group_part << "." << name_part << " to " << value << LL_ENDL;
- LLControlGroup* g = LLControlGroup::getInstance(group_part);
- if (g) control = g->getControl(name_part);
- }
- else
- {
- LL_INFOS() << "Setting Global." << name << " to " << value << LL_ENDL;
- control = gSavedSettings.getControl(name);
- }
-
- if (control)
- {
- control->setValue(value, false);
- }
- else
+ if (!tempSetControl(name,value))
{
LL_WARNS() << "Failed --set " << name << ": setting name unknown." << LL_ENDL;
}
@@ -2729,6 +2742,19 @@ bool LLAppViewer::initConfiguration()
}
}
+ if (gNonInteractive)
+ {
+ tempSetControl("AllowMultipleViewers", "TRUE");
+ tempSetControl("SLURLPassToOtherInstance", "FALSE");
+ tempSetControl("RenderWater", "FALSE");
+ tempSetControl("FlyingAtExit", "FALSE");
+ tempSetControl("WindowWidth", "1024");
+ tempSetControl("WindowHeight", "200");
+ LLError::setEnabledLogTypesMask(0);
+ llassert_always(!gSavedSettings.getBOOL("SLURLPassToOtherInstance"));
+ }
+
+
// Handle slurl use. NOTE: Don't let SL-55321 reappear.
// This initial-SLURL logic, up through the call to
// sendURLToOtherInstance(), must precede LLSplashScreen::show() --
@@ -3505,11 +3531,14 @@ void LLAppViewer::writeSystemInfo()
gDebugInfo["FirstRunThisInstall"] = gSavedSettings.getBOOL("FirstRunThisInstall");
gDebugInfo["StartupState"] = LLStartUp::getStartupStateString();
+ if (gViewerWindow)
+ {
std::vector<std::string> resolutions = gViewerWindow->getWindow()->getDisplaysResolutionList();
for (auto res_iter : resolutions)
{
gDebugInfo["DisplayInfo"].append(res_iter);
}
+ }
writeDebugInfo(); // Save out debug_info.log early, in case of crash.
}
@@ -4251,12 +4280,12 @@ bool LLAppViewer::initCache()
{
if (mPurgeCache)
{
- LLSplashScreen::update(LLTrans::getString("StartupClearingCache"));
- purgeCache();
+ LLSplashScreen::update(LLTrans::getString("StartupClearingCache"));
+ purgeCache();
// clear the new C++ file system based cache
LLDiskCache::getInstance()->clearCache();
- }
+ }
else
{
// purge excessive files from the new file system based cache
@@ -4283,12 +4312,12 @@ bool LLAppViewer::initCache()
LLVOCache::getInstance()->initCache(LL_PATH_CACHE, gSavedSettings.getU32("CacheNumberOfRegionsForObjects"), getObjectCacheVersion());
- return true;
+ return true;
}
void LLAppViewer::addOnIdleCallback(const boost::function<void()>& cb)
{
- LLDeferredTaskList::instance().addTask(cb);
+ gMainloopWork.post(cb);
}
void LLAppViewer::loadKeyBindings()
@@ -4690,6 +4719,20 @@ void LLAppViewer::idle()
LLDirPickerThread::clearDead();
F32 dt_raw = idle_timer.getElapsedTimeAndResetF32();
+ // Service the WorkQueue we use for replies from worker threads.
+ // Use function statics for the timeslice setting so we only have to fetch
+ // and convert MainWorkTime once.
+ static F32 MainWorkTimeRaw = gSavedSettings.getF32("MainWorkTime");
+ static F32Milliseconds MainWorkTimeMs(MainWorkTimeRaw);
+ // MainWorkTime is specified in fractional milliseconds, but std::chrono
+ // uses integer representations. What if we want less than a microsecond?
+ // Use nanoseconds. We're very sure we will never need to specify a
+ // MainWorkTime that would be larger than we could express in
+ // std::chrono::nanoseconds.
+ static std::chrono::nanoseconds MainWorkTimeNanoSec{
+ std::chrono::nanoseconds::rep(MainWorkTimeMs.value() * 1000000)};
+ gMainloopWork.runFor(MainWorkTimeNanoSec);
+
// Cap out-of-control frame times
// Too low because in menus, swapping, debugger, etc.
// Too high because idle called with no objects in view, etc.
@@ -5062,9 +5105,6 @@ void LLAppViewer::idle()
}
}
- // Execute deferred tasks.
- LLDeferredTaskList::instance().run();
-
// Handle shutdown process, for example,
// wait for floaters to close, send quit message,
// forcibly quit if it has taken too long
@@ -5471,19 +5511,6 @@ 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;