diff --git a/indra/llcommon/llfasttimer.cpp b/indra/llcommon/llfasttimer.cpp
index 2235eb1a086d0cb52c637addf25b0c646aa192f8..c58fad12e7002996f91347fe07c21f83abcbd07f 100755
--- a/indra/llcommon/llfasttimer.cpp
+++ b/indra/llcommon/llfasttimer.cpp
@@ -189,7 +189,7 @@ void TimeBlock::bootstrapTimerTree()
 		// when this timer was called
 		if (timer.getParent() == &TimeBlock::getRootTimeBlock())
 		{
-			TimeBlockAccumulator& accumulator = timer.getPrimaryAccumulator();
+			TimeBlockAccumulator& accumulator = timer.getCurrentAccumulator();
 
 			if (accumulator.mLastCaller)
 			{
@@ -223,7 +223,7 @@ void TimeBlock::incrementalUpdateTimerTree()
 		// skip root timer
 		if (timerp != &TimeBlock::getRootTimeBlock())
 		{
-			TimeBlockAccumulator& accumulator = timerp->getPrimaryAccumulator();
+			TimeBlockAccumulator& accumulator = timerp->getCurrentAccumulator();
 
 			if (accumulator.mMoveUpTree)
 			{
@@ -253,7 +253,7 @@ void TimeBlock::updateTimes()
 
 	U64 cur_time = getCPUClockCount64();
 	BlockTimer* cur_timer				= stack_record->mActiveTimer;
-	TimeBlockAccumulator* accumulator	= &stack_record->mTimeBlock->getPrimaryAccumulator();
+	TimeBlockAccumulator* accumulator	= &stack_record->mTimeBlock->getCurrentAccumulator();
 
 	while(cur_timer 
 		&& cur_timer->mParentTimerData.mActiveTimer != cur_timer) // root defined by parent pointing to self
@@ -269,7 +269,7 @@ void TimeBlock::updateTimes()
 		cur_timer->mBlockStartTotalTimeCounter = accumulator->mTotalTimeCounter;
 
 		stack_record = &cur_timer->mParentTimerData;
-		accumulator  = &stack_record->mTimeBlock->getPrimaryAccumulator();
+		accumulator  = &stack_record->mTimeBlock->getCurrentAccumulator();
 		cur_timer    = stack_record->mActiveTimer;
 
 		stack_record->mChildTime += cumulative_time_delta;
@@ -299,7 +299,7 @@ void TimeBlock::processTimes()
 		++it)
 	{
 		TimeBlock& timer = *it;
-		TimeBlockAccumulator& accumulator = timer.getPrimaryAccumulator();
+		TimeBlockAccumulator& accumulator = timer.getCurrentAccumulator();
 
 		accumulator.mLastCaller = NULL;
 		accumulator.mMoveUpTree = false;
diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h
index 7bad6134c5a400b79df648c8499af66bc7c51ce4..1586ea2d041907495014a8a5fe884a0a79185860 100755
--- a/indra/llcommon/llfasttimer.h
+++ b/indra/llcommon/llfasttimer.h
@@ -257,11 +257,11 @@ LL_FORCE_INLINE BlockTimer::BlockTimer(TimeBlock& timer)
 #if FAST_TIMER_ON
 	BlockTimerStackRecord* cur_timer_data = LLThreadLocalSingletonPointer<BlockTimerStackRecord>::getInstance();
 	if (!cur_timer_data) return;
-	TimeBlockAccumulator& accumulator = timer.getPrimaryAccumulator();
+	TimeBlockAccumulator& accumulator = timer.getCurrentAccumulator();
 	accumulator.mActiveCount++;
 	mBlockStartTotalTimeCounter = accumulator.mTotalTimeCounter;
 	// keep current parent as long as it is active when we are
-	accumulator.mMoveUpTree |= (accumulator.mParent->getPrimaryAccumulator().mActiveCount == 0);
+	accumulator.mMoveUpTree |= (accumulator.mParent->getCurrentAccumulator().mActiveCount == 0);
 
 	// store top of stack
 	mParentTimerData = *cur_timer_data;
@@ -281,7 +281,7 @@ LL_FORCE_INLINE BlockTimer::~BlockTimer()
 	BlockTimerStackRecord* cur_timer_data = LLThreadLocalSingletonPointer<BlockTimerStackRecord>::getInstance();
 	if (!cur_timer_data) return;
 
-	TimeBlockAccumulator& accumulator = cur_timer_data->mTimeBlock->getPrimaryAccumulator();
+	TimeBlockAccumulator& accumulator = cur_timer_data->mTimeBlock->getCurrentAccumulator();
 
 	accumulator.mCalls++;
 	accumulator.mTotalTimeCounter += total_time - (accumulator.mTotalTimeCounter - mBlockStartTotalTimeCounter);
diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp
index cb2f853070616562f23443de21f474d40effbf60..e0b2aa87c2e5f9d0ee60bee3d5ebf6799f074513 100755
--- a/indra/llcommon/llmemory.cpp
+++ b/indra/llcommon/llmemory.cpp
@@ -43,12 +43,15 @@
 
 #include "llsys.h"
 #include "llframetimer.h"
+#include "lltrace.h"
 //----------------------------------------------------------------------------
 
 //static
 char* LLMemory::reserveMem = 0;
 U32Kilobytes LLMemory::sAvailPhysicalMemInKB(U32_MAX);
 U32Kilobytes LLMemory::sMaxPhysicalMemInKB(0);
+static LLTrace::SampleStatHandle<F64Megabytes> sAllocatedMem("allocated_mem", "active memory in use by application");
+static LLTrace::SampleStatHandle<F64Megabytes> sVirtualMem("virtual_mem", "virtual memory assigned to application");
 U32Kilobytes LLMemory::sAllocatedMemInKB(0);
 U32Kilobytes LLMemory::sAllocatedPageSizeInKB(0);
 U32Kilobytes LLMemory::sMaxHeapSizeInKB(U32_MAX);
@@ -114,7 +117,9 @@ void LLMemory::updateMemoryInfo()
 	}
 
 	sAllocatedMemInKB = (U32Bytes)(counters.WorkingSetSize) ;
+	sample(sAllocatedMem, sAllocatedMemInKB);
 	sAllocatedPageSizeInKB = (U32Bytes)(counters.PagefileUsage) ;
+	sample(sVirtualMem, sAllocatedPageSizeInKB);
 
 	U32Kilobytes avail_phys, avail_virtual;
 	LLMemoryInfo::getAvailableMemoryKB(avail_phys, avail_virtual) ;
diff --git a/indra/llcommon/lltrace.cpp b/indra/llcommon/lltrace.cpp
index 05422f91916a85a0187c470a89fb6404b05756ee..e4a6f4c9027602e48c1a4b406f851a3ee4f71dba 100644
--- a/indra/llcommon/lltrace.cpp
+++ b/indra/llcommon/lltrace.cpp
@@ -76,7 +76,7 @@ void TimeBlockTreeNode::setParent( TimeBlock* parent )
 	}
 
 	mParent = parent;
-	mBlock->getPrimaryAccumulator().mParent = parent;
+	mBlock->getCurrentAccumulator().mParent = parent;
 	parent_tree_node->mChildren.push_back(mBlock);
 	parent_tree_node->mNeedsSorting = true;
 }
diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h
index bf8e950a8cda84e7f9babb872557b1dbed9cc080..cda15c0de52108d0320eb8efde7a8b90ca240972 100644
--- a/indra/llcommon/lltrace.h
+++ b/indra/llcommon/lltrace.h
@@ -80,9 +80,9 @@ class TraceType
 		mAccumulatorIndex(AccumulatorBuffer<ACCUMULATOR>::getDefaultBuffer()->reserveSlot())
 	{}
 
-	LL_FORCE_INLINE ACCUMULATOR& getPrimaryAccumulator() const
+	LL_FORCE_INLINE ACCUMULATOR& getCurrentAccumulator() const
 	{
-		ACCUMULATOR* accumulator_storage = AccumulatorBuffer<ACCUMULATOR>::getPrimaryStorage();
+		ACCUMULATOR* accumulator_storage = AccumulatorBuffer<ACCUMULATOR>::getCurrentStorage();
 		return accumulator_storage[mAccumulatorIndex];
 	}
 
@@ -137,7 +137,7 @@ template<typename T, typename VALUE_T>
 void record(EventStatHandle<T>& measurement, VALUE_T value)
 {
 	T converted_value(value);
-	measurement.getPrimaryAccumulator().record(storage_value(converted_value));
+	measurement.getCurrentAccumulator().record(storage_value(converted_value));
 }
 
 template <typename T = F64>
@@ -160,7 +160,22 @@ template<typename T, typename VALUE_T>
 void sample(SampleStatHandle<T>& measurement, VALUE_T value)
 {
 	T converted_value(value);
-	measurement.getPrimaryAccumulator().sample(storage_value(converted_value));
+	measurement.getCurrentAccumulator().sample(storage_value(converted_value));
+}
+
+template<typename T, typename VALUE_T>
+void add(SampleStatHandle<T>& measurement, VALUE_T value)
+{
+	T converted_value(value);
+	SampleAccumulator& acc = measurement.getCurrentAccumulator();
+	if (acc.hasValue())
+	{
+		acc.sample(acc.getLastValue() + converted_value);
+	}
+	else
+	{
+		acc.sample(converted_value);
+	}
 }
 
 template <typename T = F64>
@@ -183,7 +198,7 @@ template<typename T, typename VALUE_T>
 void add(CountStatHandle<T>& count, VALUE_T value)
 {
 	T converted_value(value);
-	count.getPrimaryAccumulator().add(storage_value(converted_value));
+	count.getCurrentAccumulator().add(storage_value(converted_value));
 }
 
 template<>
@@ -340,7 +355,7 @@ class MemTrackable
 
 	void* operator new(size_t size) 
 	{
-		MemStatAccumulator& accumulator = DERIVED::sMemStat.getPrimaryAccumulator();
+		MemStatAccumulator& accumulator = DERIVED::sMemStat.getCurrentAccumulator();
 		accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() + (F64)size : (F64)size);
 		accumulator.mAllocatedCount++;
 
@@ -349,7 +364,7 @@ class MemTrackable
 
 	void operator delete(void* ptr, size_t size)
 	{
-		MemStatAccumulator& accumulator = DERIVED::sMemStat.getPrimaryAccumulator();
+		MemStatAccumulator& accumulator = DERIVED::sMemStat.getCurrentAccumulator();
 		accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() - (F64)size : -(F64)size);
 		accumulator.mAllocatedCount--;
 		accumulator.mDeallocatedCount++;
@@ -358,7 +373,7 @@ class MemTrackable
 
 	void *operator new [](size_t size)
 	{
-		MemStatAccumulator& accumulator = DERIVED::sMemStat.getPrimaryAccumulator();
+		MemStatAccumulator& accumulator = DERIVED::sMemStat.getCurrentAccumulator();
 		accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() + (F64)size : (F64)size);
 		accumulator.mAllocatedCount++;
 
@@ -367,7 +382,7 @@ class MemTrackable
 
 	void operator delete[](void* ptr, size_t size)
 	{
-		MemStatAccumulator& accumulator = DERIVED::sMemStat.getPrimaryAccumulator();
+		MemStatAccumulator& accumulator = DERIVED::sMemStat.getCurrentAccumulator();
 		accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() - (F64)size : -(F64)size);
 		accumulator.mAllocatedCount--;
 		accumulator.mDeallocatedCount++;
@@ -393,7 +408,7 @@ class MemTrackable
 	template<typename AMOUNT_T>
 	AMOUNT_T& memClaimAmount(AMOUNT_T& size)
 	{
-		MemStatAccumulator& accumulator = DERIVED::sMemStat.getPrimaryAccumulator();
+		MemStatAccumulator& accumulator = DERIVED::sMemStat.getCurrentAccumulator();
 		mMemFootprint += (size_t)size;
 		accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() + (F64)size : (F64)size);
 		return size;
@@ -417,7 +432,7 @@ class MemTrackable
 	template<typename AMOUNT_T>
 	AMOUNT_T& memDisclaimAmount(AMOUNT_T& size)
 	{
-		MemStatAccumulator& accumulator = DERIVED::sMemStat.getPrimaryAccumulator();
+		MemStatAccumulator& accumulator = DERIVED::sMemStat.getCurrentAccumulator();
 		accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() - (F64)size : -(F64)size);
 		return size;
 	}
