From 7378259aa551c395b67e40196487584eaf5e8007 Mon Sep 17 00:00:00 2001
From: Xiaohong Bao <bao@lindenlab.com>
Date: Tue, 15 Jan 2013 14:14:29 -0700
Subject: for SH-3667: Create an extendable recording tied to scene load time

---
 indra/newview/llagent.cpp        |  8 ++++++++
 indra/newview/llagent.h          |  2 ++
 indra/newview/llscenemonitor.cpp | 23 ++++++++++++++++++++++-
 indra/newview/llscenemonitor.h   |  5 +++++
 4 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 14235bcee4..24c9da8e17 100755
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -1046,6 +1046,14 @@ const LLVector3d &LLAgent::getPositionGlobal() const
 	return mPositionGlobal;
 }
 
+bool LLAgent::isPositionChanged() const
+{
+	LLVector3d diff;
+	diff = mPositionGlobal - mLastPositionGlobal;
+	
+	return diff.lengthSquared() > 1.0;
+}
+
 //-----------------------------------------------------------------------------
 // getPositionAgent()
 //-----------------------------------------------------------------------------
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index 99904e118c..a1e899b45d 100644
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -250,6 +250,8 @@ public:
 	
 	const LLVector3d &getLastPositionGlobal() const { return mLastPositionGlobal; }
 	void			setLastPositionGlobal(const LLVector3d &pos) { mLastPositionGlobal = pos; }
+
+	bool            isPositionChanged() const;
 private:
 	std::set<U64>	mRegionsVisited;		// Stat - what distinct regions has the avatar been to?
 	F64				mDistanceTraveled;		// Stat - how far has the avatar moved?
diff --git a/indra/newview/llscenemonitor.cpp b/indra/newview/llscenemonitor.cpp
index 4872200f24..7a960f7baa 100644
--- a/indra/newview/llscenemonitor.cpp
+++ b/indra/newview/llscenemonitor.cpp
@@ -37,6 +37,7 @@
 #include "llwindow.h"
 #include "llpointer.h"
 #include "llspatialpartition.h"
+#include "llagent.h"
 
 LLSceneMonitorView* gSceneMonitorView = NULL;
 
@@ -67,7 +68,10 @@ LLSceneMonitor::LLSceneMonitor() :
 	mDiffPixelRatio(0.5f)
 {
 	mFrames[0] = NULL;
-	mFrames[1] = NULL;	
+	mFrames[1] = NULL;
+
+	mRecording = new LLTrace::ExtendableRecording();
+	mRecording->start();
 }
 
 LLSceneMonitor::~LLSceneMonitor()
@@ -78,6 +82,9 @@ LLSceneMonitor::~LLSceneMonitor()
 void LLSceneMonitor::destroyClass()
 {
 	reset();
+
+	delete mRecording;
+	mRecording = NULL;
 }
 
 void LLSceneMonitor::reset()
@@ -137,6 +144,11 @@ bool LLSceneMonitor::preCapture()
 		return false;
 	}
 
+	if(gAgent.isPositionChanged())
+	{
+		mRecording->reset();
+	}
+
 	if(timer.getElapsedTimeF32() < mSamplingTime)
 	{
 		return false;
@@ -388,6 +400,10 @@ void LLSceneMonitor::fetchQueryResult()
 	
 	mDiffResult = count * 0.5f / (mDiff->getWidth() * mDiff->getHeight() * mDiffPixelRatio * mDiffPixelRatio); //0.5 -> (front face + back face)
 
+	if(mDiffResult > 0.01f)
+	{
+		mRecording->extend();
+	}
 	//llinfos << count << " : " << mDiffResult << llendl;
 }
 //-------------------------------------------------------------------------------------------------------------
@@ -454,6 +470,11 @@ void LLSceneMonitorView::draw()
 
 	num_str = llformat("Sampling time: %.3f seconds", LLSceneMonitor::getInstance()->getSamplingTime());
 	LLFontGL::getFontMonospace()->renderUTF8(num_str, 0, 5, getRect().getHeight() - line_height * lines, color, LLFontGL::LEFT, LLFontGL::TOP);
