Added some simple counters to the mesh repository code and then

Mon, 05 Aug 2013 19:04:08 -0400

author
Monty Brandenberg <monty@lindenlab.com>
date
Mon, 05 Aug 2013 19:04:08 -0400
changeset 40703
cbf70fcee978
parent 40702
8e25ca0fe818
child 40704
1d61fa020f51

Added some simple counters to the mesh repository code and then
added a Mesh status line to the texture fetch console. Mesh is
often in competition with textures and so the mesh information
seems appropriate there. Do get a nice feel for progress and
you definitely see when the throttles kick in.

indra/newview/llmeshrepository.cpp file | annotate | diff | revisions
indra/newview/llmeshrepository.h file | annotate | diff | revisions
indra/newview/lltextureview.cpp file | annotate | diff | revisions
     1.1 --- a/indra/newview/llmeshrepository.cpp	Mon Aug 05 13:54:14 2013 -0400
     1.2 +++ b/indra/newview/llmeshrepository.cpp	Mon Aug 05 19:04:08 2013 -0400
     1.3 @@ -155,20 +155,26 @@
     1.4  //
     1.5  //   So, in addition to documentation, take this as a to-do/review
     1.6  //   list and see if you can improve things.  For porters to non-x86
     1.7 -//   architectures, including amd64, the weaker memory models will
     1.8 -//   make these platforms probabilistically more susceptible to hitting
     1.9 -//   race conditions.  True here and in other multi-thread code such
    1.10 -//   as texture fetching.
    1.11 +//   architectures, the weaker memory models will make these platforms
    1.12 +//   probabilistically more susceptible to hitting race conditions.
    1.13 +//   True here and in other multi-thread code such as texture fetching.
    1.14 +//   (Strong memory models make weak programmers.  Weak memory models
    1.15 +//   make strong programmers.  Ref:  arm, ppc, mips, alpha)
    1.16  //
    1.17  //   LLMeshRepository:
    1.18  //
    1.19  //     sBytesReceived
    1.20 +//     sMeshRequestCount
    1.21  //     sHTTPRequestCount
    1.22 +//     sHTTPLargeRequestCount
    1.23  //     sHTTPRetryCount
    1.24 +//     sHTTPErrorCount
    1.25  //     sLODPending
    1.26  //     sLODProcessing
    1.27  //     sCacheBytesRead
    1.28  //     sCacheBytesWritten
    1.29 +//     sCacheReads
    1.30 +//     sCacheWrites
    1.31  //     mLoadingMeshes                  none            rw.main.none, rw.main.mMeshMutex [4]
    1.32  //     mSkinMap                        none            rw.main.none
    1.33  //     mDecompositionMap               none            rw.main.none
    1.34 @@ -246,13 +252,19 @@
    1.35  const S32 MAX_MESH_VERSION = 999;
    1.36  
    1.37  U32 LLMeshRepository::sBytesReceived = 0;
    1.38 +U32 LLMeshRepository::sMeshRequestCount = 0;
    1.39  U32 LLMeshRepository::sHTTPRequestCount = 0;
    1.40 +U32 LLMeshRepository::sHTTPLargeRequestCount = 0;
    1.41  U32 LLMeshRepository::sHTTPRetryCount = 0;
    1.42 +U32 LLMeshRepository::sHTTPErrorCount = 0;
    1.43  U32 LLMeshRepository::sLODProcessing = 0;
    1.44  U32 LLMeshRepository::sLODPending = 0;
    1.45  
    1.46  U32 LLMeshRepository::sCacheBytesRead = 0;
    1.47  U32 LLMeshRepository::sCacheBytesWritten = 0;
    1.48 +U32 LLMeshRepository::sCacheReads = 0;
    1.49 +U32 LLMeshRepository::sCacheWrites = 0;
    1.50 +
    1.51  LLDeadmanTimer LLMeshRepository::sQuiescentTimer(15.0, true);	// true -> gather cpu metrics
    1.52  
    1.53  	
    1.54 @@ -366,6 +378,7 @@
    1.55  U32	LLMeshRepoThread::sMaxConcurrentRequests = 1;
    1.56  S32 LLMeshRepoThread::sRequestLowWater = REQUEST_LOW_WATER_MIN;
    1.57  S32 LLMeshRepoThread::sRequestHighWater = REQUEST_HIGH_WATER_MIN;
    1.58 +S32 LLMeshRepoThread::sRequestWaterLevel = 0;
    1.59  
    1.60  // Base handler class for all mesh users of llcorehttp.
    1.61  // This is roughly equivalent to a Responder class in
    1.62 @@ -619,9 +632,7 @@
    1.63    mHttpPolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID),
    1.64    mHttpLegacyPolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID),
    1.65    mHttpLargePolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID),
    1.66 -  mHttpPriority(0),
    1.67 -  mHttpGetCount(0U),
    1.68 -  mHttpLargeGetCount(0U)
    1.69 +  mHttpPriority(0)
    1.70  { 
    1.71  	mMutex = new LLMutex(NULL);
    1.72  	mHeaderMutex = new LLMutex(NULL);
    1.73 @@ -641,8 +652,8 @@
    1.74  
    1.75  LLMeshRepoThread::~LLMeshRepoThread()
    1.76  {
    1.77 -	LL_INFOS(LOG_MESH) << "Small GETs issued:  " << mHttpGetCount
    1.78 -					   << ", Large GETs issued:  " << mHttpLargeGetCount
    1.79 +	LL_INFOS(LOG_MESH) << "Small GETs issued:  " << LLMeshRepository::sHTTPRequestCount
    1.80 +					   << ", Large GETs issued:  " << LLMeshRepository::sHTTPLargeRequestCount
    1.81  					   << LL_ENDL;
    1.82  
    1.83  	for (http_request_set::iterator iter(mHttpRequestSet.begin());
    1.84 @@ -700,7 +711,8 @@
    1.85  		if (! LLApp::isQuitting())
    1.86  		{
    1.87  			// NOTE: order of queue processing intentionally favors LOD requests over header requests
    1.88 -			
    1.89 +
    1.90 +			sRequestWaterLevel = mHttpRequestSet.size();
    1.91  			while (!mLODReqQ.empty() && mHttpRequestSet.size() < sRequestHighWater)
    1.92  			{
    1.93  				if (! mMutex)
    1.94 @@ -743,19 +755,26 @@
    1.95  			// list, we scan the entire thing.  This gets us through any requests
    1.96  			// which can be resolved in the cache.  It also keeps the request
    1.97  			// set somewhat fresher otherwise items at the end of the set
    1.98 -			// order will lose.  Keep to the throttle enforcement and pay
    1.99 -			// attention to the highwater level (enforced in each fetchXXX()
   1.100 -			// method).
   1.101 +			// order will lose.
   1.102  			if (! mSkinRequests.empty() && mHttpRequestSet.size() < sRequestHighWater)
   1.103  			{
   1.104  				// *FIXME:  this really does need a lock as do the following ones
   1.105  				std::set<LLUUID> incomplete;
   1.106  				for (std::set<LLUUID>::iterator iter = mSkinRequests.begin(); iter != mSkinRequests.end(); ++iter)
   1.107  				{
   1.108 -					LLUUID mesh_id = *iter;
   1.109 -					if (!fetchMeshSkinInfo(mesh_id))
   1.110 +					if (mHttpRequestSet.size() < sRequestHighWater)
   1.111  					{
   1.112 -						incomplete.insert(mesh_id);
   1.113 +						LLUUID mesh_id = *iter;
   1.114 +						if (!fetchMeshSkinInfo(mesh_id))
   1.115 +						{
   1.116 +							incomplete.insert(mesh_id);
   1.117 +						}
   1.118 +					}
   1.119 +					else
   1.120 +					{
   1.121 +						// Hit high-water mark, copy remaining to incomplete.
   1.122 +						incomplete.insert(iter, mSkinRequests.end());
   1.123 +						break;
   1.124  					}
   1.125  				}
   1.126  				mSkinRequests.swap(incomplete);
   1.127 @@ -766,10 +785,19 @@
   1.128  				std::set<LLUUID> incomplete;
   1.129  				for (std::set<LLUUID>::iterator iter = mDecompositionRequests.begin(); iter != mDecompositionRequests.end(); ++iter)
   1.130  				{
   1.131 -					LLUUID mesh_id = *iter;
   1.132 -					if (!fetchMeshDecomposition(mesh_id))
   1.133 +					if (mHttpRequestSet.size() < sRequestHighWater)
   1.134  					{
   1.135 -						incomplete.insert(mesh_id);
   1.136 +						LLUUID mesh_id = *iter;
   1.137 +						if (!fetchMeshDecomposition(mesh_id))
   1.138 +						{
   1.139 +							incomplete.insert(mesh_id);
   1.140 +						}
   1.141 +					}
   1.142 +					else
   1.143 +					{
   1.144 +						// Hit high-water mark, copy remaining to incomplete.
   1.145 +						incomplete.insert(iter, mDecompositionRequests.end());
   1.146 +						break;
   1.147  					}
   1.148  				}
   1.149  				mDecompositionRequests.swap(incomplete);
   1.150 @@ -780,10 +808,19 @@
   1.151  				std::set<LLUUID> incomplete;
   1.152  				for (std::set<LLUUID>::iterator iter = mPhysicsShapeRequests.begin(); iter != mPhysicsShapeRequests.end(); ++iter)
   1.153  				{
   1.154 -					LLUUID mesh_id = *iter;
   1.155 -					if (!fetchMeshPhysicsShape(mesh_id))
   1.156 +					if (mHttpRequestSet.size() < sRequestHighWater)
   1.157  					{
   1.158 -						incomplete.insert(mesh_id);
   1.159 +						LLUUID mesh_id = *iter;
   1.160 +						if (!fetchMeshPhysicsShape(mesh_id))
   1.161 +						{
   1.162 +							incomplete.insert(mesh_id);
   1.163 +						}
   1.164 +					}
   1.165 +					else
   1.166 +					{
   1.167 +						// Hit high-water mark, copy remaining to incomplete.
   1.168 +						incomplete.insert(iter, mPhysicsShapeRequests.end());
   1.169 +						break;
   1.170  					}
   1.171  				}
   1.172  				mPhysicsShapeRequests.swap(incomplete);
   1.173 @@ -926,7 +963,10 @@
   1.174  												   mHttpOptions,
   1.175  												   mHttpHeaders,
   1.176  												   handler);
   1.177 -		++mHttpGetCount;
   1.178 +		if (LLCORE_HTTP_HANDLE_INVALID != handle)
   1.179 +		{
   1.180 +			++LLMeshRepository::sHTTPRequestCount;
   1.181 +		}
   1.182  	}
   1.183  	else
   1.184  	{
   1.185 @@ -938,7 +978,10 @@
   1.186  												   mHttpLargeOptions,
   1.187  												   mHttpHeaders,
   1.188  												   handler);
   1.189 -		++mHttpLargeGetCount;
   1.190 +		if (LLCORE_HTTP_HANDLE_INVALID != handle)
   1.191 +		{
   1.192 +			++LLMeshRepository::sHTTPLargeRequestCount;
   1.193 +		}
   1.194  	}
   1.195  	if (LLCORE_HTTP_HANDLE_INVALID == handle)
   1.196  	{
   1.197 @@ -965,7 +1008,8 @@
   1.198  		return false;
   1.199  	}
   1.200  
   1.201 -	bool ret = true ;
   1.202 +	++LLMeshRepository::sMeshRequestCount;
   1.203 +	bool ret = true;
   1.204  	U32 header_size = mMeshHeaderSize[mesh_id];
   1.205  	
   1.206  	if (header_size > 0)
   1.207 @@ -983,6 +1027,7 @@
   1.208  			if (file.getSize() >= offset+size)
   1.209  			{				
   1.210  				LLMeshRepository::sCacheBytesRead += size;
   1.211 +				++LLMeshRepository::sCacheReads;
   1.212  				file.seek(offset);
   1.213  				U8* buffer = new U8[size];
   1.214  				file.read(buffer, size);
   1.215 @@ -1007,10 +1052,6 @@
   1.216  			}
   1.217  
   1.218  			//reading from VFS failed for whatever reason, fetch from sim
   1.219 -			if (mHttpRequestSet.size() >= sRequestHighWater)
   1.220 -			{
   1.221 -				return false;
   1.222 -			}
   1.223  			int cap_version(gMeshRepo.mGetMeshVersion);
   1.224  			std::string http_url = constructUrl(mesh_id);
   1.225  			if (!http_url.empty())
   1.226 @@ -1025,12 +1066,12 @@
   1.227  									   << LL_ENDL;
   1.228  					delete handler;
   1.229  					ret = false;
   1.230 +
   1.231  				}
   1.232  				else
   1.233  				{
   1.234  					handler->mHttpHandle = handle;
   1.235  					mHttpRequestSet.insert(handler);
   1.236 -					++LLMeshRepository::sHTTPRequestCount;
   1.237  				}
   1.238  			}
   1.239  		}
   1.240 @@ -1059,8 +1100,9 @@
   1.241  		return false;
   1.242  	}
   1.243  
   1.244 +	++LLMeshRepository::sMeshRequestCount;
   1.245  	U32 header_size = mMeshHeaderSize[mesh_id];
   1.246 -	bool ret = true ;
   1.247 +	bool ret = true;
   1.248  	
   1.249  	if (header_size > 0)
   1.250  	{
   1.251 @@ -1077,6 +1119,7 @@
   1.252  			if (file.getSize() >= offset+size)
   1.253  			{
   1.254  				LLMeshRepository::sCacheBytesRead += size;
   1.255 +				++LLMeshRepository::sCacheReads;
   1.256  
   1.257  				file.seek(offset);
   1.258  				U8* buffer = new U8[size];
   1.259 @@ -1102,10 +1145,6 @@
   1.260  			}
   1.261  
   1.262  			//reading from VFS failed for whatever reason, fetch from sim
   1.263 -			if (mHttpRequestSet.size() >= sRequestHighWater)
   1.264 -			{
   1.265 -				return false;
   1.266 -			}
   1.267  			int cap_version(gMeshRepo.mGetMeshVersion);
   1.268  			std::string http_url = constructUrl(mesh_id);
   1.269  			if (!http_url.empty())
   1.270 @@ -1125,7 +1164,6 @@
   1.271  				{
   1.272  					handler->mHttpHandle = handle;
   1.273  					mHttpRequestSet.insert(handler);
   1.274 -					++LLMeshRepository::sHTTPRequestCount;
   1.275  				}
   1.276  			}
   1.277  		}
   1.278 @@ -1154,8 +1192,9 @@
   1.279  		return false;
   1.280  	}
   1.281  
   1.282 +	++LLMeshRepository::sMeshRequestCount;
   1.283  	U32 header_size = mMeshHeaderSize[mesh_id];
   1.284 -	bool ret = true ;
   1.285 +	bool ret = true;
   1.286  
   1.287  	if (header_size > 0)
   1.288  	{
   1.289 @@ -1172,6 +1211,7 @@
   1.290  			if (file.getSize() >= offset+size)
   1.291  			{
   1.292  				LLMeshRepository::sCacheBytesRead += size;
   1.293 +				++LLMeshRepository::sCacheReads;
   1.294  				file.seek(offset);
   1.295  				U8* buffer = new U8[size];
   1.296  				file.read(buffer, size);
   1.297 @@ -1196,10 +1236,6 @@
   1.298  			}
   1.299  
   1.300  			//reading from VFS failed for whatever reason, fetch from sim
   1.301 -			if (mHttpRequestSet.size() >= sRequestHighWater)
   1.302 -			{
   1.303 -				return false;
   1.304 -			}
   1.305  			int cap_version(gMeshRepo.mGetMeshVersion);
   1.306  			std::string http_url = constructUrl(mesh_id);
   1.307  			if (!http_url.empty())
   1.308 @@ -1219,7 +1255,6 @@
   1.309  				{
   1.310  					handler->mHttpHandle = handle;
   1.311  					mHttpRequestSet.insert(handler);
   1.312 -					++LLMeshRepository::sHTTPRequestCount;
   1.313  				}
   1.314  			}
   1.315  		}
   1.316 @@ -1268,6 +1303,8 @@
   1.317  //return false if failed to get header
   1.318  bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params)
   1.319  {
   1.320 +	++LLMeshRepository::sMeshRequestCount;
   1.321 +
   1.322  	{
   1.323  		//look for mesh in asset in vfs
   1.324  		LLVFile file(gVFS, mesh_params.getSculptID(), LLAssetType::AT_MESH);
   1.325 @@ -1280,6 +1317,7 @@
   1.326  			U8 buffer[MESH_HEADER_SIZE];
   1.327  			S32 bytes = llmin(size, MESH_HEADER_SIZE);
   1.328  			LLMeshRepository::sCacheBytesRead += bytes;	
   1.329 +			++LLMeshRepository::sCacheReads;
   1.330  			file.read(buffer, bytes);
   1.331  			if (headerReceived(mesh_params, buffer, bytes))
   1.332  			{
   1.333 @@ -1314,7 +1352,6 @@
   1.334  		{
   1.335  			handler->mHttpHandle = handle;
   1.336  			mHttpRequestSet.insert(handler);
   1.337 -			++LLMeshRepository::sHTTPRequestCount;
   1.338  		}
   1.339  	}
   1.340  
   1.341 @@ -1331,6 +1368,7 @@
   1.342  
   1.343  	mHeaderMutex->lock();
   1.344  
   1.345 +	++LLMeshRepository::sMeshRequestCount;
   1.346  	bool retval = true;
   1.347  
   1.348  	LLUUID mesh_id = mesh_params.getSculptID();
   1.349 @@ -1352,6 +1390,7 @@
   1.350  			if (file.getSize() >= offset+size)
   1.351  			{
   1.352  				LLMeshRepository::sCacheBytesRead += size;
   1.353 +				++LLMeshRepository::sCacheReads;
   1.354  				file.seek(offset);
   1.355  				U8* buffer = new U8[size];
   1.356  				file.read(buffer, size);
   1.357 @@ -1395,7 +1434,6 @@
   1.358  				{
   1.359  					handler->mHttpHandle = handle;
   1.360  					mHttpRequestSet.insert(handler);
   1.361 -					++LLMeshRepository::sHTTPRequestCount;
   1.362  				}
   1.363  			}
   1.364  			else
   1.365 @@ -2364,6 +2402,7 @@
   1.366  	if (! status)
   1.367  	{
   1.368  		processFailure(status);
   1.369 +		++LLMeshRepository::sHTTPErrorCount;
   1.370  	}
   1.371  	else
   1.372  	{
   1.373 @@ -2484,6 +2523,7 @@
   1.374  			if (file.getMaxSize() >= bytes || file.setMaxSize(bytes))
   1.375  			{
   1.376  				LLMeshRepository::sCacheBytesWritten += data_size;
   1.377 +				++LLMeshRepository::sCacheWrites;
   1.378  
   1.379  				file.write(data, data_size);
   1.380  			
   1.381 @@ -2556,6 +2596,7 @@
   1.382  			file.seek(offset);
   1.383  			file.write(data, size);
   1.384  			LLMeshRepository::sCacheBytesWritten += size;
   1.385 +			++LLMeshRepository::sCacheWrites;
   1.386  		}
   1.387  	}
   1.388  	// *TODO:  Mark mesh unavailable on error
   1.389 @@ -2601,6 +2642,7 @@
   1.390  		if (file.getSize() >= offset+size)
   1.391  		{
   1.392  			LLMeshRepository::sCacheBytesWritten += size;
   1.393 +			++LLMeshRepository::sCacheWrites;
   1.394  			file.seek(offset);
   1.395  			file.write(data, size);
   1.396  		}
   1.397 @@ -2648,6 +2690,7 @@
   1.398  		if (file.getSize() >= offset+size)
   1.399  		{
   1.400  			LLMeshRepository::sCacheBytesWritten += size;
   1.401 +			++LLMeshRepository::sCacheWrites;
   1.402  			file.seek(offset);
   1.403  			file.write(data, size);
   1.404  		}
   1.405 @@ -2695,6 +2738,7 @@
   1.406  		if (file.getSize() >= offset+size)
   1.407  		{
   1.408  			LLMeshRepository::sCacheBytesWritten += size;
   1.409 +			++LLMeshRepository::sCacheWrites;
   1.410  			file.seek(offset);
   1.411  			file.write(data, size);
   1.412  		}
   1.413 @@ -4204,7 +4248,7 @@
   1.414  		LLSD metrics;
   1.415  
   1.416  		metrics["reason"] = "Mesh Download Quiescent";
   1.417 -		metrics["scope"] = "Login";
   1.418 +		metrics["scope"] = metrics_teleport_start_count > 1 ? "Teleport" : "Login";
   1.419  		metrics["start"] = started;
   1.420  		metrics["stop"] = stopped;
   1.421  		metrics["fetches"] = LLSD::Integer(total_count);
     2.1 --- a/indra/newview/llmeshrepository.h	Mon Aug 05 13:54:14 2013 -0400
     2.2 +++ b/indra/newview/llmeshrepository.h	Mon Aug 05 19:04:08 2013 -0400
     2.3 @@ -224,6 +224,7 @@
     2.4  	static U32 sMaxConcurrentRequests;
     2.5  	static S32 sRequestLowWater;
     2.6  	static S32 sRequestHighWater;
     2.7 +	static S32 sRequestWaterLevel;			// Stats-use only, may read outside of thread
     2.8  
     2.9  	LLMutex*	mMutex;
    2.10  	LLMutex*	mHeaderMutex;
    2.11 @@ -387,10 +388,6 @@
    2.12  	LLCore::HttpHandle getByteRange(const std::string & url, int cap_version,
    2.13  									size_t offset, size_t len, 
    2.14  									LLCore::HttpHandler * handler);
    2.15 -
    2.16 -private:
    2.17 -	U32 mHttpGetCount;
    2.18 -	U32 mHttpLargeGetCount;
    2.19  };
    2.20  
    2.21  
    2.22 @@ -497,12 +494,18 @@
    2.23  
    2.24  	//metrics
    2.25  	static U32 sBytesReceived;
    2.26 +	static U32 sMeshRequestCount;
    2.27  	static U32 sHTTPRequestCount;
    2.28 +	static U32 sHTTPLargeRequestCount;
    2.29  	static U32 sHTTPRetryCount;
    2.30 +	static U32 sHTTPErrorCount;
    2.31  	static U32 sLODPending;
    2.32  	static U32 sLODProcessing;
    2.33  	static U32 sCacheBytesRead;
    2.34  	static U32 sCacheBytesWritten;
    2.35 +	static U32 sCacheReads;
    2.36 +	static U32 sCacheWrites;
    2.37 +	
    2.38  	static LLDeadmanTimer sQuiescentTimer;  // time-to-complete-mesh-downloads after significant events
    2.39  
    2.40  	static F32 getStreamingCost(LLSD& header, F32 radius, S32* bytes = NULL, S32* visible_bytes = NULL, S32 detail = -1, F32 *unscaled_value = NULL);
     3.1 --- a/indra/newview/lltextureview.cpp	Mon Aug 05 13:54:14 2013 -0400
     3.2 +++ b/indra/newview/lltextureview.cpp	Mon Aug 05 19:04:08 2013 -0400
     3.3 @@ -4,7 +4,7 @@
     3.4   *
     3.5   * $LicenseInfo:firstyear=2001&license=viewerlgpl$
     3.6   * Second Life Viewer Source Code
     3.7 - * Copyright (C) 2012, Linden Research, Inc.
     3.8 + * Copyright (C) 2012-2013, Linden Research, Inc.
     3.9   * 
    3.10   * This library is free software; you can redistribute it and/or
    3.11   * modify it under the terms of the GNU Lesser General Public
    3.12 @@ -49,6 +49,7 @@
    3.13  #include "llviewertexturelist.h"
    3.14  #include "llvovolume.h"
    3.15  #include "llviewerstats.h"
    3.16 +#include "llmeshrepository.h"
    3.17  
    3.18  // For avatar texture view
    3.19  #include "llvoavatarself.h"
    3.20 @@ -517,6 +518,8 @@
    3.21  	F32 total_texture_downloaded = (F32)gTotalTextureBytes / (1024 * 1024);
    3.22  	F32 total_object_downloaded = (F32)gTotalObjectBytes / (1024 * 1024);
    3.23  	U32 total_http_requests = LLAppViewer::getTextureFetch()->getTotalNumHTTPRequests();
    3.24 +	F32 x_right = 0.0;
    3.25 +	
    3.26  	//----------------------------------------------------------------------------
    3.27  	LLGLSUIDefault gls_ui;
    3.28  	LLColor4 text_color(1.f, 1.f, 1.f, 0.75f);
    3.29 @@ -543,7 +546,7 @@
    3.30  					cache_max_usage);
    3.31  	//, cache_entries, cache_max_entries
    3.32  
    3.33 -	LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*4,
    3.34 +	LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*5,
    3.35  											 text_color, LLFontGL::LEFT, LLFontGL::TOP);
    3.36  
    3.37  	U32 cache_read(0U), cache_write(0U), res_wait(0U);
    3.38 @@ -557,13 +560,12 @@
    3.39  					cache_write,
    3.40  					res_wait);
    3.41  
    3.42 -	LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*3,
    3.43 +	LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*4,
    3.44  											 text_color, LLFontGL::LEFT, LLFontGL::TOP);
    3.45  
    3.46 -	S32 left = 0 ;
    3.47  	//----------------------------------------------------------------------------
    3.48  
    3.49 -	text = llformat("Textures: %d Fetch: %d(%d) Pkts:%d(%d) Cache R/W: %d/%d LFS:%d RAW:%d HTP:%d DEC:%d CRE:%d",
    3.50 +	text = llformat("Textures: %d Fetch: %d(%d) Pkts:%d(%d) Cache R/W: %d/%d LFS:%d RAW:%d HTP:%d DEC:%d CRE:%d ",
    3.51  					gTextureList.getNumImages(),
    3.52  					LLAppViewer::getTextureFetch()->getNumRequests(), LLAppViewer::getTextureFetch()->getNumDeletes(),
    3.53  					LLAppViewer::getTextureFetch()->mPacketCount, LLAppViewer::getTextureFetch()->mBadPacketCount, 
    3.54 @@ -574,19 +576,30 @@
    3.55  					LLAppViewer::getImageDecodeThread()->getPending(), 
    3.56  					gTextureList.mCreateTextureList.size());
    3.57  
    3.58 -	LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*2,
    3.59 -									 text_color, LLFontGL::LEFT, LLFontGL::TOP);
    3.60 +	x_right = 550.0;
    3.61 +	LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*3,
    3.62 +											 text_color, LLFontGL::LEFT, LLFontGL::TOP,
    3.63 +											 LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX,
    3.64 +											 &x_right, FALSE);
    3.65  
    3.66 -
    3.67 -	left = 550;
    3.68  	F32 bandwidth = LLAppViewer::getTextureFetch()->getTextureBandwidth();
    3.69  	F32 max_bandwidth = gSavedSettings.getF32("ThrottleBandwidthKBPS");
    3.70 -	color = bandwidth > max_bandwidth ? LLColor4::red : bandwidth > max_bandwidth*.75f ? LLColor4::yellow : text_color;
    3.71 +	color = bandwidth > max_bandwidth ? LLColor4::red : bandwidth > max_bandwidth * .75f ? LLColor4::yellow : text_color;
    3.72  	color[VALPHA] = text_color[VALPHA];
    3.73 -	text = llformat("BW:%.0f/%.0f",bandwidth, max_bandwidth);
    3.74 -	LLFontGL::getFontMonospace()->renderUTF8(text, 0, left, v_offset + line_height*2,
    3.75 +	text = llformat("BW:%.0f/%.0f", bandwidth, max_bandwidth);
    3.76 +	LLFontGL::getFontMonospace()->renderUTF8(text, 0, x_right, v_offset + line_height*3,
    3.77  											 color, LLFontGL::LEFT, LLFontGL::TOP);
    3.78 -	
    3.79 +
    3.80 +	// Mesh status line
    3.81 +	text = llformat("Mesh: Reqs(Tot/Htp/Big): %u/%u/%u Rtr/Err: %u/%u Cread/Cwrite: %u/%u Low/At/High: %d/%d/%d",
    3.82 +					LLMeshRepository::sMeshRequestCount, LLMeshRepository::sHTTPRequestCount, LLMeshRepository::sHTTPLargeRequestCount,
    3.83 +					LLMeshRepository::sHTTPRetryCount, LLMeshRepository::sHTTPErrorCount,
    3.84 +					LLMeshRepository::sCacheReads, LLMeshRepository::sCacheWrites,
    3.85 +					LLMeshRepoThread::sRequestLowWater, LLMeshRepoThread::sRequestWaterLevel, LLMeshRepoThread::sRequestHighWater);
    3.86 +	LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*2,
    3.87 +											 text_color, LLFontGL::LEFT, LLFontGL::TOP);
    3.88 +
    3.89 +	// Header for texture table columns
    3.90  	S32 dx1 = 0;
    3.91  	if (LLAppViewer::getTextureFetch()->mDebugPause)
    3.92  	{
    3.93 @@ -629,7 +642,7 @@
    3.94  LLRect LLGLTexMemBar::getRequiredRect()
    3.95  {
    3.96  	LLRect rect;
    3.97 -	rect.mTop = 50; //LLFontGL::getFontMonospace()->getLineHeight() * 6;
    3.98 +	rect.mTop = 68; //LLFontGL::getFontMonospace()->getLineHeight() * 6;
    3.99  	return rect;
   3.100  }
   3.101  

mercurial