diff options
| -rwxr-xr-x | indra/newview/llappviewer.cpp | 2 | ||||
| -rw-r--r-- | indra/newview/llavatarrenderinfoaccountant.cpp | 470 | ||||
| -rw-r--r-- | indra/newview/llavatarrenderinfoaccountant.h | 33 | ||||
| -rwxr-xr-x | indra/newview/llviewerregion.cpp | 3 | ||||
| -rwxr-xr-x | indra/newview/llviewerregion.h | 6 | ||||
| -rwxr-xr-x | indra/newview/llvoavatar.cpp | 59 | 
6 files changed, 337 insertions, 236 deletions
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 3a5008507a..4ad8181055 100755 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -5090,7 +5090,7 @@ void LLAppViewer::idle()  	}  	// Update AV render info -	LLAvatarRenderInfoAccountant::idle(); +	LLAvatarRenderInfoAccountant::getInstance()->idle();  	{  		LL_RECORD_BLOCK_TIME(FTM_AUDIO_UPDATE); diff --git a/indra/newview/llavatarrenderinfoaccountant.cpp b/indra/newview/llavatarrenderinfoaccountant.cpp index 83ae0438d9..8631f245a9 100644 --- a/indra/newview/llavatarrenderinfoaccountant.cpp +++ b/indra/newview/llavatarrenderinfoaccountant.cpp @@ -28,14 +28,16 @@  // Precompiled header  #include "llviewerprecompiledheaders.h" -// associated header -#include "llavatarrenderinfoaccountant.h"  // STL headers  // std headers  // external library headers  // other Linden headers  #include "llcharacter.h" -#include "llhttpclient.h" +#include "httprequest.h" +#include "httphandler.h" +#include "httpresponse.h" +#include "llcorehttputil.h" +#include "llappcorehttp.h"  #include "lltimer.h"  #include "llviewercontrol.h"  #include "llviewermenu.h" @@ -43,6 +45,8 @@  #include "llviewerregion.h"  #include "llvoavatar.h"  #include "llworld.h" +// associated header +#include "llavatarrenderinfoaccountant.h"  static	const std::string KEY_AGENTS = "agents";			// map @@ -53,228 +57,259 @@ static	const std::string KEY_MESSAGE = "message";  static	const std::string KEY_ERROR = "error"; -// Send data updates about once per minute, only need per-frame resolution -LLFrameTimer LLAvatarRenderInfoAccountant::sRenderInfoReportTimer; +static const F32 SECS_BETWEEN_REGION_SCANS   =  5.f;		// Scan the region list every 5 seconds +static const F32 SECS_BETWEEN_REGION_REQUEST = 15.0;		// Look for new avs every 15 seconds +static const F32 SECS_BETWEEN_REGION_REPORTS = 60.0;		// Update each region every 60 seconds +	 + +// The policy class for HTTP traffic; this is the right value for all capability requests. +static LLCore::HttpRequest::policy_t http_policy(LLAppCoreHttp::AP_REPORTING); + +// Priority for HTTP requests.  Use 0U. +static LLCore::HttpRequest::priority_t http_priority(0U); +LLAvatarRenderInfoAccountant::LLAvatarRenderInfoAccountant() +	: mHttpRequest(new LLCore::HttpRequest) +	, mHttpHeaders(new LLCore::HttpHeaders) +	, mHttpOptions(new LLCore::HttpOptions) +{ +	mHttpOptions->setTransferTimeout(SECS_BETWEEN_REGION_SCANS); + +	mHttpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_LLSD_XML); +	mHttpHeaders->append(HTTP_OUT_HEADER_ACCEPT, HTTP_CONTENT_LLSD_XML); +} + +LLAvatarRenderInfoAccountant::~LLAvatarRenderInfoAccountant() +{ +	mHttpOptions->release(); +	mHttpHeaders->release(); +	// delete mHttpRequest; ??? +}  // HTTP responder class for GET request for avatar render weight information -class LLAvatarRenderInfoGetResponder : public LLHTTPClient::Responder +class LLAvatarRenderInfoGetHandler : public LLCore::HttpHandler  { +private: +	LOG_CLASS(LLAvatarRenderInfoGetHandler); +	  public: -	LLAvatarRenderInfoGetResponder(U64 region_handle) : mRegionHandle(region_handle) +	LLAvatarRenderInfoGetHandler() : LLCore::HttpHandler()  	{  	} -	virtual void error(U32 statusNum, const std::string& reason) -	{ -		LLViewerRegion * regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle); -		if (regionp) +	void onCompleted(LLCore::HttpHandle handle, +					 LLCore::HttpResponse* response)  		{ -			LL_WARNS("AvatarRenderInfo") << "HTTP error result for avatar weight GET: " << statusNum  -				<< ", " << reason -				<< " returned by region " << regionp->getName() -				<< LL_ENDL; -		} -		else -		{ -			LL_WARNS("AvatarRenderInfo") << "Avatar render weight GET error recieved but region not found for "  -				<< mRegionHandle  -				<< ", error " << statusNum  -				<< ", " << reason -				<< LL_ENDL; -		} - -	} - -	virtual void result(const LLSD& content) -	{ -		LLViewerRegion * regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle); -		if (regionp) -		{ -			LL_DEBUGS("AvatarRenderInfo") << "LRI: Result for avatar weights request for region '" << regionp->getName() << "':" << LL_ENDL; - -			if (content.isMap()) -			{ -				if (content.has(KEY_AGENTS)) +            LLCore::HttpStatus status = response->getStatus(); +            if (status) +            { +				LLSD avatar_render_info; +				if (LLCoreHttpUtil::responseToLLSD(response, false /* quiet logging */, +												   avatar_render_info))  				{ -					const LLSD & agents = content[KEY_AGENTS]; -					if (agents.isMap()) +					if (avatar_render_info.isMap())  					{ -						LLSD::map_const_iterator	report_iter = agents.beginMap(); -						while (report_iter != agents.endMap()) +						if (avatar_render_info.has(KEY_AGENTS))  						{ -							LLUUID target_agent_id = LLUUID(report_iter->first); -							const LLSD & agent_info_map = report_iter->second; -							LLViewerObject* avatarp = gObjectList.findObject(target_agent_id); -							if (   avatarp -								&& avatarp->isAvatar() -								&& agent_info_map.isMap()) -							{	// Extract the data for this avatar - -								LL_DEBUGS("AvatarRenderInfo") << "LRI:  Agent " << target_agent_id  -															 << ": " << agent_info_map << LL_ENDL; - -								if (agent_info_map.has(KEY_WEIGHT)) +							const LLSD & agents = avatar_render_info[KEY_AGENTS]; +							if (agents.isMap()) +							{ +								for (LLSD::map_const_iterator agent_iter = agents.beginMap(); +									 agent_iter != agents.endMap(); +									 agent_iter++ +									 )  								{ -									((LLVOAvatar *) avatarp)->setReportedVisualComplexity(agent_info_map[KEY_WEIGHT].asInteger()); -								} +									LLUUID target_agent_id = LLUUID(agent_iter->first); +									LLViewerObject* avatarp = gObjectList.findObject(target_agent_id); +									if (avatarp && avatarp->isAvatar()) +									{ +										const LLSD & agent_info_map = agent_iter->second; +										if (agent_info_map.isMap()) +										{ +											LL_DEBUGS("AvatarRenderInfo") << " Agent " << target_agent_id  +																		  << ": " << agent_info_map << LL_ENDL; + +											if (agent_info_map.has(KEY_WEIGHT)) +											{ +												((LLVOAvatar *) avatarp)->setReportedVisualComplexity(agent_info_map[KEY_WEIGHT].asInteger()); +											} +										} +										else +										{ +											LL_WARNS("AvatarRenderInfo") << "agent entry invalid" +																		 << " agent " << target_agent_id +																		 << " map " << agent_info_map +																		 << LL_ENDL; +										} +									} +									else +									{ +										LL_DEBUGS("AvatarRenderInfo") << "Unknown agent " << target_agent_id << LL_ENDL; +									} +								} // for agent_iter  							}  							else  							{ -								LL_WARNS("AvatarRenderInfo") << "LRI: agent entry invalid" -															 << " agent " << target_agent_id -															 << " map " << agent_info_map -															 << LL_ENDL; +								LL_WARNS("AvatarRenderInfo") << "malformed get response agents avatar_render_info is not map" << LL_ENDL;  							} -							report_iter++; +						}	// has "agents" +						else if (avatar_render_info.has(KEY_ERROR)) +						{ +							const LLSD & error = avatar_render_info[KEY_ERROR]; +							LL_WARNS("AvatarRenderInfo") << "Avatar render info GET error: " +														 << error[KEY_IDENTIFIER] +														 << ": " << error[KEY_MESSAGE]  +														 << LL_ENDL; +						} +						else +						{ +							LL_WARNS("AvatarRenderInfo") << "no agent key in get response" << LL_ENDL;  						}  					}  					else  					{ -						LL_WARNS("AvatarRenderInfo") << "LRI: malformed get response agents content is not map" << LL_ENDL; +						LL_WARNS("AvatarRenderInfo") << "malformed get response is not map" << LL_ENDL;  					} - -				}	// has "agents" -				else if (content.has(KEY_ERROR)) -				{ -					const LLSD & error = content[KEY_ERROR]; -					LL_WARNS("AvatarRenderInfo") << "Avatar render info GET error: " -						<< error[KEY_IDENTIFIER] -						<< ": " << error[KEY_MESSAGE]  -						<< " from region " << regionp->getName() -						<< LL_ENDL; -				} +                }  				else  				{ -					LL_WARNS("AvatarRenderInfo") << "LRI: no agent key in get response" << LL_ENDL; +					LL_WARNS("AvatarRenderInfo") << "malformed get response parse failure" << LL_ENDL;  				} -			} -			else -			{ -				LL_WARNS("AvatarRenderInfo") << "LRI: malformed get response is not map" << LL_ENDL; -			} -		} -		else -		{ -			LL_WARNS("AvatarRenderInfo") << "Avatar render weight info recieved but region not found for "  -				<< mRegionHandle << LL_ENDL; +            } +            else +            { +                // Something went wrong.  Translate the status to +                // a meaningful message. +                LL_WARNS("AvatarRenderInfo") << "GET failed Status:  " +											 << status.toTerseString() +											 << ", Reason:  " << status.toString() +											 << LL_ENDL; +            }            + +			delete this;    // release the handler object  		} -	} - -private: -	U64		mRegionHandle;  };  // HTTP responder class for POST request for avatar render weight information -class LLAvatarRenderInfoPostResponder : public LLHTTPClient::Responder +class LLAvatarRenderInfoPostHandler : public LLCore::HttpHandler  { -public: -	LLAvatarRenderInfoPostResponder(U64 region_handle) : mRegionHandle(region_handle) -	{ -	} +  private: +	LOG_CLASS(LLAvatarRenderInfoPostHandler); -	virtual void error(U32 statusNum, const std::string& reason) +  public: +	LLAvatarRenderInfoPostHandler() : LLCore::HttpHandler()  	{ -		LLViewerRegion * regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle); -		if (regionp) -		{ -			LL_WARNS("AvatarRenderInfo") << "HTTP error result for avatar weight POST: " << statusNum  -				<< ", " << reason -				<< " returned by region " << regionp->getName() -				<< LL_ENDL; -		} -		else -		{ -			LL_WARNS("AvatarRenderInfo") << "Avatar render weight POST error recieved but region not found for "  -				<< mRegionHandle  -				<< ", error " << statusNum  -				<< ", " << reason -				<< LL_ENDL; -		}  	} -	virtual void result(const LLSD& content) -	{ -		LLViewerRegion * regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle); -		if (regionp) +	void onCompleted(LLCore::HttpHandle handle, +					 LLCore::HttpResponse* response)  		{ -			LL_DEBUGS("AvatarRenderInfo") << "LRI: Result for avatar weights POST for region " << regionp->getName() -										 << ": " << content << LL_ENDL; - -			if (content.isMap()) +			LLCore::HttpStatus status = response->getStatus(); +			if (status)  			{ -				if (content.has(KEY_ERROR)) -				{ -					const LLSD & error = content[KEY_ERROR]; -					LL_WARNS("AvatarRenderInfo") << "Avatar render info POST error: " -						<< error[KEY_IDENTIFIER] -						<< ": " << error[KEY_MESSAGE]  -						<< " from region " << regionp->getName() -						<< LL_ENDL; -				} +				LL_DEBUGS("AvatarRenderInfo") << "post succeeded" << LL_ENDL;  			} +			else +			{ +				// Something went wrong.  Translate the status to +				// a meaningful message. +				LL_WARNS("AvatarRenderInfo") << "POST failed Status:  " +											 << status.toTerseString() +											 << ", Reason:  " << status.toString() +											 << LL_ENDL; +			}            + +			delete this;    // release the handler object  		} -		else -		{ -			LL_INFOS("AvatarRenderInfo") << "Avatar render weight POST result recieved but region not found for "  -				<< mRegionHandle << LL_ENDL; -		} -	} - -private: -	U64		mRegionHandle;  }; -// static   // Send request for one region, no timer checks +// called when the   void LLAvatarRenderInfoAccountant::sendRenderInfoToRegion(LLViewerRegion * regionp)  { -	std::string url = regionp->getCapability("AvatarRenderInfo"); -	if (!url.empty()) +	if ( regionp->getRenderInfoReportTimer().hasExpired() ) // Time to make request  	{ -		LL_DEBUGS("AvatarRenderInfo") << "LRI: Checking for avatar render info to send to region " -									  << regionp->getName()  -									  << " from " << url -									  << LL_ENDL; - -		// Build the render info to POST to the region -		LLSD report = LLSD::emptyMap(); -		LLSD agents = LLSD::emptyMap(); -				 -		std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin(); -		while( iter != LLCharacter::sInstances.end() ) +		U32 num_avs = 0; +	 +		std::string url = regionp->getCapability("AvatarRenderInfo"); +		if (!url.empty())  		{ -			LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(*iter); -			if (avatar && -				avatar->getRezzedStatus() >= 2 &&					// Mostly rezzed (maybe without baked textures downloaded) -				!avatar->isDead() &&								// Not dead yet -				avatar->getObjectHost() == regionp->getHost())		// Ensure it's on the same region +			// Build the render info to POST to the region +			LLSD agents = LLSD::emptyMap(); +				 +			std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin(); +			while( iter != LLCharacter::sInstances.end() )  			{ -				avatar->calculateUpdateRenderCost();			// Make sure the numbers are up-to-date - -				LLSD info = LLSD::emptyMap(); -				if (avatar->getVisualComplexity() > 0) +				LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(*iter); +				if (avatar && +					avatar->getRezzedStatus() >= 2 &&					// Mostly rezzed (maybe without baked textures downloaded) +					!avatar->isDead() &&								// Not dead yet +					avatar->getObjectHost() == regionp->getHost())		// Ensure it's on the same region  				{ -					info[KEY_WEIGHT] = avatar->getVisualComplexity(); -					agents[avatar->getID().asString()] = info; +					avatar->calculateUpdateRenderCost();			// Make sure the numbers are up-to-date -					LL_DEBUGS("AvatarRenderInfo") << "LRI: Sending avatar render info for " << avatar->getID() -												 << ": " << info << LL_ENDL; +					LLSD info = LLSD::emptyMap(); +					if (avatar->getVisualComplexity() > 0) +					{ +						info[KEY_WEIGHT] = avatar->getVisualComplexity(); +						agents[avatar->getID().asString()] = info; + +						LL_DEBUGS("AvatarRenderInfo") << "Sending avatar render info for " << avatar->getID() +													  << ": " << info << LL_ENDL; +						num_avs++; +					}  				} +				iter++;  			} -			iter++; -		} -		report[KEY_AGENTS] = agents; -		if (agents.size() > 0) +			if (num_avs > 0) +			{ +				LLSD report = LLSD::emptyMap(); +				report[KEY_AGENTS] = agents; + +				LLCore::HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID); +				LLAvatarRenderInfoPostHandler* handler = new LLAvatarRenderInfoPostHandler; +			 +				handle = LLCoreHttpUtil::requestPostWithLLSD(mHttpRequest, +															 http_policy, +															 http_priority, +															 url, +															 report, +															 mHttpOptions, +															 mHttpHeaders, +															 handler); +				if (LLCORE_HTTP_HANDLE_INVALID == handle) +				{ +					LLCore::HttpStatus status(mHttpRequest->getStatus()); +					LL_WARNS("AvatarRenderInfo") << "HTTP POST request failed" +												 << " Status: " << status.toTerseString() +												 << " Reason: '" << status.toString() << "'" +												 << LL_ENDL; +					delete handler; +				} +				else +				{ +					LL_INFOS("AvatarRenderInfo") << "Sent render costs for " << num_avs +												 << " avatars to region " << regionp->getName() +												 << LL_ENDL; + + +				}			 +			} +			else +			{ +				LL_DEBUGS("AvatarRenderInfo") << "no agent info to send" << LL_ENDL; +			} +		} +		else  		{ -			LL_INFOS("AvatarRenderInfo") << "LRI: Sending info for " << agents.size() -										 << " avatars to region " << regionp->getName() -										 << LL_ENDL; -			LLHTTPClient::post(url, report, new LLAvatarRenderInfoPostResponder(regionp->getHandle())); +			LL_WARNS("AvatarRenderInfo") << "AvatarRenderInfo cap is empty" << LL_ENDL;  		} + +		// Reset this regions timer, moving to longer intervals if there are lots of avatars around +		regionp->getRenderInfoReportTimer().resetWithExpiry(SECS_BETWEEN_REGION_REPORTS + (2.f * num_avs));  	}  } @@ -285,16 +320,39 @@ void LLAvatarRenderInfoAccountant::sendRenderInfoToRegion(LLViewerRegion * regio  // Send request for one region, no timer checks  void LLAvatarRenderInfoAccountant::getRenderInfoFromRegion(LLViewerRegion * regionp)  { -	std::string url = regionp->getCapability("AvatarRenderInfo"); -	if (!url.empty()) +	if (regionp->getRenderInfoRequestTimer().hasExpired())  	{ -		LL_DEBUGS("AvatarRenderInfo") << "LRI: Requesting avatar render info for region " -									 << regionp->getName()  -									 << " from " << url -									 << LL_ENDL; +		std::string url = regionp->getCapability("AvatarRenderInfo"); +		if (!url.empty()) +		{ +			 +			LLAvatarRenderInfoGetHandler* handler = new LLAvatarRenderInfoGetHandler; +			// First send a request to get the latest data +			LLCore::HttpHandle handle = mHttpRequest->requestGet(http_policy, +																 http_priority, +																 url, +																 NULL, +																 NULL, +																 handler); +			if (LLCORE_HTTP_HANDLE_INVALID != handle) +			{ +				LL_INFOS("AvatarRenderInfo") << "Requested avatar render info for region " +											 << regionp->getName()  +											 << LL_ENDL; +			} +			else +			{ +				LL_WARNS("AvatarRenderInfo") << "Failed to launch HTTP GET request.  Try again." +											 << LL_ENDL; +				delete handler; +			} +		} +		else +		{ +			LL_WARNS("AvatarRenderInfo") << "no AvatarRenderInfo cap for " << regionp->getName() << LL_ENDL; +		} -		// First send a request to get the latest data -		LLHTTPClient::get(url, new LLAvatarRenderInfoGetResponder(regionp->getHandle())); +		regionp->getRenderInfoRequestTimer().resetWithExpiry(SECS_BETWEEN_REGION_REQUEST);  	}  } @@ -303,56 +361,60 @@ void LLAvatarRenderInfoAccountant::getRenderInfoFromRegion(LLViewerRegion * regi  // Called every frame - send render weight requests to every region  void LLAvatarRenderInfoAccountant::idle()  { -	if (sRenderInfoReportTimer.hasExpired()) -	{ -		const F32 SECS_BETWEEN_REGION_SCANS   =  5.f;		// Scan the region list every 5 seconds -		const F32 SECS_BETWEEN_REGION_REQUEST = 60.0;		// Update each region every 60 seconds +	mHttpRequest->update(0); // give any pending http operations a chance to call completion methods -		S32 num_avs = LLCharacter::sInstances.size(); - -		LL_DEBUGS("AvatarRenderInfo") << "LRI: Scanning all regions and checking for render info updates" +	if (mRenderInfoScanTimer.hasExpired()) +	{ +		LL_DEBUGS("AvatarRenderInfo") << "Scanning regions for render info updates"  									  << LL_ENDL; -		// Check all regions and see if it's time to fetch/send data +		// Check all regions  		for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); -				iter != LLWorld::getInstance()->getRegionList().end(); ++iter) +			 iter != LLWorld::getInstance()->getRegionList().end(); +			 ++iter)  		{  			LLViewerRegion* regionp = *iter; -			if (regionp && -				regionp->isAlive() && -				regionp->capabilitiesReceived() &&						// Region has capability URLs available -				regionp->getRenderInfoRequestTimer().hasExpired())		// Time to make request +			if (   regionp +				&& regionp->isAlive() +				&& regionp->capabilitiesReceived())  			{ +				// each of these is further governed by and resets its own timer  				sendRenderInfoToRegion(regionp);  				getRenderInfoFromRegion(regionp); - -				// Reset this regions timer, moving to longer intervals if there are lots of avatars around -				regionp->getRenderInfoRequestTimer().resetWithExpiry(SECS_BETWEEN_REGION_REQUEST + (2.f * num_avs));  			}  		}  		// We scanned all the regions, reset the request timer. -		sRenderInfoReportTimer.resetWithExpiry(SECS_BETWEEN_REGION_SCANS); +		mRenderInfoScanTimer.resetWithExpiry(SECS_BETWEEN_REGION_SCANS);  	}  } +void LLAvatarRenderInfoAccountant::resetRenderInfoScanTimer() +{ +	// this will force the next frame to rescan +	mRenderInfoScanTimer.reset(); +}  // static -// Make sRenderInfoReportTimer expire so the next call to idle() will scan and query a new region -// called via LLViewerRegion::setCapabilitiesReceived() boost signals when the capabilities +// Called via LLViewerRegion::setCapabilitiesReceived() boost signals when the capabilities  // are returned for a new LLViewerRegion, and is the earliest time to get render info -void LLAvatarRenderInfoAccountant::expireRenderInfoReportTimer(const LLUUID& region_id) +void LLAvatarRenderInfoAccountant::scanNewRegion(const LLUUID& region_id)  { -	LL_INFOS("AvatarRenderInfo") << "LRI: Viewer has new region capabilities, clearing global render info timer"  -								 << " and timer for region " << region_id -								 << LL_ENDL; +	LL_INFOS("AvatarRenderInfo") << region_id << LL_ENDL; -	// Reset the global timer so it will scan regions immediately -	sRenderInfoReportTimer.reset(); +	// Reset the global timer so it will scan regions on the next call to ::idle +	LLAvatarRenderInfoAccountant::getInstance()->resetRenderInfoScanTimer();  	LLViewerRegion* regionp = LLWorld::instance().getRegionFromID(region_id);  	if (regionp) -	{	// Reset the region's timer so it will request data immediately +	{	// Reset the region's timers so we will: +		//  * request render info from it immediately +		//  * report on the following scan  		regionp->getRenderInfoRequestTimer().reset(); +		regionp->getRenderInfoReportTimer().resetWithExpiry(SECS_BETWEEN_REGION_SCANS); +	} +	else +	{ +		LL_WARNS("AvatarRenderInfo") << "unable to resolve region "<<region_id<<LL_ENDL;  	}  } diff --git a/indra/newview/llavatarrenderinfoaccountant.h b/indra/newview/llavatarrenderinfoaccountant.h index 62c899f7a4..8117c18f4d 100644 --- a/indra/newview/llavatarrenderinfoaccountant.h +++ b/indra/newview/llavatarrenderinfoaccountant.h @@ -33,22 +33,33 @@ class LLViewerRegion;  // Class to gather avatar rendering information   // that is sent to or fetched from regions. -class LLAvatarRenderInfoAccountant +class LLAvatarRenderInfoAccountant : public LLSingleton<LLAvatarRenderInfoAccountant>  { -public: -	LLAvatarRenderInfoAccountant()	{}; -	~LLAvatarRenderInfoAccountant()	{}; +  private: +	LOG_CLASS(LLAvatarRenderInfoAccountant); -	static void sendRenderInfoToRegion(LLViewerRegion * regionp); -	static void getRenderInfoFromRegion(LLViewerRegion * regionp); +  public: +	LLAvatarRenderInfoAccountant(); +	~LLAvatarRenderInfoAccountant(); -	static void expireRenderInfoReportTimer(const LLUUID& region_id); +	void sendRenderInfoToRegion(LLViewerRegion * regionp); +	void getRenderInfoFromRegion(LLViewerRegion * regionp); -    static void idle(); +	void idle(); // called once per frame  -private: -	// Send data updates about once per minute, only need per-frame resolution -	static LLFrameTimer sRenderInfoReportTimer; +	void resetRenderInfoScanTimer(); +	 +	static void scanNewRegion(const LLUUID& region_id); + +  private: +	// frequency of region scans, +	// further limited by per region Request and Report timers +	LLFrameTimer mRenderInfoScanTimer;  + +	//  +	LLCore::HttpRequest* mHttpRequest; +	LLCore::HttpHeaders* mHttpHeaders; +	LLCore::HttpOptions* mHttpOptions;  };  #endif /* ! defined(LL_llavatarrenderinfoaccountant_H) */ diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 11cbf3fc24..31493ca6ce 100755 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -475,8 +475,7 @@ LLViewerRegion::LLViewerRegion(const U64 &handle,  	mImpl->mObjectPartition.push_back(NULL);					//PARTITION_NONE  	mImpl->mVOCachePartition = getVOCachePartition(); -	mRenderInfoRequestTimer.resetWithExpiry(0.f);		// Set timer to be expired -	setCapabilitiesReceivedCallback(boost::bind(&LLAvatarRenderInfoAccountant::expireRenderInfoReportTimer, _1)); +	setCapabilitiesReceivedCallback(boost::bind(&LLAvatarRenderInfoAccountant::scanNewRegion, _1));  } diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index 1e225553b8..fbe229e00f 100755 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -431,7 +431,8 @@ public:  	static BOOL sVOCacheCullingEnabled; //vo cache culling enabled or not.  	static S32  sLastCameraUpdated; -	LLFrameTimer &	getRenderInfoRequestTimer()			{ return mRenderInfoRequestTimer;		}; +	LLFrameTimer &	getRenderInfoRequestTimer()	{ return mRenderInfoRequestTimer; }; +	LLFrameTimer &	getRenderInfoReportTimer()	{ return mRenderInfoReportTimer; };  	struct CompareRegionByLastUpdate  	{ @@ -536,7 +537,8 @@ private:  	// the materials capability throttle  	LLFrameTimer mMaterialsCapThrottleTimer; -LLFrameTimer	mRenderInfoRequestTimer; +	LLFrameTimer mRenderInfoRequestTimer; +	LLFrameTimer mRenderInfoReportTimer;  };  inline BOOL LLViewerRegion::getRegionProtocol(U64 protocol) const diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 816b2c8b67..7e9f098172 100755 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -3121,12 +3121,10 @@ bool LLVOAvatar::isVisuallyMuted()  				else  				{	// Determine if visually muted or not -					U32 max_cost = (U32) (max_render_cost); -  					muted = LLMuteList::getInstance()->isMuted(getID()) ||  						(mAttachmentGeometryBytes > max_attachment_bytes && max_attachment_bytes > 0) ||  						(mAttachmentSurfaceArea > max_attachment_area && max_attachment_area > 0.f) || -						(mVisualComplexity > max_cost && max_render_cost > 0); +						(mVisualComplexity > max_render_cost && max_render_cost > 0);  					// Could be part of the grand || collection above, but yanked out to make the logic visible  					if (!muted) @@ -7967,11 +7965,17 @@ void LLVOAvatar::idleUpdateRenderCost()  		{  			mText->clearString(); // clear debug text  		} -		 + +		/* +		 * NOTE: the logic for whether or not each of the values below +		 *       controls muting MUST match that in the isVisuallyMuted method. +		 */ + +		// Render Cost (ARC)  		calculateUpdateRenderCost();				// Update mVisualComplexity if needed	  		static LLCachedControl<U32> max_render_cost(gSavedSettings, "RenderAutoMuteRenderWeightLimit", 0); -		info_line = llformat("%d arc", mVisualComplexity); +		info_line = llformat("%d ARC", mVisualComplexity);  		if (max_render_cost != 0) // zero means don't care, so don't bother coloring based on this  		{ @@ -7980,16 +7984,37 @@ void LLVOAvatar::idleUpdateRenderCost()  			info_color.set(red_level, green_level, 0.0, 1.0);  			info_style = (  mVisualComplexity > max_render_cost  						  ? LLFontGL::BOLD : LLFontGL::NORMAL ); +		} +		else +		{ +			info_color.set(LLColor4::grey); +			info_style = LLFontGL::NORMAL; +		} +		mText->addLine(info_line, info_color, info_style); + +		// TEMPORARY Reported Cost +		info_line = llformat("%d reported ARC", mReportedVisualComplexity); +		mText->addLine(info_line, info_color /* same as real ARC */, LLFontGL::ITALIC); + +		// Visual rank +		info_line = llformat("%d rank", mVisibilityRank); +		if (sMaxVisible != 0) // zero means no limit, so don't bother coloring based on this +		{ +			green_level = 1.f-llclamp(((F32)sMaxVisible-(F32)mVisibilityRank)/(F32)sMaxVisible, 0.f, 1.f); +			red_level   = llmin((F32) mVisibilityRank/(F32)sMaxVisible, 1.f); +			info_color.set(red_level, green_level, 0.0, 1.0); +			info_style = (  mVisibilityRank > sMaxVisible +						  ? LLFontGL::BOLD : LLFontGL::NORMAL );  		}  		else  		{  			info_color.set(LLColor4::grey);  			info_style = LLFontGL::NORMAL;  		} -		LL_DEBUGS() << "adding max cost " << info_line << LL_ENDL;  		mText->addLine(info_line, info_color, info_style); +		// Attachment Surface Area  		static LLCachedControl<F32> max_attachment_area(gSavedSettings, "RenderAutoMuteSurfaceAreaLimit", 0);  		info_line = llformat("%.2f m^2", mAttachmentSurfaceArea); @@ -8007,9 +8032,9 @@ void LLVOAvatar::idleUpdateRenderCost()  			info_color.set(LLColor4::grey);  			info_style = LLFontGL::NORMAL;  		} -		LL_DEBUGS() << "adding max area " << info_line << LL_ENDL;  		mText->addLine(info_line, info_color, info_style); +		// Attachment byte limit  		static LLCachedControl<U32> max_attachment_bytes(gSavedSettings, "RenderAutoMuteByteLimit", 0);  		info_line = llformat("%.1f KB", mAttachmentGeometryBytes/1024.f);  		if (max_attachment_bytes != 0) // zero means don't care, so don't bother coloring based on this @@ -8025,8 +8050,7 @@ void LLVOAvatar::idleUpdateRenderCost()  			info_color.set(LLColor4::grey);  			info_style = LLFontGL::NORMAL;  		} -		LL_DEBUGS() << "adding max bytes " << info_line << LL_ENDL; -		mText->addLine(info_line, info_color); +		mText->addLine(info_line, info_color, info_style);  		updateText(); // corrects position  	} @@ -8049,7 +8073,8 @@ void LLVOAvatar::calculateUpdateRenderCost()  		for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)  		{ -		    const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)baked_index); +		    const LLAvatarAppearanceDictionary::BakedEntry *baked_dict +				= LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)baked_index);  			ETextureIndex tex_index = baked_dict->mTextureIndex;  			if ((tex_index != TEX_SKIRT_BAKED) || (isWearingWearableType(LLWearableType::WT_SKIRT)))  			{ @@ -8061,11 +8086,11 @@ void LLVOAvatar::calculateUpdateRenderCost()  		} -		for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();  -			 iter != mAttachmentPoints.end(); -			 ++iter) +		for (attachment_map_t::const_iterator attachment_point = mAttachmentPoints.begin();  +			 attachment_point != mAttachmentPoints.end(); +			 ++attachment_point)  		{ -			LLViewerJointAttachment* attachment = iter->second; +			LLViewerJointAttachment* attachment = attachment_point->second;  			for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();  				 attachment_iter != attachment->mAttachedObjects.end();  				 ++attachment_iter) @@ -8095,10 +8120,12 @@ void LLVOAvatar::calculateUpdateRenderCost()  								}  							} -							for (LLVOVolume::texture_cost_t::iterator iter = textures.begin(); iter != textures.end(); ++iter) +							for (LLVOVolume::texture_cost_t::iterator volume_texture = textures.begin(); +								 volume_texture != textures.end(); +								 ++volume_texture)  							{  								// add the cost of each individual texture in the linkset -								cost += iter->second; +								cost += volume_texture->second;  							}  						}  					}  | 