+	lines++;
+
+	num_str = llformat("Scene Loading time: %.3f seconds", (F32)LLSceneMonitor::getInstance()->getRecording()->getAcceptedRecording().getDuration().value());
+	LLFontGL::getFontMonospace()->renderUTF8(num_str, 0, 5, getRect().getHeight() - line_height * lines, color, LLFontGL::LEFT, LLFontGL::TOP);
+	lines++;
 
 	LLView::draw();
 }
diff --git a/indra/newview/llscenemonitor.h b/indra/newview/llscenemonitor.h
index 02e3d57d46..93e6c20bb9 100644
--- a/indra/newview/llscenemonitor.h
+++ b/indra/newview/llscenemonitor.h
@@ -31,6 +31,7 @@
 #include "llmath.h"
 #include "llfloater.h"
 #include "llcharacter.h"
+#include "lltracerecording.h"
 
 class LLCharacter;
 class LLRenderTarget;
@@ -61,6 +62,8 @@ public:
 	bool isEnabled()const {return mEnabled;}
 	bool needsUpdate() const;
 	
+	LLTrace::ExtendableRecording* getRecording() const {return mRecording;}
+
 private:
 	void freezeScene();
 	void unfreezeScene();
@@ -86,6 +89,8 @@ private:
 	F32     mDiffPixelRatio; //ratio of pixels used for comparison against the original mDiff size along one dimension
 
 	std::vector<LLAnimPauseRequest> mAvatarPauseHandles;
+
+	LLTrace::ExtendableRecording* mRecording;
 };
 
 class LLSceneMonitorView : public LLFloater
-- 
cgit v1.2.3


From 970fbdbeb80f20811fb286f6731b854f9b20a76e Mon Sep 17 00:00:00 2001
From: Xiaohong Bao <bao@lindenlab.com>
Date: Tue, 15 Jan 2013 20:28:05 -0700
Subject: a minor change to LLTrace::ExtendableRecording, make its functions
 public.

---
 indra/llcommon/lltracerecording.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/indra/llcommon/lltracerecording.h b/indra/llcommon/lltracerecording.h
index aa3200e5ad..5105874ba1 100644
--- a/indra/llcommon/lltracerecording.h
+++ b/indra/llcommon/lltracerecording.h
@@ -390,6 +390,7 @@ namespace LLTrace
 	class ExtendableRecording
 	:	public LLStopWatchControlsMixin<ExtendableRecording>
 	{
+	public:
 		void extend();
 
 		// implementation for LLStopWatchControlsMixin
@@ -401,6 +402,8 @@ namespace LLTrace
 		/*virtual*/ void reset();
 		/*virtual*/ void splitTo(ExtendableRecording& other);
 		/*virtual*/ void splitFrom(ExtendableRecording& other);
+
+		const Recording& getAcceptedRecording() const {return mAcceptedRecording;}
 	private:
 		Recording mAcceptedRecording;
 		Recording mPotentialRecording;
-- 
cgit v1.2.3


From 45a7fe901aa4cd7af14fa1cb894da46a988e3aa2 Mon Sep 17 00:00:00 2001
From: Xiaohong Bao <bao@lindenlab.com>
Date: Tue, 15 Jan 2013 23:01:40 -0700
Subject: for SH-3653: Can we repurpose
 ObjectUpdateCached:ObjectData:UpdateFlags field to carry spatial+size data?

---
 indra/newview/llviewerobjectlist.cpp |  4 +-
 indra/newview/llviewerregion.cpp     | 81 ++++++++++++++++--------------------
 indra/newview/llviewerregion.h       | 35 ++++++++++++++--
 3 files changed, 70 insertions(+), 50 deletions(-)

diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index 0335cd769b..dce963c5c5 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -657,13 +657,15 @@ void LLViewerObjectList::processCachedObjectUpdate(LLMessageSystem *mesgsys,
 		S32	msg_size = 0;
 		U32 id;
 		U32 crc;
+		U32 flags;
 		mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, id, i);
 		mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_CRC, crc, i);
+		mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, i);
 		msg_size += sizeof(U32) * 2;
 		
 		// Lookup data packer and add this id to cache miss lists if necessary.
 		U8 cache_miss_type = LLViewerRegion::CACHE_MISS_TYPE_NONE;
