summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorMonty Brandenberg <monty@lindenlab.com>2013-08-05 19:04:08 -0400
committerMonty Brandenberg <monty@lindenlab.com>2013-08-05 19:04:08 -0400
commit43788d612042deb6f9329746a101774370f7c67b (patch)
tree3688143c8ab7563b40bbc32dbdf598cd55b403d5 /indra
parent549e20cf7766dc7fba2f42883659a6bcac863d91 (diff)
Added some simple counters to the mesh repository code and then
added a Mesh status line to the texture fetch console. Mesh is often in competition with textures and so the mesh information seems appropriate there. Do get a nice feel for progress and you definitely see when the throttles kick in.
Diffstat (limited to 'indra')
-rwxr-xr-xindra/newview/llmeshrepository.cpp134
-rwxr-xr-xindra/newview/llmeshrepository.h11
-rwxr-xr-xindra/newview/lltextureview.cpp41
3 files changed, 123 insertions, 63 deletions
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 7146c7f4f5..97d6c57a78 100755
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -155,20 +155,26 @@
//
// So, in addition to documentation, take this as a to-do/review
// list and see if you can improve things. For porters to non-x86
-// architectures, including amd64, the weaker memory models will
-// make these platforms probabilistically more susceptible to hitting
-// race conditions. True here and in other multi-thread code such
-// as texture fetching.
+// architectures, the weaker memory models will make these platforms
+// probabilistically more susceptible to hitting race conditions.
+// True here and in other multi-thread code such as texture fetching.
+// (Strong memory models make weak programmers. Weak memory models
+// make strong programmers. Ref: arm, ppc, mips, alpha)
//
// LLMeshRepository:
//
// sBytesReceived
+// sMeshRequestCount
// sHTTPRequestCount
+// sHTTPLargeRequestCount
// sHTTPRetryCount
+// sHTTPErrorCount
// sLODPending
// sLODProcessing
// sCacheBytesRead
// sCacheBytesWritten
+// sCacheReads
+// sCacheWrites
// mLoadingMeshes none rw.main.none, rw.main.mMeshMutex [4]
// mSkinMap none rw.main.none
// mDecompositionMap none rw.main.none
@@ -246,13 +252,19 @@ const long LARGE_MESH_XFER_TIMEOUT = 600L; // Seconds to complete xfer, large
const S32 MAX_MESH_VERSION = 999;
U32 LLMeshRepository::sBytesReceived = 0;
+U32 LLMeshRepository::sMeshRequestCount = 0;
U32 LLMeshRepository::sHTTPRequestCount = 0;
+U32 LLMeshRepository::sHTTPLargeRequestCount = 0;
U32 LLMeshRepository::sHTTPRetryCount = 0;
+U32 LLMeshRepository::sHTTPErrorCount = 0;
U32 LLMeshRepository::sLODProcessing = 0;
U32 LLMeshRepository::sLODPending = 0;
U32 LLMeshRepository::sCacheBytesRead = 0;
U32 LLMeshRepository::sCacheBytesWritten = 0;
+U32 LLMeshRepository::sCacheReads = 0;
+U32 LLMeshRepository::sCacheWrites = 0;
+
LLDeadmanTimer LLMeshRepository::sQuiescentTimer(15.0, true); // true -> gather cpu metrics
@@ -366,6 +378,7 @@ volatile S32 LLMeshRepoThread::sActiveLODRequests = 0;
U32 LLMeshRepoThread::sMaxConcurrentRequests = 1;
S32 LLMeshRepoThread::sRequestLowWater = REQUEST_LOW_WATER_MIN;
S32 LLMeshRepoThread::sRequestHighWater = REQUEST_HIGH_WATER_MIN;
+S32 LLMeshRepoThread::sRequestWaterLevel = 0;
// Base handler class for all mesh users of llcorehttp.
// This is roughly equivalent to a Responder class in
@@ -619,9 +632,7 @@ LLMeshRepoThread::LLMeshRepoThread()
mHttpPolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID),
mHttpLegacyPolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID),
mHttpLargePolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID),
- mHttpPriority(0),
- mHttpGetCount(0U),
- mHttpLargeGetCount(0U)
+ mHttpPriority(0)
{
mMutex = new LLMutex(NULL);
mHeaderMutex = new LLMutex(NULL);
@@ -641,8 +652,8 @@ LLMeshRepoThread::LLMeshRepoThread()
LLMeshRepoThread::~LLMeshRepoThread()
{
- LL_INFOS(LOG_MESH) << "Small GETs issued: " << mHttpGetCount
- << ", Large GETs issued: " << mHttpLargeGetCount
+ LL_INFOS(LOG_MESH) << "Small GETs issued: " << LLMeshRepository::sHTTPRequestCount
+ << ", Large GETs issued: " << LLMeshRepository::sHTTPLargeRequestCount
<< LL_ENDL;
for (http_request_set::iterator iter(mHttpRequestSet.begin());
@@ -700,7 +711,8 @@ void LLMeshRepoThread::run()
if (! LLApp::isQuitting())
{
// NOTE: order of queue processing intentionally favors LOD requests over header requests
-
+
+ sRequestWaterLevel = mHttpRequestSet.size();
while (!mLODReqQ.empty() && mHttpRequestSet.size() < sRequestHighWater)
{
if (! mMutex)
@@ -743,19 +755,26 @@ void LLMeshRepoThread::run()
// list, we scan the entire thing. This gets us through any requests
// which can be resolved in the cache. It also keeps the request
// set somewhat fresher otherwise items at the end of the set
- // order will lose. Keep to the throttle enforcement and pay
- // attention to the highwater level (enforced in each fetchXXX()
- // method).
+ // order will lose.
if (! mSkinRequests.empty() && mHttpRequestSet.size() < sRequestHighWater)
{
// *FIXME: this really does need a lock as do the following ones
std::set<LLUUID> incomplete;
for (std::set<LLUUID>::iterator iter = mSkinRequests.begin(); iter != mSkinRequests.end(); ++iter)
{
- LLUUID mesh_id = *iter;
- if (!fetchMeshSkinInfo(mesh_id))
+ if (mHttpRequestSet.size() < sRequestHighWater)
+ {
+ LLUUID mesh_id = *iter;
+ if (!fetchMeshSkinInfo(mesh_id))
+ {
+ incomplete.insert(mesh_id);
+ }
+ }
+ else
{
- incomplete.insert(mesh_id);
+ // Hit high-water mark, copy remaining to incomplete.
+ incomplete.insert(iter, mSkinRequests.end());
+ break;
}
}
mSkinRequests.swap(incomplete);
@@ -766,10 +785,19 @@ void LLMeshRepoThread::run()
std::set<LLUUID> incomplete;
for (std::set<LLUUID>::iterator iter = mDecompositionRequests.begin(); iter != mDecompositionRequests.end(); ++iter)
{
- LLUUID mesh_id = *iter;
- if (!fetchMeshDecomposition(mesh_id))
+ if (mHttpRequestSet.size() < sRequestHighWater)
{
- incomplete.insert(mesh_id);
+ LLUUID mesh_id = *iter;
+ if (!fetchMeshDecomposition(mesh_id))
+ {
+ incomplete.insert(mesh_id);
+ }
+ }
+ else
+ {
+ // Hit high-water mark, copy remaining to incomplete.
+ incomplete.insert(iter, mDecompositionRequests.end());
+ break;
}
}
mDecompositionRequests.swap(incomplete);
@@ -780,10 +808,19 @@ void LLMeshRepoThread::run()
std::set<LLUUID> incomplete;
for (std::set<LLUUID>::iterator iter = mPhysicsShapeRequests.begin(); iter != mPhysicsShapeRequests.end(); ++iter)
{
- LLUUID mesh_id = *iter;
- if (!fetchMeshPhysicsShape(mesh_id))
+ if (mHttpRequestSet.size() < sRequestHighWater)
+ {
+ LLUUID mesh_id = *iter;
+ if (!fetchMeshPhysicsShape(mesh_id))
+ {
+ incomplete.insert(mesh_id);
+ }
+ }
+ else
{
- incomplete.insert(mesh_id);
+ // Hit high-water mark, copy remaining to incomplete.
+ incomplete.insert(iter, mPhysicsShapeRequests.end());
+ break;
}
}
mPhysicsShapeRequests.swap(incomplete);
@@ -926,7 +963,10 @@ LLCore::HttpHandle LLMeshRepoThread::getByteRange(const std::string & url, int c
mHttpOptions,
mHttpHeaders,
handler);
- ++mHttpGetCount;
+ if (LLCORE_HTTP_HANDLE_INVALID != handle)
+ {
+ ++LLMeshRepository::sHTTPRequestCount;
+ }
}
else
{
@@ -938,7 +978,10 @@ LLCore::HttpHandle LLMeshRepoThread::getByteRange(const std::string & url, int c
mHttpLargeOptions,
mHttpHeaders,
handler);
- ++mHttpLargeGetCount;
+ if (LLCORE_HTTP_HANDLE_INVALID != handle)
+ {
+ ++LLMeshRepository::sHTTPLargeRequestCount;
+ }
}
if (LLCORE_HTTP_HANDLE_INVALID == handle)
{
@@ -965,7 +1008,8 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id)
return false;
}
- bool ret = true ;
+ ++LLMeshRepository::sMeshRequestCount;
+ bool ret = true;
U32 header_size = mMeshHeaderSize[mesh_id];
if (header_size > 0)
@@ -983,6 +1027,7 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id)
if (file.getSize() >= offset+size)
{
LLMeshRepository::sCacheBytesRead += size;
+ ++LLMeshRepository::sCacheReads;
file.seek(offset);
U8* buffer = new U8[size];
file.read(buffer, size);
@@ -1007,10 +1052,6 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id)
}
//reading from VFS failed for whatever reason, fetch from sim
- if (mHttpRequestSet.size() >= sRequestHighWater)
- {
- return false;
- }
int cap_version(gMeshRepo.mGetMeshVersion);
std::string http_url = constructUrl(mesh_id);
if (!http_url.empty())
@@ -1025,12 +1066,12 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id)
<< LL_ENDL;
delete handler;
ret = false;
+
}
else
{
handler->mHttpHandle = handle;
mHttpRequestSet.insert(handler);
- ++LLMeshRepository::sHTTPRequestCount;
}
}
}
@@ -1059,8 +1100,9 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)
return false;
}
+ ++LLMeshRepository::sMeshRequestCount;
U32 header_size = mMeshHeaderSize[mesh_id];
- bool ret = true ;
+ bool ret = true;
if (header_size > 0)
{
@@ -1077,6 +1119,7 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)
if (file.getSize() >= offset+size)
{
LLMeshRepository::sCacheBytesRead += size;
+ ++LLMeshRepository::sCacheReads;
file.seek(offset);
U8* buffer = new U8[size];
@@ -1102,10 +1145,6 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)
}
//reading from VFS failed for whatever reason, fetch from sim
- if (mHttpRequestSet.size() >= sRequestHighWater)
- {
- return false;
- }
int cap_version(gMeshRepo.mGetMeshVersion);
std::string http_url = constructUrl(mesh_id);
if (!http_url.empty())
@@ -1125,7 +1164,6 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)
{
handler->mHttpHandle = handle;
mHttpRequestSet.insert(handler);
- ++LLMeshRepository::sHTTPRequestCount;
}
}
}
@@ -1154,8 +1192,9 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)
return false;
}
+ ++LLMeshRepository::sMeshRequestCount;
U32 header_size = mMeshHeaderSize[mesh_id];
- bool ret = true ;
+ bool ret = true;
if (header_size > 0)
{
@@ -1172,6 +1211,7 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)
if (file.getSize() >= offset+size)
{
LLMeshRepository::sCacheBytesRead += size;
+ ++LLMeshRepository::sCacheReads;
file.seek(offset);
U8* buffer = new U8[size];
file.read(buffer, size);
@@ -1196,10 +1236,6 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)
}
//reading from VFS failed for whatever reason, fetch from sim
- if (mHttpRequestSet.size() >= sRequestHighWater)
- {
- return false;
- }
int cap_version(gMeshRepo.mGetMeshVersion);
std::string http_url = constructUrl(mesh_id);
if (!http_url.empty())
@@ -1219,7 +1255,6 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)
{
handler->mHttpHandle = handle;
mHttpRequestSet.insert(handler);
- ++LLMeshRepository::sHTTPRequestCount;
}
}
}
@@ -1268,6 +1303,8 @@ void LLMeshRepoThread::decActiveHeaderRequests()
//return false if failed to get header
bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params)
{
+ ++LLMeshRepository::sMeshRequestCount;
+
{
//look for mesh in asset in vfs
LLVFile file(gVFS, mesh_params.getSculptID(), LLAssetType::AT_MESH);
@@ -1280,6 +1317,7 @@ bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params)
U8 buffer[MESH_HEADER_SIZE];
S32 bytes = llmin(size, MESH_HEADER_SIZE);
LLMeshRepository::sCacheBytesRead += bytes;
+ ++LLMeshRepository::sCacheReads;
file.read(buffer, bytes);
if (headerReceived(mesh_params, buffer, bytes))
{
@@ -1314,7 +1352,6 @@ bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params)
{
handler->mHttpHandle = handle;
mHttpRequestSet.insert(handler);
- ++LLMeshRepository::sHTTPRequestCount;
}
}
@@ -1331,6 +1368,7 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
mHeaderMutex->lock();
+ ++LLMeshRepository::sMeshRequestCount;
bool retval = true;
LLUUID mesh_id = mesh_params.getSculptID();
@@ -1352,6 +1390,7 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
if (file.getSize() >= offset+size)
{
LLMeshRepository::sCacheBytesRead += size;
+ ++LLMeshRepository::sCacheReads;
file.seek(offset);
U8* buffer = new U8[size];
file.read(buffer, size);
@@ -1395,7 +1434,6 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
{
handler->mHttpHandle = handle;
mHttpRequestSet.insert(handler);
- ++LLMeshRepository::sHTTPRequestCount;
}
}
else
@@ -2364,6 +2402,7 @@ void LLMeshHandlerBase::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRespo
if (! status)
{
processFailure(status);
+ ++LLMeshRepository::sHTTPErrorCount;
}
else
{
@@ -2484,6 +2523,7 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * body, U8 * data, S32
if (file.getMaxSize() >= bytes || file.setMaxSize(bytes))
{
LLMeshRepository::sCacheBytesWritten += data_size;
+ ++LLMeshRepository::sCacheWrites;
file.write(data, data_size);
@@ -2556,6 +2596,7 @@ void LLMeshLODHandler::processData(LLCore::BufferArray * body, U8 * data, S32 da
file.seek(offset);
file.write(data, size);
LLMeshRepository::sCacheBytesWritten += size;
+ ++LLMeshRepository::sCacheWrites;
}
}
// *TODO: Mark mesh unavailable on error
@@ -2601,6 +2642,7 @@ void LLMeshSkinInfoHandler::processData(LLCore::BufferArray * body, U8 * data, S
if (file.getSize() >= offset+size)
{
LLMeshRepository::sCacheBytesWritten += size;
+ ++LLMeshRepository::sCacheWrites;
file.seek(offset);
file.write(data, size);
}
@@ -2648,6 +2690,7 @@ void LLMeshDecompositionHandler::processData(LLCore::BufferArray * body, U8 * da
if (file.getSize() >= offset+size)
{
LLMeshRepository::sCacheBytesWritten += size;
+ ++LLMeshRepository::sCacheWrites;
file.seek(offset);
file.write(data, size);
}
@@ -2695,6 +2738,7 @@ void LLMeshPhysicsShapeHandler::processData(LLCore::BufferArray * body, U8 * dat
if (file.getSize() >= offset+size)
{
LLMeshRepository::sCacheBytesWritten += size;
+ ++LLMeshRepository::sCacheWrites;
file.seek(offset);
file.write(data, size);
}
@@ -4204,7 +4248,7 @@ void LLMeshRepository::metricsUpdate()
LLSD metrics;
metrics["reason"] = "Mesh Download Quiescent";
- metrics["scope"] = "Login";
+ metrics["scope"] = metrics_teleport_start_count > 1 ? "Teleport" : "Login";
metrics["start"] = started;
metrics["stop"] = stopped;
metrics["fetches"] = LLSD::Integer(total_count);
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index 400ceb4ad7..7e89f60bc3 100755
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -224,6 +224,7 @@ public:
static U32 sMaxConcurrentRequests;
static S32 sRequestLowWater;
static S32 sRequestHighWater;
+ static S32 sRequestWaterLevel; // Stats-use only, may read outside of thread
LLMutex* mMutex;
LLMutex* mHeaderMutex;
@@ -387,10 +388,6 @@ private:
LLCore::HttpHandle getByteRange(const std::string & url, int cap_version,
size_t offset, size_t len,
LLCore::HttpHandler * handler);
-
-private:
- U32 mHttpGetCount;
- U32 mHttpLargeGetCount;
};
@@ -497,12 +494,18 @@ public:
//metrics
static U32 sBytesReceived;
+ static U32 sMeshRequestCount;
static U32 sHTTPRequestCount;
+ static U32 sHTTPLargeRequestCount;
static U32 sHTTPRetryCount;
+ static U32 sHTTPErrorCount;
static U32 sLODPending;
static U32 sLODProcessing;
static U32 sCacheBytesRead;
static U32 sCacheBytesWritten;
+ static U32 sCacheReads;
+ static U32 sCacheWrites;
+
static LLDeadmanTimer sQuiescentTimer; // time-to-complete-mesh-downloads after significant events
static F32 getStreamingCost(LLSD& header, F32 radius, S32* bytes = NULL, S32* visible_bytes = NULL, S32 detail = -1, F32 *unscaled_value = NULL);
diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp
index e80136b286..50edbb61a8 100755
--- a/indra/newview/lltextureview.cpp
+++ b/indra/newview/lltextureview.cpp
@@ -4,7 +4,7 @@
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2012, Linden Research, Inc.
+ * Copyright (C) 2012-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
@@ -49,6 +49,7 @@
#include "llviewertexturelist.h"
#include "llvovolume.h"
#include "llviewerstats.h"
+#include "llmeshrepository.h"
// For avatar texture view
#include "llvoavatarself.h"
@@ -517,6 +518,8 @@ void LLGLTexMemBar::draw()
F32 total_texture_downloaded = (F32)gTotalTextureBytes / (1024 * 1024);
F32 total_object_downloaded = (F32)gTotalObjectBytes / (1024 * 1024);
U32 total_http_requests = LLAppViewer::getTextureFetch()->getTotalNumHTTPRequests();
+ F32 x_right = 0.0;
+
//----------------------------------------------------------------------------
LLGLSUIDefault gls_ui;
LLColor4 text_color(1.f, 1.f, 1.f, 0.75f);
@@ -543,7 +546,7 @@ void LLGLTexMemBar::draw()
cache_max_usage);
//, cache_entries, cache_max_entries
- LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*4,
+ LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*5,
text_color, LLFontGL::LEFT, LLFontGL::TOP);
U32 cache_read(0U), cache_write(0U), res_wait(0U);
@@ -557,13 +560,12 @@ void LLGLTexMemBar::draw()
cache_write,
res_wait);
- LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*3,
+ LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*4,
text_color, LLFontGL::LEFT, LLFontGL::TOP);
- S32 left = 0 ;
//----------------------------------------------------------------------------
- text = llformat("Textures: %d Fetch: %d(%d) Pkts:%d(%d) Cache R/W: %d/%d LFS:%d RAW:%d HTP:%d DEC:%d CRE:%d",
+ text = llformat("Textures: %d Fetch: %d(%d) Pkts:%d(%d) Cache R/W: %d/%d LFS:%d RAW:%d HTP:%d DEC:%d CRE:%d ",
gTextureList.getNumImages(),
LLAppViewer::getTextureFetch()->getNumRequests(), LLAppViewer::getTextureFetch()->getNumDeletes(),
LLAppViewer::getTextureFetch()->mPacketCount, LLAppViewer::getTextureFetch()->mBadPacketCount,
@@ -574,19 +576,30 @@ void LLGLTexMemBar::draw()
LLAppViewer::getImageDecodeThread()->getPending(),
gTextureList.mCreateTextureList.size());
- LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*2,
- text_color, LLFontGL::LEFT, LLFontGL::TOP);
-
+ x_right = 550.0;
+ LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*3,
+ text_color, LLFontGL::LEFT, LLFontGL::TOP,
+ LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX,
+ &x_right, FALSE);
- left = 550;
F32 bandwidth = LLAppViewer::getTextureFetch()->getTextureBandwidth();
F32 max_bandwidth = gSavedSettings.getF32("ThrottleBandwidthKBPS");
- color = bandwidth > max_bandwidth ? LLColor4::red : bandwidth > max_bandwidth*.75f ? LLColor4::yellow : text_color;
+ color = bandwidth > max_bandwidth ? LLColor4::red : bandwidth > max_bandwidth * .75f ? LLColor4::yellow : text_color;
color[VALPHA] = text_color[VALPHA];
- text = llformat("BW:%.0f/%.0f",bandwidth, max_bandwidth);
- LLFontGL::getFontMonospace()->renderUTF8(text, 0, left, v_offset + line_height*2,
+ text = llformat("BW:%.0f/%.0f", bandwidth, max_bandwidth);
+ LLFontGL::getFontMonospace()->renderUTF8(text, 0, x_right, v_offset + line_height*3,
color, LLFontGL::LEFT, LLFontGL::TOP);
-
+
+ // Mesh status line
+ text = llformat("Mesh: Reqs(Tot/Htp/Big): %u/%u/%u Rtr/Err: %u/%u Cread/Cwrite: %u/%u Low/At/High: %d/%d/%d",
+ LLMeshRepository::sMeshRequestCount, LLMeshRepository::sHTTPRequestCount, LLMeshRepository::sHTTPLargeRequestCount,
+ LLMeshRepository::sHTTPRetryCount, LLMeshRepository::sHTTPErrorCount,
+ LLMeshRepository::sCacheReads, LLMeshRepository::sCacheWrites,
+ LLMeshRepoThread::sRequestLowWater, LLMeshRepoThread::sRequestWaterLevel, LLMeshRepoThread::sRequestHighWater);
+ LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*2,
+ text_color, LLFontGL::LEFT, LLFontGL::TOP);
+
+ // Header for texture table columns
S32 dx1 = 0;
if (LLAppViewer::getTextureFetch()->mDebugPause)
{
@@ -629,7 +642,7 @@ BOOL LLGLTexMemBar::handleMouseDown(S32 x, S32 y, MASK mask)
LLRect LLGLTexMemBar::getRequiredRect()
{
LLRect rect;
- rect.mTop = 50; //LLFontGL::getFontMonospace()->getLineHeight() * 6;
+ rect.mTop = 68; //LLFontGL::getFontMonospace()->getLineHeight() * 6;
return rect;
}