MAINT-4716: correct reading of and debug display for avatar render cost info

master
Oz Linden 2014-12-15 15:59:49 -05:00
parent 8f5ddebf0a
commit fe627f6474
6 changed files with 340 additions and 239 deletions

View File

@ -5090,7 +5090,7 @@ void LLAppViewer::idle()
}
// Update AV render info
LLAvatarRenderInfoAccountant::idle();
LLAvatarRenderInfoAccountant::getInstance()->idle();
{
LL_RECORD_BLOCK_TIME(FTM_AUDIO_UPDATE);

View File

@ -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;
}
private:
U64 mRegionHandle;
delete this; // release the handler object
}
};
// 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);
public:
LLAvatarRenderInfoPostHandler() : 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 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)
{
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
{
LL_INFOS("AvatarRenderInfo") << "Avatar render weight POST result recieved but region not found for "
<< mRegionHandle << 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;
}
private:
U64 mRegionHandle;
delete this; // release the handler object
}
};
// 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();
U32 num_avs = 0;
std::string url = regionp->getCapability("AvatarRenderInfo");
if (!url.empty())
{
// 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() )
{
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
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++;
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_WARNS("AvatarRenderInfo") << "AvatarRenderInfo cap is empty" << LL_ENDL;
}
report[KEY_AGENTS] = agents;
if (agents.size() > 0)
{
LL_INFOS("AvatarRenderInfo") << "LRI: Sending info for " << agents.size()
<< " avatars to region " << regionp->getName()
<< LL_ENDL;
LLHTTPClient::post(url, report, new LLAvatarRenderInfoPostResponder(regionp->getHandle()));
}
// 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;
}
}

View File

@ -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) */

View File

@ -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));
}

View File

@ -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

View File

@ -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;
}
LL_DEBUGS() << "adding max cost " << info_line << LL_ENDL;
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;
}
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;
}
}
}