diff options
| -rw-r--r-- | indra/linux_crash_logger/linux_crash_logger.cpp | 2 | ||||
| -rw-r--r-- | indra/linux_crash_logger/llcrashloggerlinux.cpp | 2 | ||||
| -rw-r--r-- | indra/linux_crash_logger/llcrashloggerlinux.h | 2 | ||||
| -rw-r--r-- | indra/llcommon/llapp.h | 8 | ||||
| -rw-r--r-- | indra/llcrashlogger/llcrashlogger.h | 2 | ||||
| -rw-r--r-- | indra/llwindow/llappdelegate-objc.h | 2 | ||||
| -rw-r--r-- | indra/llwindow/llwindowmacosx-objc.h | 2 | ||||
| -rw-r--r-- | indra/mac_crash_logger/llcrashloggermac.cpp | 2 | ||||
| -rw-r--r-- | indra/mac_crash_logger/llcrashloggermac.h | 2 | ||||
| -rw-r--r-- | indra/mac_crash_logger/mac_crash_logger.cpp | 2 | ||||
| -rw-r--r-- | indra/newview/llappdelegate-objc.mm | 24 | ||||
| -rw-r--r-- | indra/newview/llappviewer.cpp | 456 | ||||
| -rw-r--r-- | indra/newview/llappviewer.h | 3 | ||||
| -rw-r--r-- | indra/newview/llappviewerlinux.cpp | 6 | ||||
| -rw-r--r-- | indra/newview/llappviewermacosx.cpp | 9 | ||||
| -rw-r--r-- | indra/newview/llappviewerwin32.cpp | 6 | ||||
| -rw-r--r-- | indra/test/llapp_tut.cpp | 2 | ||||
| -rw-r--r-- | indra/win_crash_logger/llcrashloggerwindows.cpp | 8 | ||||
| -rw-r--r-- | indra/win_crash_logger/llcrashloggerwindows.h | 2 | ||||
| -rw-r--r-- | indra/win_crash_logger/win_crash_logger.cpp | 2 | 
20 files changed, 263 insertions, 281 deletions
| diff --git a/indra/linux_crash_logger/linux_crash_logger.cpp b/indra/linux_crash_logger/linux_crash_logger.cpp index 9d5ec33fed..63e5409876 100644 --- a/indra/linux_crash_logger/linux_crash_logger.cpp +++ b/indra/linux_crash_logger/linux_crash_logger.cpp @@ -51,7 +51,7 @@ int main(int argc, char **argv)  		return 1;  	} -	app.mainLoop(); +	app.frame();  	app.cleanup();  	LL_INFOS() << "Crash reporter finished normally." << LL_ENDL;  	return 0; diff --git a/indra/linux_crash_logger/llcrashloggerlinux.cpp b/indra/linux_crash_logger/llcrashloggerlinux.cpp index e2d2e7ff26..4092d43fc5 100644 --- a/indra/linux_crash_logger/llcrashloggerlinux.cpp +++ b/indra/linux_crash_logger/llcrashloggerlinux.cpp @@ -114,7 +114,7 @@ void LLCrashLoggerLinux::gatherPlatformSpecificFiles()  {  } -bool LLCrashLoggerLinux::mainLoop() +bool LLCrashLoggerLinux::frame()  {  	bool send_logs = true;  	if(CRASH_BEHAVIOR_ASK == getCrashBehavior()) diff --git a/indra/linux_crash_logger/llcrashloggerlinux.h b/indra/linux_crash_logger/llcrashloggerlinux.h index dae6c46651..789f6f03f5 100644 --- a/indra/linux_crash_logger/llcrashloggerlinux.h +++ b/indra/linux_crash_logger/llcrashloggerlinux.h @@ -36,7 +36,7 @@ class LLCrashLoggerLinux : public LLCrashLogger  public:  	LLCrashLoggerLinux(void);  	~LLCrashLoggerLinux(void); -	virtual bool mainLoop(); +	virtual bool frame();  	virtual void updateApplication(const std::string& = LLStringUtil::null);  	virtual void gatherPlatformSpecificFiles();  	virtual bool cleanup(); diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h index d9933b3d36..ff9a92b45f 100644 --- a/indra/llcommon/llapp.h +++ b/indra/llcommon/llapp.h @@ -172,12 +172,12 @@ public:  	virtual bool cleanup() = 0;			// Override to do application cleanup  	// -	// mainLoop() +	// frame()  	// -	// Runs the application main loop.  It's assumed that when you exit -	// this method, the application is in one of the cleanup states, either QUITTING or ERROR +	// Pass control to the application for a single frame. Returns 'done' +	// flag: if frame() returns false, it expects to be called again.  	// -	virtual bool mainLoop() = 0; // Override for the application main loop.  Needs to at least gracefully notice the QUITTING state and exit. +	virtual bool frame() = 0; // Override for application body logic  	//  	// Crash logging diff --git a/indra/llcrashlogger/llcrashlogger.h b/indra/llcrashlogger/llcrashlogger.h index 8b4afae24a..56e26c23ba 100644 --- a/indra/llcrashlogger/llcrashlogger.h +++ b/indra/llcrashlogger/llcrashlogger.h @@ -57,7 +57,7 @@ public:  	LLSD constructPostData();  	virtual void updateApplication(const std::string& message = LLStringUtil::null);  	virtual bool init(); -	virtual bool mainLoop() = 0; +	virtual bool frame() = 0;  	virtual bool cleanup() = 0;  	void commonCleanup();  	void setUserText(const std::string& text) { mCrashInfo["UserNotes"] = text; } diff --git a/indra/llwindow/llappdelegate-objc.h b/indra/llwindow/llappdelegate-objc.h index faa5d3abb7..6daf1ac55b 100644 --- a/indra/llwindow/llappdelegate-objc.h +++ b/indra/llwindow/llappdelegate-objc.h @@ -41,7 +41,7 @@  @property (retain) NSString *currentInputLanguage; -- (void) mainLoop; +- (void) oneFrame;  - (void) showInputWindow:(bool)show withEvent:(NSEvent*)textEvent;  - (void) languageUpdated;  - (bool) romanScript; diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h index c22f3382fb..b06cd2c184 100644 --- a/indra/llwindow/llwindowmacosx-objc.h +++ b/indra/llwindow/llwindowmacosx-objc.h @@ -69,7 +69,7 @@ typedef const NativeKeyEventData * NSKeyEventRef;  // These are defined in llappviewermacosx.cpp.  bool initViewer();  void handleQuit(); -bool runMainLoop(); +bool pumpMainLoop();  void initMainLoop();  void cleanupViewer();  void handleUrl(const char* url); diff --git a/indra/mac_crash_logger/llcrashloggermac.cpp b/indra/mac_crash_logger/llcrashloggermac.cpp index 3149fad6e8..ec3616e26a 100644 --- a/indra/mac_crash_logger/llcrashloggermac.cpp +++ b/indra/mac_crash_logger/llcrashloggermac.cpp @@ -64,7 +64,7 @@ void LLCrashLoggerMac::gatherPlatformSpecificFiles()  {  } -bool LLCrashLoggerMac::mainLoop() +bool LLCrashLoggerMac::frame()  {      if (mCrashBehavior == CRASH_BEHAVIOR_ALWAYS_SEND) diff --git a/indra/mac_crash_logger/llcrashloggermac.h b/indra/mac_crash_logger/llcrashloggermac.h index 6d8f63ecac..05ef8c9f53 100644 --- a/indra/mac_crash_logger/llcrashloggermac.h +++ b/indra/mac_crash_logger/llcrashloggermac.h @@ -37,7 +37,7 @@ public:  	LLCrashLoggerMac(void);  	~LLCrashLoggerMac(void);  	virtual bool init(); -	virtual bool mainLoop(); +	virtual bool frame();  	virtual bool cleanup();  	virtual void gatherPlatformSpecificFiles();  }; diff --git a/indra/mac_crash_logger/mac_crash_logger.cpp b/indra/mac_crash_logger/mac_crash_logger.cpp index 95d4e65207..54e41a1954 100644 --- a/indra/mac_crash_logger/mac_crash_logger.cpp +++ b/indra/mac_crash_logger/mac_crash_logger.cpp @@ -49,7 +49,7 @@ int main(int argc, char **argv)      {  //        return NSApplicationMain(argc, (const char **)argv);      } -	app.mainLoop(); +	app.frame();  	app.cleanup();  	LL_INFOS() << "Crash reporter finished normally." << LL_ENDL; diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm index 549df80fa1..be8877328d 100644 --- a/indra/newview/llappdelegate-objc.mm +++ b/indra/newview/llappdelegate-objc.mm @@ -48,16 +48,19 @@  - (void) applicationDidFinishLaunching:(NSNotification *)notification  {  	frameTimer = nil; -	 +  	[self languageUpdated]; -	 +  	if (initViewer())  	{ -		frameTimer = [NSTimer scheduledTimerWithTimeInterval:0.0 target:self selector:@selector(mainLoop) userInfo:nil repeats:YES]; +		// Set up recurring calls to oneFrame (repeating timer with timeout 0) +		// until applicationShouldTerminate. +		frameTimer = [NSTimer scheduledTimerWithTimeInterval:0.0 target:self +							  selector:@selector(oneFrame) userInfo:nil repeats:YES];  	} else {  		handleQuit();  	} -	 +  	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(languageUpdated) name:@"NSTextInputContextKeyboardSelectionDidChangeNotification" object:nil];   //   [[NSAppleEventManager sharedAppleEventManager] setEventHandler:self andSelector:@selector(handleGetURLEvent:withReplyEvent:) forEventClass:kInternetEventClass andEventID:kAEGetURL]; @@ -96,22 +99,29 @@  - (NSApplicationDelegateReply) applicationShouldTerminate:(NSApplication *)sender  { -	if (!runMainLoop()) +	// run one frame to assess state +	if (!pumpMainLoop())  	{ +		// pumpMainLoop() returns true when done, false if it wants to be +		// called again. Since it returned false, do not yet cancel +		// frameTimer.  		handleQuit();  		return NSTerminateCancel;  	} else { +		// pumpMainLoop() returned true: it's done. Okay, done with frameTimer.  		[frameTimer release];  		cleanupViewer();  		return NSTerminateNow;  	}  } -- (void) mainLoop +- (void) oneFrame  { -	bool appExiting = runMainLoop(); +	bool appExiting = pumpMainLoop();  	if (appExiting)  	{ +		// Once pumpMainLoop() reports that we're done, cancel frameTimer: +		// stop the repetitive calls.  		[frameTimer release];  		[[NSApplication sharedApplication] terminate:self];  	} diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index b6d02ea2f8..604e45f314 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -769,9 +769,6 @@ bool LLAppViewer::init()  	//  	// Start of the application  	// -#ifdef LL_DARWIN -	mMainLoopInitialized = false; -#endif  	// initialize LLWearableType translation bridge.  	// Memory will be cleaned up in ::cleanupClass() @@ -1220,6 +1217,23 @@ bool LLAppViewer::init()          boost::bind(&LLControlGroup::getU32, boost::ref(gSavedSettings), _1),          boost::bind(&LLControlGroup::declareU32, boost::ref(gSavedSettings), _1, _2, _3, LLControlVariable::PERSIST_ALWAYS)); +	/*----------------------------------------------------------------------*/ +	// nat 2016-06-29 moved the following here from the former mainLoop(). +	mMainloopTimeout = new LLWatchdogTimeout(); + +	// Create IO Pump to use for HTTP Requests. +	gServicePump = new LLPumpIO(gAPRPoolp); + +	// Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be instantiated. + +	LLVoiceChannel::initClass(); +	LLVoiceClient::getInstance()->init(gServicePump); +	LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLFloaterIMContainer::onCurrentChannelChanged, _1), true); + +	joystick = LLViewerJoystick::getInstance(); +	joystick->setNeedsReset(true); +	/*----------------------------------------------------------------------*/ +  	return true;  } @@ -1294,297 +1308,255 @@ static LLTrace::BlockTimerStatHandle FTM_AGENT_UPDATE("Update");  // externally visible timers  LLTrace::BlockTimerStatHandle FTM_FRAME("Frame"); -bool LLAppViewer::mainLoop() +bool LLAppViewer::frame()  { -#ifdef LL_DARWIN -	if (!mMainLoopInitialized) -#endif -	{ -        LL_INFOS() << "Entering main_loop" << LL_ENDL; -		mMainloopTimeout = new LLWatchdogTimeout(); -		 -		//------------------------------------------- -		// Run main loop until time to quit -		//------------------------------------------- -		 -		// Create IO Pump to use for HTTP Requests. -		gServicePump = new LLPumpIO(gAPRPoolp); -		 -		// Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be instantiated. -		 -		LLVoiceChannel::initClass(); -		LLVoiceClient::getInstance()->init(gServicePump); -		LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLFloaterIMContainer::onCurrentChannelChanged, _1), true); -		 -		joystick = LLViewerJoystick::getInstance(); -		joystick->setNeedsReset(true); -		 -#ifdef LL_DARWIN -		// Ensure that this section of code never gets called again on OS X. -		mMainLoopInitialized = true; -#endif -	} -	// As we do not (yet) send data on the mainloop LLEventPump that varies -	// with each frame, no need to instantiate a new LLSD event object each -	// time. Obviously, if that changes, just instantiate the LLSD at the -	// point of posting. -	  	LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop")); -	 -    LLSD newFrame; -	 +	LLSD newFrame; +  	LLTimer frameTimer,idleTimer;  	LLTimer debugTime; -	 +  	//LLPrivateMemoryPoolTester::getInstance()->run(false) ;  	//LLPrivateMemoryPoolTester::getInstance()->run(true) ;  	//LLPrivateMemoryPoolTester::destroy() ; -	// Handle messages -#ifdef LL_DARWIN -	if (!LLApp::isExiting()) -#else -	while (!LLApp::isExiting()) -#endif +	LL_RECORD_BLOCK_TIME(FTM_FRAME); +	LLTrace::BlockTimer::processTimes(); +	LLTrace::get_frame_recording().nextPeriod(); +	LLTrace::BlockTimer::logStats(); + +	LLTrace::get_thread_recorder()->pullFromChildren(); + +	//clear call stack records +	LL_CLEAR_CALLSTACKS(); + +	//check memory availability information +	checkMemory() ; + +	try  	{ -		LL_RECORD_BLOCK_TIME(FTM_FRAME); -		LLTrace::BlockTimer::processTimes(); -		LLTrace::get_frame_recording().nextPeriod(); -		LLTrace::BlockTimer::logStats(); +		pingMainloopTimeout("Main:MiscNativeWindowEvents"); + +		if (gViewerWindow) +		{ +			LL_RECORD_BLOCK_TIME(FTM_MESSAGES); +			gViewerWindow->getWindow()->processMiscNativeEvents(); +		} -		LLTrace::get_thread_recorder()->pullFromChildren(); +		pingMainloopTimeout("Main:GatherInput"); -		//clear call stack records -		LL_CLEAR_CALLSTACKS(); +		if (gViewerWindow) +		{ +			LL_RECORD_BLOCK_TIME(FTM_MESSAGES); +			if (!restoreErrorTrap()) +			{ +				LL_WARNS() << " Someone took over my signal/exception handler (post messagehandling)!" << LL_ENDL; +			} -		//check memory availability information -		checkMemory() ; +			gViewerWindow->getWindow()->gatherInput(); +		} + +#if 1 && !LL_RELEASE_FOR_DOWNLOAD +		// once per second debug info +		if (debugTime.getElapsedTimeF32() > 1.f) +		{ +			debugTime.reset(); +		} -		try +#endif +		//memory leaking simulation +		LLFloaterMemLeak* mem_leak_instance = +			LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking"); +		if(mem_leak_instance)  		{ -			pingMainloopTimeout("Main:MiscNativeWindowEvents"); +			mem_leak_instance->idle() ;				 +		}							 + +		// canonical per-frame event +		mainloop.post(newFrame); -			if (gViewerWindow) +		if (!LLApp::isExiting()) +		{ +			pingMainloopTimeout("Main:JoystickKeyboard"); + +			// Scan keyboard for movement keys.  Command keys and typing +			// are handled by windows callbacks.  Don't do this until we're +			// done initializing.  JC +			if ((gHeadlessClient || gViewerWindow->getWindow()->getVisible()) +				&& gViewerWindow->getActive() +				&& !gViewerWindow->getWindow()->getMinimized() +				&& LLStartUp::getStartupState() == STATE_STARTED +				&& (gHeadlessClient || !gViewerWindow->getShowProgress()) +				&& !gFocusMgr.focusLocked())  			{ -				LL_RECORD_BLOCK_TIME(FTM_MESSAGES); -				gViewerWindow->getWindow()->processMiscNativeEvents(); +				joystick->scanJoystick(); +				gKeyboard->scanKeyboard();  			} -		 -			pingMainloopTimeout("Main:GatherInput"); -			 -			if (gViewerWindow) + +			// Update state based on messages, user input, object idle.  			{ -				LL_RECORD_BLOCK_TIME(FTM_MESSAGES); -				if (!restoreErrorTrap()) -				{ -					LL_WARNS() << " Someone took over my signal/exception handler (post messagehandling)!" << LL_ENDL; -				} +				pauseMainloopTimeout(); // *TODO: Remove. Messages shouldn't be stalling for 20+ seconds! +				 +				LL_RECORD_BLOCK_TIME(FTM_IDLE); +				idle(); -				gViewerWindow->getWindow()->gatherInput(); +				resumeMainloopTimeout();  			} -#if 1 && !LL_RELEASE_FOR_DOWNLOAD -			// once per second debug info -			if (debugTime.getElapsedTimeF32() > 1.f) +			if (gDoDisconnect && (LLStartUp::getStartupState() == STATE_STARTED))  			{ -				debugTime.reset(); +				pauseMainloopTimeout(); +				saveFinalSnapshot(); +				disconnectViewer(); +				resumeMainloopTimeout();  			} -			 -#endif -			//memory leaking simulation -			LLFloaterMemLeak* mem_leak_instance = -				LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking"); -			if(mem_leak_instance) -			{ -				mem_leak_instance->idle() ;				 -			}							 - -            // canonical per-frame event -            mainloop.post(newFrame); -			if (!LLApp::isExiting()) +			// Render scene. +			// *TODO: Should we run display() even during gHeadlessClient?  DK 2011-02-18 +			if (!LLApp::isExiting() && !gHeadlessClient)  			{ -				pingMainloopTimeout("Main:JoystickKeyboard"); -				 -				// Scan keyboard for movement keys.  Command keys and typing -				// are handled by windows callbacks.  Don't do this until we're -				// done initializing.  JC -				if ((gHeadlessClient || gViewerWindow->getWindow()->getVisible()) -					&& gViewerWindow->getActive() -					&& !gViewerWindow->getWindow()->getMinimized() -					&& LLStartUp::getStartupState() == STATE_STARTED -					&& (gHeadlessClient || !gViewerWindow->getShowProgress()) -					&& !gFocusMgr.focusLocked()) -				{ -					joystick->scanJoystick(); -					gKeyboard->scanKeyboard(); -				} +				pingMainloopTimeout("Main:Display"); +				gGLActive = TRUE; +				display(); +				pingMainloopTimeout("Main:Snapshot"); +				LLFloaterSnapshot::update(); // take snapshots +				gGLActive = FALSE; +			} +		} -				// Update state based on messages, user input, object idle. -				{ -					pauseMainloopTimeout(); // *TODO: Remove. Messages shouldn't be stalling for 20+ seconds! -					 -					LL_RECORD_BLOCK_TIME(FTM_IDLE); -					idle(); +		pingMainloopTimeout("Main:Sleep"); -					resumeMainloopTimeout(); -				} -  -				if (gDoDisconnect && (LLStartUp::getStartupState() == STATE_STARTED)) -				{ -					pauseMainloopTimeout(); -					saveFinalSnapshot(); -					disconnectViewer(); -					resumeMainloopTimeout(); -				} +		pauseMainloopTimeout(); -				// Render scene. -				// *TODO: Should we run display() even during gHeadlessClient?  DK 2011-02-18 -				if (!LLApp::isExiting() && !gHeadlessClient) +		// Sleep and run background threads +		{ +			LL_RECORD_BLOCK_TIME(FTM_SLEEP); +			 +			// yield some time to the os based on command line option +			if(mYieldTime >= 0) +			{ +				LL_RECORD_BLOCK_TIME(FTM_YIELD); +				ms_sleep(mYieldTime); +			} + +			// yield cooperatively when not running as foreground window +			if (   (gViewerWindow && !gViewerWindow->getWindow()->getVisible()) +					|| !gFocusMgr.getAppHasFocus()) +			{ +				// Sleep if we're not rendering, or the window is minimized. +				S32 milliseconds_to_sleep = llclamp(gSavedSettings.getS32("BackgroundYieldTime"), 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)  				{ -					pingMainloopTimeout("Main:Display"); -					gGLActive = TRUE; -					display(); -					pingMainloopTimeout("Main:Snapshot"); -					LLFloaterSnapshot::update(); // take snapshots -					gGLActive = FALSE; +					ms_sleep(milliseconds_to_sleep); +					// also pause worker threads during this wait period +					LLAppViewer::getTextureCache()->pause(); +					LLAppViewer::getImageDecodeThread()->pause();  				}  			} - -			pingMainloopTimeout("Main:Sleep"); -			pauseMainloopTimeout(); +			if (mRandomizeFramerate) +			{ +				ms_sleep(rand() % 200); +			} -			// Sleep and run background threads +			if (mPeriodicSlowFrame +				&& (gFrameCount % 10 == 0))  			{ -				LL_RECORD_BLOCK_TIME(FTM_SLEEP); -				 -				// yield some time to the os based on command line option -				if(mYieldTime >= 0) -				{ -					LL_RECORD_BLOCK_TIME(FTM_YIELD); -					ms_sleep(mYieldTime); -				} +				LL_INFOS() << "Periodic slow frame - sleeping 500 ms" << LL_ENDL; +				ms_sleep(500); +			} + +			const F64Milliseconds max_idle_time = llmin(.005f*10.f*(F32Milliseconds)gFrameTimeSeconds, F32Milliseconds(5)); // 5 ms a second +			idleTimer.reset(); +			S32 total_work_pending = 0; +			S32 total_io_pending = 0;	 +			while(1) +			{ +				S32 work_pending = 0; +				S32 io_pending = 0; +				F32 max_time = llmin(gFrameIntervalSeconds.value() *10.f, 1.f); + +				work_pending += updateTextureThreads(max_time); -				// yield cooperatively when not running as foreground window -				if (   (gViewerWindow && !gViewerWindow->getWindow()->getVisible()) -						|| !gFocusMgr.getAppHasFocus())  				{ -					// Sleep if we're not rendering, or the window is minimized. -					S32 milliseconds_to_sleep = llclamp(gSavedSettings.getS32("BackgroundYieldTime"), 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) -					{ -						ms_sleep(milliseconds_to_sleep); -						// also pause worker threads during this wait period -						LLAppViewer::getTextureCache()->pause(); -						LLAppViewer::getImageDecodeThread()->pause(); -					} +					LL_RECORD_BLOCK_TIME(FTM_VFS); + 					io_pending += LLVFSThread::updateClass(1);  				} -				 -				if (mRandomizeFramerate)  				{ -					ms_sleep(rand() % 200); +					LL_RECORD_BLOCK_TIME(FTM_LFS); + 					io_pending += LLLFSThread::updateClass(1);  				} -				if (mPeriodicSlowFrame -					&& (gFrameCount % 10 == 0)) +				if (io_pending > 1000)  				{ -					LL_INFOS() << "Periodic slow frame - sleeping 500 ms" << LL_ENDL; -					ms_sleep(500); +					ms_sleep(llmin(io_pending/100,100)); // give the vfs some time to catch up  				} -				const F64Milliseconds max_idle_time = llmin(.005f*10.f*(F32Milliseconds)gFrameTimeSeconds, F32Milliseconds(5)); // 5 ms a second -				idleTimer.reset(); -				S32 total_work_pending = 0; -				S32 total_io_pending = 0;	 -				while(1) -				{ -					S32 work_pending = 0; -					S32 io_pending = 0; -					F32 max_time = llmin(gFrameIntervalSeconds.value() *10.f, 1.f); - -					work_pending += updateTextureThreads(max_time); - -					{ -						LL_RECORD_BLOCK_TIME(FTM_VFS); -	 					io_pending += LLVFSThread::updateClass(1); -					} -					{ -						LL_RECORD_BLOCK_TIME(FTM_LFS); -	 					io_pending += LLLFSThread::updateClass(1); -					} - -					if (io_pending > 1000) -					{ -						ms_sleep(llmin(io_pending/100,100)); // give the vfs some time to catch up -					} - -					total_work_pending += work_pending ; -					total_io_pending += io_pending ; -					 -					if (!work_pending || idleTimer.getElapsedTimeF64() >= max_idle_time) -					{ -						break; -					} -				} -				gMeshRepo.update() ; +				total_work_pending += work_pending ; +				total_io_pending += io_pending ; -				if(!total_work_pending) //pause texture fetching threads if nothing to process. +				if (!work_pending || idleTimer.getElapsedTimeF64() >= max_idle_time)  				{ -					LLAppViewer::getTextureCache()->pause(); -					LLAppViewer::getImageDecodeThread()->pause(); -					LLAppViewer::getTextureFetch()->pause();  -				} -				if(!total_io_pending) //pause file threads if nothing to process. -				{ -					LLVFSThread::sLocal->pause();  -					LLLFSThread::sLocal->pause();  -				}									 - -				//texture fetching debugger -				if(LLTextureFetchDebugger::isEnabled()) -				{ -					LLFloaterTextureFetchDebugger* tex_fetch_debugger_instance = -						LLFloaterReg::findTypedInstance<LLFloaterTextureFetchDebugger>("tex_fetch_debugger"); -					if(tex_fetch_debugger_instance) -					{ -						tex_fetch_debugger_instance->idle() ;				 -					} +					break;  				} +			} +			gMeshRepo.update() ; +			 +			if(!total_work_pending) //pause texture fetching threads if nothing to process. +			{ +				LLAppViewer::getTextureCache()->pause(); +				LLAppViewer::getImageDecodeThread()->pause(); +				LLAppViewer::getTextureFetch()->pause();  +			} +			if(!total_io_pending) //pause file threads if nothing to process. +			{ +				LLVFSThread::sLocal->pause();  +				LLLFSThread::sLocal->pause();  +			}									 -				if ((LLStartUp::getStartupState() >= STATE_CLEANUP) && -					(frameTimer.getElapsedTimeF64() > FRAME_STALL_THRESHOLD)) +			//texture fetching debugger +			if(LLTextureFetchDebugger::isEnabled()) +			{ +				LLFloaterTextureFetchDebugger* tex_fetch_debugger_instance = +					LLFloaterReg::findTypedInstance<LLFloaterTextureFetchDebugger>("tex_fetch_debugger"); +				if(tex_fetch_debugger_instance)  				{ -					gFrameStalls++; +					tex_fetch_debugger_instance->idle() ;				  				} -				frameTimer.reset(); - -				resumeMainloopTimeout(); -	 -				pingMainloopTimeout("Main:End"); -			}	 -		} -		catch(std::bad_alloc) -		{			 -			LLMemory::logMemoryInfo(TRUE) ; +			} -			//stop memory leaking simulation -			LLFloaterMemLeak* mem_leak_instance = -				LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking"); -			if(mem_leak_instance) +			if ((LLStartUp::getStartupState() >= STATE_CLEANUP) && +				(frameTimer.getElapsedTimeF64() > FRAME_STALL_THRESHOLD))  			{ -				mem_leak_instance->stop() ;				 -				LL_WARNS() << "Bad memory allocation in LLAppViewer::mainLoop()!" << LL_ENDL ; +				gFrameStalls++;  			} -			else -			{ -				//output possible call stacks to log file. -				LLError::LLCallStacks::print() ; +			frameTimer.reset(); -				LL_ERRS() << "Bad memory allocation in LLAppViewer::mainLoop()!" << LL_ENDL ; -			} +			resumeMainloopTimeout(); + +			pingMainloopTimeout("Main:End"); +		}	 +	} +	catch(std::bad_alloc) +	{			 +		LLMemory::logMemoryInfo(TRUE) ; + +		//stop memory leaking simulation +		LLFloaterMemLeak* mem_leak_instance = +			LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking"); +		if(mem_leak_instance) +		{ +			mem_leak_instance->stop() ;				 +			LL_WARNS() << "Bad memory allocation in LLAppViewer::frame()!" << LL_ENDL ; +		} +		else +		{ +			//output possible call stacks to log file. +			LLError::LLCallStacks::print() ; + +			LL_ERRS() << "Bad memory allocation in LLAppViewer::frame()!" << LL_ENDL ;  		}  	} @@ -1618,7 +1590,7 @@ bool LLAppViewer::mainLoop()  		LL_INFOS() << "Exiting main_loop" << LL_ENDL;  	} -	return LLApp::isExiting(); +	return ! LLApp::isRunning();  }  S32 LLAppViewer::updateTextureThreads(F32 max_time) diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index b5e674bd7b..f7c1bb58b4 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -79,7 +79,7 @@ public:  	//  	virtual bool init();			// Override to do application initialization  	virtual bool cleanup();			// Override to do application cleanup -	virtual bool mainLoop(); // Override for the application main loop.  Needs to at least gracefully notice the QUITTING state and exit. +	virtual bool frame(); // Override for application body logic  	// Application control  	void flushVFSIO(); // waits for vfs transfers to complete @@ -283,7 +283,6 @@ private:  	std::string mSerialNumber;  	bool mPurgeCache;      bool mPurgeOnExit; -	bool mMainLoopInitialized;  	LLViewerJoystick* joystick;  	bool mSavedFinalSnapshot; diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp index f5742b29cf..6f32aab851 100644 --- a/indra/newview/llappviewerlinux.cpp +++ b/indra/newview/llappviewerlinux.cpp @@ -95,10 +95,8 @@ int main( int argc, char **argv )  	}  		// Run the application main loop -	if(!LLApp::isQuitting())  -	{ -		viewer_app_ptr->mainLoop(); -	} +	while (! viewer_app_ptr->frame())  +	{}  	if (!LLApp::isError())  	{ diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp index ca219fda59..4fe1e31668 100644 --- a/indra/newview/llappviewermacosx.cpp +++ b/indra/newview/llappviewermacosx.cpp @@ -117,12 +117,17 @@ void handleQuit()  	LLAppViewer::instance()->userQuit();  } -bool runMainLoop() +// This function is called pumpMainLoop() rather than runMainLoop() because +// it passes control to the viewer's main-loop logic for a single frame. Like +// LLAppViewer::frame(), it returns 'true' when it's done. Until then, it +// expects to be called again by the timer in LLAppDelegate +// (llappdelegate-objc.mm). +bool pumpMainLoop()  {  	bool ret = LLApp::isQuitting();  	if (!ret && gViewerAppPtr != NULL)  	{ -		ret = gViewerAppPtr->mainLoop(); +		ret = gViewerAppPtr->frame();  	} else {  		ret = true;  	} diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index 4786f83bfd..a7f248ab5a 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -317,10 +317,8 @@ int APIENTRY WINMAIN(HINSTANCE hInstance,  	}  	// Run the application main loop -	if(!LLApp::isQuitting())  -	{ -		viewer_app_ptr->mainLoop(); -	} +	while (! viewer_app_ptr->frame())  +	{}  	if (!LLApp::isError())  	{ diff --git a/indra/test/llapp_tut.cpp b/indra/test/llapp_tut.cpp index aa5c0672e6..98e714a497 100644 --- a/indra/test/llapp_tut.cpp +++ b/indra/test/llapp_tut.cpp @@ -41,7 +41,7 @@ namespace tut  		public:  			virtual bool init() { return true; }  			virtual bool cleanup() { return true; } -			virtual bool mainLoop() { return true; } +			virtual bool frame() { return true; }  		};  		LLTestApp* mApp;  		application() diff --git a/indra/win_crash_logger/llcrashloggerwindows.cpp b/indra/win_crash_logger/llcrashloggerwindows.cpp index 23c29e6b18..167acf6ac7 100644 --- a/indra/win_crash_logger/llcrashloggerwindows.cpp +++ b/indra/win_crash_logger/llcrashloggerwindows.cpp @@ -454,7 +454,7 @@ void LLCrashLoggerWindows::gatherPlatformSpecificFiles()  	//mDebugLog["DisplayDeviceInfo"] = gDXHardware.getDisplayInfo();  //Not initialized.  } -bool LLCrashLoggerWindows::mainLoop() +bool LLCrashLoggerWindows::frame()  {	  	LL_INFOS() << "CrashSubmitBehavior is " << mCrashBehavior << LL_ENDL; @@ -503,14 +503,14 @@ bool LLCrashLoggerWindows::mainLoop()  			TranslateMessage(&msg);  			DispatchMessage(&msg);  		} -		return msg.wParam; +		return true; // msg.wParam;  	}  	else  	{  		LL_WARNS() << "Unknown crash behavior " << mCrashBehavior << LL_ENDL; -		return 1; +		return true; // 1;  	} -	return 0; +	return true; // 0;  }  void LLCrashLoggerWindows::updateApplication(const std::string& message) diff --git a/indra/win_crash_logger/llcrashloggerwindows.h b/indra/win_crash_logger/llcrashloggerwindows.h index 1812e2737e..f89b8708dc 100644 --- a/indra/win_crash_logger/llcrashloggerwindows.h +++ b/indra/win_crash_logger/llcrashloggerwindows.h @@ -46,7 +46,7 @@ public:  	static LLCrashLoggerWindows* sInstance;   	virtual bool init(); -	virtual bool mainLoop(); +	virtual bool frame();  	virtual void updateApplication(const std::string& message = LLStringUtil::null);  	virtual bool cleanup();  	virtual void gatherPlatformSpecificFiles(); diff --git a/indra/win_crash_logger/win_crash_logger.cpp b/indra/win_crash_logger/win_crash_logger.cpp index 366edd894b..7466dbb766 100644 --- a/indra/win_crash_logger/win_crash_logger.cpp +++ b/indra/win_crash_logger/win_crash_logger.cpp @@ -52,7 +52,7 @@ int APIENTRY WinMain(HINSTANCE hInstance,  	}  	app.processingLoop(); -	app.mainLoop(); +	app.frame();  	app.cleanup();  	LL_INFOS() << "Crash reporter finished normally." << LL_ENDL;  	return 0; | 
