diff options
| author | Oz Linden <oz@lindenlab.com> | 2012-05-22 06:03:42 -0400 | 
|---|---|---|
| committer | Oz Linden <oz@lindenlab.com> | 2012-05-22 06:03:42 -0400 | 
| commit | 7637acf76e6a1170508e8bddd381c426d219b1ee (patch) | |
| tree | c48b5ea58fda587a103278860b943122f6ce8fae /indra/newview | |
| parent | 6525fc4a4fc09e02c4fa709e0cbba4aa8d7d25ae (diff) | |
| parent | c4dfdcb338aaeeb4e3adc4e1aef4f5b190ef5c57 (diff) | |
merge changes for DRTVWR-149
Diffstat (limited to 'indra/newview')
50 files changed, 3379 insertions, 962 deletions
| diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 9aaefa9c6a..4e8b6fc39d 100644..100755 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -237,6 +237,7 @@ set(viewer_SOURCE_FILES      llfloatertelehub.cpp      llfloatertestinspectors.cpp      llfloatertestlistview.cpp +    llfloatertexturefetchdebugger.cpp      llfloatertools.cpp      llfloatertopobjects.cpp      llfloatertos.cpp @@ -793,6 +794,7 @@ set(viewer_HEADER_FILES      llfloatertelehub.h      llfloatertestinspectors.h      llfloatertestlistview.h +    llfloatertexturefetchdebugger.h      llfloatertools.h      llfloatertopobjects.h      llfloatertos.h diff --git a/indra/newview/app_settings/logcontrol.xml b/indra/newview/app_settings/logcontrol.xml index a76eb3cd37..64122bbb6c 100644..100755 --- a/indra/newview/app_settings/logcontrol.xml +++ b/indra/newview/app_settings/logcontrol.xml @@ -20,7 +20,7 @@  					<key>tags</key>  						<array>  							<string>AppInit</string> -              <string>Capabilities</string> +							<string>Capabilities</string>  							<string>SystemInfo</string>  							<string>TextureCache</string>  							<string>AppCache</string> @@ -42,8 +42,10 @@  						</array>  					<key>tags</key>  						<array> -							<!-- sample entry for debugging a specific item	--> -<!--						<string>Voice</string>		--> +						<!-- sample entry for debugging specific items	 +						     <string>Avatar</string> +						     <string>Voice</string>		 +						-->  						</array>  				</map>  			</array> diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 05c05b9393..d5c43a67f2 100644..100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -335,17 +335,6 @@        <key>Value</key>        <integer>1</integer>      </map> -  <key>AuditTexture</key> -  <map> -    <key>Comment</key> -    <string>Enable texture auditting.</string> -    <key>Persist</key> -    <integer>1</integer> -    <key>Type</key> -    <string>Boolean</string> -    <key>Value</key> -    <integer>0</integer> -  </map>    <key>AutoAcceptNewInventory</key>      <map>        <key>Comment</key> @@ -1936,7 +1925,7 @@      <key>Type</key>      <string>Boolean</string>      <key>Value</key> -    <integer>0</integer> +    <integer>1</integer>    </map>      <key>DebugBeaconLineWidth</key>      <map> @@ -7183,6 +7172,17 @@        <key>Value</key>        <integer>-1</integer>      </map> +    <key>QAModeMetrics</key> +    <map> +      <key>Comment</key> +      <string>"Enables QA features (logging, faster cycling) for metrics collector"</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map>      <key>QuietSnapshotsToDisk</key>      <map>        <key>Comment</key> @@ -10664,6 +10664,39 @@        <key>Value</key>        <real>20.0</real>      </map> +    <key>TexelPixelRatio</key> +    <map> +      <key>Comment</key> +      <string>texel pixel ratio = texel / pixel</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>F32</string> +      <key>Value</key> +      <real>1.0</real> +    </map> +    <key>TextureCameraMotionThreshold</key> +    <map> +      <key>Comment</key> +      <string>If the overall motion is lower than this value, textures will be loaded faster</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>F32</string> +      <key>Value</key> +      <real>0.2</real> +    </map> +    <key>TextureCameraMotionBoost</key> +    <map> +      <key>Comment</key> +      <string>Progressive discard level decrement when the camera is still</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>S32</string> +      <key>Value</key> +      <integer>3</integer> +    </map>      <key>TextureDecodeDisabled</key>      <map>        <key>Comment</key> @@ -10697,6 +10730,17 @@        <key>Value</key>        <integer>0</integer>      </map> +    <key>TextureFetchDebuggerEnabled</key> +    <map> +      <key>Comment</key> +      <string>Enable the texture fetching debugger if set</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map>      <key>TextureLoadFullRes</key>      <map>        <key>Comment</key> @@ -10719,6 +10763,17 @@        <key>Value</key>        <integer>0</integer>      </map> +    <key>TextureNewByteRange</key> +    <map> +      <key>Comment</key> +      <string>Use the new more accurate byte range computation for j2c discard levels</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>1</integer> +    </map>      <key>TexturePickerShowFolders</key>      <map>        <key>Comment</key> @@ -10741,6 +10796,17 @@        <key>Value</key>        <integer>2</integer>      </map> +    <key>TextureReverseByteRange</key> +    <map> +      <key>Comment</key> +      <string>Minimal percent of the optimal byte range allowed to render a given discard level</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>S32</string> +      <key>Value</key> +      <integer>50</integer> +    </map>      <key>ThrottleBandwidthKBPS</key>      <map>        <key>Comment</key> diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 3870a3be2e..3367604753 100755 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -3253,6 +3253,10 @@ void LLAgent::processControlRelease(LLMessageSystem *msg, void **)  void LLAgent::processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void **user_data)  {  	gAgentQueryManager.mNumPendingQueries--; +	if (gAgentQueryManager.mNumPendingQueries == 0) +	{ +		selfStopPhase("fetch_texture_cache_entries"); +	}  	if (!isAgentAvatarValid() || gAgentAvatarp->isDead())  	{ @@ -3302,13 +3306,12 @@ void LLAgent::processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void *  					else  					{  						// no cache of this bake. request upload. -						gAgentAvatarp->requestLayerSetUpload(baked_index); +						gAgentAvatarp->invalidateComposite(gAgentAvatarp->getLayerSet(baked_index),TRUE);  					}  				}  			}  		}  	} -  	llinfos << "Received cached texture response for " << num_results << " textures." << llendl;  	gAgentAvatarp->outputRezTiming("Fetched agent wearables textures from cache. Will now load them"); @@ -3775,7 +3778,15 @@ void LLAgent::sendAgentSetAppearance()  		return;  	} -	llinfos << "TAT: Sent AgentSetAppearance: " << gAgentAvatarp->getBakedStatusForPrintout() << llendl; +	if (!gAgentWearables.changeInProgress()) +	{ +		// Change is fully resolved, can close some open phases. +		gAgentAvatarp->getPhases().stopPhase("process_initial_wearables_update"); +		gAgentAvatarp->getPhases().stopPhase("wear_inventory_category"); +	} +	 +	gAgentAvatarp->sendAppearanceChangeMetrics(); +	LL_INFOS("Avatar") << gAgentAvatarp->avString() << "TAT: Sent AgentSetAppearance: " << gAgentAvatarp->getBakedStatusForPrintout() << LL_ENDL;  	//dumpAvatarTEs( "sendAgentSetAppearance()" );  	LLMessageSystem* msg = gMessageSystem; @@ -3822,14 +3833,14 @@ void LLAgent::sendAgentSetAppearance()  	// only update cache entries if we have all our baked textures  	if (textures_current)  	{ -		llinfos << "TAT: Sending cached texture data" << llendl; +		LL_INFOS("Avatar") << gAgentAvatarp->avString() << "TAT: Sending cached texture data" << LL_ENDL;  		for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)  		{  			BOOL generate_valid_hash = TRUE;  			if (isAgentAvatarValid() && !gAgentAvatarp->isBakedTextureFinal((LLVOAvatarDefines::EBakedTextureIndex)baked_index))  			{  				generate_valid_hash = FALSE; -				llinfos << "Not caching baked texture upload for " << (U32)baked_index << " due to being uploaded at low resolution." << llendl; +				LL_DEBUGS("Avatar") << gAgentAvatarp->avString() << "Not caching baked texture upload for " << (U32)baked_index << " due to being uploaded at low resolution." << LL_ENDL;  			}  			const LLUUID hash = gAgentWearables.computeBakedTextureHash((EBakedTextureIndex) baked_index, generate_valid_hash); diff --git a/indra/newview/llagentlistener.cpp b/indra/newview/llagentlistener.cpp index a8d2222c03..a4c0b056ac 100644 --- a/indra/newview/llagentlistener.cpp +++ b/indra/newview/llagentlistener.cpp @@ -126,6 +126,17 @@ LLAgentListener::LLAgentListener(LLAgent &agent)  		"[\"obj_uuid\"]: id of object to look at, use this or [\"position\"] to indicate the target\n"  		"[\"position\"]: region position {x, y, z} where to find closest object or avatar to look at",          &LLAgentListener::lookAt); +    add("getGroups", +        "Send information about the agent's groups on [\"reply\"]:\n" +        "[\"groups\"]: array of group information\n" +        "[\"id\"]: group id\n" +        "[\"name\"]: group name\n" +        "[\"insignia\"]: group insignia texture id\n" +        "[\"notices\"]: boolean indicating if this user accepts notices from this group\n" +        "[\"display\"]: boolean indicating if this group is listed in the user's profile\n" +        "[\"contrib\"]: user's land contribution to this group\n", +        &LLAgentListener::getGroups, +        LLSDMap("reply", LLSD()));  }  void LLAgentListener::requestTeleport(LLSD const & event_data) const diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index dd02a74a38..e441f21f90 100644..100755 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -955,6 +955,8 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs  	if (isAgentAvatarValid())  	{ +		//gAgentAvatarp->clearPhases(); // reset phase timers for outfit loading. +		gAgentAvatarp->getPhases().startPhase("process_initial_wearables_update");  		gAgentAvatarp->outputRezTiming("Received initial wearables update");  	} @@ -1448,7 +1450,16 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it  	{  		gAgentAvatarp->setCompositeUpdatesEnabled(TRUE);  		gAgentAvatarp->updateVisualParams(); -		gAgentAvatarp->invalidateAll(); + +		// If we have not yet declouded, we may want to use +		// baked texture UUIDs sent from the first objectUpdate message +		// don't overwrite these. If we have already declouded, we've saved +		// these ids as the last known good textures and can invalidate without +		// re-clouding. +		if (!gAgentAvatarp->getIsCloud()) +		{ +			gAgentAvatarp->invalidateAll(); +		}  	}  	// Start rendering & update the server @@ -1630,10 +1641,11 @@ void LLAgentWearables::queryWearableCache()  	{  		if (isAgentAvatarValid())  		{ +			selfStartPhase("fetch_texture_cache_entries");  			gAgentAvatarp->outputRezTiming("Fetching textures from cache");  		} -		llinfos << "Requesting texture cache entry for " << num_queries << " baked textures" << llendl; +		LL_INFOS("Avatar") << gAgentAvatarp->avString() << "Requesting texture cache entry for " << num_queries << " baked textures" << LL_ENDL;  		gMessageSystem->sendReliable(gAgent.getRegion()->getHost());  		gAgentQueryManager.mNumPendingQueries++;  		gAgentQueryManager.mWearablesCacheQueryID++; @@ -2081,6 +2093,11 @@ boost::signals2::connection LLAgentWearables::addLoadedCallback(loaded_callback_  	return mLoadedSignal.connect(cb);  } +bool LLAgentWearables::changeInProgress() const +{ +	return mCOFChangeInProgress; +} +  void LLAgentWearables::notifyLoadingStarted()  {  	mCOFChangeInProgress = true; diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h index 01cae3ffd8..5932be21c6 100644..100755 --- a/indra/newview/llagentwearables.h +++ b/indra/newview/llagentwearables.h @@ -233,6 +233,7 @@ public:  	typedef boost::signals2::signal<void()>	loaded_signal_t;  	boost::signals2::connection				addLoadedCallback(loaded_callback_t cb); +	bool									changeInProgress() const;  	void									notifyLoadingStarted();  	void									notifyLoadingFinished(); diff --git a/indra/newview/llagentwearablesfetch.cpp b/indra/newview/llagentwearablesfetch.cpp index 8cba54347e..e2417cdddb 100644 --- a/indra/newview/llagentwearablesfetch.cpp +++ b/indra/newview/llagentwearablesfetch.cpp @@ -89,6 +89,7 @@ LLInitialWearablesFetch::LLInitialWearablesFetch(const LLUUID& cof_id) :  {  	if (isAgentAvatarValid())  	{ +		gAgentAvatarp->getPhases().startPhase("initial_wearables_fetch");  		gAgentAvatarp->outputRezTiming("Initial wearables fetch started");  	}  } @@ -107,6 +108,7 @@ void LLInitialWearablesFetch::done()  	doOnIdleOneTime(boost::bind(&LLInitialWearablesFetch::processContents,this));  	if (isAgentAvatarValid())  	{ +		gAgentAvatarp->getPhases().stopPhase("initial_wearables_fetch");  		gAgentAvatarp->outputRezTiming("Initial wearables fetch done");  	}  } diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 33f5373d7e..faadfb4b87 100644..100755 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -50,6 +50,11 @@  #include "llviewerregion.h"  #include "llwearablelist.h" +std::string self_av_string() +{ +	return gAgentAvatarp->avString(); +} +  // RAII thingy to guarantee that a variable gets reset when the Setter  // goes out of scope.  More general utility would be handy - TODO:  // check boost. @@ -156,6 +161,10 @@ public:  	{  		mCatID = cat_id;  		mAppend = append; + +		LL_INFOS("Avatar") << self_av_string() << "starting" << LL_ENDL; +		 +		selfStartPhase("wear_inventory_category_callback");  	}  	void fire(const LLUUID& item_id)  	{ @@ -167,13 +176,16 @@ public:  		 * after the last item has fired the event and dereferenced it -- if all  		 * the events actually fire!  		 */ +		LL_DEBUGS("Avatar") << self_av_string() << " fired on copied item, id " << item_id << LL_ENDL;  	}  protected:  	~LLWearInventoryCategoryCallback()  	{ -		llinfos << "done all inventory callbacks" << llendl; +		LL_INFOS("Avatar") << self_av_string() << "done all inventory callbacks" << LL_ENDL; +		selfStopPhase("wear_inventory_category_callback"); +  		// Is the destructor called by ordinary dereference, or because the app's shutting down?  		// If the inventory callback manager goes away, we're shutting down, no longer want the callback.  		if( LLInventoryCallbackManager::is_instantiated() ) @@ -182,7 +194,7 @@ protected:  		}  		else  		{ -			llwarns << "Dropping unhandled LLWearInventoryCategoryCallback" << llendl; +			llwarns << self_av_string() << "Dropping unhandled LLWearInventoryCategoryCallback" << llendl;  		}  	} @@ -212,11 +224,14 @@ LLUpdateAppearanceOnDestroy::LLUpdateAppearanceOnDestroy(bool update_base_outfit  	mFireCount(0),  	mUpdateBaseOrder(update_base_outfit_ordering)  { +	selfStartPhase("update_appearance_on_destroy");  }  LLUpdateAppearanceOnDestroy::~LLUpdateAppearanceOnDestroy()  { -	llinfos << "done update appearance on destroy" << llendl; +	LL_INFOS("Avatar") << self_av_string() << "done update appearance on destroy" << LL_ENDL; + +	selfStopPhase("update_appearance_on_destroy");  	if (!LLApp::isExiting())  	{ @@ -229,7 +244,7 @@ void LLUpdateAppearanceOnDestroy::fire(const LLUUID& inv_item)  	LLViewerInventoryItem* item = (LLViewerInventoryItem*)gInventory.getItem(inv_item);  	const std::string item_name = item ? item->getName() : "ITEM NOT FOUND";  #ifndef LL_RELEASE_FOR_DOWNLOAD -	llinfos << "callback fired [ name:" << item_name << " UUID:" << inv_item << " count:" << mFireCount << " ] " << llendl; +	LL_DEBUGS("Avatar") << self_av_string() << "callback fired [ name:" << item_name << " UUID:" << inv_item << " count:" << mFireCount << " ] " << LL_ENDL;  #endif  	mFireCount++;  } @@ -339,11 +354,16 @@ LLWearableHoldingPattern::LLWearableHoldingPattern():  	}  	sActiveHoldingPatterns.insert(this); +	selfStartPhase("holding_pattern");  }  LLWearableHoldingPattern::~LLWearableHoldingPattern()  {  	sActiveHoldingPatterns.erase(this); +	if (isMostRecent()) +	{ +		selfStopPhase("holding_pattern"); +	}  }  bool LLWearableHoldingPattern::isMostRecent() @@ -390,9 +410,10 @@ void LLWearableHoldingPattern::checkMissingWearables()  {  	if (!isMostRecent())  	{ -		llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; +		// runway why don't we actually skip here? +		llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;  	} -		 +  	std::vector<S32> found_by_type(LLWearableType::WT_COUNT,0);  	std::vector<S32> requested_by_type(LLWearableType::WT_COUNT,0);  	for (found_list_t::iterator it = getFoundList().begin(); it != getFoundList().end(); ++it) @@ -408,7 +429,7 @@ void LLWearableHoldingPattern::checkMissingWearables()  	{  		if (requested_by_type[type] > found_by_type[type])  		{ -			llwarns << "got fewer wearables than requested, type " << type << ": requested " << requested_by_type[type] << ", found " << found_by_type[type] << llendl; +			llwarns << self_av_string() << "got fewer wearables than requested, type " << type << ": requested " << requested_by_type[type] << ", found " << found_by_type[type] << llendl;  		}  		if (found_by_type[type] > 0)  			continue; @@ -425,11 +446,13 @@ void LLWearableHoldingPattern::checkMissingWearables()  			mTypesToRecover.insert(type);  			mTypesToLink.insert(type);  			recoverMissingWearable((LLWearableType::EType)type); -			llwarns << "need to replace " << type << llendl;  +			llwarns << self_av_string() << "need to replace " << type << llendl;   		}  	}  	resetTime(60.0F); + +	selfStartPhase("get_missing_wearables");  	if (!pollMissingWearables())  	{  		doOnIdleRepeating(boost::bind(&LLWearableHoldingPattern::pollMissingWearables,this)); @@ -445,13 +468,14 @@ void LLWearableHoldingPattern::onAllComplete()  	if (!isMostRecent())  	{ -		llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; +		// runway need to skip here? +		llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;  	}  	// Activate all gestures in this folder  	if (mGestItems.count() > 0)  	{ -		llinfos << "Activating " << mGestItems.count() << " gestures" << llendl; +		LL_DEBUGS("Avatar") << self_av_string() << "Activating " << mGestItems.count() << " gestures" << LL_ENDL;  		LLGestureMgr::instance().activateGestures(mGestItems); @@ -468,13 +492,13 @@ void LLWearableHoldingPattern::onAllComplete()  	}  	// Update wearables. -	llinfos << "Updating agent wearables with " << mResolved << " wearable items " << llendl; +	LL_INFOS("Avatar") << self_av_string() << "Updating agent wearables with " << mResolved << " wearable items " << LL_ENDL;  	LLAppearanceMgr::instance().updateAgentWearables(this, false);  	// Update attachments to match those requested.  	if (isAgentAvatarValid())  	{ -		llinfos << "Updating " << mObjItems.count() << " attachments" << llendl; +		LL_DEBUGS("Avatar") << self_av_string() << "Updating " << mObjItems.count() << " attachments" << LL_ENDL;  		LLAgentWearables::userUpdateAttachments(mObjItems);  	} @@ -492,9 +516,12 @@ void LLWearableHoldingPattern::onAllComplete()  void LLWearableHoldingPattern::onFetchCompletion()  { +	selfStopPhase("get_wearables"); +		  	if (!isMostRecent())  	{ -		llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; +		// runway skip here? +		llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;  	}  	checkMissingWearables(); @@ -505,7 +532,8 @@ bool LLWearableHoldingPattern::pollFetchCompletion()  {  	if (!isMostRecent())  	{ -		llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; +		// runway skip here? +		llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;  	}  	bool completed = isFetchCompleted(); @@ -514,14 +542,14 @@ bool LLWearableHoldingPattern::pollFetchCompletion()  	if (done)  	{ -		llinfos << "polling, done status: " << completed << " timed out " << timed_out -				<< " elapsed " << mWaitTime.getElapsedTimeF32() << llendl; +		LL_INFOS("Avatar") << self_av_string() << "polling, done status: " << completed << " timed out " << timed_out +				<< " elapsed " << mWaitTime.getElapsedTimeF32() << LL_ENDL;  		mFired = true;  		if (timed_out)  		{ -			llwarns << "Exceeded max wait time for wearables, updating appearance based on what has arrived" << llendl; +			llwarns << self_av_string() << "Exceeded max wait time for wearables, updating appearance based on what has arrived" << llendl;  		}  		onFetchCompletion(); @@ -543,6 +571,7 @@ public:  		if (!mHolder->isMostRecent())  		{  			llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; +			// runway skip here?  		}  		llinfos << "Recovered item link for type " << mType << llendl; @@ -569,12 +598,12 @@ public:  			}  			else  			{ -				llwarns << "inventory item not found for recovered wearable" << llendl; +				llwarns << self_av_string() << "inventory item not found for recovered wearable" << llendl;  			}  		}  		else  		{ -			llwarns << "inventory link not found for recovered wearable" << llendl; +			llwarns << self_av_string() << "inventory link not found for recovered wearable" << llendl;  		}  	}  private: @@ -596,10 +625,11 @@ public:  	{  		if (!mHolder->isMostRecent())  		{ -			llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; +			// runway skip here? +			llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;  		} -		llinfos << "Recovered item for type " << mType << llendl; +		LL_DEBUGS("Avatar") << self_av_string() << "Recovered item for type " << mType << LL_ENDL;  		LLViewerInventoryItem *itemp = gInventory.getItem(item_id);  		mWearable->setItemID(item_id);  		LLPointer<LLInventoryCallback> cb = new RecoveredItemLinkCB(mType,mWearable,mHolder); @@ -626,7 +656,8 @@ void LLWearableHoldingPattern::recoverMissingWearable(LLWearableType::EType type  {  	if (!isMostRecent())  	{ -		llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; +		// runway skip here? +		llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;  	}  		// Try to recover by replacing missing wearable with a new one. @@ -665,7 +696,7 @@ void LLWearableHoldingPattern::clearCOFLinksForMissingWearables()  		if ((data.mWearableType < LLWearableType::WT_COUNT) && (!data.mWearable))  		{  			// Wearable link that was never resolved; remove links to it from COF -			llinfos << "removing link for unresolved item " << data.mItemID.asString() << llendl; +			LL_INFOS("Avatar") << self_av_string() << "removing link for unresolved item " << data.mItemID.asString() << LL_ENDL;  			LLAppearanceMgr::instance().removeCOFItemLinks(data.mItemID,false);  		}  	} @@ -675,7 +706,8 @@ bool LLWearableHoldingPattern::pollMissingWearables()  {  	if (!isMostRecent())  	{ -		llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; +		// runway skip here? +		llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;  	}  	bool timed_out = isTimedOut(); @@ -684,15 +716,17 @@ bool LLWearableHoldingPattern::pollMissingWearables()  	if (!done)  	{ -		llinfos << "polling missing wearables, waiting for items " << mTypesToRecover.size() +		LL_INFOS("Avatar") << self_av_string() << "polling missing wearables, waiting for items " << mTypesToRecover.size()  				<< " links " << mTypesToLink.size()  				<< " wearables, timed out " << timed_out  				<< " elapsed " << mWaitTime.getElapsedTimeF32() -				<< " done " << done << llendl; +				<< " done " << done << LL_ENDL;  	}  	if (done)  	{ +		selfStopPhase("get_missing_wearables"); +  		gAgentAvatarp->debugWearablesLoaded();  		// BAP - if we don't call clearCOFLinksForMissingWearables() @@ -722,14 +756,14 @@ void LLWearableHoldingPattern::handleLateArrivals()  	}  	if (!isMostRecent())  	{ -		llwarns << "Late arrivals not handled - outfit change no longer valid" << llendl; +		llwarns << self_av_string() << "Late arrivals not handled - outfit change no longer valid" << llendl;  	}  	if (!mIsAllComplete)  	{ -		llwarns << "Late arrivals not handled - in middle of missing wearables processing" << llendl; +		llwarns << self_av_string() << "Late arrivals not handled - in middle of missing wearables processing" << llendl;  	} -	llinfos << "Need to handle " << mLateArrivals.size() << " late arriving wearables" << llendl; +	LL_INFOS("Avatar") << self_av_string() << "Need to handle " << mLateArrivals.size() << " late arriving wearables" << LL_ENDL;  	// Update mFoundList using late-arriving wearables.  	std::set<LLWearableType::EType> replaced_types; @@ -805,19 +839,19 @@ void LLWearableHoldingPattern::onWearableAssetFetch(LLWearable *wearable)  {  	if (!isMostRecent())  	{ -		llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; +		llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;  	}  	mResolved += 1;  // just counting callbacks, not successes. -	llinfos << "resolved " << mResolved << "/" << getFoundList().size() << llendl; +	LL_DEBUGS("Avatar") << self_av_string() << "resolved " << mResolved << "/" << getFoundList().size() << LL_ENDL;  	if (!wearable)  	{ -		llwarns << "no wearable found" << llendl; +		llwarns << self_av_string() << "no wearable found" << llendl;  	}  	if (mFired)  	{ -		llwarns << "called after holder fired" << llendl; +		llwarns << self_av_string() << "called after holder fired" << llendl;  		if (wearable)  		{  			mLateArrivals.insert(wearable); @@ -843,7 +877,7 @@ void LLWearableHoldingPattern::onWearableAssetFetch(LLWearable *wearable)  			// Failing this means inventory or asset server are corrupted in a way we don't handle.  			if ((data.mWearableType >= LLWearableType::WT_COUNT) || (wearable->getType() != data.mWearableType))  			{ -				llwarns << "recovered wearable but type invalid. inventory wearable type: " << data.mWearableType << " asset wearable type: " << wearable->getType() << llendl; +				llwarns << self_av_string() << "recovered wearable but type invalid. inventory wearable type: " << data.mWearableType << " asset wearable type: " << wearable->getType() << llendl;  				break;  			} @@ -1391,8 +1425,8 @@ void LLAppearanceMgr::filterWearableItems(  // Create links to all listed items.  void LLAppearanceMgr::linkAll(const LLUUID& cat_uuid, -								  LLInventoryModel::item_array_t& items, -								  LLPointer<LLInventoryCallback> cb) +							  LLInventoryModel::item_array_t& items, +							  LLPointer<LLInventoryCallback> cb)  {  	for (S32 i=0; i<items.count(); i++)  	{ @@ -1408,7 +1442,7 @@ void LLAppearanceMgr::linkAll(const LLUUID& cat_uuid,  		const LLViewerInventoryCategory *cat = gInventory.getCategory(cat_uuid);  		const std::string cat_name = cat ? cat->getName() : "CAT NOT FOUND";  #ifndef LL_RELEASE_FOR_DOWNLOAD -		llinfos << "Linking Item [ name:" << item->getName() << " UUID:" << item->getUUID() << " ] to Category [ name:" << cat_name << " UUID:" << cat_uuid << " ] " << llendl; +		LL_DEBUGS("Avatar") << self_av_string() << "Linking Item [ name:" << item->getName() << " UUID:" << item->getUUID() << " ] to Category [ name:" << cat_name << " UUID:" << cat_uuid << " ] " << LL_ENDL;  #endif  	}  } @@ -1416,7 +1450,7 @@ void LLAppearanceMgr::linkAll(const LLUUID& cat_uuid,  void LLAppearanceMgr::updateCOF(const LLUUID& category, bool append)  {  	LLViewerInventoryCategory *pcat = gInventory.getCategory(category); -	llinfos << "starting, cat " << (pcat ? pcat->getName() : "[UNKNOWN]") << llendl; +	LL_INFOS("Avatar") << self_av_string() << "starting, cat '" << (pcat ? pcat->getName() : "[UNKNOWN]") << "'" << LL_ENDL;  	const LLUUID cof = getCOF(); @@ -1478,26 +1512,26 @@ void LLAppearanceMgr::updateCOF(const LLUUID& category, bool append)  	gInventory.notifyObservers();  	// Create links to new COF contents. -	llinfos << "creating LLUpdateAppearanceOnDestroy" << llendl; +	LL_DEBUGS("Avatar") << self_av_string() << "creating LLUpdateAppearanceOnDestroy" << LL_ENDL;  	LLPointer<LLInventoryCallback> link_waiter = new LLUpdateAppearanceOnDestroy(!append);  #ifndef LL_RELEASE_FOR_DOWNLOAD -	llinfos << "Linking body items" << llendl; +	LL_DEBUGS("Avatar") << self_av_string() << "Linking body items" << LL_ENDL;  #endif  	linkAll(cof, body_items, link_waiter);  #ifndef LL_RELEASE_FOR_DOWNLOAD -	llinfos << "Linking wear items" << llendl; +	LL_DEBUGS("Avatar") << self_av_string() << "Linking wear items" << LL_ENDL;  #endif  	linkAll(cof, wear_items, link_waiter);  #ifndef LL_RELEASE_FOR_DOWNLOAD -	llinfos << "Linking obj items" << llendl; +	LL_DEBUGS("Avatar") << self_av_string() << "Linking obj items" << LL_ENDL;  #endif  	linkAll(cof, obj_items, link_waiter);  #ifndef LL_RELEASE_FOR_DOWNLOAD -	llinfos << "Linking gesture items" << llendl; +	LL_DEBUGS("Avatar") << self_av_string() << "Linking gesture items" << LL_ENDL;  #endif  	linkAll(cof, gest_items, link_waiter); @@ -1506,7 +1540,7 @@ void LLAppearanceMgr::updateCOF(const LLUUID& category, bool append)  	{  		createBaseOutfitLink(category, link_waiter);  	} -	llinfos << "waiting for LLUpdateAppearanceOnDestroy" << llendl; +	LL_DEBUGS("Avatar") << self_av_string() << "waiting for LLUpdateAppearanceOnDestroy" << LL_ENDL;  }  void LLAppearanceMgr::updatePanelOutfitName(const std::string& name) @@ -1663,7 +1697,7 @@ void LLAppearanceMgr::enforceItemRestrictions()  			 ++it)  		{  			LLViewerInventoryItem *item = *it; -			llinfos << "purging duplicate or excess item " << item->getName() << llendl; +			LL_DEBUGS("Avatar") << self_av_string() << "purging duplicate or excess item " << item->getName() << LL_ENDL;  			gInventory.purgeObject(item->getUUID());  		}  		gInventory.notifyObservers(); @@ -1678,9 +1712,11 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool update_base_outfit_ordering)  		return;  	} +	LLVOAvatar::ScopedPhaseSetter(gAgentAvatarp,"update_appearance_from_cof"); +	  	BoolSetter setIsInUpdateAppearanceFromCOF(mIsInUpdateAppearanceFromCOF); -	llinfos << "starting" << llendl; +	LL_INFOS("Avatar") << self_av_string() << "starting" << LL_ENDL;  	//checking integrity of the COF in terms of ordering of wearables,   	//checking and updating links' descriptions of wearables in the COF (before analyzed for "dirty" state) @@ -1772,12 +1808,14 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool update_base_outfit_ordering)  		}  	} +	selfStartPhase("get_wearables"); +  	for (LLWearableHoldingPattern::found_list_t::iterator it = holder->getFoundList().begin();  		 it != holder->getFoundList().end(); ++it)  	{  		LLFoundData& found = *it; -		lldebugs << "waiting for onWearableAssetFetch callback, asset " << found.mAssetID.asString() << llendl; +		lldebugs << self_av_string() << "waiting for onWearableAssetFetch callback, asset " << found.mAssetID.asString() << llendl;  		// Fetch the wearables about to be worn.  		LLWearableList::instance().getAsset(found.mAssetID, @@ -1849,11 +1887,15 @@ void LLAppearanceMgr::wearInventoryCategory(LLInventoryCategory* category, bool  {  	if(!category) return; +	selfClearPhases(); +	selfStartPhase("wear_inventory_category"); +  	gAgentWearables.notifyLoadingStarted(); -	llinfos << "wearInventoryCategory( " << category->getName() -			 << " )" << llendl; +	LL_INFOS("Avatar") << self_av_string() << "wearInventoryCategory( " << category->getName() +			 << " )" << LL_ENDL; +	selfStartPhase("wear_inventory_category_fetch");  	callAfterCategoryFetch(category->getUUID(),boost::bind(&LLAppearanceMgr::wearCategoryFinal,  														   &LLAppearanceMgr::instance(),  														   category->getUUID(), copy, append)); @@ -1861,7 +1903,9 @@ void LLAppearanceMgr::wearInventoryCategory(LLInventoryCategory* category, bool  void LLAppearanceMgr::wearCategoryFinal(LLUUID& cat_id, bool copy_items, bool append)  { -	llinfos << "starting" << llendl; +	LL_INFOS("Avatar") << self_av_string() << "starting" << LL_ENDL; + +	selfStopPhase("wear_inventory_category_fetch");  	// We now have an outfit ready to be copied to agent inventory. Do  	// it, and wear that outfit normally. @@ -1944,8 +1988,8 @@ void LLAppearanceMgr::wearInventoryCategoryOnAvatar( LLInventoryCategory* catego  	// wearables being dirty.  	if(!category) return; -	llinfos << "wearInventoryCategoryOnAvatar( " << category->getName() -			 << " )" << llendl; +	LL_INFOS("Avatar") << self_av_string() << "wearInventoryCategoryOnAvatar '" << category->getName() +			 << "'" << LL_ENDL;  	if (gAgentCamera.cameraCustomizeAvatar())  	{ @@ -1958,7 +2002,7 @@ void LLAppearanceMgr::wearInventoryCategoryOnAvatar( LLInventoryCategory* catego  void LLAppearanceMgr::wearOutfitByName(const std::string& name)  { -	llinfos << "Wearing category " << name << llendl; +	LL_INFOS("Avatar") << self_av_string() << "Wearing category " << name << LL_ENDL;  	//inc_busy_count();  	LLInventoryModel::cat_array_t cat_array; @@ -2281,7 +2325,7 @@ const std::string OTHER_GESTURES_FOLDER = "Other Gestures";  void LLAppearanceMgr::copyLibraryGestures()  { -	llinfos << "Copying library gestures" << llendl; +	LL_INFOS("Avatar") << self_av_string() << "Copying library gestures" << LL_ENDL;  	// Copy gestures  	LLUUID lib_gesture_cat_id = @@ -2337,11 +2381,11 @@ void LLAppearanceMgr::copyLibraryGestures()  		LLUUID cat_id = findDescendentCategoryIDByName(lib_gesture_cat_id,folder_name);  		if (cat_id.isNull())  		{ -			llwarns << "failed to find gesture folder for " << folder_name << llendl; +			llwarns << self_av_string() << "failed to find gesture folder for " << folder_name << llendl;  		}  		else  		{ -			llinfos << "initiating fetch and copy for " << folder_name << " cat_id " << cat_id << llendl; +			LL_DEBUGS("Avatar") << self_av_string() << "initiating fetch and copy for " << folder_name << " cat_id " << cat_id << LL_ENDL;  			callAfterCategoryFetch(cat_id,  								   boost::bind(&LLAppearanceMgr::shallowCopyCategory,  											   &LLAppearanceMgr::instance(), @@ -2355,7 +2399,7 @@ void LLAppearanceMgr::autopopulateOutfits()  	// If this is the very first time the user has logged into viewer2+ (from a legacy viewer, or new account)  	// then auto-populate outfits from the library into the My Outfits folder. -	llinfos << "avatar fully visible" << llendl; +	LL_INFOS("Avatar") << self_av_string() << "avatar fully visible" << LL_ENDL;  	static bool check_populate_my_outfits = true;  	if (check_populate_my_outfits &&  @@ -2731,7 +2775,7 @@ void LLAppearanceMgr::dumpCat(const LLUUID& cat_id, const std::string& msg)  }  void LLAppearanceMgr::dumpItemArray(const LLInventoryModel::item_array_t& items, -										const std::string& msg) +									const std::string& msg)  {  	for (S32 i=0; i<items.count(); i++)  	{ @@ -2742,9 +2786,8 @@ void LLAppearanceMgr::dumpItemArray(const LLInventoryModel::item_array_t& items,  		{  			asset_id = linked_item->getAssetUUID();  		} -		llinfos << msg << " " << i <<" " << (item ? item->getName() : "(nullitem)") << " " << asset_id.asString() << llendl; +		LL_DEBUGS("Avatar") << self_av_string() << msg << " " << i <<" " << (item ? item->getName() : "(nullitem)") << " " << asset_id.asString() << LL_ENDL;  	} -	llinfos << llendl;  }  LLAppearanceMgr::LLAppearanceMgr(): diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 1174d108d2..178b96e42e 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -93,6 +93,7 @@  #include "llsecondlifeurls.h"  #include "llupdaterservice.h"  #include "llcallfloater.h" +#include "llfloatertexturefetchdebugger.h"  // Linden library includes  #include "llavatarnamecache.h" @@ -560,7 +561,6 @@ static void settings_modify()  	LLVOSurfacePatch::sLODFactor *= LLVOSurfacePatch::sLODFactor; //square lod factor to get exponential range of [1,4]  	gDebugGL = gSavedSettings.getBOOL("RenderDebugGL") || gDebugSession;  	gDebugPipeline = gSavedSettings.getBOOL("RenderDebugPipeline"); -	gAuditTexture = gSavedSettings.getBOOL("AuditTexture");  }  class LLFastTimerLogThread : public LLThread @@ -731,12 +731,12 @@ bool LLAppViewer::init()  	{  		// Viewer metrics initialization -		static LLCachedControl<bool> metrics_submode(gSavedSettings, -													 "QAModeMetrics", -													 false, -													 "Enables QA features (logging, faster cycling) for metrics collector"); +		//static LLCachedControl<bool> metrics_submode(gSavedSettings, +		//											 "QAModeMetrics", +		//											 false, +		//											 "Enables QA features (logging, faster cycling) for metrics collector"); -		if (metrics_submode) +		if (gSavedSettings.getBOOL("QAModeMetrics"))  		{  			app_metrics_qa_mode = true;  			app_metrics_interval = METRICS_INTERVAL_QA; @@ -1219,7 +1219,7 @@ bool LLAppViewer::mainLoop()  			if(mem_leak_instance)  			{  				mem_leak_instance->idle() ;				 -			}			 +			}							              // canonical per-frame event              mainloop.post(newFrame); @@ -1340,13 +1340,11 @@ bool LLAppViewer::mainLoop()  					ms_sleep(500);  				} -				static const F64 FRAME_SLOW_THRESHOLD = 0.5; //2 frames per seconds				  				const F64 max_idle_time = llmin(.005*10.0*gFrameTimeSeconds, 0.005); // 5 ms a second  				idleTimer.reset(); -				bool is_slow = (frameTimer.getElapsedTimeF64() > FRAME_SLOW_THRESHOLD) ;  				S32 total_work_pending = 0;  				S32 total_io_pending = 0;	 -				while(!is_slow)//do not unpause threads if the frame rates are very low. +				while(1)  				{  					S32 work_pending = 0;  					S32 io_pending = 0; @@ -1406,6 +1404,17 @@ bool LLAppViewer::mainLoop()  					LLLFSThread::sLocal->pause();   				}									 +				//texture fetching debugger +				if(LLTextureFetchDebugger::isEnabled()) +				{ +					LLFloaterTextureFetchDebugger* tex_fetch_debugger_instance = +						LLFloaterReg::findTypedInstance<LLFloaterTextureFetchDebugger>("tex_fetch_debugger"); +					if(tex_fetch_debugger_instance) +					{ +						tex_fetch_debugger_instance->idle() ;				 +					} +				} +  				if ((LLStartUp::getStartupState() >= STATE_CLEANUP) &&  					(frameTimer.getElapsedTimeF64() > FRAME_STALL_THRESHOLD))  				{ @@ -1951,7 +1960,7 @@ bool LLAppViewer::initThreads()  	static const bool enable_threads = true;  #endif -	LLImage::initClass(); +	LLImage::initClass(gSavedSettings.getBOOL("TextureNewByteRange"),gSavedSettings.getS32("TextureReverseByteRange"));  	LLVFSThread::initClass(enable_threads && false);  	LLLFSThread::initClass(enable_threads && false); @@ -4201,6 +4210,7 @@ void LLAppViewer::idle()  			// The 5-second interval is nice for this purpose.  If the object debug  			// bit moves or is disabled, please give this a suitable home.  			LLViewerAssetStatsFF::record_fps_main(gFPSClamped); +			LLViewerAssetStatsFF::record_avatar_stats();  		}  	} @@ -4248,7 +4258,8 @@ void LLAppViewer::idle()  		static LLTimer report_interval;  		// *TODO:  Add configuration controls for this -		if (report_interval.getElapsedTimeF32() >= app_metrics_interval) +		F32 seconds = report_interval.getElapsedTimeF32(); +		if (seconds >= app_metrics_interval)  		{  			metricsSend(! gDisconnected);  			report_interval.reset(); diff --git a/indra/newview/llavatarpropertiesprocessor.cpp b/indra/newview/llavatarpropertiesprocessor.cpp index b1cd83a1fb..706bc42ea0 100644 --- a/indra/newview/llavatarpropertiesprocessor.cpp +++ b/indra/newview/llavatarpropertiesprocessor.cpp @@ -33,6 +33,7 @@  #include "llagentpicksinfo.h"  #include "lldateutil.h"  #include "llviewergenericmessage.h" +#include "llstartup.h"  // Linden library includes  #include "llavatarconstants.h"	// AVATAR_TRANSACTED, etc. @@ -113,6 +114,14 @@ void LLAvatarPropertiesProcessor::sendGenericRequest(const LLUUID& avatar_id, EA  void LLAvatarPropertiesProcessor::sendAvatarPropertiesRequest(const LLUUID& avatar_id)  { +	// this is the startup state when send_complete_agent_movement() message is sent. +	// Before this, the AvatarPropertiesRequest message   +	// won't work so don't bother trying +	if (LLStartUp::getStartupState() <= STATE_AGENT_SEND) +	{ +		return; +	} +  	if (isPendingRequest(avatar_id, APT_PROPERTIES))  	{  		// waiting for a response, don't re-request diff --git a/indra/newview/lldebugview.cpp b/indra/newview/lldebugview.cpp index 7d3170cb76..29b1d23d7d 100644 --- a/indra/newview/lldebugview.cpp +++ b/indra/newview/lldebugview.cpp @@ -68,8 +68,6 @@ LLDebugView::~LLDebugView()  	gDebugView = NULL;  	gTextureView = NULL;  	gSceneView = NULL; -	gTextureSizeView = NULL; -	gTextureCategoryView = NULL;  }  void LLDebugView::init() @@ -117,35 +115,11 @@ void LLDebugView::init()  	LLTextureView::Params tvp;  	tvp.name("gTextureView");  	tvp.rect(r); -	tvp.follows.flags(FOLLOWS_BOTTOM|FOLLOWS_LEFT); +	tvp.follows.flags(FOLLOWS_TOP|FOLLOWS_LEFT);  	tvp.visible(false);  	gTextureView = LLUICtrlFactory::create<LLTextureView>(tvp);  	addChild(gTextureView);  	//gTextureView->reshape(r.getWidth(), r.getHeight(), TRUE); - - -	if(gAuditTexture) -	{ -		r.set(150, rect.getHeight() - 50, 900 + LLImageGL::sTextureLoadedCounter.size() * 30, 100); -		LLTextureSizeView::Params tsv ; -		tsv.name("gTextureSizeView"); -		tsv.rect(r); -		tsv.follows.flags(FOLLOWS_BOTTOM|FOLLOWS_LEFT); -		tsv.visible(false); -		gTextureSizeView = LLUICtrlFactory::create<LLTextureSizeView>(tsv); -		addChild(gTextureSizeView); -		gTextureSizeView->setType(LLTextureSizeView::TEXTURE_MEM_OVER_SIZE) ; - -		r.set(150, rect.getHeight() - 50, 900 + LLViewerTexture::getTotalNumOfCategories() * 30, 100); -		LLTextureSizeView::Params tcv ; -		tcv.name("gTextureCategoryView"); -		tcv.rect(r); -		tcv.follows.flags(FOLLOWS_BOTTOM|FOLLOWS_LEFT); -		tcv.visible(false); -		gTextureCategoryView = LLUICtrlFactory::create<LLTextureSizeView>(tcv); -		gTextureCategoryView->setType(LLTextureSizeView::TEXTURE_MEM_OVER_CATEGORY); -		addChild(gTextureCategoryView); -	}  }  void LLDebugView::draw() diff --git a/indra/newview/llfloatertexturefetchdebugger.cpp b/indra/newview/llfloatertexturefetchdebugger.cpp new file mode 100644 index 0000000000..2b34b72055 --- /dev/null +++ b/indra/newview/llfloatertexturefetchdebugger.cpp @@ -0,0 +1,390 @@ +/**  + * @file llfloatertexturefetchdebugger.cpp + * @brief LLFloaterTextureFetchDebugger class definition + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfloatertexturefetchdebugger.h" + +#include "lluictrlfactory.h" +#include "llbutton.h" +#include "llspinctrl.h" +#include "llresmgr.h" + +#include "llmath.h" +#include "llviewerwindow.h" +#include "llappviewer.h" +#include "lltexturefetch.h" +#include "llviewercontrol.h" + +LLFloaterTextureFetchDebugger::LLFloaterTextureFetchDebugger(const LLSD& key) +	: LLFloater(key), +	mDebugger(NULL) +{ +	setTitle("Texture Fetching Debugger Floater"); +	 +	mCommitCallbackRegistrar.add("TexFetchDebugger.ChangeTexelPixelRatio",	boost::bind(&LLFloaterTextureFetchDebugger::onChangeTexelPixelRatio, this)); + +	mCommitCallbackRegistrar.add("TexFetchDebugger.Start",	boost::bind(&LLFloaterTextureFetchDebugger::onClickStart, this)); +	mCommitCallbackRegistrar.add("TexFetchDebugger.Clear",	boost::bind(&LLFloaterTextureFetchDebugger::onClickClear, this)); +	mCommitCallbackRegistrar.add("TexFetchDebugger.Close",	boost::bind(&LLFloaterTextureFetchDebugger::onClickClose, this)); + +	mCommitCallbackRegistrar.add("TexFetchDebugger.CacheRead",	boost::bind(&LLFloaterTextureFetchDebugger::onClickCacheRead, this)); +	mCommitCallbackRegistrar.add("TexFetchDebugger.CacheWrite",	boost::bind(&LLFloaterTextureFetchDebugger::onClickCacheWrite, this)); +	mCommitCallbackRegistrar.add("TexFetchDebugger.HTTPLoad",	boost::bind(&LLFloaterTextureFetchDebugger::onClickHTTPLoad, this)); +	mCommitCallbackRegistrar.add("TexFetchDebugger.Decode",	boost::bind(&LLFloaterTextureFetchDebugger::onClickDecode, this)); +	mCommitCallbackRegistrar.add("TexFetchDebugger.GLTexture",	boost::bind(&LLFloaterTextureFetchDebugger::onClickGLTexture, this)); + +	mCommitCallbackRegistrar.add("TexFetchDebugger.RefetchVisCache",	boost::bind(&LLFloaterTextureFetchDebugger::onClickRefetchVisCache, this)); +	mCommitCallbackRegistrar.add("TexFetchDebugger.RefetchVisHTTP",	boost::bind(&LLFloaterTextureFetchDebugger::onClickRefetchVisHTTP, this)); +} +//---------------------------------------------- + +BOOL LLFloaterTextureFetchDebugger::postBuild(void)  +{	 +	mDebugger = LLAppViewer::getTextureFetch()->getFetchDebugger(); + +	//set states for buttons +	mButtonStateMap["start_btn"] = true; +	mButtonStateMap["close_btn"] = true; +	mButtonStateMap["clear_btn"] = true; +	mButtonStateMap["cacheread_btn"] = false; +	mButtonStateMap["cachewrite_btn"] = false; +	mButtonStateMap["http_btn"] = false; +	mButtonStateMap["decode_btn"] = false; +	mButtonStateMap["gl_btn"] = false; + +	mButtonStateMap["refetchviscache_btn"] = true; +	mButtonStateMap["refetchvishttp_btn"] = true; + +	updateButtons(); + +	getChild<LLUICtrl>("texel_pixel_ratio")->setValue(gSavedSettings.getF32("TexelPixelRatio")); + +	return TRUE ; +} + +LLFloaterTextureFetchDebugger::~LLFloaterTextureFetchDebugger() +{ +	//stop everything +	mDebugger->stopDebug(); +} + +void LLFloaterTextureFetchDebugger::updateButtons() +{ +	for(std::map<std::string, bool>::iterator iter = mButtonStateMap.begin(); iter != mButtonStateMap.end(); ++iter) +	{ +		if(iter->second) +		{ +			childEnable(iter->first.c_str()); +		} +		else +		{ +			childDisable(iter->first.c_str()); +		} +	} +} + +void LLFloaterTextureFetchDebugger::disableButtons() +{ +	childDisable("start_btn"); +	childDisable("clear_btn"); +	childDisable("cacheread_btn"); +	childDisable("cachewrite_btn"); +	childDisable("http_btn"); +	childDisable("decode_btn"); +	childDisable("gl_btn"); +	childDisable("refetchviscache_btn"); +	childDisable("refetchvishttp_btn"); +} + +void LLFloaterTextureFetchDebugger::idle() +{	 +	LLTextureFetchDebugger::e_debug_state state = mDebugger->getState(); +	 +	if(mDebugger->update()) +	{ +		switch(state) +		{ +		case LLTextureFetchDebugger::IDLE: +			break; +		case LLTextureFetchDebugger::READ_CACHE: +			mButtonStateMap["cachewrite_btn"] = true; +			mButtonStateMap["decode_btn"] = true; +			updateButtons(); +			break; +		case LLTextureFetchDebugger::WRITE_CACHE: +			updateButtons(); +			break; +		case LLTextureFetchDebugger::DECODING: +			mButtonStateMap["gl_btn"] = true; +			updateButtons(); +			break; +		case LLTextureFetchDebugger::HTTP_FETCHING: +			mButtonStateMap["cacheread_btn"] = true; +			mButtonStateMap["cachewrite_btn"] = true; +			mButtonStateMap["decode_btn"] = true; +			updateButtons(); +			break; +		case LLTextureFetchDebugger::GL_TEX: +			updateButtons(); +			break; +		case LLTextureFetchDebugger::REFETCH_VIS_CACHE: +			updateButtons(); +		case LLTextureFetchDebugger::REFETCH_VIS_HTTP: +			updateButtons(); +			break; +		default: +			break; +		} +	} +} + +//---------------------- +void LLFloaterTextureFetchDebugger::onChangeTexelPixelRatio() +{ +	gSavedSettings.setF32("TexelPixelRatio", getChild<LLUICtrl>("texel_pixel_ratio")->getValue().asReal()); +} + +void LLFloaterTextureFetchDebugger::onClickStart() +{ +	disableButtons(); + +	mDebugger->startDebug(); + +	mButtonStateMap["start_btn"] = false; +	mButtonStateMap["cacheread_btn"] = true; +	mButtonStateMap["http_btn"] = true; +	updateButtons(); +} + +void LLFloaterTextureFetchDebugger::onClickClose() +{ +	setVisible(FALSE); +	 +	//stop everything +	mDebugger->stopDebug(); +} + +void LLFloaterTextureFetchDebugger::onClickClear() +{ +	mButtonStateMap["start_btn"] = true; +	mButtonStateMap["close_btn"] = true; +	mButtonStateMap["clear_btn"] = true; +	mButtonStateMap["cacheread_btn"] = false; +	mButtonStateMap["cachewrite_btn"] = false; +	mButtonStateMap["http_btn"] = false; +	mButtonStateMap["decode_btn"] = false; +	mButtonStateMap["gl_btn"] = false; +	mButtonStateMap["refetchviscache_btn"] = true; +	mButtonStateMap["refetchvishttp_btn"] = true; +	updateButtons(); + +	//stop everything +	mDebugger->stopDebug(); +	mDebugger->clearHistory(); +} + +void LLFloaterTextureFetchDebugger::onClickCacheRead() +{ +	disableButtons(); + +	mDebugger->debugCacheRead(); +} + +void LLFloaterTextureFetchDebugger::onClickCacheWrite() +{ +	disableButtons(); + +	mDebugger->debugCacheWrite(); +} + +void LLFloaterTextureFetchDebugger::onClickHTTPLoad() +{ +	disableButtons(); + +	mDebugger->debugHTTP(); +} + +void LLFloaterTextureFetchDebugger::onClickDecode() +{ +	disableButtons(); + +	mDebugger->debugDecoder(); +} + +void LLFloaterTextureFetchDebugger::onClickGLTexture() +{ +	disableButtons(); + +	mDebugger->debugGLTextureCreation(); +} + +void LLFloaterTextureFetchDebugger::onClickRefetchVisCache() +{ +	disableButtons(); + +	mDebugger->debugRefetchVisibleFromCache(); +} + +void LLFloaterTextureFetchDebugger::onClickRefetchVisHTTP() +{ +	disableButtons(); + +	mDebugger->debugRefetchVisibleFromHTTP(); +} + +void LLFloaterTextureFetchDebugger::draw() +{ +	//total number of fetched textures +	{ +		getChild<LLUICtrl>("total_num_fetched_label")->setTextArg("[NUM]", llformat("%d", mDebugger->getNumFetchedTextures())); +	} + +	//total number of fetching requests +	{ +		getChild<LLUICtrl>("total_num_fetching_requests_label")->setTextArg("[NUM]", llformat("%d", mDebugger->getNumFetchingRequests())); +	} + +	//total number of cache hits +	{ +		getChild<LLUICtrl>("total_num_cache_hits_label")->setTextArg("[NUM]", llformat("%d", mDebugger->getNumCacheHits())); +	} + +	//total number of visible textures +	{ +		getChild<LLUICtrl>("total_num_visible_tex_label")->setTextArg("[NUM]", llformat("%d", mDebugger->getNumVisibleFetchedTextures())); +	} + +	//total number of visible texture fetching requests +	{ +		getChild<LLUICtrl>("total_num_visible_tex_fetch_req_label")->setTextArg("[NUM]", llformat("%d", mDebugger->getNumVisibleFetchingRequests())); +	} + +	//total number of fetched data +	{ +		getChild<LLUICtrl>("total_fetched_data_label")->setTextArg("[SIZE1]", llformat("%d", mDebugger->getFetchedData() >> 10));		 +		getChild<LLUICtrl>("total_fetched_data_label")->setTextArg("[SIZE2]", llformat("%d", mDebugger->getDecodedData() >> 10)); +		getChild<LLUICtrl>("total_fetched_data_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getFetchedPixels() / 1000000.f)); +	} + +	//total number of visible fetched data +	{		 +		getChild<LLUICtrl>("total_fetched_vis_data_label")->setTextArg("[SIZE1]", llformat("%d", mDebugger->getVisibleFetchedData() >> 10));		 +		getChild<LLUICtrl>("total_fetched_vis_data_label")->setTextArg("[SIZE2]", llformat("%d", mDebugger->getVisibleDecodedData() >> 10)); +	} + +	//total number of rendered fetched data +	{ +		getChild<LLUICtrl>("total_fetched_rendered_data_label")->setTextArg("[SIZE1]", llformat("%d", mDebugger->getRenderedData() >> 10));		 +		getChild<LLUICtrl>("total_fetched_rendered_data_label")->setTextArg("[SIZE2]", llformat("%d", mDebugger->getRenderedDecodedData() >> 10)); +		getChild<LLUICtrl>("total_fetched_rendered_data_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRenderedPixels() / 1000000.f)); +	} + +	//total time on cache readings +	if(mDebugger->getCacheReadTime() < 0.f) +	{ +		getChild<LLUICtrl>("total_time_cache_read_label")->setTextArg("[TIME]", std::string("----")); +	} +	else +	{ +		getChild<LLUICtrl>("total_time_cache_read_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getCacheReadTime())); +	} + +	//total time on cache writings +	if(mDebugger->getCacheWriteTime() < 0.f) +	{ +		getChild<LLUICtrl>("total_time_cache_write_label")->setTextArg("[TIME]", std::string("----")); +	} +	else +	{ +		getChild<LLUICtrl>("total_time_cache_write_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getCacheWriteTime())); +	} + +	//total time on decoding +	if(mDebugger->getDecodeTime() < 0.f) +	{ +		getChild<LLUICtrl>("total_time_decode_label")->setTextArg("[TIME]", std::string("----")); +	} +	else +	{ +		getChild<LLUICtrl>("total_time_decode_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getDecodeTime())); +	} + +	//total time on gl texture creation +	if(mDebugger->getGLCreationTime() < 0.f) +	{ +		getChild<LLUICtrl>("total_time_gl_label")->setTextArg("[TIME]", std::string("----")); +	} +	else +	{ +		getChild<LLUICtrl>("total_time_gl_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getGLCreationTime())); +	} + +	//total time on HTTP fetching +	if(mDebugger->getHTTPTime() < 0.f) +	{ +		getChild<LLUICtrl>("total_time_http_label")->setTextArg("[TIME]", std::string("----")); +	} +	else +	{ +		getChild<LLUICtrl>("total_time_http_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getHTTPTime())); +	} + +	//total time on entire fetching +	{ +		getChild<LLUICtrl>("total_time_fetch_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getTotalFetchingTime())); +	} + +	//total time on refetching visible textures from cache +	if(mDebugger->getRefetchVisCacheTime() < 0.f) +	{ +		getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[TIME]", std::string("----")); +		getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[SIZE]", std::string("----")); +		getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[PIXEL]", std::string("----")); +	} +	else +	{ +		getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getRefetchVisCacheTime())); +		getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedData() >> 10)); +		getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedPixels() / 1000000.f)); +	} + +	//total time on refetching visible textures from http +	if(mDebugger->getRefetchVisHTTPTime() < 0.f) +	{ +		getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[TIME]", std::string("----")); +		getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[SIZE]", std::string("----")); +		getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[PIXEL]", std::string("----")); +	} +	else +	{ +		getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getRefetchVisHTTPTime())); +		getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedData() >> 10)); +		getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedPixels() / 1000000.f)); +	} + +	LLFloater::draw(); +} diff --git a/indra/newview/llfloatertexturefetchdebugger.h b/indra/newview/llfloatertexturefetchdebugger.h new file mode 100644 index 0000000000..33012c6a3d --- /dev/null +++ b/indra/newview/llfloatertexturefetchdebugger.h @@ -0,0 +1,71 @@ +/**  + * @file llfloatertexturefetchdebugger.h + * @brief texture fetching debugger window, debug use only + * + * $LicenseInfo:firstyear=2004&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#ifndef LL_FLOATER_TEXTURE_FETCH_DEBUGGER__H +#define LL_FLOATER_TEXTURE_FETCH_DEBUGGER__H + +#include "llfloater.h" +class LLTextureFetchDebugger; + +class LLFloaterTextureFetchDebugger : public LLFloater +{ +	friend class LLFloaterReg; +public: +	/// initialize all the callbacks for the menu + +	virtual BOOL postBuild() ; +	virtual void draw() ; +	 +	void onChangeTexelPixelRatio(); +	 +	void onClickStart(); +	void onClickClear(); +	void onClickClose(); + +	void onClickCacheRead(); +	void onClickCacheWrite(); +	void onClickHTTPLoad(); +	void onClickDecode(); +	void onClickGLTexture(); + +	void onClickRefetchVisCache(); +	void onClickRefetchVisHTTP(); +public: +	void idle() ; + +private:	 +	LLFloaterTextureFetchDebugger(const LLSD& key); +	virtual ~LLFloaterTextureFetchDebugger(); + +	void updateButtons(); +	void disableButtons(); + +private:	 +	LLTextureFetchDebugger* mDebugger; +	std::map<std::string, bool> mButtonStateMap; +}; + +#endif // LL_FLOATER_TEXTURE_FETCH_DEBUGGER__H diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 85ecb133d0..8092f3bf36 100644..100755 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -1759,6 +1759,7 @@ bool LLInventoryModel::loadSkeleton(  		update_map_t child_counts;  		cat_array_t categories;  		item_array_t items; +		item_array_t possible_broken_links;  		cat_set_t invalid_categories; // Used to mark categories that weren't successfully loaded.  		std::string owner_id_str;  		owner_id.toString(owner_id_str); @@ -1807,7 +1808,7 @@ bool LLInventoryModel::loadSkeleton(  				LLViewerInventoryCategory* tcat = *cit;  				// we can safely ignore anything loaded from file, but -				// not sent down in the skeleton. +				// not sent down in the skeleton. Must have been removed from inventory.  				if(cit == not_cached)  				{  					continue; @@ -1845,6 +1846,8 @@ bool LLInventoryModel::loadSkeleton(  			// Add all the items loaded which are parented to a  			// category with a correctly cached parent  			S32 bad_link_count = 0; +			S32 good_link_count = 0; +			S32 recovered_link_count = 0;  			cat_map_t::iterator unparented = mCategoryMap.end();  			for(item_array_t::const_iterator item_iter = items.begin();  				item_iter != items.end(); @@ -1861,26 +1864,56 @@ bool LLInventoryModel::loadSkeleton(  						// This can happen if the linked object's baseobj is removed from the cache but the linked object is still in the cache.  						if (item->getIsBrokenLink())  						{ -							bad_link_count++; +							//bad_link_count++;  							lldebugs << "Attempted to add cached link item without baseobj present ( name: "  									 << item->getName() << " itemID: " << item->getUUID()  									 << " assetID: " << item->getAssetUUID()  									 << " ).  Ignoring and invalidating " << cat->getName() << " . " << llendl; -							invalid_categories.insert(cit->second); +							possible_broken_links.push_back(item);  							continue;  						} +						else if (item->getIsLinkType()) +						{ +							good_link_count++; +						}  						addItem(item);  						cached_item_count += 1;  						++child_counts[cat->getUUID()];  					}  				}  			} -			if (bad_link_count > 0) +			if (possible_broken_links.size() > 0)  			{ -				llinfos << "Attempted to add " << bad_link_count -						<< " cached link items without baseobj present. " -						<< "The corresponding categories were invalidated." << llendl; +				for(item_array_t::const_iterator item_iter = possible_broken_links.begin(); +				    item_iter != possible_broken_links.end(); +				    ++item_iter) +				{ +					LLViewerInventoryItem *item = (*item_iter).get(); +					const cat_map_t::iterator cit = mCategoryMap.find(item->getParentUUID()); +					const LLViewerInventoryCategory* cat = cit->second.get(); +					if (item->getIsBrokenLink()) +					{ +						bad_link_count++; +						invalid_categories.insert(cit->second); +						//llinfos << "link still broken: " << item->getName() << " in folder " << cat->getName() << llendl; +					} +					else +					{ +						// was marked as broken because of loading order, its actually fine to load +						addItem(item); +						cached_item_count += 1; +						++child_counts[cat->getUUID()]; +						recovered_link_count++; +					} +				} + + 				llinfos << "Attempted to add " << bad_link_count + 						<< " cached link items without baseobj present. " +					    << good_link_count << " link items were successfully added. " +					    << recovered_link_count << " links added in recovery. " + 						<< "The corresponding categories were invalidated." << llendl;  			} +  		}  		else  		{ @@ -2778,7 +2811,7 @@ void LLInventoryModel::processBulkUpdateInventory(LLMessageSystem* msg, void**)  	{  		LLPointer<LLViewerInventoryItem> titem = new LLViewerInventoryItem;  		titem->unpackMessage(msg, _PREHASH_ItemData, i); -		llinfos << "unpaked item '" << titem->getName() << "' in " +		llinfos << "unpacked item '" << titem->getName() << "' in "  				<< titem->getParentUUID() << llendl;  		U32 callback_id;  		msg->getU32Fast(_PREHASH_ItemData, _PREHASH_CallbackID, callback_id); diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp index b4224e30e6..c71ea48193 100644 --- a/indra/newview/llnearbychatbar.cpp +++ b/indra/newview/llnearbychatbar.cpp @@ -34,6 +34,7 @@  #include "llfirstuse.h"  #include "llnearbychatbar.h" +#include "llnearbychatbarlistener.h"  #include "llagent.h"  #include "llgesturemgr.h"  #include "llmultigesture.h" @@ -80,6 +81,7 @@ LLNearbyChatBar::LLNearbyChatBar(const LLSD& key)  	mExpandedHeight(COLLAPSED_HEIGHT + EXPANDED_HEIGHT)  {  	mSpeakerMgr = LLLocalSpeakerMgr::getInstance(); +	mListener.reset(new LLNearbyChatBarListener(*this));  }  //virtual diff --git a/indra/newview/llnearbychatbar.h b/indra/newview/llnearbychatbar.h index 8547cf0bce..aa9c3a6a98 100644 --- a/indra/newview/llnearbychatbar.h +++ b/indra/newview/llnearbychatbar.h @@ -35,6 +35,8 @@  #include "lloutputmonitorctrl.h"  #include "llspeakers.h" +class LLNearbyChatBarListener; +  class LLNearbyChatBar :	public LLFloater  {  public: @@ -92,6 +94,8 @@ protected:  	LLLocalSpeakerMgr*		mSpeakerMgr;  	S32 mExpandedHeight; + +	boost::shared_ptr<LLNearbyChatBarListener> mListener;  };  #endif diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 5d196a465f..b7a5eea27c 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -3647,6 +3647,110 @@ void renderShadowFrusta(LLDrawInfo* params)  	gGL.setSceneBlendType(LLRender::BT_ALPHA);  } +void renderTexelDensity(LLDrawable* drawable) +{ +	if (LLViewerTexture::sDebugTexelsMode == LLViewerTexture::DEBUG_TEXELS_OFF +		|| LLViewerTexture::sCheckerBoardImagep.isNull()) +	{ +		return; +	} + +	LLGLEnable _(GL_BLEND); +	//gObjectFullbrightProgram.bind(); + +	LLMatrix4 checkerboard_matrix; +	S32 discard_level = -1; + +	for (S32 f = 0; f < drawable->getNumFaces(); f++) +	{ +		LLFace* facep = drawable->getFace(f); +		LLVertexBuffer* buffer = facep->getVertexBuffer(); +		LLViewerTexture* texturep = facep->getTexture(); + +		if (texturep == NULL) continue; + +		switch(LLViewerTexture::sDebugTexelsMode) +		{ +		case LLViewerTexture::DEBUG_TEXELS_CURRENT: +			discard_level = -1; +			break; +		case LLViewerTexture::DEBUG_TEXELS_DESIRED: +			{ +				LLViewerFetchedTexture* fetched_texturep = dynamic_cast<LLViewerFetchedTexture*>(texturep); +				discard_level = fetched_texturep ? fetched_texturep->getDesiredDiscardLevel() : -1; +				break; +			} +		default: +		case LLViewerTexture::DEBUG_TEXELS_FULL: +			discard_level = 0; +			break; +		} + +		checkerboard_matrix.initScale(LLVector3(texturep->getWidth(discard_level) / 8, texturep->getHeight(discard_level) / 8, 1.f)); + +		gGL.getTexUnit(0)->bind(LLViewerTexture::sCheckerBoardImagep, TRUE); +		gGL.matrixMode(LLRender::MM_TEXTURE); +		gGL.loadMatrix((GLfloat*)&checkerboard_matrix.mMatrix); + +		if (buffer && (facep->getGeomCount() >= 3)) +		{ +			buffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0); +			U16 start = facep->getGeomStart(); +			U16 end = start + facep->getGeomCount()-1; +			U32 count = facep->getIndicesCount(); +			U16 offset = facep->getIndicesStart(); +			buffer->drawRange(LLRender::TRIANGLES, start, end, count, offset); +		} + +		gGL.loadIdentity(); +		gGL.matrixMode(LLRender::MM_MODELVIEW); +	} + +	//S32 num_textures = llmax(1, (S32)params->mTextureList.size()); + +	//for (S32 i = 0; i < num_textures; i++) +	//{ +	//	LLViewerTexture* texturep = params->mTextureList.empty() ? params->mTexture.get() : params->mTextureList[i].get(); +	//	if (texturep == NULL) continue; + +	//	LLMatrix4 checkboard_matrix; +	//	S32 discard_level = -1; +	//	switch(LLViewerTexture::sDebugTexelsMode) +	//	{ +	//	case LLViewerTexture::DEBUG_TEXELS_CURRENT: +	//		discard_level = -1; +	//		break; +	//	case LLViewerTexture::DEBUG_TEXELS_DESIRED: +	//		{ +	//			LLViewerFetchedTexture* fetched_texturep = dynamic_cast<LLViewerFetchedTexture*>(texturep); +	//			discard_level = fetched_texturep ? fetched_texturep->getDesiredDiscardLevel() : -1; +	//			break; +	//		} +	//	default: +	//	case LLViewerTexture::DEBUG_TEXELS_FULL: +	//		discard_level = 0; +	//		break; +	//	} + +	//	checkboard_matrix.initScale(LLVector3(texturep->getWidth(discard_level) / 8, texturep->getHeight(discard_level) / 8, 1.f)); +	//	gGL.getTexUnit(i)->activate(); + +	//	glMatrixMode(GL_TEXTURE); +	//	glPushMatrix(); +	//	glLoadIdentity(); +	//	//gGL.matrixMode(LLRender::MM_TEXTURE); +	//	glLoadMatrixf((GLfloat*) checkboard_matrix.mMatrix); + +	//	gGL.getTexUnit(i)->bind(LLViewerTexture::sCheckerBoardImagep, TRUE); + +	//	pushVerts(params, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_NORMAL ); + +	//	glPopMatrix(); +	//	glMatrixMode(GL_MODELVIEW); +	//	//gGL.matrixMode(LLRender::MM_MODELVIEW); +	//} +} +  void renderLights(LLDrawable* drawablep)  { @@ -4042,6 +4146,10 @@ public:  			{  				renderComplexityDisplay(drawable);  			} +			if(gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY)) +			{ +				renderTexelDensity(drawable); +			}  			LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(drawable->getVObj().get()); @@ -4291,7 +4399,8 @@ void LLSpatialPartition::renderDebug()  									  LLPipeline::RENDER_DEBUG_AGENT_TARGET |  									  //LLPipeline::RENDER_DEBUG_BUILD_QUEUE |  									  LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA | -									  LLPipeline::RENDER_DEBUG_RENDER_COMPLEXITY))  +									  LLPipeline::RENDER_DEBUG_RENDER_COMPLEXITY | +									  LLPipeline::RENDER_DEBUG_TEXEL_DENSITY))   	{  		return;  	} diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 0ac8c1fe39..6b0fc26db7 100644..100755 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -240,6 +240,7 @@ static bool mLoginStatePastUI = false;  boost::scoped_ptr<LLEventPump> LLStartUp::sStateWatcher(new LLEventStream("StartupState"));  boost::scoped_ptr<LLStartupListener> LLStartUp::sListener(new LLStartupListener()); +boost::scoped_ptr<LLViewerStats::PhaseMap> LLStartUp::sPhases(new LLViewerStats::PhaseMap);  //  // local function declaration @@ -2705,7 +2706,10 @@ void LLStartUp::setStartupState( EStartupState state )  	LL_INFOS("AppInit") << "Startup state changing from " <<    		getStartupStateString() << " to " <<    		startupStateToString(state) << LL_ENDL; + +	sPhases->stopPhase(getStartupStateString());  	gStartupState = state; +	sPhases->startPhase(getStartupStateString());  	postStartupState();  } diff --git a/indra/newview/llstartup.h b/indra/newview/llstartup.h index 0a18ef1b2d..3754aaf966 100644..100755 --- a/indra/newview/llstartup.h +++ b/indra/newview/llstartup.h @@ -34,6 +34,8 @@ class LLEventPump;  class LLStartupListener;  class LLSLURL; +#include "llviewerstats.h" +  // functions  bool idle_startup();  void release_start_screen(); @@ -113,6 +115,7 @@ public:  	static bool startLLProxy(); // Initialize the SOCKS 5 proxy +	static LLViewerStats::PhaseMap& getPhases() { return *sPhases; }  private:  	static LLSLURL sStartSLURL; @@ -120,6 +123,7 @@ private:  	static EStartupState gStartupState; // Do not set directly, use LLStartup::setStartupState  	static boost::scoped_ptr<LLEventPump> sStateWatcher;  	static boost::scoped_ptr<LLStartupListener> sListener; +	static boost::scoped_ptr<LLViewerStats::PhaseMap> sPhases;  }; diff --git a/indra/newview/lltexlayer.cpp b/indra/newview/lltexlayer.cpp index 6f6d5dbf12..467115c928 100644 --- a/indra/newview/lltexlayer.cpp +++ b/indra/newview/lltexlayer.cpp @@ -55,6 +55,9 @@ using namespace LLVOAvatarDefines;  static const S32 BAKE_UPLOAD_ATTEMPTS = 7;  static const F32 BAKE_UPLOAD_RETRY_DELAY = 2.f; // actual delay grows by power of 2 each attempt +// runway consolidate +extern std::string self_av_string(); +  class LLTexLayerInfo  {  	friend class LLTexLayer; @@ -494,7 +497,6 @@ void LLTexLayerSetBuffer::doUpload()  	}  	LLPointer<LLImageJ2C> compressedImage = new LLImageJ2C; -	compressedImage->setRate(0.f);  	const char* comment_text = LINDEN_J2C_COMMENT_PREFIX "RGBHM"; // writes into baked_color_data. 5 channels (rgb, heightfield/alpha, mask)  	if (compressedImage->encode(baked_image, comment_text))  	{ @@ -577,7 +579,7 @@ void LLTexLayerSetBuffer::doUpload()  					args["BODYREGION"] = mTexLayerSet->getBodyRegionName();  					args["RESOLUTION"] = lod_str;  					LLNotificationsUtil::add("AvatarRezSelfBakedTextureUploadNotification",args); -					llinfos << "Uploading [ name: " << mTexLayerSet->getBodyRegionName() << " res:" << lod_str << " time:" << (U32)mNeedsUploadTimer.getElapsedTimeF32() << " ]" << llendl; +					LL_DEBUGS("Avatar") << self_av_string() << "Uploading [ name: " << mTexLayerSet->getBodyRegionName() << " res:" << lod_str << " time:" << (U32)mNeedsUploadTimer.getElapsedTimeF32() << " ]" << LL_ENDL;  				}  			}  			else @@ -631,7 +633,7 @@ void LLTexLayerSetBuffer::doUpdate()  		args["BODYREGION"] = mTexLayerSet->getBodyRegionName();  		args["RESOLUTION"] = lod_str;  		LLNotificationsUtil::add("AvatarRezSelfBakedTextureUpdateNotification",args); -		llinfos << "Locally updating [ name: " << mTexLayerSet->getBodyRegionName() << " res:" << lod_str << " time:" << (U32)mNeedsUpdateTimer.getElapsedTimeF32() << " ]" << llendl; +		LL_DEBUGS("Avatar") << self_av_string() << "Locally updating [ name: " << mTexLayerSet->getBodyRegionName() << " res:" << lod_str << " time:" << (U32)mNeedsUpdateTimer.getElapsedTimeF32() << " ]" << LL_ENDL;  	}  } diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index f18aa8b4e6..e2af497a7d 100644..100755 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -52,12 +52,20 @@  #include "llviewerstats.h"  #include "llviewerassetstats.h"  #include "llworld.h" +#include "llsdutil.h" +#include "llstartup.h" +#include "llviewerstats.h" + +bool LLTextureFetchDebugger::sDebuggerEnabled = false ; +LLStat LLTextureFetch::sCacheHitRate("texture_cache_hits", 128); +LLStat LLTextureFetch::sCacheReadLatency("texture_cache_read_latency", 128);  //////////////////////////////////////////////////////////////////////////////  class LLTextureFetchWorker : public LLWorkerClass  {  	friend class LLTextureFetch;  	friend class HTTPGetResponder; +	friend class LLTextureFetchDebugger;  private:  	class CacheReadResponder : public LLTextureCache::ReadResponder @@ -242,6 +250,8 @@ private:  	S32 mDecodedDiscard;  	LLFrameTimer mRequestedTimer;  	LLFrameTimer mFetchTimer; +	LLTimer			mCacheReadTimer; +	F32				mCacheReadTime;  	LLTextureCache::handle_t mCacheReadHandle;  	LLTextureCache::handle_t mCacheWriteHandle;  	U8* mBuffer; @@ -258,6 +268,7 @@ private:  	BOOL mNeedsAux;  	BOOL mHaveAllData;  	BOOL mInLocalCache; +	BOOL mInCache;  	bool mCanUseHTTP ;  	bool mCanUseNET ; //can get from asset server.  	S32 mHTTPFailCount; @@ -653,6 +664,7 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,  	  mRequestedDiscard(-1),  	  mLoadedDiscard(-1),  	  mDecodedDiscard(-1), +	  mCacheReadTime(0.f),  	  mCacheReadHandle(LLTextureCache::nullHandle()),  	  mCacheWriteHandle(LLTextureCache::nullHandle()),  	  mBuffer(NULL), @@ -669,6 +681,7 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,  	  mNeedsAux(FALSE),  	  mHaveAllData(FALSE),  	  mInLocalCache(FALSE), +	  mInCache(FALSE),  	  mCanUseHTTP(true),  	  mHTTPFailCount(0),  	  mRetryAttempt(0), @@ -838,6 +851,8 @@ void LLTextureFetchWorker::startWork(S32 param)  // Called from LLWorkerThread::processRequest()  bool LLTextureFetchWorker::doWork(S32 param)  { +	static const F32 FETCHING_TIMEOUT = 120.f;//seconds +  	LLMutexLock lock(&mWorkMutex);  	if ((mFetcher->isQuitting() || getFlags(LLWorkerClass::WCF_DELETE_REQUESTED))) @@ -896,6 +911,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  		mCacheReadHandle = LLTextureCache::nullHandle();  		mCacheWriteHandle = LLTextureCache::nullHandle();  		mState = LOAD_FROM_TEXTURE_CACHE; +		mInCache = FALSE;  		mDesiredSize = llmax(mDesiredSize, TEXTURE_CACHE_ENTRY_SIZE); // min desired size is TEXTURE_CACHE_ENTRY_SIZE  		LL_DEBUGS("Texture") << mID << ": Priority: " << llformat("%8.0f",mImagePriority)  							 << " Desired Discard: " << mDesiredDiscard << " Desired Size: " << mDesiredSize << LL_ENDL; @@ -926,6 +942,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  				CacheReadResponder* responder = new CacheReadResponder(mFetcher, mID, mFormattedImage);  				mCacheReadHandle = mFetcher->mTextureCache->readFromCache(filename, mID, cache_priority,  																		  offset, size, responder); +				mCacheReadTimer.reset();  			}  			else if (mUrl.empty())  			{ @@ -934,6 +951,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  				CacheReadResponder* responder = new CacheReadResponder(mFetcher, mID, mFormattedImage);  				mCacheReadHandle = mFetcher->mTextureCache->readFromCache(mID, cache_priority,  																		  offset, size, responder); +				mCacheReadTimer.reset();  			}  			else if(mCanUseHTTP)  			{ @@ -982,11 +1000,12 @@ bool LLTextureFetchWorker::doWork(S32 param)  			llassert_always(mFormattedImage->getDataSize() > 0);  			mLoadedDiscard = mDesiredDiscard;  			mState = DECODE_IMAGE; +			mInCache = TRUE;  			mWriteToCacheState = NOT_WRITE ;  			LL_DEBUGS("Texture") << mID << ": Cached. Bytes: " << mFormattedImage->getDataSize()  								 << " Size: " << llformat("%dx%d",mFormattedImage->getWidth(),mFormattedImage->getHeight())  								 << " Desired Discard: " << mDesiredDiscard << " Desired Size: " << mDesiredSize << LL_ENDL; -			// fall through +			LLTextureFetch::sCacheHitRate.addValue(100.f);  		}  		else  		{ @@ -1002,6 +1021,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  				mState = LOAD_FROM_NETWORK;  			}  			// fall through +			LLTextureFetch::sCacheHitRate.addValue(0.f);  		}  	} @@ -1177,6 +1197,8 @@ bool LLTextureFetchWorker::doWork(S32 param)  			bool res = false;  			if (!mUrl.empty())  			{ +				mRequestedTimer.reset(); +  				mLoaded = FALSE;  				mGetStatus = 0;  				mGetReason.clear(); @@ -1335,6 +1357,13 @@ bool LLTextureFetchWorker::doWork(S32 param)  		}  		else  		{ +			if(FETCHING_TIMEOUT < mRequestedTimer.getElapsedTimeF32()) +			{ +				//timeout, abort. +				mState = DONE; +				return true; +			} +  			setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);  			return false;  		} @@ -1396,6 +1425,11 @@ bool LLTextureFetchWorker::doWork(S32 param)  	{  		if (mDecoded)  		{ +			if(mFetcher->getFetchDebugger() && !mInLocalCache) +			{ +				mFetcher->getFetchDebugger()->addHistoryEntry(this); +			} +  			if (mDecodedDiscard < 0)  			{  				LL_DEBUGS("Texture") << mID << ": Failed to Decode." << LL_ENDL; @@ -1780,6 +1814,7 @@ void LLTextureFetchWorker::callbackDecoded(bool success, LLImageRaw* raw, LLImag  	mDecoded = TRUE;  // 	llinfos << mID << " : DECODE COMPLETE " << llendl;  	setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); +	mCacheReadTime = mCacheReadTimer.getElapsedTimeF32();  }  ////////////////////////////////////////////////////////////////////////////// @@ -1824,11 +1859,18 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image  	  mHTTPTextureBits(0),  	  mTotalHTTPRequests(0),  	  mCurlGetRequest(NULL), -	  mQAMode(qa_mode) +	  mQAMode(qa_mode), +	  mFetchDebugger(NULL)  {  	mCurlPOSTRequestCount = 0;  	mMaxBandwidth = gSavedSettings.getF32("ThrottleBandwidthKBPS");  	mTextureInfo.setUpLogging(gSavedSettings.getBOOL("LogTextureDownloadsToViewerLog"), gSavedSettings.getBOOL("LogTextureDownloadsToSimulator"), gSavedSettings.getU32("TextureLoggingThreshold")); + +	LLTextureFetchDebugger::sDebuggerEnabled = gSavedSettings.getBOOL("TextureFetchDebuggerEnabled"); +	if(LLTextureFetchDebugger::isEnabled()) +	{ +		mFetchDebugger = new LLTextureFetchDebugger(this, cache, imagedecodethread) ; +	}  }  LLTextureFetch::~LLTextureFetch() @@ -1843,11 +1885,17 @@ LLTextureFetch::~LLTextureFetch()  	}  	// ~LLQueuedThread() called here + +	delete mFetchDebugger;  }  bool LLTextureFetch::createRequest(const std::string& url, const LLUUID& id, const LLHost& host, F32 priority,  								   S32 w, S32 h, S32 c, S32 desired_discard, bool needs_aux, bool can_use_http)  { +	if(mFetcherLocked) +	{ +		return false; +	}  	if (mDebugPause)  	{  		return false; @@ -2092,6 +2140,11 @@ bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level,  			discard_level = worker->mDecodedDiscard;  			raw = worker->mRawImage;  			aux = worker->mAuxImage; +			F32 cache_read_time = worker->mCacheReadTime; +			if (cache_read_time != 0.f) +			{ +				sCacheReadLatency.addValue(cache_read_time * 1000.f); +			}  			res = true;  			LL_DEBUGS("Texture") << id << ": Request Finished. State: " << worker->mState << " Discard: " << discard_level << LL_ENDL;  			worker->unlockWorkMutex(); @@ -2222,7 +2275,13 @@ S32 LLTextureFetch::update(F32 max_time_ms)  	if (!mDebugPause)  	{ -		sendRequestListToSimulators(); +		// this is the startup state when send_complete_agent_movement() message is sent. +		// Before this, the RequestImages message sent by sendRequestListToSimulators  +		// won't work so don't bother trying +		if (LLStartUp::getStartupState() > STATE_AGENT_SEND) +		{ +			sendRequestListToSimulators(); +		}  	}  	if (!mThreaded) @@ -2258,6 +2317,11 @@ void LLTextureFetch::startThread()  {  	// Construct mCurlGetRequest from Worker Thread  	mCurlGetRequest = new LLCurlRequest(); +	 +	if(mFetchDebugger) +	{ +		mFetchDebugger->setCurlGetRequest(mCurlGetRequest); +	}  }  // WORKER THREAD @@ -2266,6 +2330,10 @@ void LLTextureFetch::endThread()  	// Destroy mCurlGetRequest from Worker Thread  	delete mCurlGetRequest;  	mCurlGetRequest = NULL; +	if(mFetchDebugger) +	{ +		mFetchDebugger->setCurlGetRequest(NULL); +	}  }  // WORKER THREAD @@ -2803,7 +2871,6 @@ void LLTextureFetch::cmdDoWork()  	}  } -  //////////////////////////////////////////////////////////////////////////////  // Private (anonymous) class methods implementing the command scheme. @@ -2959,7 +3026,7 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher)  	// In QA mode, Metrics submode, log the result for ease of testing  	if (fetcher->isQAMode())  	{ -		LL_INFOS("Textures") << merged_llsd << LL_ENDL; +		LL_INFOS("Textures") << ll_pretty_print_sd(merged_llsd) << LL_ENDL;  	}  	gViewerAssetStatsThread1->reset(); @@ -3007,5 +3074,659 @@ truncate_viewer_metrics(int max_regions, LLSD & metrics)  } // end of anonymous namespace +/////////////////////////////////////////////////////////////////////////////////////////// +//Start LLTextureFetchDebugger +/////////////////////////////////////////////////////////////////////////////////////////// +//--------------------- +class LLDebuggerCacheReadResponder : public LLTextureCache::ReadResponder +{ +public: +	LLDebuggerCacheReadResponder(LLTextureFetchDebugger* debugger, S32 id, LLImageFormatted* image) +		: mDebugger(debugger), mID(id) +	{ +		setImage(image); +	} +	virtual void completed(bool success) +	{ +		mDebugger->callbackCacheRead(mID, success, mFormattedImage, mImageSize, mImageLocal); +	} +private: +	LLTextureFetchDebugger* mDebugger; +	S32 mID; +}; + +class LLDebuggerCacheWriteResponder : public LLTextureCache::WriteResponder +{ +public: +	LLDebuggerCacheWriteResponder(LLTextureFetchDebugger* debugger, S32 id) +		: mDebugger(debugger), mID(id) +	{ +	} +	virtual void completed(bool success) +	{ +		mDebugger->callbackCacheWrite(mID, success); +	} +private: +	LLTextureFetchDebugger* mDebugger; +	S32 mID; +}; + +class LLDebuggerDecodeResponder : public LLImageDecodeThread::Responder +{ +public: +	LLDebuggerDecodeResponder(LLTextureFetchDebugger* debugger, S32 id) +		: mDebugger(debugger), mID(id) +	{ +	} +	virtual void completed(bool success, LLImageRaw* raw, LLImageRaw* aux) +	{ +		mDebugger->callbackDecoded(mID, success, raw, aux); +	} +private: +	LLTextureFetchDebugger* mDebugger; +	S32 mID; +}; + +class LLDebuggerHTTPResponder : public LLCurl::Responder +{ +public: +	LLDebuggerHTTPResponder(LLTextureFetchDebugger* debugger, S32 index) +	: mDebugger(debugger), mIndex(index) +	{ +	} +	virtual void completedRaw(U32 status, const std::string& reason, +							  const LLChannelDescriptors& channels, +							  const LLIOPipe::buffer_ptr_t& buffer) +	{ +		bool success = false; +		bool partial = false; +		if (HTTP_OK <= status &&  status < HTTP_MULTIPLE_CHOICES) +		{ +			success = true; +			if (HTTP_PARTIAL_CONTENT == status) // partial information +			{ +				partial = true; +			} +		} +		if (!success) +		{ +			llinfos << "Fetch Debugger : CURL GET FAILED, index = " << mIndex << ", status:" << status << " reason:" << reason << llendl; +		} +		mDebugger->callbackHTTP(mIndex, channels, buffer, partial, success); +	} +	virtual bool followRedir() +	{ +		return true; +	} +private: +	LLTextureFetchDebugger* mDebugger; +	S32 mIndex; +}; + +LLTextureFetchDebugger::LLTextureFetchDebugger(LLTextureFetch* fetcher, LLTextureCache* cache, LLImageDecodeThread* imagedecodethread) : +	mFetcher(fetcher), +	mTextureCache(cache), +	mImageDecodeThread(imagedecodethread), +	mCurlGetRequest(NULL) +{ +	init(); +} +	 +LLTextureFetchDebugger::~LLTextureFetchDebugger() +{ +	mFetchingHistory.clear(); +	stopDebug(); +} + +void LLTextureFetchDebugger::init() +{ +	mState = IDLE; +	 +	mCacheReadTime = -1.f; +	mCacheWriteTime = -1.f; +	mDecodingTime = -1.f; +	mHTTPTime = -1.f; +	mGLCreationTime = -1.f; +	mTotalFetchingTime = 0.f; +	mRefetchVisCacheTime = -1.f; +	mRefetchVisHTTPTime = -1.f; + +	mNumFetchedTextures = 0; +	mNumCacheHits = 0; +	mNumVisibleFetchedTextures = 0; +	mNumVisibleFetchingRequests = 0; +	mFetchedData = 0; +	mDecodedData = 0; +	mVisibleFetchedData = 0; +	mVisibleDecodedData = 0; +	mRenderedData = 0; +	mRenderedDecodedData = 0; +	mFetchedPixels = 0; +	mRenderedPixels = 0; +	mRefetchedData = 0; +	mRefetchedPixels = 0; + +	mFreezeHistory = FALSE; +} + +void LLTextureFetchDebugger::startDebug() +{ +	//lock the fetcher +	mFetcher->lockFetcher(true); +	mFreezeHistory = TRUE; + +	//clear the current fetching queue +	gTextureList.clearFetchingRequests(); + +	//wait for all works to be done +	while(1) +	{ +		S32 pending = 0; +		pending += LLAppViewer::getTextureCache()->update(1);  +		pending += LLAppViewer::getImageDecodeThread()->update(1);  +		pending += LLAppViewer::getTextureFetch()->update(1);  +		if(!pending) +		{ +			break; +		} +	} + +	//collect statistics +	mTotalFetchingTime = gDebugTimers[0].getElapsedTimeF32() - mTotalFetchingTime; +	 +	std::set<LLUUID> fetched_textures; +	S32 size = mFetchingHistory.size(); +	for(S32 i = 0 ; i < size; i++) +	{ +		bool in_list = true; +		if(fetched_textures.find(mFetchingHistory[i].mID) == fetched_textures.end()) +		{ +			fetched_textures.insert(mFetchingHistory[i].mID); +			in_list = false; +		} +		 +		LLViewerFetchedTexture* tex = LLViewerTextureManager::findFetchedTexture(mFetchingHistory[i].mID); +		if(tex && tex->isJustBound()) //visible +		{ +			if(!in_list) +			{ +				mNumVisibleFetchedTextures++; +			} +			mNumVisibleFetchingRequests++; +	 +			mVisibleFetchedData += mFetchingHistory[i].mFetchedSize; +			mVisibleDecodedData += mFetchingHistory[i].mDecodedSize; +	 +			if(tex->getDiscardLevel() >= mFetchingHistory[i].mDecodedLevel) +			{ +				mRenderedData += mFetchingHistory[i].mFetchedSize; +				mRenderedDecodedData += mFetchingHistory[i].mDecodedSize; +				mRenderedPixels += tex->getWidth() * tex->getHeight(); +			} +		} +	} + +	mNumFetchedTextures = fetched_textures.size(); +} + +void LLTextureFetchDebugger::stopDebug() +{ +	//clear the current debug work +	S32 size = mFetchingHistory.size(); +	switch(mState) +	{ +	case READ_CACHE:		 +		for(S32 i = 0 ; i < size; i++) +		{ +			if (mFetchingHistory[i]. mCacheHandle != LLTextureCache::nullHandle()) +			{ +				mTextureCache->readComplete(mFetchingHistory[i].mCacheHandle, true); +			} +		}	 +		break; +	case WRITE_CACHE: +		for(S32 i = 0 ; i < size; i++) +		{ +			if (mFetchingHistory[i].mCacheHandle != LLTextureCache::nullHandle()) +			{ +				mTextureCache->writeComplete(mFetchingHistory[i].mCacheHandle, true); +			} +		} +		break; +	case DECODING: +		break; +	case HTTP_FETCHING: +		break; +	case GL_TEX: +		break; +	default: +		break; +	} + +	while(1) +	{ +		if(update()) +		{ +			break; +		} +	} + +	//unlock the fetcher +	mFetcher->lockFetcher(false); +	mFreezeHistory = FALSE; +	mTotalFetchingTime = gDebugTimers[0].getElapsedTimeF32(); //reset +} + +//called in the main thread and when the fetching queue is empty +void LLTextureFetchDebugger::clearHistory() +{ +	mFetchingHistory.clear(); +	init(); +} + +void LLTextureFetchDebugger::addHistoryEntry(LLTextureFetchWorker* worker) +{ +	if(mFreezeHistory) +	{ +		mRefetchedPixels += worker->mRawImage->getWidth() * worker->mRawImage->getHeight(); +		mRefetchedData += worker->mFormattedImage->getDataSize(); +		return; +	} + +	if(worker->mInCache) +	{ +		mNumCacheHits++; +	} +	mFetchedData += worker->mFormattedImage->getDataSize(); +	mDecodedData += worker->mRawImage->getDataSize(); +	mFetchedPixels += worker->mRawImage->getWidth() * worker->mRawImage->getHeight(); + +	mFetchingHistory.push_back(FetchEntry(worker->mID, worker->mDesiredSize, worker->mDecodedDiscard, worker->mFormattedImage->getDataSize(), worker->mRawImage->getDataSize())); +	//mFetchingHistory.push_back(FetchEntry(worker->mID, worker->mDesiredSize, worker->mHaveAllData ? 0 : worker->mLoadedDiscard, worker->mFormattedImage->getComponents(), +		//worker->mDecodedDiscard, worker->mFormattedImage->getDataSize(), worker->mRawImage->getDataSize())); +} + +void LLTextureFetchDebugger::lockCache() +{ +} +	 +void LLTextureFetchDebugger::unlockCache() +{ +} +	 +void LLTextureFetchDebugger::debugCacheRead() +{ +	lockCache(); +	llassert_always(mState == IDLE); +	mTimer.reset(); +	mState = READ_CACHE; + +	S32 size = mFetchingHistory.size(); +	for(S32 i = 0 ; i < size ; i++) +	{		 +		mFetchingHistory[i].mFormattedImage = NULL; +		mFetchingHistory[i].mCacheHandle = mTextureCache->readFromCache(mFetchingHistory[i].mID, LLWorkerThread::PRIORITY_NORMAL, 0, mFetchingHistory[i].mFetchedSize,  +			new LLDebuggerCacheReadResponder(this, i, mFetchingHistory[i].mFormattedImage)); +	} +} +	 +void LLTextureFetchDebugger::clearCache() +{ +	S32 size = mFetchingHistory.size(); +	{ +		std::set<LLUUID> deleted_list; +		for(S32 i = 0 ; i < size ; i++) +		{ +			if(deleted_list.find(mFetchingHistory[i].mID) == deleted_list.end()) +			{ +				deleted_list.insert(mFetchingHistory[i].mID); +				mTextureCache->removeFromCache(mFetchingHistory[i].mID); +			} +		} +	} +} + +void LLTextureFetchDebugger::debugCacheWrite() +{ +	//remove from cache +	clearCache(); + +	lockCache(); +	llassert_always(mState == IDLE); +	mTimer.reset(); +	mState = WRITE_CACHE; + +	S32 size = mFetchingHistory.size(); +	for(S32 i = 0 ; i < size ; i++) +	{		 +		if(mFetchingHistory[i].mFormattedImage.notNull()) +		{ +			mFetchingHistory[i].mCacheHandle = mTextureCache->writeToCache(mFetchingHistory[i].mID, LLWorkerThread::PRIORITY_NORMAL,  +				mFetchingHistory[i].mFormattedImage->getData(), mFetchingHistory[i].mFetchedSize, +				mFetchingHistory[i].mDecodedLevel == 0 ? mFetchingHistory[i].mFetchedSize : mFetchingHistory[i].mFetchedSize + 1,  +				new LLDebuggerCacheWriteResponder(this, i));					 +		} +	} +} + +void LLTextureFetchDebugger::lockDecoder() +{ +} +	 +void LLTextureFetchDebugger::unlockDecoder() +{ +} + +void LLTextureFetchDebugger::debugDecoder() +{ +	lockDecoder(); +	llassert_always(mState == IDLE); +	mTimer.reset(); +	mState = DECODING; + +	S32 size = mFetchingHistory.size(); +	for(S32 i = 0 ; i < size ; i++) +	{		 +		if(mFetchingHistory[i].mFormattedImage.isNull()) +		{ +			continue; +		} + +		mImageDecodeThread->decodeImage(mFetchingHistory[i].mFormattedImage, LLWorkerThread::PRIORITY_NORMAL,  +			mFetchingHistory[i].mDecodedLevel, mFetchingHistory[i].mNeedsAux, +			new LLDebuggerDecodeResponder(this, i)); +	} +} + +void LLTextureFetchDebugger::debugHTTP() +{ +	llassert_always(mState == IDLE); + +	LLViewerRegion* region = gAgent.getRegion(); +	if (!region) +	{ +		llinfos << "Fetch Debugger : Current region undefined. Cannot fetch textures through HTTP." << llendl; +		return; +	} +	 +	mHTTPUrl = region->getHttpUrl(); +	if (mHTTPUrl.empty()) +	{ +		llinfos << "Fetch Debugger : Current region URL undefined. Cannot fetch textures through HTTP." << llendl; +		return; +	} +	 +	mTimer.reset(); +	mState = HTTP_FETCHING; +	 +	S32 size = mFetchingHistory.size(); +	for (S32 i = 0 ; i < size ; i++) +	{ +		mFetchingHistory[i].mCurlState = FetchEntry::CURL_NOT_DONE; +		mFetchingHistory[i].mCurlReceivedSize = 0; +		mFetchingHistory[i].mHTTPFailCount = 0; +	} +	mNbCurlRequests = 0; +	mNbCurlCompleted = 0; +	 +	fillCurlQueue(); +} + +S32 LLTextureFetchDebugger::fillCurlQueue() +{ +	if (mNbCurlRequests == 24) +		return mNbCurlRequests; +	 +	S32 size = mFetchingHistory.size(); +	for (S32 i = 0 ; i < size ; i++) +	{		 +		if (mFetchingHistory[i].mCurlState != FetchEntry::CURL_NOT_DONE) +			continue; +		std::string texture_url = mHTTPUrl + "/?texture_id=" + mFetchingHistory[i].mID.asString().c_str(); +		S32 requestedSize = mFetchingHistory[i].mRequestedSize; +		// We request the whole file if the size was not set. +		requestedSize = llmax(0,requestedSize); +		// We request the whole file if the size was set to an absurdly high value (meaning all file) +		requestedSize = (requestedSize == 33554432 ? 0 : requestedSize); +		std::vector<std::string> headers; +		headers.push_back("Accept: image/x-j2c"); +		bool res = mCurlGetRequest->getByteRange(texture_url, headers, 0, requestedSize, new LLDebuggerHTTPResponder(this, i)); +		if (res) +		{ +			mFetchingHistory[i].mCurlState = FetchEntry::CURL_IN_PROGRESS; +			mNbCurlRequests++; +			// Hack +			if (mNbCurlRequests == 24) +				break; +		} +		else  +		{ +			break; +		} +	} +	//llinfos << "Fetch Debugger : Having " << mNbCurlRequests << " requests through the curl thread." << llendl; +	return mNbCurlRequests; +} + +void LLTextureFetchDebugger::debugGLTextureCreation() +{ +	llassert_always(mState == IDLE); +	mState = GL_TEX; +	std::vector<LLViewerFetchedTexture*> tex_list; + +	S32 size = mFetchingHistory.size(); +	for(S32 i = 0 ; i < size ; i++) +	{ +		if(mFetchingHistory[i].mRawImage.notNull()) +		{ +			LLViewerFetchedTexture* tex = gTextureList.findImage(mFetchingHistory[i].mID) ; +			if(tex && !tex->isForSculptOnly()) +			{ +				tex->destroyGLTexture() ; +				tex_list.push_back(tex); +			} +		} +	} + +	mTimer.reset(); +	S32 j = 0 ; +	S32 size1 = tex_list.size(); +	for(S32 i = 0 ; i < size && j < size1; i++) +	{ +		if(mFetchingHistory[i].mRawImage.notNull()) +		{ +			if(mFetchingHistory[i].mID == tex_list[j]->getID()) +			{ +				tex_list[j]->createGLTexture(mFetchingHistory[i].mDecodedLevel, mFetchingHistory[i].mRawImage, 0, TRUE, tex_list[j]->getBoostLevel()); +				j++; +			} +		} +	} + +	mGLCreationTime = mTimer.getElapsedTimeF32() ; +	return; +} + +//clear fetching results of all textures. +void LLTextureFetchDebugger::clearTextures() +{ +	S32 size = mFetchingHistory.size(); +	for(S32 i = 0 ; i < size ; i++) +	{ +		LLViewerFetchedTexture* tex = gTextureList.findImage(mFetchingHistory[i].mID) ; +		if(tex) +		{ +			tex->clearFetchedResults() ; +		} +	} +} + +void LLTextureFetchDebugger::debugRefetchVisibleFromCache() +{ +	llassert_always(mState == IDLE); +	mState = REFETCH_VIS_CACHE; + +	clearTextures(); + +	mTimer.reset(); +	mFetcher->lockFetcher(false); +} + +void LLTextureFetchDebugger::debugRefetchVisibleFromHTTP() +{ +	llassert_always(mState == IDLE); +	mState = REFETCH_VIS_HTTP; + +	clearCache(); +	clearTextures(); + +	mTimer.reset(); +	mFetcher->lockFetcher(false); +} + +bool LLTextureFetchDebugger::update() +{ +	switch(mState) +	{ +	case READ_CACHE: +		if(!mTextureCache->update(1)) +		{ +			mCacheReadTime = mTimer.getElapsedTimeF32() ; +			mState = IDLE; +			unlockCache(); +		} +		break; +	case WRITE_CACHE: +		if(!mTextureCache->update(1)) +		{ +			mCacheWriteTime = mTimer.getElapsedTimeF32() ; +			mState = IDLE; +			unlockCache(); +		} +		break; +	case DECODING: +		if(!mImageDecodeThread->update(1)) +		{ +			mDecodingTime =  mTimer.getElapsedTimeF32() ; +			mState = IDLE; +			unlockDecoder(); +		} +		break; +	case HTTP_FETCHING: +		mCurlGetRequest->process(); +		LLCurl::getCurlThread()->update(1); +		if (!fillCurlQueue() && mNbCurlCompleted == mFetchingHistory.size()) +		{ +			mHTTPTime =  mTimer.getElapsedTimeF32() ; +			mState = IDLE; +		} +		break; +	case GL_TEX: +		mState = IDLE; +		break; +	case REFETCH_VIS_CACHE: +		if (LLAppViewer::getTextureFetch()->getNumRequests() == 0) +		{ +			mRefetchVisCacheTime = gDebugTimers[0].getElapsedTimeF32() - mTotalFetchingTime; +			mState = IDLE; +			mFetcher->lockFetcher(true); +		} +		break; +	case REFETCH_VIS_HTTP: +		if (LLAppViewer::getTextureFetch()->getNumRequests() == 0) +		{ +			mRefetchVisHTTPTime = gDebugTimers[0].getElapsedTimeF32() - mTotalFetchingTime; +			mState = IDLE; +			mFetcher->lockFetcher(true); +		} +		break; +	default: +		mState = IDLE; +		break; +	} + +	return mState == IDLE; +} + +void LLTextureFetchDebugger::callbackCacheRead(S32 id, bool success, LLImageFormatted* image, +						   S32 imagesize, BOOL islocal) +{ +	if (success) +	{ +		mFetchingHistory[id].mFormattedImage = image; +	} +	mTextureCache->readComplete(mFetchingHistory[id].mCacheHandle, false); +	mFetchingHistory[id].mCacheHandle = LLTextureCache::nullHandle(); +} + +void LLTextureFetchDebugger::callbackCacheWrite(S32 id, bool success) +{ +	mTextureCache->writeComplete(mFetchingHistory[id].mCacheHandle); +	mFetchingHistory[id].mCacheHandle = LLTextureCache::nullHandle(); +} + +void LLTextureFetchDebugger::callbackDecoded(S32 id, bool success, LLImageRaw* raw, LLImageRaw* aux) +{ +	if (success) +	{ +		llassert_always(raw); +		mFetchingHistory[id].mRawImage = raw; +	} +} + +void LLTextureFetchDebugger::callbackHTTP(S32 id, const LLChannelDescriptors& channels, +										  const LLIOPipe::buffer_ptr_t& buffer,  +										  bool partial, bool success) +{ +	mNbCurlRequests--; +	if (success) +	{ +		mFetchingHistory[id].mCurlState = FetchEntry::CURL_DONE; +		mNbCurlCompleted++; + +		S32 data_size = buffer->countAfter(channels.in(), NULL); +		mFetchingHistory[id].mCurlReceivedSize += data_size; +		//llinfos << "Fetch Debugger : got results for " << id << ", data_size = " << data_size << ", received = " << mFetchingHistory[id].mCurlReceivedSize << ", requested = " << mFetchingHistory[id].mRequestedSize << ", partial = " << partial << llendl; +		if ((mFetchingHistory[id].mCurlReceivedSize >= mFetchingHistory[id].mRequestedSize) || !partial || (mFetchingHistory[id].mRequestedSize == 600)) +		{ +			U8* d_buffer = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), data_size); +			buffer->readAfter(channels.in(), NULL, d_buffer, data_size); +			 +			llassert_always(mFetchingHistory[id].mFormattedImage.isNull()); +			{ +				// For now, create formatted image based on extension +				std::string texture_url = mHTTPUrl + "/?texture_id=" + mFetchingHistory[id].mID.asString().c_str(); +				std::string extension = gDirUtilp->getExtension(texture_url); +				mFetchingHistory[id].mFormattedImage = LLImageFormatted::createFromType(LLImageBase::getCodecFromExtension(extension)); +				if (mFetchingHistory[id].mFormattedImage.isNull()) +				{ +					mFetchingHistory[id].mFormattedImage = new LLImageJ2C; // default +				} +			} +						 +			mFetchingHistory[id].mFormattedImage->setData(d_buffer, data_size);	 +		} +	} +	else //failed +	{ +		mFetchingHistory[id].mHTTPFailCount++; +		if(mFetchingHistory[id].mHTTPFailCount < 5) +		{ +			// Fetch will have to be redone +			mFetchingHistory[id].mCurlState = FetchEntry::CURL_NOT_DONE; +		} +		else //skip +		{ +			mFetchingHistory[id].mCurlState = FetchEntry::CURL_DONE; +			mNbCurlCompleted++; +		} +	} +} + + +//--------------------- +/////////////////////////////////////////////////////////////////////////////////////////// +//End LLTextureFetchDebugger +/////////////////////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index 35df7d816f..107e1623b0 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -34,14 +34,17 @@  #include "llcurl.h"  #include "lltextureinfo.h"  #include "llapr.h" +#include "llimageworker.h" +//#include "lltexturecache.h"  class LLViewerTexture;  class LLTextureFetchWorker;  class HTTPGetResponder; -class LLTextureCache;  class LLImageDecodeThread;  class LLHost;  class LLViewerAssetStats; +class LLTextureFetchDebugger; +class LLTextureCache;  // Interface class  class LLTextureFetch : public LLWorkerThread @@ -164,6 +167,9 @@ private:  	LLMutex mQueueMutex;        //to protect mRequestMap and mCommands only  	LLMutex mNetworkQueueMutex; //to protect mNetworkQueue, mHTTPTextureQueue and mCancelQueue. +	static LLStat sCacheHitRate; +	static LLStat sCacheReadLatency; +  	LLTextureCache* mTextureCache;  	LLImageDecodeThread* mImageDecodeThread;  	LLCurlRequest* mCurlGetRequest; @@ -209,7 +215,195 @@ public:  	// attempt to log metrics follows a break in the metrics stream  	// reporting due to either startup or a problem POSTing data.  	static volatile bool svMetricsDataBreak; + +private: +	//debug use +	LLTextureFetchDebugger* mFetchDebugger; +	bool mFetcherLocked; + +public: +	//debug use +	LLTextureFetchDebugger* getFetchDebugger() { return mFetchDebugger;} +	void lockFetcher(bool lock) { mFetcherLocked = lock;}  }; +//debug use +class LLTextureFetchDebugger +{ +	friend class LLTextureFetch; +public: +	LLTextureFetchDebugger(LLTextureFetch* fetcher, LLTextureCache* cache, LLImageDecodeThread* imagedecodethread) ; +	~LLTextureFetchDebugger(); + +public: +	enum e_debug_state +	{ +		IDLE = 0, +		READ_CACHE, +		WRITE_CACHE, +		DECODING, +		HTTP_FETCHING, +		GL_TEX, +		REFETCH_VIS_CACHE, +		REFETCH_VIS_HTTP, +		REFETCH_ALL_CACHE, +		REFETCH_ALL_HTTP, +		INVALID +	}; + +private:	 +	struct FetchEntry +	{ +		enum e_curl_state +		{ +			CURL_NOT_DONE = 0, +			CURL_IN_PROGRESS, +			CURL_DONE +		}; +		LLUUID mID; +		S32 mRequestedSize; +		S32 mDecodedLevel; +		S32 mFetchedSize; +		S32 mDecodedSize; +		BOOL mNeedsAux; +		U32 mCacheHandle; +		LLPointer<LLImageFormatted> mFormattedImage; +		LLPointer<LLImageRaw> mRawImage; +		e_curl_state mCurlState; +		S32 mCurlReceivedSize; +		S32 mHTTPFailCount; + +		FetchEntry() : +			mDecodedLevel(-1), +			mFetchedSize(0), +			mDecodedSize(0) +			{} +		FetchEntry(LLUUID& id, S32 r_size, /*S32 f_discard, S32 c,*/ S32 level, S32 f_size, S32 d_size) : +			mID(id), +			mRequestedSize(r_size), +			mDecodedLevel(level), +			mFetchedSize(f_size), +			mDecodedSize(d_size), +			mNeedsAux(false), +			mHTTPFailCount(0) +			{} +	}; +	std::vector<FetchEntry> mFetchingHistory; +	 +	e_debug_state mState; +	 +	F32 mCacheReadTime; +	F32 mCacheWriteTime; +	F32 mDecodingTime; +	F32 mHTTPTime; +	F32 mGLCreationTime; + +	F32 mTotalFetchingTime; +	F32 mRefetchVisCacheTime; +	F32 mRefetchVisHTTPTime; + +	LLTimer mTimer; +	 +	LLTextureFetch* mFetcher; +	LLTextureCache* mTextureCache; +	LLImageDecodeThread* mImageDecodeThread; +	LLCurlRequest* mCurlGetRequest; +	 +	S32 mNumFetchedTextures; +	S32 mNumCacheHits; +	S32 mNumVisibleFetchedTextures; +	S32 mNumVisibleFetchingRequests; +	U32 mFetchedData; +	U32 mDecodedData; +	U32 mVisibleFetchedData; +	U32 mVisibleDecodedData; +	U32 mRenderedData; +	U32 mRenderedDecodedData; +	U32 mFetchedPixels; +	U32 mRenderedPixels; +	U32 mRefetchedData; +	U32 mRefetchedPixels; + +	BOOL mFreezeHistory; + +	std::string mHTTPUrl; +	S32 mNbCurlRequests; +	S32 mNbCurlCompleted; + +public: +	bool update(); //called in the main thread once per frame + +	//fetching history +	void clearHistory(); +	void addHistoryEntry(LLTextureFetchWorker* worker); +	 +	void setCurlGetRequest(LLCurlRequest* request) { mCurlGetRequest = request;} +	 +	void startDebug(); +	void stopDebug(); //stop everything +	void debugCacheRead(); +	void debugCacheWrite();	 +	void debugHTTP(); +	void debugDecoder(); +	void debugGLTextureCreation(); +	void debugRefetchVisibleFromCache(); +	void debugRefetchVisibleFromHTTP(); + +	void callbackCacheRead(S32 id, bool success, LLImageFormatted* image, +						   S32 imagesize, BOOL islocal); +	void callbackCacheWrite(S32 id, bool success); +	void callbackDecoded(S32 id, bool success, LLImageRaw* raw, LLImageRaw* aux); +	void callbackHTTP(S32 id, const LLChannelDescriptors& channels, +					  const LLIOPipe::buffer_ptr_t& buffer,  +					  bool partial, bool success); +	 + +	e_debug_state getState()             {return mState;} +	S32  getNumFetchedTextures()         {return mNumFetchedTextures;} +	S32  getNumFetchingRequests()        {return mFetchingHistory.size();} +	S32  getNumCacheHits()               {return mNumCacheHits;} +	S32  getNumVisibleFetchedTextures()  {return mNumVisibleFetchedTextures;} +	S32  getNumVisibleFetchingRequests() {return mNumVisibleFetchingRequests;} +	U32  getFetchedData()                {return mFetchedData;} +	U32  getDecodedData()                {return mDecodedData;} +	U32  getVisibleFetchedData()         {return mVisibleFetchedData;} +	U32  getVisibleDecodedData()         {return mVisibleDecodedData;} +	U32  getRenderedData()               {return mRenderedData;} +	U32  getRenderedDecodedData()        {return mRenderedDecodedData;} +	U32  getFetchedPixels()              {return mFetchedPixels;} +	U32  getRenderedPixels()             {return mRenderedPixels;} +	U32  getRefetchedData()              {return mRefetchedData;} +	U32  getRefetchedPixels()            {return mRefetchedPixels;} + +	F32  getCacheReadTime()     {return mCacheReadTime;} +	F32  getCacheWriteTime()    {return mCacheWriteTime;} +	F32  getDecodeTime()        {return mDecodingTime;} +	F32  getGLCreationTime()    {return mGLCreationTime;} +	F32  getHTTPTime()          {return mHTTPTime;} +	F32  getTotalFetchingTime() {return mTotalFetchingTime;} +	F32  getRefetchVisCacheTime() {return mRefetchVisCacheTime;} +	F32  getRefetchVisHTTPTime()  {return mRefetchVisHTTPTime;} + +private: +	void init(); +	void clearTextures();//clear fetching results of all textures. +	void clearCache(); + +	void lockFetcher(); +	void unlockFetcher(); + +	void lockCache(); +	void unlockCache(); + +	void lockDecoder(); +	void unlockDecoder(); +	 +	S32 fillCurlQueue(); + +private: +	static bool sDebuggerEnabled; +public: +	static bool isEnabled() {return sDebuggerEnabled;} +};  #endif // LL_LLTEXTUREFETCH_H diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp index 5b41a05f2a..425bf7ee87 100644..100755 --- a/indra/newview/lltextureview.cpp +++ b/indra/newview/lltextureview.cpp @@ -57,8 +57,6 @@  extern F32 texmem_lower_bound_scale;  LLTextureView *gTextureView = NULL; -LLTextureSizeView *gTextureSizeView = NULL; -LLTextureSizeView *gTextureCategoryView = NULL;  #define HIGH_PRIORITY 100000000.f @@ -512,8 +510,8 @@ void LLGLTexMemBar::draw()  	F32 discard_bias = LLViewerTexture::sDesiredDiscardBias;  	F32 cache_usage = (F32)BYTES_TO_MEGA_BYTES(LLAppViewer::getTextureCache()->getUsage()) ;  	F32 cache_max_usage = (F32)BYTES_TO_MEGA_BYTES(LLAppViewer::getTextureCache()->getMaxUsage()) ; -	S32 line_height = LLFontGL::getFontMonospace()->getLineHeight(); -	S32 v_offset = (S32)((texture_bar_height + 2.2f) * mTextureView->mNumTextureBars + 2.0f); +	S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f); +	S32 v_offset = 0;//(S32)((texture_bar_height + 2.2f) * mTextureView->mNumTextureBars + 2.0f);  	F32 total_texture_downloaded = (F32)gTotalTextureBytes / (1024 * 1024);  	F32 total_object_downloaded = (F32)gTotalObjectBytes / (1024 * 1024);  	U32 total_http_requests = LLAppViewer::getTextureFetch()->getTotalNumHTTPRequests() ; @@ -527,80 +525,24 @@ void LLGLTexMemBar::draw()  	LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*6,  											 text_color, LLFontGL::LEFT, LLFontGL::TOP); -	text = llformat("GL Tot: %d/%d MB Bound: %d/%d MB FBO: %d MB Raw Tot: %d MB Bias: %.2f Cache: %.1f/%.1f MB Net Tot Tex: %.1f MB Tot Obj: %.1f MB Tot Htp: %d", +	text = llformat("GL Tot: %d/%d MB Bound: %d/%d MB FBO: %d MB Raw Tot: %d MB Bias: %.2f Cache: %.1f/%.1f MB",  					total_mem,  					max_total_mem,  					bound_mem,  					max_bound_mem,  					LLRenderTarget::sBytesAllocated/(1024*1024),  					LLImageRaw::sGlobalRawMemory >> 20,	discard_bias, -					cache_usage, cache_max_usage, total_texture_downloaded, total_object_downloaded, total_http_requests); -	//, cache_entries, cache_max_entries - -	LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*3, +					cache_usage, cache_max_usage); +	LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*4,  											 text_color, LLFontGL::LEFT, LLFontGL::TOP); -	//---------------------------------------------------------------------------- -#if 0 -	S32 bar_left = 400; -	S32 bar_width = 200; -	S32 top = line_height*3 - 2 + v_offset; -	S32 bottom = top - 6; -	S32 left = bar_left; -	S32 right = left + bar_width; -	F32 bar_scale; -	 -	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - -	// GL Mem Bar -		 -	left = bar_left; -	text = "GL"; -	LLFontGL::getFontMonospace()->renderUTF8(text, 0, left, line_height*3, +	text = llformat("Net Tot Tex: %.1f MB Tot Obj: %.1f MB Tot Htp: %d", +					total_texture_downloaded, total_object_downloaded, total_http_requests); +	//, cache_entries, cache_max_entries +	LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*3,  											 text_color, LLFontGL::LEFT, LLFontGL::TOP); -	 -	left = bar_left+20; -	right = left + bar_width; -	 -	gGL.color4f(0.5f, 0.5f, 0.5f, 0.75f); // grey -	gl_rect_2d(left, top, right, bottom); - -	bar_scale = (F32)bar_width / (max_total_mem * 1.5f); -	right = left + llfloor(total_mem * bar_scale); -	right = llclamp(right, bar_left, bar_left + bar_width); -	 -	color = (total_mem < llfloor(max_total_mem * texmem_lower_bound_scale)) ? LLColor4::green : -		  	(total_mem < max_total_mem) ? LLColor4::yellow : LLColor4::red; -	color[VALPHA] = .75f; -	gGL.diffuseColor4fv(color.mV); -	 -	gl_rect_2d(left, top, right, bottom); // red/yellow/green - -	// -	bar_left += bar_width + bar_space; -	//top = bottom - 2; bottom = top - 6; -	 -	// Bound Mem Bar - -	left = bar_left; -	text = "GL"; -	LLFontGL::getFontMonospace()->renderUTF8(text, 0, left, line_height*3, -									 text_color, LLFontGL::LEFT, LLFontGL::TOP); -	left = bar_left + 20; -	right = left + bar_width; -	 -	gGL.color4f(0.5f, 0.5f, 0.5f, 0.75f); -	gl_rect_2d(left, top, right, bottom); - -	color = (bound_mem < llfloor(max_bound_mem * texmem_lower_bound_scale)) ? LLColor4::green : -		  	(bound_mem < max_bound_mem) ? LLColor4::yellow : LLColor4::red; -	color[VALPHA] = .75f; -	gGL.diffuseColor4fv(color.mV); -	gl_rect_2d(left, top, right, bottom); -#else  	S32 left = 0 ; -#endif  	//----------------------------------------------------------------------------  	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", @@ -669,8 +611,7 @@ BOOL LLGLTexMemBar::handleMouseDown(S32 x, S32 y, MASK mask)  LLRect LLGLTexMemBar::getRequiredRect()  {  	LLRect rect; -	//rect.mTop = 50; -	rect.mTop = 0; +	rect.mTop = 50; //LLFontGL::getFontMonospace()->getLineHeight() * 6;  	return rect;  } @@ -954,9 +895,11 @@ void LLTextureView::draw()  		LLRect tmbr;  		tmbp.name("gl texmem bar");  		tmbp.rect(tmbr); +		tmbp.follows.flags = FOLLOWS_LEFT|FOLLOWS_TOP;  		tmbp.texture_view(this);  		mGLTexMemBar = LLUICtrlFactory::create<LLGLTexMemBar>(tmbp); -		addChildInBack(mGLTexMemBar); +		addChild(mGLTexMemBar); +		sendChildToFront(mGLTexMemBar);  		LLAvatarTexBar::Params atbp;  		LLRect atbr; @@ -965,16 +908,13 @@ void LLTextureView::draw()  		atbp.rect(atbr);  		mAvatarTexBar = LLUICtrlFactory::create<LLAvatarTexBar>(atbp);  		addChild(mAvatarTexBar); +		sendChildToFront(mAvatarTexBar);  		reshape(getRect().getWidth(), getRect().getHeight(), TRUE); -		/* -		  count = gTextureList.getNumImages(); -		  std::string info_string; -		  info_string = llformat("Global Info:\nTexture Count: %d", count); -		  mInfoTextp->setText(info_string); -		*/ - +		LLUI::popMatrix(); +		LLUI::pushMatrix(); +		LLUI::translate((F32)getRect().mLeft, (F32)getRect().mBottom);  		for (child_list_const_iter_t child_iter = getChildList()->begin();  			 child_iter != getChildList()->end(); ++child_iter) @@ -1049,302 +989,4 @@ BOOL LLTextureView::handleKey(KEY key, MASK mask, BOOL called_from_parent)  	return FALSE;  } -//----------------------------------------------------------------- -LLTextureSizeView::LLTextureSizeView(const LLTextureSizeView::Params& p) : LLContainerView(p) -{ -	setVisible(FALSE) ; - -	mTextureSizeBarWidth = 30 ; -} - -LLTextureSizeView::~LLTextureSizeView() -{ -	if(mTextureSizeBar.size()) -	{ -		for(U32 i = 0 ; i < mTextureSizeBar.size() ; i++) -		{ -			delete mTextureSizeBar[i] ; -		} -		mTextureSizeBar.clear() ; -	} -} -void LLTextureSizeView::draw() -{ -	if(mType == TEXTURE_MEM_OVER_SIZE) -	{ -		drawTextureSizeGraph(); -	} -	else -	{ -		drawTextureCategoryGraph() ; -	} -	 -	LLView::draw(); -} - -BOOL LLTextureSizeView::handleHover(S32 x, S32 y, MASK mask)  -{ -	if(x > mTextureSizeBarRect.mLeft && x < mTextureSizeBarRect.mRight) -	{ -		mTextureSizeBar[(x - mTextureSizeBarRect.mLeft) / mTextureSizeBarWidth]->handleHover(x, y, mask, (mType == TEXTURE_MEM_OVER_SIZE)) ; -	} - -	return TRUE ; -} - -//draw real-time texture mem bar over size -void LLTextureSizeView::drawTextureSizeGraph() -{ -	if(mTextureSizeBar.size() == 0) -	{ -		S32 line_height = LLFontGL::getFontMonospace()->getLineHeight(); -		mTextureSizeBar.resize(LLImageGL::sTextureLoadedCounter.size()) ; -		mTextureSizeBarRect.set(700, line_height * 2 + 400, 700 + mTextureSizeBar.size() * mTextureSizeBarWidth, line_height * 2) ; -		 -		for(U32 i = 0 ; i < mTextureSizeBar.size() ; i++) -		{				 -			mTextureSizeBar[i] = new LLGLTexSizeBar(i, mTextureSizeBarRect.mLeft + i * mTextureSizeBarWidth ,  -				line_height * 2, mTextureSizeBarRect.mLeft + (i + 1) * mTextureSizeBarWidth, line_height) ;				 -		}			 -	} - -	F32 size_bar_scale = drawTextureSizeDistributionGraph() ;		 -	for(U32 i = 0 ; i < mTextureSizeBar.size() ; i++) -	{ -		mTextureSizeBar[i]->setTop(LLImageGL::sTextureLoadedCounter[i], LLImageGL::sTextureBoundCounter[i], size_bar_scale) ; -		mTextureSizeBar[i]->draw() ; -	}		 -	LLImageGL::resetCurTexSizebar(); -} - -//draw background of texture size bar graph -F32 LLTextureSizeView::drawTextureSizeDistributionGraph() -{	 -	//scale -	F32 scale = 1.0f ; -	 -	LLGLSUIDefault gls_ui; - -	{ -		S32 count = 0 ; -		for(U32 i = 0 ; i < LLImageGL::sTextureLoadedCounter.size() ; i++) -		{ -			if(LLImageGL::sTextureLoadedCounter[i] > count) -			{ -				count = LLImageGL::sTextureLoadedCounter[i] ; -			} -		} -		if(count > mTextureSizeBarRect.getHeight()) -		{ -			scale = (F32)mTextureSizeBarRect.getHeight() / count ; -		} -	} - -	S32 line_height = LLFontGL::getFontMonospace()->getLineHeight(); -	S32 left = mTextureSizeBarRect.mLeft ; -	S32 bottom = mTextureSizeBarRect.mBottom ; -	S32 right = mTextureSizeBarRect.mRight ; -	S32 top = mTextureSizeBarRect.mTop ; - -	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); -	 -	//background rect -	gl_rect_2d(left - 25, top + 30, right + 100, bottom - 25, LLColor4(0.0f, 0.0f, 0.0f, 0.25f)) ; - -	//-------------------------------------------------- -	gGL.color4f(1.0f, 0.5f, 0.5f, 0.75f); -	gl_line_2d(left, bottom, right, bottom) ; //x axis -	gl_line_2d(left, bottom, left, top) ; //y axis - -	//ruler -	//-------------------------------------------------- -	gGL.color4f(1.0f, 0.5f, 0.5f, 0.5f); -	for(S32 i = bottom + 50 ; i <= top ; i += 50) -	{ -		gl_line_2d(left, i, right, i) ; -	} - -	//texts -	//-------------------------------------------------- -	F32 text_color[] = {1.f, 1.f, 1.f, 0.75f};	 -	std::string text; -	 -	//------- -	//x axis: size label -	text = llformat("%d", 0) ; -	LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 12, bottom - line_height / 2, -									 text_color, LLFontGL::LEFT, LLFontGL::TOP); -	for(U32 i = 1 ; i < mTextureSizeBar.size() ; i++) -	{ -		text = llformat("%d", (1 << (i / 2)) + ((i & 1) ? ((1 << (i / 2)) >> 1) : 0)) ; -		LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + i * mTextureSizeBarWidth + 12, bottom - line_height / 2, -									 text_color, LLFontGL::LEFT, LLFontGL::TOP); -	} -	text = llformat("(w + h)/2") ; -	LLFontGL::getFontMonospace()->renderUTF8(text, 0, right + 10, bottom - line_height / 2, -									 text_color, LLFontGL::LEFT, LLFontGL::TOP); -	//------- - -	//y axis: number label -	for(S32 i = bottom + 50 ; i <= top ; i += 50) -	{ -		text = llformat("%d", (S32)((i - bottom) / scale)) ; -		LLFontGL::getFontMonospace()->renderUTF8(text, 0, left - 20, i + line_height / 2 , -									 text_color, LLFontGL::LEFT, LLFontGL::TOP); -		LLFontGL::getFontMonospace()->renderUTF8(text, 0, right + 5, i + line_height / 2 , -									 text_color, LLFontGL::LEFT, LLFontGL::TOP); -	} - -	//-------------------------------------------------- -	F32 loaded_color[] = {1.0f, 0.0f, 0.0f, 0.75f}; -	gl_rect_2d(left + 70, top + line_height * 2, left + 90, top + line_height, loaded_color) ; -	text = llformat("Loaded") ; -	LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 100, top + line_height * 2, -									 loaded_color, LLFontGL::LEFT, LLFontGL::TOP); - -	F32 bound_color[] = {1.0f, 1.0f, 0.0f, 0.75f}; -	gl_rect_2d(left + 170, top + line_height * 2, left + 190, top + line_height, bound_color) ; -	text = llformat("Bound") ; -	LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 200, top + line_height * 2, -									 bound_color, LLFontGL::LEFT, LLFontGL::TOP); - -	//-------------------------------------------------- - -	//title -	text = llformat("Texture Size Distribution") ; -	LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 250, top + line_height * 3, -									 text_color, LLFontGL::LEFT, LLFontGL::TOP); -	return scale ; -} - -//draw real-time texture mem bar over category -void LLTextureSizeView::drawTextureCategoryGraph() -{ -	if(mTextureSizeBar.size() == 0) -	{ -		S32 line_height = LLFontGL::getFontMonospace()->getLineHeight(); -		mTextureSizeBar.resize(LLViewerTexture::getTotalNumOfCategories()) ; -		mTextureSizeBarRect.set(700, line_height * 2 + 400, 700 + mTextureSizeBar.size() * mTextureSizeBarWidth, line_height * 2) ; -		 -		for(U32 i = 0 ; i < mTextureSizeBar.size() ; i++) -		{				 -			mTextureSizeBar[i] = new LLGLTexSizeBar(i, mTextureSizeBarRect.mLeft + i * mTextureSizeBarWidth ,  -				line_height * 2, mTextureSizeBarRect.mLeft + (i + 1) * mTextureSizeBarWidth, line_height) ;				 -		}			 -	} - -	F32 size_bar_scale = drawTextureCategoryDistributionGraph() ;		 -	for(U32 i = 0 ; i < mTextureSizeBar.size() ; i++) -	{ -		U32 k = LLViewerTexture::getIndexFromCategory(i) ; -		mTextureSizeBar[i]->setTop(LLImageGL::sTextureMemByCategory[k] >> 20, LLImageGL::sTextureMemByCategoryBound[k] >> 20, size_bar_scale) ; -		mTextureSizeBar[i]->draw() ; -	}		 -	LLImageGL::resetCurTexSizebar(); -} - -//draw background for TEXTURE_MEM_OVER_CATEGORY -F32 LLTextureSizeView::drawTextureCategoryDistributionGraph()  -{ -	//scale -	F32 scale = 4.0f ; -	 -	LLGLSUIDefault gls_ui; -	{ -		S32 count = 0 ; -		for(U32 i = 0 ; i < LLImageGL::sTextureMemByCategory.size() ; i++) -		{ -			S32 tmp = LLImageGL::sTextureMemByCategory[i] >> 20 ; -			if(tmp > count) -			{ -				count = tmp ; -			} -		} -		if(count > mTextureSizeBarRect.getHeight() * 0.25f) -		{ -			scale = (F32)mTextureSizeBarRect.getHeight() * 0.25f / count ; -		} -	} - -	S32 line_height = LLFontGL::getFontMonospace()->getLineHeight(); -	S32 left = mTextureSizeBarRect.mLeft ; -	S32 bottom = mTextureSizeBarRect.mBottom ; -	S32 right = mTextureSizeBarRect.mRight ; -	S32 top = mTextureSizeBarRect.mTop ; - -	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); -	 -	//background rect -	gl_rect_2d(left - 25, top + 30, right + 100, bottom - 25, LLColor4(0.0f, 0.0f, 0.0f, 0.25f)) ; - -	//-------------------------------------------------- -	gGL.color4f(1.0f, 0.5f, 0.5f, 0.75f); -	gl_line_2d(left, bottom, right, bottom) ; //x axis -	gl_line_2d(left, bottom, left, top) ; //y axis - -	//ruler -	//-------------------------------------------------- -	gGL.color4f(1.0f, 0.5f, 0.5f, 0.5f); -	for(S32 i = bottom + 50 ; i <= top ; i += 50) -	{ -		gl_line_2d(left, i, right, i) ; -	} - -	//texts -	//-------------------------------------------------- -	F32 text_color[] = {1.f, 1.f, 1.f, 0.75f};	 -	std::string text; -	 -	//------- -	//x axis: size label			 -	static char category[LLViewerTexture::MAX_GL_IMAGE_CATEGORY][4] =  -	{"Non", "Bak", "Av", "Cld", "Scp", "Hi", "Trn", "Slt", "Hud", "Bsf", "UI", "Pvw", "Map", "Mvs", "Slf", "Loc", "Scr", "Dyn", "Mdi", "ALT", "Oth" } ; - -	text = llformat("%s", category[0]) ; -	LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 12, bottom - line_height / 2, -									 text_color, LLFontGL::LEFT, LLFontGL::TOP); -	for(U32 i = 1 ; i < mTextureSizeBar.size() ; i++) -	{ -		text = llformat("%s", category[i]) ; -		LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + i * mTextureSizeBarWidth + 12, bottom - line_height / 2, -									 text_color, LLFontGL::LEFT, LLFontGL::TOP); -	} -	//------- - -	//y axis: number label -	for(S32 i = bottom + 50 ; i <= top ; i += 50) -	{ -		text = llformat("%d", (S32)((i - bottom) / scale)) ; -		LLFontGL::getFontMonospace()->renderUTF8(text, 0, left - 20, i + line_height / 2 , -									 text_color, LLFontGL::LEFT, LLFontGL::TOP); -		LLFontGL::getFontMonospace()->renderUTF8(text, 0, right + 5, i + line_height / 2 , -									 text_color, LLFontGL::LEFT, LLFontGL::TOP); -	} - -	text = llformat("MB") ; -	LLFontGL::getFontMonospace()->renderUTF8(text, 0, left - 20, top + line_height * 2 , -									 text_color, LLFontGL::LEFT, LLFontGL::TOP); -	//-------------------------------------------------- -	F32 loaded_color[] = {1.0f, 0.0f, 0.0f, 0.75f}; -	gl_rect_2d(left + 70, top + line_height * 2, left + 90, top + line_height, loaded_color) ; -	text = llformat("Loaded") ; -	LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 100, top + line_height * 2, -									 loaded_color,  -									 LLFontGL::LEFT, LLFontGL::TOP); - -	F32 bound_color[] = {1.0f, 1.0f, 0.0f, 0.75f}; -	gl_rect_2d(left + 170, top + line_height * 2, left + 190, top + line_height, bound_color) ; -	text = llformat("Bound") ; -	LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 200, top + line_height * 2, -									 bound_color, LLFontGL::LEFT, LLFontGL::TOP); - -	//-------------------------------------------------- - -	//title -	text = llformat("Texture Category Distribution") ; -	LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 250, top + line_height * 3, -									 text_color, LLFontGL::LEFT, LLFontGL::TOP); - -	return scale ; -} diff --git a/indra/newview/lltextureview.h b/indra/newview/lltextureview.h index 3723eb737b..900b4e17d8 100644 --- a/indra/newview/lltextureview.h +++ b/indra/newview/lltextureview.h @@ -75,41 +75,6 @@ public:  };  class LLGLTexSizeBar; -class LLTextureSizeView : public LLContainerView -{ -protected: -	LLTextureSizeView(const Params&); -	friend class LLUICtrlFactory; -public:	 -	~LLTextureSizeView(); - -	/*virtual*/ void draw(); -	/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask) ; -	 -	void setType(S32 type) {mType = type ;} -	enum -	{ -		TEXTURE_MEM_OVER_SIZE, -		TEXTURE_MEM_OVER_CATEGORY -	}; -private: -	//draw background for TEXTURE_MEM_OVER_SIZE -	F32 drawTextureSizeDistributionGraph() ; -	//draw real-time texture mem bar over size -	void drawTextureSizeGraph(); - -	//draw background for TEXTURE_MEM_OVER_CATEGORY -	F32 drawTextureCategoryDistributionGraph() ; -	//draw real-time texture mem bar over category -	void drawTextureCategoryGraph(); -private: -	std::vector<LLGLTexSizeBar*> mTextureSizeBar ; -	LLRect mTextureSizeBarRect ; -	S32    mTextureSizeBarWidth ;	 -	S32    mType ; -};  extern LLTextureView *gTextureView; -extern LLTextureSizeView *gTextureSizeView; -extern LLTextureSizeView *gTextureCategoryView;  #endif // LL_TEXTURE_VIEW_H diff --git a/indra/newview/llviewerassetstats.cpp b/indra/newview/llviewerassetstats.cpp index e621cf647e..4c59fd0371 100644..100755 --- a/indra/newview/llviewerassetstats.cpp +++ b/indra/newview/llviewerassetstats.cpp @@ -30,6 +30,7 @@  #include "llregionhandle.h"  #include "stdtypes.h" +#include "llvoavatar.h"  /*   * Classes and utility functions for per-thread and per-region @@ -126,6 +127,8 @@ LLViewerAssetStats::PerRegionStats::merge(const LLViewerAssetStats::PerRegionSta  		mFPS.merge(src.mFPS);  	} +	// Avatar stats - data all comes from main thread, so leave alone. +  	// Requests  	for (int i = 0; i < LL_ARRAY_SIZE(mRequests); ++i)  	{ @@ -133,6 +136,7 @@ LLViewerAssetStats::PerRegionStats::merge(const LLViewerAssetStats::PerRegionSta  		mRequests[i].mDequeued.merge(src.mRequests[i].mDequeued);  		mRequests[i].mResponse.merge(src.mRequests[i].mResponse);  	} +  } @@ -156,7 +160,9 @@ LLViewerAssetStats::LLViewerAssetStats()  LLViewerAssetStats::LLViewerAssetStats(const LLViewerAssetStats & src)  	: mRegionHandle(src.mRegionHandle), -	  mResetTimestamp(src.mResetTimestamp) +	  mResetTimestamp(src.mResetTimestamp), +	  mPhaseStats(src.mPhaseStats), +	  mAvatarRezStates(src.mAvatarRezStates)  {  	const PerRegionContainer::const_iterator it_end(src.mRegionStats.end());  	for (PerRegionContainer::const_iterator it(src.mRegionStats.begin()); it_end != it; ++it) @@ -252,6 +258,17 @@ LLViewerAssetStats::recordFPS(F32 fps)  	mCurRegionStats->mFPS.record(fps);  } +void +LLViewerAssetStats::recordAvatarStats() +{ +	std::vector<S32> rez_counts; +	LLVOAvatar::getNearbyRezzedStats(rez_counts); +	mAvatarRezStates = rez_counts; +	mPhaseStats.clear(); +	mPhaseStats["cloud"] = LLViewerStats::PhaseMap::getPhaseStats("cloud"); +	mPhaseStats["cloud-or-gray"] = LLViewerStats::PhaseMap::getPhaseStats("cloud-or-gray"); +} +  LLSD  LLViewerAssetStats::asLLSD(bool compact_output)  { @@ -282,6 +299,11 @@ LLViewerAssetStats::asLLSD(bool compact_output)  	static const LLSD::String max_tag("max");  	static const LLSD::String mean_tag("mean"); +	// Avatar sub-tags +	static const LLSD::String avatar_tag("avatar"); +	static const LLSD::String avatar_nearby_tag("nearby"); +	static const LLSD::String avatar_phase_stats_tag("phase_stats"); +	  	const duration_t now = LLViewerAssetStatsFF::get_timestamp();  	mCurRegionStats->accumulateTime(now); @@ -329,7 +351,6 @@ LLViewerAssetStats::asLLSD(bool compact_output)  			slot[max_tag] = LLSD(F64(stats.mFPS.getMax()));  			slot[mean_tag] = LLSD(F64(stats.mFPS.getMean()));  		} -  		U32 grid_x(0), grid_y(0);  		grid_from_region_handle(it->first, &grid_x, &grid_y);  		reg_stat["grid_x"] = LLSD::Integer(grid_x); @@ -341,6 +362,16 @@ LLViewerAssetStats::asLLSD(bool compact_output)  	LLSD ret = LLSD::emptyMap();  	ret["regions"] = regions;  	ret["duration"] = LLSD::Real((now - mResetTimestamp) * 1.0e-6); +	LLSD avatar_info; +	avatar_info[avatar_nearby_tag] = LLSD::emptyArray(); +	for (S32 rez_stat=0; rez_stat < mAvatarRezStates.size(); ++rez_stat) +	{ +		std::string rez_status_name = LLVOAvatar::rezStatusToString(rez_stat); +		avatar_info[avatar_nearby_tag][rez_status_name] = mAvatarRezStates[rez_stat]; +	} +	avatar_info[avatar_phase_stats_tag]["cloud"] = mPhaseStats["cloud"].getData(); +	avatar_info[avatar_phase_stats_tag]["cloud-or-gray"] = mPhaseStats["cloud-or-gray"].getData(); +	ret[avatar_tag] = avatar_info;  	return ret;  } @@ -439,6 +470,14 @@ record_fps_main(F32 fps)  	gViewerAssetStatsMain->recordFPS(fps);  } +void +record_avatar_stats() +{ +	if (! gViewerAssetStatsMain) +		return; + +	gViewerAssetStatsMain->recordAvatarStats(); +}  // 'thread1' - should be for TextureFetch thread diff --git a/indra/newview/llviewerassetstats.h b/indra/newview/llviewerassetstats.h index 73ec5974b2..8319752230 100644..100755 --- a/indra/newview/llviewerassetstats.h +++ b/indra/newview/llviewerassetstats.h @@ -36,6 +36,7 @@  #include "llviewerassetstorage.h"  #include "llsimplestat.h"  #include "llsd.h" +#include "llvoavatar.h"  /**   * @class LLViewerAssetStats @@ -181,6 +182,9 @@ public:  	// Frames-Per-Second Samples  	void recordFPS(F32 fps); +	// Avatar-related statistics +	void recordAvatarStats(); +  	// Merge a source instance into a destination instance.  This is  	// conceptually an 'operator+=()' method:  	// - counts are added @@ -252,6 +256,10 @@ protected:  	// Time of last reset  	duration_t mResetTimestamp; + +	// Nearby avatar stats +	std::vector<S32> mAvatarRezStates; +	LLViewerStats::phase_stats_t mPhaseStats;  }; @@ -310,6 +318,7 @@ void record_response_main(LLViewerAssetType::EType at, bool with_http, bool is_t  void record_fps_main(F32 fps); +void record_avatar_stats();  /**   * Region context, event and duration loggers for Thread 1. diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index ab45aae5cc..f2712e7590 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -87,7 +87,6 @@ std::string gLastRunVersion;  extern BOOL gResizeScreenTexture;  extern BOOL gDebugGL; -extern BOOL gAuditTexture;  ////////////////////////////////////////////////////////////////////////////  // Listeners @@ -411,12 +410,6 @@ static bool handleRenderUseImpostorsChanged(const LLSD& newvalue)  	return true;  } -static bool handleAuditTextureChanged(const LLSD& newvalue) -{ -	gAuditTexture = newvalue.asBoolean(); -	return true; -} -  static bool handleRenderDebugGLChanged(const LLSD& newvalue)  {  	gDebugGL = newvalue.asBoolean() || gDebugSession; @@ -618,7 +611,6 @@ void settings_setup_listeners()  	gSavedSettings.getControl("RenderDeferredSSAO")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));  	gSavedSettings.getControl("RenderPerformanceTest")->getSignal()->connect(boost::bind(&handleRenderPerfTestChanged, _2));  	gSavedSettings.getControl("TextureMemory")->getSignal()->connect(boost::bind(&handleVideoMemoryChanged, _2)); -	gSavedSettings.getControl("AuditTexture")->getSignal()->connect(boost::bind(&handleAuditTextureChanged, _2));  	gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&handleChatFontSizeChanged, _2));  	gSavedSettings.getControl("ChatPersistTime")->getSignal()->connect(boost::bind(&handleChatPersistTimeChanged, _2));  	gSavedSettings.getControl("ConsoleMaxLines")->getSignal()->connect(boost::bind(&handleConsoleMaxLinesChanged, _2)); diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 7fdaac68c8..d0e0d0d826 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -103,6 +103,7 @@  #include "llfloatertelehub.h"  #include "llfloatertestinspectors.h"  #include "llfloatertestlistview.h" +#include "llfloatertexturefetchdebugger.h"  #include "llfloatertools.h"  #include "llfloatertos.h"  #include "llfloatertopobjects.h" @@ -227,6 +228,11 @@ void LLViewerFloaterReg::registerFloaters()  	LLFloaterReg::add("land_holdings", "floater_land_holdings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLandHoldings>);  	LLFloaterReg::add("mem_leaking", "floater_mem_leaking.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMemLeak>); + +	if(gSavedSettings.getBOOL("TextureFetchDebuggerEnabled")) +	{ +		LLFloaterReg::add("tex_fetch_debugger", "floater_texture_fetch_debugger.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTextureFetchDebugger>); +	}  	LLFloaterReg::add("media_settings", "floater_media_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMediaSettings>);	  	LLFloaterReg::add("message_critical", "floater_critical.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTOS>);  	LLFloaterReg::add("message_tos", "floater_tos.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTOS>); diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index 45ca23cdfe..b47a41c44c 100644..100755 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -342,8 +342,8 @@ void LLViewerInventoryItem::cloneViewerItem(LLPointer<LLViewerInventoryItem>& ne  void LLViewerInventoryItem::removeFromServer()  { -	llinfos << "Removing inventory item " << mUUID << " from server." -			<< llendl; +	lldebugs << "Removing inventory item " << mUUID << " from server." +			 << llendl;  	LLInventoryModel::LLCategoryUpdate up(mParentUUID, -1);  	gInventory.accountForUpdate(up); diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp index e052e37393..f029ae5302 100644..100755 --- a/indra/newview/llviewerjointmesh.cpp +++ b/indra/newview/llviewerjointmesh.cpp @@ -576,7 +576,6 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)  		{  			old_mode = mTexture->getAddressMode();  		} -		gGL.getTexUnit(diffuse_channel)->bind(mTexture.get());  		gGL.getTexUnit(diffuse_channel)->bind(mTexture);  		gGL.getTexUnit(diffuse_channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);  	} diff --git a/indra/newview/llviewerjointmesh.h b/indra/newview/llviewerjointmesh.h index 0191f0cae8..dd5dae1dc1 100644..100755 --- a/indra/newview/llviewerjointmesh.h +++ b/indra/newview/llviewerjointmesh.h @@ -61,6 +61,7 @@ public:  //-----------------------------------------------------------------------------  class LLViewerJointMesh : public LLViewerJoint  { +	friend class LLVOAvatar;  protected:  	LLColor4					mColor;			// color value  // 	LLColor4					mSpecular;		// specular color (always white for now) diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 7481414b5c..48e4813205 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -516,14 +516,6 @@ class LLAdvancedToggleConsole : public view_listener_t  		{  			toggle_visibility( (void*)static_cast<LLUICtrl*>(gDebugView->mDebugConsolep));  		} -		else if (gTextureSizeView && "texture size" == console_type) -		{ -			toggle_visibility( (void*)gTextureSizeView ); -		} -		else if (gTextureCategoryView && "texture category" == console_type) -		{ -			toggle_visibility( (void*)gTextureCategoryView ); -		}  		else if ("fast timers" == console_type)  		{  			LLFloaterReg::toggleInstance("fast_timers"); @@ -556,14 +548,6 @@ class LLAdvancedCheckConsole : public view_listener_t  		{  			new_value = get_visibility( (void*)((LLView*)gDebugView->mDebugConsolep) );  		} -		else if (gTextureSizeView && "texture size" == console_type) -		{ -			new_value = get_visibility( (void*)gTextureSizeView ); -		} -		else if (gTextureCategoryView && "texture category" == console_type) -		{ -			new_value = get_visibility( (void*)gTextureCategoryView ); -		}  		else if ("fast timers" == console_type)  		{  			new_value = LLFloaterReg::instanceVisible("fast_timers"); @@ -866,6 +850,73 @@ class LLAdvancedCheckFeature : public view_listener_t  }  }; +class LLAdvancedCheckDisplayTextureDensity : public view_listener_t +{ +	bool handleEvent(const LLSD& userdata) +	{ +		std::string mode = userdata.asString(); +		if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY)) +		{ +			return mode == "none"; +		} +		if (mode == "current") +		{ +			return LLViewerTexture::sDebugTexelsMode == LLViewerTexture::DEBUG_TEXELS_CURRENT; +		} +		else if (mode == "desired") +		{ +			return LLViewerTexture::sDebugTexelsMode == LLViewerTexture::DEBUG_TEXELS_DESIRED; +		} +		else if (mode == "full") +		{ +			return LLViewerTexture::sDebugTexelsMode == LLViewerTexture::DEBUG_TEXELS_FULL; +		} +		return false; +	} +}; + +class LLAdvancedSetDisplayTextureDensity : public view_listener_t +{ +	bool handleEvent(const LLSD& userdata) +	{ +		std::string mode = userdata.asString(); +		if (mode == "none") +		{ +			if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY) == TRUE)  +			{ +				gPipeline.toggleRenderDebug((void*)LLPipeline::RENDER_DEBUG_TEXEL_DENSITY); +			} +			LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_OFF; +		} +		else if (mode == "current") +		{ +			if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY) == FALSE)  +			{ +				gPipeline.toggleRenderDebug((void*)LLPipeline::RENDER_DEBUG_TEXEL_DENSITY); +			} +			LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_CURRENT; +		} +		else if (mode == "desired") +		{ +			if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY) == FALSE)  +			{ +				gPipeline.toggleRenderDebug((void*)LLPipeline::RENDER_DEBUG_TEXEL_DENSITY); +			} +			gPipeline.setRenderDebugFeatureControl(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY, true); +			LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_DESIRED; +		} +		else if (mode == "full") +		{ +			if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY) == FALSE)  +			{ +				gPipeline.toggleRenderDebug((void*)LLPipeline::RENDER_DEBUG_TEXEL_DENSITY); +			} +			LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_FULL; +		} +		return true; +	} +}; +  //////////////////  // INFO DISPLAY // @@ -980,6 +1031,10 @@ U32 info_display_from_string(std::string info_display)  	{  		return LLPipeline::RENDER_DEBUG_WIND_VECTORS;  	} +	else if ("texel density" == info_display) +	{ +		return LLPipeline::RENDER_DEBUG_TEXEL_DENSITY; +	}  	else  	{  		return 0; @@ -2245,6 +2300,14 @@ class LLDevelopSetLoggingLevel : public view_listener_t  	}  }; +class LLDevelopTextureFetchDebugger : public view_listener_t +{ +	bool handleEvent(const LLSD& userdata) +	{ +		return gSavedSettings.getBOOL("TextureFetchDebuggerEnabled"); +	} +}; +  //////////////////  // ADMIN MENU   //  ////////////////// @@ -8164,6 +8227,10 @@ void initialize_menus()  	//// Advanced > Render > Features  	view_listener_t::addMenu(new LLAdvancedToggleFeature(), "Advanced.ToggleFeature");  	view_listener_t::addMenu(new LLAdvancedCheckFeature(), "Advanced.CheckFeature"); + +	view_listener_t::addMenu(new LLAdvancedCheckDisplayTextureDensity(), "Advanced.CheckDisplayTextureDensity"); +	view_listener_t::addMenu(new LLAdvancedSetDisplayTextureDensity(), "Advanced.SetDisplayTextureDensity"); +  	// Advanced > Render > Info Displays  	view_listener_t::addMenu(new LLAdvancedToggleInfoDisplay(), "Advanced.ToggleInfoDisplay");  	view_listener_t::addMenu(new LLAdvancedCheckInfoDisplay(), "Advanced.CheckInfoDisplay"); @@ -8295,6 +8362,9 @@ void initialize_menus()  	// Develop >Set logging level  	view_listener_t::addMenu(new LLDevelopCheckLoggingLevel(), "Develop.CheckLoggingLevel");  	view_listener_t::addMenu(new LLDevelopSetLoggingLevel(), "Develop.SetLoggingLevel"); +	 +	//Develop (Texture Fetch Debug Console) +	view_listener_t::addMenu(new LLDevelopTextureFetchDebugger(), "Develop.SetTexFetchDebugger");  	// Admin >Object  	view_listener_t::addMenu(new LLAdminForceTakeCopy(), "Admin.ForceTakeCopy"); diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 6912faa9ec..54ccfb9aae 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -91,8 +91,9 @@ extern LLPipeline	gPipeline;  // Statics for object lookup tables.  U32						LLViewerObjectList::sSimulatorMachineIndex = 1; // Not zero deliberately, to speed up index check. -std::map<U64, U32>			LLViewerObjectList::sIPAndPortToIndex; +std::map<U64, U32>		LLViewerObjectList::sIPAndPortToIndex;  std::map<U64, LLUUID>	LLViewerObjectList::sIndexAndLocalIDToUUID; +LLStat					LLViewerObjectList::sCacheHitRate("object_cache_hits", 128);  LLViewerObjectList::LLViewerObjectList()  { @@ -542,6 +543,8 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,  			}  			justCreated = TRUE;  			mNumNewObjects++; +			sCacheHitRate.addValue(cached ? 100.f : 0.f); +  		} diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h index c5f2a2c1ee..64925f46ae 100644 --- a/indra/newview/llviewerobjectlist.h +++ b/indra/newview/llviewerobjectlist.h @@ -192,6 +192,8 @@ protected:  	std::vector<OrphanInfo> mOrphanChildren;	// UUID's of orphaned objects  	S32 mNumOrphans; +	static LLStat sCacheHitRate; +  	typedef std::vector<LLPointer<LLViewerObject> > vobj_list_t;  	vobj_list_t mObjects; diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index c88122f22c..497e95c5e3 100644..100755 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -860,3 +860,110 @@ void send_stats()  	LLHTTPClient::post(url, body, new ViewerStatsResponder());  } +LLFrameTimer& LLViewerStats::PhaseMap::getPhaseTimer(const std::string& phase_name) +{ +	phase_map_t::iterator iter = mPhaseMap.find(phase_name); +	if (iter == mPhaseMap.end()) +	{ +		LLFrameTimer timer; +		mPhaseMap[phase_name] = timer; +	} +	LLFrameTimer& timer = mPhaseMap[phase_name]; +	return timer; +} + +void LLViewerStats::PhaseMap::startPhase(const std::string& phase_name) +{ +	LLFrameTimer& timer = getPhaseTimer(phase_name); +	lldebugs << "startPhase " << phase_name << llendl; +	timer.unpause(); +} + +void LLViewerStats::PhaseMap::stopPhase(const std::string& phase_name) +{ +	phase_map_t::iterator iter = mPhaseMap.find(phase_name); +	if (iter != mPhaseMap.end()) +	{ +		if (iter->second.getStarted()) +		{ +			// Going from started to paused state - record stats. +			recordPhaseStat(phase_name,iter->second.getElapsedTimeF32()); +		} +		lldebugs << "stopPhase " << phase_name << llendl; +		iter->second.pause(); +	} +	else +	{ +		lldebugs << "stopPhase " << phase_name << " is not started, no-op" << llendl; +	} +} + +void LLViewerStats::PhaseMap::stopAllPhases() +{ +	for (phase_map_t::iterator iter = mPhaseMap.begin(); +		 iter != mPhaseMap.end(); ++iter) +	{ +		const std::string& phase_name = iter->first; +		if (iter->second.getStarted()) +		{ +			// Going from started to paused state - record stats. +			recordPhaseStat(phase_name,iter->second.getElapsedTimeF32()); +		} +		lldebugs << "stopPhase (all) " << phase_name << llendl; +		iter->second.pause(); +	} +} + +void LLViewerStats::PhaseMap::clearPhases() +{ +	lldebugs << "clearPhases" << llendl; + +	mPhaseMap.clear(); +} + +LLSD LLViewerStats::PhaseMap::dumpPhases() +{ +	LLSD result; +	for (phase_map_t::iterator iter = mPhaseMap.begin(); iter != mPhaseMap.end(); ++iter) +	{ +		const std::string& phase_name = iter->first; +		result[phase_name]["completed"] = !(iter->second.getStarted()); +		result[phase_name]["elapsed"] = iter->second.getElapsedTimeF32(); +#if 0 // global stats for each phase seem like overkill here +		phase_stats_t::iterator stats_iter = sPhaseStats.find(phase_name); +		if (stats_iter != sPhaseStats.end()) +		{ +			result[phase_name]["stats"] = stats_iter->second.getData(); +		} +#endif +	} +	return result; +} + +// static initializer +//static +LLViewerStats::phase_stats_t LLViewerStats::PhaseMap::sStats; + +LLViewerStats::PhaseMap::PhaseMap() +{ +} + +// static +LLViewerStats::StatsAccumulator& LLViewerStats::PhaseMap::getPhaseStats(const std::string& phase_name) +{ +	phase_stats_t::iterator it = sStats.find(phase_name); +	if (it == sStats.end()) +	{ +		LLViewerStats::StatsAccumulator new_stats; +		sStats[phase_name] = new_stats; +	} +	return sStats[phase_name]; +} + +// static +void LLViewerStats::PhaseMap::recordPhaseStat(const std::string& phase_name, F32 value) +{ +	LLViewerStats::StatsAccumulator& stats = getPhaseStats(phase_name); +	stats.push(value); +} + diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h index f91a1241fe..750d963f69 100644..100755 --- a/indra/newview/llviewerstats.h +++ b/indra/newview/llviewerstats.h @@ -244,7 +244,7 @@ public:  		inline F32 getStdDev() const  		{  			const F32 mean = getMean(); -			return (mCount == 0) ? 0.f : sqrt( mSumOfSquares/mCount - (mean * mean) ); +			return (mCount < 2) ? 0.f : sqrt(llmax(0.f,mSumOfSquares/mCount - (mean * mean)));  		}  		inline U32 getCount() const @@ -274,7 +274,28 @@ public:  	};  	StatsAccumulator mAgentPositionSnaps; -	 + +	// Phase tracking (originally put in for avatar rezzing), tracking +	// progress of active/completed phases for activities like outfit changing. +	typedef std::map<std::string,LLFrameTimer>	phase_map_t; +	typedef std::map<std::string,StatsAccumulator>	phase_stats_t; +	class PhaseMap +	{ +	private: +		phase_map_t mPhaseMap; +		static phase_stats_t sStats; +	public: +		PhaseMap(); +		LLFrameTimer& 	getPhaseTimer(const std::string& phase_name); +		void			startPhase(const std::string& phase_name); +		void			stopPhase(const std::string& phase_name); +		void			stopAllPhases(); +		void			clearPhases(); +		LLSD			dumpPhases(); +		static StatsAccumulator& getPhaseStats(const std::string& phase_name); +		static void recordPhaseStat(const std::string& phase_name, F32 value); +	}; +  private:  	F64	mStats[ST_COUNT]; diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 61236edc86..ea329f6aac 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -67,6 +67,7 @@  // statics  LLPointer<LLViewerTexture>        LLViewerTexture::sNullImagep = NULL;  LLPointer<LLViewerTexture>        LLViewerTexture::sBlackImagep = NULL; +LLPointer<LLViewerTexture>        LLViewerTexture::sCheckerBoardImagep = NULL;  LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sMissingAssetImagep = NULL;  LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sWhiteImagep = NULL;  LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sDefaultImagep = NULL; @@ -87,6 +88,7 @@ S32 LLViewerTexture::sMaxBoundTextureMemInMegaBytes = 0;  S32 LLViewerTexture::sMaxTotalTextureMemInMegaBytes = 0;  S32 LLViewerTexture::sMaxDesiredTextureMemInBytes = 0 ;  S8  LLViewerTexture::sCameraMovingDiscardBias = 0 ; +F32 LLViewerTexture::sCameraMovingBias = 0.0f ;  S32 LLViewerTexture::sMaxSculptRez = 128 ; //max sculpt image size  const S32 MAX_CACHED_RAW_IMAGE_AREA = 64 * 64 ;  const S32 MAX_CACHED_RAW_SCULPT_IMAGE_AREA = LLViewerTexture::sMaxSculptRez * LLViewerTexture::sMaxSculptRez ; @@ -96,6 +98,9 @@ S32 LLViewerTexture::sMaxSmallImageSize = MAX_CACHED_RAW_IMAGE_AREA ;  BOOL LLViewerTexture::sFreezeImageScalingDown = FALSE ;  F32 LLViewerTexture::sCurrentTime = 0.0f ;  BOOL LLViewerTexture::sUseTextureAtlas        = FALSE ; +F32  LLViewerTexture::sTexelPixelRatio = 1.0f; + +LLViewerTexture::EDebugTexels LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_OFF;  const F32 desired_discard_bias_min = -2.0f; // -max number of levels to improve image quality by  const F32 desired_discard_bias_max = (F32)MAX_DISCARD_LEVEL; // max number of levels to reduce image quality by @@ -175,7 +180,12 @@ LLViewerTexture*  LLViewerTextureManager::findTexture(const LLUUID& id)  	}  	return tex ;  } -		 + +LLViewerFetchedTexture*  LLViewerTextureManager::findFetchedTexture(const LLUUID& id)  +{ +	return gTextureList.findImage(id); +} +  LLViewerMediaTexture* LLViewerTextureManager::findMediaTexture(const LLUUID &media_id)  {  	return LLViewerMediaTexture::findMediaTexture(media_id) ;	 @@ -347,6 +357,21 @@ void LLViewerTextureManager::init()   	LLViewerFetchedTexture::sSmokeImagep = LLViewerTextureManager::getFetchedTexture(IMG_SMOKE, TRUE, LLViewerTexture::BOOST_UI);  	LLViewerFetchedTexture::sSmokeImagep->setNoDelete() ; +	image_raw = new LLImageRaw(32,32,3); +	data = image_raw->getData(); + +	for (S32 i = 0; i < (32*32*3); i+=3) +	{ +		S32 x = (i % (32*3)) / (3*16); +		S32 y = i / (32*3*16); +		U8 color = ((x + y) % 2) * 255; +		data[i] = color; +		data[i+1] = color; +		data[i+2] = color; +	} + +	LLViewerTexture::sCheckerBoardImagep = LLViewerTextureManager::getLocalTexture(image_raw.get(), TRUE); +  	LLViewerTexture::initClass() ;  	if (LLMetricPerformanceTesterBasic::isMetricLogRequested(sTesterName) && !LLMetricPerformanceTesterBasic::getTester(sTesterName)) @@ -367,6 +392,7 @@ void LLViewerTextureManager::cleanup()  	LLImageGL::sDefaultGLTexture = NULL ;  	LLViewerTexture::sNullImagep = NULL;  	LLViewerTexture::sBlackImagep = NULL; +	LLViewerTexture::sCheckerBoardImagep = NULL;  	LLViewerFetchedTexture::sDefaultImagep = NULL;	  	LLViewerFetchedTexture::sSmokeImagep = NULL;  	LLViewerFetchedTexture::sMissingAssetImagep = NULL; @@ -383,11 +409,7 @@ void LLViewerTextureManager::cleanup()  void LLViewerTexture::initClass()  {  	LLImageGL::sDefaultGLTexture = LLViewerFetchedTexture::sDefaultImagep->getGLTexture() ; - -	if(gAuditTexture) -	{ -		LLImageGL::setHighlightTexture(LLViewerTexture::OTHER) ;	 -	} +	sTexelPixelRatio = gSavedSettings.getF32("TexelPixelRatio");  }  // static @@ -534,7 +556,8 @@ void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity  	F32 camera_moving_speed = LLViewerCamera::getInstance()->getAverageSpeed() ;  	F32 camera_angular_speed = LLViewerCamera::getInstance()->getAverageAngularSpeed(); -	sCameraMovingDiscardBias = (S8)llmax(0.2f * camera_moving_speed, 2.0f * camera_angular_speed - 1) ; +	sCameraMovingBias = llmax(0.2f * camera_moving_speed, 2.0f * camera_angular_speed - 1); +	sCameraMovingDiscardBias = (S8)(sCameraMovingBias);  	LLViewerTexture::sFreezeImageScalingDown = (BYTES_TO_MEGA_BYTES(sBoundTextureMemoryInBytes) < 0.75f * sMaxBoundTextureMemInMegaBytes * texmem_middle_bound_scale) &&  				(BYTES_TO_MEGA_BYTES(sTotalTextureMemoryInBytes) < 0.75f * sMaxTotalTextureMemInMegaBytes * texmem_middle_bound_scale) ; @@ -655,10 +678,6 @@ void LLViewerTexture::setBoostLevel(S32 level)  		{  			setNoDelete() ;		  		} -		if(gAuditTexture) -		{ -			setCategory(mBoostLevel); -		}  	}  } @@ -712,6 +731,7 @@ void LLViewerTexture::addTextureStats(F32 virtual_size, BOOL needs_gltexture) co  		mNeedsGLTexture = TRUE ;  	} +	virtual_size *= sTexelPixelRatio;  	if(!mMaxVirtualSizeResetCounter)  	{  		//flag to reset the values because the old values are used. @@ -1287,6 +1307,7 @@ void LLViewerFetchedTexture::cleanup()  	mCachedRawDiscardLevel = -1 ;  	mCachedRawImageReady = FALSE ;  	mSavedRawImage = NULL ; +	mSavedRawDiscardLevel = -1;  }  void LLViewerFetchedTexture::setForSculpt() @@ -1880,6 +1901,8 @@ S32 LLViewerFetchedTexture::getCurrentDiscardLevelForFetching()  bool LLViewerFetchedTexture::updateFetch()  {  	static LLCachedControl<bool> textures_decode_disabled(gSavedSettings,"TextureDecodeDisabled"); +	static LLCachedControl<F32>  sCameraMotionThreshold(gSavedSettings,"TextureCameraMotionThreshold"); +	static LLCachedControl<S32>  sCameraMotionBoost(gSavedSettings,"TextureCameraMotionBoost");  	if(textures_decode_disabled)  	{  		return false ; @@ -2042,18 +2065,24 @@ bool LLViewerFetchedTexture::updateFetch()  	//	make_request = false;  	//} -	if(make_request) +	if (make_request)  	{ -		//load the texture progressively. +		// Load the texture progressively: we try not to rush to the desired discard too fast. +		// If the camera is not moving, we do not tweak the discard level notch by notch but go to the desired discard with larger boosted steps +		// This mitigates the "textures stay blurry" problem when loading while not killing the texture memory while moving around  		S32 delta_level = (mBoostLevel > LLViewerTexture::BOOST_NONE) ? 2 : 1 ;  -		if(current_discard < 0) +		if (current_discard < 0)  		{  			desired_discard = llmax(desired_discard, getMaxDiscardLevel() - delta_level);  		} -		else +		else if (LLViewerTexture::sCameraMovingBias < sCameraMotionThreshold)  		{ -			desired_discard = llmax(desired_discard, current_discard - delta_level); +			desired_discard = llmax(desired_discard, current_discard - sCameraMotionBoost);  		} +        else +        { +			desired_discard = llmax(desired_discard, current_discard - delta_level); +        }  		if (mIsFetching)  		{ @@ -2121,6 +2150,30 @@ bool LLViewerFetchedTexture::updateFetch()  	return mIsFetching ? true : false;  } +void LLViewerFetchedTexture::clearFetchedResults() +{ +	llassert_always(!mNeedsCreateTexture && !mIsFetching); +	 +	cleanup(); +	destroyGLTexture(); + +	if(getDiscardLevel() >= 0) //sculpty texture, force to invalidate +	{ +		mGLTexturep->forceToInvalidateGLTexture(); +	} +} + +void LLViewerFetchedTexture::forceToDeleteRequest() +{ +	if (mHasFetcher) +	{ +		LLAppViewer::getTextureFetch()->deleteRequest(getID(), true); +		mHasFetcher = FALSE; +		mIsFetching = FALSE ; +		resetTextureStats(); +	} +} +  void LLViewerFetchedTexture::setIsMissingAsset()  {  	if (mUrl.empty()) diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index b96441127d..41bf625225 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -139,6 +139,7 @@ public:  		OTHER,  		MAX_GL_IMAGE_CATEGORY  	}; +  	static S32 getTotalNumOfCategories() ;  	static S32 getIndexFromCategory(S32 category) ;  	static S32 getCategoryFromIndex(S32 index) ; @@ -309,6 +310,7 @@ protected:  	} LLGLTextureState;  	LLGLTextureState  mTextureState ; +	static F32 sTexelPixelRatio;  public:  	static const U32 sCurrentFileVersion;	  	static S32 sImageCount; @@ -323,6 +325,7 @@ public:  	static S32 sMaxTotalTextureMemInMegaBytes;  	static S32 sMaxDesiredTextureMemInBytes ;  	static S8  sCameraMovingDiscardBias; +	static F32 sCameraMovingBias;  	static S32 sMaxSculptRez ;  	static S32 sMinLargeImageSize ;  	static S32 sMaxSmallImageSize ; @@ -330,8 +333,19 @@ public:  	static F32  sCurrentTime ;  	static BOOL sUseTextureAtlas ; +	enum EDebugTexels +	{ +		DEBUG_TEXELS_OFF, +		DEBUG_TEXELS_CURRENT, +		DEBUG_TEXELS_DESIRED, +		DEBUG_TEXELS_FULL +	}; + +	static EDebugTexels sDebugTexelsMode; +  	static LLPointer<LLViewerTexture> sNullImagep; // Null texture for non-textured objects.  	static LLPointer<LLViewerTexture> sBlackImagep;	// Texture to show NOTHING (pure black) +	static LLPointer<LLViewerTexture> sCheckerBoardImagep;	// Texture to show NOTHING (pure black)  }; @@ -420,6 +434,8 @@ public:  	bool updateFetch(); +	void clearFetchedResults(); //clear all fetched results, for debug use. +  	// Override the computation of discard levels if we know the exact output  	// size of the image.  Used for UI textures to not decode, even if we have  	// more data. @@ -478,6 +494,7 @@ public:  	BOOL        hasFetcher() const { return mHasFetcher;}  	void        setCanUseHTTP(bool can_use_http) {mCanUseHTTP = can_use_http;} +	void        forceToDeleteRequest();  protected:  	/*virtual*/ void switchToCachedImage();  	S32 getCurrentDiscardLevelForFetching() ; @@ -687,6 +704,7 @@ public:  	//"find-texture" just check if the texture exists, if yes, return it, otherwise return null.  	//  	static LLViewerTexture*           findTexture(const LLUUID& id) ; +	static LLViewerFetchedTexture*    findFetchedTexture(const LLUUID& id) ;  	static LLViewerMediaTexture*      findMediaTexture(const LLUUID& id) ;  	static LLViewerMediaTexture*      createMediaTexture(const LLUUID& id, BOOL usemipmaps = TRUE, LLImageGL* gl_image = NULL) ; diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 089f45ca89..2008a884db 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -58,6 +58,7 @@  #include "pipeline.h"  #include "llappviewer.h"  #include "llxuiparser.h" +#include "llagent.h"  //////////////////////////////////////////////////////////////////////////// @@ -597,6 +598,12 @@ static LLFastTimer::DeclareTimer FTM_IMAGE_STATS("Stats");  void LLViewerTextureList::updateImages(F32 max_time)  { +	if(gAgent.getTeleportState() != LLAgent::TELEPORT_NONE) +	{ +		clearFetchingRequests(); +		return; +	} +  	LLAppViewer::getTextureFetch()->setTextureBandwidth(LLViewerStats::getInstance()->mTextureKBitStat.getMeanPerSec());  	LLViewerStats::getInstance()->mNumImagesStat.addValue(sNumImages); @@ -659,6 +666,24 @@ void LLViewerTextureList::updateImages(F32 max_time)  	}  } +void LLViewerTextureList::clearFetchingRequests() +{ +	if (LLAppViewer::getTextureFetch()->getNumRequests() == 0) +	{ +		return; +	} + +	for (image_priority_list_t::iterator iter = mImageList.begin(); +		 iter != mImageList.end(); ++iter) +	{ +		LLViewerFetchedTexture* image = *iter; +		if(image->hasFetcher()) +		{ +			image->forceToDeleteRequest() ; +		} +	} +} +  void LLViewerTextureList::updateImagesDecodePriorities()  {  	// Update the decode priority for N images each frame @@ -1030,7 +1055,6 @@ LLPointer<LLImageJ2C> LLViewerTextureList::convertToUploadFile(LLPointer<LLImage  {  	raw_image->biasedScaleToPowerOfTwo(LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT);  	LLPointer<LLImageJ2C> compressedImage = new LLImageJ2C(); -	compressedImage->setRate(0.f);  	if (gSavedSettings.getBOOL("LosslessJ2CUpload") &&  		(raw_image->getWidth() * raw_image->getHeight() <= LL_IMAGE_REZ_LOSSLESS_CUTOFF * LL_IMAGE_REZ_LOSSLESS_CUTOFF)) diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h index b386c73d2a..e89997fe28 100644 --- a/indra/newview/llviewertexturelist.h +++ b/indra/newview/llviewertexturelist.h @@ -110,6 +110,8 @@ public:  	void doPreloadImages();  	void doPrefetchImages(); +	void clearFetchingRequests(); +  	static S32 getMinVideoRamSetting();  	static S32 getMaxVideoRamSetting(bool get_recommended = false); @@ -164,7 +166,7 @@ private:  	// Request image from a specific host, used for baked avatar textures.  	// Implemented in header in case someone changes default params above. JC  	LLViewerFetchedTexture* getImageFromHost(const LLUUID& image_id, LLHost host) -	{ return getImage(image_id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, host); } +	{ return getImage(image_id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, host); }	  public:  	typedef std::set<LLPointer<LLViewerFetchedTexture> > image_list_t;	 diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index a7a4281860..eada77156e 100644..100755 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -101,6 +101,8 @@  #include "llvoicevisualizer.h" // Ventrella  #include "lldebugmessagebox.h" +#include "llsdutil.h" +  extern F32 SPEED_ADJUST_MAX;  extern F32 SPEED_ADJUST_MAX_SEC;  extern F32 ANIM_SPEED_MAX; @@ -627,7 +629,6 @@ F32 LLVOAvatar::sLODFactor = 1.f;  F32 LLVOAvatar::sPhysicsLODFactor = 1.f;  BOOL LLVOAvatar::sUseImpostors = FALSE;  BOOL LLVOAvatar::sJointDebug = FALSE; -  F32 LLVOAvatar::sUnbakedTime = 0.f;  F32 LLVOAvatar::sUnbakedUpdateTime = 0.f;  F32 LLVOAvatar::sGreyTime = 0.f; @@ -683,13 +684,16 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,  	mNeedsSkin(FALSE),  	mLastSkinTime(0.f),  	mUpdatePeriod(1), +	mFirstFullyVisible(TRUE),  	mFullyLoaded(FALSE),  	mPreviousFullyLoaded(FALSE),  	mFullyLoadedInitialized(FALSE),  	mSupportsAlphaLayers(FALSE),  	mLoadedCallbacksPaused(FALSE),  	mHasPelvisOffset( FALSE ), -	mRenderUnloadedAvatar(LLCachedControl<bool>(gSavedSettings, "RenderUnloadedAvatar")) +	mRenderUnloadedAvatar(LLCachedControl<bool>(gSavedSettings, "RenderUnloadedAvatar")), +	mLastRezzedStatus(-1) +  {  	LLMemType mt(LLMemType::MTYPE_AVATAR);  	//VTResume();  // VTune @@ -770,32 +774,46 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,  	mLastPelvisFixup = 0.0f;  } +std::string LLVOAvatar::avString() const +{ +	std::string viz_string = LLVOAvatar::rezStatusToString(getRezzedStatus()); +	return " Avatar '" + getFullname() + "' " + viz_string + " "; +} + +void LLVOAvatar::debugAvatarRezTime(std::string notification_name, std::string comment) +{ +	LL_INFOS("Avatar") << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() +					   << "sec ]" +					   << avString()  +					   << "RuthTimer " << (U32)mRuthDebugTimer.getElapsedTimeF32() +					   << " Notification " << notification_name +					   << " : " << comment +					   << llendl; + +	if (gSavedSettings.getBOOL("DebugAvatarRezTime")) +	{ +		LLSD args; +		args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32()); +		args["TIME"] = llformat("%d",(U32)mRuthDebugTimer.getElapsedTimeF32()); +		args["NAME"] = getFullname(); +		LLNotificationsUtil::add(notification_name,args); +	} +} +  //------------------------------------------------------------------------  // LLVOAvatar::~LLVOAvatar()  //------------------------------------------------------------------------  LLVOAvatar::~LLVOAvatar()  { -	if (gSavedSettings.getBOOL("DebugAvatarRezTime")) +	if (!mFullyLoaded)  	{ -		if (!mFullyLoaded) -		{ -			llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' left after " << (U32)mRuthDebugTimer.getElapsedTimeF32() << " seconds as cloud." << llendl; -			LLSD args; -			args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32()); -			args["TIME"] = llformat("%d",(U32)mRuthDebugTimer.getElapsedTimeF32()); -			args["NAME"] = getFullname(); -			LLNotificationsUtil::add("AvatarRezLeftCloudNotification",args); -		} -		else -		{ -			llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' left." << llendl; -			LLSD args; -			args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32()); -			args["NAME"] = getFullname(); -			LLNotificationsUtil::add("AvatarRezLeftNotification",args); -		} - +		debugAvatarRezTime("AvatarRezLeftCloudNotification","left after ruth seconds as cloud");  	} +	else +	{ +		debugAvatarRezTime("AvatarRezLeftNotification","left sometime after declouding"); +	} +  	lldebugs << "LLVOAvatar Destructor (0x" << this << ") id:" << mID << llendl;  	mRoot.removeAllChildren(); @@ -844,6 +862,8 @@ LLVOAvatar::~LLVOAvatar()  	mAnimationSources.clear();  	LLLoadedCallbackEntry::cleanUpCallbackList(&mCallbackTextureList) ; +	getPhases().clearPhases(); +	  	lldebugs << "LLVOAvatar Destructor end" << llendl;  } @@ -877,6 +897,55 @@ BOOL LLVOAvatar::isFullyBaked()  	return TRUE;  } +BOOL LLVOAvatar::isFullyTextured() const +{ +	for (S32 i = 0; i < mMeshLOD.size(); i++) +	{ +		LLViewerJoint* joint = (LLViewerJoint*) mMeshLOD[i]; +		if (i==MESH_ID_SKIRT && !isWearingWearableType(LLWearableType::WT_SKIRT)) +		{ +			continue; // don't care about skirt textures if we're not wearing one. +		} +		if (!joint) +		{ +			continue; // nonexistent LOD OK. +		} +		std::vector<LLViewerJointMesh*>::iterator meshIter = joint->mMeshParts.begin(); +		if (meshIter != joint->mMeshParts.end()) +		{ +			LLViewerJointMesh *mesh = (LLViewerJointMesh *) *meshIter; +			if (!mesh) +			{ +				continue; // nonexistent mesh OK +			} +			if (mesh->mTexture.notNull() && mesh->mTexture->hasGLTexture()) +			{ +				continue; // Mesh exists and has a baked texture. +			} +			if (mesh->mLayerSet && mesh->mLayerSet->hasComposite()) +			{ +				continue; // Mesh exists and has a composite texture. +			} +			// Fail +			return FALSE; +		} +	} +	return TRUE; +} + +BOOL LLVOAvatar::hasGray() const +{ +	return !getIsCloud() && !isFullyTextured(); +} + +S32 LLVOAvatar::getRezzedStatus() const +{ +	if (getIsCloud()) return 0; +	if (isFullyTextured()) return 2; +	llassert(hasGray()); +	return 1; // gray +} +  void LLVOAvatar::deleteLayerSetCaches(bool clearAll)  {  	for (U32 i = 0; i < mBakedTextureDatas.size(); i++) @@ -924,6 +993,31 @@ BOOL LLVOAvatar::areAllNearbyInstancesBaked(S32& grey_avatars)  }  // static +void LLVOAvatar::getNearbyRezzedStats(std::vector<S32>& counts) +{ +	counts.clear(); +	counts.resize(3); +	for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin(); +		 iter != LLCharacter::sInstances.end(); ++iter) +	{ +		LLVOAvatar* inst = (LLVOAvatar*) *iter; +		if (!inst) +			continue; +		S32 rez_status = inst->getRezzedStatus(); +		counts[rez_status]++; +	} +} + +// static +std::string LLVOAvatar::rezStatusToString(S32 rez_status) +{ +	if (rez_status==0) return "cloud"; +	if (rez_status==1) return "gray"; +	if (rez_status==2) return "textured"; +	return "unknown"; +} + +// static  void LLVOAvatar::dumpBakedStatus()  {  	LLVector3d camera_pos_global = gAgentCamera.getCameraPositionGlobal(); @@ -2248,18 +2342,12 @@ U32 LLVOAvatar::processUpdateMessage(LLMessageSystem *mesgsys,  	U32 retval = LLViewerObject::processUpdateMessage(mesgsys, user_data, block_num, update_type, dp);  	// Print out arrival information once we have name of avatar. -	if (gSavedSettings.getBOOL("DebugAvatarRezTime")) +	if (has_name && getNVPair("FirstName"))  	{ -		if (has_name && getNVPair("FirstName")) -		{ -			mDebugExistenceTimer.reset(); -			LLSD args; -			args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32()); -			args["NAME"] = getFullname(); -			LLNotificationsUtil::add("AvatarRezArrivedNotification",args); -			llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' arrived." << llendl; -		} +		mDebugExistenceTimer.reset(); +		debugAvatarRezTime("AvatarRezArrivedNotification","avatar arrived");  	} +  	if(retval & LLViewerObject::INVALID_UPDATE)  	{  		if (isSelf()) @@ -2765,16 +2853,16 @@ void LLVOAvatar::idleUpdateLoadingEffect()  	// update visibility when avatar is partially loaded  	if (updateIsFullyLoaded()) // changed?  	{ -		if (isFullyLoaded() && isSelf()) +		if (isFullyLoaded() && mFirstFullyVisible && isSelf())  		{ -			static bool first_fully_visible = true; -			if (first_fully_visible) -			{ -				llinfos << "self isFullyLoaded, first_fully_visible" << llendl; - -				first_fully_visible = false; -				LLAppearanceMgr::instance().onFirstFullyVisible(); -			} +			LL_INFOS("Avatar") << avString() << "self isFullyLoaded, mFirstFullyVisible" << LL_ENDL; +			mFirstFullyVisible = FALSE; +			LLAppearanceMgr::instance().onFirstFullyVisible(); +		} +		if (isFullyLoaded() && mFirstFullyVisible && !isSelf()) +		{ +			LL_INFOS("Avatar") << avString() << "other isFullyLoaded, mFirstFullyVisible" << LL_ENDL; +			mFirstFullyVisible = FALSE;  		}  		if (isFullyLoaded())  		{ @@ -2918,43 +3006,43 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)  		return;  	} -		BOOL new_name = FALSE; -		if (visible_chat != mVisibleChat) +	BOOL new_name = FALSE; +	if (visible_chat != mVisibleChat) +	{ +		mVisibleChat = visible_chat; +		new_name = TRUE; +	} +		 +	if (sRenderGroupTitles != mRenderGroupTitles) +	{ +		mRenderGroupTitles = sRenderGroupTitles; +		new_name = TRUE; +	} + +	// First Calculate Alpha +	// If alpha > 0, create mNameText if necessary, otherwise delete it +	F32 alpha = 0.f; +	if (mAppAngle > 5.f) +	{ +		const F32 START_FADE_TIME = NAME_SHOW_TIME - FADE_DURATION; +		if (!visible_chat && sRenderName == RENDER_NAME_FADE && time_visible > START_FADE_TIME)  		{ -			mVisibleChat = visible_chat; -			new_name = TRUE; +			alpha = 1.f - (time_visible - START_FADE_TIME) / FADE_DURATION;  		} -		 -		if (sRenderGroupTitles != mRenderGroupTitles) +		else  		{ -			mRenderGroupTitles = sRenderGroupTitles; -			new_name = TRUE; +			// ...not fading, full alpha +			alpha = 1.f;  		} - -		// First Calculate Alpha -		// If alpha > 0, create mNameText if necessary, otherwise delete it -			F32 alpha = 0.f; -			if (mAppAngle > 5.f) -			{ -				const F32 START_FADE_TIME = NAME_SHOW_TIME - FADE_DURATION; -				if (!visible_chat && sRenderName == RENDER_NAME_FADE && time_visible > START_FADE_TIME) -				{ -					alpha = 1.f - (time_visible - START_FADE_TIME) / FADE_DURATION; -				} -				else -				{ -					// ...not fading, full alpha -					alpha = 1.f; -				} -			} -			else if (mAppAngle > 2.f) -			{ -				// far away is faded out also -				alpha = (mAppAngle-2.f)/3.f; -			} +	} +	else if (mAppAngle > 2.f) +	{ +		// far away is faded out also +		alpha = (mAppAngle-2.f)/3.f; +	}  	if (alpha <= 0.f) -			{ +	{  		if (mNameText)  		{  			mNameText->markDead(); @@ -2964,19 +3052,19 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)  		return;  	} -				if (!mNameText) -				{ +	if (!mNameText) +	{  		mNameText = static_cast<LLHUDNameTag*>( LLHUDObject::addHUDObject( -			LLHUDObject::LL_HUD_NAME_TAG) ); +													LLHUDObject::LL_HUD_NAME_TAG) );  		//mNameText->setMass(10.f); -					mNameText->setSourceObject(this); +		mNameText->setSourceObject(this);  		mNameText->setVertAlignment(LLHUDNameTag::ALIGN_VERT_TOP); -					mNameText->setVisibleOffScreen(TRUE); -					mNameText->setMaxLines(11); -					mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f); -					sNumVisibleChatBubbles++; -					new_name = TRUE; -				} +		mNameText->setVisibleOffScreen(TRUE); +		mNameText->setMaxLines(11); +		mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f); +		sNumVisibleChatBubbles++; +		new_name = TRUE; +	}  	LLVector3 name_position = idleUpdateNameTagPosition(root_pos_last);  	mNameText->setPositionAgent(name_position);				 @@ -2985,10 +3073,10 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)  }  void LLVOAvatar::idleUpdateNameTagText(BOOL new_name) -			{ -		LLNameValue *title = getNVPair("Title"); -		LLNameValue* firstname = getNVPair("FirstName"); -		LLNameValue* lastname = getNVPair("LastName"); +{ +	LLNameValue *title = getNVPair("Title"); +	LLNameValue* firstname = getNVPair("FirstName"); +	LLNameValue* lastname = getNVPair("LastName");  	// Avatars must have a first and last name  	if (!firstname || !lastname) return; @@ -3002,34 +3090,23 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)  		is_muted = false;  	}  	else -		{ +	{  		is_muted = LLMuteList::getInstance()->isMuted(getID());  	}  	bool is_friend = LLAvatarTracker::instance().isBuddy(getID());  	bool is_cloud = getIsCloud(); -			if (gSavedSettings.getBOOL("DebugAvatarRezTime")) -			{ -				if (is_appearance != mNameAppearance) -				{ -					if (is_appearance) -					{ -						LLSD args; -						args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32()); -						args["NAME"] = getFullname(); -						LLNotificationsUtil::add("AvatarRezEnteredAppearanceNotification",args); -						llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' entered appearance mode." << llendl; -					} -					else -					{ -						LLSD args; -						args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32()); -						args["NAME"] = getFullname(); -						LLNotificationsUtil::add("AvatarRezLeftAppearanceNotification",args); -						llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' left appearance mode." << llendl; -					} -				} -			} +	if (is_appearance != mNameAppearance) +	{ +		if (is_appearance) +		{ +			debugAvatarRezTime("AvatarRezEnteredAppearanceNotification","entered appearance mode"); +		} +		else +		{ +			debugAvatarRezTime("AvatarRezLeftAppearanceNotification","left appearance mode"); +		} +	}  	// Rebuild name tag if state change detected  	if (mNameString.empty() @@ -3039,56 +3116,56 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)  		|| is_away != mNameAway   		|| is_busy != mNameBusy   		|| is_muted != mNameMute -				|| is_appearance != mNameAppearance  +		|| is_appearance != mNameAppearance   		|| is_friend != mNameFriend  		|| is_cloud != mNameCloud) -				{ +	{  		LLColor4 name_tag_color = getNameTagColor(is_friend);  		clearNameTag();  		if (is_away || is_muted || is_busy || is_appearance) -				{ +		{  			std::string line; -					if (is_away) -					{ -						line += LLTrans::getString("AvatarAway"); +			if (is_away) +			{ +				line += LLTrans::getString("AvatarAway");  				line += ", "; -					} -					if (is_busy) -					{ +			} +			if (is_busy) +			{  				line += LLTrans::getString("AvatarBusy");  				line += ", ";  			}  			if (is_muted) -						{ +			{  				line += LLTrans::getString("AvatarMuted"); -							line += ", "; -						} +				line += ", "; +			}  			if (is_appearance)  			{  				line += LLTrans::getString("AvatarEditingAppearance");  				line += ", "; -					} +			}  			if (is_cloud) -					{ +			{  				line += LLTrans::getString("LoadingData");  				line += ", ";  			}  			// trim last ", "  			line.resize( line.length() - 2 );  			addNameTagLine(line, name_tag_color, LLFontGL::NORMAL, -				LLFontGL::getFontSansSerifSmall()); +						   LLFontGL::getFontSansSerifSmall());  		}  		if (sRenderGroupTitles  			&& title && title->getString() && title->getString()[0] != '\0') -						{ +		{  			std::string title_str = title->getString();  			LLStringFn::replace_ascii_controlchars(title_str,LL_UNKNOWN_CHAR);  			addNameTagLine(title_str, name_tag_color, LLFontGL::NORMAL, -				LLFontGL::getFontSansSerifSmall()); -						} +						   LLFontGL::getFontSansSerifSmall()); +		}  		static LLUICachedControl<bool> show_display_names("NameTagShowDisplayNames");  		static LLUICachedControl<bool> show_usernames("NameTagShowUsernames"); @@ -3101,120 +3178,120 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)  				// ...call this function back when the name arrives  				// and force a rebuild  				LLAvatarNameCache::get(getID(), -					boost::bind(&LLVOAvatar::clearNameTag, this)); -					} +									   boost::bind(&LLVOAvatar::clearNameTag, this)); +			}  			// Might be blank if name not available yet, that's OK  			if (show_display_names)  			{  				addNameTagLine(av_name.mDisplayName, name_tag_color, LLFontGL::NORMAL, -					LLFontGL::getFontSansSerif()); -				} +							   LLFontGL::getFontSansSerif()); +			}  			// Suppress SLID display if display name matches exactly (ugh)  			if (show_usernames && !av_name.mIsDisplayNameDefault) -				{ +			{  				// *HACK: Desaturate the color  				LLColor4 username_color = name_tag_color * 0.83f;  				addNameTagLine(av_name.mUsername, username_color, LLFontGL::NORMAL, -					LLFontGL::getFontSansSerifSmall()); +							   LLFontGL::getFontSansSerifSmall());  			} -				} +		}  		else -				{ +		{  			const LLFontGL* font = LLFontGL::getFontSansSerif();  			std::string full_name =  				LLCacheName::buildFullName( firstname->getString(), lastname->getString() );  			addNameTagLine(full_name, name_tag_color, LLFontGL::NORMAL, font); -				} +		} -				mNameAway = is_away; -				mNameBusy = is_busy; -				mNameMute = is_muted; -				mNameAppearance = is_appearance; +		mNameAway = is_away; +		mNameBusy = is_busy; +		mNameMute = is_muted; +		mNameAppearance = is_appearance;  		mNameFriend = is_friend; -				mNameCloud = is_cloud; -				mTitle = title ? title->getString() : ""; -				LLStringFn::replace_ascii_controlchars(mTitle,LL_UNKNOWN_CHAR); -				new_name = TRUE; -			} +		mNameCloud = is_cloud; +		mTitle = title ? title->getString() : ""; +		LLStringFn::replace_ascii_controlchars(mTitle,LL_UNKNOWN_CHAR); +		new_name = TRUE; +	}  	if (mVisibleChat) -			{ -				mNameText->setFont(LLFontGL::getFontSansSerif()); +	{ +		mNameText->setFont(LLFontGL::getFontSansSerif());  		mNameText->setTextAlignment(LLHUDNameTag::ALIGN_TEXT_LEFT); -				mNameText->setFadeDistance(CHAT_NORMAL_RADIUS * 2.f, 5.f); +		mNameText->setFadeDistance(CHAT_NORMAL_RADIUS * 2.f, 5.f); -				char line[MAX_STRING];		/* Flawfinder: ignore */ -				line[0] = '\0'; -				std::deque<LLChat>::iterator chat_iter = mChats.begin(); -				mNameText->clearString(); - -				LLColor4 new_chat = LLUIColorTable::instance().getColor( isSelf() ? "UserChatColor" : "AgentChatColor" ); -				LLColor4 normal_chat = lerp(new_chat, LLColor4(0.8f, 0.8f, 0.8f, 1.f), 0.7f); -				LLColor4 old_chat = lerp(normal_chat, LLColor4(0.6f, 0.6f, 0.6f, 1.f), 0.7f); -				if (mTyping && mChats.size() >= MAX_BUBBLE_CHAT_UTTERANCES)  -				{ -					++chat_iter; -				} +		char line[MAX_STRING];		/* Flawfinder: ignore */ +		line[0] = '\0'; +		std::deque<LLChat>::iterator chat_iter = mChats.begin(); +		mNameText->clearString(); -				for(; chat_iter != mChats.end(); ++chat_iter) -				{ -					F32 chat_fade_amt = llclamp((F32)((LLFrameTimer::getElapsedSeconds() - chat_iter->mTime) / CHAT_FADE_TIME), 0.f, 4.f); -					LLFontGL::StyleFlags style; -					switch(chat_iter->mChatType) -					{ -						case CHAT_TYPE_WHISPER: -							style = LLFontGL::ITALIC; -							break; -						case CHAT_TYPE_SHOUT: -							style = LLFontGL::BOLD; -							break; -						default: -							style = LLFontGL::NORMAL; -							break; -					} -					if (chat_fade_amt < 1.f) -					{ -						F32 u = clamp_rescale(chat_fade_amt, 0.9f, 1.f, 0.f, 1.f); -						mNameText->addLine(chat_iter->mText, lerp(new_chat, normal_chat, u), style); -					} -					else if (chat_fade_amt < 2.f) -					{ -						F32 u = clamp_rescale(chat_fade_amt, 1.9f, 2.f, 0.f, 1.f); -						mNameText->addLine(chat_iter->mText, lerp(normal_chat, old_chat, u), style); -					} -					else if (chat_fade_amt < 3.f) -					{ -						// *NOTE: only remove lines down to minimum number -						mNameText->addLine(chat_iter->mText, old_chat, style); -					} -				} -				mNameText->setVisibleOffScreen(TRUE); - -				if (mTyping) -				{ -					S32 dot_count = (llfloor(mTypingTimer.getElapsedTimeF32() * 3.f) + 2) % 3 + 1; -					switch(dot_count) -					{ -						case 1: -							mNameText->addLine(".", new_chat); -							break; -						case 2: -							mNameText->addLine("..", new_chat); -							break; -						case 3: -							mNameText->addLine("...", new_chat); -							break; -					} +		LLColor4 new_chat = LLUIColorTable::instance().getColor( isSelf() ? "UserChatColor" : "AgentChatColor" ); +		LLColor4 normal_chat = lerp(new_chat, LLColor4(0.8f, 0.8f, 0.8f, 1.f), 0.7f); +		LLColor4 old_chat = lerp(normal_chat, LLColor4(0.6f, 0.6f, 0.6f, 1.f), 0.7f); +		if (mTyping && mChats.size() >= MAX_BUBBLE_CHAT_UTTERANCES)  +		{ +			++chat_iter; +		} -				} +		for(; chat_iter != mChats.end(); ++chat_iter) +		{ +			F32 chat_fade_amt = llclamp((F32)((LLFrameTimer::getElapsedSeconds() - chat_iter->mTime) / CHAT_FADE_TIME), 0.f, 4.f); +			LLFontGL::StyleFlags style; +			switch(chat_iter->mChatType) +			{ +				case CHAT_TYPE_WHISPER: +				style = LLFontGL::ITALIC; +				break; +				case CHAT_TYPE_SHOUT: +				style = LLFontGL::BOLD; +				break; +				default: +				style = LLFontGL::NORMAL; +				break;  			} -			else +			if (chat_fade_amt < 1.f) +			{ +				F32 u = clamp_rescale(chat_fade_amt, 0.9f, 1.f, 0.f, 1.f); +				mNameText->addLine(chat_iter->mText, lerp(new_chat, normal_chat, u), style); +			} +			else if (chat_fade_amt < 2.f) +			{ +				F32 u = clamp_rescale(chat_fade_amt, 1.9f, 2.f, 0.f, 1.f); +				mNameText->addLine(chat_iter->mText, lerp(normal_chat, old_chat, u), style); +			} +			else if (chat_fade_amt < 3.f) +			{ +				// *NOTE: only remove lines down to minimum number +				mNameText->addLine(chat_iter->mText, old_chat, style); +			} +		} +		mNameText->setVisibleOffScreen(TRUE); + +		if (mTyping) +		{ +			S32 dot_count = (llfloor(mTypingTimer.getElapsedTimeF32() * 3.f) + 2) % 3 + 1; +			switch(dot_count)  			{ +				case 1: +				mNameText->addLine(".", new_chat); +				break; +				case 2: +				mNameText->addLine("..", new_chat); +				break; +				case 3: +				mNameText->addLine("...", new_chat); +				break; +			} + +		} +	} +	else +	{  		// ...not using chat bubbles, just names  		mNameText->setTextAlignment(LLHUDNameTag::ALIGN_TEXT_CENTER); -				mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f); -				mNameText->setVisibleOffScreen(FALSE); +		mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f); +		mNameText->setVisibleOffScreen(FALSE);  	}  } @@ -3237,8 +3314,8 @@ void LLVOAvatar::clearNameTag()  {  	mNameString.clear();  	if (mNameText) -				{ -					mNameText->setLabel(""); +	{ +		mNameText->setLabel("");  		mNameText->setString( "" );  	}  } @@ -3964,7 +4041,7 @@ void LLVOAvatar::updateVisibility()  			LLNameValue* firstname = getNVPair("FirstName");  			if (firstname)  			{ -				llinfos << "Avatar " << firstname->getString() << " updating visiblity" << llendl; +				LL_DEBUGS("Avatar") << avString() << " updating visibility" << LL_ENDL;  			}  			else  			{ @@ -4130,11 +4207,11 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)  	{	//LOD changed or new mesh created, allocate new vertex buffer if needed  		if (needs_rebuild || mDirtyMesh >= 2 || mVisibilityRank <= 4)  		{ -		updateMeshData(); +			updateMeshData();  			mDirtyMesh = 0; -		mNeedsSkin = TRUE; -		mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY); -	} +			mNeedsSkin = TRUE; +			mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY); +		}  	}  	if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) <= 0) @@ -4176,7 +4253,7 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)  		LLNameValue* firstname = getNVPair("FirstName");  		if (firstname)  		{ -			llinfos << "Avatar " << firstname->getString() << " in render" << llendl; +			LL_DEBUGS("Avatar") << avString() << " in render" << LL_ENDL;  		}  		else  		{ @@ -6393,10 +6470,10 @@ BOOL LLVOAvatar::isVisible() const  }  // Determine if we have enough avatar data to render -BOOL LLVOAvatar::getIsCloud() +BOOL LLVOAvatar::getIsCloud() const  {  	// Do we have a shape? -	if (visualParamWeightsAreDefault()) +	if ((const_cast<LLVOAvatar*>(this))->visualParamWeightsAreDefault())  	{  		return TRUE;  	} @@ -6415,11 +6492,53 @@ BOOL LLVOAvatar::getIsCloud()  	return FALSE;  } +void LLVOAvatar::updateRezzedStatusTimers() +{ +	// State machine for rezzed status. Statuses are 0 = cloud, 1 = gray, 2 = textured. +	// Purpose is to collect time data for each period of cloud or cloud+gray. +	S32 rez_status = getRezzedStatus(); +	if (rez_status != mLastRezzedStatus) +	{ +		LL_DEBUGS("Avatar") << avString() << "rez state change: " << mLastRezzedStatus << " -> " << rez_status << LL_ENDL; +		bool is_cloud_or_gray = (rez_status==0 || rez_status==1); +		bool was_cloud_or_gray = (mLastRezzedStatus==0 || mLastRezzedStatus==1); +		bool is_cloud = (rez_status==0); +		bool was_cloud = (mLastRezzedStatus==0); + +		// Non-cloud to cloud +		if (is_cloud && !was_cloud) +		{ +			// start cloud timer. +			getPhases().startPhase("cloud"); +		} +		else if (was_cloud && !is_cloud) +		{ +			// stop cloud timer, which will capture stats. +			getPhases().stopPhase("cloud"); +		} + +		// Non-cloud-or-gray to cloud-or-gray +		if (is_cloud_or_gray && !was_cloud_or_gray) +		{ +			// start cloud-or-gray timer. +			getPhases().startPhase("cloud-or-gray"); +		} +		else if (was_cloud_or_gray && !is_cloud_or_gray) +		{ +			// stop cloud-or-gray timer, which will capture stats. +			getPhases().stopPhase("cloud-or-gray"); +		} +		 +		mLastRezzedStatus = rez_status; +	} +} +  // call periodically to keep isFullyLoaded up to date.  // returns true if the value has changed.  BOOL LLVOAvatar::updateIsFullyLoaded()  {  	const BOOL loading = getIsCloud(); +	updateRezzedStatusTimers();  	updateRuthTimer(loading);  	return processFullyLoadedChange(loading);  } @@ -6434,27 +6553,19 @@ void LLVOAvatar::updateRuthTimer(bool loading)  	if (mPreviousFullyLoaded)  	{  		mRuthTimer.reset(); -		if (gSavedSettings.getBOOL("DebugAvatarRezTime")) -		{ -			llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' became cloud." << llendl; -			LLSD args; -			args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32()); -			args["TIME"] = llformat("%d",(U32)mRuthDebugTimer.getElapsedTimeF32()); -			args["NAME"] = getFullname(); -			LLNotificationsUtil::add("AvatarRezCloudNotification",args); -		} -		mRuthDebugTimer.reset(); +		debugAvatarRezTime("AvatarRezCloudNotification","became cloud");  	}  	const F32 LOADING_TIMEOUT__SECONDS = 120.f;  	if (mRuthTimer.getElapsedTimeF32() > LOADING_TIMEOUT__SECONDS)  	{ -		llinfos << "Ruth Timer timeout: Missing texture data for '" << getFullname() << "' " +		LL_DEBUGS("Avatar") << avString() +				<< "Ruth Timer timeout: Missing texture data for '" << getFullname() << "' "  				<< "( Params loaded : " << !visualParamWeightsAreDefault() << " ) "  				<< "( Lower : " << isTextureDefined(TEX_LOWER_BAKED) << " ) "  				<< "( Upper : " << isTextureDefined(TEX_UPPER_BAKED) << " ) "  				<< "( Head : " << isTextureDefined(TEX_HEAD_BAKED) << " )." -				<< llendl; +				<< LL_ENDL;  		LLAvatarPropertiesProcessor::getInstance()->sendAvatarTexturesRequest(getID());  		mRuthTimer.reset(); @@ -6471,20 +6582,13 @@ BOOL LLVOAvatar::processFullyLoadedChange(bool loading)  	mFullyLoaded = (mFullyLoadedTimer.getElapsedTimeF32() > PAUSE); -	if (gSavedSettings.getBOOL("DebugAvatarRezTime")) +	if (!mPreviousFullyLoaded && !loading && mFullyLoaded)  	{ -		if (!mPreviousFullyLoaded && !loading && mFullyLoaded) -		{ -			llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' resolved in " << (U32)mRuthDebugTimer.getElapsedTimeF32() << " seconds." << llendl; -			LLSD args; -			args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32()); -			args["TIME"] = llformat("%d",(U32)mRuthDebugTimer.getElapsedTimeF32()); -			args["NAME"] = getFullname(); -			LLNotificationsUtil::add("AvatarRezNotification",args); -		} +		debugAvatarRezTime("AvatarRezNotification","fully loaded");  	}  	// did our loading state "change" from last call? +	// runway - why are we updating every 30 calls even if nothing has changed?  	const S32 UPDATE_RATE = 30;  	BOOL changed =  		((mFullyLoaded != mPreviousFullyLoaded) ||         // if the value is different from the previous call @@ -6924,7 +7028,7 @@ LLColor4 LLVOAvatar::getDummyColor()  void LLVOAvatar::dumpAvatarTEs( const std::string& context ) const  {	 -	llinfos << (isSelf() ? "Self: " : "Other: ") << context << llendl; +	LL_DEBUGS("Avatar") << avString() << (isSelf() ? "Self: " : "Other: ") << context << LL_ENDL;  	for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();  		 iter != LLVOAvatarDictionary::getInstance()->getTextures().end();  		 ++iter) @@ -6934,23 +7038,23 @@ void LLVOAvatar::dumpAvatarTEs( const std::string& context ) const  		const LLViewerTexture* te_image = getImage(iter->first,0);  		if( !te_image )  		{ -			llinfos << "       " << texture_dict->mName << ": null ptr" << llendl; +			LL_DEBUGS("Avatar") << avString() << "       " << texture_dict->mName << ": null ptr" << LL_ENDL;  		}  		else if( te_image->getID().isNull() )  		{ -			llinfos << "       " << texture_dict->mName << ": null UUID" << llendl; +			LL_DEBUGS("Avatar") << avString() << "       " << texture_dict->mName << ": null UUID" << LL_ENDL;  		}  		else if( te_image->getID() == IMG_DEFAULT )  		{ -			llinfos << "       " << texture_dict->mName << ": IMG_DEFAULT" << llendl; +			LL_DEBUGS("Avatar") << avString() << "       " << texture_dict->mName << ": IMG_DEFAULT" << LL_ENDL;  		}  		else if( te_image->getID() == IMG_DEFAULT_AVATAR )  		{ -			llinfos << "       " << texture_dict->mName << ": IMG_DEFAULT_AVATAR" << llendl; +			LL_DEBUGS("Avatar") << avString() << "       " << texture_dict->mName << ": IMG_DEFAULT_AVATAR" << LL_ENDL;  		}  		else  		{ -			llinfos << "       " << texture_dict->mName << ": " << te_image->getID() << llendl; +			LL_DEBUGS("Avatar") << avString() << "       " << texture_dict->mName << ": " << te_image->getID() << LL_ENDL;  		}  	}  } @@ -7081,6 +7185,7 @@ void LLVOAvatar::rebuildHUD()  //-----------------------------------------------------------------------------  void LLVOAvatar::onFirstTEMessageReceived()  { +	LL_INFOS("Avatar") << avString() << LL_ENDL;  	if( !mFirstTEMessageReceived )  	{  		mFirstTEMessageReceived = TRUE; @@ -7109,6 +7214,7 @@ void LLVOAvatar::onFirstTEMessageReceived()  					image->setLoadedCallback( onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, TRUE, new LLTextureMaskData( mID ),   						src_callback_list, paused);  				} +				LL_DEBUGS("Avatar") << avString() << "layer_baked, setting onInitialBakedTextureLoaded as callback" << LL_ENDL;  				image->setLoadedCallback( onInitialBakedTextureLoaded, MAX_DISCARD_LEVEL, FALSE, FALSE, new LLUUID( mID ),   					src_callback_list, paused );  			} @@ -7167,14 +7273,16 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )  	LLMemType mt(LLMemType::MTYPE_AVATAR); -//	llinfos << "processAvatarAppearance start " << mID << llendl;  	BOOL is_first_appearance_message = !mFirstAppearanceMessageReceived; -  	mFirstAppearanceMessageReceived = TRUE; +	LL_INFOS("Avatar") << avString() << "processAvatarAppearance start " << mID +			<< " first? " << is_first_appearance_message << " self? " << isSelf() << LL_ENDL; + +  	if( isSelf() )  	{ -		llwarns << "Received AvatarAppearance for self" << llendl; +		llwarns << avString() << "Received AvatarAppearance for self" << llendl;  		if( mFirstTEMessageReceived )  		{  //			llinfos << "processAvatarAppearance end  " << mID << llendl; @@ -7202,7 +7310,10 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )  	} -	if( !is_first_appearance_message ) +	// runway - was +	// if (!is_first_appearance_message ) +	// which means it would be called on second appearance message - probably wrong. +	if (is_first_appearance_message )  	{  		onFirstTEMessageReceived();  	} @@ -7223,6 +7334,7 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )  	bool drop_visual_params_debug = gSavedSettings.getBOOL("BlockSomeAvatarAppearanceVisualParams") && (ll_rand(2) == 0); // pretend that ~12% of AvatarAppearance messages arrived without a VisualParam block, for testing  	if( num_blocks > 1 && !drop_visual_params_debug)  	{ +		LL_DEBUGS("Avatar") << avString() << " handle visual params, num_blocks " << num_blocks << LL_ENDL;  		BOOL params_changed = FALSE;  		BOOL interp_params = FALSE; @@ -7295,6 +7407,7 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )  	else  	{  		// AvatarAppearance message arrived without visual params +		LL_DEBUGS("Avatar") << avString() << "no visual params" << LL_ENDL;  		if (drop_visual_params_debug)  		{  			llinfos << "Debug-faked lack of parameters on AvatarAppearance for object: "  << getID() << llendl; @@ -7447,8 +7560,15 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture  // static  void LLVOAvatar::onInitialBakedTextureLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata )  { + +	  	LLUUID *avatar_idp = (LLUUID *)userdata;  	LLVOAvatar *selfp = (LLVOAvatar *)gObjectList.findObject(*avatar_idp); +	 +	if (selfp) +	{ +		LL_DEBUGS("Avatar") << selfp->avString() << "discard_level " << discard_level << " success " << success << " final " << final << LL_ENDL; +	}  	if (!success && selfp)  	{ @@ -7460,13 +7580,20 @@ void LLVOAvatar::onInitialBakedTextureLoaded( BOOL success, LLViewerFetchedTextu  	}  } -void LLVOAvatar::onBakedTextureLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata) +// Static +void LLVOAvatar::onBakedTextureLoaded(BOOL success, +									  LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, +									  S32 discard_level, BOOL final, void* userdata)  {  	//llinfos << "onBakedTextureLoaded: " << src_vi->getID() << llendl;  	LLUUID id = src_vi->getID();  	LLUUID *avatar_idp = (LLUUID *)userdata;  	LLVOAvatar *selfp = (LLVOAvatar *)gObjectList.findObject(*avatar_idp); +	if (selfp) +	{	 +		LL_DEBUGS("Avatar") << selfp->avString() << "discard_level " << discard_level << " success " << success << " final " << final << " id " << src_vi->getID() << LL_ENDL; +	}  	if (selfp && !success)  	{ @@ -7488,6 +7615,8 @@ void LLVOAvatar::onBakedTextureLoaded(BOOL success, LLViewerFetchedTexture *src_  // Called when baked texture is loaded and also when we start up with a baked texture  void LLVOAvatar::useBakedTexture( const LLUUID& id )  { + +	  	/* if(id == head_baked->getID())  		 mHeadBakedLoaded = TRUE;  		 mLastHeadBakedID = id; @@ -7498,6 +7627,7 @@ void LLVOAvatar::useBakedTexture( const LLUUID& id )  		LLViewerTexture* image_baked = getImage( mBakedTextureDatas[i].mTextureIndex, 0 );  		if (id == image_baked->getID())  		{ +			LL_DEBUGS("Avatar") << avString() << " i " << i << " id " << id << LL_ENDL;  			mBakedTextureDatas[i].mIsLoaded = true;  			mBakedTextureDatas[i].mLastTextureIndex = id;  			mBakedTextureDatas[i].mIsUsed = true; @@ -7672,6 +7802,9 @@ void LLVOAvatar::cullAvatarsByPixelArea()  		}  	} +	// runway - this doesn't detect gray/grey state. +	// think we just need to be checking self av since it's the only +	// one with lltexlayer stuff.  	S32 grey_avatars = 0;  	if (LLVOAvatar::areAllNearbyInstancesBaked(grey_avatars))  	{ @@ -8475,7 +8608,9 @@ void LLVOAvatar::idleUpdateRenderCost()  		}  	} -	setDebugText(llformat("%d", cost)); +	 +	std::string viz_string = LLVOAvatar::rezStatusToString(getRezzedStatus()); +	setDebugText(llformat("%s %d", viz_string.c_str(), cost));  	mVisualComplexity = cost;  	F32 green = 1.f-llclamp(((F32) cost-(F32)ARC_LIMIT)/(F32)ARC_LIMIT, 0.f, 1.f);  	F32 red = llmin((F32) cost/(F32)ARC_LIMIT, 1.f); diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 6a4e09593c..6fb56a4c0b 100644..100755 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -48,6 +48,7 @@  #include "lltexglobalcolor.h"  #include "lldriverparam.h"  #include "material_codes.h"		// LL_MCODE_END +#include "llviewerstats.h"  extern const LLUUID ANIM_AGENT_BODY_NOISE;  extern const LLUUID ANIM_AGENT_BREATHE_ROT; @@ -277,14 +278,27 @@ public:  public:  	BOOL			isFullyLoaded() const;  	bool			isTooComplex() const; -	bool visualParamWeightsAreDefault(); +	bool 			visualParamWeightsAreDefault(); +	virtual BOOL	getIsCloud() const; +	BOOL			isFullyTextured() const; +	BOOL			hasGray() const;  +	S32				getRezzedStatus() const; // 0 = cloud, 1 = gray, 2 = fully textured. +	void			updateRezzedStatusTimers(); + +	S32				mLastRezzedStatus; + +	LLViewerStats::PhaseMap& getPhases() +	{ +		return mPhases; +	} +  protected: -	virtual BOOL	getIsCloud();  	BOOL			updateIsFullyLoaded();  	BOOL			processFullyLoadedChange(bool loading);  	void			updateRuthTimer(bool loading);  	F32 			calcMorphAmount();  private: +	BOOL			mFirstFullyVisible;  	BOOL			mFullyLoaded;  	BOOL			mPreviousFullyLoaded;  	BOOL			mFullyLoadedInitialized; @@ -292,6 +306,28 @@ private:  	S32				mVisualComplexity;  	LLFrameTimer	mFullyLoadedTimer;  	LLFrameTimer	mRuthTimer; + +public: +	class ScopedPhaseSetter +	{ +	public: +		ScopedPhaseSetter(LLVOAvatar *avatarp, std::string phase_name): +			mAvatar(avatarp), mPhaseName(phase_name) +		{ +			if (mAvatar) { mAvatar->getPhases().startPhase(mPhaseName); } +		} +		~ScopedPhaseSetter() +		{ +			if (mAvatar) { mAvatar->getPhases().stopPhase(mPhaseName); } +		} +	private: +		std::string mPhaseName; +		LLVOAvatar* mAvatar; +	}; + +private: +	LLViewerStats::PhaseMap mPhases; +  protected:  	LLFrameTimer    mInvisibleTimer; @@ -518,9 +554,10 @@ public:  	virtual BOOL	isTextureVisible(LLVOAvatarDefines::ETextureIndex type, U32 index = 0) const;  	virtual BOOL	isTextureVisible(LLVOAvatarDefines::ETextureIndex type, LLWearable *wearable) const; -protected:  	BOOL			isFullyBaked();  	static BOOL		areAllNearbyInstancesBaked(S32& grey_avatars); +	static void		getNearbyRezzedStats(std::vector<S32>& counts); +	static std::string rezStatusToString(S32 status);  	//--------------------------------------------------------------------  	// Baked textures @@ -882,6 +919,7 @@ private:  public:  	std::string		getFullname() const; // Returns "FirstName LastName" +	std::string		avString() const; // Frequently used string in log messages "Avatar '<full name'"  protected:  	static void		getAnimLabels(LLDynamicArray<std::string>* labels);  	static void		getAnimNames(LLDynamicArray<std::string>* names);	 @@ -983,7 +1021,9 @@ private:  	// Avatar Rez Metrics  	//--------------------------------------------------------------------  public: +	void 			debugAvatarRezTime(std::string notification_name, std::string comment = "");  	F32				debugGetExistenceTimeElapsedF32() const { return mDebugExistenceTimer.getElapsedTimeF32(); } +  protected:  	LLFrameTimer	mRuthDebugTimer; // For tracking how long it takes for av to rez  	LLFrameTimer	mDebugExistenceTimer; // Debugging for how long the avatar has been in memory. diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index f063653cc5..d2609e5587 100644..100755 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -58,6 +58,8 @@  #include "llappearancemgr.h"  #include "llmeshrepository.h"  #include "llvovolume.h" +#include "llsdutil.h" +#include "llstartup.h"  #if LL_MSVC  // disable boost::lexical_cast warning @@ -75,6 +77,39 @@ BOOL isAgentAvatarValid()  			(!gAgentAvatarp->isDead()));  } +void selfStartPhase(const std::string& phase_name) +{ +	if (isAgentAvatarValid()) +	{ +		gAgentAvatarp->getPhases().startPhase(phase_name); +	} +} + +void selfStopPhase(const std::string& phase_name) +{ +	if (isAgentAvatarValid()) +	{ +		gAgentAvatarp->getPhases().stopPhase(phase_name); +	} +} + +void selfClearPhases() +{ +	if (isAgentAvatarValid()) +	{ +		gAgentAvatarp->getPhases().clearPhases(); +		gAgentAvatarp->mLastRezzedStatus = -1; +	} +} + +void selfStopAllPhases() +{ +	if (isAgentAvatarValid()) +	{ +		gAgentAvatarp->getPhases().stopAllPhases(); +	} +} +  using namespace LLVOAvatarDefines;  /********************************************************************************* @@ -131,7 +166,8 @@ LLVOAvatarSelf::LLVOAvatarSelf(const LLUUID& id,  	LLVOAvatar(id, pcode, regionp),  	mScreenp(NULL),  	mLastRegionHandle(0), -	mRegionCrossingCount(0) +	mRegionCrossingCount(0), +	mInitialBakesLoaded(false)  {  	gAgentWearables.setAvatarObject(this); @@ -164,6 +200,7 @@ void LLVOAvatarSelf::initInstance()  	{  		mDebugBakedTextureTimes[i][0] = -1.0f;  		mDebugBakedTextureTimes[i][1] = -1.0f; +		mInitialBakeIDs[i] = LLUUID::null;  	}  	status &= buildMenus(); @@ -762,6 +799,41 @@ void LLVOAvatarSelf::stopMotionFromSource(const LLUUID& source_id)  	}  } +//virtual +U32  LLVOAvatarSelf::processUpdateMessage(LLMessageSystem *mesgsys, +													 void **user_data, +													 U32 block_num, +													 const EObjectUpdateType update_type, +													 LLDataPacker *dp) +{ +	U32 retval = LLVOAvatar::processUpdateMessage(mesgsys,user_data,block_num,update_type,dp); + +	if (mInitialBakesLoaded == false && retval == 0x0) +	{ +		// call update textures to force the images to be created +		updateMeshTextures(); + +		// unpack the texture UUIDs to the texture slots +		retval = unpackTEMessage(mesgsys, _PREHASH_ObjectData, block_num); + +		// need to trigger a few operations to get the avatar to use the new bakes +		for (U32 i = 0; i < mBakedTextureDatas.size(); i++) +		{ +			const LLVOAvatarDefines::ETextureIndex te = mBakedTextureDatas[i].mTextureIndex; +			LLUUID texture_id = getTEImage(te)->getID(); +			setNewBakedTexture(te, texture_id); +			mInitialBakeIDs[i] = texture_id; +		} + +		onFirstTEMessageReceived(); + +		mInitialBakesLoaded = true; +	} + +	return retval; +} + +  void LLVOAvatarSelf::setLocalTextureTE(U8 te, LLViewerTexture* image, U32 index)  {  	if (te >= TEX_NUM_INDICES) @@ -1889,7 +1961,7 @@ void LLVOAvatarSelf::dumpTotalLocalTextureByteCount()  	llinfos << "Total Avatar LocTex GL:" << (gl_bytes/1024) << "KB" << llendl;  } -BOOL LLVOAvatarSelf::getIsCloud() +BOOL LLVOAvatarSelf::getIsCloud() const  {  	// do we have our body parts?  	if (gAgentWearables.getWearableCount(LLWearableType::WT_SHAPE) == 0 || @@ -2055,6 +2127,80 @@ const std::string LLVOAvatarSelf::debugDumpAllLocalTextureDataInfo() const  	return text;  } +// Dump avatar metrics data. +LLSD LLVOAvatarSelf::metricsData() +{ +	// runway - add region info +	LLSD result; +	result["id"] = getID(); +	result["rez_status"] = LLVOAvatar::rezStatusToString(getRezzedStatus()); +	result["is_self"] = isSelf(); +	std::vector<S32> rez_counts; +	LLVOAvatar::getNearbyRezzedStats(rez_counts); +	result["nearby"] = LLSD::emptyMap(); +	for (S32 i=0; i<rez_counts.size(); ++i) +	{ +		std::string rez_status_name = LLVOAvatar::rezStatusToString(i); +		result["nearby"][rez_status_name] = rez_counts[i]; +	} +	result["timers"]["debug_existence"] = mDebugExistenceTimer.getElapsedTimeF32(); +	result["timers"]["ruth_debug"] = mRuthDebugTimer.getElapsedTimeF32(); +	result["timers"]["ruth"] = mRuthTimer.getElapsedTimeF32(); +	result["timers"]["invisible"] = mInvisibleTimer.getElapsedTimeF32(); +	result["timers"]["fully_loaded"] = mFullyLoadedTimer.getElapsedTimeF32(); +	result["phases"] = getPhases().dumpPhases(); +	result["startup"] = LLStartUp::getPhases().dumpPhases(); +	 +	return result; +} + +class ViewerAppearanceChangeMetricsResponder: public LLCurl::Responder +{ +public: +	ViewerAppearanceChangeMetricsResponder() +	{ +	} + +	virtual void completed(U32 status, +						   const std::string& reason, +						   const LLSD& content) +	{ +		if (isGoodStatus(status)) +		{ +			LL_DEBUGS("Avatar") << "OK" << LL_ENDL; +			result(content); +		} +		else +		{ +			LL_WARNS("Avatar") << "Failed " << status << " reason " << reason << LL_ENDL; +			error(status,reason); +		} +	} +}; + +void LLVOAvatarSelf::sendAppearanceChangeMetrics() +{ +	// gAgentAvatarp->stopAllPhases(); + +	LLSD msg = metricsData(); +	msg["message"] = "ViewerAppearanceChangeMetrics"; + +	LL_DEBUGS("Avatar") << avString() << "message: " << ll_pretty_print_sd(msg) << LL_ENDL; +	std::string	caps_url; +	if (getRegion()) +	{ +		// runway - change here to activate. +		caps_url = getRegion()->getCapability("ViewerMetrics"); +	} +	if (!caps_url.empty()) +	{ +		LLCurlRequest::headers_t headers; +		LLHTTPClient::post(caps_url, +							msg, +							new ViewerAppearanceChangeMetricsResponder); +	} +} +  const LLUUID& LLVOAvatarSelf::grabBakedTexture(EBakedTextureIndex baked_index) const  {  	if (canGrabBakedTexture(baked_index)) @@ -2253,11 +2399,25 @@ void LLVOAvatarSelf::setNewBakedTexture( ETextureIndex te, const LLUUID& uuid )  			if (isAllLocalTextureDataFinal())  			{  				LLNotificationsUtil::add("AvatarRezSelfBakedDoneNotification",args); +				LL_DEBUGS("Avatar") << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() +						<< "sec ]" +						<< avString()  +						<< "RuthTimer " << (U32)mRuthDebugTimer.getElapsedTimeF32() +						<< " SelfLoadTimer " << (U32)mDebugSelfLoadTimer.getElapsedTimeF32() +						<< " Notification " << "AvatarRezSelfBakedDoneNotification" +						<< llendl;  			}  			else  			{  				args["STATUS"] = debugDumpAllLocalTextureDataInfo();  				LLNotificationsUtil::add("AvatarRezSelfBakedUpdateNotification",args); +				LL_DEBUGS("Avatar") << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() +						<< "sec ]" +						<< avString()  +						<< "RuthTimer " << (U32)mRuthDebugTimer.getElapsedTimeF32() +						<< " SelfLoadTimer " << (U32)mDebugSelfLoadTimer.getElapsedTimeF32() +						<< " Notification " << "AvatarRezSelfBakedUpdateNotification" +						<< llendl;  			}  		} @@ -2265,7 +2425,7 @@ void LLVOAvatarSelf::setNewBakedTexture( ETextureIndex te, const LLUUID& uuid )  	}  } -// FIXME: This is never called. Something may be broken. +// FIXME: This is not called consistently. Something may be broken.  void LLVOAvatarSelf::outputRezDiagnostics() const  {  	if(!gSavedSettings.getBOOL("DebugAvatarLocalTexLoadedTime")) @@ -2274,11 +2434,11 @@ void LLVOAvatarSelf::outputRezDiagnostics() const  	}  	const F32 final_time = mDebugSelfLoadTimer.getElapsedTimeF32(); -	llinfos << "REZTIME: Myself rez stats:" << llendl; -	llinfos << "\t Time from avatar creation to load wearables: " << (S32)mDebugTimeWearablesLoaded << llendl; -	llinfos << "\t Time from avatar creation to de-cloud: " << (S32)mDebugTimeAvatarVisible << llendl; -	llinfos << "\t Time from avatar creation to de-cloud for others: " << (S32)final_time << llendl; -	llinfos << "\t Load time for each texture: " << llendl; +	LL_DEBUGS("Avatar") << "REZTIME: Myself rez stats:" << llendl; +	LL_DEBUGS("Avatar") << "\t Time from avatar creation to load wearables: " << (S32)mDebugTimeWearablesLoaded << llendl; +	LL_DEBUGS("Avatar") << "\t Time from avatar creation to de-cloud: " << (S32)mDebugTimeAvatarVisible << llendl; +	LL_DEBUGS("Avatar") << "\t Time from avatar creation to de-cloud for others: " << (S32)final_time << llendl; +	LL_DEBUGS("Avatar") << "\t Load time for each texture: " << llendl;  	for (U32 i = 0; i < LLVOAvatarDefines::TEX_NUM_INDICES; ++i)  	{  		std::stringstream out; @@ -2302,12 +2462,14 @@ void LLVOAvatarSelf::outputRezDiagnostics() const  		// Don't print out non-existent textures.  		if (j != 0) -			llinfos << out.str() << llendl; +		{ +			LL_DEBUGS("Avatar") << out.str() << LL_ENDL; +		}  	} -	llinfos << "\t Time points for each upload (start / finish)" << llendl; +	LL_DEBUGS("Avatar") << "\t Time points for each upload (start / finish)" << llendl;  	for (U32 i = 0; i < LLVOAvatarDefines::BAKED_NUM_INDICES; ++i)  	{ -		llinfos << "\t\t (" << i << ") \t" << (S32)mDebugBakedTextureTimes[i][0] << " / " << (S32)mDebugBakedTextureTimes[i][1] << llendl; +		LL_DEBUGS("Avatar") << "\t\t (" << i << ") \t" << (S32)mDebugBakedTextureTimes[i][0] << " / " << (S32)mDebugBakedTextureTimes[i][1] << llendl;  	}  	for (LLVOAvatarDefines::LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDefines::LLVOAvatarDictionary::getInstance()->getBakedTextures().begin(); @@ -2319,15 +2481,16 @@ void LLVOAvatarSelf::outputRezDiagnostics() const  		if (!layerset) continue;  		const LLTexLayerSetBuffer *layerset_buffer = layerset->getComposite();  		if (!layerset_buffer) continue; -		llinfos << layerset_buffer->dumpTextureInfo() << llendl; +		LL_DEBUGS("Avatar") << layerset_buffer->dumpTextureInfo() << llendl;  	}  }  void LLVOAvatarSelf::outputRezTiming(const std::string& msg) const  { -	LL_DEBUGS("Avatar Rez") +	LL_INFOS("Avatar") +		<< avString()  		<< llformat("%s. Time from avatar creation: %.2f", msg.c_str(), mDebugSelfLoadTimer.getElapsedTimeF32()) -		<< llendl; +		<< LL_ENDL;  }  void LLVOAvatarSelf::reportAvatarRezTime() const @@ -2351,6 +2514,18 @@ void LLVOAvatarSelf::setCachedBakedTexture( ETextureIndex te, const LLUUID& uuid  	{  		if ( mBakedTextureDatas[i].mTextureIndex == te && mBakedTextureDatas[i].mTexLayerSet)  		{ +			if (mInitialBakeIDs[i] != LLUUID::null) +			{ +				if (mInitialBakeIDs[i] == uuid) +				{ +					llinfos << "baked texture correctly loaded at login! " << i << llendl; +				} +				else +				{ +					llwarns << "baked texture does not match id loaded at login!" << i << llendl; +				} +				mInitialBakeIDs[i] = LLUUID::null; +			}  			mBakedTextureDatas[i].mTexLayerSet->cancelUpload();  		}  	} @@ -2478,6 +2653,20 @@ LLTexLayerSet* LLVOAvatarSelf::getLayerSet(ETextureIndex index) const  	return NULL;  } +LLTexLayerSet* LLVOAvatarSelf::getLayerSet(EBakedTextureIndex baked_index) const +{ +       /* switch(index) +               case TEX_HEAD_BAKED: +               case TEX_HEAD_BODYPAINT: +                       return mHeadLayerSet; */ +       if (baked_index >= 0 && baked_index < BAKED_NUM_INDICES) +       { +                       return mBakedTextureDatas[baked_index].mTexLayerSet; +       } +       return NULL; +} + +  // static  void LLVOAvatarSelf::onCustomizeStart()  { @@ -2558,49 +2747,6 @@ BOOL LLVOAvatarSelf::needsRenderBeam()  // static  void LLVOAvatarSelf::deleteScratchTextures()  { -	if(gAuditTexture) -	{ -		S32 total_tex_size = sScratchTexBytes ; -		S32 tex_size = SCRATCH_TEX_WIDTH * SCRATCH_TEX_HEIGHT ; - -		if( sScratchTexNames.checkData( GL_LUMINANCE ) ) -		{ -			LLImageGL::decTextureCounter(tex_size, 1, LLViewerTexture::AVATAR_SCRATCH_TEX) ; -			total_tex_size -= tex_size ; -		} -		if( sScratchTexNames.checkData( GL_ALPHA ) ) -		{ -			LLImageGL::decTextureCounter(tex_size, 1, LLViewerTexture::AVATAR_SCRATCH_TEX) ; -			total_tex_size -= tex_size ; -		} -		if( sScratchTexNames.checkData( GL_COLOR_INDEX ) ) -		{ -			LLImageGL::decTextureCounter(tex_size, 1, LLViewerTexture::AVATAR_SCRATCH_TEX) ; -			total_tex_size -= tex_size ; -		} -		if( sScratchTexNames.checkData( LLRender::sGLCoreProfile ? GL_RG : GL_LUMINANCE_ALPHA ) ) -		{ -			LLImageGL::decTextureCounter(tex_size, 2, LLViewerTexture::AVATAR_SCRATCH_TEX) ; -			total_tex_size -= 2 * tex_size ; -		} -		if( sScratchTexNames.checkData( GL_RGB ) ) -		{ -			LLImageGL::decTextureCounter(tex_size, 3, LLViewerTexture::AVATAR_SCRATCH_TEX) ; -			total_tex_size -= 3 * tex_size ; -		} -		if( sScratchTexNames.checkData( GL_RGBA ) ) -		{ -			LLImageGL::decTextureCounter(tex_size, 4, LLViewerTexture::AVATAR_SCRATCH_TEX) ; -			total_tex_size -= 4 * tex_size ; -		} -		//others -		while(total_tex_size > 0) -		{ -			LLImageGL::decTextureCounter(tex_size, 4, LLViewerTexture::AVATAR_SCRATCH_TEX) ; -			total_tex_size -= 4 * tex_size ; -		} -	} -  	for( LLGLuint* namep = sScratchTexNames.getFirstData();   		 namep;   		 namep = sScratchTexNames.getNextData() ) diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h index 655fb3a012..543891ca63 100644..100755 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -93,15 +93,27 @@ public:  	/*virtual*/ void updateVisualParams();  	/*virtual*/ void idleUpdateAppearanceAnimation(); +	/*virtual*/ U32  processUpdateMessage(LLMessageSystem *mesgsys, +													 void **user_data, +													 U32 block_num, +													 const EObjectUpdateType update_type, +													 LLDataPacker *dp); +  private:  	// helper function. Passed in param is assumed to be in avatar's parameter list.  	BOOL setParamWeight(LLViewerVisualParam *param, F32 weight, BOOL upload_bake = FALSE ); +  /**                    Initialization   **                                                                            **   *******************************************************************************/ +private: +	LLUUID mInitialBakeIDs[6]; +	bool mInitialBakesLoaded; + +  /********************************************************************************   **                                                                            **   **                    STATE @@ -121,7 +133,7 @@ public:  	// Loading state  	//--------------------------------------------------------------------  public: -	/*virtual*/ BOOL    getIsCloud(); +	/*virtual*/ BOOL    getIsCloud() const;  	//--------------------------------------------------------------------  	// Region state @@ -229,6 +241,7 @@ public:  	void				requestLayerSetUpload(LLVOAvatarDefines::EBakedTextureIndex i);  	void				requestLayerSetUpdate(LLVOAvatarDefines::ETextureIndex i);  	LLTexLayerSet*		getLayerSet(LLVOAvatarDefines::ETextureIndex index) const; +	LLTexLayerSet* 		getLayerSet(LLVOAvatarDefines::EBakedTextureIndex baked_index) const;  	//--------------------------------------------------------------------  	// Composites @@ -369,6 +382,8 @@ public:  	const LLTexLayerSet*  	debugGetLayerSet(LLVOAvatarDefines::EBakedTextureIndex index) const { return mBakedTextureDatas[index].mTexLayerSet; }  	const std::string		debugDumpLocalTextureDataInfo(const LLTexLayerSet* layerset) const; // Lists out state of this particular baked texture layer  	const std::string		debugDumpAllLocalTextureDataInfo() const; // Lists out which baked textures are at highest LOD +	LLSD					metricsData(); +	void					sendAppearanceChangeMetrics(); // send data associated with completing a change.  private:  	LLFrameTimer    		mDebugSelfLoadTimer;  	F32						mDebugTimeWearablesLoaded; @@ -387,4 +402,9 @@ extern LLPointer<LLVOAvatarSelf> gAgentAvatarp;  BOOL isAgentAvatarValid(); +void selfStartPhase(const std::string& phase_name); +void selfStopPhase(const std::string& phase_name); +void selfStopAllPhases(); +void selfClearPhases(); +  #endif // LL_VO_AVATARSELF_H diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 201952876f..f922e3b4f3 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -464,6 +464,7 @@ public:  		RENDER_DEBUG_LOD_INFO	        = 0x04000000,  		RENDER_DEBUG_RENDER_COMPLEXITY  = 0x08000000,  		RENDER_DEBUG_ATTACHMENT_BYTES	= 0x10000000, +		RENDER_DEBUG_TEXEL_DENSITY		= 0x20000000  	};  public: diff --git a/indra/newview/skins/default/xui/en/floater_stats.xml b/indra/newview/skins/default/xui/en/floater_stats.xml index 2fd932786b..9400f7b94f 100644 --- a/indra/newview/skins/default/xui/en/floater_stats.xml +++ b/indra/newview/skins/default/xui/en/floater_stats.xml @@ -149,13 +149,52 @@  				 show_per_sec="true"  				 show_bar="false">  			  </stat_bar> +       <stat_bar +				 name="object_cache_hits" +				 label="Object Cache Hit Rate" +				 stat="object_cache_hits" +				 bar_min="0" +				 bar_max="100" +         unit_label="%" +				 tick_spacing="20" +				 label_spacing="20" +				 show_history="true" +         show_per_sec="false" +				 show_bar="false"> +        </stat_bar>  			</stat_view>          <!--Texture Stats-->  			<stat_view  			   name="texture"  			   label="Texture"  			   show_label="true"> -			  <stat_bar +        <stat_bar +				 name="texture_cache_hits" +				 label="Cache Hit Rate" +				 stat="texture_cache_hits" +				 bar_min="0.f" +				 bar_max="100.f" +         unit_label="%" +				 tick_spacing="20" +				 label_spacing="20" +				 show_history="true" +         show_per_sec="false" +				 show_bar="false"> +        </stat_bar> +        <stat_bar +				 name="texture_cache_read_latency" +				 label="Cache Read Latency" +         unit_label="msec" +				 stat="texture_cache_read_latency" +				 bar_min="0.f" +				 bar_max="1000.f" +				 tick_spacing="100" +				 label_spacing="200" +				 show_history="true" +         show_per_sec="false" +				 show_bar="false"> +        </stat_bar> +        <stat_bar  				 name="numimagesstat"  				 label="Count"  				 stat="numimagesstat"  diff --git a/indra/newview/skins/default/xui/en/floater_texture_fetch_debugger.xml b/indra/newview/skins/default/xui/en/floater_texture_fetch_debugger.xml new file mode 100644 index 0000000000..44b6a63bca --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_texture_fetch_debugger.xml @@ -0,0 +1,341 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 +<floater
 + legacy_header_height="18"
 + can_minimize="false"
 + height="550"
 + layout="topleft"
 + name="TexFetchDebugger"
 + help_topic="texfetchdebugger"
 + title="Texture Fetching Debugger"
 + width="540">
 +  <text
 +   type="string"
 +   length="1"
 +   follows="left|top"
 +   height="25"
 +   layout="topleft"
 +   left="10"
 +   name="total_num_fetched_label"
 +   top="30"
 +   width="400">
 +    1, Total number of fetched textures: [NUM]
 +  </text>
 +  <text
 +   type="string"
 +   length="1"
 +   follows="left|top"
 +   height="25"
 +   layout="topleft"
 +   left_delta="0"
 +   name="total_num_fetching_requests_label"
 +   top_delta="25"
 +   width="400">
 +    2, Total number of fetching requests: [NUM]
 +  </text>
 +  <text
 +   type="string"
 +   length="1"
 +   follows="left|top"
 +   height="25"
 +   layout="topleft"
 +   left_delta="0"
 +   name="total_num_cache_hits_label"
 +   top_delta="25"
 +   width="400">
 +    3, Total number of cache hits: [NUM]
 +  </text>
 +  <text
 +   type="string"
 +   length="1"
 +   follows="left|top"
 +   height="25"
 +   layout="topleft"
 +   left_delta="0"
 +   name="total_num_visible_tex_label"
 +   top_delta="25"
 +   width="400">
 +    4, Total number of visible textures: [NUM]
 +  </text>
 +  <text
 +   type="string"
 +   length="1"
 +   follows="left|top"
 +   height="25"
 +   layout="topleft"
 +   left_delta="0"
 +   name="total_num_visible_tex_fetch_req_label"
 +   top_delta="25"
 +   width="450">
 +    5, Total number of visible texture fetching requests: [NUM]
 +  </text>
 +  <text
 +   type="string"
 +   length="1"
 +   follows="left|top"
 +   height="25"
 +   layout="topleft"
 +   left_delta="0"
 +   name="total_fetched_data_label"
 +   top_delta="25"
 +   width="530">
 +    6, Total number of fetched data: [SIZE1]KB, Decoded Data: [SIZE2]KB, [PIXEL]MPixels
 +  </text>
 +  <text
 +   type="string"
 +   length="1"
 +   follows="left|top"
 +   height="25"
 +   layout="topleft"
 +   left_delta="0"
 +   name="total_fetched_vis_data_label"
 +   top_delta="25"
 +   width="480">
 +    7, Total number of visible data: [SIZE1]KB, Decoded Data: [SIZE2]KB
 +  </text>
 +  <text
 +   type="string"
 +   length="1"
 +   follows="left|top"
 +   height="25"
 +   layout="topleft"
 +   left_delta="0"
 +   name="total_fetched_rendered_data_label"
 +   top_delta="25"
 +   width="530">
 +    8, Total number of rendered data: [SIZE1]KB, Decoded Data: [SIZE2]KB, [PIXEL]MPixels
 +  </text>
 +  <text
 +   type="string"
 +   length="1"
 +   follows="left|top"
 +   height="25"
 +   layout="topleft"
 +   left_delta="0"
 +   name="total_time_cache_read_label"
 +   top_delta="25"
 +   width="400">
 +    9, Total time on cache readings: [TIME] seconds
 +  </text>
 +  <text
 +   type="string"
 +   length="1"
 +   follows="left|top"
 +   height="25"
 +   layout="topleft"
 +   left_delta="0"
 +   name="total_time_cache_write_label"
 +   top_delta="25"
 +   width="400">
 +    10, Total time on cache writings: [TIME] seconds
 +  </text>
 +  <text
 +   type="string"
 +   length="1"
 +   follows="left|top"
 +   height="25"
 +   layout="topleft"
 +   left_delta="0"
 +   name="total_time_decode_label"
 +   top_delta="25"
 +   width="400">
 +    11, Total time on decodings: [TIME] seconds
 +  </text>
 +  <text
 +   type="string"
 +   length="1"
 +   follows="left|top"
 +   height="25"
 +   layout="topleft"
 +   left_delta="0"
 +   name="total_time_gl_label"
 +   top_delta="25"
 +   width="400">
 +    12, Total time on gl texture creation: [TIME] seconds
 +  </text>
 +  <text
 +   type="string"
 +   length="1"
 +   follows="left|top"
 +   height="25"
 +   layout="topleft"
 +   left_delta="0"
 +   name="total_time_http_label"
 +   top_delta="25"
 +   width="400">
 +    13, Total time on HTTP fetching: [TIME] seconds
 +  </text>
 +  <text
 +   type="string"
 +   length="1"
 +   follows="left|top"
 +   height="25"
 +   layout="topleft"
 +   left_delta="0"
 +   name="total_time_fetch_label"
 +   top_delta="25"
 +   width="400">
 +    14, Total time on entire fetching: [TIME] seconds
 +  </text>
 +  <text
 +  type="string"
 +  length="1"
 +  follows="left|top"
 +  height="25"
 +  layout="topleft"
 +  left_delta="0"
 +  name="total_time_refetch_vis_cache_label"
 +  top_delta="25"
 +  width="540">
 +    15, Refetching visibles from cache, Time: [TIME] seconds, Fetched: [SIZE]KB, [PIXEL]MPixels
 +  </text>
 +  <text
 +  type="string"
 +  length="1"
 +  follows="left|top"
 +  height="25"
 +  layout="topleft"
 +  left_delta="0"
 +  name="total_time_refetch_vis_http_label"
 +  top_delta="25"
 +  width="540">
 +    16, Refetching visibles from HTTP, Time: [TIME] seconds, Fetched: [SIZE]KB, [PIXEL]MPixels
 +  </text>
 +  <spinner
 +     decimal_digits="2"
 +     follows="left|top"
 +     height="20"
 +     increment="0.01"
 +     initial_value="1.0"
 +     label="17, Ratio of Texel/Pixel:"
 +     label_width="130"
 +     layout="topleft"
 +     left_delta="0"
 +     max_val="10.0"
 +     min_val="0.01"
 +     name="texel_pixel_ratio"
 +     top_delta="30"
 +     width="200">
 +    <spinner.commit_callback
 +		function="TexFetchDebugger.ChangeTexelPixelRatio" />
 +  </spinner>
 +  <button
 +   follows="left|top"
 +   height="20"
 +   label="Start"
 +   layout="topleft"
 +   left_delta="0"
 +   name="start_btn"
 +   top_delta="30"
 +   width="70">
 +    <button.commit_callback
 +		function="TexFetchDebugger.Start" />
 +  </button>
 +  <button
 +   follows="left|top"
 +   height="20"
 +   label="Reset"
 +   layout="topleft"
 +   left_pad="7"
 +   name="clear_btn"
 +   top_delta="0"
 +   width="70">
 +    <button.commit_callback
 +		function="TexFetchDebugger.Clear" />
 +  </button>
 +  <button
 +   follows="left|top"
 +   height="20"
 +   label="Close"
 +   layout="topleft"
 +   left_pad="7"
 +   name="close_btn"
 +   top_delta="0"
 +   width="70">
 +    <button.commit_callback
 +		function="TexFetchDebugger.Close" />
 +  </button>
 +  <button
 +   follows="left|top"
 +   height="20"
 +   label="Cache Read"
 +   layout="topleft"
 +   left="10"
 +   name="cacheread_btn"
 +   top_delta="30"
 +   width="80">
 +    <button.commit_callback
 +		function="TexFetchDebugger.CacheRead" />
 +  </button>
 +  <button
 +   follows="left|top"
 +   height="20"
 +   label="Cache Write"
 +   layout="topleft"
 +   left_pad="7"
 +   name="cachewrite_btn"
 +   top_delta="0"
 +   width="80">
 +    <button.commit_callback
 +		function="TexFetchDebugger.CacheWrite" />
 +  </button>
 +  <button
 +   follows="left|top"
 +   height="20"
 +   label="HTTP"
 +   layout="topleft"
 +   left_pad="7"
 +   name="http_btn"
 +   top_delta="0"
 +   width="70">
 +    <button.commit_callback
 +		function="TexFetchDebugger.HTTPLoad" />
 +  </button>
 +  <button
 +   follows="left|top"
 +   height="20"
 +   label="Decode"
 +   layout="topleft"
 +   left_pad="7"
 +   name="decode_btn"
 +   top_delta="0"
 +   width="70">
 +    <button.commit_callback
 +		function="TexFetchDebugger.Decode" />
 +  </button>
 +  <button
 +   follows="left|top"
 +   height="20"
 +   label="GL Texture"
 +   layout="topleft"
 +   left_pad="7"
 +   name="gl_btn"
 +   top_delta="0"
 +   width="70">
 +    <button.commit_callback
 +		function="TexFetchDebugger.GLTexture" />
 +  </button>
 +  <button
 +   follows="left|top"
 +   height="20"
 +   label="Refetch Vis Cache"
 +   layout="topleft"
 +   left="10"
 +   name="refetchviscache_btn"
 +   top_delta="30"
 +   width="120">
 +    <button.commit_callback
 +		function="TexFetchDebugger.RefetchVisCache" />
 +  </button>
 +  <button
 +   follows="left|top"
 +   height="20"
 +   label="Refetch Vis HTTP"
 +   layout="topleft"
 +   left_pad="7"
 +   name="refetchvishttp_btn"
 +   top_delta="0"
 +   width="120">
 +    <button.commit_callback
 +		function="TexFetchDebugger.RefetchVisHTTP" />
 +  </button>
 +</floater>
 diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 5ba566b175..a6898c554f 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -1876,7 +1876,7 @@                  <menu_item_check.on_click                   function="Advanced.ToggleConsole"                   parameter="texture" /> -            </menu_item_check> +            </menu_item_check>                          <menu_item_check               label="Debug Console"               name="Debug Console" @@ -1898,28 +1898,6 @@                 parameter="notifications_console" />              </menu_item_call>              <menu_item_check -               label="Texture Size Console" -               name="Texture Size" -               shortcut="control|shift|6"> -              <menu_item_check.on_check -               function="Advanced.CheckConsole" -               parameter="texture size" /> -              <menu_item_check.on_click -               function="Advanced.ToggleConsole" -               parameter="texture size" /> -            </menu_item_check> -            <menu_item_check -               label="Texture Category Console" -               name="Texture Category" -               shortcut="control|shift|7"> -              <menu_item_check.on_check -               function="Advanced.CheckConsole" -               parameter="texture category" /> -              <menu_item_check.on_click -               function="Advanced.ToggleConsole" -               parameter="texture category" /> -            </menu_item_check> -            <menu_item_check               label="Fast Timers"               name="Fast Timers"               shortcut="control|shift|9" @@ -1953,7 +1931,20 @@                 function="Advanced.ToggleConsole"                 parameter="scene view" />              </menu_item_check> - +            <menu_item_call +              enabled="false" +              visible="false" +              label="Texture Fetch Debug Console" +              name="Texture Fetch Debug Console"> +              <menu_item_call.on_click +                function="Floater.Show" +                parameter="tex_fetch_debugger" /> +              <on_enable +                function="Develop.SetTexFetchDebugger" /> +              <on_visible +                function="Develop.SetTexFetchDebugger" /> +            </menu_item_call> +                        <menu_item_separator/>              <menu_item_call @@ -2439,6 +2430,52 @@             function="Advanced.ToggleInfoDisplay"             parameter="sculpt" />  		</menu_item_check> +       <menu +         create_jump_keys="true" +         label="Texture Density" +         name="Texture Density" +         tear_off="true"> +          <menu_item_check +           label="None" +           name="None"> +            <menu_item_check.on_check +             function="Advanced.CheckDisplayTextureDensity" +             parameter="none" /> +            <menu_item_check.on_click +             function="Advanced.SetDisplayTextureDensity" +             parameter="none" /> +          </menu_item_check> +          <menu_item_check +           label="Current" +           name="Current"> +            <menu_item_check.on_check +             function="Advanced.CheckDisplayTextureDensity" +             parameter="current" /> +            <menu_item_check.on_click +             function="Advanced.SetDisplayTextureDensity" +             parameter="current" /> +          </menu_item_check> +          <menu_item_check +           label="Desired" +           name="Desired"> +            <menu_item_check.on_check +             function="Advanced.CheckDisplayTextureDensity" +             parameter="desired" /> +            <menu_item_check.on_click +             function="Advanced.SetDisplayTextureDensity" +             parameter="desired" /> +          </menu_item_check> +          <menu_item_check +           label="Full" +           name="Full"> +            <menu_item_check.on_check +             function="Advanced.CheckDisplayTextureDensity" +             parameter="full" /> +            <menu_item_check.on_click +             function="Advanced.SetDisplayTextureDensity" +             parameter="full" /> +          </menu_item_check> +        </menu>        </menu>          <menu           create_jump_keys="true" @@ -2606,16 +2643,6 @@                   parameter="TextureLoadFullRes" />              </menu_item_check>              <menu_item_check -               label="Audit Textures" -               name="Audit Textures"> -              <menu_item_check.on_check -               function="CheckControl" -               parameter="AuditTexture" /> -              <menu_item_check.on_click -               function="ToggleControl" -               parameter="AuditTexture" /> -            </menu_item_check> -            <menu_item_check               label="Texture Atlas (experimental)"               name="Texture Atlas">                <menu_item_check.on_check diff --git a/indra/newview/tests/llviewerassetstats_test.cpp b/indra/newview/tests/llviewerassetstats_test.cpp index 3faddc13c1..f8923b9868 100644..100755 --- a/indra/newview/tests/llviewerassetstats_test.cpp +++ b/indra/newview/tests/llviewerassetstats_test.cpp @@ -35,6 +35,31 @@  #include "lluuid.h"  #include "llsdutil.h"  #include "llregionhandle.h" +#include "../llvoavatar.h" + +void LLVOAvatar::getNearbyRezzedStats(std::vector<S32>& counts) +{ +	counts.resize(3); +	counts[0] = 0; +	counts[1] = 0; +	counts[2] = 1; +} + +// static +std::string LLVOAvatar::rezStatusToString(S32 rez_status) +{ +	if (rez_status==0) return "cloud"; +	if (rez_status==1) return "gray"; +	if (rez_status==2) return "textured"; +	return "unknown"; +} + +// static +LLViewerStats::StatsAccumulator& LLViewerStats::PhaseMap::getPhaseStats(const std::string& phase_name) +{ +	static LLViewerStats::StatsAccumulator junk; +	return junk; +}  static const char * all_keys[] =   { @@ -104,18 +129,25 @@ is_single_key_map(const LLSD & sd, const std::string & key)  {  	return sd.isMap() && 1 == sd.size() && sd.has(key);  } -#endif  static bool  is_double_key_map(const LLSD & sd, const std::string & key1, const std::string & key2)  {  	return sd.isMap() && 2 == sd.size() && sd.has(key1) && sd.has(key2);  } +#endif + +static bool +is_triple_key_map(const LLSD & sd, const std::string & key1, const std::string & key2, const std::string& key3) +{ +	return sd.isMap() && 3 == sd.size() && sd.has(key1) && sd.has(key2) && sd.has(key3); +} +  static bool  is_no_stats_map(const LLSD & sd)  { -	return is_double_key_map(sd, "duration", "regions"); +	return is_triple_key_map(sd, "duration", "regions", "avatar");  }  static bool @@ -226,7 +258,7 @@ namespace tut  		// Once the region is set, we will get a response even with no data collection  		it->setRegion(region1_handle);  		sd_full = it->asLLSD(false); -		ensure("Correct single-key LLSD map root", is_double_key_map(sd_full, "duration", "regions")); +		ensure("Correct single-key LLSD map root", is_triple_key_map(sd_full, "duration", "regions", "avatar"));  		ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd_full["regions"], region1_handle));  		LLSD sd = sd_full["regions"][0]; @@ -267,7 +299,7 @@ namespace tut  		it->setRegion(region1_handle);  		LLSD sd = it->asLLSD(false); -		ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration")); +		ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "regions", "duration", "avatar"));  		ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle));  		sd = sd[0]; @@ -292,7 +324,7 @@ namespace tut  		LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, false, false);  		LLSD sd = gViewerAssetStatsMain->asLLSD(false); -		ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration")); +		ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "regions", "duration", "avatar"));  		ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle));  		sd = sd["regions"][0]; @@ -332,7 +364,7 @@ namespace tut  		LLSD sd = gViewerAssetStatsThread1->asLLSD(false);  		ensure("Other collector is empty", is_no_stats_map(sd));  		sd = gViewerAssetStatsMain->asLLSD(false); -		ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration")); +		ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "regions", "duration", "avatar"));  		ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle));  		sd = sd["regions"][0]; @@ -382,7 +414,7 @@ namespace tut  		// std::cout << sd << std::endl; -		ensure("Correct double-key LLSD map root", is_double_key_map(sd, "duration", "regions")); +		ensure("Correct double-key LLSD map root", is_triple_key_map(sd, "duration", "regions", "avatar"));  		ensure("Correct double-slot LLSD array regions", is_double_slot_array(sd["regions"], region1_handle, region2_handle));  		LLSD sd1 = get_region(sd, region1_handle);  		LLSD sd2 = get_region(sd, region2_handle); @@ -405,7 +437,7 @@ namespace tut  		// Reset leaves current region in place  		gViewerAssetStatsMain->reset();  		sd = gViewerAssetStatsMain->asLLSD(false); -		ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration")); +		ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "regions", "duration", "avatar"));  		ensure("Correct single-slot LLSD array regions (p2)", is_single_slot_array(sd["regions"], region2_handle));  		sd2 = sd["regions"][0]; @@ -454,7 +486,7 @@ namespace tut  		LLSD sd = gViewerAssetStatsMain->asLLSD(false); -		ensure("Correct double-key LLSD map root", is_double_key_map(sd, "duration", "regions")); +		ensure("Correct double-key LLSD map root", is_triple_key_map(sd, "duration", "regions", "avatar"));  		ensure("Correct double-slot LLSD array regions", is_double_slot_array(sd["regions"], region1_handle, region2_handle));  		LLSD sd1 = get_region(sd, region1_handle);  		LLSD sd2 = get_region(sd, region2_handle); @@ -477,7 +509,7 @@ namespace tut  		// Reset leaves current region in place  		gViewerAssetStatsMain->reset();  		sd = gViewerAssetStatsMain->asLLSD(false); -		ensure("Correct single-key LLSD map root", is_double_key_map(sd, "duration", "regions")); +		ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "duration", "regions", "avatar"));  		ensure("Correct single-slot LLSD array regions (p2)", is_single_slot_array(sd["regions"], region2_handle));  		sd2 = get_region(sd, region2_handle);  		ensure("Region2 is present in results", sd2.isMap()); @@ -523,7 +555,7 @@ namespace tut  		LLSD sd = gViewerAssetStatsThread1->asLLSD(false);  		ensure("Other collector is empty", is_no_stats_map(sd));  		sd = gViewerAssetStatsMain->asLLSD(false); -		ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration")); +		ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "regions", "duration", "avatar"));  		ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle));  		sd = get_region(sd, region1_handle);  		ensure("Region1 is present in results", sd.isMap()); | 
