diff options
| author | Merov Linden <merov@lindenlab.com> | 2012-04-02 19:05:32 -0700 | 
|---|---|---|
| committer | Merov Linden <merov@lindenlab.com> | 2012-04-02 19:05:32 -0700 | 
| commit | df09fd8e8b5b73330e4942c2cb218a216d7aca99 (patch) | |
| tree | 7b945cde73ff1cc666c1f2b03d522452d2102eea | |
| parent | 792943c211f90738e245b11e128525190ff1b107 (diff) | |
SH-3060 : Preliminary implementation of the new byte range computation, implement setting to turn it on or off
| -rw-r--r-- | indra/llimage/llimage.cpp | 4 | ||||
| -rw-r--r-- | indra/llimage/llimage.h | 5 | ||||
| -rw-r--r-- | indra/llimage/llimagej2c.cpp | 47 | ||||
| -rw-r--r-- | indra/llkdu/llimagej2ckdu.cpp | 14 | ||||
| -rwxr-xr-x | indra/newview/app_settings/settings.xml | 11 | ||||
| -rw-r--r-- | indra/newview/llappviewer.cpp | 2 | 
6 files changed, 47 insertions, 36 deletions
| diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp index 937655a22d..7f95441075 100644 --- a/indra/llimage/llimage.cpp +++ b/indra/llimage/llimage.cpp @@ -48,11 +48,13 @@  //static  std::string LLImage::sLastErrorMessage;  LLMutex* LLImage::sMutex = NULL; +bool LLImage::sUseNewByteRange = false;  LLPrivateMemoryPool* LLImageBase::sPrivatePoolp = NULL ;  //static -void LLImage::initClass() +void LLImage::initClass(bool use_new_byte_range)  { +	sUseNewByteRange = use_new_byte_range;  	sMutex = new LLMutex(NULL);  	LLImageBase::createPrivatePool() ; diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h index eba8362f1c..b757547ab8 100644 --- a/indra/llimage/llimage.h +++ b/indra/llimage/llimage.h @@ -89,15 +89,18 @@ typedef enum e_image_codec  class LLImage  {  public: -	static void initClass(); +	static void initClass(bool use_new_byte_range = false);  	static void cleanupClass();  	static const std::string& getLastError();  	static void setLastError(const std::string& message); +	static bool useNewByteRange() { return sUseNewByteRange; } +	  protected:  	static LLMutex* sMutex;  	static std::string sLastErrorMessage; +	static bool sUseNewByteRange;  };  //============================================================================ diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp index fbf4b769e1..cbb6f75b43 100644 --- a/indra/llimage/llimagej2c.cpp +++ b/indra/llimage/llimagej2c.cpp @@ -262,10 +262,12 @@ S32 LLImageJ2C::calcHeaderSizeJ2C()  //static  S32 LLImageJ2C::calcDataSizeJ2C(S32 w, S32 h, S32 comp, S32 discard_level, F32 rate)  { -	// Note: this only provides an *estimate* of the size in bytes of an image level -	// *TODO: find a way to read the true size (when available) and convey the fact -	// that the result is an estimate in the other cases -	if (rate <= 0.f) rate = .125f; +	// Note: This provides an estimation for the first quality layer of a given discard level +	// This is however an efficient approximation, as the true discard level boundary would be +	// in general too big for fast fetching. +	// For details about the equation used here, see https://wiki.lindenlab.com/wiki/THX1138_KDU_Improvements#Byte_Range_Study +	if (rate <= 0.f) rate = 1.f/8.f; +	// Compute w/pow(2,discard_level) and h/pow(2,discard_level)  	while (discard_level > 0)  	{  		if (w < 1 || h < 1) @@ -274,7 +276,13 @@ S32 LLImageJ2C::calcDataSizeJ2C(S32 w, S32 h, S32 comp, S32 discard_level, F32 r  		h >>= 1;  		discard_level--;  	} -	S32 bytes = (S32)((F32)(w*h*comp)*rate); +	// Temporary: compute both new and old range and pick one according to the settings TextureNewByteRange  +	// *TODO: Take the old code out once we have enough tests done +	// *TODO: Replace the magic "7" by the number of quality layers in the j2c image +	S32 bytes; +	S32 new_bytes = sqrt((F32)(w*h))*(F32)(comp)*rate*1000.f/7.f; +	S32 old_bytes = (S32)((F32)(w*h*comp)*rate); +	bytes = (LLImage::useNewByteRange() ? new_bytes : old_bytes);  	bytes = llmax(bytes, calcHeaderSizeJ2C());  	return bytes;  } @@ -284,11 +292,7 @@ S32 LLImageJ2C::calcHeaderSize()  	return calcHeaderSizeJ2C();  } - -// calcDataSize() returns how many bytes to read  -// to load discard_level (including header and higher discard levels) -// *TODO: This is deeply wrong. That size should be taken from the image file header or other  -// relevant infos. In any case, this is only an approximation. +// calcDataSize() returns how many bytes to read to load discard_level (including header)  S32 LLImageJ2C::calcDataSize(S32 discard_level)  {  	discard_level = llclamp(discard_level, 0, MAX_DISCARD_LEVEL); @@ -304,25 +308,6 @@ S32 LLImageJ2C::calcDataSize(S32 discard_level)  			mDataSizes[level] = calcDataSizeJ2C(getWidth(), getHeight(), getComponents(), level, mRate);  			level--;  		} - -		/* This is technically a more correct way to calculate the size required -		   for each discard level, since they should include the size needed for -		   lower levels.   Unfortunately, this doesn't work well and will lead to  -		   download stalls.  The true correct way is to parse the header.  This will -		   all go away with http textures at some point. - -		// Calculate the size for each discard level.   Lower levels (higher quality) -		// contain the cumulative size of higher levels		 -		S32 total_size = calcHeaderSizeJ2C(); - -		S32 level = MAX_DISCARD_LEVEL;	// Start at the highest discard -		while ( level >= 0 ) -		{	// Add in this discard level and all before it -			total_size += calcDataSizeJ2C(getWidth(), getHeight(), getComponents(), level, mRate); -			mDataSizes[level] = total_size; -			level--; -		} -		*/  	}  	return mDataSizes[discard_level];  } @@ -337,8 +322,8 @@ S32 LLImageJ2C::calcDiscardLevelBytes(S32 bytes)  	}  	while (1)  	{ -		S32 bytes_needed = calcDataSize(discard_level); // virtual -		if (bytes >= bytes_needed - (bytes_needed>>2)) // For J2c, up the res at 75% of the optimal number of bytes +		S32 bytes_needed = calcDataSize(discard_level); +		if (bytes >= bytes_needed)  		{  			break;  		} diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index fdfab5506a..4468b8563b 100644 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -294,6 +294,13 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, BOOL keep_codestream, ECod  	// Get the number of resolution levels in that image  	mLevels = mCodeStreamp->get_min_dwt_levels(); +	 +	//kdu_coords idx; idx.x = 0; idx.y = 0; +	//kdu_dims tile_indices_in;   +	//mCodeStreamp->get_valid_tiles(tile_indices_in); +	//mCodeStreamp->create_tile(idx+tile_indices_in.pos); +	//int layers = mCodeStreamp->get_max_tile_layers(); +	//llinfos << "Merov debug : setupCodeStream, levels = " << mLevels << ", layers = " << layers << llendl;  	// Set the base dimensions  	base.setSize(dims.size.x, dims.size.y, components); @@ -390,7 +397,7 @@ BOOL LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco  			region_kdu->size.y = region[3] - region[1];  		}  		int discard = (discard_level != -1 ? discard_level : base.getRawDiscardLevel()); -		 +		llinfos << "Merov debug : initDecode, discard used = " << discard << ", asked = " << discard_level << llendl;  		// Apply loading restrictions  		mCodeStreamp->apply_input_restrictions( first_channel, max_channel_count, discard, 0, region_kdu); @@ -468,6 +475,9 @@ BOOL LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco  				{  					kdu_tile tile = mCodeStreamp->open_tile(*(mTPosp)+mTileIndicesp->pos); +					int layers = mCodeStreamp->get_max_tile_layers(); +					llinfos << "Merov debug : decodeImpl, levels = " << mLevels << ", layers = " << layers << llendl; +  					// Find the region of the buffer occupied by this  					// tile.  Note that we have no control over  					// sub-sampling factors which might have been used @@ -675,7 +685,7 @@ BOOL LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co  				std::string blocks_string = llformat("Cblk={%d,%d}",mBlocksSize,mBlocksSize);  				codestream.access_siz()->parse_string(blocks_string.c_str());  			} -			std::string ordering_string = llformat("Corder=RPCL"); +			std::string ordering_string = llformat("Corder=LRCP");  			codestream.access_siz()->parse_string(ordering_string.c_str());  			std::string PLT_string = llformat("ORGgen_plt=yes");  			codestream.access_siz()->parse_string(PLT_string.c_str()); diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 9fff543b13..5fc9c5d863 100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10686,6 +10686,17 @@        <key>Value</key>        <integer>0</integer>      </map> +    <key>TextureNewByteRange</key> +    <map> +      <key>Comment</key> +      <string>Use the new more accurate byte range computation for j2c discard levels</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>1</integer> +    </map>      <key>TexturePickerShowFolders</key>      <map>        <key>Comment</key> diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index bea8303d69..1a68d0317e 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1947,7 +1947,7 @@ bool LLAppViewer::initThreads()  	static const bool enable_threads = true;  #endif -	LLImage::initClass(); +	LLImage::initClass(gSavedSettings.getBOOL("TextureNewByteRange"));  	LLVFSThread::initClass(enable_threads && false);  	LLLFSThread::initClass(enable_threads && false); | 
