298 lines
8.5 KiB
C++
298 lines
8.5 KiB
C++
/**
|
|
* @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_VERSION
|
|
StatAttributes("Version", TRUE, FALSE),
|
|
// 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", FALSE, 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_2_SECONDS
|
|
StatAttributes("Seconds below 2 FPS", FALSE, TRUE),
|
|
// ST_MOUSELOOK_SECONDS
|
|
StatAttributes("Seconds in Mouselook", 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", FALSE, TRUE),
|
|
// ST_SIM_FPS_20_SECONDS
|
|
StatAttributes("Seconds with sim FPS below 20", FALSE, TRUE),
|
|
// ST_PHYS_FPS_20_SECONDS
|
|
StatAttributes("Seconds with physics FPS below 20", FALSE, TRUE),
|
|
// ST_LOSS_05_SECONDS
|
|
StatAttributes("Seconds with packet loss > 5%", FALSE, TRUE),
|
|
// ST_FPS_DROP_50_RATIO
|
|
StatAttributes("Ratio of frames 2x longer than previous", FALSE, FALSE),
|
|
// ST_ENABLE_VBO
|
|
StatAttributes("Vertex Buffers Enabled", TRUE, FALSE),
|
|
// ST_DELTA_BANDWIDTH
|
|
StatAttributes("Increase/Decrease in bandwidth based on packet loss", FALSE, FALSE),
|
|
// ST_MAX_BANDWIDTH
|
|
StatAttributes("Max bandwidth setting", FALSE, FALSE),
|
|
// ST_LIGHTING_DETAIL
|
|
StatAttributes("Lighting Detail", FALSE, FALSE),
|
|
// ST_VISIBLE_AVATARS
|
|
StatAttributes("Visible Avatars", FALSE, FALSE),
|
|
// ST_SHADER_OJECTS
|
|
StatAttributes("Object Shaders", FALSE, FALSE),
|
|
// ST_SHADER_ENVIRONMENT
|
|
StatAttributes("Environment Shaders", FALSE, FALSE),
|
|
// ST_VISIBLE_DRAW_DIST
|
|
StatAttributes("Draw Distance", FALSE, FALSE),
|
|
// ST_VISIBLE_CHAT_BUBBLES
|
|
StatAttributes("Chat Bubbles Enabled", FALSE, FALSE),
|
|
// ST_SHADER_AVATAR
|
|
StatAttributes("Avatar Shaders", FALSE, FALSE),
|
|
// ST_FRAME_SECS
|
|
StatAttributes("FRAME_SECS", FALSE, FALSE),
|
|
// ST_UPDATE_SECS
|
|
StatAttributes("UPDATE_SECS", FALSE, FALSE),
|
|
// ST_NETWORK_SECS
|
|
StatAttributes("NETWORK_SECS", FALSE, FALSE),
|
|
// ST_IMAGE_SECS
|
|
StatAttributes("IMAGE_SECS", FALSE, FALSE),
|
|
// ST_REBUILD_SECS
|
|
StatAttributes("REBUILD_SECS", FALSE, FALSE),
|
|
// ST_RENDER_SECS
|
|
StatAttributes("RENDER_SECS", FALSE, FALSE),
|
|
// ST_CROSSING_AVG
|
|
StatAttributes("CROSSING_AVG", FALSE, FALSE),
|
|
// ST_CROSSING_MAX
|
|
StatAttributes("CROSSING_MAX", FALSE, FALSE),
|
|
// ST_LIBXUL_WIDGET_USED
|
|
StatAttributes("LibXUL Widget used", FALSE, FALSE),
|
|
// ST_WINDOW_WIDTH
|
|
StatAttributes("Window width", FALSE, FALSE),
|
|
// ST_WINDOW_HEIGHT
|
|
StatAttributes("Window height", FALSE, FALSE),
|
|
// ST_TEX_BAKES
|
|
StatAttributes("Texture Bakes", FALSE, FALSE),
|
|
// ST_TEX_REBAKES
|
|
StatAttributes("Texture Rebakes", FALSE, 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.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";
|
|
}
|
|
}
|