diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index d8a9ce93745897e474c3c820b7f0d7e815d23ca0..7e779986df5b7140f2a5f05615bccfac0f30cbac 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -1447,8 +1447,14 @@ void LLViewerFetchedTexture::setKnownDrawSize(S32 width, S32 height)
 //virtual
 void LLViewerFetchedTexture::processTextureStats()
 {
-	if(mFullyLoaded)//already loaded
+	if(mFullyLoaded)
 	{
+		if(mDesiredDiscardLevel <= mMinDesiredDiscardLevel)//already loaded
+		{
+			return ;
+		}
+		mDesiredDiscardLevel = llmin(mDesiredDiscardLevel, mMinDesiredDiscardLevel) ;
+		mFullyLoaded = FALSE ;
 		return ;
 	}
 
@@ -1482,6 +1488,7 @@ void LLViewerFetchedTexture::processTextureStats()
 			mDesiredDiscardLevel = (S8)llmin(log((F32)mFullWidth / mKnownDrawWidth) / log_2, 
 					                             log((F32)mFullHeight / mKnownDrawHeight) / log_2) ;
 			mDesiredDiscardLevel = 	llclamp(mDesiredDiscardLevel, (S8)0, (S8)getMaxDiscardLevel()) ;
+			mDesiredDiscardLevel = llmin(mDesiredDiscardLevel, mMinDesiredDiscardLevel) ;
 		}
 		mKnownDrawSizeChanged = FALSE ;
 		
@@ -1514,7 +1521,7 @@ F32 LLViewerFetchedTexture::calcDecodePriority()
 	}
 	if(mFullyLoaded && !mForceToSaveRawImage)//already loaded for static texture
 	{
-		return -4.0f ; //alreay fetched
+		return -1.0f ; //alreay fetched
 	}
 
 	S32 cur_discard = getCurrentDiscardLevelForFetching();
@@ -1528,16 +1535,16 @@ F32 LLViewerFetchedTexture::calcDecodePriority()
 	}
 	else if(mDesiredDiscardLevel >= cur_discard && cur_discard > -1)
 	{
-		priority = -1.0f ;
+		priority = -2.0f ;
 	}
 	else if(mCachedRawDiscardLevel > -1 && mDesiredDiscardLevel >= mCachedRawDiscardLevel)
 	{
-		priority = -1.0f;
+		priority = -3.0f;
 	}
 	else if (mDesiredDiscardLevel > getMaxDiscardLevel())
 	{
 		// Don't decode anything we don't need
-		priority = -1.0f;
+		priority = -4.0f;
 	}
 	else if ((mBoostLevel == LLViewerTexture::BOOST_UI || mBoostLevel == LLViewerTexture::BOOST_ICON) && !have_all_data)
 	{
@@ -1551,9 +1558,14 @@ F32 LLViewerFetchedTexture::calcDecodePriority()
 			// Always want high boosted images
 			priority = 1.f;
 		}
+		else if(mForceToSaveRawImage)
+		{
+			//force to fetch the raw image.
+			priority = 1.f;
+		}
 		else
 		{
-			priority = -1.f; //stop fetching
+			priority = -5.f; //stop fetching
 		}
 	}
 	else if (cur_discard < 0)
@@ -1569,7 +1581,7 @@ F32 LLViewerFetchedTexture::calcDecodePriority()
 	else if ((mMinDiscardLevel > 0) && (cur_discard <= mMinDiscardLevel))
 	{
 		// larger mips are corrupted
-		priority = -3.0f;
+		priority = -6.0f;
 	}
 	else
 	{
@@ -2052,10 +2064,13 @@ bool LLViewerFetchedTexture::doLoadedCallbacks()
 	bool run_raw_callbacks = false;
 	bool need_readback = false;
 
+	mMinDesiredDiscardLevel = MAX_DISCARD_LEVEL + 1;
 	for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
 		iter != mLoadedCallbackList.end(); )
 	{
 		LLLoadedCallbackEntry *entryp = *iter++;
+		mMinDesiredDiscardLevel = llmin(mMinDesiredDiscardLevel, (S8)entryp->mDesiredDiscard) ;
+
 		if (entryp->mNeedsImageRaw)
 		{
 			if (mNeedsAux)
@@ -2187,6 +2202,7 @@ bool LLViewerFetchedTexture::doLoadedCallbacks()
 	if (mLoadedCallbackList.empty())
 	{
 		gTextureList.mCallbackList.erase(this);
+		mMinDesiredDiscardLevel = MAX_DISCARD_LEVEL + 1;
 	}
 
 	// Done with any raw image data at this point (will be re-created if we still have callbacks)