-		if(!regionp->probeCache(id, crc, cache_miss_type))
+		if(!regionp->probeCache(id, crc, flags, cache_miss_type))
 		{
 			// Cache Miss.
 			recorder.cacheMissEvent(id, update_type, cache_miss_type, msg_size);
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 7d2e08c1c6..f44c8ffe46 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -1718,9 +1718,26 @@ LLVOCacheEntry* LLViewerRegion::getCacheEntry(U32 local_id)
 	return NULL;
 }
 
+//estimate weight of cache missed object
+F32 LLViewerRegion::calcObjectWeight(U32 flags)
+{
+	LLVector3 pos((F32)(flags & 0xff), (F32)((flags >> 8) & 0xff), (F32)((flags >> 16) & 0xff) * 16.f);
+	F32 rad = (F32)((flags >> 24) & 0xff);
+
+	pos += getOriginAgent();
+	pos -= LLViewerCamera::getInstance()->getOrigin();
+
+	return rad * rad / pos.lengthSquared();
+}
+
+void LLViewerRegion::addCacheMiss(U32 id, LLViewerRegion::eCacheMissType miss_type, F32 weight)
+{
+	mCacheMissList.insert(CacheMissItem(id, miss_type, weight));
+}
+
 // Get data packer for this object, if we have cached data
 // AND the CRC matches. JC
-bool LLViewerRegion::probeCache(U32 local_id, U32 crc, U8 &cache_miss_type)
+bool LLViewerRegion::probeCache(U32 local_id, U32 crc, U32 flags, U8 &cache_miss_type)
 {
 	//llassert(mCacheLoaded);  This assert failes often, changing to early-out -- davep, 2010/10/18
 
@@ -1746,15 +1763,14 @@ bool LLViewerRegion::probeCache(U32 local_id, U32 crc, U8 &cache_miss_type)
 		else
 		{
 			// llinfos << "CRC miss for " << local_id << llendl;
-			cache_miss_type = CACHE_MISS_TYPE_CRC;
-			mCacheMissCRC.put(local_id);
+
+			addCacheMiss(local_id, CACHE_MISS_TYPE_CRC, calcObjectWeight(flags));
 		}
 	}
 	else
 	{
 		// llinfos << "Cache miss for " << local_id << llendl;
-		cache_miss_type = CACHE_MISS_TYPE_FULL;
-		mCacheMissFull.put(local_id);
+		addCacheMiss(local_id, CACHE_MISS_TYPE_FULL, calcObjectWeight(flags));
 	}
 
 	return false;
@@ -1762,49 +1778,22 @@ bool LLViewerRegion::probeCache(U32 local_id, U32 crc, U8 &cache_miss_type)
 
 void LLViewerRegion::addCacheMissFull(const U32 local_id)
 {
-	mCacheMissFull.put(local_id);
+	addCacheMiss(local_id, CACHE_MISS_TYPE_FULL, 100.f);
 }
 
 void LLViewerRegion::requestCacheMisses()
 {
-	S32 full_count = mCacheMissFull.count();
-	S32 crc_count = mCacheMissCRC.count();
-	if (full_count == 0 && crc_count == 0) return;
+	if (!mCacheMissList.size()) 
+	{
+		return;
+	}
 
 	LLMessageSystem* msg = gMessageSystem;
 	BOOL start_new_message = TRUE;
 	S32 blocks = 0;
-	S32 i;
-
-	// Send full cache miss updates.  For these, we KNOW we don't
-	// have a viewer object.
-	for (i = 0; i < full_count; i++)
-	{
-		if (start_new_message)
-		{
-			msg->newMessageFast(_PREHASH_RequestMultipleObjects);
-			msg->nextBlockFast(_PREHASH_AgentData);
-			msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-			msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-			start_new_message = FALSE;
-		}
-
-		msg->nextBlockFast(_PREHASH_ObjectData);
-		msg->addU8Fast(_PREHASH_CacheMissType, CACHE_MISS_TYPE_FULL);
-		msg->addU32Fast(_PREHASH_ID, mCacheMissFull[i]);
-		blocks++;
-
-		if (blocks >= 255)
-		{
-			sendReliableMessage();
-			start_new_message = TRUE;
-			blocks = 0;
-		}
-	}
-
-	// Send CRC miss updates.  For these, we _might_ have a viewer object,
-	// but probably not.
-	for (i = 0; i < crc_count; i++)
+	
+	//send requests for all cache-missed objects
+	for (CacheMissItem::cache_miss_list_t::iterator iter = mCacheMissList.begin(); iter != mCacheMissList.end(); ++iter)
 	{
 		if (start_new_message)
 		{
@@ -1816,8 +1805,8 @@ void LLViewerRegion::requestCacheMisses()
 		}
 
 		msg->nextBlockFast(_PREHASH_ObjectData);
-		msg->addU8Fast(_PREHASH_CacheMissType, CACHE_MISS_TYPE_CRC);
-		msg->addU32Fast(_PREHASH_ID, mCacheMissCRC[i]);
+		msg->addU8Fast(_PREHASH_CacheMissType, (*iter).mType);
+		msg->addU32Fast(_PREHASH_ID, (*iter).mID);
 		blocks++;
 
 		if (blocks >= 255)
@@ -1832,14 +1821,14 @@ void LLViewerRegion::requestCacheMisses()
 	if (!start_new_message)
 	{
 		sendReliableMessage();
-	}
-	mCacheMissFull.reset();
-	mCacheMissCRC.reset();
+	}	
 
 	mCacheDirty = TRUE ;
 	// llinfos << "KILLDEBUG Sent cache miss full " << full_count << " crc " << crc_count << llendl;
-	LLViewerStatsRecorder::instance().requestCacheMissesEvent(full_count + crc_count);
+	LLViewerStatsRecorder::instance().requestCacheMissesEvent(mCacheMissList.size());
 	LLViewerStatsRecorder::instance().log(0.2f);
+
+	mCacheMissList.clear();
 }
 
 void LLViewerRegion::dumpCache()
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index 9252923aa3..4f0087ba7c 100644
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -169,6 +169,9 @@ public:
 	const LLVector3d &getOriginGlobal() const;
 	LLVector3 getOriginAgent() const;
 
