summaryrefslogtreecommitdiff
path: root/indra/newview/llviewerstats.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llviewerstats.cpp')
-rw-r--r--indra/newview/llviewerstats.cpp301
1 files changed, 301 insertions, 0 deletions
diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp
new file mode 100644
index 0000000000..bb490959c7
--- /dev/null
+++ b/indra/newview/llviewerstats.cpp
@@ -0,0 +1,301 @@
+/**
+ * @file llviewerstats.cpp
+ * @brief LLViewerStats class implementation
+ *
+ * Copyright (c) 2002-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llviewerstats.h"
+#include "llviewerthrottle.h"
+
+#include "message.h"
+#include "lltimer.h"
+
+LLViewerStats *gViewerStats = NULL;
+
+extern U32 gFrameCount;
+extern LLTimer gRenderStartTime;
+
+class StatAttributes
+{
+public:
+ StatAttributes(const char *name,
+ const BOOL enabled,
+ const BOOL is_timer)
+ : mName(name),
+ mEnabled(enabled),
+ mIsTimer(is_timer)
+ {
+ }
+
+ const char *mName;
+ const BOOL mEnabled;
+ const BOOL mIsTimer;
+};
+
+const StatAttributes STAT_INFO[LLViewerStats::ST_COUNT] =
+{
+ // ST_MOUSELOOK_SECONDS
+ StatAttributes("Seconds in Mouselook", FALSE, TRUE),
+ // ST_AVATAR_EDIT_SECONDS
+ StatAttributes("Seconds in Edit Appearence", FALSE, TRUE),
+ // ST_TOOLBOX_SECONDS
+ StatAttributes("Seconds using Toolbox", FALSE, TRUE),
+ // ST_CHAT_COUNT
+ StatAttributes("Chat messages sent", FALSE, FALSE),
+ // ST_IM_COUNT
+ StatAttributes("IMs sent", FALSE, FALSE),
+ // ST_FULLSCREEN_BOOL
+ StatAttributes("Fullscreen mode", TRUE, FALSE),
+ // ST_RELEASE_COUNT
+ StatAttributes("Object release count", FALSE, FALSE),
+ // ST_CREATE_COUNT
+ StatAttributes("Object create count", FALSE, FALSE),
+ // ST_REZ_COUNT
+ StatAttributes("Object rez count", FALSE, FALSE),
+ // ST_FPS_10_SECONDS
+ StatAttributes("Seconds below 10 FPS", FALSE, TRUE),
+ // ST_FPS_5_SECONDS
+ StatAttributes("Seconds below 5 FPS", FALSE, TRUE),
+ // ST_FPS_2_SECONDS
+ StatAttributes("Seconds below 2 FPS", FALSE, TRUE),
+ // ST_FLY_COUNT
+ StatAttributes("Fly count", FALSE, FALSE),
+ // ST_TELEPORT_COUNT
+ StatAttributes("Teleport count", FALSE, FALSE),
+ // ST_OBJECT_DELETE_COUNT
+ StatAttributes("Objects deleted", FALSE, FALSE),
+ // ST_SNAPSHOT_COUNT
+ StatAttributes("Snapshots taken", FALSE, FALSE),
+ // ST_UPLOAD_SOUND_COUNT
+ StatAttributes("Sounds uploaded", FALSE, FALSE),
+ // ST_UPLOAD_TEXTURE_COUNT
+ StatAttributes("Textures uploaded", FALSE, FALSE),
+ // ST_EDIT_TEXTURE_COUNT
+ StatAttributes("Changes to textures on objects", FALSE, FALSE),
+ // ST_KILLED_COUNT
+ StatAttributes("Number of times killed", FALSE, FALSE),
+ // ST_FRAMETIME_JITTER
+ StatAttributes("Average delta between sucessive frame times", FALSE, FALSE),
+ // ST_FRAMETIME_SLEW
+ StatAttributes("Average delta between frame time and mean", FALSE, FALSE),
+ // ST_INVENTORY_TOO_LONG
+ StatAttributes("Inventory took too long to load", FALSE, FALSE),
+ // ST_WEARABLES_TOO_LONG
+ StatAttributes("Wearables took too long to load", FALSE, FALSE),
+ // ST_LOGIN_SECONDS
+ StatAttributes("Time between LoginRequest and LoginReply", FALSE, FALSE),
+ // ST_LOGIN_TIMEOUT_COUNT
+ StatAttributes("Number of login attempts that timed out", FALSE, FALSE),
+ // ST_HAS_BAD_TIMER
+ StatAttributes("Known bad timer if != 0.0", FALSE, FALSE),
+ // ST_DOWNLOAD_FAILED
+ StatAttributes("Number of times LLAssetStorage::getAssetData() has failed", FALSE, FALSE),
+ // ST_LSL_SAVE_COUNT
+ StatAttributes("Number of times user has saved a script", FALSE, FALSE),
+ // ST_UPLOAD_ANIM_COUNT
+ StatAttributes("Animations uploaded", FALSE, FALSE),
+ // ST_FPS_8_SECONDS
+ StatAttributes("Seconds below 8 FPS", TRUE, TRUE),
+ // ST_SIM_FPS_20_SECONDS
+ StatAttributes("Seconds with sim FPS below 20", TRUE, TRUE),
+ // ST_PHYS_FPS_20_SECONDS
+ StatAttributes("Seconds with physics FPS below 20", TRUE, TRUE),
+ // ST_LOSS_05_SECONDS
+ StatAttributes("Seconds with packet loss > 5%", TRUE, TRUE),
+ // ST_FPS_DROP_50_RATIO
+ StatAttributes("Ratio of frames 2x longer than previous", TRUE, FALSE),
+ // ST_MEDIA_OBJECT_LIST_LENGTH
+ StatAttributes("Number of objects that want to display web pages", TRUE, FALSE),
+ // ST_DELTA_BANDWIDTH
+ StatAttributes("Increase/Decrease in bandwidth based on packet loss", TRUE, FALSE),
+ // ST_MAX_BANDWIDTH
+ StatAttributes("Max bandwidth setting", TRUE, FALSE),
+ // ST_LIGHTING_DETAIL
+ StatAttributes("Lighting Detail", TRUE, FALSE),
+ // ST_VISIBLE_AVATARS
+ StatAttributes("Visible Avatars", TRUE, FALSE),
+ // ST_SHADER_OJECTS
+ StatAttributes("Object Shaders", TRUE, FALSE),
+ // ST_SHADER_ENVIRONMENT
+ StatAttributes("Environment Shaders", TRUE, FALSE),
+ // ST_VISIBLE_DRAW_DIST
+ StatAttributes("Draw Distance", TRUE, FALSE),
+ // ST_VISIBLE_CHAT_BUBBLES
+ StatAttributes("Chat Bubbles Enabled", TRUE, FALSE),
+ // ST_SHADER_AVATAR
+ StatAttributes("Avatar Shaders", TRUE, FALSE),
+ // ST_FRAME_SECS
+ StatAttributes("FRAME_SECS", TRUE, FALSE),
+ // ST_UPDATE_SECS
+ StatAttributes("UPDATE_SECS", TRUE, FALSE),
+ // ST_NETWORK_SECS
+ StatAttributes("NETWORK_SECS", TRUE, FALSE),
+ // ST_IMAGE_SECS
+ StatAttributes("IMAGE_SECS", TRUE, FALSE),
+ // ST_REBUILD_SECS
+ StatAttributes("REBUILD_SECS", TRUE, FALSE),
+ // ST_RENDER_SECS
+ StatAttributes("RENDER_SECS", TRUE, FALSE),
+ // ST_CROSSING_AVG
+ StatAttributes("CROSSING_AVG", TRUE, FALSE),
+ // ST_CROSSING_MAX
+ StatAttributes("CROSSING_MAX", TRUE, FALSE),
+ // ST_LIBXUL_WIDGET_USED
+ StatAttributes("LibXUL Widget used", TRUE, FALSE),
+ // ST_WINDOW_WIDTH
+ StatAttributes("Window width", TRUE, FALSE),
+ // ST_WINDOW_HEIGHT
+ StatAttributes("Window height", TRUE, FALSE),
+ // ST_TEX_BAKES
+ StatAttributes("Texture Bakes", TRUE, FALSE),
+ // ST_TEX_REBAKES
+ StatAttributes("Texture Rebakes", TRUE, FALSE)
+};
+
+LLViewerStats::LLViewerStats()
+ : mPacketsLostPercentStat(64),
+ mLastTimeDiff(0.0)
+{
+ for (S32 i = 0; i < ST_COUNT; i++)
+ {
+ mStats[i] = 0.0;
+ }
+
+ if (LLTimer::knownBadTimer())
+ {
+ mStats[ST_HAS_BAD_TIMER] = 1.0;
+ }
+}
+
+LLViewerStats::~LLViewerStats()
+{
+}
+
+void LLViewerStats::resetStats()
+{
+ gViewerStats->mKBitStat.reset();
+ gViewerStats->mLayersKBitStat.reset();
+ gViewerStats->mObjectKBitStat.reset();
+ gViewerStats->mTextureKBitStat.reset();
+ gViewerStats->mVFSPendingOperations.reset();
+ gViewerStats->mAssetKBitStat.reset();
+ gViewerStats->mPacketsInStat.reset();
+ gViewerStats->mPacketsLostStat.reset();
+ gViewerStats->mPacketsOutStat.reset();
+ gViewerStats->mFPSStat.reset();
+ gViewerStats->mTexturePacketsStat.reset();
+}
+
+
+F64 LLViewerStats::getStat(EStatType type) const
+{
+ return mStats[type];
+}
+
+F64 LLViewerStats::setStat(EStatType type, F64 value)
+{
+ mStats[type] = value;
+ return mStats[type];
+}
+
+F64 LLViewerStats::incStat(EStatType type, F64 value)
+{
+ mStats[type] += value;
+ return mStats[type];
+}
+
+void LLViewerStats::updateFrameStats(const F64 time_diff)
+{
+ if (mPacketsLostPercentStat.getCurrent() > 5.0)
+ {
+ incStat(LLViewerStats::ST_LOSS_05_SECONDS, time_diff);
+ }
+
+ if (mSimFPS.getCurrent() < 20.f && mSimFPS.getCurrent() > 0.f)
+ {
+ incStat(LLViewerStats::ST_SIM_FPS_20_SECONDS, time_diff);
+ }
+
+ if (mSimPhysicsFPS.getCurrent() < 20.f && mSimPhysicsFPS.getCurrent() > 0.f)
+ {
+ incStat(LLViewerStats::ST_PHYS_FPS_20_SECONDS, time_diff);
+ }
+
+ if (time_diff >= 0.5)
+ {
+ incStat(LLViewerStats::ST_FPS_2_SECONDS, time_diff);
+ }
+ if (time_diff >= 0.2)
+ {
+ incStat(LLViewerStats::ST_FPS_5_SECONDS, time_diff);
+ }
+ if (time_diff >= 0.125)
+ {
+ incStat(LLViewerStats::ST_FPS_8_SECONDS, time_diff);
+ }
+ if (time_diff >= 0.1)
+ {
+ incStat(LLViewerStats::ST_FPS_10_SECONDS, time_diff);
+ }
+
+ if (gFrameCount && mLastTimeDiff > 0.0)
+ {
+ // new "stutter" meter
+ setStat(LLViewerStats::ST_FPS_DROP_50_RATIO,
+ (getStat(LLViewerStats::ST_FPS_DROP_50_RATIO) * (F64)(gFrameCount - 1) +
+ (time_diff >= 2.0 * mLastTimeDiff ? 1.0 : 0.0)) / gFrameCount);
+
+
+ // old stats that were never really used
+ setStat(LLViewerStats::ST_FRAMETIME_JITTER,
+ (getStat(LLViewerStats::ST_FRAMETIME_JITTER) * (gFrameCount - 1) +
+ fabs(mLastTimeDiff - time_diff) / mLastTimeDiff) / gFrameCount);
+
+ F32 average_frametime = gRenderStartTime.getElapsedTimeF32() / (F32)gFrameCount;
+ setStat(LLViewerStats::ST_FRAMETIME_SLEW,
+ (getStat(LLViewerStats::ST_FRAMETIME_SLEW) * (gFrameCount - 1) +
+ fabs(average_frametime - time_diff) / average_frametime) / gFrameCount);
+
+ F32 max_bandwidth = gViewerThrottle.getMaxBandwidth();
+ F32 delta_bandwidth = gViewerThrottle.getCurrentBandwidth() - max_bandwidth;
+ setStat(LLViewerStats::ST_DELTA_BANDWIDTH, delta_bandwidth / 1024.f);
+
+ setStat(LLViewerStats::ST_MAX_BANDWIDTH, max_bandwidth / 1024.f);
+
+ }
+
+ mLastTimeDiff = time_diff;
+
+}
+
+void LLViewerStats::addToMessage() const
+{
+ for (S32 i = 0; i < ST_COUNT; i++)
+ {
+ if (STAT_INFO[i].mEnabled)
+ {
+ // TODO: send timer value so dataserver can normalize
+ gMessageSystem->nextBlockFast(_PREHASH_MiscStats);
+ gMessageSystem->addU32Fast(_PREHASH_Type, (U32)i);
+ gMessageSystem->addF64Fast(_PREHASH_Value, mStats[i]);
+ llinfos << "STAT: " << STAT_INFO[i].mName << ": " << mStats[i] << llendl;
+ }
+ }
+}
+
+// static
+const char *LLViewerStats::statTypeToText(EStatType type)
+{
+ if (type >= 0 && type < ST_COUNT)
+ {
+ return STAT_INFO[type].mName;
+ }
+ else
+ {
+ return "Unknown statistic";
+ }
+}