summaryrefslogtreecommitdiff
path: root/indra/newview/llavatarrenderinfoaccountant.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llavatarrenderinfoaccountant.cpp')
-rw-r--r--indra/newview/llavatarrenderinfoaccountant.cpp292
1 files changed, 146 insertions, 146 deletions
diff --git a/indra/newview/llavatarrenderinfoaccountant.cpp b/indra/newview/llavatarrenderinfoaccountant.cpp
index 470f516db2..5431daca32 100644
--- a/indra/newview/llavatarrenderinfoaccountant.cpp
+++ b/indra/newview/llavatarrenderinfoaccountant.cpp
@@ -30,6 +30,7 @@
#include "llviewerprecompiledheaders.h"
// associated header
#include "llavatarrenderinfoaccountant.h"
+#include "llavatarrendernotifier.h"
// STL headers
// std headers
// external library headers
@@ -49,17 +50,29 @@
static const std::string KEY_AGENTS = "agents"; // map
static const std::string KEY_WEIGHT = "weight"; // integer
+static const std::string KEY_TOO_COMPLEX = "tooComplex"; // bool
+static const std::string KEY_OVER_COMPLEXITY_LIMIT = "overlimit"; // integer
+static const std::string KEY_REPORTING_COMPLEXITY_LIMIT = "reportinglimit"; // integer
static const std::string KEY_IDENTIFIER = "identifier";
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;
-//LLCore::HttpRequest::ptr_t LLAvatarRenderInfoAccountant::sHttpRequest;
+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
+
//=========================================================================
+LLAvatarRenderInfoAccountant::LLAvatarRenderInfoAccountant()
+{
+}
+
+LLAvatarRenderInfoAccountant::~LLAvatarRenderInfoAccountant()
+{
+}
+
+
void LLAvatarRenderInfoAccountant::avatarRenderInfoGetCoro(std::string url, U64 regionHandle)
{
LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
@@ -77,6 +90,8 @@ void LLAvatarRenderInfoAccountant::avatarRenderInfoGetCoro(std::string url, U64
return;
}
+ regionp->getRenderInfoRequestTimer().resetWithExpiry(SECS_BETWEEN_REGION_REQUEST);
+
LLSD httpResults = result["http_result"];
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
@@ -91,39 +106,65 @@ void LLAvatarRenderInfoAccountant::avatarRenderInfoGetCoro(std::string url, U64
const LLSD & agents = result[KEY_AGENTS];
if (agents.isMap())
{
- LLSD::map_const_iterator report_iter = agents.beginMap();
- while (report_iter != agents.endMap())
+ for (LLSD::map_const_iterator agent_iter = agents.beginMap();
+ agent_iter != agents.endMap();
+ agent_iter++
+ )
{
- LLUUID target_agent_id = LLUUID(report_iter->first);
- const LLSD & agent_info_map = report_iter->second;
+ LLUUID target_agent_id = LLUUID(agent_iter->first);
LLViewerObject* avatarp = gObjectList.findObject(target_agent_id);
- if (avatarp &&
- avatarp->isAvatar() &&
- agent_info_map.isMap())
- { // Extract the data for this avatar
-
- if (LLAvatarRenderInfoAccountant::logRenderInfo())
+ if (avatarp && avatarp->isAvatar())
+ {
+ const LLSD & agent_info_map = agent_iter->second;
+ if (agent_info_map.isMap())
{
- LL_INFOS() << "LRI: Agent " << target_agent_id
- << ": " << agent_info_map << LL_ENDL;
- }
+ LL_DEBUGS("AvatarRenderInfo") << " Agent " << target_agent_id
+ << ": " << agent_info_map << LL_ENDL;
- if (agent_info_map.has(KEY_WEIGHT))
+ if (agent_info_map.has(KEY_WEIGHT))
+ {
+ ((LLVOAvatar *) avatarp)->setReportedVisualComplexity(agent_info_map[KEY_WEIGHT].asInteger());
+ }
+ }
+ else
{
- ((LLVOAvatar *) avatarp)->setReportedVisualComplexity(agent_info_map[KEY_WEIGHT].asInteger());
+ LL_WARNS("AvatarRenderInfo") << "agent entry invalid"
+ << " agent " << target_agent_id
+ << " map " << agent_info_map
+ << LL_ENDL;
}
}
- report_iter++;
- }
+ else
+ {
+ LL_DEBUGS("AvatarRenderInfo") << "Unknown agent " << target_agent_id << LL_ENDL;
+ }
+ } // for agent_iter
+ }
+ else
+ {
+ LL_WARNS("AvatarRenderInfo") << "malformed get response '" << KEY_AGENTS << "' is not map" << LL_ENDL;
}
} // has "agents"
- else if (result.has(KEY_ERROR))
+ else
{
- const LLSD & error = result[KEY_ERROR];
- LL_WARNS() << "Avatar render info GET error: "
- << error[KEY_IDENTIFIER]
- << ": " << error[KEY_MESSAGE]
- << " from region " << regionp->getName()
+ LL_INFOS("AvatarRenderInfo") << "no '"<< KEY_AGENTS << "' key in get response" << LL_ENDL;
+ }
+
+ if ( result.has(KEY_REPORTING_COMPLEXITY_LIMIT)
+ && result.has(KEY_OVER_COMPLEXITY_LIMIT))
+ {
+ U32 reporting = result[KEY_REPORTING_COMPLEXITY_LIMIT].asInteger();
+ U32 overlimit = result[KEY_OVER_COMPLEXITY_LIMIT].asInteger();
+
+ LL_DEBUGS("AvatarRenderInfo") << "complexity limit: "<<reporting<<" reporting, "<<overlimit<<" over limit"<<LL_ENDL;
+
+ LLAvatarRenderNotifier::getInstance()->updateNotificationRegion(reporting, overlimit);
+ }
+ else
+ {
+ LL_WARNS("AvatarRenderInfo")
+ << "response is missing either '" << KEY_REPORTING_COMPLEXITY_LIMIT
+ << "' or '" << KEY_OVER_COMPLEXITY_LIMIT << "'"
<< LL_ENDL;
}
@@ -145,16 +186,14 @@ void LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro(std::string url, U
return;
}
- if (logRenderInfo())
- {
- LL_INFOS("AvatarRenderInfoAccountant") << "LRI: Sending avatar render info to region " << regionp->getName()
- << " from " << url << LL_ENDL;
- }
+ LL_DEBUGS("AvatarRenderInfoAccountant")
+ << "Sending avatar render info for region " << regionp->getName()
+ << " to " << url << LL_ENDL;
+ U32 num_avs = 0;
// 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() )
{
@@ -164,31 +203,35 @@ void LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro(std::string url, U
!avatar->isDead() && // Not dead yet
avatar->getObjectHost() == regionp->getHost()) // Ensure it's on the same region
{
- avatar->calculateUpdateRenderCost(); // Make sure the numbers are up-to-date
+ avatar->calculateUpdateRenderComplexity(); // Make sure the numbers are up-to-date
LLSD info = LLSD::emptyMap();
- if (avatar->getVisualComplexity() > 0)
+ U32 avatar_complexity = avatar->getVisualComplexity();
+ if (avatar_complexity > 0)
{
- info[KEY_WEIGHT] = avatar->getVisualComplexity();
+ // the weight/complexity is unsigned, but LLSD only stores signed integers,
+ // so if it's over that (which would be ridiculously high), just store the maximum signed int value
+ info[KEY_WEIGHT] = (S32)(avatar_complexity < S32_MAX ? avatar_complexity : S32_MAX);
+ info[KEY_TOO_COMPLEX] = LLSD::Boolean(avatar->isTooComplex());
agents[avatar->getID().asString()] = info;
- if (logRenderInfo())
- {
- LL_INFOS("AvatarRenderInfoAccountant") << "LRI: Sending avatar render info for " << avatar->getID()
- << ": " << info << LL_ENDL;
- LL_INFOS("AvatarRenderInfoAccountant") << "LRI: other info geometry " << avatar->getAttachmentGeometryBytes()
- << ", area " << avatar->getAttachmentSurfaceArea()
- << LL_ENDL;
- }
+ LL_DEBUGS("AvatarRenderInfo") << "Sending avatar render info for " << avatar->getID()
+ << ": " << info << LL_ENDL;
+ num_avs++;
}
}
iter++;
}
- if (agents.size() == 0)
- return;
+ // 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));
+ if (num_avs == 0)
+ return; // nothing to report
+
+ LLSD report = LLSD::emptyMap();
report[KEY_AGENTS] = agents;
+
regionp = NULL;
LLSD result = httpAdapter->postAndSuspend(httpRequest, url, report);
@@ -208,34 +251,40 @@ void LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro(std::string url, U
return;
}
- if (LLAvatarRenderInfoAccountant::logRenderInfo())
- {
- LL_INFOS("AvatarRenderInfoAccountant") << "LRI: Result for avatar weights POST for region " << regionp->getName()
- << ": " << result << LL_ENDL;
- }
-
if (result.isMap())
{
if (result.has(KEY_ERROR))
{
const LLSD & error = result[KEY_ERROR];
- LL_WARNS("AvatarRenderInfoAccountant") << "Avatar render info POST error: "
+ LL_WARNS("AvatarRenderInfoAccountant") << "POST error: "
<< error[KEY_IDENTIFIER]
<< ": " << error[KEY_MESSAGE]
<< " from region " << regionp->getName()
<< LL_ENDL;
}
+ else
+ {
+ LL_DEBUGS("AvatarRenderInfoAccountant")
+ << "POST result for region " << regionp->getName()
+ << ": " << result
+ << LL_ENDL;
+ }
+ }
+ else
+ {
+ LL_WARNS("AvatarRenderInfoAccountant") << "Malformed POST response from region '" << regionp->getName()
+ << LL_ENDL;
}
-
-
}
-// static
-// Send request for one region, no timer checks
+// Send request for avatar weights in one region
+// called when the mRenderInfoScanTimer expires (forced when entering a new region)
void LLAvatarRenderInfoAccountant::sendRenderInfoToRegion(LLViewerRegion * regionp)
{
std::string url = regionp->getCapability("AvatarRenderInfo");
- if (!url.empty())
+ if ( !url.empty() // we have the capability
+ && regionp->getRenderInfoReportTimer().hasExpired() // Time to make request)
+ )
{
std::string coroname =
LLCoros::instance().launch("LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro",
@@ -243,23 +292,19 @@ void LLAvatarRenderInfoAccountant::sendRenderInfoToRegion(LLViewerRegion * regio
}
}
-
-
-
-// static
-// Send request for one region, no timer checks
+// Send request for avatar weights in one region
+// called when the mRenderInfoScanTimer expires (forced when entering a new region)
void LLAvatarRenderInfoAccountant::getRenderInfoFromRegion(LLViewerRegion * regionp)
{
std::string url = regionp->getCapability("AvatarRenderInfo");
- if (!url.empty())
+ if ( !url.empty()
+ && regionp->getRenderInfoRequestTimer().hasExpired()
+ )
{
- if (logRenderInfo())
- {
- LL_INFOS() << "LRI: Requesting avatar render info for region "
- << regionp->getName()
- << " from " << url
- << LL_ENDL;
- }
+ LL_DEBUGS("AvatarRenderInfo")
+ << "Requesting avatar render info for region " << regionp->getName()
+ << " from " << url
+ << LL_ENDL;
// First send a request to get the latest data
std::string coroname =
@@ -268,107 +313,62 @@ void LLAvatarRenderInfoAccountant::getRenderInfoFromRegion(LLViewerRegion * regi
}
}
-
// static
// Called every frame - send render weight requests to every region
void LLAvatarRenderInfoAccountant::idle()
{
-// if (!LLAvatarRenderInfoAccountant::sHttpRequest)
-// sHttpRequest = LLCore::HttpRequest::ptr_t(new LLCore::HttpRequest());
-
- if (sRenderInfoReportTimer.hasExpired())
+ if (mRenderInfoScanTimer.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
-
- S32 num_avs = LLCharacter::sInstances.size();
+ LL_DEBUGS("AvatarRenderInfo") << "Scanning regions for render info updates"
+ << LL_ENDL;
- if (logRenderInfo())
- {
- LL_INFOS() << "LRI: Scanning all regions and checking 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);
- }
-
- static LLCachedControl<U32> render_auto_mute_functions(gSavedSettings, "RenderAutoMuteFunctions", 0);
- static U32 prev_render_auto_mute_functions = (U32) -1;
- if (prev_render_auto_mute_functions != render_auto_mute_functions)
- {
- prev_render_auto_mute_functions = render_auto_mute_functions;
-
- // Adjust menus
- BOOL show_items = (BOOL)(render_auto_mute_functions & 0x04);
- gMenuAvatarOther->setItemVisible( std::string("Normal"), show_items);
- gMenuAvatarOther->setItemVisible( std::string("Always use impostor"), show_items);
- gMenuAvatarOther->setItemVisible( std::string("Never use impostor"), show_items);
- gMenuAvatarOther->setItemVisible( std::string("Impostor seperator"), show_items);
-
- gMenuAttachmentOther->setItemVisible( std::string("Normal"), show_items);
- gMenuAttachmentOther->setItemVisible( std::string("Always use impostor"), show_items);
- gMenuAttachmentOther->setItemVisible( std::string("Never use impostor"), show_items);
- gMenuAttachmentOther->setItemVisible( std::string("Impostor seperator"), show_items);
-
- if (!show_items)
- { // Turning off visual muting
- for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
- iter != LLCharacter::sInstances.end(); ++iter)
- { // Make sure all AVs have the setting cleared
- LLVOAvatar* inst = (LLVOAvatar*) *iter;
- inst->setCachedVisualMute(false);
- }
- }
+ 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)
{
- if (logRenderInfo())
- {
- LL_INFOS() << "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;
}
-}
-
-// static
-bool LLAvatarRenderInfoAccountant::logRenderInfo()
-{
- return true;
-// static LLCachedControl<bool> render_mute_logging_enabled(gSavedSettings, "RenderAutoMuteLogging", false);
-// return render_mute_logging_enabled;
}