From 15fe4b3bbaf139960f934b629c236092182ed297 Mon Sep 17 00:00:00 2001
From: Xiaohong Bao <bao@lindenlab.com>
Date: Tue, 30 Jul 2013 22:05:12 -0600
Subject: fix for SH-4297: interesting: viewer-interesting starts loading
 cached scene late

---
 indra/newview/app_settings/settings.xml | 11 ++++++
 indra/newview/llviewerregion.cpp        | 64 ++++++++++++++++++++++++---------
 indra/newview/llviewerregion.h          |  4 +--
 indra/newview/llvocache.cpp             | 10 ++++--
 4 files changed, 69 insertions(+), 20 deletions(-)

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index f0be4e394e..2a4e10fb6f 100755
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -6295,6 +6295,17 @@
       <key>Value</key>
       <integer>130</integer>
     </map>
+    <key>NewObjectCreationThrottle</key>
+    <map>
+      <key>Comment</key>
+      <string>maximum number of new objects created per frame, -1 to disable this throttle</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>S32</string>
+      <key>Value</key>
+      <integer>64</integer>
+    </map>
     <key>NextOwnerCopy</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index cd8466d948..65e190a927 100755
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -71,6 +71,7 @@
 #include "llviewercontrol.h"
 #include "llsdserialize.h"
 #include "llvieweroctree.h"
+#include "llviewerdisplay.h"
 
 #ifdef LL_WINDOWS
 	#pragma warning(disable:4355)
@@ -992,8 +993,7 @@ void LLViewerRegion::removeFromVOCacheTree(LLVOCacheEntry* entry)
 		return;
 	}
 
-	mImpl->mVOCachePartition->removeEntry(entry->getEntry());
-	entry->mLastCameraUpdated = sLastCameraUpdated;
+	mImpl->mVOCachePartition->removeEntry(entry->getEntry());	
 }
 
 //add the visible entries
@@ -1128,7 +1128,7 @@ F32 LLViewerRegion::updateVisibleEntries(F32 max_time)
 	return 2.0f * max_time - update_timer.getElapsedTimeF32();
 }
 
