MAINT-4716: correct reading of and debug display for avatar render cost info
parent
8f5ddebf0a
commit
fe627f6474
|
|
@ -5090,7 +5090,7 @@ void LLAppViewer::idle()
|
|||
}
|
||||
|
||||
// Update AV render info
|
||||
LLAvatarRenderInfoAccountant::idle();
|
||||
LLAvatarRenderInfoAccountant::getInstance()->idle();
|
||||
|
||||
{
|
||||
LL_RECORD_BLOCK_TIME(FTM_AUDIO_UPDATE);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) */
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue