diff options
Diffstat (limited to 'indra/newview')
| -rw-r--r-- | indra/newview/app_settings/settings.xml | 20 | ||||
| -rw-r--r-- | indra/newview/llappviewer.cpp | 21 | ||||
| -rw-r--r-- | indra/newview/llmeshrepository.cpp | 147 | ||||
| -rw-r--r-- | indra/newview/llmeshrepository.h | 13 | ||||
| -rw-r--r-- | indra/newview/lltexturefetch.cpp | 95 | ||||
| -rw-r--r-- | indra/newview/lltexturefetch.h | 2 | ||||
| -rw-r--r-- | indra/newview/llviewerassetstats.cpp | 398 | ||||
| -rw-r--r-- | indra/newview/llviewerassetstats.h | 59 | ||||
| -rw-r--r-- | indra/newview/llviewerassetstorage.cpp | 758 | ||||
| -rw-r--r-- | indra/newview/llviewerassetstorage.h | 34 | ||||
| -rw-r--r-- | indra/newview/llviewerdisplay.cpp | 7 | ||||
| -rw-r--r-- | indra/newview/llviewerregion.cpp | 14 | ||||
| -rw-r--r-- | indra/newview/llviewerregion.h | 4 | ||||
| -rw-r--r-- | indra/newview/llvoavatar.cpp | 3 | ||||
| -rw-r--r-- | indra/newview/tests/llviewerassetstats_test.cpp | 26 | 
15 files changed, 828 insertions, 773 deletions
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index de31425c27..fbc984692d 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -14694,6 +14694,17 @@        <key>Value</key>        <integer>0</integer>      </map> +    <key>AssetStorageLogFrequency</key> +        <map> +        <key>Comment</key> +        <string>Seconds between display of AssetStorage info in log (0 for never)</string> +        <key>Persist</key> +        <integer>1</integer> +        <key>Type</key> +        <string>F32</string> +        <key>Value</key> +        <real>60.0</real> +        </map>      <key>LogWearableAssetSave</key>      <map>        <key>Comment</key> @@ -14767,6 +14778,15 @@          <key>Value</key>              <real>1</real>          </map> +    <key>PoolSizeAssetStorage</key> +        <map> +        <key>Comment</key> +            <string>Coroutine Pool size for AssetStorage requests</string> +        <key>Type</key> +            <string>U32</string> +        <key>Value</key> +            <real>12</real> +        </map>      <!-- Settings below are for back compatibility only.      They are not used in current viewer anymore. But they can't be removed to avoid diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 0f3a889007..686cad9255 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -831,12 +831,6 @@ bool LLAppViewer::init()      LLMachineID::init();  	{ -		// Viewer metrics initialization -		//static LLCachedControl<bool> metrics_submode(gSavedSettings, -		//											 "QAModeMetrics", -		//											 false, -		//											 "Enables QA features (logging, faster cycling) for metrics collector"); -  		if (gSavedSettings.getBOOL("QAModeMetrics"))  		{  			app_metrics_qa_mode = true; @@ -5552,23 +5546,14 @@ void LLAppViewer::metricsSend(bool enable_reporting)  		{  			std::string	caps_url = regionp->getCapability("ViewerMetrics"); -            if (gSavedSettings.getBOOL("QAModeMetrics")) -            { -                dump_sequential_xml("metric_asset_stats",gViewerAssetStats->asLLSD(true)); -            } -             -			// Make a copy of the main stats to send into another thread. -			// Receiving thread takes ownership. -			LLViewerAssetStats * main_stats(new LLViewerAssetStats(*gViewerAssetStats)); -			main_stats->stop(); -			 +            LLSD sd = gViewerAssetStats->asLLSD(true); +  			// Send a report request into 'thread1' to get the rest of the data  			// and provide some additional parameters while here.  			LLAppViewer::sTextureFetch->commandSendMetrics(caps_url,  														   gAgentSessionID,  														   gAgentID, -														   main_stats); -			main_stats = 0;		// Ownership transferred +														   sd);  		}  		else  		{ diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index f7e0e32256..c4d1917567 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -343,10 +343,6 @@ LLMeshRepository gMeshRepo;  const S32 MESH_HEADER_SIZE = 4096;                      // Important:  assumption is that headers fit in this space -const S32 REQUEST_HIGH_WATER_MIN = 32;					// Limits for GetMesh regions -const S32 REQUEST_HIGH_WATER_MAX = 150;					// Should remain under 2X throttle -const S32 REQUEST_LOW_WATER_MIN = 16; -const S32 REQUEST_LOW_WATER_MAX = 75;  const S32 REQUEST2_HIGH_WATER_MIN = 32;					// Limits for GetMesh2 regions  const S32 REQUEST2_HIGH_WATER_MAX = 100; @@ -808,10 +804,8 @@ LLMeshRepoThread::LLMeshRepoThread()    mHttpLargeOptions(),    mHttpHeaders(),    mHttpPolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID), -  mHttpLegacyPolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID),    mHttpLargePolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID), -  mHttpPriority(0), -  mGetMeshVersion(2) +  mHttpPriority(0)  {  	LLAppCoreHttp & app_core_http(LLAppViewer::instance()->getAppCoreHttp()); @@ -828,7 +822,6 @@ LLMeshRepoThread::LLMeshRepoThread()  	mHttpHeaders = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders);  	mHttpHeaders->append(HTTP_OUT_HEADER_ACCEPT, HTTP_CONTENT_VND_LL_MESH);  	mHttpPolicyClass = app_core_http.getPolicy(LLAppCoreHttp::AP_MESH2); -	mHttpLegacyPolicyClass = app_core_http.getPolicy(LLAppCoreHttp::AP_MESH1);  	mHttpLargePolicyClass = app_core_http.getPolicy(LLAppCoreHttp::AP_LARGE_MESH);  } @@ -1103,13 +1096,9 @@ void LLMeshRepoThread::loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod)  }  // Mutex:  must be holding mMutex when called -void LLMeshRepoThread::setGetMeshCaps(const std::string & get_mesh1, -									  const std::string & get_mesh2, -									  int pref_version) +void LLMeshRepoThread::setGetMeshCap(const std::string & mesh_cap)  { -	mGetMeshCapability = get_mesh1; -	mGetMesh2Capability = get_mesh2; -	mGetMeshVersion = pref_version; +	mGetMeshCapability = mesh_cap;  } @@ -1117,29 +1106,14 @@ void LLMeshRepoThread::setGetMeshCaps(const std::string & get_mesh1,  // over a GetMesh cap.  //  // Mutex:  acquires mMutex -void LLMeshRepoThread::constructUrl(LLUUID mesh_id, std::string * url, int * version) +void LLMeshRepoThread::constructUrl(LLUUID mesh_id, std::string * url)  {  	std::string res_url; -	int res_version(2);  	if (gAgent.getRegion())  	{  		LLMutexLock lock(mMutex); - -		// Get a consistent pair of (cap string, version).  The -		// locking could be eliminated here without loss of safety -		// by using a set of staging values in setGetMeshCaps(). -		 -		if (! mGetMesh2Capability.empty() && mGetMeshVersion > 1) -		{ -			res_url = mGetMesh2Capability; -			res_version = 2; -		} -		else -		{ -			res_url = mGetMeshCapability; -			res_version = 1; -		} +        res_url = mGetMeshCapability;  	}  	if (! res_url.empty()) @@ -1149,19 +1123,15 @@ void LLMeshRepoThread::constructUrl(LLUUID mesh_id, std::string * url, int * ver  	}  	else  	{ -		LL_WARNS_ONCE(LOG_MESH) << "Current region does not have GetMesh capability!  Cannot load " +		LL_WARNS_ONCE(LOG_MESH) << "Current region does not have ViewerAsset capability!  Cannot load "  								<< mesh_id << ".mesh" << LL_ENDL;  	}  	*url = res_url; -	*version = res_version;  }  // Issue an HTTP GET request with byte range using the right -// policy class.  Large requests go to the large request class. -// If the current region supports GetMesh2, we prefer that for -// smaller requests otherwise we try to use the traditional -// GetMesh capability and connection concurrency. +// policy class.    //  // @return		Valid handle or LLCORE_HTTP_HANDLE_INVALID.  //				If the latter, actual status is found in @@ -1169,7 +1139,7 @@ void LLMeshRepoThread::constructUrl(LLUUID mesh_id, std::string * url, int * ver  //				next call to this method.  //  // Thread:  repo -LLCore::HttpHandle LLMeshRepoThread::getByteRange(const std::string & url, int cap_version, +LLCore::HttpHandle LLMeshRepoThread::getByteRange(const std::string & url,  												  size_t offset, size_t len,  												  const LLCore::HttpHandler::ptr_t &handler)  { @@ -1180,16 +1150,14 @@ LLCore::HttpHandle LLMeshRepoThread::getByteRange(const std::string & url, int c  	if (len < LARGE_MESH_FETCH_THRESHOLD)  	{ -		handle = mHttpRequest->requestGetByteRange((2 == cap_version -													? mHttpPolicyClass -													: mHttpLegacyPolicyClass), -												   mHttpPriority, -												   url, -												   (disable_range_req ? size_t(0) : offset), -												   (disable_range_req ? size_t(0) : len), -												   mHttpOptions, -												   mHttpHeaders, -												   handler); +		handle = mHttpRequest->requestGetByteRange( mHttpPolicyClass, +                                                    mHttpPriority, +                                                    url, +                                                    (disable_range_req ? size_t(0) : offset), +                                                    (disable_range_req ? size_t(0) : len), +                                                    mHttpOptions, +                                                    mHttpHeaders, +                                                    handler);  		if (LLCORE_HTTP_HANDLE_INVALID != handle)  		{  			++LLMeshRepository::sHTTPRequestCount; @@ -1279,14 +1247,13 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id)  			}  			//reading from VFS failed for whatever reason, fetch from sim -			int cap_version(2);  			std::string http_url; -			constructUrl(mesh_id, &http_url, &cap_version); +			constructUrl(mesh_id, &http_url);  			if (!http_url.empty())  			{                  LLMeshHandlerBase::ptr_t handler(new LLMeshSkinInfoHandler(mesh_id, offset, size)); -				LLCore::HttpHandle handle = getByteRange(http_url, cap_version, offset, size, handler); +				LLCore::HttpHandle handle = getByteRange(http_url, offset, size, handler);  				if (LLCORE_HTTP_HANDLE_INVALID == handle)  				{  					LL_WARNS(LOG_MESH) << "HTTP GET request failed for skin info on mesh " << mID @@ -1372,14 +1339,13 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)  			}  			//reading from VFS failed for whatever reason, fetch from sim -			int cap_version(2);  			std::string http_url; -			constructUrl(mesh_id, &http_url, &cap_version); +			constructUrl(mesh_id, &http_url);  			if (!http_url.empty())  			{                  LLMeshHandlerBase::ptr_t handler(new LLMeshDecompositionHandler(mesh_id, offset, size)); -				LLCore::HttpHandle handle = getByteRange(http_url, cap_version, offset, size, handler); +				LLCore::HttpHandle handle = getByteRange(http_url, offset, size, handler);  				if (LLCORE_HTTP_HANDLE_INVALID == handle)  				{  					LL_WARNS(LOG_MESH) << "HTTP GET request failed for decomposition mesh " << mID @@ -1464,14 +1430,13 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)  			}  			//reading from VFS failed for whatever reason, fetch from sim -			int cap_version(2);  			std::string http_url; -			constructUrl(mesh_id, &http_url, &cap_version); +			constructUrl(mesh_id, &http_url);  			if (!http_url.empty())  			{                  LLMeshHandlerBase::ptr_t handler(new LLMeshPhysicsShapeHandler(mesh_id, offset, size)); -				LLCore::HttpHandle handle = getByteRange(http_url, cap_version, offset, size, handler); +				LLCore::HttpHandle handle = getByteRange(http_url, offset, size, handler);  				if (LLCORE_HTTP_HANDLE_INVALID == handle)  				{  					LL_WARNS(LOG_MESH) << "HTTP GET request failed for physics shape on mesh " << mID @@ -1558,9 +1523,8 @@ bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params)  	//either cache entry doesn't exist or is corrupt, request header from simulator	  	bool retval = true; -	int cap_version(2);  	std::string http_url; -	constructUrl(mesh_params.getSculptID(), &http_url, &cap_version); +	constructUrl(mesh_params.getSculptID(), &http_url);  	if (!http_url.empty())  	{ @@ -1569,7 +1533,7 @@ bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params)  		//NOTE -- this will break of headers ever exceed 4KB		          LLMeshHandlerBase::ptr_t handler(new LLMeshHeaderHandler(mesh_params, 0, MESH_HEADER_SIZE)); -		LLCore::HttpHandle handle = getByteRange(http_url, cap_version, 0, MESH_HEADER_SIZE, handler); +		LLCore::HttpHandle handle = getByteRange(http_url, 0, MESH_HEADER_SIZE, handler);  		if (LLCORE_HTTP_HANDLE_INVALID == handle)  		{  			LL_WARNS(LOG_MESH) << "HTTP GET request failed for mesh header " << mID @@ -1645,14 +1609,13 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod)  			}  			//reading from VFS failed for whatever reason, fetch from sim -			int cap_version(2);  			std::string http_url; -			constructUrl(mesh_id, &http_url, &cap_version); +			constructUrl(mesh_id, &http_url);  			if (!http_url.empty())  			{                  LLMeshHandlerBase::ptr_t handler(new LLMeshLODHandler(mesh_params, lod, offset, size)); -				LLCore::HttpHandle handle = getByteRange(http_url, cap_version, offset, size, handler); +				LLCore::HttpHandle handle = getByteRange(http_url, offset, size, handler);  				if (LLCORE_HTTP_HANDLE_INVALID == handle)  				{  					LL_WARNS(LOG_MESH) << "HTTP GET request failed for LOD on mesh " << mID @@ -3292,8 +3255,7 @@ void LLMeshPhysicsShapeHandler::processData(LLCore::BufferArray * /* body */, S3  LLMeshRepository::LLMeshRepository()  : mMeshMutex(NULL),    mMeshThreadCount(0), -  mThread(NULL), -  mGetMeshVersion(2) +  mThread(NULL)  {  } @@ -3476,35 +3438,21 @@ void LLMeshRepository::notifyLoadedMeshes()  { //called from main thread  	LL_RECORD_BLOCK_TIME(FTM_MESH_FETCH); -	if (1 == mGetMeshVersion) -	{ -		// Legacy GetMesh operation with high connection concurrency -		LLMeshRepoThread::sMaxConcurrentRequests = gSavedSettings.getU32("MeshMaxConcurrentRequests"); -		LLMeshRepoThread::sRequestHighWater = llclamp(2 * S32(LLMeshRepoThread::sMaxConcurrentRequests), -													  REQUEST_HIGH_WATER_MIN, -													  REQUEST_HIGH_WATER_MAX); -		LLMeshRepoThread::sRequestLowWater = llclamp(LLMeshRepoThread::sRequestHighWater / 2, -													 REQUEST_LOW_WATER_MIN, -													 REQUEST_LOW_WATER_MAX); -	} -	else -	{ -		// GetMesh2 operation with keepalives, etc.  With pipelining, -		// we'll increase this.  See llappcorehttp and llcorehttp for -		// discussion on connection strategies. -		LLAppCoreHttp & app_core_http(LLAppViewer::instance()->getAppCoreHttp()); -		S32 scale(app_core_http.isPipelined(LLAppCoreHttp::AP_MESH2) -				  ? (2 * LLAppCoreHttp::PIPELINING_DEPTH) -				  : 5); - -		LLMeshRepoThread::sMaxConcurrentRequests = gSavedSettings.getU32("Mesh2MaxConcurrentRequests"); -		LLMeshRepoThread::sRequestHighWater = llclamp(scale * S32(LLMeshRepoThread::sMaxConcurrentRequests), -													  REQUEST2_HIGH_WATER_MIN, -													  REQUEST2_HIGH_WATER_MAX); -		LLMeshRepoThread::sRequestLowWater = llclamp(LLMeshRepoThread::sRequestHighWater / 2, -													 REQUEST2_LOW_WATER_MIN, -													 REQUEST2_LOW_WATER_MAX); -	} +    // GetMesh2 operation with keepalives, etc.  With pipelining, +    // we'll increase this.  See llappcorehttp and llcorehttp for +    // discussion on connection strategies. +    LLAppCoreHttp & app_core_http(LLAppViewer::instance()->getAppCoreHttp()); +    S32 scale(app_core_http.isPipelined(LLAppCoreHttp::AP_MESH2) +              ? (2 * LLAppCoreHttp::PIPELINING_DEPTH) +              : 5); + +    LLMeshRepoThread::sMaxConcurrentRequests = gSavedSettings.getU32("Mesh2MaxConcurrentRequests"); +    LLMeshRepoThread::sRequestHighWater = llclamp(scale * S32(LLMeshRepoThread::sMaxConcurrentRequests), +                                                  REQUEST2_HIGH_WATER_MIN, +                                                  REQUEST2_HIGH_WATER_MAX); +    LLMeshRepoThread::sRequestLowWater = llclamp(LLMeshRepoThread::sRequestHighWater / 2, +                                                 REQUEST2_LOW_WATER_MIN, +                                                 REQUEST2_LOW_WATER_MAX);  	//clean up completed upload threads  	for (std::vector<LLMeshUploadThread*>::iterator iter = mUploads.begin(); iter != mUploads.end(); ) @@ -3610,15 +3558,10 @@ void LLMeshRepository::notifyLoadedMeshes()  			if (gAgent.getRegion()->getName() != region_name && gAgent.getRegion()->capabilitiesReceived())  			{  				region_name = gAgent.getRegion()->getName(); -				const bool use_v1(gSavedSettings.getBOOL("MeshUseGetMesh1")); -				const std::string mesh1(gAgent.getRegion()->getCapability("GetMesh")); -				const std::string mesh2(gAgent.getRegion()->getCapability("GetMesh2")); -				mGetMeshVersion = (mesh2.empty() || use_v1) ? 1 : 2; -				mThread->setGetMeshCaps(mesh1, mesh2, mGetMeshVersion); +				const std::string mesh_cap(gAgent.getRegion()->getViewerAssetUrl()); +				mThread->setGetMeshCap(mesh_cap);  				LL_DEBUGS(LOG_MESH) << "Retrieving caps for region '" << region_name -									<< "', GetMesh2:  " << mesh2 -									<< ", GetMesh:  " << mesh1 -									<< ", using version:  " << mGetMeshVersion +									<< "', ViewerAsset cap:  " << mesh_cap  									<< LL_ENDL;  			}  		} diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index 30f042845a..23af837f6f 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -279,7 +279,6 @@ public:  	LLCore::HttpOptions::ptr_t			mHttpLargeOptions;  	LLCore::HttpHeaders::ptr_t			mHttpHeaders;  	LLCore::HttpRequest::policy_t		mHttpPolicyClass; -	LLCore::HttpRequest::policy_t		mHttpLegacyPolicyClass;  	LLCore::HttpRequest::policy_t		mHttpLargePolicyClass;  	LLCore::HttpRequest::priority_t		mHttpPriority; @@ -287,8 +286,6 @@ public:  	http_request_set					mHttpRequestSet;			// Outstanding HTTP requests  	std::string mGetMeshCapability; -	std::string mGetMesh2Capability; -	int mGetMeshVersion;  	LLMeshRepoThread();  	~LLMeshRepoThread(); @@ -335,12 +332,10 @@ public:  	// mesh fetch URLs.  	//  	// Mutex:  must be holding mMutex when called -	void setGetMeshCaps(const std::string & get_mesh1, -						const std::string & get_mesh2, -						int pref_version); +	void setGetMeshCap(const std::string & get_mesh);  	// Mutex:  acquires mMutex -	void constructUrl(LLUUID mesh_id, std::string * url, int * version); +	void constructUrl(LLUUID mesh_id, std::string * url);  private:  	// Issue a GET request to a URL with 'Range' header using @@ -349,7 +344,7 @@ private:  	// or dispose of handler.  	//  	// Threads:  Repo thread only -	LLCore::HttpHandle getByteRange(const std::string & url, int cap_version, +	LLCore::HttpHandle getByteRange(const std::string & url,   									size_t offset, size_t len,   									const LLCore::HttpHandler::ptr_t &handler);  }; @@ -585,8 +580,6 @@ public:  	void uploadError(LLSD& args);  	void updateInventory(inventory_data data); - -	int mGetMeshVersion;		// Shadows value in LLMeshRepoThread  };  extern LLMeshRepository gMeshRepo; diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 07b3dc1aa4..b78d0b51d5 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -30,8 +30,6 @@  #include <map>  #include <algorithm> -#include "llstl.h" -  #include "lltexturefetch.h"  #include "lldir.h" @@ -485,7 +483,7 @@ private:  	void recordTextureStart(bool is_http);  	// Threads:  Ttf -	void recordTextureDone(bool is_http); +	void recordTextureDone(bool is_http, F64 byte_count);  	void lockWorkMutex() { mWorkMutex.lock(); }  	void unlockWorkMutex() { mWorkMutex.unlock(); } @@ -824,7 +822,7 @@ public:      TFReqSendMetrics(const std::string & caps_url,          const LLUUID & session_id,          const LLUUID & agent_id, -        LLViewerAssetStats * main_stats); +        LLSD& stats_sd);  	TFReqSendMetrics & operator=(const TFReqSendMetrics &);	// Not defined  	virtual ~TFReqSendMetrics(); @@ -835,7 +833,7 @@ public:  	const std::string mCapsURL;  	const LLUUID mSessionID;  	const LLUUID mAgentID; -	LLViewerAssetStats * mMainStats; +    LLSD mStatsSD;  private:      LLCore::HttpHandler::ptr_t  mHandler; @@ -1351,7 +1349,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  			if (region)  			{ -				std::string http_url = region->getHttpUrl() ; +				std::string http_url = region->getViewerAssetUrl();  				if (!http_url.empty())  				{  					if (mFTType != FTT_DEFAULT) @@ -1426,6 +1424,20 @@ bool LLTextureFetchWorker::doWork(S32 param)  		}  		if (processSimulatorPackets())  		{ +            // Capture some measure of total size for metrics +            F64 byte_count = 0; +            if (mLastPacket >= mFirstPacket) +            { +                for (S32 i=mFirstPacket; i<=mLastPacket; i++) +                { +                    llassert_always((i>=0) && (i<mPackets.size())); +                    if (mPackets[i]) +                    { +                        byte_count += mPackets[i]->mSize; +                    } +                } +            } +  			LL_DEBUGS(LOG_TXT) << mID << ": Loaded from Sim. Bytes: " << mFormattedImage->getDataSize() << LL_ENDL;  			mFetcher->removeFromNetworkQueue(this, false);  			if (mFormattedImage.isNull() || !mFormattedImage->getDataSize()) @@ -1443,7 +1455,8 @@ bool LLTextureFetchWorker::doWork(S32 param)  			}  			setState(DECODE_IMAGE);  			mWriteToCacheState = SHOULD_WRITE; -			recordTextureDone(false); + +			recordTextureDone(false, byte_count);  		}  		else  		{ @@ -2093,7 +2106,7 @@ void LLTextureFetchWorker::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRe  	mFetcher->removeFromHTTPQueue(mID, data_size); -	recordTextureDone(true); +	recordTextureDone(true, data_size);  }																		// -Mw @@ -2222,6 +2235,7 @@ bool LLTextureFetchWorker::processSimulatorPackets()  		S32 buffer_size = mFormattedImage->getDataSize();  		for (S32 i = mFirstPacket; i<=mLastPacket; i++)  		{ +            llassert_always((i>=0) && (i<mPackets.size()));  			llassert_always(mPackets[i]);  			buffer_size += mPackets[i]->mSize;  		} @@ -2493,14 +2507,15 @@ void LLTextureFetchWorker::recordTextureStart(bool is_http)  // Threads:  Ttf -void LLTextureFetchWorker::recordTextureDone(bool is_http) +void LLTextureFetchWorker::recordTextureDone(bool is_http, F64 byte_count)  {  	if (mMetricsStartTime.value())  	{  		LLViewerAssetStatsFF::record_response(LLViewerAssetType::AT_TEXTURE, -													  is_http, -													  LLImageBase::TYPE_AVATAR_BAKE == mType, -													  LLViewerAssetStatsFF::get_timestamp() - mMetricsStartTime); +                                              is_http, +                                              LLImageBase::TYPE_AVATAR_BAKE == mType, +                                              LLViewerAssetStatsFF::get_timestamp() - mMetricsStartTime, +                                              byte_count);  		mMetricsStartTime = (U32Seconds)0;  	}  	LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_TEXTURE, @@ -3863,9 +3878,9 @@ void LLTextureFetch::commandSetRegion(U64 region_handle)  void LLTextureFetch::commandSendMetrics(const std::string & caps_url,  										const LLUUID & session_id,  										const LLUUID & agent_id, -										LLViewerAssetStats * main_stats) +										LLSD& stats_sd)  { -	TFReqSendMetrics * req = new TFReqSendMetrics(caps_url, session_id, agent_id, main_stats); +	TFReqSendMetrics * req = new TFReqSendMetrics(caps_url, session_id, agent_id, stats_sd);  	cmdEnqueue(req);  } @@ -3974,22 +3989,20 @@ TFReqSetRegion::doWork(LLTextureFetch *)  }  TFReqSendMetrics::TFReqSendMetrics(const std::string & caps_url, -        const LLUUID & session_id, -        const LLUUID & agent_id, -        LLViewerAssetStats * main_stats):  +                                   const LLUUID & session_id, +                                   const LLUUID & agent_id, +                                   LLSD& stats_sd):      LLTextureFetch::TFRequest(),      mCapsURL(caps_url),      mSessionID(session_id),      mAgentID(agent_id), -    mMainStats(main_stats), +    mStatsSD(stats_sd),      mHandler(new AssetReportHandler)  {}  TFReqSendMetrics::~TFReqSendMetrics()  { -	delete mMainStats; -	mMainStats = 0;  } @@ -4010,26 +4023,19 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher)  	static volatile bool reporting_started(false);  	static volatile S32 report_sequence(0); -	// We've taken over ownership of the stats copy at this -	// point.  Get a working reference to it for merging here -	// but leave it in 'this'.  Destructor will rid us of it. -	LLViewerAssetStats & main_stats = *mMainStats; - -	LLViewerAssetStats::AssetStats stats; -	main_stats.getStats(stats, true); -	//LLSD merged_llsd = main_stats.asLLSD(); +	// In mStatsSD, we have a copy we own of the LLSD representation +	// of the asset stats. Add some additional fields and ship it off. +    static const S32 metrics_data_version = 2; +      	bool initial_report = !reporting_started; -	stats.session_id = mSessionID; -	stats.agent_id = mAgentID; -	stats.message = "ViewerAssetMetrics"; -	stats.sequence = static_cast<bool>(report_sequence); -	stats.initial = initial_report; -	stats.break_ = static_cast<bool>(LLTextureFetch::svMetricsDataBreak); - -	LLSD sd; -	LLParamSDParser parser; -	parser.writeSD(sd, stats); +	mStatsSD["session_id"] = mSessionID; +	mStatsSD["agent_id"] = mAgentID; +	mStatsSD["message"] = "ViewerAssetMetrics"; +	mStatsSD["sequence"] = report_sequence; +	mStatsSD["initial"] = initial_report; +	mStatsSD["version"] = metrics_data_version; +	mStatsSD["break"] = static_cast<bool>(LLTextureFetch::svMetricsDataBreak);  	// Update sequence number  	if (S32_MAX == ++report_sequence) @@ -4040,8 +4046,13 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher)  	// Limit the size of the stats report if necessary. -	sd["truncated"] = truncate_viewer_metrics(10, sd); +	mStatsSD["truncated"] = truncate_viewer_metrics(10, mStatsSD); +    if (gSavedSettings.getBOOL("QAModeMetrics")) +    { +        dump_sequential_xml("metric_asset_stats",mStatsSD); +    } +              	if (! mCapsURL.empty())  	{  		// Don't care about handle, this is a fire-and-forget operation.   @@ -4049,7 +4060,7 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher)  											fetcher->getMetricsPolicyClass(),  											report_priority,  											mCapsURL, -											sd, +											mStatsSD,  											LLCore::HttpOptions::ptr_t(),  											fetcher->getMetricsHeaders(),  											mHandler); @@ -4063,7 +4074,7 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher)  	// In QA mode, Metrics submode, log the result for ease of testing  	if (fetcher->isQAMode())  	{ -		LL_INFOS(LOG_TXT) << ll_pretty_print_sd(sd) << LL_ENDL; +		LL_INFOS(LOG_TXT) << "ViewerAssetMetrics as submitted\n" << ll_pretty_print_sd(mStatsSD) << LL_ENDL;  	}  	return true; @@ -4580,7 +4591,7 @@ void LLTextureFetchDebugger::debugHTTP()  		return;  	} -	mHTTPUrl = region->getHttpUrl(); +	mHTTPUrl = region->getViewerAssetUrl();  	if (mHTTPUrl.empty())  	{  		LL_INFOS(LOG_TXT) << "Fetch Debugger : Current region URL undefined. Cannot fetch textures through HTTP." << LL_ENDL; diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index 072e6a3307..cfa312ccd9 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -160,7 +160,7 @@ public:  	void commandSendMetrics(const std::string & caps_url,  							const LLUUID & session_id,  							const LLUUID & agent_id, -							LLViewerAssetStats * main_stats); +							LLSD& stats_sd);  	// Threads:  T*  	void commandDataBreak(); diff --git a/indra/newview/llviewerassetstats.cpp b/indra/newview/llviewerassetstats.cpp index 54ac29723f..14e05fd440 100644 --- a/indra/newview/llviewerassetstats.cpp +++ b/indra/newview/llviewerassetstats.cpp @@ -80,6 +80,47 @@   *   */ +namespace LLTrace +{ +// This little bit of shimmery is to allow the creation of +// default-constructed stat and event handles so we can make arrays of +// the things. + +// The only sensible way to use this function is to immediately make a +// copy of the contents, since it always returns the same pointer. +const char *makeNewAutoName() +{ +    static char name[64]; +    static S32 auto_namer_number = 0; +    snprintf(name,64,"auto_name_%d",auto_namer_number); +    auto_namer_number++; +    return name; +} + +template <typename T = F64> +class DCCountStatHandle: +        public CountStatHandle<T> +{ +public: +    DCCountStatHandle(const char *name = makeNewAutoName(), const char *description=NULL): +        CountStatHandle<T>(name,description) +    { +    } +}; + +template <typename T = F64> +class DCEventStatHandle: +        public EventStatHandle<T> +{ +public: +    DCEventStatHandle(const char *name = makeNewAutoName(), const char *description=NULL): +        EventStatHandle<T>(name,description) +    { +    } +}; + +} +  namespace LLViewerAssetStatsFF  {  	static EViewerAssetCategories asset_type_to_category(const LLViewerAssetType::EType at, bool with_http, bool is_temp) @@ -90,176 +131,45 @@ namespace LLViewerAssetStatsFF  		//  - wearables (clothing, bodyparts) which directly affect  		//    user experiences when they log in  		//  - sounds -		//  - gestures +		//  - gestures, including animations  		//  - 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]; -		} +        EViewerAssetCategories ret; +        switch (at) +        { +            case LLAssetType::AT_TEXTURE: +                if (is_temp) +                    ret = with_http ? EVACTextureTempHTTPGet : EVACTextureTempUDPGet; +                else +                    ret = with_http ? EVACTextureNonTempHTTPGet : EVACTextureNonTempUDPGet; +                break; +            case LLAssetType::AT_SOUND: +            case LLAssetType::AT_SOUND_WAV: +                ret = with_http ? EVACSoundHTTPGet : EVACSoundUDPGet; +                break; +            case LLAssetType::AT_CLOTHING: +            case LLAssetType::AT_BODYPART: +                ret = with_http ? EVACWearableHTTPGet : EVACWearableUDPGet; +                break; +            case LLAssetType::AT_ANIMATION: +            case LLAssetType::AT_GESTURE: +                ret = with_http ? EVACGestureHTTPGet : EVACGestureUDPGet; +                break; +            case LLAssetType::AT_LANDMARK: +                ret = with_http ? EVACLandmarkHTTPGet : EVACLandmarkUDPGet; +                break; +            default: +                ret = with_http ? EVACOtherHTTPGet : EVACOtherUDPGet; +                break; +        }  		return ret;  	} -	static LLTrace::CountStatHandle<> sEnqueueAssetRequestsTempTextureHTTP   ("enqueuedassetrequeststemptexturehttp",  -																	"Number of temporary texture asset http requests enqueued"), -							sEnqueueAssetRequestsTempTextureUDP    ("enqueuedassetrequeststemptextureudp",  -																	"Number of temporary texture asset udp requests enqueued"), -							sEnqueueAssetRequestsNonTempTextureHTTP("enqueuedassetrequestsnontemptexturehttp",  -																	"Number of texture asset http requests enqueued"), -							sEnqueueAssetRequestsNonTempTextureUDP ("enqueuedassetrequestsnontemptextureudp",  -																	"Number of texture asset udp requests enqueued"), -							sEnqueuedAssetRequestsWearableUdp      ("enqueuedassetrequestswearableudp",  -																	"Number of wearable asset requests enqueued"), -							sEnqueuedAssetRequestsSoundUdp         ("enqueuedassetrequestssoundudp",  -																	"Number of sound asset requests enqueued"), -							sEnqueuedAssetRequestsGestureUdp       ("enqueuedassetrequestsgestureudp",  -																	"Number of gesture asset requests enqueued"), -							sEnqueuedAssetRequestsOther            ("enqueuedassetrequestsother",  -																	"Number of other asset requests enqueued"); - -	static LLTrace::CountStatHandle<>* sEnqueued[EVACCount] = {		 -		&sEnqueueAssetRequestsTempTextureHTTP,    -		&sEnqueueAssetRequestsTempTextureUDP,   -		&sEnqueueAssetRequestsNonTempTextureHTTP, -		&sEnqueueAssetRequestsNonTempTextureUDP, -		&sEnqueuedAssetRequestsWearableUdp, -		&sEnqueuedAssetRequestsSoundUdp, -		&sEnqueuedAssetRequestsGestureUdp, -		&sEnqueuedAssetRequestsOther             -	}; -	 -	static LLTrace::CountStatHandle<> sDequeueAssetRequestsTempTextureHTTP   ("dequeuedassetrequeststemptexturehttp",  -																	"Number of temporary texture asset http requests dequeued"), -							sDequeueAssetRequestsTempTextureUDP    ("dequeuedassetrequeststemptextureudp",  -																	"Number of temporary texture asset udp requests dequeued"), -							sDequeueAssetRequestsNonTempTextureHTTP("dequeuedassetrequestsnontemptexturehttp",  -																	"Number of texture asset http requests dequeued"), -							sDequeueAssetRequestsNonTempTextureUDP ("dequeuedassetrequestsnontemptextureudp",  -																	"Number of texture asset udp requests dequeued"), -							sDequeuedAssetRequestsWearableUdp      ("dequeuedassetrequestswearableudp",  -																	"Number of wearable asset requests dequeued"), -							sDequeuedAssetRequestsSoundUdp         ("dequeuedassetrequestssoundudp",  -																	"Number of sound asset requests dequeued"), -							sDequeuedAssetRequestsGestureUdp       ("dequeuedassetrequestsgestureudp",  -																	"Number of gesture asset requests dequeued"), -							sDequeuedAssetRequestsOther            ("dequeuedassetrequestsother",  -																	"Number of other asset requests dequeued"); - -	static LLTrace::CountStatHandle<>* sDequeued[EVACCount] = { -		&sDequeueAssetRequestsTempTextureHTTP,    -		&sDequeueAssetRequestsTempTextureUDP,   -		&sDequeueAssetRequestsNonTempTextureHTTP, -		&sDequeueAssetRequestsNonTempTextureUDP, -		&sDequeuedAssetRequestsWearableUdp, -		&sDequeuedAssetRequestsSoundUdp, -		&sDequeuedAssetRequestsGestureUdp, -		&sDequeuedAssetRequestsOther             -	}; - -	static LLTrace::EventStatHandle<F64Seconds >	sResponseAssetRequestsTempTextureHTTP   ("assetresponsetimestemptexturehttp", -																							"Time spent responding to temporary texture asset http requests"), -													sResponseAssetRequestsTempTextureUDP    ("assetresponsetimestemptextureudp",  -																							"Time spent responding to temporary texture asset udp requests"), -													sResponseAssetRequestsNonTempTextureHTTP("assetresponsetimesnontemptexturehttp",  -																							"Time spent responding to texture asset http requests"), -													sResponseAssetRequestsNonTempTextureUDP ("assetresponsetimesnontemptextureudp",  -																							"Time spent responding to texture asset udp requests"), -													sResponsedAssetRequestsWearableUdp      ("assetresponsetimeswearableudp",  -																							"Time spent responding to wearable asset requests"), -													sResponsedAssetRequestsSoundUdp         ("assetresponsetimessoundudp",  -																							"Time spent responding to sound asset requests"), -													sResponsedAssetRequestsGestureUdp       ("assetresponsetimesgestureudp",  -																							"Time spent responding to gesture asset requests"), -													sResponsedAssetRequestsOther            ("assetresponsetimesother",  -																							"Time spent responding to other asset requests"); - -	static LLTrace::EventStatHandle<F64Seconds >* sResponse[EVACCount] = { -		&sResponseAssetRequestsTempTextureHTTP,    -		&sResponseAssetRequestsTempTextureUDP,   -		&sResponseAssetRequestsNonTempTextureHTTP, -		&sResponseAssetRequestsNonTempTextureUDP, -		&sResponsedAssetRequestsWearableUdp, -		&sResponsedAssetRequestsSoundUdp, -		&sResponsedAssetRequestsGestureUdp, -		&sResponsedAssetRequestsOther             -	}; +	static LLTrace::DCCountStatHandle<> sEnqueued[EVACCount]; +	static LLTrace::DCCountStatHandle<> sDequeued[EVACCount]; +	static LLTrace::DCEventStatHandle<> sBytesFetched[EVACCount]; +	static LLTrace::DCEventStatHandle<F64Seconds > sResponse[EVACCount];  }  // ------------------------------------------------------ @@ -353,6 +263,26 @@ void LLViewerAssetStats::setRegion(region_handle_t region_handle)  	mRegionHandle = region_handle;  } +template <typename T> +void LLViewerAssetStats::getStat(LLTrace::Recording& rec, T& req, LLViewerAssetStatsFF::EViewerAssetCategories cat, bool compact_output) +{ +	using namespace LLViewerAssetStatsFF; + +    if (!compact_output +        || rec.getSampleCount(sEnqueued[cat])  +        || rec.getSampleCount(sDequeued[cat]) +        || rec.getSampleCount(sResponse[cat])) +    { +        req	.enqueued(rec.getSampleCount(sEnqueued[cat])) +            .dequeued(rec.getSampleCount(sDequeued[cat])) +            .resp_count(rec.getSampleCount(sResponse[cat])) +            .resp_min(rec.getMin(sResponse[cat]).value()) +            .resp_max(rec.getMax(sResponse[cat]).value()) +            .resp_mean(rec.getMean(sResponse[cat]).value()) +            .resp_mean_bytes(rec.getMean(sBytesFetched[cat])); +    } +} +  void LLViewerAssetStats::getStats(AssetStats& stats, bool compact_output)  {  	using namespace LLViewerAssetStatsFF; @@ -365,108 +295,22 @@ void LLViewerAssetStats::getStats(AssetStats& stats, bool compact_output)  	{  		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((S32)rec.getSum(*sEnqueued[EVACTextureTempHTTPGet])) -									.dequeued((S32)rec.getSum(*sDequeued[EVACTextureTempHTTPGet])) -									.resp_count((S32)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((S32)rec.getSum(*sEnqueued[EVACTextureTempUDPGet])) -									.dequeued((S32)rec.getSum(*sDequeued[EVACTextureTempUDPGet])) -									.resp_count((S32)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((S32)rec.getSum(*sEnqueued[EVACTextureNonTempHTTPGet])) -										.dequeued((S32)rec.getSum(*sDequeued[EVACTextureNonTempHTTPGet])) -										.resp_count((S32)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((S32)rec.getSum(*sEnqueued[EVACTextureNonTempUDPGet])) -										.dequeued((S32)rec.getSum(*sDequeued[EVACTextureNonTempUDPGet])) -										.resp_count((S32)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((S32)rec.getSum(*sEnqueued[EVACWearableUDPGet])) -								.dequeued((S32)rec.getSum(*sDequeued[EVACWearableUDPGet])) -								.resp_count((S32)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((S32)rec.getSum(*sEnqueued[EVACSoundUDPGet])) -							.dequeued((S32)rec.getSum(*sDequeued[EVACSoundUDPGet])) -							.resp_count((S32)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((S32)rec.getSum(*sEnqueued[EVACGestureUDPGet])) -								.dequeued((S32)rec.getSum(*sDequeued[EVACGestureUDPGet])) -								.resp_count((S32)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((S32)rec.getSum(*sEnqueued[EVACOtherGet])) -						.dequeued((S32)rec.getSum(*sDequeued[EVACOtherGet])) -						.resp_count((S32)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()); -		} +        getStat(rec, r.get_texture_temp_http, EVACTextureTempHTTPGet, compact_output); +        getStat(rec, r.get_texture_temp_udp, EVACTextureTempUDPGet, compact_output); +        getStat(rec, r.get_texture_non_temp_http, EVACTextureNonTempHTTPGet, compact_output); +        getStat(rec, r.get_texture_non_temp_udp, EVACTextureNonTempUDPGet, compact_output); +        getStat(rec, r.get_wearable_http, EVACWearableHTTPGet, compact_output); +        getStat(rec, r.get_wearable_udp, EVACWearableUDPGet, compact_output); +        getStat(rec, r.get_sound_http, EVACSoundHTTPGet, compact_output); +        getStat(rec, r.get_sound_udp, EVACSoundUDPGet, compact_output); +        getStat(rec, r.get_gesture_http, EVACGestureHTTPGet, compact_output); +        getStat(rec, r.get_gesture_udp, EVACGestureUDPGet, compact_output); +        getStat(rec, r.get_landmark_http, EVACLandmarkHTTPGet, compact_output); +        getStat(rec, r.get_landmark_udp, EVACLandmarkUDPGet, compact_output); +        getStat(rec, r.get_other_http, EVACOtherHTTPGet, compact_output); +        getStat(rec, r.get_other_udp, EVACOtherUDPGet, compact_output); +          		S32 fps = (S32)rec.getLastValue(LLStatViewer::FPS_SAMPLE);  		if (!compact_output || fps != 0)  		{ @@ -479,10 +323,10 @@ void LLViewerAssetStats::getStats(AssetStats& stats, bool compact_output)  		grid_from_region_handle(it->first, &grid_x, &grid_y);  		r	.grid_x(grid_x)  			.grid_y(grid_y) -			.duration(F64Microseconds(rec.getDuration()).value()); +			.duration(F64Seconds(rec.getDuration()).value());  	} -	stats.duration(mCurRecording ? F64Microseconds(mCurRecording->getDuration()).value() : 0.0); +	stats.duration(mCurRecording ? F64Seconds(mCurRecording->getDuration()).value() : 0.0);  }  LLSD LLViewerAssetStats::asLLSD(bool compact_output) @@ -518,21 +362,22 @@ void record_enqueue(LLViewerAssetType::EType at, bool with_http, bool is_temp)  {  	const EViewerAssetCategories eac(asset_type_to_category(at, with_http, is_temp)); -	add(*sEnqueued[int(eac)], 1); +	add(sEnqueued[int(eac)], 1);  }  void record_dequeue(LLViewerAssetType::EType at, bool with_http, bool is_temp)  {  	const EViewerAssetCategories eac(asset_type_to_category(at, with_http, is_temp)); -	add(*sDequeued[int(eac)], 1); +	add(sDequeued[int(eac)], 1);  } -void record_response(LLViewerAssetType::EType at, bool with_http, bool is_temp, LLViewerAssetStats::duration_t duration) +void record_response(LLViewerAssetType::EType at, bool with_http, bool is_temp, LLViewerAssetStats::duration_t duration, F64 bytes)  {  	const EViewerAssetCategories eac(asset_type_to_category(at, with_http, is_temp)); -	record(*sResponse[int(eac)], F64Microseconds(duration)); +	record(sResponse[int(eac)], F64Seconds(duration)); +	record(sBytesFetched[int(eac)], bytes);  }  void init() @@ -561,7 +406,8 @@ LLViewerAssetStats::AssetRequestType::AssetRequestType()  	resp_count("resp_count"),  	resp_min("resp_min"),  	resp_max("resp_max"), -	resp_mean("resp_mean") +	resp_mean("resp_mean"), +    resp_mean_bytes("resp_mean_bytes")  {}  LLViewerAssetStats::FPSStats::FPSStats()  @@ -576,10 +422,16 @@ LLViewerAssetStats::RegionStats::RegionStats()  	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_http("get_wearable_http"),  	get_wearable_udp("get_wearable_udp"), +	get_sound_http("get_sound_http"),  	get_sound_udp("get_sound_udp"), +	get_gesture_http("get_gesture_http"),  	get_gesture_udp("get_gesture_udp"), -	get_other("get_other"), +	get_landmark_http("get_landmark_http"), +	get_landmark_udp("get_landmark_udp"), +	get_other_http("get_other_http"), +	get_other_udp("get_other_udp"),  	fps("fps"),  	grid_x("grid_x"),  	grid_y("grid_y"), diff --git a/indra/newview/llviewerassetstats.h b/indra/newview/llviewerassetstats.h index 9d425c82fc..718c284224 100644 --- a/indra/newview/llviewerassetstats.h +++ b/indra/newview/llviewerassetstats.h @@ -39,6 +39,29 @@  #include "lltrace.h"  #include "llinitparam.h" +namespace LLViewerAssetStatsFF +{ +	enum EViewerAssetCategories +	{ +		EVACTextureTempHTTPGet,			//< Texture GETs - temp/baked, HTTP +		EVACTextureTempUDPGet,			//< Texture GETs - temp/baked, UDP +		EVACTextureNonTempHTTPGet,		//< Texture GETs - perm, HTTP +		EVACTextureNonTempUDPGet,		//< Texture GETs - perm, UDP +		EVACWearableHTTPGet,			//< Wearable GETs HTTP +		EVACWearableUDPGet,				//< Wearable GETs UDP +		EVACSoundHTTPGet,				//< Sound GETs HTTP +		EVACSoundUDPGet,				//< Sound GETs UDP +		EVACGestureHTTPGet,				//< Gesture GETs HTTP +		EVACGestureUDPGet,				//< Gesture GETs UDP +		EVACLandmarkHTTPGet,			//< Landmark GETs HTTP +		EVACLandmarkUDPGet,				//< Landmark GETs UDP +		EVACOtherHTTPGet,				//< Other GETs HTTP +		EVACOtherUDPGet,				//< Other GETs UDP + +		EVACCount						// Must be last +	}; +} +  /**   * @class LLViewerAssetStats   * @brief Records performance aspects of asset access operations. @@ -74,6 +97,7 @@   * LLViewerAssetStatsFF is provided for conditional test-and-call   * operations.   */ +  class LLViewerAssetStats : public LLStopWatchControlsMixin<LLViewerAssetStats>  {  public: @@ -98,13 +122,14 @@ public:  						resp_count;  		Mandatory<F64>	resp_min,  						resp_max, -						resp_mean; +						resp_mean, +						resp_mean_bytes;  		AssetRequestType();  	};  	struct FPSStats : public LLInitParam::Block<FPSStats> -			{ +    {  		Mandatory<S32>	count;  		Mandatory<F64>	min,  						max, @@ -113,15 +138,21 @@ public:  	};  	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_http,  									get_wearable_udp, +									get_sound_http,  									get_sound_udp, +									get_gesture_http,  									get_gesture_udp, -									get_other; +									get_landmark_http, +									get_landmark_udp, +									get_other_http, +									get_other_udp;  		Optional<FPSStats>			fps;  		Optional<S32>				grid_x,  									grid_y; @@ -165,6 +196,11 @@ public:  	// Retrieve current metrics for all visited regions (NULL region UUID/handle excluded)      // Uses AssetStats structure seen above  	void getStats(AssetStats& stats, bool compact_output); + +    // Retrieve a single asset request type (taken from a single region) +    template <typename T> +    void getStat(LLTrace::Recording& rec, T& req, LLViewerAssetStatsFF::EViewerAssetCategories cat, bool compact_output); +  	LLSD asLLSD(bool compact_output);  protected: @@ -205,19 +241,6 @@ extern LLViewerAssetStats * gViewerAssetStats;  namespace LLViewerAssetStatsFF  { -	enum EViewerAssetCategories -	{ -		EVACTextureTempHTTPGet,			//< Texture GETs - temp/baked, HTTP -		EVACTextureTempUDPGet,			//< Texture GETs - temp/baked, UDP -		EVACTextureNonTempHTTPGet,		//< Texture GETs - perm, HTTP -		EVACTextureNonTempUDPGet,		//< Texture GETs - perm, UDP -		EVACWearableUDPGet,				//< Wearable GETs -		EVACSoundUDPGet,				//< Sound GETs -		EVACGestureUDPGet,				//< Gesture GETs -		EVACOtherGet,					//< Other GETs - -		EVACCount						// Must be last -	};  /**   * @brief Allocation and deallocation of globals. @@ -250,7 +273,7 @@ void record_enqueue(LLViewerAssetType::EType at, bool with_http, bool is_temp);  void record_dequeue(LLViewerAssetType::EType at, bool with_http, bool is_temp);  void record_response(LLViewerAssetType::EType at, bool with_http, bool is_temp, -						  LLViewerAssetStats::duration_t duration); +                     LLViewerAssetStats::duration_t duration, F64 bytes=0);  void record_avatar_stats(); diff --git a/indra/newview/llviewerassetstorage.cpp b/indra/newview/llviewerassetstorage.cpp index 2db9c7e67c..e0b64403ef 100644 --- a/indra/newview/llviewerassetstorage.cpp +++ b/indra/newview/llviewerassetstorage.cpp @@ -33,9 +33,17 @@  #include "message.h"  #include "llagent.h" +#include "llappcorehttp.h" +#include "llviewerregion.h" +  #include "lltransfersourceasset.h"  #include "lltransfertargetvfile.h"  #include "llviewerassetstats.h" +#include "llcoros.h" +#include "llcoproceduremanager.h" +#include "lleventcoro.h" +#include "llsdutil.h" +#include "llworld.h"  ///----------------------------------------------------------------------------  /// LLViewerAssetRequest @@ -51,267 +59,283 @@  class LLViewerAssetRequest : public LLAssetRequest  {  public: -	LLViewerAssetRequest(const LLUUID &uuid, const LLAssetType::EType type) -		: LLAssetRequest(uuid, type), -		  mMetricsStartTime(0) -		{ -		} -	 -	LLViewerAssetRequest & operator=(const LLViewerAssetRequest &);	// Not defined -	// Default assignment operator valid -	 -	// virtual -	~LLViewerAssetRequest() -		{ -			recordMetrics(); -		} +    LLViewerAssetRequest(const LLUUID &uuid, const LLAssetType::EType type, bool with_http) +        : LLAssetRequest(uuid, type), +          mMetricsStartTime(0), +          mWithHTTP(with_http) +    { +    } +     +    LLViewerAssetRequest & operator=(const LLViewerAssetRequest &); // Not defined +    // Default assignment operator valid +     +    // virtual +    ~LLViewerAssetRequest() +    { +        recordMetrics(); +    }  protected: -	void recordMetrics() -		{ -			if (mMetricsStartTime.value()) -			{ -				// Okay, it appears this request was used for useful things.  Record -				// the expected dequeue and duration of request processing. -				LLViewerAssetStatsFF::record_dequeue(mType, false, false); -				LLViewerAssetStatsFF::record_response(mType, false, false, -														   (LLViewerAssetStatsFF::get_timestamp() -															- mMetricsStartTime)); -				mMetricsStartTime = (U32Seconds)0; -			} -		} -	 +    void recordMetrics() +    { +        if (mMetricsStartTime.value()) +        { +            // Okay, it appears this request was used for useful things.  Record +            // the expected dequeue and duration of request processing. +            LLViewerAssetStatsFF::record_dequeue(mType, mWithHTTP, false); +            LLViewerAssetStatsFF::record_response(mType, mWithHTTP, false, +                                                  (LLViewerAssetStatsFF::get_timestamp() +                                                   - mMetricsStartTime), +                                                  mBytesFetched); +            mMetricsStartTime = (U32Seconds)0; +        } +    } +      public: -	LLViewerAssetStats::duration_t		mMetricsStartTime; +    LLViewerAssetStats::duration_t      mMetricsStartTime; +    bool mWithHTTP;  };  ///----------------------------------------------------------------------------  /// LLViewerAssetStorage  ///---------------------------------------------------------------------------- +// Unused?  LLViewerAssetStorage::LLViewerAssetStorage(LLMessageSystem *msg, LLXferManager *xfer, -										   LLVFS *vfs, LLVFS *static_vfs,  -										   const LLHost &upstream_host) -		: LLAssetStorage(msg, xfer, vfs, static_vfs, upstream_host) +                                           LLVFS *vfs, LLVFS *static_vfs,  +                                           const LLHost &upstream_host) +    : LLAssetStorage(msg, xfer, vfs, static_vfs, upstream_host), +      mAssetCoroCount(0), +      mCountRequests(0), +      mCountStarted(0), +      mCountCompleted(0), +      mCountSucceeded(0), +      mTotalBytesFetched(0)  {  }  LLViewerAssetStorage::LLViewerAssetStorage(LLMessageSystem *msg, LLXferManager *xfer, -										   LLVFS *vfs, LLVFS *static_vfs) -		: LLAssetStorage(msg, xfer, vfs, static_vfs) +                                           LLVFS *vfs, LLVFS *static_vfs) +    : LLAssetStorage(msg, xfer, vfs, static_vfs), +      mAssetCoroCount(0), +      mCountRequests(0), +      mCountStarted(0), +      mCountCompleted(0), +      mCountSucceeded(0), +      mTotalBytesFetched(0)  {  }  // virtual   void LLViewerAssetStorage::storeAssetData( -	const LLTransactionID& tid, -	LLAssetType::EType asset_type, -	LLStoreAssetCallback callback, -	void* user_data, -	bool temp_file, -	bool is_priority, -	bool store_local, -	bool user_waiting, -	F64Seconds timeout) +    const LLTransactionID& tid, +    LLAssetType::EType asset_type, +    LLStoreAssetCallback callback, +    void* user_data, +    bool temp_file, +    bool is_priority, +    bool store_local, +    bool user_waiting, +    F64Seconds timeout)  { -	LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); -	LL_DEBUGS("AssetStorage") << "LLViewerAssetStorage::storeAssetData (legacy) " << tid << ":" << LLAssetType::lookup(asset_type) -			<< " ASSET_ID: " << asset_id << LL_ENDL; -	 -	if (mUpstreamHost.isOk()) -	{ -		if (mVFS->getExists(asset_id, asset_type)) -		{ -			// Pack data into this packet if we can fit it. -			U8 buffer[MTUBYTES]; -			buffer[0] = 0; - -			LLVFile vfile(mVFS, asset_id, asset_type, LLVFile::READ); -			S32 asset_size = vfile.getSize(); - -			LLAssetRequest *req = new LLAssetRequest(asset_id, asset_type); -			req->mUpCallback = callback; -			req->mUserData = user_data; - -			if (asset_size < 1) -			{ -				// This can happen if there's a bug in our code or if the VFS has been corrupted. -				LL_WARNS() << "LLViewerAssetStorage::storeAssetData()  Data _should_ already be in the VFS, but it's not! " << asset_id << LL_ENDL; -				// LLAssetStorage metric: Zero size VFS -				reportMetric( asset_id, asset_type, LLStringUtil::null, LLUUID::null, 0, MR_ZERO_SIZE, __FILE__, __LINE__, "The file didn't exist or was zero length (VFS - can't tell which)" ); - -				delete req; -				if (callback) -				{ -					callback(asset_id, user_data, LL_ERR_ASSET_REQUEST_FAILED, LL_EXSTAT_VFS_CORRUPT); -				} -				return; -			} -			else -			{ -				// LLAssetStorage metric: Successful Request -				S32 size = mVFS->getSize(asset_id, asset_type); -				const char *message = "Added to upload queue"; -				reportMetric( asset_id, asset_type, LLStringUtil::null, LLUUID::null, size, MR_OKAY, __FILE__, __LINE__, message ); - -				if(is_priority) -				{ -					mPendingUploads.push_front(req); -				} -				else -				{ -					mPendingUploads.push_back(req); -				} -			} - -			// Read the data from the VFS if it'll fit in this packet. -			if (asset_size + 100 < MTUBYTES) -			{ -				BOOL res = vfile.read(buffer, asset_size);		/* Flawfinder: ignore */ -				S32 bytes_read = res ? vfile.getLastBytesRead() : 0; -				 -				if( bytes_read == asset_size ) -				{ -					req->mDataSentInFirstPacket = TRUE; -					//LL_INFOS() << "LLViewerAssetStorage::createAsset sending data in first packet" << LL_ENDL; -				} -				else -				{ -					LL_WARNS() << "Probable corruption in VFS file, aborting store asset data" << LL_ENDL; - -					// LLAssetStorage metric: VFS corrupt - bogus size -					reportMetric( asset_id, asset_type, LLStringUtil::null, LLUUID::null, asset_size, MR_VFS_CORRUPTION, __FILE__, __LINE__, "VFS corruption" ); - -					if (callback) -					{ -						callback(asset_id, user_data, LL_ERR_ASSET_REQUEST_NONEXISTENT_FILE, LL_EXSTAT_VFS_CORRUPT); -					} -					return; -				} -			} -			else -			{ -				// Too big, do an xfer -				buffer[0] = 0; -				asset_size = 0; -			} -			mMessageSys->newMessageFast(_PREHASH_AssetUploadRequest); -			mMessageSys->nextBlockFast(_PREHASH_AssetBlock); -			mMessageSys->addUUIDFast(_PREHASH_TransactionID, tid); -			mMessageSys->addS8Fast(_PREHASH_Type, (S8)asset_type); -			mMessageSys->addBOOLFast(_PREHASH_Tempfile, temp_file); -			mMessageSys->addBOOLFast(_PREHASH_StoreLocal, store_local); -			mMessageSys->addBinaryDataFast( _PREHASH_AssetData, buffer, asset_size ); -			mMessageSys->sendReliable(mUpstreamHost); -		} -		else -		{ -			LL_WARNS() << "AssetStorage: attempt to upload non-existent vfile " << asset_id << ":" << LLAssetType::lookup(asset_type) << LL_ENDL; -			// LLAssetStorage metric: Zero size VFS -			reportMetric( asset_id, asset_type, LLStringUtil::null, LLUUID::null, 0, MR_ZERO_SIZE, __FILE__, __LINE__, "The file didn't exist or was zero length (VFS - can't tell which)" ); -			if (callback) -			{ -				callback(asset_id, user_data,  LL_ERR_ASSET_REQUEST_NONEXISTENT_FILE, LL_EXSTAT_NONEXISTENT_FILE); -			} -		} -	} -	else -	{ -		LL_WARNS() << "Attempt to move asset store request upstream w/o valid upstream provider" << LL_ENDL; -		// LLAssetStorage metric: Upstream provider dead -		reportMetric( asset_id, asset_type, LLStringUtil::null, LLUUID::null, 0, MR_NO_UPSTREAM, __FILE__, __LINE__, "No upstream provider" ); -		if (callback) -		{ -			callback(asset_id, user_data, LL_ERR_CIRCUIT_GONE, LL_EXSTAT_NO_UPSTREAM); -		} -	} +    LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); +    LL_DEBUGS("AssetStorage") << "LLViewerAssetStorage::storeAssetData (legacy) " << tid << ":" << LLAssetType::lookup(asset_type) +                              << " ASSET_ID: " << asset_id << LL_ENDL; +     +    if (mUpstreamHost.isOk()) +    { +        if (mVFS->getExists(asset_id, asset_type)) +        { +            // Pack data into this packet if we can fit it. +            U8 buffer[MTUBYTES]; +            buffer[0] = 0; + +            LLVFile vfile(mVFS, asset_id, asset_type, LLVFile::READ); +            S32 asset_size = vfile.getSize(); + +            LLAssetRequest *req = new LLAssetRequest(asset_id, asset_type); +            req->mUpCallback = callback; +            req->mUserData = user_data; + +            if (asset_size < 1) +            { +                // This can happen if there's a bug in our code or if the VFS has been corrupted. +                LL_WARNS("AssetStorage") << "LLViewerAssetStorage::storeAssetData()  Data _should_ already be in the VFS, but it's not! " << asset_id << LL_ENDL; +                // LLAssetStorage metric: Zero size VFS +                reportMetric( asset_id, asset_type, LLStringUtil::null, LLUUID::null, 0, MR_ZERO_SIZE, __FILE__, __LINE__, "The file didn't exist or was zero length (VFS - can't tell which)" ); + +                delete req; +                if (callback) +                { +                    callback(asset_id, user_data, LL_ERR_ASSET_REQUEST_FAILED, LL_EXSTAT_VFS_CORRUPT); +                } +                return; +            } +            else +            { +                // LLAssetStorage metric: Successful Request +                S32 size = mVFS->getSize(asset_id, asset_type); +                const char *message = "Added to upload queue"; +                reportMetric( asset_id, asset_type, LLStringUtil::null, LLUUID::null, size, MR_OKAY, __FILE__, __LINE__, message ); + +                if(is_priority) +                { +                    mPendingUploads.push_front(req); +                } +                else +                { +                    mPendingUploads.push_back(req); +                } +            } + +            // Read the data from the VFS if it'll fit in this packet. +            if (asset_size + 100 < MTUBYTES) +            { +                BOOL res = vfile.read(buffer, asset_size);      /* Flawfinder: ignore */ +                S32 bytes_read = res ? vfile.getLastBytesRead() : 0; +                 +                if( bytes_read == asset_size ) +                { +                    req->mDataSentInFirstPacket = TRUE; +                    //LL_INFOS() << "LLViewerAssetStorage::createAsset sending data in first packet" << LL_ENDL; +                } +                else +                { +                    LL_WARNS("AssetStorage") << "Probable corruption in VFS file, aborting store asset data" << LL_ENDL; + +                    // LLAssetStorage metric: VFS corrupt - bogus size +                    reportMetric( asset_id, asset_type, LLStringUtil::null, LLUUID::null, asset_size, MR_VFS_CORRUPTION, __FILE__, __LINE__, "VFS corruption" ); + +                    if (callback) +                    { +                        callback(asset_id, user_data, LL_ERR_ASSET_REQUEST_NONEXISTENT_FILE, LL_EXSTAT_VFS_CORRUPT); +                    } +                    return; +                } +            } +            else +            { +                // Too big, do an xfer +                buffer[0] = 0; +                asset_size = 0; +            } +            mMessageSys->newMessageFast(_PREHASH_AssetUploadRequest); +            mMessageSys->nextBlockFast(_PREHASH_AssetBlock); +            mMessageSys->addUUIDFast(_PREHASH_TransactionID, tid); +            mMessageSys->addS8Fast(_PREHASH_Type, (S8)asset_type); +            mMessageSys->addBOOLFast(_PREHASH_Tempfile, temp_file); +            mMessageSys->addBOOLFast(_PREHASH_StoreLocal, store_local); +            mMessageSys->addBinaryDataFast( _PREHASH_AssetData, buffer, asset_size ); +            mMessageSys->sendReliable(mUpstreamHost); +        } +        else +        { +            LL_WARNS("AssetStorage") << "AssetStorage: attempt to upload non-existent vfile " << asset_id << ":" << LLAssetType::lookup(asset_type) << LL_ENDL; +            // LLAssetStorage metric: Zero size VFS +            reportMetric( asset_id, asset_type, LLStringUtil::null, LLUUID::null, 0, MR_ZERO_SIZE, __FILE__, __LINE__, "The file didn't exist or was zero length (VFS - can't tell which)" ); +            if (callback) +            { +                callback(asset_id, user_data,  LL_ERR_ASSET_REQUEST_NONEXISTENT_FILE, LL_EXSTAT_NONEXISTENT_FILE); +            } +        } +    } +    else +    { +        LL_WARNS("AssetStorage") << "Attempt to move asset store request upstream w/o valid upstream provider" << LL_ENDL; +        // LLAssetStorage metric: Upstream provider dead +        reportMetric( asset_id, asset_type, LLStringUtil::null, LLUUID::null, 0, MR_NO_UPSTREAM, __FILE__, __LINE__, "No upstream provider" ); +        if (callback) +        { +            callback(asset_id, user_data, LL_ERR_CIRCUIT_GONE, LL_EXSTAT_NO_UPSTREAM); +        } +    }  }  void LLViewerAssetStorage::storeAssetData( -	const std::string& filename, -	const LLTransactionID& tid, -	LLAssetType::EType asset_type, -	LLStoreAssetCallback callback, -	void* user_data, -	bool temp_file, -	bool is_priority, -	bool user_waiting, -	F64Seconds timeout) +    const std::string& filename, +    const LLTransactionID& tid, +    LLAssetType::EType asset_type, +    LLStoreAssetCallback callback, +    void* user_data, +    bool temp_file, +    bool is_priority, +    bool user_waiting, +    F64Seconds timeout)  { -	if(filename.empty()) -	{ -		// LLAssetStorage metric: no filename -		reportMetric( LLUUID::null, asset_type, LLStringUtil::null, LLUUID::null, 0, MR_VFS_CORRUPTION, __FILE__, __LINE__, "Filename missing" ); -		LL_ERRS() << "No filename specified" << LL_ENDL; -		return; -	} -	 -	LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); -	LL_DEBUGS("AssetStorage") << "LLViewerAssetStorage::storeAssetData (legacy)" << asset_id << ":" << LLAssetType::lookup(asset_type) << LL_ENDL; - -	LL_DEBUGS("AssetStorage") << "ASSET_ID: " << asset_id << LL_ENDL; - -	S32 size = 0; -	LLFILE* fp = LLFile::fopen(filename, "rb"); -	if (fp) -	{ -		fseek(fp, 0, SEEK_END); -		size = ftell(fp); -		fseek(fp, 0, SEEK_SET); -	} -	if( size ) -	{ -		LLLegacyAssetRequest *legacy = new LLLegacyAssetRequest; -		 -		legacy->mUpCallback = callback; -		legacy->mUserData = user_data; - -		LLVFile file(mVFS, asset_id, asset_type, LLVFile::WRITE); - -		file.setMaxSize(size); - -		const S32 buf_size = 65536; -		U8 copy_buf[buf_size]; -		while ((size = (S32)fread(copy_buf, 1, buf_size, fp))) -		{ -			file.write(copy_buf, size); -		} -		fclose(fp); - -		// if this upload fails, the caller needs to setup a new tempfile for us -		if (temp_file) -		{ -			LLFile::remove(filename); -		} - -		// LLAssetStorage metric: Success not needed; handled in the overloaded method here: - -		LLViewerAssetStorage::storeAssetData( -			tid, -			asset_type, -			legacyStoreDataCallback, -			(void**)legacy, -			temp_file, -			is_priority); -	} -	else // size == 0 (but previous block changes size) -	{ -		if( fp ) -		{ -			// LLAssetStorage metric: Zero size -			reportMetric( asset_id, asset_type, filename, LLUUID::null, 0, MR_ZERO_SIZE, __FILE__, __LINE__, "The file was zero length" ); -		} -		else -		{ -			// LLAssetStorage metric: Missing File -			reportMetric( asset_id, asset_type, filename, LLUUID::null, 0, MR_FILE_NONEXIST, __FILE__, __LINE__, "The file didn't exist" ); -		} -		if (callback) -		{ -			callback(asset_id, user_data, LL_ERR_CANNOT_OPEN_FILE, LL_EXSTAT_BLOCKED_FILE); -		} -	} +    if(filename.empty()) +    { +        // LLAssetStorage metric: no filename +        reportMetric( LLUUID::null, asset_type, LLStringUtil::null, LLUUID::null, 0, MR_VFS_CORRUPTION, __FILE__, __LINE__, "Filename missing" ); +        LL_ERRS() << "No filename specified" << LL_ENDL; +        return; +    } +     +    LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); +    LL_DEBUGS("AssetStorage") << "LLViewerAssetStorage::storeAssetData (legacy)" << asset_id << ":" << LLAssetType::lookup(asset_type) << LL_ENDL; + +    LL_DEBUGS("AssetStorage") << "ASSET_ID: " << asset_id << LL_ENDL; + +    S32 size = 0; +    LLFILE* fp = LLFile::fopen(filename, "rb"); +    if (fp) +    { +        fseek(fp, 0, SEEK_END); +        size = ftell(fp); +        fseek(fp, 0, SEEK_SET); +    } +    if( size ) +    { +        LLLegacyAssetRequest *legacy = new LLLegacyAssetRequest; +         +        legacy->mUpCallback = callback; +        legacy->mUserData = user_data; + +        LLVFile file(mVFS, asset_id, asset_type, LLVFile::WRITE); + +        file.setMaxSize(size); + +        const S32 buf_size = 65536; +        U8 copy_buf[buf_size]; +        while ((size = (S32)fread(copy_buf, 1, buf_size, fp))) +        { +            file.write(copy_buf, size); +        } +        fclose(fp); + +        // if this upload fails, the caller needs to setup a new tempfile for us +        if (temp_file) +        { +            LLFile::remove(filename); +        } + +        // LLAssetStorage metric: Success not needed; handled in the overloaded method here: + +        LLViewerAssetStorage::storeAssetData( +            tid, +            asset_type, +            legacyStoreDataCallback, +            (void**)legacy, +            temp_file, +            is_priority); +    } +    else // size == 0 (but previous block changes size) +    { +        if( fp ) +        { +            // LLAssetStorage metric: Zero size +            reportMetric( asset_id, asset_type, filename, LLUUID::null, 0, MR_ZERO_SIZE, __FILE__, __LINE__, "The file was zero length" ); +        } +        else +        { +            // LLAssetStorage metric: Missing File +            reportMetric( asset_id, asset_type, filename, LLUUID::null, 0, MR_FILE_NONEXIST, __FILE__, __LINE__, "The file didn't exist" ); +        } +        if (callback) +        { +            callback(asset_id, user_data, LL_ERR_CANNOT_OPEN_FILE, LL_EXSTAT_BLOCKED_FILE); +        } +    }  } @@ -334,56 +358,218 @@ void LLViewerAssetStorage::storeAssetData(  // virtual  void LLViewerAssetStorage::_queueDataRequest( -	const LLUUID& uuid, -	LLAssetType::EType atype, -	LLGetAssetCallback callback, -	void *user_data, -	BOOL duplicate, -	BOOL is_priority) +    const LLUUID& uuid, +    LLAssetType::EType atype, +    LLGetAssetCallback callback, +    void *user_data, +    BOOL duplicate, +    BOOL is_priority) +{ +    mCountRequests++; +    queueRequestHttp(uuid, atype, callback, user_data, duplicate, is_priority); +} + +void LLViewerAssetStorage::queueRequestHttp( +    const LLUUID& uuid, +    LLAssetType::EType atype, +    LLGetAssetCallback callback, +    void *user_data, +    BOOL duplicate, +    BOOL is_priority)  { -	if (mUpstreamHost.isOk()) -	{ -		// stash the callback info so we can find it after we get the response message -		LLViewerAssetRequest *req = new LLViewerAssetRequest(uuid, atype); -		req->mDownCallback = callback; -		req->mUserData = user_data; -		req->mIsPriority = is_priority; -		if (!duplicate) -		{ -			// Only collect metrics for non-duplicate requests.  Others  -			// are piggy-backing and will artificially lower averages. -			req->mMetricsStartTime = LLViewerAssetStatsFF::get_timestamp(); -		} -		 -		mPendingDownloads.push_back(req); -	 -		if (!duplicate) -		{ -			// send request message to our upstream data provider -			// Create a new asset transfer. -			LLTransferSourceParamsAsset spa; -			spa.setAsset(uuid, atype); - -			// Set our destination file, and the completion callback. -			LLTransferTargetParamsVFile tpvf; -			tpvf.setAsset(uuid, atype); -			tpvf.setCallback(downloadCompleteCallback, *req); - -			LL_DEBUGS("AssetStorage") << "Starting transfer for " << uuid << LL_ENDL; -			LLTransferTargetChannel *ttcp = gTransferManager.getTargetChannel(mUpstreamHost, LLTCT_ASSET); -			ttcp->requestTransfer(spa, tpvf, 100.f + (is_priority ? 1.f : 0.f)); - -			LLViewerAssetStatsFF::record_enqueue(atype, false, false); -		} -	} -	else -	{ -		// uh-oh, we shouldn't have gotten here -		LL_WARNS() << "Attempt to move asset data request upstream w/o valid upstream provider" << LL_ENDL; -		if (callback) -		{ -			callback(mVFS, uuid, atype, user_data, LL_ERR_CIRCUIT_GONE, LL_EXSTAT_NO_UPSTREAM); -		} -	} +    LL_DEBUGS("ViewerAsset") << "Request asset via HTTP " << uuid << " type " << LLAssetType::lookup(atype) << LL_ENDL; + +    bool with_http = true; +    LLViewerAssetRequest *req = new LLViewerAssetRequest(uuid, atype, with_http); +    req->mDownCallback = callback; +    req->mUserData = user_data; +    req->mIsPriority = is_priority; +    if (!duplicate) +    { +        // Only collect metrics for non-duplicate requests.  Others  +        // are piggy-backing and will artificially lower averages. +        req->mMetricsStartTime = LLViewerAssetStatsFF::get_timestamp(); +    } +    mPendingDownloads.push_back(req); + +    // This is the same as the current UDP logic - don't re-request a duplicate. +    if (!duplicate) +    { +        bool with_http = true; +        bool is_temp = false; +        LLViewerAssetStatsFF::record_enqueue(atype, with_http, is_temp); + +        LLCoprocedureManager::instance().enqueueCoprocedure("AssetStorage","LLViewerAssetStorage::assetRequestCoro", +            boost::bind(&LLViewerAssetStorage::assetRequestCoro, this, req, uuid, atype, callback, user_data)); +    }  } +void LLViewerAssetStorage::capsRecvForRegion(const LLUUID& region_id, std::string pumpname) +{ +    LLViewerRegion *regionp = LLWorld::instance().getRegionFromID(region_id); +    if (!regionp) +    { +        LL_WARNS("ViewerAsset") << "region not found for region_id " << region_id << LL_ENDL; +    } +    else +    { +        mViewerAssetUrl = regionp->getViewerAssetUrl(); +    } + +    LLEventPumps::instance().obtain(pumpname).post(LLSD()); +} + +struct LLScopedIncrement +{ +    LLScopedIncrement(S32& counter): +        mCounter(counter) +    { +        ++mCounter; +    } +    ~LLScopedIncrement() +    { +        --mCounter; +    } +    S32& mCounter; +}; + +void LLViewerAssetStorage::assetRequestCoro( +    LLViewerAssetRequest *req, +    const LLUUID uuid, +    LLAssetType::EType atype, +    LLGetAssetCallback callback, +    void *user_data) +{ +    LLScopedIncrement coro_count_boost(mAssetCoroCount); +    mCountStarted++; +     +    S32 result_code = LL_ERR_NOERR; +    LLExtStat ext_status = LL_EXSTAT_NONE; + +    if (!gAgent.getRegion()) +    { +        LL_WARNS_ONCE("ViewerAsset") << "Asset request fails: no region set" << LL_ENDL; +        result_code = LL_ERR_ASSET_REQUEST_FAILED; +        ext_status = LL_EXSTAT_NONE; +        removeAndCallbackPendingDownloads(uuid, atype, uuid, atype, result_code, ext_status); +		return; +    } +    else if (!gAgent.getRegion()->capabilitiesReceived()) +    { +        LL_WARNS_ONCE("ViewerAsset") << "Waiting for capabilities" << LL_ENDL; + +        LLEventStream capsRecv("waitForCaps", true); + +        gAgent.getRegion()->setCapabilitiesReceivedCallback( +            boost::bind(&LLViewerAssetStorage::capsRecvForRegion, this, _1, capsRecv.getName())); +         +        llcoro::suspendUntilEventOn(capsRecv); +        LL_WARNS_ONCE("ViewerAsset") << "capsRecv got event" << LL_ENDL; +        LL_WARNS_ONCE("ViewerAsset") << "region " << gAgent.getRegion() << " mViewerAssetUrl " << mViewerAssetUrl << LL_ENDL; +    } +    if (mViewerAssetUrl.empty() && gAgent.getRegion()) +    { +        mViewerAssetUrl = gAgent.getRegion()->getViewerAssetUrl(); +    } +    if (mViewerAssetUrl.empty()) +    { +        LL_WARNS_ONCE("ViewerAsset") << "asset request fails: caps received but no viewer asset cap found" << LL_ENDL; +        result_code = LL_ERR_ASSET_REQUEST_FAILED; +        ext_status = LL_EXSTAT_NONE; +        removeAndCallbackPendingDownloads(uuid, atype, uuid, atype, result_code, ext_status); +		return; +    } +    std::string url = getAssetURL(mViewerAssetUrl, uuid,atype); +    LL_DEBUGS("ViewerAsset") << "request url: " << url << LL_ENDL; + +    LLCore::HttpRequest::policy_t httpPolicy(LLAppCoreHttp::AP_TEXTURE); +    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t +        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("assetRequestCoro", httpPolicy)); +    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); +    LLCore::HttpOptions::ptr_t httpOpts = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions); + +    LLSD result = httpAdapter->getRawAndSuspend(httpRequest, url, httpOpts); + +    if (LLApp::isQuitting()) +    { +        // Bail out if result arrives after shutdown has been started. +        return; +    } + +    mCountCompleted++; +     +    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; +    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); +    if (!status) +    { +        LL_DEBUGS("ViewerAsset") << "request failed, status " << status.toTerseString() << LL_ENDL; +        result_code = LL_ERR_ASSET_REQUEST_FAILED; +        ext_status = LL_EXSTAT_NONE; +    } +    else +    { +        LL_DEBUGS("ViewerAsset") << "request succeeded, url " << url << LL_ENDL; + +        const LLSD::Binary &raw = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_RAW].asBinary(); + +        S32 size = raw.size(); +        if (size > 0) +        { +            mTotalBytesFetched += size; +             +			// This create-then-rename flow is modeled on +			// LLTransferTargetVFile, which is what was used in the UDP +			// case. +            LLUUID temp_id; +            temp_id.generate(); +            LLVFile vf(gAssetStorage->mVFS, temp_id, atype, LLVFile::WRITE); +            vf.setMaxSize(size); +            req->mBytesFetched = size; +            if (!vf.write(raw.data(),size)) +            { +                // TODO asset-http: handle error +                LL_WARNS("ViewerAsset") << "Failure in vf.write()" << LL_ENDL; +                result_code = LL_ERR_ASSET_REQUEST_FAILED; +                ext_status = LL_EXSTAT_VFS_CORRUPT; +            } +            else if (!vf.rename(uuid, atype)) +            { +                LL_WARNS("ViewerAsset") << "rename failed" << LL_ENDL; +                result_code = LL_ERR_ASSET_REQUEST_FAILED; +                ext_status = LL_EXSTAT_VFS_CORRUPT; +            } +            else +            { +                mCountSucceeded++; +            } +        } +        else +        { +            // TODO asset-http: handle invalid size case +			LL_WARNS("ViewerAsset") << "bad size" << LL_ENDL; +            result_code = LL_ERR_ASSET_REQUEST_FAILED; +            ext_status = LL_EXSTAT_NONE; +        } +    } + +    // Clean up pending downloads and trigger callbacks +    removeAndCallbackPendingDownloads(uuid, atype, uuid, atype, result_code, ext_status); +} + +std::string LLViewerAssetStorage::getAssetURL(const std::string& cap_url, const LLUUID& uuid, LLAssetType::EType atype) +{ +    std::string type_name = LLAssetType::lookup(atype); +    std::string url = cap_url + "/?" + type_name + "_id=" + uuid.asString(); +    return url; +} + +void LLViewerAssetStorage::logAssetStorageInfo() +{ +    LLMemory::logMemoryInfo(true); +    LL_INFOS("AssetStorage") << "Active coros " << mAssetCoroCount << LL_ENDL; +    LL_INFOS("AssetStorage") << "mPendingDownloads size " << mPendingDownloads.size() << LL_ENDL; +    LL_INFOS("AssetStorage") << "mCountStarted " << mCountStarted << LL_ENDL; +    LL_INFOS("AssetStorage") << "mCountCompleted " << mCountCompleted << LL_ENDL; +    LL_INFOS("AssetStorage") << "mCountSucceeded " << mCountSucceeded << LL_ENDL; +    LL_INFOS("AssetStorage") << "mTotalBytesFetched " << mTotalBytesFetched << LL_ENDL; +} diff --git a/indra/newview/llviewerassetstorage.h b/indra/newview/llviewerassetstorage.h index 6baec647e6..50131682e7 100644 --- a/indra/newview/llviewerassetstorage.h +++ b/indra/newview/llviewerassetstorage.h @@ -28,10 +28,12 @@  #define LLVIEWERASSETSTORAGE_H  #include "llassetstorage.h" -//#include "curl/curl.h" +#include "llcorehttputil.h"  class LLVFile; +class LLViewerAssetRequest; +  class LLViewerAssetStorage : public LLAssetStorage  {  public: @@ -41,7 +43,6 @@ public:  	LLViewerAssetStorage(LLMessageSystem *msg, LLXferManager *xfer,  				   LLVFS *vfs, LLVFS *static_vfs); -	using LLAssetStorage::storeAssetData;  	virtual void storeAssetData(  		const LLTransactionID& tid,  		LLAssetType::EType atype, @@ -65,8 +66,6 @@ public:  		F64Seconds timeout=LL_ASSET_STORAGE_TIMEOUT);  protected: -	using LLAssetStorage::_queueDataRequest; -  	// virtual  	void _queueDataRequest(const LLUUID& uuid,  						   LLAssetType::EType type, @@ -74,6 +73,33 @@ protected:  						   void *user_data,  						   BOOL duplicate,  						   BOOL is_priority); + +    void queueRequestHttp(const LLUUID& uuid, +                          LLAssetType::EType type, +                          void (*callback) (LLVFS *vfs, const LLUUID&, LLAssetType::EType, void *, S32, LLExtStat), +                          void *user_data, +                          BOOL duplicate, +                          BOOL is_priority); + +    void capsRecvForRegion(const LLUUID& region_id, std::string pumpname); +     +    void assetRequestCoro(LLViewerAssetRequest *req, +                          const LLUUID uuid, +                          LLAssetType::EType atype, +                          void (*callback) (LLVFS *vfs, const LLUUID&, LLAssetType::EType, void *, S32, LLExtStat), +                          void *user_data); + +    std::string getAssetURL(const std::string& cap_url, const LLUUID& uuid, LLAssetType::EType atype); + +    void logAssetStorageInfo(); +     +    std::string mViewerAssetUrl; +    S32 mAssetCoroCount; +    S32 mCountRequests; +    S32 mCountStarted; +    S32 mCountCompleted; +    S32 mCountSucceeded; +    S64 mTotalBytesFetched;  };  #endif diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 960a36a251..e53db403e1 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -106,6 +106,7 @@ const F32 TELEPORT_EXPIRY_PER_ATTACHMENT = 3.f;  U32 gRecentFrameCount = 0; // number of 'recent' frames  LLFrameTimer gRecentFPSTime;  LLFrameTimer gRecentMemoryTime; +LLFrameTimer gAssetStorageLogTime;  // Rendering stuff  void pre_show_depth_buffer(); @@ -226,6 +227,12 @@ void display_stats()  		LLMemory::logMemoryInfo(TRUE) ;  		gRecentMemoryTime.reset();  	} +    F32 asset_storage_log_freq = gSavedSettings.getF32("AssetStorageLogFrequency"); +    if (asset_storage_log_freq > 0.f && gAssetStorageLogTime.getElapsedTimeF32() >= asset_storage_log_freq) +    { +        gAssetStorageLogTime.reset(); +        gAssetStorage->logAssetStorageInfo(); +    }  }  static LLTrace::BlockTimerStatHandle FTM_PICK("Picking"); diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 899ab3a371..eb37613c95 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -521,7 +521,7 @@ LLViewerRegion::LLViewerRegion(const U64 &handle,  	mColoName("unknown"),  	mProductSKU("unknown"),  	mProductName("unknown"), -	mHttpUrl(""), +	mViewerAssetUrl(""),  	mCacheLoaded(FALSE),  	mCacheDirty(FALSE),  	mReleaseNotesRequested(FALSE), @@ -2843,12 +2843,9 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)  	capabilityNames.append("IsExperienceAdmin");  	capabilityNames.append("IsExperienceContributor");  	capabilityNames.append("RegionExperiences"); -	capabilityNames.append("GetMesh"); -	capabilityNames.append("GetMesh2");  	capabilityNames.append("GetMetadata");  	capabilityNames.append("GetObjectCost");  	capabilityNames.append("GetObjectPhysicsData"); -	capabilityNames.append("GetTexture");  	capabilityNames.append("GroupAPIv1");  	capabilityNames.append("GroupMemberData");  	capabilityNames.append("GroupProposalBallot"); @@ -2895,6 +2892,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)  	capabilityNames.append("UpdateScriptAgent");  	capabilityNames.append("UpdateScriptTask");  	capabilityNames.append("UploadBakedTexture"); +	capabilityNames.append("ViewerAsset");   	capabilityNames.append("ViewerMetrics");  	capabilityNames.append("ViewerStartAuction");  	capabilityNames.append("ViewerStats"); @@ -2961,9 +2959,9 @@ void LLViewerRegion::setCapability(const std::string& name, const std::string& u  	else  	{  		mImpl->mCapabilities[name] = url; -		if(name == "GetTexture") +		if(name == "ViewerAsset")  		{ -			mHttpUrl = url ; +			mViewerAssetUrl = url;  		}  	}  } @@ -2974,9 +2972,9 @@ void LLViewerRegion::setCapabilityDebug(const std::string& name, const std::stri  	if ( ! ( name == "EventQueueGet" || name == "UntrustedSimulatorMessage" || name == "SimulatorFeatures" ) )  	{  		mImpl->mSecondCapabilitiesTracker[name] = url; -		if(name == "GetTexture") +		if(name == "ViewerAsset")  		{ -			mHttpUrl = url ; +			mViewerAssetUrl = url;  		}  	}  } diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index a7bb546d2c..61ce5b454d 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -354,7 +354,7 @@ public:  	friend std::ostream& operator<<(std::ostream &s, const LLViewerRegion ®ion);      /// implements LLCapabilityProvider      virtual std::string getDescription() const; -	std::string getHttpUrl() const { return mHttpUrl ;} +    std::string getViewerAssetUrl() const { return mViewerAssetUrl; }  	U32 getNumOfVisibleGroups() const;  	U32 getNumOfActiveCachedObjects() const; @@ -506,7 +506,7 @@ private:  	std::string mColoName;  	std::string mProductSKU;  	std::string mProductName; -	std::string mHttpUrl ; +	std::string mViewerAssetUrl ;  	// Maps local ids to cache entries.  	// Regions can have order 10,000 objects, so assume diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 3968266c27..80c6805ead 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -9387,6 +9387,3 @@ BOOL LLVOAvatar::isTextureVisible(LLAvatarAppearanceDefines::ETextureIndex type,  	// non-self avatars don't have wearables  	return FALSE;  } - - - diff --git a/indra/newview/tests/llviewerassetstats_test.cpp b/indra/newview/tests/llviewerassetstats_test.cpp index a08e32cb49..e2e7f09c3b 100644 --- a/indra/newview/tests/llviewerassetstats_test.cpp +++ b/indra/newview/tests/llviewerassetstats_test.cpp @@ -71,25 +71,33 @@ static const char * all_keys[] =  {  	"duration",  	"fps", -	"get_other", +	"get_other_http", +	"get_other_udp",  	"get_texture_temp_http",  	"get_texture_temp_udp",  	"get_texture_non_temp_http",  	"get_texture_non_temp_udp", +	"get_wearable_http",  	"get_wearable_udp", +	"get_sound_http",  	"get_sound_udp", +	"get_gesture_http",  	"get_gesture_udp"  };  static const char * resp_keys[] =   { -	"get_other", +	"get_other_http", +	"get_other_udp",  	"get_texture_temp_http",  	"get_texture_temp_udp",  	"get_texture_non_temp_http",  	"get_texture_non_temp_udp", +	"get_wearable_http",  	"get_wearable_udp", +	"get_sound_http",  	"get_sound_udp", +	"get_gesture_http",  	"get_gesture_udp"  }; @@ -540,11 +548,17 @@ namespace tut  		ensure("sd[get_gesture_udp][enqueued] is 0", (0 == sd["get_gesture_udp"]["enqueued"].asInteger()));  		ensure("sd[get_gesture_udp][dequeued] is 0", (0 == sd["get_gesture_udp"]["dequeued"].asInteger())); -		ensure("sd[get_wearable_udp][enqueued] is 4", (4 == sd["get_wearable_udp"]["enqueued"].asInteger())); -		ensure("sd[get_wearable_udp][dequeued] is 4", (4 == sd["get_wearable_udp"]["dequeued"].asInteger())); +		ensure("sd[get_wearable_http][enqueued] is 2", (2 == sd["get_wearable_http"]["enqueued"].asInteger())); +		ensure("sd[get_wearable_http][dequeued] is 2", (2 == sd["get_wearable_http"]["dequeued"].asInteger())); -		ensure("sd[get_other][enqueued] is 4", (4 == sd["get_other"]["enqueued"].asInteger())); -		ensure("sd[get_other][dequeued] is 0", (0 == sd["get_other"]["dequeued"].asInteger())); +		ensure("sd[get_wearable_udp][enqueued] is 2", (2 == sd["get_wearable_udp"]["enqueued"].asInteger())); +		ensure("sd[get_wearable_udp][dequeued] is 2", (2 == sd["get_wearable_udp"]["dequeued"].asInteger())); + +		ensure("sd[get_other_http][enqueued] is 2", (2 == sd["get_other_http"]["enqueued"].asInteger())); +		ensure("sd[get_other_http][dequeued] is 0", (0 == sd["get_other_http"]["dequeued"].asInteger())); + +		ensure("sd[get_other_udp][enqueued] is 2", (2 == sd["get_other_udp"]["enqueued"].asInteger())); +		ensure("sd[get_other_udp][dequeued] is 0", (0 == sd["get_other_udp"]["dequeued"].asInteger()));  		// Reset and check zeros...  		// Reset leaves current region in place  | 
