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 | 245 | ||||
| -rw-r--r-- | indra/llcommon/llmetricperformancetester.h | 197 | ||||
| -rw-r--r-- | indra/llimage/llimagej2c.cpp | 170 | ||||
| -rw-r--r-- | indra/llimage/llimagej2c.h | 42 | ||||
| -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 | 59 | ||||
| -rw-r--r-- | indra/newview/llappviewer.h | 4 | ||||
| -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 | 87 | ||||
| -rw-r--r-- | indra/newview/llviewertexture.h | 6 | 
18 files changed, 788 insertions, 492 deletions
| diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 7bad780dd8..a6f07f9600 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -55,6 +55,7 @@ set(llcommon_SOURCE_FILES      llevents.cpp      lleventtimer.cpp      llfasttimer_class.cpp +    llmetricperformancetester.cpp      llfile.cpp      llfindlocale.cpp      llfixedbuffer.cpp @@ -160,6 +161,7 @@ set(llcommon_HEADER_FILES      llextendedstatus.h      llfasttimer.h      llfasttimer_class.h +    llmetricperformancetester.h      llfile.h      llfindlocale.h      llfixedbuffer.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..bd548f199a --- /dev/null +++ b/indra/llcommon/llmetricperformancetester.cpp @@ -0,0 +1,245 @@ +/**  + * @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)  +{ +	name_tester_map_t::iterator found_it = sTesterMap.find(name) ; +	if (found_it != sTesterMap.end()) +	{ +		return found_it->second ; +	} +	return NULL ; +} +	 +//---------------------------------------------------------------------------------------------- +// 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 currentLabel = getCurrentLabelName(); +    BOOL in_base = (*base).has(currentLabel) ; +    BOOL in_current = (*current).has(currentLabel) ; + +    while(in_base || in_current) +    { +        LLSD::String label = currentLabel ;		 +         +        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(); +        currentLabel = getCurrentLabelName(); +        in_base = (*base).has(currentLabel) ; +        in_current = (*current).has(currentLabel) ; +    } +} + +/*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..82d579b188 --- /dev/null +++ b/indra/llcommon/llmetricperformancetester.h @@ -0,0 +1,197 @@ +/**  + * @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  + +/** + * @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 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 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..22610817e4 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() @@ -195,6 +201,16 @@ LLImageJ2C::LLImageJ2C() : 	LLImageFormatted(IMG_CODEC_J2C),  	{	// Array size is MAX_DISCARD_LEVEL+1  		mDataSizes[i] = 0;  	} + +	if (LLFastTimer::sMetricLog && !LLImageJ2C::sTesterp && ((LLFastTimer::sLogName == sTesterName) || (LLFastTimer::sLogName == "metric"))) +	{ +		LLImageJ2C::sTesterp = new LLImageCompressionTester() ; +        if (!LLImageJ2C::sTesterp->isValid()) +        { +            delete LLImageJ2C::sTesterp; +            LLImageJ2C::sTesterp = NULL; +        } +	}  }  // virtual @@ -280,6 +296,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 +335,20 @@ BOOL LLImageJ2C::decodeChannels(LLImageRaw *raw_imagep, F32 decode_time, S32 fir  		LLImage::setLastError(mLastError);  	} +    if (LLImageJ2C::sTesterp) +    { +        // Decompression stat gathering +        // Note that we *do not* take into account the decompression failures data so we night overestimate the time spent processing +         +        // Always add the decompression time to the stat +        LLImageJ2C::sTesterp->updateDecompressionStats(elapsed.getElapsedTimeF32()) ; +        if (res) +        { +            // The whole data stream is finally decompressed when res is returned as TRUE +            LLImageJ2C::sTesterp->updateDecompressionStats(this->getDataSize(), raw_imagep->getDataSize()) ; +        } +    } +  	return res;  } @@ -330,6 +361,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 +369,22 @@ BOOL LLImageJ2C::encode(const LLImageRaw *raw_imagep, const char* comment_text,  	{  		LLImage::setLastError(mLastError);  	} + +    if (LLImageJ2C::sTesterp) +    { +        // 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 +        LLImageJ2C::sTesterp->updateCompressionStats(elapsed.getElapsedTimeF32()) ; +        if (res) +        { +            // The whole data stream is finally compressed when res is returned as TRUE +            LLImageJ2C::sTesterp->updateCompressionStats(this->getDataSize(), raw_imagep->getDataSize()) ; +        } +    } +     +      	return res;  } @@ -540,3 +588,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..3933c9236f 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,6 +75,9 @@ public:  	static void openDSO();  	static void closeDSO();  	static std::string getEngineInfo(); + +    // Image compression/decompression tester +	static LLImageCompressionTester* sTesterp ;  protected:  	friend class LLImageJ2CImpl; @@ -118,4 +124,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..6db9807861 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& testName) : 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 fileName = testName + std::string(".slp"); +		mFile = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, fileName);  	}  	void run() @@ -535,6 +529,7 @@ public:  		os.close();  	} +  };  //virtual @@ -1308,7 +1303,7 @@ bool LLAppViewer::cleanup()  {  	// workaround for DEV-35406 crash on shutdown  	LLEventPumps::instance().reset(); - +      	// remove any old breakpad minidump files from the log directory  	if (! isError())  	{ @@ -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 baselineName = LLFastTimer::sLogName + "_baseline.slp"; +		std::string currentName  = LLFastTimer::sLogName + ".slp";  +		std::string reportName   = LLFastTimer::sLogName + "_report.csv"; +		 +		LLFastTimerView::doAnalysis( +			gDirUtilp->getExpandedFilename(LL_PATH_LOGS, baselineName), +			gDirUtilp->getExpandedFilename(LL_PATH_LOGS, currentName), +			gDirUtilp->getExpandedFilename(LL_PATH_LOGS, reportName));  	} -	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 testName = clp.getOption("logmetrics")[0]; +		llinfos << "'--logmetrics' argument : " << testName << llendl; +        if (testName == "") +        { +            llwarns << "No '--logmetrics' argument given, will output all metrics." << llendl; +			LLFastTimer::sLogName = std::string("metric"); +        } +        else +        { +			LLFastTimer::sLogName = testName; +		}  	}  	if (clp.hasOption("graphicslevel")) @@ -2161,7 +2164,7 @@ bool LLAppViewer::initConfiguration()  	{  		LLFastTimerView::sAnalyzePerformance = TRUE;  	} - +      	if (clp.hasOption("replaysession"))  	{  		LLAgentPilot::sReplaySession = TRUE; diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index a40cd83182..3bdc6325c1 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -167,7 +167,7 @@ public:  	// mute/unmute the system's master audio  	virtual void setMasterSystemAudioMute(bool mute);  	virtual bool getMasterSystemAudioMute(); -	 +  protected:  	virtual bool initWindow(); // Initialize the viewer's window.  	virtual bool initLogging(); // Initialize log files, logging system, return false on failure. @@ -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..5b6a25a041 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..1d844454c8 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..aba52cda4f 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 (LLFastTimer::sMetricLog && !LLViewerTextureManager::sTesterp && ((LLFastTimer::sLogName == sTesterName) || (LLFastTimer::sLogName == "metric")))  	{  		LLViewerTextureManager::sTesterp = new LLTexturePipelineTester() ; +        if (!LLViewerTextureManager::sTesterp->isValid()) +        { +            delete LLViewerTextureManager::sTesterp; +            LLViewerTextureManager::sTesterp = NULL; +        }  	}  } @@ -3588,23 +3594,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 ;	 @@ -3682,22 +3687,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 +3792,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 +3847,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 +3874,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 +3944,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) ;  }; | 
