diff options
-rwxr-xr-x | indra/newview/llagent.cpp | 7 | ||||
-rwxr-xr-x | indra/newview/llagentwearables.cpp | 2 | ||||
-rw-r--r-- | indra/newview/llagentwearablesfetch.cpp | 4 | ||||
-rwxr-xr-x | indra/newview/llappearancemgr.cpp | 2 | ||||
-rwxr-xr-x[-rw-r--r--] | indra/newview/llappviewer.cpp | 7 | ||||
-rw-r--r-- | indra/newview/llappviewerwin32.cpp | 2 | ||||
-rwxr-xr-x | indra/newview/llviewerassetstats.cpp | 42 | ||||
-rwxr-xr-x | indra/newview/llviewerassetstats.h | 10 | ||||
-rwxr-xr-x[-rw-r--r--] | indra/newview/llviewerstats.cpp | 73 | ||||
-rwxr-xr-x | indra/newview/llviewerstats.h | 11 | ||||
-rwxr-xr-x | indra/newview/llvoavatar.cpp | 111 | ||||
-rwxr-xr-x | indra/newview/llvoavatar.h | 12 | ||||
-rwxr-xr-x | indra/newview/llvoavatarself.cpp | 137 | ||||
-rwxr-xr-x | indra/newview/llvoavatarself.h | 13 | ||||
-rwxr-xr-x | indra/newview/tests/llviewerassetstats_test.cpp | 47 |
15 files changed, 289 insertions, 191 deletions
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 60873cf41f..c86b75791d 100755 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -4338,11 +4338,9 @@ void LLAgent::sendAgentSetAppearance() if (!gAgentWearables.changeInProgress()) { // Change is fully resolved, can close some open phases. - gAgentAvatarp->getPhases().stopPhase("process_initial_wearables_update"); - gAgentAvatarp->getPhases().stopPhase("wear_inventory_category"); + gAgentAvatarp->stopPhase("process_initial_wearables_update"); + gAgentAvatarp->stopPhase("wear_inventory_category"); } - - gAgentAvatarp->sendAppearanceChangeMetrics(); if (!isAgentAvatarValid() || (getRegion() && getRegion()->getCentralBakeVersion())) return; @@ -4409,6 +4407,7 @@ void LLAgent::sendAgentSetAppearance() // IMG_DEFAULT_AVATAR means not baked. 0 index should be ignored for baked textures if (!gAgentAvatarp->isTextureDefined(texture_index, 0)) { + LL_DEBUGS("Avatar") << "texture not current for baked " << (S32)baked_index << " local " << (S32)texture_index << llendl; textures_current = FALSE; break; } diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index 70f4de8db2..0c79ac0ba3 100755 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -797,7 +797,7 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs if (isAgentAvatarValid()) { //gAgentAvatarp->clearPhases(); // reset phase timers for outfit loading. - gAgentAvatarp->getPhases().startPhase("process_initial_wearables_update"); + gAgentAvatarp->startPhase("process_initial_wearables_update"); gAgentAvatarp->outputRezTiming("Received initial wearables update"); } diff --git a/indra/newview/llagentwearablesfetch.cpp b/indra/newview/llagentwearablesfetch.cpp index 2d622b380a..6f1658d1cc 100644 --- a/indra/newview/llagentwearablesfetch.cpp +++ b/indra/newview/llagentwearablesfetch.cpp @@ -80,7 +80,7 @@ LLInitialWearablesFetch::LLInitialWearablesFetch(const LLUUID& cof_id) : { if (isAgentAvatarValid()) { - gAgentAvatarp->getPhases().startPhase("initial_wearables_fetch"); + gAgentAvatarp->startPhase("initial_wearables_fetch"); gAgentAvatarp->outputRezTiming("Initial wearables fetch started"); } } @@ -99,7 +99,7 @@ void LLInitialWearablesFetch::done() doOnIdleOneTime(boost::bind(&LLInitialWearablesFetch::processContents,this)); if (isAgentAvatarValid()) { - gAgentAvatarp->getPhases().stopPhase("initial_wearables_fetch"); + gAgentAvatarp->stopPhase("initial_wearables_fetch"); gAgentAvatarp->outputRezTiming("Initial wearables fetch done"); } } diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index f1ba4ad453..1a6d49c7a2 100755 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -2006,8 +2006,6 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool update_base_outfit_ordering) llwarns << "Called updateAppearanceFromCOF inside updateAppearanceFromCOF, skipping" << llendl; return; } - - LLVOAvatar::ScopedPhaseSetter(gAgentAvatarp,"update_appearance_from_cof"); BoolSetter setIsInUpdateAppearanceFromCOF(mIsInUpdateAppearanceFromCOF); diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 03b11939a9..9a5010c781 100644..100755 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -3612,6 +3612,12 @@ void LLAppViewer::requestQuit() // Try to send metrics back to the grid metricsSend(!gDisconnected); + + // Try to send last batch of avatar rez metrics. + if (!gDisconnected && isAgentAvatarValid()) + { + gAgentAvatarp->updateAvatarRezMetrics(true); // force a last packet to be sent. + } LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral*)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINT, TRUE); effectp->setPositionGlobal(gAgent.getPositionGlobal()); @@ -4404,7 +4410,6 @@ void LLAppViewer::idle() // The 5-second interval is nice for this purpose. If the object debug // bit moves or is disabled, please give this a suitable home. LLViewerAssetStatsFF::record_fps_main(gFPSClamped); - LLViewerAssetStatsFF::record_avatar_stats(); } } diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index 8326be433e..82b93b52a2 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -92,7 +92,7 @@ void nvapi_error(NvAPI_Status status) llwarns << szDesc << llendl; //should always trigger when asserts are enabled - llassert(status == NVAPI_OK); + //llassert(status == NVAPI_OK); } // Create app mutex creates a unique global windows object. diff --git a/indra/newview/llviewerassetstats.cpp b/indra/newview/llviewerassetstats.cpp index 4c59fd0371..ed768eb093 100755 --- a/indra/newview/llviewerassetstats.cpp +++ b/indra/newview/llviewerassetstats.cpp @@ -30,7 +30,6 @@ #include "llregionhandle.h" #include "stdtypes.h" -#include "llvoavatar.h" /* * Classes and utility functions for per-thread and per-region @@ -127,8 +126,6 @@ LLViewerAssetStats::PerRegionStats::merge(const LLViewerAssetStats::PerRegionSta mFPS.merge(src.mFPS); } - // Avatar stats - data all comes from main thread, so leave alone. - // Requests for (int i = 0; i < LL_ARRAY_SIZE(mRequests); ++i) { @@ -160,9 +157,7 @@ LLViewerAssetStats::LLViewerAssetStats() LLViewerAssetStats::LLViewerAssetStats(const LLViewerAssetStats & src) : mRegionHandle(src.mRegionHandle), - mResetTimestamp(src.mResetTimestamp), - mPhaseStats(src.mPhaseStats), - mAvatarRezStates(src.mAvatarRezStates) + mResetTimestamp(src.mResetTimestamp) { const PerRegionContainer::const_iterator it_end(src.mRegionStats.end()); for (PerRegionContainer::const_iterator it(src.mRegionStats.begin()); it_end != it; ++it) @@ -258,17 +253,6 @@ LLViewerAssetStats::recordFPS(F32 fps) mCurRegionStats->mFPS.record(fps); } -void -LLViewerAssetStats::recordAvatarStats() -{ - std::vector<S32> rez_counts; - LLVOAvatar::getNearbyRezzedStats(rez_counts); - mAvatarRezStates = rez_counts; - mPhaseStats.clear(); - mPhaseStats["cloud"] = LLViewerStats::PhaseMap::getPhaseStats("cloud"); - mPhaseStats["cloud-or-gray"] = LLViewerStats::PhaseMap::getPhaseStats("cloud-or-gray"); -} - LLSD LLViewerAssetStats::asLLSD(bool compact_output) { @@ -299,11 +283,6 @@ LLViewerAssetStats::asLLSD(bool compact_output) static const LLSD::String max_tag("max"); static const LLSD::String mean_tag("mean"); - // Avatar sub-tags - static const LLSD::String avatar_tag("avatar"); - static const LLSD::String avatar_nearby_tag("nearby"); - static const LLSD::String avatar_phase_stats_tag("phase_stats"); - const duration_t now = LLViewerAssetStatsFF::get_timestamp(); mCurRegionStats->accumulateTime(now); @@ -362,16 +341,6 @@ LLViewerAssetStats::asLLSD(bool compact_output) LLSD ret = LLSD::emptyMap(); ret["regions"] = regions; ret["duration"] = LLSD::Real((now - mResetTimestamp) * 1.0e-6); - LLSD avatar_info; - avatar_info[avatar_nearby_tag] = LLSD::emptyArray(); - for (S32 rez_stat=0; rez_stat < mAvatarRezStates.size(); ++rez_stat) - { - std::string rez_status_name = LLVOAvatar::rezStatusToString(rez_stat); - avatar_info[avatar_nearby_tag][rez_status_name] = mAvatarRezStates[rez_stat]; - } - avatar_info[avatar_phase_stats_tag]["cloud"] = mPhaseStats["cloud"].getData(); - avatar_info[avatar_phase_stats_tag]["cloud-or-gray"] = mPhaseStats["cloud-or-gray"].getData(); - ret[avatar_tag] = avatar_info; return ret; } @@ -470,15 +439,6 @@ record_fps_main(F32 fps) gViewerAssetStatsMain->recordFPS(fps); } -void -record_avatar_stats() -{ - if (! gViewerAssetStatsMain) - return; - - gViewerAssetStatsMain->recordAvatarStats(); -} - // 'thread1' - should be for TextureFetch thread void diff --git a/indra/newview/llviewerassetstats.h b/indra/newview/llviewerassetstats.h index 8319752230..3381c01ed5 100755 --- a/indra/newview/llviewerassetstats.h +++ b/indra/newview/llviewerassetstats.h @@ -36,7 +36,6 @@ #include "llviewerassetstorage.h" #include "llsimplestat.h" #include "llsd.h" -#include "llvoavatar.h" /** * @class LLViewerAssetStats @@ -182,9 +181,6 @@ public: // Frames-Per-Second Samples void recordFPS(F32 fps); - // Avatar-related statistics - void recordAvatarStats(); - // Merge a source instance into a destination instance. This is // conceptually an 'operator+=()' method: // - counts are added @@ -256,10 +252,6 @@ protected: // Time of last reset duration_t mResetTimestamp; - - // Nearby avatar stats - std::vector<S32> mAvatarRezStates; - LLViewerStats::phase_stats_t mPhaseStats; }; @@ -318,8 +310,6 @@ void record_response_main(LLViewerAssetType::EType at, bool with_http, bool is_t void record_fps_main(F32 fps); -void record_avatar_stats(); - /** * Region context, event and duration loggers for Thread 1. */ diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index 1627870262..65cae9b338 100644..100755 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -733,23 +733,27 @@ void send_stats() LLHTTPClient::post(url, body, new ViewerStatsResponder()); } -LLFrameTimer& LLViewerStats::PhaseMap::getPhaseTimer(const std::string& phase_name) +LLViewerStats::PhaseMap::PhaseMap() +{ +} + +LLTimer& LLViewerStats::PhaseMap::getPhaseTimer(const std::string& phase_name) { phase_map_t::iterator iter = mPhaseMap.find(phase_name); if (iter == mPhaseMap.end()) { - LLFrameTimer timer; + LLTimer timer; mPhaseMap[phase_name] = timer; } - LLFrameTimer& timer = mPhaseMap[phase_name]; + LLTimer& timer = mPhaseMap[phase_name]; return timer; } void LLViewerStats::PhaseMap::startPhase(const std::string& phase_name) { - LLFrameTimer& timer = getPhaseTimer(phase_name); + LLTimer& timer = getPhaseTimer(phase_name); lldebugs << "startPhase " << phase_name << llendl; - timer.unpause(); + timer.start(); } void LLViewerStats::PhaseMap::stopPhase(const std::string& phase_name) @@ -760,33 +764,26 @@ void LLViewerStats::PhaseMap::stopPhase(const std::string& phase_name) if (iter->second.getStarted()) { // Going from started to paused state - record stats. - recordPhaseStat(phase_name,iter->second.getElapsedTimeF32()); + iter->second.stop(); } - lldebugs << "stopPhase " << phase_name << llendl; - iter->second.pause(); - } - else - { - lldebugs << "stopPhase " << phase_name << " is not started, no-op" << llendl; } } -void LLViewerStats::PhaseMap::stopAllPhases() +bool LLViewerStats::PhaseMap::getPhaseValues(const std::string& phase_name, F32& elapsed, bool& completed) { - for (phase_map_t::iterator iter = mPhaseMap.begin(); - iter != mPhaseMap.end(); ++iter) + phase_map_t::iterator iter = mPhaseMap.find(phase_name); + if (iter != mPhaseMap.end()) { - const std::string& phase_name = iter->first; - if (iter->second.getStarted()) - { - // Going from started to paused state - record stats. - recordPhaseStat(phase_name,iter->second.getElapsedTimeF32()); - } - lldebugs << "stopPhase (all) " << phase_name << llendl; - iter->second.pause(); + elapsed = iter->second.getElapsedTimeF32(); + completed = !iter->second.getStarted(); + return true; + } + else + { + return false; } } - + void LLViewerStats::PhaseMap::clearPhases() { lldebugs << "clearPhases" << llendl; @@ -805,31 +802,3 @@ LLSD LLViewerStats::PhaseMap::dumpPhases() } return result; } - -// static initializer -//static -LLViewerStats::phase_stats_t LLViewerStats::PhaseMap::sStats; - -LLViewerStats::PhaseMap::PhaseMap() -{ -} - -// static -LLViewerStats::StatsAccumulator& LLViewerStats::PhaseMap::getPhaseStats(const std::string& phase_name) -{ - phase_stats_t::iterator it = sStats.find(phase_name); - if (it == sStats.end()) - { - LLViewerStats::StatsAccumulator new_stats; - sStats[phase_name] = new_stats; - } - return sStats[phase_name]; -} - -// static -void LLViewerStats::PhaseMap::recordPhaseStat(const std::string& phase_name, F32 value) -{ - LLViewerStats::StatsAccumulator& stats = getPhaseStats(phase_name); - stats.push(value); -} - diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h index e02a4ccdc7..e74fb36e97 100755 --- a/indra/newview/llviewerstats.h +++ b/indra/newview/llviewerstats.h @@ -279,23 +279,22 @@ public: // Phase tracking (originally put in for avatar rezzing), tracking // progress of active/completed phases for activities like outfit changing. - typedef std::map<std::string,LLFrameTimer> phase_map_t; + typedef std::map<std::string,LLTimer> phase_map_t; typedef std::map<std::string,StatsAccumulator> phase_stats_t; class PhaseMap { private: phase_map_t mPhaseMap; - static phase_stats_t sStats; public: PhaseMap(); - LLFrameTimer& getPhaseTimer(const std::string& phase_name); + LLTimer& getPhaseTimer(const std::string& phase_name); + bool getPhaseValues(const std::string& phase_name, F32& elapsed, bool& completed); void startPhase(const std::string& phase_name); void stopPhase(const std::string& phase_name); - void stopAllPhases(); void clearPhases(); LLSD dumpPhases(); - static StatsAccumulator& getPhaseStats(const std::string& phase_name); - static void recordPhaseStat(const std::string& phase_name, F32 value); + phase_map_t::iterator begin() { return mPhaseMap.begin(); } + phase_map_t::iterator end() { return mPhaseMap.end(); } }; private: diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 483bc25b33..e298ccdb9c 100755 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -99,6 +99,7 @@ #include "lldebugmessagebox.h" #include "llsdutil.h" +#include "llsdserialize.h" extern F32 SPEED_ADJUST_MAX; extern F32 SPEED_ADJUST_MAX_SEC; @@ -5887,30 +5888,132 @@ void LLVOAvatar::updateRezzedStatusTimers() if (is_cloud && !was_cloud) { // start cloud timer. - getPhases().startPhase("cloud"); + startPhase("cloud"); } else if (was_cloud && !is_cloud) { // stop cloud timer, which will capture stats. - getPhases().stopPhase("cloud"); + stopPhase("cloud"); } // Non-cloud-or-gray to cloud-or-gray if (is_cloud_or_gray && !was_cloud_or_gray) { // start cloud-or-gray timer. - getPhases().startPhase("cloud-or-gray"); + startPhase("cloud-or-gray"); } else if (was_cloud_or_gray && !is_cloud_or_gray) { // stop cloud-or-gray timer, which will capture stats. - getPhases().stopPhase("cloud-or-gray"); + stopPhase("cloud-or-gray"); } mLastRezzedStatus = rez_status; } } +void LLVOAvatar::clearPhases() +{ + getPhases().clearPhases(); +} + +void LLVOAvatar::startPhase(const std::string& phase_name) +{ + getPhases().startPhase(phase_name); +} + +void LLVOAvatar::logPendingPhases() +{ + for (LLViewerStats::phase_map_t::iterator it = getPhases().begin(); + it != getPhases().end(); + ++it) + { + const std::string& phase_name = it->first; + F32 elapsed; + bool completed; + if (getPhases().getPhaseValues(phase_name, elapsed, completed)) + { + if (!completed) + { + logMetricsTimerRecord(phase_name, elapsed, completed); + } + else + { + llwarns << "ignoring " << phase_name << llendl; + } + } + } +} + +//static +void LLVOAvatar::logPendingPhasesAllAvatars() +{ + for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin(); + iter != LLCharacter::sInstances.end(); ++iter) + { + LLVOAvatar* inst = (LLVOAvatar*) *iter; + if( inst->isDead() ) + { + continue; + } + inst->logPendingPhases(); + } +} + +void LLVOAvatar::logMetricsTimerRecord(const std::string& phase_name, F32 elapsed, bool completed) +{ + LLSD record; + record["timer_name"] = phase_name; + record["agent_id"] = gAgent.getID(); + record["avatar_id"] = getID(); + record["elapsed"] = elapsed; + record["completed"] = completed; + U32 grid_x(0), grid_y(0); + if (getRegion()) + { + record["central_bake_version"] = LLSD::Integer(getRegion()->getCentralBakeVersion()); + grid_from_region_handle(getRegion()->getHandle(), &grid_x, &grid_y); + } + record["grid_x"] = LLSD::Integer(grid_x); + record["grid_y"] = LLSD::Integer(grid_y); + record["is_using_server_bakes"] = ((bool) isUsingServerBakes()); + record["is_self"] = isSelf(); + + + std::ostringstream ostr; + ostr << LLSDNotationStreamer(record); + LL_DEBUGS("Avatar") << "record\n" << ostr.str() << llendl; + + if (isAgentAvatarValid()) + { + gAgentAvatarp->addMetricsTimerRecord(record); + } +} + +void LLVOAvatar::stopPhase(const std::string& phase_name) +{ + F32 elapsed; + bool completed; + if (getPhases().getPhaseValues(phase_name, elapsed, completed)) + { + if (!completed) + { + getPhases().stopPhase(phase_name); + completed = true; + + } + else + { + llwarns << "stop when stopped already for " << phase_name << llendl; + } + logMetricsTimerRecord(phase_name, elapsed, completed); + } + else + { + llwarns << "stop when not started for " << phase_name << llendl; + } +} + // call periodically to keep isFullyLoaded up to date. // returns true if the value has changed. BOOL LLVOAvatar::updateIsFullyLoaded() diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index c14f18d00e..8babcc3ef3 100755 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -292,12 +292,16 @@ public: S32 mLastRezzedStatus; - LLViewerStats::PhaseMap& getPhases() - { - return mPhases; - } + + void startPhase(const std::string& phase_name); + void stopPhase(const std::string& phase_name); + void clearPhases(); + void logPendingPhases(); + static void logPendingPhasesAllAvatars(); + void logMetricsTimerRecord(const std::string& phase_name, F32 elapsed, bool completed); protected: + LLViewerStats::PhaseMap& getPhases() { return mPhases; } BOOL updateIsFullyLoaded(); BOOL processFullyLoadedChange(bool loading); void updateRuthTimer(bool loading); diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index aeac478d4e..55e927652e 100755 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -62,6 +62,7 @@ #include "llvovolume.h" #include "llsdutil.h" #include "llstartup.h" +#include "llsdserialize.h" #if LL_MSVC // disable boost::lexical_cast warning @@ -81,7 +82,7 @@ void selfStartPhase(const std::string& phase_name) { if (isAgentAvatarValid()) { - gAgentAvatarp->getPhases().startPhase(phase_name); + gAgentAvatarp->startPhase(phase_name); } } @@ -89,7 +90,7 @@ void selfStopPhase(const std::string& phase_name) { if (isAgentAvatarValid()) { - gAgentAvatarp->getPhases().stopPhase(phase_name); + gAgentAvatarp->stopPhase(phase_name); } } @@ -97,19 +98,11 @@ void selfClearPhases() { if (isAgentAvatarValid()) { - gAgentAvatarp->getPhases().clearPhases(); + gAgentAvatarp->clearPhases(); gAgentAvatarp->mLastRezzedStatus = -1; } } -void selfStopAllPhases() -{ - if (isAgentAvatarValid()) - { - gAgentAvatarp->getPhases().stopAllPhases(); - } -} - using namespace LLAvatarAppearanceDefines; /********************************************************************************* @@ -222,6 +215,7 @@ void LLVOAvatarSelf::initInstance() } //doPeriodically(output_self_av_texture_diagnostics, 30.0); + doPeriodically(boost::bind(&LLVOAvatarSelf::updateAvatarRezMetrics, this, false), 5.0); } // virtual @@ -1462,7 +1456,9 @@ BOOL LLVOAvatarSelf::isAllLocalTextureDataFinal() const const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type); for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++) { - if (getLocalDiscardLevel(*local_tex_iter, wearable_index) > (S32)(desired_tex_discard_level)) + S32 local_discard_level = getLocalDiscardLevel(*local_tex_iter, wearable_index); + if ((local_discard_level > (S32)(desired_tex_discard_level)) || + (local_discard_level < 0 )) { return FALSE; } @@ -2171,20 +2167,14 @@ const std::string LLVOAvatarSelf::debugDumpAllLocalTextureDataInfo() const return text; } + +#if 0 // Dump avatar metrics data. LLSD LLVOAvatarSelf::metricsData() { // runway - add region info LLSD result; result["rez_status"] = LLVOAvatar::rezStatusToString(getRezzedStatus()); - std::vector<S32> rez_counts; - LLVOAvatar::getNearbyRezzedStats(rez_counts); - result["nearby"] = LLSD::emptyMap(); - for (S32 i=0; i<rez_counts.size(); ++i) - { - std::string rez_status_name = LLVOAvatar::rezStatusToString(i); - result["nearby"][rez_status_name] = rez_counts[i]; - } result["timers"]["debug_existence"] = mDebugExistenceTimer.getElapsedTimeF32(); result["timers"]["ruth_debug"] = mRuthDebugTimer.getElapsedTimeF32(); result["timers"]["ruth"] = mRuthTimer.getElapsedTimeF32(); @@ -2194,6 +2184,7 @@ LLSD LLVOAvatarSelf::metricsData() return result; } +#endif class ViewerAppearanceChangeMetricsResponder: public LLCurl::Responder { @@ -2243,25 +2234,124 @@ private: volatile bool & mReportingStarted; }; -void LLVOAvatarSelf::sendAppearanceChangeMetrics() +bool LLVOAvatarSelf::updateAvatarRezMetrics(bool force_send) +{ + const F32 AV_METRICS_INTERVAL_QA = 30.0; + F32 send_period = 300.0; + if (gSavedSettings.getBOOL("QAModeMetrics")) + { + send_period = AV_METRICS_INTERVAL_QA; + } + + if (force_send || mTimeSinceLastRezMessage.getElapsedTimeF32() > send_period) + { + // Stats for completed phases have been getting logged as they + // complete. This will give us stats for any timers that + // haven't finished as of the metric's being sent. + LLVOAvatar::logPendingPhasesAllAvatars(); + sendViewerAppearanceChangeMetrics(); + } + + return false; +} + +void LLVOAvatarSelf::addMetricsTimerRecord(const LLSD& record) +{ + mPendingTimerRecords.push_back(record); +} + +bool operator<(const LLSD& a, const LLSD& b) +{ + std::ostringstream aout, bout; + aout << LLSDNotationStreamer(a); + bout << LLSDNotationStreamer(b); + std::string astring = aout.str(); + std::string bstring = bout.str(); + + return astring < bstring; + +} + +// Given a vector of LLSD records, return an LLSD array of bucketed stats for val_field. +LLSD summarize_by_buckets(std::vector<LLSD> in_records, + std::vector<std::string> by_fields, + std::string& val_field) +{ + LLSD result = LLSD::emptyArray(); + std::map<LLSD,LLViewerStats::StatsAccumulator> accum; + for (std::vector<LLSD>::iterator in_record_iter = in_records.begin(); + in_record_iter != in_records.end(); ++in_record_iter) + { + LLSD& record = *in_record_iter; + LLSD key; + for (std::vector<std::string>::iterator field_iter = by_fields.begin(); + field_iter != by_fields.end(); ++field_iter) + { + const std::string& field = *field_iter; + key[field] = record[field]; + } + LLViewerStats::StatsAccumulator& stats = accum[key]; + F32 value = record[val_field].asReal(); + stats.push(value); + } + for (std::map<LLSD,LLViewerStats::StatsAccumulator>::iterator accum_it = accum.begin(); + accum_it != accum.end(); ++accum_it) + { + LLSD out_record = accum_it->first; + out_record["stats"] = accum_it->second.getData(); + result.append(out_record); + } + return result; +} + +void LLVOAvatarSelf::sendViewerAppearanceChangeMetrics() { // gAgentAvatarp->stopAllPhases(); static volatile bool reporting_started(false); static volatile S32 report_sequence(0); - LLSD msg = metricsData(); + LLSD msg; // = metricsData(); msg["message"] = "ViewerAppearanceChangeMetrics"; msg["session_id"] = gAgentSessionID; msg["agent_id"] = gAgentID; msg["sequence"] = report_sequence; msg["initial"] = !reporting_started; msg["break"] = false; + msg["duration"] = mTimeSinceLastRezMessage.getElapsedTimeF32(); + + // Status of our own rezzing. + msg["rez_status"] = LLVOAvatar::rezStatusToString(getRezzedStatus()); + + // Status of all nearby avs including ourself. + msg["nearby"] = LLSD::emptyArray(); + std::vector<S32> rez_counts; + LLVOAvatar::getNearbyRezzedStats(rez_counts); + for (S32 rez_stat=0; rez_stat < rez_counts.size(); ++rez_stat) + { + std::string rez_status_name = LLVOAvatar::rezStatusToString(rez_stat); + msg["nearby"][rez_status_name] = rez_counts[rez_stat]; + } + + // std::vector<std::string> bucket_fields("timer_name","agent_id","is_self","grid_x","grid_y","is_using_server_bake"); + std::vector<std::string> by_fields; + by_fields.push_back("timer_name"); + by_fields.push_back("agent_id"); + by_fields.push_back("completed"); + by_fields.push_back("grid_x"); + by_fields.push_back("grid_y"); + by_fields.push_back("is_using_server_bakes"); + by_fields.push_back("is_self"); + by_fields.push_back("central_bake_version"); + LLSD summary = summarize_by_buckets(mPendingTimerRecords, by_fields, std::string("elapsed")); + msg["timers"] = summary; + + mPendingTimerRecords.clear(); // Update sequence number if (S32_MAX == ++report_sequence) report_sequence = 0; -// LL_DEBUGS("Avatar") << avString() << "message: " << ll_pretty_print_sd(msg) << LL_ENDL; + LL_DEBUGS("Avatar") << avString() << "message: " << ll_pretty_print_sd(msg) << LL_ENDL; std::string caps_url; if (getRegion()) { @@ -2276,6 +2366,7 @@ void LLVOAvatarSelf::sendAppearanceChangeMetrics() new ViewerAppearanceChangeMetricsResponder(report_sequence, report_sequence, reporting_started)); + mTimeSinceLastRezMessage.reset(); } } diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h index 74888e470d..04b0fb760c 100755 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -379,6 +379,13 @@ public: LLUUID mAvatarID; LLAvatarAppearanceDefines::ETextureIndex mIndex; }; + + LLTimer mTimeSinceLastRezMessage; + bool updateAvatarRezMetrics(bool force_send); + + std::vector<LLSD> mPendingTimerRecords; + void addMetricsTimerRecord(const LLSD& record); + void debugWearablesLoaded() { mDebugTimeWearablesLoaded = mDebugSelfLoadTimer.getElapsedTimeF32(); } void debugAvatarVisible() { mDebugTimeAvatarVisible = mDebugSelfLoadTimer.getElapsedTimeF32(); } void outputRezDiagnostics() const; @@ -394,8 +401,7 @@ public: void dumpAllTextures() const; const std::string debugDumpLocalTextureDataInfo(const LLViewerTexLayerSet* layerset) const; // Lists out state of this particular baked texture layer const std::string debugDumpAllLocalTextureDataInfo() const; // Lists out which baked textures are at highest LOD - LLSD metricsData(); - void sendAppearanceChangeMetrics(); // send data associated with completing a change. + void sendViewerAppearanceChangeMetrics(); // send data associated with completing a change. private: LLFrameTimer mDebugSelfLoadTimer; F32 mDebugTimeWearablesLoaded; @@ -416,7 +422,8 @@ BOOL isAgentAvatarValid(); void selfStartPhase(const std::string& phase_name); void selfStopPhase(const std::string& phase_name); -void selfStopAllPhases(); void selfClearPhases(); +void update_avatar_rez_metrics(bool force_send); + #endif // LL_VO_AVATARSELF_H diff --git a/indra/newview/tests/llviewerassetstats_test.cpp b/indra/newview/tests/llviewerassetstats_test.cpp index f8923b9868..b55b6c13d4 100755 --- a/indra/newview/tests/llviewerassetstats_test.cpp +++ b/indra/newview/tests/llviewerassetstats_test.cpp @@ -35,31 +35,6 @@ #include "lluuid.h" #include "llsdutil.h" #include "llregionhandle.h" -#include "../llvoavatar.h" - -void LLVOAvatar::getNearbyRezzedStats(std::vector<S32>& counts) -{ - counts.resize(3); - counts[0] = 0; - counts[1] = 0; - counts[2] = 1; -} - -// static -std::string LLVOAvatar::rezStatusToString(S32 rez_status) -{ - if (rez_status==0) return "cloud"; - if (rez_status==1) return "gray"; - if (rez_status==2) return "textured"; - return "unknown"; -} - -// static -LLViewerStats::StatsAccumulator& LLViewerStats::PhaseMap::getPhaseStats(const std::string& phase_name) -{ - static LLViewerStats::StatsAccumulator junk; - return junk; -} static const char * all_keys[] = { @@ -117,7 +92,6 @@ static const U64 region2_handle(0x0000030000004200ULL); static const std::string region1_handle_str("0000040000003f00"); static const std::string region2_handle_str("0000030000004200"); -#if 0 static bool is_empty_map(const LLSD & sd) { @@ -135,7 +109,6 @@ is_double_key_map(const LLSD & sd, const std::string & key1, const std::string & { return sd.isMap() && 2 == sd.size() && sd.has(key1) && sd.has(key2); } -#endif static bool is_triple_key_map(const LLSD & sd, const std::string & key1, const std::string & key2, const std::string& key3) @@ -147,7 +120,7 @@ is_triple_key_map(const LLSD & sd, const std::string & key1, const std::string & static bool is_no_stats_map(const LLSD & sd) { - return is_triple_key_map(sd, "duration", "regions", "avatar"); + return is_double_key_map(sd, "duration", "regions"); } static bool @@ -258,7 +231,7 @@ namespace tut // Once the region is set, we will get a response even with no data collection it->setRegion(region1_handle); sd_full = it->asLLSD(false); - ensure("Correct single-key LLSD map root", is_triple_key_map(sd_full, "duration", "regions", "avatar")); + ensure("Correct single-key LLSD map root", is_double_key_map(sd_full, "duration", "regions")); ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd_full["regions"], region1_handle)); LLSD sd = sd_full["regions"][0]; @@ -299,7 +272,7 @@ namespace tut it->setRegion(region1_handle); LLSD sd = it->asLLSD(false); - ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "regions", "duration", "avatar")); + ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration")); ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle)); sd = sd[0]; @@ -324,7 +297,7 @@ namespace tut LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, false, false); LLSD sd = gViewerAssetStatsMain->asLLSD(false); - ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "regions", "duration", "avatar")); + ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration")); ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle)); sd = sd["regions"][0]; @@ -364,7 +337,7 @@ namespace tut LLSD sd = gViewerAssetStatsThread1->asLLSD(false); ensure("Other collector is empty", is_no_stats_map(sd)); sd = gViewerAssetStatsMain->asLLSD(false); - ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "regions", "duration", "avatar")); + ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration")); ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle)); sd = sd["regions"][0]; @@ -414,7 +387,7 @@ namespace tut // std::cout << sd << std::endl; - ensure("Correct double-key LLSD map root", is_triple_key_map(sd, "duration", "regions", "avatar")); + ensure("Correct double-key LLSD map root", is_double_key_map(sd, "duration", "regions")); ensure("Correct double-slot LLSD array regions", is_double_slot_array(sd["regions"], region1_handle, region2_handle)); LLSD sd1 = get_region(sd, region1_handle); LLSD sd2 = get_region(sd, region2_handle); @@ -437,7 +410,7 @@ namespace tut // Reset leaves current region in place gViewerAssetStatsMain->reset(); sd = gViewerAssetStatsMain->asLLSD(false); - ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "regions", "duration", "avatar")); + ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration")); ensure("Correct single-slot LLSD array regions (p2)", is_single_slot_array(sd["regions"], region2_handle)); sd2 = sd["regions"][0]; @@ -486,7 +459,7 @@ namespace tut LLSD sd = gViewerAssetStatsMain->asLLSD(false); - ensure("Correct double-key LLSD map root", is_triple_key_map(sd, "duration", "regions", "avatar")); + ensure("Correct double-key LLSD map root", is_double_key_map(sd, "duration", "regions")); ensure("Correct double-slot LLSD array regions", is_double_slot_array(sd["regions"], region1_handle, region2_handle)); LLSD sd1 = get_region(sd, region1_handle); LLSD sd2 = get_region(sd, region2_handle); @@ -509,7 +482,7 @@ namespace tut // Reset leaves current region in place gViewerAssetStatsMain->reset(); sd = gViewerAssetStatsMain->asLLSD(false); - ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "duration", "regions", "avatar")); + ensure("Correct single-key LLSD map root", is_double_key_map(sd, "duration", "regions")); ensure("Correct single-slot LLSD array regions (p2)", is_single_slot_array(sd["regions"], region2_handle)); sd2 = get_region(sd, region2_handle); ensure("Region2 is present in results", sd2.isMap()); @@ -555,7 +528,7 @@ namespace tut LLSD sd = gViewerAssetStatsThread1->asLLSD(false); ensure("Other collector is empty", is_no_stats_map(sd)); sd = gViewerAssetStatsMain->asLLSD(false); - ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "regions", "duration", "avatar")); + ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration")); ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle)); sd = get_region(sd, region1_handle); ensure("Region1 is present in results", sd.isMap()); |