diff options
Diffstat (limited to 'indra/newview/llappviewer.cpp')
| -rw-r--r-- | indra/newview/llappviewer.cpp | 358 | 
1 files changed, 206 insertions, 152 deletions
| diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index d8a584faae..f56ca8233e 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -232,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" @@ -362,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; @@ -377,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 @@ -563,7 +532,7 @@ static void settings_to_globals()  	LLSurface::setTextureSize(gSavedSettings.getU32("RegionTextureSize")); -	LLRender::sGLCoreProfile = gSavedSettings.getBOOL("RenderGLCoreProfile"); +	LLRender::sGLCoreProfile = gSavedSettings.getBOOL("RenderGLContextCoreProfile");  	LLRender::sNsightDebugSupport = gSavedSettings.getBOOL("RenderNsightDebugSupport");  	LLVertexBuffer::sUseVAO = gSavedSettings.getBOOL("RenderUseVAO");  	LLImageGL::sGlobalUseAnisotropic	= gSavedSettings.getBOOL("RenderAnisotropic"); @@ -599,8 +568,8 @@ 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"); +    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; @@ -668,6 +637,7 @@ LLAppViewer::LLAppViewer()  	mLogoutMarkerFile(),  	mReportedCrash(false),  	mNumSessions(0), +    mGeneralThreadPool(nullptr),  	mPurgeCache(false),  	mPurgeCacheOnExit(false),  	mPurgeUserDataOnExit(false), @@ -685,8 +655,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)  	{ @@ -855,8 +824,6 @@ bool LLAppViewer::init()  	LLNotifications::instance();  	LL_INFOS("InitInfo") << "Notifications initialized." << LL_ENDL ; -    writeSystemInfo(); -  	//////////////////////////////////////////////////////////////////////////////  	//////////////////////////////////////////////////////////////////////////////  	////////////////////////////////////////////////////////////////////////////// @@ -963,8 +930,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 @@ -973,6 +940,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"); @@ -987,26 +957,7 @@ bool LLAppViewer::init()  	// If we don't have the right GL requirements, exit.  	if (!gGLManager.mHasRequirements)  	{ -		// can't use an alert here since we're exiting and -		// all hell breaks lose. -		LLUIString details = LLNotifications::instance().getGlobalString("UnsupportedGLRequirements"); -		OSMessageBox( -			details.getString(), -			LLStringUtil::null, -			OSMB_OK); -		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); +        // already handled with a MBVideoDrvErr          return 0;      } @@ -1135,7 +1086,7 @@ bool LLAppViewer::init()  		{  			url = LLTrans::getString("NvidiaDriverPage");  		} -		else if (gGLManager.mIsATI) +		else if (gGLManager.mIsAMD)  		{  			url = LLTrans::getString("AMDDriverPage");  		} @@ -1318,13 +1269,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)      { @@ -1350,14 +1304,18 @@ void LLAppViewer::initMaxHeapSize()  	//------------------------------------------------------------------------------------------  	//currently SL is built under 32-bit setting, we set its max heap size no more than 1.6 GB. -	//F32 max_heap_size_gb = llmin(1.6f, (F32)gSavedSettings.getF32("MaxHeapSize")) ; + #ifndef LL_X86_64  	F32Gigabytes max_heap_size_gb = (F32Gigabytes)gSavedSettings.getF32("MaxHeapSize") ; +#else +    F32Gigabytes max_heap_size_gb = (F32Gigabytes)gSavedSettings.getF32("MaxHeapSize64"); +#endif  	LLMemory::initMaxHeapSizeGB(max_heap_size_gb);  }  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"); @@ -1418,13 +1376,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_CATEGORY_APP("df LLTrace"); +        if (LLFloaterReg::instanceVisible("block_timers")) +        {  	LLTrace::BlockTimer::processTimes(); +        } +          	LLTrace::get_frame_recording().nextPeriod();  	LLTrace::BlockTimer::logStats(); +	}  	LLTrace::get_thread_recorder()->pullFromChildren(); @@ -1432,6 +1403,7 @@ bool LLAppViewer::doFrame()  	LL_CLEAR_CALLSTACKS();  	{ +		LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df processMiscNativeEvents" )  		pingMainloopTimeout("Main:MiscNativeWindowEvents");  		if (gViewerWindow) @@ -1440,7 +1412,10 @@ bool LLAppViewer::doFrame()  			gViewerWindow->getWindow()->processMiscNativeEvents();  		} +		{ +			LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df gatherInput" )  		pingMainloopTimeout("Main:GatherInput"); +		}  		if (gViewerWindow)  		{ @@ -1464,13 +1439,21 @@ bool LLAppViewer::doFrame()  			}  		} +		{ +			LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df mainloop" )  		// canonical per-frame event  		mainloop.post(newFrame); +		} + +		{ +			LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df suspend" )  		// give listeners a chance to run  		llcoro::suspend(); +		}  		if (!LLApp::isExiting())  		{ +			LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df JoystickKeyboard" )  			pingMainloopTimeout("Main:JoystickKeyboard");  			// Scan keyboard for movement keys.  Command keys and typing @@ -1491,13 +1474,21 @@ bool LLAppViewer::doFrame()  			// Update state based on messages, user input, object idle.  			{ +				{ +					LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df pauseMainloopTimeout" )  				pauseMainloopTimeout(); // *TODO: Remove. Messages shouldn't be stalling for 20+ seconds! +				} -				LL_RECORD_BLOCK_TIME(FTM_IDLE); +				{ +					LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df idle"); //LL_RECORD_BLOCK_TIME(FTM_IDLE);  				idle(); +				} +				{ +					LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df resumeMainloopTimeout" )  				resumeMainloopTimeout();  			} +			}  			if (gDoDisconnect && (LLStartUp::getStartupState() == STATE_STARTED))  			{ @@ -1517,49 +1508,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_CATEGORY_APP( "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_CATEGORY_APP( "df Snapshot" )  				pingMainloopTimeout("Main:Snapshot");  				LLFloaterSnapshot::update(); // take snapshots  					LLFloaterOutfitSnapshot::update();  				gGLActive = FALSE;  			}  		} +		} +		{ +			LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "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() @@ -1567,8 +1560,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) @@ -1615,22 +1608,29 @@ bool LLAppViewer::doFrame()  				total_io_pending += io_pending ;  			} + +			{ +				LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df gMeshRepo" )  			gMeshRepo.update() ; +			}  			if(!total_work_pending) //pause texture fetching threads if nothing to process.  			{ +				LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "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_CATEGORY_APP( "df LLVFSThread" )  				LLLFSThread::sLocal->pause();  			}  			//texture fetching debugger  			if(LLTextureFetchDebugger::isEnabled())  			{ +				LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df tex_fetch_debugger_instance" )  				LLFloaterTextureFetchDebugger* tex_fetch_debugger_instance =  					LLFloaterReg::findTypedInstance<LLFloaterTextureFetchDebugger>("tex_fetch_debugger");  				if(tex_fetch_debugger_instance) @@ -1639,8 +1639,10 @@ bool LLAppViewer::doFrame()  				}  			} +			{ +				LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df resumeMainloopTimeout" )  			resumeMainloopTimeout(); - +			}  			pingMainloopTimeout("Main:End");  		}  	} @@ -1666,6 +1668,8 @@ bool LLAppViewer::doFrame()  		LL_INFOS() << "Exiting main_loop" << LL_ENDL;  	} +    LL_PROFILER_FRAME_END +  	return ! LLApp::isRunning();  } @@ -1751,6 +1755,7 @@ bool LLAppViewer::cleanup()      LLPluginProcessParent::shutdown();  	disconnectViewer(); +	LLViewerCamera::deleteSingleton();  	LL_INFOS() << "Viewer disconnected" << LL_ENDL; @@ -1946,7 +1951,7 @@ bool LLAppViewer::cleanup()      if (LLEnvironment::instanceExists())      { -        //Store environment settings if nessesary +		//Store environment settings if necessary          LLEnvironment::getInstance()->saveToSettings();      } @@ -2055,6 +2060,10 @@ bool LLAppViewer::cleanup()  	sTextureCache->shutdown();  	sImageDecodeThread->shutdown();  	sPurgeDiskCacheThread->shutdown(); +    if (mGeneralThreadPool) +    { +        mGeneralThreadPool->close(); +    }  	sTextureFetch->shutDownTextureCacheThread() ;  	sTextureFetch->shutDownImageDecodeThread() ; @@ -2079,6 +2088,8 @@ bool LLAppViewer::cleanup()  	mFastTimerLogThread = NULL;  	delete sPurgeDiskCacheThread;  	sPurgeDiskCacheThread = NULL; +    delete mGeneralThreadPool; +    mGeneralThreadPool = NULL;  	if (LLFastTimerView::sAnalyzePerformance)  	{ @@ -2137,12 +2148,15 @@ 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(); +    LLWorld::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 @@ -2162,6 +2176,24 @@ bool LLAppViewer::cleanup()  	return true;  } +void LLAppViewer::initGeneralThread() +{ +    if (mGeneralThreadPool) +    { +        return; +    } + +    LLSD poolSizes{ gSavedSettings.getLLSD("ThreadPoolSizes") }; +    LLSD sizeSpec{ poolSizes["General"] }; +    LLSD::Integer poolSize{ sizeSpec.isInteger() ? sizeSpec.asInteger() : 3 }; +    LL_DEBUGS("ThreadPool") << "Instantiating General pool with " +        << poolSize << " threads" << LL_ENDL; +    // We don't want anyone, especially the main thread, to have to block +    // due to this ThreadPool being full. +    mGeneralThreadPool = new LL::ThreadPool("General", poolSize, 1024 * 1024); +    mGeneralThreadPool->start(); +} +  bool LLAppViewer::initThreads()  {  	static const bool enable_threads = true; @@ -2325,7 +2357,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; @@ -2420,6 +2452,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 @@ -2470,12 +2534,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); @@ -2581,9 +2640,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();  	} @@ -2616,32 +2676,8 @@ 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 +                if (!tempSetControl(name,value))  				{ -					LL_INFOS() << "Setting Global." << name << " to " << value << LL_ENDL; -					control = gSavedSettings.getControl(name); -				} - -                if (control) -                { -                    control->setValue(value, false); -                } -                else -                {  					LL_WARNS() << "Failed --set " << name << ": setting name unknown." << LL_ENDL;                  }              } @@ -2728,6 +2764,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() -- @@ -3509,11 +3558,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.  } @@ -4292,7 +4344,7 @@ bool LLAppViewer::initCache()  void LLAppViewer::addOnIdleCallback(const boost::function<void()>& cb)  { -	LLDeferredTaskList::instance().addTask(cb); +	gMainloopWork.post(cb);  }  void LLAppViewer::loadKeyBindings() @@ -4562,6 +4614,7 @@ static LLTrace::BlockTimerStatHandle FTM_HUD_EFFECTS("HUD Effects");  ///////////////////////////////////////////////////////  void LLAppViewer::idle()  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_APP;  	pingMainloopTimeout("Main:Idle");  	// Update frame timers @@ -4580,6 +4633,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. @@ -4633,7 +4700,7 @@ void LLAppViewer::idle()  	if (!gDisconnected)  	{ -		LL_RECORD_BLOCK_TIME(FTM_NETWORK); +		LL_PROFILE_ZONE_NAMED_CATEGORY_NETWORK("network"); //LL_RECORD_BLOCK_TIME(FTM_NETWORK);  		// Update spaceserver timeinfo  	    LLWorld::getInstance()->setSpaceTimeUSec(LLWorld::getInstance()->getSpaceTimeUSec() + LLUnits::Seconds::fromValue(dt_raw)); @@ -4665,7 +4732,7 @@ void LLAppViewer::idle()  							|| (agent_force_update_time > (1.0f / (F32) AGENT_FORCE_UPDATES_PER_SECOND));  		if (force_update || (agent_update_time > (1.0f / (F32) AGENT_UPDATES_PER_SECOND)))  		{ -			LL_RECORD_BLOCK_TIME(FTM_AGENT_UPDATE); +			LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; //LL_RECORD_BLOCK_TIME(FTM_AGENT_UPDATE);  			// Send avatar and camera info  			mLastAgentControlFlags = gAgent.getControlFlags();  			mLastAgentForceUpdate = force_update ? 0 : agent_force_update_time; @@ -4902,8 +4969,10 @@ void LLAppViewer::idle()  	// Here, particles are updated and drawables are moved.  	// -	LL_RECORD_BLOCK_TIME(FTM_WORLD_UPDATE); +	{ +		LL_PROFILE_ZONE_NAMED_CATEGORY_APP("world update"); //LL_RECORD_BLOCK_TIME(FTM_WORLD_UPDATE);  	gPipeline.updateMove(); +	}  	LLWorld::getInstance()->updateParticles(); @@ -4942,7 +5011,7 @@ void LLAppViewer::idle()  	LLAvatarRenderInfoAccountant::getInstance()->idle();  	{ -		LL_RECORD_BLOCK_TIME(FTM_AUDIO_UPDATE); +		LL_PROFILE_ZONE_NAMED_CATEGORY_APP("audio update"); //LL_RECORD_BLOCK_TIME(FTM_AUDIO_UPDATE);  		if (gAudiop)  		{ @@ -4956,9 +5025,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 @@ -5186,6 +5252,7 @@ static LLTrace::BlockTimerStatHandle FTM_CHECK_REGION_CIRCUIT("Check Region Circ  void LLAppViewer::idleNetwork()  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;  	pingMainloopTimeout("idleNetwork");  	gObjectList.mNumNewObjects = 0; @@ -5193,7 +5260,7 @@ void LLAppViewer::idleNetwork()  	if (!gSavedSettings.getBOOL("SpeedTest"))  	{ -		LL_RECORD_BLOCK_TIME(FTM_IDLE_NETWORK); // decode +		LL_PROFILE_ZONE_NAMED_CATEGORY_NETWORK("idle network"); //LL_RECORD_BLOCK_TIME(FTM_IDLE_NETWORK); // decode  		LLTimer check_message_timer;  		//  Read all available packets from network @@ -5354,7 +5421,7 @@ void LLAppViewer::disconnectViewer()  	// Now we just ask the LLWorld singleton to cleanly shut down.  	if(LLWorld::instanceExists())  	{ -		LLWorld::getInstance()->destroyClass(); +		LLWorld::getInstance()->resetClass();  	}  	LLVOCache::deleteSingleton(); @@ -5369,19 +5436,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; | 
