summaryrefslogtreecommitdiff
path: root/indra/newview/llmeshrepository.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llmeshrepository.cpp')
-rwxr-xr-xindra/newview/llmeshrepository.cpp106
1 files changed, 103 insertions, 3 deletions
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 8d3539d297..6dc834e852 100755
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -5,7 +5,7 @@
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
+ * Copyright (C) 2010-2013, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -38,6 +38,7 @@
#include "llcallbacklist.h"
#include "llcurl.h"
#include "lldatapacker.h"
+#include "lldeadmantimer.h"
#include "llfloatermodelpreview.h"
#include "llfloaterperms.h"
#include "lleconomy.h"
@@ -52,6 +53,7 @@
#include "llviewercontrol.h"
#include "llviewerinventory.h"
#include "llviewermenufile.h"
+#include "llviewermessage.h"
#include "llviewerobjectlist.h"
#include "llviewerregion.h"
#include "llviewertexturelist.h"
@@ -95,8 +97,9 @@ U32 LLMeshRepository::sLODPending = 0;
U32 LLMeshRepository::sCacheBytesRead = 0;
U32 LLMeshRepository::sCacheBytesWritten = 0;
U32 LLMeshRepository::sPeakKbps = 0;
-
+LLDeadmanTimer LLMeshRepository::sQuiescentTimer(15.0, true); // true -> gather cpu metrics
+
const U32 MAX_TEXTURE_UPLOAD_RETRIES = 5;
static S32 dump_num = 0;
@@ -108,7 +111,7 @@ std::string make_dump_name(std::string prefix, S32 num)
void dump_llsd_to_file(const LLSD& content, std::string filename);
LLSD llsd_from_file(std::string filename);
-std::string header_lod[] =
+const std::string header_lod[] =
{
"lowest_lod",
"low_lod",
@@ -116,6 +119,12 @@ std::string header_lod[] =
"high_lod"
};
+// Static data and functions to measure mesh load
+// time metrics for a new region scene.
+static bool metrics_inited(false);
+static boost::signals2::connection metrics_teleport_connection;
+static unsigned int metrics_teleport_start_count(0);
+static void metrics_teleport_started();
//get the number of bytes resident in memory for given volume
U32 get_volume_memory_size(const LLVolume* volume)
@@ -2307,12 +2316,26 @@ void LLMeshRepository::init()
mThread = new LLMeshRepoThread();
mThread->start();
+
+ if (! metrics_inited)
+ {
+ // Get teleport started signals to restart timings.
+ metrics_teleport_connection = LLViewerMessage::getInstance()->
+ setTeleportStartedCallback(metrics_teleport_started);
+ metrics_inited = true;
+ }
}
void LLMeshRepository::shutdown()
{
llinfos << "Shutting down mesh repository." << llendl;
+ if (metrics_inited)
+ {
+ metrics_teleport_connection.disconnect();
+ metrics_inited = false;
+ }
+
for (U32 i = 0; i < mUploads.size(); ++i)
{
llinfos << "Discard the pending mesh uploads " << llendl;
@@ -2358,6 +2381,9 @@ void LLMeshRepository::shutdown()
//called in the main thread.
S32 LLMeshRepository::update()
{
+ // Conditionally log a mesh metrics event
+ metricsUpdate();
+
if(mUploadWaitList.empty())
{
return 0 ;
@@ -2377,6 +2403,9 @@ S32 LLMeshRepository::update()
S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_params, S32 detail, S32 last_lod)
{
+ // Manage time-to-load metrics for mesh download operations.
+ metricsProgress(1);
+
if (detail < 0 || detail > 4)
{
return detail;
@@ -2679,6 +2708,9 @@ void LLMeshRepository::notifyDecompositionReceived(LLModel::Decomposition* decom
void LLMeshRepository::notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVolume* volume)
{ //called from main thread
+ // Manage time-to-load metrics for mesh download operations.
+ metricsProgress(0);
+
S32 detail = LLVolumeLODGroup::getVolumeDetailFromScale(volume->getDetail());
//get list of objects waiting to be notified this mesh is loaded
@@ -2722,6 +2754,9 @@ void LLMeshRepository::notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVol
void LLMeshRepository::notifyMeshUnavailable(const LLVolumeParams& mesh_params, S32 lod)
{ //called from main thread
+ // Manage time-to-load metrics for mesh download operations.
+ metricsProgress(0);
+
//get list of objects waiting to be notified this mesh is loaded
mesh_load_map::iterator obj_iter = mLoadingMeshes[lod].find(mesh_params);
@@ -3698,3 +3733,68 @@ bool LLMeshRepository::meshRezEnabled()
}
return false;
}
+
+// Threading: main thread only
+// static
+void LLMeshRepository::metricsStart()
+{
+ sQuiescentTimer.start(0);
+}
+
+// Threading: main thread only
+// static
+void LLMeshRepository::metricsStop()
+{
+ sQuiescentTimer.stop(0);
+}
+
+// Threading: main thread only
+// static
+void LLMeshRepository::metricsProgress(unsigned int this_count)
+{
+ static bool first_start(true);
+
+ if (first_start)
+ {
+ ++metrics_teleport_start_count;
+ metricsStart();
+ first_start = false;
+ }
+ sQuiescentTimer.ringBell(0, this_count);
+}
+
+// Threading: main thread only
+// static
+void LLMeshRepository::metricsUpdate()
+{
+ F64 started, stopped;
+ U64 total_count(U64L(0)), user_cpu(U64L(0)), sys_cpu(U64L(0));
+
+ if (sQuiescentTimer.isExpired(0, started, stopped, total_count, user_cpu, sys_cpu))
+ {
+ LLSD metrics;
+
+ metrics["reason"] = "Mesh Download Quiescent";
+ metrics["scope"] = "Login";
+ metrics["start"] = started;
+ metrics["stop"] = stopped;
+ metrics["downloads"] = LLSD::Integer(total_count);
+ metrics["teleports"] = LLSD::Integer(metrics_teleport_start_count);
+ metrics["user_cpu"] = double(user_cpu) / 1.0e6;
+ metrics["sys_cpu"] = double(sys_cpu) / 1.0e6;
+ llinfos << "EventMarker " << metrics << llendl;
+ }
+}
+
+// Will use a request to start a teleport as a signal to
+// restart a timing sequence. We don't get one of these
+// for login so initial start is done above.
+//
+// Threading: main thread only
+// static
+void metrics_teleport_started()
+{
+ LLMeshRepository::metricsStart();
+ ++metrics_teleport_start_count;
+}
+