From 4cca9ba279f908f206fa5e32adccf1038f05cc7f Mon Sep 17 00:00:00 2001
From: Xiaohong Bao <bao@lindenlab.com>
Date: Mon, 29 Jul 2013 10:15:10 -0600
Subject: [PATCH] fix for SH-4293: texture console takes a while to settle down
 on Interesting viewer.

---
 indra/llmath/llcamera.cpp        | 16 ++++++++++++++++
 indra/llmath/llcamera.h          |  2 ++
 indra/llmath/llplane.h           |  8 +++++++-
 indra/newview/llviewerregion.cpp |  4 +++-
 indra/newview/llviewerregion.h   |  1 +
 indra/newview/llvocache.cpp      | 10 +++-------
 indra/newview/llvocache.h        |  1 +
 indra/newview/llworld.cpp        |  5 +++++
 8 files changed, 38 insertions(+), 9 deletions(-)

diff --git a/indra/llmath/llcamera.cpp b/indra/llmath/llcamera.cpp
index 054afd3e959..6a1e3804be3 100755
--- a/indra/llmath/llcamera.cpp
+++ b/indra/llmath/llcamera.cpp
@@ -161,6 +161,22 @@ size_t LLCamera::readFrustumFromBuffer(const char *buffer)
 
 // ---------------- test methods  ---------------- 
 
+bool LLCamera::isChanged()
+{
+	bool changed = false;
+	for (U32 i = 0; i < mPlaneCount; i++)
+	{
+		U8 mask = mPlaneMask[i];
+		if (mask != 0xff && !changed)
+		{
+			changed = !mAgentPlanes[i].equal(mLastAgentPlanes[i]);
+		}
+		mLastAgentPlanes[i].set(mAgentPlanes[i]);
+	}
+
+	return changed;
+}
+
 S32 LLCamera::AABBInFrustum(const LLVector4a &center, const LLVector4a& radius, const LLPlane* planes) 
 {
 	static const LLVector4a scaler[] = {
diff --git a/indra/llmath/llcamera.h b/indra/llmath/llcamera.h
index 898d73ed7ee..a7cdcff4aca 100755
--- a/indra/llmath/llcamera.h
+++ b/indra/llmath/llcamera.h
@@ -110,6 +110,7 @@ class LLCamera
 private:
 	LL_ALIGN_16(LLPlane mAgentPlanes[7]);  //frustum planes in agent space a la gluUnproject (I'm a bastard, I know) - DaveP
 	LL_ALIGN_16(LLPlane mRegionPlanes[7]);  //frustum planes in a local region space, derived from mAgentPlanes
+	LL_ALIGN_16(LLPlane mLastAgentPlanes[7]);
 	U8 mPlaneMask[8];         // 8 for alignment	
 	
 	F32 mView;					// angle between top and bottom frustum planes in radians.
@@ -138,6 +139,7 @@ class LLCamera
 	LLCamera(F32 vertical_fov_rads, F32 aspect_ratio, S32 view_height_in_pixels, F32 near_plane, F32 far_plane);
 	virtual ~LLCamera();
 	
+	bool isChanged(); //check if mAgentPlanes changed since last frame.
 
 	void setUserClipPlane(LLPlane& plane);
 	void disableUserClipPlane();
diff --git a/indra/llmath/llplane.h b/indra/llmath/llplane.h
index 3c32441b118..64a3eed0e53 100755
--- a/indra/llmath/llplane.h
+++ b/indra/llmath/llplane.h
@@ -93,7 +93,13 @@ class LLPlane
 	{ 
 		return mV.greaterEqual(LLVector4a::getZero()).getGatheredBits() & LLVector4Logical::MASK_XYZ;
 	}
-		
+	
+	//check if two planes are nearly same
+	bool equal(const LLPlane& p) const
+	{
+		return mV.equals4(p.mV);
+	}
+
 private:
 	LLVector4a mV;
 } LL_ALIGN_POSTFIX(16);
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index b80d87ef075..cd8466d948c 100755
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -87,6 +87,7 @@ const F32 CAP_REQUEST_TIMEOUT = 18;
 const S32 MAX_CAP_REQUEST_ATTEMPTS = 30;
 
 BOOL LLViewerRegion::sVOCacheCullingEnabled = FALSE;
+S32  LLViewerRegion::sLastCameraUpdated = 0;
 
 typedef std::map<std::string, std::string> CapabilityMap;
 
@@ -992,6 +993,7 @@ void LLViewerRegion::removeFromVOCacheTree(LLVOCacheEntry* entry)
 	}
 
 	mImpl->mVOCachePartition->removeEntry(entry->getEntry());