@@ -430,7 +445,7 @@ class MemTrackable
 	{
 		static void claim(mem_trackable_t& tracker, const TRACKED& tracked)
 		{
-			MemStatAccumulator& accumulator = DERIVED::sMemStat.getPrimaryAccumulator();
+			MemStatAccumulator& accumulator = DERIVED::sMemStat.getCurrentAccumulator();
 			size_t footprint = MemFootprint<TRACKED>::measure(tracked);
 			accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() + (F64)footprint : (F64)footprint);
 			tracker.mMemFootprint += footprint;
@@ -438,7 +453,7 @@ class MemTrackable
 
 		static void disclaim(mem_trackable_t& tracker, const TRACKED& tracked)
 		{
-			MemStatAccumulator& accumulator = DERIVED::sMemStat.getPrimaryAccumulator();
+			MemStatAccumulator& accumulator = DERIVED::sMemStat.getCurrentAccumulator();
 			size_t footprint = MemFootprint<TRACKED>::measure(tracked);
 			accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() - (F64)footprint : -(F64)footprint);
 			tracker.mMemFootprint -= footprint;
@@ -450,13 +465,13 @@ class MemTrackable
 	{
 		static void claim(mem_trackable_t& tracker, TRACKED& tracked)
 		{
-			MemStatAccumulator& accumulator = DERIVED::sMemStat.getPrimaryAccumulator();
+			MemStatAccumulator& accumulator = DERIVED::sMemStat.getCurrentAccumulator();
 			accumulator.mChildSize.sample(accumulator.mChildSize.hasValue() ? accumulator.mChildSize.getLastValue() + (F64)MemFootprint<TRACKED>::measure(tracked) : (F64)MemFootprint<TRACKED>::measure(tracked));
 		}
 
 		static void disclaim(mem_trackable_t& tracker, TRACKED& tracked)
 		{
-			MemStatAccumulator& accumulator = DERIVED::sMemStat.getPrimaryAccumulator();
+			MemStatAccumulator& accumulator = DERIVED::sMemStat.getCurrentAccumulator();
 			accumulator.mChildSize.sample(accumulator.mChildSize.hasValue() ? accumulator.mChildSize.getLastValue() - (F64)MemFootprint<TRACKED>::measure(tracked) : -(F64)MemFootprint<TRACKED>::measure(tracked));
 		}
 	};
diff --git a/indra/llcommon/lltraceaccumulators.cpp b/indra/llcommon/lltraceaccumulators.cpp
index ae769350b9558545ee1829e1155de4b66c413048..b234f43337ff402347329fab87617c9dbfda09ec 100644
--- a/indra/llcommon/lltraceaccumulators.cpp
+++ b/indra/llcommon/lltraceaccumulators.cpp
@@ -48,13 +48,13 @@ void AccumulatorBufferGroup::handOffTo(AccumulatorBufferGroup& other)
 	other.mMemStats.reset(&mMemStats);
 }
 
-void AccumulatorBufferGroup::makePrimary()
+void AccumulatorBufferGroup::makeCurrent()
 {
-	mCounts.makePrimary();
-	mSamples.makePrimary();
-	mEvents.makePrimary();
-	mStackTimers.makePrimary();
-	mMemStats.makePrimary();
+	mCounts.makeCurrent();
+	mSamples.makeCurrent();
+	mEvents.makeCurrent();
+	mStackTimers.makeCurrent();
+	mMemStats.makeCurrent();
 
 	ThreadRecorder* thread_recorder = get_thread_recorder().get();
 	AccumulatorBuffer<TimeBlockAccumulator>& timer_accumulator_buffer = mStackTimers;
@@ -70,18 +70,18 @@ void AccumulatorBufferGroup::makePrimary()
 }
 
 //static
-void AccumulatorBufferGroup::clearPrimary()
+void AccumulatorBufferGroup::resetCurrent()
 {
-	AccumulatorBuffer<CountAccumulator>::clearPrimary();	
-	AccumulatorBuffer<SampleAccumulator>::clearPrimary();
-	AccumulatorBuffer<EventAccumulator>::clearPrimary();
-	AccumulatorBuffer<TimeBlockAccumulator>::clearPrimary();
-	AccumulatorBuffer<MemStatAccumulator>::clearPrimary();
+	AccumulatorBuffer<CountAccumulator>::resetCurrent();	
+	AccumulatorBuffer<SampleAccumulator>::resetCurrent();
+	AccumulatorBuffer<EventAccumulator>::resetCurrent();
+	AccumulatorBuffer<TimeBlockAccumulator>::resetCurrent();
+	AccumulatorBuffer<MemStatAccumulator>::resetCurrent();
 }
 
