summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorAndrey Kleshchev <andreykproductengine@lindenlab.com>2024-11-11 20:53:50 +0200
committerAndrey Kleshchev <andreykproductengine@lindenlab.com>2025-01-28 20:46:52 +0200
commit8f274bfdf9683895a2245b531dc45f4d047d69d6 (patch)
tree9dbd82c92d523e432888ff011fcd623150b433f9 /indra
parent5029f0322f264e17f7509952f7bf9812db17a9ec (diff)
#1186 Make lod and skin request share priorities
skins are needed to decloud avatars as much as lods
Diffstat (limited to 'indra')
-rw-r--r--indra/newview/llmeshrepository.cpp149
-rw-r--r--indra/newview/llmeshrepository.h90
2 files changed, 165 insertions, 74 deletions
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index a5bed1dbe6..4eb1fdc8de 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -925,7 +925,7 @@ void LLMeshRepoThread::run()
}
sRequestWaterLevel = static_cast<S32>(mHttpRequestSet.size()); // Stats data update
- // NOTE: order of queue processing intentionally favors LOD requests over header requests
+ // NOTE: order of queue processing intentionally favors LOD and Skin requests over header requests
// Todo: we are processing mLODReqQ, mHeaderReqQ, mSkinRequests, mDecompositionRequests and mPhysicsShapeRequests
// in relatively similar manners, remake code to simplify/unify the process,
// like processRequests(&requestQ, fetchFunction); which does same thing for each element
@@ -979,6 +979,50 @@ void LLMeshRepoThread::run()
}
}
+ if (mHttpRequestSet.size() < sRequestHighWater
+ && !mSkinRequests.empty())
+ {
+ if (!mSkinRequests.empty())
+ {
+ std::list<UUIDBasedRequest> incomplete;
+ while (!mSkinRequests.empty() && mHttpRequestSet.size() < sRequestHighWater)
+ {
+
+ mMutex->lock();
+ auto req = mSkinRequests.front();
+ mSkinRequests.pop_front();
+ mMutex->unlock();
+ if (req.isDelayed())
+ {
+ incomplete.emplace_back(req);
+ }
+ else if (!fetchMeshSkinInfo(req.mId, req.canRetry()))
+ {
+ if (req.canRetry())
+ {
+ req.updateTime();
+ incomplete.emplace_back(req);
+ }
+ else
+ {
+ LLMutexLock locker(mMutex);
+ mSkinUnavailableQ.push_back(req);
+ LL_DEBUGS() << "mSkinReqQ failed: " << req.mId << LL_ENDL;
+ }
+ }
+ }
+
+ if (!incomplete.empty())
+ {
+ LLMutexLock locker(mMutex);
+ for (const auto& req : incomplete)
+ {
+ mSkinRequests.push_back(req);
+ }
+ }
+ }
+ }
+
if (!mHeaderReqQ.empty() && mHttpRequestSet.size() < sRequestHighWater)
{
std::list<HeaderRequest> incomplete;
@@ -1028,54 +1072,13 @@ void LLMeshRepoThread::run()
// performing long-duration actions.
if (mHttpRequestSet.size() < sRequestHighWater
- && (!mSkinRequests.empty()
- || !mDecompositionRequests.empty()
+ && (!mDecompositionRequests.empty()
|| !mPhysicsShapeRequests.empty()))
{
// Something to do probably, lock and double-check. We don't want
// to hold the lock long here. That will stall main thread activities
// so we bounce it.
- if (!mSkinRequests.empty())
- {
- std::list<UUIDBasedRequest> incomplete;
- while (!mSkinRequests.empty() && mHttpRequestSet.size() < sRequestHighWater)
- {
-
- mMutex->lock();
- auto req = mSkinRequests.front();
- mSkinRequests.pop_front();
- mMutex->unlock();
- if (req.isDelayed())
- {
- incomplete.emplace_back(req);
- }
- else if (!fetchMeshSkinInfo(req.mId, req.canRetry()))
- {
- if (req.canRetry())
- {
- req.updateTime();
- incomplete.emplace_back(req);
- }
- else
- {
- LLMutexLock locker(mMutex);
- mSkinUnavailableQ.push_back(req);
- LL_DEBUGS() << "mSkinReqQ failed: " << req.mId << LL_ENDL;
- }
- }
- }
-
- if (!incomplete.empty())
- {
- LLMutexLock locker(mMutex);
- for (const auto& req : incomplete)
- {
- mSkinRequests.push_back(req);
- }
- }
- }
-
// holding lock, try next list
// *TODO: For UI/debug-oriented lists, we might drop the fine-
// grained locking as there's a lowered expectation of smoothness
@@ -1195,7 +1198,6 @@ void LLMeshRepoThread::lockAndLoadMeshLOD(const LLVolumeParams& mesh_params, S32
}
}
-
void LLMeshRepoThread::loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
{ //could be called from any thread
const LLUUID& mesh_id = mesh_params.getSculptID();
@@ -3738,7 +3740,7 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para
{
//first request for this mesh
mLoadingMeshes[detail][mesh_id].push_back(vobj);
- mPendingRequests.push_back(LLMeshRepoThread::LODRequest(mesh_params, detail));
+ mPendingRequests.push_back(PendingRequestLOD(mesh_params, detail));
LLMeshRepository::sLODPending++;
}
}
@@ -4011,35 +4013,64 @@ void LLMeshRepository::notifyLoadedMeshes()
score_map[iter->first] = max_score;
}
}
+ for (mesh_load_map::iterator iter = mLoadingSkins.begin(); iter != mLoadingSkins.end(); ++iter)
+ {
+ F32 max_score = 0.f;
+ for (auto obj_iter = iter->second.begin(); obj_iter != iter->second.end(); ++obj_iter)
+ {
+ LLVOVolume* object = *obj_iter;
+ if (object)
+ {
+ LLDrawable* drawable = object->mDrawable;
+ if (drawable)
+ {
+ F32 cur_score = drawable->getRadius() / llmax(drawable->mDistanceWRTCamera, 1.f);
+ max_score = llmax(max_score, cur_score);
+ }
+ }
+ }
+
+ score_map[iter->first] = max_score;
+ }
//set "score" for pending requests
- for (std::vector<LLMeshRepoThread::LODRequest>::iterator iter = mPendingRequests.begin(); iter != mPendingRequests.end(); ++iter)
+ for (std::vector<PendingRequestBase>::iterator iter = mPendingRequests.begin(); iter != mPendingRequests.end(); ++iter)
{
- iter->mScore = score_map[iter->mMeshParams.getSculptID()];
+ iter->setScore(score_map[iter->getId()]);
}
//sort by "score"
std::partial_sort(mPendingRequests.begin(), mPendingRequests.begin() + push_count,
- mPendingRequests.end(), LLMeshRepoThread::CompareScoreGreater());
+ mPendingRequests.end(), PendingRequestBase::CompareScoreGreater());
}
while (!mPendingRequests.empty() && push_count > 0)
{
- LLMeshRepoThread::LODRequest& request = mPendingRequests.front();
- mThread->loadMeshLOD(request.mMeshParams, request.mLOD);
+ PendingRequestBase& request = mPendingRequests.front();
+ switch (request.getRequestType())
+ {
+ case MESH_REQUEST_LOD:
+ {
+ PendingRequestLOD& lod = (PendingRequestLOD&)request;
+ mThread->loadMeshLOD(lod.mMeshParams, lod.mLOD);
+ LLMeshRepository::sLODPending--;
+ break;
+ }
+ case MESH_REQUEST_SKIN:
+ {
+ PendingRequestUUID& skin = (PendingRequestUUID&)request;
+ mThread->loadMeshSkinInfo(skin.getId());
+ break;
+ }
+
+ default:
+ break;
+ }
mPendingRequests.erase(mPendingRequests.begin());
- LLMeshRepository::sLODPending--;
push_count--;
}
}
- //send skin info requests
- while (!mPendingSkinRequests.empty())
- {
- mThread->loadMeshSkinInfo(mPendingSkinRequests.front());
- mPendingSkinRequests.pop();
- }
-
//send decomposition requests
while (!mPendingDecompositionRequests.empty())
{
@@ -4231,7 +4262,7 @@ const LLMeshSkinInfo* LLMeshRepository::getSkinInfo(const LLUUID& mesh_id, LLVOV
{
//first request for this mesh
mLoadingSkins[mesh_id].push_back(requesting_obj);
- mPendingSkinRequests.push(mesh_id);
+ mPendingRequests.push_back(PendingRequestUUID(mesh_id, MESH_REQUEST_SKIN));
}
}
}
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index b5c2424578..c5b2a910ce 100644
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -63,6 +63,16 @@ typedef enum e_mesh_processing_result_enum
MESH_UNKNOWN
} EMeshProcessingResult;
+typedef enum e_mesh_request_type_enum
+{
+ MESH_REQUEST_HEADER,
+ MESH_REQUEST_LOD,
+ MESH_REQUEST_SKIN,
+ MESH_REQUEST_DECOMPOSITION,
+ MESH_REQUEST_PHYSICS,
+ MESH_REQUEST_UKNOWN
+} EMeshRequestType;
+
class LLMeshUploadData
{
public:
@@ -183,7 +193,8 @@ public:
class RequestStats
{
public:
- RequestStats() : mRetries(0) {};
+
+ RequestStats() :mRetries(0) {};
void updateTime();
bool canRetry() const;
@@ -195,6 +206,67 @@ private:
LLFrameTimer mTimer;
};
+
+class PendingRequestBase
+{
+public:
+ struct CompareScoreGreater
+ {
+ bool operator()(const PendingRequestBase& lhs, const PendingRequestBase& rhs)
+ {
+ return lhs.mScore > rhs.mScore; // greatest = first
+ }
+ };
+
+ PendingRequestBase() : mScore(0.f) {};
+ virtual ~PendingRequestBase() {}
+
+ bool operator<(const PendingRequestBase& rhs) const
+ {
+ return mId < rhs.mId;
+ }
+
+ void setScore(F32 score) { mScore = score; }
+ F32 getScore() const { return mScore; }
+ LLUUID getId() const { return mId; }
+ virtual EMeshRequestType getRequestType() const { return MESH_REQUEST_UKNOWN; }
+
+protected:
+ F32 mScore;
+ LLUUID mId;
+};
+
+class PendingRequestLOD : public PendingRequestBase
+{
+public:
+ LLVolumeParams mMeshParams;
+ S32 mLOD;
+
+ PendingRequestLOD(const LLVolumeParams& mesh_params, S32 lod)
+ : PendingRequestBase(), mMeshParams(mesh_params), mLOD(lod)
+ {
+ mId = mMeshParams.getSculptID();
+ }
+
+ EMeshRequestType getRequestType() const override { return MESH_REQUEST_LOD; }
+};
+
+class PendingRequestUUID : public PendingRequestBase
+{
+public:
+
+ PendingRequestUUID(const LLUUID& id, EMeshRequestType type)
+ : PendingRequestBase(), mRequestType(type)
+ {
+ mId = id;
+ }
+
+ EMeshRequestType getRequestType() const override { return mRequestType; }
+
+private:
+ EMeshRequestType mRequestType;
+};
+
class LLMeshHeader
{
public:
@@ -292,22 +364,13 @@ public:
public:
LLVolumeParams mMeshParams;
S32 mLOD;
- F32 mScore;
LODRequest(const LLVolumeParams& mesh_params, S32 lod)
- : RequestStats(), mMeshParams(mesh_params), mLOD(lod), mScore(0.f)
+ : RequestStats(), mMeshParams(mesh_params), mLOD(lod)
{
}
};
- struct CompareScoreGreater
- {
- bool operator()(const LODRequest& lhs, const LODRequest& rhs)
- {
- return lhs.mScore > rhs.mScore; // greatest = first
- }
- };
-
class UUIDBasedRequest : public RequestStats
{
public:
@@ -695,15 +758,12 @@ public:
LLMutex* mMeshMutex;
- std::vector<LLMeshRepoThread::LODRequest> mPendingRequests;
+ std::vector<PendingRequestBase> mPendingRequests;
//list of mesh ids awaiting skin info
typedef boost::unordered_map<LLUUID, std::vector<LLVOVolume*> > skin_load_map;
skin_load_map mLoadingSkins;
- //list of mesh ids that need to send skin info fetch requests
- std::queue<LLUUID> mPendingSkinRequests;
-
//list of mesh ids awaiting decompositions
std::unordered_set<LLUUID> mLoadingDecompositions;