From 5caea1bcae24688bf3bbc3172a811bcccd4c3016 Mon Sep 17 00:00:00 2001
From: Xiaohong Bao <bao@lindenlab.com>
Date: Tue, 8 May 2012 16:02:24 -0600
Subject: [PATCH] For SH-3086. Make the fetch debugger not to stall the main
 thread.

---
 .../newview/llfloatertexturefetchdebugger.cpp |  70 ++--------
 indra/newview/lltexturefetch.cpp              | 120 +++++++++++++++---
 indra/newview/lltexturefetch.h                |  33 +++--
 3 files changed, 137 insertions(+), 86 deletions(-)

diff --git a/indra/newview/llfloatertexturefetchdebugger.cpp b/indra/newview/llfloatertexturefetchdebugger.cpp
index 02872f54a00..91573891877 100644
--- a/indra/newview/llfloatertexturefetchdebugger.cpp
+++ b/indra/newview/llfloatertexturefetchdebugger.cpp
@@ -134,46 +134,9 @@ void LLFloaterTextureFetchDebugger::setStartStatus(S32 status)
 	
 bool LLFloaterTextureFetchDebugger::idleStart()
 {
-	switch((LLTextureFetchDebugger::e_debug_state)mStartStatus)
-	{
-		case LLTextureFetchDebugger::IDLE:
-			break;
-		case LLTextureFetchDebugger::START_DEBUG:
-			mDebugger->startDebug();
-			break;
-		case LLTextureFetchDebugger::READ_CACHE:			
-			mDebugger->debugCacheRead();
-			break;
-		case LLTextureFetchDebugger::WRITE_CACHE:
-			mDebugger->debugCacheWrite();
-			break;
-		case LLTextureFetchDebugger::DECODING:
-			mDebugger->debugDecoder();
-			break;
-		case LLTextureFetchDebugger::HTTP_FETCHING:
-			mDebugger->debugHTTP();
-			break;
-		case LLTextureFetchDebugger::GL_TEX:
-			mDebugger->debugGLTextureCreation();
-			break;
-		case LLTextureFetchDebugger::REFETCH_VIS_CACHE:
-			mDebugger->debugRefetchVisibleFromCache();
-			break;
-		case LLTextureFetchDebugger::REFETCH_VIS_HTTP:
-			mDebugger->debugRefetchVisibleFromHTTP();
-			break;
-		case LLTextureFetchDebugger::REFETCH_ALL_CACHE:
-			mDebugger->debugRefetchAllFromCache();
-			break;
-		case LLTextureFetchDebugger::REFETCH_ALL_HTTP:
-			mDebugger->debugRefetchAllFromHTTP();
-			break;
-		default:
-			break;
-		}
-
 	if(mStartStatus != (S32)LLTextureFetchDebugger::IDLE)
 	{
+		mDebugger->startWork((LLTextureFetchDebugger::e_debug_state)mStartStatus);
 		mStartStatus = (S32)LLTextureFetchDebugger::IDLE;
 		return true;
 	}
@@ -188,13 +151,22 @@ void LLFloaterTextureFetchDebugger::idle()
 		return;
 	}
 
+	const F32 max_time = 0.005f; //5ms
 	LLTextureFetchDebugger::e_debug_state state = mDebugger->getState();	
-	if(mDebugger->update())
+	if(mDebugger->update(max_time))
 	{
 		switch(state)
 		{
 		case LLTextureFetchDebugger::IDLE:
 			break;
+		case LLTextureFetchDebugger::START_DEBUG:
+			mButtonStateMap["cacheread_btn"] = true;
+			mButtonStateMap["http_btn"] = true;
+			mButtonStateMap["refetchviscache_btn"] = true;
+			mButtonStateMap["refetchvishttp_btn"] = true;
+			mButtonStateMap["refetchallcache_btn"] = true;
+			mButtonStateMap["refetchallhttp_btn"] = true;
+			break;
 		case LLTextureFetchDebugger::READ_CACHE:			
 			mButtonStateMap["decode_btn"] = true;			
 			break;
@@ -243,26 +215,6 @@ void LLFloaterTextureFetchDebugger::onClickStart()
 
 	mButtonStateMap["start_btn"] = false;
 
-	//if(LLAppViewer::getTextureFetch()->canLoadFromCache())
-	//{
-	//	mButtonStateMap["cacheread_btn"] = true;
-	//	mButtonStateMap["http_btn"] = false;
-	//	mButtonStateMap["refetchviscache_btn"] = true;
-	//	mButtonStateMap["refetchvishttp_btn"] = false;
-	//	mButtonStateMap["refetchallcache_btn"] = true;
-	//	mButtonStateMap["refetchallhttp_btn"] = false;
-	//	mButtonStateMap["cachewrite_btn"] = false;
-	//}
-	//else
-	{
-		mButtonStateMap["cacheread_btn"] = true;
-		mButtonStateMap["http_btn"] = true;
-		mButtonStateMap["refetchviscache_btn"] = true;
-		mButtonStateMap["refetchvishttp_btn"] = true;
-		mButtonStateMap["refetchallcache_btn"] = true;
-		mButtonStateMap["refetchallhttp_btn"] = true;
-	}
-
 	updateButtons();
 }
 
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index 332b5e6f6a2..a4c8993ae6b 100755
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -3230,6 +3230,48 @@ void LLTextureFetchDebugger::init()
 	mClearHistory = FALSE;
 }
 
