From 0ba75fe2d6fe8eddd6efaaf8e6c604ea96bb30c0 Mon Sep 17 00:00:00 2001
From: Xiaohong Bao <bao@lindenlab.com>
Date: Tue, 13 Jul 2010 13:40:08 -0600
Subject: [PATCH] EXT-7400: FIXED: 2.0.2 texture queue gets jammed; EXT-7399:
 FIXED: 2.0.2 with http textures loads textures slower than 1.23.5

---
 indra/llcommon/llqueuedthread.cpp |  5 ++-
 indra/newview/llviewertexture.cpp | 71 ++++++++++++++++++++++---------
 indra/newview/llviewertexture.h   | 13 +++---
 indra/newview/llvoavatar.cpp      | 13 ++++--
 indra/newview/llvoavatar.h        |  1 +
 indra/newview/llvoavatarself.cpp  |  2 +-
 6 files changed, 73 insertions(+), 32 deletions(-)

diff --git a/indra/llcommon/llqueuedthread.cpp b/indra/llcommon/llqueuedthread.cpp
index 809a626c931..e0b56b7973f 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/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index 0afbce7d513..75bb9f84e2a 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 8b69408e4bd..b33d04e8dd3 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 1954a573d4a..1193471ccc6 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -4272,10 +4272,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.
@@ -4285,9 +4287,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) ;
 	}
 }
 
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index 3dad9198750..a86e824426b 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 4edbbb7402a..b80e47e11a6 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)
 			{
-- 
GitLab