diff --git a/indra/llcommon/llqueuedthread.cpp b/indra/llcommon/llqueuedthread.cpp
index 6e2a2b140fe308ef2e8dec61b0a52996e47fb0e4..218f6dbcd0b3edb56cbfeb791fd61411ae0f36f7 100644
--- a/indra/llcommon/llqueuedthread.cpp
+++ b/indra/llcommon/llqueuedthread.cpp
@@ -28,7 +28,7 @@
 
 #include "llstl.h"
 #include "lltimer.h"	// ms_sleep()
-#include "lltrace.h"
+#include "lltracethreadrecorder.h"
 
 //============================================================================
 
diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp
index 6723e427f53a8a46e0f14e8c4b80663dce4a2211..cc661bab5913b1b2df92677a872cce5066745a1a 100644
--- a/indra/llcommon/llthread.cpp
+++ b/indra/llcommon/llthread.cpp
@@ -33,6 +33,7 @@
 
 #include "lltimer.h"
 #include "lltrace.h"
+#include "lltracethreadrecorder.h"
 
 #if LL_LINUX || LL_SOLARIS
 #include <sched.h>
diff --git a/indra/llcommon/lltrace.cpp b/indra/llcommon/lltrace.cpp
index 2b1c8d8ce88cd9cf4a299d6cbed2f3052cf5c0bf..d5911ece2529e8703fccb5d2803c85c2164b12cd 100644
--- a/indra/llcommon/lltrace.cpp
+++ b/indra/llcommon/lltrace.cpp
@@ -27,6 +27,7 @@
 
 #include "lltrace.h"
 #include "lltracerecording.h"
+#include "lltracethreadrecorder.h"
 
 namespace LLTrace
 {
diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h
index e655a3582e412f5a93aca441e9354f1ebf7edfa5..a6334e176b376f7b8117da8934ff9444448d2da8 100644
--- a/indra/llcommon/lltrace.h
+++ b/indra/llcommon/lltrace.h
@@ -32,9 +32,9 @@
 
 #include "llmemory.h"
 #include "llrefcount.h"
-#include "lltracerecording.h"
-#include "lltracethreadrecorder.h"
+//#include "lltracethreadrecorder.h"
 #include "llunit.h"
+#include "llapr.h"
 
 #include <list>
 
@@ -44,6 +44,8 @@
 
 namespace LLTrace
 {
+	class Recording;
+
 	void init();
 	void cleanup();
 
@@ -89,23 +91,23 @@ namespace LLTrace
 			return mStorage[index]; 
 		}
 
-		void mergeSamples(const AccumulatorBuffer<ACCUMULATOR>& other)
+		void addSamples(const AccumulatorBuffer<ACCUMULATOR>& other)
 		{
 			llassert(mNextStorageSlot == other.mNextStorageSlot);
 
 			for (size_t i = 0; i < mNextStorageSlot; i++)
 			{
-				mStorage[i].mergeSamples(other.mStorage[i]);
+				mStorage[i].addSamples(other.mStorage[i]);
 			}
 		}
 
-		void mergeDeltas(const AccumulatorBuffer<ACCUMULATOR>& start, const AccumulatorBuffer<ACCUMULATOR>& finish)
+		void addDeltas(const AccumulatorBuffer<ACCUMULATOR>& start, const AccumulatorBuffer<ACCUMULATOR>& finish)
 		{
 			llassert(mNextStorageSlot == start.mNextStorageSlot && mNextStorageSlot == finish.mNextStorageSlot);
 
 			for (size_t i = 0; i < mNextStorageSlot; i++)
 			{
-				mStorage[i].mergeDeltas(start.mStorage[i], finish.mStorage[i]);
+				mStorage[i].addDeltas(start.mStorage[i], finish.mStorage[i]);
 			}
 		}
 
@@ -173,8 +175,9 @@ namespace LLTrace
 	class LL_COMMON_API TraceType 
 	{
 	public:
-		TraceType(const std::string& name)
-		:	mName(name)
+		TraceType(const char* name, const char* description = NULL)
+		:	mName(name),
+			mDescription(description ? description : "")
 		{
 			mAccumulatorIndex = AccumulatorBuffer<ACCUMULATOR>::getDefaultBuffer().reserveSlot();
 		}
@@ -189,6 +192,7 @@ namespace LLTrace
 
 	protected:
 		std::string	mName;
+		std::string mDescription;
 		size_t		mAccumulatorIndex;
 	};
 
@@ -201,6 +205,8 @@ namespace LLTrace
 		:	mSum(0),
 			mMin(0),
 			mMax(0),
+			mMean(0),
+			mVarianceSum(0),
 			mNumSamples(0)
 		{}
 
@@ -218,10 +224,11 @@ namespace LLTrace
 			}
 			F32 old_mean = mMean;
 			mMean += ((F32)value - old_mean) / (F32)mNumSamples;
-			mStandardDeviation += ((F32)value - old_mean) * ((F32)value - mMean);
+			mVarianceSum += ((F32)value - old_mean) * ((F32)value - mMean);
+			mLastValue = value;
 		}
 
-		void mergeSamples(const MeasurementAccumulator<T>& other)
+		void addSamples(const MeasurementAccumulator<T>& other)
 		{
 			mSum += other.mSum;
 			if (other.mMin < mMin)
@@ -240,19 +247,20 @@ namespace LLTrace
 				n_2 = (F32)other.mNumSamples;
 			F32 m_1 = mMean,
 				m_2 = other.mMean;
-			F32 sd_1 = mStandardDeviation,
-				sd_2 = other.mStandardDeviation;
+			F32 sd_1 = getStandardDeviation(),
+				sd_2 = other.getStandardDeviation();
 			// combine variance (and hence standard deviation) of 2 different sized sample groups using
 			// the following formula: http://www.mrc-bsu.cam.ac.uk/cochrane/handbook/chapter_7/7_7_3_8_combining_groups.htm
-			F32 variance = ((((n_1 - 1.f) * sd_1 * sd_1)
+			mVarianceSum =  (F32)mNumSamples
+							* ((((n_1 - 1.f) * sd_1 * sd_1)
 								+ ((n_2 - 1.f) * sd_2 * sd_2)
 								+ (((n_1 * n_2) / (n_1 + n_2))
 									* ((m_1 * m_1) + (m_2 * m_2) - (2.f * m_1 * m_2))))
 							/ (n_1 + n_2 - 1.f));
-			mStandardDeviation = sqrtf(variance);
+			mLastValue = other.mLastValue;
 		}
 
-		void mergeDeltas(const MeasurementAccumulator<T>& start, const MeasurementAccumulator<T>& finish)
+		void addDeltas(const MeasurementAccumulator<T>& start, const MeasurementAccumulator<T>& finish)
 		{
 			llerrs << "Delta merge invalid for measurement accumulators" << llendl;
 		}
@@ -268,16 +276,18 @@ namespace LLTrace
 		T	getSum() const { return mSum; }
 		T	getMin() const { return mMin; }
 		T	getMax() const { return mMax; }
+		T	getLastValue() const { return mLastValue; }
 		F32	getMean() const { return mMean; }
-		F32 getStandardDeviation() const { return mStandardDeviation; }
+		F32 getStandardDeviation() const { return sqrtf(mVarianceSum / mNumSamples); }
 
 	private:
 		T	mSum,
 			mMin,
-			mMax;
+			mMax,
+			mLastValue;
 
 		F32 mMean,
-			mStandardDeviation;
+			mVarianceSum;
 
 		U32	mNumSamples;
 	};
@@ -297,13 +307,13 @@ namespace LLTrace
 			mSum += value;
 		}
 
-		void mergeSamples(const RateAccumulator<T>& other)
+		void addSamples(const RateAccumulator<T>& other)
 		{
 			mSum += other.mSum;
 			mNumSamples += other.mNumSamples;
 		}
 
