#1186 Make lod and skin request share priorities
skins are needed to decloud avatars as much as lodsmeow-7.2.2
parent
5029f0322f
commit
8f274bfdf9
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue