diff options
| -rw-r--r-- | indra/newview/llmeshrepository.cpp | 149 | ||||
| -rw-r--r-- | indra/newview/llmeshrepository.h | 90 | 
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;  | 
