summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorsimon <simon@lindenlab.com>2023-05-04 16:52:35 +0100
committersimon <simon@lindenlab.com>2023-05-04 16:52:35 +0100
commite8c1a18105bddc29951d4c4b1700dc0af37c83c2 (patch)
treee9c50905806989dbca456a49c33875536ef5ad7e /indra
parent7ed52090a67882cd0bc904f1e0a9ce07cf6768e9 (diff)
First work on sl-19676 - Stats on updates
Diffstat (limited to 'indra')
-rw-r--r--indra/newview/app_settings/settings.xml33
-rw-r--r--indra/newview/llappviewer.cpp7
-rw-r--r--indra/newview/llfloater360capture.cpp18
-rw-r--r--indra/newview/lltexturefetch.cpp5
-rw-r--r--indra/newview/llviewermenu.cpp143
-rw-r--r--indra/newview/llviewerobjectlist.cpp42
-rwxr-xr-xindra/newview/llviewerregion.cpp17
-rw-r--r--indra/newview/llviewerregion.h12
-rw-r--r--indra/newview/llviewerstatsrecorder.cpp267
-rw-r--r--indra/newview/llviewerstatsrecorder.h117
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml24
11 files changed, 409 insertions, 276 deletions
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 9fffab70f4..3d1a384793 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -17085,5 +17085,38 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>StatsReportMaxDuration</key>
+ <map>
+ <key>Comment</key>
+ <string>Maximum seconds for viewer stats file data, prevents huge file</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>300</real>
+ </map>
+ <key>StatsReportFileInterval</key>
+ <map>
+ <key>Comment</key>
+ <string>Interval to save viewer stats file data</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>0.2</real>
+ </map>
+ <key>StatsReportSkipZeroDataSaves</key>
+ <map>
+ <key>Comment</key>
+ <string>In viewer stats data file, skip saving entry if there is no data</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
</map>
</llsd>
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 8d77a39c74..9c194562f9 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -1536,7 +1536,12 @@ bool LLAppViewer::doFrame()
LLFloaterSimpleOutfitSnapshot::update();
gGLActive = FALSE;
}
- }
+
+ if (LLViewerStatsRecorder::instanceExists())
+ {
+ LLViewerStatsRecorder::instance().idle();
+ }
+ }
}
{
diff --git a/indra/newview/llfloater360capture.cpp b/indra/newview/llfloater360capture.cpp
index 23f86e2361..9c25cdbc7d 100644
--- a/indra/newview/llfloater360capture.cpp
+++ b/indra/newview/llfloater360capture.cpp
@@ -197,21 +197,18 @@ void LLFloater360Capture::changeInterestListMode(bool send_everything)
if (gAgent.requestPostCapability("InterestList", body, [](const LLSD & response)
{
- LL_INFOS("360Capture") <<
- "InterestList capability responded: \n" <<
+ LL_DEBUGS("360Capture") << "InterestList capability responded: \n" <<
ll_pretty_print_sd(response) <<
LL_ENDL;
}))
{
- LL_INFOS("360Capture") <<
- "Successfully posted an InterestList capability request with payload: \n" <<
+ LL_DEBUGS("360Capture") << "Successfully posted an InterestList capability request with payload: \n" <<
ll_pretty_print_sd(body) <<
LL_ENDL;
}
else
{
- LL_INFOS("360Capture") <<
- "Unable to post an InterestList capability request with payload: \n" <<
+ LL_WARNS("360Capture") << "Unable to post an InterestList capability request with payload: \n" <<
ll_pretty_print_sd(body) <<
LL_ENDL;
}
@@ -632,11 +629,8 @@ void LLFloater360Capture::capture360Images()
// display time to encode all 6 images. It tends to be a fairly linear
// time for each so we don't need to worry about displaying the time
// for each - this gives us plenty to use for optimizing
- LL_INFOS("360Capture") <<
- "Time to encode and save 6 images was " <<
- encode_time_total <<
- " seconds" <<
- LL_ENDL;
+ LL_INFOS("360Capture") << "Time to encode and save 6 images was " <<
+ encode_time_total << " seconds" << LL_ENDL;
// Write the JavaScript file footer (the bottom of the file after the
// declarations of the actual data URLs array). The footer comprises of
@@ -668,7 +662,7 @@ void LLFloater360Capture::capture360Images()
// as a change - only the subsequent 5 are
if (camera_changed_times < 5)
{
- LL_INFOS("360Capture") << "Warning: we only captured " << camera_changed_times << " images." << LL_ENDL;
+ LL_WARNS("360Capture") << "360 image capture expected 5 or more images, only captured " << camera_changed_times << " images." << LL_ENDL;
}
// now we have the 6 shots saved in a well specified location,
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index a7dcb1a9bb..b0d6a5d466 100644
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -2258,11 +2258,6 @@ S32 LLTextureFetchWorker::callbackHttpGet(LLCore::HttpResponse * response,
mLoaded = TRUE;
setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
- if (LLViewerStatsRecorder::instanceExists())
- {
- // Do not create this instance inside thread
- LLViewerStatsRecorder::instance().log(0.2f);
- }
return data_size ;
}
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 998f5c020e..77cb5f86af 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -119,6 +119,7 @@
#include "llviewerobjectlist.h"
#include "llviewerparcelmgr.h"
#include "llviewerstats.h"
+#include "llviewerstatsrecorder.h"
#include "llvoavatarself.h"
#include "llvoicevivox.h"
#include "llworldmap.h"
@@ -1295,49 +1296,99 @@ class LLAdvancedDumpRegionObjectCache : public view_listener_t
}
};
-class LLAdvancedInterestListFullUpdate : public view_listener_t
+class LLAdvancedToggleInterestList360Mode : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- LLSD request;
- LLSD body;
- static bool using_360 = false;
-
- if (using_360)
- {
- body["mode"] = LLSD::String("default");
- }
- else
- {
- body["mode"] = LLSD::String("360");
- }
- using_360 = !using_360;
+public:
+ bool handleEvent(const LLSD &userdata)
+ {
+ LLSD request;
+ LLSD body;
+
+ // First do a GET to report on current mode and update stats
+ if (gAgent.requestGetCapability("InterestList",
+ [](const LLSD &response) {
+ LL_DEBUGS("360Capture") << "InterestList capability GET responded: \n"
+ << ll_pretty_print_sd(response) << LL_ENDL;
+ }))
+ {
+ LL_DEBUGS("360Capture") << "Successful GET InterestList capability request with return body: \n"
+ << ll_pretty_print_sd(body) << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS("360Capture") << "Unable to GET InterestList capability request with return body: \n"
+ << ll_pretty_print_sd(body) << LL_ENDL;
+ }
- if (gAgent.requestPostCapability("InterestList", body, [](const LLSD& response)
+ // Now do a POST to change the mode
+ if (sUsing360)
{
- LL_INFOS("360Capture") <<
- "InterestList capability responded: \n" <<
- ll_pretty_print_sd(response) <<
- LL_ENDL;
- }))
+ body["mode"] = LLSD::String("default");
+ }
+ else
{
- LL_INFOS("360Capture") <<
- "Successfully posted an InterestList capability request with payload: \n" <<
- ll_pretty_print_sd(body) <<
- LL_ENDL;
+ body["mode"] = LLSD::String("360");
+ }
+ sUsing360 = !sUsing360;
+ LL_INFOS("360Capture") << "Setting InterestList capability mode to " << body["mode"].asString() << LL_ENDL;
+
+ if (gAgent.requestPostCapability("InterestList", body,
+ [](const LLSD &response) {
+ LL_DEBUGS("360Capture") << "InterestList capability responded: \n"
+ << ll_pretty_print_sd(response) << LL_ENDL;
+ }))
+ {
+ LL_DEBUGS("360Capture") << "Successfully posted an InterestList capability request with payload: \n"
+ << ll_pretty_print_sd(body) << LL_ENDL;
return true;
}
else
{
- LL_INFOS("360Capture") <<
- "Unable to post an InterestList capability request with payload: \n" <<
- ll_pretty_print_sd(body) <<
- LL_ENDL;
+ LL_DEBUGS("360Capture") << "Unable to post an InterestList capability request with payload: \n"
+ << ll_pretty_print_sd(body) << LL_ENDL;
return false;
}
+ };
+
+ static bool sUsing360;
+};
+
+bool LLAdvancedToggleInterestList360Mode::sUsing360 = false;
+
+class LLAdvancedCheckInterestList360Mode : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ return LLAdvancedToggleInterestList360Mode::sUsing360;
}
};
+class LLAdvancedToggleStatsRecorder : public view_listener_t
+{
+ bool handleEvent(const LLSD &userdata)
+ {
+ if (LLViewerStatsRecorder::instance().isEnabled())
+ { // Turn off both recording and logging
+ LLViewerStatsRecorder::instance().enableObjectStatsRecording(false);
+ }
+ else
+ { // Turn on both recording and logging
+ LLViewerStatsRecorder::instance().enableObjectStatsRecording(true, true);
+ }
+ return true;
+ }
+};
+
+class LLAdvancedCheckStatsRecorder : public view_listener_t
+{
+ bool handleEvent(const LLSD &userdata)
+ { // Use the logging state as the indicator of whether the stats recorder is on
+ return LLViewerStatsRecorder::instance().isLogging();
+ }
+};
+
+
+
class LLAdvancedBuyCurrencyTest : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -4492,33 +4543,6 @@ void handle_duplicate_in_place(void*)
LLSelectMgr::getInstance()->selectDuplicate(offset, TRUE);
}
-/* dead code 30-apr-2008
-void handle_deed_object_to_group(void*)
-{
- LLUUID group_id;
-
- LLSelectMgr::getInstance()->selectGetGroup(group_id);
- LLSelectMgr::getInstance()->sendOwner(LLUUID::null, group_id, FALSE);
- LLViewerStats::getInstance()->incStat(LLViewerStats::ST_RELEASE_COUNT);
-}
-
-BOOL enable_deed_object_to_group(void*)
-{
- if(LLSelectMgr::getInstance()->getSelection()->isEmpty()) return FALSE;
- LLPermissions perm;
- LLUUID group_id;
-
- if (LLSelectMgr::getInstance()->selectGetGroup(group_id) &&
- gAgent.hasPowerInGroup(group_id, GP_OBJECT_DEED) &&
- LLSelectMgr::getInstance()->selectGetPermissions(perm) &&
- perm.deedToGroup(gAgent.getID(), group_id))
- {
- return TRUE;
- }
- return FALSE;
-}
-
-*/
/*
@@ -9448,7 +9472,10 @@ void initialize_menus()
// Advanced > World
view_listener_t::addMenu(new LLAdvancedDumpScriptedCamera(), "Advanced.DumpScriptedCamera");
view_listener_t::addMenu(new LLAdvancedDumpRegionObjectCache(), "Advanced.DumpRegionObjectCache");
- view_listener_t::addMenu(new LLAdvancedInterestListFullUpdate(), "Advanced.InterestListFullUpdate");
+ view_listener_t::addMenu(new LLAdvancedToggleInterestList360Mode(), "Advanced.ToggleInterestList360Mode");
+ view_listener_t::addMenu(new LLAdvancedCheckInterestList360Mode(), "Advanced.CheckInterestList360Mode");
+ view_listener_t::addMenu(new LLAdvancedToggleStatsRecorder(), "Advanced.ToggleStatsRecorder");
+ view_listener_t::addMenu(new LLAdvancedCheckStatsRecorder(), "Advanced.CheckStatsRecorder");
// Advanced > UI
commit.add("Advanced.WebBrowserTest", boost::bind(&handle_web_browser_test, _2)); // sigh! this one opens the MEDIA browser
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index efc4ded79e..0c9e929cf3 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -369,7 +369,7 @@ LLViewerObject* LLViewerObjectList::processObjectUpdateFromCache(LLVOCacheEntry*
if (!objectp)
{
LL_INFOS() << "createObject failure for object: " << fullid << LL_ENDL;
- recorder.objectUpdateFailure(entry->getLocalID(), OUT_FULL_CACHED, 0);
+ recorder.objectUpdateFailure(0);
return NULL;
}
justCreated = true;
@@ -393,7 +393,6 @@ LLViewerObject* LLViewerObjectList::processObjectUpdateFromCache(LLVOCacheEntry*
objectp->setLastUpdateType(OUT_FULL_COMPRESSED); //newly cached
objectp->setLastUpdateCached(TRUE);
}
- recorder.log(0.2f);
LLVOAvatar::cullAvatarsByPixelArea();
return objectp;
@@ -472,18 +471,15 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
for (i = 0; i < num_objects; i++)
{
- // timer is unused?
- LLTimer update_timer;
BOOL justCreated = FALSE;
S32 msg_size = 0;
bool update_cache = false; //update object cache if it is a full-update or terse update
if (compressed)
{
- S32 uncompressed_length = 2048;
compressed_dp.reset();
- uncompressed_length = mesgsys->getSizeFast(_PREHASH_ObjectData, i, _PREHASH_Data);
+ S32 uncompressed_length = mesgsys->getSizeFast(_PREHASH_ObjectData, i, _PREHASH_Data);
LL_DEBUGS("ObjectUpdate") << "got binary data from message to compressed_dpbuffer" << LL_ENDL;
mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_Data, compressed_dpbuffer, 0, i, 2048);
compressed_dp.assignBuffer(compressed_dpbuffer, uncompressed_length);
@@ -505,7 +501,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
<< " Flags: " << flags
<< " Region: " << regionp->getName()
<< " Region id: " << regionp->getRegionID() << LL_ENDL;
- recorder.objectUpdateFailure(local_id, update_type, msg_size);
+ recorder.objectUpdateFailure(msg_size);
continue;
}
else if ((flags & FLAGS_TEMPORARY_ON_REZ) == 0)
@@ -616,7 +612,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
if (update_type == OUT_TERSE_IMPROVED)
{
// LL_INFOS() << "terse update for an unknown object (compressed):" << fullid << LL_ENDL;
- recorder.objectUpdateFailure(local_id, update_type, msg_size);
+ recorder.objectUpdateFailure(msg_size);
continue;
}
}
@@ -625,7 +621,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
if (update_type != OUT_FULL)
{
//LL_INFOS() << "terse update for an unknown object:" << fullid << LL_ENDL;
- recorder.objectUpdateFailure(local_id, update_type, msg_size);
+ recorder.objectUpdateFailure(msg_size);
continue;
}
@@ -638,7 +634,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
{
mNumDeadObjectUpdates++;
//LL_INFOS() << "update for a dead object:" << fullid << LL_ENDL;
- recorder.objectUpdateFailure(local_id, update_type, msg_size);
+ recorder.objectUpdateFailure(msg_size);
continue;
}
#endif
@@ -651,7 +647,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
if (!objectp)
{
LL_INFOS() << "createObject failure for object: " << fullid << LL_ENDL;
- recorder.objectUpdateFailure(local_id, update_type, msg_size);
+ recorder.objectUpdateFailure(msg_size);
continue;
}
@@ -681,11 +677,11 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
if(!(flags & FLAGS_TEMPORARY_ON_REZ))
{
- bCached = true;
+ bCached = true;
LLViewerRegion::eCacheUpdateResult result = objectp->mRegionp->cacheFullUpdate(objectp, compressed_dp, flags);
- recorder.cacheFullUpdate(local_id, update_type, result, objectp, msg_size);
+ recorder.cacheFullUpdate(result);
+ }
}
- }
#endif
}
else
@@ -696,12 +692,10 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
}
processUpdateCore(objectp, user_data, i, update_type, NULL, justCreated);
}
- recorder.objectUpdateEvent(local_id, update_type, objectp, msg_size);
+ recorder.objectUpdateEvent(update_type);
objectp->setLastUpdateType(update_type);
}
- recorder.log(0.2f);
-
LLVOAvatar::cullAvatarsByPixelArea();
}
@@ -748,14 +742,14 @@ void LLViewerObjectList::processCachedObjectUpdate(LLMessageSystem *mesgsys,
// Lookup data packer and add this id to cache miss lists if necessary.
U8 cache_miss_type = LLViewerRegion::CACHE_MISS_TYPE_NONE;
- if(!regionp->probeCache(id, crc, flags, cache_miss_type))
- {
- // Cache Miss.
+ if (regionp->probeCache(id, crc, flags, cache_miss_type))
+ { // Cache Hit
+ recorder.cacheHitEvent();
+ }
+ else
+ { // Cache Miss
LL_DEBUGS("ObjectUpdate") << "cache miss for id " << id << " crc " << crc << " miss type " << (S32) cache_miss_type << LL_ENDL;
-
- recorder.cacheMissEvent(id, update_type, cache_miss_type, msg_size);
-
- continue; // no data packer, skip this object
+ recorder.cacheMissEvent(cache_miss_type);
}
}
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index ad7321ca4b..3d1a81694a 100755
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -2618,14 +2618,10 @@ LLVOCacheEntry* LLViewerRegion::getCacheEntry(U32 local_id, bool valid)
return NULL;
}
-void LLViewerRegion::addCacheMiss(U32 id, LLViewerRegion::eCacheMissType miss_type)
+void LLViewerRegion::addCacheMiss(U32 id, LLViewerRegion::eCacheMissType cache_miss_type)
{
mRegionCacheMissCount++;
-#if 0
- mCacheMissList.insert(CacheMissItem(id, miss_type));
-#else
- mCacheMissList.push_back(CacheMissItem(id, miss_type));
-#endif
+ mCacheMissList.push_back(CacheMissItem(id, cache_miss_type));
}
//check if a non-cacheable object is already created.
@@ -2701,10 +2697,10 @@ bool LLViewerRegion::probeCache(U32 local_id, U32 crc, U32 flags, U8 &cache_miss
}
}
else
- {
+ { // Total miss, don't have the object in cache
// LL_INFOS() << "Cache miss for " << local_id << LL_ENDL;
- addCacheMiss(local_id, CACHE_MISS_TYPE_FULL);
- cache_miss_type = CACHE_MISS_TYPE_FULL;
+ addCacheMiss(local_id, CACHE_MISS_TYPE_TOTAL);
+ cache_miss_type = CACHE_MISS_TYPE_TOTAL;
}
return false;
@@ -2712,7 +2708,7 @@ bool LLViewerRegion::probeCache(U32 local_id, U32 crc, U32 flags, U8 &cache_miss
void LLViewerRegion::addCacheMissFull(const U32 local_id)
{
- addCacheMiss(local_id, CACHE_MISS_TYPE_FULL);
+ addCacheMiss(local_id, CACHE_MISS_TYPE_TOTAL);
}
void LLViewerRegion::requestCacheMisses()
@@ -2763,7 +2759,6 @@ void LLViewerRegion::requestCacheMisses()
mCacheDirty = TRUE ;
// LL_INFOS() << "KILLDEBUG Sent cache miss full " << full_count << " crc " << crc_count << LL_ENDL;
LLViewerStatsRecorder::instance().requestCacheMissesEvent(mCacheMissList.size());
- LLViewerStatsRecorder::instance().log(0.2f);
mCacheMissList.clear();
}
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index 6548e8d372..81371b7f30 100644
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -332,9 +332,9 @@ public:
typedef enum
{
- CACHE_MISS_TYPE_FULL = 0,
- CACHE_MISS_TYPE_CRC,
- CACHE_MISS_TYPE_NONE
+ CACHE_MISS_TYPE_TOTAL = 0, // total cache miss - object not in cache
+ CACHE_MISS_TYPE_CRC, // object in cache, but CRC doesn't match
+ CACHE_MISS_TYPE_NONE // not a miss: cache hit
} eCacheMissType;
typedef enum
@@ -551,10 +551,10 @@ private:
class CacheMissItem
{
public:
- CacheMissItem(U32 id, LLViewerRegion::eCacheMissType miss_type) : mID(id), mType(miss_type){}
+ CacheMissItem(U32 id, LLViewerRegion::eCacheMissType miss_type) : mID(id), mType(miss_type) {}
- U32 mID; //local object id
- LLViewerRegion::eCacheMissType mType; //cache miss type
+ U32 mID; //local object id
+ LLViewerRegion::eCacheMissType mType; // cache miss type
typedef std::list<CacheMissItem> cache_miss_list_t;
};
diff --git a/indra/newview/llviewerstatsrecorder.cpp b/indra/newview/llviewerstatsrecorder.cpp
index b5ccf4ffa0..64167135ac 100644
--- a/indra/newview/llviewerstatsrecorder.cpp
+++ b/indra/newview/llviewerstatsrecorder.cpp
@@ -28,24 +28,25 @@
#include "llviewerstatsrecorder.h"
+#include "llcontrol.h"
#include "llfile.h"
#include "llviewerregion.h"
#include "llviewerobject.h"
+#include "llworld.h"
-
-// To do - something using region name or global position
-#if LL_WINDOWS
- static const std::string STATS_FILE_NAME("C:\\ViewerObjectCacheStats.csv");
-#else
- static const std::string STATS_FILE_NAME("/tmp/viewerstats.csv");
-#endif
+extern LLControlGroup gSavedSettings;
LLViewerStatsRecorder* LLViewerStatsRecorder::sInstance = NULL;
LLViewerStatsRecorder::LLViewerStatsRecorder() :
- mObjectCacheFile(NULL),
+ mStatsFile(NULL),
mTimer(),
- mStartTime(0.0),
- mLastSnapshotTime(0.0)
+ mFileOpenTime(0.0),
+ mLastSnapshotTime(0.0),
+ mEnableStatsRecording(false),
+ mEnableStatsLogging(false),
+ mInterval(0.2),
+ mMaxDuration(300.f),
+ mSkipSaveIfZeros(false)
{
if (NULL != sInstance)
{
@@ -57,30 +58,22 @@ LLViewerStatsRecorder::LLViewerStatsRecorder() :
LLViewerStatsRecorder::~LLViewerStatsRecorder()
{
- if (mObjectCacheFile != NULL)
+ if (mStatsFile)
{
- // last chance snapshot
- writeToLog(0.f);
- LLFile::close(mObjectCacheFile);
- mObjectCacheFile = NULL;
+ writeToLog(0.f); // Save last data
+ closeStatsFile();
}
}
void LLViewerStatsRecorder::clearStats()
{
mObjectCacheHitCount = 0;
- mObjectCacheHitSize = 0;
mObjectCacheMissFullCount = 0;
- mObjectCacheMissFullSize = 0;
mObjectCacheMissCrcCount = 0;
- mObjectCacheMissCrcSize = 0;
mObjectFullUpdates = 0;
- mObjectFullUpdatesSize = 0;
mObjectTerseUpdates = 0;
- mObjectTerseUpdatesSize = 0;
mObjectCacheMissRequests = 0;
mObjectCacheMissResponses = 0;
- mObjectCacheMissResponsesSize = 0;
mObjectCacheUpdateDupes = 0;
mObjectCacheUpdateChanges = 0;
mObjectCacheUpdateAdds = 0;
@@ -91,45 +84,57 @@ void LLViewerStatsRecorder::clearStats()
}
-void LLViewerStatsRecorder::recordObjectUpdateFailure(U32 local_id, const EObjectUpdateType update_type, S32 msg_size)
+void LLViewerStatsRecorder::enableObjectStatsRecording(bool enable, bool logging /* false */)
+{
+ mEnableStatsRecording = enable;
+
+ // if logging is stopping, close the file
+ if (mStatsFile && !logging)
+ {
+ writeToLog(0.f); // Save last data
+ closeStatsFile();
+ }
+ mEnableStatsLogging = logging;
+}
+
+
+
+void LLViewerStatsRecorder::recordObjectUpdateFailure(S32 msg_size)
{
mObjectUpdateFailures++;
mObjectUpdateFailuresSize += msg_size;
}
-void LLViewerStatsRecorder::recordCacheMissEvent(U32 local_id, const EObjectUpdateType update_type, U8 cache_miss_type, S32 msg_size)
+void LLViewerStatsRecorder::recordCacheMissEvent(U8 cache_miss_type)
{
- if (LLViewerRegion::CACHE_MISS_TYPE_FULL == cache_miss_type)
+ if (LLViewerRegion::CACHE_MISS_TYPE_TOTAL == cache_miss_type)
{
mObjectCacheMissFullCount++;
- mObjectCacheMissFullSize += msg_size;
}
else
{
mObjectCacheMissCrcCount++;
- mObjectCacheMissCrcSize += msg_size;
}
}
-void LLViewerStatsRecorder::recordObjectUpdateEvent(U32 local_id, const EObjectUpdateType update_type, LLViewerObject * objectp, S32 msg_size)
+
+void LLViewerStatsRecorder::recordCacheHitEvent()
+{
+ mObjectCacheHitCount++;
+}
+
+void LLViewerStatsRecorder::recordObjectUpdateEvent(const EObjectUpdateType update_type)
{
- switch (update_type)
+ switch (update_type)
{
case OUT_FULL:
mObjectFullUpdates++;
- mObjectFullUpdatesSize += msg_size;
break;
case OUT_TERSE_IMPROVED:
mObjectTerseUpdates++;
- mObjectTerseUpdatesSize += msg_size;
break;
case OUT_FULL_COMPRESSED:
mObjectCacheMissResponses++;
- mObjectCacheMissResponsesSize += msg_size;
- break;
- case OUT_FULL_CACHED:
- mObjectCacheHitCount++;
- mObjectCacheHitSize += msg_size;
break;
default:
LL_WARNS() << "Unknown update_type" << LL_ENDL;
@@ -137,9 +142,9 @@ void LLViewerStatsRecorder::recordObjectUpdateEvent(U32 local_id, const EObjectU
};
}
-void LLViewerStatsRecorder::recordCacheFullUpdate(U32 local_id, const EObjectUpdateType update_type, LLViewerRegion::eCacheUpdateResult update_result, LLViewerObject* objectp, S32 msg_size)
+void LLViewerStatsRecorder::recordCacheFullUpdate(LLViewerRegion::eCacheUpdateResult update_result)
{
- switch (update_result)
+ switch (update_result)
{
case LLViewerRegion::CACHE_UPDATE_DUPE:
mObjectCacheUpdateDupes++;
@@ -154,7 +159,7 @@ void LLViewerStatsRecorder::recordCacheFullUpdate(U32 local_id, const EObjectUpd
mObjectCacheUpdateReplacements++;
break;
default:
- LL_WARNS() << "Unknown update_result type" << LL_ENDL;
+ LL_WARNS() << "Unknown update_result type " << (S32) update_result << LL_ENDL;
break;
};
}
@@ -166,14 +171,30 @@ void LLViewerStatsRecorder::recordRequestCacheMissesEvent(S32 count)
void LLViewerStatsRecorder::writeToLog( F32 interval )
{
+ if (!mEnableStatsLogging || !mEnableStatsRecording)
+ {
+ return;
+ }
+
size_t data_size = 0;
- F64 delta_time = LLTimer::getTotalSeconds() - mLastSnapshotTime;
- S32 total_objects = mObjectCacheHitCount + mObjectCacheMissCrcCount + mObjectCacheMissFullCount + mObjectFullUpdates + mObjectTerseUpdates + mObjectCacheMissRequests + mObjectCacheMissResponses + mObjectCacheUpdateDupes + mObjectCacheUpdateChanges + mObjectCacheUpdateAdds + mObjectCacheUpdateReplacements + mObjectUpdateFailures;
+ F64 delta_time = LLFrameTimer::getTotalSeconds() - mLastSnapshotTime;
+ if (delta_time < interval)
+ return;
- if ( delta_time < interval || total_objects == 0) return;
+ if (mSkipSaveIfZeros)
+ {
+ S32 total_events = mObjectCacheHitCount + mObjectCacheMissCrcCount + mObjectCacheMissFullCount + mObjectFullUpdates +
+ mObjectTerseUpdates + mObjectCacheMissRequests + mObjectCacheMissResponses + mObjectCacheUpdateDupes +
+ mObjectCacheUpdateChanges + mObjectCacheUpdateAdds + mObjectCacheUpdateReplacements + mObjectUpdateFailures;
+ if (total_events == 0)
+ {
+ LL_DEBUGS("ILXZeroData") << "ILX: not saving zero data" << LL_ENDL;
+ return;
+ }
+ }
- mLastSnapshotTime = LLTimer::getTotalSeconds();
- LL_DEBUGS() << "ILX: "
+ mLastSnapshotTime = LLFrameTimer::getTotalSeconds();
+ LL_DEBUGS("ILX") << "ILX: "
<< mObjectCacheHitCount << " hits, "
<< mObjectCacheMissFullCount << " full misses, "
<< mObjectCacheMissCrcCount << " crc misses, "
@@ -188,84 +209,124 @@ void LLViewerStatsRecorder::writeToLog( F32 interval )
<< mObjectUpdateFailures << " update failures"
<< LL_ENDL;
- if (mObjectCacheFile == NULL)
+ if (mStatsFile == NULL)
{
- mStartTime = LLTimer::getTotalSeconds();
- mObjectCacheFile = LLFile::fopen(STATS_FILE_NAME, "wb");
- if (mObjectCacheFile)
- { // Write column headers
- std::ostringstream data_msg;
- data_msg << "EventTime(ms)\t"
- << "Cache Hits\t"
- << "Cache Full Misses\t"
- << "Cache Crc Misses\t"
- << "Full Updates\t"
- << "Terse Updates\t"
- << "Cache Miss Requests\t"
- << "Cache Miss Responses\t"
- << "Cache Update Dupes\t"
- << "Cache Update Changes\t"
- << "Cache Update Adds\t"
- << "Cache Update Replacements\t"
- << "Update Failures\t"
- << "Cache Hits bps\t"
- << "Cache Full Misses bps\t"
- << "Cache Crc Misses bps\t"
- << "Full Updates bps\t"
- << "Terse Updates bps\t"
- << "Cache Miss Responses bps\t"
- << "Texture Fetch bps\t"
- << "\n";
-
- data_size = data_msg.str().size();
- if (fwrite(data_msg.str().c_str(), 1, data_size, mObjectCacheFile ) != data_size)
+ // Refresh settings
+ mInterval = gSavedSettings.getF32("StatsReportFileInterval");
+ mSkipSaveIfZeros = gSavedSettings.getBOOL("StatsReportSkipZeroDataSaves");
+ mMaxDuration = gSavedSettings.getF32("StatsReportMaxDuration");
+
+ // Open the data file
+ makeStatsFileName();
+ mStatsFile = LLFile::fopen(mStatsFileName, "wb");
+
+ if (mStatsFile)
+ {
+ LL_INFOS("ILX") << "ILX: Writing update information to " << mStatsFileName << LL_ENDL;
+
+ mFileOpenTime = LLFrameTimer::getTotalSeconds();
+
+ // Write column headers
+ std::ostringstream col_headers;
+ col_headers << "Time (sec),"
+ << "Regions,"
+ << "Active Cached Objects,"
+ << "Cache Hits,"
+ << "Cache Full Misses,"
+ << "Cache Crc Misses,"
+ << "Full Updates,"
+ << "Terse Updates,"
+ << "Cache Miss Requests,"
+ << "Cache Miss Responses,"
+ << "Cache Update Dupes,"
+ << "Cache Update Changes,"
+ << "Cache Update Adds,"
+ << "Cache Update Replacements,"
+ << "Update Failures,"
+ << "Texture Fetch bps,"
+ << "\n";
+
+ data_size = col_headers.str().size();
+ if (fwrite(col_headers.str().c_str(), 1, data_size, mStatsFile ) != data_size)
{
- LL_WARNS() << "failed to write full headers to " << STATS_FILE_NAME << LL_ENDL;
+ LL_WARNS() << "failed to write full headers to " << mStatsFileName << LL_ENDL;
}
}
else
- {
- //LL_WARNS() << "Couldn't open " << STATS_FILE_NAME << " for logging." << LL_ENDL;
+ { // Failed to open file
+ LL_WARNS() << "Couldn't open " << mStatsFileName << " for logging, turning off stats recording." << LL_ENDL;
+ mEnableStatsLogging = false;
return;
}
}
- std::ostringstream data_msg;
-
- data_msg << getTimeSinceStart()
- << "\t " << mObjectCacheHitCount
- << "\t" << mObjectCacheMissFullCount
- << "\t" << mObjectCacheMissCrcCount
- << "\t" << mObjectFullUpdates
- << "\t" << mObjectTerseUpdates
- << "\t" << mObjectCacheMissRequests
- << "\t" << mObjectCacheMissResponses
- << "\t" << mObjectCacheUpdateDupes
- << "\t" << mObjectCacheUpdateChanges
- << "\t" << mObjectCacheUpdateAdds
- << "\t" << mObjectCacheUpdateReplacements
- << "\t" << mObjectUpdateFailures
- << "\t" << (mObjectCacheHitSize * 8 / delta_time)
- << "\t" << (mObjectCacheMissFullSize * 8 / delta_time)
- << "\t" << (mObjectCacheMissCrcSize * 8 / delta_time)
- << "\t" << (mObjectFullUpdatesSize * 8 / delta_time)
- << "\t" << (mObjectTerseUpdatesSize * 8 / delta_time)
- << "\t" << (mObjectCacheMissResponsesSize * 8 / delta_time)
- << "\t" << (mTextureFetchSize * 8 / delta_time)
+ std::ostringstream stats_data;
+
+ stats_data << getTimeSinceStart()
+ << "," << LLWorld::getInstance()->getRegionList().size()
+ << "," << LLWorld::getInstance()->getNumOfActiveCachedObjects()
+ << "," << mObjectCacheHitCount
+ << "," << mObjectCacheMissFullCount
+ << "," << mObjectCacheMissCrcCount
+ << "," << mObjectFullUpdates
+ << "," << mObjectTerseUpdates
+ << "," << mObjectCacheMissRequests
+ << "," << mObjectCacheMissResponses
+ << "," << mObjectCacheUpdateDupes
+ << "," << mObjectCacheUpdateChanges
+ << "," << mObjectCacheUpdateAdds
+ << "," << mObjectCacheUpdateReplacements
+ << "," << mObjectUpdateFailures
+ << "," << (mTextureFetchSize * 8 / delta_time)
<< "\n";
- data_size = data_msg.str().size();
- if ( data_size != fwrite(data_msg.str().c_str(), 1, data_size, mObjectCacheFile ))
+ data_size = stats_data.str().size();
+ if ( data_size != fwrite(stats_data.str().c_str(), 1, data_size, mStatsFile ))
{
- LL_WARNS() << "Unable to write complete column data to " << STATS_FILE_NAME << LL_ENDL;
- }
+ LL_WARNS() << "Unable to write complete column data to " << mStatsFileName << LL_ENDL;
+ closeStatsFile();
+ }
clearStats();
+
+ if (getTimeSinceStart() >= mMaxDuration)
+ { // If file recording has been running for too long, stop it.
+ closeStatsFile();
+ }
+}
+
+void LLViewerStatsRecorder::closeStatsFile()
+{
+ if (mStatsFile)
+ {
+ LL_INFOS("ILX") << "ILX: Stopped writing update information to " << mStatsFileName << " after " << getTimeSinceStart()
+ << " seconds." << LL_ENDL;
+ LLFile::close(mStatsFile);
+ mStatsFile = NULL;
+ }
+ mEnableStatsLogging = false;
+}
+
+void LLViewerStatsRecorder::makeStatsFileName()
+{
+ // Create filename - tbd: use pid?
+#if LL_WINDOWS
+ std::string stats_file_name("SLViewerStats-");
+#else
+ std::string stats_file_name("slviewerstats-");
+#endif
+
+ F64 now = LLFrameTimer::getTotalSeconds();
+ std::string date_str = LLDate(now).asString();
+ std::replace(date_str.begin(), date_str.end(), ':', '-'); // Make it valid for a filename
+ stats_file_name.append(date_str);
+ stats_file_name.append(".csv");
+ mStatsFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, stats_file_name);
}
F32 LLViewerStatsRecorder::getTimeSinceStart()
{
- return (F32) (LLTimer::getTotalSeconds() - mStartTime);
+ return (F32) (LLFrameTimer::getTotalSeconds() - mFileOpenTime);
}
void LLViewerStatsRecorder::recordTextureFetch( S32 msg_size )
diff --git a/indra/newview/llviewerstatsrecorder.h b/indra/newview/llviewerstatsrecorder.h
index c974bea49d..90f8ca8742 100644
--- a/indra/newview/llviewerstatsrecorder.h
+++ b/indra/newview/llviewerstatsrecorder.h
@@ -31,10 +31,6 @@
// This is a diagnostic class used to record information from the viewer
// for analysis.
-// This is normally 0. Set to 1 to enable viewer stats recording
-#define LL_RECORD_VIEWER_STATS 0
-
-
#include "llframetimer.h"
#include "llviewerobject.h"
#include "llviewerregion.h"
@@ -49,86 +45,111 @@ class LLViewerStatsRecorder : public LLSingleton<LLViewerStatsRecorder>
~LLViewerStatsRecorder();
public:
- void objectUpdateFailure(U32 local_id, const EObjectUpdateType update_type, S32 msg_size)
- {
-#if LL_RECORD_VIEWER_STATS
- recordObjectUpdateFailure(local_id, update_type, msg_size);
-#endif
+ // Enable/disable stats recording. This is broken down into two
+ // flags so we can record stats without writing them to the log
+ // file. This is useful to analyzing updates for scene loading.
+ void enableObjectStatsRecording(bool enable, bool logging = false);
+
+ bool isEnabled() const { return mEnableStatsRecording; }
+ bool isLogging() const { return mEnableStatsLogging; }
+
+ void objectUpdateFailure(S32 msg_size)
+ {
+ if (mEnableStatsRecording)
+ {
+ recordObjectUpdateFailure(msg_size);
+ }
}
- void cacheMissEvent(U32 local_id, const EObjectUpdateType update_type, U8 cache_miss_type, S32 msg_size)
+ void cacheMissEvent(U8 cache_miss_type)
{
-#if LL_RECORD_VIEWER_STATS
- recordCacheMissEvent(local_id, update_type, cache_miss_type, msg_size);
-#endif
+ if (mEnableStatsRecording)
+ {
+ recordCacheMissEvent(cache_miss_type);
+ }
+ }
+
+ void cacheHitEvent()
+ {
+ if (mEnableStatsRecording)
+ {
+ recordCacheHitEvent();
+ }
+ }
+
+ void objectUpdateEvent(const EObjectUpdateType update_type)
+ {
+ if (mEnableStatsRecording)
+ {
+ recordObjectUpdateEvent(update_type);
+ }
}
- void objectUpdateEvent(U32 local_id, const EObjectUpdateType update_type, LLViewerObject * objectp, S32 msg_size)
- {
-#if LL_RECORD_VIEWER_STATS
- recordObjectUpdateEvent(local_id, update_type, objectp, msg_size);
-#endif
- }
-
- void cacheFullUpdate(U32 local_id, const EObjectUpdateType update_type, LLViewerRegion::eCacheUpdateResult update_result, LLViewerObject* objectp, S32 msg_size)
- {
-#if LL_RECORD_VIEWER_STATS
- recordCacheFullUpdate(local_id, update_type, update_result, objectp, msg_size);
-#endif
+ void cacheFullUpdate(LLViewerRegion::eCacheUpdateResult update_result)
+ {
+ if (mEnableStatsRecording)
+ {
+ recordCacheFullUpdate(update_result);
+ }
}
void requestCacheMissesEvent(S32 count)
{
-#if LL_RECORD_VIEWER_STATS
- recordRequestCacheMissesEvent(count);
-#endif
+ if (mEnableStatsRecording)
+ {
+ recordRequestCacheMissesEvent(count);
+ }
}
void textureFetch(S32 msg_size)
{
-#if LL_RECORD_VIEWER_STATS
- recordTextureFetch(msg_size);
-#endif
+ if (mEnableStatsRecording)
+ {
+ recordTextureFetch(msg_size);
+ }
}
- void log(F32 interval)
+ void idle()
{
-#if LL_RECORD_VIEWER_STATS
- writeToLog(interval);
-#endif
+ writeToLog(mInterval);
}
F32 getTimeSinceStart();
private:
- void recordObjectUpdateFailure(U32 local_id, const EObjectUpdateType update_type, S32 msg_size);
- void recordCacheMissEvent(U32 local_id, const EObjectUpdateType update_type, U8 cache_miss_type, S32 msg_size);
- void recordObjectUpdateEvent(U32 local_id, const EObjectUpdateType update_type, LLViewerObject * objectp, S32 msg_size);
- void recordCacheFullUpdate(U32 local_id, const EObjectUpdateType update_type, LLViewerRegion::eCacheUpdateResult update_result, LLViewerObject* objectp, S32 msg_size);
+ void recordObjectUpdateFailure(S32 msg_size);
+ void recordCacheMissEvent(U8 cache_miss_type);
+ void recordCacheHitEvent();
+ void recordObjectUpdateEvent(const EObjectUpdateType update_type);
+ void recordCacheFullUpdate(LLViewerRegion::eCacheUpdateResult update_result);
void recordRequestCacheMissesEvent(S32 count);
void recordTextureFetch(S32 msg_size);
void writeToLog(F32 interval);
+ void closeStatsFile();
+ void makeStatsFileName();
static LLViewerStatsRecorder* sInstance;
- LLFILE * mObjectCacheFile; // File to write data into
+ LLFILE * mStatsFile; // File to write data into
+ std::string mStatsFileName;
+
LLFrameTimer mTimer;
- F64 mStartTime;
+ F64 mFileOpenTime;
F64 mLastSnapshotTime;
+ F32 mInterval; // Interval between data log writes
+ F32 mMaxDuration; // Time limit on file
+
+ bool mEnableStatsRecording; // Set to true to enable recording stats data
+ bool mEnableStatsLogging; // Set true to write stats to log file
+ bool mSkipSaveIfZeros; // Set true to skip saving stats if all values are zero
S32 mObjectCacheHitCount;
- S32 mObjectCacheHitSize;
S32 mObjectCacheMissFullCount;
- S32 mObjectCacheMissFullSize;
S32 mObjectCacheMissCrcCount;
- S32 mObjectCacheMissCrcSize;
S32 mObjectFullUpdates;
- S32 mObjectFullUpdatesSize;
S32 mObjectTerseUpdates;
- S32 mObjectTerseUpdatesSize;
S32 mObjectCacheMissRequests;
S32 mObjectCacheMissResponses;
- S32 mObjectCacheMissResponsesSize;
S32 mObjectCacheUpdateDupes;
S32 mObjectCacheUpdateChanges;
S32 mObjectCacheUpdateAdds;
@@ -137,9 +158,7 @@ private:
S32 mObjectUpdateFailuresSize;
S32 mTextureFetchSize;
-
void clearStats();
};
#endif // LLVIEWERSTATSRECORDER_H
-
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index f72d1f0bf9..d78ebf17e3 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -3463,14 +3463,24 @@ function="World.EnvPreset"
<menu_item_call.on_click
function="Advanced.DumpRegionObjectCache" />
</menu_item_call>
-
-<menu_item_call
- label="Interest List: Full Update"
- name="Interest List: Full Update"
+
+ <menu_item_check
+ label="Interest List 360 Mode"
+ name="Interest List: 360 Mode"
shortcut="alt|shift|I">
- <menu_item_call.on_click
- function="Advanced.InterestListFullUpdate" />
- </menu_item_call>
+ <menu_item_check.on_check
+ function="Advanced.CheckInterestList360Mode" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleInterestList360Mode" />
+ </menu_item_check>
+ <menu_item_check
+ label="Record Stats to File"
+ name="Stats Recorder File">
+ <menu_item_check.on_check
+ function="Advanced.CheckStatsRecorder" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleStatsRecorder" />
+ </menu_item_check>
</menu>
<menu
create_jump_keys="true"