diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 0ed10789ad404d1cd76b7d811712992d7a4fb5e6..ac41d87a5095020aae03ce89befda24bfadccf68 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -247,7 +247,6 @@ // sActiveLODRequests mMutex rw.any.mMutex, ro.repo.none [1] // sMaxConcurrentRequests mMutex wo.main.none, ro.repo.none, ro.main.mMutex // mMeshHeader mHeaderMutex rw.repo.mHeaderMutex, ro.main.mHeaderMutex, ro.main.none [0] -// mMeshHeaderSize mHeaderMutex rw.repo.mHeaderMutex // mSkinReqQ mMutex rw.repo.mMutex, ro.repo.none [5] // mSkinUnavailableQ mMutex rw.repo.mMutex, ro.repo.none [5] // mSkinInfoQ mMutex rw.repo.mMutex, rw.main.mMutex [5] (was: [0]) @@ -1192,18 +1191,20 @@ void LLMeshRepoThread::loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod) HeaderRequest req(mesh_params); + const LLUUID& mesh_id = mesh_params.getSculptID(); + LLMutexLock lock(mMutex); - pending_lod_map::iterator pending = mPendingLOD.find(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); + pending->second.emplace_back(lod); llassert(pending->second.size() <= LLModel::NUM_LODS); } else { //if no header request is pending, fetch header mHeaderReqQ.push(req); - mPendingLOD[mesh_params].push_back(lod); + mPendingLOD[mesh_id].emplace_back(lod); } } } @@ -1326,11 +1327,11 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id, bool can_retry) ++LLMeshRepository::sMeshRequestCount; bool ret = true; - U32 header_size = mMeshHeaderSize[mesh_id]; + U32 header_size = header_it->second.first; if (header_size > 0) { - const auto& header = header_it->second; + const auto& header = header_it->second.second; S32 version = header["version"].asInteger(); S32 offset = header_size + header["skin"]["offset"].asInteger(); S32 size = header["skin"]["size"].asInteger(); @@ -1438,12 +1439,12 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id) } ++LLMeshRepository::sMeshRequestCount; - U32 header_size = mMeshHeaderSize[mesh_id]; + U32 header_size = header_it->second.first; bool ret = true; if (header_size > 0) { - const auto& header = header_it->second; + const auto& header = header_it->second.second; S32 version = header["version"].asInteger(); S32 offset = header_size + header["physics_convex"]["offset"].asInteger(); S32 size = header["physics_convex"]["size"].asInteger(); @@ -1537,12 +1538,12 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id) } ++LLMeshRepository::sMeshRequestCount; - U32 header_size = mMeshHeaderSize[mesh_id]; + U32 header_size = header_it->second.first; bool ret = true; if (header_size > 0) { - const auto& header = header_it->second; + const auto& header = header_it->second.second; S32 version = header["version"].asInteger(); S32 offset = header_size + header["physics_mesh"]["offset"].asInteger(); S32 size = header["physics_mesh"]["size"].asInteger(); @@ -1728,10 +1729,10 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, ++LLMeshRepository::sMeshRequestCount; bool retval = true; - U32 header_size = mMeshHeaderSize[mesh_id]; + U32 header_size = header_it->second.first; if (header_size > 0) { - const auto& header = header_it->second; + const auto& header = header_it->second.second; S32 version = header["version"].asInteger(); S32 offset = header_size + header[header_lod[lod]]["offset"].asInteger(); S32 size = header[header_lod[lod]]["size"].asInteger(); @@ -1889,15 +1890,14 @@ EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mes { LLMutexLock lock(mHeaderMutex); - mMeshHeaderSize[mesh_id] = header_size; - mMeshHeader[mesh_id] = header; + mMeshHeader[mesh_id] = { header_size, header }; } LLMutexLock lock(mMutex); // make sure only one thread access mPendingLOD at the same time. //check for pending requests - pending_lod_map::iterator iter = mPendingLOD.find(mesh_params); + pending_lod_map::iterator iter = mPendingLOD.find(mesh_id); if (iter != mPendingLOD.end()) { for (U32 i = 0; i < iter->second.size(); ++i) @@ -3007,7 +3007,7 @@ S32 LLMeshRepoThread::getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lo if (iter != mMeshHeader.end()) { - LLSD& header = iter->second; + LLSD& header = iter->second.second; return LLMeshRepository::getActualMeshLOD(header, lod); } @@ -3025,7 +3025,7 @@ S32 LLMeshRepository::getActualMeshLOD(LLSD& header, S32 lod) return -1; } - S32 version = header["version"]; + S32 version = header["version"].asInteger(); if (version > MAX_MESH_VERSION) { @@ -3060,27 +3060,6 @@ S32 LLMeshRepository::getActualMeshLOD(LLSD& header, S32 lod) return -1; } -void LLMeshRepository::cacheOutgoingMesh(LLMeshUploadData& data, LLSD& header) -{ - mThread->mMeshHeader[data.mUUID] = header; - - // we cache the mesh for default parameters - LLVolumeParams volume_params; - volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE); - volume_params.setSculptID(data.mUUID, LL_SCULPT_TYPE_MESH); - - for (U32 i = 0; i < 4; i++) - { - if (data.mModel[i].notNull()) - { - LLPointer<LLVolume> volume = new LLVolume(volume_params, LLVolumeLODGroup::getVolumeScaleFromDetail(i)); - volume->copyVolumeFaces(data.mModel[i]); - volume->setMeshAssetLoaded(TRUE); - } - } - -} - // Handle failed or successful requests for mesh assets. // // Support for 200 responses was added for several reasons. One, @@ -3273,8 +3252,8 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b LLMeshRepoThread::mesh_header_map::iterator iter = gMeshRepo.mThread->mMeshHeader.find(mesh_id); if (iter != gMeshRepo.mThread->mMeshHeader.end()) { - header_bytes = (S32)gMeshRepo.mThread->mMeshHeaderSize[mesh_id]; - header = iter->second; + header_bytes = (S32)iter->second.first; + header = iter->second.second; } if (header_bytes > 0 @@ -3316,7 +3295,7 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b file.write(data, data_size); // zero out the rest of the file - U8 block[MESH_HEADER_SIZE] = {0}; + U8 block[MESH_HEADER_SIZE] = {}; while (bytes-file.tell() > sizeof(block)) { @@ -3699,7 +3678,7 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para { LLMutexLock lock(mMeshMutex); //add volume to list of loading meshes - mesh_load_map::iterator iter = mLoadingMeshes[detail].find(mesh_params); + mesh_load_map::iterator iter = mLoadingMeshes[detail].find(mesh_params.getSculptID()); if (iter != mLoadingMeshes[detail].end()) { //request pending for this mesh, append volume id to list auto it = std::find(iter->second.begin(), iter->second.end(), vobj); @@ -3710,7 +3689,7 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para else { //first request for this mesh - mLoadingMeshes[detail][mesh_params].push_back(vobj); + mLoadingMeshes[detail][mesh_params.getSculptID()].push_back(vobj); mPendingRequests.emplace_back(mesh_params, detail); LLMeshRepository::sLODPending++; } @@ -3815,8 +3794,8 @@ void LLMeshRepository::notifyLoadedMeshes() { inventory_data& data = mInventoryQ.front(); - LLAssetType::EType asset_type = LLAssetType::lookup(data.mPostData["asset_type"].asStringRef()); - LLInventoryType::EType inventory_type = LLInventoryType::lookup(data.mPostData["inventory_type"].asStringRef()); + LLAssetType::EType asset_type = LLAssetType::lookup(data.mPostData["asset_type"].asString()); + LLInventoryType::EType inventory_type = LLInventoryType::lookup(data.mPostData["inventory_type"].asString()); // Handle addition of texture, if any. if ( data.mResponse.has("new_texture_folder_id") ) @@ -3931,7 +3910,7 @@ void LLMeshRepository::notifyLoadedMeshes() //calculate "score" for pending requests //create score map - std::map<LLUUID, F32> score_map; + absl::flat_hash_map<LLUUID, F32> score_map; for (const auto& lod : mLoadingMeshes) { @@ -3947,7 +3926,7 @@ void LLMeshRepository::notifyLoadedMeshes() } } - score_map[param.first.getSculptID()] = max_score; + score_map[param.first] = max_score; } } @@ -4054,7 +4033,7 @@ void LLMeshRepository::notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVol S32 detail = LLVolumeLODGroup::getVolumeDetailFromScale(volume->getDetail()); //get list of objects waiting to be notified this mesh is loaded - mesh_load_map::iterator obj_iter = mLoadingMeshes[detail].find(mesh_params); + mesh_load_map::iterator obj_iter = mLoadingMeshes[detail].find(mesh_params.getSculptID()); if (volume && obj_iter != mLoadingMeshes[detail].end()) { @@ -4096,7 +4075,7 @@ void LLMeshRepository::notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVol void LLMeshRepository::notifyMeshUnavailable(const LLVolumeParams& mesh_params, S32 lod) { //called from main thread //get list of objects waiting to be notified this mesh is loaded - mesh_load_map::iterator obj_iter = mLoadingMeshes[lod].find(mesh_params); + mesh_load_map::iterator obj_iter = mLoadingMeshes[lod].find(mesh_params.getSculptID()); if (obj_iter != mLoadingMeshes[lod].end()) { @@ -4262,16 +4241,13 @@ bool LLMeshRepository::hasPhysicsShape(const LLUUID& mesh_id) bool LLMeshRepoThread::hasPhysicsShapeInHeader(const LLUUID& mesh_id) { LLMutexLock lock(mHeaderMutex); - if (mMeshHeaderSize[mesh_id] > 0) + mesh_header_map::iterator iter = mMeshHeader.find(mesh_id); + if (iter != mMeshHeader.end() && iter->second.first > 0) { - mesh_header_map::iterator iter = mMeshHeader.find(mesh_id); - if (iter != mMeshHeader.end()) + LLSD &mesh = iter->second.second; + if (mesh.has("physics_mesh") && mesh["physics_mesh"].has("size") && (mesh["physics_mesh"]["size"].asInteger() > 0)) { - LLSD &mesh = iter->second; - if (mesh.has("physics_mesh") && mesh["physics_mesh"].has("size") && (mesh["physics_mesh"]["size"].asInteger() > 0)) - { - return true; - } + return true; } } @@ -4296,9 +4272,9 @@ S32 LLMeshRepository::getMeshSize(const LLUUID& mesh_id, S32 lod) { LLMutexLock lock(mThread->mHeaderMutex); LLMeshRepoThread::mesh_header_map::iterator iter = mThread->mMeshHeader.find(mesh_id); - if (iter != mThread->mMeshHeader.end() && mThread->mMeshHeaderSize[mesh_id] > 0) + if (iter != mThread->mMeshHeader.end() && iter->second.first > 0) { - LLSD& header = iter->second; + const LLSD& header = iter->second.second; if (header.has("404")) { @@ -4402,9 +4378,9 @@ F32 LLMeshRepository::getStreamingCostLegacy(LLUUID mesh_id, F32 radius, S32* by { LLMutexLock lock(mThread->mHeaderMutex); LLMeshRepoThread::mesh_header_map::iterator iter = mThread->mMeshHeader.find(mesh_id); - if (iter != mThread->mMeshHeader.end() && mThread->mMeshHeaderSize[mesh_id] > 0) + if (iter != mThread->mMeshHeader.end() && iter->second.first > 0) { - result = getStreamingCostLegacy(iter->second, radius, bytes, bytes_visible, lod, unscaled_value); + result = getStreamingCostLegacy(iter->second.second, radius, bytes, bytes_visible, lod, unscaled_value); } } if (result > 0.f) @@ -4545,7 +4521,8 @@ F32 LLMeshRepository::getStreamingCostLegacy(LLSD& header, F32 radius, S32* byte *unscaled_value = weighted_avg; } - return weighted_avg/gSavedSettings.getU32("MeshTriangleBudget")*15000.f; + static LLCachedControl< U32 > mesh_triangle_budget( gSavedSettings, "MeshTriangleBudget"); + return weighted_avg / mesh_triangle_budget * 15000.f; } LLMeshCostData::LLMeshCostData() @@ -4564,7 +4541,7 @@ bool LLMeshCostData::init(const LLSD& header) std::fill(mSizeByLOD.begin(), mSizeByLOD.end(), 0); std::fill(mEstTrisByLOD.begin(), mEstTrisByLOD.end(), 0.f); - + S32 bytes_high = header["high_lod"]["size"].asInteger(); S32 bytes_med = header["medium_lod"]["size"].asInteger(); if (bytes_med == 0) @@ -4581,6 +4558,7 @@ bool LLMeshCostData::init(const LLSD& header) { bytes_lowest = bytes_low; } + mSizeByLOD[0] = bytes_lowest; mSizeByLOD[1] = bytes_low; mSizeByLOD[2] = bytes_med; @@ -4717,9 +4695,9 @@ bool LLMeshRepository::getCostData(LLUUID mesh_id, LLMeshCostData& data) { LLMutexLock lock(mThread->mHeaderMutex); LLMeshRepoThread::mesh_header_map::iterator iter = mThread->mMeshHeader.find(mesh_id); - if (iter != mThread->mMeshHeader.end() && mThread->mMeshHeaderSize[mesh_id] > 0) + if (iter != mThread->mMeshHeader.end() && iter->second.first > 0) { - LLSD& header = iter->second; + LLSD& header = iter->second.second; bool header_invalid = (header.has("404") || !header.has("lowest_lod") @@ -4735,7 +4713,7 @@ bool LLMeshRepository::getCostData(LLUUID mesh_id, LLMeshCostData& data) return false; } -bool LLMeshRepository::getCostData(LLSD& header, LLMeshCostData& data) +bool LLMeshRepository::getCostData(const LLSD& header, LLMeshCostData& data) { data = LLMeshCostData(); diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index 7be5afb7b116ef0d20f9b98121fda6f16c95cac4..754907991ba7ce3572cc0f12720115e75a9a6515 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -40,6 +40,8 @@ #include "httphandler.h" #include "llthread.h" +#include "absl/container/node_hash_map.h" + #define LLCONVEXDECOMPINTER_STATIC 1 #include "llconvexdecomposition.h" @@ -210,10 +212,8 @@ class LLMeshRepoThread : public LLThread LLCondition* mSignal; //map of known mesh headers - typedef std::map<LLUUID, LLSD> mesh_header_map; + typedef absl::node_hash_map<LLUUID, std::pair<U32, LLSD>> mesh_header_map; mesh_header_map mMeshHeader; - - std::map<LLUUID, U32> mMeshHeaderSize; class HeaderRequest : public RequestStats { @@ -313,7 +313,7 @@ class LLMeshRepoThread : public LLThread std::queue<LoadedMesh> mLoadedQ; //map of pending header requests and currently desired LODs - typedef std::map<LLVolumeParams, std::vector<S32> > pending_lod_map; + typedef absl::node_hash_map<LLUUID, std::vector<S32>> pending_lod_map; pending_lod_map mPendingLOD; // llcorehttp library interface objects. @@ -569,7 +569,7 @@ class LLMeshRepository F32 getStreamingCostLegacy(LLUUID mesh_id, F32 radius, S32* bytes = NULL, S32* visible_bytes = NULL, S32 detail = -1, F32 *unscaled_value = NULL); static F32 getStreamingCostLegacy(LLSD& header, F32 radius, S32* bytes = NULL, S32* visible_bytes = NULL, S32 detail = -1, F32 *unscaled_value = NULL); bool getCostData(LLUUID mesh_id, LLMeshCostData& data); - bool getCostData(LLSD& header, LLMeshCostData& data); + bool getCostData(const LLSD& header, LLMeshCostData& data); LLMeshRepository(); @@ -615,10 +615,10 @@ class LLMeshRepository static void metricsProgress(unsigned int count); static void metricsUpdate(); - typedef std::map<LLVolumeParams, std::vector<LLVOVolume*> > mesh_load_map; + typedef absl::node_hash_map<LLUUID, std::vector<LLVOVolume*> > mesh_load_map; mesh_load_map mLoadingMeshes[4]; - typedef std::map<LLUUID, LLMeshSkinInfo> skin_map; + typedef absl::node_hash_map<LLUUID, LLMeshSkinInfo> skin_map; skin_map mSkinMap; typedef std::map<LLUUID, LLModel::Decomposition*> decomposition_map; @@ -629,7 +629,7 @@ class LLMeshRepository std::vector<LLMeshRepoThread::LODRequest> mPendingRequests; //list of mesh ids awaiting skin info - typedef std::map<LLUUID, std::vector<LLVOVolume*> > skin_load_map; + typedef absl::node_hash_map<LLUUID, std::vector<LLVOVolume*> > skin_load_map; skin_load_map mLoadingSkins; //list of mesh ids that need to send skin info fetch requests @@ -649,8 +649,6 @@ class LLMeshRepository U32 mMeshThreadCount; - void cacheOutgoingMesh(LLMeshUploadData& data, LLSD& header); - LLMeshRepoThread* mThread; std::vector<LLMeshUploadThread*> mUploads; std::vector<LLMeshUploadThread*> mUploadWaitList;