summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorAndrey Kleshchev <andreykproductengine@lindenlab.com>2024-12-05 01:32:54 +0200
committerAndrey Kleshchev <andreykproductengine@lindenlab.com>2025-01-28 20:48:44 +0200
commita428b7dfbd7d5b766b2ae6e4fbd2c8c510ee19a1 (patch)
tree793a39ef6d97e3c26b1cf242874e4c65a45aa679 /indra
parente20f4c0e4f10151bb5e5f208ea49b6065dd667ca (diff)
#1186 Improve handling of duplciate requests
Diffstat (limited to 'indra')
-rw-r--r--indra/newview/llmeshrepository.cpp100
-rw-r--r--indra/newview/llmeshrepository.h5
2 files changed, 59 insertions, 46 deletions
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index f58ceae852..e098ce80bc 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -1109,7 +1109,7 @@ void LLMeshRepoThread::run()
}
else
{
- LL_DEBUGS() << "mDecompositionRequests failed: " << req.mId << LL_ENDL;
+ LL_DEBUGS(LOG_MESH) << "mDecompositionRequests failed: " << req.mId << LL_ENDL;
}
}
}
@@ -1145,7 +1145,7 @@ void LLMeshRepoThread::run()
}
else
{
- LL_DEBUGS() << "mPhysicsShapeRequests failed: " << req.mId << LL_ENDL;
+ LL_DEBUGS(LOG_MESH) << "mPhysicsShapeRequests failed: " << req.mId << LL_ENDL;
}
}
}
@@ -1206,6 +1206,25 @@ void LLMeshRepoThread::loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
const LLUUID& mesh_id = mesh_params.getSculptID();
LLMutexLock lock(mMutex);
LLMutexLock header_lock(mHeaderMutex);
+ loadMeshLOD(mesh_id, mesh_params, lod);
+}
+
+void LLMeshRepoThread::loadMeshLODs(const lod_list_t& list)
+{ //could be called from any thread
+ LLMutexLock lock(mMutex);
+ LLMutexLock header_lock(mHeaderMutex);
+ for (auto lod_pair : list)
+ {
+ const LLVolumeParams& mesh_params = lod_pair.first;
+ const LLUUID& mesh_id = mesh_params.getSculptID();
+ S32 lod = lod_pair.second;
+ loadMeshLOD(mesh_id, mesh_params, lod);
+ }
+}
+
+void LLMeshRepoThread::loadMeshLOD(const LLUUID& mesh_id, const LLVolumeParams& mesh_params, S32 lod)
+{
+ // must be mutex locked by caller
mesh_header_map::iterator iter = mMeshHeader.find(mesh_id);
if (iter != mMeshHeader.end())
{ //if we have the header, request LOD byte range
@@ -1222,50 +1241,25 @@ void LLMeshRepoThread::loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
pending_lod_map::iterator pending = mPendingLOD.find(mesh_id);
if (pending != mPendingLOD.end())
- { //append this lod request to existing header request
- pending->second.push_back(lod);
- llassert(pending->second.size() <= LLModel::NUM_LODS);
- }
- else
- { //if no header request is pending, fetch header
- mHeaderReqQ.push(req);
- mPendingLOD[mesh_id].push_back(lod);
- }
- }
-}
-
-void LLMeshRepoThread::loadMeshLODs(const lod_list_t& list)
-{ //could be called from any thread
- LLMutexLock lock(mMutex);
- LLMutexLock header_lock(mHeaderMutex);
- for (auto lod_pair : list)
- {
- const LLVolumeParams& mesh_params = lod_pair.first;
- const LLUUID& mesh_id = mesh_params.getSculptID();
- S32 lod = lod_pair.second;
- mesh_header_map::iterator iter = mMeshHeader.find(mesh_id);
- if (iter != mMeshHeader.end())
- { // if we have the header, request LOD byte range
- LODRequest req(mesh_params, lod);
+ {
+ //append this lod request to existing header request
+ if (lod < LLModel::NUM_LODS && lod >= 0)
{
- mLODReqQ.push(req);
- LLMeshRepository::sLODProcessing++;
+ pending->second[lod]++;
}
+ else
+ {
+ LL_WARNS(LOG_MESH) << "Invalid LOD request: " << lod << "for mesh" << mesh_id << LL_ENDL;
+ }
+ llassert_msg(lod < LLModel::NUM_LODS, "Requested lod is out of bounds");
}
else
{
- HeaderRequest req(mesh_params);
- pending_lod_map::iterator pending = mPendingLOD.find(mesh_id);
- if (pending != mPendingLOD.end())
- { // append this lod request to existing header request
- pending->second.push_back(lod);
- llassert(pending->second.size() <= LLModel::NUM_LODS);
- }
- else
- { // if no header request is pending, fetch header
- mHeaderReqQ.push(req);
- mPendingLOD[mesh_id].push_back(lod);
- }
+ //if no header request is pending, fetch header
+ mHeaderReqQ.push(req);
+ auto& array = mPendingLOD[mesh_id];
+ std::fill(array.begin(), array.end(), 0);
+ array[lod]++;
}
}
}
@@ -2024,11 +2018,27 @@ EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mes
pending_lod_map::iterator iter = mPendingLOD.find(mesh_id);
if (iter != mPendingLOD.end())
{
- for (U32 i = 0; i < iter->second.size(); ++i)
+ for (S32 i = 0; i < iter->second.size(); ++i)
{
- LODRequest req(mesh_params, iter->second[i]);
- mLODReqQ.push(req);
- LLMeshRepository::sLODProcessing++;
+ if (iter->second[i] > 1)
+ {
+ // mLoadingMeshes should be protecting from dupplciates, but looks
+ // like this is possible if object rezzes, unregisterMesh, then
+ // rezzes again before first request completes.
+ // mLoadingMeshes might need to change a bit to not rerequest if
+ // mesh is already pending.
+ //
+ // Todo: Improve mLoadingMeshes and once done turn this into an assert.
+ // Low priority since such situation should be relatively rare
+ LL_INFOS(LOG_MESH) << "Multiple dupplicate requests for mesd ID: " << mesh_id << " LOD: " << i
+ << LL_ENDL;
+ }
+ if (iter->second[i] > 0)
+ {
+ LODRequest req(mesh_params, i);
+ mLODReqQ.push(req);
+ LLMeshRepository::sLODProcessing++;
+ }
}
mPendingLOD.erase(iter);
}
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index 8ced9a7ef6..703f4cf9ce 100644
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -433,7 +433,7 @@ public:
std::deque<LoadedMesh> mLoadedQ;
//map of pending header requests and currently desired LODs
- typedef std::unordered_map<LLUUID, std::vector<S32> > pending_lod_map;
+ typedef std::unordered_map<LLUUID, std::array<S32, LLModel::NUM_LODS> > pending_lod_map;
pending_lod_map mPendingLOD;
// map of mesh ID to skin info (mirrors LLMeshRepository::mSkinMap)
@@ -525,6 +525,9 @@ private:
LLCore::HttpHandle getByteRange(const std::string & url,
size_t offset, size_t len,
const LLCore::HttpHandler::ptr_t &handler);
+
+ // Mutex: mMutex must be alerady locked when calling
+ void loadMeshLOD(const LLUUID &mesh_id, const LLVolumeParams& mesh_params, S32 lod);
};