-bool AccumulatorBufferGroup::isPrimary() const
+bool AccumulatorBufferGroup::isCurrent() const
 {
-	return mCounts.isPrimary();
+	return mCounts.isCurrent();
 }
 
 void AccumulatorBufferGroup::append( const AccumulatorBufferGroup& other )
@@ -114,7 +114,7 @@ void AccumulatorBufferGroup::reset(AccumulatorBufferGroup* other)
 
 void AccumulatorBufferGroup::sync()
 {
-	if (isPrimary())
+	if (isCurrent())
 	{
 		F64SecondsImplicit time_stamp = LLTimer::getTotalSeconds();
 
diff --git a/indra/llcommon/lltraceaccumulators.h b/indra/llcommon/lltraceaccumulators.h
index 02af480b8a729c7e3769e82a6c83edb38f79828e..e31058ab4b8a5d8ec31dd6316d49cdbdff08d631 100644
--- a/indra/llcommon/lltraceaccumulators.h
+++ b/indra/llcommon/lltraceaccumulators.h
@@ -75,7 +75,7 @@ namespace LLTrace
 
 		~AccumulatorBuffer()
 		{
-			if (isPrimary())
+			if (isCurrent())
 			{
 				LLThreadLocalSingletonPointer<ACCUMULATOR>::setInstance(NULL);
 			}
@@ -128,22 +128,22 @@ namespace LLTrace
 			}
 		}
 
-		void makePrimary()
+		void makeCurrent()
 		{
 			LLThreadLocalSingletonPointer<ACCUMULATOR>::setInstance(mStorage);
 		}
 
-		bool isPrimary() const
+		bool isCurrent() const
 		{
 			return LLThreadLocalSingletonPointer<ACCUMULATOR>::getInstance() == mStorage;
 		}
 
-		static void clearPrimary()
+		static void resetCurrent()
 		{
 			LLThreadLocalSingletonPointer<ACCUMULATOR>::setInstance(NULL);
 		}
 
-		LL_FORCE_INLINE static ACCUMULATOR* getPrimaryStorage() 
+		LL_FORCE_INLINE static ACCUMULATOR* getCurrentStorage() 
 		{ 
 			ACCUMULATOR* accumulator = LLThreadLocalSingletonPointer<ACCUMULATOR>::getInstance();
 			return accumulator ? accumulator : getDefaultBuffer()->mStorage;
@@ -534,9 +534,9 @@ namespace LLTrace
 		AccumulatorBufferGroup();
 
 		void handOffTo(AccumulatorBufferGroup& other);
-		void makePrimary();
-		bool isPrimary() const;
-		static void clearPrimary();
+		void makeCurrent();
+		bool isCurrent() const;
+		static void resetCurrent();
 
 		void append(const AccumulatorBufferGroup& other);
 		void merge(const AccumulatorBufferGroup& other);
diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp
index 28470fb4c403e68663c446e3ffff45fafc12826a..df4af89184999386922f9db427cb9b2a0c0e81c5 100644
--- a/indra/llcommon/lltracethreadrecorder.cpp
+++ b/indra/llcommon/lltracethreadrecorder.cpp
@@ -69,13 +69,13 @@ void ThreadRecorder::init()
 		tree_node.mBlock = &time_block;
 		tree_node.mParent = &root_time_block;
 
-		it->getPrimaryAccumulator().mParent = &root_time_block;
+		it->getCurrentAccumulator().mParent = &root_time_block;
 	}
 
 	mRootTimer = new BlockTimer(root_time_block);
 	timer_stack->mActiveTimer = mRootTimer;
 
-	TimeBlock::getRootTimeBlock().getPrimaryAccumulator().mActiveCount = 1;
+	TimeBlock::getRootTimeBlock().getCurrentAccumulator().mActiveCount = 1;
 }
 
 