-		void mergeDeltas(const RateAccumulator<T>& start, const RateAccumulator<T>& finish)
+		void addDeltas(const RateAccumulator<T>& start, const RateAccumulator<T>& finish)
 		{
 			mSum += finish.mSum - start.mSum;
 			mNumSamples += finish.mNumSamples - start.mNumSamples;
@@ -329,7 +339,10 @@ namespace LLTrace
 		public LLInstanceTracker<Measurement<T, IS_UNIT>, std::string>
 	{
 	public:
-		Measurement(const std::string& name) 
+		typedef T storage_t;
+		typedef T base_unit_t;
+
+		Measurement(const char* name, const char* description = NULL) 
 		:	TraceType(name),
 			LLInstanceTracker(name)
 		{}
@@ -345,8 +358,11 @@ namespace LLTrace
 	:	public Measurement<typename T::value_t>
 	{
 	public:
+		typedef typename T::storage_t storage_t;
+		typedef typename T::base_unit_t base_unit_t;
+
 		typedef Measurement<typename T::value_t> base_measurement_t;
-		Measurement(const std::string& name) 
+		Measurement(const char* name, const char* description = NULL) 
 		:	Measurement<typename T::value_t>(name)
 		{}
 
@@ -363,7 +379,10 @@ namespace LLTrace
 		public LLInstanceTracker<Rate<T>, std::string>
 	{
 	public:
-		Rate(const std::string& name) 
+		typedef T storage_t;
+		typedef T base_unit_t;
+
+		Rate(const char* name, const char* description = NULL) 
 		:	TraceType(name),
 			LLInstanceTracker(name)
 		{}
@@ -379,7 +398,10 @@ namespace LLTrace
 	:	public Rate<typename T::value_t>
 	{
 	public:
-		Rate(const std::string& name) 
+		typedef typename T::storage_t storage_t;
+		typedef typename T::base_unit_t base_unit_t;
+
+		Rate(const char* name, const char* description = NULL) 
 		:	Rate<typename T::value_t>(name)
 		{}
 
@@ -394,7 +416,9 @@ namespace LLTrace
 	class LL_COMMON_API Count 
 	{
 	public:
-		Count(const std::string& name) 
+		typedef typename Rate<T>::base_unit_t base_unit_t;
+
+		Count(const char* name) 
 		:	mIncrease(name + "_increase"),
 			mDecrease(name + "_decrease"),
 			mTotal(name)
@@ -413,7 +437,7 @@ namespace LLTrace
 			mTotal.add(value);
 		}
 	private:
-		friend class LLTrace::Recording;
+		friend LLTrace::Recording;
 		Rate<T> mIncrease;
 		Rate<T> mDecrease;
 		Rate<T> mTotal;
@@ -433,14 +457,14 @@ namespace LLTrace
 		bool							mMoveUpTree;	// needs to be moved up the tree of timers at the end of frame
 		std::vector<TimerAccumulator*>	mChildren;		// currently assumed child timers
 
-		void mergeSamples(const TimerAccumulator& other)
+		void addSamples(const TimerAccumulator& other)
 		{
 			mTotalTimeCounter += other.mTotalTimeCounter;
 			mChildTimeCounter += other.mChildTimeCounter;
 			mCalls += other.mCalls;
 		}
 
-		void mergeDeltas(const TimerAccumulator& start, const TimerAccumulator& finish)
+		void addDeltas(const TimerAccumulator& start, const TimerAccumulator& finish)
 		{
 			mTotalTimeCounter += finish.mTotalTimeCounter - start.mTotalTimeCounter;
 			mChildTimeCounter += finish.mChildTimeCounter - start.mChildTimeCounter;
diff --git a/indra/llcommon/lltracerecording.cpp b/indra/llcommon/lltracerecording.cpp
index 9a08770bd7668916a1e5686a9c2e7b5379fd0e40..08839303190125171b0366cdd463f030f4493208 100644
--- a/indra/llcommon/lltracerecording.cpp
+++ b/indra/llcommon/lltracerecording.cpp
@@ -25,8 +25,9 @@
 
 #include "linden_common.h"
 
-#include "lltracerecording.h"
 #include "lltrace.h"
+#include "lltracerecording.h"
+#include "lltracethreadrecorder.h"
 #include "llthread.h"
 
 namespace LLTrace
@@ -49,7 +50,7 @@ Recording::~Recording()
 void Recording::update()
 {
 	if (isStarted())
-	{
+{
 		LLTrace::get_thread_recorder()->update(this);
 		mElapsedSeconds = 0.0;
 		mSamplingTimer.reset();
@@ -67,16 +68,16 @@ void Recording::handleReset()
 }
 
 void Recording::handleStart()
-{
-	mSamplingTimer.reset();
-	LLTrace::get_thread_recorder()->activate(this);
+	{
+		mSamplingTimer.reset();
+		LLTrace::get_thread_recorder()->activate(this);
 }
 
 void Recording::handleStop()
-{
-	mElapsedSeconds += mSamplingTimer.getElapsedTimeF64();
-	LLTrace::get_thread_recorder()->deactivate(this);
-}
+	{
+		mElapsedSeconds += mSamplingTimer.getElapsedTimeF64();
+		LLTrace::get_thread_recorder()->deactivate(this);
+	}
 
 void Recording::handleSplitTo(Recording& other)
 {
@@ -92,99 +93,22 @@ void Recording::makePrimary()
 	mStackTimers.write()->makePrimary();
 }
 
-bool Recording::isPrimary()
+bool Recording::isPrimary() const
 {
 	return mRates->isPrimary();
 }
 
 void Recording::mergeRecording( const Recording& other )
 {
-	mRates.write()->mergeSamples(*other.mRates);
-	mMeasurements.write()->mergeSamples(*other.mMeasurements);
-	mStackTimers.write()->mergeSamples(*other.mStackTimers);
-}
-
-void Recording::mergeDeltas(const Recording& baseline, const Recording& target)
-{
-	mRates.write()->mergeDeltas(*baseline.mRates, *target.mRates);
-	mStackTimers.write()->mergeDeltas(*baseline.mStackTimers, *target.mStackTimers);
+	mRates.write()->addSamples(*other.mRates);
+	mMeasurements.write()->addSamples(*other.mMeasurements);
+	mStackTimers.write()->addSamples(*other.mStackTimers);
 }
 
-
-F32 Recording::getSum(const Rate<F32>& stat)
-{
-	return stat.getAccumulator(mRates).getSum();
-}
-
-F32 Recording::getPerSec(const Rate<F32>& stat)
+void Recording::mergeRecordingDelta(const Recording& baseline, const Recording& target)
 {
-	return stat.getAccumulator(mRates).getSum() / mElapsedSeconds;
+	mRates.write()->addDeltas(*baseline.mRates, *target.mRates);
+	mStackTimers.write()->addDeltas(*baseline.mStackTimers, *target.mStackTimers);
 }
 
-F32 Recording::getSum(const Measurement<F32>& stat)
-{
-	return stat.getAccumulator(mMeasurements).getSum();
-}
-
-F32 Recording::getMin(const Measurement<F32>& stat)
-{
-	return stat.getAccumulator(mMeasurements).getMin();
-}
-
-F32 Recording::getMax(const Measurement<F32>& stat)
-{
-	return stat.getAccumulator(mMeasurements).getMax();
-}
-
-F32 Recording::getMean(const Measurement<F32>& stat)
-{
-	return stat.getAccumulator(mMeasurements).getMean();
-}
-
-F32 Recording::getStandardDeviation(const Measurement<F32>& stat)
-{
-	return stat.getAccumulator(mMeasurements).getStandardDeviation();
-}
-
-F32 Recording::getSum(const Count<F32>& stat)
-{
-	return getSum(stat.mTotal);
-}
-
-F32 Recording::getPerSec(const Count<F32>& stat)
-{
-	return getPerSec(stat.mTotal);
-}
-
-F32 Recording::getIncrease(const Count<F32>& stat)
-{
-	return getSum(stat.mIncrease);
-}
-
-F32 Recording::getIncreasePerSec(const Count<F32>& stat)
-{
-	return getPerSec(stat.mIncrease);
-}
-
-F32 Recording::getDecrease(const Count<F32>& stat)
-{
-	return getSum(stat.mDecrease);
-}
-
-F32 Recording::getDecreasePerSec(const Count<F32>& stat)
-{
-	return getPerSec(stat.mDecrease);
-}
-
-F32 Recording::getChurn(const Count<F32>& stat)
-{
-	return getIncrease(stat) + getDecrease(stat);
-}
-
-F32 Recording::getChurnPerSec(const Count<F32>& stat)
-{
-	return getIncreasePerSec(stat) + getDecreasePerSec(stat);
-}
-
-
 }
diff --git a/indra/llcommon/lltracerecording.h b/indra/llcommon/lltracerecording.h
index 4399a65cfb2d7fe8f73d9746030ab373625d4d80..0a1a02fa02199ab463746ebe7e7b28ad1132d9c2 100644
--- a/indra/llcommon/lltracerecording.h
+++ b/indra/llcommon/lltracerecording.h
@@ -32,6 +32,7 @@
 
 #include "llpointer.h"
 #include "lltimer.h"
+#include "lltrace.h"
 
 template<typename DERIVED>
 class LL_COMMON_API LLVCRControlsMixinInterface
@@ -176,13 +177,13 @@ class LL_COMMON_API LLVCRControlsMixin
 
 namespace LLTrace
 {
-	template<typename T, typename IS_UNIT> class Rate;
-	template<typename T, typename IS_UNIT> class Measurement;
-	template<typename T> class Count;
-	template<typename T> class AccumulatorBuffer;
-	template<typename T> class RateAccumulator;
-	template<typename T> class MeasurementAccumulator;
-	class TimerAccumulator;
+	//template<typename T, typename IS_UNIT> class Rate;
+	//template<typename T, typename IS_UNIT> class Measurement;
+	//template<typename T> class Count;
+	//template<typename T> class AccumulatorBuffer;
+	//template<typename T> class RateAccumulator;
+	//template<typename T> class MeasurementAccumulator;
+	//class TimerAccumulator;
 
 	class LL_COMMON_API Recording : public LLVCRControlsMixin<Recording>
 	{
@@ -192,37 +193,120 @@ namespace LLTrace
 		~Recording();
 
 		void makePrimary();
-		bool isPrimary();
+		bool isPrimary() const;
 
 		void mergeRecording(const Recording& other);
-		void mergeDeltas(const Recording& baseline, const Recording& target);
+		void mergeRecordingDelta(const Recording& baseline, const Recording& target);
 
-		void reset();
 		void update();
-		
+
 		// Rate accessors
-		F32 getSum(const Rate<F32, void>& stat);
-		F32 getPerSec(const Rate<F32, void>& stat);
+		template <typename T, typename IS_UNIT>
+		typename Rate<T, IS_UNIT>::base_unit_t getSum(const Rate<T, IS_UNIT>& stat) const
+		{
+			return (typename Rate<T, IS_UNIT>::base_unit_t)stat.getAccumulator(mRates).getSum();
+		}
+
+		template <typename T, typename IS_UNIT>
+		typename Rate<T, IS_UNIT>::base_unit_t getPerSec(const Rate<T, IS_UNIT>& stat) const
+		{
+			return (typename Rate<T, IS_UNIT>::base_unit_t)stat.getAccumulator(mRates).getSum() / mElapsedSeconds;
+		}
 
 		// Measurement accessors
-		F32 getSum(const Measurement<F32, void>& stat);
-		F32 getPerSec(const Measurement<F32, void>& stat);
-		F32 getMin(const Measurement<F32, void>& stat);
-		F32 getMax(const Measurement<F32, void>& stat);
-		F32 getMean(const Measurement<F32, void>& stat);
-		F32 getStandardDeviation(const Measurement<F32, void>& stat);
+		template <typename T, typename IS_UNIT>
+		typename Measurement<T, IS_UNIT>::base_unit_t getSum(const Measurement<T, IS_UNIT>& stat) const
+		{
+			return (typename Measurement<T, IS_UNIT>::base_unit_t)stat.getAccumulator(mMeasurements).getSum();
+
+		}
+
+		template <typename T, typename IS_UNIT>
+		typename Measurement<T, IS_UNIT>::base_unit_t getPerSec(const Measurement<T, IS_UNIT>& stat) const
+		{
+			return (typename Rate<T, IS_UNIT>::base_unit_t)stat.getAccumulator(mMeasurements).getSum() / mElapsedSeconds;
+		}
+
+		template <typename T, typename IS_UNIT>
+		typename Measurement<T, IS_UNIT>::base_unit_t getMin(const Measurement<T, IS_UNIT>& stat) const
+		{
+			return (typename Measurement<T, IS_UNIT>::base_unit_t)stat.getAccumulator(mMeasurements).getMin();
+		}
+
+		template <typename T, typename IS_UNIT>
+		typename Measurement<T, IS_UNIT>::base_unit_t getMax(const Measurement<T, IS_UNIT>& stat) const
+		{
+			return (typename Measurement<T, IS_UNIT>::base_unit_t)stat.getAccumulator(mMeasurements).getMax();
+		}
+
+		template <typename T, typename IS_UNIT>
+		typename Measurement<T, IS_UNIT>::base_unit_t getMean(const Measurement<T, IS_UNIT>& stat) const
+		{
+			return (typename Measurement<T, IS_UNIT>::base_unit_t)stat.getAccumulator(mMeasurements).getMean();
+		}
+
+		template <typename T, typename IS_UNIT>
+		typename Measurement<T, IS_UNIT>::base_unit_t getStandardDeviation(const Measurement<T, IS_UNIT>& stat) const
+		{
+			return (typename Measurement<T, IS_UNIT>::base_unit_t)stat.getAccumulator(mMeasurements).getStandardDeviation();
+		}
+
+		template <typename T, typename IS_UNIT>
+		typename Measurement<T, IS_UNIT>::base_unit_t getLastValue(const Measurement<T, IS_UNIT>& stat) const
+		{
+			return (typename Measurement<T, IS_UNIT>::base_unit_t)stat.getAccumulator(mMeasurements).getLastValue();
+		}
 
 		// Count accessors
-		F32 getSum(const Count<F32>& stat);
-		F32 getPerSec(const Count<F32>& stat);
-		F32 getIncrease(const Count<F32>& stat);
-		F32 getIncreasePerSec(const Count<F32>& stat);
-		F32 getDecrease(const Count<F32>& stat);
-		F32 getDecreasePerSec(const Count<F32>& stat);
-		F32 getChurn(const Count<F32>& stat);
-		F32 getChurnPerSec(const Count<F32>& stat);
+		template <typename T>
+		typename Count<T>::base_unit_t getSum(const Count<T>& stat) const
+		{
+			return getSum(stat.mTotal);
+		}
+
+		template <typename T>
+		typename Count<T>::base_unit_t getPerSec(const Count<T>& stat) const
+		{
+			return getPerSec(stat.mTotal);
+		}
+
+		template <typename T>
+		typename Count<T>::base_unit_t getIncrease(const Count<T>& stat) const
+		{
+			return getPerSec(stat.mTotal);
+		}
+
+		template <typename T>
+		typename Count<T>::base_unit_t getIncreasePerSec(const Count<T>& stat) const
+		{
+			return getPerSec(stat.mIncrease);
+		}
+
+		template <typename T>
+		typename Count<T>::base_unit_t getDecrease(const Count<T>& stat) const
+		{
+			return getPerSec(stat.mDecrease);
+		}
 
-		F64 getSampleTime() { return mElapsedSeconds; }
+		template <typename T>
+		typename Count<T>::base_unit_t getDecreasePerSec(const Count<T>& stat) const
+		{
+			return getPerSec(stat.mDecrease);
+		}
+
+		template <typename T>
+		typename Count<T>::base_unit_t getChurn(const Count<T>& stat) const
+		{
+			return getIncrease(stat) + getDecrease(stat);
+		}
+
+		template <typename T>
+		typename Count<T>::base_unit_t getChurnPerSec(const Count<T>& stat) const
+		{
+			return getIncreasePerSec(stat) + getDecreasePerSec(stat);
+		}
+
+		F64 getSampleTime() const { return mElapsedSeconds; }
 
 	private:
 		friend class PeriodicRecording;
@@ -254,7 +338,7 @@ namespace LLTrace
 			mCurPeriod(0),
 			mTotalValid(false),
 			mRecordingPeriods(new Recording[num_periods])
-		{
+	{
 			llassert(mNumPeriods > 0);
 		}
 
diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp
index 4d020f5650d47ffa9ac22334ccb16b539fcce4e4..3acd06d553e724d4aea1e530374d52d9a8108f6c 100644
--- a/indra/llcommon/lltracethreadrecorder.cpp
+++ b/indra/llcommon/lltracethreadrecorder.cpp
@@ -25,7 +25,7 @@
 
 #include "linden_common.h"
 
-#include "lltrace.h"
+#include "lltracethreadrecorder.h"
 
 namespace LLTrace
 {
@@ -118,16 +118,16 @@ ThreadRecorder::ActiveRecording::ActiveRecording( Recording* source, Recording*
 
 void ThreadRecorder::ActiveRecording::mergeMeasurements(ThreadRecorder::ActiveRecording& other)
 {
-	mBaseline.mMeasurements.write()->mergeSamples(*other.mBaseline.mMeasurements);
+	mBaseline.mMeasurements.write()->addSamples(*other.mBaseline.mMeasurements);
 }
 
 void ThreadRecorder::ActiveRecording::flushAccumulators(Recording* current)
 {
 	// accumulate statistics-like measurements
-	mTargetRecording->mMeasurements.write()->mergeSamples(*mBaseline.mMeasurements);
+	mTargetRecording->mMeasurements.write()->addSamples(*mBaseline.mMeasurements);
 	// for rate-like measurements, merge total change since baseline
-	mTargetRecording->mRates.write()->mergeDeltas(*mBaseline.mRates, *current->mRates);
-	mTargetRecording->mStackTimers.write()->mergeDeltas(*mBaseline.mStackTimers, *current->mStackTimers);
+	mTargetRecording->mRates.write()->addDeltas(*mBaseline.mRates, *current->mRates);
+	mTargetRecording->mStackTimers.write()->addDeltas(*mBaseline.mStackTimers, *current->mStackTimers);
 	// reset baselines
 	mBaseline.mRates.write()->copyFrom(*current->mRates);
 	mBaseline.mStackTimers.write()->copyFrom(*current->mStackTimers);
diff --git a/indra/llcommon/llunit.h b/indra/llcommon/llunit.h
index 52b837fdc304e05da19f7331128e67a728d1fcd2..2664bd77e9bfae9dc64f097ca1cea3b62d8f5eb5 100644
--- a/indra/llcommon/llunit.h
+++ b/indra/llcommon/llunit.h
@@ -30,21 +30,24 @@
 #include "stdtypes.h"
 #include "llpreprocessor.h"
 
-template<typename BASE_UNIT, typename DERIVED_UNIT = BASE_UNIT>
-struct LLUnit : public BASE_UNIT
+template<typename STORAGE_TYPE, typename BASE_UNIT, typename DERIVED_UNIT = BASE_UNIT>
+struct LLUnitType : public BASE_UNIT
 {
-	typedef LLUnit<BASE_UNIT, DERIVED_UNIT> unit_t;
+	typedef DERIVED_UNIT unit_t;
 	typedef typename BASE_UNIT::value_t value_t;
 	typedef void is_unit_t;
 
-	LLUnit()
+	LLUnitType()
 	{}
 
-	explicit LLUnit(value_t value)
+	explicit LLUnitType(value_t value)
 	:	BASE_UNIT(convertToBase(value))
 	{}
 
-	operator value_t() { return value(); }
+	operator unit_t& ()
+	{
+		return static_cast<unit_t&>(*this);
+	}
 
 	value_t value() const
 	{
@@ -59,47 +62,72 @@ struct LLUnit : public BASE_UNIT
 
 	static value_t convertToBase(value_t derived_value)
 	{
-		return (value_t)((F32)derived_value * DERIVED_UNIT::conversionToBaseFactor());
+		return (value_t)((F32)derived_value * unit_t::conversionToBaseFactor());
 	}
 
 	static value_t convertToDerived(value_t base_value)
 	{
-		return (value_t)((F32)base_value / DERIVED_UNIT::conversionToBaseFactor());
+		return (value_t)((F32)base_value / unit_t::conversionToBaseFactor());
+	}
+
+	unit_t operator + (const unit_t other) const
+	{
+		return unit_t(mValue + other.mValue);
+	}
+
+	unit_t operator - (const unit_t other) const
+	{
+		return unit_t(mValue - other.mValue);
+	}
+
+	unit_t operator * (value_t multiplicand) const
+	{
+		return unit_t(mValue * multiplicand);
+	}
+
+	unit_t operator / (value_t divisor) const
+	{
+		return unit_t(mValue / divisor);
 	}
 
 };
 
-template<typename T>
-struct LLUnit<T, T>
+template<typename STORAGE_TYPE, typename T>
+struct LLUnitType<STORAGE_TYPE, T, T>
 {
-	typedef LLUnit<T, T> unit_t;
-	typedef T value_t;
+	typedef T unit_t;
+	typedef typename STORAGE_TYPE value_t;
 	typedef void is_unit_t;
 
-	LLUnit()
+	LLUnitType()
 	:	mValue()
 	{}
 
-	explicit LLUnit(T value)
+	explicit LLUnitType(value_t value)
 	:	mValue(value)
 	{}
 
-	unit_t& operator=(T value)
+	unit_t& operator=(value_t value)
 	{
 		setBaseValue(value);
 		return *this;
 	}
 
+	operator unit_t& ()
+	{
+		return static_cast<unit_t&>(*this);
+	}
+
 	value_t value() { return mValue; }
 
 	static value_t convertToBase(value_t derived_value)
 	{
-		return (value_t)1;
+		return (value_t)derived_value;
 	}
 
 	static value_t convertToDerived(value_t base_value)
 	{
-		return (value_t)1;
+		return (value_t)base_value;
 	}
 
 	unit_t operator + (const unit_t other) const
@@ -143,68 +171,74 @@ struct LLUnit<T, T>
 	}
 
 protected:
-	void setBaseValue(T value)
+	void setBaseValue(value_t value)
 	{
 		mValue = value;
 	}
 
-	T mValue;
+	value_t mValue;
 };
 
 #define LL_DECLARE_BASE_UNIT(unit_name)                 \
 	template<typename STORAGE_TYPE>                     \
-	struct unit_name : public LLUnit<STORAGE_TYPE>      \
+	struct unit_name : public LLUnitType<STORAGE_TYPE, unit_name<STORAGE_TYPE> >            \
 	{                                                   \
+		typedef unit_name<STORAGE_TYPE> base_unit_t;                                        \
+		typedef STORAGE_TYPE			storage_t;			                                \
+	                                                                                        \
 		unit_name(STORAGE_TYPE value)                   \
-		:	LLUnit(value)                               \
+		:	LLUnitType(value)                                                               \
 		{}                                              \
 		                                                \
 		unit_name()                                     \
 		{}                                              \
 		                                                \
-		template <typename T>                           \
-		unit_name(const LLUnit<unit_name, T>& other)    \
+		template <typename SOURCE_STORAGE_TYPE, typename SOURCE_TYPE>                       \
+		unit_name(const LLUnitType<SOURCE_STORAGE_TYPE, unit_name, SOURCE_TYPE>& source)    \
 		{                                               \
-			setBaseValue(other.unit_name::get());       \
+			setBaseValue(source.unit_t::value());												\
 		}                                               \
 		                                                \
-		using LLUnit<STORAGE_TYPE>::operator +;	        \
-		using LLUnit<STORAGE_TYPE>::operator +=;        \
-		using LLUnit<STORAGE_TYPE>::operator -;         \
-		using LLUnit<STORAGE_TYPE>::operator -=;        \
-		using LLUnit<STORAGE_TYPE>::operator *;         \
-		using LLUnit<STORAGE_TYPE>::operator *=;        \
-		using LLUnit<STORAGE_TYPE>::operator /;         \
-		using LLUnit<STORAGE_TYPE>::operator /=;        \
+		using LLUnitType::operator +;	                                                    \
+		using LLUnitType::operator +=;														\
+		using LLUnitType::operator -;														\
+		using LLUnitType::operator -=;														\
+		using LLUnitType::operator *;														\
+		using LLUnitType::operator *=;														\
+		using LLUnitType::operator /;														\
+		using LLUnitType::operator /=;														\
 	};
 
 #define LL_DECLARE_DERIVED_UNIT(base_unit, derived_unit, conversion_factor)                   \
 	template<typename STORAGE_TYPE>                                                           \
-	struct derived_unit : public LLUnit<base_unit<STORAGE_TYPE>, derived_unit<STORAGE_TYPE> > \
+	struct derived_unit : public LLUnitType<STORAGE_TYPE, base_unit<STORAGE_TYPE>, derived_unit<STORAGE_TYPE> >     \
 	{                                                                                         \
+		typedef base_unit<STORAGE_TYPE> base_unit_t;                                                                \
+		typedef STORAGE_TYPE			storage_t;							                                        \
+		                                                                                                            \
 		derived_unit(value_t value)                                                           \
-		:	LLUnit(value)                                                                     \
+		:	LLUnitType(value)                                                                                       \
 		{}                                                                                    \
 		                                                                                      \
 		derived_unit()                                                                        \
 		{}                                                                                    \
 		                                                                                      \
-		template <typename T>                                                                 \
-		derived_unit(const LLUnit<base_unit<STORAGE_TYPE>, T>& other)                         \
+		template <typename SOURCE_STORAGE_TYPE, typename SOURCE_TYPE>                                               \
+		derived_unit(const LLUnitType<SOURCE_STORAGE_TYPE, base_unit<STORAGE_TYPE>, SOURCE_TYPE>& source)           \
 		{                                                                                     \
-			setBaseValue(other.base_unit<STORAGE_TYPE>::get());                               \
+			setBaseValue(source.base_unit_t::value());																\
 		}                                                                                     \
 		                                                                                      \
 		static F32 conversionToBaseFactor() { return (F32)(conversion_factor); }              \
 		                                                                                      \
-	using LLUnit<STORAGE_TYPE>::operator +;	                                                  \
-	using LLUnit<STORAGE_TYPE>::operator +=;                                                  \
-	using LLUnit<STORAGE_TYPE>::operator -;                                                   \
-	using LLUnit<STORAGE_TYPE>::operator -=;                                                  \
-	using LLUnit<STORAGE_TYPE>::operator *;                                                   \
-	using LLUnit<STORAGE_TYPE>::operator *=;                                                  \
-	using LLUnit<STORAGE_TYPE>::operator /;                                                   \
-	using LLUnit<STORAGE_TYPE>::operator /=;                                                  \
+		using LLUnitType::operator +;	                                                                            \
+		using LLUnitType::operator +=;                                                                              \
+		using LLUnitType::operator -;                                                                               \
+		using LLUnitType::operator -=;                                                                              \
+		using LLUnitType::operator *;                                                                               \
+		using LLUnitType::operator *=;                                                                              \
+		using LLUnitType::operator /;                                                                               \
+		using LLUnitType::operator /=;                                                                              \
 	};
 
 namespace LLUnits
diff --git a/indra/llui/llstatbar.cpp b/indra/llui/llstatbar.cpp
index bc9603804b803f4a3cd2cd8740361330a989038d..4cbf6950597ca61327f2bfa3217a7f0acd7f72c8 100644
--- a/indra/llui/llstatbar.cpp
+++ b/indra/llui/llstatbar.cpp
@@ -37,6 +37,7 @@
 #include "llstat.h"
 #include "lluictrlfactory.h"
 #include "lltracerecording.h"
+#include "lltracethreadrecorder.h"
 
 ///////////////////////////////////////////////////////////////////////////////////
 
diff --git a/indra/llui/llstatgraph.cpp b/indra/llui/llstatgraph.cpp
index aed9e4ec93808fbe3709e6bbc67bf5278a8ad23d..1d4527aaa3378fa69e56d02310f0c5c0c4c3b65c 100644
--- a/indra/llui/llstatgraph.cpp
+++ b/indra/llui/llstatgraph.cpp
@@ -36,6 +36,7 @@
 #include "llgl.h"
 #include "llglheaders.h"
 #include "lltracerecording.h"
+#include "lltracethreadrecorder.h"
 //#include "llviewercontrol.h"
 
 ///////////////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 22f3cce9e86e9deffddaf8a7a85f2f6aa338771d..a43776912c2d5c17da04f8d06bc957e091039019 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -61,6 +61,7 @@
 #include "llcalc.h"
 #include "lltexturestats.h"
 #include "lltrace.h"
+#include "lltracethreadrecorder.h"
 #include "llviewerwindow.h"
 #include "llviewerdisplay.h"
 #include "llviewermedia.h"
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index e7538d685dc37231324c27006b1afdaf35010f43..2ce5f95b546de5f0194ec62d6b61b1e4b8c36bd9 100644
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -2316,7 +2316,8 @@ S32 LLTextureFetch::update(F32 max_time_ms)
 
 	if(mCurlGetRequest)
 	{
-		gTextureList.sTextureBits += mCurlGetRequest->getTotalReceivedBits();
+		LLStatViewer::TEXTURE_KBIT.add<LLUnits::Bits<F32> >(mCurlGetRequest->getTotalReceivedBits());
+		//gTextureList.sTextureBits += mCurlGetRequest->getTotalReceivedBits();
 	}
 
 	if(mFetchDebugger)
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 85ea54383863deb20b4bbaeb05720e3655cb5622..79ed093382d9dd7cec0ce28380345db0de6d37bd 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -4756,18 +4756,23 @@ void process_sim_stats(LLMessageSystem *msg, void **user_data)
 		switch (stat_id)
 		{
 		case LL_SIM_STAT_TIME_DILATION:
-			LLViewerStats::getInstance()->mSimTimeDilation.addValue(stat_value);
+			LLStatViewer::SIM_TIME_DILATION.sample(stat_value);
+			//LLViewerStats::getInstance()->mSimTimeDilation.addValue(stat_value);
 			break;
 		case LL_SIM_STAT_FPS:
-			LLViewerStats::getInstance()->mSimFPS.addValue(stat_value);
+			LLStatViewer::SIM_FPS.sample(stat_value);
+			//LLViewerStats::getInstance()->mSimFPS.addValue(stat_value);
 			break;
 		case LL_SIM_STAT_PHYSFPS:
-			LLViewerStats::getInstance()->mSimPhysicsFPS.addValue(stat_value);
+			LLStatViewer::SIM_PHYSICS_FPS.sample(stat_value);
+			//LLViewerStats::getInstance()->mSimPhysicsFPS.addValue(stat_value);
 			break;
 		case LL_SIM_STAT_AGENTUPS:
-			LLViewerStats::getInstance()->mSimAgentUPS.addValue(stat_value);
+			LLStatViewer::SIM_AGENT_UPS.sample(stat_value);
+			//LLViewerStats::getInstance()->mSimAgentUPS.addValue(stat_value);
 			break;
 		case LL_SIM_STAT_FRAMEMS:
+			//LLStatViewer::SIM_.sample(stat_value);
 			LLViewerStats::getInstance()->mSimFrameMsec.addValue(stat_value);
 			break;
 		case LL_SIM_STAT_NETMS:
diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp
index 954fa24eaa6593f761b134272e3b715289f7a61f..11d9f5e1eccffae9a161db278a937de8913a4b7b 100755
--- a/indra/newview/llviewerstats.cpp
+++ b/indra/newview/llviewerstats.cpp
@@ -64,32 +64,32 @@
 namespace LLStatViewer
 {
 
-LLTrace::Rate<F32>					FPS("fpsstat"),
-									PACKETS_IN("packetsinstat"),
-									PACKETS_LOST("packetsloststat"),
-									PACKETS_OUT("packetsoutstat"),
-									TEXTURE_PACKETS("texturepacketsstat"),
-									TRIANGLES_DRAWN("trianglesdrawnstat"),
-									CHAT_COUNT("chatcount"),
-									IM_COUNT("imcount"),
-									OBJECT_CREATE("objectcreate"),
-									OBJECT_REZ("objectrez"),
-									LOADING_WEARABLES_LONG_DELAY("loadingwearableslongdelay"),
-									LOGIN_TIMEOUTS("logintimeouts"),
-									FAILED_DOWNLOADS("faileddownloads"),
-									LSL_SAVES("lslsaves"),
-									ANIMATION_UPLOADS("animationuploads"),
-									FLY("fly"),
-									TELEPORT("teleport"),
-									DELETE_OBJECT("deleteobject"),
-									SNAPSHOT("snapshot"),
-									UPLOAD_SOUND("uploadsound"),
-									UPLOAD_TEXTURE("uploadtexture"),
-									EDIT_TEXTURE("edittexture"),
-									KILLED("killed"),
-									FRAMETIME_DOUBLED("frametimedoubled"),
-									TEX_BAKES("texbakes"),
-									TEX_REBAKES("texrebakes");
+LLTrace::Rate<F32>	FPS("fpsstat"),
+					PACKETS_IN("packetsinstat"),
+					PACKETS_LOST("packetsloststat"),
+					PACKETS_OUT("packetsoutstat"),
+					TEXTURE_PACKETS("texturepacketsstat"),
+					TRIANGLES_DRAWN("trianglesdrawnstat"),
+					CHAT_COUNT("chatcount", "Chat messages sent"),
+					IM_COUNT("imcount", "IMs sent"),
+					OBJECT_CREATE("objectcreate"),
+					OBJECT_REZ("objectrez", "Object rez count"),
+					LOADING_WEARABLES_LONG_DELAY("loadingwearableslongdelay", "Wearables took too long to load"),
+					LOGIN_TIMEOUTS("logintimeouts", "Number of login attempts that timed out"),
+					FAILED_DOWNLOADS("faileddownloads", "Number of times LLAssetStorage::getAssetData() has failed"),
+					LSL_SAVES("lslsaves", "Number of times user has saved a script"),
+					ANIMATION_UPLOADS("animationuploads", "Animations uploaded"),
+					FLY("fly", "Fly count"),
+					TELEPORT("teleport", "Teleport count"),
+					DELETE_OBJECT("deleteobject", "Objects deleted"),
+					SNAPSHOT("snapshot", "Snapshots taken"),
+					UPLOAD_SOUND("uploadsound", "Sounds uploaded"),
+					UPLOAD_TEXTURE("uploadtexture", "Textures uploaded"),
+					EDIT_TEXTURE("edittexture", "Changes to textures on objects"),
+					KILLED("killed", "Number of times killed"),
+					FRAMETIME_DOUBLED("frametimedoubled", "Ratio of frames 2x longer than previous"),
+					TEX_BAKES("texbakes"),
+					TEX_REBAKES("texrebakes");
 LLTrace::Rate<LLUnits::Bytes<F32> >	KBIT("kbitstat"),
 									LAYERS_KBIT("layerskbitstat"),
 									OBJECT_KBIT("objectkbitstat"),
@@ -98,53 +98,54 @@ LLTrace::Rate<LLUnits::Bytes<F32> >	KBIT("kbitstat"),
 									ACTUAL_IN_KBIT("actualinkbit"),
 									ACTUAL_OUT_KBIT("actualoutkbit");
 
-LLTrace::Rate<LLUnits::Seconds<F32> > AVATAR_EDIT_TIME("avataredittimr"),
-									 TOOLBOX_TIME("toolboxtime"),
-									 MOUSELOOK_TIME("mouselooktime"),
-									 FPS_10_TIME("fps10time"),
-									 FPS_8_TIME("fps8time"),
-									 FPS_2_TIME("fps2time"),
-									 SIM_20_FPS_TIME("sim20fpstime"),
-									 SIM_PHYSICS_20_FPS_TIME("simphysics20fpstime"),
-									 LOSS_5_PERCENT_TIME("loss5percenttime");
-
-LLTrace::Measurement<F32>			SIM_TIME_DILATION("simtimedilation"),
-									SIM_FPS("simfps"),
-									SIM_PHYSICS_FPS("simphysicsfps"),
-									SIM_AGENT_UPS("simagentups"),
-									SIM_SCRIPT_EPS("simscripteps"),
-									SIM_SKIPPED_SILHOUETTE("simsimskippedsilhouettesteps"),
-									SIM_SKIPPED_CHARACTERS_PERCENTAGE("simsimpctsteppedcharacters"),
-									SIM_MAIN_AGENTS("simmainagents"),
-									SIM_CHILD_AGENTS("simchildagents"),
-									SIM_OBJECTS("simobjects"),
-									SIM_ACTIVE_OBJECTS("simactiveobjects"),
-									SIM_ACTIVE_SCRIPTS("simactivescripts"),
-									SIM_PERCENTAGE_SCRIPTS_RUN("simpctscriptsrun"),
-									SIM_IN_PACKETS_PER_SEC("siminpps"),
-									SIM_OUT_PACKETS_PER_SEC("simoutpps"),
-									SIM_PENDING_DOWNLOADS("simpendingdownloads"),
-									SIM_PENDING_UPLOADS("simpendinguploads"),
-									SIM_PENING_LOCAL_UPLOADS("simpendinglocaluploads"),
-									SIM_PHYSICS_PINNED_TASKS("physicspinnedtasks"),
-									SIM_PHYSICS_LOD_TASKS("physicslodtasks"),
-									NUM_IMAGES("numimagesstat"),
-									NUM_RAW_IMAGES("numrawimagesstat"),
-									NUM_OBJECTS("numobjectsstat"),
-									NUM_ACTIVE_OBJECTS("numactiveobjectsstat"),
-									NUM_NEW_OBJECTS("numnewobjectsstat"),
-									NUM_SIZE_CULLED("numsizeculledstat"),
-									NUM_VIS_CULLED("numvisculledstat"),
-									ENABLE_VBO("enablevbo"),
-									DELTA_BANDWIDTH("deltabandwidth"),
-									MAX_BANDWIDTH("maxbandwidth"),
-									LIGHTING_DETAIL("lightingdetail"),
-									VISIBLE_AVATARS("visibleavatars"),
-									SHADER_OBJECTS("shaderobjects"),
-									DRAW_DISTANCE("drawdistance"),
-									CHAT_BUBBLES("chatbubbles"),
-									WINDOW_WIDTH("windowwidth"),
-									WINDOW_HEIGHT("windowheight");
+LLTrace::Rate<LLUnits::Seconds<F32> > AVATAR_EDIT_TIME("avataredittime", "Seconds in Edit Appearence"),
+									 TOOLBOX_TIME("toolboxtime", "Seconds using Toolbox"),
+									 MOUSELOOK_TIME("mouselooktime", "Seconds in Mouselook"),
+									 FPS_10_TIME("fps10time", "Seconds below 10 FPS"),
+									 FPS_8_TIME("fps8time", "Seconds below 8 FPS"),
+									 FPS_2_TIME("fps2time", "Seconds below 2 FPS"),
+									 SIM_20_FPS_TIME("sim20fpstime", "Seconds with sim FPS below 20"),
+									 SIM_PHYSICS_20_FPS_TIME("simphysics20fpstime", "Seconds with physics FPS below 20"),
+									 LOSS_5_PERCENT_TIME("loss5percenttime", "Seconds with packet loss > 5%");
+
+LLTrace::Measurement<F32>	SIM_TIME_DILATION("simtimedilation"),
+							SIM_FPS("simfps"),
+							SIM_PHYSICS_FPS("simphysicsfps"),
+							SIM_AGENT_UPS("simagentups"),
+							SIM_SCRIPT_EPS("simscripteps"),
+							SIM_SKIPPED_SILHOUETTE("simsimskippedsilhouettesteps"),
+							SIM_SKIPPED_CHARACTERS_PERCENTAGE("simsimpctsteppedcharacters"),
+							SIM_MAIN_AGENTS("simmainagents"),
+							SIM_CHILD_AGENTS("simchildagents"),
+							SIM_OBJECTS("simobjects"),
+							SIM_ACTIVE_OBJECTS("simactiveobjects"),
+							SIM_ACTIVE_SCRIPTS("simactivescripts"),
+							SIM_PERCENTAGE_SCRIPTS_RUN("simpctscriptsrun"),
+							SIM_IN_PACKETS_PER_SEC("siminpps"),
+							SIM_OUT_PACKETS_PER_SEC("simoutpps"),
+							SIM_PENDING_DOWNLOADS("simpendingdownloads"),
+							SIM_PENDING_UPLOADS("simpendinguploads"),
+							SIM_PENDING_LOCAL_UPLOADS("simpendinglocaluploads"),
+							SIM_PENDING_VFS_OPERATIONS("vfspendingoperations"), 
+							SIM_PHYSICS_PINNED_TASKS("physicspinnedtasks"),
+							SIM_PHYSICS_LOD_TASKS("physicslodtasks"),
+							NUM_IMAGES("numimagesstat"),
+							NUM_RAW_IMAGES("numrawimagesstat"),
+							NUM_OBJECTS("numobjectsstat"),
+							NUM_ACTIVE_OBJECTS("numactiveobjectsstat"),
+							NUM_NEW_OBJECTS("numnewobjectsstat"),
+							NUM_SIZE_CULLED("numsizeculledstat"),
+							NUM_VIS_CULLED("numvisculledstat"),
+							ENABLE_VBO("enablevbo", "Vertex Buffers Enabled"),
+							DELTA_BANDWIDTH("deltabandwidth", "Increase/Decrease in bandwidth based on packet loss"),
+							MAX_BANDWIDTH("maxbandwidth", "Max bandwidth setting"),
+							LIGHTING_DETAIL("lightingdetail", "Lighting Detail"),
+							VISIBLE_AVATARS("visibleavatars", "Visible Avatars"),
+							SHADER_OBJECTS("shaderobjects", "Object Shaders"),
+							DRAW_DISTANCE("drawdistance", "Draw Distance"),
+							CHAT_BUBBLES("chatbubbles", "Chat Bubbles Enabled"),
+							WINDOW_WIDTH("windowwidth", "Window width"),
+							WINDOW_HEIGHT("windowheight", "Window height");
 
 LLTrace::Measurement<LLUnits::Bytes<F32> >	SIM_UNACKED_BYTES("simtotalunackedbytes"),
 											SIM_PHYSICS_MEM("physicsmemoryallocated"),
@@ -166,14 +167,16 @@ LLTrace::Measurement<LLUnits::Seconds<F32> > SIM_PHYSICS_TIME("simsimphysicsmsec
 											SIM_SLEEP_TIME("simsleepmsec"),
 											SIM_PUMP_IO_TIME("simpumpiomsec"),
 											SIM_PING("simpingstat"),
-											LOGIN_SECONDS("loginseconds"),
-											REGION_CROSSING_TIME("regioncrossingtime"),
-											FRAME_STACKTIME("framestacktime"),
-											UPDATE_STACKTIME("updatestacktime"),
-											NETWORK_STACKTIME("networkstacktime"),
-											IMAGE_STACKTIME("imagestacktime"),
-											REBUILD_STACKTIME("rebuildstacktime"),
-											RENDER_STACKTIME("renderstacktime");
+											FRAMETIME_JITTER("frametimejitter", "Average delta between successive frame times"),
+											FRAMETIME_SLEW("frametimeslew", "Average delta between frame time and mean"),
+											LOGIN_SECONDS("loginseconds", "Time between LoginRequest and LoginReply"),
+											REGION_CROSSING_TIME("regioncrossingtime", "CROSSING_AVG"),
+											FRAME_STACKTIME("framestacktime", "FRAME_SECS"),
+											UPDATE_STACKTIME("updatestacktime", "UPDATE_SECS"),
+											NETWORK_STACKTIME("networkstacktime", "NETWORK_SECS"),
+											IMAGE_STACKTIME("imagestacktime", "IMAGE_SECS"),
+											REBUILD_STACKTIME("rebuildstacktime", "REBUILD_SECS"),
+											RENDER_STACKTIME("renderstacktime", "RENDER_SECS");
 }
 
 class StatAttributes
@@ -190,139 +193,18 @@ class StatAttributes
 	BOOL mEnabled;
 };
 
-const StatAttributes STAT_INFO[LLViewerStats::ST_COUNT] =
-{
-	// ST_VERSION
-	StatAttributes("Version", TRUE),
-	// ST_AVATAR_EDIT_SECONDS
-	StatAttributes("Seconds in Edit Appearence", FALSE),
-	// ST_TOOLBOX_SECONDS
-	StatAttributes("Seconds using Toolbox", FALSE),
-	// ST_CHAT_COUNT
-	StatAttributes("Chat messages sent", FALSE),
-	// ST_IM_COUNT
-	StatAttributes("IMs sent", FALSE),
-	// ST_FULLSCREEN_BOOL
-	StatAttributes("Fullscreen mode", FALSE),
-	// ST_RELEASE_COUNT
-	StatAttributes("Object release count", FALSE),
-	// ST_CREATE_COUNT
-	StatAttributes("Object create count", FALSE),
-	// ST_REZ_COUNT
-	StatAttributes("Object rez count", FALSE),
-	// ST_FPS_10_SECONDS
-	StatAttributes("Seconds below 10 FPS", FALSE),
-	// ST_FPS_2_SECONDS
-	StatAttributes("Seconds below 2 FPS", FALSE),
-	// ST_MOUSELOOK_SECONDS
-	StatAttributes("Seconds in Mouselook", FALSE),
-	// ST_FLY_COUNT
-	StatAttributes("Fly count", FALSE),
-	// ST_TELEPORT_COUNT
-	StatAttributes("Teleport count", FALSE),
-	// ST_OBJECT_DELETE_COUNT
-	StatAttributes("Objects deleted", FALSE),
-	// ST_SNAPSHOT_COUNT
-	StatAttributes("Snapshots taken", FALSE),
-	// ST_UPLOAD_SOUND_COUNT
-	StatAttributes("Sounds uploaded", FALSE),
-	// ST_UPLOAD_TEXTURE_COUNT
-	StatAttributes("Textures uploaded", FALSE),
-	// ST_EDIT_TEXTURE_COUNT
-	StatAttributes("Changes to textures on objects", FALSE),
-	// ST_KILLED_COUNT
-	StatAttributes("Number of times killed", FALSE),
-	// ST_FRAMETIME_JITTER
-	StatAttributes("Average delta between successive frame times", FALSE),
-	// ST_FRAMETIME_SLEW
-	StatAttributes("Average delta between frame time and mean", FALSE),
-	// ST_INVENTORY_TOO_LONG
-	StatAttributes("Inventory took too long to load", FALSE),
-	// ST_WEARABLES_TOO_LONG
-	StatAttributes("Wearables took too long to load", FALSE),
-	// ST_LOGIN_SECONDS
-	StatAttributes("Time between LoginRequest and LoginReply", FALSE),
-	// ST_LOGIN_TIMEOUT_COUNT
-	StatAttributes("Number of login attempts that timed out", FALSE),
-	// ST_HAS_BAD_TIMER
-	StatAttributes("Known bad timer if != 0.0", FALSE),
-	// ST_DOWNLOAD_FAILED
-	StatAttributes("Number of times LLAssetStorage::getAssetData() has failed", FALSE),
-	// ST_LSL_SAVE_COUNT
-	StatAttributes("Number of times user has saved a script", FALSE),
-	// ST_UPLOAD_ANIM_COUNT
-	StatAttributes("Animations uploaded", FALSE),
-	// ST_FPS_8_SECONDS
-	StatAttributes("Seconds below 8 FPS", FALSE),
-	// ST_SIM_FPS_20_SECONDS
-	StatAttributes("Seconds with sim FPS below 20", FALSE),
-	// ST_PHYS_FPS_20_SECONDS
-	StatAttributes("Seconds with physics FPS below 20", FALSE),
-	// ST_LOSS_05_SECONDS
-	StatAttributes("Seconds with packet loss > 5%", FALSE),
-	// ST_FPS_DROP_50_RATIO
-	StatAttributes("Ratio of frames 2x longer than previous", FALSE),
-	// ST_ENABLE_VBO
-	StatAttributes("Vertex Buffers Enabled", TRUE),
-	// ST_DELTA_BANDWIDTH
-	StatAttributes("Increase/Decrease in bandwidth based on packet loss", FALSE),
-	// ST_MAX_BANDWIDTH
-	StatAttributes("Max bandwidth setting", FALSE),
-	// ST_LIGHTING_DETAIL
-	StatAttributes("Lighting Detail", FALSE),
-	// ST_VISIBLE_AVATARS
-	StatAttributes("Visible Avatars", FALSE),
-	// ST_SHADER_OJECTS
-	StatAttributes("Object Shaders", FALSE),
-	// ST_SHADER_ENVIRONMENT
-	StatAttributes("Environment Shaders", FALSE),
-	// ST_VISIBLE_DRAW_DIST
-	StatAttributes("Draw Distance", FALSE),
-	// ST_VISIBLE_CHAT_BUBBLES
-	StatAttributes("Chat Bubbles Enabled", FALSE),
-	// ST_SHADER_AVATAR
-	StatAttributes("Avatar Shaders", FALSE),
-	// ST_FRAME_SECS
-	StatAttributes("FRAME_SECS", FALSE),
-	// ST_UPDATE_SECS
-	StatAttributes("UPDATE_SECS", FALSE),
-	// ST_NETWORK_SECS
-	StatAttributes("NETWORK_SECS", FALSE),
-	// ST_IMAGE_SECS
-	StatAttributes("IMAGE_SECS", FALSE),
-	// ST_REBUILD_SECS
-	StatAttributes("REBUILD_SECS", FALSE),
-	// ST_RENDER_SECS
-	StatAttributes("RENDER_SECS", FALSE),
-	// ST_CROSSING_AVG
-	StatAttributes("CROSSING_AVG", FALSE),
-	// ST_CROSSING_MAX
-	StatAttributes("CROSSING_MAX", FALSE),
-	// ST_LIBXUL_WIDGET_USED
-	StatAttributes("LibXUL Widget used", FALSE), // Unused
-	// ST_WINDOW_WIDTH
-	StatAttributes("Window width", FALSE),
-	// ST_WINDOW_HEIGHT
-	StatAttributes("Window height", FALSE),
-	// ST_TEX_BAKES
-	StatAttributes("Texture Bakes", FALSE),
-	// ST_TEX_REBAKES
-	StatAttributes("Texture Rebakes", FALSE)
-
-};
-
 LLViewerStats::LLViewerStats() :
-	mVFSPendingOperations("vfspendingoperations"),
-	mFPSStat("fpsstat"),
-	mPacketsInStat("packetsinstat"),
-	mPacketsLostStat("packetsloststat"),
-	mPacketsOutStat("packetsoutstat"),
-	mPacketsLostPercentStat("packetslostpercentstat"),
-	mTexturePacketsStat("texturepacketsstat"),
-	mActualInKBitStat("actualinkbitstat"),
-	mActualOutKBitStat("actualoutkbitstat"),
-	mTrianglesDrawnStat("trianglesdrawnstat"),
-	mSimTimeDilation("simtimedilation"),
+	//mVFSPendingOperations("vfspendingoperations"),
+	//mFPSStat("fpsstat"),
+	//mPacketsInStat("packetsinstat"),
+	//mPacketsLostStat("packetsloststat"),
+	//mPacketsOutStat("packetsoutstat"),
+	//mPacketsLostPercentStat("packetslostpercentstat"),
+	//mTexturePacketsStat("texturepacketsstat"),
+	//mActualInKBitStat("actualinkbitstat"),
+	//mActualOutKBitStat("actualoutkbitstat"),
+	//mTrianglesDrawnStat("trianglesdrawnstat"),
+	//mSimTimeDilation("simtimedilation"),
 	mSimFPS("simfps"),
 	mSimPhysicsFPS("simphysicsfps"),
 	mSimAgentUPS("simagentups"),
@@ -393,13 +275,14 @@ LLViewerStats::~LLViewerStats()
 void LLViewerStats::resetStats()
 {
 	LLViewerStats& stats = LLViewerStats::instance();
-	stats.mVFSPendingOperations.reset();
-	stats.mPacketsInStat.reset();
-	stats.mPacketsLostStat.reset();
-	stats.mPacketsOutStat.reset();
-	stats.mFPSStat.reset();
-	stats.mTexturePacketsStat.reset();
-	stats.mAgentPositionSnaps.reset();
+	stats.mRecording.reset();
+	//stats.mVFSPendingOperations.reset();
+	//stats.mPacketsInStat.reset();
+	//stats.mPacketsLostStat.reset();
+	//stats.mPacketsOutStat.reset();
+	//stats.mFPSStat.reset();
+	//stats.mTexturePacketsStat.reset();
+	//stats.mAgentPositionSnaps.reset();
 }
 
 
@@ -484,16 +367,9 @@ void LLViewerStats::addToMessage(LLSD &body) const
 {
 	LLSD &misc = body["misc"];
 	
-	for (S32 i = 0; i < ST_COUNT; i++)
-	{
-		if (STAT_INFO[i].mEnabled)
-		{
-			// TODO: send timer value so dataserver can normalize
-			misc[STAT_INFO[i].mName] = mStats[i];
-			llinfos << "STAT: " << STAT_INFO[i].mName << ": " << mStats[i]
-					<< llendl;
-		}
-	}
+	misc["Version"] = TRUE;
+	//TODO RN: get last value, not mean
+	misc["Vertex Buffers Enabled"] = mRecording.getMean(LLStatViewer::ENABLE_VBO);
 	
 	body["AgentPositionSnaps"] = mAgentPositionSnaps.asLLSD();
 	llinfos << "STAT: AgentPositionSnaps: Mean = " << mAgentPositionSnaps.getMean() << "; StdDev = " << mAgentPositionSnaps.getStdDev() 
@@ -570,13 +446,15 @@ void update_statistics()
 		stats.mSimPingStat.addValue(10000);
 	}
 
-	stats.mFPSStat.addValue(1);
+	//stats.mFPSStat.addValue(1);
+	LLStatViewer::FPS.add(1);
 	F32 layer_bits = (F32)(gVLManager.getLandBits() + gVLManager.getWindBits() + gVLManager.getCloudBits());
 	LLStatViewer::LAYERS_KBIT.add<LLUnits::Bits<F32> >(layer_bits);
 	//stats.mLayersKBitStat.addValue(layer_bits/1024.f);
 	LLStatViewer::OBJECT_KBIT.add<LLUnits::Bits<F32> >(gObjectBits);
 	//stats.mObjectKBitStat.addValue(gObjectBits/1024.f);
-	stats.mVFSPendingOperations.addValue(LLVFile::getVFSThread()->getPending());
+	//stats.mVFSPendingOperations.addValue(LLVFile::getVFSThread()->getPending());
+	LLStatViewer::SIM_PENDING_VFS_OPERATIONS.sample(LLVFile::getVFSThread()->getPending());
 	LLStatViewer::ASSET_KBIT.add<LLUnits::Bits<F32> >(gTransferManager.getTransferBitsIn(LLTCT_ASSET));
 	//stats.mAssetKBitStat.addValue(gTransferManager.getTransferBitsIn(LLTCT_ASSET)/1024.f);
 	gTransferManager.resetTransferBitsIn(LLTCT_ASSET);
@@ -615,12 +493,7 @@ void update_statistics()
 		static LLFrameTimer texture_stats_timer;
 		if (texture_stats_timer.getElapsedTimeF32() >= texture_stats_freq)
 		{
-			LLStatViewer::TEXTURE_KBIT.add<LLUnits::Bits<F32> >(LLViewerTextureList::sTextureBits);
-			//stats.mTextureKBitStat.addValue(LLViewerTextureList::sTextureBits/1024.f);
-			stats.mTexturePacketsStat.addValue(LLViewerTextureList::sTexturePackets);
-			gTotalTextureBytes += LLViewerTextureList::sTextureBits / 8;
-			LLViewerTextureList::sTextureBits = 0;
-			LLViewerTextureList::sTexturePackets = 0;
+			gTotalTextureBytes = LLUnits::Bytes<F32>(LLViewerStats::instance().getRecording().getSum(LLStatViewer::TEXTURE_KBIT)).value();
 			texture_stats_timer.reset();
 		}
 	}
diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h
index af2e9159949ec74d93aa0e9de541aa91fe878209..a14518f53633e8183fe7668d77408d7772fede62 100755
--- a/indra/newview/llviewerstats.h
+++ b/indra/newview/llviewerstats.h
@@ -1,5 +1,5 @@
 /** 
- * @file llviewerstats.h
+ * @file llviewerim_peningtats.h
  * @brief LLViewerStats class header file
  *
  * $LicenseInfo:firstyear=2002&license=viewerlgpl$
@@ -97,7 +97,8 @@ extern LLTrace::Measurement<F32>			SIM_TIME_DILATION,
 											SIM_OUT_PACKETS_PER_SEC,
 											SIM_PENDING_DOWNLOADS,
 											SIM_PENDING_UPLOADS,
-											SIM_PENING_LOCAL_UPLOADS,
+											SIM_PENDING_LOCAL_UPLOADS,
+											SIM_PENDING_VFS_OPERATIONS,
 											SIM_PHYSICS_PINNED_TASKS,
 											SIM_PHYSICS_LOD_TASKS,
 											NUM_IMAGES,
@@ -138,6 +139,8 @@ extern LLTrace::Measurement<LLUnits::Seconds<F32> > SIM_PHYSICS_TIME,
 													SIM_SLEEP_TIME,
 													SIM_PUMP_IO_TIME,
 													SIM_PING,
+													FRAMETIME_JITTER,
+													FRAMETIME_SLEW,
 													LOGIN_SECONDS,
 													REGION_CROSSING_TIME,
 													FRAME_STACKTIME,
@@ -409,10 +412,12 @@ class LLViewerStats : public LLSingleton<LLViewerStats>
 	};
 
 	LLTrace::Recording& getRecording() { return mRecording; }
+	LLTrace::Recording& getFrameRecording() { return mFrameRecording; }
 
 private:
 	F64	mStats[ST_COUNT];
 	LLTrace::Recording	mRecording;
+	LLTrace::Recording	mFrameRecording;
 
 	F64 mLastTimeDiff;  // used for time stat updates
 };
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index de3dd3c1c61671ea4f863dd39cb74470eac60096..81c45cfb84a4a3d6bcbe0870198f3cab07033353 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -58,14 +58,13 @@
 #include "pipeline.h"
 #include "llappviewer.h"
 #include "llxuiparser.h"
+#include "lltracethreadrecorder.h"
 #include "llviewerdisplay.h"
 
 ////////////////////////////////////////////////////////////////////////////
 
 void (*LLViewerTextureList::sUUIDCallback)(void **, const LLUUID&) = NULL;
 
-U32 LLViewerTextureList::sTextureBits = 0;
-U32 LLViewerTextureList::sTexturePackets = 0;
 S32 LLViewerTextureList::sNumImages = 0;
 LLStat LLViewerTextureList::sNumImagesStat("Num Images", TRUE);
 LLStat LLViewerTextureList::sNumRawImagesStat("Num Raw Images", TRUE);
@@ -624,7 +623,7 @@ void LLViewerTextureList::updateImages(F32 max_time)
 
 	LLTrace::Recording* recording = LLTrace::get_thread_recorder()->getPrimaryRecording();
 
-	LLAppViewer::getTextureFetch()->setTextureBandwidth(recording->getPerSec(LLStatViewer::TEXTURE_KBIT));
+	LLAppViewer::getTextureFetch()->setTextureBandwidth(recording->getPerSec(LLStatViewer::TEXTURE_KBIT).value());
 
 	LLViewerStats::getInstance()->mNumImagesStat.addValue(sNumImages);
 	LLViewerStats::getInstance()->mNumRawImagesStat.addValue(LLImageRaw::sRawImageCount);
@@ -1326,8 +1325,8 @@ void LLViewerTextureList::receiveImageHeader(LLMessageSystem *msg, void **user_d
 	{
 		received_size = msg->getReceiveSize() ;		
 	}
-	gTextureList.sTextureBits += received_size * 8;
-	gTextureList.sTexturePackets++;
+	LLStatViewer::TEXTURE_KBIT.add<LLUnits::Bytes<F32> >(received_size);
+	LLStatViewer::TEXTURE_PACKETS.add(1);
 	
 	U8 codec;
 	U16 packets;
@@ -1399,8 +1398,9 @@ void LLViewerTextureList::receiveImagePacket(LLMessageSystem *msg, void **user_d
 	{
 		received_size = msg->getReceiveSize() ;		
 	}
-	gTextureList.sTextureBits += received_size * 8;
-	gTextureList.sTexturePackets++;
+
+	LLStatViewer::TEXTURE_KBIT.add<LLUnits::Bytes<F32> >(received_size);
+	LLStatViewer::TEXTURE_PACKETS.add(1);
 	
 	//llprintline("Start decode, image header...");
 	msg->getUUIDFast(_PREHASH_ImageID, _PREHASH_ID, id);
diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h
index 3dda973d3fa98edf01d20a9c573c8cd514e2589f..ab6f009e289b7895e2f62d9d9f9d9d3e2368e7bc 100644
--- a/indra/newview/llviewertexturelist.h
+++ b/indra/newview/llviewertexturelist.h
@@ -201,9 +201,6 @@ class LLViewerTextureList
 	LLFrameTimer mForceDecodeTimer;
 	
 public:
-	static U32 sTextureBits;
-	static U32 sTexturePackets;
-
 	static LLStat sNumImagesStat;
 	static LLStat sNumRawImagesStat;
 	static LLStat sGLTexMemStat;
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 8b50e56fb3d4406a040a28b2b1f0589c56ac5fca..4ad7c49d4b5d94eb7e576816ba3aece4575be635 100755
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1402,10 +1402,11 @@ BOOL LLViewerWindow::handlePaint(LLWindow *window,  S32 x,  S32 y, S32 width,  S
 		FillRect(hdc, &wnd_rect, CreateSolidBrush(RGB(255, 255, 255)));
 
 		std::string temp_str;
+		LLTrace::Recording& recording = LLViewerStats::instance().getRecording();
 		temp_str = llformat( "FPS %3.1f Phy FPS %2.1f Time Dil %1.3f",		/* Flawfinder: ignore */
-				LLViewerStats::getInstance()->mFPSStat.getMeanPerSec(),
-				LLViewerStats::getInstance()->mSimPhysicsFPS.getPrev(0),
-				LLViewerStats::getInstance()->mSimTimeDilation.getPrev(0));
+				recording.getPerSec(LLStatViewer::FPS), //mFPSStat.getMeanPerSec(),
+				recording.getMean(LLStatViewer::SIM_PHYSICS_FPS), //LLViewerStats::getInstance()->mSimPhysicsFPS.getPrev(0),
+				recording.getMean(LLStatViewer::SIM_TIME_DILATION)); //LLViewerStats::getInstance()->mSimTimeDilation.getPrev(0));
 		S32 len = temp_str.length();
 		TextOutA(hdc, 0, 0, temp_str.c_str(), len); 
 
diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp
index bf2a58f107dcf6651f72919ab7e843db1f9e7e6b..056132c165ec4127ce4f8d1baf06467e734f4bce 100644
--- a/indra/newview/llworld.cpp
+++ b/indra/newview/llworld.cpp
@@ -703,21 +703,26 @@ void LLWorld::updateNetStats()
 	S32 actual_in_bits = gMessageSystem->mPacketRing.getAndResetActualInBits();
 	S32 actual_out_bits = gMessageSystem->mPacketRing.getAndResetActualOutBits();
 
-	LLViewerStats::getInstance()->mActualInKBitStat.addValue(actual_in_bits/1024.f);
-	LLViewerStats::getInstance()->mActualOutKBitStat.addValue(actual_out_bits/1024.f);
+	LLStatViewer::ACTUAL_IN_KBIT.add<LLUnits::Bits<F32> >(actual_in_bits);
+	LLStatViewer::ACTUAL_OUT_KBIT.add<LLUnits::Bits<F32> >(actual_out_bits);
+	//LLViewerStats::getInstance()->mActualInKBitStat.addValue(actual_in_bits/1024.f);
+	//LLViewerStats::getInstance()->mActualOutKBitStat.addValue(actual_out_bits/1024.f);
 	LLStatViewer::KBIT.add<LLUnits::Bits<F32> >(bits);
 	//LLViewerStats::getInstance()->mKBitStat.addValue(bits/1024.f);
-	LLViewerStats::getInstance()->mPacketsInStat.addValue(packets_in);
-	LLViewerStats::getInstance()->mPacketsOutStat.addValue(packets_out);
-	LLViewerStats::getInstance()->mPacketsLostStat.addValue(gMessageSystem->mDroppedPackets);
-	if (packets_in)
-	{
-		LLViewerStats::getInstance()->mPacketsLostPercentStat.addValue(100.f*((F32)packets_lost/(F32)packets_in));
-	}
-	else
-	{
-		LLViewerStats::getInstance()->mPacketsLostPercentStat.addValue(0.f);
-	}
+	LLStatViewer::PACKETS_IN.add(packets_in);
+	LLStatViewer::PACKETS_OUT.add(packets_out);
+	LLStatViewer::PACKETS_LOST.add(packets_lost);
+	//LLViewerStats::getInstance()->mPacketsInStat.addValue(packets_in);
+	//LLViewerStats::getInstance()->mPacketsOutStat.addValue(packets_out);
+	//LLViewerStats::getInstance()->mPacketsLostStat.addValue(gMessageSystem->mDroppedPackets);
+	//if (packets_in)
+	//{
+	//	LLViewerStats::getInstance()->mPacketsLostPercentStat.addValue(100.f*((F32)packets_lost/(F32)packets_in));
+	//}
+	//else
+	//{
+	//	LLViewerStats::getInstance()->mPacketsLostPercentStat.addValue(0.f);
+	//}
 
 	mLastPacketsIn = gMessageSystem->mPacketsIn;
 	mLastPacketsOut = gMessageSystem->mPacketsOut;
@@ -1129,6 +1134,7 @@ void send_agent_pause()
 	}
 
 	gObjectList.mWasPaused = TRUE;
+	LLViewerStats::instance().getRecording().stop();
 }
 
 
@@ -1158,8 +1164,8 @@ void send_agent_resume()
 		gMessageSystem->sendReliable(regionp->getHost());
 	}
 
-	// Reset the FPS counter to avoid an invalid fps
-	LLViewerStats::getInstance()->mFPSStat.reset();
+	// Resume data collection to ignore invalid rates
+	LLViewerStats::instance().getRecording().resume();//getInstance()->mFPSStat.reset();
 
 	LLAppViewer::instance()->resumeMainloopTimeout();
 }
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 86791a37fbff3d998199f26703a23e57b88bef21..4582de805faae885a20a1877568500f60c16cedc 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -488,7 +488,7 @@ void LLPipeline::init()
 	getPool(LLDrawPool::POOL_BUMP);
 	getPool(LLDrawPool::POOL_GLOW);
 
-	LLViewerStats::getInstance()->mTrianglesDrawnStat.reset();
+	//LLViewerStats::getInstance()->mTrianglesDrawnStat.reset();
 	resetFrameStats();
 
 	for (U32 i = 0; i < NUM_RENDER_TYPES; ++i)
@@ -1768,7 +1768,8 @@ void LLPipeline::resetFrameStats()
 {
 	assertInitialized();
 
-	LLViewerStats::getInstance()->mTrianglesDrawnStat.addValue(mTrianglesDrawn/1000.f);
+	LLStatViewer::TRIANGLES_DRAWN.add(mTrianglesDrawn);
+	//LLViewerStats::getInstance()->mTrianglesDrawnStat.addValue(mTrianglesDrawn/1000.f);
 
 	if (mBatchCount > 0)
 	{