Skip to content

Commit 56093cb

Browse files
committed
viewer#3070 Fix mesh queues getting overfilled
Account for queue size instead of just active request Reduce mutex locking Prioritize skininfo queue over lod queue to lessen issues with t-poses
1 parent c6b7b2f commit 56093cb

File tree

2 files changed

+95
-47
lines changed

2 files changed

+95
-47
lines changed

indra/newview/llmeshrepository.cpp

Lines changed: 92 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -933,6 +933,50 @@ void LLMeshRepoThread::run()
933933
// in relatively similar manners, remake code to simplify/unify the process,
934934
// like processRequests(&requestQ, fetchFunction); which does same thing for each element
935935

936+
if (mHttpRequestSet.size() < sRequestHighWater
937+
&& !mSkinRequests.empty())
938+
{
939+
if (!mSkinRequests.empty())
940+
{
941+
std::list<UUIDBasedRequest> incomplete;
942+
while (!mSkinRequests.empty() && mHttpRequestSet.size() < sRequestHighWater)
943+
{
944+
945+
mMutex->lock();
946+
auto req = mSkinRequests.front();
947+
mSkinRequests.pop_front();
948+
mMutex->unlock();
949+
if (req.isDelayed())
950+
{
951+
incomplete.emplace_back(req);
952+
}
953+
else if (!fetchMeshSkinInfo(req.mId, req.canRetry()))
954+
{
955+
if (req.canRetry())
956+
{
957+
req.updateTime();
958+
incomplete.emplace_back(req);
959+
}
960+
else
961+
{
962+
LLMutexLock locker(mMutex);
963+
mSkinUnavailableQ.push_back(req);
964+
LL_DEBUGS() << "mSkinReqQ failed: " << req.mId << LL_ENDL;
965+
}
966+
}
967+
}
968+
969+
if (!incomplete.empty())
970+
{
971+
LLMutexLock locker(mMutex);
972+
for (const auto& req : incomplete)
973+
{
974+
mSkinRequests.push_back(req);
975+
}
976+
}
977+
}
978+
}
979+
936980
if (!mLODReqQ.empty() && mHttpRequestSet.size() < sRequestHighWater)
937981
{
938982
std::list<LODRequest> incomplete;
@@ -982,50 +1026,6 @@ void LLMeshRepoThread::run()
9821026
}
9831027
}
9841028

985-
if (mHttpRequestSet.size() < sRequestHighWater
986-
&& !mSkinRequests.empty())
987-
{
988-
if (!mSkinRequests.empty())
989-
{
990-
std::list<UUIDBasedRequest> incomplete;
991-
while (!mSkinRequests.empty() && mHttpRequestSet.size() < sRequestHighWater)
992-
{
993-
994-
mMutex->lock();
995-
auto req = mSkinRequests.front();
996-
mSkinRequests.pop_front();
997-
mMutex->unlock();
998-
if (req.isDelayed())
999-
{
1000-
incomplete.emplace_back(req);
1001-
}
1002-
else if (!fetchMeshSkinInfo(req.mId, req.canRetry()))
1003-
{
1004-
if (req.canRetry())
1005-
{
1006-
req.updateTime();
1007-
incomplete.emplace_back(req);
1008-
}
1009-
else
1010-
{
1011-
LLMutexLock locker(mMutex);
1012-
mSkinUnavailableQ.push_back(req);
1013-
LL_DEBUGS() << "mSkinReqQ failed: " << req.mId << LL_ENDL;
1014-
}
1015-
}
1016-
}
1017-
1018-
if (!incomplete.empty())
1019-
{
1020-
LLMutexLock locker(mMutex);
1021-
for (const auto& req : incomplete)
1022-
{
1023-
mSkinRequests.push_back(req);
1024-
}
1025-
}
1026-
}
1027-
}
1028-
10291029
if (!mHeaderReqQ.empty() && mHttpRequestSet.size() < sRequestHighWater)
10301030
{
10311031
std::list<HeaderRequest> incomplete;
@@ -1234,6 +1234,42 @@ void LLMeshRepoThread::loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
12341234
}
12351235
}
12361236

