diff options
| -rw-r--r-- | indra/llcommon/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | indra/llcommon/llfasttimer_class.cpp | 1 | ||||
| -rw-r--r-- | indra/llcommon/llfasttimer_class.h | 1 | ||||
| -rw-r--r-- | indra/llcommon/llmetricperformancetester.cpp | 254 | ||||
| -rw-r--r-- | indra/llcommon/llmetricperformancetester.h | 206 | ||||
| -rw-r--r-- | indra/llimage/llimagej2c.cpp | 178 | ||||
| -rw-r--r-- | indra/llimage/llimagej2c.h | 45 | ||||
| -rw-r--r-- | indra/newview/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | indra/newview/app_settings/cmd_line.xml | 2 | ||||
| -rw-r--r-- | indra/newview/llappviewer.cpp | 55 | ||||
| -rw-r--r-- | indra/newview/llappviewer.h | 2 | ||||
| -rw-r--r-- | indra/newview/llfasttimerview.cpp | 55 | ||||
| -rw-r--r-- | indra/newview/llfasttimerview.h | 1 | ||||
| -rw-r--r-- | indra/newview/llmetricperformancetester.cpp | 252 | ||||
| -rw-r--r-- | indra/newview/llmetricperformancetester.h | 153 | ||||
| -rw-r--r-- | indra/newview/lltexturefetch.cpp | 1 | ||||
| -rw-r--r-- | indra/newview/llviewertexture.cpp | 116 | ||||
| -rw-r--r-- | indra/newview/llviewertexture.h | 6 | 
18 files changed, 827 insertions, 505 deletions
| diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 7bad780dd8..478f2fedbd 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -70,6 +70,7 @@ set(llcommon_SOURCE_FILES      llmemorystream.cpp      llmemtype.cpp      llmetrics.cpp +    llmetricperformancetester.cpp      llmortician.cpp      lloptioninterface.cpp      llptrto.cpp  @@ -186,6 +187,7 @@ set(llcommon_HEADER_FILES      llmemorystream.h      llmemtype.h      llmetrics.h +    llmetricperformancetester.h      llmortician.h      llnametable.h      lloptioninterface.h diff --git a/indra/llcommon/llfasttimer_class.cpp b/indra/llcommon/llfasttimer_class.cpp index c45921cdec..bce87ada96 100644 --- a/indra/llcommon/llfasttimer_class.cpp +++ b/indra/llcommon/llfasttimer_class.cpp @@ -56,6 +56,7 @@ bool LLFastTimer::sPauseHistory = 0;  bool LLFastTimer::sResetHistory = 0;  LLFastTimer::CurTimerData LLFastTimer::sCurTimerData;  BOOL LLFastTimer::sLog = FALSE; +std::string LLFastTimer::sLogName = "";  BOOL LLFastTimer::sMetricLog = FALSE;  LLMutex* LLFastTimer::sLogLock = NULL;  std::queue<LLSD> LLFastTimer::sLogQueue; diff --git a/indra/llcommon/llfasttimer_class.h b/indra/llcommon/llfasttimer_class.h index 1158ac5140..eb9789682b 100644 --- a/indra/llcommon/llfasttimer_class.h +++ b/indra/llcommon/llfasttimer_class.h @@ -211,6 +211,7 @@ public:  	static std::queue<LLSD> sLogQueue;  	static BOOL				sLog;  	static BOOL				sMetricLog; +	static std::string		sLogName;  	static bool 			sPauseHistory;  	static bool 			sResetHistory;  	static U64				sTimerCycles; diff --git a/indra/llcommon/llmetricperformancetester.cpp b/indra/llcommon/llmetricperformancetester.cpp new file mode 100644 index 0000000000..5fa3a5ea07 --- /dev/null +++ b/indra/llcommon/llmetricperformancetester.cpp @@ -0,0 +1,254 @@ +/**  + * @file llmetricperformancetester.cpp + * @brief LLMetricPerformanceTesterBasic and LLMetricPerformanceTesterWithSession classes implementation + * + * $LicenseInfo:firstyear=2004&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "indra_constants.h" +#include "llerror.h" +#include "llsdserialize.h" +#include "llstat.h" +#include "lltreeiterators.h" +#include "llmetricperformancetester.h" + +//---------------------------------------------------------------------------------------------- +// LLMetricPerformanceTesterBasic : static methods and testers management +//---------------------------------------------------------------------------------------------- + +LLMetricPerformanceTesterBasic::name_tester_map_t LLMetricPerformanceTesterBasic::sTesterMap ; + +/*static*/  +void LLMetricPerformanceTesterBasic::cleanClass()  +{ +	for (name_tester_map_t::iterator iter = sTesterMap.begin() ; iter != sTesterMap.end() ; ++iter) +	{ +		delete iter->second ; +	} +	sTesterMap.clear() ; +} + +/*static*/  +BOOL LLMetricPerformanceTesterBasic::addTester(LLMetricPerformanceTesterBasic* tester)  +{ +	llassert_always(tester != NULL);	 +	std::string name = tester->getTesterName() ; +	if (getTester(name)) +	{ +		llerrs << "Tester name is already used by some other tester : " << name << llendl ; +		return FALSE; +	} + +	sTesterMap.insert(std::make_pair(name, tester)); +	return TRUE; +} +	 +/*static*/  +LLMetricPerformanceTesterBasic* LLMetricPerformanceTesterBasic::getTester(std::string name)  +{ +	// Check for the requested metric name +	name_tester_map_t::iterator found_it = sTesterMap.find(name) ; +	if (found_it != sTesterMap.end()) +	{ +		return found_it->second ; +	} +	return NULL ; +} + +/*static*/  +// Return TRUE if this metric is requested or if the general default "catch all" metric is requested +BOOL LLMetricPerformanceTesterBasic::isMetricLogRequested(std::string name) +{ +	return (LLFastTimer::sMetricLog && ((LLFastTimer::sLogName == name) || (LLFastTimer::sLogName == DEFAULT_METRIC_NAME))); +} + +	 +//---------------------------------------------------------------------------------------------- +// LLMetricPerformanceTesterBasic : Tester instance methods +//---------------------------------------------------------------------------------------------- + +LLMetricPerformanceTesterBasic::LLMetricPerformanceTesterBasic(std::string name) :  +	mName(name), +	mCount(0) +{ +	if (mName == std::string()) +	{ +		llerrs << "LLMetricPerformanceTesterBasic construction invalid : Empty name passed to constructor" << llendl ; +	} + +	mValidInstance = LLMetricPerformanceTesterBasic::addTester(this) ; +} + +LLMetricPerformanceTesterBasic::~LLMetricPerformanceTesterBasic()  +{ +} + +void LLMetricPerformanceTesterBasic::preOutputTestResults(LLSD* sd)  +{ +	incrementCurrentCount() ; +	(*sd)[getCurrentLabelName()]["Name"] = mName ; +} + +void LLMetricPerformanceTesterBasic::postOutputTestResults(LLSD* sd) +{ +	LLMutexLock lock(LLFastTimer::sLogLock); +	LLFastTimer::sLogQueue.push((*sd)); +} + +void LLMetricPerformanceTesterBasic::outputTestResults()  +{ +	LLSD sd; + +	preOutputTestResults(&sd) ;  +	outputTestRecord(&sd) ; +	postOutputTestResults(&sd) ; +} + +void LLMetricPerformanceTesterBasic::addMetric(std::string str) +{ +	mMetricStrings.push_back(str) ; +} + +/*virtual*/  +void LLMetricPerformanceTesterBasic::analyzePerformance(std::ofstream* os, LLSD* base, LLSD* current)  +{ +	resetCurrentCount() ; + +	std::string current_label = getCurrentLabelName(); +	BOOL in_base = (*base).has(current_label) ; +	BOOL in_current = (*current).has(current_label) ; + +	while(in_base || in_current) +	{ +		LLSD::String label = current_label ;		 + +		if(in_base && in_current) +		{				 +			*os << llformat("%s\n", label.c_str()) ; + +			for(U32 index = 0 ; index < mMetricStrings.size() ; index++) +			{ +				switch((*current)[label][ mMetricStrings[index] ].type()) +				{ +				case LLSD::TypeInteger: +					compareTestResults(os, mMetricStrings[index],  +						(S32)((*base)[label][ mMetricStrings[index] ].asInteger()), (S32)((*current)[label][ mMetricStrings[index] ].asInteger())) ; +					break ; +				case LLSD::TypeReal: +					compareTestResults(os, mMetricStrings[index],  +						(F32)((*base)[label][ mMetricStrings[index] ].asReal()), (F32)((*current)[label][ mMetricStrings[index] ].asReal())) ; +					break; +				default: +					llerrs << "unsupported metric " << mMetricStrings[index] << " LLSD type: " << (S32)(*current)[label][ mMetricStrings[index] ].type() << llendl ; +				} +			}	 +		} + +		incrementCurrentCount(); +		current_label = getCurrentLabelName(); +		in_base = (*base).has(current_label) ; +		in_current = (*current).has(current_label) ; +	} +} + +/*virtual*/  +void LLMetricPerformanceTesterBasic::compareTestResults(std::ofstream* os, std::string metric_string, S32 v_base, S32 v_current)  +{ +	*os << llformat(" ,%s, %d, %d, %d, %.4f\n", metric_string.c_str(), v_base, v_current,  +						v_current - v_base, (v_base != 0) ? 100.f * v_current / v_base : 0) ; +} + +/*virtual*/  +void LLMetricPerformanceTesterBasic::compareTestResults(std::ofstream* os, std::string metric_string, F32 v_base, F32 v_current)  +{ +	*os << llformat(" ,%s, %.4f, %.4f, %.4f, %.4f\n", metric_string.c_str(), v_base, v_current,						 +						v_current - v_base, (fabs(v_base) > 0.0001f) ? 100.f * v_current / v_base : 0.f ) ; +} + +//---------------------------------------------------------------------------------------------- +// LLMetricPerformanceTesterWithSession +//---------------------------------------------------------------------------------------------- + +LLMetricPerformanceTesterWithSession::LLMetricPerformanceTesterWithSession(std::string name) :  +	LLMetricPerformanceTesterBasic(name), +	mBaseSessionp(NULL), +	mCurrentSessionp(NULL) +{ +} + +LLMetricPerformanceTesterWithSession::~LLMetricPerformanceTesterWithSession() +{ +	if (mBaseSessionp) +	{ +		delete mBaseSessionp ; +		mBaseSessionp = NULL ; +	} +	if (mCurrentSessionp) +	{ +		delete mCurrentSessionp ; +		mCurrentSessionp = NULL ; +	} +} + +/*virtual*/  +void LLMetricPerformanceTesterWithSession::analyzePerformance(std::ofstream* os, LLSD* base, LLSD* current)  +{ +	// Load the base session +	resetCurrentCount() ; +	mBaseSessionp = loadTestSession(base) ; + +	// Load the current session +	resetCurrentCount() ; +	mCurrentSessionp = loadTestSession(current) ; + +	if (!mBaseSessionp || !mCurrentSessionp) +	{ +		llerrs << "Error loading test sessions." << llendl ; +	} + +	// Compare +	compareTestSessions(os) ; + +	// Release memory +	if (mBaseSessionp) +	{ +		delete mBaseSessionp ; +		mBaseSessionp = NULL ; +	} +	if (mCurrentSessionp) +	{ +		delete mCurrentSessionp ; +		mCurrentSessionp = NULL ; +	} +} + + +//---------------------------------------------------------------------------------------------- +// LLTestSession +//---------------------------------------------------------------------------------------------- + +LLMetricPerformanceTesterWithSession::LLTestSession::~LLTestSession()  +{ +} + diff --git a/indra/llcommon/llmetricperformancetester.h b/indra/llcommon/llmetricperformancetester.h new file mode 100644 index 0000000000..925010ac96 --- /dev/null +++ b/indra/llcommon/llmetricperformancetester.h @@ -0,0 +1,206 @@ +/**  + * @file llmetricperformancetester.h  + * @brief LLMetricPerformanceTesterBasic and LLMetricPerformanceTesterWithSession classes definition + * + * $LicenseInfo:firstyear=2004&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#ifndef LL_METRICPERFORMANCETESTER_H  +#define LL_METRICPERFORMANCETESTER_H  + +const std::string DEFAULT_METRIC_NAME("metric"); + +/** + * @class LLMetricPerformanceTesterBasic + * @brief Performance Metric Base Class + */ +class LL_COMMON_API LLMetricPerformanceTesterBasic +{ +public: +	/** +	 * @brief Creates a basic tester instance. +	 * @param[in] name - Unique string identifying this tester instance. +	 */ +	LLMetricPerformanceTesterBasic(std::string name); +	virtual ~LLMetricPerformanceTesterBasic(); + +	/** +	 * @return Returns true if the instance has been added to the tester map. +	 * Need to be tested after creation of a tester instance so to know if the tester is correctly handled. +	 * A tester might not be added to the map if another tester with the same name already exists. +	 */ +	BOOL isValid() const { return mValidInstance; } + +	/** +	 * @brief Write a set of test results to the log LLSD. +	 */ +	void outputTestResults() ; + +	/** +	 * @brief Compare the test results. +	 * By default, compares the test results against the baseline one by one, item by item,  +	 * in the increasing order of the LLSD record counter, starting from the first one. +	 */ +	virtual void analyzePerformance(std::ofstream* os, LLSD* base, LLSD* current) ; + +	/** +	 * @return Returns the number of the test metrics in this tester instance. +	 */ +	S32 getNumberOfMetrics() const { return mMetricStrings.size() ;} +	/** +	 * @return Returns the metric name at index +	 * @param[in] index - Index on the list of metrics managed by this tester instance. +	 */ +	std::string getMetricName(S32 index) const { return mMetricStrings[index] ;} + +protected: +	/** +	 * @return Returns the name of this tester instance. +	 */ +	std::string getTesterName() const { return mName ;} + +	/** +	 * @brief Insert a new metric to be managed by this tester instance. +	 * @param[in] str - Unique string identifying the new metric. +	 */ +	void addMetric(std::string str) ; + +	/** +	 * @brief Compare test results, provided in 2 flavors: compare integers and compare floats. +	 * @param[out] os - Formatted output string holding the compared values. +	 * @param[in] metric_string - Name of the metric. +	 * @param[in] v_base - Base value of the metric. +	 * @param[in] v_current - Current value of the metric. +	 */ +	virtual void compareTestResults(std::ofstream* os, std::string metric_string, S32 v_base, S32 v_current) ; +	virtual void compareTestResults(std::ofstream* os, std::string metric_string, F32 v_base, F32 v_current) ; + +	/** +	 * @brief Reset internal record count. Count starts with 1. +	 */ +	void resetCurrentCount() { mCount = 1; } +	/** +	 * @brief Increment internal record count. +	 */ +	void incrementCurrentCount() { mCount++; } +	/** +	 * @return Returns the label to be used for the current count. It's "TesterName"-"Count". +	 */ +	std::string getCurrentLabelName() const { return llformat("%s-%d", mName.c_str(), mCount) ;} + +	/** +	 * @brief Write a test record to the LLSD. Implementers need to overload this method. +	 * @param[out] sd - The LLSD record to store metric data into. +	 */ +	virtual void outputTestRecord(LLSD* sd) = 0 ; + +private: +	void preOutputTestResults(LLSD* sd) ; +	void postOutputTestResults(LLSD* sd) ; + +	std::string mName ;							// Name of this tester instance +	S32 mCount ;								// Current record count +	BOOL mValidInstance;						// TRUE if the instance is managed by the map +	std::vector< std::string > mMetricStrings ; // Metrics strings + +// Static members managing the collection of testers +public:	 +	// Map of all the tester instances in use +	typedef std::map< std::string, LLMetricPerformanceTesterBasic* > name_tester_map_t;	 +	static name_tester_map_t sTesterMap ; + +	/** +	 * @return Returns a pointer to the tester +	 * @param[in] name - Name of the tester instance queried. +	 */ +	static LLMetricPerformanceTesterBasic* getTester(std::string name) ; +	 +	/** +	 * @return Returns TRUE if that metric *or* the default catch all metric has been requested to be logged +	 * @param[in] name - Name of the tester queried. +	 */ +	static BOOL isMetricLogRequested(std::string name); +	 +	/** +	 * @return Returns TRUE if there's a tester defined, FALSE otherwise. +	 */ +	static BOOL hasMetricPerformanceTesters() { return !sTesterMap.empty() ;} +	/** +	 * @brief Delete all testers and reset the tester map +	 */ +	static void cleanClass() ; + +private: +	// Add a tester to the map. Returns false if adding fails. +	static BOOL addTester(LLMetricPerformanceTesterBasic* tester) ; +}; + +/** + * @class LLMetricPerformanceTesterWithSession + * @brief Performance Metric Class with custom session  + */ +class LL_COMMON_API LLMetricPerformanceTesterWithSession : public LLMetricPerformanceTesterBasic +{ +public: +	/** +	 * @param[in] name - Unique string identifying this tester instance. +	 */ +	LLMetricPerformanceTesterWithSession(std::string name); +	virtual ~LLMetricPerformanceTesterWithSession(); + +	/** +	 * @brief Compare the test results. +	 * This will be loading the base and current sessions and compare them using the virtual  +	 * abstract methods loadTestSession() and compareTestSessions() +	 */ +	virtual void analyzePerformance(std::ofstream* os, LLSD* base, LLSD* current) ; + +protected: +	/** +	 * @class LLMetricPerformanceTesterWithSession::LLTestSession +	 * @brief Defines an interface for the two abstract virtual functions loadTestSession() and compareTestSessions() +	 */ +	class LL_COMMON_API LLTestSession +		{ +		public: +			virtual ~LLTestSession() ; +		}; + +	/** +	 * @brief Convert an LLSD log into a test session. +	 * @param[in] log - The LLSD record +	 * @return Returns the record as a test session +	 */ +	virtual LLMetricPerformanceTesterWithSession::LLTestSession* loadTestSession(LLSD* log) = 0; + +	/** +	 * @brief Compare the base session and the target session. Assumes base and current sessions have been loaded. +	 * @param[out] os - The comparison result as a standard stream +	 */ +	virtual void compareTestSessions(std::ofstream* os) = 0; + +	LLTestSession* mBaseSessionp; +	LLTestSession* mCurrentSessionp; +}; + +#endif + diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp index c8c866b7f2..d005aaf29f 100644 --- a/indra/llimage/llimagej2c.cpp +++ b/indra/llimage/llimagej2c.cpp @@ -30,6 +30,8 @@  #include "lldir.h"  #include "llimagej2c.h"  #include "llmemtype.h" +#include "lltimer.h" +#include "llmath.h"  typedef LLImageJ2CImpl* (*CreateLLImageJ2CFunction)();  typedef void (*DestroyLLImageJ2CFunction)(LLImageJ2CImpl*); @@ -51,6 +53,10 @@ LLImageJ2CImpl* fallbackCreateLLImageJ2CImpl();  void fallbackDestroyLLImageJ2CImpl(LLImageJ2CImpl* impl);  const char* fallbackEngineInfoLLImageJ2CImpl(); +// Test data gathering handle +LLImageCompressionTester* LLImageJ2C::sTesterp = NULL ; +const std::string sTesterName("ImageCompressionTester"); +  //static  //Loads the required "create", "destroy" and "engineinfo" functions needed  void LLImageJ2C::openDSO() @@ -71,8 +77,8 @@ void LLImageJ2C::openDSO()  #endif  	dso_path = gDirUtilp->findFile(dso_name, -				       gDirUtilp->getAppRODataDir(), -				       gDirUtilp->getExecutableDir()); +								   gDirUtilp->getAppRODataDir(), +								   gDirUtilp->getExecutableDir());  	j2cimpl_dso_handle      = NULL;  	j2cimpl_dso_memory_pool = NULL; @@ -102,7 +108,7 @@ void LLImageJ2C::openDSO()  			//so lets check for a destruction function  			rv = apr_dso_sym((apr_dso_handle_sym_t*)&dest_func,  							 j2cimpl_dso_handle, -						       "destroyLLImageJ2CKDU"); +							 "destroyLLImageJ2CKDU");  			if ( rv == APR_SUCCESS )  			{  				//we've loaded the destroy function ok @@ -195,6 +201,17 @@ LLImageJ2C::LLImageJ2C() : 	LLImageFormatted(IMG_CODEC_J2C),  	{	// 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 @@ -280,6 +297,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 +336,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 +363,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 +371,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 +590,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..cc3dabd7d8 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: @@ -72,11 +75,12 @@ public:  	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 +94,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 +125,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/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index bf885e5934..09622d3af5 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -290,7 +290,6 @@ set(viewer_SOURCE_FILES      llmediadataclient.cpp      llmemoryview.cpp      llmenucommands.cpp -    llmetricperformancetester.cpp      llmimetypes.cpp      llmorphview.cpp      llmoveview.cpp @@ -822,7 +821,6 @@ set(viewer_HEADER_FILES      llmediadataclient.h      llmemoryview.h      llmenucommands.h -    llmetricperformancetester.h      llmimetypes.h      llmorphview.h      llmoveview.h diff --git a/indra/newview/app_settings/cmd_line.xml b/indra/newview/app_settings/cmd_line.xml index ba3b6a42a4..0562cf5480 100644 --- a/indra/newview/app_settings/cmd_line.xml +++ b/indra/newview/app_settings/cmd_line.xml @@ -118,6 +118,8 @@      <map>        <key>desc</key>        <string>Log metrics for benchmarking</string> +      <key>count</key> +      <integer>1</integer>        <key>map-to</key>        <string>LogMetrics</string>      </map> diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 60ed37bdfb..bf0f948a6d 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -510,16 +510,10 @@ class LLFastTimerLogThread : public LLThread  public:  	std::string mFile; -	LLFastTimerLogThread() : LLThread("fast timer log") +	LLFastTimerLogThread(std::string& test_name) : LLThread("fast timer log")  	{ -		if(LLFastTimer::sLog) -		{ -			mFile = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "performance.slp"); -		} -		if(LLFastTimer::sMetricLog) -		{ -			mFile = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "metric.slp"); -		} +		std::string file_name = test_name + std::string(".slp"); +		mFile = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, file_name);  	}  	void run() @@ -535,6 +529,7 @@ public:  		os.close();  	} +  };  //virtual @@ -1643,22 +1638,16 @@ bool LLAppViewer::cleanup()  	{  		llinfos << "Analyzing performance" << llendl; -		if(LLFastTimer::sLog) -		{ -			LLFastTimerView::doAnalysis( -				gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "performance_baseline.slp"), -				gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "performance.slp"), -				gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "performance_report.csv")); -		} -		if(LLFastTimer::sMetricLog) -		{ -			LLFastTimerView::doAnalysis( -				gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "metric_baseline.slp"), -				gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "metric.slp"), -				gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "metric_report.csv")); -		} +		std::string baseline_name = LLFastTimer::sLogName + "_baseline.slp"; +		std::string current_name  = LLFastTimer::sLogName + ".slp";  +		std::string report_name   = LLFastTimer::sLogName + "_report.csv"; + +		LLFastTimerView::doAnalysis( +			gDirUtilp->getExpandedFilename(LL_PATH_LOGS, baseline_name), +			gDirUtilp->getExpandedFilename(LL_PATH_LOGS, current_name), +			gDirUtilp->getExpandedFilename(LL_PATH_LOGS, report_name));  	} -	LLMetricPerformanceTester::cleanClass() ; +	LLMetricPerformanceTesterBasic::cleanClass() ;  	llinfos << "Cleaning up Media and Textures" << llendflush; @@ -1765,7 +1754,7 @@ bool LLAppViewer::initThreads()  	if (LLFastTimer::sLog || LLFastTimer::sMetricLog)  	{  		LLFastTimer::sLogLock = new LLMutex(NULL); -		mFastTimerLogThread = new LLFastTimerLogThread(); +		mFastTimerLogThread = new LLFastTimerLogThread(LLFastTimer::sLogName);  		mFastTimerLogThread->start();  	} @@ -2116,11 +2105,25 @@ bool LLAppViewer::initConfiguration()  	if (clp.hasOption("logperformance"))  	{  		LLFastTimer::sLog = TRUE; +		LLFastTimer::sLogName = std::string("performance");  	} -	if(clp.hasOption("logmetrics")) +	if (clp.hasOption("logmetrics"))  	{  		LLFastTimer::sMetricLog = TRUE ; +		// '--logmetrics' can be specified with a named test metric argument so the data gathering is done only on that test +		// In the absence of argument, every metric is gathered (makes for a rather slow run and hard to decipher report...) +		std::string test_name = clp.getOption("logmetrics")[0]; +		llinfos << "'--logmetrics' argument : " << test_name << llendl; +		if (test_name == "") +		{ +			llwarns << "No '--logmetrics' argument given, will output all metrics to " << DEFAULT_METRIC_NAME << llendl; +			LLFastTimer::sLogName = DEFAULT_METRIC_NAME; +		} +		else +		{ +			LLFastTimer::sLogName = test_name; +		}  	}  	if (clp.hasOption("graphicslevel")) diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index a40cd83182..a14ab4362f 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -251,7 +251,9 @@ private:  	LLWatchdogTimeout* mMainloopTimeout; +	// For performance and metric gathering  	LLThread*	mFastTimerLogThread; +  	// for tracking viewer<->region circuit death  	bool mAgentRegionLastAlive;  	LLUUID mAgentRegionLastID; diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp index a09c0ea0f8..92a3b9b2f5 100644 --- a/indra/newview/llfasttimerview.cpp +++ b/indra/newview/llfasttimerview.cpp @@ -1086,14 +1086,22 @@ LLSD LLFastTimerView::analyzePerformanceLogDefault(std::istream& is)  //static  void LLFastTimerView::doAnalysisDefault(std::string baseline, std::string target, std::string output)  { +	// Open baseline and current target, exit if one is inexistent +	std::ifstream base_is(baseline.c_str()); +	std::ifstream target_is(target.c_str()); +	if (!base_is.is_open() || !target_is.is_open()) +	{ +		llwarns << "'-analyzeperformance' error : baseline or current target file inexistent" << llendl; +		base_is.close(); +		target_is.close(); +		return; +	}  	//analyze baseline -	std::ifstream base_is(baseline.c_str());  	LLSD base = analyzePerformanceLogDefault(base_is);  	base_is.close();  	//analyze current -	std::ifstream target_is(target.c_str());  	LLSD current = analyzePerformanceLogDefault(target_is);  	target_is.close(); @@ -1154,15 +1162,15 @@ LLSD LLFastTimerView::analyzeMetricPerformanceLog(std::istream& is)  		{  			std::string label = iter->first; -			LLMetricPerformanceTester* tester = LLMetricPerformanceTester::getTester(iter->second["Name"].asString()) ; +			LLMetricPerformanceTesterBasic* tester = LLMetricPerformanceTesterBasic::getTester(iter->second["Name"].asString()) ;  			if(tester)  			{  				ret[label]["Name"] = iter->second["Name"] ; -				S32 num_of_strings = tester->getNumOfMetricStrings() ; -				for(S32 index = 0 ; index < num_of_strings ; index++) +				S32 num_of_metrics = tester->getNumberOfMetrics() ; +				for(S32 index = 0 ; index < num_of_metrics ; index++)  				{ -					ret[label][ tester->getMetricString(index) ] = iter->second[ tester->getMetricString(index) ] ; +					ret[label][ tester->getMetricName(index) ] = iter->second[ tester->getMetricName(index) ] ;  				}  			}  		} @@ -1172,20 +1180,43 @@ LLSD LLFastTimerView::analyzeMetricPerformanceLog(std::istream& is)  }  //static +void LLFastTimerView::outputAllMetrics() +{ +	if (LLMetricPerformanceTesterBasic::hasMetricPerformanceTesters()) +	{ +		for (LLMetricPerformanceTesterBasic::name_tester_map_t::iterator iter = LLMetricPerformanceTesterBasic::sTesterMap.begin();  +			iter != LLMetricPerformanceTesterBasic::sTesterMap.end(); ++iter) +		{ +			LLMetricPerformanceTesterBasic* tester = ((LLMetricPerformanceTesterBasic*)iter->second);	 +			tester->outputTestResults(); +		} +	} +} + +//static  void LLFastTimerView::doAnalysisMetrics(std::string baseline, std::string target, std::string output)  { -	if(!LLMetricPerformanceTester::hasMetricPerformanceTesters()) +	if(!LLMetricPerformanceTesterBasic::hasMetricPerformanceTesters())  	{  		return ;  	} -	//analyze baseline +	// Open baseline and current target, exit if one is inexistent  	std::ifstream base_is(baseline.c_str()); +	std::ifstream target_is(target.c_str()); +	if (!base_is.is_open() || !target_is.is_open()) +	{ +		llwarns << "'-analyzeperformance' error : baseline or current target file inexistent" << llendl; +		base_is.close(); +		target_is.close(); +		return; +	} + +	//analyze baseline  	LLSD base = analyzeMetricPerformanceLog(base_is);  	base_is.close();  	//analyze current -	std::ifstream target_is(target.c_str());  	LLSD current = analyzeMetricPerformanceLog(target_is);  	target_is.close(); @@ -1193,10 +1224,10 @@ void LLFastTimerView::doAnalysisMetrics(std::string baseline, std::string target  	std::ofstream os(output.c_str());  	os << "Label, Metric, Base(B), Target(T), Diff(T-B), Percentage(100*T/B)\n";  -	for(LLMetricPerformanceTester::name_tester_map_t::iterator iter = LLMetricPerformanceTester::sTesterMap.begin() ;  -		iter != LLMetricPerformanceTester::sTesterMap.end() ; ++iter) +	for(LLMetricPerformanceTesterBasic::name_tester_map_t::iterator iter = LLMetricPerformanceTesterBasic::sTesterMap.begin() ;  +		iter != LLMetricPerformanceTesterBasic::sTesterMap.end() ; ++iter)  	{ -		LLMetricPerformanceTester* tester = ((LLMetricPerformanceTester*)iter->second) ;	 +		LLMetricPerformanceTesterBasic* tester = ((LLMetricPerformanceTesterBasic*)iter->second) ;	  		tester->analyzePerformance(&os, &base, ¤t) ;  	} diff --git a/indra/newview/llfasttimerview.h b/indra/newview/llfasttimerview.h index 3788897cec..1a54a53f09 100644 --- a/indra/newview/llfasttimerview.h +++ b/indra/newview/llfasttimerview.h @@ -37,6 +37,7 @@ public:  	static BOOL sAnalyzePerformance; +	static void outputAllMetrics();  	static void doAnalysis(std::string baseline, std::string target, std::string output);  private: diff --git a/indra/newview/llmetricperformancetester.cpp b/indra/newview/llmetricperformancetester.cpp deleted file mode 100644 index 903c97378e..0000000000 --- a/indra/newview/llmetricperformancetester.cpp +++ /dev/null @@ -1,252 +0,0 @@ -/**  - * @file llmetricperformancetester.cpp - * @brief LLMetricPerformanceTester class implementation - * - * $LicenseInfo:firstyear=2004&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - *  - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - *  - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU - * Lesser General Public License for more details. - *  - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" - -#include "indra_constants.h" -#include "llerror.h" -#include "llmath.h" -#include "llfontgl.h" -#include "llsdserialize.h" -#include "llstat.h" -#include "lltreeiterators.h" -#include "llmetricperformancetester.h" - -LLMetricPerformanceTester::name_tester_map_t LLMetricPerformanceTester::sTesterMap ; - -//static  -void LLMetricPerformanceTester::initClass()  -{ -} -//static  -void LLMetricPerformanceTester::cleanClass()  -{ -	for(name_tester_map_t::iterator iter = sTesterMap.begin() ; iter != sTesterMap.end() ; ++iter) -	{ -		delete iter->second ; -	} -	sTesterMap.clear() ; -} - -//static  -void LLMetricPerformanceTester::addTester(LLMetricPerformanceTester* tester)  -{ -	if(!tester) -	{ -		llerrs << "invalid tester!" << llendl ; -		return ; -	} -	 -	std::string name = tester->getName() ; -	if(getTester(name)) -	{ -		llerrs << "Tester name is used by some other tester: " << name << llendl ; -		return ; -	} - -	sTesterMap.insert(std::make_pair(name, tester)); - -	return ; -} -	 -//static  -LLMetricPerformanceTester* LLMetricPerformanceTester::getTester(std::string label)  -{ -	name_tester_map_t::iterator found_it = sTesterMap.find(label) ; -	if(found_it != sTesterMap.end()) -	{ -		return found_it->second ; -	} - -	return NULL ; -} -	 -LLMetricPerformanceTester::LLMetricPerformanceTester(std::string name, BOOL use_default_performance_analysis) -	: mName(name), -	mBaseSessionp(NULL), -	mCurrentSessionp(NULL), -	mCount(0), -	mUseDefaultPerformanceAnalysis(use_default_performance_analysis) -{ -	if(mName == std::string()) -	{ -		llerrs << "invalid name." << llendl ; -	} - -	LLMetricPerformanceTester::addTester(this) ; -} - -/*virtual*/  -LLMetricPerformanceTester::~LLMetricPerformanceTester()  -{ -	if(mBaseSessionp) -	{ -		delete mBaseSessionp ; -		mBaseSessionp = NULL ; -	} -	if(mCurrentSessionp) -	{ -		delete mCurrentSessionp ; -		mCurrentSessionp = NULL ; -	} -} - -void LLMetricPerformanceTester::incLabel() -{ -	mCurLabel = llformat("%s-%d", mName.c_str(), mCount++) ; -} -void LLMetricPerformanceTester::preOutputTestResults(LLSD* sd)  -{ -	incLabel() ; -	(*sd)[mCurLabel]["Name"] = mName ; -} -void LLMetricPerformanceTester::postOutputTestResults(LLSD* sd) -{ -	LLMutexLock lock(LLFastTimer::sLogLock); -	LLFastTimer::sLogQueue.push((*sd)); -} - -void LLMetricPerformanceTester::outputTestResults()  -{ -	LLSD sd ; -	preOutputTestResults(&sd) ;  - -	outputTestRecord(&sd) ; - -	postOutputTestResults(&sd) ; -} - -void LLMetricPerformanceTester::addMetricString(std::string str) -{ -	mMetricStrings.push_back(str) ; -} - -const std::string& LLMetricPerformanceTester::getMetricString(U32 index) const  -{ -	return mMetricStrings[index] ; -} - -void LLMetricPerformanceTester::prePerformanceAnalysis()  -{ -	mCount = 0 ; -	incLabel() ; -} - -// -//default analyzing the performance -// -/*virtual*/  -void LLMetricPerformanceTester::analyzePerformance(std::ofstream* os, LLSD* base, LLSD* current)  -{ -	if(mUseDefaultPerformanceAnalysis)//use default performance analysis -	{ -		prePerformanceAnalysis() ; - -		BOOL in_base = (*base).has(mCurLabel) ; -		BOOL in_current = (*current).has(mCurLabel) ; - -		while(in_base || in_current) -		{ -			LLSD::String label = mCurLabel ;		 -			 -			if(in_base && in_current) -			{				 -				*os << llformat("%s\n", label.c_str()) ; - -				for(U32 index = 0 ; index < mMetricStrings.size() ; index++) -				{ -					switch((*current)[label][ mMetricStrings[index] ].type()) -					{ -					case LLSD::TypeInteger: -						compareTestResults(os, mMetricStrings[index],  -							(S32)((*base)[label][ mMetricStrings[index] ].asInteger()), (S32)((*current)[label][ mMetricStrings[index] ].asInteger())) ; -						break ; -					case LLSD::TypeReal: -						compareTestResults(os, mMetricStrings[index],  -							(F32)((*base)[label][ mMetricStrings[index] ].asReal()), (F32)((*current)[label][ mMetricStrings[index] ].asReal())) ; -						break; -					default: -						llerrs << "unsupported metric " << mMetricStrings[index] << " LLSD type: " << (S32)(*current)[label][ mMetricStrings[index] ].type() << llendl ; -					} -				}	 -			} - -			incLabel() ; -			in_base = (*base).has(mCurLabel) ; -			in_current = (*current).has(mCurLabel) ; -		} -	}//end of default -	else -	{ -		//load the base session -		prePerformanceAnalysis() ; -		mBaseSessionp = loadTestSession(base) ; - -		//load the current session -		prePerformanceAnalysis() ; -		mCurrentSessionp = loadTestSession(current) ; - -		if(!mBaseSessionp || !mCurrentSessionp) -		{ -			llerrs << "memory error during loading test sessions." << llendl ; -		} - -		//compare -		compareTestSessions(os) ; - -		//release memory -		if(mBaseSessionp) -		{ -			delete mBaseSessionp ; -			mBaseSessionp = NULL ; -		} -		if(mCurrentSessionp) -		{ -			delete mCurrentSessionp ; -			mCurrentSessionp = NULL ; -		} -	} -} - -//virtual  -void LLMetricPerformanceTester::compareTestResults(std::ofstream* os, std::string metric_string, S32 v_base, S32 v_current)  -{ -	*os << llformat(" ,%s, %d, %d, %d, %.4f\n", metric_string.c_str(), v_base, v_current,  -						v_current - v_base, (v_base != 0) ? 100.f * v_current / v_base : 0) ; -} - -//virtual  -void LLMetricPerformanceTester::compareTestResults(std::ofstream* os, std::string metric_string, F32 v_base, F32 v_current)  -{ -	*os << llformat(" ,%s, %.4f, %.4f, %.4f, %.4f\n", metric_string.c_str(), v_base, v_current,						 -						v_current - v_base, (fabs(v_base) > 0.0001f) ? 100.f * v_current / v_base : 0.f ) ; -} - -//virtual  -LLMetricPerformanceTester::LLTestSession::~LLTestSession()  -{ -} - diff --git a/indra/newview/llmetricperformancetester.h b/indra/newview/llmetricperformancetester.h deleted file mode 100644 index 6f5dc03564..0000000000 --- a/indra/newview/llmetricperformancetester.h +++ /dev/null @@ -1,153 +0,0 @@ -/**  - * @file LLMetricPerformanceTester.h  - * @brief LLMetricPerformanceTester class definition - * - * $LicenseInfo:firstyear=2004&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - *  - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - *  - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU - * Lesser General Public License for more details. - *  - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA - * $/LicenseInfo$ - */ - -#ifndef LL_METRICPERFORMANCETESTER_H  -#define LL_METRICPERFORMANCETESTER_H  - -class LLMetricPerformanceTester  -{ -public: -	// -    //name passed to the constructor is a unique string for each tester. -    //an error is reported if the name is already used by some other tester. -    // -	LLMetricPerformanceTester(std::string name, BOOL use_default_performance_analysis) ; -	virtual ~LLMetricPerformanceTester(); - -	// -    //return the name of the tester -    // -	std::string getName() const { return mName ;} -	// -    //return the number of the test metrics in this tester -    // -	S32 getNumOfMetricStrings() const { return mMetricStrings.size() ;} -	// -    //return the metric string at the index -    // -	const std::string& getMetricString(U32 index) const ; - -	// -    //this function to compare the test results. -    //by default, it compares the test results against the baseline one by one, item by item,  -    //in the increasing order of the LLSD label counter, starting from the first one. -	//you can define your own way to analyze performance by passing FALSE to "use_default_performance_analysis", -    //and implement two abstract virtual functions below: loadTestSession(...) and compareTestSessions(...). -    // -	void analyzePerformance(std::ofstream* os, LLSD* base, LLSD* current) ; - -protected: -	// -    //insert metric strings used in the tester. -    // -	void addMetricString(std::string str) ; - -	// -    //increase LLSD label by 1 -    // -	void incLabel() ; -	 -	// -    //the function to write a set of test results to the log LLSD. -    // -	void outputTestResults() ; - -	// -    //compare the test results. -    //you can write your own to overwrite the default one. -    // -	virtual void compareTestResults(std::ofstream* os, std::string metric_string, S32 v_base, S32 v_current) ; -	virtual void compareTestResults(std::ofstream* os, std::string metric_string, F32 v_base, F32 v_current) ; - -	// -	//for performance analysis use  -	//it defines an interface for the two abstract virtual functions loadTestSession(...) and compareTestSessions(...). -    //please make your own test session class derived from it. -	// -	class LLTestSession -	{ -	public: -		virtual ~LLTestSession() ; -	}; - -	// -    //load a test session for log LLSD -    //you need to implement it only when you define your own way to analyze performance. -    //otherwise leave it empty. -    // -	virtual LLMetricPerformanceTester::LLTestSession* loadTestSession(LLSD* log) = 0 ; -	// -    //compare the base session and the target session -    //you need to implement it only when you define your own way to analyze performance. -    //otherwise leave it empty. -    // -	virtual void compareTestSessions(std::ofstream* os) = 0 ; -	// -    //the function to write a set of test results to the log LLSD. -    //you have to write you own version of this function.	 -	// -	virtual void outputTestRecord(LLSD* sd) = 0 ; - -private: -	void preOutputTestResults(LLSD* sd) ; -	void postOutputTestResults(LLSD* sd) ; -	void prePerformanceAnalysis() ; - -protected: -	// -    //the unique name string of the tester -    // -	std::string mName ; -	// -    //the current label counter for the log LLSD -    // -	std::string mCurLabel ; -	S32 mCount ; -	 -	BOOL mUseDefaultPerformanceAnalysis ; -	LLTestSession* mBaseSessionp ; -	LLTestSession* mCurrentSessionp ; - -	//metrics strings -	std::vector< std::string > mMetricStrings ; - -//static members -private: -	static void addTester(LLMetricPerformanceTester* tester) ; - -public:	 -	typedef std::map< std::string, LLMetricPerformanceTester* > name_tester_map_t;	 -	static name_tester_map_t sTesterMap ; - -	static LLMetricPerformanceTester* getTester(std::string label) ; -	static BOOL hasMetricPerformanceTesters() {return !sTesterMap.empty() ;} - -	static void initClass() ; -	static void cleanClass() ; -}; - -#endif - diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index d6d38de225..13fd51f473 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -1574,7 +1574,6 @@ bool LLTextureFetch::createRequest(const std::string& url, const LLUUID& id, con  	if (!url.empty() && (!exten.empty() && LLImageBase::getCodecFromExtension(exten) != IMG_CODEC_J2C))  	{  		// Only do partial requests for J2C at the moment -		//llinfos << "Merov : LLTextureFetch::createRequest(), blocking fetch on " << url << llendl;  		desired_size = MAX_IMAGE_DATA_SIZE;  		desired_discard = 0;  	} diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index f96b93da4d..6160510c0e 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -72,6 +72,7 @@ LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sDefaultImagep = NULL;  LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sSmokeImagep = NULL;  LLViewerMediaTexture::media_map_t LLViewerMediaTexture::sMediaMap ;  LLTexturePipelineTester* LLViewerTextureManager::sTesterp = NULL ; +const std::string sTesterName("TextureTester");  S32 LLViewerTexture::sImageCount = 0;  S32 LLViewerTexture::sRawCount = 0; @@ -341,9 +342,14 @@ void LLViewerTextureManager::init()  	LLViewerTexture::initClass() ; -	if(LLFastTimer::sMetricLog) +	if (LLMetricPerformanceTesterBasic::isMetricLogRequested(sTesterName) && !LLMetricPerformanceTesterBasic::getTester(sTesterName))  	{ -		LLViewerTextureManager::sTesterp = new LLTexturePipelineTester() ; +		sTesterp = new LLTexturePipelineTester() ; +		if (!sTesterp->isValid()) +		{ +			delete sTesterp; +			sTesterp = NULL; +		}  	}  } @@ -408,9 +414,10 @@ void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity  {  	sCurrentTime = gFrameTimeSeconds ; -	if(LLViewerTextureManager::sTesterp) +	LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName); +	if (tester)  	{ -		LLViewerTextureManager::sTesterp->update() ; +		tester->update() ;  	}  	LLViewerMediaTexture::updateClass() ; @@ -603,9 +610,10 @@ bool LLViewerTexture::bindDefaultImage(S32 stage)  	//check if there is cached raw image and switch to it if possible  	switchToCachedImage() ; -	if(LLViewerTextureManager::sTesterp) +	LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName); +	if (tester)  	{ -		LLViewerTextureManager::sTesterp->updateGrayTextureBinding() ; +		tester->updateGrayTextureBinding() ;  	}  	return res;  } @@ -1066,9 +1074,10 @@ BOOL LLViewerTexture::isLargeImage()  //virtual   void LLViewerTexture::updateBindStatsForTester()  { -	if(LLViewerTextureManager::sTesterp) +	LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName); +	if (tester)  	{ -		LLViewerTextureManager::sTesterp->updateTextureBindingStats(this) ; +		tester->updateTextureBindingStats(this) ;  	}  } @@ -1849,10 +1858,11 @@ bool LLViewerFetchedTexture::updateFetch()  		// We may have data ready regardless of whether or not we are finished (e.g. waiting on write)  		if (mRawImage.notNull())  		{ -			if(LLViewerTextureManager::sTesterp) +			LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName); +			if (tester)  			{  				mIsFetched = TRUE ; -				LLViewerTextureManager::sTesterp->updateTextureLoadingStats(this, mRawImage, LLAppViewer::getTextureFetch()->isFromLocalCache(mID)) ; +				tester->updateTextureLoadingStats(this, mRawImage, LLAppViewer::getTextureFetch()->isFromLocalCache(mID)) ;  			}  			mRawDiscardLevel = fetch_discard;  			if ((mRawImage->getDataSize() > 0 && mRawDiscardLevel >= 0) && @@ -3076,9 +3086,10 @@ void LLViewerLODTexture::scaleDown()  	{		  		switchToCachedImage() ;	 -		if(LLViewerTextureManager::sTesterp) +		LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName); +		if (tester)  		{ -			LLViewerTextureManager::sTesterp->setStablizingTime() ; +			tester->setStablizingTime() ;  		}  	}  } @@ -3588,23 +3599,22 @@ F32 LLViewerMediaTexture::getMaxVirtualSize()  //----------------------------------------------------------------------------------------------  //start of LLTexturePipelineTester  //---------------------------------------------------------------------------------------------- -LLTexturePipelineTester::LLTexturePipelineTester() : -	LLMetricPerformanceTester("TextureTester", FALSE)  -{ -	addMetricString("TotalBytesLoaded") ; -	addMetricString("TotalBytesLoadedFromCache") ; -	addMetricString("TotalBytesLoadedForLargeImage") ; -	addMetricString("TotalBytesLoadedForSculpties") ; -	addMetricString("StartFetchingTime") ; -	addMetricString("TotalGrayTime") ; -	addMetricString("TotalStablizingTime") ; -	addMetricString("StartTimeLoadingSculpties") ; -	addMetricString("EndTimeLoadingSculpties") ; - -	addMetricString("Time") ; -	addMetricString("TotalBytesBound") ; -	addMetricString("TotalBytesBoundForLargeImage") ; -	addMetricString("PercentageBytesBound") ; +LLTexturePipelineTester::LLTexturePipelineTester() : LLMetricPerformanceTesterWithSession(sTesterName)  +{ +	addMetric("TotalBytesLoaded") ; +	addMetric("TotalBytesLoadedFromCache") ; +	addMetric("TotalBytesLoadedForLargeImage") ; +	addMetric("TotalBytesLoadedForSculpties") ; +	addMetric("StartFetchingTime") ; +	addMetric("TotalGrayTime") ; +	addMetric("TotalStablizingTime") ; +	addMetric("StartTimeLoadingSculpties") ; +	addMetric("EndTimeLoadingSculpties") ; + +	addMetric("Time") ; +	addMetric("TotalBytesBound") ; +	addMetric("TotalBytesBoundForLargeImage") ; +	addMetric("PercentageBytesBound") ;  	mTotalBytesLoaded = 0 ;  	mTotalBytesLoadedFromCache = 0 ;	 @@ -3616,7 +3626,7 @@ LLTexturePipelineTester::LLTexturePipelineTester() :  LLTexturePipelineTester::~LLTexturePipelineTester()  { -	LLViewerTextureManager::sTesterp = NULL ; +	LLViewerTextureManager::sTesterp = NULL;  }  void LLTexturePipelineTester::update() @@ -3682,22 +3692,23 @@ void LLTexturePipelineTester::reset()  //virtual   void LLTexturePipelineTester::outputTestRecord(LLSD *sd)   {	 -	(*sd)[mCurLabel]["TotalBytesLoaded"]              = (LLSD::Integer)mTotalBytesLoaded ; -	(*sd)[mCurLabel]["TotalBytesLoadedFromCache"]     = (LLSD::Integer)mTotalBytesLoadedFromCache ; -	(*sd)[mCurLabel]["TotalBytesLoadedForLargeImage"] = (LLSD::Integer)mTotalBytesLoadedForLargeImage ; -	(*sd)[mCurLabel]["TotalBytesLoadedForSculpties"]  = (LLSD::Integer)mTotalBytesLoadedForSculpties ; +	std::string currentLabel = getCurrentLabelName(); +	(*sd)[currentLabel]["TotalBytesLoaded"]              = (LLSD::Integer)mTotalBytesLoaded ; +	(*sd)[currentLabel]["TotalBytesLoadedFromCache"]     = (LLSD::Integer)mTotalBytesLoadedFromCache ; +	(*sd)[currentLabel]["TotalBytesLoadedForLargeImage"] = (LLSD::Integer)mTotalBytesLoadedForLargeImage ; +	(*sd)[currentLabel]["TotalBytesLoadedForSculpties"]  = (LLSD::Integer)mTotalBytesLoadedForSculpties ; -	(*sd)[mCurLabel]["StartFetchingTime"]             = (LLSD::Real)mStartFetchingTime ; -	(*sd)[mCurLabel]["TotalGrayTime"]                 = (LLSD::Real)mTotalGrayTime ; -	(*sd)[mCurLabel]["TotalStablizingTime"]           = (LLSD::Real)mTotalStablizingTime ; +	(*sd)[currentLabel]["StartFetchingTime"]             = (LLSD::Real)mStartFetchingTime ; +	(*sd)[currentLabel]["TotalGrayTime"]                 = (LLSD::Real)mTotalGrayTime ; +	(*sd)[currentLabel]["TotalStablizingTime"]           = (LLSD::Real)mTotalStablizingTime ; -	(*sd)[mCurLabel]["StartTimeLoadingSculpties"]     = (LLSD::Real)mStartTimeLoadingSculpties ; -	(*sd)[mCurLabel]["EndTimeLoadingSculpties"]       = (LLSD::Real)mEndTimeLoadingSculpties ; +	(*sd)[currentLabel]["StartTimeLoadingSculpties"]     = (LLSD::Real)mStartTimeLoadingSculpties ; +	(*sd)[currentLabel]["EndTimeLoadingSculpties"]       = (LLSD::Real)mEndTimeLoadingSculpties ; -	(*sd)[mCurLabel]["Time"]                          = LLImageGL::sLastFrameTime ; -	(*sd)[mCurLabel]["TotalBytesBound"]               = (LLSD::Integer)mLastTotalBytesUsed ; -	(*sd)[mCurLabel]["TotalBytesBoundForLargeImage"]  = (LLSD::Integer)mLastTotalBytesUsedForLargeImage ; -	(*sd)[mCurLabel]["PercentageBytesBound"]          = (LLSD::Real)(100.f * mLastTotalBytesUsed / mTotalBytesLoaded) ; +	(*sd)[currentLabel]["Time"]                          = LLImageGL::sLastFrameTime ; +	(*sd)[currentLabel]["TotalBytesBound"]               = (LLSD::Integer)mLastTotalBytesUsed ; +	(*sd)[currentLabel]["TotalBytesBoundForLargeImage"]  = (LLSD::Integer)mLastTotalBytesUsedForLargeImage ; +	(*sd)[currentLabel]["PercentageBytesBound"]          = (LLSD::Real)(100.f * mLastTotalBytesUsed / mTotalBytesLoaded) ;  }  void LLTexturePipelineTester::updateTextureBindingStats(const LLViewerTexture* imagep)  @@ -3786,7 +3797,7 @@ void LLTexturePipelineTester::compareTestSessions(std::ofstream* os)  	}  	//compare and output the comparison -	*os << llformat("%s\n", mName.c_str()) ; +	*os << llformat("%s\n", getTesterName().c_str()) ;  	*os << llformat("AggregateResults\n") ;  	compareTestResults(os, "TotalFetchingTime", base_sessionp->mTotalFetchingTime, current_sessionp->mTotalFetchingTime) ; @@ -3841,7 +3852,7 @@ void LLTexturePipelineTester::compareTestSessions(std::ofstream* os)  }  //virtual  -LLMetricPerformanceTester::LLTestSession* LLTexturePipelineTester::loadTestSession(LLSD* log) +LLMetricPerformanceTesterWithSession::LLTestSession* LLTexturePipelineTester::loadTestSession(LLSD* log)  {  	LLTexturePipelineTester::LLTextureTestSession* sessionp = new LLTexturePipelineTester::LLTextureTestSession() ;  	if(!sessionp) @@ -3868,12 +3879,11 @@ LLMetricPerformanceTester::LLTestSession* LLTexturePipelineTester::loadTestSessi  	sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mTime = 0.f ;  	//load a session -	BOOL in_log = (*log).has(mCurLabel) ; -	while(in_log) +	std::string currentLabel = getCurrentLabelName(); +	BOOL in_log = (*log).has(currentLabel) ; +	while (in_log)  	{ -		LLSD::String label = mCurLabel ;		 -		incLabel() ; -		in_log = (*log).has(mCurLabel) ; +		LLSD::String label = currentLabel ;		  		if(sessionp->mInstantPerformanceListCounter >= (S32)sessionp->mInstantPerformanceList.size())  		{ @@ -3939,7 +3949,11 @@ LLMetricPerformanceTester::LLTestSession* LLTexturePipelineTester::loadTestSessi  			sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedForLargeImagePerSecond = 0 ;  			sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAveragePercentageBytesUsedPerSecond = 0.f ;  			sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mTime = 0.f ; -		}		 +		} +		// Next label +		incrementCurrentCount() ; +		currentLabel = getCurrentLabelName(); +		in_log = (*log).has(currentLabel) ;  	}  	sessionp->mTotalFetchingTime += total_fetching_time ; diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index b779396293..b5636bbdc7 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -735,7 +735,7 @@ public:  //it tracks the activities of the texture pipeline  //records them, and outputs them to log files  // -class LLTexturePipelineTester : public LLMetricPerformanceTester +class LLTexturePipelineTester : public LLMetricPerformanceTesterWithSession  {  	enum  	{ @@ -751,8 +751,6 @@ public:  	void updateGrayTextureBinding() ;  	void setStablizingTime() ; -	/*virtual*/ void analyzePerformance(std::ofstream* os, LLSD* base, LLSD* current) ; -  private:  	void reset() ;  	void updateStablizingTime() ; @@ -823,7 +821,7 @@ private:  		S32 mInstantPerformanceListCounter ;  	}; -	/*virtual*/ LLMetricPerformanceTester::LLTestSession* loadTestSession(LLSD* log) ; +	/*virtual*/ LLMetricPerformanceTesterWithSession::LLTestSession* loadTestSession(LLSD* log) ;  	/*virtual*/ void compareTestSessions(std::ofstream* os) ;  }; | 
