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 #include "llappviewer.h"
00041
00042 #include "pipeline.h"
00043 #include "llviewerobjectlist.h"
00044 #include "llviewerimagelist.h"
00045 #include "lltexlayer.h"
00046 #include "llsurface.h"
00047 #include "llvlmanager.h"
00048 #include "llagent.h"
00049 #include "llviewercontrol.h"
00050 #include "llfloaterdirectory.h"
00051 #include "llfloatertools.h"
00052 #include "lldebugview.h"
00053 #include "llfasttimerview.h"
00054 #include "llviewerregion.h"
00055 #include "llfloaterhtml.h"
00056 #include "llviewerwindow.h"
00057 #include "llworld.h"
00058 #include "llfeaturemanager.h"
00059 #if LL_WINDOWS && LL_LCD_COMPILE
00060 #include "lllcd.h"
00061 #endif
00062
00063
00064 class StatAttributes
00065 {
00066 public:
00067 StatAttributes(const char *name,
00068 const BOOL enabled,
00069 const BOOL is_timer)
00070 : mName(name),
00071 mEnabled(enabled),
00072 mIsTimer(is_timer)
00073 {
00074 }
00075
00076 const char *mName;
00077 const BOOL mEnabled;
00078 const BOOL mIsTimer;
00079 };
00080
00081 const StatAttributes STAT_INFO[LLViewerStats::ST_COUNT] =
00082 {
00083
00084 StatAttributes("Version", TRUE, FALSE),
00085
00086 StatAttributes("Seconds in Edit Appearence", FALSE, TRUE),
00087
00088 StatAttributes("Seconds using Toolbox", FALSE, TRUE),
00089
00090 StatAttributes("Chat messages sent", FALSE, FALSE),
00091
00092 StatAttributes("IMs sent", FALSE, FALSE),
00093
00094 StatAttributes("Fullscreen mode", FALSE, FALSE),
00095
00096 StatAttributes("Object release count", FALSE, FALSE),
00097
00098 StatAttributes("Object create count", FALSE, FALSE),
00099
00100 StatAttributes("Object rez count", FALSE, FALSE),
00101
00102 StatAttributes("Seconds below 10 FPS", FALSE, TRUE),
00103
00104 StatAttributes("Seconds below 2 FPS", FALSE, TRUE),
00105
00106 StatAttributes("Seconds in Mouselook", FALSE, TRUE),
00107
00108 StatAttributes("Fly count", FALSE, FALSE),
00109
00110 StatAttributes("Teleport count", FALSE, FALSE),
00111
00112 StatAttributes("Objects deleted", FALSE, FALSE),
00113
00114 StatAttributes("Snapshots taken", FALSE, FALSE),
00115
00116 StatAttributes("Sounds uploaded", FALSE, FALSE),
00117
00118 StatAttributes("Textures uploaded", FALSE, FALSE),
00119
00120 StatAttributes("Changes to textures on objects", FALSE, FALSE),
00121
00122 StatAttributes("Number of times killed", FALSE, FALSE),
00123
00124 StatAttributes("Average delta between sucessive frame times", FALSE, FALSE),
00125
00126 StatAttributes("Average delta between frame time and mean", FALSE, FALSE),
00127
00128 StatAttributes("Inventory took too long to load", FALSE, FALSE),
00129
00130 StatAttributes("Wearables took too long to load", FALSE, FALSE),
00131
00132 StatAttributes("Time between LoginRequest and LoginReply", FALSE, FALSE),
00133
00134 StatAttributes("Number of login attempts that timed out", FALSE, FALSE),
00135
00136 StatAttributes("Known bad timer if != 0.0", FALSE, FALSE),
00137
00138 StatAttributes("Number of times LLAssetStorage::getAssetData() has failed", FALSE, FALSE),
00139
00140 StatAttributes("Number of times user has saved a script", FALSE, FALSE),
00141
00142 StatAttributes("Animations uploaded", FALSE, FALSE),
00143
00144 StatAttributes("Seconds below 8 FPS", FALSE, TRUE),
00145
00146 StatAttributes("Seconds with sim FPS below 20", FALSE, TRUE),
00147
00148 StatAttributes("Seconds with physics FPS below 20", FALSE, TRUE),
00149
00150 StatAttributes("Seconds with packet loss > 5%", FALSE, TRUE),
00151
00152 StatAttributes("Ratio of frames 2x longer than previous", FALSE, FALSE),
00153
00154 StatAttributes("Vertex Buffers Enabled", TRUE, FALSE),
00155
00156 StatAttributes("Increase/Decrease in bandwidth based on packet loss", FALSE, FALSE),
00157
00158 StatAttributes("Max bandwidth setting", FALSE, FALSE),
00159
00160 StatAttributes("Lighting Detail", FALSE, FALSE),
00161
00162 StatAttributes("Visible Avatars", FALSE, FALSE),
00163
00164 StatAttributes("Object Shaders", FALSE, FALSE),
00165
00166 StatAttributes("Environment Shaders", FALSE, FALSE),
00167
00168 StatAttributes("Draw Distance", FALSE, FALSE),
00169
00170 StatAttributes("Chat Bubbles Enabled", FALSE, FALSE),
00171
00172 StatAttributes("Avatar Shaders", FALSE, FALSE),
00173
00174 StatAttributes("FRAME_SECS", FALSE, FALSE),
00175
00176 StatAttributes("UPDATE_SECS", FALSE, FALSE),
00177
00178 StatAttributes("NETWORK_SECS", FALSE, FALSE),
00179
00180 StatAttributes("IMAGE_SECS", FALSE, FALSE),
00181
00182 StatAttributes("REBUILD_SECS", FALSE, FALSE),
00183
00184 StatAttributes("RENDER_SECS", FALSE, FALSE),
00185
00186 StatAttributes("CROSSING_AVG", FALSE, FALSE),
00187
00188 StatAttributes("CROSSING_MAX", FALSE, FALSE),
00189
00190 StatAttributes("LibXUL Widget used", FALSE, FALSE),
00191
00192 StatAttributes("Window width", FALSE, FALSE),
00193
00194 StatAttributes("Window height", FALSE, FALSE),
00195
00196 StatAttributes("Texture Bakes", FALSE, FALSE),
00197
00198 StatAttributes("Texture Rebakes", FALSE, FALSE),
00199
00200
00201 StatAttributes("Logitech LCD", FALSE, FALSE)
00202
00203 };
00204
00205 LLViewerStats::LLViewerStats()
00206 : mPacketsLostPercentStat(64),
00207 mLastTimeDiff(0.0)
00208 {
00209 for (S32 i = 0; i < ST_COUNT; i++)
00210 {
00211 mStats[i] = 0.0;
00212 }
00213
00214 if (LLTimer::knownBadTimer())
00215 {
00216 mStats[ST_HAS_BAD_TIMER] = 1.0;
00217 }
00218 }
00219
00220 LLViewerStats::~LLViewerStats()
00221 {
00222 }
00223
00224 void LLViewerStats::resetStats()
00225 {
00226 LLViewerStats::getInstance()->mKBitStat.reset();
00227 LLViewerStats::getInstance()->mLayersKBitStat.reset();
00228 LLViewerStats::getInstance()->mObjectKBitStat.reset();
00229 LLViewerStats::getInstance()->mTextureKBitStat.reset();
00230 LLViewerStats::getInstance()->mVFSPendingOperations.reset();
00231 LLViewerStats::getInstance()->mAssetKBitStat.reset();
00232 LLViewerStats::getInstance()->mPacketsInStat.reset();
00233 LLViewerStats::getInstance()->mPacketsLostStat.reset();
00234 LLViewerStats::getInstance()->mPacketsOutStat.reset();
00235 LLViewerStats::getInstance()->mFPSStat.reset();
00236 LLViewerStats::getInstance()->mTexturePacketsStat.reset();
00237 }
00238
00239
00240 F64 LLViewerStats::getStat(EStatType type) const
00241 {
00242 return mStats[type];
00243 }
00244
00245 F64 LLViewerStats::setStat(EStatType type, F64 value)
00246 {
00247 mStats[type] = value;
00248 return mStats[type];
00249 }
00250
00251 F64 LLViewerStats::incStat(EStatType type, F64 value)
00252 {
00253 mStats[type] += value;
00254 return mStats[type];
00255 }
00256
00257 void LLViewerStats::updateFrameStats(const F64 time_diff)
00258 {
00259 if (mPacketsLostPercentStat.getCurrent() > 5.0)
00260 {
00261 incStat(LLViewerStats::ST_LOSS_05_SECONDS, time_diff);
00262 }
00263
00264 if (mSimFPS.getCurrent() < 20.f && mSimFPS.getCurrent() > 0.f)
00265 {
00266 incStat(LLViewerStats::ST_SIM_FPS_20_SECONDS, time_diff);
00267 }
00268
00269 if (mSimPhysicsFPS.getCurrent() < 20.f && mSimPhysicsFPS.getCurrent() > 0.f)
00270 {
00271 incStat(LLViewerStats::ST_PHYS_FPS_20_SECONDS, time_diff);
00272 }
00273
00274 if (time_diff >= 0.5)
00275 {
00276 incStat(LLViewerStats::ST_FPS_2_SECONDS, time_diff);
00277 }
00278 if (time_diff >= 0.125)
00279 {
00280 incStat(LLViewerStats::ST_FPS_8_SECONDS, time_diff);
00281 }
00282 if (time_diff >= 0.1)
00283 {
00284 incStat(LLViewerStats::ST_FPS_10_SECONDS, time_diff);
00285 }
00286
00287 if (gFrameCount && mLastTimeDiff > 0.0)
00288 {
00289
00290 setStat(LLViewerStats::ST_FPS_DROP_50_RATIO,
00291 (getStat(LLViewerStats::ST_FPS_DROP_50_RATIO) * (F64)(gFrameCount - 1) +
00292 (time_diff >= 2.0 * mLastTimeDiff ? 1.0 : 0.0)) / gFrameCount);
00293
00294
00295
00296 setStat(LLViewerStats::ST_FRAMETIME_JITTER,
00297 (getStat(LLViewerStats::ST_FRAMETIME_JITTER) * (gFrameCount - 1) +
00298 fabs(mLastTimeDiff - time_diff) / mLastTimeDiff) / gFrameCount);
00299
00300 F32 average_frametime = gRenderStartTime.getElapsedTimeF32() / (F32)gFrameCount;
00301 setStat(LLViewerStats::ST_FRAMETIME_SLEW,
00302 (getStat(LLViewerStats::ST_FRAMETIME_SLEW) * (gFrameCount - 1) +
00303 fabs(average_frametime - time_diff) / average_frametime) / gFrameCount);
00304
00305 F32 max_bandwidth = gViewerThrottle.getMaxBandwidth();
00306 F32 delta_bandwidth = gViewerThrottle.getCurrentBandwidth() - max_bandwidth;
00307 setStat(LLViewerStats::ST_DELTA_BANDWIDTH, delta_bandwidth / 1024.f);
00308
00309 setStat(LLViewerStats::ST_MAX_BANDWIDTH, max_bandwidth / 1024.f);
00310
00311 }
00312
00313 mLastTimeDiff = time_diff;
00314
00315 }
00316
00317 void LLViewerStats::addToMessage(LLSD &body) const
00318 {
00319 LLSD &misc = body["misc"];
00320
00321 for (S32 i = 0; i < ST_COUNT; i++)
00322 {
00323 if (STAT_INFO[i].mEnabled)
00324 {
00325
00326 misc[STAT_INFO[i].mName] = mStats[i];
00327 llinfos << "STAT: " << STAT_INFO[i].mName << ": " << mStats[i]
00328 << llendl;
00329 }
00330 }
00331 }
00332
00333
00334 const char *LLViewerStats::statTypeToText(EStatType type)
00335 {
00336 if (type >= 0 && type < ST_COUNT)
00337 {
00338 return STAT_INFO[type].mName;
00339 }
00340 else
00341 {
00342 return "Unknown statistic";
00343 }
00344 }
00345
00346
00347
00348 void reset_statistics()
00349 {
00350 gPipeline.resetFrameStats();
00351 if (LLSurface::sTextureUpdateTime)
00352 {
00353 LLSurface::sTexelsUpdatedPerSecStat.addValue(0.001f*(LLSurface::sTexelsUpdated / LLSurface::sTextureUpdateTime));
00354 LLSurface::sTexelsUpdated = 0;
00355 LLSurface::sTextureUpdateTime = 0.f;
00356 }
00357 }
00358
00359
00360 void output_statistics(void*)
00361 {
00362 llinfos << "Number of orphans: " << gObjectList.getOrphanCount() << llendl;
00363 llinfos << "Number of dead objects: " << gObjectList.mNumDeadObjects << llendl;
00364 llinfos << "Num images: " << gImageList.getNumImages() << llendl;
00365 llinfos << "Texture usage: " << LLImageGL::sGlobalTextureMemory << llendl;
00366 llinfos << "Texture working set: " << LLImageGL::sBoundTextureMemory << llendl;
00367 llinfos << "Raw usage: " << LLImageRaw::sGlobalRawMemory << llendl;
00368 llinfos << "Formatted usage: " << LLImageFormatted::sGlobalFormattedMemory << llendl;
00369 llinfos << "Zombie Viewer Objects: " << LLViewerObject::getNumZombieObjects() << llendl;
00370 llinfos << "Number of lights: " << gPipeline.getLightCount() << llendl;
00371
00372 llinfos << "Memory Usage:" << llendl;
00373 llinfos << "--------------------------------" << llendl;
00374 llinfos << "Pipeline:" << llendl;
00375 llinfos << llendl;
00376
00377 #if LL_SMARTHEAP
00378 llinfos << "--------------------------------" << llendl;
00379 {
00380 llinfos << "sizeof(LLVOVolume) = " << sizeof(LLVOVolume) << llendl;
00381
00382 U32 total_pool_size = 0;
00383 U32 total_used_size = 0;
00384 MEM_POOL_INFO pool_info;
00385 MEM_POOL_STATUS pool_status;
00386 U32 pool_num = 0;
00387 for(pool_status = MemPoolFirst( &pool_info, 1 );
00388 pool_status != MEM_POOL_END;
00389 pool_status = MemPoolNext( &pool_info, 1 ) )
00390 {
00391 llinfos << "Pool #" << pool_num << llendl;
00392 if( MEM_POOL_OK != pool_status )
00393 {
00394 llwarns << "Pool not ok" << llendl;
00395 continue;
00396 }
00397
00398 llinfos << "Pool blockSizeFS " << pool_info.blockSizeFS
00399 << " pageSize " << pool_info.pageSize
00400 << llendl;
00401
00402 U32 pool_count = MemPoolCount(pool_info.pool);
00403 llinfos << "Blocks " << pool_count << llendl;
00404
00405 U32 pool_size = MemPoolSize( pool_info.pool );
00406 if( pool_size == MEM_ERROR_RET )
00407 {
00408 llinfos << "MemPoolSize() failed (" << pool_num << ")" << llendl;
00409 }
00410 else
00411 {
00412 llinfos << "MemPool Size " << pool_size / 1024 << "K" << llendl;
00413 }
00414
00415 total_pool_size += pool_size;
00416
00417 if( !MemPoolLock( pool_info.pool ) )
00418 {
00419 llinfos << "MemPoolLock failed (" << pool_num << ") " << llendl;
00420 continue;
00421 }
00422
00423 U32 used_size = 0;
00424 MEM_POOL_ENTRY entry;
00425 entry.entry = NULL;
00426 while( MemPoolWalk( pool_info.pool, &entry ) == MEM_POOL_OK )
00427 {
00428 if( entry.isInUse )
00429 {
00430 used_size += entry.size;
00431 }
00432 }
00433
00434 MemPoolUnlock( pool_info.pool );
00435
00436 llinfos << "MemPool Used " << used_size/1024 << "K" << llendl;
00437 total_used_size += used_size;
00438 pool_num++;
00439 }
00440
00441 llinfos << "Total Pool Size " << total_pool_size/1024 << "K" << llendl;
00442 llinfos << "Total Used Size " << total_used_size/1024 << "K" << llendl;
00443
00444 }
00445 #endif
00446
00447 llinfos << "--------------------------------" << llendl;
00448 llinfos << "Avatar Memory (partly overlaps with above stats):" << llendl;
00449 gTexStaticImageList.dumpByteCount();
00450 LLVOAvatar::dumpScratchTextureByteCount();
00451 LLTexLayerSetBuffer::dumpTotalByteCount();
00452 LLVOAvatar::dumpTotalLocalTextureByteCount();
00453 LLTexLayerParamAlpha::dumpCacheByteCount();
00454 LLVOAvatar::dumpBakedStatus();
00455
00456 llinfos << llendl;
00457
00458 llinfos << "Object counts:" << llendl;
00459 S32 i;
00460 S32 obj_counts[256];
00461
00462 for (i = 0; i < 256; i++)
00463 {
00464 obj_counts[i] = 0;
00465 }
00466 for (i = 0; i < gObjectList.getNumObjects(); i++)
00467 {
00468 LLViewerObject *objectp = gObjectList.getObject(i);
00469 if (objectp)
00470 {
00471 obj_counts[objectp->getPCode()]++;
00472 }
00473 }
00474 for (i = 0; i < 256; i++)
00475 {
00476 if (obj_counts[i])
00477 {
00478 llinfos << LLPrimitive::pCodeToString(i) << ":" << obj_counts[i] << llendl;
00479 }
00480 }
00481 }
00482
00483
00484 U32 gTotalLandIn = 0, gTotalLandOut = 0;
00485 U32 gTotalWaterIn = 0, gTotalWaterOut = 0;
00486
00487 F32 gAveLandCompression = 0.f, gAveWaterCompression = 0.f;
00488 F32 gBestLandCompression = 1.f, gBestWaterCompression = 1.f;
00489 F32 gWorstLandCompression = 0.f, gWorstWaterCompression = 0.f;
00490
00491
00492
00493 U32 gTotalWorldBytes = 0, gTotalObjectBytes = 0, gTotalTextureBytes = 0, gSimPingCount = 0;
00494 U32 gObjectBits = 0;
00495 F32 gAvgSimPing = 0.f;
00496
00497
00498 extern U32 gVisCompared;
00499 extern U32 gVisTested;
00500
00501 std::map<S32,LLFrameTimer> gDebugTimers;
00502
00503 void update_statistics(U32 frame_count)
00504 {
00505 gTotalWorldBytes += gVLManager.getTotalBytes();
00506 gTotalObjectBytes += gObjectBits / 8;
00507 gTotalTextureBytes += LLViewerImageList::sTextureBits / 8;
00508
00509
00510 if (gFrameIntervalSeconds > 0.f)
00511 {
00512 if (gAgent.getCameraMode() == CAMERA_MODE_MOUSELOOK)
00513 {
00514 LLViewerStats::getInstance()->incStat(LLViewerStats::ST_MOUSELOOK_SECONDS, gFrameIntervalSeconds);
00515 }
00516 else if (gAgent.getCameraMode() == CAMERA_MODE_CUSTOMIZE_AVATAR)
00517 {
00518 LLViewerStats::getInstance()->incStat(LLViewerStats::ST_AVATAR_EDIT_SECONDS, gFrameIntervalSeconds);
00519 }
00520 else if (gFloaterTools && gFloaterTools->getVisible())
00521 {
00522 LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TOOLBOX_SECONDS, gFrameIntervalSeconds);
00523 }
00524 }
00525 LLViewerStats::getInstance()->setStat(LLViewerStats::ST_ENABLE_VBO, (F64)gSavedSettings.getBOOL("RenderVBOEnable"));
00526 LLViewerStats::getInstance()->setStat(LLViewerStats::ST_LIGHTING_DETAIL, (F64)gSavedSettings.getS32("RenderLightingDetail"));
00527 LLViewerStats::getInstance()->setStat(LLViewerStats::ST_DRAW_DIST, (F64)gSavedSettings.getF32("RenderFarClip"));
00528 LLViewerStats::getInstance()->setStat(LLViewerStats::ST_CHAT_BUBBLES, (F64)gSavedSettings.getBOOL("UseChatBubbles"));
00529 #if 0 // 1.9.2
00530 LLViewerStats::getInstance()->setStat(LLViewerStats::ST_SHADER_OBJECTS, (F64)gSavedSettings.getS32("VertexShaderLevelObject"));
00531 LLViewerStats::getInstance()->setStat(LLViewerStats::ST_SHADER_AVATAR, (F64)gSavedSettings.getBOOL("VertexShaderLevelAvatar"));
00532 LLViewerStats::getInstance()->setStat(LLViewerStats::ST_SHADER_ENVIRONMENT, (F64)gSavedSettings.getBOOL("VertexShaderLevelEnvironment"));
00533 #endif
00534 LLViewerStats::getInstance()->setStat(LLViewerStats::ST_FRAME_SECS, gDebugView->mFastTimerView->getTime(LLFastTimer::FTM_FRAME));
00535 F64 idle_secs = gDebugView->mFastTimerView->getTime(LLFastTimer::FTM_IDLE);
00536 F64 network_secs = gDebugView->mFastTimerView->getTime(LLFastTimer::FTM_NETWORK);
00537 LLViewerStats::getInstance()->setStat(LLViewerStats::ST_UPDATE_SECS, idle_secs - network_secs);
00538 LLViewerStats::getInstance()->setStat(LLViewerStats::ST_NETWORK_SECS, network_secs);
00539 LLViewerStats::getInstance()->setStat(LLViewerStats::ST_IMAGE_SECS, gDebugView->mFastTimerView->getTime(LLFastTimer::FTM_IMAGE_UPDATE));
00540 LLViewerStats::getInstance()->setStat(LLViewerStats::ST_REBUILD_SECS, gDebugView->mFastTimerView->getTime(LLFastTimer::FTM_STATESORT ));
00541 LLViewerStats::getInstance()->setStat(LLViewerStats::ST_RENDER_SECS, gDebugView->mFastTimerView->getTime(LLFastTimer::FTM_RENDER_GEOMETRY));
00542
00543 LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(gAgent.getRegion()->getHost());
00544 if (cdp)
00545 {
00546 LLViewerStats::getInstance()->mSimPingStat.addValue(cdp->getPingDelay());
00547 gAvgSimPing = ((gAvgSimPing * (F32)gSimPingCount) + (F32)(cdp->getPingDelay())) / ((F32)gSimPingCount + 1);
00548 gSimPingCount++;
00549 }
00550 else
00551 {
00552 LLViewerStats::getInstance()->mSimPingStat.addValue(10000);
00553 }
00554
00555 LLViewerStats::getInstance()->mFPSStat.addValue(1);
00556 F32 layer_bits = (F32)(gVLManager.getLandBits() + gVLManager.getWindBits() + gVLManager.getCloudBits());
00557 LLViewerStats::getInstance()->mLayersKBitStat.addValue(layer_bits/1024.f);
00558 LLViewerStats::getInstance()->mObjectKBitStat.addValue(gObjectBits/1024.f);
00559 LLViewerStats::getInstance()->mTextureKBitStat.addValue(LLViewerImageList::sTextureBits/1024.f);
00560 LLViewerStats::getInstance()->mVFSPendingOperations.addValue(LLVFile::getVFSThread()->getPending());
00561 LLViewerStats::getInstance()->mAssetKBitStat.addValue(gTransferManager.getTransferBitsIn(LLTCT_ASSET)/1024.f);
00562 gTransferManager.resetTransferBitsIn(LLTCT_ASSET);
00563
00564 static S32 tex_bits_idle_count = 0;
00565 if (LLViewerImageList::sTextureBits == 0)
00566 {
00567 if (++tex_bits_idle_count >= 30)
00568 gDebugTimers[0].pause();
00569 }
00570 else
00571 {
00572 tex_bits_idle_count = 0;
00573 gDebugTimers[0].unpause();
00574 }
00575
00576 LLViewerStats::getInstance()->mTexturePacketsStat.addValue(LLViewerImageList::sTexturePackets);
00577
00578 {
00579 static F32 visible_avatar_frames = 0.f;
00580 static F32 avg_visible_avatars = 0;
00581 F32 visible_avatars = (F32)LLVOAvatar::sNumVisibleAvatars;
00582 if (visible_avatars > 0.f)
00583 {
00584 visible_avatar_frames = 1.f;
00585 avg_visible_avatars = (avg_visible_avatars * (F32)(visible_avatar_frames - 1.f) + visible_avatars) / visible_avatar_frames;
00586 }
00587 LLViewerStats::getInstance()->setStat(LLViewerStats::ST_VISIBLE_AVATARS, (F64)avg_visible_avatars);
00588 }
00589 LLWorld::getInstance()->updateNetStats();
00590 LLWorld::getInstance()->requestCacheMisses();
00591
00592
00593 gVLManager.resetBitCounts();
00594 gObjectBits = 0;
00595
00596
00597 LLViewerImageList::sTextureBits = 0;
00598 LLViewerImageList::sTexturePackets = 0;
00599
00600 #if LL_WINDOWS && LL_LCD_COMPILE
00601 bool LCDenabled = gLcdScreen->Enabled();
00602 LLViewerStats::getInstance()->setStat(LLViewerStats::ST_LOGITECH_LCD, LCDenabled);
00603 #else
00604 LLViewerStats::getInstance()->setStat(LLViewerStats::ST_LOGITECH_LCD, false);
00605 #endif
00606 }
00607
00608 class ViewerStatsResponder : public LLHTTPClient::Responder
00609 {
00610 public:
00611 ViewerStatsResponder() { }
00612
00613 void error(U32 statusNum, const std::string& reason)
00614 {
00615 llinfos << "ViewerStatsResponder::error " << statusNum << " "
00616 << reason << llendl;
00617 }
00618
00619 void result(const LLSD& content)
00620 {
00621 llinfos << "ViewerStatsResponder::result" << llendl;
00622 }
00623 };
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634 void send_stats()
00635 {
00636
00637
00638
00639
00640
00641
00642 if (!gAgent.getRegion() || gNoRender)
00643 {
00644 return;
00645 }
00646
00647 LLSD body;
00648 std::string url = gAgent.getRegion()->getCapability("ViewerStats");
00649
00650 if (url.empty()) {
00651 llwarns << "Could not get ViewerStats capability" << llendl;
00652 return;
00653 }
00654
00655 body["session_id"] = gAgentSessionID;
00656
00657 LLSD &agent = body["agent"];
00658
00659 time_t ltime;
00660 time(<ime);
00661 F32 run_time = F32(LLFrameTimer::getElapsedSeconds());
00662
00663 agent["start_time"] = ltime - run_time;
00664
00665
00666
00667
00668
00669
00670 if (run_time < (SEND_STATS_PERIOD / 2))
00671 {
00672 agent["run_time"] = 0.0f;
00673 }
00674 else
00675 {
00676 agent["run_time"] = run_time;
00677 }
00678
00679
00680 agent["fps"] = (F32)gForegroundFrameCount / gForegroundTime.getElapsedTimeF32();
00681 agent["version"] = gCurrentVersion;
00682 LLString language(gSavedSettings.getString("Language"));
00683 if(language == "default") language = gSavedSettings.getString("SystemLanguage");
00684 agent["language"] = language;
00685
00686 agent["sim_fps"] = ((F32) gFrameCount - gSimFrames) /
00687 (F32) (gRenderStartTime.getElapsedTimeF32() - gSimLastTime);
00688
00689 gSimLastTime = gRenderStartTime.getElapsedTimeF32();
00690 gSimFrames = (F32) gFrameCount;
00691
00692 agent["agents_in_view"] = LLVOAvatar::sNumVisibleAvatars;
00693 agent["ping"] = gAvgSimPing;
00694 agent["meters_traveled"] = gAgent.getDistanceTraveled();
00695 agent["regions_visited"] = gAgent.getRegionsVisited();
00696 agent["mem_use"] = getCurrentRSS() / 1024.0;
00697
00698 LLSD &system = body["system"];
00699
00700 system["ram"] = (S32) gSysMemory.getPhysicalMemoryKB();
00701 system["os"] = LLAppViewer::instance()->getOSInfo().getOSStringSimple();
00702 system["cpu"] = gSysCPU.getCPUString();
00703
00704 std::string gpu_desc = llformat(
00705 "%-6s Class %d ",
00706 gGLManager.mGLVendorShort.substr(0,6).c_str(),
00707 (S32)LLFeatureManager::getInstance()->getGPUClass())
00708 + LLFeatureManager::getInstance()->getGPUString();
00709
00710 system["gpu"] = gpu_desc;
00711 system["gpu_class"] = (S32)LLFeatureManager::getInstance()->getGPUClass();
00712 system["gpu_vendor"] = gGLManager.mGLVendorShort;
00713 system["gpu_version"] = gGLManager.mDriverVersionVendorString;
00714
00715 LLSD &download = body["downloads"];
00716
00717 download["world_kbytes"] = gTotalWorldBytes / 1024.0;
00718 download["object_kbytes"] = gTotalObjectBytes / 1024.0;
00719 download["texture_kbytes"] = gTotalTextureBytes / 1024.0;
00720
00721 LLSD &in = body["stats"]["net"]["in"];
00722
00723 in["kbytes"] = gMessageSystem->mTotalBytesIn / 1024.0;
00724 in["packets"] = (S32) gMessageSystem->mPacketsIn;
00725 in["compressed_packets"] = (S32) gMessageSystem->mCompressedPacketsIn;
00726 in["savings"] = (gMessageSystem->mUncompressedBytesIn -
00727 gMessageSystem->mCompressedBytesIn) / 1024.0;
00728
00729 LLSD &out = body["stats"]["net"]["out"];
00730
00731 out["kbytes"] = gMessageSystem->mTotalBytesOut / 1024.0;
00732 out["packets"] = (S32) gMessageSystem->mPacketsOut;
00733 out["compressed_packets"] = (S32) gMessageSystem->mCompressedPacketsOut;
00734 out["savings"] = (gMessageSystem->mUncompressedBytesOut -
00735 gMessageSystem->mCompressedBytesOut) / 1024.0;
00736
00737 LLSD &fail = body["stats"]["failures"];
00738
00739 fail["send_packet"] = (S32) gMessageSystem->mSendPacketFailureCount;
00740 fail["dropped"] = (S32) gMessageSystem->mDroppedPackets;
00741 fail["resent"] = (S32) gMessageSystem->mResentPackets;
00742 fail["failed_resends"] = (S32) gMessageSystem->mFailedResendPackets;
00743 fail["off_circuit"] = (S32) gMessageSystem->mOffCircuitPackets;
00744 fail["invalid"] = (S32) gMessageSystem->mInvalidOnCircuitPackets;
00745
00746
00747
00748
00749
00750 LLSD &misc = body["stats"]["misc"];
00751
00752
00753
00754
00755 S32 window_width = gViewerWindow->getWindowDisplayWidth();
00756 S32 window_height = gViewerWindow->getWindowDisplayHeight();
00757 misc["string_1"] = llformat("%.dx%d", window_width, window_height);
00758
00759 misc["int_1"] = LLFloaterDirectory::sOldSearchCount;
00760 misc["int_2"] = LLFloaterDirectory::sNewSearchCount;
00761
00762 LLViewerStats::getInstance()->addToMessage(body);
00763
00764 LLHTTPClient::post(url, body, new ViewerStatsResponder());
00765 }