-F32 LLViewerRegion::createVisibleObjects(F32 max_time)
+F32 LLViewerRegion::createVisibleObjects(F32 max_time, S32 throttle)
 {
 	if(mDead)
 	{
@@ -1139,8 +1139,7 @@ F32 LLViewerRegion::createVisibleObjects(F32 max_time)
 		return max_time;
 	}
 
-	LLTimer update_timer;
-	S32 max_num_objects = 64; //minimum number of new objects to be added
+	LLTimer update_timer;	
 	for(LLVOCacheEntry::vocache_entry_priority_list_t::iterator iter = mImpl->mWaitingList.begin();
 		iter != mImpl->mWaitingList.end(); ++iter)
 	{
@@ -1149,7 +1148,7 @@ F32 LLViewerRegion::createVisibleObjects(F32 max_time)
 		if(vo_entry->getState() < LLVOCacheEntry::WAITING)
 		{
 			addNewObject(vo_entry);
-			if(max_num_objects-- < 0 && update_timer.getElapsedTimeF32() > max_time)
+			if(throttle > 0 && !(--throttle) && update_timer.getElapsedTimeF32() > max_time)
 			{
 				break;
 			}
@@ -1161,6 +1160,8 @@ F32 LLViewerRegion::createVisibleObjects(F32 max_time)
 
 BOOL LLViewerRegion::idleUpdate(F32 max_update_time)
 {
+	static LLCachedControl<S32> new_object_creation_throttle(gSavedSettings,"NewObjectCreationThrottle");
+
 	LLTimer update_timer;
 
 	// did_update returns TRUE if we did at least one significant update
@@ -1171,23 +1172,54 @@ BOOL LLViewerRegion::idleUpdate(F32 max_update_time)
 		// Hopefully not a significant time sink...
 		mParcelOverlay->idleUpdate();
 	}
+	
+	if(!sVOCacheCullingEnabled)
+	{
+		return did_update;
+	}
+	if(mImpl->mCacheMap.empty())
+	{
+		return did_update;
+	}
+
+	max_update_time -= update_timer.getElapsedTimeF32();	
 
-	max_update_time -= update_timer.getElapsedTimeF32();
-	if(max_update_time < 0.f || mImpl->mCacheMap.empty())
+	//update the throttling number
+	static S32 throttle = new_object_creation_throttle;
+	if(LLStartUp::getStartupState() < STATE_STARTED || gTeleportDisplay)
 	{
-	return did_update;
-}
+		throttle = -1; //cancel the throttling
 
-	if(!sVOCacheCullingEnabled)
+		S32 occlusion = LLPipeline::sUseOcclusion;
+		LLPipeline::sUseOcclusion = 0; //disable occlusion
+		
+		//apply octree cullings here to pick up visible objects because rendering pipeline stops view culling at this moment
+		mImpl->mVOCachePartition->cull(*LLViewerCamera::getInstance());
+		
+		LLPipeline::sUseOcclusion = occlusion;
+	}	
+	else if(throttle < 0) //just recoved from the login/teleport screen
+	{
+		if(new_object_creation_throttle > 0)
+		{
+			throttle = 4096; //a big number
+		}
+	}
+	else
+	{
+		throttle = llmax((S32)new_object_creation_throttle, (S32)(throttle >> 1));
+	}
+
+	if(max_update_time < 0.f && throttle > 0 && throttle < new_object_creation_throttle * 2)
 	{
 		return did_update;
 	}
 
 	//kill invisible objects
-	max_update_time = killInvisibleObjects(max_update_time);	
+	max_update_time = killInvisibleObjects(max_update_time, throttle);	
 	
 	max_update_time = updateVisibleEntries(max_update_time);
-	createVisibleObjects(max_update_time);
+	createVisibleObjects(max_update_time, throttle);
 
 	mImpl->mWaitingList.clear();
 	mImpl->mVisibleGroups.clear();
@@ -1195,7 +1227,7 @@ BOOL LLViewerRegion::idleUpdate(F32 max_update_time)
 	return did_update;
 }
 
-F32 LLViewerRegion::killInvisibleObjects(F32 max_time)
+F32 LLViewerRegion::killInvisibleObjects(F32 max_time, S32 throttle)
 {
 #if 1
 	if(!sVOCacheCullingEnabled)
@@ -1209,7 +1241,7 @@ F32 LLViewerRegion::killInvisibleObjects(F32 max_time)
 
 	static LLVOCacheEntry* last_visited_entry = NULL;
 
-	const size_t MAX_UPDATE = 32; 
+	const size_t MAX_UPDATE = throttle < 0 ? mImpl->mActiveSet.size() : 64; 
 	std::vector<LLDrawable*> delete_list;
 	S32 update_counter = llmin(MAX_UPDATE, mImpl->mActiveSet.size());
 	LLVOCacheEntry::vocache_entry_set_t::iterator iter = mImpl->mActiveSet.upper_bound(last_visited_entry);	
@@ -1823,7 +1855,7 @@ void LLViewerRegion::decodeBoundingInfo(LLVOCacheEntry* entry)
 	else if(entry->getGroup() != NULL)
 	{
 		return; //already in octree, no post processing.
-	}
+	}	
 
 	LLVector3 pos;
 	LLVector3 scale;
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index 2ac934d19c..366462e22f 100755
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -370,8 +370,8 @@ private:
 	void replaceVisibleCacheEntry(LLVOCacheEntry* old_entry, LLVOCacheEntry* new_entry);
 	void killCacheEntry(LLVOCacheEntry* entry); //physically delete the cache entry	
 
-	F32 killInvisibleObjects(F32 max_time);
-	F32 createVisibleObjects(F32 max_time);
+	F32 killInvisibleObjects(F32 max_time, S32 throttle);
+	F32 createVisibleObjects(F32 max_time, S32 throttle);
 	F32 updateVisibleEntries(F32 max_time); //update visible entries
 
 	void addCacheMiss(U32 id, LLViewerRegion::eCacheMissType miss_type);
diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp
index 6e0243e985..d1c27edce7 100755
--- a/indra/newview/llvocache.cpp
+++ b/indra/newview/llvocache.cpp
@@ -219,15 +219,21 @@ void LLVOCacheEntry::setState(U32 state)
 
 	if(getState() == ACTIVE)
 	{
-		const S32 MIN_REAVTIVE_INTERVAL = 128;
+		const S32 MIN_INTERVAL = 64 + mMinFrameRange;
 		U32 last_visible = getVisible();
 		
 		setVisible();
 
-		if(getVisible() - last_visible > MIN_REAVTIVE_INTERVAL + mMinFrameRange)
+		U32 cur_visible = getVisible();
+		if(cur_visible - last_visible > MIN_INTERVAL ||
+			cur_visible < MIN_INTERVAL)
 		{
 			mLastCameraUpdated = 0; //reset
 		}
+		else
+		{
+			mLastCameraUpdated = LLViewerRegion::sLastCameraUpdated;
+		}
 	}
 }
 
-- 
cgit v1.2.3