llviewerstats.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:28k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llviewerstats.cpp
  3.  * @brief LLViewerStats class implementation
  4.  *
  5.  * $LicenseInfo:firstyear=2002&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2002-2010, Linden Research, Inc.
  8.  * 
  9.  * Second Life Viewer Source Code
  10.  * The source code in this file ("Source Code") is provided by Linden Lab
  11.  * to you under the terms of the GNU General Public License, version 2.0
  12.  * ("GPL"), unless you have obtained a separate licensing agreement
  13.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  14.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16.  * 
  17.  * There are special exceptions to the terms and conditions of the GPL as
  18.  * it is applied to this Source Code. View the full text of the exception
  19.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  20.  * online at
  21.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22.  * 
  23.  * By copying, modifying or distributing this software, you acknowledge
  24.  * that you have read and understood your obligations described above,
  25.  * and agree to abide by those obligations.
  26.  * 
  27.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29.  * COMPLETENESS OR PERFORMANCE.
  30.  * $/LicenseInfo$
  31.  */
  32. #include "llviewerprecompiledheaders.h"
  33. #include "llviewerstats.h"
  34. #include "llviewerthrottle.h"
  35. #include "message.h"
  36. #include "llfloaterreg.h"
  37. #include "llmemory.h"
  38. #include "lltimer.h"
  39. #include "llvfile.h"
  40. #include "llappviewer.h"
  41. #include "pipeline.h" 
  42. #include "lltexturefetch.h" 
  43. #include "llviewerobjectlist.h" 
  44. #include "llviewertexturelist.h" 
  45. #include "lltexlayer.h"
  46. #include "lltexlayerparams.h"
  47. #include "llsurface.h"
  48. #include "llvlmanager.h"
  49. #include "llagent.h"
  50. #include "llviewercontrol.h"
  51. #include "llfloatertools.h"
  52. #include "lldebugview.h"
  53. #include "llfasttimerview.h"
  54. #include "llviewerregion.h"
  55. #include "llvoavatar.h"
  56. #include "llvoavatarself.h"
  57. #include "llviewerwindow.h" // *TODO: remove, only used for width/height
  58. #include "llworld.h"
  59. #include "llfeaturemanager.h"
  60. #include "llviewernetwork.h"
  61. class StatAttributes
  62. {
  63. public:
  64. StatAttributes(const char* name,
  65.    const BOOL enabled,
  66.    const BOOL is_timer)
  67. : mName(name),
  68.   mEnabled(enabled),
  69.   mIsTimer(is_timer)
  70. {
  71. }
  72. std::string mName;
  73. BOOL mEnabled;
  74. BOOL mIsTimer;
  75. };
  76. const StatAttributes STAT_INFO[LLViewerStats::ST_COUNT] =
  77. {
  78. // ST_VERSION
  79. StatAttributes("Version", TRUE, FALSE),
  80. // ST_AVATAR_EDIT_SECONDS
  81. StatAttributes("Seconds in Edit Appearence", FALSE, TRUE),
  82. // ST_TOOLBOX_SECONDS
  83. StatAttributes("Seconds using Toolbox", FALSE, TRUE),
  84. // ST_CHAT_COUNT
  85. StatAttributes("Chat messages sent", FALSE, FALSE),
  86. // ST_IM_COUNT
  87. StatAttributes("IMs sent", FALSE, FALSE),
  88. // ST_FULLSCREEN_BOOL
  89. StatAttributes("Fullscreen mode", FALSE, FALSE),
  90. // ST_RELEASE_COUNT
  91. StatAttributes("Object release count", FALSE, FALSE),
  92. // ST_CREATE_COUNT
  93. StatAttributes("Object create count", FALSE, FALSE),
  94. // ST_REZ_COUNT
  95. StatAttributes("Object rez count", FALSE, FALSE),
  96. // ST_FPS_10_SECONDS
  97. StatAttributes("Seconds below 10 FPS", FALSE, TRUE),
  98. // ST_FPS_2_SECONDS
  99. StatAttributes("Seconds below 2 FPS", FALSE, TRUE),
  100. // ST_MOUSELOOK_SECONDS
  101. StatAttributes("Seconds in Mouselook", FALSE, TRUE),
  102. // ST_FLY_COUNT
  103. StatAttributes("Fly count", FALSE, FALSE),
  104. // ST_TELEPORT_COUNT
  105. StatAttributes("Teleport count", FALSE, FALSE),
  106. // ST_OBJECT_DELETE_COUNT
  107. StatAttributes("Objects deleted", FALSE, FALSE),
  108. // ST_SNAPSHOT_COUNT
  109. StatAttributes("Snapshots taken", FALSE, FALSE),
  110. // ST_UPLOAD_SOUND_COUNT
  111. StatAttributes("Sounds uploaded", FALSE, FALSE),
  112. // ST_UPLOAD_TEXTURE_COUNT
  113. StatAttributes("Textures uploaded", FALSE, FALSE),
  114. // ST_EDIT_TEXTURE_COUNT
  115. StatAttributes("Changes to textures on objects", FALSE, FALSE),
  116. // ST_KILLED_COUNT
  117. StatAttributes("Number of times killed", FALSE, FALSE),
  118. // ST_FRAMETIME_JITTER
  119. StatAttributes("Average delta between sucessive frame times", FALSE, FALSE),
  120. // ST_FRAMETIME_SLEW
  121. StatAttributes("Average delta between frame time and mean", FALSE, FALSE),
  122. // ST_INVENTORY_TOO_LONG
  123. StatAttributes("Inventory took too long to load", FALSE, FALSE),
  124. // ST_WEARABLES_TOO_LONG
  125. StatAttributes("Wearables took too long to load", FALSE, FALSE),
  126. // ST_LOGIN_SECONDS
  127. StatAttributes("Time between LoginRequest and LoginReply", FALSE, FALSE),
  128. // ST_LOGIN_TIMEOUT_COUNT
  129. StatAttributes("Number of login attempts that timed out", FALSE, FALSE),
  130. // ST_HAS_BAD_TIMER
  131. StatAttributes("Known bad timer if != 0.0", FALSE, FALSE),
  132. // ST_DOWNLOAD_FAILED
  133. StatAttributes("Number of times LLAssetStorage::getAssetData() has failed", FALSE, FALSE),
  134. // ST_LSL_SAVE_COUNT
  135. StatAttributes("Number of times user has saved a script", FALSE, FALSE),
  136. // ST_UPLOAD_ANIM_COUNT
  137. StatAttributes("Animations uploaded", FALSE, FALSE),
  138. // ST_FPS_8_SECONDS
  139. StatAttributes("Seconds below 8 FPS", FALSE, TRUE),
  140. // ST_SIM_FPS_20_SECONDS
  141. StatAttributes("Seconds with sim FPS below 20", FALSE, TRUE),
  142. // ST_PHYS_FPS_20_SECONDS
  143. StatAttributes("Seconds with physics FPS below 20", FALSE, TRUE),
  144. // ST_LOSS_05_SECONDS
  145. StatAttributes("Seconds with packet loss > 5%", FALSE, TRUE),
  146. // ST_FPS_DROP_50_RATIO
  147. StatAttributes("Ratio of frames 2x longer than previous", FALSE, FALSE),
  148. // ST_ENABLE_VBO
  149. StatAttributes("Vertex Buffers Enabled", TRUE, FALSE),
  150. // ST_DELTA_BANDWIDTH
  151. StatAttributes("Increase/Decrease in bandwidth based on packet loss", FALSE, FALSE),
  152. // ST_MAX_BANDWIDTH
  153. StatAttributes("Max bandwidth setting", FALSE, FALSE),
  154. // ST_LIGHTING_DETAIL
  155. StatAttributes("Lighting Detail", FALSE, FALSE),
  156. // ST_VISIBLE_AVATARS
  157. StatAttributes("Visible Avatars", FALSE, FALSE),
  158. // ST_SHADER_OJECTS
  159. StatAttributes("Object Shaders", FALSE, FALSE),
  160. // ST_SHADER_ENVIRONMENT
  161. StatAttributes("Environment Shaders", FALSE, FALSE),
  162. // ST_VISIBLE_DRAW_DIST
  163. StatAttributes("Draw Distance", FALSE, FALSE),
  164. // ST_VISIBLE_CHAT_BUBBLES
  165. StatAttributes("Chat Bubbles Enabled", FALSE, FALSE),
  166. // ST_SHADER_AVATAR
  167. StatAttributes("Avatar Shaders", FALSE, FALSE),
  168. // ST_FRAME_SECS
  169. StatAttributes("FRAME_SECS", FALSE, FALSE),
  170. // ST_UPDATE_SECS
  171. StatAttributes("UPDATE_SECS", FALSE, FALSE),
  172. // ST_NETWORK_SECS
  173. StatAttributes("NETWORK_SECS", FALSE, FALSE),
  174. // ST_IMAGE_SECS
  175. StatAttributes("IMAGE_SECS", FALSE, FALSE),
  176. // ST_REBUILD_SECS
  177. StatAttributes("REBUILD_SECS", FALSE, FALSE),
  178. // ST_RENDER_SECS
  179. StatAttributes("RENDER_SECS", FALSE, FALSE),
  180. // ST_CROSSING_AVG
  181. StatAttributes("CROSSING_AVG", FALSE, FALSE),
  182. // ST_CROSSING_MAX
  183. StatAttributes("CROSSING_MAX", FALSE, FALSE),
  184. // ST_LIBXUL_WIDGET_USED
  185. StatAttributes("LibXUL Widget used", FALSE, FALSE), // Unused
  186. // ST_WINDOW_WIDTH
  187. StatAttributes("Window width", FALSE, FALSE),
  188. // ST_WINDOW_HEIGHT
  189. StatAttributes("Window height", FALSE, FALSE),
  190. // ST_TEX_BAKES
  191. StatAttributes("Texture Bakes", FALSE, FALSE),
  192. // ST_TEX_REBAKES
  193. StatAttributes("Texture Rebakes", FALSE, FALSE)
  194. };
  195. LLViewerStats::LLViewerStats() :
  196. mKBitStat("kbitstat"),
  197. mLayersKBitStat("layerskbitstat"),
  198. mObjectKBitStat("objectkbitstat"),
  199. mAssetKBitStat("assetkbitstat"),
  200. mTextureKBitStat("texturekbitstat"),
  201. mVFSPendingOperations("vfspendingoperations"),
  202. mObjectsDrawnStat("objectsdrawnstat"),
  203. mObjectsCulledStat("objectsculledstat"),
  204. mObjectsTestedStat("objectstestedstat"),
  205. mObjectsComparedStat("objectscomparedstat"),
  206. mObjectsOccludedStat("objectsoccludedstat"),
  207. mFPSStat("fpsstat"),
  208. mPacketsInStat("packetsinstat"),
  209. mPacketsLostStat("packetsloststat"),
  210. mPacketsOutStat("packetsoutstat"),
  211. mPacketsLostPercentStat("packetslostpercentstat", 64),
  212. mTexturePacketsStat("texturepacketsstat"),
  213. mActualInKBitStat("actualinkbitstat"),
  214. mActualOutKBitStat("actualoutkbitstat"),
  215. mTrianglesDrawnStat("trianglesdrawnstat"),
  216. mSimTimeDilation("simtimedilation"),
  217. mSimFPS("simfps"),
  218. mSimPhysicsFPS("simphysicsfps"),
  219. mSimAgentUPS("simagentups"),
  220. mSimScriptEPS("simscripteps"),
  221. mSimFrameMsec("simframemsec"),
  222. mSimNetMsec("simnetmsec"),
  223. mSimSimOtherMsec("simsimothermsec"),
  224. mSimSimPhysicsMsec("simsimphysicsmsec"),
  225. mSimSimPhysicsStepMsec("simsimphysicsstepmsec"),
  226. mSimSimPhysicsShapeUpdateMsec("simsimphysicsshapeupdatemsec"),
  227. mSimSimPhysicsOtherMsec("simsimphysicsothermsec"),
  228. mSimAgentMsec("simagentmsec"),
  229. mSimImagesMsec("simimagesmsec"),
  230. mSimScriptMsec("simscriptmsec"),
  231. mSimSpareMsec("simsparemsec"),
  232. mSimSleepMsec("simsleepmsec"),
  233. mSimPumpIOMsec("simpumpiomsec"),
  234. mSimMainAgents("simmainagents"),
  235. mSimChildAgents("simchildagents"),
  236. mSimObjects("simobjects"),
  237. mSimActiveObjects("simactiveobjects"),
  238. mSimActiveScripts("simactivescripts"),
  239. mSimInPPS("siminpps"),
  240. mSimOutPPS("simoutpps"),
  241. mSimPendingDownloads("simpendingdownloads"),
  242. mSimPendingUploads("simpendinguploads"),
  243. mSimPendingLocalUploads("simpendinglocaluploads"),
  244. mSimTotalUnackedBytes("simtotalunackedbytes"),
  245. mPhysicsPinnedTasks("physicspinnedtasks"),
  246. mPhysicsLODTasks("physicslodtasks"),
  247. mPhysicsMemoryAllocated("physicsmemoryallocated"),
  248. mSimPingStat("simpingstat"),
  249. mNumImagesStat("numimagesstat", 32, TRUE),
  250. mNumRawImagesStat("numrawimagesstat", 32, TRUE),
  251. mGLTexMemStat("gltexmemstat", 32, TRUE),
  252. mGLBoundMemStat("glboundmemstat", 32, TRUE),
  253. mRawMemStat("rawmemstat", 32, TRUE),
  254. mFormattedMemStat("formattedmemstat", 32, TRUE),
  255. mNumObjectsStat("numobjectsstat"),
  256. mNumActiveObjectsStat("numactiveobjectsstat"),
  257. mNumNewObjectsStat("numnewobjectsstat"),
  258. mNumSizeCulledStat("numsizeculledstat"),
  259. mNumVisCulledStat("numvisculledstat"),
  260. mLastTimeDiff(0.0)
  261. {
  262. for (S32 i = 0; i < ST_COUNT; i++)
  263. {
  264. mStats[i] = 0.0;
  265. }
  266. if (LLTimer::knownBadTimer())
  267. {
  268. mStats[ST_HAS_BAD_TIMER] = 1.0;
  269. }
  270. }
  271. LLViewerStats::~LLViewerStats()
  272. {
  273. }
  274. void LLViewerStats::resetStats()
  275. {
  276. LLViewerStats::getInstance()->mKBitStat.reset();
  277. LLViewerStats::getInstance()->mLayersKBitStat.reset();
  278. LLViewerStats::getInstance()->mObjectKBitStat.reset();
  279. LLViewerStats::getInstance()->mTextureKBitStat.reset();
  280. LLViewerStats::getInstance()->mVFSPendingOperations.reset();
  281. LLViewerStats::getInstance()->mAssetKBitStat.reset();
  282. LLViewerStats::getInstance()->mPacketsInStat.reset();
  283. LLViewerStats::getInstance()->mPacketsLostStat.reset();
  284. LLViewerStats::getInstance()->mPacketsOutStat.reset();
  285. LLViewerStats::getInstance()->mFPSStat.reset();
  286. LLViewerStats::getInstance()->mTexturePacketsStat.reset();
  287. }
  288. F64 LLViewerStats::getStat(EStatType type) const
  289. {
  290. return mStats[type];
  291. }
  292. F64 LLViewerStats::setStat(EStatType type, F64 value)
  293. {
  294. mStats[type] = value;
  295. return mStats[type];
  296. }
  297. F64 LLViewerStats::incStat(EStatType type, F64 value)
  298. {
  299. mStats[type] += value;
  300. return mStats[type];
  301. }
  302. void LLViewerStats::updateFrameStats(const F64 time_diff)
  303. {
  304. if (mPacketsLostPercentStat.getCurrent() > 5.0)
  305. {
  306. incStat(LLViewerStats::ST_LOSS_05_SECONDS, time_diff);
  307. }
  308. if (mSimFPS.getCurrent() < 20.f && mSimFPS.getCurrent() > 0.f)
  309. {
  310. incStat(LLViewerStats::ST_SIM_FPS_20_SECONDS, time_diff);
  311. }
  312. if (mSimPhysicsFPS.getCurrent() < 20.f && mSimPhysicsFPS.getCurrent() > 0.f)
  313. {
  314. incStat(LLViewerStats::ST_PHYS_FPS_20_SECONDS, time_diff);
  315. }
  316. if (time_diff >= 0.5)
  317. {
  318. incStat(LLViewerStats::ST_FPS_2_SECONDS, time_diff);
  319. }
  320. if (time_diff >= 0.125)
  321. {
  322. incStat(LLViewerStats::ST_FPS_8_SECONDS, time_diff);
  323. }
  324. if (time_diff >= 0.1)
  325. {
  326. incStat(LLViewerStats::ST_FPS_10_SECONDS, time_diff);
  327. }
  328. if (gFrameCount && mLastTimeDiff > 0.0)
  329. {
  330. // new "stutter" meter
  331. setStat(LLViewerStats::ST_FPS_DROP_50_RATIO,
  332. (getStat(LLViewerStats::ST_FPS_DROP_50_RATIO) * (F64)(gFrameCount - 1) + 
  333.  (time_diff >= 2.0 * mLastTimeDiff ? 1.0 : 0.0)) / gFrameCount);
  334. // old stats that were never really used
  335. setStat(LLViewerStats::ST_FRAMETIME_JITTER,
  336. (getStat(LLViewerStats::ST_FRAMETIME_JITTER) * (gFrameCount - 1) + 
  337.  fabs(mLastTimeDiff - time_diff) / mLastTimeDiff) / gFrameCount);
  338. F32 average_frametime = gRenderStartTime.getElapsedTimeF32() / (F32)gFrameCount;
  339. setStat(LLViewerStats::ST_FRAMETIME_SLEW,
  340. (getStat(LLViewerStats::ST_FRAMETIME_SLEW) * (gFrameCount - 1) + 
  341.  fabs(average_frametime - time_diff) / average_frametime) / gFrameCount);
  342. F32 max_bandwidth = gViewerThrottle.getMaxBandwidth();
  343. F32 delta_bandwidth = gViewerThrottle.getCurrentBandwidth() - max_bandwidth;
  344. setStat(LLViewerStats::ST_DELTA_BANDWIDTH, delta_bandwidth / 1024.f);
  345. setStat(LLViewerStats::ST_MAX_BANDWIDTH, max_bandwidth / 1024.f);
  346. }
  347. mLastTimeDiff = time_diff;
  348. }
  349. void LLViewerStats::addToMessage(LLSD &body) const
  350. {
  351. LLSD &misc = body["misc"];
  352. for (S32 i = 0; i < ST_COUNT; i++)
  353. {
  354. if (STAT_INFO[i].mEnabled)
  355. {
  356. // TODO: send timer value so dataserver can normalize
  357. misc[STAT_INFO[i].mName] = mStats[i];
  358. llinfos << "STAT: " << STAT_INFO[i].mName << ": " << mStats[i]
  359. << llendl;
  360. }
  361. }
  362. }
  363. // static
  364. // const std::string LLViewerStats::statTypeToText(EStatType type)
  365. // {
  366. //  if (type >= 0 && type < ST_COUNT)
  367. //  {
  368. //  return STAT_INFO[type].mName;
  369. //  }
  370. //  else
  371. //  {
  372. //  return "Unknown statistic";
  373. //  }
  374. // }
  375. // *NOTE:Mani The following methods used to exist in viewer.cpp
  376. // Moving them here, but not merging them into LLViewerStats yet.
  377. void reset_statistics()
  378. {
  379. if (LLSurface::sTextureUpdateTime)
  380. {
  381. LLSurface::sTexelsUpdated = 0;
  382. LLSurface::sTextureUpdateTime = 0.f;
  383. }
  384. }
  385. void output_statistics(void*)
  386. {
  387. llinfos << "Number of orphans: " << gObjectList.getOrphanCount() << llendl;
  388. llinfos << "Number of dead objects: " << gObjectList.mNumDeadObjects << llendl;
  389. llinfos << "Num images: " << gTextureList.getNumImages() << llendl;
  390. llinfos << "Texture usage: " << LLImageGL::sGlobalTextureMemoryInBytes << llendl;
  391. llinfos << "Texture working set: " << LLImageGL::sBoundTextureMemoryInBytes << llendl;
  392. llinfos << "Raw usage: " << LLImageRaw::sGlobalRawMemory << llendl;
  393. llinfos << "Formatted usage: " << LLImageFormatted::sGlobalFormattedMemory << llendl;
  394. llinfos << "Zombie Viewer Objects: " << LLViewerObject::getNumZombieObjects() << llendl;
  395. llinfos << "Number of lights: " << gPipeline.getLightCount() << llendl;
  396. llinfos << "Memory Usage:" << llendl;
  397. llinfos << "--------------------------------" << llendl;
  398. llinfos << "Pipeline:" << llendl;
  399. llinfos << llendl;
  400. #if LL_SMARTHEAP
  401. llinfos << "--------------------------------" << llendl;
  402. {
  403. llinfos << "sizeof(LLVOVolume) = " << sizeof(LLVOVolume) << llendl;
  404. U32 total_pool_size = 0;
  405. U32 total_used_size = 0;
  406. MEM_POOL_INFO pool_info;
  407. MEM_POOL_STATUS pool_status;
  408. U32 pool_num = 0;
  409. for(pool_status = MemPoolFirst( &pool_info, 1 ); 
  410. pool_status != MEM_POOL_END; 
  411. pool_status = MemPoolNext( &pool_info, 1 ) )
  412. {
  413. llinfos << "Pool #" << pool_num << llendl;
  414. if( MEM_POOL_OK != pool_status )
  415. {
  416. llwarns << "Pool not ok" << llendl;
  417. continue;
  418. }
  419. llinfos << "Pool blockSizeFS " << pool_info.blockSizeFS
  420. << " pageSize " << pool_info.pageSize
  421. << llendl;
  422. U32 pool_count = MemPoolCount(pool_info.pool);
  423. llinfos << "Blocks " << pool_count << llendl;
  424. U32 pool_size = MemPoolSize( pool_info.pool );
  425. if( pool_size == MEM_ERROR_RET )
  426. {
  427. llinfos << "MemPoolSize() failed (" << pool_num << ")" << llendl;
  428. }
  429. else
  430. {
  431. llinfos << "MemPool Size " << pool_size / 1024 << "K" << llendl;
  432. }
  433. total_pool_size += pool_size;
  434. if( !MemPoolLock( pool_info.pool ) )
  435. {
  436. llinfos << "MemPoolLock failed (" << pool_num << ") " << llendl;
  437. continue;
  438. }
  439. U32 used_size = 0; 
  440. MEM_POOL_ENTRY entry;
  441. entry.entry = NULL;
  442. while( MemPoolWalk( pool_info.pool, &entry ) == MEM_POOL_OK )
  443. {
  444. if( entry.isInUse )
  445. {
  446. used_size += entry.size;
  447. }
  448. }
  449. MemPoolUnlock( pool_info.pool );
  450. llinfos << "MemPool Used " << used_size/1024 << "K" << llendl;
  451. total_used_size += used_size;
  452. pool_num++;
  453. }
  454. llinfos << "Total Pool Size " << total_pool_size/1024 << "K" << llendl;
  455. llinfos << "Total Used Size " << total_used_size/1024 << "K" << llendl;
  456. }
  457. #endif
  458. llinfos << "--------------------------------" << llendl;
  459. llinfos << "Avatar Memory (partly overlaps with above stats):" << llendl;
  460. LLTexLayerStaticImageList::getInstance()->dumpByteCount();
  461. LLVOAvatarSelf::dumpScratchTextureByteCount();
  462. LLTexLayerSetBuffer::dumpTotalByteCount();
  463. LLVOAvatarSelf::dumpTotalLocalTextureByteCount();
  464. LLTexLayerParamAlpha::dumpCacheByteCount();
  465. LLVOAvatar::dumpBakedStatus();
  466. llinfos << llendl;
  467. llinfos << "Object counts:" << llendl;
  468. S32 i;
  469. S32 obj_counts[256];
  470. // S32 app_angles[256];
  471. for (i = 0; i < 256; i++)
  472. {
  473. obj_counts[i] = 0;
  474. }
  475. for (i = 0; i < gObjectList.getNumObjects(); i++)
  476. {
  477. LLViewerObject *objectp = gObjectList.getObject(i);
  478. if (objectp)
  479. {
  480. obj_counts[objectp->getPCode()]++;
  481. }
  482. }
  483. for (i = 0; i < 256; i++)
  484. {
  485. if (obj_counts[i])
  486. {
  487. llinfos << LLPrimitive::pCodeToString(i) << ":" << obj_counts[i] << llendl;
  488. }
  489. }
  490. }
  491. U32 gTotalLandIn = 0, gTotalLandOut = 0;
  492. U32 gTotalWaterIn = 0, gTotalWaterOut = 0;
  493. F32 gAveLandCompression = 0.f, gAveWaterCompression = 0.f;
  494. F32 gBestLandCompression = 1.f, gBestWaterCompression = 1.f;
  495. F32 gWorstLandCompression = 0.f, gWorstWaterCompression = 0.f;
  496. U32 gTotalWorldBytes = 0, gTotalObjectBytes = 0, gTotalTextureBytes = 0, gSimPingCount = 0;
  497. U32 gObjectBits = 0;
  498. F32 gAvgSimPing = 0.f;
  499. extern U32  gVisCompared;
  500. extern U32  gVisTested;
  501. std::map<S32,LLFrameTimer> gDebugTimers;
  502. std::map<S32,std::string> gDebugTimerLabel;
  503. void init_statistics()
  504. {
  505. // Label debug timers
  506. gDebugTimerLabel[0] = "Texture";
  507. }
  508. void update_statistics(U32 frame_count)
  509. {
  510. gTotalWorldBytes += gVLManager.getTotalBytes();
  511. gTotalObjectBytes += gObjectBits / 8;
  512. // make sure we have a valid time delta for this frame
  513. if (gFrameIntervalSeconds > 0.f)
  514. {
  515. if (gAgent.getCameraMode() == CAMERA_MODE_MOUSELOOK)
  516. {
  517. LLViewerStats::getInstance()->incStat(LLViewerStats::ST_MOUSELOOK_SECONDS, gFrameIntervalSeconds);
  518. }
  519. else if (gAgent.getCameraMode() == CAMERA_MODE_CUSTOMIZE_AVATAR)
  520. {
  521. LLViewerStats::getInstance()->incStat(LLViewerStats::ST_AVATAR_EDIT_SECONDS, gFrameIntervalSeconds);
  522. }
  523. else if (LLFloaterReg::instanceVisible("build"))
  524. {
  525. LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TOOLBOX_SECONDS, gFrameIntervalSeconds);
  526. }
  527. }
  528. LLViewerStats::getInstance()->setStat(LLViewerStats::ST_ENABLE_VBO, (F64)gSavedSettings.getBOOL("RenderVBOEnable"));
  529. LLViewerStats::getInstance()->setStat(LLViewerStats::ST_LIGHTING_DETAIL, (F64)gSavedSettings.getS32("RenderLightingDetail"));
  530. LLViewerStats::getInstance()->setStat(LLViewerStats::ST_DRAW_DIST, (F64)gSavedSettings.getF32("RenderFarClip"));
  531. LLViewerStats::getInstance()->setStat(LLViewerStats::ST_CHAT_BUBBLES, (F64)gSavedSettings.getBOOL("UseChatBubbles"));
  532. #if 0 // 1.9.2
  533. LLViewerStats::getInstance()->setStat(LLViewerStats::ST_SHADER_OBJECTS, (F64)gSavedSettings.getS32("VertexShaderLevelObject"));
  534. LLViewerStats::getInstance()->setStat(LLViewerStats::ST_SHADER_AVATAR, (F64)gSavedSettings.getBOOL("VertexShaderLevelAvatar"));
  535. LLViewerStats::getInstance()->setStat(LLViewerStats::ST_SHADER_ENVIRONMENT, (F64)gSavedSettings.getBOOL("VertexShaderLevelEnvironment"));
  536. #endif
  537. LLViewerStats::getInstance()->setStat(LLViewerStats::ST_FRAME_SECS, gDebugView->mFastTimerView->getTime("Frame"));
  538. F64 idle_secs = gDebugView->mFastTimerView->getTime("Idle");
  539. F64 network_secs = gDebugView->mFastTimerView->getTime("Network");
  540. LLViewerStats::getInstance()->setStat(LLViewerStats::ST_UPDATE_SECS, idle_secs - network_secs);
  541. LLViewerStats::getInstance()->setStat(LLViewerStats::ST_NETWORK_SECS, network_secs);
  542. LLViewerStats::getInstance()->setStat(LLViewerStats::ST_IMAGE_SECS, gDebugView->mFastTimerView->getTime("Update Images"));
  543. LLViewerStats::getInstance()->setStat(LLViewerStats::ST_REBUILD_SECS, gDebugView->mFastTimerView->getTime("Sort Draw State"));
  544. LLViewerStats::getInstance()->setStat(LLViewerStats::ST_RENDER_SECS, gDebugView->mFastTimerView->getTime("Geometry"));
  545. LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(gAgent.getRegion()->getHost());
  546. if (cdp)
  547. {
  548. LLViewerStats::getInstance()->mSimPingStat.addValue(cdp->getPingDelay());
  549. gAvgSimPing = ((gAvgSimPing * (F32)gSimPingCount) + (F32)(cdp->getPingDelay())) / ((F32)gSimPingCount + 1);
  550. gSimPingCount++;
  551. }
  552. else
  553. {
  554. LLViewerStats::getInstance()->mSimPingStat.addValue(10000);
  555. }
  556. LLViewerStats::getInstance()->mFPSStat.addValue(1);
  557. F32 layer_bits = (F32)(gVLManager.getLandBits() + gVLManager.getWindBits() + gVLManager.getCloudBits());
  558. LLViewerStats::getInstance()->mLayersKBitStat.addValue(layer_bits/1024.f);
  559. LLViewerStats::getInstance()->mObjectKBitStat.addValue(gObjectBits/1024.f);
  560. LLViewerStats::getInstance()->mVFSPendingOperations.addValue(LLVFile::getVFSThread()->getPending());
  561. LLViewerStats::getInstance()->mAssetKBitStat.addValue(gTransferManager.getTransferBitsIn(LLTCT_ASSET)/1024.f);
  562. gTransferManager.resetTransferBitsIn(LLTCT_ASSET);
  563. if (LLAppViewer::getTextureFetch()->getNumRequests() == 0)
  564. {
  565. gDebugTimers[0].pause();
  566. }
  567. else
  568. {
  569. gDebugTimers[0].unpause();
  570. }
  571. {
  572. static F32 visible_avatar_frames = 0.f;
  573. static F32 avg_visible_avatars = 0;
  574. F32 visible_avatars = (F32)LLVOAvatar::sNumVisibleAvatars;
  575. if (visible_avatars > 0.f)
  576. {
  577. visible_avatar_frames = 1.f;
  578. avg_visible_avatars = (avg_visible_avatars * (F32)(visible_avatar_frames - 1.f) + visible_avatars) / visible_avatar_frames;
  579. }
  580. LLViewerStats::getInstance()->setStat(LLViewerStats::ST_VISIBLE_AVATARS, (F64)avg_visible_avatars);
  581. }
  582. LLWorld::getInstance()->updateNetStats();
  583. LLWorld::getInstance()->requestCacheMisses();
  584. // Reset all of these values.
  585. gVLManager.resetBitCounts();
  586. gObjectBits = 0;
  587. // gDecodedBits = 0;
  588. // Only update texture stats periodically so that they are less noisy
  589. {
  590. static const F32 texture_stats_freq = 10.f;
  591. static LLFrameTimer texture_stats_timer;
  592. if (texture_stats_timer.getElapsedTimeF32() >= texture_stats_freq)
  593. {
  594. LLViewerStats::getInstance()->mTextureKBitStat.addValue(LLViewerTextureList::sTextureBits/1024.f);
  595. LLViewerStats::getInstance()->mTexturePacketsStat.addValue(LLViewerTextureList::sTexturePackets);
  596. gTotalTextureBytes += LLViewerTextureList::sTextureBits / 8;
  597. LLViewerTextureList::sTextureBits = 0;
  598. LLViewerTextureList::sTexturePackets = 0;
  599. texture_stats_timer.reset();
  600. }
  601. }
  602. }
  603. class ViewerStatsResponder : public LLHTTPClient::Responder
  604. {
  605. public:
  606.     ViewerStatsResponder() { }
  607.     void error(U32 statusNum, const std::string& reason)
  608.     {
  609. llinfos << "ViewerStatsResponder::error " << statusNum << " "
  610. << reason << llendl;
  611.     }
  612.     void result(const LLSD& content)
  613.     {
  614. llinfos << "ViewerStatsResponder::result" << llendl;
  615. }
  616. };
  617. /*
  618.  * The sim-side LLSD is in newsim/llagentinfo.cpp:forwardViewerStats.
  619.  *
  620.  * There's also a compatibility shim for the old fixed-format sim
  621.  * stats in newsim/llagentinfo.cpp:processViewerStats.
  622.  *
  623.  * If you move stats around here, make the corresponding changes in
  624.  * those locations, too.
  625.  */
  626. void send_stats()
  627. {
  628. // IW 9/23/02 I elected not to move this into LLViewerStats
  629. // because it depends on too many viewer.cpp globals.
  630. // Someday we may want to merge all our stats into a central place
  631. // but that day is not today.
  632. // Only send stats if the agent is connected to a region.
  633. if (!gAgent.getRegion() || gNoRender)
  634. {
  635. return;
  636. }
  637. LLSD body;
  638. std::string url = gAgent.getRegion()->getCapability("ViewerStats");
  639. if (url.empty()) {
  640. llwarns << "Could not get ViewerStats capability" << llendl;
  641. return;
  642. }
  643. body["session_id"] = gAgentSessionID;
  644. LLSD &agent = body["agent"];
  645. time_t ltime;
  646. time(&ltime);
  647. F32 run_time = F32(LLFrameTimer::getElapsedSeconds());
  648. agent["start_time"] = S32(ltime - S32(run_time));
  649. // The first stat set must have a 0 run time if it doesn't actually
  650. // contain useful data in terms of FPS, etc.  We use half the
  651. // SEND_STATS_PERIOD seconds as the point at which these statistics become
  652. // valid.  Data warehouse uses a 0 value here to easily discard these
  653. // records with non-useful FPS values etc.
  654. if (run_time < (SEND_STATS_PERIOD / 2))
  655. {
  656. agent["run_time"] = 0.0f;
  657. }
  658. else
  659. {
  660. agent["run_time"] = run_time;
  661. }
  662. // send fps only for time app spends in foreground
  663. agent["fps"] = (F32)gForegroundFrameCount / gForegroundTime.getElapsedTimeF32();
  664. agent["version"] = gCurrentVersion;
  665. std::string language = LLUI::getLanguage();
  666. agent["language"] = language;
  667. agent["sim_fps"] = ((F32) gFrameCount - gSimFrames) /
  668. (F32) (gRenderStartTime.getElapsedTimeF32() - gSimLastTime);
  669. gSimLastTime = gRenderStartTime.getElapsedTimeF32();
  670. gSimFrames   = (F32) gFrameCount;
  671. agent["agents_in_view"] = LLVOAvatar::sNumVisibleAvatars;
  672. agent["ping"] = gAvgSimPing;
  673. agent["meters_traveled"] = gAgent.getDistanceTraveled();
  674. agent["regions_visited"] = gAgent.getRegionsVisited();
  675. agent["mem_use"] = LLMemory::getCurrentRSS() / 1024.0;
  676. LLSD &system = body["system"];
  677. system["ram"] = (S32) gSysMemory.getPhysicalMemoryKB();
  678. system["os"] = LLAppViewer::instance()->getOSInfo().getOSStringSimple();
  679. system["cpu"] = gSysCPU.getCPUString();
  680. std::string macAddressString = llformat("%02x-%02x-%02x-%02x-%02x-%02x",
  681. gMACAddress[0],gMACAddress[1],gMACAddress[2],
  682. gMACAddress[3],gMACAddress[4],gMACAddress[5]);
  683. system["mac_address"] = macAddressString;
  684. system["serial_number"] = LLAppViewer::instance()->getSerialNumber();
  685. std::string gpu_desc = llformat(
  686. "%-6s Class %d ",
  687. gGLManager.mGLVendorShort.substr(0,6).c_str(),
  688. (S32)LLFeatureManager::getInstance()->getGPUClass())
  689. + LLFeatureManager::getInstance()->getGPUString();
  690. system["gpu"] = gpu_desc;
  691. system["gpu_class"] = (S32)LLFeatureManager::getInstance()->getGPUClass();
  692. system["gpu_vendor"] = gGLManager.mGLVendorShort;
  693. system["gpu_version"] = gGLManager.mDriverVersionVendorString;
  694. LLSD &download = body["downloads"];
  695. download["world_kbytes"] = gTotalWorldBytes / 1024.0;
  696. download["object_kbytes"] = gTotalObjectBytes / 1024.0;
  697. download["texture_kbytes"] = gTotalTextureBytes / 1024.0;
  698. LLSD &in = body["stats"]["net"]["in"];
  699. in["kbytes"] = gMessageSystem->mTotalBytesIn / 1024.0;
  700. in["packets"] = (S32) gMessageSystem->mPacketsIn;
  701. in["compressed_packets"] = (S32) gMessageSystem->mCompressedPacketsIn;
  702. in["savings"] = (gMessageSystem->mUncompressedBytesIn -
  703.  gMessageSystem->mCompressedBytesIn) / 1024.0;
  704. LLSD &out = body["stats"]["net"]["out"];
  705. out["kbytes"] = gMessageSystem->mTotalBytesOut / 1024.0;
  706. out["packets"] = (S32) gMessageSystem->mPacketsOut;
  707. out["compressed_packets"] = (S32) gMessageSystem->mCompressedPacketsOut;
  708. out["savings"] = (gMessageSystem->mUncompressedBytesOut -
  709.   gMessageSystem->mCompressedBytesOut) / 1024.0;
  710. LLSD &fail = body["stats"]["failures"];
  711. fail["send_packet"] = (S32) gMessageSystem->mSendPacketFailureCount;
  712. fail["dropped"] = (S32) gMessageSystem->mDroppedPackets;
  713. fail["resent"] = (S32) gMessageSystem->mResentPackets;
  714. fail["failed_resends"] = (S32) gMessageSystem->mFailedResendPackets;
  715. fail["off_circuit"] = (S32) gMessageSystem->mOffCircuitPackets;
  716. fail["invalid"] = (S32) gMessageSystem->mInvalidOnCircuitPackets;
  717. // Misc stats, two strings and two ints
  718. // These are not expecticed to persist across multiple releases
  719. // Comment any changes with your name and the expected release revision
  720. // If the current revision is recent, ping the previous author before overriding
  721. LLSD &misc = body["stats"]["misc"];
  722. // Screen size so the UI team can figure out how big the widgets
  723. // appear and use a "typical" size for end user tests.
  724. S32 window_width = gViewerWindow->getWindowWidthRaw();
  725. S32 window_height = gViewerWindow->getWindowHeightRaw();
  726. S32 window_size = (window_width * window_height) / 1024;
  727. misc["string_1"] = llformat("%d", window_size);
  728. // misc["string_2"] = 
  729. //  misc["int_1"] = LLSD::Integer(gSavedSettings.getU32("RenderQualityPerformance")); // Steve: 1.21
  730. //  misc["int_2"] = LLSD::Integer(gFrameStalls); // Steve: 1.21
  731. F32 unbaked_time = LLVOAvatar::sUnbakedTime * 1000.f / gFrameTimeSeconds;
  732. misc["int_1"] = LLSD::Integer(unbaked_time); // Steve: 1.22
  733. F32 grey_time = LLVOAvatar::sGreyTime * 1000.f / gFrameTimeSeconds;
  734. misc["int_2"] = LLSD::Integer(grey_time); // Steve: 1.22
  735. llinfos << "Misc Stats: int_1: " << misc["int_1"] << " int_2: " << misc["int_2"] << llendl;
  736. llinfos << "Misc Stats: string_1: " << misc["string_1"] << " string_2: " << misc["string_2"] << llendl;
  737. LLViewerStats::getInstance()->addToMessage(body);
  738. LLHTTPClient::post(url, body, new ViewerStatsResponder());
  739. }