@@ -135,7 +135,7 @@ void ThreadRecorder::activate( AccumulatorBufferGroup* recording, bool from_hand
 	}
 	mActiveRecordings.push_back(active_recording);
 
-	mActiveRecordings.back()->mPartialRecording.makePrimary();
+	mActiveRecordings.back()->mPartialRecording.makeCurrent();
 }
 
 ThreadRecorder::active_recording_list_t::reverse_iterator ThreadRecorder::bringUpToDate( AccumulatorBufferGroup* recording )
@@ -186,19 +186,19 @@ void ThreadRecorder::deactivate( AccumulatorBufferGroup* recording )
 	if (it != mActiveRecordings.rend())
 	{
 		active_recording_list_t::iterator recording_to_remove = (++it).base();
-		bool was_primary = (*recording_to_remove)->mPartialRecording.isPrimary();
+		bool was_current = (*recording_to_remove)->mPartialRecording.isCurrent();
 		llassert((*recording_to_remove)->mTargetRecording == recording);
 		delete *recording_to_remove;
 		mActiveRecordings.erase(recording_to_remove);
-		if (was_primary)
+		if (was_current)
 		{
 			if (mActiveRecordings.empty())
 			{
-				AccumulatorBufferGroup::clearPrimary();
+				AccumulatorBufferGroup::resetCurrent();
 			}
 			else
 			{
-				mActiveRecordings.back()->mPartialRecording.makePrimary();
+				mActiveRecordings.back()->mPartialRecording.makeCurrent();
 			}
 		}
 	}
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index 093a65682a45c47ecdeaff4dab73e5dd07eaebe4..8e9a1dd40ab66eaee73ab86cb765f86faf847705 100755
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -34,6 +34,7 @@
 #include "llcoordframe.h"			// for mFrameAgent
 #include "llavatarappearancedefines.h"
 #include "llpermissionsflags.h"