+void LLTextureFetchDebugger::startWork(e_debug_state state)
+{
+	switch(state)
+	{
+		case IDLE:
+			break;
+		case START_DEBUG:
+			startDebug();
+			break;
+		case READ_CACHE:			
+			debugCacheRead();
+			break;
+		case WRITE_CACHE:
+			debugCacheWrite();
+			break;
+		case DECODING:
+			debugDecoder();
+			break;
+		case HTTP_FETCHING:
+			debugHTTP();
+			break;
+		case GL_TEX:
+			debugGLTextureCreation();
+			break;
+		case REFETCH_VIS_CACHE:
+			debugRefetchVisibleFromCache();
+			break;
+		case REFETCH_VIS_HTTP:
+			debugRefetchVisibleFromHTTP();
+			break;
+		case REFETCH_ALL_CACHE:
+			debugRefetchAllFromCache();
+			break;
+		case REFETCH_ALL_HTTP:
+			debugRefetchAllFromHTTP();
+			break;
+		default:
+			break;
+	}
+	return;
+}
+
 void LLTextureFetchDebugger::startDebug()
 {
 	//lock the fetcher
@@ -3240,6 +3282,13 @@ void LLTextureFetchDebugger::startDebug()
 	//clear the current fetching queue
 	gTextureList.clearFetchingRequests();
 
+	mState = START_DEBUG;
+}
+
+bool LLTextureFetchDebugger::processStartDebug(F32 max_time)
+{
+	mTimer.reset();
+
 	//wait for all works to be done
 	while(1)
 	{
@@ -3251,6 +3300,11 @@ void LLTextureFetchDebugger::startDebug()
 		{
 			break;
 		}
+
+		if(mTimer.getElapsedTimeF32() > max_time)
+		{
+			return false;
+		}
 	}
 
 	//collect statistics
@@ -3289,6 +3343,8 @@ void LLTextureFetchDebugger::startDebug()
 	}
 
 	mNumFetchedTextures = fetched_textures.size();
+
+	return true;
 }
 
 void LLTextureFetchDebugger::tryToStopDebug()
@@ -3340,7 +3396,7 @@ void LLTextureFetchDebugger::tryToStopDebug()
 		break;
 	}
 
-	if(update())
+	if(update(0.005f))
 	{
 		//unlock the fetcher
 		mFetcher->lockFetcher(false);
@@ -3582,7 +3638,7 @@ void LLTextureFetchDebugger::debugGLTextureCreation()
 {
 	llassert_always(mState == IDLE);
 	mState = GL_TEX;
-	std::vector<LLViewerFetchedTexture*> tex_list;
+	mTempTexList.clear();
 
 	S32 size = mFetchingHistory.size();
 	for(S32 i = 0 ; i < size ; i++)
@@ -3593,30 +3649,54 @@ void LLTextureFetchDebugger::debugGLTextureCreation()
 			if(tex && !tex->isForSculptOnly())
 			{
 				tex->destroyGLTexture() ;
-				tex_list.push_back(tex);
+				mTempTexList.push_back(tex);
 			}
 		}
 	}
+	
+	mGLCreationTime = -1.f;
+	mTempIndex = 0;
+	mHistoryListIndex = 0;
+	
+	return;
+}
 
