00001
00032 #include "llviewerprecompiledheaders.h"
00033
00034 #include "llviewerstats.h"
00035 #include "llviewerthrottle.h"
00036
00037 #include "message.h"
00038 #include "lltimer.h"
00039
00040 LLViewerStats *gViewerStats = NULL;
00041
00042 extern U32 gFrameCount;
00043 extern LLTimer gRenderStartTime;
00044
00045 class StatAttributes
00046 {
00047 public:
00048 StatAttributes(const char *name,
00049 const BOOL enabled,
00050 const BOOL is_timer)
00051 : mName(name),
00052 mEnabled(enabled),
00053 mIsTimer(is_timer)
00054 {
00055 }
00056
00057 const char *mName;
00058 const BOOL mEnabled;
00059 const BOOL mIsTimer;
00060 };
00061
00062 const StatAttributes STAT_INFO[LLViewerStats::ST_COUNT] =
00063 {
00064
00065 StatAttributes("Version", TRUE, FALSE),
00066
00067 StatAttributes("Seconds in Edit Appearence", FALSE, TRUE),
00068
00069 StatAttributes("Seconds using Toolbox", FALSE, TRUE),
00070
00071 StatAttributes("Chat messages sent", FALSE, FALSE),
00072
00073 StatAttributes("IMs sent", FALSE, FALSE),
00074
00075 StatAttributes("Fullscreen mode", FALSE, FALSE),
00076
00077 StatAttributes("Object release count", FALSE, FALSE),
00078
00079 StatAttributes("Object create count", FALSE, FALSE),
00080
00081 StatAttributes("Object rez count", FALSE, FALSE),
00082
00083 StatAttributes("Seconds below 10 FPS", FALSE, TRUE),
00084
00085 StatAttributes("Seconds below 2 FPS", FALSE, TRUE),
00086
00087 StatAttributes("Seconds in Mouselook", FALSE, TRUE),
00088
00089 StatAttributes("Fly count", FALSE, FALSE),
00090
00091 StatAttributes("Teleport count", FALSE, FALSE),
00092
00093 StatAttributes("Objects deleted", FALSE, FALSE),
00094
00095 StatAttributes("Snapshots taken", FALSE, FALSE),
00096
00097 StatAttributes("Sounds uploaded", FALSE, FALSE),
00098
00099 StatAttributes("Textures uploaded", FALSE, FALSE),
00100
00101 StatAttributes("Changes to textures on objects", FALSE, FALSE),
00102
00103 StatAttributes("Number of times killed", FALSE, FALSE),
00104
00105 StatAttributes("Average delta between sucessive frame times", FALSE, FALSE),
00106
00107 StatAttributes("Average delta between frame time and mean", FALSE, FALSE),
00108
00109 StatAttributes("Inventory took too long to load", FALSE, FALSE),
00110
00111 StatAttributes("Wearables took too long to load", FALSE, FALSE),
00112
00113 StatAttributes("Time between LoginRequest and LoginReply", FALSE, FALSE),
00114
00115 StatAttributes("Number of login attempts that timed out", FALSE, FALSE),
00116
00117 StatAttributes("Known bad timer if != 0.0", FALSE, FALSE),
00118
00119 StatAttributes("Number of times LLAssetStorage::getAssetData() has failed", FALSE, FALSE),
00120
00121 StatAttributes("Number of times user has saved a script", FALSE, FALSE),
00122
00123 StatAttributes("Animations uploaded", FALSE, FALSE),
00124
00125 StatAttributes("Seconds below 8 FPS", FALSE, TRUE),
00126
00127 StatAttributes("Seconds with sim FPS below 20", FALSE, TRUE),
00128
00129 StatAttributes("Seconds with physics FPS below 20", FALSE, TRUE),
00130
00131 StatAttributes("Seconds with packet loss > 5%", FALSE, TRUE),
00132
00133 StatAttributes("Ratio of frames 2x longer than previous", FALSE, FALSE),
00134
00135 StatAttributes("Vertex Buffers Enabled", TRUE, FALSE),
00136
00137 StatAttributes("Increase/Decrease in bandwidth based on packet loss", FALSE, FALSE),
00138
00139 StatAttributes("Max bandwidth setting", FALSE, FALSE),
00140
00141 StatAttributes("Lighting Detail", FALSE, FALSE),
00142
00143 StatAttributes("Visible Avatars", FALSE, FALSE),
00144
00145 StatAttributes("Object Shaders", FALSE, FALSE),
00146
00147 StatAttributes("Environment Shaders", FALSE, FALSE),
00148
00149 StatAttributes("Draw Distance", FALSE, FALSE),
00150
00151 StatAttributes("Chat Bubbles Enabled", FALSE, FALSE),
00152
00153 StatAttributes("Avatar Shaders", FALSE, FALSE),
00154
00155 StatAttributes("FRAME_SECS", FALSE, FALSE),
00156
00157 StatAttributes("UPDATE_SECS", FALSE, FALSE),
00158
00159 StatAttributes("NETWORK_SECS", FALSE, FALSE),
00160
00161 StatAttributes("IMAGE_SECS", FALSE, FALSE),
00162
00163 StatAttributes("REBUILD_SECS", FALSE, FALSE),
00164
00165 StatAttributes("RENDER_SECS", FALSE, FALSE),
00166
00167 StatAttributes("CROSSING_AVG", FALSE, FALSE),
00168
00169 StatAttributes("CROSSING_MAX", FALSE, FALSE),
00170
00171 StatAttributes("LibXUL Widget used", FALSE, FALSE),
00172
00173 StatAttributes("Window width", FALSE, FALSE),
00174
00175 StatAttributes("Window height", FALSE, FALSE),
00176
00177 StatAttributes("Texture Bakes", FALSE, FALSE),
00178
00179 StatAttributes("Texture Rebakes", FALSE, FALSE),
00180
00181
00182 StatAttributes("Logitech LCD", FALSE, FALSE)
00183
00184 };
00185
00186 LLViewerStats::LLViewerStats()
00187 : mPacketsLostPercentStat(64),
00188 mLastTimeDiff(0.0)
00189 {
00190 for (S32 i = 0; i < ST_COUNT; i++)
00191 {
00192 mStats[i] = 0.0;
00193 }
00194
00195 if (LLTimer::knownBadTimer())
00196 {
00197 mStats[ST_HAS_BAD_TIMER] = 1.0;
00198 }
00199 }
00200
00201 LLViewerStats::~LLViewerStats()
00202 {
00203 }
00204
00205 void LLViewerStats::resetStats()
00206 {
00207 gViewerStats->mKBitStat.reset();
00208 gViewerStats->mLayersKBitStat.reset();
00209 gViewerStats->mObjectKBitStat.reset();
00210 gViewerStats->mTextureKBitStat.reset();
00211 gViewerStats->mVFSPendingOperations.reset();
00212 gViewerStats->mAssetKBitStat.reset();
00213 gViewerStats->mPacketsInStat.reset();
00214 gViewerStats->mPacketsLostStat.reset();
00215 gViewerStats->mPacketsOutStat.reset();
00216 gViewerStats->mFPSStat.reset();
00217 gViewerStats->mTexturePacketsStat.reset();
00218 }
00219
00220
00221 F64 LLViewerStats::getStat(EStatType type) const
00222 {
00223 return mStats[type];
00224 }
00225
00226 F64 LLViewerStats::setStat(EStatType type, F64 value)
00227 {
00228 mStats[type] = value;
00229 return mStats[type];
00230 }
00231
00232 F64 LLViewerStats::incStat(EStatType type, F64 value)
00233 {
00234 mStats[type] += value;
00235 return mStats[type];
00236 }
00237
00238 void LLViewerStats::updateFrameStats(const F64 time_diff)
00239 {
00240 if (mPacketsLostPercentStat.getCurrent() > 5.0)
00241 {
00242 incStat(LLViewerStats::ST_LOSS_05_SECONDS, time_diff);
00243 }
00244
00245 if (mSimFPS.getCurrent() < 20.f && mSimFPS.getCurrent() > 0.f)
00246 {
00247 incStat(LLViewerStats::ST_SIM_FPS_20_SECONDS, time_diff);
00248 }
00249
00250 if (mSimPhysicsFPS.getCurrent() < 20.f && mSimPhysicsFPS.getCurrent() > 0.f)
00251 {
00252 incStat(LLViewerStats::ST_PHYS_FPS_20_SECONDS, time_diff);
00253 }
00254
00255 if (time_diff >= 0.5)
00256 {
00257 incStat(LLViewerStats::ST_FPS_2_SECONDS, time_diff);
00258 }
00259 if (time_diff >= 0.125)
00260 {
00261 incStat(LLViewerStats::ST_FPS_8_SECONDS, time_diff);
00262 }
00263 if (time_diff >= 0.1)
00264 {
00265 incStat(LLViewerStats::ST_FPS_10_SECONDS, time_diff);
00266 }
00267
00268 if (gFrameCount && mLastTimeDiff > 0.0)
00269 {
00270
00271 setStat(LLViewerStats::ST_FPS_DROP_50_RATIO,
00272 (getStat(LLViewerStats::ST_FPS_DROP_50_RATIO) * (F64)(gFrameCount - 1) +
00273 (time_diff >= 2.0 * mLastTimeDiff ? 1.0 : 0.0)) / gFrameCount);
00274
00275
00276
00277 setStat(LLViewerStats::ST_FRAMETIME_JITTER,
00278 (getStat(LLViewerStats::ST_FRAMETIME_JITTER) * (gFrameCount - 1) +
00279 fabs(mLastTimeDiff - time_diff) / mLastTimeDiff) / gFrameCount);
00280
00281 F32 average_frametime = gRenderStartTime.getElapsedTimeF32() / (F32)gFrameCount;
00282 setStat(LLViewerStats::ST_FRAMETIME_SLEW,
00283 (getStat(LLViewerStats::ST_FRAMETIME_SLEW) * (gFrameCount - 1) +
00284 fabs(average_frametime - time_diff) / average_frametime) / gFrameCount);
00285
00286 F32 max_bandwidth = gViewerThrottle.getMaxBandwidth();
00287 F32 delta_bandwidth = gViewerThrottle.getCurrentBandwidth() - max_bandwidth;
00288 setStat(LLViewerStats::ST_DELTA_BANDWIDTH, delta_bandwidth / 1024.f);
00289
00290 setStat(LLViewerStats::ST_MAX_BANDWIDTH, max_bandwidth / 1024.f);
00291
00292 }
00293
00294 mLastTimeDiff = time_diff;
00295
00296 }
00297
00298 void LLViewerStats::addToMessage(LLSD &body) const
00299 {
00300 LLSD &misc = body["misc"];
00301
00302 for (S32 i = 0; i < ST_COUNT; i++)
00303 {
00304 if (STAT_INFO[i].mEnabled)
00305 {
00306
00307 misc[STAT_INFO[i].mName] = mStats[i];
00308 llinfos << "STAT: " << STAT_INFO[i].mName << ": " << mStats[i]
00309 << llendl;
00310 }
00311 }
00312 }
00313
00314
00315 const char *LLViewerStats::statTypeToText(EStatType type)
00316 {
00317 if (type >= 0 && type < ST_COUNT)
00318 {
00319 return STAT_INFO[type].mName;
00320 }
00321 else
00322 {
00323 return "Unknown statistic";
00324 }
00325 }