aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llviewerstats.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/newview/llviewerstats.cpp')
-rw-r--r--linden/indra/newview/llviewerstats.cpp449
1 files changed, 446 insertions, 3 deletions
diff --git a/linden/indra/newview/llviewerstats.cpp b/linden/indra/newview/llviewerstats.cpp
index 96f52a1..2b278c7 100644
--- a/linden/indra/newview/llviewerstats.cpp
+++ b/linden/indra/newview/llviewerstats.cpp
@@ -37,10 +37,29 @@
37#include "message.h" 37#include "message.h"
38#include "lltimer.h" 38#include "lltimer.h"
39 39
40LLViewerStats *gViewerStats = NULL; 40#include "llappviewer.h"
41
42#include "pipeline.h"
43#include "llviewerobjectlist.h"
44#include "llviewerimagelist.h"
45#include "lltexlayer.h"
46#include "llsurface.h"
47#include "llvlmanager.h"
48#include "llagent.h"
49#include "llviewercontrol.h"
50#include "llfloaterdirectory.h"
51#include "llfloatertools.h"
52#include "lldebugview.h"
53#include "llfasttimerview.h"
54#include "llviewerregion.h"
55#include "llfloaterhtmlhelp.h"
56#include "llworld.h"
57#include "llfeaturemanager.h"
58#if LL_WINDOWS && LL_LCD_COMPILE
59 #include "lllcd.h"
60#endif
41 61
42extern U32 gFrameCount; 62LLViewerStats *gViewerStats = NULL;
43extern LLTimer gRenderStartTime;
44 63
45class StatAttributes 64class StatAttributes
46{ 65{
@@ -323,3 +342,427 @@ const char *LLViewerStats::statTypeToText(EStatType type)
323 return "Unknown statistic"; 342 return "Unknown statistic";
324 } 343 }
325} 344}
345
346// *NOTE:Mani The following methods used to exist in viewer.cpp
347// Moving them here, but not merging them into LLViewerStats yet.
348void reset_statistics()
349{
350 gPipeline.resetFrameStats(); // Reset per-frame statistics.
351 if (LLSurface::sTextureUpdateTime)
352 {
353 LLSurface::sTexelsUpdatedPerSecStat.addValue(0.001f*(LLSurface::sTexelsUpdated / LLSurface::sTextureUpdateTime));
354 LLSurface::sTexelsUpdated = 0;
355 LLSurface::sTextureUpdateTime = 0.f;
356 }
357}
358
359
360void output_statistics(void*)
361{
362 llinfos << "Number of orphans: " << gObjectList.getOrphanCount() << llendl;
363 llinfos << "Number of dead objects: " << gObjectList.mNumDeadObjects << llendl;
364 llinfos << "Num images: " << gImageList.getNumImages() << llendl;
365 llinfos << "Texture usage: " << LLImageGL::sGlobalTextureMemory << llendl;
366 llinfos << "Texture working set: " << LLImageGL::sBoundTextureMemory << llendl;
367 llinfos << "Raw usage: " << LLImageRaw::sGlobalRawMemory << llendl;
368 llinfos << "Formatted usage: " << LLImageFormatted::sGlobalFormattedMemory << llendl;
369 llinfos << "Zombie Viewer Objects: " << LLViewerObject::getNumZombieObjects() << llendl;
370 llinfos << "Number of lights: " << gPipeline.getLightCount() << llendl;
371
372 llinfos << "Memory Usage:" << llendl;
373 llinfos << "--------------------------------" << llendl;
374 llinfos << "Pipeline:" << llendl;
375 llinfos << llendl;
376
377#if LL_SMARTHEAP
378 llinfos << "--------------------------------" << llendl;
379 {
380 llinfos << "sizeof(LLVOVolume) = " << sizeof(LLVOVolume) << llendl;
381
382 U32 total_pool_size = 0;
383 U32 total_used_size = 0;
384 MEM_POOL_INFO pool_info;
385 MEM_POOL_STATUS pool_status;
386 U32 pool_num = 0;
387 for(pool_status = MemPoolFirst( &pool_info, 1 );
388 pool_status != MEM_POOL_END;
389 pool_status = MemPoolNext( &pool_info, 1 ) )
390 {
391 llinfos << "Pool #" << pool_num << llendl;
392 if( MEM_POOL_OK != pool_status )
393 {
394 llwarns << "Pool not ok" << llendl;
395 continue;
396 }
397
398 llinfos << "Pool blockSizeFS " << pool_info.blockSizeFS
399 << " pageSize " << pool_info.pageSize
400 << llendl;
401
402 U32 pool_count = MemPoolCount(pool_info.pool);
403 llinfos << "Blocks " << pool_count << llendl;
404
405 U32 pool_size = MemPoolSize( pool_info.pool );
406 if( pool_size == MEM_ERROR_RET )
407 {
408 llinfos << "MemPoolSize() failed (" << pool_num << ")" << llendl;
409 }
410 else
411 {
412 llinfos << "MemPool Size " << pool_size / 1024 << "K" << llendl;
413 }
414
415 total_pool_size += pool_size;
416
417 if( !MemPoolLock( pool_info.pool ) )
418 {
419 llinfos << "MemPoolLock failed (" << pool_num << ") " << llendl;
420 continue;
421 }
422
423 U32 used_size = 0;
424 MEM_POOL_ENTRY entry;
425 entry.entry = NULL;
426 while( MemPoolWalk( pool_info.pool, &entry ) == MEM_POOL_OK )
427 {
428 if( entry.isInUse )
429 {
430 used_size += entry.size;
431 }
432 }
433
434 MemPoolUnlock( pool_info.pool );
435
436 llinfos << "MemPool Used " << used_size/1024 << "K" << llendl;
437 total_used_size += used_size;
438 pool_num++;
439 }
440
441 llinfos << "Total Pool Size " << total_pool_size/1024 << "K" << llendl;
442 llinfos << "Total Used Size " << total_used_size/1024 << "K" << llendl;
443
444 }
445#endif
446
447 llinfos << "--------------------------------" << llendl;
448 llinfos << "Avatar Memory (partly overlaps with above stats):" << llendl;
449 gTexStaticImageList.dumpByteCount();
450 LLVOAvatar::dumpScratchTextureByteCount();
451 LLTexLayerSetBuffer::dumpTotalByteCount();
452 LLVOAvatar::dumpTotalLocalTextureByteCount();
453 LLTexLayerParamAlpha::dumpCacheByteCount();
454 LLVOAvatar::dumpBakedStatus();
455
456 llinfos << llendl;
457
458 llinfos << "Object counts:" << llendl;
459 S32 i;
460 S32 obj_counts[256];
461// S32 app_angles[256];
462 for (i = 0; i < 256; i++)
463 {
464 obj_counts[i] = 0;
465 }
466 for (i = 0; i < gObjectList.getNumObjects(); i++)
467 {
468 LLViewerObject *objectp = gObjectList.getObject(i);
469 if (objectp)
470 {
471 obj_counts[objectp->getPCode()]++;
472 }
473 }
474 for (i = 0; i < 256; i++)
475 {
476 if (obj_counts[i])
477 {
478 llinfos << LLPrimitive::pCodeToString(i) << ":" << obj_counts[i] << llendl;
479 }
480 }
481}
482
483
484U32 gTotalLandIn = 0, gTotalLandOut = 0;
485U32 gTotalWaterIn = 0, gTotalWaterOut = 0;
486
487F32 gAveLandCompression = 0.f, gAveWaterCompression = 0.f;
488F32 gBestLandCompression = 1.f, gBestWaterCompression = 1.f;
489F32 gWorstLandCompression = 0.f, gWorstWaterCompression = 0.f;
490
491
492
493U32 gTotalWorldBytes = 0, gTotalObjectBytes = 0, gTotalTextureBytes = 0, gSimPingCount = 0;
494U32 gObjectBits = 0;
495F32 gAvgSimPing = 0.f;
496
497
498extern U32 gVisCompared;
499extern U32 gVisTested;
500
501std::map<S32,LLFrameTimer> gDebugTimers;
502
503void update_statistics(U32 frame_count)
504{
505 gTotalWorldBytes += gVLManager.getTotalBytes();
506 gTotalObjectBytes += gObjectBits / 8;
507 gTotalTextureBytes += LLViewerImageList::sTextureBits / 8;
508
509 // make sure we have a valid time delta for this frame
510 if (gFrameIntervalSeconds > 0.f)
511 {
512 if (gAgent.getCameraMode() == CAMERA_MODE_MOUSELOOK)
513 {
514 gViewerStats->incStat(LLViewerStats::ST_MOUSELOOK_SECONDS, gFrameIntervalSeconds);
515 }
516 else if (gAgent.getCameraMode() == CAMERA_MODE_CUSTOMIZE_AVATAR)
517 {
518 gViewerStats->incStat(LLViewerStats::ST_AVATAR_EDIT_SECONDS, gFrameIntervalSeconds);
519 }
520 else if (gFloaterTools && gFloaterTools->getVisible())
521 {
522 gViewerStats->incStat(LLViewerStats::ST_TOOLBOX_SECONDS, gFrameIntervalSeconds);
523 }
524 }
525 gViewerStats->setStat(LLViewerStats::ST_ENABLE_VBO, (F64)gSavedSettings.getBOOL("RenderVBOEnable"));
526 gViewerStats->setStat(LLViewerStats::ST_LIGHTING_DETAIL, (F64)gSavedSettings.getS32("RenderLightingDetail"));
527 gViewerStats->setStat(LLViewerStats::ST_DRAW_DIST, (F64)gSavedSettings.getF32("RenderFarClip"));
528 gViewerStats->setStat(LLViewerStats::ST_CHAT_BUBBLES, (F64)gSavedSettings.getBOOL("UseChatBubbles"));
529#if 0 // 1.9.2
530 gViewerStats->setStat(LLViewerStats::ST_SHADER_OBJECTS, (F64)gSavedSettings.getS32("VertexShaderLevelObject"));
531 gViewerStats->setStat(LLViewerStats::ST_SHADER_AVATAR, (F64)gSavedSettings.getBOOL("VertexShaderLevelAvatar"));
532 gViewerStats->setStat(LLViewerStats::ST_SHADER_ENVIRONMENT, (F64)gSavedSettings.getBOOL("VertexShaderLevelEnvironment"));
533#endif
534 gViewerStats->setStat(LLViewerStats::ST_FRAME_SECS, gDebugView->mFastTimerView->getTime(LLFastTimer::FTM_FRAME));
535 F64 idle_secs = gDebugView->mFastTimerView->getTime(LLFastTimer::FTM_IDLE);
536 F64 network_secs = gDebugView->mFastTimerView->getTime(LLFastTimer::FTM_NETWORK);
537 gViewerStats->setStat(LLViewerStats::ST_UPDATE_SECS, idle_secs - network_secs);
538 gViewerStats->setStat(LLViewerStats::ST_NETWORK_SECS, network_secs);
539 gViewerStats->setStat(LLViewerStats::ST_IMAGE_SECS, gDebugView->mFastTimerView->getTime(LLFastTimer::FTM_IMAGE_UPDATE));
540 gViewerStats->setStat(LLViewerStats::ST_REBUILD_SECS, gDebugView->mFastTimerView->getTime(LLFastTimer::FTM_REBUILD));
541 gViewerStats->setStat(LLViewerStats::ST_RENDER_SECS, gDebugView->mFastTimerView->getTime(LLFastTimer::FTM_RENDER_GEOMETRY));
542
543 LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(gAgent.getRegion()->getHost());
544 if (cdp)
545 {
546 gViewerStats->mSimPingStat.addValue(cdp->getPingDelay());
547 gAvgSimPing = ((gAvgSimPing * (F32)gSimPingCount) + (F32)(cdp->getPingDelay())) / ((F32)gSimPingCount + 1);
548 gSimPingCount++;
549 }
550 else
551 {
552 gViewerStats->mSimPingStat.addValue(10000);
553 }
554
555 gViewerStats->mFPSStat.addValue(1);
556 F32 layer_bits = (F32)(gVLManager.getLandBits() + gVLManager.getWindBits() + gVLManager.getCloudBits());
557 gViewerStats->mLayersKBitStat.addValue(layer_bits/1024.f);
558 gViewerStats->mObjectKBitStat.addValue(gObjectBits/1024.f);
559 gViewerStats->mTextureKBitStat.addValue(LLViewerImageList::sTextureBits/1024.f);
560 gViewerStats->mVFSPendingOperations.addValue(LLVFile::getVFSThread()->getPending());
561 gViewerStats->mAssetKBitStat.addValue(gTransferManager.getTransferBitsIn(LLTCT_ASSET)/1024.f);
562 gTransferManager.resetTransferBitsIn(LLTCT_ASSET);
563
564 static S32 tex_bits_idle_count = 0;
565 if (LLViewerImageList::sTextureBits == 0)
566 {
567 if (++tex_bits_idle_count >= 30)
568 gDebugTimers[0].pause();
569 }
570 else
571 {
572 tex_bits_idle_count = 0;
573 gDebugTimers[0].unpause();
574 }
575
576 gViewerStats->mTexturePacketsStat.addValue(LLViewerImageList::sTexturePackets);
577
578 // log when the LibXUL (aka Mozilla) widget is used and opened so we can monitor framerate changes
579 #if LL_LIBXUL_ENABLED
580 {
581 BOOL result = gViewerHtmlHelp.getFloaterOpened();
582 gViewerStats->setStat(LLViewerStats::ST_LIBXUL_WIDGET_USED, (F64)result);
583 }
584 #endif
585
586 {
587 static F32 visible_avatar_frames = 0.f;
588 static F32 avg_visible_avatars = 0;
589 F32 visible_avatars = (F32)LLVOAvatar::sNumVisibleAvatars;
590 if (visible_avatars > 0.f)
591 {
592 visible_avatar_frames = 1.f;
593 avg_visible_avatars = (avg_visible_avatars * (F32)(visible_avatar_frames - 1.f) + visible_avatars) / visible_avatar_frames;
594 }
595 gViewerStats->setStat(LLViewerStats::ST_VISIBLE_AVATARS, (F64)avg_visible_avatars);
596 }
597 gWorldp->updateNetStats();
598 gWorldp->requestCacheMisses();
599
600 // Reset all of these values.
601 gVLManager.resetBitCounts();
602 gObjectBits = 0;
603// gDecodedBits = 0;
604
605 LLViewerImageList::sTextureBits = 0;
606 LLViewerImageList::sTexturePackets = 0;
607
608#if LL_WINDOWS && LL_LCD_COMPILE
609 bool LCDenabled = gLcdScreen->Enabled();
610 gViewerStats->setStat(LLViewerStats::ST_LOGITECH_LCD, LCDenabled);
611#else
612 gViewerStats->setStat(LLViewerStats::ST_LOGITECH_LCD, false);
613#endif
614}
615
616class ViewerStatsResponder : public LLHTTPClient::Responder
617{
618public:
619 ViewerStatsResponder() { }
620
621 void error(U32 statusNum, const std::string& reason)
622 {
623 llinfos << "ViewerStatsResponder::error " << statusNum << " "
624 << reason << llendl;
625 }
626
627 void result(const LLSD& content)
628 {
629 llinfos << "ViewerStatsResponder::result" << llendl;
630 }
631};
632
633/*
634 * The sim-side LLSD is in newsim/llagentinfo.cpp:forwardViewerStats.
635 *
636 * There's also a compatibility shim for the old fixed-format sim
637 * stats in newsim/llagentinfo.cpp:processViewerStats.
638 *
639 * If you move stats around here, make the corresponding changes in
640 * those locations, too.
641 */
642void send_stats()
643{
644 // IW 9/23/02 I elected not to move this into LLViewerStats
645 // because it depends on too many viewer.cpp globals.
646 // Someday we may want to merge all our stats into a central place
647 // but that day is not today.
648
649 // Only send stats if the agent is connected to a region.
650 if (!gAgent.getRegion() || gNoRender)
651 {
652 return;
653 }
654
655 LLSD body;
656 std::string url = gAgent.getRegion()->getCapability("ViewerStats");
657
658 if (url.empty()) {
659 llwarns << "Could not get ViewerStats capability" << llendl;
660 return;
661 }
662
663 body["session_id"] = gAgentSessionID;
664
665 LLSD &agent = body["agent"];
666
667 time_t ltime;
668 time(&ltime);
669 F32 run_time = F32(LLFrameTimer::getElapsedSeconds());
670
671 agent["start_time"] = ltime - run_time;
672
673 // The first stat set must have a 0 run time if it doesn't actually
674 // contain useful data in terms of FPS, etc. We use half the
675 // SEND_STATS_PERIOD seconds as the point at which these statistics become
676 // valid. Data warehouse uses a 0 value here to easily discard these
677 // records with non-useful FPS values etc.
678 if (run_time < (SEND_STATS_PERIOD / 2))
679 {
680 agent["run_time"] = 0.0f;
681 }
682 else
683 {
684 agent["run_time"] = run_time;
685 }
686
687 // send fps only for time app spends in foreground
688 agent["fps"] = (F32)gForegroundFrameCount / gForegroundTime.getElapsedTimeF32();
689 agent["version"] = gCurrentVersion;
690 LLString language(gSavedSettings.getString("Language"));
691 if(language == "default") language = gSavedSettings.getString("SystemLanguage");
692 agent["language"] = language;
693
694 agent["sim_fps"] = ((F32) gFrameCount - gSimFrames) /
695 (F32) (gRenderStartTime.getElapsedTimeF32() - gSimLastTime);
696
697 gSimLastTime = gRenderStartTime.getElapsedTimeF32();
698 gSimFrames = (F32) gFrameCount;
699
700 agent["agents_in_view"] = LLVOAvatar::sNumVisibleAvatars;
701 agent["ping"] = gAvgSimPing;
702 agent["meters_traveled"] = gAgent.getDistanceTraveled();
703 agent["regions_visited"] = gAgent.getRegionsVisited();
704 agent["mem_use"] = getCurrentRSS() / 1024.0;
705
706 LLSD &system = body["system"];
707
708 system["ram"] = (S32) gSysMemory.getPhysicalMemoryKB();
709 system["os"] = LLAppViewer::instance()->getOSInfo().getOSStringSimple();
710 system["cpu"] = gSysCPU.getCPUString();
711
712 std::string gpu_desc = llformat(
713 "%-6s Class %d ",
714 gGLManager.mGLVendorShort.substr(0,6).c_str(),
715 gFeatureManagerp->getGPUClass())
716 + gFeatureManagerp->getGPUString();
717
718 system["gpu"] = gpu_desc;
719 system["gpu_class"] = gFeatureManagerp->getGPUClass();
720 system["gpu_vendor"] = gGLManager.mGLVendorShort;
721 system["gpu_version"] = gGLManager.mDriverVersionVendorString;
722
723 LLSD &download = body["downloads"];
724
725 download["world_kbytes"] = gTotalWorldBytes / 1024.0;
726 download["object_kbytes"] = gTotalObjectBytes / 1024.0;
727 download["texture_kbytes"] = gTotalTextureBytes / 1024.0;
728
729 LLSD &in = body["stats"]["net"]["in"];
730
731 in["kbytes"] = gMessageSystem->mTotalBytesIn / 1024.0;
732 in["packets"] = (S32) gMessageSystem->mPacketsIn;
733 in["compressed_packets"] = (S32) gMessageSystem->mCompressedPacketsIn;
734 in["savings"] = (gMessageSystem->mUncompressedBytesIn -
735 gMessageSystem->mCompressedBytesIn) / 1024.0;
736
737 LLSD &out = body["stats"]["net"]["out"];
738
739 out["kbytes"] = gMessageSystem->mTotalBytesOut / 1024.0;
740 out["packets"] = (S32) gMessageSystem->mPacketsOut;
741 out["compressed_packets"] = (S32) gMessageSystem->mCompressedPacketsOut;
742 out["savings"] = (gMessageSystem->mUncompressedBytesOut -
743 gMessageSystem->mCompressedBytesOut) / 1024.0;
744
745 LLSD &fail = body["stats"]["failures"];
746
747 fail["send_packet"] = (S32) gMessageSystem->mSendPacketFailureCount;
748 fail["dropped"] = (S32) gMessageSystem->mDroppedPackets;
749 fail["resent"] = (S32) gMessageSystem->mResentPackets;
750 fail["failed_resends"] = (S32) gMessageSystem->mFailedResendPackets;
751 fail["off_circuit"] = (S32) gMessageSystem->mOffCircuitPackets;
752 fail["invalid"] = (S32) gMessageSystem->mInvalidOnCircuitPackets;
753
754 // Misc stats, two strings and two ints
755 // These are not expecticed to persist across multiple releases
756 // Comment any changes with your name and the expected release revision
757 // If the current revision is recent, ping the previous author before overriding
758 LLSD &misc = body["stats"]["misc"];
759
760 // misc["string_1"] =
761 // misc["string_2"] =
762 misc["int_1"] = LLFloaterDirectory::sOldSearchCount; // Steve: 1.18.6
763 misc["int_2"] = LLFloaterDirectory::sNewSearchCount; // Steve: 1.18.6
764
765 gViewerStats->addToMessage(body);
766
767 LLHTTPClient::post(url, body, new ViewerStatsResponder());
768}