+bool LLTextureFetchDebugger::processGLCreation(F32 max_time)
+{
 	mTimer.reset();
-	mGLCreationTime = -1.f;
 
-	S32 j = 0 ;
-	S32 size1 = tex_list.size();
-	for(S32 i = 0 ; i < size && j < size1; i++)
+	bool done = true;
+	S32 size = mFetchingHistory.size();
+	S32 size1 = mTempTexList.size();
+	for(; mHistoryListIndex < size && mTempIndex < size1; mHistoryListIndex++)
 	{
-		if(mFetchingHistory[i].mRawImage.notNull())
+		if(mFetchingHistory[mHistoryListIndex].mRawImage.notNull())
 		{
-			if(mFetchingHistory[i].mID == tex_list[j]->getID())
+			if(mFetchingHistory[mHistoryListIndex].mID == mTempTexList[mTempIndex]->getID())
 			{
-				tex_list[j]->createGLTexture(mFetchingHistory[i].mDecodedLevel, mFetchingHistory[i].mRawImage, 0, TRUE, tex_list[j]->getBoostLevel());
-				j++;
+				mTempTexList[mTempIndex]->createGLTexture(mFetchingHistory[mHistoryListIndex].mDecodedLevel, 
+					mFetchingHistory[mHistoryListIndex].mRawImage, 0, TRUE, mTempTexList[mTempIndex]->getBoostLevel());
+				mTempIndex++;
 			}
 		}
+
+		if(mTimer.getElapsedTimeF32() > max_time)
+		{
+			done = false;
+			break;
+		}
 	}
 
-	mGLCreationTime = mTimer.getElapsedTimeF32() ;
-	return;
+	if(mGLCreationTime < 0.f)
+	{
+		mGLCreationTime = mTimer.getElapsedTimeF32() ;
+	}
+	else
+	{
+		mGLCreationTime += mTimer.getElapsedTimeF32() ;
+	}
+
+	return done;
 }
 
 //clear fetching results of all textures.
@@ -3740,10 +3820,16 @@ void LLTextureFetchDebugger::debugRefetchAllFromHTTP()
 	mRefetchNonVis = TRUE;
 }
 
-bool LLTextureFetchDebugger::update()
+bool LLTextureFetchDebugger::update(F32 max_time)
 {
 	switch(mState)
 	{
+	case START_DEBUG:
+		if(processStartDebug(max_time))
+		{
+			mState = IDLE;
+		}
+		break;
 	case READ_CACHE:
 		if(!mTextureCache->update(1))
 		{
@@ -3778,7 +3864,11 @@ bool LLTextureFetchDebugger::update()
 		}
 		break;
 	case GL_TEX:
-		mState = IDLE;
+		if(processGLCreation(max_time))
+		{
+			mState = IDLE;
+			mTempTexList.clear();
+		}
 		break;
 	case REFETCH_VIS_CACHE:
 		if (LLAppViewer::getTextureFetch()->getNumRequests() == 0)
diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h
index 436306398ed..d7677295c06 100644
--- a/indra/newview/lltexturefetch.h
+++ b/indra/newview/lltexturefetch.h
@@ -355,8 +355,12 @@ class LLTextureFetchDebugger
 	S32 mNbCurlCompleted;
 
 	std::map< LLPointer<LLViewerFetchedTexture>, std::vector<S32> > mRefetchList;
+	std::vector< LLPointer<LLViewerFetchedTexture> > mTempTexList;
+	S32 mTempIndex;
+	S32 mHistoryListIndex;
+
 public:
-	bool update(); //called in the main thread once per frame
+	bool update(F32 max_time); //called in the main thread once per frame
 
 	//fetching history
 	void clearHistory();
@@ -364,19 +368,10 @@ class LLTextureFetchDebugger
 	
 	void setCurlGetRequest(LLCurlRequest* request) { mCurlGetRequest = request;}
 	
-	void startDebug();
+	void startWork(e_debug_state state);
 	void setStopDebug() {mStopDebug = TRUE;}
 	void tryToStopDebug(); //stop everything
-	void debugCacheRead();
-	void debugCacheWrite();	
-	void debugHTTP();
-	void debugDecoder();
-	void debugGLTextureCreation();
-	void debugRefetchVisibleFromCache();
-	void debugRefetchVisibleFromHTTP();
-	void debugRefetchAllFromCache();
-	void debugRefetchAllFromHTTP();
-
+	
 	void callbackCacheRead(S32 id, bool success, LLImageFormatted* image,
 						   S32 imagesize, BOOL islocal);
 	void callbackCacheWrite(S32 id, bool success);
@@ -434,6 +429,20 @@ class LLTextureFetchDebugger
 	
 	S32 fillCurlQueue();
 
+	void startDebug();
+	void debugCacheRead();
+	void debugCacheWrite();	
+	void debugHTTP();
+	void debugDecoder();
+	void debugGLTextureCreation();
+	void debugRefetchVisibleFromCache();
+	void debugRefetchVisibleFromHTTP();
+	void debugRefetchAllFromCache();
+	void debugRefetchAllFromHTTP();
+
+	bool processStartDebug(F32 max_time);
+	bool processGLCreation(F32 max_time);
+
 private:
 	static bool sDebuggerEnabled;
 public:
-- 
GitLab