+#include "v3dmath.h"
 
 #include <boost/function.hpp>
 #include <boost/shared_ptr.hpp>
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 7f37cee8b8319e6371e296f86ebffad37e068edc..9cd589c34af37706adb1a07354da9180202c175b 100755
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -1224,8 +1224,8 @@ void LLAppViewer::checkMemory()
 	}
 	mMemCheckTimer.reset() ;
 
-		//update the availability of memory
-		LLMemory::updateMemoryInfo() ;
+	//update the availability of memory
+	LLMemory::updateMemoryInfo() ;
 
 	bool is_low = LLMemory::isMemoryPoolLow() ;
 
diff --git a/indra/newview/llremoteparcelrequest.h b/indra/newview/llremoteparcelrequest.h
index b87056573b1bfea0ea4753f9a220b57b83b11763..e4b8791f7c7d8b331e33fdd3e0177c701ed4e355 100755
--- a/indra/newview/llremoteparcelrequest.h
+++ b/indra/newview/llremoteparcelrequest.h
@@ -30,7 +30,8 @@
 #define LL_LLREMOTEPARCELREQUEST_H
 
 #include "llhttpclient.h"
-#include "llpanel.h"
+#include "llhandle.h"
+#include "llsingleton.h"
 
 class LLMessageSystem;
 class LLRemoteParcelInfoObserver;
