From 1f507c3cfca0c7722ebeaf71883fbaa83988e1a9 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Thu, 21 Mar 2013 00:37:20 -0700
Subject: [PATCH] SH-3931 WIP Interesting: Add graphs to visualize scene load
 metrics copied over scene load frame differencing changes from
 viewer-interesting made periodicrecording flexible enough to allow for
 indefinite number of periods added scene loading stats floater fixed
 collapsing behavior of container views

---
 indra/llcommon/lltracerecording.cpp           |  55 ++++-----
 indra/llcommon/lltracerecording.h             |  51 +++++----
 indra/llcommon/llunit.h                       |   8 +-
 indra/llimage/tests/llimageworker_test.cpp    |   2 +-
 indra/llkdu/tests/llimagej2ckdu_test.cpp      |   2 +-
 indra/llui/llcontainerview.cpp                |   8 +-
 indra/llui/llcontainerview.h                  |   4 +-
 indra/llui/llmultifloater.h                   |   3 -
 indra/llui/llstatbar.cpp                      |  13 ++-
 indra/llui/llstatbar.h                        |   2 +-
 indra/newview/CMakeLists.txt                  |  10 +-
 indra/newview/llagent.cpp                     |   8 ++
 indra/newview/llagent.h                       |   2 +
 indra/newview/llfasttimerview.cpp             |   8 +-
 indra/newview/llfloatersceneloadstats.cpp     |  37 ++++++
 indra/newview/llfloatersceneloadstats.h       |  39 +++++++
 indra/newview/llscenemonitor.cpp              | 108 +++++++++++++++++-
 indra/newview/llscenemonitor.h                |  13 +++
 indra/newview/llviewerfloaterreg.cpp          |  35 +++---
 indra/newview/llworld.cpp                     |   2 +-
 .../xui/en/floater_scene_load_stats.xml       |  84 ++++++++++----
 21 files changed, 380 insertions(+), 114 deletions(-)
 create mode 100644 indra/newview/llfloatersceneloadstats.cpp
 create mode 100644 indra/newview/llfloatersceneloadstats.h

