diff --git a/indra/llcommon/llqueuedthread.cpp b/indra/llcommon/llqueuedthread.cpp
index 809a626c93110eb406e1770d704af65c3e0975f6..e0b56b7973ff22e19fa9b177f03d583bf57ea4ef 100644
--- a/indra/llcommon/llqueuedthread.cpp
+++ b/indra/llcommon/llqueuedthread.cpp
@@ -428,9 +428,11 @@ S32 LLQueuedThread::processNextRequest()
 		llassert_always(req->getStatus() == STATUS_QUEUED);
 		break;
 	}
+	U32 start_priority = 0 ;
 	if (req)
 	{
 		req->setStatus(STATUS_INPROGRESS);
+		start_priority = req->getPriority();
 	}
 	unlockData();
 
@@ -439,8 +441,7 @@ S32 LLQueuedThread::processNextRequest()
 	// safe to access req.
 	if (req)
 	{
-		// process request
-		U32 start_priority = req->getPriority();
+		// process request		
 		bool complete = req->processRequest();
 
 		if (complete)
diff --git a/indra/newview/llpreviewtexture.cpp b/indra/newview/llpreviewtexture.cpp
index bf18c9e5e7c1b4e5acddce3a9e8d9a4de1e9412b..c4cbbbb791b887b0e8e7f89f72052d56a2190f5a 100644
--- a/indra/newview/llpreviewtexture.cpp
+++ b/indra/newview/llpreviewtexture.cpp
@@ -75,7 +75,8 @@ LLPreviewTexture::LLPreviewTexture(const LLSD& key)
 	  mLastWidth(0),
 	  mAspectRatio(0.f),
 	  mPreviewToSave(FALSE),
-	  mImage(NULL)
+	  mImage(NULL),
+	  mImageOldBoostLevel(LLViewerTexture::BOOST_NONE)
 {
 	updateImageID();
 	if (key.has("save_as"))
@@ -93,7 +94,7 @@ LLPreviewTexture::~LLPreviewTexture()
 	{
 		getWindow()->decBusyCount();
 	}
-
+	mImage->setBoostLevel(mImageOldBoostLevel);
 	mImage = NULL;
 }
 
@@ -543,6 +544,7 @@ void LLPreviewTexture::onAspectRatioCommit(LLUICtrl* ctrl, void* userdata)
 void LLPreviewTexture::loadAsset()
 {
 	mImage = LLViewerTextureManager::getFetchedTexture(mImageID, MIPMAP_TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+	mImageOldBoostLevel = mImage->getBoostLevel();
 	mImage->setBoostLevel(LLViewerTexture::BOOST_PREVIEW);
 	mImage->forceToSaveRawImage(0) ;
 	mAssetStatus = PREVIEW_ASSET_LOADING;
diff --git a/indra/newview/llpreviewtexture.h b/indra/newview/llpreviewtexture.h
index 0f29a741c11deff173cc4d4bbfeacba05cc498c7..cbdb057781ceb7f92426411b7a9cad730de2a885 100644
--- a/indra/newview/llpreviewtexture.h
+++ b/indra/newview/llpreviewtexture.h
@@ -82,9 +82,10 @@ class LLPreviewTexture : public LLPreview
 	void				updateDimensions();
 	LLUUID				mImageID;
 	LLPointer<LLViewerFetchedTexture>		mImage;
-	BOOL				mLoadingFullImage;
+	S32                 mImageOldBoostLevel;
 	std::string			mSaveFileName;
 	LLFrameTimer		mSavedFileTimer;
+	BOOL				mLoadingFullImage;
 	BOOL                mShowKeepDiscard;
 	BOOL                mCopyToInv;
 
@@ -94,11 +95,10 @@ class LLPreviewTexture : public LLPreview
 	// This is stored off in a member variable, because the save-as
 	// button and drag and drop functionality need to know.
 	BOOL mIsCopyable;
-
+	BOOL mUpdateDimensions;
 	S32 mLastHeight;
 	S32 mLastWidth;
-	F32 mAspectRatio;
-	BOOL mUpdateDimensions;
+	F32 mAspectRatio;	
 
 	LLLoadedCallbackEntry::source_callback_list_t mCallbackTextureList ; 
 };
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index 0afbce7d513de0fd8f9efdeec761d120c1a3e473..75bb9f84e2a47b5319c2e8f246fd3c767835b1ae 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -495,6 +495,7 @@ LLViewerTexture::LLViewerTexture(const U32 width, const U32 height, const U8 com
 	mFullHeight = height ;
 	mUseMipMaps = usemipmaps ;
 	mComponents = components ;
+	setTexelsPerImage();
 
 	mID.generate();
 	sImageCount++;
@@ -522,6 +523,7 @@ void LLViewerTexture::init(bool firstinit)
 
 	mFullWidth = 0;
 	mFullHeight = 0;
+	mTexelsPerImage = 0 ;
 	mUseMipMaps = FALSE ;
 	mComponents = 0 ;
 
@@ -530,7 +532,7 @@ void LLViewerTexture::init(bool firstinit)
 	mMaxVirtualSize = 0.f;
 	mNeedsGLTexture = FALSE ;
 	mMaxVirtualSizeResetInterval = 1;
-	mMaxVirtualSizeResetCounter = 1 ;
+	mMaxVirtualSizeResetCounter = mMaxVirtualSizeResetInterval ;
 	mAdditionalDecodePriority = 0.f ;	
 	mParcelMedia = NULL ;
 	mNumFaces = 0 ;
@@ -838,7 +840,8 @@ BOOL LLViewerTexture::createGLTexture(S32 discard_level, const LLImageRaw* image
 	{
 		mFullWidth = mGLTexturep->getCurrentWidth() ;
 		mFullHeight = mGLTexturep->getCurrentHeight() ; 
-		mComponents = mGLTexturep->getComponents() ;		
+		mComponents = mGLTexturep->getComponents() ;	
+		setTexelsPerImage();
 	}
 
 	return ret ;
@@ -1056,9 +1059,16 @@ void LLViewerTexture::destroyGLTexture()
 	}	
 }
 
+void LLViewerTexture::setTexelsPerImage()
+{
+	S32 fullwidth = llmin(mFullWidth,(S32)MAX_IMAGE_SIZE_DEFAULT);
+	S32 fullheight = llmin(mFullHeight,(S32)MAX_IMAGE_SIZE_DEFAULT);
+	mTexelsPerImage = (F32)fullwidth * fullheight;
+}
+
 BOOL LLViewerTexture::isLargeImage()
 {
-	return mFullWidth * mFullHeight > LLViewerTexture::sMinLargeImageSize ;
+	return  (S32)mTexelsPerImage > LLViewerTexture::sMinLargeImageSize ;
 }
 
 //virtual 
@@ -1415,6 +1425,7 @@ BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/)
 			
 			mFullWidth = mRawImage->getWidth();
 			mFullHeight = mRawImage->getHeight();
+			setTexelsPerImage();
 		}
 		else
 		{
@@ -1619,11 +1630,7 @@ F32 LLViewerFetchedTexture::calcDecodePriority()
 	{
 		// priority range = 100,000 - 500,000
 		S32 desired_discard = mDesiredDiscardLevel;
-		if (getDontDiscard())
-		{
-			desired_discard -= 2;
-		}
-		else if (!isJustBound() && mCachedRawImageReady)
+		if (!isJustBound() && mCachedRawImageReady)
 		{
 			if(mBoostLevel < BOOST_HIGH)
 			{
@@ -1639,7 +1646,7 @@ F32 LLViewerFetchedTexture::calcDecodePriority()
 
 		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 = (ddiscard + 1) * PRIORITY_DELTA_DISCARD_LEVEL_FACTOR;		
 	}
 
 	// Priority Formula:
@@ -1647,19 +1654,51 @@ F32 LLViewerFetchedTexture::calcDecodePriority()
 	// [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)
 		{
-			priority += PRIORITY_BOOST_HIGH_FACTOR;
+			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
-			priority += PRIORITY_ADDITIONAL_FACTOR * (1.0 + mAdditionalDecodePriority * MAX_ADDITIONAL_LEVEL_FOR_PRIORITY);
+			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;
@@ -1702,11 +1741,6 @@ void LLViewerFetchedTexture::updateVirtualSize()
 		addTextureStats(0.f, FALSE) ;//reset
 	}
 
-	if(mForceToSaveRawImage)
-	{
-		setAdditionalDecodePriority(0.75f) ; //boost the fetching priority
-	}
-
 	for(U32 i = 0 ; i < mNumFaces ; i++)
 	{				
 		LLFace* facep = mFaceList[i] ;
@@ -1819,6 +1853,7 @@ bool LLViewerFetchedTexture::updateFetch()
 			{
 				mFullWidth = mRawImage->getWidth() << mRawDiscardLevel;
 				mFullHeight = mRawImage->getHeight() << mRawDiscardLevel;
+				setTexelsPerImage();
 
 				if(mFullWidth > MAX_IMAGE_SIZE || mFullHeight > MAX_IMAGE_SIZE)
 				{ 
@@ -2887,10 +2922,6 @@ void LLViewerLODTexture::processTextureStats()
 		//static const F64 log_2 = log(2.0);
 		static const F64 log_4 = log(4.0);
 
-		S32 fullwidth = llmin(mFullWidth,(S32)MAX_IMAGE_SIZE_DEFAULT);
-		S32 fullheight = llmin(mFullHeight,(S32)MAX_IMAGE_SIZE_DEFAULT);
-		mTexelsPerImage = (F32)fullwidth * fullheight;
-
 		F32 discard_level = 0.f;
 
 		// If we know the output width and height, we can force the discard
diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h
index 8b69408e4bdfa52dcafc482739ab94a7fbc2fcf6..b33d04e8dd3c65c2f89f408b5468477d0c22bb36 100644
--- a/indra/newview/llviewertexture.h
+++ b/indra/newview/llviewertexture.h
@@ -126,15 +126,16 @@ class LLViewerTexture : public LLTexture
 		BOOST_HIGH 			= 10,
 		BOOST_BUMP          ,
 		BOOST_TERRAIN		, // has to be high priority for minimap / low detail
-		BOOST_SELECTED		,
-		BOOST_HUD			,
+		BOOST_SELECTED		,		
 		BOOST_AVATAR_BAKED_SELF	,
+		BOOST_AVATAR_SELF	, // needed for baking avatar
+		BOOST_SUPER_HIGH    , //textures higher than this need to be downloaded at the required resolution without delay.
+		BOOST_HUD			,
 		BOOST_ICON			,
 		BOOST_UI			,
 		BOOST_PREVIEW		,
 		BOOST_MAP			,
-		BOOST_MAP_VISIBLE	,
-		BOOST_AVATAR_SELF	, // needed for baking avatar
+		BOOST_MAP_VISIBLE	,		
 		BOOST_MAX_LEVEL,
 
 		//other texture Categories
@@ -268,6 +269,7 @@ class LLViewerTexture : public LLTexture
 	void init(bool firstinit) ;	
 	void reorganizeFaceList() ;
 	void reorganizeVolumeList() ;
+	void setTexelsPerImage();
 private:
 	//note: do not make this function public.
 	/*virtual*/ LLImageGL* getGLTexture() const ;
@@ -280,6 +282,7 @@ class LLViewerTexture : public LLTexture
 	S32 mFullHeight;
 	BOOL  mUseMipMaps ;
 	S8  mComponents;
+	F32 mTexelsPerImage;			// Texels per image.
 	mutable S8  mNeedsGLTexture;
 	mutable F32 mMaxVirtualSize;	// The largest virtual size of the image, in pixels - how much data to we need?	
 	mutable S32  mMaxVirtualSizeResetCounter ;
@@ -598,8 +601,6 @@ class LLViewerLODTexture : public LLViewerFetchedTexture
 	void scaleDown() ;		
 
 private:
-	
-	F32 mTexelsPerImage;			// Texels per image.
 	F32 mDiscardVirtualSize;		// Virtual size used to calculate desired discard	
 	F32 mCalculatedDiscardLevel;    // Last calculated discard level
 };
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 47e35ca0c40d9c23696aa0135884c897e5d5cb2c..aca4ac2d852e4907e6620bc5bbdf5e9ae9b926a9 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -3189,29 +3189,26 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
 		{ // muted avatars update at 16 hz
 			mUpdatePeriod = 16;
 		}
-		else if (visible && mVisibilityRank <= LLVOAvatar::sMaxVisible)
+		else if (mVisibilityRank <= LLVOAvatar::sMaxVisible)
 		{ //first 25% of max visible avatars are not impostored
 			mUpdatePeriod = 1;
 		}
-		else if (visible && mVisibilityRank > LLVOAvatar::sMaxVisible * 4)
+		else if (mVisibilityRank > LLVOAvatar::sMaxVisible * 4)
 		{ //background avatars are REALLY slow updating impostors
 			mUpdatePeriod = 16;
 		}
-		else if (visible && mVisibilityRank > LLVOAvatar::sMaxVisible * 3)
+		else if (mVisibilityRank > LLVOAvatar::sMaxVisible * 3)
 		{ //back 25% of max visible avatars are slow updating impostors
 			mUpdatePeriod = 8;
 		}
-		else if (visible && mImpostorPixelArea <= impostor_area)
+		else if (mImpostorPixelArea <= impostor_area)
 		{  // stuff in between gets an update period based on pixel area
 			mUpdatePeriod = llclamp((S32) sqrtf(impostor_area*4.f/mImpostorPixelArea), 2, 8);
 		}
-		else if (visible && mVisibilityRank > LLVOAvatar::sMaxVisible)
-		{ // force nearby impostors in ultra crowded areas
-			mUpdatePeriod = 2;
-		}
 		else
-		{ // not impostored
-			mUpdatePeriod = 1;
+		{
+			//nearby avatars, update the impostors more frequently.
+			mUpdatePeriod = 4;
 		}
 
 		visible = (LLDrawable::getCurrentFrame()+mID.mData[0])%mUpdatePeriod == 0 ? TRUE : FALSE;
@@ -4274,10 +4271,12 @@ void LLVOAvatar::checkTextureLoading()
 	return ;
 }
 
+const F32  SELF_ADDITIONAL_PRI = 0.75f ;
+const F32  ADDITIONAL_PRI = 0.5f;
 void LLVOAvatar::addBakedTextureStats( LLViewerFetchedTexture* imagep, F32 pixel_area, F32 texel_area_ratio, S32 boost_level)
 {
 	//if this function is not called for the last 512 frames, the texture pipeline will stop fetching this texture.
-	static const S32  MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL = 512 ; //frames	
+	static const S32  MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL = 512 ; //frames		
 
 	imagep->resetTextureStats();
 	imagep->setCanUseHTTP(false) ; //turn off http fetching for baked textures.
@@ -4287,9 +4286,14 @@ 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 == LLViewerTexture::BOOST_AVATAR_BAKED_SELF)
+	
+	if(boost_level != LLViewerTexture::BOOST_AVATAR_BAKED_SELF)
+	{
+		imagep->setAdditionalDecodePriority(ADDITIONAL_PRI) ;
+	}
+	else
 	{
-		imagep->setAdditionalDecodePriority(1.0f) ;
+		imagep->setAdditionalDecodePriority(SELF_ADDITIONAL_PRI) ;
 	}
 }
 
@@ -7300,7 +7304,7 @@ void LLVOAvatar::cullAvatarsByPixelArea()
 	std::sort(LLCharacter::sInstances.begin(), LLCharacter::sInstances.end(), CompareScreenAreaGreater());
 	
 	// Update the avatars that have changed status
-	U32 rank = 0;
+	U32 rank = 2; //1 is reserved for self. 
 	for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
 		 iter != LLCharacter::sInstances.end(); ++iter)
 	{
@@ -7324,7 +7328,7 @@ void LLVOAvatar::cullAvatarsByPixelArea()
 
 		if (inst->isSelf())
 		{
-			inst->setVisibilityRank(0);
+			inst->setVisibilityRank(1);
 		}
 		else if (inst->mDrawable.notNull() && inst->mDrawable->isVisible())
 		{
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index dd7d0bb24db0c4102ce6c608277181019fca4307..49b9fe1536ebf632a55d15c450deb8ef76e5735b 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -1048,5 +1048,6 @@ class LLVOAvatar :
  *******************************************************************************/
 
 }; // LLVOAvatar
+extern const F32  SELF_ADDITIONAL_PRI;
 
 #endif // LL_VO_AVATAR_H
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index 4edbbb7402ada511837fa4fa8601043f215860e5..b80e47e11a63c2312fc758ffffd966b95a3bcedb 100644
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -2034,7 +2034,7 @@ void LLVOAvatarSelf::addLocalTextureStats( ETextureIndex type, LLViewerFetchedTe
 			imagep->resetTextureStats();
 			imagep->setMaxVirtualSizeResetInterval(16);
 			imagep->addTextureStats( desired_pixels / texel_area_ratio );
-			imagep->setAdditionalDecodePriority(1.0f) ;
+			imagep->setAdditionalDecodePriority(SELF_ADDITIONAL_PRI) ;
 			imagep->forceUpdateBindStats() ;
 			if (imagep->getDiscardLevel() < 0)
 			{