From b6841d75c2f259c84d5ab6b012bd2ae37d985451 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Fri, 15 Apr 2022 19:02:07 -0500
Subject: [PATCH] SL-17219 WIP - Texture pipeline overhaul

---
 indra/llappearance/lltexlayerparams.cpp       |   2 +-
 indra/llappearance/lltexlayerparams.h         |   2 +-
 indra/llcommon/llapr.cpp                      |   2 +
 indra/llcommon/llqueuedthread.cpp             | 289 ++++++------
 indra/llcommon/llqueuedthread.h               |  51 +--
 indra/llcommon/lltimer.cpp                    |   3 +-
 indra/llcommon/llworkerthread.cpp             |  27 +-
 indra/llcommon/llworkerthread.h               |  11 +-
 indra/llcommon/workqueue.h                    |   8 +-
 indra/llcorehttp/_httplibcurl.cpp             |  59 ++-
 indra/llcorehttp/_httpoperation.cpp           |   1 -
 indra/llcorehttp/_httpoperation.h             |   1 -
 indra/llcorehttp/_httpoprequest.cpp           |  48 +-
 indra/llcorehttp/_httpoprequest.h             |  22 -
 indra/llcorehttp/_httpopsetpriority.cpp       |   3 +
 indra/llcorehttp/_httpopsetpriority.h         |   6 +-
 indra/llcorehttp/_httppolicy.cpp              |  31 --
 indra/llcorehttp/_httppolicy.h                |   6 -
 indra/llcorehttp/_httpservice.cpp             |  32 +-
 indra/llcorehttp/_httpservice.h               |   9 -
 indra/llcorehttp/httprequest.cpp              |  45 +-
 indra/llcorehttp/httprequest.h                |  30 --
 indra/llfilesystem/lllfsthread.cpp            |  25 +-
 indra/llfilesystem/lllfsthread.h              |  13 +-
 indra/llimage/llimagej2c.cpp                  |   2 +
 indra/llimage/llimageworker.cpp               |  36 +-
 indra/llimage/llimageworker.h                 |   9 +-
 indra/llimagej2coj/llimagej2coj.cpp           |   1 +
 indra/llkdu/llimagej2ckdu.cpp                 |  29 +-
 indra/llmessage/llavatarnamecache.cpp         |   2 -
 indra/llmessage/llcorehttputil.cpp            |  27 +-
 indra/llmessage/llcorehttputil.h              |  25 +-
 indra/llrender/llimagegl.cpp                  |  50 +-
 indra/newview/app_settings/settings.xml       |  28 +-
 indra/newview/featuretable.txt                |   1 -
 indra/newview/featuretable_mac.txt            |   1 -
 indra/newview/llappviewer.cpp                 |   2 +-
 indra/newview/lldrawpoolterrain.cpp           |   2 +-
 indra/newview/llface.cpp                      |   1 +
 indra/newview/llfloaterpreference.cpp         |   7 +-
 indra/newview/llinventorymodel.cpp            |   3 -
 indra/newview/llinventorymodel.h              |   2 -
 indra/newview/llmaterialmgr.cpp               |   7 +-
 indra/newview/llmaterialmgr.h                 |   1 -
 indra/newview/llmediadataclient.cpp           |   2 +-
 indra/newview/llmeshrepository.cpp            |   8 +-
 indra/newview/llmeshrepository.h              |   2 -
 indra/newview/llspatialpartition.cpp          |   6 +-
 indra/newview/lltexturecache.cpp              | 110 ++---
 indra/newview/lltexturecache.h                |   6 +-
 indra/newview/lltexturefetch.cpp              | 275 +++++------
 indra/newview/lltexturefetch.h                |  11 +-
 indra/newview/lltextureview.cpp               |  39 +-
 indra/newview/llviewercontrol.cpp             |   7 -
 indra/newview/llviewertexture.cpp             | 316 ++++---------
 indra/newview/llviewertexture.h               |  27 +-
 indra/newview/llviewertexturelist.cpp         | 433 +++++++-----------
 indra/newview/llviewertexturelist.h           |  17 +-
 indra/newview/llvoavatar.cpp                  |   9 -
 indra/newview/llvoavatarself.cpp              |   8 +-
 indra/newview/llvovolume.cpp                  |  34 +-
 indra/newview/llxmlrpctransaction.cpp         |   2 +-
 indra/newview/pipeline.cpp                    |  48 +-
 .../floater_preferences_graphics_advanced.xml |  17 -
 64 files changed, 893 insertions(+), 1446 deletions(-)

diff --git a/indra/llappearance/lltexlayerparams.cpp b/indra/llappearance/lltexlayerparams.cpp
index ce5c7142d5c..06b4f6c75aa 100644
--- a/indra/llappearance/lltexlayerparams.cpp
+++ b/indra/llappearance/lltexlayerparams.cpp
@@ -151,7 +151,7 @@ LLTexLayerParamAlpha::LLTexLayerParamAlpha(const LLTexLayerParamAlpha& pOther)
 	mCachedProcessedTexture(pOther.mCachedProcessedTexture),
 	mStaticImageTGA(pOther.mStaticImageTGA),
 	mStaticImageRaw(pOther.mStaticImageRaw),
-	mNeedsCreateTexture(pOther.mNeedsCreateTexture),
+	mNeedsCreateTexture(pOther.mNeedsCreateTexture.load()),
 	mStaticImageInvalid(pOther.mStaticImageInvalid),
 	mAvgDistortionVec(pOther.mAvgDistortionVec),
 	mCachedEffectiveWeight(pOther.mCachedEffectiveWeight)
diff --git a/indra/llappearance/lltexlayerparams.h b/indra/llappearance/lltexlayerparams.h
index e2440998b34..000f55685e0 100644
--- a/indra/llappearance/lltexlayerparams.h
+++ b/indra/llappearance/lltexlayerparams.h
@@ -100,7 +100,7 @@ class alignas(16) LLTexLayerParamAlpha : public LLTexLayerParam
 	LLPointer<LLGLTexture>	mCachedProcessedTexture;
 	LLPointer<LLImageTGA>	mStaticImageTGA;
 	LLPointer<LLImageRaw>	mStaticImageRaw;
-	BOOL					mNeedsCreateTexture;
+	std::atomic<BOOL>		mNeedsCreateTexture;
 	BOOL					mStaticImageInvalid;
 	LL_ALIGN_16(LLVector4a				mAvgDistortionVec);
 	F32						mCachedEffectiveWeight;
diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp
index db947658719..b5371025106 100644
--- a/indra/llcommon/llapr.cpp
+++ b/indra/llcommon/llapr.cpp
@@ -526,6 +526,7 @@ S32 LLAPRFile::seek(apr_file_t* file_handle, apr_seek_where_t where, S32 offset)
 //static
 S32 LLAPRFile::readEx(const std::string& filename, void *buf, S32 offset, S32 nbytes, LLVolatileAPRPool* pool)
 {
+    LL_PROFILE_ZONE_SCOPED;
 	//*****************************************
 	LLAPRFilePoolScope scope(pool);
 	apr_file_t* file_handle = open(filename, scope.getVolatileAPRPool(), APR_READ|APR_BINARY); 
@@ -570,6 +571,7 @@ S32 LLAPRFile::readEx(const std::string& filename, void *buf, S32 offset, S32 nb
 //static
 S32 LLAPRFile::writeEx(const std::string& filename, void *buf, S32 offset, S32 nbytes, LLVolatileAPRPool* pool)
 {
+    LL_PROFILE_ZONE_SCOPED;
 	apr_int32_t flags = APR_CREATE|APR_WRITE|APR_BINARY;
 	if (offset < 0)
 	{
diff --git a/indra/llcommon/llqueuedthread.cpp b/indra/llcommon/llqueuedthread.cpp
index 8cef4293cd7..871c42f7eed 100644
--- a/indra/llcommon/llqueuedthread.cpp
+++ b/indra/llcommon/llqueuedthread.cpp
@@ -26,20 +26,25 @@
 #include "linden_common.h"
 #include "llqueuedthread.h"
 
+#include <chrono>
+
 #include "llstl.h"
 #include "lltimer.h"	// ms_sleep()
-#include "lltracethreadrecorder.h"
+#include "llmutex.h"
 
 //============================================================================
 
 // MAIN THREAD
 LLQueuedThread::LLQueuedThread(const std::string& name, bool threaded, bool should_pause) :
-	LLThread(name),
-	mThreaded(threaded),
-	mIdleThread(TRUE),
-	mNextHandle(0),
-	mStarted(FALSE)
+    LLThread(name),
+    mThreaded(threaded),
+    mIdleThread(TRUE),
+    mNextHandle(0),
+    mStarted(FALSE),
+    mRequestQueue(name, 1024 * 1024)
 {
+    mMainQueue = LL::WorkQueue::getInstance("mainloop");
+
 	if (mThreaded)
 	{
 		if(should_pause)
@@ -104,6 +109,8 @@ void LLQueuedThread::shutdown()
 	{
 		LL_WARNS() << "~LLQueuedThread() called with active requests: " << active_count << LL_ENDL;
 	}
+
+    mRequestQueue.close();
 }
 
 //----------------------------------------------------------------------------
@@ -112,6 +119,7 @@ void LLQueuedThread::shutdown()
 // virtual
 S32 LLQueuedThread::update(F32 max_time_ms)
 {
+    LL_PROFILE_ZONE_SCOPED;
 	if (!mStarted)
 	{
 		if (!mThreaded)
@@ -125,29 +133,30 @@ S32 LLQueuedThread::update(F32 max_time_ms)
 
 S32 LLQueuedThread::updateQueue(F32 max_time_ms)
 {
-	F64 max_time = (F64)max_time_ms * .001;
-	LLTimer timer;
-	S32 pending = 1;
-
+    LL_PROFILE_ZONE_SCOPED;
 	// Frame Update
 	if (mThreaded)
 	{
-		pending = getPending();
-		if(pending > 0)
+        // schedule a call to threadedUpdate for every call to updateQueue
+        mRequestQueue.post([=]() 
+            {
+                LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("qt - update");
+                mIdleThread = FALSE;
+                threadedUpdate(); 
+                mIdleThread = TRUE;
+            }
+        );
+		if(getPending() > 0)
 		{
-		unpause();
-	}
+		    unpause();
+	    }
 	}
 	else
 	{
-		while (pending > 0)
-		{
-			pending = processNextRequest();
-			if (max_time && timer.getElapsedTimeF64() > max_time)
-				break;
-		}
+        mRequestQueue.runFor(std::chrono::microseconds((int) (max_time_ms*1000.f)));
+        threadedUpdate();
 	}
-	return pending;
+	return getPending();
 }
 
 void LLQueuedThread::incQueue()
@@ -166,11 +175,7 @@ void LLQueuedThread::incQueue()
 // May be called from any thread
 S32 LLQueuedThread::getPending()
 {
-	S32 res;
-	lockData();
-	res = mRequestQueue.size();
-	unlockData();
-	return res;
+	return mRequestQueue.size();
 }
 
 // MAIN thread
@@ -195,35 +200,28 @@ void LLQueuedThread::waitOnPending()
 // MAIN thread
 void LLQueuedThread::printQueueStats()
 {
-	lockData();
-	if (!mRequestQueue.empty())
+    U32 size = mRequestQueue.size();
+	if (size > 0)
 	{
-		QueuedRequest *req = *mRequestQueue.begin();
-		LL_INFOS() << llformat("Pending Requests:%d Current status:%d", mRequestQueue.size(), req->getStatus()) << LL_ENDL;
+		LL_INFOS() << llformat("Pending Requests:%d ", mRequestQueue.size()) << LL_ENDL;
 	}
 	else
 	{
 		LL_INFOS() << "Queued Thread Idle" << LL_ENDL;
 	}
-	unlockData();
 }
 
 // MAIN thread
 LLQueuedThread::handle_t LLQueuedThread::generateHandle()
 {
-	lockData();
-	while ((mNextHandle == nullHandle()) || (mRequestHash.find(mNextHandle)))
-	{
-		mNextHandle++;
-	}
-	const LLQueuedThread::handle_t res = mNextHandle++;
-	unlockData();
+    U32 res = ++mNextHandle;
 	return res;
 }
 
 // MAIN thread
 bool LLQueuedThread::addRequest(QueuedRequest* req)
 {
+    LL_PROFILE_ZONE_SCOPED;
 	if (mStatus == QUITTING)
 	{
 		return false;
@@ -231,14 +229,14 @@ bool LLQueuedThread::addRequest(QueuedRequest* req)
 	
 	lockData();
 	req->setStatus(STATUS_QUEUED);
-	mRequestQueue.insert(req);
-	mRequestHash.insert(req);
+    mRequestHash.insert(req);
 #if _DEBUG
 // 	LL_INFOS() << llformat("LLQueuedThread::Added req [%08d]",handle) << LL_ENDL;
 #endif
 	unlockData();
 
-	incQueue();
+    llassert(!mDataLock->isSelfLocked());
+    mRequestQueue.post([this, req]() { processRequest(req); });
 
 	return true;
 }
@@ -246,6 +244,7 @@ bool LLQueuedThread::addRequest(QueuedRequest* req)
 // MAIN thread
 bool LLQueuedThread::waitForResult(LLQueuedThread::handle_t handle, bool auto_complete)
 {
+    LL_PROFILE_ZONE_SCOPED;
 	llassert (handle != nullHandle());
 	bool res = false;
 	bool waspaused = isPaused();
@@ -312,6 +311,7 @@ LLQueuedThread::status_t LLQueuedThread::getRequestStatus(handle_t handle)
 
 void LLQueuedThread::abortRequest(handle_t handle, bool autocomplete)
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
 	lockData();
 	QueuedRequest* req = (QueuedRequest*)mRequestHash.find(handle);
 	if (req)
@@ -333,30 +333,9 @@ void LLQueuedThread::setFlags(handle_t handle, U32 flags)
 	unlockData();
 }
 
-void LLQueuedThread::setPriority(handle_t handle, U32 priority)
-{
-	lockData();
-	QueuedRequest* req = (QueuedRequest*)mRequestHash.find(handle);
-	if (req)
-	{
-		if(req->getStatus() == STATUS_INPROGRESS)
-		{
-			// not in list
-			req->setPriority(priority);
-		}
-		else if(req->getStatus() == STATUS_QUEUED)
-		{
-			// remove from list then re-insert
-			llverify(mRequestQueue.erase(req) == 1);
-			req->setPriority(priority);
-			mRequestQueue.insert(req);
-		}
-	}
-	unlockData();
-}
-
 bool LLQueuedThread::completeRequest(handle_t handle)
 {
+    LL_PROFILE_ZONE_SCOPED;
 	bool res = false;
 	lockData();
 	QueuedRequest* req = (QueuedRequest*)mRequestHash.find(handle);
@@ -399,89 +378,115 @@ bool LLQueuedThread::check()
 //============================================================================
 // Runs on its OWN thread
 
-S32 LLQueuedThread::processNextRequest()
+void LLQueuedThread::processRequest(LLQueuedThread::QueuedRequest* req)
 {
-	QueuedRequest *req;
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
+
+    mIdleThread = FALSE;
+    //threadedUpdate();
+
 	// Get next request from pool
 	lockData();
 	
-	while(1)
-	{
-		req = NULL;
-		if (mRequestQueue.empty())
-		{
-			break;
-		}
-		req = *mRequestQueue.begin();
-		mRequestQueue.erase(mRequestQueue.begin());
-		if ((req->getFlags() & FLAG_ABORT) || (mStatus == QUITTING))
-		{
-			req->setStatus(STATUS_ABORTED);
-			req->finishRequest(false);
-			if (req->getFlags() & FLAG_AUTO_COMPLETE)
-			{
-				mRequestHash.erase(req);
-				req->deleteRequest();
-// 				check();
-			}
-			continue;
-		}
-		llassert_always(req->getStatus() == STATUS_QUEUED);
-		break;
-	}
-	U32 start_priority = 0 ;
-	if (req)
-	{
-		req->setStatus(STATUS_INPROGRESS);
-		start_priority = req->getPriority();
-	}
-	unlockData();
-
-	// This is the only place we will call req->setStatus() after
-	// it has initially been seet to STATUS_QUEUED, so it is
-	// safe to access req.
-	if (req)
+	if ((req->getFlags() & FLAG_ABORT) || (mStatus == QUITTING))
 	{
-		// process request		
-		bool complete = req->processRequest();
-
-		if (complete)
+        LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("qtpr - abort");
+		req->setStatus(STATUS_ABORTED);
+		req->finishRequest(false);
+		if (req->getFlags() & FLAG_AUTO_COMPLETE)
 		{
-			lockData();
-			req->setStatus(STATUS_COMPLETE);
-			req->finishRequest(true);
-			if (req->getFlags() & FLAG_AUTO_COMPLETE)
-			{
-				mRequestHash.erase(req);
-				req->deleteRequest();
+			mRequestHash.erase(req);
+			req->deleteRequest();
 // 				check();
-			}
-			unlockData();
 		}
-		else
-		{
-			lockData();
-			req->setStatus(STATUS_QUEUED);
-			mRequestQueue.insert(req);
-			unlockData();
-			if (mThreaded && start_priority < PRIORITY_NORMAL)
-			{
-				ms_sleep(1); // sleep the thread a little
-			}
-		}
-		
-		LLTrace::get_thread_recorder()->pushToParent();
+        unlockData();
 	}
+    else
+    {
+        llassert_always(req->getStatus() == STATUS_QUEUED);
+
+        if (req)
+        {
+            req->setStatus(STATUS_INPROGRESS);
+        }
+        unlockData();
+
+        // This is the only place we will call req->setStatus() after
+        // it has initially been seet to STATUS_QUEUED, so it is
+        // safe to access req.
+        if (req)
+        {
+            // process request		
+            bool complete = req->processRequest();
+
+            if (complete)
+            {
+                LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("qtpr - complete");
+                lockData();
+                req->setStatus(STATUS_COMPLETE);
+                req->finishRequest(true);
+                if (req->getFlags() & FLAG_AUTO_COMPLETE)
+                {
+                    mRequestHash.erase(req);
+                    req->deleteRequest();
+                    // 				check();
+                }
+                unlockData();
+            }
+            else
+            {
+                LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("qtpr - retry");
+                //put back on queue and try again in 0.1ms
+                lockData();
+                req->setStatus(STATUS_QUEUED);
+                
+                unlockData();
+
+                llassert(!mDataLock->isSelfLocked());
+
+#if 0
+                // try again on next frame
+                // NOTE: tried using "post" with a time in the future, but this
+                // would invariably cause this thread to wait for a long time (10+ ms)
+                // while work is pending
+                bool ret = LL::WorkQueue::postMaybe(
+                    mMainQueue,
+                    [=]()
+                    {
+                        LL_PROFILE_ZONE_NAMED("processRequest - retry");
+                        mRequestQueue.post([=]()
+                            {
+                                LL_PROFILE_ZONE_NAMED("processRequest - retry"); // <-- not redundant, track retry on both queues
+                                processRequest(req);
+                            });
+                    });
+                llassert(ret);
+#else
+                using namespace std::chrono_literals;
+                auto retry_time = LL::WorkQueue::TimePoint::clock::now() + 16ms;
+                mRequestQueue.post([=]
+                    {
+                        LL_PROFILE_ZONE_NAMED("processRequest - retry");
+                        while (LL::WorkQueue::TimePoint::clock::now() < retry_time)
+                        {
+                            std::this_thread::yield(); //note: don't use LLThread::yield here to avoid 
+                        }
+                        processRequest(req);
+                    });
+#endif
+                
+            }
+        }
+    }
 
-	S32 pending = getPending();
-	return pending;
+    mIdleThread = TRUE;
 }
 
 // virtual
 bool LLQueuedThread::runCondition()
 {
 	// mRunCondition must be locked here
-	if (mRequestQueue.empty() && mIdleThread)
+	if (mRequestQueue.size() == 0 && mIdleThread)
 		return false;
 	else
 		return true;
@@ -495,18 +500,13 @@ void LLQueuedThread::run()
 	startThread();
 	mStarted = TRUE;
 	
-	while (1)
+
+	/*while (1)
 	{
+        LL_PROFILE_ZONE_SCOPED;
 		// this will block on the condition until runCondition() returns true, the thread is unpaused, or the thread leaves the RUNNING state.
 		checkPause();
 		
-		if (isQuitting())
-		{
-			LLTrace::get_thread_recorder()->pushToParent();
-			endThread();
-			break;
-		}
-
 		mIdleThread = FALSE;
 
 		threadedUpdate();
@@ -515,12 +515,18 @@ void LLQueuedThread::run()
 
 		if (pending_work == 0)
 		{
+            //LL_PROFILE_ZONE_NAMED("LLQueuedThread - sleep");
 			mIdleThread = TRUE;
-			ms_sleep(1);
+			//ms_sleep(1);
 		}
 		//LLThread::yield(); // thread should yield after each request		
-	}
+	}*/
+    mRequestQueue.runUntilClose();
+
+    endThread();
 	LL_INFOS() << "LLQueuedThread " << mName << " EXITING." << LL_ENDL;
+
+    
 }
 
 // virtual
@@ -540,10 +546,9 @@ void LLQueuedThread::threadedUpdate()
 
 //============================================================================
 
-LLQueuedThread::QueuedRequest::QueuedRequest(LLQueuedThread::handle_t handle, U32 priority, U32 flags) :
+LLQueuedThread::QueuedRequest::QueuedRequest(LLQueuedThread::handle_t handle, U32 flags) :
 	LLSimpleHashEntry<LLQueuedThread::handle_t>(handle),
 	mStatus(STATUS_UNKNOWN),
-	mPriority(priority),
 	mFlags(flags)
 {
 }
diff --git a/indra/llcommon/llqueuedthread.h b/indra/llcommon/llqueuedthread.h
index 5d3f8736467..6b82ccc434b 100644
--- a/indra/llcommon/llqueuedthread.h
+++ b/indra/llcommon/llqueuedthread.h
@@ -36,6 +36,7 @@
 
 #include "llthread.h"
 #include "llsimplehash.h"
+#include "workqueue.h"
 
 //============================================================================
 // Note: ~LLQueuedThread is O(N) N=# of queued threads, assumed to be small
@@ -45,15 +46,6 @@ class LL_COMMON_API LLQueuedThread : public LLThread
 {
 	//------------------------------------------------------------------------
 public:
-	enum priority_t {
-		PRIORITY_IMMEDIATE = 0x7FFFFFFF,
-		PRIORITY_URGENT =    0x40000000,
-		PRIORITY_HIGH =      0x30000000,
-		PRIORITY_NORMAL =    0x20000000,
-		PRIORITY_LOW =       0x10000000,
-		PRIORITY_LOWBITS =   0x0FFFFFFF,
-		PRIORITY_HIGHBITS =  0x70000000
-	};
 	enum status_t {
 		STATUS_EXPIRED = -1,
 		STATUS_UNKNOWN = 0,
@@ -82,28 +74,17 @@ class LL_COMMON_API LLQueuedThread : public LLThread
 		virtual ~QueuedRequest(); // use deleteRequest()
 		
 	public:
-		QueuedRequest(handle_t handle, U32 priority, U32 flags = 0);
+		QueuedRequest(handle_t handle, U32 flags = 0);
 
 		status_t getStatus()
 		{
 			return mStatus;
 		}
-		U32 getPriority() const
-		{
-			return mPriority;
-		}
 		U32 getFlags() const
 		{
 			return mFlags;
 		}
-		bool higherPriority(const QueuedRequest& second) const
-		{
-			if ( mPriority == second.mPriority)
-				return mHashKey < second.mHashKey;
-			else
-				return mPriority > second.mPriority;
-		}
-
+		
 	protected:
 		status_t setStatus(status_t newstatus)
 		{
@@ -121,28 +102,11 @@ class LL_COMMON_API LLQueuedThread : public LLThread
 		virtual void finishRequest(bool completed); // Always called from thread after request has completed or aborted
 		virtual void deleteRequest(); // Only method to delete a request
 
-		void setPriority(U32 pri)
-		{
-			// Only do this on a request that is not in a queued list!
-			mPriority = pri;
-		};
-		
 	protected:
 		LLAtomicBase<status_t> mStatus;
-		U32 mPriority;
 		U32 mFlags;
 	};
 
-protected:
-	struct queued_request_less
-	{
-		bool operator()(const QueuedRequest* lhs, const QueuedRequest* rhs) const
-		{
-			return lhs->higherPriority(*rhs); // higher priority in front of queue (set)
-		}
-	};
-
-
 	//------------------------------------------------------------------------
 	
 public:
@@ -167,7 +131,7 @@ class LL_COMMON_API LLQueuedThread : public LLThread
 protected:
 	handle_t generateHandle();
 	bool addRequest(QueuedRequest* req);
-	S32  processNextRequest(void);
+	void processRequest(QueuedRequest* req);
 	void incQueue();
 
 public:
@@ -186,7 +150,6 @@ class LL_COMMON_API LLQueuedThread : public LLThread
 	status_t getRequestStatus(handle_t handle);
 	void abortRequest(handle_t handle, bool autocomplete);
 	void setFlags(handle_t handle, U32 flags);
-	void setPriority(handle_t handle, U32 priority);
 	bool completeRequest(handle_t handle);
 	// This is public for support classes like LLWorkerThread,
 	// but generally the methods above should be used.
@@ -200,8 +163,10 @@ class LL_COMMON_API LLQueuedThread : public LLThread
 	BOOL mStarted;  // required when mThreaded is false to call startThread() from update()
 	LLAtomicBool mIdleThread; // request queue is empty (or we are quitting) and the thread is idle
 	
-	typedef std::set<QueuedRequest*, queued_request_less> request_queue_t;
-	request_queue_t mRequestQueue;
+	//typedef std::set<QueuedRequest*, queued_request_less> request_queue_t;
+	//request_queue_t mRequestQueue;
+    LL::WorkQueue mRequestQueue;
+    LL::WorkQueue::weak_t mMainQueue;
 
 	enum { REQUEST_HASH_SIZE = 512 }; // must be power of 2
 	typedef LLSimpleHash<handle_t, REQUEST_HASH_SIZE> request_hash_t;
diff --git a/indra/llcommon/lltimer.cpp b/indra/llcommon/lltimer.cpp
index aaa6df325cb..b250bc3e1c6 100644
--- a/indra/llcommon/lltimer.cpp
+++ b/indra/llcommon/lltimer.cpp
@@ -64,7 +64,8 @@ LLTimer* LLTimer::sTimer = NULL;
 #if LL_WINDOWS
 void ms_sleep(U32 ms)
 {
-	Sleep(ms);
+    LL_PROFILE_ZONE_SCOPED;
+    std::this_thread::sleep_for(std::chrono::microseconds(ms));
 }
 
 U32 micro_sleep(U64 us, U32 max_yields)
diff --git a/indra/llcommon/llworkerthread.cpp b/indra/llcommon/llworkerthread.cpp
index 4b91b2cacaf..02ce4823b83 100644
--- a/indra/llcommon/llworkerthread.cpp
+++ b/indra/llcommon/llworkerthread.cpp
@@ -133,11 +133,11 @@ S32 LLWorkerThread::update(F32 max_time_ms)
 
 //----------------------------------------------------------------------------
 
-LLWorkerThread::handle_t LLWorkerThread::addWorkRequest(LLWorkerClass* workerclass, S32 param, U32 priority)
+LLWorkerThread::handle_t LLWorkerThread::addWorkRequest(LLWorkerClass* workerclass, S32 param)
 {
 	handle_t handle = generateHandle();
 	
-	WorkRequest* req = new WorkRequest(handle, priority, workerclass, param);
+	WorkRequest* req = new WorkRequest(handle, workerclass, param);
 
 	bool res = addRequest(req);
 	if (!res)
@@ -160,8 +160,8 @@ void LLWorkerThread::deleteWorker(LLWorkerClass* workerclass)
 //============================================================================
 // Runs on its OWN thread
 
-LLWorkerThread::WorkRequest::WorkRequest(handle_t handle, U32 priority, LLWorkerClass* workerclass, S32 param) :
-	LLQueuedThread::QueuedRequest(handle, priority),
+LLWorkerThread::WorkRequest::WorkRequest(handle_t handle, LLWorkerClass* workerclass, S32 param) :
+	LLQueuedThread::QueuedRequest(handle),
 	mWorkerClass(workerclass),
 	mParam(param)
 {
@@ -180,6 +180,7 @@ void LLWorkerThread::WorkRequest::deleteRequest()
 // virtual
 bool LLWorkerThread::WorkRequest::processRequest()
 {
+    LL_PROFILE_ZONE_SCOPED;
 	LLWorkerClass* workerclass = getWorkerClass();
 	workerclass->setWorking(true);
 	bool complete = workerclass->doWork(getParam());
@@ -190,6 +191,7 @@ bool LLWorkerThread::WorkRequest::processRequest()
 // virtual
 void LLWorkerThread::WorkRequest::finishRequest(bool completed)
 {
+    LL_PROFILE_ZONE_SCOPED;
 	LLWorkerClass* workerclass = getWorkerClass();
 	workerclass->finishWork(getParam(), completed);
 	U32 flags = LLWorkerClass::WCF_WORK_FINISHED | (completed ? 0 : LLWorkerClass::WCF_WORK_ABORTED);
@@ -203,7 +205,6 @@ LLWorkerClass::LLWorkerClass(LLWorkerThread* workerthread, const std::string& na
 	: mWorkerThread(workerthread),
 	  mWorkerClassName(name),
 	  mRequestHandle(LLWorkerThread::nullHandle()),
-	  mRequestPriority(LLWorkerThread::PRIORITY_NORMAL),
 	  mMutex(),
 	  mWorkFlags(0)
 {
@@ -292,7 +293,7 @@ bool LLWorkerClass::yield()
 //----------------------------------------------------------------------------
 
 // calls startWork, adds doWork() to queue
-void LLWorkerClass::addWork(S32 param, U32 priority)
+void LLWorkerClass::addWork(S32 param)
 {
 	mMutex.lock();
 	llassert_always(!(mWorkFlags & (WCF_WORKING|WCF_HAVE_WORK)));
@@ -306,7 +307,7 @@ void LLWorkerClass::addWork(S32 param, U32 priority)
 	startWork(param);
 	clearFlags(WCF_WORK_FINISHED|WCF_WORK_ABORTED);
 	setFlags(WCF_HAVE_WORK);
-	mRequestHandle = mWorkerThread->addWorkRequest(this, param, priority);
+	mRequestHandle = mWorkerThread->addWorkRequest(this, param);
 	mMutex.unlock();
 }
 
@@ -321,7 +322,6 @@ void LLWorkerClass::abortWork(bool autocomplete)
 	if (mRequestHandle != LLWorkerThread::nullHandle())
 	{
 		mWorkerThread->abortRequest(mRequestHandle, autocomplete);
-		mWorkerThread->setPriority(mRequestHandle, LLQueuedThread::PRIORITY_IMMEDIATE);
 		setFlags(WCF_ABORT_REQUESTED);
 	}
 	mMutex.unlock();
@@ -395,16 +395,5 @@ void LLWorkerClass::scheduleDelete()
 	}
 }
 
-void LLWorkerClass::setPriority(U32 priority)
-{
-	mMutex.lock();
-	if (mRequestHandle != LLWorkerThread::nullHandle() && mRequestPriority != priority)
-	{
-		mRequestPriority = priority;
-		mWorkerThread->setPriority(mRequestHandle, priority);
-	}
-	mMutex.unlock();
-}
-
 //============================================================================
 
diff --git a/indra/llcommon/llworkerthread.h b/indra/llcommon/llworkerthread.h
index 0387e75c653..06bbb7369ed 100644
--- a/indra/llcommon/llworkerthread.h
+++ b/indra/llcommon/llworkerthread.h
@@ -56,7 +56,7 @@ class LL_COMMON_API LLWorkerThread : public LLQueuedThread
 		virtual ~WorkRequest(); // use deleteRequest()
 		
 	public:
-		WorkRequest(handle_t handle, U32 priority, LLWorkerClass* workerclass, S32 param);
+		WorkRequest(handle_t handle, LLWorkerClass* workerclass, S32 param);
 
 		S32 getParam()
 		{
@@ -90,7 +90,7 @@ class LL_COMMON_API LLWorkerThread : public LLQueuedThread
 
 	/*virtual*/ S32 update(F32 max_time_ms);
 	
-	handle_t addWorkRequest(LLWorkerClass* workerclass, S32 param, U32 priority = PRIORITY_NORMAL);
+	handle_t addWorkRequest(LLWorkerClass* workerclass, S32 param);
 	
 	S32 getNumDeletes() { return (S32)mDeleteList.size(); } // debug
 
@@ -151,10 +151,6 @@ class LL_COMMON_API LLWorkerClass
 	bool isWorking() { return getFlags(WCF_WORKING); }
 	bool wasAborted() { return getFlags(WCF_ABORT_REQUESTED); }
 
-	// setPriority(): changes the priority of a request
-	void setPriority(U32 priority);
-	U32  getPriority() { return mRequestPriority; }
-		
 	const std::string& getName() const { return mWorkerClassName; }
 
 protected:
@@ -169,7 +165,7 @@ class LL_COMMON_API LLWorkerClass
 	void setWorkerThread(LLWorkerThread* workerthread);
 
 	// addWork(): calls startWork, adds doWork() to queue
-	void addWork(S32 param, U32 priority = LLWorkerThread::PRIORITY_NORMAL);
+	void addWork(S32 param);
 
 	// abortWork(): requests that work be aborted
 	void abortWork(bool autocomplete);
@@ -193,7 +189,6 @@ class LL_COMMON_API LLWorkerClass
 	LLWorkerThread* mWorkerThread;
 	std::string mWorkerClassName;
 	handle_t mRequestHandle;
-	U32 mRequestPriority; // last priority set
 
 private:
 	LLMutex mMutex;
diff --git a/indra/llcommon/workqueue.h b/indra/llcommon/workqueue.h
index 96574a18b92..46f7363830c 100644
--- a/indra/llcommon/workqueue.h
+++ b/indra/llcommon/workqueue.h
@@ -161,10 +161,16 @@ namespace LL
         void postEvery(const std::chrono::duration<Rep, Period>& interval,
                        CALLABLE&& callable);
 
+        template <typename CALLABLE>
+        bool tryPost(const TimePoint& time, CALLABLE&& callable)
+        {
+            return mQueue.tryPush(TimedWork(time, std::move(callable)));
+        }
+
         template <typename CALLABLE>
         bool tryPost(CALLABLE&& callable)
         {
-            return mQueue.tryPush(TimedWork(TimePoint::clock::now(), std::move(callable)));
+            return mQueue.tryPost(TimePoint::clock::now(), std::move(callable));
         }
 
         /*------------------------- handshake API --------------------------*/
diff --git a/indra/llcorehttp/_httplibcurl.cpp b/indra/llcorehttp/_httplibcurl.cpp
index 975ce8a4d5b..bd0ac740dbe 100644
--- a/indra/llcorehttp/_httplibcurl.cpp
+++ b/indra/llcorehttp/_httplibcurl.cpp
@@ -113,6 +113,7 @@ void HttpLibcurl::shutdown()
 
 void HttpLibcurl::start(int policy_count)
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
 	llassert_always(policy_count <= HTTP_POLICY_CLASS_LIMIT);
 	llassert_always(! mMultiHandles);					// One-time call only
 	
@@ -143,6 +144,7 @@ void HttpLibcurl::start(int policy_count)
 // sleep otherwise ask for a normal polling interval.
 HttpService::ELoopSpeed HttpLibcurl::processTransport()
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
 	HttpService::ELoopSpeed	ret(HttpService::REQUEST_SLEEP);
 
 	// Give libcurl some cycles to do I/O & callbacks
@@ -168,6 +170,7 @@ HttpService::ELoopSpeed HttpLibcurl::processTransport()
 		CURLMcode status(CURLM_CALL_MULTI_PERFORM);
 		do
 		{
+            LL_PROFILE_ZONE_NAMED_CATEGORY_NETWORK("httppt - curl_multi_perform");
 			running = 0;
 			status = curl_multi_perform(mMultiHandles[policy_class], &running);
 		}
@@ -176,31 +179,34 @@ HttpService::ELoopSpeed HttpLibcurl::processTransport()
 		// Run completion on anything done
 		CURLMsg * msg(NULL);
 		int msgs_in_queue(0);
-		while ((msg = curl_multi_info_read(mMultiHandles[policy_class], &msgs_in_queue)))
-		{
-			if (CURLMSG_DONE == msg->msg)
-			{
-				CURL * handle(msg->easy_handle);
-				CURLcode result(msg->data.result);
+        {
+            LL_PROFILE_ZONE_NAMED_CATEGORY_NETWORK("httppt - curl_multi_info_read");
+            while ((msg = curl_multi_info_read(mMultiHandles[policy_class], &msgs_in_queue)))
+            {
+                if (CURLMSG_DONE == msg->msg)
+                {
+                    CURL* handle(msg->easy_handle);
+                    CURLcode result(msg->data.result);
 
-				completeRequest(mMultiHandles[policy_class], handle, result);
-				handle = NULL;					// No longer valid on return
-				ret = HttpService::NORMAL;		// If anything completes, we may have a free slot.
-												// Turning around quickly reduces connection gap by 7-10mS.
-			}
-			else if (CURLMSG_NONE == msg->msg)
-			{
-				// Ignore this... it shouldn't mean anything.
-				;
-			}
-			else
-			{
-				LL_WARNS_ONCE(LOG_CORE) << "Unexpected message from libcurl.  Msg code:  "
-										<< msg->msg
-										<< LL_ENDL;
-			}
-			msgs_in_queue = 0;
-		}
+                    completeRequest(mMultiHandles[policy_class], handle, result);
+                    handle = NULL;					// No longer valid on return
+                    ret = HttpService::NORMAL;		// If anything completes, we may have a free slot.
+                                                    // Turning around quickly reduces connection gap by 7-10mS.
+                }
+                else if (CURLMSG_NONE == msg->msg)
+                {
+                    // Ignore this... it shouldn't mean anything.
+                    ;
+                }
+                else
+                {
+                    LL_WARNS_ONCE(LOG_CORE) << "Unexpected message from libcurl.  Msg code:  "
+                        << msg->msg
+                        << LL_ENDL;
+                }
+                msgs_in_queue = 0;
+            }
+        }
 	}
 
 	if (! mActiveOps.empty())
@@ -214,6 +220,7 @@ HttpService::ELoopSpeed HttpLibcurl::processTransport()
 // Caller has provided us with a ref count on op.
 void HttpLibcurl::addOp(const HttpOpRequest::ptr_t &op)
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
 	llassert_always(op->mReqPolicy < mPolicyCount);
 	llassert_always(mMultiHandles[op->mReqPolicy] != NULL);
 	
@@ -257,6 +264,7 @@ void HttpLibcurl::addOp(const HttpOpRequest::ptr_t &op)
 // method to kill the request.
 bool HttpLibcurl::cancel(HttpHandle handle)
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
     HttpOpRequest::ptr_t op = HttpOpRequest::fromHandle<HttpOpRequest>(handle);
 	active_set_t::iterator it(mActiveOps.find(op));
 	if (mActiveOps.end() == it)
@@ -282,6 +290,7 @@ bool HttpLibcurl::cancel(HttpHandle handle)
 // op to the reply queue with refcount intact.
 void HttpLibcurl::cancelRequest(const HttpOpRequest::ptr_t &op)
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
 	// Deactivate request
 	op->mCurlActive = false;
 
@@ -308,6 +317,7 @@ void HttpLibcurl::cancelRequest(const HttpOpRequest::ptr_t &op)
 // Keep them synchronized as necessary.
 bool HttpLibcurl::completeRequest(CURLM * multi_handle, CURL * handle, CURLcode status)
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
     HttpHandle ophandle(NULL);
 
     CURLcode ccode(CURLE_OK);
@@ -445,6 +455,7 @@ int HttpLibcurl::getActiveCountInClass(int policy_class) const
 
 void HttpLibcurl::policyUpdated(int policy_class)
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
 	if (policy_class < 0 || policy_class >= mPolicyCount || ! mMultiHandles)
 	{
 		return;
diff --git a/indra/llcorehttp/_httpoperation.cpp b/indra/llcorehttp/_httpoperation.cpp
index 3fc4e289105..3b640181320 100644
--- a/indra/llcorehttp/_httpoperation.cpp
+++ b/indra/llcorehttp/_httpoperation.cpp
@@ -62,7 +62,6 @@ HttpOperation::HttpOperation():
     mReplyQueue(),
     mUserHandler(),
     mReqPolicy(HttpRequest::DEFAULT_POLICY_ID),
-    mReqPriority(0U),
     mTracing(HTTP_TRACE_OFF),
     mMyHandle(LLCORE_HTTP_HANDLE_INVALID)
 {
diff --git a/indra/llcorehttp/_httpoperation.h b/indra/llcorehttp/_httpoperation.h
index 1a75921c09c..8c1364bab4e 100644
--- a/indra/llcorehttp/_httpoperation.h
+++ b/indra/llcorehttp/_httpoperation.h
@@ -181,7 +181,6 @@ class HttpOperation : private boost::noncopyable,
 public:
 	// Request Data
 	HttpRequest::policy_t		mReqPolicy;
-	HttpRequest::priority_t		mReqPriority;
 
 	// Reply Data
 	HttpStatus					mStatus;
diff --git a/indra/llcorehttp/_httpoprequest.cpp b/indra/llcorehttp/_httpoprequest.cpp
index ba31290c245..d60eb6c95fa 100644
--- a/indra/llcorehttp/_httpoprequest.cpp
+++ b/indra/llcorehttp/_httpoprequest.cpp
@@ -200,6 +200,7 @@ HttpOpRequest::~HttpOpRequest()
 
 void HttpOpRequest::stageFromRequest(HttpService * service)
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
     HttpOpRequest::ptr_t self(boost::dynamic_pointer_cast<HttpOpRequest>(shared_from_this()));
     service->getPolicy().addOp(self);			// transfers refcount
 }
@@ -207,6 +208,7 @@ void HttpOpRequest::stageFromRequest(HttpService * service)
 
 void HttpOpRequest::stageFromReady(HttpService * service)
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
     HttpOpRequest::ptr_t self(boost::dynamic_pointer_cast<HttpOpRequest>(shared_from_this()));
     service->getTransport().addOp(self);		// transfers refcount
 }
@@ -214,6 +216,7 @@ void HttpOpRequest::stageFromReady(HttpService * service)
 
 void HttpOpRequest::stageFromActive(HttpService * service)
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
 	if (mReplyLength)
 	{
 		// If non-zero, we received and processed a Content-Range
@@ -250,6 +253,7 @@ void HttpOpRequest::stageFromActive(HttpService * service)
 
 void HttpOpRequest::visitNotifier(HttpRequest * request)
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
 	if (mUserHandler)
 	{
 		HttpResponse * response = new HttpResponse();
@@ -292,6 +296,7 @@ void HttpOpRequest::visitNotifier(HttpRequest * request)
 
 HttpStatus HttpOpRequest::cancel()
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
 	mStatus = HttpStatus(HttpStatus::LLCORE, HE_OP_CANCELED);
 
 	addAsReply();
@@ -301,12 +306,12 @@ HttpStatus HttpOpRequest::cancel()
 
 
 HttpStatus HttpOpRequest::setupGet(HttpRequest::policy_t policy_id,
-								   HttpRequest::priority_t priority,
 								   const std::string & url,
                                    const HttpOptions::ptr_t & options,
 								   const HttpHeaders::ptr_t & headers)
 {
-	setupCommon(policy_id, priority, url, NULL, options, headers);
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
+	setupCommon(policy_id, url, NULL, options, headers);
 	mReqMethod = HOR_GET;
 	
 	return HttpStatus();
@@ -314,14 +319,14 @@ HttpStatus HttpOpRequest::setupGet(HttpRequest::policy_t policy_id,
 
 
 HttpStatus HttpOpRequest::setupGetByteRange(HttpRequest::policy_t policy_id,
-											HttpRequest::priority_t priority,
 											const std::string & url,
 											size_t offset,
 											size_t len,
                                             const HttpOptions::ptr_t & options,
                                             const HttpHeaders::ptr_t & headers)
 {
-	setupCommon(policy_id, priority, url, NULL, options, headers);
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
+	setupCommon(policy_id, url, NULL, options, headers);
 	mReqMethod = HOR_GET;
 	mReqOffset = offset;
 	mReqLength = len;
@@ -335,13 +340,13 @@ HttpStatus HttpOpRequest::setupGetByteRange(HttpRequest::policy_t policy_id,
 
 
 HttpStatus HttpOpRequest::setupPost(HttpRequest::policy_t policy_id,
-									HttpRequest::priority_t priority,
 									const std::string & url,
 									BufferArray * body,
                                     const HttpOptions::ptr_t & options,
                                     const HttpHeaders::ptr_t & headers)
 {
-	setupCommon(policy_id, priority, url, body, options, headers);
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
+	setupCommon(policy_id, url, body, options, headers);
 	mReqMethod = HOR_POST;
 	
 	return HttpStatus();
@@ -349,13 +354,13 @@ HttpStatus HttpOpRequest::setupPost(HttpRequest::policy_t policy_id,
 
 
 HttpStatus HttpOpRequest::setupPut(HttpRequest::policy_t policy_id,
-								   HttpRequest::priority_t priority,
 								   const std::string & url,
 								   BufferArray * body,
                                    const HttpOptions::ptr_t & options,
 								   const HttpHeaders::ptr_t & headers)
 {
-	setupCommon(policy_id, priority, url, body, options, headers);
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
+	setupCommon(policy_id, url, body, options, headers);
 	mReqMethod = HOR_PUT;
 	
 	return HttpStatus();
@@ -363,12 +368,12 @@ HttpStatus HttpOpRequest::setupPut(HttpRequest::policy_t policy_id,
 
 
 HttpStatus HttpOpRequest::setupDelete(HttpRequest::policy_t policy_id,
-    HttpRequest::priority_t priority,
     const std::string & url,
     const HttpOptions::ptr_t & options,
     const HttpHeaders::ptr_t & headers)
 {
-    setupCommon(policy_id, priority, url, NULL, options, headers);
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
+    setupCommon(policy_id, url, NULL, options, headers);
     mReqMethod = HOR_DELETE;
 
     return HttpStatus();
@@ -376,13 +381,13 @@ HttpStatus HttpOpRequest::setupDelete(HttpRequest::policy_t policy_id,
 
 
 HttpStatus HttpOpRequest::setupPatch(HttpRequest::policy_t policy_id,
-    HttpRequest::priority_t priority,
     const std::string & url,
     BufferArray * body,
     const HttpOptions::ptr_t & options,
     const HttpHeaders::ptr_t & headers)
 {
-    setupCommon(policy_id, priority, url, body, options, headers);
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
+    setupCommon(policy_id, url, body, options, headers);
     mReqMethod = HOR_PATCH;
 
     return HttpStatus();
@@ -390,12 +395,12 @@ HttpStatus HttpOpRequest::setupPatch(HttpRequest::policy_t policy_id,
 
 
 HttpStatus HttpOpRequest::setupCopy(HttpRequest::policy_t policy_id,
-    HttpRequest::priority_t priority,
     const std::string & url,
     const HttpOptions::ptr_t & options,
     const HttpHeaders::ptr_t &headers)
 {
-    setupCommon(policy_id, priority, url, NULL, options, headers);
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
+    setupCommon(policy_id, url, NULL, options, headers);
     mReqMethod = HOR_COPY;
 
     return HttpStatus();
@@ -403,12 +408,12 @@ HttpStatus HttpOpRequest::setupCopy(HttpRequest::policy_t policy_id,
 
 
 HttpStatus HttpOpRequest::setupMove(HttpRequest::policy_t policy_id,
-    HttpRequest::priority_t priority,
     const std::string & url,
     const HttpOptions::ptr_t & options,
     const HttpHeaders::ptr_t &headers)
 {
-    setupCommon(policy_id, priority, url, NULL, options, headers);
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
+    setupCommon(policy_id, url, NULL, options, headers);
     mReqMethod = HOR_MOVE;
 
     return HttpStatus();
@@ -416,15 +421,14 @@ HttpStatus HttpOpRequest::setupMove(HttpRequest::policy_t policy_id,
 
 
 void HttpOpRequest::setupCommon(HttpRequest::policy_t policy_id,
-								HttpRequest::priority_t priority,
 								const std::string & url,
 								BufferArray * body,
                                 const HttpOptions::ptr_t & options,
 								const HttpHeaders::ptr_t & headers)
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
 	mProcFlags = 0U;
 	mReqPolicy = policy_id;
-	mReqPriority = priority;
 	mReqURL = url;
 	if (body)
 	{
@@ -465,6 +469,7 @@ void HttpOpRequest::setupCommon(HttpRequest::policy_t policy_id,
 // *TODO:  Move this to _httplibcurl where it belongs.
 HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
 	// Scrub transport and result data for retried op case
 	mCurlActive = false;
 	mCurlHandle = NULL;
@@ -773,6 +778,7 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
 
 size_t HttpOpRequest::writeCallback(void * data, size_t size, size_t nmemb, void * userdata)
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
     HttpOpRequest::ptr_t op(HttpOpRequest::fromHandle<HttpOpRequest>(userdata));
 
 	if (! op->mReplyBody)
@@ -788,6 +794,7 @@ size_t HttpOpRequest::writeCallback(void * data, size_t size, size_t nmemb, void
 		
 size_t HttpOpRequest::readCallback(void * data, size_t size, size_t nmemb, void * userdata)
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
     HttpOpRequest::ptr_t op(HttpOpRequest::fromHandle<HttpOpRequest>(userdata));
 
 	if (! op->mReqBody)
@@ -819,6 +826,7 @@ size_t HttpOpRequest::readCallback(void * data, size_t size, size_t nmemb, void
 
 int HttpOpRequest::seekCallback(void *userdata, curl_off_t offset, int origin)
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
     HttpOpRequest::ptr_t op(HttpOpRequest::fromHandle<HttpOpRequest>(userdata));
 
     if (!op->mReqBody)
@@ -850,6 +858,7 @@ int HttpOpRequest::seekCallback(void *userdata, curl_off_t offset, int origin)
 		
 size_t HttpOpRequest::headerCallback(void * data, size_t size, size_t nmemb, void * userdata)
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
 	static const char status_line[] = "HTTP/";
 	static const size_t status_line_len = sizeof(status_line) - 1;
 	static const char con_ran_line[] = "content-range";
@@ -999,6 +1008,7 @@ size_t HttpOpRequest::headerCallback(void * data, size_t size, size_t nmemb, voi
 
 CURLcode HttpOpRequest::curlSslCtxCallback(CURL *curl, void *sslctx, void *userdata)
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
     HttpOpRequest::ptr_t op(HttpOpRequest::fromHandle<HttpOpRequest>(userdata));
 
     if (op->mCallbackSSLVerify)
@@ -1025,6 +1035,7 @@ CURLcode HttpOpRequest::curlSslCtxCallback(CURL *curl, void *sslctx, void *userd
 
 int HttpOpRequest::sslCertVerifyCallback(X509_STORE_CTX *ctx, void *param)
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
     HttpOpRequest::ptr_t op(HttpOpRequest::fromHandle<HttpOpRequest>(param));
 
 	if (op->mCallbackSSLVerify)
@@ -1037,6 +1048,7 @@ int HttpOpRequest::sslCertVerifyCallback(X509_STORE_CTX *ctx, void *param)
 
 int HttpOpRequest::debugCallback(CURL * handle, curl_infotype info, char * buffer, size_t len, void * userdata)
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
     HttpOpRequest::ptr_t op(HttpOpRequest::fromHandle<HttpOpRequest>(userdata));
 
 	std::string safe_line;
diff --git a/indra/llcorehttp/_httpoprequest.h b/indra/llcorehttp/_httpoprequest.h
index cdbe3507853..ec84822cf46 100644
--- a/indra/llcorehttp/_httpoprequest.h
+++ b/indra/llcorehttp/_httpoprequest.h
@@ -105,13 +105,11 @@ class HttpOpRequest : public HttpOperation
 	/// Threading:  called by application thread
 	///
 	HttpStatus setupGet(HttpRequest::policy_t policy_id,
-						HttpRequest::priority_t priority,
 						const std::string & url,
 						const HttpOptions::ptr_t & options,
 						const HttpHeaders::ptr_t & headers);
 	
 	HttpStatus setupGetByteRange(HttpRequest::policy_t policy_id,
-								 HttpRequest::priority_t priority,
 								 const std::string & url,
 								 size_t offset,
 								 size_t len,
@@ -119,40 +117,34 @@ class HttpOpRequest : public HttpOperation
 								 const HttpHeaders::ptr_t & headers);
 	
 	HttpStatus setupPost(HttpRequest::policy_t policy_id,
-						 HttpRequest::priority_t priority,
 						 const std::string & url,
 						 BufferArray * body,
                          const HttpOptions::ptr_t & options,
 						 const HttpHeaders::ptr_t & headers);
 	
 	HttpStatus setupPut(HttpRequest::policy_t policy_id,
-						HttpRequest::priority_t priority,
 						const std::string & url,
 						BufferArray * body,
                         const HttpOptions::ptr_t & options,
 						const HttpHeaders::ptr_t & headers);
 
     HttpStatus setupDelete(HttpRequest::policy_t policy_id,
-                        HttpRequest::priority_t priority,
                         const std::string & url,
                         const HttpOptions::ptr_t & options,
                         const HttpHeaders::ptr_t & headers);
 
     HttpStatus setupPatch(HttpRequest::policy_t policy_id,
-                        HttpRequest::priority_t priority,
                         const std::string & url,
                         BufferArray * body,
                         const HttpOptions::ptr_t & options,
                         const HttpHeaders::ptr_t & headers);
 
     HttpStatus setupCopy(HttpRequest::policy_t policy_id,
-                        HttpRequest::priority_t priority,
                         const std::string & url,
                         const HttpOptions::ptr_t & options,
                         const HttpHeaders::ptr_t & headers);
 
     HttpStatus setupMove(HttpRequest::policy_t policy_id,
-                        HttpRequest::priority_t priority,
                         const std::string & url,
                         const HttpOptions::ptr_t & options,
                         const HttpHeaders::ptr_t & headers);
@@ -172,7 +164,6 @@ class HttpOpRequest : public HttpOperation
 	// Threading:  called by application thread
 	//
 	void setupCommon(HttpRequest::policy_t policy_id,
-					 HttpRequest::priority_t priority,
 					 const std::string & url,
 					 BufferArray * body,
                      const HttpOptions::ptr_t & options,
@@ -239,19 +230,6 @@ class HttpOpRequest : public HttpOperation
 
 
 
-/// HttpOpRequestCompare isn't an operation but a uniform comparison
-/// functor for STL containers that order by priority.  Mainly
-/// used for the ready queue container but defined here.
-class HttpOpRequestCompare
-{
-public:
-	bool operator()(const HttpOpRequest * lhs, const HttpOpRequest * rhs)
-		{
-			return lhs->mReqPriority > rhs->mReqPriority;
-		}
-};  // end class HttpOpRequestCompare
-
-
 // ---------------------------------------
 // Free functions
 // ---------------------------------------
diff --git a/indra/llcorehttp/_httpopsetpriority.cpp b/indra/llcorehttp/_httpopsetpriority.cpp
index d48c7a0b7d6..b99b4e9e4a0 100644
--- a/indra/llcorehttp/_httpopsetpriority.cpp
+++ b/indra/llcorehttp/_httpopsetpriority.cpp
@@ -24,6 +24,7 @@
  * $/LicenseInfo$
  */
 
+#if 0 // DEPRECATED
 #include "_httpopsetpriority.h"
 
 #include "httpresponse.h"
@@ -61,3 +62,5 @@ void HttpOpSetPriority::stageFromRequest(HttpService * service)
 
 
 }   // end namespace LLCore
+
+#endif
diff --git a/indra/llcorehttp/_httpopsetpriority.h b/indra/llcorehttp/_httpopsetpriority.h
index 43e2aa081b2..fd543f37ccb 100644
--- a/indra/llcorehttp/_httpopsetpriority.h
+++ b/indra/llcorehttp/_httpopsetpriority.h
@@ -27,7 +27,7 @@
 #ifndef	_LLCORE_HTTP_SETPRIORITY_H_
 #define	_LLCORE_HTTP_SETPRIORITY_H_
 
-
+#if 0 // DEPRECATED
 #include "httpcommon.h"
 #include "httprequest.h"
 #include "_httpoperation.h"
@@ -49,7 +49,7 @@ namespace LLCore
 class HttpOpSetPriority : public HttpOperation
 {
 public:
-	HttpOpSetPriority(HttpHandle handle, HttpRequest::priority_t priority);
+	HttpOpSetPriority(HttpHandle handle);
 
 	virtual ~HttpOpSetPriority();
 
@@ -63,10 +63,10 @@ class HttpOpSetPriority : public HttpOperation
 protected:
 	// Request Data
 	HttpHandle					mHandle;
-	HttpRequest::priority_t		mPriority;
 }; // end class HttpOpSetPriority
 
 }  // end namespace LLCore
+#endif
 
 #endif	// _LLCORE_HTTP_SETPRIORITY_H_
 
diff --git a/indra/llcorehttp/_httppolicy.cpp b/indra/llcorehttp/_httppolicy.cpp
index 885f0ed61d6..29f50c16939 100644
--- a/indra/llcorehttp/_httppolicy.cpp
+++ b/indra/llcorehttp/_httppolicy.cpp
@@ -330,37 +330,6 @@ HttpService::ELoopSpeed HttpPolicy::processReadyQueue()
 	return result;
 }
 
-
-bool HttpPolicy::changePriority(HttpHandle handle, HttpRequest::priority_t priority)
-{
-	for (int policy_class(0); policy_class < mClasses.size(); ++policy_class)
-	{
-		ClassState & state(*mClasses[policy_class]);
-		// We don't scan retry queue because a priority change there
-		// is meaningless.  The request will be issued based on retry
-		// intervals not priority value, which is now moot.
-		
-		// Scan ready queue for requests that match policy
-		HttpReadyQueue::container_type & c(state.mReadyQueue.get_container());
-		for (HttpReadyQueue::container_type::iterator iter(c.begin()); c.end() != iter;)
-		{
-			HttpReadyQueue::container_type::iterator cur(iter++);
-
-			if ((*cur)->getHandle() == handle)
-			{
-				HttpOpRequest::ptr_t op(*cur);
-				c.erase(cur);									// All iterators are now invalidated
-				op->mReqPriority = priority;
-				state.mReadyQueue.push(op);						// Re-insert using adapter class
-				return true;
-			}
-		}
-	}
-	
-	return false;
-}
-
-
 bool HttpPolicy::cancel(HttpHandle handle)
 {
 	for (int policy_class(0); policy_class < mClasses.size(); ++policy_class)
diff --git a/indra/llcorehttp/_httppolicy.h b/indra/llcorehttp/_httppolicy.h
index 3c4126e14bb..0b8806a3e2f 100644
--- a/indra/llcorehttp/_httppolicy.h
+++ b/indra/llcorehttp/_httppolicy.h
@@ -110,12 +110,6 @@ class HttpPolicy
 	/// Threading:  called by worker thread
     void retryOp(const opReqPtr_t &);
 
-	/// Attempt to change the priority of an earlier request.
-	/// Request that Shadows HttpService's method
-	///
-	/// Threading:  called by worker thread
-	bool changePriority(HttpHandle handle, HttpRequest::priority_t priority);
-
 	/// Attempt to cancel a previous request.
 	/// Shadows HttpService's method as well
 	///
diff --git a/indra/llcorehttp/_httpservice.cpp b/indra/llcorehttp/_httpservice.cpp
index 56f52f1b091..294acd7f638 100644
--- a/indra/llcorehttp/_httpservice.cpp
+++ b/indra/llcorehttp/_httpservice.cpp
@@ -80,6 +80,7 @@ HttpService::HttpService()
 
 HttpService::~HttpService()
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
 	mExitRequested = 1U;
 	if (RUNNING == sState)
 	{
@@ -131,6 +132,7 @@ HttpService::~HttpService()
 
 void HttpService::init(HttpRequestQueue * queue)
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
 	llassert_always(! sInstance);
 	llassert_always(NOT_INITIALIZED == sState);
 	sInstance = new HttpService();
@@ -145,6 +147,7 @@ void HttpService::init(HttpRequestQueue * queue)
 
 void HttpService::term()
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
 	if (sInstance)
 	{
 		if (RUNNING == sState && sInstance->mThread)
@@ -196,6 +199,7 @@ bool HttpService::isStopped()
 /// Threading:  callable by consumer thread *once*.
 void HttpService::startThread()
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
 	llassert_always(! mThread || STOPPED == sState);
 	llassert_always(INITIALIZED == sState || STOPPED == sState);
 
@@ -220,22 +224,6 @@ void HttpService::stopRequested()
 }
 
 
-/// Threading:  callable by worker thread.
-bool HttpService::changePriority(HttpHandle handle, HttpRequest::priority_t priority)
-{
-	bool found(false);
-
-	// Skip the request queue as we currently don't leave earlier
-	// requests sitting there.  Start with the ready queue...
-	found = mPolicy->changePriority(handle, priority);
-
-	// If not there, we could try the transport/active queue but priority
-	// doesn't really have much effect there so we don't waste cycles.
-	
-	return found;
-}
-
-
 /// Try to find the given request handle on any of the request
 /// queues and cancel the operation.
 ///
@@ -244,6 +232,7 @@ bool HttpService::changePriority(HttpHandle handle, HttpRequest::priority_t prio
 /// Threading:  callable by worker thread.
 bool HttpService::cancel(HttpHandle handle)
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
 	bool canceled(false);
 
 	// Request can't be on request queue so skip that.
@@ -264,6 +253,7 @@ bool HttpService::cancel(HttpHandle handle)
 /// Threading:  callable by worker thread.
 void HttpService::shutdown()
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
 	// Disallow future enqueue of requests
 	mRequestQueue->stopQueue();
 
@@ -293,6 +283,8 @@ void HttpService::shutdown()
 // requested to stop.
 void HttpService::threadRun(LLCoreInt::HttpThread * thread)
 {
+    LL_PROFILER_SET_THREAD_NAME("HttpService");
+
 	boost::this_thread::disable_interruption di;
 
 	LLThread::registerThreadID();
@@ -300,6 +292,7 @@ void HttpService::threadRun(LLCoreInt::HttpThread * thread)
 	ELoopSpeed loop(REQUEST_SLEEP);
 	while (! mExitRequested)
 	{
+        LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
         try
         {
 		    loop = processRequestQueue(loop);
@@ -344,6 +337,7 @@ void HttpService::threadRun(LLCoreInt::HttpThread * thread)
 
 HttpService::ELoopSpeed HttpService::processRequestQueue(ELoopSpeed loop)
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
 	HttpRequestQueue::OpContainer ops;
 	const bool wait_for_req(REQUEST_SLEEP == loop);
 	
@@ -384,6 +378,7 @@ HttpService::ELoopSpeed HttpService::processRequestQueue(ELoopSpeed loop)
 HttpStatus HttpService::getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass,
 										long * ret_value)
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
 	if (opt < HttpRequest::PO_CONNECTION_LIMIT											// option must be in range
 		|| opt >= HttpRequest::PO_LAST													// ditto
 		|| (! sOptionDesc[opt].mIsLong)													// datatype is long
@@ -416,6 +411,7 @@ HttpStatus HttpService::getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequ
 HttpStatus HttpService::getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass,
 										std::string * ret_value)
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
 	HttpStatus status(HttpStatus::LLCORE, LLCore::HE_INVALID_ARG);
 
 	if (opt < HttpRequest::PO_CONNECTION_LIMIT											// option must be in range
@@ -443,6 +439,7 @@ HttpStatus HttpService::getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequ
 HttpStatus HttpService::getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass,
 	HttpRequest::policyCallback_t * ret_value)
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
 	HttpStatus status(HttpStatus::LLCORE, LLCore::HE_INVALID_ARG);
 
 	if (opt < HttpRequest::PO_CONNECTION_LIMIT											// option must be in range
@@ -472,6 +469,7 @@ HttpStatus HttpService::getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequ
 HttpStatus HttpService::setPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass,
 										long value, long * ret_value)
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
 	HttpStatus status(HttpStatus::LLCORE, LLCore::HE_INVALID_ARG);
 	
 	if (opt < HttpRequest::PO_CONNECTION_LIMIT											// option must be in range
@@ -517,6 +515,7 @@ HttpStatus HttpService::setPolicyOption(HttpRequest::EPolicyOption opt, HttpRequ
 HttpStatus HttpService::setPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass,
 										const std::string & value, std::string * ret_value)
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
 	HttpStatus status(HttpStatus::LLCORE, LLCore::HE_INVALID_ARG);
 	
 	if (opt < HttpRequest::PO_CONNECTION_LIMIT											// option must be in range
@@ -548,6 +547,7 @@ HttpStatus HttpService::setPolicyOption(HttpRequest::EPolicyOption opt, HttpRequ
 HttpStatus HttpService::setPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass,
 	HttpRequest::policyCallback_t value, HttpRequest::policyCallback_t * ret_value)
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
 	HttpStatus status(HttpStatus::LLCORE, LLCore::HE_INVALID_ARG);
 
 	if (opt < HttpRequest::PO_CONNECTION_LIMIT											// option must be in range
diff --git a/indra/llcorehttp/_httpservice.h b/indra/llcorehttp/_httpservice.h
index d0c37ac1956..551a718f20b 100644
--- a/indra/llcorehttp/_httpservice.h
+++ b/indra/llcorehttp/_httpservice.h
@@ -146,15 +146,6 @@ class HttpService
 	/// Threading:  callable by worker thread.
 	void shutdown();
 
-	/// Try to find the given request handle on any of the request
-	/// queues and reset the priority (and queue position) of the
-	/// request if found.
-	///
-	/// @return			True if the request was found somewhere.
-	///
-	/// Threading:  callable by worker thread.
-	bool changePriority(HttpHandle handle, HttpRequest::priority_t priority);
-	
 	/// Try to find the given request handle on any of the request
 	/// queues and cancel the operation.
 	///
diff --git a/indra/llcorehttp/httprequest.cpp b/indra/llcorehttp/httprequest.cpp
index 2687f772176..de3854a101b 100644
--- a/indra/llcorehttp/httprequest.cpp
+++ b/indra/llcorehttp/httprequest.cpp
@@ -32,7 +32,6 @@
 #include "_httppolicy.h"
 #include "_httpoperation.h"
 #include "_httpoprequest.h"
-#include "_httpopsetpriority.h"
 #include "_httpopcancel.h"
 #include "_httpopsetget.h"
 
@@ -183,16 +182,16 @@ HttpStatus HttpRequest::getStatus() const
 
 
 HttpHandle HttpRequest::requestGet(policy_t policy_id,
-								   priority_t priority,
 								   const std::string & url,
                                    const HttpOptions::ptr_t & options,
 								   const HttpHeaders::ptr_t & headers,
 								   HttpHandler::ptr_t user_handler)
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
 	HttpStatus status;
 
 	HttpOpRequest::ptr_t op(new HttpOpRequest());
-	if (! (status = op->setupGet(policy_id, priority, url, options, headers)))
+	if (! (status = op->setupGet(policy_id, url, options, headers)))
 	{
 		mLastReqStatus = status;
         return LLCORE_HTTP_HANDLE_INVALID;
@@ -210,7 +209,6 @@ HttpHandle HttpRequest::requestGet(policy_t policy_id,
 
 
 HttpHandle HttpRequest::requestGetByteRange(policy_t policy_id,
-											priority_t priority,
 											const std::string & url,
 											size_t offset,
 											size_t len,
@@ -218,10 +216,11 @@ HttpHandle HttpRequest::requestGetByteRange(policy_t policy_id,
 											const HttpHeaders::ptr_t & headers,
 											HttpHandler::ptr_t user_handler)
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
 	HttpStatus status;
 
 	HttpOpRequest::ptr_t op(new HttpOpRequest());
-	if (! (status = op->setupGetByteRange(policy_id, priority, url, offset, len, options, headers)))
+	if (! (status = op->setupGetByteRange(policy_id, url, offset, len, options, headers)))
 	{
 		mLastReqStatus = status;
         return LLCORE_HTTP_HANDLE_INVALID;
@@ -239,7 +238,6 @@ HttpHandle HttpRequest::requestGetByteRange(policy_t policy_id,
 
 
 HttpHandle HttpRequest::requestPost(policy_t policy_id,
-									priority_t priority,
 									const std::string & url,
 									BufferArray * body,
                                     const HttpOptions::ptr_t & options,
@@ -249,7 +247,7 @@ HttpHandle HttpRequest::requestPost(policy_t policy_id,
 	HttpStatus status;
 
 	HttpOpRequest::ptr_t op(new HttpOpRequest());
-	if (! (status = op->setupPost(policy_id, priority, url, body, options, headers)))
+	if (! (status = op->setupPost(policy_id, url, body, options, headers)))
 	{
 		mLastReqStatus = status;
         return LLCORE_HTTP_HANDLE_INVALID;
@@ -267,7 +265,6 @@ HttpHandle HttpRequest::requestPost(policy_t policy_id,
 
 
 HttpHandle HttpRequest::requestPut(policy_t policy_id,
-								   priority_t priority,
 								   const std::string & url,
 								   BufferArray * body,
                                    const HttpOptions::ptr_t & options,
@@ -277,7 +274,7 @@ HttpHandle HttpRequest::requestPut(policy_t policy_id,
 	HttpStatus status;
 
 	HttpOpRequest::ptr_t op (new HttpOpRequest());
-	if (! (status = op->setupPut(policy_id, priority, url, body, options, headers)))
+	if (! (status = op->setupPut(policy_id, url, body, options, headers)))
 	{
 		mLastReqStatus = status;
         return LLCORE_HTTP_HANDLE_INVALID;
@@ -294,7 +291,6 @@ HttpHandle HttpRequest::requestPut(policy_t policy_id,
 }
 
 HttpHandle HttpRequest::requestDelete(policy_t policy_id,
-    priority_t priority,
     const std::string & url,
     const HttpOptions::ptr_t & options,
     const HttpHeaders::ptr_t & headers,
@@ -303,7 +299,7 @@ HttpHandle HttpRequest::requestDelete(policy_t policy_id,
     HttpStatus status;
 
     HttpOpRequest::ptr_t op(new HttpOpRequest());
-    if (!(status = op->setupDelete(policy_id, priority, url, options, headers)))
+    if (!(status = op->setupDelete(policy_id, url, options, headers)))
     {
         mLastReqStatus = status;
         return LLCORE_HTTP_HANDLE_INVALID;
@@ -320,7 +316,6 @@ HttpHandle HttpRequest::requestDelete(policy_t policy_id,
 }
 
 HttpHandle HttpRequest::requestPatch(policy_t policy_id,
-    priority_t priority,
     const std::string & url,
     BufferArray * body,
     const HttpOptions::ptr_t & options,
@@ -330,7 +325,7 @@ HttpHandle HttpRequest::requestPatch(policy_t policy_id,
     HttpStatus status;
 
     HttpOpRequest::ptr_t op (new HttpOpRequest());
-    if (!(status = op->setupPatch(policy_id, priority, url, body, options, headers)))
+    if (!(status = op->setupPatch(policy_id, url, body, options, headers)))
     {
         mLastReqStatus = status;
         return LLCORE_HTTP_HANDLE_INVALID;
@@ -347,7 +342,6 @@ HttpHandle HttpRequest::requestPatch(policy_t policy_id,
 }
 
 HttpHandle HttpRequest::requestCopy(policy_t policy_id,
-    priority_t priority,
     const std::string & url,
     const HttpOptions::ptr_t & options,
     const HttpHeaders::ptr_t & headers,
@@ -356,7 +350,7 @@ HttpHandle HttpRequest::requestCopy(policy_t policy_id,
     HttpStatus status;
 
     HttpOpRequest::ptr_t op(new HttpOpRequest());
-    if (!(status = op->setupCopy(policy_id, priority, url, options, headers)))
+    if (!(status = op->setupCopy(policy_id, url, options, headers)))
     {
         mLastReqStatus = status;
         return LLCORE_HTTP_HANDLE_INVALID;
@@ -374,7 +368,6 @@ HttpHandle HttpRequest::requestCopy(policy_t policy_id,
 }
 
 HttpHandle HttpRequest::requestMove(policy_t policy_id,
-    priority_t priority,
     const std::string & url,
     const HttpOptions::ptr_t & options,
     const HttpHeaders::ptr_t & headers,
@@ -383,7 +376,7 @@ HttpHandle HttpRequest::requestMove(policy_t policy_id,
     HttpStatus status;
 
     HttpOpRequest::ptr_t op (new HttpOpRequest());
-    if (!(status = op->setupMove(policy_id, priority, url, options, headers)))
+    if (!(status = op->setupMove(policy_id, url, options, headers)))
     {
         mLastReqStatus = status;
         return LLCORE_HTTP_HANDLE_INVALID;
@@ -483,24 +476,6 @@ HttpHandle HttpRequest::requestCancel(HttpHandle request, HttpHandler::ptr_t use
 }
 
 
-HttpHandle HttpRequest::requestSetPriority(HttpHandle request, priority_t priority,
-										   HttpHandler::ptr_t handler)
-{
-	HttpStatus status;
-
-	HttpOperation::ptr_t op (new HttpOpSetPriority(request, priority));
-	op->setReplyPath(mReplyQueue, handler);
-	if (! (status = mRequestQueue->addOp(op)))			// transfers refcount
-	{
-		mLastReqStatus = status;
-        return LLCORE_HTTP_HANDLE_INVALID;
-	}
-
-	mLastReqStatus = status;
-	return op->getHandle();
-}
-
-
 // ====================================
 // Utility Methods
 // ====================================
diff --git a/indra/llcorehttp/httprequest.h b/indra/llcorehttp/httprequest.h
index a418eb6a7ad..ca4b9e92bca 100644
--- a/indra/llcorehttp/httprequest.h
+++ b/indra/llcorehttp/httprequest.h
@@ -95,7 +95,6 @@ class HttpRequest
 
 public:
 	typedef unsigned int policy_t;
-	typedef unsigned int priority_t;
 	
 	typedef boost::shared_ptr<HttpRequest> ptr_t;
     typedef boost::weak_ptr<HttpRequest>   wptr_t;
@@ -316,8 +315,6 @@ class HttpRequest
 	///
 	/// @param	policy_id		Default or user-defined policy class under
 	///							which this request is to be serviced.
-	/// @param	priority		Standard priority scheme inherited from
-	///							Indra code base (U32-type scheme).
 	/// @param	url				URL with any encoded query parameters to
 	///							be accessed.
 	/// @param	options			Optional instance of an HttpOptions object
@@ -346,7 +343,6 @@ class HttpRequest
 	///							case, @see getStatus() will return more info.
 	///
 	HttpHandle requestGet(policy_t policy_id,
-						  priority_t priority,
 						  const std::string & url,
                           const HttpOptions::ptr_t & options,
 						  const HttpHeaders::ptr_t & headers,
@@ -377,7 +373,6 @@ class HttpRequest
 	/// - Referer:
 	///
 	/// @param	policy_id		@see requestGet()
-	/// @param	priority		"
 	/// @param	url				"
 	/// @param	offset			Offset of first byte into resource to be returned.
 	/// @param	len				Count of bytes to be returned
@@ -387,7 +382,6 @@ class HttpRequest
 	/// @return					"
 	///
 	HttpHandle requestGetByteRange(policy_t policy_id,
-								   priority_t priority,
 								   const std::string & url,
 								   size_t offset,
 								   size_t len,
@@ -418,7 +412,6 @@ class HttpRequest
 	/// - Expect:
 	///
 	/// @param	policy_id		@see requestGet()
-	/// @param	priority		"
 	/// @param	url				"
 	/// @param	body			Byte stream to be sent as the body.  No
 	///							further encoding or escaping will be done
@@ -429,7 +422,6 @@ class HttpRequest
 	/// @return					"
 	///
 	HttpHandle requestPost(policy_t policy_id,
-						   priority_t priority,
 						   const std::string & url,
 						   BufferArray * body,
                            const HttpOptions::ptr_t & options,
@@ -459,7 +451,6 @@ class HttpRequest
 	/// - Content-Type:
 	///
 	/// @param	policy_id		@see requestGet()
-	/// @param	priority		"
 	/// @param	url				"
 	/// @param	body			Byte stream to be sent as the body.  No
 	///							further encoding or escaping will be done
@@ -470,7 +461,6 @@ class HttpRequest
 	/// @return					"
 	///
 	HttpHandle requestPut(policy_t policy_id,
-						  priority_t priority,
 						  const std::string & url,
 						  BufferArray * body,
                           const HttpOptions::ptr_t & options,
@@ -483,7 +473,6 @@ class HttpRequest
     /// encoding and communicating the content types.
     ///
     /// @param	policy_id		@see requestGet()
-    /// @param	priority		"
     /// @param	url				"
     /// @param	options			@see requestGet()K(optional)
     /// @param	headers			"
@@ -491,7 +480,6 @@ class HttpRequest
     /// @return					"
     ///
     HttpHandle requestDelete(policy_t policy_id,
-            priority_t priority,
             const std::string & url,
             const HttpOptions::ptr_t & options,
             const HttpHeaders::ptr_t & headers,
@@ -502,7 +490,6 @@ class HttpRequest
     /// encoding and communicating the content types.
     ///
     /// @param	policy_id		@see requestGet()
-    /// @param	priority		"
     /// @param	url				"
     /// @param	body			Byte stream to be sent as the body.  No
     ///							further encoding or escaping will be done
@@ -513,7 +500,6 @@ class HttpRequest
     /// @return					"
     ///
     HttpHandle requestPatch(policy_t policy_id,
-            priority_t priority,
             const std::string & url,
             BufferArray * body,
             const HttpOptions::ptr_t & options,
@@ -525,7 +511,6 @@ class HttpRequest
     /// encoding and communicating the content types.
     ///
     /// @param	policy_id		@see requestGet()
-    /// @param	priority		"
     /// @param	url				"
     /// @param	options			@see requestGet()K(optional)
     /// @param	headers			"
@@ -533,7 +518,6 @@ class HttpRequest
     /// @return					"
     ///
     HttpHandle requestCopy(policy_t policy_id,
-            priority_t priority,
             const std::string & url,
             const HttpOptions::ptr_t & options,
             const HttpHeaders::ptr_t & headers,
@@ -544,7 +528,6 @@ class HttpRequest
     /// encoding and communicating the content types.
     ///
     /// @param	policy_id		@see requestGet()
-    /// @param	priority		"
     /// @param	url				"
     /// @param	options			@see requestGet()K(optional)
     /// @param	headers			"
@@ -552,7 +535,6 @@ class HttpRequest
     /// @return					"
     ///
     HttpHandle requestMove(policy_t policy_id,
-            priority_t priority,
             const std::string & url,
             const HttpOptions::ptr_t & options,
             const HttpHeaders::ptr_t & headers,
@@ -593,18 +575,6 @@ class HttpRequest
 	
 	HttpHandle requestCancel(HttpHandle request, HttpHandler::ptr_t);
 
-	/// Request that a previously-issued request be reprioritized.
-	/// The status of whether the change itself succeeded arrives
-	/// via notification.  
-	///
-	/// @param	request			Handle of previously-issued request to
-	///							be changed.
-	/// @param	priority		New priority value.
-	/// @param	handler			@see requestGet()
-	/// @return					"
-	///
-	HttpHandle requestSetPriority(HttpHandle request, priority_t priority, HttpHandler::ptr_t handler);
-
 	/// @}
 
 	/// @name UtilityMethods
diff --git a/indra/llfilesystem/lllfsthread.cpp b/indra/llfilesystem/lllfsthread.cpp
index be8e83a56f0..944e981ecff 100644
--- a/indra/llfilesystem/lllfsthread.cpp
+++ b/indra/llfilesystem/lllfsthread.cpp
@@ -65,8 +65,7 @@ void LLLFSThread::cleanupClass()
 //----------------------------------------------------------------------------
 
 LLLFSThread::LLLFSThread(bool threaded) :
-	LLQueuedThread("LFS", threaded),
-	mPriorityCounter(PRIORITY_LOWBITS)
+	LLQueuedThread("LFS", threaded)
 {
 	if(!mLocalAPRFilePoolp)
 	{
@@ -84,14 +83,12 @@ LLLFSThread::~LLLFSThread()
 
 LLLFSThread::handle_t LLLFSThread::read(const std::string& filename,	/* Flawfinder: ignore */ 
 										U8* buffer, S32 offset, S32 numbytes,
-										Responder* responder, U32 priority)
+										Responder* responder)
 {
+    LL_PROFILE_ZONE_SCOPED;
 	handle_t handle = generateHandle();
 
-	if (priority == 0) priority = PRIORITY_NORMAL | priorityCounter();
-	else if (priority < PRIORITY_LOW) priority |= PRIORITY_LOW; // All reads are at least PRIORITY_LOW
-
-	Request* req = new Request(this, handle, priority,
+	Request* req = new Request(this, handle,
 							   FILE_READ, filename,
 							   buffer, offset, numbytes,
 							   responder);
@@ -107,13 +104,12 @@ LLLFSThread::handle_t LLLFSThread::read(const std::string& filename,	/* Flawfind
 
 LLLFSThread::handle_t LLLFSThread::write(const std::string& filename,
 										 U8* buffer, S32 offset, S32 numbytes,
-										 Responder* responder, U32 priority)
+										 Responder* responder)
 {
+    LL_PROFILE_ZONE_SCOPED;
 	handle_t handle = generateHandle();
 
-	if (priority == 0) priority = PRIORITY_LOW | priorityCounter();
-	
-	Request* req = new Request(this, handle, priority,
+	Request* req = new Request(this, handle,
 							   FILE_WRITE, filename,
 							   buffer, offset, numbytes,
 							   responder);
@@ -130,11 +126,11 @@ LLLFSThread::handle_t LLLFSThread::write(const std::string& filename,
 //============================================================================
 
 LLLFSThread::Request::Request(LLLFSThread* thread,
-							  handle_t handle, U32 priority,
+							  handle_t handle,
 							  operation_t op, const std::string& filename,
 							  U8* buffer, S32 offset, S32 numbytes,
 							  Responder* responder) :
-	QueuedRequest(handle, priority, FLAG_AUTO_COMPLETE),
+	QueuedRequest(handle, FLAG_AUTO_COMPLETE),
 	mThread(thread),
 	mOperation(op),
 	mFileName(filename),
@@ -157,6 +153,7 @@ LLLFSThread::Request::~Request()
 // virtual, called from own thread
 void LLLFSThread::Request::finishRequest(bool completed)
 {
+    LL_PROFILE_ZONE_SCOPED;
 	if (mResponder.notNull())
 	{
 		mResponder->completed(completed ? mBytesRead : 0);
@@ -166,6 +163,7 @@ void LLLFSThread::Request::finishRequest(bool completed)
 
 void LLLFSThread::Request::deleteRequest()
 {
+    LL_PROFILE_ZONE_SCOPED;
 	if (getStatus() == STATUS_QUEUED)
 	{
 		LL_ERRS() << "Attempt to delete a queued LLLFSThread::Request!" << LL_ENDL;
@@ -180,6 +178,7 @@ void LLLFSThread::Request::deleteRequest()
 
 bool LLLFSThread::Request::processRequest()
 {
+    LL_PROFILE_ZONE_SCOPED;
 	bool complete = false;
 	if (mOperation ==  FILE_READ)
 	{
diff --git a/indra/llfilesystem/lllfsthread.h b/indra/llfilesystem/lllfsthread.h
index 58f658f7bab..f2693a1172c 100644
--- a/indra/llfilesystem/lllfsthread.h
+++ b/indra/llfilesystem/lllfsthread.h
@@ -68,7 +68,7 @@ class LLLFSThread : public LLQueuedThread
 		
 	public:
 		Request(LLLFSThread* thread,
-				handle_t handle, U32 priority, 
+				handle_t handle,
 				operation_t op, const std::string& filename,
 				U8* buffer, S32 offset, S32 numbytes,
 				Responder* responder);
@@ -120,22 +120,15 @@ class LLLFSThread : public LLQueuedThread
 	// Return a Request handle
 	handle_t read(const std::string& filename,	/* Flawfinder: ignore */ 
 				  U8* buffer, S32 offset, S32 numbytes,
-				  Responder* responder, U32 pri=0);
+				  Responder* responder);
 	handle_t write(const std::string& filename,
 				   U8* buffer, S32 offset, S32 numbytes,
-				   Responder* responder, U32 pri=0);
-	
-	// Misc
-	U32 priorityCounter() { return mPriorityCounter-- & PRIORITY_LOWBITS; } // Use to order IO operations
+				   Responder* responder);
 	
 	// static initializers
 	static void initClass(bool local_is_threaded = TRUE); // Setup sLocal
 	static S32 updateClass(U32 ms_elapsed);
 	static void cleanupClass();		// Delete sLocal
-
-	
-private:
-	U32 mPriorityCounter;
 	
 public:
 	static LLLFSThread* sLocal;		// Default local file thread
diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp
index e1809dbe592..8dba1641a6d 100644
--- a/indra/llimage/llimagej2c.cpp
+++ b/indra/llimage/llimagej2c.cpp
@@ -146,6 +146,7 @@ bool LLImageJ2C::initEncode(LLImageRaw &raw_image, int blocks_size, int precinct
 
 bool LLImageJ2C::decode(LLImageRaw *raw_imagep, F32 decode_time)
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
 	return decodeChannels(raw_imagep, decode_time, 0, 4);
 }
 
@@ -153,6 +154,7 @@ bool LLImageJ2C::decode(LLImageRaw *raw_imagep, F32 decode_time)
 // Returns true to mean done, whether successful or not.
 bool LLImageJ2C::decodeChannels(LLImageRaw *raw_imagep, F32 decode_time, S32 first_channel, S32 max_channel_count )
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
 	LLTimer elapsed;
 
 	bool res = true;
diff --git a/indra/llimage/llimageworker.cpp b/indra/llimage/llimageworker.cpp
index 0dbb744bcf9..1aace5f3e83 100644
--- a/indra/llimage/llimageworker.cpp
+++ b/indra/llimage/llimageworker.cpp
@@ -49,33 +49,22 @@ LLImageDecodeThread::~LLImageDecodeThread()
 S32 LLImageDecodeThread::update(F32 max_time_ms)
 {
     LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
-	LLMutexLock lock(mCreationMutex);
-	for (creation_list_t::iterator iter = mCreationList.begin();
-		 iter != mCreationList.end(); ++iter)
-	{
-		creation_info& info = *iter;
-		ImageRequest* req = new ImageRequest(info.handle, info.image,
-						     info.priority, info.discard, info.needs_aux,
-						     info.responder);
-
-		bool res = addRequest(req);
-		if (!res)
-		{
-			LL_ERRS() << "request added after LLLFSThread::cleanupClass()" << LL_ENDL;
-		}
-	}
-	mCreationList.clear();
 	S32 res = LLQueuedThread::update(max_time_ms);
 	return res;
 }
 
 LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(LLImageFormatted* image, 
-	U32 priority, S32 discard, BOOL needs_aux, Responder* responder)
+	S32 discard, BOOL needs_aux, Responder* responder)
 {
     LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
-	LLMutexLock lock(mCreationMutex);
 	handle_t handle = generateHandle();
-	mCreationList.push_back(creation_info(handle, image, priority, discard, needs_aux, responder));
+
+    ImageRequest* req = new ImageRequest(handle, image,
+        discard, needs_aux,
+        responder);
+
+    addRequest(req);
+
 	return handle;
 }
 
@@ -84,8 +73,7 @@ LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(LLImageFormatted*
 S32 LLImageDecodeThread::tut_size()
 {
 	LLMutexLock lock(mCreationMutex);
-	S32 res = mCreationList.size();
-	return res;
+	return 0;
 }
 
 LLImageDecodeThread::Responder::~Responder()
@@ -95,9 +83,9 @@ LLImageDecodeThread::Responder::~Responder()
 //----------------------------------------------------------------------------
 
 LLImageDecodeThread::ImageRequest::ImageRequest(handle_t handle, LLImageFormatted* image, 
-												U32 priority, S32 discard, BOOL needs_aux,
+												S32 discard, BOOL needs_aux,
 												LLImageDecodeThread::Responder* responder)
-	: LLQueuedThread::QueuedRequest(handle, priority, FLAG_AUTO_COMPLETE),
+	: LLQueuedThread::QueuedRequest(handle, FLAG_AUTO_COMPLETE),
 	  mFormattedImage(image),
 	  mDiscardLevel(discard),
 	  mNeedsAux(needs_aux),
@@ -121,7 +109,7 @@ LLImageDecodeThread::ImageRequest::~ImageRequest()
 bool LLImageDecodeThread::ImageRequest::processRequest()
 {
     LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
-	const F32 decode_time_slice = .1f;
+	const F32 decode_time_slice = 0.f; //disable time slicing
 	bool done = true;
 	if (!mDecodedRaw && mFormattedImage.notNull())
 	{
diff --git a/indra/llimage/llimageworker.h b/indra/llimage/llimageworker.h
index 1bfb0ddfd3f..4619ddd6a28 100644
--- a/indra/llimage/llimageworker.h
+++ b/indra/llimage/llimageworker.h
@@ -49,7 +49,7 @@ class LLImageDecodeThread : public LLQueuedThread
 		
 	public:
 		ImageRequest(handle_t handle, LLImageFormatted* image,
-					 U32 priority, S32 discard, BOOL needs_aux,
+					 S32 discard, BOOL needs_aux,
 					 LLImageDecodeThread::Responder* responder);
 
 		/*virtual*/ bool processRequest();
@@ -76,7 +76,7 @@ class LLImageDecodeThread : public LLQueuedThread
 	virtual ~LLImageDecodeThread();
 
 	handle_t decodeImage(LLImageFormatted* image,
-						 U32 priority, S32 discard, BOOL needs_aux,
+						 S32 discard, BOOL needs_aux,
 						 Responder* responder);
 	S32 update(F32 max_time_ms);
 
@@ -88,16 +88,13 @@ class LLImageDecodeThread : public LLQueuedThread
 	{
 		handle_t handle;
 		LLPointer<LLImageFormatted> image;
-		U32 priority;
 		S32 discard;
 		BOOL needs_aux;
 		LLPointer<Responder> responder;
 		creation_info(handle_t h, LLImageFormatted* i, U32 p, S32 d, BOOL aux, Responder* r)
-			: handle(h), image(i), priority(p), discard(d), needs_aux(aux), responder(r)
+			: handle(h), image(i), discard(d), needs_aux(aux), responder(r)
 		{}
 	};
-	typedef std::list<creation_info> creation_list_t;
-	creation_list_t mCreationList;
 	LLMutex* mCreationMutex;
 };
 
diff --git a/indra/llimagej2coj/llimagej2coj.cpp b/indra/llimagej2coj/llimagej2coj.cpp
index 925da5674bf..8a641617fa4 100644
--- a/indra/llimagej2coj/llimagej2coj.cpp
+++ b/indra/llimagej2coj/llimagej2coj.cpp
@@ -118,6 +118,7 @@ bool LLImageJ2COJ::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int block
 
 bool LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count)
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
 	//
 	// FIXME: Get the comment field out of the texture
 	//
diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp
index dac5349f573..2ad42d6b879 100644
--- a/indra/llkdu/llimagej2ckdu.cpp
+++ b/indra/llkdu/llimagej2ckdu.cpp
@@ -379,6 +379,7 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, bool keep_codestream, ECod
 
 void LLImageJ2CKDU::cleanupCodeStream()
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
 	mInputp.reset();
 	mDecodeState.reset();
 	mCodeStreamp.reset();
@@ -426,6 +427,7 @@ bool LLImageJ2CKDU::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int bloc
 // decodeImpl() usage matters for production.
 bool LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, ECodeStreamMode mode, S32 first_channel, S32 max_channel_count, int discard_level, int* region)
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
 	base.resetLastError();
 
 	// *FIX: kdu calls our callback function if there's an error, and then bombs.
@@ -509,6 +511,7 @@ bool LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco
 // Returns true to mean done, whether successful or not.
 bool LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count)
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
 	ECodeStreamMode mode = MODE_FAST;
 
 	LLTimer decode_timer;
@@ -1332,6 +1335,7 @@ the `buf' pointer may actually point into a larger buffer representing
 multiple tiles.  For this reason, `row_gap' is needed to identify the
 separation between consecutive rows in the real buffer. */
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
 	S32 c;
 	// Now walk through the lines of the buffer, recovering them from the
 	// relevant tile-component processing engines.
@@ -1339,18 +1343,27 @@ separation between consecutive rows in the real buffer. */
 	LLTimer decode_timer;
 	while (mDims.size.y--)
 	{
-		for (c = 0; c < mNumComponents; c++)
-		{
-			mEngines[c].pull(mLines[c]);
-		}
+        {
+            LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("kduptc - pull");
+            for (c = 0; c < mNumComponents; c++)
+            {
+                mEngines[c].pull(mLines[c]);
+            }
+        }
+
 		if ((mNumComponents >= 3) && mUseYCC)
 		{
+            LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("kduptc - convert");
 			kdu_convert_ycc_to_rgb(mLines[0],mLines[1],mLines[2]);
 		}
-		for (c = 0; c < mNumComponents; c++)
-		{
-			transfer_bytes(mBuf+c,mLines[c],mNumComponents,mBitDepths[c]);
-		}
+
+        {
+            LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("kduptc - transfer");
+            for (c = 0; c < mNumComponents; c++)
+            {
+                transfer_bytes(mBuf + c, mLines[c], mNumComponents, mBitDepths[c]);
+            }
+        }
 		mBuf += mRowGap;
 		if (mDims.size.y % 10)
 		{
diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp
index c67f59bc0c3..ae066112c11 100644
--- a/indra/llmessage/llavatarnamecache.cpp
+++ b/indra/llmessage/llavatarnamecache.cpp
@@ -64,7 +64,6 @@ LLCore::HttpRequest::ptr_t		sHttpRequest;
 LLCore::HttpHeaders::ptr_t		sHttpHeaders;
 LLCore::HttpOptions::ptr_t		sHttpOptions;
 LLCore::HttpRequest::policy_t	sHttpPolicy;
-LLCore::HttpRequest::priority_t	sHttpPriority;
 
 /* Sample response:
 <?xml version="1.0"?>
@@ -121,7 +120,6 @@ LLAvatarNameCache::LLAvatarNameCache()
     sHttpHeaders = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders());
     sHttpOptions = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions());
     sHttpPolicy = LLCore::HttpRequest::DEFAULT_POLICY_ID;
-    sHttpPriority = 0;
 }
 
 LLAvatarNameCache::~LLAvatarNameCache()
diff --git a/indra/llmessage/llcorehttputil.cpp b/indra/llmessage/llcorehttputil.cpp
index 7031f1aa8c8..96af8bacee5 100644
--- a/indra/llmessage/llcorehttputil.cpp
+++ b/indra/llmessage/llcorehttputil.cpp
@@ -131,7 +131,6 @@ bool responseToLLSD(HttpResponse * response, bool log, LLSD & out_llsd)
 
 HttpHandle requestPostWithLLSD(HttpRequest * request,
     HttpRequest::policy_t policy_id,
-    HttpRequest::priority_t priority,
     const std::string & url,
     const LLSD & body,
     const HttpOptions::ptr_t &options,
@@ -145,7 +144,6 @@ HttpHandle requestPostWithLLSD(HttpRequest * request,
     LLSDSerialize::toXML(body, bas);
 
     handle = request->requestPost(policy_id,
-        priority,
         url,
         ba,
         options,
@@ -158,7 +156,6 @@ HttpHandle requestPostWithLLSD(HttpRequest * request,
 
 HttpHandle requestPutWithLLSD(HttpRequest * request,
     HttpRequest::policy_t policy_id,
-    HttpRequest::priority_t priority,
     const std::string & url,
     const LLSD & body,
     const HttpOptions::ptr_t &options,
@@ -172,7 +169,6 @@ HttpHandle requestPutWithLLSD(HttpRequest * request,
     LLSDSerialize::toXML(body, bas);
 
     handle = request->requestPut(policy_id,
-        priority,
         url,
         ba,
         options,
@@ -184,7 +180,6 @@ HttpHandle requestPutWithLLSD(HttpRequest * request,
 
 HttpHandle requestPatchWithLLSD(HttpRequest * request,
     HttpRequest::policy_t policy_id,
-    HttpRequest::priority_t priority,
     const std::string & url,
     const LLSD & body,
     const HttpOptions::ptr_t &options,
@@ -198,7 +193,6 @@ HttpHandle requestPatchWithLLSD(HttpRequest * request,
     LLSDSerialize::toXML(body, bas);
 
     handle = request->requestPatch(policy_id,
-        priority,
         url,
         ba,
         options,
@@ -672,10 +666,9 @@ const std::string HttpCoroutineAdapter::HTTP_RESULTS_CONTENT("content");
 const std::string HttpCoroutineAdapter::HTTP_RESULTS_RAW("raw");
 
 HttpCoroutineAdapter::HttpCoroutineAdapter(const std::string &name,
-    LLCore::HttpRequest::policy_t policyId, LLCore::HttpRequest::priority_t priority) :
+    LLCore::HttpRequest::policy_t policyId) :
     mAdapterName(name),
     mPolicyId(policyId),
-    mPriority(priority),
     mYieldingHandle(LLCORE_HTTP_HANDLE_INVALID),
     mWeakRequest(),
     mWeakHandler()
@@ -709,7 +702,7 @@ LLSD HttpCoroutineAdapter::postAndSuspend_(LLCore::HttpRequest::ptr_t &request,
     // The HTTPCoroHandler does not self delete, so retrieval of a the contained 
     // pointer from the smart pointer is safe in this case.
     LLCore::HttpHandle hhandle = requestPostWithLLSD(request,
-        mPolicyId, mPriority, url, body, options, headers,
+        mPolicyId, url, body, options, headers,
         handler);
 
     if (hhandle == LLCORE_HTTP_HANDLE_INVALID)
@@ -832,7 +825,7 @@ LLSD HttpCoroutineAdapter::postAndSuspend_(LLCore::HttpRequest::ptr_t &request,
 
     // The HTTPCoroHandler does not self delete, so retrieval of a the contained 
     // pointer from the smart pointer is safe in this case.
-    LLCore::HttpHandle hhandle = request->requestPost(mPolicyId, mPriority, url, rawbody.get(),
+    LLCore::HttpHandle hhandle = request->requestPost(mPolicyId, url, rawbody.get(),
         options, headers, handler);
 
     if (hhandle == LLCORE_HTTP_HANDLE_INVALID)
@@ -890,7 +883,7 @@ LLSD HttpCoroutineAdapter::putAndSuspend_(LLCore::HttpRequest::ptr_t &request,
     // The HTTPCoroHandler does not self delete, so retrieval of a the contained 
     // pointer from the smart pointer is safe in this case.
     LLCore::HttpHandle hhandle = requestPutWithLLSD(request,
-        mPolicyId, mPriority, url, body, options, headers,
+        mPolicyId, url, body, options, headers,
         handler);
 
     if (hhandle == LLCORE_HTTP_HANDLE_INVALID)
@@ -916,7 +909,7 @@ LLSD HttpCoroutineAdapter::putAndSuspend_(LLCore::HttpRequest::ptr_t &request,
 
     // The HTTPCoroHandler does not self delete, so retrieval of a the contained 
     // pointer from the smart pointer is safe in this case.
-    LLCore::HttpHandle hhandle = request->requestPut(mPolicyId, mPriority, 
+    LLCore::HttpHandle hhandle = request->requestPut(mPolicyId,
         url, rawbody.get(), options, headers, handler);
 
     if (hhandle == LLCORE_HTTP_HANDLE_INVALID)
@@ -972,7 +965,7 @@ LLSD HttpCoroutineAdapter::getAndSuspend_(LLCore::HttpRequest::ptr_t &request,
 
     // The HTTPCoroHandler does not self delete, so retrieval of a the contained 
     // pointer from the smart pointer is safe in this case.
-    LLCore::HttpHandle hhandle = request->requestGet(mPolicyId, mPriority,
+    LLCore::HttpHandle hhandle = request->requestGet(mPolicyId,
         url, options, headers, handler);
 
     if (hhandle == LLCORE_HTTP_HANDLE_INVALID)
@@ -1018,7 +1011,7 @@ LLSD HttpCoroutineAdapter::deleteAndSuspend_(LLCore::HttpRequest::ptr_t &request
     checkDefaultHeaders(headers);
     // The HTTPCoroHandler does not self delete, so retrieval of a the contained 
     // pointer from the smart pointer is safe in this case.
-    LLCore::HttpHandle hhandle = request->requestDelete(mPolicyId, mPriority,
+    LLCore::HttpHandle hhandle = request->requestDelete(mPolicyId,
         url, options, headers, handler);
 
     if (hhandle == LLCORE_HTTP_HANDLE_INVALID)
@@ -1056,7 +1049,7 @@ LLSD HttpCoroutineAdapter::patchAndSuspend_(LLCore::HttpRequest::ptr_t &request,
     // The HTTPCoroHandler does not self delete, so retrieval of a the contained 
     // pointer from the smart pointer is safe in this case.
     LLCore::HttpHandle hhandle = requestPatchWithLLSD(request,
-        mPolicyId, mPriority, url, body, options, headers,
+        mPolicyId, url, body, options, headers,
         handler);
 
     if (hhandle == LLCORE_HTTP_HANDLE_INVALID)
@@ -1098,7 +1091,7 @@ LLSD HttpCoroutineAdapter::copyAndSuspend_(LLCore::HttpRequest::ptr_t &request,
     // The HTTPCoroHandler does not self delete, so retrieval of a the contained 
     // pointer from the smart pointer is safe in this case.
     // 
-    LLCore::HttpHandle hhandle = request->requestCopy(mPolicyId, mPriority, url,
+    LLCore::HttpHandle hhandle = request->requestCopy(mPolicyId, url,
         options, headers, handler);
 
     if (hhandle == LLCORE_HTTP_HANDLE_INVALID)
@@ -1140,7 +1133,7 @@ LLSD HttpCoroutineAdapter::moveAndSuspend_(LLCore::HttpRequest::ptr_t &request,
     // The HTTPCoroHandler does not self delete, so retrieval of a the contained 
     // pointer from the smart pointer is safe in this case.
     // 
-    LLCore::HttpHandle hhandle = request->requestMove(mPolicyId, mPriority, url,
+    LLCore::HttpHandle hhandle = request->requestMove(mPolicyId, url,
         options, headers, handler);
 
     if (hhandle == LLCORE_HTTP_HANDLE_INVALID)
diff --git a/indra/llmessage/llcorehttputil.h b/indra/llmessage/llcorehttputil.h
index 6f0b865f830..430dc417acf 100644
--- a/indra/llmessage/llcorehttputil.h
+++ b/indra/llmessage/llcorehttputil.h
@@ -116,7 +116,6 @@ std::string responseToString(LLCore::HttpResponse * response);
 ///
 LLCore::HttpHandle requestPostWithLLSD(LLCore::HttpRequest * request,
     LLCore::HttpRequest::policy_t policy_id,
-    LLCore::HttpRequest::priority_t priority,
     const std::string & url,
     const LLSD & body,
     const LLCore::HttpOptions::ptr_t &options,
@@ -125,20 +124,18 @@ LLCore::HttpHandle requestPostWithLLSD(LLCore::HttpRequest * request,
 
 inline LLCore::HttpHandle requestPostWithLLSD(LLCore::HttpRequest::ptr_t & request,
 	LLCore::HttpRequest::policy_t policy_id,
-	LLCore::HttpRequest::priority_t priority,
 	const std::string & url,
 	const LLSD & body,
 	const LLCore::HttpOptions::ptr_t & options,
 	const LLCore::HttpHeaders::ptr_t & headers,
     const LLCore::HttpHandler::ptr_t & handler)
 {
-    return requestPostWithLLSD(request.get(), policy_id, priority,
+    return requestPostWithLLSD(request.get(), policy_id,
         url, body, options, headers, handler);
 }
 
 inline LLCore::HttpHandle requestPostWithLLSD(LLCore::HttpRequest::ptr_t & request,
     LLCore::HttpRequest::policy_t policy_id,
-    LLCore::HttpRequest::priority_t priority,
     const std::string & url,
     const LLSD & body,
     const LLCore::HttpHandler::ptr_t &handler)
@@ -146,7 +143,7 @@ inline LLCore::HttpHandle requestPostWithLLSD(LLCore::HttpRequest::ptr_t & reque
     LLCore::HttpOptions::ptr_t options;
     LLCore::HttpHeaders::ptr_t headers;
 
-    return requestPostWithLLSD(request.get(), policy_id, priority,
+    return requestPostWithLLSD(request.get(), policy_id,
         url, body, options, headers, handler);
 }
 
@@ -169,7 +166,6 @@ inline LLCore::HttpHandle requestPostWithLLSD(LLCore::HttpRequest::ptr_t & reque
 ///
 LLCore::HttpHandle requestPutWithLLSD(LLCore::HttpRequest * request,
 	LLCore::HttpRequest::policy_t policy_id,
-	LLCore::HttpRequest::priority_t priority,
 	const std::string & url,
 	const LLSD & body,
 	const LLCore::HttpOptions::ptr_t &options,
@@ -178,20 +174,18 @@ LLCore::HttpHandle requestPutWithLLSD(LLCore::HttpRequest * request,
 
 inline LLCore::HttpHandle requestPutWithLLSD(LLCore::HttpRequest::ptr_t & request,
 	LLCore::HttpRequest::policy_t policy_id,
-	LLCore::HttpRequest::priority_t priority,
 	const std::string & url,
 	const LLSD & body,
 	const LLCore::HttpOptions::ptr_t & options,
 	const LLCore::HttpHeaders::ptr_t & headers,
     LLCore::HttpHandler::ptr_t handler)
 {
-    return requestPutWithLLSD(request.get(), policy_id, priority,
+    return requestPutWithLLSD(request.get(), policy_id,
         url, body, options, headers, handler);
 }
 
 inline LLCore::HttpHandle requestPutWithLLSD(LLCore::HttpRequest::ptr_t & request,
     LLCore::HttpRequest::policy_t policy_id,
-    LLCore::HttpRequest::priority_t priority,
     const std::string & url,
     const LLSD & body,
     LLCore::HttpHandler::ptr_t handler)
@@ -199,7 +193,7 @@ inline LLCore::HttpHandle requestPutWithLLSD(LLCore::HttpRequest::ptr_t & reques
     LLCore::HttpOptions::ptr_t options;
     LLCore::HttpHeaders::ptr_t headers;
 
-    return requestPutWithLLSD(request.get(), policy_id, priority,
+    return requestPutWithLLSD(request.get(), policy_id,
         url, body, options, headers, handler);
 }
 
@@ -221,7 +215,6 @@ inline LLCore::HttpHandle requestPutWithLLSD(LLCore::HttpRequest::ptr_t & reques
 ///
 LLCore::HttpHandle requestPatchWithLLSD(LLCore::HttpRequest * request,
     LLCore::HttpRequest::policy_t policy_id,
-    LLCore::HttpRequest::priority_t priority,
     const std::string & url,
     const LLSD & body,
     const LLCore::HttpOptions::ptr_t &options,
@@ -230,20 +223,18 @@ LLCore::HttpHandle requestPatchWithLLSD(LLCore::HttpRequest * request,
 
 inline LLCore::HttpHandle requestPatchWithLLSD(LLCore::HttpRequest::ptr_t & request,
     LLCore::HttpRequest::policy_t policy_id,
-    LLCore::HttpRequest::priority_t priority,
     const std::string & url,
     const LLSD & body,
     const LLCore::HttpOptions::ptr_t & options,
     const LLCore::HttpHeaders::ptr_t & headers,
     const LLCore::HttpHandler::ptr_t & handler)
 {
-    return requestPatchWithLLSD(request.get(), policy_id, priority,
+    return requestPatchWithLLSD(request.get(), policy_id,
         url, body, options, headers, handler);
 }
 
 inline LLCore::HttpHandle requestPatchWithLLSD(LLCore::HttpRequest::ptr_t & request,
     LLCore::HttpRequest::policy_t policy_id,
-    LLCore::HttpRequest::priority_t priority,
     const std::string & url,
     const LLSD & body,
     const LLCore::HttpHandler::ptr_t &handler)
@@ -251,7 +242,7 @@ inline LLCore::HttpHandle requestPatchWithLLSD(LLCore::HttpRequest::ptr_t & requ
     LLCore::HttpOptions::ptr_t options;
     LLCore::HttpHeaders::ptr_t headers;
 
-    return requestPatchWithLLSD(request.get(), policy_id, priority,
+    return requestPatchWithLLSD(request.get(), policy_id,
         url, body, options, headers, handler);
 }
 
@@ -329,8 +320,7 @@ class HttpCoroutineAdapter
     typedef boost::shared_ptr<HttpCoroutineAdapter> ptr_t;
     typedef boost::weak_ptr<HttpCoroutineAdapter>   wptr_t;
 
-    HttpCoroutineAdapter(const std::string &name, LLCore::HttpRequest::policy_t policyId,
-        LLCore::HttpRequest::priority_t priority = 0L);
+    HttpCoroutineAdapter(const std::string &name, LLCore::HttpRequest::policy_t policyId);
     ~HttpCoroutineAdapter();
 
     /// Execute a Post transaction on the supplied URL and yield execution of 
@@ -673,7 +663,6 @@ class HttpCoroutineAdapter
     void checkDefaultHeaders(LLCore::HttpHeaders::ptr_t &headers);
 
     std::string                     mAdapterName;
-    LLCore::HttpRequest::priority_t mPriority;
     LLCore::HttpRequest::policy_t   mPolicyId;
 
     LLCore::HttpHandle              mYieldingHandle;
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index 0a5d258b3a2..04974d9122f 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -1624,26 +1624,38 @@ void LLImageGL::syncToMainThread(LLGLuint new_tex_name)
         LL_PROFILE_ZONE_NAMED("cglt - sync");
         if (gGLManager.mHasSync)
         {
-            // post a sync to the main thread (will execute before tex name swap lambda below)
-            // glFlush calls here are partly superstitious and partly backed by observation
-            // on AMD hardware
-            glFlush();
-            auto sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
-            glFlush();
-            LL::WorkQueue::postMaybe(
-                mMainQueue,
-                [=]()
-                {
-                    LL_PROFILE_ZONE_NAMED("cglt - wait sync");
-                    {
-                        LL_PROFILE_ZONE_NAMED("glWaitSync");
-                        glWaitSync(sync, 0, GL_TIMEOUT_IGNORED);
-                    }
+            if (gGLManager.mIsNVIDIA)
+            {
+                // wait for texture upload to finish before notifying main thread
+                // upload is complete
+                auto sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
+                glFlush();
+                glClientWaitSync(sync, 0, GL_TIMEOUT_IGNORED);
+                glDeleteSync(sync);
+            }
+            else
+            {
+                // post a sync to the main thread (will execute before tex name swap lambda below)
+                // glFlush calls here are partly superstitious and partly backed by observation
+                // on AMD hardware
+                glFlush();
+                auto sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
+                glFlush();
+                LL::WorkQueue::postMaybe(
+                    mMainQueue,
+                    [=]()
                     {
-                        LL_PROFILE_ZONE_NAMED("glDeleteSync");
-                        glDeleteSync(sync);
-                    }
-                });
+                        LL_PROFILE_ZONE_NAMED("cglt - wait sync");
+                        {
+                            LL_PROFILE_ZONE_NAMED("glWaitSync");
+                            glWaitSync(sync, 0, GL_TIMEOUT_IGNORED);
+                        }
+                        {
+                            LL_PROFILE_ZONE_NAMED("glDeleteSync");
+                            glDeleteSync(sync);
+                        }
+                    });
+            }
         }
         else
         {
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 17071d4a655..ffb2fa326d8 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -3913,7 +3913,7 @@
         <key>Type</key>
         <string>F32</string>
         <key>Value</key>
-        <real>0.1</real>
+        <real>1.0</real>
     </map>
     <key>QueueInventoryFetchTimeout</key>
     <map>
@@ -10368,17 +10368,6 @@
       <key>Value</key>
       <real>12.0</real>
     </map>
-    <key>RenderTextureMemoryMultiple</key>
-    <map>
-      <key>Comment</key>
-      <string>Multiple of texture memory value to use (should fit: 0 &lt; value &lt;= 1.0)</string>
-      <key>Persist</key>
-      <integer>1</integer>
-      <key>Type</key>
-      <string>F32</string>
-      <key>Value</key>
-      <real>1.0</real>
-    </map>
     <key>RenderTrackerBeacon</key>
     <map>
       <key>Comment</key>
@@ -12456,7 +12445,7 @@
       <key>Type</key>
       <string>F32</string>
       <key>Value</key>
-      <real>1.0</real>
+      <real>2.0</real>
     </map>
     <key>TextureCameraMotionThreshold</key>
     <map>
@@ -12683,20 +12672,9 @@
       <key>Comment</key>
       <string>If TRUE, always load textures at full resolution (discard = 0)</string>
       <key>Persist</key>
-      <integer>0</integer>
-      <key>Type</key>
-      <string>Boolean</string>
-      <key>Value</key>
-      <integer>0</integer>
-    </map>
-    <key>TextureMemory</key>
-    <map>
-      <key>Comment</key>
-      <string>Amount of memory to use for textures in MB (0 = autodetect)</string>
-      <key>Persist</key>
       <integer>1</integer>
       <key>Type</key>
-      <string>S32</string>
+      <string>Boolean</string>
       <key>Value</key>
       <integer>0</integer>
     </map>
diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt
index 1ccde982837..e04e38b9de6 100644
--- a/indra/newview/featuretable.txt
+++ b/indra/newview/featuretable.txt
@@ -60,7 +60,6 @@ WindLightUseAtmosShaders	1	1
 WLSkyDetail					1	128
 Disregard128DefaultDrawDistance	1	1
 Disregard96DefaultDrawDistance	1	1
-RenderTextureMemoryMultiple		1	1.0
 RenderCompressTextures		1	1
 RenderShaderLightingMaxLevel	1	3
 RenderDeferred				1	1
diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt
index c9efd89cc87..d319d26e1fc 100644
--- a/indra/newview/featuretable_mac.txt
+++ b/indra/newview/featuretable_mac.txt
@@ -60,7 +60,6 @@ WindLightUseAtmosShaders	1	1
 WLSkyDetail					1	128
 Disregard128DefaultDrawDistance	1	1
 Disregard96DefaultDrawDistance	1	1
-RenderTextureMemoryMultiple		1	1.0
 RenderCompressTextures		1	1
 RenderShaderLightingMaxLevel	1	3
 RenderDeferred				1	1
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 61fc693b99e..7625547dd9a 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -3227,7 +3227,7 @@ LLSD LLAppViewer::getViewerInfo() const
     info["LOD_FACTOR"] = gSavedSettings.getF32("RenderVolumeLODFactor");
     info["RENDER_QUALITY"] = (F32)gSavedSettings.getU32("RenderQualityPerformance");
     info["GPU_SHADERS"] = gSavedSettings.getBOOL("RenderDeferred") ? "Enabled" : "Disabled";
-    info["TEXTURE_MEMORY"] = gSavedSettings.getS32("TextureMemory");
+    info["TEXTURE_MEMORY"] = gGLManager.mVRAM;
 
 #if LL_DARWIN
     info["HIDPI"] = gHiDPISupport;
diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp
index cc5cb667f0a..be33e1b30a0 100644
--- a/indra/newview/lldrawpoolterrain.cpp
+++ b/indra/newview/lldrawpoolterrain.cpp
@@ -148,7 +148,7 @@ void LLDrawPoolTerrain::boostTerrainDetailTextures()
 	for (S32 i = 0; i < 4; i++)
 	{
 		compp->mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_TERRAIN);
-		compp->mDetailTextures[i]->addTextureStats(1024.f*1024.f); // assume large pixel area
+        gPipeline.touchTexture(compp->mDetailTextures[i], 1024.f * 1024.f);
 	}
 }
 
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index b328dd2962c..9bf9e7503eb 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -2311,6 +2311,7 @@ void LLFace::resetVirtualSize()
 
 F32 LLFace::getTextureVirtualSize()
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
 	F32 radius;
 	F32 cos_angle_to_view_dir;	
 	BOOL in_frustum = calcPixelArea(cos_angle_to_view_dir, radius);
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 90bb80a08b1..f94c53a08ba 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -1275,12 +1275,7 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState()
 	shadow_text->setEnabled(enabled);
 
 	// Hardware settings
-	F32 mem_multiplier = gSavedSettings.getF32("RenderTextureMemoryMultiple");
-	S32Megabytes min_tex_mem = LLViewerTextureList::getMinVideoRamSetting();
-	S32Megabytes max_tex_mem = LLViewerTextureList::getMaxVideoRamSetting(false, mem_multiplier);
-	getChild<LLSliderCtrl>("GraphicsCardTextureMemory")->setMinValue(min_tex_mem.value());
-	getChild<LLSliderCtrl>("GraphicsCardTextureMemory")->setMaxValue(max_tex_mem.value());
-
+	
 	if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderVBOEnable") ||
 		!gGLManager.mHasVertexBufferObject)
 	{
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index b4fc8325965..fa7deb78f86 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -215,8 +215,6 @@ LLInventoryModel::LLInventoryModel()
 	mHttpOptions(),
 	mHttpHeaders(),
 	mHttpPolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID),
-	mHttpPriorityFG(0),
-	mHttpPriorityBG(0),
 	mCategoryLock(),
 	mItemLock(),
 	mValidationInfo(new LLInventoryValidationInfo)
@@ -2778,7 +2776,6 @@ LLCore::HttpHandle LLInventoryModel::requestPost(bool foreground,
 		
 	handle = LLCoreHttpUtil::requestPostWithLLSD(request,
 												 mHttpPolicyClass,
-												 (foreground ? mHttpPriorityFG : mHttpPriorityBG),
 												 url,
 												 body,
 												 mHttpOptions,
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index e81652820f5..fdbc6426adc 100644
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -610,8 +610,6 @@ class LLInventoryModel
 	LLCore::HttpOptions::ptr_t			mHttpOptions;
 	LLCore::HttpHeaders::ptr_t			mHttpHeaders;
 	LLCore::HttpRequest::policy_t		mHttpPolicyClass;
-	LLCore::HttpRequest::priority_t		mHttpPriorityFG;
-	LLCore::HttpRequest::priority_t		mHttpPriorityBG;
 	
 /**                    HTTP Transport
  **                                                                            **
diff --git a/indra/newview/llmaterialmgr.cpp b/indra/newview/llmaterialmgr.cpp
index 11aa6073936..27a9758ec37 100644
--- a/indra/newview/llmaterialmgr.cpp
+++ b/indra/newview/llmaterialmgr.cpp
@@ -133,8 +133,7 @@ LLMaterialMgr::LLMaterialMgr():
 	mHttpRequest(),
 	mHttpHeaders(),
 	mHttpOptions(),
-	mHttpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID),
-	mHttpPriority(0)
+	mHttpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID)
 {
 	LLAppCoreHttp & app_core_http(LLAppViewer::instance()->getAppCoreHttp());
 
@@ -699,7 +698,7 @@ void LLMaterialMgr::processGetQueue()
 			<< "\ndata: " << ll_pretty_print_sd(materialsData) << LL_ENDL;
 
 		LLCore::HttpHandle handle = LLCoreHttpUtil::requestPostWithLLSD(mHttpRequest, 
-				mHttpPolicy, mHttpPriority, capURL, 
+				mHttpPolicy, capURL, 
 				postData, mHttpOptions, mHttpHeaders, handler);
 
 		if (handle == LLCORE_HTTP_HANDLE_INVALID)
@@ -985,7 +984,7 @@ void LLMaterialMgr::processPutQueue()
 										));
 
 			LLCore::HttpHandle handle = LLCoreHttpUtil::requestPutWithLLSD(
-				mHttpRequest, mHttpPolicy, mHttpPriority, capURL,
+				mHttpRequest, mHttpPolicy, capURL,
 				putData, mHttpOptions, mHttpHeaders, handler);
 
 			if (handle == LLCORE_HTTP_HANDLE_INVALID)
diff --git a/indra/newview/llmaterialmgr.h b/indra/newview/llmaterialmgr.h
index 843dc66fbca..f76cc27db1b 100644
--- a/indra/newview/llmaterialmgr.h
+++ b/indra/newview/llmaterialmgr.h
@@ -141,7 +141,6 @@ class LLMaterialMgr : public LLSingleton<LLMaterialMgr>
 	LLCore::HttpHeaders::ptr_t		mHttpHeaders;
 	LLCore::HttpOptions::ptr_t		mHttpOptions;
 	LLCore::HttpRequest::policy_t	mHttpPolicy;
-	LLCore::HttpRequest::priority_t	mHttpPriority;
 
 	U32 getMaxEntries(const LLViewerRegion* regionp);
 };
diff --git a/indra/newview/llmediadataclient.cpp b/indra/newview/llmediadataclient.cpp
index bc45eb6d3ae..142977e9390 100644
--- a/indra/newview/llmediadataclient.cpp
+++ b/indra/newview/llmediadataclient.cpp
@@ -355,7 +355,7 @@ void LLMediaDataClient::serviceQueue()
 		
 		// and make the post
         LLCore::HttpHandler::ptr_t handler = request->createHandler();
-        LLCore::HttpHandle handle = LLCoreHttpUtil::requestPostWithLLSD(mHttpRequest, mHttpPolicy, 0,
+        LLCore::HttpHandle handle = LLCoreHttpUtil::requestPostWithLLSD(mHttpRequest, mHttpPolicy,
             url, sd_payload, mHttpOpts, mHttpHeaders, handler);
 
         if (handle == LLCORE_HTTP_HANDLE_INVALID)
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index d28e929b488..6fa71e130ea 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -823,8 +823,7 @@ LLMeshRepoThread::LLMeshRepoThread()
   mHttpLargeOptions(),
   mHttpHeaders(),
   mHttpPolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID),
-  mHttpLargePolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID),
-  mHttpPriority(0)
+  mHttpLargePolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID)
 {
 	LLAppCoreHttp & app_core_http(LLAppViewer::instance()->getAppCoreHttp());
 
@@ -1268,7 +1267,6 @@ LLCore::HttpHandle LLMeshRepoThread::getByteRange(const std::string & url,
 	if (len < LARGE_MESH_FETCH_THRESHOLD)
 	{
 		handle = mHttpRequest->requestGetByteRange( mHttpPolicyClass,
-                                                    mHttpPriority,
                                                     url,
                                                     (disable_range_req ? size_t(0) : offset),
                                                     (disable_range_req ? size_t(0) : len),
@@ -1283,7 +1281,6 @@ LLCore::HttpHandle LLMeshRepoThread::getByteRange(const std::string & url,
 	else
 	{
 		handle = mHttpRequest->requestGetByteRange(mHttpLargePolicyClass,
-												   mHttpPriority,
 												   url,
 												   (disable_range_req ? size_t(0) : offset),
 												   (disable_range_req ? size_t(0) : len),
@@ -2130,7 +2127,6 @@ LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list& data,
 	mHttpHeaders = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders);
 	mHttpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_LLSD_XML);
 	mHttpPolicyClass = LLAppViewer::instance()->getAppCoreHttp().getPolicy(LLAppCoreHttp::AP_UPLOADS);
-	mHttpPriority = 0;
 }
 
 LLMeshUploadThread::~LLMeshUploadThread()
@@ -2649,7 +2645,6 @@ void LLMeshUploadThread::doWholeModelUpload()
 
 		LLCore::HttpHandle handle = LLCoreHttpUtil::requestPostWithLLSD(mHttpRequest,
 																		mHttpPolicyClass,
-																		mHttpPriority,
 																		mWholeModelUploadURL,
 																		body,
 																		mHttpOptions,
@@ -2700,7 +2695,6 @@ void LLMeshUploadThread::requestWholeModelFee()
 	dump_llsd_to_file(mModelData, make_dump_name("whole_model_fee_request_", dump_num));
 	LLCore::HttpHandle handle = LLCoreHttpUtil::requestPostWithLLSD(mHttpRequest,
 																	mHttpPolicyClass,
-																	mHttpPriority,
 																	mWholeModelFeeCapability,
 																	mModelData,
 																	mHttpOptions,
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index 19893503030..5459bbb4af4 100644
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -321,7 +321,6 @@ class LLMeshRepoThread : public LLThread
 	LLCore::HttpHeaders::ptr_t			mHttpHeaders;
 	LLCore::HttpRequest::policy_t		mHttpPolicyClass;
 	LLCore::HttpRequest::policy_t		mHttpLargePolicyClass;
-	LLCore::HttpRequest::priority_t		mHttpPriority;
 
 	typedef std::set<LLCore::HttpHandler::ptr_t> http_request_set;
 	http_request_set					mHttpRequestSet;			// Outstanding HTTP requests
@@ -489,7 +488,6 @@ class LLMeshUploadThread : public LLThread, public LLCore::HttpHandler
 	LLCore::HttpOptions::ptr_t			mHttpOptions;
 	LLCore::HttpHeaders::ptr_t			mHttpHeaders;
 	LLCore::HttpRequest::policy_t		mHttpPolicyClass;
-	LLCore::HttpRequest::priority_t		mHttpPriority;
 };
 
 // Params related to streaming cost, render cost, and scene complexity tracking.
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index 5c648c11e1e..99d7c81c8d8 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -3364,10 +3364,10 @@ class LLOctreeRenderNonOccluded : public OctreeTraveler
 				}
 			}	
 
-			if (drawable->getVOVolume() && gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY))
+			/*if (drawable->getVOVolume() && gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY))
 			{
 				renderTexturePriority(drawable);
-			}
+			}*/
 
 			if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_POINTS))
 			{
@@ -3694,7 +3694,7 @@ void LLSpatialPartition::renderDebug()
 									  LLPipeline::RENDER_DEBUG_BBOXES |
 									  LLPipeline::RENDER_DEBUG_NORMALS |
 									  LLPipeline::RENDER_DEBUG_POINTS |
-									  LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY |
+									  //LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY |
 									  LLPipeline::RENDER_DEBUG_TEXTURE_ANIM |
 									  LLPipeline::RENDER_DEBUG_RAYCAST |
 									  LLPipeline::RENDER_DEBUG_AVATAR_VOLUME |
diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp
index d4fc6f3de28..8f4eb9438bc 100644
--- a/indra/newview/lltexturecache.cpp
+++ b/indra/newview/lltexturecache.cpp
@@ -95,14 +95,13 @@ class LLTextureCacheWorker : public LLWorkerClass
 	};
 	
 public:
-	LLTextureCacheWorker(LLTextureCache* cache, U32 priority, const LLUUID& id,
+	LLTextureCacheWorker(LLTextureCache* cache, const LLUUID& id,
 						 U8* data, S32 datasize, S32 offset,
 						 S32 imagesize, // for writes
 						 LLTextureCache::Responder* responder)
 		: LLWorkerClass(cache, "LLTextureCacheWorker"),
 		  mID(id),
 		  mCache(cache),
-		  mPriority(priority),
 		  mReadData(NULL),
 		  mWriteData(data),
 		  mDataSize(datasize),
@@ -115,7 +114,6 @@ class LLTextureCacheWorker : public LLWorkerClass
 		  mBytesToRead(0),
 		  mBytesRead(0)
 	{
-		mPriority &= LLWorkerThread::PRIORITY_LOWBITS;
 	}
 	~LLTextureCacheWorker()
 	{
@@ -129,13 +127,12 @@ class LLTextureCacheWorker : public LLWorkerClass
 
 	virtual bool doWork(S32 param); // Called from LLWorkerThread::processRequest()
 
-	handle_t read() { addWork(0, LLWorkerThread::PRIORITY_HIGH | mPriority); return mRequestHandle; }
-	handle_t write() { addWork(1, LLWorkerThread::PRIORITY_HIGH | mPriority); return mRequestHandle; }
+	handle_t read() { addWork(0); return mRequestHandle; }
+	handle_t write() { addWork(1); return mRequestHandle; }
 	bool complete() { return checkWork(); }
 	void ioComplete(S32 bytes)
 	{
 		mBytesRead = bytes;
-		setPriority(LLWorkerThread::PRIORITY_HIGH | mPriority);
 	}
 
 private:
@@ -145,7 +142,6 @@ class LLTextureCacheWorker : public LLWorkerClass
 
 protected:
 	LLTextureCache* mCache;
-	U32 mPriority;
 	LLUUID	mID;
 	
 	U8* mReadData;
@@ -164,11 +160,11 @@ class LLTextureCacheWorker : public LLWorkerClass
 class LLTextureCacheLocalFileWorker : public LLTextureCacheWorker
 {
 public:
-	LLTextureCacheLocalFileWorker(LLTextureCache* cache, U32 priority, const std::string& filename, const LLUUID& id,
+	LLTextureCacheLocalFileWorker(LLTextureCache* cache, const std::string& filename, const LLUUID& id,
 						 U8* data, S32 datasize, S32 offset,
 						 S32 imagesize, // for writes
 						 LLTextureCache::Responder* responder) 
-			: LLTextureCacheWorker(cache, priority, id, data, datasize, offset, imagesize, responder),
+			: LLTextureCacheWorker(cache, id, data, datasize, offset, imagesize, responder),
 			mFileName(filename)
 
 	{
@@ -183,6 +179,7 @@ class LLTextureCacheLocalFileWorker : public LLTextureCacheWorker
 
 bool LLTextureCacheLocalFileWorker::doRead()
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
 	S32 local_size = LLAPRFile::size(mFileName, mCache->getLocalAPRFilePool());
 
 	if (local_size > 0 && mFileName.size() > 4)
@@ -207,50 +204,6 @@ bool LLTextureCacheLocalFileWorker::doRead()
 		return true;
 	}
 
-#if USE_LFS_READ
-	if (mFileHandle == LLLFSThread::nullHandle())
-	{
-		mImageLocal = TRUE;
-		mImageSize = local_size;
-		if (!mDataSize || mDataSize + mOffset > local_size)
-		{
-			mDataSize = local_size - mOffset;
-		}
-		if (mDataSize <= 0)
-		{
-			// no more data to read
-			mDataSize = 0;
-			return true;
-		}
-		mReadData = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), mDataSize);
-		mBytesRead = -1;
-		mBytesToRead = mDataSize;
-		setPriority(LLWorkerThread::PRIORITY_LOW | mPriority);
-		mFileHandle = LLLFSThread::sLocal->read(local_filename, mReadData, mOffset, mDataSize,
-												new ReadResponder(mCache, mRequestHandle));
-		return false;
-	}
-	else
-	{
-		if (mBytesRead >= 0)
-		{
-			if (mBytesRead != mBytesToRead)
-			{
-// 				LL_WARNS() << "Error reading file from local cache: " << local_filename
-// 						<< " Bytes: " << mDataSize << " Offset: " << mOffset
-// 						<< " / " << mDataSize << LL_ENDL;
-				mDataSize = 0; // failed
-				ll_aligned_free_16(mReadData);
-				mReadData = NULL;
-			}
-			return true;
-		}
-		else
-		{
-			return false;
-		}
-	}
-#else
 	if (!mDataSize || mDataSize > local_size)
 	{
 		mDataSize = local_size;
@@ -274,7 +227,6 @@ bool LLTextureCacheLocalFileWorker::doRead()
 		mImageLocal = TRUE;
 	}
 	return true;
-#endif
 }
 
 bool LLTextureCacheLocalFileWorker::doWrite()
@@ -286,12 +238,12 @@ bool LLTextureCacheLocalFileWorker::doWrite()
 class LLTextureCacheRemoteWorker : public LLTextureCacheWorker
 {
 public:
-	LLTextureCacheRemoteWorker(LLTextureCache* cache, U32 priority, const LLUUID& id,
+	LLTextureCacheRemoteWorker(LLTextureCache* cache, const LLUUID& id,
 						 U8* data, S32 datasize, S32 offset,
 						 S32 imagesize, // for writes
 						 LLPointer<LLImageRaw> raw, S32 discardlevel,
 						 LLTextureCache::Responder* responder) 
-			: LLTextureCacheWorker(cache, priority, id, data, datasize, offset, imagesize, responder),
+			: LLTextureCacheWorker(cache, id, data, datasize, offset, imagesize, responder),
 			mState(INIT),
 			mRawImage(raw),
 			mRawDiscardLevel(discardlevel)
@@ -329,6 +281,7 @@ void LLTextureCacheWorker::startWork(S32 param)
 // - the code supports offset reading but this is actually never exercised in the viewer
 bool LLTextureCacheRemoteWorker::doRead()
 {
+    LL_PROFILE_ZONE_SCOPED;
 	bool done = false;
 	S32 idx = -1;
 
@@ -580,6 +533,7 @@ bool LLTextureCacheRemoteWorker::doRead()
 // - the code *does not* support offset writing so there are no difference between buffer addresses and start of data
 bool LLTextureCacheRemoteWorker::doWrite()
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
 	bool done = false;
 	S32 idx = -1;	
 
@@ -756,6 +710,7 @@ bool LLTextureCacheRemoteWorker::doWrite()
 //virtual
 bool LLTextureCacheWorker::doWork(S32 param)
 {
+    LL_PROFILE_ZONE_SCOPED;
 	bool res = false;
 	if (param == 0) // read
 	{
@@ -775,11 +730,13 @@ bool LLTextureCacheWorker::doWork(S32 param)
 //virtual (WORKER THREAD)
 void LLTextureCacheWorker::finishWork(S32 param, bool completed)
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
 	if (mResponder.notNull())
 	{
 		bool success = (completed && mDataSize > 0);
 		if (param == 0)
 		{
+            LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("tcwfw - read");
 			// read
 			if (success)
 			{
@@ -789,12 +746,14 @@ void LLTextureCacheWorker::finishWork(S32 param, bool completed)
 			}
 			else
 			{
+                LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("tcwfw - read fail");
 				ll_aligned_free_16(mReadData);
 				mReadData = NULL;
 			}
 		}
 		else
 		{
+            LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("tcwfw - write");
 			// write
 			mWriteData = NULL; // we never owned data
 			mDataSize = 0;
@@ -806,6 +765,7 @@ void LLTextureCacheWorker::finishWork(S32 param, bool completed)
 //virtual (MAIN THREAD)
 void LLTextureCacheWorker::endWork(S32 param, bool aborted)
 {
+    LL_PROFILE_ZONE_SCOPED;
 	if (aborted)
 	{
 		// Let the destructor handle any cleanup
@@ -861,6 +821,7 @@ LLTextureCache::~LLTextureCache()
 //virtual
 S32 LLTextureCache::update(F32 max_time_ms)
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
 	static LLFrameTimer timer ;
 	static const F32 MAX_TIME_INTERVAL = 300.f ; //seconds.
 
@@ -874,22 +835,6 @@ S32 LLTextureCache::update(F32 max_time_ms)
 	mCompletedList.clear();
 	mListMutex.unlock();
 	
-	lockWorkers();
-	
-	for (handle_list_t::iterator iter1 = priorty_list.begin();
-		 iter1 != priorty_list.end(); ++iter1)
-	{
-		handle_t handle = *iter1;
-		handle_map_t::iterator iter2 = mWriters.find(handle);
-		if(iter2 != mWriters.end())
-		{
-			LLTextureCacheWorker* worker = iter2->second;
-			worker->setPriority(LLWorkerThread::PRIORITY_HIGH | worker->mPriority);
-		}
-	}
-
-	unlockWorkers(); 
-	
 	// call 'completed' with workers list unlocked (may call readComplete() or writeComplete()
 	for (responder_list_t::iterator iter1 = completed_list.begin();
 		 iter1 != completed_list.end(); ++iter1)
@@ -1323,6 +1268,7 @@ void LLTextureCache::updateEntryTimeStamp(S32 idx, Entry& entry)
 //update an existing entry, write to header file immediately.
 bool LLTextureCache::updateEntry(S32& idx, Entry& entry, S32 new_image_size, S32 new_data_size)
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
 	S32 new_body_size = llmax(0, new_data_size - TEXTURE_CACHE_ENTRY_SIZE) ;
 	
 	if(new_image_size == entry.mImageSize && new_body_size == entry.mBodySize)
@@ -1872,6 +1818,7 @@ void LLTextureCache::purgeTextures(bool validate)
 // call lockWorkers() first!
 LLTextureCacheWorker* LLTextureCache::getReader(handle_t handle)
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
 	LLTextureCacheWorker* res = NULL;
 	handle_map_t::iterator iter = mReaders.find(handle);
 	if (iter != mReaders.end())
@@ -1883,6 +1830,7 @@ LLTextureCacheWorker* LLTextureCache::getReader(handle_t handle)
 
 LLTextureCacheWorker* LLTextureCache::getWriter(handle_t handle)
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
 	LLTextureCacheWorker* res = NULL;
 	handle_map_t::iterator iter = mWriters.find(handle);
 	if (iter != mWriters.end())
@@ -1898,6 +1846,7 @@ LLTextureCacheWorker* LLTextureCache::getWriter(handle_t handle)
 // Reads imagesize from the header, updates timestamp
 S32 LLTextureCache::getHeaderCacheEntry(const LLUUID& id, Entry& entry)
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
 	LLMutexLock lock(&mHeaderMutex);	
 	S32 idx = openAndReadEntry(id, entry, false);
 	if (idx >= 0)
@@ -1910,6 +1859,7 @@ S32 LLTextureCache::getHeaderCacheEntry(const LLUUID& id, Entry& entry)
 // Writes imagesize to the header, updates timestamp
 S32 LLTextureCache::setHeaderCacheEntry(const LLUUID& id, Entry& entry, S32 imagesize, S32 datasize)
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
 	mHeaderMutex.lock();
 	S32 idx = openAndReadEntry(id, entry, true); // read or create
 	mHeaderMutex.unlock();
@@ -1942,13 +1892,14 @@ S32 LLTextureCache::setHeaderCacheEntry(const LLUUID& id, Entry& entry, S32 imag
 
 // Calls from texture pipeline thread (i.e. LLTextureFetch)
 
-LLTextureCache::handle_t LLTextureCache::readFromCache(const std::string& filename, const LLUUID& id, U32 priority,
+LLTextureCache::handle_t LLTextureCache::readFromCache(const std::string& filename, const LLUUID& id,
 													   S32 offset, S32 size, ReadResponder* responder)
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
 	// Note: checking to see if an entry exists can cause a stall,
 	//  so let the thread handle it
 	LLMutexLock lock(&mWorkersMutex);
-	LLTextureCacheWorker* worker = new LLTextureCacheLocalFileWorker(this, priority, filename, id,
+	LLTextureCacheWorker* worker = new LLTextureCacheLocalFileWorker(this, filename, id,
 																	 NULL, size, offset, 0,
 																	 responder);
 	handle_t handle = worker->read();
@@ -1956,13 +1907,14 @@ LLTextureCache::handle_t LLTextureCache::readFromCache(const std::string& filena
 	return handle;
 }
 
-LLTextureCache::handle_t LLTextureCache::readFromCache(const LLUUID& id, U32 priority,
+LLTextureCache::handle_t LLTextureCache::readFromCache(const LLUUID& id,
 													   S32 offset, S32 size, ReadResponder* responder)
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
 	// Note: checking to see if an entry exists can cause a stall,
 	//  so let the thread handle it
 	LLMutexLock lock(&mWorkersMutex);
-	LLTextureCacheWorker* worker = new LLTextureCacheRemoteWorker(this, priority, id,
+	LLTextureCacheWorker* worker = new LLTextureCacheRemoteWorker(this, id,
 																  NULL, size, offset,
 																  0, NULL, 0, responder);
 	handle_t handle = worker->read();
@@ -1973,6 +1925,7 @@ LLTextureCache::handle_t LLTextureCache::readFromCache(const LLUUID& id, U32 pri
 
 bool LLTextureCache::readComplete(handle_t handle, bool abort)
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
 	lockWorkers();
 	handle_map_t::iterator iter = mReaders.find(handle);
 	LLTextureCacheWorker* worker = NULL;
@@ -2000,7 +1953,7 @@ bool LLTextureCache::readComplete(handle_t handle, bool abort)
 	return (complete || abort);
 }
 
-LLTextureCache::handle_t LLTextureCache::writeToCache(const LLUUID& id, U32 priority,
+LLTextureCache::handle_t LLTextureCache::writeToCache(const LLUUID& id,
 													  U8* data, S32 datasize, S32 imagesize,
 													  LLPointer<LLImageRaw> rawimage, S32 discardlevel,
 													  WriteResponder* responder)
@@ -2018,7 +1971,7 @@ LLTextureCache::handle_t LLTextureCache::writeToCache(const LLUUID& id, U32 prio
 		mDoPurge = !mPurgeEntryList.empty();
 	}
 	LLMutexLock lock(&mWorkersMutex);
-	LLTextureCacheWorker* worker = new LLTextureCacheRemoteWorker(this, priority, id,
+	LLTextureCacheWorker* worker = new LLTextureCacheRemoteWorker(this, id,
 																  data, datasize, 0,
 																  imagesize, rawimage, discardlevel, responder);
 	handle_t handle = worker->write();
@@ -2086,6 +2039,7 @@ LLPointer<LLImageRaw> LLTextureCache::readFromFastCache(const LLUUID& id, S32& d
 //return the fast cache location
 bool LLTextureCache::writeToFastCache(LLUUID image_id, S32 id, LLPointer<LLImageRaw> raw, S32 discardlevel)
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
 	//rescale image if needed
 	if (raw.isNull() || raw->isBufferInvalid() || !raw->getData())
 	{
diff --git a/indra/newview/lltexturecache.h b/indra/newview/lltexturecache.h
index e1c752b58ed..f2a5978a7c2 100644
--- a/indra/newview/lltexturecache.h
+++ b/indra/newview/lltexturecache.h
@@ -119,13 +119,13 @@ class LLTextureCache : public LLWorkerThread
 	void setReadOnly(BOOL read_only) ;
 	S64 initCache(ELLPath location, S64 maxsize, BOOL texture_cache_mismatch);
 
-	handle_t readFromCache(const std::string& local_filename, const LLUUID& id, U32 priority, S32 offset, S32 size,
+	handle_t readFromCache(const std::string& local_filename, const LLUUID& id, S32 offset, S32 size,
 						   ReadResponder* responder);
 
-	handle_t readFromCache(const LLUUID& id, U32 priority, S32 offset, S32 size,
+	handle_t readFromCache(const LLUUID& id, S32 offset, S32 size,
 						   ReadResponder* responder);
 	bool readComplete(handle_t handle, bool abort);
-	handle_t writeToCache(const LLUUID& id, U32 priority, U8* data, S32 datasize, S32 imagesize, LLPointer<LLImageRaw> rawimage, S32 discardlevel,
+	handle_t writeToCache(const LLUUID& id, U8* data, S32 datasize, S32 imagesize, LLPointer<LLImageRaw> rawimage, S32 discardlevel,
 						  WriteResponder* responder);
 	LLPointer<LLImageRaw> readFromFastCache(const LLUUID& id, S32& discardlevel);
 	bool writeComplete(handle_t handle, bool abort = false);
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index 0edaf40c66d..8ad28074de6 100644
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -213,35 +213,17 @@ const std::string sTesterName("TextureFetchTester");
 //
 // Worker State Machine
 //
-// (ASCII art needed)
-//
-//
-// Priority Scheme
-//
-// [PRIORITY_LOW, PRIORITY_NORMAL)   - for WAIT_HTTP_RESOURCE state
-//									   and other wait states
-// [PRIORITY_HIGH, PRIORITY_URGENT)  - External event delivered,
-//                                     rapidly transitioning through states,
-//                                     no waiting allowed
-//
-// By itself, the above work queue model would fail the concurrency
-// and liveness requirements of the interface.  A high priority
-// request could find itself on the head and stalled for external
-// reasons (see VWR-28996).  So a few additional constraints are
-// required to keep things running:
-// * Anything that can make forward progress must be kept at a
-//   higher priority than anything that can't.
-// * On completion of external events, the associated request
-//   needs to be elevated beyond the normal range to handle
-//   any data delivery and release any external resource.
-//
-// This effort is made to keep higher-priority entities moving
-// forward in their state machines at every possible step of
-// processing.  It's not entirely proven that this produces the
-// experiencial benefits promised.
+// "doWork" will be executed for a given worker on its respective
+// LLQueuedThread.  If doWork returns true, the worker is treated 
+// as completed.  If doWork returns false, the worker will be 
+// put on the back of the work queue at the start of the next iteration
+// of the mainloop.  If a worker is waiting on a resource, it should
+// return false as soon as possible and not block to avoid starving
+// other workers of cpu cycles.
 //
 
 
+
 //////////////////////////////////////////////////////////////////////////////
 
 // Tuning/Parameterization Constants
@@ -386,14 +368,7 @@ class LLTextureFetchWorker : public LLWorkerClass, public LLCore::HttpHandler
 		bool operator()(const LLTextureFetchWorker* lhs, const LLTextureFetchWorker* rhs) const
 		{
 			// greater priority is "less"
-			const F32 lpriority = lhs->mImagePriority;
-			const F32 rpriority = rhs->mImagePriority;
-			if (lpriority > rpriority) // higher priority
-				return true;
-			else if (lpriority < rpriority)
-				return false;
-			else
-				return lhs < rhs;
+            return lhs->mImagePriority > rhs->mImagePriority;
 		}
 	};
 	
@@ -484,6 +459,9 @@ class LLTextureFetchWorker : public LLWorkerClass, public LLCore::HttpHandler
 	// Locks:  Mw
 	void resetFormattedData();
 	
+    // get the relative priority of this worker (should map to max virtual size)
+    F32 getImagePriority() const;
+
 	// Locks:  Mw
 	void setImagePriority(F32 priority);
 
@@ -500,9 +478,6 @@ class LLTextureFetchWorker : public LLWorkerClass, public LLCore::HttpHandler
 	// Locks:  Mw
 	void setupPacketData();
 
-	// Locks:  Mw (ctor invokes without lock)
-	U32 calcWorkPriority();
-	
 	// Locks:  Mw
 	void removeFromCache();
 
@@ -573,8 +548,7 @@ class LLTextureFetchWorker : public LLWorkerClass, public LLCore::HttpHandler
 	LLHost mHost;
 	std::string mUrl;
 	U8 mType;
-	F32 mImagePriority;
-	U32 mWorkPriority;
+	F32 mImagePriority; // should map to max virtual size
 	F32 mRequestedPriority;
 	S32 mDesiredDiscard;
 	S32 mSimRequestedDiscard;
@@ -923,7 +897,6 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,
 	  mHost(host),
 	  mUrl(url),
 	  mImagePriority(priority),
-	  mWorkPriority(0),
 	  mRequestedPriority(0.f),
 	  mDesiredDiscard(-1),
 	  mSimRequestedDiscard(-1),
@@ -970,17 +943,15 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,
 	  mCacheReadCount(0U),
 	  mCacheWriteCount(0U),
 	  mResourceWaitCount(0U),
-	  mFetchRetryPolicy(10.0,3600.0,2.0,10)
+	  mFetchRetryPolicy(10.f,3600.f,2.f,10)
 {
 	mCanUseNET = mUrl.empty() ;
 	
-	calcWorkPriority();
 	mType = host.isOk() ? LLImageBase::TYPE_AVATAR_BAKE : LLImageBase::TYPE_NORMAL;
 // 	LL_INFOS(LOG_TXT) << "Create: " << mID << " mHost:" << host << " Discard=" << discard << LL_ENDL;
 	if (!mFetcher->mDebugPause)
 	{
-		U32 work_priority = mWorkPriority | LLWorkerThread::PRIORITY_HIGH;
-		addWork(0, work_priority );
+		addWork(0);
 	}
 	setDesiredDiscard(discard, size);
 }
@@ -1070,16 +1041,6 @@ void LLTextureFetchWorker::setupPacketData()
 	}
 }
 
-// Locks:  Mw (ctor invokes without lock)
-U32 LLTextureFetchWorker::calcWorkPriority()
-{
- 	//llassert_always(mImagePriority >= 0 && mImagePriority <= LLViewerFetchedTexture::maxDecodePriority());
-	static const F32 PRIORITY_SCALE = (F32)LLWorkerThread::PRIORITY_LOWBITS / LLViewerFetchedTexture::maxDecodePriority();
-
-	mWorkPriority = llmin((U32)LLWorkerThread::PRIORITY_LOWBITS, (U32)(mImagePriority * PRIORITY_SCALE));
-	return mWorkPriority;
-}
-
 // Locks:  Mw (ctor invokes without lock)
 void LLTextureFetchWorker::setDesiredDiscard(S32 discard, S32 size)
 {
@@ -1088,11 +1049,9 @@ void LLTextureFetchWorker::setDesiredDiscard(S32 discard, S32 size)
 	{
 		if (!haveWork())
 		{
-			calcWorkPriority();
 			if (!mFetcher->mDebugPause)
 			{
-				U32 work_priority = mWorkPriority | LLWorkerThread::PRIORITY_HIGH;
-				addWork(0, work_priority);
+				addWork(0);
 			}
 		}
 		else if (mDesiredDiscard < discard)
@@ -1111,23 +1070,13 @@ void LLTextureFetchWorker::setDesiredDiscard(S32 discard, S32 size)
 	if ((prioritize && mState == INIT) || mState == DONE)
 	{
 		setState(INIT);
-		U32 work_priority = mWorkPriority | LLWorkerThread::PRIORITY_HIGH;
-		setPriority(work_priority);
 	}
 }
 
 // Locks:  Mw
 void LLTextureFetchWorker::setImagePriority(F32 priority)
 {
-// 	llassert_always(priority >= 0 && priority <= LLViewerTexture::maxDecodePriority());
-	F32 delta = fabs(priority - mImagePriority);
-	if (delta > (mImagePriority * .05f) || mState == DONE)
-	{
-		mImagePriority = priority;
-		calcWorkPriority();
-		U32 work_priority = mWorkPriority | (getPriority() & LLWorkerThread::PRIORITY_HIGHBITS);
-		setPriority(work_priority);
-	}
+	mImagePriority = priority; //should map to max virtual size
 }
 
 // Locks:  Mw
@@ -1147,6 +1096,11 @@ void LLTextureFetchWorker::resetFormattedData()
 	mHaveAllData = FALSE;
 }
 
+F32 LLTextureFetchWorker::getImagePriority() const
+{
+    return mImagePriority;
+}
+
 // Threads:  Tmain
 void LLTextureFetchWorker::startWork(S32 param)
 {
@@ -1156,7 +1110,7 @@ void LLTextureFetchWorker::startWork(S32 param)
 // Threads:  Ttf
 bool LLTextureFetchWorker::doWork(S32 param)
 {
-    LL_PROFILE_ZONE_SCOPED;
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
 	if (gNonInteractive)
 	{
 		return true;
@@ -1171,20 +1125,23 @@ bool LLTextureFetchWorker::doWork(S32 param)
 	{
 		if (mState < DECODE_IMAGE)
 		{
+            LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - state < decode");
 			return true; // abort
 		}
 	}
 
-	if(mImagePriority < F_ALMOST_ZERO)
+	if (mImagePriority < F_ALMOST_ZERO)
 	{
 		if (mState == INIT || mState == LOAD_FROM_NETWORK || mState == LOAD_FROM_SIMULATOR)
 		{
+            LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - priority < 0");
 			LL_DEBUGS(LOG_TXT) << mID << " abort: mImagePriority < F_ALMOST_ZERO" << LL_ENDL;
 			return true; // abort
 		}
 	}
 	if(mState > CACHE_POST && !mCanUseNET && !mCanUseHTTP)
 	{
+        LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - state > cache_post");
 		//nowhere to get data, abort.
 		LL_WARNS(LOG_TXT) << mID << " abort, nowhere to get data" << LL_ENDL;
 		return true ;
@@ -1206,6 +1163,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 
 	if (mState == INIT)
 	{		
+        LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - INIT");
 		mStateTimer.reset();
 		mFetchTimer.reset();
 		for(auto i : LOGGED_STATES) 
@@ -1247,15 +1205,16 @@ bool LLTextureFetchWorker::doWork(S32 param)
 
 	if (mState == LOAD_FROM_TEXTURE_CACHE)
 	{
+        LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - LOAD_FROM_TEXTURE_CACHE");
 		if (mCacheReadHandle == LLTextureCache::nullHandle())
 		{
-			U32 cache_priority = mWorkPriority;
 			S32 offset = mFormattedImage.notNull() ? mFormattedImage->getDataSize() : 0;
 			S32 size = mDesiredSize - offset;
 			if (size <= 0)
 			{
 				setState(CACHE_POST);
-				return false;
+                return doWork(param);
+                // return false;
 			}
 			mFileSize = 0;
 			mLoaded = FALSE;			
@@ -1264,35 +1223,28 @@ bool LLTextureFetchWorker::doWork(S32 param)
 
 			if (mUrl.compare(0, 7, "file://") == 0)
 			{
-				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);
 				mCacheReadTimer.reset();  
-				mCacheReadHandle = mFetcher->mTextureCache->readFromCache(filename, mID, cache_priority,
-																		  offset, size, responder);
+				mCacheReadHandle = mFetcher->mTextureCache->readFromCache(filename, mID, offset, size, responder);
               
 			}
 			else if ((mUrl.empty() || mFTType==FTT_SERVER_BAKE) && mFetcher->canLoadFromCache())
 			{
-				setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it
-
 				++mCacheReadCount;
 				CacheReadResponder* responder = new CacheReadResponder(mFetcher, mID, mFormattedImage);
 				mCacheReadTimer.reset();
-				mCacheReadHandle = mFetcher->mTextureCache->readFromCache(mID, cache_priority,
+				mCacheReadHandle = mFetcher->mTextureCache->readFromCache(mID,
 																		  offset, size, responder);;
 			}
 			else if(!mUrl.empty() && mCanUseHTTP)
 			{
-				setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
 				setState(WAIT_HTTP_RESOURCE);
 			}
 			else
 			{
-				setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
 				setState(LOAD_FROM_NETWORK);
 			}
 		}
@@ -1325,6 +1277,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 
 	if (mState == CACHE_POST)
 	{
+        LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - CACHE_POST");
 		mCachedSize = mFormattedImage.notNull() ? mFormattedImage->getDataSize() : 0;
 		// Successfully loaded
 		if ((mCachedSize >= mDesiredSize) || mHaveAllData)
@@ -1366,6 +1319,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 
 	if (mState == LOAD_FROM_NETWORK)
 	{
+        LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - LOAD_FROM_NETWORK");
 		// Check for retries to previous server failures.
 		F32 wait_seconds;
 		if (mFetchRetryPolicy.shouldRetry(wait_seconds))
@@ -1427,7 +1381,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
 		if (mCanUseHTTP && !mUrl.empty())
 		{
 			setState(WAIT_HTTP_RESOURCE);
-			setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
 			if(mWriteToCacheState != NOT_WRITE)
 			{
 				mWriteToCacheState = CAN_WRITE ;
@@ -1444,25 +1397,19 @@ bool LLTextureFetchWorker::doWork(S32 param)
 			mSentRequest = QUEUED;
 			mFetcher->addToNetworkQueue(this);
 			recordTextureStart(false);
-			setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
-			
 			return false;
 		}
 		else
 		{
 			// Shouldn't need to do anything here
-			//llassert_always(mFetcher->mNetworkQueue.find(mID) != mFetcher->mNetworkQueue.end());
-			// Make certain this is in the network queue
-			//mFetcher->addToNetworkQueue(this);
-			//recordTextureStart(false);
-			//setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
-
+			llassert(mFetcher->mNetworkQueue.find(mID) != mFetcher->mNetworkQueue.end());
 			return false;
 		}
 	}
 	
 	if (mState == LOAD_FROM_SIMULATOR)
 	{
+        LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - LOAD_FROM_SIMULATOR");
 		if (mFormattedImage.isNull())
 		{
 			mFormattedImage = new LLImageJ2C;
@@ -1492,7 +1439,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 				LL_WARNS(LOG_TXT) << mID << " processSimulatorPackets() failed to load buffer" << LL_ENDL;
 				return true; // failed
 			}
-			setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
+
 			if (mLoadedDiscard < 0)
 			{
 				LL_WARNS(LOG_TXT) << mID << " mLoadedDiscard is " << mLoadedDiscard
@@ -1506,7 +1453,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
 		else
 		{
 			mFetcher->addToNetworkQueue(this); // failsafe
-			setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
 			recordTextureStart(false);
 		}
 		return false;
@@ -1514,6 +1460,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 	
 	if (mState == WAIT_HTTP_RESOURCE)
 	{
+        LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - WAIT_HTTP_RESOURCE");
 		// NOTE:
 		// control the number of the http requests issued for:
 		// 1, not openning too many file descriptors at the same time;
@@ -1524,7 +1471,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
 		if (mFetcher->getHttpWaitersCount() || ! acquireHttpSemaphore())
 		{
 			setState(WAIT_HTTP_RESOURCE2);
-			setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
 			mFetcher->addHttpWaiter(this->mID);
 			++mResourceWaitCount;
 			return false;
@@ -1538,12 +1484,14 @@ bool LLTextureFetchWorker::doWork(S32 param)
 
 	if (mState == WAIT_HTTP_RESOURCE2)
 	{
+        LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - WAIT_HTTP_RESOURCE2");
 		// Just idle it if we make it to the head...
 		return false;
 	}
 	
 	if (mState == SEND_HTTP_REQ)
 	{
+        LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - SEND_HTTP_REQ");
 		// Also used in llmeshrepository
 		static LLCachedControl<bool> disable_range_req(gSavedSettings, "HttpRangeRequestsDisable", false);
 		
@@ -1566,7 +1514,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
 				{
 					// We already have all the data, just decode it
 					mLoadedDiscard = mFormattedImage->getDiscardLevel();
-					setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
 					if (mLoadedDiscard < 0)
 					{
 						LL_WARNS(LOG_TXT) << mID << " mLoadedDiscard is " << mLoadedDiscard
@@ -1574,7 +1521,8 @@ bool LLTextureFetchWorker::doWork(S32 param)
 					}
 					setState(DECODE_IMAGE);
 					releaseHttpSemaphore();
-					return false;
+					//return false;
+                    return doWork(param);
 				}
 				else
 				{
@@ -1635,7 +1583,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
 			// by people with questionable ISPs or networking gear that
 			// doesn't handle these well.
 			mHttpHandle = mFetcher->mHttpRequest->requestGet(mHttpPolicyClass,
-															 mWorkPriority,
 															 mUrl,
 															 options,
 															 mFetcher->mHttpHeaders,
@@ -1644,7 +1591,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
 		else
 		{
 			mHttpHandle = mFetcher->mHttpRequest->requestGetByteRange(mHttpPolicyClass,
-																	  mWorkPriority,
 																	  mUrl,
 																	  mRequestedOffset,
 																	  (mRequestedOffset + mRequestedSize) > HTTP_REQUESTS_RANGE_END_MAX
@@ -1669,7 +1615,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
 		mHttpActive = true;
 		mFetcher->addToHTTPQueue(mID);
 		recordTextureStart(true);
-		setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
 		setState(WAIT_HTTP_REQ);	
 		
 		// fall through
@@ -1677,6 +1622,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 	
 	if (mState == WAIT_HTTP_REQ)
 	{
+        LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - WAIT_HTTP_REQ");
 		// *NOTE:  As stated above, all transitions out of this state should
 		// call releaseHttpSemaphore().
 		if (mLoaded)
@@ -1708,9 +1654,9 @@ bool LLTextureFetchWorker::doWork(S32 param)
 						setState(INIT);
 						mCanUseHTTP = false;
 						mUrl.clear();
-						setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
 						releaseHttpSemaphore();
-						return false;
+						//return false;
+                        return doWork(param);
 					}
 				}
 				else if (http_service_unavail == mGetStatus)
@@ -1738,7 +1684,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
 				{
 					// Use available data
 					mLoadedDiscard = mFormattedImage->getDiscardLevel();
-					setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
 					if (mLoadedDiscard < 0)
 					{
 						LL_WARNS(LOG_TXT) << mID << " mLoadedDiscard is " << mLoadedDiscard
@@ -1746,7 +1691,8 @@ bool LLTextureFetchWorker::doWork(S32 param)
 					}
 					setState(DECODE_IMAGE);
 					releaseHttpSemaphore();
-					return false; 
+					//return false; 
+                    return doWork(param);
 				}
 
 				// Fail harder
@@ -1863,9 +1809,9 @@ bool LLTextureFetchWorker::doWork(S32 param)
 			{
 				mWriteToCacheState = SHOULD_WRITE ;
 			}
-			setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
 			releaseHttpSemaphore();
-			return false;
+			//return false;
+            return doWork(param);
 		}
 		else
 		{
@@ -1875,17 +1821,16 @@ bool LLTextureFetchWorker::doWork(S32 param)
 			// an enormous amount of time to load textures.  We'll revisit the
 			// various possible timeout components (total request time, connection
 			// time, I/O time, with and without retries, etc.) in the future.
-
-			setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
+			
 			return false;
 		}
 	}
 	
 	if (mState == DECODE_IMAGE)
 	{
+        LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - DECODE_IMAGE");
 		static LLCachedControl<bool> textures_decode_disabled(gSavedSettings, "TextureDecodeDisabled", false);
 
-		setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it
 		if (textures_decode_disabled)
 		{
 			// for debug use, don't decode
@@ -1924,18 +1869,18 @@ bool LLTextureFetchWorker::doWork(S32 param)
 		mAuxImage = NULL;
 		llassert_always(mFormattedImage.notNull());
 		S32 discard = mHaveAllData ? 0 : mLoadedDiscard;
-		U32 image_priority = LLWorkerThread::PRIORITY_NORMAL | mWorkPriority;
 		mDecoded  = FALSE;
 		setState(DECODE_IMAGE_UPDATE);
 		LL_DEBUGS(LOG_TXT) << mID << ": Decoding. Bytes: " << mFormattedImage->getDataSize() << " Discard: " << discard
 						   << " All Data: " << mHaveAllData << LL_ENDL;
-		mDecodeHandle = mFetcher->mImageDecodeThread->decodeImage(mFormattedImage, image_priority, discard, mNeedsAux,
+		mDecodeHandle = mFetcher->mImageDecodeThread->decodeImage(mFormattedImage, discard, mNeedsAux,
 																  new DecodeResponder(mFetcher, mID, this));
 		// fall though
 	}
 	
 	if (mState == DECODE_IMAGE_UPDATE)
 	{
+        LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - DECODE_IMAGE_UPDATE");
 		if (mDecoded)
 		{
 			if(mFetcher->getFetchDebugger() && !mInLocalCache)
@@ -1954,9 +1899,9 @@ bool LLTextureFetchWorker::doWork(S32 param)
 					llassert_always(mDecodeHandle == 0);
 					mFormattedImage = NULL;
 					++mRetryAttempt;
-					setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
 					setState(INIT);
-					return false;
+					//return false;
+                    return doWork(param);
 				}
 				else
 				{
@@ -1969,7 +1914,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
 				llassert_always(mRawImage.notNull());
 				LL_DEBUGS(LOG_TXT) << mID << ": Decoded. Discard: " << mDecodedDiscard
 								   << " Raw Image: " << llformat("%dx%d",mRawImage->getWidth(),mRawImage->getHeight()) << LL_ENDL;
-				setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
 				setState(WRITE_TO_CACHE);
 			}
 			// fall through
@@ -1982,12 +1926,14 @@ bool LLTextureFetchWorker::doWork(S32 param)
 
 	if (mState == WRITE_TO_CACHE)
 	{
+        LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - WRITE_TO_CACHE");
 		if (mWriteToCacheState != SHOULD_WRITE || mFormattedImage.isNull())
 		{
 			// If we're in a local cache or we didn't actually receive any new data,
 			// or we failed to load anything, skip
 			setState(DONE);
-			return false;
+			//return false;
+            return doWork(param);
 		}
 		S32 datasize = mFormattedImage->getDataSize();
 		if(mFileSize < datasize)//This could happen when http fetching and sim fetching mixed.
@@ -2002,8 +1948,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
 			}
 		}
 		llassert_always(datasize);
-		setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it
-		U32 cache_priority = mWorkPriority;
 		mWritten = FALSE;
 		setState(WAIT_ON_WRITE);
 		++mCacheWriteCount;
@@ -2014,7 +1958,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
         // So make sure users of getRequestFinished() does not attempt to modify image while
         // fetcher is working
 		mCacheWriteTimer.reset();
-		mCacheWriteHandle = mFetcher->mTextureCache->writeToCache(mID, cache_priority,
+		mCacheWriteHandle = mFetcher->mTextureCache->writeToCache(mID,
 																  mFormattedImage->getData(), datasize,
 																  mFileSize, mRawImage, mDecodedDiscard, responder);
 		// fall through
@@ -2022,6 +1966,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 	
 	if (mState == WAIT_ON_WRITE)
 	{
+        LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - WAIT_ON_WRITE");
 		if (writeToCacheComplete())
 		{
 			mCacheWriteTime = mCacheWriteTimer.getElapsedTimeF32();
@@ -2043,6 +1988,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 
 	if (mState == DONE)
 	{
+        LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - DONE");
 		if (mDecodedDiscard >= 0 && mDesiredDiscard < mDecodedDiscard)
 		{
 			// More data was requested, return to INIT
@@ -2050,12 +1996,11 @@ bool LLTextureFetchWorker::doWork(S32 param)
 			LL_DEBUGS(LOG_TXT) << mID << " more data requested, returning to INIT: " 
 							   << " mDecodedDiscard " << mDecodedDiscard << ">= 0 && mDesiredDiscard " << mDesiredDiscard
 							   << "<" << " mDecodedDiscard " << mDecodedDiscard << LL_ENDL;
-			setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
-			return false;
+			// return false;
+            return doWork(param);
 		}
 		else
 		{
-			setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
             mFetchTime = mFetchTimer.getElapsedTimeF32();
 			return true;
 		}
@@ -2068,6 +2013,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 // virtual
 void LLTextureFetchWorker::onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response)
 {
+    LL_PROFILE_ZONE_SCOPED;
 	static LLCachedControl<bool> log_to_viewer_log(gSavedSettings, "LogTextureDownloadsToViewerLog", false);
 	static LLCachedControl<bool> log_to_sim(gSavedSettings, "LogTextureDownloadsToSimulator", false);
 	static LLCachedControl<bool> log_texture_traffic(gSavedSettings, "LogTextureNetworkTraffic", false) ;
@@ -2177,6 +2123,7 @@ void LLTextureFetchWorker::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRe
 // Threads:  Tmain
 void LLTextureFetchWorker::endWork(S32 param, bool aborted)
 {
+    LL_PROFILE_ZONE_SCOPED;
 	if (mDecodeHandle != 0)
 	{
 		mFetcher->mImageDecodeThread->abortRequest(mDecodeHandle, false);
@@ -2192,6 +2139,7 @@ void LLTextureFetchWorker::endWork(S32 param, bool aborted)
 // virtual
 void LLTextureFetchWorker::finishWork(S32 param, bool completed)
 {
+    LL_PROFILE_ZONE_SCOPED;
 	// The following are required in case the work was aborted
 	if (mCacheReadHandle != LLTextureCache::nullHandle())
 	{
@@ -2445,7 +2393,6 @@ S32 LLTextureFetchWorker::callbackHttpGet(LLCore::HttpResponse * response,
 	}
 	
 	mLoaded = TRUE;
-	setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
 
 	if (LLViewerStatsRecorder::instanceExists())
 	{
@@ -2461,6 +2408,7 @@ S32 LLTextureFetchWorker::callbackHttpGet(LLCore::HttpResponse * response,
 void LLTextureFetchWorker::callbackCacheRead(bool success, LLImageFormatted* image,
 											 S32 imagesize, BOOL islocal)
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
 	LLMutexLock lock(&mWorkMutex);										// +Mw
 	if (mState != LOAD_FROM_TEXTURE_CACHE)
 	{
@@ -2480,7 +2428,6 @@ void LLTextureFetchWorker::callbackCacheRead(bool success, LLImageFormatted* ima
 		}
 	}
 	mLoaded = TRUE;
-	setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
 }																		// -Mw
 
 // Threads:  Ttc
@@ -2493,7 +2440,6 @@ void LLTextureFetchWorker::callbackCacheWrite(bool success)
 		return;
 	}
 	mWritten = TRUE;
-	setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
 }																		// -Mw
 
 //////////////////////////////////////////////////////////////////////////////
@@ -2532,7 +2478,6 @@ void LLTextureFetchWorker::callbackDecoded(bool success, LLImageRaw* raw, LLImag
 	}
 	mDecoded = TRUE;
 // 	LL_INFOS(LOG_TXT) << mID << " : DECODE COMPLETE " << LL_ENDL;
-	setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
 }																		// -Mw
 
 //////////////////////////////////////////////////////////////////////////////
@@ -2595,6 +2540,16 @@ void LLTextureFetchWorker::recordTextureDone(bool is_http, F64 byte_count)
 //////////////////////////////////////////////////////////////////////////////
 // public
 
+const char* LLTextureFetch::getStateString(S32 state)
+{
+    if (state < 0 || state > sizeof(e_state_name) / sizeof(char*))
+    {
+        return llformat("%d", state).c_str();
+    }
+
+    return e_state_name[state];
+}
+
 LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* imagedecodethread, bool threaded, bool qa_mode)
 	: LLWorkerThread("TextureFetch", threaded, true),
 	  mDebugCount(0),
@@ -2695,6 +2650,7 @@ LLTextureFetch::~LLTextureFetch()
 bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const LLUUID& id, const LLHost& host, F32 priority,
 								   S32 w, S32 h, S32 c, S32 desired_discard, bool needs_aux, bool can_use_http)
 {
+    LL_PROFILE_ZONE_SCOPED;
 	if(mFetcherLocked)
 	{
 		return false;
@@ -2786,7 +2742,7 @@ bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const
 			worker->setState(LLTextureFetchWorker::INIT);
 			worker->unlockWorkMutex();									// -Mw
 
-			worker->addWork(0, LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority);
+			worker->addWork(0);
 		}
 		else
 		{
@@ -2818,6 +2774,7 @@ bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const
 // protected
 void LLTextureFetch::addToNetworkQueue(LLTextureFetchWorker* worker)
 {
+    LL_PROFILE_ZONE_SCOPED;
 	lockQueue();														// +Mfq
 	bool in_request_map = (mRequestMap.find(worker->mID) != mRequestMap.end()) ;
 	unlockQueue();														// -Mfq
@@ -2839,6 +2796,7 @@ void LLTextureFetch::addToNetworkQueue(LLTextureFetchWorker* worker)
 // Threads:  T*
 void LLTextureFetch::removeFromNetworkQueue(LLTextureFetchWorker* worker, bool cancel)
 {
+    LL_PROFILE_ZONE_SCOPED;
 	LLMutexLock lock(&mNetworkQueueMutex);								// +Mfnq
 	size_t erased = mNetworkQueue.erase(worker->mID);
 	if (cancel && erased > 0)
@@ -2852,6 +2810,7 @@ void LLTextureFetch::removeFromNetworkQueue(LLTextureFetchWorker* worker, bool c
 // protected
 void LLTextureFetch::addToHTTPQueue(const LLUUID& id)
 {
+    LL_PROFILE_ZONE_SCOPED;
 	LLMutexLock lock(&mNetworkQueueMutex);								// +Mfnq
 	mHTTPTextureQueue.insert(id);
 	mTotalHTTPRequests++;
@@ -2860,6 +2819,7 @@ void LLTextureFetch::addToHTTPQueue(const LLUUID& id)
 // Threads:  T*
 void LLTextureFetch::removeFromHTTPQueue(const LLUUID& id, S32Bytes received_size)
 {
+    LL_PROFILE_ZONE_SCOPED;
 	LLMutexLock lock(&mNetworkQueueMutex);								// +Mfnq
 	mHTTPTextureQueue.erase(id);
 	mHTTPTextureBits += received_size; // Approximate - does not include header bits	
@@ -2872,6 +2832,7 @@ void LLTextureFetch::removeFromHTTPQueue(const LLUUID& id, S32Bytes received_siz
 // Threads:  T*
 void LLTextureFetch::deleteRequest(const LLUUID& id, bool cancel)
 {
+    LL_PROFILE_ZONE_SCOPED;
 	lockQueue();														// +Mfq
 	LLTextureFetchWorker* worker = getWorkerAfterLock(id);
 	if (worker)
@@ -2898,6 +2859,7 @@ void LLTextureFetch::deleteRequest(const LLUUID& id, bool cancel)
 // Threads:  T*
 void LLTextureFetch::removeRequest(LLTextureFetchWorker* worker, bool cancel)
 {
+    LL_PROFILE_ZONE_SCOPED;
 	if(!worker)
 	{
 		return;
@@ -2967,6 +2929,7 @@ U32 LLTextureFetch::getTotalNumHTTPRequests()
 // Locks:  Mfq
 LLTextureFetchWorker* LLTextureFetch::getWorkerAfterLock(const LLUUID& id)
 {
+    LL_PROFILE_ZONE_SCOPED;
 	LLTextureFetchWorker* res = NULL;
 	map_t::iterator iter = mRequestMap.find(id);
 	if (iter != mRequestMap.end())
@@ -2990,6 +2953,7 @@ bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level,
 										LLPointer<LLImageRaw>& raw, LLPointer<LLImageRaw>& aux,
 										LLCore::HttpStatus& last_http_get_status)
 {
+    LL_PROFILE_ZONE_SCOPED;
 	bool res = false;
 	LLTextureFetchWorker* worker = getWorker(id);
 	if (worker)
@@ -3004,7 +2968,7 @@ bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level,
 			if (!mDebugPause)
 			{
 // 				LL_WARNS(LOG_TXT) << "Adding work for inactive worker: " << id << LL_ENDL;
-				worker->addWork(0, LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority);
+				worker->addWork(0);
 			}
 		}
 		else if (worker->checkWork())
@@ -3080,6 +3044,7 @@ bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level,
 // Threads:  T*
 bool LLTextureFetch::updateRequestPriority(const LLUUID& id, F32 priority)
 {
+    LL_PROFILE_ZONE_SCOPED;
 	bool res = false;
 	LLTextureFetchWorker* worker = getWorker(id);
 	if (worker)
@@ -3106,6 +3071,7 @@ bool LLTextureFetch::updateRequestPriority(const LLUUID& id, F32 priority)
 //virtual
 S32 LLTextureFetch::getPending()
 {
+    LL_PROFILE_ZONE_SCOPED;
 	S32 res;
 	lockData();															// +Ct
     {
@@ -3139,7 +3105,7 @@ bool LLTextureFetch::runCondition()
 	}																	// -Mfq
 	
 	return ! (have_no_commands
-			  && (mRequestQueue.empty() && mIdleThread));		// From base class
+			  && (mRequestQueue.size() == 0 && mIdleThread));		// From base class
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -3147,6 +3113,7 @@ bool LLTextureFetch::runCondition()
 // Threads:  Ttf
 void LLTextureFetch::commonUpdate()
 {
+    LL_PROFILE_ZONE_SCOPED;
 	// Update low/high water levels based on pipelining.  We pick
 	// up setting eventually, so the semaphore/request level can
 	// fall outside the [0..HIGH_WATER] range.  Expect that.
@@ -3183,6 +3150,7 @@ void LLTextureFetch::commonUpdate()
 //virtual
 S32 LLTextureFetch::update(F32 max_time_ms)
 {
+    LL_PROFILE_ZONE_SCOPED;
 	static LLCachedControl<F32> band_width(gSavedSettings,"ThrottleBandwidthKBPS", 3000.0);
 
 	{
@@ -3266,6 +3234,7 @@ void LLTextureFetch::endThread()
 // Threads:  Ttf
 void LLTextureFetch::threadedUpdate()
 {
+    LL_PROFILE_ZONE_SCOPED;
 	llassert_always(mHttpRequest);
 
 #if 0
@@ -3301,6 +3270,7 @@ void LLTextureFetch::threadedUpdate()
 // Threads:  Tmain
 void LLTextureFetch::sendRequestListToSimulators()
 {
+    LL_PROFILE_ZONE_SCOPED;
 	// All requests
 	const F32 REQUEST_DELTA_TIME = 0.10f; // 10 fps
 	
@@ -3351,7 +3321,6 @@ void LLTextureFetch::sendRequestListToSimulators()
 				req->mLastPacket >= req->mTotalPackets-1)
 			{
 				// We have all the packets... make sure this is high priority
-// 			req->setPriority(LLWorkerThread::PRIORITY_HIGH | req->mWorkPriority);
 				continue;
 			}
 			F32 elapsed = req->mRequestedDeltaTimer.getElapsedTimeF32();
@@ -3498,6 +3467,7 @@ void LLTextureFetch::sendRequestListToSimulators()
 // Locks:  Mw
 bool LLTextureFetchWorker::insertPacket(S32 index, U8* data, S32 size)
 {
+    LL_PROFILE_ZONE_SCOPED;
 	mRequestedDeltaTimer.reset();
 	if (index >= mTotalPackets)
 	{
@@ -3530,6 +3500,7 @@ bool LLTextureFetchWorker::insertPacket(S32 index, U8* data, S32 size)
 
 void LLTextureFetchWorker::setState(e_state new_state)
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
 	if (mFTType == FTT_SERVER_BAKE)
 	{
 	// NOTE: turning on these log statements is a reliable way to get
@@ -3551,7 +3522,7 @@ void LLTextureFetchWorker::setState(e_state new_state)
 			mSkippedStatesTime += d_time;
 		}
 	}
-	
+
 	mStateTimer.reset();
 	mState = new_state;
 }
@@ -3560,6 +3531,7 @@ void LLTextureFetchWorker::setState(e_state new_state)
 bool LLTextureFetch::receiveImageHeader(const LLHost& host, const LLUUID& id, U8 codec, U16 packets, U32 totalbytes,
 										U16 data_size, U8* data)
 {
+    LL_PROFILE_ZONE_SCOPED;
 	LLTextureFetchWorker* worker = getWorker(id);
 	bool res = true;
 
@@ -3611,7 +3583,6 @@ bool LLTextureFetch::receiveImageHeader(const LLHost& host, const LLUUID& id, U8
 	llassert_always(totalbytes > 0);
 	llassert_always(data_size == FIRST_PACKET_SIZE || data_size == worker->mFileSize);
 	res = worker->insertPacket(0, data, data_size);
-	worker->setPriority(LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority);
 	worker->setState(LLTextureFetchWorker::LOAD_FROM_SIMULATOR);
 	worker->unlockWorkMutex();											// -Mw
 	return res;
@@ -3621,6 +3592,7 @@ bool LLTextureFetch::receiveImageHeader(const LLHost& host, const LLUUID& id, U8
 // Threads:  T*
 bool LLTextureFetch::receiveImagePacket(const LLHost& host, const LLUUID& id, U16 packet_num, U16 data_size, U8* data)
 {
+    LL_PROFILE_ZONE_SCOPED;
 	LLTextureFetchWorker* worker = getWorker(id);
 	bool res = true;
 
@@ -3661,7 +3633,6 @@ bool LLTextureFetch::receiveImagePacket(const LLHost& host, const LLUUID& id, U1
 	if ((worker->mState == LLTextureFetchWorker::LOAD_FROM_SIMULATOR) ||
 		(worker->mState == LLTextureFetchWorker::LOAD_FROM_NETWORK))
 	{
-		worker->setPriority(LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority);
 		worker->setState(LLTextureFetchWorker::LOAD_FROM_SIMULATOR);
 	}
 	else
@@ -3706,10 +3677,23 @@ BOOL LLTextureFetch::isFromLocalCache(const LLUUID& id)
 	return from_cache ;
 }
 
+S32 LLTextureFetch::getFetchState(const LLUUID& id)
+{
+    S32 state = LLTextureFetchWorker::INVALID;
+    LLTextureFetchWorker* worker = getWorker(id);
+    if (worker && worker->haveWork())
+    {
+        state = worker->mState;
+    }
+
+    return state;
+}
+
 // Threads:  T*
 S32 LLTextureFetch::getFetchState(const LLUUID& id, F32& data_progress_p, F32& requested_priority_p,
 								  U32& fetch_priority_p, F32& fetch_dtime_p, F32& request_dtime_p, bool& can_use_http)
 {
+    LL_PROFILE_ZONE_SCOPED;
 	S32 state = LLTextureFetchWorker::INVALID;
 	F32 data_progress = 0.0f;
 	F32 requested_priority = 0.0f;
@@ -3745,7 +3729,7 @@ S32 LLTextureFetch::getFetchState(const LLUUID& id, F32& data_progress_p, F32& r
 		{
 			requested_priority = worker->mImagePriority;
 		}
-		fetch_priority = worker->getPriority();
+		fetch_priority = worker->getImagePriority();
 		can_use_http = worker->getCanUseHTTP() ;
 		worker->unlockWorkMutex();										// -Mw
 	}
@@ -3759,19 +3743,6 @@ S32 LLTextureFetch::getFetchState(const LLUUID& id, F32& data_progress_p, F32& r
 
 void LLTextureFetch::dump()
 {
-	LL_INFOS(LOG_TXT) << "LLTextureFetch REQUESTS:" << LL_ENDL;
-	for (request_queue_t::iterator iter = mRequestQueue.begin();
-		 iter != mRequestQueue.end(); ++iter)
-	{
-		LLQueuedThread::QueuedRequest* qreq = *iter;
-		LLWorkerThread::WorkRequest* wreq = (LLWorkerThread::WorkRequest*)qreq;
-		LLTextureFetchWorker* worker = (LLTextureFetchWorker*)wreq->getWorkerClass();
-		LL_INFOS(LOG_TXT) << " ID: " << worker->mID
-						  << " PRI: " << llformat("0x%08x",wreq->getPriority())
-						  << " STATE: " << sStateDescs[worker->mState]
-						  << LL_ENDL;
-	}
-
 	LL_INFOS(LOG_TXT) << "LLTextureFetch ACTIVE_HTTP:" << LL_ENDL;
 	for (queue_t::const_iterator iter(mHTTPTextureQueue.begin());
 		 mHTTPTextureQueue.end() != iter;
@@ -3838,6 +3809,7 @@ bool LLTextureFetch::isHttpWaiter(const LLUUID & tid)
 // Locks:  -Mw (must not hold any worker when called)
 void LLTextureFetch::releaseHttpWaiters()
 {
+    LL_PROFILE_ZONE_SCOPED;
 	// Use mHttpSemaphore rather than mHTTPTextureQueue.size()
 	// to avoid a lock.  
 	if (mHttpSemaphore >= mHttpLowWater)
@@ -3934,7 +3906,6 @@ void LLTextureFetch::releaseHttpWaiters()
 		}
 		
 		worker->setState(LLTextureFetchWorker::SEND_HTTP_REQ);
-		worker->setPriority(LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority);
 		worker->unlockWorkMutex();										// -Mw
 
 		removeHttpWaiter(worker->mID);
@@ -4024,6 +3995,7 @@ void LLTextureFetch::commandDataBreak()
 // Threads:  T*
 void LLTextureFetch::cmdEnqueue(TFRequest * req)
 {
+    LL_PROFILE_ZONE_SCOPED;
 	lockQueue();														// +Mfq
 	mCommands.push_back(req);
 	unlockQueue();														// -Mfq
@@ -4034,6 +4006,7 @@ void LLTextureFetch::cmdEnqueue(TFRequest * req)
 // Threads:  T*
 LLTextureFetch::TFRequest * LLTextureFetch::cmdDequeue()
 {
+    LL_PROFILE_ZONE_SCOPED;
 	TFRequest * ret = 0;
 	
 	lockQueue();														// +Mfq
@@ -4050,6 +4023,7 @@ LLTextureFetch::TFRequest * LLTextureFetch::cmdDequeue()
 // Threads:  Ttf
 void LLTextureFetch::cmdDoWork()
 {
+    LL_PROFILE_ZONE_SCOPED;
 	if (mDebugPause)
 	{
 		return;  // debug: don't do any work
@@ -4140,6 +4114,7 @@ TFReqSendMetrics::~TFReqSendMetrics()
 bool
 TFReqSendMetrics::doWork(LLTextureFetch * fetcher)
 {
+    LL_PROFILE_ZONE_SCOPED;
 	static const U32 report_priority(1);
 	
 	//if (! gViewerAssetStatsThread1)
@@ -4183,7 +4158,6 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher)
 		// Don't care about handle, this is a fire-and-forget operation.  
 		LLCoreHttpUtil::requestPostWithLLSD(&fetcher->getHttpRequest(),
 											fetcher->getMetricsPolicyClass(),
-											report_priority,
 											mCapsURL,
 											mStatsSD,
 											LLCore::HttpOptions::ptr_t(),
@@ -4630,7 +4604,7 @@ void LLTextureFetchDebugger::debugCacheRead()
 	for(S32 i = 0 ; i < size ; i++)
 	{		
 		mFetchingHistory[i].mFormattedImage = NULL;
-		mFetchingHistory[i].mCacheHandle = mTextureCache->readFromCache(mFetchingHistory[i].mID, LLWorkerThread::PRIORITY_NORMAL, 0, mFetchingHistory[i].mFetchedSize, 
+		mFetchingHistory[i].mCacheHandle = mTextureCache->readFromCache(mFetchingHistory[i].mID, 0, mFetchingHistory[i].mFetchedSize, 
 			new LLDebuggerCacheReadResponder(this, i, mFetchingHistory[i].mFormattedImage));
 	}
 }
@@ -4667,8 +4641,8 @@ void LLTextureFetchDebugger::debugCacheWrite()
 	{		
 		if(mFetchingHistory[i].mFormattedImage.notNull())
 		{
-			mFetchingHistory[i].mCacheHandle = mTextureCache->writeToCache(mFetchingHistory[i].mID, LLWorkerThread::PRIORITY_NORMAL, 
-				mFetchingHistory[i].mFormattedImage->getData(), mFetchingHistory[i].mFetchedSize,
+			mFetchingHistory[i].mCacheHandle = mTextureCache->writeToCache(mFetchingHistory[i].mID,
+                mFetchingHistory[i].mFormattedImage->getData(), mFetchingHistory[i].mFetchedSize,
 				mFetchingHistory[i].mDecodedLevel == 0 ? mFetchingHistory[i].mFetchedSize : mFetchingHistory[i].mFetchedSize + 1, 
 				NULL, 0, new LLDebuggerCacheWriteResponder(this, i));					
 		}
@@ -4699,7 +4673,7 @@ void LLTextureFetchDebugger::debugDecoder()
 			continue;
 		}
 
-		mImageDecodeThread->decodeImage(mFetchingHistory[i].mFormattedImage, LLWorkerThread::PRIORITY_NORMAL, 
+		mImageDecodeThread->decodeImage(mFetchingHistory[i].mFormattedImage,
 			mFetchingHistory[i].mDecodedLevel, mFetchingHistory[i].mNeedsAux,
 			new LLDebuggerDecodeResponder(this, i));
 	}
@@ -4767,7 +4741,6 @@ S32 LLTextureFetchDebugger::fillCurlQueue()
 		requestedSize = (requestedSize == 33554432 ? 0 : requestedSize);
 
 		LLCore::HttpHandle handle = mFetcher->getHttpRequest().requestGetByteRange(mHttpPolicyClass,
-																				   LLWorkerThread::PRIORITY_LOWBITS,
 																				   texture_url,
 																				   0,
 																				   requestedSize,
diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h
index bf6732963f9..0cf9775af2e 100644
--- a/indra/newview/lltexturefetch.h
+++ b/indra/newview/lltexturefetch.h
@@ -59,6 +59,8 @@ class LLTextureFetch : public LLWorkerThread
 	friend class LLTextureFetchWorker;
 	
 public:
+    static const char* getStateString(S32 state);
+
 	LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* imagedecodethread, bool threaded, bool qa_mode);
 	~LLTextureFetch();
 
@@ -116,10 +118,11 @@ class LLTextureFetch : public LLWorkerThread
     // Threads:  T*
 	BOOL isFromLocalCache(const LLUUID& id);
 
-	// @return	Magic number giving the internal state of the
-	//			request.  We should make these codes public if we're
-	//			going to return them as a status value.
-	//
+    // get the current fetch state, if any, from the given UUID
+    S32 getFetchState(const LLUUID& id);
+
+	// @return	Fetch state of given image and associates statistics
+	//          See also getStateString
     // Threads:  T*
 	S32 getFetchState(const LLUUID& id, F32& decode_progress_p, F32& requested_priority_p,
 					  U32& fetch_priority_p, F32& fetch_dtime_p, F32& request_dtime_p, bool& can_use_http);
diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp
index 99ab8542935..f0e9cee101f 100644
--- a/indra/newview/lltextureview.cpp
+++ b/indra/newview/lltextureview.cpp
@@ -119,8 +119,8 @@ class LLTextureBar : public LLView
 			LLTextureBar* bar2p = (LLTextureBar*)i2;
 			LLViewerFetchedTexture *i1p = bar1p->mImagep;
 			LLViewerFetchedTexture *i2p = bar2p->mImagep;
-			F32 pri1 = i1p->getDecodePriority(); // i1p->mRequestedDownloadPriority
-			F32 pri2 = i2p->getDecodePriority(); // i2p->mRequestedDownloadPriority
+			F32 pri1 = i1p->getMaxVirtualSize();
+			F32 pri2 = i2p->getMaxVirtualSize();
 			if (pri1 > pri2)
 				return true;
 			else if (pri2 > pri1)
@@ -179,7 +179,7 @@ void LLTextureBar::draw()
 	{
 		color = LLColor4::magenta; // except none and alm
 	}
-	else if (mImagep->getDecodePriority() <= 0.0f)
+	else if (mImagep->getMaxVirtualSize() <= 0.0f)
 	{
 		color = LLColor4::grey; color[VALPHA] = .7f;
 	}
@@ -204,26 +204,13 @@ void LLTextureBar::draw()
 	std::string uuid_str;
 	mImagep->mID.toString(uuid_str);
 	uuid_str = uuid_str.substr(0,7);
-	if (mTextureView->mOrderFetch)
-	{
-		tex_str = llformat("%s %7.0f %d(%d) 0x%08x(%8.0f)",
-						   uuid_str.c_str(),
-						   mImagep->mMaxVirtualSize,
-						   mImagep->mDesiredDiscardLevel,
-						   mImagep->mRequestedDiscardLevel,
-						   mImagep->mFetchPriority,
-						   mImagep->getDecodePriority());
-	}
-	else
-	{
-		tex_str = llformat("%s %7.0f %d(%d) %8.0f(0x%08x)",
-						   uuid_str.c_str(),
-						   mImagep->mMaxVirtualSize,
-						   mImagep->mDesiredDiscardLevel,
-						   mImagep->mRequestedDiscardLevel,
-						   mImagep->getDecodePriority(),
-						   mImagep->mFetchPriority);
-	}
+	
+    tex_str = llformat("%s %7.0f %d(%d)",
+        uuid_str.c_str(),
+        mImagep->mMaxVirtualSize,
+        mImagep->mDesiredDiscardLevel,
+        mImagep->mRequestedDiscardLevel);
+
 
 	LLFontGL::getFontMonospace()->renderUTF8(tex_str, 0, title_x1, getRect().getHeight(),
 									 color, LLFontGL::LEFT, LLFontGL::TOP);
@@ -547,7 +534,7 @@ void LLGLTexMemBar::draw()
     U32 texFetchLatMed = U32(recording.getMean(LLTextureFetch::sTexFetchLatency).value() * 1000.0f);
     U32 texFetchLatMax = U32(recording.getMax(LLTextureFetch::sTexFetchLatency).value() * 1000.0f);
 
-    text = llformat("GL Free: %d Sys Free: %d MB FBO: %d MB Bias: %.2f Cache: %.1f/%.1f MB",
+    text = llformat("GL Free: %d MB Sys Free: %d MB FBO: %d MB Bias: %.2f Cache: %.1f/%.1f MB",
                     gViewerWindow->getWindow()->getAvailableVRAMMegabytes(),
                     LLMemory::getAvailableMemKB()/1024,
 					LLRenderTarget::sBytesAllocated/(1024*1024),
@@ -830,7 +817,7 @@ void LLTextureView::draw()
 				LL_INFOS() << imagep->getID()
 						<< "\t" << tex_mem
 						<< "\t" << imagep->getBoostLevel()
-						<< "\t" << imagep->getDecodePriority()
+						<< "\t" << imagep->getMaxVirtualSize()
 						<< "\t" << imagep->getWidth()
 						<< "\t" << imagep->getHeight()
 						<< "\t" << cur_discard
@@ -850,7 +837,7 @@ void LLTextureView::draw()
 			}
 			else
 			{
-				pri = imagep->getDecodePriority();
+				pri = imagep->getMaxVirtualSize();
 			}
 			pri = llclamp(pri, 0.0f, HIGH_PRIORITY-1.f);
 			
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index 46188716308..602597a86ba 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -341,12 +341,6 @@ static bool handleMaxPartCountChanged(const LLSD& newvalue)
 	return true;
 }
 
-static bool handleVideoMemoryChanged(const LLSD& newvalue)
-{
-	gTextureList.updateMaxResidentTexMem(S32Megabytes(newvalue.asInteger()));
-	return true;
-}
-
 static bool handleChatFontSizeChanged(const LLSD& newvalue)
 {
 	if(gConsole)
@@ -697,7 +691,6 @@ void settings_setup_listeners()
 	gSavedSettings.getControl("RenderShadowDetail")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
 	gSavedSettings.getControl("RenderDeferredSSAO")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
 	gSavedSettings.getControl("RenderPerformanceTest")->getSignal()->connect(boost::bind(&handleRenderPerfTestChanged, _2));
-	gSavedSettings.getControl("TextureMemory")->getSignal()->connect(boost::bind(&handleVideoMemoryChanged, _2));
 	gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&handleChatFontSizeChanged, _2));
 	gSavedSettings.getControl("ChatPersistTime")->getSignal()->connect(boost::bind(&handleChatPersistTimeChanged, _2));
 	gSavedSettings.getControl("ConsoleMaxLines")->getSignal()->connect(boost::bind(&handleConsoleMaxLinesChanged, _2));
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index ac6c86d9c60..06673b50fa8 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -78,6 +78,8 @@ LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sSmokeImagep = NULL;
 LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sFlatNormalImagep = NULL;
 LLViewerMediaTexture::media_map_t LLViewerMediaTexture::sMediaMap;
 LLTexturePipelineTester* LLViewerTextureManager::sTesterp = NULL;
+F32 LLViewerFetchedTexture::sMaxVirtualSize = F32_MAX/2.f;
+
 const std::string sTesterName("TextureTester");
 
 S32 LLViewerTexture::sImageCount = 0;
@@ -490,7 +492,7 @@ bool LLViewerTexture::isMemoryForTextureLow()
     S32Megabytes physical;
     getGPUMemoryForTextures(gpu, physical);
 
-    return (gpu < MIN_FREE_TEXTURE_MEMORY) || (physical < MIN_FREE_MAIN_MEMORY);
+    return (gpu < MIN_FREE_TEXTURE_MEMORY); // || (physical < MIN_FREE_MAIN_MEMORY);
 }
 
 //static
@@ -504,7 +506,7 @@ bool LLViewerTexture::isMemoryForTextureSuficientlyFree()
     S32Megabytes physical;
     getGPUMemoryForTextures(gpu, physical);
 
-    return (gpu > DESIRED_FREE_TEXTURE_MEMORY) && (physical > DESIRED_FREE_MAIN_MEMORY);
+    return (gpu > DESIRED_FREE_TEXTURE_MEMORY); // && (physical > DESIRED_FREE_MAIN_MEMORY);
 }
 
 //static
@@ -629,7 +631,6 @@ void LLViewerTexture::init(bool firstinit)
 	mMaxVirtualSize = 0.f;
 	mMaxVirtualSizeResetInterval = 1;
 	mMaxVirtualSizeResetCounter = mMaxVirtualSizeResetInterval;
-	mAdditionalDecodePriority = 0.f;	
 	mParcelMedia = NULL;
 	
 	memset(&mNumVolumes, 0, sizeof(U32)* LLRender::NUM_VOLUME_TEXTURE_CHANNELS);
@@ -796,15 +797,14 @@ void LLViewerTexture::addTextureStats(F32 virtual_size, BOOL needs_gltexture) co
 	}
 
 	virtual_size *= sTexelPixelRatio;
-	if(!mMaxVirtualSizeResetCounter)
+	/*if (!mMaxVirtualSizeResetCounter)
 	{
 		//flag to reset the values because the old values are used.
 		resetMaxVirtualSizeResetCounter();
 		mMaxVirtualSize = virtual_size;
-		mAdditionalDecodePriority = 0.f;
 		mNeedsGLTexture = needs_gltexture;
 	}
-	else if (virtual_size > mMaxVirtualSize)
+	else*/ if (virtual_size > mMaxVirtualSize)
 	{
 		mMaxVirtualSize = virtual_size;
 	}
@@ -813,7 +813,6 @@ void LLViewerTexture::addTextureStats(F32 virtual_size, BOOL needs_gltexture) co
 void LLViewerTexture::resetTextureStats()
 {
 	mMaxVirtualSize = 0.0f;
-	mAdditionalDecodePriority = 0.f;	
 	mMaxVirtualSizeResetCounter = 0;
 }
 
@@ -1082,7 +1081,6 @@ void LLViewerFetchedTexture::init(bool firstinit)
 
 	if (firstinit)
 	{
-		mDecodePriority = 0.f;
 		mInImageList = 0;
 	}
 
@@ -1131,6 +1129,7 @@ void LLViewerFetchedTexture::init(bool firstinit)
 
 LLViewerFetchedTexture::~LLViewerFetchedTexture()
 {
+    assert_main_thread();
 	//*NOTE getTextureFetch can return NULL when Viewer is shutting down.
 	// This is due to LLWearableList is singleton and is destroyed after 
 	// LLAppViewer::cleanup() was called. (see ticket EXT-177)
@@ -1563,6 +1562,7 @@ BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/)
 
 void LLViewerFetchedTexture::postCreateTexture()
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
     if (!mNeedsCreateTexture)
     {
         return;
@@ -1586,6 +1586,8 @@ void LLViewerFetchedTexture::postCreateTexture()
 
 void LLViewerFetchedTexture::scheduleCreateTexture()
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
+
     if (!mNeedsCreateTexture)
     {
         mNeedsCreateTexture = TRUE;
@@ -1662,6 +1664,7 @@ void LLViewerFetchedTexture::scheduleCreateTexture()
 //virtual
 void LLViewerFetchedTexture::setKnownDrawSize(S32 width, S32 height)
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
 	if(mKnownDrawWidth < width || mKnownDrawHeight < height)
 	{
 		mKnownDrawWidth = llmax(mKnownDrawWidth, width);
@@ -1673,9 +1676,31 @@ void LLViewerFetchedTexture::setKnownDrawSize(S32 width, S32 height)
 	addTextureStats((F32)(mKnownDrawWidth * mKnownDrawHeight));
 }
 
+void LLViewerFetchedTexture::setDebugText(const std::string& text)
+{
+    for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
+    {
+        llassert(mNumFaces[ch] <= mFaceList[ch].size());
+
+        for (U32 i = 0; i < mNumFaces[ch]; i++)
+        {
+            LLFace* facep = mFaceList[ch][i];
+            if (facep)
+            {
+                LLDrawable* drawable = facep->getDrawable();
+                if (drawable)
+                {
+                    drawable->getVObj()->setDebugText(text);
+                }
+            }
+        }
+    }
+}
+
 //virtual
 void LLViewerFetchedTexture::processTextureStats()
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
 	if(mFullyLoaded)
 	{		
 		if(mDesiredDiscardLevel > mMinDesiredDiscardLevel)//need to load more
@@ -1683,6 +1708,7 @@ void LLViewerFetchedTexture::processTextureStats()
 			mDesiredDiscardLevel = llmin(mDesiredDiscardLevel, mMinDesiredDiscardLevel);
 			mFullyLoaded = FALSE;
 		}
+        //setDebugText("fully loaded");
 	}
 	else
 	{
@@ -1695,7 +1721,7 @@ void LLViewerFetchedTexture::processTextureStats()
 			mDesiredDiscardLevel = 0;
 		}
 		else if (!LLPipeline::sRenderDeferred && mBoostLevel == LLGLTexture::BOOST_ALM)
-		{
+		{ // ??? don't load spec and normal maps when alm is disabled ???
 			mDesiredDiscardLevel = MAX_DISCARD_LEVEL + 1;
 		}
         else if (mDontDiscard && mBoostLevel == LLGLTexture::BOOST_ICON)
@@ -1760,191 +1786,9 @@ const S32 MAX_DELTA_DISCARD_LEVEL_FOR_PRIORITY       = 4;
 const F32 PRIORITY_ADDITIONAL_FACTOR                 = 1000000.f; //additional 
 const S32 MAX_ADDITIONAL_LEVEL_FOR_PRIORITY          = 8;
 const F32 PRIORITY_BOOST_HIGH_FACTOR                 = 10000000.f;//boost high
-F32 LLViewerFetchedTexture::calcDecodePriority()
-{
-#ifndef LL_RELEASE_FOR_DOWNLOAD
-	if (mID == LLAppViewer::getTextureFetch()->mDebugID)
-	{
-		LLAppViewer::getTextureFetch()->mDebugCount++; // for setting breakpoints
-	}
-#endif
-	
-	if (mNeedsCreateTexture)
-	{
-		return mDecodePriority; // no change while waiting to create
-	}
-	if(mFullyLoaded && !mForceToSaveRawImage)//already loaded for static texture
-	{
-		return -1.0f; //alreay fetched
-	}
-
-	S32 cur_discard = getCurrentDiscardLevelForFetching();
-	bool have_all_data = (cur_discard >= 0 && (cur_discard <= mDesiredDiscardLevel));
-	F32 pixel_priority = (F32) sqrt(mMaxVirtualSize);
-
-	F32 priority = 0.f;
-
-	if (mIsMissingAsset)
-	{
-		priority = 0.0f;
-	}
-	else if(mDesiredDiscardLevel >= cur_discard && cur_discard > -1)
-	{
-		priority = -2.0f;
-	}
-	else if(mCachedRawDiscardLevel > -1 && mDesiredDiscardLevel >= mCachedRawDiscardLevel)
-	{
-		priority = -3.0f;
-	}
-	else if (mDesiredDiscardLevel > getMaxDiscardLevel())
-	{
-		// Don't decode anything we don't need
-		priority = -4.0f;
-	}
-	else if ((mBoostLevel == LLGLTexture::BOOST_UI || mBoostLevel == LLGLTexture::BOOST_ICON) && !have_all_data)
-	{
-		priority = 1.f;
-	}
-	else if (pixel_priority < 0.001f && !have_all_data)
-	{
-		// Not on screen but we might want some data
-		if (mBoostLevel > BOOST_SELECTED)
-		{
-			// Always want high boosted images
-			priority = 1.f;
-		}
-		else
-		{
-			priority = -5.f; //stop fetching
-		}
-	}
-	else if (cur_discard < 0)
-	{
-		//texture does not have any data, so we don't know the size of the image, treat it like 32 * 32.
-		// priority range = 100,000 - 500,000
-		static const F64 log_2 = log(2.0);
-		F32 desired = (F32)(log(32.0/pixel_priority) / log_2);
-		S32 ddiscard = MAX_DISCARD_LEVEL - (S32)desired;
-		ddiscard = llclamp(ddiscard, 0, MAX_DELTA_DISCARD_LEVEL_FOR_PRIORITY);
-		priority = (ddiscard + 1) * PRIORITY_DELTA_DISCARD_LEVEL_FACTOR;
-		setAdditionalDecodePriority(0.1f);//boost the textures without any data so far.
-	}
-	else if ((mMinDiscardLevel > 0) && (cur_discard <= mMinDiscardLevel))
-	{
-		// larger mips are corrupted
-		priority = -6.0f;
-	}
-	else
-	{
-		// priority range = 100,000 - 500,000
-		S32 desired_discard = mDesiredDiscardLevel;
-		if (!isJustBound() && mCachedRawImageReady)
-		{
-			if(mBoostLevel < BOOST_HIGH)
-			{
-				// We haven't rendered this in a while, de-prioritize it
-				desired_discard += 2;
-			}
-			else
-			{
-				// We haven't rendered this in the last half second, and we have a cached raw image, leave the desired discard as-is
-				desired_discard = cur_discard;
-			}
-		}
-
-		S32 ddiscard = cur_discard - desired_discard;
-		ddiscard = llclamp(ddiscard, -1, MAX_DELTA_DISCARD_LEVEL_FOR_PRIORITY);
-		priority = (ddiscard + 1) * PRIORITY_DELTA_DISCARD_LEVEL_FACTOR;		
-	}
-
-	// Priority Formula:
-	// BOOST_HIGH  +  ADDITIONAL PRI + DELTA DISCARD + BOOST LEVEL + PIXELS
-	// [10,000,000] + [1,000,000-9,000,000]  + [100,000-500,000]   + [1-20,000]  + [0-999]
-	if (priority > 0.0f)
-	{
-		bool large_enough = mCachedRawImageReady && ((S32)mTexelsPerImage > sMinLargeImageSize);
-		if(large_enough)
-		{
-			//Note: 
-			//to give small, low-priority textures some chance to be fetched, 
-			//cut the priority in half if the texture size is larger than 256 * 256 and has a 64*64 ready.
-			priority *= 0.5f; 
-		}
-
-		pixel_priority = llclamp(pixel_priority, 0.0f, MAX_PRIORITY_PIXEL); 
-
-		priority += pixel_priority + PRIORITY_BOOST_LEVEL_FACTOR * mBoostLevel;
-
-		if ( mBoostLevel > BOOST_HIGH)
-		{
-			if(mBoostLevel > BOOST_SUPER_HIGH)
-			{
-				//for very important textures, always grant the highest priority.
-				priority += PRIORITY_BOOST_HIGH_FACTOR;
-			}
-			else if(mCachedRawImageReady)
-			{
-				//Note: 
-				//to give small, low-priority textures some chance to be fetched, 
-				//if high priority texture has a 64*64 ready, lower its fetching priority.
-				setAdditionalDecodePriority(0.5f);
-			}
-			else
-			{
-				priority += PRIORITY_BOOST_HIGH_FACTOR;
-			}
-		}		
-
-		if(mAdditionalDecodePriority > 0.0f)
-		{
-			// priority range += 1,000,000.f-9,000,000.f
-			F32 additional = PRIORITY_ADDITIONAL_FACTOR * (1.0 + mAdditionalDecodePriority * MAX_ADDITIONAL_LEVEL_FOR_PRIORITY);
-			if(large_enough)
-			{
-				//Note: 
-				//to give small, low-priority textures some chance to be fetched, 
-				//cut the additional priority to a quarter if the texture size is larger than 256 * 256 and has a 64*64 ready.
-				additional *= 0.25f;
-			}
-			priority += additional;
-		}
-	}
-	return priority;
-}
-
-//static
-F32 LLViewerFetchedTexture::maxDecodePriority()
-{
-	static const F32 max_priority = PRIORITY_BOOST_HIGH_FACTOR +                           //boost_high
-		PRIORITY_ADDITIONAL_FACTOR * (MAX_ADDITIONAL_LEVEL_FOR_PRIORITY + 1) +             //additional (view dependent factors)
-		PRIORITY_DELTA_DISCARD_LEVEL_FACTOR * (MAX_DELTA_DISCARD_LEVEL_FOR_PRIORITY + 1) + //delta discard
-		PRIORITY_BOOST_LEVEL_FACTOR * (BOOST_MAX_LEVEL - 1) +                              //boost level
-		MAX_PRIORITY_PIXEL + 1.0f;                                                        //pixel area.
-	
-	return max_priority;
-}
 
 //============================================================================
 
-void LLViewerFetchedTexture::setDecodePriority(F32 priority)
-{
-	mDecodePriority = priority;
-
-	if(mDecodePriority < F_ALMOST_ZERO)
-	{
-		mStopFetchingTimer.reset();
-	}
-}
-
-void LLViewerFetchedTexture::setAdditionalDecodePriority(F32 priority)
-{
-	priority = llclamp(priority, 0.f, 1.f);
-	if(mAdditionalDecodePriority < priority)
-	{
-		mAdditionalDecodePriority = priority;
-	}
-}
-
 void LLViewerFetchedTexture::updateVirtualSize() 
 {	
     LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
@@ -1953,6 +1797,12 @@ void LLViewerFetchedTexture::updateVirtualSize()
 		addTextureStats(0.f, FALSE);//reset
 	}
 
+    if (getBoostLevel() >= LLViewerTexture::BOOST_HIGH)
+    { //always load boosted textures at highest priority full res
+        addTextureStats(sMaxVirtualSize);
+        return;
+    }
+
 	for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
 	{				
 		llassert(mNumFaces[ch] <= mFaceList[ch].size());
@@ -1974,8 +1824,12 @@ void LLViewerFetchedTexture::updateVirtualSize()
 						setBoostLevel(LLViewerTexture::BOOST_SELECTED);
 					}
 					addTextureStats(facep->getVirtualSize());
-					setAdditionalDecodePriority(facep->getImportanceToCamera());
+                    //drawable->getVObj()->setDebugText(llformat("%d:%d", (S32)sqrtf(facep->getVirtualSize()), (S32)sqrtf(getMaxVirtualSize())));
 				}
+                else
+                {
+                    //drawable->getVObj()->setDebugText("");
+                }
 			}
 		}
 	}
@@ -2063,31 +1917,35 @@ bool LLViewerFetchedTexture::updateFetch()
 
 	if (mNeedsCreateTexture)
 	{
+        LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - needs create");
 		// We may be fetching still (e.g. waiting on write)
 		// but don't check until we've processed the raw data we have
 		return false;
 	}
 	if (mIsMissingAsset)
 	{
+        LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - missing asset");
 		llassert_always(!mHasFetcher);
 		return false; // skip
 	}
 	if (!mLoadedCallbackList.empty() && mRawImage.notNull())
 	{
+        LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - callback pending");
 		return false; // process any raw image data in callbacks before replacing
 	}
 	if(mInFastCacheList)
 	{
+        LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - in fast cache");
 		return false;
 	}
 	
 	S32 current_discard = getCurrentDiscardLevelForFetching();
 	S32 desired_discard = getDesiredDiscardLevel();
-	F32 decode_priority = getDecodePriority();
-	decode_priority = llclamp(decode_priority, 0.0f, maxDecodePriority());
+	F32 decode_priority = mMaxVirtualSize;
 
 	if (mIsFetching)
 	{
+        LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - is fetching");
 		// Sets mRawDiscardLevel, mRawImage, mAuxRawImage
 		S32 fetch_discard = current_discard;
 		
@@ -2105,17 +1963,25 @@ bool LLViewerFetchedTexture::updateFetch()
 		if (finished)
 		{
 			mIsFetching = FALSE;
+            mLastFetchState = -1;
+            setDebugText("");
 			mLastPacketTimer.reset();
 		}
 		else
 		{
 			mFetchState = LLAppViewer::getTextureFetch()->getFetchState(mID, mDownloadProgress, mRequestedDownloadPriority,
 																		mFetchPriority, mFetchDeltaTime, mRequestDeltaTime, mCanUseHTTP);
+            if (mFetchState != mLastFetchState)
+            {
+                setDebugText(LLTextureFetch::getStateString(mFetchState));
+                mLastFetchState = mFetchState;
+            }
 		}
 		
 		// We may have data ready regardless of whether or not we are finished (e.g. waiting on write)
 		if (mRawImage.notNull())
 		{
+            LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - has raw image");
 			LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName);
 			if (tester)
 			{
@@ -2126,6 +1992,7 @@ bool LLViewerFetchedTexture::updateFetch()
 			if ((mRawImage->getDataSize() > 0 && mRawDiscardLevel >= 0) &&
 				(current_discard < 0 || mRawDiscardLevel < current_discard))
 			{
+                LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - data good");
 				mFullWidth = mRawImage->getWidth() << mRawDiscardLevel;
 				mFullHeight = mRawImage->getHeight() << mRawDiscardLevel;
 				setTexelsPerImage();
@@ -2162,6 +2029,7 @@ bool LLViewerFetchedTexture::updateFetch()
 			}
 			else
 			{
+                LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - data not needed");
 				// Data is ready but we don't need it
 				// (received it already while fetcher was writing to disk)
 				destroyRawImage();
@@ -2194,13 +2062,13 @@ bool LLViewerFetchedTexture::updateFetch()
 					if(current_discard >= 0)
 					{
 						mMinDiscardLevel = current_discard;
-						desired_discard = current_discard;
+						//desired_discard = current_discard;
 					}
 					else
 					{
 						S32 dis_level = getDiscardLevel();
 						mMinDiscardLevel = dis_level;
-						desired_discard = dis_level;
+						//desired_discard = dis_level;
 					}
 				}
 				destroyRawImage();
@@ -2214,12 +2082,6 @@ bool LLViewerFetchedTexture::updateFetch()
 		}
 		else
 		{
-// 			// Useful debugging code for undesired deprioritization of textures.
-// 			if (decode_priority <= 0.0f && desired_discard >= 0 && desired_discard < current_discard)
-// 			{
-// 				LL_INFOS() << "Calling updateRequestPriority() with decode_priority = 0.0f" << LL_ENDL;
-// 				calcDecodePriority();
-// 			}
 			static const F32 MAX_HOLD_TIME = 5.0f; //seconds to wait before canceling fecthing if decode_priority is 0.f.
 			if(decode_priority > 0.0f || mStopFetchingTimer.getElapsedTimeF32() > MAX_HOLD_TIME)
 			{
@@ -2229,21 +2091,27 @@ bool LLViewerFetchedTexture::updateFetch()
 		}
 	}
 
+    desired_discard = llmin(desired_discard, getMaxDiscardLevel());
+
 	bool make_request = true;	
-	if (decode_priority <= 0)
+	/*if (decode_priority <= 0)
 	{
+        LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - priority <= 0");
 		make_request = false;
 	}
 	else if(mDesiredDiscardLevel > getMaxDiscardLevel())
 	{
+        LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - desired > max");
 		make_request = false;
 	}
-	else if (mNeedsCreateTexture || mIsMissingAsset)
+	else */ if (mNeedsCreateTexture || mIsMissingAsset)
 	{
+        LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - create or missing");
 		make_request = false;
 	}
 	else if (current_discard >= 0 && current_discard <= mMinDiscardLevel)
 	{
+        LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - current < min");
 		make_request = false;
 	}
 	else if(mCachedRawImage.notNull() // can be empty
@@ -2260,6 +2128,7 @@ bool LLViewerFetchedTexture::updateFetch()
 	
 	if (make_request)
 	{
+#if 0
 		// Load the texture progressively: we try not to rush to the desired discard too fast.
 		// If the camera is not moving, we do not tweak the discard level notch by notch but go to the desired discard with larger boosted steps
 		// This mitigates the "textures stay blurry" problem when loading while not killing the texture memory while moving around
@@ -2276,18 +2145,23 @@ bool LLViewerFetchedTexture::updateFetch()
         {
 			desired_discard = llmax(desired_discard, current_discard - delta_level);
         }
+#endif
 
 		if (mIsFetching)
 		{
+            // already requested a higher resolution mip
 			if (mRequestedDiscardLevel <= desired_discard)
 			{
+                LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - requested < desired");
 				make_request = false;
 			}
 		}
 		else
 		{
+            // already at a higher resolution mip, don't discard
 			if (current_discard >= 0 && current_discard <= desired_discard)
 			{
+                LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - current <= desired");
 				make_request = false;
 			}
 		}
@@ -2295,6 +2169,7 @@ bool LLViewerFetchedTexture::updateFetch()
 	
 	if (make_request)
 	{
+        LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - make request");
 		S32 w=0, h=0, c=0;
 		if (getDiscardLevel() >= 0)
 		{
@@ -2316,6 +2191,7 @@ bool LLViewerFetchedTexture::updateFetch()
 		
 		if (fetch_request_created)
 		{
+            LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - request created");
 			mHasFetcher = TRUE;
 			mIsFetching = TRUE;
 			mRequestedDiscardLevel = desired_discard;
@@ -2331,7 +2207,7 @@ bool LLViewerFetchedTexture::updateFetch()
 		// Only delete requests that haven't received any network data
 		// for a while.  Note - this is the normal mechanism for
 		// deleting requests, not just a place to handle timeouts.
-		const F32 FETCH_IDLE_TIME = 5.f;
+		const F32 FETCH_IDLE_TIME = 0.1f;
 		if (mLastPacketTimer.getElapsedTimeF32() > FETCH_IDLE_TIME)
 		{
  			LL_DEBUGS("Texture") << "exceeded idle time " << FETCH_IDLE_TIME << ", deleting request: " << getID() << LL_ENDL;
@@ -2641,7 +2517,7 @@ bool LLViewerFetchedTexture::doLoadedCallbacks()
 			LL_INFOS() << "baked texture: " << mID << "clears all call backs due to inactivity." << LL_ENDL;
 			LL_INFOS() << mUrl << LL_ENDL;
 			LL_INFOS() << "current discard: " << getDiscardLevel() << " current discard for fetch: " << getCurrentDiscardLevelForFetching() <<
-				" Desired discard: " << getDesiredDiscardLevel() << "decode Pri: " << getDecodePriority() << LL_ENDL;
+				" Desired discard: " << getDesiredDiscardLevel() << "decode Pri: " << mMaxVirtualSize << LL_ENDL;
 		}
 
 		clearCallbackEntryList() ; //remove all callbacks.
@@ -2872,7 +2748,7 @@ void LLViewerFetchedTexture::forceImmediateUpdate()
 		return;
 	}
 	//if already called forceImmediateUpdate()
-	if(mInImageList && mDecodePriority == LLViewerFetchedTexture::maxDecodePriority())
+	if(mInImageList && mMaxVirtualSize == LLViewerFetchedTexture::sMaxVirtualSize)
 	{
 		return;
 	}
@@ -2941,6 +2817,7 @@ bool LLViewerFetchedTexture::needsToSaveRawImage()
 
 void LLViewerFetchedTexture::destroyRawImage()
 {	
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
 	if (mAuxRawImage.notNull() && !needsToSaveRawImage())
 	{
 		sAuxCount--;
@@ -3024,6 +2901,7 @@ void LLViewerFetchedTexture::setCachedRawImage(S32 discard_level, LLImageRaw* im
 
 void LLViewerFetchedTexture::setCachedRawImage()
 {	
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
 	if(mRawImage == mCachedRawImage)
 	{
 		return;
@@ -3099,6 +2977,7 @@ void LLViewerFetchedTexture::checkCachedRawSculptImage()
 
 void LLViewerFetchedTexture::saveRawImage() 
 {
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
 	if(mRawImage.isNull() || mRawImage == mSavedRawImage || (mSavedRawDiscardLevel >= 0 && mSavedRawDiscardLevel <= mRawDiscardLevel))
 	{
 		return;
@@ -3314,25 +3193,10 @@ void LLViewerLODTexture::processTextureStats()
 		}
 		else
 		{
-			if(isLargeImage() && !isJustBound() && mAdditionalDecodePriority < 0.3f)
-			{
-				//if is a big image and not being used recently, nor close to the view point, do not load hi-res data.
-				mMaxVirtualSize = llmin(mMaxVirtualSize, (F32)LLViewerTexture::sMinLargeImageSize);
-			}
-
-			if ((mCalculatedDiscardLevel >= 0.f) &&
-				(llabs(mMaxVirtualSize - mDiscardVirtualSize) < mMaxVirtualSize*.20f))
-			{
-				// < 20% change in virtual size = no change in desired discard
-				discard_level = mCalculatedDiscardLevel; 
-			}
-			else
-			{
-				// Calculate the required scale factor of the image using pixels per texel
-				discard_level = (F32)(log(mTexelsPerImage/mMaxVirtualSize) / log_4);
-				mDiscardVirtualSize = mMaxVirtualSize;
-				mCalculatedDiscardLevel = discard_level;
-			}
+			// Calculate the required scale factor of the image using pixels per texel
+			discard_level = (F32)(log(mTexelsPerImage/mMaxVirtualSize) / log_4);
+			mDiscardVirtualSize = mMaxVirtualSize;
+			mCalculatedDiscardLevel = discard_level;
 		}
 		if (mBoostLevel < LLGLTexture::BOOST_SCULPTED)
 		{
diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h
index 0640efe6df8..ece67945922 100644
--- a/indra/newview/llviewertexture.h
+++ b/indra/newview/llviewertexture.h
@@ -194,14 +194,14 @@ class LLViewerTexture : public LLGLTexture
 public:
     static bool isMemoryForTextureLow();
 protected:
+    friend class LLViewerTextureList;
 	LLUUID mID;
 	S32 mTextureListType; // along with mID identifies where to search for this texture in TextureList
 
 	F32 mSelectedTime;				// time texture was last selected
 	mutable F32 mMaxVirtualSize;	// The largest virtual size of the image, in pixels - how much data to we need?	
-	mutable S32  mMaxVirtualSizeResetCounter ;
+	mutable S32  mMaxVirtualSizeResetCounter;
 	mutable S32  mMaxVirtualSizeResetInterval;
-	mutable F32 mAdditionalDecodePriority;  // priority add to mDecodePriority.
 	LLFrameTimer mLastReferencedTimer;	
 
 	ll_face_list_t    mFaceList[LLRender::NUM_TEXTURE_CHANNELS]; //reverse pointer pointing to the faces using this image as texture
@@ -281,7 +281,6 @@ class LLViewerFetchedTexture : public LLViewerTexture
 	LLViewerFetchedTexture(const std::string& url, FTType f_type, const LLUUID& id, BOOL usemipmaps = TRUE);
 
 public:
-	static F32 maxDecodePriority();
 	
 	struct Compare
 	{
@@ -290,9 +289,10 @@ class LLViewerFetchedTexture : public LLViewerTexture
 		{
 			const LLViewerFetchedTexture* lhsp = (const LLViewerFetchedTexture*)lhs;
 			const LLViewerFetchedTexture* rhsp = (const LLViewerFetchedTexture*)rhs;
+            
 			// greater priority is "less"
-			const F32 lpriority = lhsp->getDecodePriority();
-			const F32 rpriority = rhsp->getDecodePriority();
+			const F32 lpriority = lhsp->mMaxVirtualSize;
+			const F32 rpriority = rhsp->mMaxVirtualSize;
 			if (lpriority > rpriority) // higher priority
 				return true;
 			if (lpriority < rpriority)
@@ -331,7 +331,6 @@ class LLViewerFetchedTexture : public LLViewerTexture
 	void destroyTexture() ;
 
 	virtual void processTextureStats() ;
-	F32  calcDecodePriority() ;
 
 	BOOL needsAux() const { return mNeedsAux; }
 
@@ -339,15 +338,6 @@ class LLViewerFetchedTexture : public LLViewerTexture
 	void setTargetHost(LLHost host)			{ mTargetHost = host; }
 	LLHost getTargetHost() const			{ return mTargetHost; }
 	
-	// Set the decode priority for this image...
-	// DON'T CALL THIS UNLESS YOU KNOW WHAT YOU'RE DOING, it can mess up
-	// the priority list, and cause horrible things to happen.
-	void setDecodePriority(F32 priority = -1.0f);
-	F32 getDecodePriority() const { return mDecodePriority; };
-	F32 getAdditionalDecodePriority() const { return mAdditionalDecodePriority; };
-
-	void setAdditionalDecodePriority(F32 priority) ;
-	
 	void updateVirtualSize() ;
 
 	S32  getDesiredDiscardLevel()			 { return mDesiredDiscardLevel; }
@@ -367,6 +357,10 @@ class LLViewerFetchedTexture : public LLViewerTexture
 	// more data.
 	/*virtual*/ void setKnownDrawSize(S32 width, S32 height);
 
+    // Set the debug text of all Viewer Objects associated with this texture
+    // to the specified text
+    void setDebugText(const std::string& text);
+
 	void setIsMissingAsset(BOOL is_missing = true);
 	/*virtual*/ BOOL isMissingAsset() const { return mIsMissingAsset; }
 
@@ -468,11 +462,11 @@ class LLViewerFetchedTexture : public LLViewerTexture
 	S32 mRequestedDiscardLevel;
 	F32 mRequestedDownloadPriority;
 	S32 mFetchState;
+    S32 mLastFetchState = -1; // DEBUG
 	U32 mFetchPriority;
 	F32 mDownloadProgress;
 	F32 mFetchDeltaTime;
 	F32 mRequestDeltaTime;
-	F32 mDecodePriority;			// The priority for decoding this image.
 	S32	mMinDiscardLevel;
 	S8  mDesiredDiscardLevel;			// The discard level we'd LIKE to have - if we have it and there's space	
 	S8  mMinDesiredDiscardLevel;	// The minimum discard level we'd like to have
@@ -530,6 +524,7 @@ class LLViewerFetchedTexture : public LLViewerTexture
 	BOOL   mIsFetched ; //is loaded from remote or from cache, not generated locally.
 
 public:
+    static F32 sMaxVirtualSize; //maximum possible value of mMaxVirtualSize
 	static LLPointer<LLViewerFetchedTexture> sMissingAssetImagep;	// Texture to show for an image asset that is not in the database
 	static LLPointer<LLViewerFetchedTexture> sWhiteImagep;	// Texture to show NOTHING (whiteness)
 	static LLPointer<LLViewerFetchedTexture> sDefaultImagep; // "Default" texture for error cases, the only case of fetched texture which is generated in local.
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index 2a88d9314b3..80565b02384 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -89,8 +89,6 @@ LLTextureKey::LLTextureKey(LLUUID id, ETexListType tex_type)
 
 LLViewerTextureList::LLViewerTextureList() 
 	: mForceResetTextureStats(FALSE),
-	mMaxResidentTexMemInMegaBytes(0),
-	mMaxTotalTextureMemInMegaBytes(0),
 	mInitialized(FALSE)
 {
 }
@@ -99,12 +97,6 @@ void LLViewerTextureList::init()
 {			
 	mInitialized = TRUE ;
 	sNumImages = 0;
-	mMaxResidentTexMemInMegaBytes = (U32Bytes)0;
-	mMaxTotalTextureMemInMegaBytes = (U32Bytes)0;
-	
-	// Update how much texture RAM we're allowed to use.
-	updateMaxResidentTexMem(S32Megabytes(0)); // 0 = use current
-	
 	doPreloadImages();
 }
 
@@ -342,7 +334,7 @@ void LLViewerTextureList::dump()
 	{
 		LLViewerFetchedTexture* image = *it;
 
-		LL_INFOS() << "priority " << image->getDecodePriority()
+		LL_INFOS() << "priority " << image->getMaxVirtualSize()
 		<< " boost " << image->getBoostLevel()
 		<< " size " << image->getWidth() << "x" << image->getHeight()
 		<< " discard " << image->getDiscardLevel()
@@ -667,13 +659,14 @@ void LLViewerTextureList::removeImageFromList(LLViewerFetchedTexture *image)
 	assert_main_thread();
 	llassert_always(mInitialized) ;
 	llassert(image);
+    image->validateRefCount();
 
 	S32 count = 0;
 	if (image->isInImageList())
 	{
 		count = mImageList.erase(image) ;
 		if(count != 1) 
-	{
+	    {
 			LL_INFOS() << "Image  " << image->getID() 
 				<< " had mInImageList set but mImageList.erase() returned " << count
 				<< LL_ENDL;
@@ -699,6 +692,7 @@ void LLViewerTextureList::removeImageFromList(LLViewerFetchedTexture *image)
 			LL_INFOS() << "Image  " << image->getID() << " was in mUUIDMap with same pointer" << LL_ENDL ;
 		}
 		count = mImageList.erase(image) ;
+        llassert(count != 0);
 		if(count != 0) 
 		{	// it was in the list already?
 			LL_WARNS() << "Image  " << image->getID() 
@@ -822,7 +816,6 @@ void LLViewerTextureList::updateImages(F32 max_time)
 			didone = image->doLoadedCallbacks();
 		}
 	}
-	
 
 	updateImagesUpdateStats();
 }
@@ -847,118 +840,102 @@ void LLViewerTextureList::clearFetchingRequests()
 
 void LLViewerTextureList::updateImagesDecodePriorities()
 {
+#if 0
     LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
-	// Update the decode priority for N images each frame
-	{
-		F32 lazy_flush_timeout = 30.f; // stop decoding
-		F32 max_inactive_time  = 20.f; // actually delete
-		S32 min_refs = 3; // 1 for mImageList, 1 for mUUIDMap, 1 for local reference
-
-		//reset imagep->getLastReferencedTimer() when screen is showing the progress view to avoid removing pre-fetched textures too soon.
-		bool reset_timer = gViewerWindow->getProgressView()->getVisible();
-        
-        static const S32 MAX_PRIO_UPDATES = gSavedSettings.getS32("TextureFetchUpdatePriorities");         // default: 32
-		const size_t max_update_count = llmin((S32) (MAX_PRIO_UPDATES*MAX_PRIO_UPDATES*gFrameIntervalSeconds.value()) + 1, MAX_PRIO_UPDATES);
-		S32 update_counter = llmin(max_update_count, mUUIDMap.size());
-		uuid_map_t::iterator iter = mUUIDMap.upper_bound(mLastUpdateKey);
-		while ((update_counter-- > 0) && !mUUIDMap.empty())
-		{
-			if (iter == mUUIDMap.end())
-			{
-				iter = mUUIDMap.begin();
-            }
-            mLastUpdateKey = iter->first;
-			LLPointer<LLViewerFetchedTexture> imagep = iter->second;
-			++iter; // safe to increment now
+    // Update the decode priority for N images each frame
+    
+    /*static const S32 MAX_PRIO_UPDATES = gSavedSettings.getS32("TextureFetchUpdatePriorities");         // default: 32
+    const size_t max_update_count = llmin((S32) (MAX_PRIO_UPDATES*MAX_PRIO_UPDATES*gFrameIntervalSeconds.value()) + 1, MAX_PRIO_UPDATES);
+    S32 update_counter = llmin(max_update_count, mUUIDMap.size());
+    uuid_map_t::iterator iter = mUUIDMap.upper_bound(mLastUpdateKey);*/
+    //while ((update_counter-- > 0) && !mUUIDMap.empty())
+    for (uuid_map_t::iterator iter = mUUIDMap.begin(); iter != mUUIDMap.end(); ++iter)
+    {
+        /*if (iter == mUUIDMap.end())
+        {
+            iter = mUUIDMap.begin();
+        }*/
+        mLastUpdateKey = iter->first;
+        LLPointer<LLViewerFetchedTexture> imagep = iter->second;
+        //++iter; // safe to increment now
 
-			if(imagep->isInDebug() || imagep->isUnremovable())
-			{
-				update_counter--;
-				continue; //is in debug, ignore.
-			}
+        updateImageDecodePriority(imagep);
+    }
+#endif
+}
 
-			//
-			// Flush formatted images using a lazy flush
-			//
-			S32 num_refs = imagep->getNumRefs();
-			if (num_refs == min_refs)
-			{
-				if(reset_timer)
-				{
-					imagep->getLastReferencedTimer()->reset();
-				}
-				else if (imagep->getLastReferencedTimer()->getElapsedTimeF32() > lazy_flush_timeout)
-				{
-					// Remove the unused image from the image list
-					deleteImage(imagep);
-					imagep = NULL; // should destroy the image								
-				}
-				continue;
-			}
-			else
-			{
-				if(imagep->hasSavedRawImage())
-				{
-					if(imagep->getElapsedLastReferencedSavedRawImageTime() > max_inactive_time)
-					{
-						imagep->destroySavedRawImage() ;
-					}
-				}
+void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imagep)
+{
+    if (imagep->isInDebug() || imagep->isUnremovable())
+    {
+        //update_counter--;
+        return; //is in debug, ignore.
+    }
 
-				if(imagep->isDeleted())
-				{
-					continue ;
-				}
-				else if(imagep->isDeletionCandidate())
-				{
-					imagep->destroyTexture() ;																
-					continue ;
-				}
-				else if(imagep->isInactive())
-				{
-					if(reset_timer)
-					{
-						imagep->getLastReferencedTimer()->reset();
-					}
-					else if (imagep->getLastReferencedTimer()->getElapsedTimeF32() > max_inactive_time)
-					{
-						imagep->setDeletionCandidate() ;
-					}
-					continue ;
-				}
-				else
-				{
-					imagep->getLastReferencedTimer()->reset();
+    F32 lazy_flush_timeout = 30.f; // stop decoding
+    F32 max_inactive_time = 20.f; // actually delete
+    S32 min_refs = 3; // 1 for mImageList, 1 for mUUIDMap, 1 for local reference
 
-					//reset texture state.
-					imagep->setInactive() ;										
-				}
-			}
+    //
+    // Flush formatted images using a lazy flush
+    //
+    S32 num_refs = imagep->getNumRefs();
+    if (num_refs == min_refs)
+    {
+        if (imagep->getLastReferencedTimer()->getElapsedTimeF32() > lazy_flush_timeout)
+        {
+            // Remove the unused image from the image list
+            deleteImage(imagep);
+            imagep = NULL; // should destroy the image								
+        }
+        return;
+    }
+    else
+    {
+        if (imagep->hasSavedRawImage())
+        {
+            if (imagep->getElapsedLastReferencedSavedRawImageTime() > max_inactive_time)
+            {
+                imagep->destroySavedRawImage();
+            }
+        }
 
-			if (!imagep->isInImageList())
-			{
-				continue;
-			}
-			if(imagep->isInFastCacheList())
-			{
-				continue; //wait for loading from the fast cache.
-			}
+        if (imagep->isDeleted())
+        {
+            return;
+        }
+        else if (imagep->isDeletionCandidate())
+        {
+            imagep->destroyTexture();
+            return;
+        }
+        else if (imagep->isInactive())
+        {
+            if (imagep->getLastReferencedTimer()->getElapsedTimeF32() > max_inactive_time)
+            {
+                imagep->setDeletionCandidate();
+            }
+            return;
+        }
+        else
+        {
+            imagep->getLastReferencedTimer()->reset();
 
-			imagep->processTextureStats();
-			F32 old_priority = imagep->getDecodePriority();
-			F32 old_priority_test = llmax(old_priority, 0.0f);
-			F32 decode_priority = imagep->calcDecodePriority();
-			F32 decode_priority_test = llmax(decode_priority, 0.0f);
-			// Ignore < 20% difference
-			if ((decode_priority_test < old_priority_test * .8f) ||
-				(decode_priority_test > old_priority_test * 1.25f))
-			{
-				mImageList.erase(imagep) ;
-				imagep->setDecodePriority(decode_priority);
-				mImageList.insert(imagep);
-			}
-		}
-	}
+            //reset texture state.
+            imagep->setInactive();
+        }
+    }
+
+    if (!imagep->isInImageList())
+    {
+        return;
+    }
+    if (imagep->isInFastCacheList())
+    {
+        return; //wait for loading from the fast cache.
+    }
+
+    imagep->processTextureStats();
 }
 
 void LLViewerTextureList::setDebugFetching(LLViewerFetchedTexture* tex, S32 debug_level)
@@ -970,17 +947,9 @@ void LLViewerTextureList::setDebugFetching(LLViewerFetchedTexture* tex, S32 debu
 	}
 
 	const F32 DEBUG_PRIORITY = 100000.f;
-	F32 old_priority_test = llmax(tex->getDecodePriority(), 0.0f);
-	F32 decode_priority_test = DEBUG_PRIORITY;
-	
-	// Ignore < 20% difference
-	if ((decode_priority_test < old_priority_test * .8f) ||
-		(decode_priority_test > old_priority_test * 1.25f))
-	{
-		removeImageFromList(tex);
-		tex->setDecodePriority(decode_priority_test);
-		addImageToList(tex);
-	}
+	removeImageFromList(tex);
+    tex->mMaxVirtualSize = DEBUG_PRIORITY;
+	addImageToList(tex);
 }
 
 /*
@@ -1030,10 +999,6 @@ F32 LLViewerTextureList::updateImagesCreateTextures(F32 max_time)
 		LLViewerFetchedTexture *imagep = *curiter;
 		imagep->createTexture();
         imagep->postCreateTexture();
-		if (create_timer.getElapsedTimeF32() > max_time)
-		{
-			break;
-		}
 	}
 	mCreateTextureList.erase(mCreateTextureList.begin(), enditer);
 	return create_timer.getElapsedTimeF32();
@@ -1061,10 +1026,6 @@ F32 LLViewerTextureList::updateImagesLoadingFastCache(F32 max_time)
 		enditer = iter;
 		LLViewerFetchedTexture *imagep = *curiter;
 		imagep->loadFromFastCache();
-		if (timer.getElapsedTimeF32() > max_time)
-		{
-			break;
-		}
 	}
 	mFastCacheList.erase(mFastCacheList.begin(), enditer);
 	return timer.getElapsedTimeF32();
@@ -1083,8 +1044,7 @@ void LLViewerTextureList::forceImmediateUpdate(LLViewerFetchedTexture* imagep)
 	}
 
 	imagep->processTextureStats();
-	F32 decode_priority = LLViewerFetchedTexture::maxDecodePriority() ;
-	imagep->setDecodePriority(decode_priority);
+    imagep->sMaxVirtualSize = LLViewerFetchedTexture::sMaxVirtualSize;
 	addImageToList(imagep);
 	
 	return ;
@@ -1093,12 +1053,17 @@ void LLViewerTextureList::forceImmediateUpdate(LLViewerFetchedTexture* imagep)
 F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time)
 {
     LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
-	LLTimer image_op_timer;
-	
+    LLTimer image_op_timer;
+
+    typedef std::vector<LLViewerFetchedTexture*> entries_list_t;
+    entries_list_t entries;
+
 	// Update fetch for N images each frame
 	static const S32 MAX_HIGH_PRIO_COUNT = gSavedSettings.getS32("TextureFetchUpdateHighPriority");         // default: 32
+    static const S32 MIN_UPDATE_COUNT = gSavedSettings.getS32("TextureFetchUpdateMinMediumPriority");       // default: 32
+#if 0
 	static const S32 MAX_UPDATE_COUNT = gSavedSettings.getS32("TextureFetchUpdateMaxMediumPriority");       // default: 256
-	static const S32 MIN_UPDATE_COUNT = gSavedSettings.getS32("TextureFetchUpdateMinMediumPriority");       // default: 32
+	
 	static const F32 MIN_PRIORITY_THRESHOLD = gSavedSettings.getF32("TextureFetchUpdatePriorityThreshold"); // default: 0.0
 	static const bool SKIP_LOW_PRIO = gSavedSettings.getBOOL("TextureFetchUpdateSkipLowPriority");          // default: false
 
@@ -1110,9 +1075,9 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time)
 	max_update_count = llmin(max_update_count, total_update_count);	
 	
 	// MAX_HIGH_PRIO_COUNT high priority entries
-	typedef std::vector<LLViewerFetchedTexture*> entries_list_t;
-	entries_list_t entries;
-	size_t update_counter = max_priority_count;
+	
+	//size_t update_counter = max_priority_count;
+    size_t update_counter = mImageList.size();
 	image_priority_list_t::iterator iter1 = mImageList.begin();
 	while(update_counter > 0)
 	{
@@ -1123,7 +1088,7 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time)
 	}
 	
 	// MAX_UPDATE_COUNT cycled entries
-	update_counter = max_update_count;	
+	update_counter = max_update_count;
 	if(update_counter > 0)
 	{
 		uuid_map_t::iterator iter2 = mUUIDMap.upper_bound(mLastFetchKey);
@@ -1147,22 +1112,65 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time)
 	}
 	
 	S32 fetch_count = 0;
-	size_t min_update_count = llmin(MIN_UPDATE_COUNT,(S32)(entries.size()-max_priority_count));
-	S32 min_count = max_priority_count + min_update_count;
+	//size_t min_update_count = llmin(MIN_UPDATE_COUNT,(S32)(entries.size()-max_priority_count));
+	//S32 min_count = max_priority_count + min_update_count;
 	for (entries_list_t::iterator iter3 = entries.begin();
 		 iter3 != entries.end(); )
 	{
 		LLViewerFetchedTexture* imagep = *iter3++;
+        updateImageDecodePriority(imagep);
 		fetch_count += (imagep->updateFetch() ? 1 : 0);
-		if (min_count <= min_update_count)
+		//if (min_count <= min_update_count)
 		{
 			mLastFetchKey = LLTextureKey(imagep->getID(), (ETexListType)imagep->getTextureListType());
 		}
-		if ((min_count-- <= 0) && (image_op_timer.getElapsedTimeF32() > max_time))
+		/*if ((min_count-- <= 0) && (image_op_timer.getElapsedTimeF32() > max_time))
 		{
 			break;
-		}
+		}*/
 	}
+#else
+
+    // update N textures at beginning of mImageList
+    U32 update_count = 0;
+
+    /*for (auto& imagep : mImageList)
+    {
+        if (update_count++ > MAX_HIGH_PRIO_COUNT)
+        {
+            break;
+        }
+
+        entries.push_back(imagep);
+    }*/
+
+    // WIP -- dumb code here
+    //update MIN_UPDATE_COUNT or 10% of other textures, whichever is greater
+    //update_count = llmax((U32) MIN_UPDATE_COUNT, (U32) mUUIDMap.size()/10);
+    //update_count = llmin(update_count, (U32) mUUIDMap.size());
+    update_count -= mUUIDMap.size();
+
+    entries.reserve(update_count);
+    //uuid_map_t::iterator iter2 = mUUIDMap.upper_bound(mLastFetchKey);
+    //while (update_count-- > 0)
+    for (auto iter2 = mUUIDMap.begin(); iter2 != mUUIDMap.end(); ++iter2)
+    {
+        entries.push_back(iter2->second);
+    }
+
+    for (auto* imagep : entries)
+    {
+        updateImageDecodePriority(imagep);
+        imagep->updateFetch();
+    }
+
+    if (entries.size() > 0)
+    {
+        LLViewerFetchedTexture* imagep = *entries.rbegin();
+        mLastFetchKey = LLTextureKey(imagep->getID(), (ETexListType)imagep->getTextureListType());
+    }
+
+#endif
 	return image_op_timer.getElapsedTimeF32();
 }
 
@@ -1206,8 +1214,6 @@ void LLViewerTextureList::decodeAllImages(F32 max_time)
 	{
 		LLViewerFetchedTexture* imagep = *iter;
 		imagep->processTextureStats();
-		F32 decode_priority = imagep->calcDecodePriority();
-		imagep->setDecodePriority(decode_priority);
 		addImageToList(imagep);
 	}
 	image_list.clear();
@@ -1346,69 +1352,6 @@ LLPointer<LLImageJ2C> LLViewerTextureList::convertToUploadFile(LLPointer<LLImage
 	return compressedImage;
 }
 
-// Returns min setting for TextureMemory (in MB)
-S32Megabytes LLViewerTextureList::getMinVideoRamSetting()
-{
-    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
-	U32Megabytes system_ram = gSysMemory.getPhysicalMemoryKB();
-	//min texture mem sets to 64M if total physical mem is more than 1.5GB
-	return (system_ram > U32Megabytes(1500)) ? S32Megabytes(64) : gMinVideoRam ;
-}
-
-//static
-// Returns max setting for TextureMemory (in MB)
-S32Megabytes LLViewerTextureList::getMaxVideoRamSetting(bool get_recommended, float mem_multiplier)
-{
-    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
-	S32Megabytes max_texmem;
-	if (gGLManager.mVRAM != 0)
-	{
-		// Treat any card with < 32 MB (shudder) as having 32 MB
-		//  - it's going to be swapping constantly regardless
-		S32Megabytes max_vram(gGLManager.mVRAM);
-
-		if(gGLManager.mIsAMD)
-		{
-			//shrink the availabe vram for ATI cards because some of them do not handel texture swapping well.
-			max_vram = max_vram * 0.75f; 
-		}
-
-		max_vram = llmax(max_vram, getMinVideoRamSetting());
-		max_texmem = max_vram;
-		if (!get_recommended)
-			max_texmem *= 2;
-	}
-	else
-	{
-		if (!get_recommended)
-		{
-			max_texmem = (S32Megabytes)512;
-		}
-		else if (gSavedSettings.getBOOL("NoHardwareProbe")) //did not do hardware detection at startup
-		{
-			max_texmem = (S32Megabytes)512;
-		}
-		else
-		{
-			max_texmem = (S32Megabytes)128;
-		}
-	}
-
-	S32Megabytes system_ram = gSysMemory.getPhysicalMemoryKB(); // In MB
-	//LL_INFOS() << "*** DETECTED " << system_ram << " MB of system memory." << LL_ENDL;
-	if (get_recommended)
-		max_texmem = llmin(max_texmem, system_ram/2);
-	else
-		max_texmem = llmin(max_texmem, system_ram);
-		
-    // limit the texture memory to a multiple of the default if we've found some cards to behave poorly otherwise
-	max_texmem = llmin(max_texmem, (S32Megabytes) (mem_multiplier * max_texmem));
-
-	max_texmem = llclamp(max_texmem, getMinVideoRamSetting(), gMaxVideoRam); 
-	
-	return max_texmem;
-}
-
 bool LLViewerTextureList::isPrioRequestsFetched()
 {
 	static LLCachedControl<F32> prio_threshold(gSavedSettings, "TextureFetchUpdatePriorityThreshold", 0.0f);
@@ -1420,7 +1363,7 @@ bool LLViewerTextureList::isPrioRequestsFetched()
 		iter != gTextureList.mImageList.end(); )
 	{
 		LLPointer<LLViewerFetchedTexture> imagep = *iter++;
-		if (imagep->getDecodePriority() > prio_threshold)
+		if (imagep->getMaxVirtualSize() > prio_threshold)
 		{
 			if (imagep->hasFetcher() || imagep->isFetching())
 			{
@@ -1436,66 +1379,6 @@ bool LLViewerTextureList::isPrioRequestsFetched()
 	return true;
 }
 
-const S32Megabytes VIDEO_CARD_FRAMEBUFFER_MEM(12);
-const S32Megabytes MIN_MEM_FOR_NON_TEXTURE(512);
-void LLViewerTextureList::updateMaxResidentTexMem(S32Megabytes mem)
-{
-    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
-	// Initialize the image pipeline VRAM settings
-	S32Megabytes cur_mem(gSavedSettings.getS32("TextureMemory"));
-	F32 mem_multiplier = gSavedSettings.getF32("RenderTextureMemoryMultiple");
-	S32Megabytes default_mem = getMaxVideoRamSetting(true, mem_multiplier); // recommended default
-	if (mem == (S32Bytes)0)
-	{
-		mem = cur_mem > (S32Bytes)0 ? cur_mem : default_mem;
-	}
-	else if (mem < (S32Bytes)0)
-	{
-		mem = default_mem;
-	}
-
-	mem = llclamp(mem, getMinVideoRamSetting(), getMaxVideoRamSetting(false, mem_multiplier));
-	if (mem != cur_mem)
-	{
-		gSavedSettings.setS32("TextureMemory", mem.value());
-		return; //listener will re-enter this function
-	}
-
-	if (gGLManager.mVRAM == 0)
-	{
-		LL_WARNS() << "VRAM amount not detected, defaulting to " << mem << " MB" << LL_ENDL;
-	}
-
-	// TODO: set available resident texture mem based on use by other subsystems
-	// currently max(12MB, VRAM/4) assumed...
-	
-	S32Megabytes vb_mem = mem;
-	S32Megabytes fb_mem = llmax(VIDEO_CARD_FRAMEBUFFER_MEM, vb_mem/4);
-	mMaxResidentTexMemInMegaBytes = (vb_mem - fb_mem) ; //in MB
-	
-	mMaxTotalTextureMemInMegaBytes = mMaxResidentTexMemInMegaBytes * 2;
-	if (mMaxResidentTexMemInMegaBytes > (S32Megabytes)640)
-	{
-		mMaxTotalTextureMemInMegaBytes -= (mMaxResidentTexMemInMegaBytes / 4);
-	}
-
-	//system mem
-	S32Megabytes system_ram = gSysMemory.getPhysicalMemoryKB();
-
-	//minimum memory reserved for non-texture use.
-	//if system_raw >= 1GB, reserve at least 512MB for non-texture use;
-	//otherwise reserve half of the system_ram for non-texture use.
-	S32Megabytes min_non_texture_mem = llmin(system_ram / 2, MIN_MEM_FOR_NON_TEXTURE) ; 
-
-	if (mMaxTotalTextureMemInMegaBytes > system_ram - min_non_texture_mem)
-	{
-		mMaxTotalTextureMemInMegaBytes = system_ram - min_non_texture_mem ;
-	}
-	
-	LL_INFOS() << "Total Video Memory set to: " << vb_mem << " MB" << LL_ENDL;
-	LL_INFOS() << "Available Texture Memory set to: " << (vb_mem - fb_mem) << " MB" << LL_ENDL;
-}
-
 ///////////////////////////////////////////////////////////////////////////////
 
 // static
diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h
index fead2e52b29..8d70add7927 100644
--- a/indra/newview/llviewertexturelist.h
+++ b/indra/newview/llviewertexturelist.h
@@ -124,25 +124,24 @@ class LLViewerTextureList
 
 	void handleIRCallback(void **data, const S32 number);
 
-	S32Megabytes	getMaxResidentTexMem() const	{ return mMaxResidentTexMemInMegaBytes; }
-	S32Megabytes getMaxTotalTextureMem() const   { return mMaxTotalTextureMemInMegaBytes;}
 	S32 getNumImages()					{ return mImageList.size(); }
 
-	void updateMaxResidentTexMem(S32Megabytes mem);
-	
 	void doPreloadImages();
 	void doPrefetchImages();
 
 	void clearFetchingRequests();
 	void setDebugFetching(LLViewerFetchedTexture* tex, S32 debug_level);
 
-	static S32Megabytes getMinVideoRamSetting();
-	static S32Megabytes getMaxVideoRamSetting(bool get_recommended, float mem_multiplier);
-
 	static bool isPrioRequestsFetched();
 	
 private:
 	void updateImagesDecodePriorities();
+
+    // do some book keeping on the specified texture
+    // - updates decode priority
+    // - updates desired discard level
+    // - cleans up textures that haven't been referenced in awhile
+    void updateImageDecodePriority(LLViewerFetchedTexture* imagep);
 	F32  updateImagesCreateTextures(F32 max_time);
 	F32  updateImagesFetchTextures(F32 max_time);
 	void updateImagesUpdateStats();
@@ -217,15 +216,13 @@ class LLViewerTextureList
     LLTextureKey mLastUpdateKey;
     LLTextureKey mLastFetchKey;
 	
-	typedef std::set<LLPointer<LLViewerFetchedTexture>, LLViewerFetchedTexture::Compare> image_priority_list_t;	
+    typedef std::set < LLPointer<LLViewerFetchedTexture> > image_priority_list_t;
 	image_priority_list_t mImageList;
 
 	// simply holds on to LLViewerFetchedTexture references to stop them from being purged too soon
 	std::set<LLPointer<LLViewerFetchedTexture> > mImagePreloads;
 
 	BOOL mInitialized ;
-	S32Megabytes	mMaxResidentTexMemInMegaBytes;
-	S32Megabytes mMaxTotalTextureMemInMegaBytes;
 	LLFrameTimer mForceDecodeTimer;
 	
 private:
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 5ee661f6c0f..151e03ac3bf 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -5687,15 +5687,6 @@ void LLVOAvatar::addBakedTextureStats( LLViewerFetchedTexture* imagep, F32 pixel
 	mMinPixelArea = llmin(pixel_area, mMinPixelArea);	
 	imagep->addTextureStats(pixel_area / texel_area_ratio);
 	imagep->setBoostLevel(boost_level);
-	
-	if(boost_level != LLGLTexture::BOOST_AVATAR_BAKED_SELF)
-	{
-		imagep->setAdditionalDecodePriority(ADDITIONAL_PRI) ;
-	}
-	else
-	{
-		imagep->setAdditionalDecodePriority(SELF_ADDITIONAL_PRI) ;
-	}
 }
 
 //virtual	
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index 49f5f40f03a..4080a61fb09 100644
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -1825,7 +1825,7 @@ void LLVOAvatarSelf::dumpLocalTextures() const
 			}
 			else
 			{
-				const LLViewerFetchedTexture* image = dynamic_cast<LLViewerFetchedTexture*>( local_tex_obj->getImage() );
+				LLViewerFetchedTexture* image = dynamic_cast<LLViewerFetchedTexture*>( local_tex_obj->getImage() );
 
 				LL_INFOS() << "LocTex " << name << ": "
 						<< "Discard " << image->getDiscardLevel() << ", "
@@ -1835,7 +1835,7 @@ void LLVOAvatarSelf::dumpLocalTextures() const
 					// makes textures easier to steal
 						<< image->getID() << " "
 #endif
-						<< "Priority: " << image->getDecodePriority()
+						<< "Priority: " << image->getMaxVirtualSize()
 						<< LL_ENDL;
 			}
 		}
@@ -2074,8 +2074,7 @@ const std::string LLVOAvatarSelf::verboseDebugDumpLocalTextureDataInfo(const LLV
 									   << " glocdisc: " << getLocalDiscardLevel(tex_index, wearable_index)
 									   << " discard: " << image->getDiscardLevel()
 									   << " desired: " << image->getDesiredDiscardLevel()
-									   << " decode: " << image->getDecodePriority()
-									   << " addl: " << image->getAdditionalDecodePriority()
+									   << " vsize: " << image->getMaxVirtualSize()
 									   << " ts: " << image->getTextureState()
 									   << " bl: " << image->getBoostLevel()
 									   << " fl: " << image->isFullyLoaded() // this is not an accessor for mFullyLoaded - see comment there.
@@ -2453,7 +2452,6 @@ void LLVOAvatarSelf::addLocalTextureStats( ETextureIndex type, LLViewerFetchedTe
 				desired_pixels = llmin(mPixelArea, (F32)getTexImageArea());
 				
 				imagep->setBoostLevel(getAvatarBoostLevel());
-				imagep->setAdditionalDecodePriority(SELF_ADDITIONAL_PRI) ;
 				imagep->resetTextureStats();
 				imagep->setMaxVirtualSizeResetInterval(MAX_TEXTURE_VIRTUAL_SIZE_RESET_INTERVAL);
 				imagep->addTextureStats( desired_pixels / texel_area_ratio );
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index f18f6b1116d..a0d034850fb 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -668,12 +668,13 @@ void LLVOVolume::animateTextures()
 
 void LLVOVolume::updateTextures()
 {
-	const F32 TEXTURE_AREA_REFRESH_TIME = 5.f; // seconds
-	if (mTextureUpdateTimer.getElapsedTimeF32() > TEXTURE_AREA_REFRESH_TIME)
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
+	//const F32 TEXTURE_AREA_REFRESH_TIME = 1.f; // seconds
+	//if (mTextureUpdateTimer.getElapsedTimeF32() > TEXTURE_AREA_REFRESH_TIME)
 	{
 		updateTextureVirtualSize();
 
-		if (mDrawable.notNull() && !isVisible() && !mDrawable->isActive())
+		/*if (mDrawable.notNull() && !isVisible() && !mDrawable->isActive())
 		{ //delete vertex buffer to free up some VRAM
 			LLSpatialGroup* group  = mDrawable->getSpatialGroup();
 			if (group && (group->mVertexBuffer.notNull() || !group->mBufferMap.empty() || !group->mDrawMap.empty()))
@@ -684,9 +685,7 @@ void LLVOVolume::updateTextures()
 				//it becomes visible
 				group->setState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO);
 			}
-		}
-
-
+		}*/
     }
 }
 
@@ -760,6 +759,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)
 	const S32 num_faces = mDrawable->getNumFaces();
 	F32 min_vsize=999999999.f, max_vsize=0.f;
 	LLViewerCamera* camera = LLViewerCamera::getInstance();
+    std::stringstream debug_text;
 	for (S32 i = 0; i < num_faces; i++)
 	{
 		LLFace* face = mDrawable->getFace(i);
@@ -786,10 +786,14 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)
 		else
 		{
 			vsize = face->getTextureVirtualSize();
+            imagep->addTextureStats(vsize);
 		}
 
-		mPixelArea = llmax(mPixelArea, face->getPixelArea());		
+		mPixelArea = llmax(mPixelArea, face->getPixelArea());
 
+        // if the face has gotten small enough to turn off texture animation and texture
+        // animation is running, rebuild the render batch for this face to turn off
+        // texture animation
 		if (face->mTextureMatrix != NULL)
 		{
 			if ((vsize < MIN_TEX_ANIM_SIZE && old_size > MIN_TEX_ANIM_SIZE) ||
@@ -809,10 +813,11 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)
 			LLViewerFetchedTexture* img = LLViewerTextureManager::staticCastToFetchedTexture(imagep) ;
 			if(img)
 			{
-				F32 pri = img->getDecodePriority();
+                debug_text << img->getDiscardLevel() << ":" << img->getDesiredDiscardLevel() << ":" << img->getWidth() << ":" << (S32) sqrtf(vsize) << ":" << (S32) sqrtf(img->getMaxVirtualSize()) << "\n";
+				/*F32 pri = img->getDecodePriority();
 				pri = llmax(pri, 0.0f);
 				if (pri < min_vsize) min_vsize = pri;
-				if (pri > max_vsize) max_vsize = pri;
+				if (pri > max_vsize) max_vsize = pri;*/
 			}
 		}
 		else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_FACE_AREA))
@@ -844,14 +849,6 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)
 				F32 lodf = ((F32)(lod + 1.0f)/4.f);
 				F32 tex_size = lodf * LLViewerTexture::sMaxSculptRez ;
 				mSculptTexture->addTextureStats(2.f * tex_size * tex_size, FALSE);
-			
-				//if the sculpty very close to the view point, load first
-				{				
-					LLVector3 lookAt = getPositionAgent() - camera->getOrigin();
-					F32 dist = lookAt.normVec() ;
-					F32 cos_angle_to_view_dir = lookAt * camera->getXAxis() ;				
-					mSculptTexture->setAdditionalDecodePriority(0.8f * LLFace::calcImportanceToCamera(cos_angle_to_view_dir, dist)) ;
-				}
 			}
 	
 			S32 texture_discard = mSculptTexture->getCachedRawImageLevel(); //try to match the texture
@@ -895,7 +892,8 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)
 	}
  	else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY))
  	{
- 		setDebugText(llformat("%.0f:%.0f", (F32) sqrt(min_vsize),(F32) sqrt(max_vsize)));
+ 		//setDebugText(llformat("%.0f:%.0f", (F32) sqrt(min_vsize),(F32) sqrt(max_vsize)));
+        setDebugText(debug_text.str());
  	}
 	else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_FACE_AREA))
 	{
diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp
index 32c8ce66a01..2b400c55860 100644
--- a/indra/newview/llxmlrpctransaction.cpp
+++ b/indra/newview/llxmlrpctransaction.cpp
@@ -395,7 +395,7 @@ void LLXMLRPCTransaction::Impl::init(XMLRPC_REQUEST request, bool useGzip, const
 
 	mHandler = LLXMLRPCTransaction::Handler::ptr_t(new Handler( mHttpRequest, this ));
 
-	mPostH = mHttpRequest->requestPost(LLCore::HttpRequest::DEFAULT_POLICY_ID, 0, 
+	mPostH = mHttpRequest->requestPost(LLCore::HttpRequest::DEFAULT_POLICY_ID,
 		mURI, body.get(), httpOpts, httpHeaders, mHandler);
 
 }
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index a5ae52af938..bc0d89f4adb 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -3776,25 +3776,47 @@ void LLPipeline::postSort(LLCamera& camera)
 			group->rebuildGeom();
 		}
 
-		for (LLSpatialGroup::draw_map_t::iterator j = group->mDrawMap.begin(); j != group->mDrawMap.end(); ++j)
-		{
-			LLSpatialGroup::drawmap_elem_t& src_vec = j->second;	
-			if (!hasRenderType(j->first))
-			{
-				continue;
-			}
-			
-			for (LLSpatialGroup::drawmap_elem_t::iterator k = src_vec.begin(); k != src_vec.end(); ++k)
-			{
+        for (LLSpatialGroup::draw_map_t::iterator j = group->mDrawMap.begin(); j != group->mDrawMap.end(); ++j)
+        {
+            LLSpatialGroup::drawmap_elem_t& src_vec = j->second;
+            if (!hasRenderType(j->first))
+            {
+                continue;
+            }
+
+            // DEBUG -- force a texture virtual size update every frame
+            /*if (group->getSpatialPartition()->mDrawableType == LLPipeline::RENDER_TYPE_VOLUME)
+            {
+                LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("plps - update vsize");
+                auto& entries = group->getData();
+                for (auto& entry : entries)
+                {
+                    if (entry)
+                    {
+                        auto* data = entry->getDrawable();
+                        if (data)
+                        {
+                            LLVOVolume* volume = ((LLDrawable*)data)->getVOVolume();
+                            if (volume)
+                            {
+                                volume->updateTextureVirtualSize(true);
+                            }
+                        }
+                    }
+                }
+            }*/
+
+            for (LLSpatialGroup::drawmap_elem_t::iterator k = src_vec.begin(); k != src_vec.end(); ++k)
+            {
                 LLDrawInfo* info = *k;
-				
-				sCull->pushDrawInfo(j->first, info);
+
+                sCull->pushDrawInfo(j->first, info);
                 if (!sShadowRender && !sReflectionRender)
                 {
                     touchTextures(info);
                     addTrianglesDrawn(info->mCount, info->mDrawMode);
                 }
-			}
+            }
 		}
 
 		if (hasRenderType(LLPipeline::RENDER_TYPE_PASS_ALPHA))
diff --git a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
index d1e167df644..0a4acd979aa 100644
--- a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
+++ b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
@@ -272,23 +272,6 @@
      Hardware
   </text>
 
-  <slider
-    control_name="TextureMemory"
-    decimal_digits="0"
-    follows="left|top"
-    height="16"
-    increment="16"
-    initial_value="32"
-    label="Texture Memory (MB):"
-    label_width="185"
-    layout="topleft"
-    left="30"
-    max_val="4096"
-    name="GraphicsCardTextureMemory"
-    tool_tip="Amount of memory to allocate for textures. Defaults to video card memory. Reducing this may improve performance but may also make textures blurry."
-    top_delta="16"
-    width="335" />
-
   <slider
     control_name="RenderFogRatio"
     follows="left|top"
-- 
GitLab