+	//estimate weight of cache missed object
+	F32 calcObjectWeight(U32 flags);
+
 	// Center is at the height of the water table.
 	const LLVector3d &getCenterGlobal() const;
 	LLVector3 getCenterAgent() const;
@@ -316,7 +319,7 @@ public:
 	// handle a full update message
 	eCacheUpdateResult cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp);	
 	LLVOCacheEntry* getCacheEntryForOctree(U32 local_id);
-	bool probeCache(U32 local_id, U32 crc, U8 &cache_miss_type);
+	bool probeCache(U32 local_id, U32 crc, U32 flags, U8 &cache_miss_type);
 	void requestCacheMisses();
 	void addCacheMissFull(const U32 local_id);
 
@@ -356,6 +359,7 @@ private:
 	F32 createVisibleObjects(F32 max_time);
 	F32 updateVisibleEntries(F32 max_time); //update visible entries
 
+	void addCacheMiss(U32 id, LLViewerRegion::eCacheMissType miss_type, F32 weight);
 public:
 	struct CompareDistance
 	{
@@ -441,8 +445,33 @@ private:
 	BOOL    mReleaseNotesRequested;
 	BOOL    mDead;  //if true, this region is in the process of deleting.
 
-	LLDynamicArray<U32>						mCacheMissFull;
-	LLDynamicArray<U32>						mCacheMissCRC;
+	class CacheMissItem
+	{
+	public:
+		CacheMissItem(U32 id, LLViewerRegion::eCacheMissType miss_type, F32 weight) : mID(id), mType(miss_type), mWeight(weight){}
+
+		U32                            mID;     //local object id
+		LLViewerRegion::eCacheMissType mType;   //cache miss type
+		F32                            mWeight; //importance of this object to the current camera.
+	
+		struct Compare
+		{
+			bool operator()(const CacheMissItem& lhs, const CacheMissItem& rhs)
+			{
+				if(lhs.mWeight == rhs.mWeight) //larger weight first
+				{
+					return &lhs < &rhs;
+				}
+				else 
+				{
+					return lhs.mWeight > rhs.mWeight; //larger weight first
+				}
+			}
+		};
+
+		typedef std::set<CacheMissItem, Compare> cache_miss_list_t;
+	};
+	CacheMissItem::cache_miss_list_t        mCacheMissList;
 	
 	caps_received_signal_t mCapabilitiesReceivedSignal;		
 	LLSD mSimulatorFeatures;
-- 
cgit v1.2.3