+	entry->mLastCameraUpdated = sLastCameraUpdated;
 }
 
 //add the visible entries
@@ -1219,7 +1221,7 @@ F32 LLViewerRegion::killInvisibleObjects(F32 max_time)
 			iter = mImpl->mActiveSet.begin();
 		}
 
-		if(!(*iter)->isRecentlyVisible())
+		if(!(*iter)->isRecentlyVisible() && (*iter)->mLastCameraUpdated != sLastCameraUpdated)
 		{
 			killObject((*iter), delete_list);
 		}
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index 29483662e87..2ac934d19c6 100755
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -411,6 +411,7 @@ class LLViewerRegion: public LLCapabilityProvider // implements this interface
 	LLDynamicArray<LLUUID> mMapAvatarIDs;
 
 	static BOOL sVOCacheCullingEnabled; //vo cache culling enabled or not.
+	static S32  sLastCameraUpdated;
 private:
 	LLViewerRegionImpl * mImpl;
 	LLFrameTimer         mRegionTimer;
diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp
index 69c32db13e6..6e0243e9850 100755
--- a/indra/newview/llvocache.cpp
+++ b/indra/newview/llvocache.cpp
@@ -219,18 +219,14 @@ void LLVOCacheEntry::setState(U32 state)
 
 	if(getState() == ACTIVE)
 	{
-		const S32 MIN_REAVTIVE_INTERVAL = 32;
+		const S32 MIN_REAVTIVE_INTERVAL = 128;
 		U32 last_visible = getVisible();
 		
 		setVisible();
 
-		if(getVisible() - last_visible < MIN_REAVTIVE_INTERVAL + mMinFrameRange)
+		if(getVisible() - last_visible > MIN_REAVTIVE_INTERVAL + mMinFrameRange)
 		{
-			mMinFrameRange = llmin(mMinFrameRange * 2, getInvisibleObjectsLiveTime() * 32);
-		}
-		else
-		{
-			mMinFrameRange = getInvisibleObjectsLiveTime(); //reset
+			mLastCameraUpdated = 0; //reset
 		}
 	}
 }
diff --git a/indra/newview/llvocache.h b/indra/newview/llvocache.h
index 0248298eb57..816ef88dc42 100755
--- a/indra/newview/llvocache.h
+++ b/indra/newview/llvocache.h
@@ -130,6 +130,7 @@ class LLVOCacheEntry : public LLViewerOctreeEntryData
 	typedef std::set<LLVOCacheEntry*>                      vocache_entry_set_t;
 	typedef std::set<LLVOCacheEntry*, CompareVOCacheEntry> vocache_entry_priority_list_t;	
 
+	S32                         mLastCameraUpdated;
 protected:
 	U32							mLocalID;
 	U32                         mParentID;
diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp
index 3dfe4c5e5f9..ea0e38824bd 100755
--- a/indra/newview/llworld.cpp
+++ b/indra/newview/llworld.cpp
@@ -666,6 +666,11 @@ void LLWorld::updateRegions(F32 max_update_time)
 	LLTimer update_timer;
 	BOOL did_one = FALSE;
 	
+	if(LLViewerCamera::getInstance()->isChanged())
+	{
+		LLViewerRegion::sLastCameraUpdated = LLViewerOctreeEntryData::getCurrentFrame();
+	}
+
 	// Perform idle time updates for the regions (and associated surfaces)
 	for (region_list_t::iterator iter = mRegionList.begin();
 		 iter != mRegionList.end(); ++iter)
-- 
GitLab