diff --git a/indra/newview/llvieweroctree.cpp b/indra/newview/llvieweroctree.cpp
index 481befdb44bf1921a590f1d12d864303e7c928a2..b6389fac338d8973a320a32a3f87b1a0b4552196 100644
--- a/indra/newview/llvieweroctree.cpp
+++ b/indra/newview/llvieweroctree.cpp
@@ -39,6 +39,11 @@
 U32 LLViewerOctreeEntryData::sCurVisible = 0;
 BOOL LLViewerOctreeDebug::sInDebug = FALSE;
 
+static LLTrace::CountStatHandle<S32> sOcclusionQueries("occlusion_queries", "Number of occlusion queries executed"),
+									 sNumObjectsOccluded("occluded_objects", "Count of objects being occluded by a query"),
+									 sNumObjectsUnoccluded("unoccluded_objects", "Count of objects being unoccluded by a query");
+static LLTrace::SampleStatHandle<S32> sOcclusionQueriesInFlight("occlusion_queries_in_flight", "Number of occlusion queries waiting for results");
+
 //-----------------------------------------------------------------------------------
 //some global functions definitions
 //-----------------------------------------------------------------------------------
@@ -921,6 +926,10 @@ void LLOcclusionCullingGroup::setOcclusionState(U32 state, S32 mode)
 	}
 	else
 	{
+		if (state & OCCLUDED)
+		{
+			add(sNumObjectsOccluded, 1);
+		}
 		mOcclusionState[LLViewerCamera::sCurCameraID] |= state;
 		if ((state & DISCARD_QUERY) && mOcclusionQuery[LLViewerCamera::sCurCameraID])
 		{
@@ -979,6 +988,10 @@ void LLOcclusionCullingGroup::clearOcclusionState(U32 state, S32 mode)
 	}
 	else
 	{
+		if (state & OCCLUDED)
+		{
+			add(sNumObjectsUnoccluded, 1);
+		}
 		mOcclusionState[LLViewerCamera::sCurCameraID] &= ~state;
 	}
 }
@@ -1082,6 +1095,7 @@ void LLOcclusionCullingGroup::checkOcclusion()
 #if LL_TRACK_PENDING_OCCLUSION_QUERIES
 					sPendingQueries.erase(mOcclusionQuery[LLViewerCamera::sCurCameraID]);
 #endif
+					add(sOcclusionQueriesInFlight, -1);
 				}
 				else if (mOcclusionQuery[LLViewerCamera::sCurCameraID])
 				{ //delete the query to avoid holding onto hundreds of pending queries
@@ -1187,6 +1201,8 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector3* reg
 #if LL_TRACK_PENDING_OCCLUSION_QUERIES
 					sPendingQueries.insert(mOcclusionQuery[LLViewerCamera::sCurCameraID]);
 #endif
+					add(sOcclusionQueries, 1);
+					add(sOcclusionQueriesInFlight, 1);
 
 					{
 						LLFastTimer t(FTM_PUSH_OCCLUSION_VERTS);