diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index 664af02f78c26f3f0911311a9c3285413e9d292e..6e14c5fc63e39659db1e84a129a13ce116fd81ba 100644
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -550,6 +550,11 @@ class LLTextureFetchWorker : public LLWorkerClass, public LLCore::HttpHandler
 	unsigned int			mHttpReplySize;
 	unsigned int			mHttpReplyOffset;
 	bool					mHttpHasResource;			// Counts against Fetcher's mHttpSemaphore
+
+	// State history
+	U32 mCacheReadCount;
+	U32 mCacheWriteCount;
+	U32 mResourceWaitCount;
 };
 
 //////////////////////////////////////////////////////////////////////////////
@@ -854,7 +859,10 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,
 	  mHttpActive(false),
 	  mHttpReplySize(0U),
 	  mHttpReplyOffset(0U),
-	  mHttpHasResource(false)
+	  mHttpHasResource(false),
+	  mCacheReadCount(0U),
+	  mCacheWriteCount(0U),
+	  mResourceWaitCount(0U)
 {
 	mCanUseNET = mUrl.empty() ;
 
@@ -905,6 +913,7 @@ LLTextureFetchWorker::~LLTextureFetchWorker()
 	unlockWorkMutex();													// -Mw
 	mFetcher->removeFromHTTPQueue(mID);
 	mFetcher->removeHttpWaiter(mID);
+	mFetcher->updateStateStats(mCacheReadCount, mCacheWriteCount, mResourceWaitCount);
 }
 
 // Locks:  Mw
@@ -1127,6 +1136,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 				setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it
 
 				// read file from local disk
