diff options
| author | Xiaohong Bao <bao@lindenlab.com> | 2011-02-23 10:44:59 -0700 | 
|---|---|---|
| committer | Xiaohong Bao <bao@lindenlab.com> | 2011-02-23 10:44:59 -0700 | 
| commit | 01cdeb0cdd8c48b76a229d42ced4e5563cd18c5c (patch) | |
| tree | e7b7ca976f17c8af3c8a2648a801030594e94c8c /indra/llimage | |
| parent | 7daa3d1ca10199468946feef0ce8eb67489deee0 (diff) | |
| parent | ff5e3f5c2e566f3a8e86efaa763f7b12e07eeb53 (diff) | |
Merge from viewer-development
Diffstat (limited to 'indra/llimage')
| -rw-r--r-- | indra/llimage/CMakeLists.txt | 14 | ||||
| -rw-r--r-- | indra/llimage/llimage.cpp | 20 | ||||
| -rw-r--r-- | indra/llimage/llimage.h | 4 | ||||
| -rw-r--r-- | indra/llimage/llimagedimensionsinfo.cpp | 16 | ||||
| -rw-r--r-- | indra/llimage/llimagej2c.cpp | 332 | ||||
| -rw-r--r-- | indra/llimage/llimagej2c.h | 47 | ||||
| -rw-r--r-- | indra/llimage/llimageworker.cpp | 6 | ||||
| -rw-r--r-- | indra/llimage/llimageworker.h | 2 | ||||
| -rw-r--r-- | indra/llimage/llpngwrapper.cpp | 18 | ||||
| -rw-r--r-- | indra/llimage/llpngwrapper.h | 3 | ||||
| -rw-r--r-- | indra/llimage/tests/llimageworker_test.cpp | 18 | 
11 files changed, 284 insertions, 196 deletions
| diff --git a/indra/llimage/CMakeLists.txt b/indra/llimage/CMakeLists.txt index a69621a57b..ea8c1a1107 100644 --- a/indra/llimage/CMakeLists.txt +++ b/indra/llimage/CMakeLists.txt @@ -3,12 +3,13 @@  project(llimage)  include(00-Common) -include(LLAddBuildTest)  include(LLCommon)  include(LLImage)  include(LLMath)  include(LLVFS)  include(ZLIB) +include(LLAddBuildTest) +include(Tut)  include_directories(      ${LLCOMMON_INCLUDE_DIRS} @@ -57,11 +58,18 @@ add_library (llimage ${llimage_SOURCE_FILES})  # Sort by high-level to low-level  target_link_libraries(llimage      llcommon -    llimagej2coj        # *HACK: In theory a noop for KDU builds?      ${JPEG_LIBRARIES}      ${PNG_LIBRARIES}      ${ZLIB_LIBRARIES}      )  # Add tests -#ADD_BUILD_TEST(llimageworker llimage) +if (LL_TESTS) +  SET(llimage_TEST_SOURCE_FILES +    llimageworker.cpp +    ) +  LL_ADD_PROJECT_UNIT_TESTS(llimage "${llimage_TEST_SOURCE_FILES}") +endif (LL_TESTS) + + + diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp index c99313f0ea..aa01df2be8 100644 --- a/indra/llimage/llimage.cpp +++ b/indra/llimage/llimage.cpp @@ -54,7 +54,6 @@ LLPrivateMemoryPool* LLImageBase::sPrivatePoolp = NULL ;  void LLImage::initClass()  {  	sMutex = new LLMutex(NULL); -	LLImageJ2C::openDSO();  	LLImageBase::createPrivatePool() ;  } @@ -62,7 +61,6 @@ void LLImage::initClass()  //static  void LLImage::cleanupClass()  { -	LLImageJ2C::closeDSO();  	delete sMutex;  	sMutex = NULL; @@ -329,11 +327,11 @@ LLImageRaw::LLImageRaw(U8 *data, U16 width, U16 height, S8 components)  	++sRawImageCount;  } -LLImageRaw::LLImageRaw(const std::string& filename, bool j2c_lowest_mip_only) -	: LLImageBase() -{ -	createFromFile(filename, j2c_lowest_mip_only); -} +//LLImageRaw::LLImageRaw(const std::string& filename, bool j2c_lowest_mip_only) +//	: LLImageBase() +//{ +//	createFromFile(filename, j2c_lowest_mip_only); +//}  LLImageRaw::~LLImageRaw()  { @@ -1237,7 +1235,7 @@ file_extensions[] =  	{ "png", IMG_CODEC_PNG }  };  #define NUM_FILE_EXTENSIONS LL_ARRAY_SIZE(file_extensions) - +#if 0  static std::string find_file(std::string &name, S8 *codec)  {  	std::string tname; @@ -1255,7 +1253,7 @@ static std::string find_file(std::string &name, S8 *codec)  	}  	return std::string("");  } - +#endif  EImageCodec LLImageBase::getCodecFromExtension(const std::string& exten)  {  	for (int i=0; i<(int)(NUM_FILE_EXTENSIONS); i++) @@ -1265,7 +1263,7 @@ EImageCodec LLImageBase::getCodecFromExtension(const std::string& exten)  	}  	return IMG_CODEC_INVALID;  } - +#if 0  bool LLImageRaw::createFromFile(const std::string &filename, bool j2c_lowest_mip_only)  {  	std::string name = filename; @@ -1372,7 +1370,7 @@ bool LLImageRaw::createFromFile(const std::string &filename, bool j2c_lowest_mip  	return true;  } - +#endif  //---------------------------------------------------------------------------  // LLImageFormatted  //--------------------------------------------------------------------------- diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h index b137ea9a61..ab20ccda9e 100644 --- a/indra/llimage/llimage.h +++ b/indra/llimage/llimage.h @@ -171,7 +171,7 @@ public:  	LLImageRaw(U16 width, U16 height, S8 components);  	LLImageRaw(U8 *data, U16 width, U16 height, S8 components);  	// Construct using createFromFile (used by tools) -	LLImageRaw(const std::string& filename, bool j2c_lowest_mip_only = false); +	//LLImageRaw(const std::string& filename, bool j2c_lowest_mip_only = false);  	/*virtual*/ void deleteData();  	/*virtual*/ U8* allocateData(S32 size = -1); @@ -233,7 +233,7 @@ public:  protected:  	// Create an image from a local file (generally used in tools) -	bool createFromFile(const std::string& filename, bool j2c_lowest_mip_only = false); +	//bool createFromFile(const std::string& filename, bool j2c_lowest_mip_only = false);  	void copyLineScaled( U8* in, U8* out, S32 in_pixel_len, S32 out_pixel_len, S32 in_pixel_step, S32 out_pixel_step );  	void compositeRowScaled4onto3( U8* in, U8* out, S32 in_pixel_len, S32 out_pixel_len ); diff --git a/indra/llimage/llimagedimensionsinfo.cpp b/indra/llimage/llimagedimensionsinfo.cpp index 5ea4a236b5..835664c60f 100644 --- a/indra/llimage/llimagedimensionsinfo.cpp +++ b/indra/llimage/llimagedimensionsinfo.cpp @@ -30,6 +30,9 @@  #include "llimagedimensionsinfo.h" +// Value is true if one of Libjpeg's functions has encountered an error while working. +static bool sJpegErrorEncountered = false; +  bool LLImageDimensionsInfo::load(const std::string& src_filename,U32 codec)  {  	clean(); @@ -101,9 +104,17 @@ bool LLImageDimensionsInfo::getImageDimensionsPng()  	return true;  } +// Called instead of exit() if Libjpeg encounters an error. +void on_jpeg_error(j_common_ptr cinfo) +{ +	(void) cinfo; +	sJpegErrorEncountered = true; +	llwarns << "Libjpeg has encountered an error!" << llendl; +}  bool LLImageDimensionsInfo::getImageDimensionsJpeg()  { +	sJpegErrorEncountered = false;  	clean();  	FILE *fp = fopen (mSrcFilename.c_str(), "rb");  	if (fp == NULL)  @@ -115,6 +126,9 @@ bool LLImageDimensionsInfo::getImageDimensionsJpeg()  	jpeg_error_mgr jerr;  	jpeg_decompress_struct cinfo;  	cinfo.err = jpeg_std_error(&jerr); +	// Call our function instead of exit() if Libjpeg encounters an error. +	// This is done to avoid crash in this case (STORM-472). +	cinfo.err->error_exit = on_jpeg_error;  	jpeg_create_decompress	(&cinfo);  	jpeg_stdio_src		(&cinfo, fp); @@ -128,6 +142,6 @@ bool LLImageDimensionsInfo::getImageDimensionsJpeg()  	jpeg_destroy_decompress(&cinfo);  	fclose(fp); -	return true; +	return !sJpegErrorEncountered;  } diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp index 0a13372b07..b144f8fc66 100644 --- a/indra/llimage/llimagej2c.cpp +++ b/indra/llimage/llimagej2c.cpp @@ -24,148 +24,32 @@   */  #include "linden_common.h" -#include "apr_pools.h" -#include "apr_dso.h" -  #include "lldir.h"  #include "llimagej2c.h"  #include "llmemtype.h" +#include "lltimer.h" +#include "llmath.h"  typedef LLImageJ2CImpl* (*CreateLLImageJ2CFunction)();  typedef void (*DestroyLLImageJ2CFunction)(LLImageJ2CImpl*);  typedef const char* (*EngineInfoLLImageJ2CFunction)(); -//some "private static" variables so we only attempt to load -//dynamic libaries once -CreateLLImageJ2CFunction j2cimpl_create_func; -DestroyLLImageJ2CFunction j2cimpl_destroy_func; -EngineInfoLLImageJ2CFunction j2cimpl_engineinfo_func; -apr_pool_t *j2cimpl_dso_memory_pool; -apr_dso_handle_t *j2cimpl_dso_handle; - -//Declare the prototype for theses functions here, their functionality -//will be implemented in other files which define a derived LLImageJ2CImpl -//but only ONE static library which has the implementation for this -//function should ever be included +// Declare the prototype for theses functions here. Their functionality +// will be implemented in other files which define a derived LLImageJ2CImpl +// but only ONE static library which has the implementation for these +// functions should ever be included.  LLImageJ2CImpl* fallbackCreateLLImageJ2CImpl();  void fallbackDestroyLLImageJ2CImpl(LLImageJ2CImpl* impl);  const char* fallbackEngineInfoLLImageJ2CImpl(); -//static -//Loads the required "create", "destroy" and "engineinfo" functions needed -void LLImageJ2C::openDSO() -{ -	//attempt to load a DSO and get some functions from it -	std::string dso_name; -	std::string dso_path; - -	bool all_functions_loaded = false; -	apr_status_t rv; - -#if LL_WINDOWS -	dso_name = "llkdu.dll"; -#elif LL_DARWIN -	dso_name = "libllkdu.dylib"; -#else -	dso_name = "libllkdu.so"; -#endif - -	dso_path = gDirUtilp->findFile(dso_name, -				       gDirUtilp->getAppRODataDir(), -				       gDirUtilp->getExecutableDir()); - -	j2cimpl_dso_handle      = NULL; -	j2cimpl_dso_memory_pool = NULL; - -	//attempt to load the shared library -	apr_pool_create(&j2cimpl_dso_memory_pool, NULL); -	rv = apr_dso_load(&j2cimpl_dso_handle, -					  dso_path.c_str(), -					  j2cimpl_dso_memory_pool); - -	//now, check for success -	if ( rv == APR_SUCCESS ) -	{ -		//found the dynamic library -		//now we want to load the functions we're interested in -		CreateLLImageJ2CFunction  create_func = NULL; -		DestroyLLImageJ2CFunction dest_func = NULL; -		EngineInfoLLImageJ2CFunction engineinfo_func = NULL; - -		rv = apr_dso_sym((apr_dso_handle_sym_t*)&create_func, -						 j2cimpl_dso_handle, -						 "createLLImageJ2CKDU"); -		if ( rv == APR_SUCCESS ) -		{ -			//we've loaded the create function ok -			//we need to delete via the DSO too -			//so lets check for a destruction function -			rv = apr_dso_sym((apr_dso_handle_sym_t*)&dest_func, -							 j2cimpl_dso_handle, -						       "destroyLLImageJ2CKDU"); -			if ( rv == APR_SUCCESS ) -			{ -				//we've loaded the destroy function ok -				rv = apr_dso_sym((apr_dso_handle_sym_t*)&engineinfo_func, -						 j2cimpl_dso_handle, -						 "engineInfoLLImageJ2CKDU"); -				if ( rv == APR_SUCCESS ) -				{ -					//ok, everything is loaded alright -					j2cimpl_create_func  = create_func; -					j2cimpl_destroy_func = dest_func; -					j2cimpl_engineinfo_func = engineinfo_func; -					all_functions_loaded = true; -				} -			} -		} -	} - -	if ( !all_functions_loaded ) -	{ -		//something went wrong with the DSO or function loading.. -		//fall back onto our satefy impl creation function - -#if 0 -		// precious verbose debugging, sadly we can't use our -		// 'llinfos' stream etc. this early in the initialisation seq. -		char errbuf[256]; -		fprintf(stderr, "failed to load syms from DSO %s (%s)\n", -			dso_name.c_str(), dso_path.c_str()); -		apr_strerror(rv, errbuf, sizeof(errbuf)); -		fprintf(stderr, "error: %d, %s\n", rv, errbuf); -		apr_dso_error(j2cimpl_dso_handle, errbuf, sizeof(errbuf)); -		fprintf(stderr, "dso-error: %d, %s\n", rv, errbuf); -#endif - -		if ( j2cimpl_dso_handle ) -		{ -			apr_dso_unload(j2cimpl_dso_handle); -			j2cimpl_dso_handle = NULL; -		} - -		if ( j2cimpl_dso_memory_pool ) -		{ -			apr_pool_destroy(j2cimpl_dso_memory_pool); -			j2cimpl_dso_memory_pool = NULL; -		} -	} -} - -//static -void LLImageJ2C::closeDSO() -{ -	if ( j2cimpl_dso_handle ) apr_dso_unload(j2cimpl_dso_handle); -	if (j2cimpl_dso_memory_pool) apr_pool_destroy(j2cimpl_dso_memory_pool); -} +// Test data gathering handle +LLImageCompressionTester* LLImageJ2C::sTesterp = NULL ; +const std::string sTesterName("ImageCompressionTester");  //static  std::string LLImageJ2C::getEngineInfo()  { -	if (!j2cimpl_engineinfo_func) -		j2cimpl_engineinfo_func = fallbackEngineInfoLLImageJ2CImpl; - -	return j2cimpl_engineinfo_func(); +    return fallbackEngineInfoLLImageJ2CImpl();  }  LLImageJ2C::LLImageJ2C() : 	LLImageFormatted(IMG_CODEC_J2C), @@ -175,47 +59,32 @@ LLImageJ2C::LLImageJ2C() : 	LLImageFormatted(IMG_CODEC_J2C),  							mReversible(FALSE),  							mAreaUsedForDataSizeCalcs(0)  { -	//We assume here that if we wanted to create via -	//a dynamic library that the approriate open calls were made -	//before any calls to this constructor. - -	//Therefore, a NULL creation function pointer here means -	//we either did not want to create using functions from the dynamic -	//library or there were issues loading it, either way -	//use our fall back -	if ( !j2cimpl_create_func ) -	{ -		j2cimpl_create_func = fallbackCreateLLImageJ2CImpl; -	} - -	mImpl = j2cimpl_create_func(); +	mImpl = fallbackCreateLLImageJ2CImpl();  	// Clear data size table  	for( S32 i = 0; i <= MAX_DISCARD_LEVEL; i++)  	{	// Array size is MAX_DISCARD_LEVEL+1  		mDataSizes[i] = 0;  	} + +	// If that test log has ben requested but not yet created, create it +	if (LLMetricPerformanceTesterBasic::isMetricLogRequested(sTesterName) && !LLMetricPerformanceTesterBasic::getTester(sTesterName)) +	{ +		sTesterp = new LLImageCompressionTester() ; +		if (!sTesterp->isValid()) +		{ +			delete sTesterp; +			sTesterp = NULL; +		} +	}  }  // virtual  LLImageJ2C::~LLImageJ2C()  { -	//We assume here that if we wanted to destroy via -	//a dynamic library that the approriate open calls were made -	//before any calls to this destructor. - -	//Therefore, a NULL creation function pointer here means -	//we either did not want to destroy using functions from the dynamic -	//library or there were issues loading it, either way -	//use our fall back -	if ( !j2cimpl_destroy_func ) -	{ -		j2cimpl_destroy_func = fallbackDestroyLLImageJ2CImpl; -	} -  	if ( mImpl )  	{ -		j2cimpl_destroy_func(mImpl); +        fallbackDestroyLLImageJ2CImpl(mImpl);  	}  } @@ -280,6 +149,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 )  { +	LLTimer elapsed;  	LLMemType mt1(mMemType);  	BOOL res = TRUE; @@ -318,6 +188,21 @@ BOOL LLImageJ2C::decodeChannels(LLImageRaw *raw_imagep, F32 decode_time, S32 fir  		LLImage::setLastError(mLastError);  	} +	LLImageCompressionTester* tester = (LLImageCompressionTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName); +	if (tester) +	{ +		// Decompression stat gathering +		// Note that we *do not* take into account the decompression failures data so we might overestimate the time spent processing + +		// Always add the decompression time to the stat +		tester->updateDecompressionStats(elapsed.getElapsedTimeF32()) ; +		if (res) +		{ +			// The whole data stream is finally decompressed when res is returned as TRUE +			tester->updateDecompressionStats(this->getDataSize(), raw_imagep->getDataSize()) ; +		} +	} +  	return res;  } @@ -330,6 +215,7 @@ BOOL LLImageJ2C::encode(const LLImageRaw *raw_imagep, F32 encode_time)  BOOL LLImageJ2C::encode(const LLImageRaw *raw_imagep, const char* comment_text, F32 encode_time)  { +	LLTimer elapsed;  	LLMemType mt1(mMemType);  	resetLastError();  	BOOL res = mImpl->encodeImpl(*this, *raw_imagep, comment_text, encode_time, mReversible); @@ -337,6 +223,22 @@ BOOL LLImageJ2C::encode(const LLImageRaw *raw_imagep, const char* comment_text,  	{  		LLImage::setLastError(mLastError);  	} + +	LLImageCompressionTester* tester = (LLImageCompressionTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName); +	if (tester) +	{ +		// Compression stat gathering +		// Note that we *do not* take into account the compression failures cases so we night overestimate the time spent processing + +		// Always add the compression time to the stat +		tester->updateCompressionStats(elapsed.getElapsedTimeF32()) ; +		if (res) +		{ +			// The whole data stream is finally compressed when res is returned as TRUE +			tester->updateCompressionStats(this->getDataSize(), raw_imagep->getDataSize()) ; +		} +	} +  	return res;  } @@ -540,3 +442,125 @@ void LLImageJ2C::updateRawDiscardLevel()  LLImageJ2CImpl::~LLImageJ2CImpl()  {  } + +//---------------------------------------------------------------------------------------------- +// Start of LLImageCompressionTester +//---------------------------------------------------------------------------------------------- +LLImageCompressionTester::LLImageCompressionTester() : LLMetricPerformanceTesterBasic(sTesterName)  +{ +	addMetric("Time Decompression (s)"); +	addMetric("Volume In Decompression (kB)"); +	addMetric("Volume Out Decompression (kB)"); +	addMetric("Decompression Ratio (x:1)"); +	addMetric("Perf Decompression (kB/s)"); + +	addMetric("Time Compression (s)"); +	addMetric("Volume In Compression (kB)"); +	addMetric("Volume Out Compression (kB)"); +	addMetric("Compression Ratio (x:1)"); +	addMetric("Perf Compression (kB/s)"); + +	mRunBytesInDecompression = 0; +	mRunBytesInCompression = 0; + +	mTotalBytesInDecompression = 0; +	mTotalBytesOutDecompression = 0; +	mTotalBytesInCompression = 0; +	mTotalBytesOutCompression = 0; + +	mTotalTimeDecompression = 0.0f; +	mTotalTimeCompression = 0.0f; +} + +LLImageCompressionTester::~LLImageCompressionTester() +{ +	LLImageJ2C::sTesterp = NULL; +} + +//virtual  +void LLImageCompressionTester::outputTestRecord(LLSD *sd)  +{	 +	std::string currentLabel = getCurrentLabelName(); + +	F32 decompressionPerf = 0.0f; +	F32 compressionPerf   = 0.0f; +	F32 decompressionRate = 0.0f; +	F32 compressionRate   = 0.0f; + +	F32 totalkBInDecompression  = (F32)(mTotalBytesInDecompression)  / 1000.0; +	F32 totalkBOutDecompression = (F32)(mTotalBytesOutDecompression) / 1000.0; +	F32 totalkBInCompression    = (F32)(mTotalBytesInCompression)    / 1000.0; +	F32 totalkBOutCompression   = (F32)(mTotalBytesOutCompression)   / 1000.0; +	 +	if (!is_approx_zero(mTotalTimeDecompression)) +	{ +		decompressionPerf = totalkBInDecompression / mTotalTimeDecompression; +	} +	if (!is_approx_zero(totalkBInDecompression)) +	{ +		decompressionRate = totalkBOutDecompression / totalkBInDecompression; +	} +	if (!is_approx_zero(mTotalTimeCompression)) +	{ +		compressionPerf = totalkBInCompression / mTotalTimeCompression; +	} +	if (!is_approx_zero(totalkBOutCompression)) +	{ +		compressionRate = totalkBInCompression / totalkBOutCompression; +	} + +	(*sd)[currentLabel]["Time Decompression (s)"]		= (LLSD::Real)mTotalTimeDecompression; +	(*sd)[currentLabel]["Volume In Decompression (kB)"]	= (LLSD::Real)totalkBInDecompression; +	(*sd)[currentLabel]["Volume Out Decompression (kB)"]= (LLSD::Real)totalkBOutDecompression; +	(*sd)[currentLabel]["Decompression Ratio (x:1)"]	= (LLSD::Real)decompressionRate; +	(*sd)[currentLabel]["Perf Decompression (kB/s)"]	= (LLSD::Real)decompressionPerf; + +	(*sd)[currentLabel]["Time Compression (s)"]			= (LLSD::Real)mTotalTimeCompression; +	(*sd)[currentLabel]["Volume In Compression (kB)"]	= (LLSD::Real)totalkBInCompression; +	(*sd)[currentLabel]["Volume Out Compression (kB)"]	= (LLSD::Real)totalkBOutCompression; +	(*sd)[currentLabel]["Compression Ratio (x:1)"]		= (LLSD::Real)compressionRate; +	(*sd)[currentLabel]["Perf Compression (kB/s)"]		= (LLSD::Real)compressionPerf; +} + +void LLImageCompressionTester::updateCompressionStats(const F32 deltaTime)  +{ +	mTotalTimeCompression += deltaTime; +} + +void LLImageCompressionTester::updateCompressionStats(const S32 bytesCompress, const S32 bytesRaw)  +{ +	mTotalBytesInCompression += bytesRaw; +	mRunBytesInCompression += bytesRaw; +	mTotalBytesOutCompression += bytesCompress; +	if (mRunBytesInCompression > (1000000)) +	{ +		// Output everything +		outputTestResults(); +		// Reset the compression data of the run +		mRunBytesInCompression = 0; +	} +} + +void LLImageCompressionTester::updateDecompressionStats(const F32 deltaTime)  +{ +	mTotalTimeDecompression += deltaTime; +} + +void LLImageCompressionTester::updateDecompressionStats(const S32 bytesIn, const S32 bytesOut)  +{ +	mTotalBytesInDecompression += bytesIn; +	mRunBytesInDecompression += bytesIn; +	mTotalBytesOutDecompression += bytesOut; +	if (mRunBytesInDecompression > (1000000)) +	{ +		// Output everything +		outputTestResults(); +		// Reset the decompression data of the run +		mRunBytesInDecompression = 0; +	} +} + +//---------------------------------------------------------------------------------------------- +// End of LLTexturePipelineTester +//---------------------------------------------------------------------------------------------- + diff --git a/indra/llimage/llimagej2c.h b/indra/llimage/llimagej2c.h index cdb3faa207..dd5bec8b2e 100644 --- a/indra/llimage/llimagej2c.h +++ b/indra/llimage/llimagej2c.h @@ -29,8 +29,11 @@  #include "llimage.h"  #include "llassettype.h" +#include "llmetricperformancetester.h"  class LLImageJ2CImpl; +class LLImageCompressionTester ; +  class LLImageJ2C : public LLImageFormatted  {  protected: @@ -69,14 +72,13 @@ public:  	static S32 calcHeaderSizeJ2C();  	static S32 calcDataSizeJ2C(S32 w, S32 h, S32 comp, S32 discard_level, F32 rate = 0.f); -	static void openDSO(); -	static void closeDSO();  	static std::string getEngineInfo(); -	 +  protected:  	friend class LLImageJ2CImpl;  	friend class LLImageJ2COJ;  	friend class LLImageJ2CKDU; +	friend class LLImageCompressionTester;  	void decodeFailed();  	void updateRawDiscardLevel(); @@ -90,6 +92,9 @@ protected:  	BOOL mReversible;  	LLImageJ2CImpl *mImpl;  	std::string mLastError; + +    // Image compression/decompression tester +	static LLImageCompressionTester* sTesterp;  };  // Derive from this class to implement JPEG2000 decoding @@ -118,4 +123,40 @@ protected:  #define LINDEN_J2C_COMMENT_PREFIX "LL_" +// +// This class is used for performance data gathering only. +// Tracks the image compression / decompression data, +// records and outputs them to the log file. +// +class LLImageCompressionTester : public LLMetricPerformanceTesterBasic +{ +    public: +        LLImageCompressionTester(); +        ~LLImageCompressionTester(); +         +        void updateDecompressionStats(const F32 deltaTime) ; +        void updateDecompressionStats(const S32 bytesIn, const S32 bytesOut) ; +        void updateCompressionStats(const F32 deltaTime) ; +        void updateCompressionStats(const S32 bytesIn, const S32 bytesOut) ; +     +    protected: +        /*virtual*/ void outputTestRecord(LLSD* sd); +         +    private: +        // +        // Data size +        // +        U32 mTotalBytesInDecompression;     // Total bytes fed to decompressor +        U32 mTotalBytesOutDecompression;    // Total bytes produced by decompressor +        U32 mTotalBytesInCompression;       // Total bytes fed to compressor +        U32 mTotalBytesOutCompression;      // Total bytes produced by compressor +		U32 mRunBytesInDecompression;		// Bytes fed to decompressor in this run +		U32 mRunBytesInCompression;			// Bytes fed to compressor in this run +        // +        // Time +        // +        F32 mTotalTimeDecompression;        // Total time spent in computing decompression +        F32 mTotalTimeCompression;          // Total time spent in computing compression +    }; +  #endif diff --git a/indra/llimage/llimageworker.cpp b/indra/llimage/llimageworker.cpp index d1c74b6fa1..28dc3bd313 100644 --- a/indra/llimage/llimageworker.cpp +++ b/indra/llimage/llimageworker.cpp @@ -38,6 +38,12 @@ LLImageDecodeThread::LLImageDecodeThread(bool threaded)  	mCreationMutex = new LLMutex(getAPRPool());  } +//virtual  +LLImageDecodeThread::~LLImageDecodeThread() +{ +	delete mCreationMutex ; +} +  // MAIN THREAD  // virtual  S32 LLImageDecodeThread::update(U32 max_time_ms) diff --git a/indra/llimage/llimageworker.h b/indra/llimage/llimageworker.h index c3c92ec832..c684222fa5 100644 --- a/indra/llimage/llimageworker.h +++ b/indra/llimage/llimageworker.h @@ -73,6 +73,8 @@ public:  public:  	LLImageDecodeThread(bool threaded = true); +	virtual ~LLImageDecodeThread(); +  	handle_t decodeImage(LLImageFormatted* image,  						 U32 priority, S32 discard, BOOL needs_aux,  						 Responder* responder); diff --git a/indra/llimage/llpngwrapper.cpp b/indra/llimage/llpngwrapper.cpp index fe737e2072..2cc7d3c460 100644 --- a/indra/llimage/llpngwrapper.cpp +++ b/indra/llimage/llpngwrapper.cpp @@ -50,8 +50,6 @@ LLPngWrapper::LLPngWrapper()  	  mCompressionType( 0 ),  	  mFilterMethod( 0 ),  	  mFinalSize( 0 ), -	  mHasBKGD(false), -	  mBackgroundColor(),  	  mGamma(0.f)  {  } @@ -111,9 +109,9 @@ void LLPngWrapper::writeFlush(png_structp png_ptr)  }  // Read the PNG file using the libpng.  The low-level interface is used here -// because we want to do various transformations (including setting the -// matte background if any, and applying gama) which can't be done with -// the high-level interface. The scanline also begins at the bottom of +// because we want to do various transformations (including applying gama) +// which can't be done with the high-level interface. +// The scanline also begins at the bottom of  // the image (per SecondLife conventions) instead of at the top, so we  // must assign row-pointers in "reverse" order.  BOOL LLPngWrapper::readPng(U8* src, LLImageRaw* rawImage, ImageInfo *infop) @@ -201,8 +199,7 @@ void LLPngWrapper::normalizeImage()  	//		2. Convert grayscales to RGB  	//		3. Create alpha layer from transparency  	//		4. Ensure 8-bpp for all images -	//		5. Apply background matte if any -	//		6. Set (or guess) gamma +	//		5. Set (or guess) gamma  	if (mColorType == PNG_COLOR_TYPE_PALETTE)  	{ @@ -229,12 +226,6 @@ void LLPngWrapper::normalizeImage()  	{  		png_set_strip_16(mReadPngPtr);  	} -	mHasBKGD = png_get_bKGD(mReadPngPtr, mReadInfoPtr, &mBackgroundColor); -	if (mHasBKGD) -	{ -		png_set_background(mReadPngPtr, mBackgroundColor, -			PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); -	}  #if LL_DARWIN  	const F64 SCREEN_GAMMA = 1.8; @@ -261,7 +252,6 @@ void LLPngWrapper::updateMetaData()      mBitDepth = png_get_bit_depth(mReadPngPtr, mReadInfoPtr);      mColorType = png_get_color_type(mReadPngPtr, mReadInfoPtr);  	mChannels = png_get_channels(mReadPngPtr, mReadInfoPtr); -	mHasBKGD = png_get_bKGD(mReadPngPtr, mReadInfoPtr, &mBackgroundColor);  }  // Method to write raw image into PNG at dest. The raw scanline begins diff --git a/indra/llimage/llpngwrapper.h b/indra/llimage/llpngwrapper.h index 47a4207d66..739f435996 100644 --- a/indra/llimage/llpngwrapper.h +++ b/indra/llimage/llpngwrapper.h @@ -88,9 +88,6 @@ private:  	U32 mFinalSize; -	bool mHasBKGD; -	png_color_16p mBackgroundColor; -  	F64 mGamma;  	std::string mErrorMessage; diff --git a/indra/llimage/tests/llimageworker_test.cpp b/indra/llimage/tests/llimageworker_test.cpp index a109276709..08476fb72c 100644 --- a/indra/llimage/tests/llimageworker_test.cpp +++ b/indra/llimage/tests/llimageworker_test.cpp @@ -26,10 +26,8 @@   */  // Precompiled header: almost always required for newview cpp files -#include <list> -#include <map> -#include <algorithm> -// Class to test +#include "linden_common.h" +// Class to test   #include "../llimageworker.h"  // For timer class  #include "../llcommon/lltimer.h" @@ -44,7 +42,17 @@  // * Do not make any assumption as to how those classes or methods work (i.e. don't copy/paste code)  // * A simulator for a class can be implemented here. Please comment and document thoroughly. -LLImageBase::LLImageBase() {} +LLImageBase::LLImageBase()  +: mData(NULL), +mDataSize(0), +mWidth(0), +mHeight(0), +mComponents(0), +mBadBufferAllocation(false), +mAllowOverSize(false), +mMemType(LLMemType::MTYPE_IMAGEBASE) +{ +}  LLImageBase::~LLImageBase() {}  void LLImageBase::dump() { }  void LLImageBase::sanityCheck() { } | 
