diff options
| author | Richard Linden <none@none> | 2012-10-19 19:35:01 -0700 | 
|---|---|---|
| committer | Richard Linden <none@none> | 2012-10-19 19:35:01 -0700 | 
| commit | 176ffa54b44f2ef73f23e3252dd439f52fab3265 (patch) | |
| tree | a261deb62bf993388805146119c15fadef917732 /indra | |
| parent | bd52d784f904cb0b46be5826f6c7df31b214fc09 (diff) | |
SH-3405 WIP convert existing stats to lltrace system
finished most of conversion of llviewerassetstats
ported some param block fixes from viewer-chui
converted viewer asset stats to param block format
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/llcommon/llinitparam.cpp | 5 | ||||
| -rw-r--r-- | indra/llcommon/llinitparam.h | 43 | ||||
| -rw-r--r-- | indra/llcommon/llsdparam.cpp | 45 | ||||
| -rw-r--r-- | indra/llcommon/lltracerecording.h | 2 | ||||
| -rw-r--r-- | indra/newview/llsimplestat.h | 58 | ||||
| -rw-r--r-- | indra/newview/lltexturefetch.cpp | 48 | ||||
| -rwxr-xr-x | indra/newview/llviewerassetstats.cpp | 627 | ||||
| -rwxr-xr-x | indra/newview/llviewerassetstats.h | 90 | ||||
| -rwxr-xr-x | indra/newview/llviewerstats.cpp | 4 | ||||
| -rwxr-xr-x | indra/newview/llviewerstats.h | 3 | ||||
| -rwxr-xr-x | indra/newview/tests/llviewerassetstats_test.cpp | 510 | 
11 files changed, 623 insertions, 812 deletions
| diff --git a/indra/llcommon/llinitparam.cpp b/indra/llcommon/llinitparam.cpp index db72aa19b9..54e98e66f3 100644 --- a/indra/llcommon/llinitparam.cpp +++ b/indra/llcommon/llinitparam.cpp @@ -196,12 +196,7 @@ namespace LLInitParam  			if (serialize_func)  			{  				const Param* diff_param = diff_block ? diff_block->getParamFromHandle(param_handle) : NULL; -				// each param descriptor remembers its serial number -				// so we can inspect the same param under different names -				// and see that it has the same number -				name_stack.push_back(std::make_pair("", true));  				serialize_func(*param, parser, name_stack, diff_param); -				name_stack.pop_back();  			}  		} diff --git a/indra/llcommon/llinitparam.h b/indra/llcommon/llinitparam.h index 9a6d1eff5c..b7607e91b9 100644 --- a/indra/llcommon/llinitparam.h +++ b/indra/llcommon/llinitparam.h @@ -1156,10 +1156,18 @@ namespace LLInitParam  		static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name)  		{  +			Parser::name_stack_range_t new_name_stack_range(name_stack_range);  			self_t& typed_param = static_cast<self_t&>(param);  			value_t value; + +			// pop first element if empty string +			if (new_name_stack_range.first != new_name_stack_range.second && new_name_stack_range.first->first.empty()) +			{ +				++new_name_stack_range.first; +			} +  			// no further names in stack, attempt to parse value now -			if (name_stack_range.first == name_stack_range.second) +			if (new_name_stack_range.first == new_name_stack_range.second)  			{  				// attempt to read value directly  				if (parser.readValue(value)) @@ -1192,14 +1200,14 @@ namespace LLInitParam  		static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param)  		{  			const self_t& typed_param = static_cast<const self_t&>(param); -			if (!typed_param.isProvided() || name_stack.empty()) return; +			if (!typed_param.isProvided()) return;  			for (const_iterator it = typed_param.mValues.begin(), end_it = typed_param.mValues.end();  				it != end_it;  				++it)  			{  				std::string key = it->getValueName(); -				name_stack.back().second = true; +				name_stack.push_back(std::make_pair(std::string(), true));  				if(key.empty())  				// not parsed via name values, write out value directly @@ -1221,6 +1229,8 @@ namespace LLInitParam  						break;  					}  				} + +				name_stack.pop_back();  			}  		} @@ -1351,10 +1361,19 @@ namespace LLInitParam  		static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name)   		{  +			Parser::name_stack_range_t new_name_stack_range(name_stack_range);  			self_t& typed_param = static_cast<self_t&>(param);  			bool new_value = false; +			bool new_array_value = false; + +			// pop first element if empty string +			if (new_name_stack_range.first != new_name_stack_range.second && new_name_stack_range.first->first.empty()) +			{ +				new_array_value = new_name_stack_range.first->second; +				++new_name_stack_range.first; +			} -			if (new_name || typed_param.mValues.empty()) +			if (new_name || new_array_value || typed_param.mValues.empty())  			{  				new_value = true;  				typed_param.mValues.push_back(value_t()); @@ -1363,9 +1382,13 @@ namespace LLInitParam  			param_value_t& value = typed_param.mValues.back();  			// attempt to parse block... -			if(value.deserializeBlock(parser, name_stack_range, new_name)) +			if(value.deserializeBlock(parser, new_name_stack_range, new_name))  			{  				typed_param.setProvided(); +				if (new_array_value) +				{ +					name_stack_range.first->second = false; +				}  				return true;  			}  			else if(name_value_lookup_t::valueNamesExist()) @@ -1379,6 +1402,10 @@ namespace LLInitParam  					{  						typed_param.mValues.back().setValueName(name);  						typed_param.setProvided(); +						if (new_array_value) +						{ +							name_stack_range.first->second = false; +						}  						return true;  					} @@ -1396,13 +1423,13 @@ namespace LLInitParam  		static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param)  		{  			const self_t& typed_param = static_cast<const self_t&>(param); -			if (!typed_param.isProvided() || name_stack.empty()) return; +			if (!typed_param.isProvided()) return;  			for (const_iterator it = typed_param.mValues.begin(), end_it = typed_param.mValues.end();  				it != end_it;  				++it)  			{ -				name_stack.back().second = true; +				name_stack.push_back(std::make_pair(std::string(), true));  				std::string key = it->getValueName();  				if (!key.empty()) @@ -1415,6 +1442,8 @@ namespace LLInitParam  				{  					it->serializeBlock(parser, name_stack, NULL);  				} + +				name_stack.pop_back();  			}  		} diff --git a/indra/llcommon/llsdparam.cpp b/indra/llcommon/llsdparam.cpp index 0e29873bb0..4b8a8dba5c 100644 --- a/indra/llcommon/llsdparam.cpp +++ b/indra/llcommon/llsdparam.cpp @@ -223,10 +223,14 @@ LLSD& LLParamSDParserUtilities::getSDWriteNode(LLSD& input, LLInitParam::Parser:  	{  		bool new_traversal = it->second; -		LLSD* child_sd = it->first.empty() ? sd_to_write : &(*sd_to_write)[it->first]; - -		if (child_sd->isArray()) +		LLSD* child_sd; +		if (it->first.empty()) +		{ +			child_sd = sd_to_write; +			if (child_sd->isUndefined())  		{ +				*child_sd = LLSD::emptyArray(); +			}  			if (new_traversal)  			{  				// write to new element at end @@ -240,22 +244,7 @@ LLSD& LLParamSDParserUtilities::getSDWriteNode(LLSD& input, LLInitParam::Parser:  		}  		else  		{ -			if (new_traversal  -				&& child_sd->isDefined()  -				&& !child_sd->isArray()) -			{ -				// copy child contents into first element of an array -				LLSD new_array = LLSD::emptyArray(); -				new_array.append(*child_sd); -				// assign array to slot that previously held the single value -				*child_sd = new_array; -				// return next element in that array -				sd_to_write = &((*child_sd)[1]); -			} -			else -			{ -				sd_to_write = child_sd; -			} +			sd_to_write = &(*sd_to_write)[it->first];  		}  		it->second = false;  	} @@ -283,8 +272,9 @@ void LLParamSDParserUtilities::readSDValues(read_sd_cb_t cb, const LLSD& sd, LLI  			it != sd.endArray();  			++it)  		{ -			stack.back().second = true; +			stack.push_back(make_pair(std::string(), true));  			readSDValues(cb, *it, stack); +			stack.pop_back();  		}  	}  	else if (sd.isUndefined()) @@ -315,6 +305,12 @@ namespace LLInitParam  	// block param interface  	bool ParamValue<LLSD, TypeValues<LLSD>, false>::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, bool new_name)  	{ +		if (name_stack.first == name_stack.second +			&& p.readValue<LLSD>(mValue)) +		{ +			return true; +		} +  		LLSD& sd = LLParamSDParserUtilities::getSDWriteNode(mValue, name_stack);  		LLSD::String string; @@ -335,8 +331,11 @@ namespace LLInitParam  	void ParamValue<LLSD, TypeValues<LLSD>, false>::serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block) const  	{ -		// read from LLSD value and serialize out to parser (which could be LLSD, XUI, etc) -		Parser::name_stack_t stack; -		LLParamSDParserUtilities::readSDValues(boost::bind(&serializeElement, boost::ref(p), _1, _2), mValue, stack); +		// attempt to write LLSD out directly +		if (!p.writeValue<LLSD>(mValue, name_stack)) +		{ +			// otherwise read from LLSD value and serialize out to parser (which could be LLSD, XUI, etc) +			LLParamSDParserUtilities::readSDValues(boost::bind(&serializeElement, boost::ref(p), _1, _2), mValue, name_stack); +		}  	}  } diff --git a/indra/llcommon/lltracerecording.h b/indra/llcommon/lltracerecording.h index 25f4f5c721..d3f001ab6a 100644 --- a/indra/llcommon/lltracerecording.h +++ b/indra/llcommon/lltracerecording.h @@ -231,7 +231,7 @@ namespace LLTrace  			return stat.getAccumulator(mMeasurements).getSampleCount();  		} -		F64 getDuration() const { return mElapsedSeconds; } +		LLUnit::Seconds<F64> getDuration() const { return mElapsedSeconds; }  		// implementation for LLVCRControlsMixin  		/*virtual*/ void handleStart(); diff --git a/indra/newview/llsimplestat.h b/indra/newview/llsimplestat.h index 9d7780c4f9..80ce99b774 100644 --- a/indra/newview/llsimplestat.h +++ b/indra/newview/llsimplestat.h @@ -99,43 +99,43 @@ public:  	 * values back to zero.  	 */  	void reset() -		{ -			mCount = 0; -			mMin = Value(0); -			mMax = Value(0); -			mTotal = Value(0); -		} +	{ +		mCount = 0; +		mMin = Value(0); +		mMax = Value(0); +		mTotal = Value(0); +	}  	void record(Value v) +	{ +		if (mCount) +		{ +			mMin = llmin(mMin, v); +			mMax = llmax(mMax, v); +		} +		else  		{ -			if (mCount) -			{ -				mMin = llmin(mMin, v); -				mMax = llmax(mMax, v); -			} -			else -			{ -				mMin = v; -				mMax = v; -			} -			mTotal += v; -			++mCount; +			mMin = v; +			mMax = v;  		} +		mTotal += v; +		++mCount; +	}  	void merge(const LLSimpleStatMMM<VALUE_T> & src) +	{ +		if (! mCount) +		{ +			*this = src; +		} +		else if (src.mCount)  		{ -			if (! mCount) -			{ -				*this = src; -			} -			else if (src.mCount) -			{ -				mMin = llmin(mMin, src.mMin); -				mMax = llmax(mMax, src.mMax); -				mCount += src.mCount; -				mTotal += src.mTotal; -			} +			mMin = llmin(mMin, src.mMin); +			mMax = llmax(mMax, src.mMax); +			mCount += src.mCount; +			mTotal += src.mTotal;  		} +	}  	inline U32 getCount() const		{ return mCount; }  	inline Value getMin() const		{ return mMin; } diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 903fd6acee..ac83fe0ca8 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -53,6 +53,7 @@  #include "llviewerstatsrecorder.h"  #include "llviewerassetstats.h"  #include "llworld.h" +#include "llsdparam.h"  #include "llsdutil.h"  #include "llstartup.h"  #include "llviewerstats.h" @@ -2867,8 +2868,8 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher)  	}; // class lcl_responder -	if (! gViewerAssetStatsThread1) -		return true; +	//if (! gViewerAssetStatsThread1) +	//	return true;  	static volatile bool reporting_started(false);  	static volatile S32 report_sequence(0); @@ -2878,31 +2879,42 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher)  	// but leave it in 'this'.  Destructor will rid us of it.  	LLViewerAssetStats & main_stats = *mMainStats; -	// Merge existing stats into those from main, convert to LLSD -	main_stats.merge(*gViewerAssetStatsThread1); -	LLSD merged_llsd = main_stats.asLLSD(true); - -	// Add some additional meta fields to the content -	merged_llsd["session_id"] = mSessionID; -	merged_llsd["agent_id"] = mAgentID; -	merged_llsd["message"] = "ViewerAssetMetrics";					// Identifies the type of metrics -	merged_llsd["sequence"] = report_sequence;						// Sequence number -	merged_llsd["initial"] = ! reporting_started;					// Initial data from viewer -	merged_llsd["break"] = LLTextureFetch::svMetricsDataBreak;		// Break in data prior to this report -		 +	LLViewerAssetStats::AssetStats stats; +	main_stats.getStats(stats); +	//LLSD merged_llsd = main_stats.asLLSD(); + +	stats.session_id = mSessionID; +	stats.agent_id = mAgentID; +	stats.message = "ViewerAssetMetrics"; +	stats.sequence = static_cast<bool>(report_sequence); +	stats.initial = static_cast<bool>(!reporting_started); +	stats.break_ = static_cast<bool>(LLTextureFetch::svMetricsDataBreak); +	//// Add some additional meta fields to the content +	//merged_llsd["session_id"] = mSessionID; +	//merged_llsd["agent_id"] = mAgentID; +	//merged_llsd["message"] = "ViewerAssetMetrics";					// Identifies the type of metrics +	//merged_llsd["sequence"] = report_sequence;						// Sequence number +	//merged_llsd["initial"] = ! reporting_started;					// Initial data from viewer +	//merged_llsd["break"] = LLTextureFetch::svMetricsDataBreak;		// Break in data prior to this report +	 +	LLSD sd; +	LLParamSDParser parser; +	parser.writeSD(sd, stats); +  	// Update sequence number  	if (S32_MAX == ++report_sequence)  		report_sequence = 0;  	// Limit the size of the stats report if necessary. -	merged_llsd["truncated"] = truncate_viewer_metrics(10, merged_llsd); +	 +	sd["truncated"] = truncate_viewer_metrics(10, sd);  	if (! mCapsURL.empty())  	{  		LLCurlRequest::headers_t headers;  		fetcher->getCurlRequest().post(mCapsURL,  									   headers, -									   merged_llsd, +									   sd,  									   new lcl_responder(fetcher,  														 report_sequence,                                                           report_sequence, @@ -2917,10 +2929,10 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher)  	// In QA mode, Metrics submode, log the result for ease of testing  	if (fetcher->isQAMode())  	{ -		LL_INFOS("Textures") << ll_pretty_print_sd(merged_llsd) << LL_ENDL; +		LL_INFOS("Textures") << ll_pretty_print_sd(sd) << LL_ENDL;  	} -	gViewerAssetStatsThread1->reset(); +	//gViewerAssetStatsThread1->reset();  	return true;  } diff --git a/indra/newview/llviewerassetstats.cpp b/indra/newview/llviewerassetstats.cpp index cc15d6433f..0b820f866e 100755 --- a/indra/newview/llviewerassetstats.cpp +++ b/indra/newview/llviewerassetstats.cpp @@ -31,6 +31,8 @@  #include "stdtypes.h"  #include "llvoavatar.h" +#include "llsdparam.h" +#include "llsdutil.h"  /*   * Classes and utility functions for per-thread and per-region @@ -78,6 +80,152 @@   *   */ +namespace LLViewerAssetStatsFF +{ +	static EViewerAssetCategories asset_type_to_category(const LLViewerAssetType::EType at, bool with_http, bool is_temp) +	{ +		// For statistical purposes, we divide GETs into several +		// populations of asset fetches: +		//  - textures which are de-prioritized in the asset system +		//  - wearables (clothing, bodyparts) which directly affect +		//    user experiences when they log in +		//  - sounds +		//  - gestures +		//  - everything else. +		// +		llassert_always(50 == LLViewerAssetType::AT_COUNT); + +		// Multiple asset definitions are floating around so this requires some +		// maintenance and attention. +		static const EViewerAssetCategories asset_to_bin_map[LLViewerAssetType::AT_COUNT] = +		{ +			EVACTextureTempHTTPGet,			// (0) AT_TEXTURE +			EVACSoundUDPGet,				// AT_SOUND +			EVACOtherGet,					// AT_CALLINGCARD +			EVACOtherGet,					// AT_LANDMARK +			EVACOtherGet,					// AT_SCRIPT +			EVACWearableUDPGet,				// AT_CLOTHING +			EVACOtherGet,					// AT_OBJECT +			EVACOtherGet,					// AT_NOTECARD +			EVACOtherGet,					// AT_CATEGORY +			EVACOtherGet,					// AT_ROOT_CATEGORY +			EVACOtherGet,					// (10) AT_LSL_TEXT +			EVACOtherGet,					// AT_LSL_BYTECODE +			EVACOtherGet,					// AT_TEXTURE_TGA +			EVACWearableUDPGet,				// AT_BODYPART +			EVACOtherGet,					// AT_TRASH +			EVACOtherGet,					// AT_SNAPSHOT_CATEGORY +			EVACOtherGet,					// AT_LOST_AND_FOUND +			EVACSoundUDPGet,				// AT_SOUND_WAV +			EVACOtherGet,					// AT_IMAGE_TGA +			EVACOtherGet,					// AT_IMAGE_JPEG +			EVACGestureUDPGet,				// (20) AT_ANIMATION +			EVACGestureUDPGet,				// AT_GESTURE +			EVACOtherGet,					// AT_SIMSTATE +			EVACOtherGet,					// AT_FAVORITE +			EVACOtherGet,					// AT_LINK +			EVACOtherGet,					// AT_LINK_FOLDER +			EVACOtherGet,					//  +			EVACOtherGet,					//  +			EVACOtherGet,					//  +			EVACOtherGet,					//  +			EVACOtherGet,					// (30) +			EVACOtherGet,					//  +			EVACOtherGet,					//  +			EVACOtherGet,					//  +			EVACOtherGet,					//  +			EVACOtherGet,					//  +			EVACOtherGet,					//  +			EVACOtherGet,					//  +			EVACOtherGet,					//  +			EVACOtherGet,					//  +			EVACOtherGet,					// (40) +			EVACOtherGet,					//  +			EVACOtherGet,					//  +			EVACOtherGet,					//  +			EVACOtherGet,					//  +			EVACOtherGet,					// +			EVACOtherGet,					//  +			EVACOtherGet,					//  +			EVACOtherGet,					//  +			EVACOtherGet,					// AT_MESH +			// (50) +		}; + +		if (at < 0 || at >= LLViewerAssetType::AT_COUNT) +		{ +			return EVACOtherGet; +		} +		EViewerAssetCategories ret(asset_to_bin_map[at]); +		if (EVACTextureTempHTTPGet == ret) +		{ +			// Indexed with [is_temp][with_http] +			static const EViewerAssetCategories texture_bin_map[2][2] = +			{ +				{ +					EVACTextureNonTempUDPGet, +						EVACTextureNonTempHTTPGet, +				}, +				{ +					EVACTextureTempUDPGet, +						EVACTextureTempHTTPGet, +					} +			}; + +			ret = texture_bin_map[is_temp][with_http]; +		} +		return ret; +	} +	static LLTrace::Count<> sEnqueued[EVACCount] = {LLTrace::Count<>("enqueuedassetrequeststemptexturehttp",  +		"Number of temporary texture asset http requests enqueued"), +		LLTrace::Count<>("enqueuedassetrequeststemptextureudp",  +		"Number of temporary texture asset udp requests enqueued"), +		LLTrace::Count<>("enqueuedassetrequestsnontemptexturehttp",  +		"Number of texture asset http requests enqueued"), +		LLTrace::Count<>("enqueuedassetrequestsnontemptextureudp",  +		"Number of texture asset udp requests enqueued"), +		LLTrace::Count<>("enqueuedassetrequestswearableudp",  +		"Number of wearable asset requests enqueued"), +		LLTrace::Count<>("enqueuedassetrequestssoundudp",  +		"Number of sound asset requests enqueued"), +		LLTrace::Count<>("enqueuedassetrequestsgestureudp",  +		"Number of gesture asset requests enqueued"), +		LLTrace::Count<>("enqueuedassetrequestsother",  +		"Number of other asset requests enqueued")}; + +	static LLTrace::Count<> sDequeued[EVACCount] = {LLTrace::Count<>("dequeuedassetrequeststemptexturehttp",  +		"Number of temporary texture asset http requests dequeued"), +		LLTrace::Count<>("dequeuedassetrequeststemptextureudp",  +		"Number of temporary texture asset udp requests dequeued"), +		LLTrace::Count<>("dequeuedassetrequestsnontemptexturehttp",  +		"Number of texture asset http requests dequeued"), +		LLTrace::Count<>("dequeuedassetrequestsnontemptextureudp",  +		"Number of texture asset udp requests dequeued"), +		LLTrace::Count<>("dequeuedassetrequestswearableudp",  +		"Number of wearable asset requests dequeued"), +		LLTrace::Count<>("dequeuedassetrequestssoundudp",  +		"Number of sound asset requests dequeued"), +		LLTrace::Count<>("dequeuedassetrequestsgestureudp",  +		"Number of gesture asset requests dequeued"), +		LLTrace::Count<>("dequeuedassetrequestsother",  +		"Number of other asset requests dequeued")}; +	static LLTrace::Measurement<LLTrace::Seconds> sResponse[EVACCount] = {LLTrace::Measurement<LLTrace::Seconds>("assetresponsetimestemptexturehttp",  +		"Time spent responding to temporary texture asset http requests"), +		LLTrace::Measurement<LLTrace::Seconds>("assetresponsetimestemptextureudp",  +		"Time spent responding to temporary texture asset udp requests"), +		LLTrace::Measurement<LLTrace::Seconds>("assetresponsetimesnontemptexturehttp",  +		"Time spent responding to texture asset http requests"), +		LLTrace::Measurement<LLTrace::Seconds>("assetresponsetimesnontemptextureudp",  +		"Time spent responding to texture asset udp requests"), +		LLTrace::Measurement<LLTrace::Seconds>("assetresponsetimeswearableudp",  +		"Time spent responding to wearable asset requests"), +		LLTrace::Measurement<LLTrace::Seconds>("assetresponsetimessoundudp",  +		"Time spent responding to sound asset requests"), +		LLTrace::Measurement<LLTrace::Seconds>("assetresponsetimesgestureudp",  +		"Time spent responding to gesture asset requests"), +		LLTrace::Measurement<LLTrace::Seconds>("assetresponsetimesother",  +		"Time spent responding to other asset requests")}; +}  // ------------------------------------------------------  // Global data definitions @@ -88,7 +236,8 @@ LLViewerAssetStats * gViewerAssetStats(0);  // LLViewerAssetStats class definition  // ------------------------------------------------------  LLViewerAssetStats::LLViewerAssetStats() -	: mRegionHandle(U64(0)) +:	mRegionHandle(U64(0)), +	mCurRecording(NULL)  {  	reset();  } @@ -110,7 +259,10 @@ void LLViewerAssetStats::reset()  	mRegionRecordings.clear();  	// initialize new recording for current region -	mCurRecording = &mRegionRecordings[mRegionHandle]; +	if (mRegionHandle) +	{ +		mCurRecording = &mRegionRecordings[mRegionHandle]; +	}  }  void LLViewerAssetStats::setRegion(region_handle_t region_handle) @@ -121,9 +273,15 @@ void LLViewerAssetStats::setRegion(region_handle_t region_handle)  		return;  	} -	mCurRecording->stop(); -	mCurRecording = &mRegionRecordings[region_handle]; -	mCurRecording->start(); +	if (mCurRecording) +	{ +		mCurRecording->pause(); +	} +	if (region_handle) +	{ +		mCurRecording = &mRegionRecordings[region_handle]; +		mCurRecording->start(); +	}  	mRegionHandle = region_handle;  } @@ -136,116 +294,169 @@ void LLViewerAssetStats::recordAvatarStats()  	mPhaseStats["cloud-or-gray"] = LLViewerStats::PhaseMap::getPhaseStats("cloud-or-gray");  } -struct AssetRequestType : public LLInitParam::Block<AssetRequestType> +void LLViewerAssetStats::getStats(AssetStats& stats, bool compact_output)  { -	Optional<S32>	enqueued, -					dequeued, -					resp_count; -	Optional<F64>	resp_min, -					resp_max, -					resp_mean; +	using namespace LLViewerAssetStatsFF; + +	if (mCurRecording) +	{ +		mCurRecording->update(); +	} -	AssetRequestType() -	:	enqueued("enqueued"), -		dequeued("dequeued"), -		resp_count("resp_count"), -		resp_min("resp_min"), -		resp_max("resp_max"), -		resp_mean("resp_mean") -	{} -}; - -struct FPSStats : public LLInitParam::Block<FPSStats> -{ -	Optional<S32>	count; -	Optional<F64>	min, -					max, -					mean; -	FPSStats() -	:	count("count"), -		min("min"), -		max("max"), -		mean("mean") -	{} -}; - -struct RegionStats : public LLInitParam::Block<RegionStats> -{ -	Optional<AssetRequestType>	get_texture_temp_http, -								get_texture_temp_udp, -								get_texture_non_temp_http, -								get_texture_non_temp_udp, -								get_wearable_udp, -								get_sound_udp, -								get_gesture_udp, -								get_other; -	Optional<FPSStats>			fps; -	Mandatory<S32>				grid_x, -								grid_y; -	Mandatory<F64>				duration; - -	RegionStats() -	:	get_texture_temp_http("get_texture_temp_http"), -		get_texture_temp_udp("get_texture_temp_udp"), -		get_texture_non_temp_http("get_texture_non_temp_http"), -		get_texture_non_temp_udp("get_texture_non_temp_udp"), -		get_wearable_udp("get_wearable_udp"), -		get_sound_udp("get_sound_udp"), -		get_gesture_udp("get_gesture_udp"), -		get_other("get_other"), -		fps("fps"), -		grid_x("grid_x"), -		grid_y("grid_y"), -		duration("duration") -	{} -}; - -struct AvatarRezState : public LLInitParam::Block<AvatarRezState> -{ -	Mandatory<S32>	cloud, -					gray, -					textured; -	AvatarRezState() -	:	cloud("cloud"), -		gray("gray"), -		textured("textured") -	{} -}; - -struct AvatarPhaseStats : public LLInitParam::Block<AvatarPhaseStats> -{ -	Mandatory<LLSD>	cloud, -					cloud_or_gray; +	if (mRegionRecordings.empty()) +	{ +		stats.regions.add().empty.setProvided(); +	} +	else +	{ +		for (PerRegionRecordingContainer::iterator it = mRegionRecordings.begin(), end_it = mRegionRecordings.end(); +			it != end_it; +			++it) +		{ +			RegionStats& r = stats.regions.add(); +			LLTrace::Recording& rec = it->second; +			if (!compact_output +				|| rec.getSum(sEnqueued[EVACTextureTempHTTPGet])  +				|| rec.getSum(sDequeued[EVACTextureTempHTTPGet]) +				|| rec.getSum(sResponse[EVACTextureTempHTTPGet]).value()) +			{ +				r.get_texture_temp_http	.enqueued(rec.getSum(sEnqueued[EVACTextureTempHTTPGet])) +										.dequeued(rec.getSum(sDequeued[EVACTextureTempHTTPGet])) +										.resp_count(rec.getSum(sResponse[EVACTextureTempHTTPGet]).value()) +										.resp_min(rec.getMin(sResponse[EVACTextureTempHTTPGet]).value()) +										.resp_max(rec.getMax(sResponse[EVACTextureTempHTTPGet]).value()) +										.resp_mean(rec.getMean(sResponse[EVACTextureTempHTTPGet]).value()); +			} +			if (!compact_output +				|| rec.getSum(sEnqueued[EVACTextureTempUDPGet])  +				|| rec.getSum(sDequeued[EVACTextureTempUDPGet]) +				|| rec.getSum(sResponse[EVACTextureTempUDPGet]).value()) +			{ +				r.get_texture_temp_udp	.enqueued(rec.getSum(sEnqueued[EVACTextureTempUDPGet])) +										.dequeued(rec.getSum(sDequeued[EVACTextureTempUDPGet])) +										.resp_count(rec.getSum(sResponse[EVACTextureTempUDPGet]).value()) +										.resp_min(rec.getMin(sResponse[EVACTextureTempUDPGet]).value()) +										.resp_max(rec.getMax(sResponse[EVACTextureTempUDPGet]).value()) +										.resp_mean(rec.getMean(sResponse[EVACTextureTempUDPGet]).value()); +			} +			if (!compact_output +				|| rec.getSum(sEnqueued[EVACTextureNonTempHTTPGet])  +				|| rec.getSum(sDequeued[EVACTextureNonTempHTTPGet]) +				|| rec.getSum(sResponse[EVACTextureNonTempHTTPGet]).value()) +			{ +				r.get_texture_non_temp_http	.enqueued(rec.getSum(sEnqueued[EVACTextureNonTempHTTPGet])) +											.dequeued(rec.getSum(sDequeued[EVACTextureNonTempHTTPGet])) +											.resp_count(rec.getSum(sResponse[EVACTextureNonTempHTTPGet]).value()) +											.resp_min(rec.getMin(sResponse[EVACTextureNonTempHTTPGet]).value()) +											.resp_max(rec.getMax(sResponse[EVACTextureNonTempHTTPGet]).value()) +											.resp_mean(rec.getMean(sResponse[EVACTextureNonTempHTTPGet]).value()); +			} + +			if (!compact_output +				|| rec.getSum(sEnqueued[EVACTextureNonTempUDPGet])  +				|| rec.getSum(sDequeued[EVACTextureNonTempUDPGet]) +				|| rec.getSum(sResponse[EVACTextureNonTempUDPGet]).value()) +			{ +				r.get_texture_non_temp_udp	.enqueued(rec.getSum(sEnqueued[EVACTextureNonTempUDPGet])) +											.dequeued(rec.getSum(sDequeued[EVACTextureNonTempUDPGet])) +											.resp_count(rec.getSum(sResponse[EVACTextureNonTempUDPGet]).value()) +											.resp_min(rec.getMin(sResponse[EVACTextureNonTempUDPGet]).value()) +											.resp_max(rec.getMax(sResponse[EVACTextureNonTempUDPGet]).value()) +											.resp_mean(rec.getMean(sResponse[EVACTextureNonTempUDPGet]).value()); +			} + +			if (!compact_output +				|| rec.getSum(sEnqueued[EVACWearableUDPGet])  +				|| rec.getSum(sDequeued[EVACWearableUDPGet]) +				|| rec.getSum(sResponse[EVACWearableUDPGet]).value()) +			{ +				r.get_wearable_udp	.enqueued(rec.getSum(sEnqueued[EVACWearableUDPGet])) +									.dequeued(rec.getSum(sDequeued[EVACWearableUDPGet])) +									.resp_count(rec.getSum(sResponse[EVACWearableUDPGet]).value()) +									.resp_min(rec.getMin(sResponse[EVACWearableUDPGet]).value()) +									.resp_max(rec.getMax(sResponse[EVACWearableUDPGet]).value()) +									.resp_mean(rec.getMean(sResponse[EVACWearableUDPGet]).value()); +			} + +			if (!compact_output +				|| rec.getSum(sEnqueued[EVACSoundUDPGet])  +				|| rec.getSum(sDequeued[EVACSoundUDPGet]) +				|| rec.getSum(sResponse[EVACSoundUDPGet]).value()) +			{ +				r.get_sound_udp	.enqueued(rec.getSum(sEnqueued[EVACSoundUDPGet])) +								.dequeued(rec.getSum(sDequeued[EVACSoundUDPGet])) +								.resp_count(rec.getSum(sResponse[EVACSoundUDPGet]).value()) +								.resp_min(rec.getMin(sResponse[EVACSoundUDPGet]).value()) +								.resp_max(rec.getMax(sResponse[EVACSoundUDPGet]).value()) +								.resp_mean(rec.getMean(sResponse[EVACSoundUDPGet]).value()); +			} + +			if (!compact_output +				|| rec.getSum(sEnqueued[EVACGestureUDPGet])  +				|| rec.getSum(sDequeued[EVACGestureUDPGet]) +				|| rec.getSum(sResponse[EVACGestureUDPGet]).value()) +			{ +				r.get_gesture_udp	.enqueued(rec.getSum(sEnqueued[EVACGestureUDPGet])) +									.dequeued(rec.getSum(sDequeued[EVACGestureUDPGet])) +									.resp_count(rec.getSum(sResponse[EVACGestureUDPGet]).value()) +									.resp_min(rec.getMin(sResponse[EVACGestureUDPGet]).value()) +									.resp_max(rec.getMax(sResponse[EVACGestureUDPGet]).value()) +									.resp_mean(rec.getMean(sResponse[EVACGestureUDPGet]).value()); +			} + +			if (!compact_output +				|| rec.getSum(sEnqueued[EVACOtherGet])  +				|| rec.getSum(sDequeued[EVACOtherGet]) +				|| rec.getSum(sResponse[EVACOtherGet]).value()) +			{ +				r.get_other	.enqueued(rec.getSum(sEnqueued[EVACOtherGet])) +							.dequeued(rec.getSum(sDequeued[EVACOtherGet])) +							.resp_count(rec.getSum(sResponse[EVACOtherGet]).value()) +							.resp_min(rec.getMin(sResponse[EVACOtherGet]).value()) +							.resp_max(rec.getMax(sResponse[EVACOtherGet]).value()) +							.resp_mean(rec.getMean(sResponse[EVACOtherGet]).value()); +			} + +			S32 fps = rec.getSum(LLStatViewer::FPS_SAMPLE); +			if (!compact_output || fps != 0) +			{ +				r.fps.count(fps); +				r.fps.min(rec.getMin(LLStatViewer::FPS_SAMPLE)); +				r.fps.max(rec.getMax(LLStatViewer::FPS_SAMPLE)); +				r.fps.mean(rec.getMean(LLStatViewer::FPS_SAMPLE)); +			} +			U32 grid_x(0), grid_y(0); +			grid_from_region_handle(it->first, &grid_x, &grid_y); +			r.grid_x(grid_x); +			r.grid_y(grid_y); +			r.duration(LLUnit::Microseconds<F64>(rec.getDuration()).value()); +		} +	} -	AvatarPhaseStats() -	:	cloud("cloud"), -		cloud_or_gray("cloud-or-gray") -	{} -}; +	stats.duration(mCurRecording ? LLUnit::Microseconds<F64>(mCurRecording->getDuration()).value() : 0.0); +	//stats.avatar.setProvided(true); -struct AvatarInfo : public LLInitParam::Block<AvatarInfo> -{ -	Mandatory<AvatarRezState> nearby; -	Mandatory<AvatarPhaseStats> phase_stats; +	for (S32 rez_stat=0; rez_stat < mAvatarRezStates.size(); ++rez_stat) +	{ +		stats.avatar.nearby	.cloud(mAvatarRezStates[0]) +							.gray(mAvatarRezStates[1]) +							.textured(mAvatarRezStates[2]); +	} -	AvatarInfo() -	:	nearby("nearby"), -		phase_stats("phase_stats") -	{} -}; +	stats.avatar.phase_stats	.cloud(mPhaseStats["cloud"].asLLSD()) +								.cloud_or_gray(mPhaseStats["cloud-or-gray"].asLLSD()); +} -struct AssetStats : public LLInitParam::Block<AssetStats> +LLSD LLViewerAssetStats::asLLSD(bool compact_output)  { -	Multiple<RegionStats>	regions; -	Mandatory<F64>			duration; - -	AssetStats() -	:	regions("regions"), -		duration("duration") -	{} - -}; - +	LLParamSDParser parser; +	LLSD sd; +	AssetStats stats; +	getStats(stats, compact_output); +	parser.writeSD(sd, stats); +	llinfos << ll_pretty_print_sd(sd) << llendl; +	return sd; +}  //LLSD LLViewerAssetStats::asLLSD(bool compact_output)  //{  //	// Top-level tags @@ -358,150 +569,6 @@ struct AssetStats : public LLInitParam::Block<AssetStats>  namespace LLViewerAssetStatsFF  { -	static EViewerAssetCategories asset_type_to_category(const LLViewerAssetType::EType at, bool with_http, bool is_temp) -	{ -		// For statistical purposes, we divide GETs into several -		// populations of asset fetches: -		//  - textures which are de-prioritized in the asset system -		//  - wearables (clothing, bodyparts) which directly affect -		//    user experiences when they log in -		//  - sounds -		//  - gestures -		//  - everything else. -		// -		llassert_always(50 == LLViewerAssetType::AT_COUNT); - -		// Multiple asset definitions are floating around so this requires some -		// maintenance and attention. -		static const EViewerAssetCategories asset_to_bin_map[LLViewerAssetType::AT_COUNT] = -		{ -			EVACTextureTempHTTPGet,			// (0) AT_TEXTURE -			EVACSoundUDPGet,				// AT_SOUND -			EVACOtherGet,					// AT_CALLINGCARD -			EVACOtherGet,					// AT_LANDMARK -			EVACOtherGet,					// AT_SCRIPT -			EVACWearableUDPGet,				// AT_CLOTHING -			EVACOtherGet,					// AT_OBJECT -			EVACOtherGet,					// AT_NOTECARD -			EVACOtherGet,					// AT_CATEGORY -			EVACOtherGet,					// AT_ROOT_CATEGORY -			EVACOtherGet,					// (10) AT_LSL_TEXT -			EVACOtherGet,					// AT_LSL_BYTECODE -			EVACOtherGet,					// AT_TEXTURE_TGA -			EVACWearableUDPGet,				// AT_BODYPART -			EVACOtherGet,					// AT_TRASH -			EVACOtherGet,					// AT_SNAPSHOT_CATEGORY -			EVACOtherGet,					// AT_LOST_AND_FOUND -			EVACSoundUDPGet,				// AT_SOUND_WAV -			EVACOtherGet,					// AT_IMAGE_TGA -			EVACOtherGet,					// AT_IMAGE_JPEG -			EVACGestureUDPGet,				// (20) AT_ANIMATION -			EVACGestureUDPGet,				// AT_GESTURE -			EVACOtherGet,					// AT_SIMSTATE -			EVACOtherGet,					// AT_FAVORITE -			EVACOtherGet,					// AT_LINK -			EVACOtherGet,					// AT_LINK_FOLDER -			EVACOtherGet,					//  -			EVACOtherGet,					//  -			EVACOtherGet,					//  -			EVACOtherGet,					//  -			EVACOtherGet,					// (30) -			EVACOtherGet,					//  -			EVACOtherGet,					//  -			EVACOtherGet,					//  -			EVACOtherGet,					//  -			EVACOtherGet,					//  -			EVACOtherGet,					//  -			EVACOtherGet,					//  -			EVACOtherGet,					//  -			EVACOtherGet,					//  -			EVACOtherGet,					// (40) -			EVACOtherGet,					//  -			EVACOtherGet,					//  -			EVACOtherGet,					//  -			EVACOtherGet,					//  -			EVACOtherGet,					// -			EVACOtherGet,					//  -			EVACOtherGet,					//  -			EVACOtherGet,					//  -			EVACOtherGet,					// AT_MESH -			// (50) -		}; - -		if (at < 0 || at >= LLViewerAssetType::AT_COUNT) -		{ -			return EVACOtherGet; -		} -		EViewerAssetCategories ret(asset_to_bin_map[at]); -		if (EVACTextureTempHTTPGet == ret) -		{ -			// Indexed with [is_temp][with_http] -			static const EViewerAssetCategories texture_bin_map[2][2] = -			{ -				{ -					EVACTextureNonTempUDPGet, -					EVACTextureNonTempHTTPGet, -				}, -				{ -					EVACTextureTempUDPGet, -					EVACTextureTempHTTPGet, -				} -			}; - -			ret = texture_bin_map[is_temp][with_http]; -		} -		return ret; -	} -static LLTrace::Count<> sEnqueued[EVACCount] = {LLTrace::Count<>("enqueuedassetrequeststemptexturehttp",  -														"Number of temporary texture asset http requests enqueued"), -													LLTrace::Count<>("enqueuedassetrequeststemptextureudp",  -														"Number of temporary texture asset udp requests enqueued"), -													LLTrace::Count<>("enqueuedassetrequestsnontemptexturehttp",  -														"Number of texture asset http requests enqueued"), -													LLTrace::Count<>("enqueuedassetrequestsnontemptextureudp",  -														"Number of texture asset udp requests enqueued"), -													LLTrace::Count<>("enqueuedassetrequestswearableudp",  -														"Number of wearable asset requests enqueued"), -													LLTrace::Count<>("enqueuedassetrequestssoundudp",  -														"Number of sound asset requests enqueued"), -													LLTrace::Count<>("enqueuedassetrequestsgestureudp",  -														"Number of gesture asset requests enqueued"), -													LLTrace::Count<>("enqueuedassetrequestsother",  -														"Number of other asset requests enqueued")}; - -static LLTrace::Count<> sDequeued[EVACCount] = {LLTrace::Count<>("dequeuedassetrequeststemptexturehttp",  -													"Number of temporary texture asset http requests dequeued"), -												LLTrace::Count<>("dequeuedassetrequeststemptextureudp",  -													"Number of temporary texture asset udp requests dequeued"), -												LLTrace::Count<>("dequeuedassetrequestsnontemptexturehttp",  -													"Number of texture asset http requests dequeued"), -												LLTrace::Count<>("dequeuedassetrequestsnontemptextureudp",  -													"Number of texture asset udp requests dequeued"), -												LLTrace::Count<>("dequeuedassetrequestswearableudp",  -													"Number of wearable asset requests dequeued"), -												LLTrace::Count<>("dequeuedassetrequestssoundudp",  -													"Number of sound asset requests dequeued"), -												LLTrace::Count<>("dequeuedassetrequestsgestureudp",  -													"Number of gesture asset requests dequeued"), -												LLTrace::Count<>("dequeuedassetrequestsother",  -													"Number of other asset requests dequeued")}; -static LLTrace::Measurement<LLTrace::Seconds> sResponse[EVACCount] = {LLTrace::Measurement<LLTrace::Seconds>("assetresponsetimestemptexturehttp",  -																			"Time spent responding to temporary texture asset http requests"), -																		LLTrace::Measurement<LLTrace::Seconds>("assetresponsetimestemptextureudp",  -																			"Time spent responding to temporary texture asset udp requests"), -																		LLTrace::Measurement<LLTrace::Seconds>("assetresponsetimesnontemptexturehttp",  -																			"Time spent responding to texture asset http requests"), -																		LLTrace::Measurement<LLTrace::Seconds>("assetresponsetimesnontemptextureudp",  -																			"Time spent responding to texture asset udp requests"), -																		LLTrace::Measurement<LLTrace::Seconds>("assetresponsetimeswearableudp",  -																			"Time spent responding to wearable asset requests"), -																		LLTrace::Measurement<LLTrace::Seconds>("assetresponsetimessoundudp",  -																			"Time spent responding to sound asset requests"), -																		LLTrace::Measurement<LLTrace::Seconds>("assetresponsetimesgestureudp",  -																			"Time spent responding to gesture asset requests"), -																		LLTrace::Measurement<LLTrace::Seconds>("assetresponsetimesother",  -																			"Time spent responding to other asset requests")}; -  //  // Target thread is elaborated in the function name.  This could  // have been something 'templatey' like specializations iterated @@ -577,3 +644,59 @@ cleanup()  } // namespace LLViewerAssetStatsFF + +LLViewerAssetStats::AssetRequestType::AssetRequestType()  +:	enqueued("enqueued"), +	dequeued("dequeued"), +	resp_count("resp_count"), +	resp_min("resp_min"), +	resp_max("resp_max"), +	resp_mean("resp_mean") +{} + +LLViewerAssetStats::FPSStats::FPSStats()  +:	count("count"), +	min("min"), +	max("max"), +	mean("mean") +{} + +LLViewerAssetStats::RegionStats::RegionStats()  +:	get_texture_temp_http("get_texture_temp_http"), +	get_texture_temp_udp("get_texture_temp_udp"), +	get_texture_non_temp_http("get_texture_non_temp_http"), +	get_texture_non_temp_udp("get_texture_non_temp_udp"), +	get_wearable_udp("get_wearable_udp"), +	get_sound_udp("get_sound_udp"), +	get_gesture_udp("get_gesture_udp"), +	get_other("get_other"), +	fps("fps"), +	grid_x("grid_x"), +	grid_y("grid_y"), +	duration("duration") +{} + +LLViewerAssetStats::AvatarRezState::AvatarRezState()  +:	cloud("cloud"), +	gray("gray"), +	textured("textured") +{} + +LLViewerAssetStats::AvatarInfo::AvatarInfo()  +:	nearby("nearby"), +	phase_stats("phase_stats") +{ + +} + +LLViewerAssetStats::AssetStats::AssetStats()  +:	regions("regions"), +	duration("duration"), +	avatar("avatar"), +	session_id("session_id"), +	agent_id("agent_id"), +	message("message"), +	sequence("sequence"), +	initial("initial"), +	break_("break") +{} diff --git a/indra/newview/llviewerassetstats.h b/indra/newview/llviewerassetstats.h index 469609ea1f..2f50c52730 100755 --- a/indra/newview/llviewerassetstats.h +++ b/indra/newview/llviewerassetstats.h @@ -91,6 +91,90 @@ public:  	 */  	typedef U64 region_handle_t; +	struct AssetRequestType : public LLInitParam::Block<AssetRequestType> +	{ +		Mandatory<S32>	enqueued, +						dequeued, +						resp_count; +		Mandatory<F64>	resp_min, +						resp_max, +						resp_mean; +	 +		AssetRequestType(); +	}; + +	struct FPSStats : public LLInitParam::Block<FPSStats> +	{ +		Mandatory<S32>	count; +		Mandatory<F64>	min, +						max, +						mean; +		FPSStats(); +	}; + +	struct RegionStats : public LLInitParam::Block<RegionStats> +	{ +		Optional<LLInitParam::Flag>				empty; +		Optional<AssetRequestType>	get_texture_temp_http, +									get_texture_temp_udp, +									get_texture_non_temp_http, +									get_texture_non_temp_udp, +									get_wearable_udp, +									get_sound_udp, +									get_gesture_udp, +									get_other; +		Optional<FPSStats>			fps; +		Optional<S32>				grid_x, +									grid_y; +		Optional<F64>				duration; + +		RegionStats(); +	}; + +	struct AvatarRezState : public LLInitParam::Block<AvatarRezState> +	{ +		Mandatory<S32>	cloud, +						gray, +						textured; +		AvatarRezState(); +	}; + +	struct AvatarPhaseStats : public LLInitParam::Block<AvatarPhaseStats> +	{ +		Mandatory<LLSD>	cloud, +						cloud_or_gray; + +		AvatarPhaseStats() +		:	cloud("cloud"), +			cloud_or_gray("cloud-or-gray") +		{} +	}; + +	struct AvatarInfo : public LLInitParam::Block<AvatarInfo> +	{ +		Optional<AvatarRezState> nearby; +		Optional<AvatarPhaseStats> phase_stats; + +		AvatarInfo(); +	}; + +	struct AssetStats : public LLInitParam::Block<AssetStats> +	{ +		Multiple<RegionStats>	regions; +		Mandatory<F64>			duration; +		Mandatory<AvatarInfo>	avatar; + +		Mandatory<LLUUID>		session_id, +								agent_id; + +		Mandatory<std::string>	message; +		Mandatory<S32>			sequence; +		Mandatory<bool>			initial, +								break_; + +		AssetStats(); +	}; +  public:  	LLViewerAssetStats();  	LLViewerAssetStats(const LLViewerAssetStats &); @@ -146,11 +230,7 @@ public:  	//   }  	// }  	// -	// @param	compact_output		If true, omits from conversion any mmm_block -	//								or stats_block that would contain all zero data. -	//								Useful for transmission when the receiver knows -	//								what is expected and will assume zero for missing -	//								blocks. +	void getStats(AssetStats& stats, bool compact_output);  	LLSD asLLSD(bool compact_output);  protected: diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index 03cc9b12e3..04b0c30b40 100755 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -128,7 +128,8 @@ SimMeasurement<>			SIM_TIME_DILATION("simtimedilation", "", LL_SIM_STAT_TIME_DIL  							SIM_PHYSICS_PINNED_TASKS("physicspinnedtasks", "", LL_SIM_STAT_PHYSICS_PINNED_TASKS),  							SIM_PHYSICS_LOD_TASKS("physicslodtasks", "", LL_SIM_STAT_PHYSICS_LOD_TASKS); -LLTrace::Measurement<>		NUM_IMAGES("numimagesstat"), +LLTrace::Measurement<>		FPS_SAMPLE("fpssample"), +							NUM_IMAGES("numimagesstat"),  							NUM_RAW_IMAGES("numrawimagesstat"),  							NUM_OBJECTS("numobjectsstat"),  							NUM_ACTIVE_OBJECTS("numactiveobjectsstat"), @@ -343,6 +344,7 @@ void update_statistics()  	}  	LLStatViewer::FPS.add(1); +	LLStatViewer::FPS_SAMPLE.sample(LLTrace::get_frame_recording().getTotalRecording().getPerSec(LLStatViewer::FPS));  	F32 layer_bits = (F32)(gVLManager.getLandBits() + gVLManager.getWindBits() + gVLManager.getCloudBits());  	LLStatViewer::LAYERS_KBIT.add<LLTrace::Bits>(layer_bits);  	LLStatViewer::OBJECT_KBIT.add(gObjectData); diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h index 78c4b89f71..34731481f5 100755 --- a/indra/newview/llviewerstats.h +++ b/indra/newview/llviewerstats.h @@ -127,7 +127,8 @@ extern SimMeasurement<>						SIM_TIME_DILATION,  											SIM_PHYSICS_PINNED_TASKS,  											SIM_PHYSICS_LOD_TASKS; -extern LLTrace::Measurement<>				NUM_IMAGES, +extern LLTrace::Measurement<>				FPS_SAMPLE, +											NUM_IMAGES,  											NUM_RAW_IMAGES,  											NUM_OBJECTS,  											NUM_ACTIVE_OBJECTS, diff --git a/indra/newview/tests/llviewerassetstats_test.cpp b/indra/newview/tests/llviewerassetstats_test.cpp index e0126ce8d3..f9d30408ac 100755 --- a/indra/newview/tests/llviewerassetstats_test.cpp +++ b/indra/newview/tests/llviewerassetstats_test.cpp @@ -37,6 +37,11 @@  #include "llregionhandle.h"  #include "../llvoavatar.h" +namespace LLStatViewer +{ +	LLTrace::Measurement<>		FPS_SAMPLE("fpssample"); +} +  void LLVOAvatar::getNearbyRezzedStats(std::vector<S32>& counts)  {  	counts.resize(3); @@ -241,7 +246,7 @@ namespace tut  	void tst_viewerassetstats_index_object_t::test<1>()  	{  		// Check that helpers aren't bothered by missing global stats -		ensure("Global gViewerAssetStatsMain should be NULL", (NULL == gViewerAssetStatsMain)); +		ensure("Global gViewerAssetStats should be NULL", (NULL == gViewerAssetStats));  		LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_TEXTURE, false, false); @@ -254,11 +259,11 @@ namespace tut  	template<> template<>  	void tst_viewerassetstats_index_object_t::test<2>()  	{ -		ensure("Global gViewerAssetStatsMain should be NULL", (NULL == gViewerAssetStatsMain)); +		ensure("Global gViewerAssetStats should be NULL", (NULL == gViewerAssetStats));  		LLViewerAssetStats * it = new LLViewerAssetStats(); -		ensure("Global gViewerAssetStatsMain should still be NULL", (NULL == gViewerAssetStatsMain)); +		ensure("Global gViewerAssetStats should still be NULL", (NULL == gViewerAssetStats));  		LLSD sd_full = it->asLLSD(false); @@ -325,7 +330,7 @@ namespace tut  	template<> template<>  	void tst_viewerassetstats_index_object_t::test<4>()  	{ -		gViewerAssetStatsMain = new LLViewerAssetStats(); +		gViewerAssetStats = new LLViewerAssetStats();  		LLViewerAssetStatsFF::set_region(region1_handle);  		LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_TEXTURE, false, false); @@ -334,7 +339,7 @@ namespace tut  		LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_BODYPART, false, false);  		LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_BODYPART, false, false); -		LLSD sd = gViewerAssetStatsMain->asLLSD(false); +		LLSD sd = gViewerAssetStats->asLLSD(false);  		ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "regions", "duration", "avatar"));  		ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle));  		sd = sd["regions"][0]; @@ -348,11 +353,11 @@ namespace tut  		// Reset and check zeros...  		// Reset leaves current region in place -		gViewerAssetStatsMain->reset(); -		sd = gViewerAssetStatsMain->asLLSD(false)["regions"][region1_handle_str]; +		gViewerAssetStats->reset(); +		sd = gViewerAssetStats->asLLSD(false)["regions"][region1_handle_str]; -		delete gViewerAssetStatsMain; -		gViewerAssetStatsMain = NULL; +		delete gViewerAssetStats; +		gViewerAssetStats = NULL;  		ensure("sd[get_texture_non_temp_udp][enqueued] is reset", (0 == sd["get_texture_non_temp_udp"]["enqueued"].asInteger()));  		ensure("sd[get_gesture_udp][dequeued] is reset", (0 == sd["get_gesture_udp"]["dequeued"].asInteger())); @@ -362,8 +367,7 @@ namespace tut  	template<> template<>  	void tst_viewerassetstats_index_object_t::test<5>()  	{ -		gViewerAssetStatsThread1 = new LLViewerAssetStats(); -		gViewerAssetStatsMain = new LLViewerAssetStats(); +		gViewerAssetStats = new LLViewerAssetStats();  		LLViewerAssetStatsFF::set_region(region1_handle);  		LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_TEXTURE, false, false); @@ -372,9 +376,7 @@ namespace tut  		LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_BODYPART, false, false);  		LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_BODYPART, false, false); -		LLSD sd = gViewerAssetStatsThread1->asLLSD(false); -		ensure("Other collector is empty", is_no_stats_map(sd)); -		sd = gViewerAssetStatsMain->asLLSD(false); +		LLSD sd = gViewerAssetStats->asLLSD(false);  		ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "regions", "duration", "avatar"));  		ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle));  		sd = sd["regions"][0]; @@ -388,11 +390,11 @@ namespace tut  		// Reset and check zeros...  		// Reset leaves current region in place -		gViewerAssetStatsMain->reset(); -		sd = gViewerAssetStatsMain->asLLSD(false)["regions"][0]; +		gViewerAssetStats->reset(); +		sd = gViewerAssetStats->asLLSD(false)["regions"][0]; -		delete gViewerAssetStatsMain; -		gViewerAssetStatsMain = NULL; +		delete gViewerAssetStats; +		gViewerAssetStats = NULL;  		ensure("sd[get_texture_non_temp_udp][enqueued] is reset", (0 == sd["get_texture_non_temp_udp"]["enqueued"].asInteger()));  		ensure("sd[get_gesture_udp][dequeued] is reset", (0 == sd["get_gesture_udp"]["dequeued"].asInteger())); @@ -402,7 +404,7 @@ namespace tut  	template<> template<>  	void tst_viewerassetstats_index_object_t::test<6>()  	{ -		gViewerAssetStatsMain = new LLViewerAssetStats(); +		gViewerAssetStats = new LLViewerAssetStats();  		LLViewerAssetStatsFF::set_region(region1_handle); @@ -419,7 +421,7 @@ namespace tut  		LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false);  		LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false); -		LLSD sd = gViewerAssetStatsMain->asLLSD(false); +		LLSD sd = gViewerAssetStats->asLLSD(false);  		// std::cout << sd << std::endl; @@ -444,14 +446,14 @@ namespace tut  		// Reset and check zeros...  		// Reset leaves current region in place -		gViewerAssetStatsMain->reset(); -		sd = gViewerAssetStatsMain->asLLSD(false); +		gViewerAssetStats->reset(); +		sd = gViewerAssetStats->asLLSD(false);  		ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "regions", "duration", "avatar"));  		ensure("Correct single-slot LLSD array regions (p2)", is_single_slot_array(sd["regions"], region2_handle));  		sd2 = sd["regions"][0]; -		delete gViewerAssetStatsMain; -		gViewerAssetStatsMain = NULL; +		delete gViewerAssetStats; +		gViewerAssetStats = NULL;  		ensure("sd2[get_texture_non_temp_udp][enqueued] is reset", (0 == sd2["get_texture_non_temp_udp"]["enqueued"].asInteger()));  		ensure("sd2[get_gesture_udp][enqueued] is reset", (0 == sd2["get_gesture_udp"]["enqueued"].asInteger())); @@ -461,7 +463,7 @@ namespace tut  	template<> template<>  	void tst_viewerassetstats_index_object_t::test<7>()  	{ -		gViewerAssetStatsMain = new LLViewerAssetStats(); +		gViewerAssetStats = new LLViewerAssetStats();  		LLViewerAssetStatsFF::set_region(region1_handle); @@ -493,7 +495,7 @@ namespace tut  		LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false);  		LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false); -		LLSD sd = gViewerAssetStatsMain->asLLSD(false); +		LLSD sd = gViewerAssetStats->asLLSD(false);  		ensure("Correct double-key LLSD map root", is_triple_key_map(sd, "duration", "regions", "avatar"));  		ensure("Correct double-slot LLSD array regions", is_double_slot_array(sd["regions"], region1_handle, region2_handle)); @@ -502,6 +504,8 @@ namespace tut  		ensure("Region1 is present in results", sd1.isMap());  		ensure("Region2 is present in results", sd2.isMap()); +		llinfos << ll_pretty_print_sd(sd1) << llendl; +  		// Check a few points on the tree for content  		ensure("sd1[get_texture_non_temp_udp][enqueued] is 1", (1 == sd1["get_texture_non_temp_udp"]["enqueued"].asInteger()));  		ensure("sd1[get_texture_temp_udp][enqueued] is 0", (0 == sd1["get_texture_temp_udp"]["enqueued"].asInteger())); @@ -516,15 +520,15 @@ namespace tut  		// Reset and check zeros...  		// Reset leaves current region in place -		gViewerAssetStatsMain->reset(); -		sd = gViewerAssetStatsMain->asLLSD(false); +		gViewerAssetStats->reset(); +		sd = gViewerAssetStats->asLLSD(false);  		ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "duration", "regions", "avatar"));  		ensure("Correct single-slot LLSD array regions (p2)", is_single_slot_array(sd["regions"], region2_handle));  		sd2 = get_region(sd, region2_handle);  		ensure("Region2 is present in results", sd2.isMap()); -		delete gViewerAssetStatsMain; -		gViewerAssetStatsMain = NULL; +		delete gViewerAssetStats; +		gViewerAssetStats = NULL;  		ensure_equals("sd2[get_texture_non_temp_udp][enqueued] is reset", sd2["get_texture_non_temp_udp"]["enqueued"].asInteger(), 0);  		ensure_equals("sd2[get_gesture_udp][enqueued] is reset", sd2["get_gesture_udp"]["enqueued"].asInteger(), 0); @@ -534,8 +538,7 @@ namespace tut  	template<> template<>  	void tst_viewerassetstats_index_object_t::test<8>()  	{ -		gViewerAssetStatsThread1 = new LLViewerAssetStats(); -		gViewerAssetStatsMain = new LLViewerAssetStats(); +		gViewerAssetStats = new LLViewerAssetStats();  		LLViewerAssetStatsFF::set_region(region1_handle);  		LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_TEXTURE, false, false); @@ -561,9 +564,7 @@ namespace tut  		LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		LLSD sd = gViewerAssetStatsThread1->asLLSD(false); -		ensure("Other collector is empty", is_no_stats_map(sd)); -		sd = gViewerAssetStatsMain->asLLSD(false); +		LLSD sd = gViewerAssetStats->asLLSD(false);  		ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "regions", "duration", "avatar"));  		ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle));  		sd = get_region(sd, region1_handle); @@ -581,445 +582,14 @@ namespace tut  		// Reset and check zeros...  		// Reset leaves current region in place -		gViewerAssetStatsMain->reset(); -		sd = get_region(gViewerAssetStatsMain->asLLSD(false), region1_handle); +		gViewerAssetStats->reset(); +		sd = get_region(gViewerAssetStats->asLLSD(false), region1_handle);  		ensure("Region1 is present in results", sd.isMap()); -		delete gViewerAssetStatsMain; -		gViewerAssetStatsMain = NULL; -		delete gViewerAssetStatsThread1; -		gViewerAssetStatsThread1 = NULL; +		delete gViewerAssetStats; +		gViewerAssetStats = NULL;  		ensure_equals("sd[get_texture_non_temp_udp][enqueued] is reset", sd["get_texture_non_temp_udp"]["enqueued"].asInteger(), 0);  		ensure_equals("sd[get_gesture_udp][dequeued] is reset", sd["get_gesture_udp"]["dequeued"].asInteger(), 0);  	} - - -	// LLViewerAssetStats::merge() basic functions work -	template<> template<> -	void tst_viewerassetstats_index_object_t::test<9>() -	{ -		LLViewerAssetStats s1; -		LLViewerAssetStats s2; - -		s1.setRegion(region1_handle); -		s2.setRegion(region1_handle); - -		s1.recordGetServiced(LLViewerAssetType::AT_TEXTURE, true, true, 5000000); -		s1.recordGetServiced(LLViewerAssetType::AT_TEXTURE, true, true, 6000000); -		s1.recordGetServiced(LLViewerAssetType::AT_TEXTURE, true, true, 8000000); -		s1.recordGetServiced(LLViewerAssetType::AT_TEXTURE, true, true, 7000000); -		s1.recordGetServiced(LLViewerAssetType::AT_TEXTURE, true, true, 9000000); -		 -		s2.recordGetServiced(LLViewerAssetType::AT_TEXTURE, true, true, 2000000); -		s2.recordGetServiced(LLViewerAssetType::AT_TEXTURE, true, true, 3000000); -		s2.recordGetServiced(LLViewerAssetType::AT_TEXTURE, true, true, 4000000); - -		s2.merge(s1); - -		LLSD s2_llsd = get_region(s2.asLLSD(false), region1_handle); -		ensure("Region1 is present in results", s2_llsd.isMap()); -		 -		ensure_equals("count after merge", s2_llsd["get_texture_temp_http"]["resp_count"].asInteger(), 8); -		ensure_approximately_equals("min after merge", s2_llsd["get_texture_temp_http"]["resp_min"].asReal(), 2.0, 22); -		ensure_approximately_equals("max after merge", s2_llsd["get_texture_temp_http"]["resp_max"].asReal(), 9.0, 22); -		ensure_approximately_equals("max after merge", s2_llsd["get_texture_temp_http"]["resp_mean"].asReal(), 5.5, 22); -	} - -	// LLViewerAssetStats::merge() basic functions work without corrupting source data -	template<> template<> -	void tst_viewerassetstats_index_object_t::test<10>() -	{ -		LLViewerAssetStats s1; -		LLViewerAssetStats s2; - -		s1.setRegion(region1_handle); -		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - -		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - -		s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 23289200); -		s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 282900); - -		 -		s2.setRegion(region2_handle); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - -		s2.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 6500000); -		s2.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 10000); - -		{ -			s2.merge(s1); -			 -			LLSD src = s1.asLLSD(false); -			LLSD dst = s2.asLLSD(false); - -			ensure_equals("merge src has single region", src["regions"].size(), 1); -			ensure_equals("merge dst has dual regions", dst["regions"].size(), 2); -			 -			// Remove time stamps, they're a problem -			src.erase("duration"); -			src["regions"][0].erase("duration"); -			dst.erase("duration"); -			dst["regions"][0].erase("duration"); -			dst["regions"][1].erase("duration"); - -			LLSD s1_llsd = get_region(src, region1_handle); -			ensure("Region1 is present in src", s1_llsd.isMap()); -			LLSD s2_llsd = get_region(dst, region1_handle); -			ensure("Region1 is present in dst", s2_llsd.isMap()); - -			ensure("result from src is in dst", llsd_equals(s1_llsd, s2_llsd)); -		} - -		s1.setRegion(region1_handle); -		s2.setRegion(region1_handle); -		s1.reset(); -		s2.reset(); -		 -		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - -		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - -		s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 23289200); -		s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 282900); - -		 -		s2.setRegion(region1_handle); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - -		s2.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 6500000); -		s2.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 10000); - -		{ -			s2.merge(s1); -			 -			LLSD src = s1.asLLSD(false); -			LLSD dst = s2.asLLSD(false); - -			ensure_equals("merge src has single region (p2)", src["regions"].size(), 1); -			ensure_equals("merge dst has single region (p2)", dst["regions"].size(), 1); - -			// Remove time stamps, they're a problem -			src.erase("duration"); -			src["regions"][0].erase("duration"); -			dst.erase("duration"); -			dst["regions"][0].erase("duration"); -			 -			LLSD s1_llsd = get_region(src, region1_handle); -			ensure("Region1 is present in src", s1_llsd.isMap()); -			LLSD s2_llsd = get_region(dst, region1_handle); -			ensure("Region1 is present in dst", s2_llsd.isMap()); - -			ensure_equals("src counts okay (enq)", s1_llsd["get_other"]["enqueued"].asInteger(), 4); -			ensure_equals("src counts okay (deq)", s1_llsd["get_other"]["dequeued"].asInteger(), 4); -			ensure_equals("src resp counts okay", s1_llsd["get_other"]["resp_count"].asInteger(), 2); -			ensure_approximately_equals("src respmin okay", s1_llsd["get_other"]["resp_min"].asReal(), 0.2829, 20); -			ensure_approximately_equals("src respmax okay", s1_llsd["get_other"]["resp_max"].asReal(), 23.2892, 20); -			 -			ensure_equals("dst counts okay (enq)", s2_llsd["get_other"]["enqueued"].asInteger(), 12); -			ensure_equals("src counts okay (deq)", s2_llsd["get_other"]["dequeued"].asInteger(), 11); -			ensure_equals("dst resp counts okay", s2_llsd["get_other"]["resp_count"].asInteger(), 4); -			ensure_approximately_equals("dst respmin okay", s2_llsd["get_other"]["resp_min"].asReal(), 0.010, 20); -			ensure_approximately_equals("dst respmax okay", s2_llsd["get_other"]["resp_max"].asReal(), 23.2892, 20); -		} -	} - - -    // Maximum merges are interesting when one side contributes nothing -	template<> template<> -	void tst_viewerassetstats_index_object_t::test<11>() -	{ -		LLViewerAssetStats s1; -		LLViewerAssetStats s2; - -		s1.setRegion(region1_handle); -		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - -		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - -		// Want to test negative numbers here but have to work in U64 -		s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 0); -		s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 0); -		s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 0); - -		s2.setRegion(region1_handle); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - -		{ -			s2.merge(s1); -			 -			LLSD src = s1.asLLSD(false); -			LLSD dst = s2.asLLSD(false); - -			ensure_equals("merge src has single region", src["regions"].size(), 1); -			ensure_equals("merge dst has single region", dst["regions"].size(), 1); -			 -			// Remove time stamps, they're a problem -			src.erase("duration"); -			src["regions"][0].erase("duration"); -			dst.erase("duration"); -			dst["regions"][0].erase("duration"); - -			LLSD s2_llsd = get_region(dst, region1_handle); -			ensure("Region1 is present in dst", s2_llsd.isMap()); -			 -			ensure_equals("dst counts come from src only", s2_llsd["get_other"]["resp_count"].asInteger(), 3); - -			ensure_approximately_equals("dst maximum with count 0 does not contribute to merged maximum", -										s2_llsd["get_other"]["resp_max"].asReal(), F64(0.0), 20); -		} - -		// Other way around -		s1.setRegion(region1_handle); -		s2.setRegion(region1_handle); -		s1.reset(); -		s2.reset(); - -		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - -		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - -		// Want to test negative numbers here but have to work in U64 -		s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 0); -		s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 0); -		s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 0); - -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - -		{ -			s1.merge(s2); -			 -			LLSD src = s2.asLLSD(false); -			LLSD dst = s1.asLLSD(false); - -			ensure_equals("merge src has single region", src["regions"].size(), 1); -			ensure_equals("merge dst has single region", dst["regions"].size(), 1); -			 -			// Remove time stamps, they're a problem -			src.erase("duration"); -			src["regions"][0].erase("duration"); -			dst.erase("duration"); -			dst["regions"][0].erase("duration"); - -			LLSD s2_llsd = get_region(dst, region1_handle); -			ensure("Region1 is present in dst", s2_llsd.isMap()); - -			ensure_equals("dst counts come from src only (flipped)", s2_llsd["get_other"]["resp_count"].asInteger(), 3); - -			ensure_approximately_equals("dst maximum with count 0 does not contribute to merged maximum (flipped)", -										s2_llsd["get_other"]["resp_max"].asReal(), F64(0.0), 20); -		} -	} - -    // Minimum merges are interesting when one side contributes nothing -	template<> template<> -	void tst_viewerassetstats_index_object_t::test<12>() -	{ -		LLViewerAssetStats s1; -		LLViewerAssetStats s2; - -		s1.setRegion(region1_handle); -		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - -		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - -		s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 3800000); -		s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 2700000); -		s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 2900000); - -		s2.setRegion(region1_handle); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - -		{ -			s2.merge(s1); -			 -			LLSD src = s1.asLLSD(false); -			LLSD dst = s2.asLLSD(false); - -			ensure_equals("merge src has single region", src["regions"].size(), 1); -			ensure_equals("merge dst has single region", dst["regions"].size(), 1); -			 -			// Remove time stamps, they're a problem -			src.erase("duration"); -			src["regions"][0].erase("duration"); -			dst.erase("duration"); -			dst["regions"][0].erase("duration"); - -			LLSD s2_llsd = get_region(dst, region1_handle); -			ensure("Region1 is present in dst", s2_llsd.isMap()); - -			ensure_equals("dst counts come from src only", s2_llsd["get_other"]["resp_count"].asInteger(), 3); - -			ensure_approximately_equals("dst minimum with count 0 does not contribute to merged minimum", -										s2_llsd["get_other"]["resp_min"].asReal(), F64(2.7), 20); -		} - -		// Other way around -		s1.setRegion(region1_handle); -		s2.setRegion(region1_handle); -		s1.reset(); -		s2.reset(); - -		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - -		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - -		s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 3800000); -		s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 2700000); -		s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 2900000); - -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - -		{ -			s1.merge(s2); -			 -			LLSD src = s2.asLLSD(false); -			LLSD dst = s1.asLLSD(false); - -			ensure_equals("merge src has single region", src["regions"].size(), 1); -			ensure_equals("merge dst has single region", dst["regions"].size(), 1); -			 -			// Remove time stamps, they're a problem -			src.erase("duration"); -			src["regions"][0].erase("duration"); -			dst.erase("duration"); -			dst["regions"][0].erase("duration"); - -			LLSD s2_llsd = get_region(dst, region1_handle); -			ensure("Region1 is present in dst", s2_llsd.isMap()); - -			ensure_equals("dst counts come from src only (flipped)", s2_llsd["get_other"]["resp_count"].asInteger(), 3); - -			ensure_approximately_equals("dst minimum with count 0 does not contribute to merged minimum (flipped)", -										s2_llsd["get_other"]["resp_min"].asReal(), F64(2.7), 20); -		} -	} -  } | 
