diff options
Diffstat (limited to 'indra/newview')
| -rw-r--r-- | indra/newview/llmeshrepository.cpp | 189 | ||||
| -rw-r--r-- | indra/newview/llmeshrepository.h | 68 | 
2 files changed, 145 insertions, 112 deletions
| diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 663afe64a9..851107b3be 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -544,6 +544,66 @@ bool RequestStats::isDelayed() const      return mTimer.getStarted() && !mTimer.hasExpired();  } +F32 calculate_score(LLVOVolume* object) +{ +    if (!object) +    { +        return -1.f; +    } +    LLDrawable* drawable = object->mDrawable; +    if (!drawable) +    { +        return -1; +    } +    if (drawable->isState(LLDrawable::RIGGED) || object->isAttachment()) +    { +        LLVOAvatar* avatar = object->getAvatar(); +        LLDrawable* av_drawable = avatar ? avatar->mDrawable : nullptr; +        if (avatar && av_drawable) +        { +            // See LLVOVolume::calcLOD() +            F32 radius; +            if (avatar->isControlAvatar()) +            { +                const LLVector3* box = avatar->getLastAnimExtents(); +                LLVector3 diag = box[1] - box[0]; +                radius = diag.magVec() * 0.5f; +            } +            else +            { +                // Volume in a rigged mesh attached to a regular avatar. +                const LLVector3* box = avatar->getLastAnimExtents(); +                LLVector3 diag = box[1] - box[0]; +                radius = diag.magVec(); + +                if (!avatar->isSelf() && !avatar->hasFirstFullAttachmentData()) +                { +                    // slightly deprioritize avatars that are still receiving data +                    radius *= 0.9f; +                } +            } +            return radius / llmax(av_drawable->mDistanceWRTCamera, 1.f); +        } +    } +    return drawable->getRadius() / llmax(drawable->mDistanceWRTCamera, 1.f); +} + +void PendingRequestBase::updateScore() +{ +    mScore = 0; +    if (mTrackedData) +    { +        for (LLVOVolume* volume : mTrackedData->mVolumes) +        { +            F32 cur_score = calculate_score(volume); +            if (cur_score > 0) +            { +                mScore = llmax(mScore, cur_score); +            } +        } +    } +} +  LLViewerFetchedTexture* LLMeshUploadThread::FindViewerTexture(const LLImportMaterial& material)  {      LLPointer< LLViewerFetchedTexture > * ppTex = static_cast< LLPointer< LLViewerFetchedTexture > * >(material.mOpaqueData); @@ -2220,7 +2280,7 @@ EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mes                  if (gMeshRepo.mLoadingSkins.find(mesh_id) == gMeshRepo.mLoadingSkins.end())                  { -                    gMeshRepo.mLoadingSkins[mesh_id] = {}; // add an empty vector to indicate to main thread that we are loading skin info +                    gMeshRepo.mLoadingSkins[mesh_id]; // add an empty vector to indicate to main thread that we are loading skin info                  }              } @@ -4212,13 +4272,13 @@ void LLMeshRepository::unregisterMesh(LLVOVolume* vobj)      {          for (auto& param : lod)          { -            vector_replace_with_last(param.second, vobj); +            vector_replace_with_last(param.second.mVolumes, vobj);          }      }      for (auto& skin_pair : mLoadingSkins)      { -        vector_replace_with_last(skin_pair.second, vobj); +        vector_replace_with_last(skin_pair.second.mVolumes, vobj);      }  } @@ -4241,16 +4301,17 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para          mesh_load_map::iterator iter = mLoadingMeshes[new_lod].find(mesh_id);          if (iter != mLoadingMeshes[new_lod].end())          { //request pending for this mesh, append volume id to list -            auto it = std::find(iter->second.begin(), iter->second.end(), vobj); -            if (it == iter->second.end()) { -                iter->second.push_back(vobj); +            auto it = std::find(iter->second.mVolumes.begin(), iter->second.mVolumes.end(), vobj); +            if (it == iter->second.mVolumes.end()) { +                iter->second.addVolume(vobj);              }          }          else          {              //first request for this mesh -            mLoadingMeshes[new_lod][mesh_id].push_back(vobj); -            mPendingRequests.emplace_back(new PendingRequestLOD(mesh_params, new_lod)); +            std::shared_ptr<PendingRequestBase> request(new PendingRequestLOD(mesh_params, new_lod)); +            mPendingRequests.emplace_back(request); +            mLoadingMeshes[new_lod][mesh_id].initData(vobj, request);              LLMeshRepository::sLODPending++;          }      } @@ -4309,50 +4370,6 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para      return new_lod;  } -F32 calculate_score(LLVOVolume* object) -{ -    if (!object) -    { -        return -1.f; -    } -    LLDrawable* drawable = object->mDrawable; -    if (!drawable) -    { -        return -1; -    } -    if (drawable->isState(LLDrawable::RIGGED) || object->isAttachment()) -    { -        LLVOAvatar* avatar = object->getAvatar(); -        LLDrawable* av_drawable = avatar ? avatar->mDrawable : nullptr; -        if (avatar && av_drawable) -        { -            // See LLVOVolume::calcLOD() -            F32 radius; -            if (avatar->isControlAvatar()) -            { -                const LLVector3* box = avatar->getLastAnimExtents(); -                LLVector3 diag = box[1] - box[0]; -                radius = diag.magVec() * 0.5f; -            } -            else -            { -                // Volume in a rigged mesh attached to a regular avatar. -                const LLVector3* box = avatar->getLastAnimExtents(); -                LLVector3 diag = box[1] - box[0]; -                radius = diag.magVec(); - -                if (!avatar->isSelf() && !avatar->hasFirstFullAttachmentData()) -                { -                    // slightly deprioritize avatars that are still receiving data -                    radius *= 0.9f; -                } -            } -            return radius / llmax(av_drawable->mDistanceWRTCamera, 1.f); -        } -    } -    return drawable->getRadius() / llmax(drawable->mDistanceWRTCamera, 1.f); -} -  void LLMeshRepository::notifyLoadedMeshes()  { //called from main thread      LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; //LL_RECORD_BLOCK_TIME(FTM_MESH_FETCH); @@ -4549,51 +4566,14 @@ void LLMeshRepository::notifyLoadedMeshes()              if (mPendingRequests.size() > push_count)              { -                LL_PROFILE_ZONE_NAMED("Mesh score_map"); +                LL_PROFILE_ZONE_NAMED("Mesh score update");                  // More requests than the high-water limit allows so                  // sort and forward the most important. -                //calculate "score" for pending requests - -                //create score map -                std::map<LLUUID, F32> score_map; - -                for (U32 i = 0; i < LLVolumeLODGroup::NUM_LODS; ++i) -                { -                    for (mesh_load_map::iterator iter = mLoadingMeshes[i].begin();  iter != mLoadingMeshes[i].end(); ++iter) -                    { -                        F32 max_score = 0.f; -                        for (auto obj_iter = iter->second.begin(); obj_iter != iter->second.end(); ++obj_iter) -                        { -                            F32 cur_score = calculate_score(*obj_iter); -                            if (cur_score >= 0.f) -                            { -                                max_score = llmax(max_score, cur_score); -                            } -                        } - -                        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) -                    { -                        F32 cur_score = calculate_score(*obj_iter); -                        if (cur_score >= 0.f) -                        { -                            max_score = llmax(max_score, cur_score); -                        } -                    } - -                    score_map[iter->first] = max_score; -                } - -                //set "score" for pending requests -                for (std::unique_ptr<PendingRequestBase>& req_p : mPendingRequests) +                // update "score" for pending requests +                for (std::shared_ptr<PendingRequestBase>& req_p : mPendingRequests)                  { -                    req_p->setScore(score_map[req_p->getId()]); +                    req_p->checkScore();                  }                  //sort by "score" @@ -4602,7 +4582,9 @@ void LLMeshRepository::notifyLoadedMeshes()              }              while (!mPendingRequests.empty() && push_count > 0)              { -                std::unique_ptr<PendingRequestBase>& req_p = mPendingRequests.front(); +                std::shared_ptr<PendingRequestBase>& req_p = mPendingRequests.front(); +                // todo: check hasTrackedData here and erase request if none +                // since this is supposed to mean that request was removed                  switch (req_p->getRequestType())                  {                  case MESH_REQUEST_LOD: @@ -4657,7 +4639,7 @@ void LLMeshRepository::notifySkinInfoReceived(LLMeshSkinInfo* info)      skin_load_map::iterator iter = mLoadingSkins.find(info->mMeshID);      if (iter != mLoadingSkins.end())      { -        for (LLVOVolume* vobj : iter->second) +        for (LLVOVolume* vobj : iter->second.mVolumes)          {              if (vobj)              { @@ -4673,7 +4655,7 @@ void LLMeshRepository::notifySkinInfoUnavailable(const LLUUID& mesh_id)      skin_load_map::iterator iter = mLoadingSkins.find(mesh_id);      if (iter != mLoadingSkins.end())      { -        for (LLVOVolume* vobj : iter->second) +        for (LLVOVolume* vobj : iter->second.mVolumes)          {              if (vobj)              { @@ -4737,7 +4719,7 @@ void LLMeshRepository::notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVol          }          //notify waiting LLVOVolume instances that their requested mesh is available -        for (LLVOVolume* vobj : obj_iter->second) +        for (LLVOVolume* vobj : obj_iter->second.mVolumes)          {              if (vobj)              { @@ -4767,7 +4749,7 @@ void LLMeshRepository::notifyMeshUnavailable(const LLVolumeParams& mesh_params,              LLPrimitive::getVolumeManager()->unrefVolume(sys_volume);          } -        for (LLVOVolume* vobj : obj_iter->second) +        for (LLVOVolume* vobj : obj_iter->second.mVolumes)          {              if (vobj)              { @@ -4810,16 +4792,17 @@ const LLMeshSkinInfo* LLMeshRepository::getSkinInfo(const LLUUID& mesh_id, LLVOV              skin_load_map::iterator iter = mLoadingSkins.find(mesh_id);              if (iter != mLoadingSkins.end())              { //request pending for this mesh, append volume id to list -                auto it = std::find(iter->second.begin(), iter->second.end(), requesting_obj); -                if (it == iter->second.end()) { -                    iter->second.push_back(requesting_obj); +                auto it = std::find(iter->second.mVolumes.begin(), iter->second.mVolumes.end(), requesting_obj); +                if (it == iter->second.mVolumes.end()) { +                    iter->second.addVolume(requesting_obj);                  }              }              else              {                  //first request for this mesh -                mLoadingSkins[mesh_id].push_back(requesting_obj); -                mPendingRequests.emplace_back(new PendingRequestUUID(mesh_id, MESH_REQUEST_SKIN)); +                std::shared_ptr<PendingRequestBase> request(new PendingRequestUUID(mesh_id, MESH_REQUEST_SKIN)); +                mLoadingSkins[mesh_id].initData(requesting_obj, request); +                mPendingRequests.emplace_back(request);              }          }      } diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index b9acb3573f..0847c29d0d 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -168,7 +168,6 @@ public:      void submitRequest(Request* request);      static S32 llcdCallback(const char*, S32, S32); -    void cancel();      void setMeshData(LLCDMeshData& mesh, bool vertex_based);      void doDecomposition(); @@ -206,19 +205,19 @@ private:      LLFrameTimer mTimer;  }; - +class MeshLoadData;  class PendingRequestBase  {  public:      struct CompareScoreGreater      { -        bool operator()(const std::unique_ptr<PendingRequestBase>& lhs, const std::unique_ptr<PendingRequestBase>& rhs) +        bool operator()(const std::shared_ptr<PendingRequestBase>& lhs, const std::shared_ptr<PendingRequestBase>& rhs)          {              return lhs->mScore > rhs->mScore; // greatest = first          }      }; -    PendingRequestBase() : mScore(0.f) {}; +    PendingRequestBase() : mScore(0.f), mTrackedData(nullptr), mScoreDirty(true) {};      virtual ~PendingRequestBase() {}      bool operator<(const PendingRequestBase& rhs) const @@ -226,14 +225,34 @@ public:          return mId < rhs.mId;      } -    void setScore(F32 score) { mScore = score; }      F32 getScore() const { return mScore; } +    void checkScore() +    { +        constexpr F32 EXPIRE_TIME_SECS = 8.f; +        if (mScoreTimer.getElapsedTimeF32() > EXPIRE_TIME_SECS || mScoreDirty) +        { +            updateScore(); +            mScoreDirty = false; +            mScoreTimer.reset(); +        } +    }; +      LLUUID getId() const { return mId; }      virtual EMeshRequestType getRequestType() const = 0; +    void trackData(MeshLoadData* data) { mTrackedData = data; mScoreDirty = true; } +    void untrackData() { mTrackedData = nullptr; } +    bool hasTrackedData() { return mTrackedData != nullptr; } +    void setScoreDirty() { mScoreDirty = true; } +  protected: -    F32 mScore; +    void updateScore(); +      LLUUID mId; +    F32 mScore; +    bool mScoreDirty; +    LLTimer mScoreTimer; +    MeshLoadData* mTrackedData;  };  class PendingRequestLOD : public PendingRequestBase @@ -267,6 +286,37 @@ private:      EMeshRequestType mRequestType;  }; + +class MeshLoadData +{ +public: +    MeshLoadData() {} +    ~MeshLoadData() +    { +        if (std::shared_ptr<PendingRequestBase> request = mRequest.lock()) +        { +            request->untrackData(); +        } +    } +    void initData(LLVOVolume* vol, std::shared_ptr<PendingRequestBase>& request) +    { +        mVolumes.push_back(vol); +        request->trackData(this); +        mRequest = request; +    } +    void addVolume(LLVOVolume* vol) +    { +        mVolumes.push_back(vol); +        if (std::shared_ptr<PendingRequestBase> request = mRequest.lock()) +        { +            request->setScoreDirty(); +        } +    } +    std::vector<LLVOVolume*> mVolumes; +private: +    std::weak_ptr<PendingRequestBase> mRequest; +}; +  class LLMeshHeader  {  public: @@ -814,7 +864,7 @@ public:      static void metricsProgress(unsigned int count);      static void metricsUpdate(); -    typedef std::unordered_map<LLUUID, std::vector<LLVOVolume*> > mesh_load_map; +    typedef std::unordered_map<LLUUID, MeshLoadData> mesh_load_map;      mesh_load_map mLoadingMeshes[4];      typedef std::unordered_map<LLUUID, LLPointer<LLMeshSkinInfo>> skin_map; @@ -825,11 +875,11 @@ public:      LLMutex*                    mMeshMutex; -    typedef std::vector <std::unique_ptr<PendingRequestBase> > pending_requests_vec; +    typedef std::vector <std::shared_ptr<PendingRequestBase> > pending_requests_vec;      pending_requests_vec mPendingRequests;      //list of mesh ids awaiting skin info -    typedef std::unordered_map<LLUUID, std::vector<LLVOVolume*> > skin_load_map; +    typedef std::unordered_map<LLUUID, MeshLoadData > skin_load_map;      skin_load_map mLoadingSkins;      //list of mesh ids awaiting decompositions | 