+				++mCacheReadCount;
 				std::string filename = mUrl.substr(7, std::string::npos);
 				CacheReadResponder* responder = new CacheReadResponder(mFetcher, mID, mFormattedImage);
 				mCacheReadHandle = mFetcher->mTextureCache->readFromCache(filename, mID, cache_priority,
@@ -1136,6 +1146,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 			{
 				setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it
 
+				++mCacheReadCount;
 				CacheReadResponder* responder = new CacheReadResponder(mFetcher, mID, mFormattedImage);
 				mCacheReadHandle = mFetcher->mTextureCache->readFromCache(mID, cache_priority,
 																		  offset, size, responder);
@@ -1323,6 +1334,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 			mState = WAIT_HTTP_RESOURCE2;
 			setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
 			mFetcher->addHttpWaiter(this->mID);
+			++mResourceWaitCount;
 			return false;
 		}
 		mState = SEND_HTTP_REQ;
@@ -1646,6 +1658,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 		U32 cache_priority = mWorkPriority;
 		mWritten = FALSE;
 		mState = WAIT_ON_WRITE;
+		++mCacheWriteCount;
 		CacheWriteResponder* responder = new CacheWriteResponder(mFetcher, mID);
 		mCacheWriteHandle = mFetcher->mTextureCache->writeToCache(mID, cache_priority,
 																  mFormattedImage->getData(), datasize,
@@ -2168,7 +2181,10 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image
 	  mHttpRequest(NULL),
 	  mHttpOptions(NULL),
 	  mHttpHeaders(NULL),
-	  mHttpSemaphore(HTTP_REQUESTS_IN_QUEUE_HIGH_WATER)
+	  mHttpSemaphore(HTTP_REQUESTS_IN_QUEUE_HIGH_WATER),
+	  mTotalCacheReadCount(0U),
+	  mTotalCacheWriteCount(0U),
+	  mTotalResourceWaitCount(0U)
 {
 	mMaxBandwidth = gSavedSettings.getF32("ThrottleBandwidthKBPS");
 	mTextureInfo.setUpLogging(gSavedSettings.getBOOL("LogTextureDownloadsToViewerLog"), gSavedSettings.getBOOL("LogTextureDownloadsToSimulator"), gSavedSettings.getU32("TextureLoggingThreshold"));
@@ -2661,12 +2677,13 @@ void LLTextureFetch::startThread()
 }
 
 // Threads:  Ttf
-//
-// This detaches the texture fetch thread from the LLCore
-// HTTP library but doesn't stop the thread running in that
-// library...
 void LLTextureFetch::endThread()
 {
+	LL_INFOS("Texture") << "CacheReads:  " << mTotalCacheReadCount
+						<< ", CacheWrites:  " << mTotalCacheWriteCount
+						<< ", ResWaits:  " << mTotalResourceWaitCount
+						<< ", TotalHTTPReq:  " << getTotalNumHTTPRequests()
+						<< LL_ENDL;
 }
 
 // Threads:  Ttf
@@ -3272,6 +3289,34 @@ int LLTextureFetch::getHttpWaitersCount()
 }
 
 
+// Threads:  T*
+void LLTextureFetch::updateStateStats(U32 cache_read, U32 cache_write, U32 res_wait)
+{
+	LLMutexLock lock(&mQueueMutex);										// +Mfq
+
+	mTotalCacheReadCount += cache_read;
+	mTotalCacheWriteCount += cache_write;
+	mTotalResourceWaitCount += res_wait;
+}																		// -Mfq
+
+
+// Threads:  T*
+void LLTextureFetch::getStateStats(U32 * cache_read, U32 * cache_write, U32 * res_wait)
+{
+	U32 ret1(0U), ret2(0U), ret3(0U);
+	
+	{
+		LLMutexLock lock(&mQueueMutex);									// +Mfq
+		ret1 = mTotalCacheReadCount;
+		ret2 = mTotalCacheWriteCount;
+		ret3 = mTotalResourceWaitCount;
+	}																	// -Mfq
+	
+	*cache_read = ret1;
+	*cache_write = ret2;
+	*res_wait = ret3;
+}
+
 //////////////////////////////////////////////////////////////////////////////
 
 // cross-thread command methods
diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h
index 50e318162363378775cb218063515531da85840c..e17c71113a4f95346f2cc497c9620716c0012f97 100644
--- a/indra/newview/lltexturefetch.h
+++ b/indra/newview/lltexturefetch.h
@@ -186,6 +186,17 @@ class LLTextureFetch : public LLWorkerThread
     // Threads:  T*
 	int getHttpWaitersCount();
 	// ----------------------------------
+	// Stats management
+
+	// Add given counts to the global totals for the states/requests
+	// Threads:  T*
+	void updateStateStats(U32 cache_read, U32 cache_write, U32 res_wait);
+
+	// Return the global counts
+	// Threads:  T*
+	void getStateStats(U32 * cache_read, U32 * cache_write, U32 * res_wait);
+
+	// ----------------------------------
 	
 protected:
 	// Threads:  T* (but Ttf in practice)
@@ -323,6 +334,12 @@ class LLTextureFetch : public LLWorkerThread
 	
 	typedef std::set<LLUUID> wait_http_res_queue_t;
 	wait_http_res_queue_t		mHttpWaitResource;						// Mfnq
+
+	// Cumulative stats on the states/requests issued by
+	// textures running through here.
+	U32 mTotalCacheReadCount;											// Mfq
+	U32 mTotalCacheWriteCount;											// Mfq
+	U32 mTotalResourceWaitCount;										// Mfq
 	
 public:
 	// A probabilistically-correct indicator that the current
diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp
index bb1535d23db7767c504142a95d1a31aadce41373..a4227ec2fffcb0b94bf66ba4dd079f2e4404d408 100644
--- a/indra/newview/lltextureview.cpp
+++ b/indra/newview/lltextureview.cpp
@@ -76,7 +76,7 @@ static std::string title_string4("  W x H (Dis) Mem");
 static S32 title_x1 = 0;
 static S32 title_x2 = 460;
 static S32 title_x3 = title_x2 + 40;
-static S32 title_x4 = title_x3 + 50;
+static S32 title_x4 = title_x3 + 46;
 static S32 texture_bar_height = 8;
 
 ////////////////////////////////////////////////////////////////////////////
@@ -349,7 +349,7 @@ void LLTextureBar::draw()
 		
 		// draw the image size at the end
 		{
-			std::string num_str = llformat("%3dx%3d (%d) %7d", mImagep->getWidth(), mImagep->getHeight(),
+			std::string num_str = llformat("%3dx%3d (%2d) %7d", mImagep->getWidth(), mImagep->getHeight(),
 				mImagep->getDiscardLevel(), mImagep->hasGLTexture() ? mImagep->getTextureMemory() : 0);
 			LLFontGL::getFontMonospace()->renderUTF8(num_str, 0, title_x4, getRect().getHeight(), color,
 											LLFontGL::LEFT, LLFontGL::TOP);
@@ -523,22 +523,42 @@ void LLGLTexMemBar::draw()
 	LLGLSUIDefault gls_ui;
 	LLColor4 text_color(1.f, 1.f, 1.f, 0.75f);
 	LLColor4 color;
-	
-	std::string text = "";
 
+	// Gray background using completely magic numbers
+	gGL.color4f(0.f, 0.f, 0.f, 0.25f);
+	const LLRect & rect(getRect());
+	gl_rect_2d(-4, v_offset, rect.mRight - rect.mLeft + 2, v_offset + line_height*4);
+
+	std::string text = "";
 	LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*6,
 											 text_color, LLFontGL::LEFT, LLFontGL::TOP);
 
-	text = llformat("GL Tot: %d/%d MB Bound: %d/%d MB FBO: %d MB Raw Tot: %d MB Bias: %.2f Cache: %.1f/%.1f MB Net Tot Tex: %.1f MB Tot Obj: %.1f MB Tot Htp: %d",
+	text = llformat("GL Tot: %d/%d MB Bound: %d/%d MB FBO: %d MB Raw Tot: %d MB Bias: %.2f Cache: %.1f/%.1f MB",
 					total_mem,
 					max_total_mem,
 					bound_mem,
 					max_bound_mem,
 					LLRenderTarget::sBytesAllocated/(1024*1024),
-					LLImageRaw::sGlobalRawMemory >> 20,	discard_bias,
-					cache_usage, cache_max_usage, total_texture_downloaded, total_object_downloaded, total_http_requests);
+					LLImageRaw::sGlobalRawMemory >> 20,
+					discard_bias,
+					cache_usage,
+					cache_max_usage);
 	//, cache_entries, cache_max_entries
 
+	LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*4,
+											 text_color, LLFontGL::LEFT, LLFontGL::TOP);
+
+	U32 cache_read(0U), cache_write(0U), res_wait(0U);
+	LLAppViewer::getTextureFetch()->getStateStats(&cache_read, &cache_write, &res_wait);
+	
+	text = llformat("Net Tot Tex: %.1f MB Tot Obj: %.1f MB Tot Htp: %d Cread: %u Cwrite: %u Rwait: %u",
+					total_texture_downloaded,
+					total_object_downloaded,
+					total_http_requests,
+					cache_read,
+					cache_write,
+					res_wait);
+
 	LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*3,
 											 text_color, LLFontGL::LEFT, LLFontGL::TOP);