summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xindra/newview/llagent.cpp7
-rwxr-xr-xindra/newview/llagentwearables.cpp2
-rw-r--r--indra/newview/llagentwearablesfetch.cpp4
-rwxr-xr-xindra/newview/llappearancemgr.cpp2
-rwxr-xr-x[-rw-r--r--]indra/newview/llappviewer.cpp7
-rw-r--r--indra/newview/llappviewerwin32.cpp2
-rwxr-xr-xindra/newview/llviewerassetstats.cpp42
-rwxr-xr-xindra/newview/llviewerassetstats.h10
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerstats.cpp73
-rwxr-xr-xindra/newview/llviewerstats.h11
-rwxr-xr-xindra/newview/llvoavatar.cpp111
-rwxr-xr-xindra/newview/llvoavatar.h12
-rwxr-xr-xindra/newview/llvoavatarself.cpp137
-rwxr-xr-xindra/newview/llvoavatarself.h13
-rwxr-xr-xindra/newview/tests/llviewerassetstats_test.cpp47
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());