diff options
Diffstat (limited to 'indra/newview/llavatarrenderinfoaccountant.cpp')
-rw-r--r-- | indra/newview/llavatarrenderinfoaccountant.cpp | 292 |
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; } |