diff --git a/indra/llcommon/lltracerecording.cpp b/indra/llcommon/lltracerecording.cpp
index 259f5a7a277..5d74ea32df5 100644
--- a/indra/llcommon/lltracerecording.cpp
+++ b/indra/llcommon/lltracerecording.cpp
@@ -355,41 +355,30 @@ U32 Recording::getSampleCount( const TraceType<MeasurementAccumulator<S64> >& st
 // PeriodicRecording
 ///////////////////////////////////////////////////////////////////////
 
-PeriodicRecording::PeriodicRecording( S32 num_periods, EPlayState state) 
-:	mNumPeriods(num_periods),
+PeriodicRecording::PeriodicRecording( U32 num_periods, EPlayState state) 
+:	mAutoResize(num_periods == 0),
 	mCurPeriod(0),
-	mTotalValid(false),
-	mRecordingPeriods( new Recording[num_periods])
+	mTotalValid(false)
 {
-	llassert(mNumPeriods > 0);
-	setPlayState(state);
-}
-
-PeriodicRecording::PeriodicRecording(PeriodicRecording& other)
-:	mNumPeriods(other.mNumPeriods),
-	mCurPeriod(other.mCurPeriod),
-	mTotalValid(other.mTotalValid),
-	mTotalRecording(other.mTotalRecording)
-{
-	mRecordingPeriods = new Recording[mNumPeriods];
-	for (S32 i = 0; i < mNumPeriods; i++)
+	if (num_periods)
 	{
-		mRecordingPeriods[i] = other.mRecordingPeriods[i];
+		mRecordingPeriods.resize(num_periods);
 	}
+	setPlayState(state);
 }
 
-
-PeriodicRecording::~PeriodicRecording()
-{
-	delete[] mRecordingPeriods;
-}
-
-
 void PeriodicRecording::nextPeriod()
 {
 	EPlayState play_state = getPlayState();
 	Recording& old_recording = getCurRecordingPeriod();
-	mCurPeriod = (mCurPeriod + 1) % mNumPeriods;
+	if (mAutoResize)
+	{
+		mRecordingPeriods.push_back(Recording());
+	}
+	U32 num_periods = mRecordingPeriods.size();
+	mCurPeriod = (num_periods > 0) 
+				? (mCurPeriod + 1) % num_periods 
+				: mCurPeriod + 1;
 	old_recording.splitTo(getCurRecordingPeriod());
 
 	switch(play_state)
@@ -412,9 +401,21 @@ Recording& PeriodicRecording::getTotalRecording()
 	if (!mTotalValid)
 	{
 		mTotalRecording.reset();
-		for (S32 i = mCurPeriod + 1; i < mCurPeriod + mNumPeriods; i++)
+		U32 num_periods = mRecordingPeriods.size();
+
+		if (num_periods)
+		{
+			for (S32 i = mCurPeriod + 1; i < mCurPeriod + num_periods; i++)
+			{
+				mTotalRecording.appendRecording(mRecordingPeriods[i % num_periods]);
+			}
+		}
+		else
 		{
-			mTotalRecording.appendRecording(mRecordingPeriods[i % mNumPeriods]);
+			for (S32 i = 0; i < mCurPeriod; i++)
+			{
+				mTotalRecording.appendRecording(mRecordingPeriods[i]);
+			}
 		}
 	}
 	mTotalValid = true;
diff --git a/indra/llcommon/lltracerecording.h b/indra/llcommon/lltracerecording.h
index 751ff298ced..3e7ed2b5926 100644
--- a/indra/llcommon/lltracerecording.h
+++ b/indra/llcommon/lltracerecording.h
@@ -249,16 +249,15 @@ namespace LLTrace
 	:	public LLStopWatchControlsMixin<PeriodicRecording>
 	{
 	public:
-		PeriodicRecording(S32 num_periods, EPlayState state = STOPPED);
-		PeriodicRecording(PeriodicRecording& recording);
-		~PeriodicRecording();
+		PeriodicRecording(U32 num_periods, EPlayState state = STOPPED);
 
 		void nextPeriod();
-		S32 getNumPeriods() { return mNumPeriods; }
+		U32 getNumPeriods() { return mRecordingPeriods.size(); }
 
 		Recording& getLastRecordingPeriod()
 		{
-			return mRecordingPeriods[(mCurPeriod + mNumPeriods - 1) % mNumPeriods];
+			U32 num_periods = mRecordingPeriods.size();
+			return mRecordingPeriods[(mCurPeriod + num_periods - 1) % num_periods];
 		}
 
 		const Recording& getLastRecordingPeriod() const
@@ -276,16 +275,18 @@ namespace LLTrace
 			return mRecordingPeriods[mCurPeriod];
 		}
 
-		Recording& getPrevRecordingPeriod(S32 offset)
+		Recording& getPrevRecordingPeriod(U32 offset)
 		{
-			offset = llclamp(offset, 0, mNumPeriods - 1);
-			return mRecordingPeriods[(mCurPeriod + mNumPeriods - offset) % mNumPeriods];
+			U32 num_periods = mRecordingPeriods.size();
+			offset = llclamp(offset, 0u, num_periods - 1);
+			return mRecordingPeriods[(mCurPeriod + num_periods - offset) % num_periods];
 		}
 
-		const Recording& getPrevRecordingPeriod(S32 offset) const
+		const Recording& getPrevRecordingPeriod(U32 offset) const
 		{
-			offset = llclamp(offset, 0, mNumPeriods - 1);
-			return mRecordingPeriods[(mCurPeriod + mNumPeriods - offset) % mNumPeriods];
+			U32 num_periods = mRecordingPeriods.size();
+			offset = llclamp(offset, 0u, num_periods - 1);
+			return mRecordingPeriods[(mCurPeriod + num_periods - offset) % num_periods];
 		}
 
 		Recording snapshotCurRecordingPeriod() const
@@ -301,7 +302,8 @@ namespace LLTrace
 		typename T::value_t getPeriodMin(const TraceType<T>& stat) const
 		{
 			typename T::value_t min_val = (std::numeric_limits<typename T::value_t>::max)();
-			for (S32 i = 0; i < mNumPeriods; i++)
+			U32 num_periods = mRecordingPeriods.size();
+			for (S32 i = 0; i < num_periods; i++)
 			{
 				min_val = llmin(min_val, mRecordingPeriods[i].getSum(stat));
 			}
@@ -312,7 +314,8 @@ namespace LLTrace
 		F64 getPeriodMinPerSec(const TraceType<T>& stat) const
 		{
 			F64 min_val = (std::numeric_limits<F64>::max)();
-			for (S32 i = 0; i < mNumPeriods; i++)
+			U32 num_periods = mRecordingPeriods.size();
+			for (S32 i = 0; i < num_periods; i++)
 			{
 				min_val = llmin(min_val, mRecordingPeriods[i].getPerSec(stat));
 			}
@@ -323,7 +326,8 @@ namespace LLTrace
 		typename T::value_t getPeriodMax(const TraceType<T>& stat) const
 		{
 			typename T::value_t max_val = (std::numeric_limits<typename T::value_t>::min)();
-			for (S32 i = 0; i < mNumPeriods; i++)
+			U32 num_periods = mRecordingPeriods.size();
+			for (S32 i = 0; i < num_periods; i++)
 			{
 				max_val = llmax(max_val, mRecordingPeriods[i].getSum(stat));
 			}
@@ -334,7 +338,8 @@ namespace LLTrace
 		F64 getPeriodMaxPerSec(const TraceType<T>& stat) const
 		{
 			F64 max_val = (std::numeric_limits<F64>::min)();
-			for (S32 i = 0; i < mNumPeriods; i++)
+			U32 num_periods = mRecordingPeriods.size();
+			for (S32 i = 0; i < num_periods; i++)
 			{
 				max_val = llmax(max_val, mRecordingPeriods[i].getPerSec(stat));
 			}
@@ -345,14 +350,15 @@ namespace LLTrace
 		typename MeanValueType<TraceType<T> >::type getPeriodMean(const TraceType<T>& stat) const
 		{
 			typename MeanValueType<TraceType<T> >::type mean = 0.0;
-			for (S32 i = 0; i < mNumPeriods; i++)
+			U32 num_periods = mRecordingPeriods.size();
+			for (S32 i = 0; i < num_periods; i++)
 			{
 				if (mRecordingPeriods[i].getDuration() > 0.f)
 				{
 					mean += mRecordingPeriods[i].getSum(stat);
 				}
 			}
-			mean /= mNumPeriods;
+			mean /= num_periods;
 			return mean;
 		}
 
@@ -360,14 +366,15 @@ namespace LLTrace
 		typename MeanValueType<TraceType<T> >::type getPeriodMeanPerSec(const TraceType<T>& stat) const
 		{
 			typename MeanValueType<TraceType<T> >::type mean = 0.0;
-			for (S32 i = 0; i < mNumPeriods; i++)
+			U32 num_periods = mRecordingPeriods.size();
+			for (S32 i = 0; i < num_periods; i++)
 			{
 				if (mRecordingPeriods[i].getDuration() > 0.f)
 				{
 					mean += mRecordingPeriods[i].getPerSec(stat);
 				}
 			}
-			mean /= mNumPeriods;
+			mean /= num_periods;
 			return mean;
 		}
 
@@ -382,11 +389,11 @@ namespace LLTrace
 		/*virtual*/ void splitFrom(PeriodicRecording& other);
 
 	private:
-		Recording*	mRecordingPeriods;
+		std::vector<Recording>	mRecordingPeriods;
 		Recording	mTotalRecording;
 		bool		mTotalValid;
-		S32			mNumPeriods,
-					mCurPeriod;
+		const bool	mAutoResize;
+		S32			mCurPeriod;
 	};
 
 	PeriodicRecording& get_frame_recording();
diff --git a/indra/llcommon/llunit.h b/indra/llcommon/llunit.h
index 823550db5de..f86f111b901 100644
--- a/indra/llcommon/llunit.h
+++ b/indra/llcommon/llunit.h
@@ -143,7 +143,7 @@ struct LLUnit
 	void operator *= (LLUnit<OTHER_UNIT, OTHER_STORAGE> multiplicand)
 	{
 		// spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template
-		llstatic_assert_template(OTHER_UNIT, 0, "Multiplication of unit types not supported.");
+		llstatic_assert_template(OTHER_UNIT, false, "Multiplication of unit types not supported.");
 	}
 
 	void operator /= (storage_t divisor)
@@ -155,7 +155,7 @@ struct LLUnit
 	void operator /= (LLUnit<OTHER_UNIT, OTHER_STORAGE> divisor)
 	{
 		// spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template
-		llstatic_assert_template(OTHER_UNIT, 0, "Illegal in-place division of unit types.");
+		llstatic_assert_template(OTHER_UNIT, false, "Illegal in-place division of unit types.");
 	}
 
 	template<typename SOURCE_UNITS, typename SOURCE_STORAGE>
@@ -315,7 +315,7 @@ template<typename UNIT_TYPE1, typename STORAGE_TYPE1, typename UNIT_TYPE2, typen
 LLUnit<UNIT_TYPE1, STORAGE_TYPE1> operator * (LLUnit<UNIT_TYPE1, STORAGE_TYPE1>, LLUnit<UNIT_TYPE2, STORAGE_TYPE2>)
 {
 	// spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template
-	llstatic_assert_template(STORAGE_TYPE1, 0, "Multiplication of unit types results in new unit type - not supported.");
+	llstatic_assert_template(STORAGE_TYPE1, false, "Multiplication of unit types results in new unit type - not supported.");
 	return LLUnit<UNIT_TYPE1, STORAGE_TYPE1>();
 }
 
@@ -335,7 +335,7 @@ template<typename UNIT_TYPE1, typename STORAGE_TYPE1, typename UNIT_TYPE2, typen
 LLUnitImplicit<UNIT_TYPE1, STORAGE_TYPE1> operator * (LLUnitImplicit<UNIT_TYPE1, STORAGE_TYPE1>, LLUnitImplicit<UNIT_TYPE2, STORAGE_TYPE2>)
 {
 	// spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template
-	llstatic_assert_template(STORAGE_TYPE1, 0, "Multiplication of unit types results in new unit type - not supported.");
+	llstatic_assert_template(STORAGE_TYPE1, false, "Multiplication of unit types results in new unit type - not supported.");
 	return LLUnitImplicit<UNIT_TYPE1, STORAGE_TYPE1>();
 }
 
diff --git a/indra/llimage/tests/llimageworker_test.cpp b/indra/llimage/tests/llimageworker_test.cpp
index 4118896768f..b6f2694742c 100644
--- a/indra/llimage/tests/llimageworker_test.cpp
+++ b/indra/llimage/tests/llimageworker_test.cpp
@@ -44,7 +44,7 @@
 // * Do not make any assumption as to how those classes or methods work (i.e. don't copy/paste code)
 // * A simulator for a class can be implemented here. Please comment and document thoroughly.
 
-LLTrace::MemStat	LLImageBase::sMemStat("LLImage");
+LLTrace::MemStatHandle	LLImageBase::sMemStat("LLImage");
 
 
 LLImageBase::LLImageBase() 
diff --git a/indra/llkdu/tests/llimagej2ckdu_test.cpp b/indra/llkdu/tests/llimagej2ckdu_test.cpp
index c28f121eb82..14fbf344abf 100755
--- a/indra/llkdu/tests/llimagej2ckdu_test.cpp
+++ b/indra/llkdu/tests/llimagej2ckdu_test.cpp
@@ -44,7 +44,7 @@
 // End Stubbing
 // -------------------------------------------------------------------------------------------
 // Stub the LL Image Classes
-LLTrace::MemStat	LLImageBase::sMemStat("LLImage");
+LLTrace::MemStatHandle	LLImageBase::sMemStat("LLImage");
 
 LLImageRaw::LLImageRaw() { }
 LLImageRaw::~LLImageRaw() { }
diff --git a/indra/llui/llcontainerview.cpp b/indra/llui/llcontainerview.cpp
index e08ccb0b78c..06f8e72c9cc 100644
--- a/indra/llui/llcontainerview.cpp
+++ b/indra/llui/llcontainerview.cpp
@@ -49,7 +49,6 @@ LLContainerView::LLContainerView(const LLContainerView::Params& p)
 	mLabel(p.label),
 	mDisplayChildren(p.display_children)
 {
-	mCollapsible = TRUE;
 	mScrollContainer = NULL;
 }
 
@@ -75,6 +74,11 @@ bool LLContainerView::addChild(LLView* child, S32 tab_group)
 	return res;
 }
 
+BOOL LLContainerView::handleDoubleClick(S32 x, S32 y, MASK mask)
+{
+	return handleMouseDown(x, y, mask);
+}
+
 BOOL LLContainerView::handleMouseDown(S32 x, S32 y, MASK mask)
 {
 	BOOL handled = FALSE;
@@ -84,7 +88,7 @@ BOOL LLContainerView::handleMouseDown(S32 x, S32 y, MASK mask)
 	}
 	if (!handled)
 	{
-		if( mCollapsible && mShowLabel && (y >= getRect().getHeight() - 10) )
+		if( mShowLabel && (y >= getRect().getHeight() - 10) )
 		{
 			setDisplayChildren(!mDisplayChildren);
 			reshape(getRect().getWidth(), getRect().getHeight(), FALSE);
diff --git a/indra/llui/llcontainerview.h b/indra/llui/llcontainerview.h
index e81600fd6c1..ac92b199775 100644
--- a/indra/llui/llcontainerview.h
+++ b/indra/llui/llcontainerview.h
@@ -66,6 +66,7 @@ class LLContainerView : public LLView
 	/*virtual*/ BOOL postBuild();
 	/*virtual*/ bool addChild(LLView* view, S32 tab_group = 0);
 	
+	/*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
 	/*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
 	/*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask);
 
@@ -87,8 +88,5 @@ class LLContainerView : public LLView
 protected:
 	BOOL mDisplayChildren;
 	std::string mLabel;
-public:
-	BOOL mCollapsible;
-
 };
 #endif // LL_CONTAINERVIEW_
diff --git a/indra/llui/llmultifloater.h b/indra/llui/llmultifloater.h
index 9fa917eca18..6c97f80e317 100644
--- a/indra/llui/llmultifloater.h
+++ b/indra/llui/llmultifloater.h
@@ -96,6 +96,3 @@ class LLMultiFloater : public LLFloater
 };
 
 #endif  // LL_MULTI_FLOATER_H
-
-
-
diff --git a/indra/llui/llstatbar.cpp b/indra/llui/llstatbar.cpp
index 219ddad4522..cda40aac729 100644
--- a/indra/llui/llstatbar.cpp
+++ b/indra/llui/llstatbar.cpp
@@ -88,7 +88,7 @@ BOOL LLStatBar::handleMouseDown(S32 x, S32 y, MASK mask)
 	LLView* parent = getParent();
 	parent->reshape(parent->getRect().getWidth(), parent->getRect().getHeight(), FALSE);
 
-	return FALSE;
+	return TRUE;
 }
 
 void LLStatBar::draw()
@@ -98,6 +98,7 @@ void LLStatBar::draw()
 		max = 0.f,
 		mean = 0.f;
 
+	S32 num_samples = 0;
 	LLTrace::PeriodicRecording& frame_recording = LLTrace::get_frame_recording();
 
 	if (mCountFloatp)
@@ -110,6 +111,7 @@ void LLStatBar::draw()
 			min = frame_recording.getPeriodMinPerSec(*mCountFloatp);
 			max = frame_recording.getPeriodMaxPerSec(*mCountFloatp);
 			mean = frame_recording.getPeriodMeanPerSec(*mCountFloatp);
+			num_samples = frame_recording.getTotalRecording().getSampleCount(*mCountFloatp);
 		}
 		else
 		{
@@ -117,6 +119,7 @@ void LLStatBar::draw()
 			min = frame_recording.getPeriodMin(*mCountFloatp);
 			max = frame_recording.getPeriodMax(*mCountFloatp);
 			mean = frame_recording.getPeriodMean(*mCountFloatp);
+			num_samples = frame_recording.getTotalRecording().getSampleCount(*mCountFloatp);
 		}
 	}
 	else if (mCountIntp)
@@ -129,6 +132,7 @@ void LLStatBar::draw()
 			min = frame_recording.getPeriodMinPerSec(*mCountIntp);
 			max = frame_recording.getPeriodMaxPerSec(*mCountIntp);
 			mean = frame_recording.getPeriodMeanPerSec(*mCountIntp);
+			num_samples = frame_recording.getTotalRecording().getSampleCount(*mCountIntp);
 		}
 		else
 		{
@@ -136,6 +140,7 @@ void LLStatBar::draw()
 			min = frame_recording.getPeriodMin(*mCountIntp);
 			max = frame_recording.getPeriodMax(*mCountIntp);
 			mean = frame_recording.getPeriodMean(*mCountIntp);
+			num_samples = frame_recording.getTotalRecording().getSampleCount(*mCountIntp);
 		}
 	}
 	else if (mMeasurementFloatp)
@@ -145,6 +150,7 @@ void LLStatBar::draw()
 		min = recording.getMin(*mMeasurementFloatp);
 		max = recording.getMax(*mMeasurementFloatp);
 		mean = recording.getMean(*mMeasurementFloatp);
+		num_samples = frame_recording.getTotalRecording().getSampleCount(*mMeasurementFloatp);
 	}
 	else if (mMeasurementIntp)
 	{
@@ -153,6 +159,7 @@ void LLStatBar::draw()
 		min = recording.getMin(*mMeasurementIntp);
 		max = recording.getMax(*mMeasurementIntp);
 		mean = recording.getMean(*mMeasurementIntp);
+		num_samples = frame_recording.getTotalRecording().getSampleCount(*mMeasurementIntp);
 	}
 
 	current *= mUnitScale;
@@ -191,7 +198,7 @@ void LLStatBar::draw()
 	const S32 tick_length = 4;
 	const S32 tick_width = 1;
 
-	if (mScaleRange)
+	if (mScaleRange && num_samples)
 	{
 		F32 cur_max = mLabelSpacing;
 		while(max > cur_max)
@@ -472,7 +479,7 @@ LLRect LLStatBar::getRequiredRect()
 			}
 			else
 			{
-				rect.mTop = 35 + llmin(mMaxHeight, llmin(mNumFrames, LLTrace::get_frame_recording().getNumPeriods()));
+				rect.mTop = 35 + llmin(mMaxHeight, llmin(mNumFrames, (S32)LLTrace::get_frame_recording().getNumPeriods()));
 			}
 		}
 		else
diff --git a/indra/llui/llstatbar.h b/indra/llui/llstatbar.h
index a83ccbe9e51..74a3ebde2f3 100644
--- a/indra/llui/llstatbar.h
+++ b/indra/llui/llstatbar.h
@@ -71,7 +71,7 @@ class LLStatBar : public LLView
 			  update_rate("update_rate", 5.0f),
 			  unit_scale("unit_scale", 1.f),
 			  show_per_sec("show_per_sec", true),
-			  show_bar("show_bar", TRUE),
+			  show_bar("show_bar", true),
 			  show_history("show_history", false),
 			  show_mean("show_mean", true),
 			  scale_range("scale_range", true),
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 16d82d5a0a6..575400941f0 100755
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -239,6 +239,7 @@ set(viewer_SOURCE_FILES
     llfloaterregiondebugconsole.cpp
     llfloaterregioninfo.cpp
     llfloaterreporter.cpp
+    llfloatersceneloadstats.cpp
     llfloaterscriptdebug.cpp
     llfloaterscriptlimits.cpp
     llfloatersearch.cpp
@@ -462,7 +463,7 @@ set(viewer_SOURCE_FILES
     llremoteparcelrequest.cpp
     llsavedsettingsglue.cpp
     llsaveoutfitcombobtn.cpp
-	llscenemonitor.cpp
+    llscenemonitor.cpp
     llsceneview.cpp
     llscreenchannel.cpp
     llscriptfloater.cpp
@@ -587,7 +588,7 @@ set(viewer_SOURCE_FILES
     llviewernetwork.cpp
     llviewerobject.cpp
     llviewerobjectlist.cpp
-	llvieweroctree.cpp
+    llvieweroctree.cpp
     llviewerparcelmedia.cpp
     llviewerparcelmediaautoplay.cpp
     llviewerparcelmgr.cpp
@@ -816,6 +817,7 @@ set(viewer_HEADER_FILES
     llfloaterregiondebugconsole.h
     llfloaterregioninfo.h
     llfloaterreporter.h
+    llfloatersceneloadstats.h
     llfloaterscriptdebug.h
     llfloaterscriptlimits.h
     llfloatersearch.h
@@ -1030,7 +1032,7 @@ set(viewer_HEADER_FILES
     llrootview.h
     llsavedsettingsglue.h
     llsaveoutfitcombobtn.h
-	llscenemonitor.h
+    llscenemonitor.h
     llsceneview.h
     llscreenchannel.h
     llscriptfloater.h
@@ -1155,7 +1157,7 @@ set(viewer_HEADER_FILES
     llviewernetwork.h
     llviewerobject.h
     llviewerobjectlist.h
-	llvieweroctree.h
+    llvieweroctree.h
     llviewerparcelmedia.h
     llviewerparcelmediaautoplay.h
     llviewerparcelmgr.h
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 4fb298df139..4e60127ef3d 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 99904e118c1..a1e899b45dd 100644
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -250,6 +250,8 @@ class LLAgent : public LLOldEvents::LLObservable
 	
 	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/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp
index f55535b6e35..6caa89a611c 100644
--- a/indra/newview/llfasttimerview.cpp
+++ b/indra/newview/llfasttimerview.cpp
@@ -263,7 +263,7 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask)
 	{
 		F32 lerp = llclamp(1.f - (F32) (x - mGraphRect.mLeft) / (F32) mGraphRect.getWidth(), 0.f, 1.f);
 		mScrollIndex = llround( lerp * (F32)(mRecording->getNumPeriods() - MAX_VISIBLE_HISTORY));
-		mScrollIndex = llclamp(	mScrollIndex, 0, mRecording->getNumPeriods());
+		mScrollIndex = llclamp(	mScrollIndex, 0, (S32)mRecording->getNumPeriods());
 		return TRUE;
 	}
 	mHoverTimer = NULL;
@@ -272,7 +272,7 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask)
 	if(mPauseHistory && mBarRect.pointInRect(x, y))
 	{
 		mHoverBarIndex = llmin((mBarRect.mTop - y) / (mBarRect.getHeight() / (MAX_VISIBLE_HISTORY + 2)) - 1,
-								mRecording->getNumPeriods() - 1,
+								(S32)mRecording->getNumPeriods() - 1,
 								MAX_VISIBLE_HISTORY);
 		if (mHoverBarIndex == 0)
 		{
@@ -381,7 +381,7 @@ BOOL LLFastTimerView::handleScrollWheel(S32 x, S32 y, S32 clicks)
 	setPauseState(true);
 	mScrollIndex = llclamp(	mScrollIndex + clicks,
 							0,
-							llmin(mRecording->getNumPeriods(), (S32)mRecording->getNumPeriods() - MAX_VISIBLE_HISTORY));
+							llmin((S32)mRecording->getNumPeriods(), (S32)mRecording->getNumPeriods() - MAX_VISIBLE_HISTORY));
 	return TRUE;
 }
 
@@ -1425,7 +1425,7 @@ void LLFastTimerView::drawBars()
 	// Special: -1 = show running average
 	LLPointer<LLUIImage> bar_image = LLUI::getUIImage("Rounded_Square");
 	gGL.getTexUnit(0)->bind(bar_image->getImage());
-	const S32 histmax = llmin(mRecording->getNumPeriods(), MAX_VISIBLE_HISTORY) + 1;
+	const S32 histmax = llmin((S32)mRecording->getNumPeriods(), MAX_VISIBLE_HISTORY) + 1;
 
 	for (S32 bar_index = 0; bar_index < histmax && y > LINE_GRAPH_HEIGHT; bar_index++)
 	{
diff --git a/indra/newview/llfloatersceneloadstats.cpp b/indra/newview/llfloatersceneloadstats.cpp
new file mode 100644
index 00000000000..95e8fbf4dda
--- /dev/null
+++ b/indra/newview/llfloatersceneloadstats.cpp
@@ -0,0 +1,37 @@
+/** 
+ * @file llfloatersceneloadstats.cpp
+ * @author Richard Nelson
+ * @brief debug floater for measuring various scene load statistics
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2013, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+ 
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloatersceneloadstats.h"
+
+
+LLFloaterSceneLoadStats::LLFloaterSceneLoadStats( const LLSD& key ) 
+:	LLFloater(key)
+{
+
+}
diff --git a/indra/newview/llfloatersceneloadstats.h b/indra/newview/llfloatersceneloadstats.h
new file mode 100644
index 00000000000..095541f2f6a
--- /dev/null
+++ b/indra/newview/llfloatersceneloadstats.h
@@ -0,0 +1,39 @@
+/** 
+ * @file llfloatersceneloadstats.h
+ * @brief debug floater for measuring various scene load statistics
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2013, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_FLOATERSCENELOADSTATS_H
+#define LL_FLOATERSCENELOADSTATS_H
+
+#include "llfloater.h"
+
+class LLFloaterSceneLoadStats : public LLFloater
+{
+	friend class LLFloaterReg;
+private:
+	LLFloaterSceneLoadStats(const LLSD& key);
+};
+
+#endif // LL_FLOATERSCENELOADSTATS_H
diff --git a/indra/newview/llscenemonitor.cpp b/indra/newview/llscenemonitor.cpp
index 189697dcf01..c69f276aa27 100644
--- a/indra/newview/llscenemonitor.cpp
+++ b/indra/newview/llscenemonitor.cpp
@@ -37,6 +37,8 @@
 #include "llwindow.h"
 #include "llpointer.h"
 #include "llspatialpartition.h"
+#include "llagent.h"
+#include "pipeline.h"
 
 LLSceneMonitorView* gSceneMonitorView = NULL;
 
@@ -67,7 +69,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 +83,10 @@ LLSceneMonitor::~LLSceneMonitor()
 void LLSceneMonitor::destroyClass()
 {
 	reset();
+
+	delete mRecording;
+	mRecording = NULL;
+	mDitheringTexture = NULL;
 }
 
 void LLSceneMonitor::reset()
@@ -100,6 +109,67 @@ void LLSceneMonitor::reset()
 	}
 }
 
+void LLSceneMonitor::generateDitheringTexture(S32 width, S32 height)
+{
+#if 1
+	//4 * 4 matrix
+	mDitherMatrixWidth = 4;	
+	S32 dither_matrix[4][4] = 
+	{
+		{1, 9, 3, 11}, 
+		{13, 5, 15, 7}, 
+		{4, 12, 2, 10}, 
+		{16, 8, 14, 6}
+	};
+	
+	mDitherScale = 255.f / 17;
+#else
+	//8 * 8 matrix
+	mDitherMatrixWidth = 16;	
+	S32 dither_matrix[16][16] = 
+	{
+		{1, 49, 13, 61, 4, 52, 16, 64, 1, 49, 13, 61, 4, 52, 16, 64}, 
+		{33, 17, 45, 29, 36, 20, 48, 32, 33, 17, 45, 29, 36, 20, 48, 32}, 
+		{9, 57, 5, 53, 12, 60, 8, 56, 9, 57, 5, 53, 12, 60, 8, 56}, 
+		{41, 25, 37, 21, 44, 28, 40, 24, 41, 25, 37, 21, 44, 28, 40, 24},
+		{3, 51, 15, 63, 2, 50, 14, 62, 3, 51, 15, 63, 2, 50, 14, 62},
+		{35, 19, 47, 31, 34, 18, 46, 30, 35, 19, 47, 31, 34, 18, 46, 30},
+		{11, 59, 7, 55, 10, 58, 6, 54, 11, 59, 7, 55, 10, 58, 6, 54},
+		{43, 27, 39, 23, 42, 26, 38, 22, 43, 27, 39, 23, 42, 26, 38, 22},
+		{1, 49, 13, 61, 4, 52, 16, 64, 1, 49, 13, 61, 4, 52, 16, 64}, 
+		{33, 17, 45, 29, 36, 20, 48, 32, 33, 17, 45, 29, 36, 20, 48, 32}, 
+		{9, 57, 5, 53, 12, 60, 8, 56, 9, 57, 5, 53, 12, 60, 8, 56}, 
+		{41, 25, 37, 21, 44, 28, 40, 24, 41, 25, 37, 21, 44, 28, 40, 24},
+		{3, 51, 15, 63, 2, 50, 14, 62, 3, 51, 15, 63, 2, 50, 14, 62},
+		{35, 19, 47, 31, 34, 18, 46, 30, 35, 19, 47, 31, 34, 18, 46, 30},
+		{11, 59, 7, 55, 10, 58, 6, 54, 11, 59, 7, 55, 10, 58, 6, 54},
+		{43, 27, 39, 23, 42, 26, 38, 22, 43, 27, 39, 23, 42, 26, 38, 22}
+	};
+
+	mDitherScale = 255.f / 65;
+#endif
+
+	LLPointer<LLImageRaw> image_raw = new LLImageRaw(mDitherMatrixWidth, mDitherMatrixWidth, 3);
+	U8* data = image_raw->getData();
+	for (S32 i = 0; i < mDitherMatrixWidth; i++)
+	{
+		for (S32 j = 0; j < mDitherMatrixWidth; j++)
+		{
+			U8 val = dither_matrix[i][j];
+			*data++ = val;
+			*data++ = val;
+			*data++ = val;
+		}
+	}
+
+	mDitheringTexture = LLViewerTextureManager::getLocalTexture(image_raw.get(), FALSE) ;
+	mDitheringTexture->setAddressMode(LLTexUnit::TAM_WRAP);
+	mDitheringTexture->setFilteringOption(LLTexUnit::TFO_POINT);
+	
+	mDitherScaleS = (F32)width / mDitherMatrixWidth;
+	mDitherScaleT = (F32)height / mDitherMatrixWidth;
+}
+
 void LLSceneMonitor::setDebugViewerVisible(BOOL visible) 
 {
 	mDebugViewerVisible = visible;
@@ -137,6 +207,11 @@ bool LLSceneMonitor::preCapture()
 		return false;
 	}
 
+	if(gAgent.isPositionChanged())
+	{
+		mRecording->reset();
+	}
+
 	if(timer.getElapsedTimeF32() < mSamplingTime)
 	{
 		return false;
@@ -197,6 +272,9 @@ void LLSceneMonitor::freezeScene()
 
 	// freeze everything else
 	gSavedSettings.setBOOL("FreezeTime", TRUE);
+
+	gPipeline.clearRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, LLPipeline::RENDER_TYPE_WL_SKY, 
+		LLPipeline::RENDER_TYPE_WATER, LLPipeline::RENDER_TYPE_CLOUDS, LLPipeline::END_RENDER_TYPES);
 }
 
 void LLSceneMonitor::unfreezeScene()
@@ -206,6 +284,9 @@ void LLSceneMonitor::unfreezeScene()
 
 	// thaw everything else
 	gSavedSettings.setBOOL("FreezeTime", FALSE);
+
+	gPipeline.setRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, LLPipeline::RENDER_TYPE_WL_SKY, 
+		LLPipeline::RENDER_TYPE_WATER, LLPipeline::RENDER_TYPE_CLOUDS, LLPipeline::END_RENDER_TYPES);
 }
 
 void LLSceneMonitor::capture()
@@ -268,10 +349,13 @@ void LLSceneMonitor::compare()
 	{
 		mDiff = new LLRenderTarget();
 		mDiff->allocate(width, height, GL_RGBA, false, false, LLTexUnit::TT_TEXTURE, true);
+
+		generateDitheringTexture(width, height);
 	}
 	else if(mDiff->getWidth() != width || mDiff->getHeight() != height)
 	{
 		mDiff->resize(width, height, GL_RGBA);
+		generateDitheringTexture(width, height);
 	}
 
 	mDiff->bindTarget();
@@ -279,6 +363,10 @@ void LLSceneMonitor::compare()
 	
 	gTwoTextureCompareProgram.bind();
 	
+	gTwoTextureCompareProgram.uniform1f("dither_scale", mDitherScale);
+	gTwoTextureCompareProgram.uniform1f("dither_scale_s", mDitherScaleS);
+	gTwoTextureCompareProgram.uniform1f("dither_scale_t", mDitherScaleT);
+
 	gGL.getTexUnit(0)->activate();
 	gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
 	gGL.getTexUnit(0)->bind(mFrames[0]);
@@ -289,6 +377,11 @@ void LLSceneMonitor::compare()
 	gGL.getTexUnit(1)->bind(mFrames[1]);
 	gGL.getTexUnit(1)->activate();	
 	
+	gGL.getTexUnit(2)->activate();
+	gGL.getTexUnit(2)->enable(LLTexUnit::TT_TEXTURE);
+	gGL.getTexUnit(2)->bind(mDitheringTexture);
+	gGL.getTexUnit(2)->activate();	
+
 	gl_rect_2d_simple_tex(width, height);
 	
 	mDiff->flush();	
@@ -299,6 +392,8 @@ void LLSceneMonitor::compare()
 	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 	gGL.getTexUnit(1)->disable();
 	gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
+	gGL.getTexUnit(2)->disable();
+	gGL.getTexUnit(2)->unbind(LLTexUnit::TT_TEXTURE);
 
 	mHasNewDiff = TRUE;
 	
@@ -368,6 +463,7 @@ void LLSceneMonitor::calcDiffAggregate()
 	}	
 }
 
+static LLTrace::MeasurementStatHandle<> sFramePixelDiff("FramePixelDifference");
 void LLSceneMonitor::fetchQueryResult()
 {
 	if(!mHasNewQueryResult)
@@ -388,6 +484,11 @@ 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();
+		sample(sFramePixelDiff, mDiffResult);
+	}
 	//llinfos << count << " : " << mDiffResult << llendl;
 }
 //-------------------------------------------------------------------------------------------------------------
@@ -454,6 +555,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 02e3d57d46d..709650e206b 100644
--- a/indra/newview/llscenemonitor.h
+++ b/indra/newview/llscenemonitor.h
@@ -31,9 +31,11 @@
 #include "llmath.h"
 #include "llfloater.h"
 #include "llcharacter.h"
+#include "lltracerecording.h"
 
 class LLCharacter;
 class LLRenderTarget;
+class LLViewerTexture;
 
 class LLSceneMonitor :  public LLSingleton<LLSceneMonitor>
 {
@@ -61,11 +63,14 @@ class LLSceneMonitor :  public LLSingleton<LLSceneMonitor>
 	bool isEnabled()const {return mEnabled;}
 	bool needsUpdate() const;
 	
+	LLTrace::ExtendableRecording* getRecording() const {return mRecording;}
+
 private:
 	void freezeScene();
 	void unfreezeScene();
 	void reset();
 	bool preCapture();
+	void generateDitheringTexture(S32 width, S32 height);
 
 private:
 	BOOL mEnabled;
@@ -85,7 +90,15 @@ class LLSceneMonitor :  public LLSingleton<LLSceneMonitor>
 	F32     mSamplingTime; //time interval to capture frames, in seconds
 	F32     mDiffPixelRatio; //ratio of pixels used for comparison against the original mDiff size along one dimension
 
+	LLPointer<LLViewerTexture> mDitheringTexture;
+	S32                        mDitherMatrixWidth;
+	F32                        mDitherScale;
+	F32                        mDitherScaleS;
+	F32                        mDitherScaleT;
+
 	std::vector<LLAnimPauseRequest> mAvatarPauseHandles;
+
+	LLTrace::ExtendableRecording* mRecording;
 };
 
 class LLSceneMonitorView : public LLFloater
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index e72ea4b8263..792c55441d9 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -28,63 +28,62 @@
 #include "llviewerprecompiledheaders.h"
 
 #include "llfloaterreg.h"
-
 #include "llviewerfloaterreg.h"
-#include "llfloaterautoreplacesettings.h"
-#include "llcompilequeue.h"
+
 #include "llcallfloater.h"
+#include "llcommandhandler.h"
+#include "llcompilequeue.h"
 #include "llfasttimerview.h"
 #include "llfloaterabout.h"
 #include "llfloaterauction.h"
+#include "llfloaterautoreplacesettings.h"
 #include "llfloateravatar.h"
 #include "llfloateravatarpicker.h"
 #include "llfloateravatartextures.h"
 #include "llfloaterbeacons.h"
 #include "llfloaterbuildoptions.h"
+#include "llfloaterbulkpermission.h"
+#include "llfloaterbump.h"
 #include "llfloaterbuy.h"
 #include "llfloaterbuycontents.h"
 #include "llfloaterbuycurrency.h"
 #include "llfloaterbuycurrencyhtml.h"
 #include "llfloaterbuyland.h"
-#include "llfloaterbulkpermission.h"
-#include "llfloaterbump.h"
 #include "llfloaterbvhpreview.h"
 #include "llfloatercamera.h"
 #include "llfloaterdeleteenvpreset.h"
+#include "llfloaterdestinations.h"
 #include "llfloaterdisplayname.h"
 #include "llfloatereditdaycycle.h"
 #include "llfloatereditsky.h"
 #include "llfloatereditwater.h"
 #include "llfloaterenvironmentsettings.h"
 #include "llfloaterevent.h"
-#include "llfloaterdestinations.h"
 #include "llfloaterfonttest.h"
 #include "llfloatergesture.h"
 #include "llfloatergodtools.h"
 #include "llfloatergroups.h"
 #include "llfloaterhardwaresettings.h"
 #include "llfloaterhelpbrowser.h"
-#include "llfloaterwebcontent.h"
-#include "llfloaterwebprofile.h"
-#include "llfloatermediasettings.h"
 #include "llfloaterhud.h"
 #include "llfloaterimagepreview.h"
-#include "llimfloater.h"
 #include "llfloaterinspect.h"
 #include "llfloaterinventory.h"
 #include "llfloaterjoystick.h"
 #include "llfloaterland.h"
 #include "llfloaterlandholdings.h"
 #include "llfloatermap.h"
+#include "llfloatermediasettings.h"
 #include "llfloatermemleak.h"
+#include "llfloatermodelpreview.h"
 #include "llfloaternamedesc.h"
 #include "llfloaternotificationsconsole.h"
 #include "llfloaterobjectweights.h"
 #include "llfloateropenobject.h"
 #include "llfloateroutbox.h"
 #include "llfloaterpathfindingcharacters.h"
-#include "llfloaterpathfindinglinksets.h"
 #include "llfloaterpathfindingconsole.h"
+#include "llfloaterpathfindinglinksets.h"
 #include "llfloaterpay.h"
 #include "llfloaterperms.h"
 #include "llfloaterpostprocess.h"
@@ -93,6 +92,7 @@
 #include "llfloaterregiondebugconsole.h"
 #include "llfloaterregioninfo.h"
 #include "llfloaterreporter.h"
+#include "llfloatersceneloadstats.h"
 #include "llfloaterscriptdebug.h"
 #include "llfloaterscriptlimits.h"
 #include "llfloatersearch.h"
@@ -107,15 +107,18 @@
 #include "llfloatertestlistview.h"
 #include "llfloatertexturefetchdebugger.h"
 #include "llfloatertools.h"
-#include "llfloatertos.h"
 #include "llfloatertopobjects.h"
+#include "llfloatertos.h"
 #include "llfloatertoybox.h"
 #include "llfloatertranslationsettings.h"
 #include "llfloateruipreview.h"
 #include "llfloatervoiceeffect.h"
+#include "llfloaterwebcontent.h"
+#include "llfloaterwebprofile.h"
 #include "llfloaterwhitelistentry.h"
 #include "llfloaterwindowsize.h"
 #include "llfloaterworldmap.h"
+#include "llimfloater.h"
 #include "llimfloatercontainer.h"
 #include "llinspectavatar.h"
 #include "llinspectgroup.h"
@@ -124,6 +127,7 @@
 #include "llinspecttoast.h"
 #include "llmoveview.h"
 #include "llnearbychat.h"
+#include "llnearbychatbar.h"
 #include "llpanelblockedlist.h"
 #include "llpanelclassified.h"
 #include "llpreviewanim.h"
@@ -132,11 +136,8 @@
 #include "llpreviewscript.h"
 #include "llpreviewsound.h"
 #include "llpreviewtexture.h"
-#include "llsyswellwindow.h"
 #include "llscriptfloater.h"
-#include "llfloatermodelpreview.h"
-#include "llcommandhandler.h"
-#include "llnearbychatbar.h"
+#include "llsyswellwindow.h"
 
 // *NOTE: Please add files in alphabetical order to keep merges easy.
 
@@ -297,8 +298,8 @@ void LLViewerFloaterReg::registerFloaters()
 	LLFloaterReg::add("settings_debug", "floater_settings_debug.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSettingsDebug>);
 	LLFloaterReg::add("sound_devices", "floater_sound_devices.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSoundDevices>);
 	LLFloaterReg::add("stats", "floater_stats.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloater>);
-	LLFloaterReg::add("scene_load_stats", "floater_scene_load_stats.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloater>);
 	LLFloaterReg::add("start_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterRunQueue>);
+	LLFloaterReg::add("scene_load_stats", "floater_scene_load_stats.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSceneLoadStats>);
 	LLFloaterReg::add("stop_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterNotRunQueue>);
 	LLFloaterReg::add("snapshot", "floater_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSnapshot>);
 	LLFloaterReg::add("search", "floater_search.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSearch>);
diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp
index e088f94d640..aba9df24c97 100644
--- a/indra/newview/llworld.cpp
+++ b/indra/newview/llworld.cpp
@@ -1172,7 +1172,7 @@ void send_agent_resume()
 	}
 
 	// Resume data collection to ignore invalid rates
-	LLViewerStats::instance().getRecording().resume();//getInstance()->mFPSStat.reset();
+	LLViewerStats::instance().getRecording().resume();
 
 	LLAppViewer::instance()->resumeMainloopTimeout();
 }
diff --git a/indra/newview/skins/default/xui/en/floater_scene_load_stats.xml b/indra/newview/skins/default/xui/en/floater_scene_load_stats.xml
index 9dbf59ef4d4..f4021d210a0 100644
--- a/indra/newview/skins/default/xui/en/floater_scene_load_stats.xml
+++ b/indra/newview/skins/default/xui/en/floater_scene_load_stats.xml
@@ -15,7 +15,7 @@
             label="Pause"
             name="playpause"/>
     <scroll_container follows="top|left|bottom|right"
-                      height="380"
+                      bottom="400"
                       layout="topleft"
                       left="0"
                       name="statistics_scroll"
@@ -34,19 +34,28 @@
                  label="Basic"
                  show_label="true"
                  setting="OpenDebugStatBasic">
-			  <stat_bar name="bandwidth"
+        <stat_bar name="frame difference"
+                  label="Frame Pixel Difference"
+                  orientation="horizontal"
+                  unit_label="%"
+                  stat="FramePixelDifference"
+                  bar_max="100"
+                  tick_spacing="10"
+                  label_spacing="20"
+                  unit_scale="100"
+                  precision="0"/>
+        <stat_bar name="bandwidth"
                   label="Bandwidth"
-                  unit_label="kbps"
                   orientation="horizontal"
+                  unit_label="kbps"
                   stat="kbitstat"
                   bar_max="5000"
                   tick_spacing="500"
                   label_spacing="1000"
-                  precision="0"
-                  show_bar="true"
-                  show_history="false"/>
+                  precision="0"/>
 			  <stat_bar name="packet_loss"
                   label="Packet Loss"
+                  orientation="horizontal"
                   unit_label=" %"
                   stat="packetslostpercentstat"
                   bar_max="5"
@@ -67,6 +76,7 @@
                    setting="OpenDebugStatRender">
           <stat_bar name="objs"
                     label="Total Objects"
+                    orientation="horizontal"
                     unit_label=""
                     stat="numobjectsstat"
                     bar_max="50000"
@@ -74,23 +84,25 @@
                     label_spacing="10000"
                     precision="0"
                     show_bar="false"/>
-			    <stat_bar name="newobjs"
+          <stat_bar name="newobjs"
                     label="New Objects"
+                    orientation="horizontal"
                     unit_label="/sec"
                     stat="numnewobjectsstat"
                     bar_max="2000"
                     tick_spacing="200"
                     label_spacing="400"
                     show_bar="false"/>
-         <stat_bar name="object_cache_hits"
-                   label="Object Cache Hit Rate"
-                   stat="object_cache_hits"
-                   bar_max="100"
-                   unit_label="%"
-                   tick_spacing="20"
-                   label_spacing="20"
-                   show_history="true"
-                   show_bar="false"/>
+          <stat_bar name="object_cache_hits"
+                    label="Object Cache Hit Rate"
+                    orientation="horizontal"
+                    stat="object_cache_hits"
+                    bar_max="100"
+                    unit_label="%"
+                    tick_spacing="20"
+                    label_spacing="20"
+                    show_history="true"
+                    show_bar="false"/>
 			  </stat_view>
 <!--Texture Stats-->
 			  <stat_view name="texture"
@@ -98,6 +110,7 @@
                    show_label="true">
 			    <stat_bar name="texture_cache_hits"
                     label="Cache Hit Rate"
+                    orientation="horizontal"
                     stat="texture_cache_hits"
                     bar_max="100.f"
                     unit_label="%"
@@ -107,6 +120,7 @@
                     show_bar="false"/>
           <stat_bar name="texture_cache_read_latency"
                     label="Cache Read Latency"
+                    orientation="horizontal"
                     unit_label="msec"
                     stat="texture_cache_read_latency"
                     bar_max="1000.f"
@@ -116,6 +130,7 @@
                     show_bar="false"/>
           <stat_bar name="numimagesstat"
                     label="Count"
+                    orientation="horizontal"
                     stat="numimagesstat" 
                     bar_max="8000.f" 
                     tick_spacing="2000.f"
@@ -123,6 +138,7 @@
                     show_bar="false"/>
 			    <stat_bar name="numrawimagesstat"
                     label="Raw Count"
+                    orientation="horizontal"
                     stat="numrawimagesstat"
                     bar_max="8000.f" 
                     tick_spacing="2000.f"
@@ -136,6 +152,7 @@
                    setting="OpenDebugStatNet">
 			    <stat_bar name="packetsinstat"
                     label="Packets In"
+                    orientation="horizontal"
                     stat="packetsinstat"
                     unit_label="/sec" 
                     bar_max="1024.f" 
@@ -145,6 +162,7 @@
                     show_bar="false"/>
 			    <stat_bar name="packetsoutstat"
                     label="Packets Out"
+                    orientation="horizontal"
                     stat="packetsoutstat"
                     unit_label="/sec"  
                     bar_max="1024.f" 
@@ -154,6 +172,7 @@
                     show_bar="false"/>
 			    <stat_bar name="objectkbitstat"
                     label="Objects"
+                    orientation="horizontal"
                     stat="objectkbitstat"
                     unit_label="kbps"
                     bar_max="1024.f"
@@ -163,6 +182,7 @@
                     show_bar="false"/>
 			    <stat_bar name="texturekbitstat"
                     label="Texture"
+                    orientation="horizontal"
                     stat="texturekbitstat"
                     unit_label="kbps"
                     bar_max="1024.f"
@@ -172,6 +192,7 @@
                     show_bar="false"/>
 			    <stat_bar name="assetkbitstat"
                     label="Asset"
+                    orientation="horizontal"
                     stat="assetkbitstat"
                     unit_label="kbps"
                     bar_max="1024.f"
@@ -181,6 +202,7 @@
                     show_bar="false"/>
 			    <stat_bar name="layerskbitstat"
                     label="Layers"
+                    orientation="horizontal"
                     stat="layerskbitstat"
                     unit_label="kbps"
                     bar_max="1024.f"
@@ -190,26 +212,27 @@
                     show_bar="false"/>
 			    <stat_bar name="actualinkbitstat"
                     label="Actual In"
+                    orientation="horizontal"
                     stat="actualinkbitstat"
                     unit_label="kbps"
                     bar_max="1024.f"
                     tick_spacing="128.f"
                     label_spacing="256.f"
                     precision="1"
-                    show_bar="false"
-                    show_history="false"/>
+                    show_bar="false"/>
 			    <stat_bar name="actualoutkbitstat"
                     label="Actual Out"
+                    orientation="horizontal"
                     stat="actualoutkbitstat"
                     unit_label="kbps"
                     bar_max="1024.f"
                     tick_spacing="128.f"
                     label_spacing="256.f"
                     precision="1"
-                    show_bar="false"
-                    show_history="false"/>
+                    show_bar="false"/>
 			    <stat_bar name="vfspendingoperations"
                     label="VFS Pending Operations"
+                    orientation="horizontal"
                     stat="vfspendingoperations"
                     unit_label=" Ops."
                     show_bar="false"/>
@@ -222,6 +245,7 @@
                  setting="OpenDebugStatSim">
 			  <stat_bar name="simobjects"
                   label="Objects"
+                  orientation="horizontal"
                   stat="simobjects"
                   precision="0"
                   bar_max="30000.f" 
@@ -231,6 +255,7 @@
                   show_mean="false"/>
 			  <stat_bar name="simactiveobjects"
                   label="Active Objects"
+                  orientation="horizontal"
                   stat="simactiveobjects"
                   precision="0"
                   bar_max="5000.f" 
@@ -240,6 +265,7 @@
                   show_mean="false"/>
 			  <stat_bar name="simactivescripts"
                   label="Active Scripts"
+                  orientation="horizontal"
                   stat="simactivescripts"
                   precision="0"
                   bar_max="15000.f" 
@@ -249,6 +275,7 @@
                   show_mean="false"/>
 			  <stat_bar name="siminpps"
                   label="Packets In"
+                  orientation="horizontal"
                   stat="siminpps"
                   unit_label="pps"
                   precision="0"
@@ -259,6 +286,7 @@
                   show_mean="false"/>
 			  <stat_bar name="simoutpps"
                   label="Packets Out"
+                  orientation="horizontal"
                   stat="simoutpps"
                   unit_label="pps" 
                   precision="0"
@@ -269,6 +297,7 @@
                   show_mean="false"/>
 			  <stat_bar name="simpendingdownloads"
                   label="Pending Downloads"
+                  orientation="horizontal"
                   stat="simpendingdownloads"
                   precision="0"
                   bar_max="800.f" 
@@ -278,6 +307,7 @@
                   show_mean="false"/>
 			  <stat_bar name="simpendinguploads"
                   label="Pending Uploads"
+                  orientation="horizontal"
                   stat="simpendinguploads"
                   precision="0"
                   bar_max="100.f" 
@@ -287,6 +317,7 @@
                   show_mean="false"/>
 			  <stat_bar name="simtotalunackedbytes"
                   label="Total Unacked Bytes"
+                  orientation="horizontal"
                   stat="simtotalunackedbytes"
                   unit_label="kb"
                   precision="1"
@@ -300,6 +331,7 @@
                    show_label="true">
 			    <stat_bar name="simframemsec"
                     label="Total Frame Time"
+                    orientation="horizontal"
                     stat="simframemsec"
                     unit_label="ms"
                     precision="3"
@@ -310,6 +342,7 @@
                     show_mean="false"/>
 			    <stat_bar name="simnetmsec"
                     label="Net Time"
+                    orientation="horizontal"
                     stat="simnetmsec"
                     unit_label="ms"
                     precision="3"
@@ -320,6 +353,7 @@
                     show_mean="false"/>
 			    <stat_bar name="simsimphysicsmsec"
                     label="Physics Time"
+                    orientation="horizontal"
                     stat="simsimphysicsmsec"
                     unit_label="ms"
                     precision="3"
@@ -330,6 +364,7 @@
                     show_mean="false"/>
 			    <stat_bar name="simsimothermsec"
                     label="Simulation Time"
+                    orientation="horizontal"
                     stat="simsimothermsec"
                     unit_label="ms"
                     precision="3"
@@ -340,6 +375,7 @@
                     show_mean="false"/>
 			    <stat_bar name="simagentmsec"
                     label="Agent Time"
+                    orientation="horizontal"
                     stat="simagentmsec"
                     unit_label="ms"
                     precision="3"
@@ -350,6 +386,7 @@
                     show_mean="false"/>
 			    <stat_bar name="simimagesmsec"
                     label="Images Time"
+                    orientation="horizontal"
                     stat="simimagesmsec"
                     unit_label="ms"
                     precision="3"
@@ -360,6 +397,7 @@
                     show_mean="false"/>
 			    <stat_bar name="simscriptmsec"
                     label="Script Time"
+                    orientation="horizontal"
                     stat="simscriptmsec"
                     unit_label="ms"
                     precision="3"
@@ -370,6 +408,7 @@
                     show_mean="false"/>
           <stat_bar name="simsparemsec"
                     label="Spare Time"
+                    orientation="horizontal"
                     stat="simsparemsec"
                     unit_label="ms"
                     precision="3"
@@ -384,6 +423,7 @@
                      show_label="true">
             <stat_bar name="simsimphysicsstepmsec"
                       label="  Physics Step"
+                      orientation="horizontal"
                       stat="simsimphysicsstepmsec"
                       unit_label="ms"
                       precision="3"
@@ -394,6 +434,7 @@
                       show_mean="false"/>
             <stat_bar name="simsimphysicsshapeupdatemsec"
                       label="  Update Phys Shapes"
+                      orientation="horizontal"
                       stat="simsimphysicsshapeupdatemsec"
                       unit_label="ms"
                       precision="3"
@@ -404,6 +445,7 @@
                       show_mean="false"/>
             <stat_bar name="simsimphysicsothermsec"
                       label="  Physics Other"
+                      orientation="horizontal"
                       stat="simsimphysicsothermsec"
                       unit_label="ms"
                       precision="3"
@@ -414,6 +456,7 @@
                       show_mean="false"/>
             <stat_bar name="simsleepmsec"
                       label="  Sleep Time"
+                      orientation="horizontal"
                       stat="simsleepmsec"
                       unit_label="ms"
                       precision="3"
@@ -424,6 +467,7 @@
                       show_mean="false"/>
             <stat_bar name="simpumpiomsec"
                       label="  Pump IO"
+                      orientation="horizontal"
                       stat="simpumpiomsec"
                       unit_label="ms"
                       precision="3"
-- 
GitLab