llviewerstats.cpp

Go to the documentation of this file.
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"             // *TODO: remove, only used for width/height
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         // ST_VERSION
00084         StatAttributes("Version", TRUE, FALSE),
00085         // ST_AVATAR_EDIT_SECONDS
00086         StatAttributes("Seconds in Edit Appearence", FALSE, TRUE),
00087         // ST_TOOLBOX_SECONDS
00088         StatAttributes("Seconds using Toolbox", FALSE, TRUE),
00089         // ST_CHAT_COUNT
00090         StatAttributes("Chat messages sent", FALSE, FALSE),
00091         // ST_IM_COUNT
00092         StatAttributes("IMs sent", FALSE, FALSE),
00093         // ST_FULLSCREEN_BOOL
00094         StatAttributes("Fullscreen mode", FALSE, FALSE),
00095         // ST_RELEASE_COUNT
00096         StatAttributes("Object release count", FALSE, FALSE),
00097         // ST_CREATE_COUNT
00098         StatAttributes("Object create count", FALSE, FALSE),
00099         // ST_REZ_COUNT
00100         StatAttributes("Object rez count", FALSE, FALSE),
00101         // ST_FPS_10_SECONDS
00102         StatAttributes("Seconds below 10 FPS", FALSE, TRUE),
00103         // ST_FPS_2_SECONDS
00104         StatAttributes("Seconds below 2 FPS", FALSE, TRUE),
00105         // ST_MOUSELOOK_SECONDS
00106         StatAttributes("Seconds in Mouselook", FALSE, TRUE),
00107         // ST_FLY_COUNT
00108         StatAttributes("Fly count", FALSE, FALSE),
00109         // ST_TELEPORT_COUNT
00110         StatAttributes("Teleport count", FALSE, FALSE),
00111         // ST_OBJECT_DELETE_COUNT
00112         StatAttributes("Objects deleted", FALSE, FALSE),
00113         // ST_SNAPSHOT_COUNT
00114         StatAttributes("Snapshots taken", FALSE, FALSE),
00115         // ST_UPLOAD_SOUND_COUNT
00116         StatAttributes("Sounds uploaded", FALSE, FALSE),
00117         // ST_UPLOAD_TEXTURE_COUNT
00118         StatAttributes("Textures uploaded", FALSE, FALSE),
00119         // ST_EDIT_TEXTURE_COUNT
00120         StatAttributes("Changes to textures on objects", FALSE, FALSE),
00121         // ST_KILLED_COUNT
00122         StatAttributes("Number of times killed", FALSE, FALSE),
00123         // ST_FRAMETIME_JITTER
00124         StatAttributes("Average delta between sucessive frame times", FALSE, FALSE),
00125         // ST_FRAMETIME_SLEW
00126         StatAttributes("Average delta between frame time and mean", FALSE, FALSE),
00127         // ST_INVENTORY_TOO_LONG
00128         StatAttributes("Inventory took too long to load", FALSE, FALSE),
00129         // ST_WEARABLES_TOO_LONG
00130         StatAttributes("Wearables took too long to load", FALSE, FALSE),
00131         // ST_LOGIN_SECONDS
00132         StatAttributes("Time between LoginRequest and LoginReply", FALSE, FALSE),
00133         // ST_LOGIN_TIMEOUT_COUNT
00134         StatAttributes("Number of login attempts that timed out", FALSE, FALSE),
00135         // ST_HAS_BAD_TIMER
00136         StatAttributes("Known bad timer if != 0.0", FALSE, FALSE),
00137         // ST_DOWNLOAD_FAILED
00138         StatAttributes("Number of times LLAssetStorage::getAssetData() has failed", FALSE, FALSE),
00139         // ST_LSL_SAVE_COUNT
00140         StatAttributes("Number of times user has saved a script", FALSE, FALSE),
00141         // ST_UPLOAD_ANIM_COUNT
00142         StatAttributes("Animations uploaded", FALSE, FALSE),
00143         // ST_FPS_8_SECONDS
00144         StatAttributes("Seconds below 8 FPS", FALSE, TRUE),
00145         // ST_SIM_FPS_20_SECONDS
00146         StatAttributes("Seconds with sim FPS below 20", FALSE, TRUE),
00147         // ST_PHYS_FPS_20_SECONDS
00148         StatAttributes("Seconds with physics FPS below 20", FALSE, TRUE),
00149         // ST_LOSS_05_SECONDS
00150         StatAttributes("Seconds with packet loss > 5%", FALSE, TRUE),
00151         // ST_FPS_DROP_50_RATIO
00152         StatAttributes("Ratio of frames 2x longer than previous", FALSE, FALSE),
00153         // ST_ENABLE_VBO
00154         StatAttributes("Vertex Buffers Enabled", TRUE, FALSE),
00155         // ST_DELTA_BANDWIDTH
00156         StatAttributes("Increase/Decrease in bandwidth based on packet loss", FALSE, FALSE),
00157         // ST_MAX_BANDWIDTH
00158         StatAttributes("Max bandwidth setting", FALSE, FALSE),
00159         // ST_LIGHTING_DETAIL
00160         StatAttributes("Lighting Detail", FALSE, FALSE),
00161         // ST_VISIBLE_AVATARS
00162         StatAttributes("Visible Avatars", FALSE, FALSE),
00163         // ST_SHADER_OJECTS
00164         StatAttributes("Object Shaders", FALSE, FALSE),
00165         // ST_SHADER_ENVIRONMENT
00166         StatAttributes("Environment Shaders", FALSE, FALSE),
00167         // ST_VISIBLE_DRAW_DIST
00168         StatAttributes("Draw Distance", FALSE, FALSE),
00169         // ST_VISIBLE_CHAT_BUBBLES
00170         StatAttributes("Chat Bubbles Enabled", FALSE, FALSE),
00171         // ST_SHADER_AVATAR
00172         StatAttributes("Avatar Shaders", FALSE, FALSE),
00173         // ST_FRAME_SECS
00174         StatAttributes("FRAME_SECS", FALSE, FALSE),
00175         // ST_UPDATE_SECS
00176         StatAttributes("UPDATE_SECS", FALSE, FALSE),
00177         // ST_NETWORK_SECS
00178         StatAttributes("NETWORK_SECS", FALSE, FALSE),
00179         // ST_IMAGE_SECS
00180         StatAttributes("IMAGE_SECS", FALSE, FALSE),
00181         // ST_REBUILD_SECS
00182         StatAttributes("REBUILD_SECS", FALSE, FALSE),
00183         // ST_RENDER_SECS
00184         StatAttributes("RENDER_SECS", FALSE, FALSE),
00185         // ST_CROSSING_AVG
00186         StatAttributes("CROSSING_AVG", FALSE, FALSE),
00187         // ST_CROSSING_MAX
00188         StatAttributes("CROSSING_MAX", FALSE, FALSE),
00189         // ST_LIBXUL_WIDGET_USED
00190         StatAttributes("LibXUL Widget used", FALSE, FALSE), // Unused
00191         // ST_WINDOW_WIDTH
00192         StatAttributes("Window width", FALSE, FALSE),
00193         // ST_WINDOW_HEIGHT
00194         StatAttributes("Window height", FALSE, FALSE),
00195         // ST_TEX_BAKES
00196         StatAttributes("Texture Bakes", FALSE, FALSE),
00197         // ST_TEX_REBAKES
00198         StatAttributes("Texture Rebakes", FALSE, FALSE),
00199 
00200         // ST_LOGITECH_KEYBOARD
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                 // new "stutter" meter
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                 // old stats that were never really used
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                         // TODO: send timer value so dataserver can normalize
00326                         misc[STAT_INFO[i].mName] = mStats[i];
00327                         llinfos << "STAT: " << STAT_INFO[i].mName << ": " << mStats[i]
00328                                         << llendl;
00329                 }
00330         }
00331 }
00332 
00333 // static
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 // *NOTE:Mani The following methods used to exist in viewer.cpp
00347 // Moving them here, but not merging them into LLViewerStats yet.
00348 void reset_statistics()
00349 {
00350         gPipeline.resetFrameStats();    // Reset per-frame statistics.
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 //      S32 app_angles[256];
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         // make sure we have a valid time delta for this frame
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         // Reset all of these values.
00593         gVLManager.resetBitCounts();
00594         gObjectBits = 0;
00595 //      gDecodedBits = 0;
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  * The sim-side LLSD is in newsim/llagentinfo.cpp:forwardViewerStats.
00627  *
00628  * There's also a compatibility shim for the old fixed-format sim
00629  * stats in newsim/llagentinfo.cpp:processViewerStats.
00630  *
00631  * If you move stats around here, make the corresponding changes in
00632  * those locations, too.
00633  */
00634 void send_stats()
00635 {
00636         // IW 9/23/02 I elected not to move this into LLViewerStats
00637         // because it depends on too many viewer.cpp globals.
00638         // Someday we may want to merge all our stats into a central place
00639         // but that day is not today.
00640 
00641         // Only send stats if the agent is connected to a region.
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(&ltime);
00661         F32 run_time = F32(LLFrameTimer::getElapsedSeconds());
00662 
00663         agent["start_time"] = ltime - run_time;
00664 
00665         // The first stat set must have a 0 run time if it doesn't actually
00666         // contain useful data in terms of FPS, etc.  We use half the
00667         // SEND_STATS_PERIOD seconds as the point at which these statistics become
00668         // valid.  Data warehouse uses a 0 value here to easily discard these
00669         // records with non-useful FPS values etc.
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         // send fps only for time app spends in foreground
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         // Misc stats, two strings and two ints
00747         // These are not expecticed to persist across multiple releases
00748         // Comment any changes with your name and the expected release revision
00749         // If the current revision is recent, ping the previous author before overriding
00750         LLSD &misc = body["stats"]["misc"];
00751 
00752         // Screen size so the UI team can figure out how big the widgets
00753         // appear and use a "typical" size for end user tests.
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         // misc["string_2"] = 
00759         misc["int_1"] = LLFloaterDirectory::sOldSearchCount; // Steve: 1.18.6
00760         misc["int_2"] = LLFloaterDirectory::sNewSearchCount; // Steve: 1.18.6
00761         
00762         LLViewerStats::getInstance()->addToMessage(body);
00763 
00764         LLHTTPClient::post(url, body, new ViewerStatsResponder());
00765 }

Generated on Fri May 16 08:34:17 2008 for SecondLife by  doxygen 1.5.5