1237+
void LLMeshRepoThread::loadMeshLODs(const lod_list_t& list)
1238+
{ //could be called from any thread
1239+
LLMutexLock lock(mMutex);
1240+
LLMutexLock header_lock(mHeaderMutex);
1241+
for (auto lod_pair : list)
1242+
{
1243+
const LLVolumeParams& mesh_params = lod_pair.first;
1244+
const LLUUID& mesh_id = mesh_params.getSculptID();
1245+
S32 lod = lod_pair.second;
1246+
mesh_header_map::iterator iter = mMeshHeader.find(mesh_id);
1247+
if (iter != mMeshHeader.end())
1248+
{ // if we have the header, request LOD byte range
1249+
LODRequest req(mesh_params, lod);
1250+
{
1251+
mLODReqQ.push(req);
1252+
LLMeshRepository::sLODProcessing++;
1253+
}
1254+
}
1255+
else
1256+
{
1257+
HeaderRequest req(mesh_params);
1258+
pending_lod_map::iterator pending = mPendingLOD.find(mesh_id);
1259+
if (pending != mPendingLOD.end())
1260+
{ // append this lod request to existing header request
1261+
pending->second.push_back(lod);
1262+
llassert(pending->second.size() <= LLModel::NUM_LODS);
1263+
}
1264+
else
1265+
{ // if no header request is pending, fetch header
1266+
mHeaderReqQ.push(req);
1267+
mPendingLOD[mesh_id].push_back(lod);
1268+
}
1269+
}
1270+
}
1271+
}
1272+
12371273
// Mutex: must be holding mMutex when called
12381274
void LLMeshRepoThread::setGetMeshCap(const std::string & mesh_cap)
12391275
{
@@ -4075,8 +4111,12 @@ void LLMeshRepository::notifyLoadedMeshes()
40754111
mUploadErrorQ.pop();
40764112
}
40774113

4114+
// mPendingRequests go into queues, queues go into active http requests.
4115+
// Checking sRequestHighWater to keep queues at least somewhat populated
4116+
// for faster transition into http
40784117
S32 active_count = LLMeshRepoThread::sActiveHeaderRequests + LLMeshRepoThread::sActiveLODRequests + LLMeshRepoThread::sActiveSkinRequests;
4079-
if (active_count < LLMeshRepoThread::sRequestLowWater)
4118+
active_count += (S32)(mThread->mLODReqQ.size() + mThread->mHeaderReqQ.size() + mThread->mSkinInfoQ.size());
4119+
if (active_count < LLMeshRepoThread::sRequestHighWater)
40804120
{
40814121
S32 push_count = LLMeshRepoThread::sRequestHighWater - active_count;
40824122

@@ -4132,7 +4172,8 @@ void LLMeshRepository::notifyLoadedMeshes()
41324172
std::partial_sort(mPendingRequests.begin(), mPendingRequests.begin() + push_count,
41334173
mPendingRequests.end(), PendingRequestBase::CompareScoreGreater());
41344174
}
4135-
4175+
LLMeshRepoThread::lod_list_t pending_lods; // to avoid locking on each operation, make a list beforehand
4176+
pending_lods.reserve(push_count);
41364177
while (!mPendingRequests.empty() && push_count > 0)
41374178
{
41384179
std::unique_ptr<PendingRequestBase>& req_p = mPendingRequests.front();
@@ -4141,7 +4182,7 @@ void LLMeshRepository::notifyLoadedMeshes()
41414182
case MESH_REQUEST_LOD:
41424183
{
41434184
PendingRequestLOD* lod = (PendingRequestLOD*)req_p.get();
4144-
mThread->loadMeshLOD(lod->mMeshParams, lod->mLOD);
4185+
pending_lods.emplace_back(lod->mMeshParams, lod->mLOD);
41454186
LLMeshRepository::sLODPending--;
41464187
break;
41474188
}
@@ -4159,6 +4200,10 @@ void LLMeshRepository::notifyLoadedMeshes()
41594200
mPendingRequests.erase(mPendingRequests.begin());
41604201
push_count--;
41614202
}
4203+
if (!pending_lods.empty())
4204+
{
4205+
mThread->loadMeshLODs(pending_lods);
4206+
}
41624207
}
41634208

41644209
//send decomposition requests

indra/newview/llmeshrepository.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,9 @@ class LLMeshRepoThread : public LLThread
466466
void lockAndLoadMeshLOD(const LLVolumeParams& mesh_params, S32 lod);
467467
void loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod);
468468

469+
typedef std::vector<std::pair<const LLVolumeParams&, S32> > lod_list_t;
470+
void loadMeshLODs(const lod_list_t& mesh_vect);
471+
469472
bool fetchMeshHeader(const LLVolumeParams& mesh_params, bool can_retry = true);
470473
bool fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, bool can_retry = true);
471474
EMeshProcessingResult headerReceived(const LLVolumeParams& mesh_params, U8* data, S32 data_size);

0 commit comments

Comments
 (0)