From 5d2eb3e4cf8c6dd039fd3682ea75703778ee622e Mon Sep 17 00:00:00 2001 From: Shyotl Date: Fri, 10 Aug 2018 23:07:13 -0500 Subject: [PATCH] Fixed hot spot in volume generation. --- indra/llcommon/llstl.h | 18 ++++++++++++++++++ indra/newview/llspatialpartition.cpp | 10 +++++----- indra/newview/llspatialpartition.h | 6 +++--- indra/newview/llvopartgroup.cpp | 2 +- indra/newview/llvovolume.cpp | 13 +++++++------ 5 files changed, 34 insertions(+), 15 deletions(-) diff --git a/indra/llcommon/llstl.h b/indra/llcommon/llstl.h index b5debf608..1c836d613 100644 --- a/indra/llcommon/llstl.h +++ b/indra/llcommon/llstl.h @@ -265,6 +265,24 @@ inline typename T::mapped_type get_ptr_in_map(const T& inmap, typename T::key_ty return get_if_there(inmap,key,NULL); }; +template +inline typename T::iterator& get_in_vec(T& invec, P pred) +{ + return std::find_if(invec.begin(), invec.end(), pred); +} + +template +inline typename T::value_type::second_type& get_val_in_pair_vec(T& invec, K key) +{ + auto it = get_in_vec(invec, [&key](T::value_type& e) { return e.first == key; }); + if (it == invec.end()) + { + invec.emplace_back(key, T::value_type::second_type()); + return invec.back().second; + } + return it->second; +} + // Useful for replacing the removeObj() functionality of LLDynamicArray // Example: // for (std::vector::iterator iter = mList.begin(); iter != mList.end(); ) diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 392a48c08..7299f6b8e 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -352,7 +352,7 @@ void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group) else { group->mVertexBuffer = NULL; - group->mBufferMap.clear(); + group->mBufferVec.clear(); } group->mLastUpdateTime = gFrameTimeSeconds; @@ -752,7 +752,7 @@ void LLSpatialGroup::handleDestruction(const TreeNode* node) clearDrawMap(); mVertexBuffer = NULL; - mBufferMap.clear(); + mBufferVec.clear(); sZombieGroups++; mOctreeNode = NULL; } @@ -784,7 +784,7 @@ void LLSpatialGroup::destroyGL(bool keep_occlusion) mLastUpdateTime = gFrameTimeSeconds; mVertexBuffer = NULL; - mBufferMap.clear(); + mBufferVec.clear(); clearDrawMap(); @@ -1483,9 +1483,9 @@ void pushBufferVerts(LLSpatialGroup* group, U32 mask, bool push_alpha = true) pushBufferVerts(group->mVertexBuffer, mask); } - for (LLSpatialGroup::buffer_map_t::iterator i = group->mBufferMap.begin(); i != group->mBufferMap.end(); ++i) + for (LLSpatialGroup::buffer_vec_t::iterator i = group->mBufferVec.begin(); i != group->mBufferVec.end(); ++i) { - for (LLSpatialGroup::buffer_texture_map_t::iterator j = i->second.begin(); j != i->second.end(); ++j) + for (LLSpatialGroup::buffer_texture_vec_t::iterator j = i->second.begin(); j != i->second.end(); ++j) { for (LLSpatialGroup::buffer_list_t::iterator k = j->second.begin(); k != j->second.end(); ++k) { diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index ea6c156a7..cd150d017 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -241,8 +241,8 @@ public: typedef std::vector > drawmap_elem_t; typedef std::map draw_map_t; typedef std::vector > buffer_list_t; - typedef std::map buffer_texture_map_t; - typedef std::map buffer_map_t; + typedef std::vector > buffer_texture_vec_t; + typedef std::vector > buffer_vec_t; @@ -337,7 +337,7 @@ protected: public: bridge_list_t mBridgeList; - buffer_map_t mBufferMap; //used by volume buffers to store unique buffers per texture + buffer_vec_t mBufferVec; //used by volume buffers to store unique buffers per texture U32 mGeometryBytes; //used by volumes to track how many bytes of geometry data are in this node F32 mSurfaceArea; //used by volumes to track estimated surface area of geometry in this node diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp index d6f5e737b..9d5f1c942 100644 --- a/indra/newview/llvopartgroup.cpp +++ b/indra/newview/llvopartgroup.cpp @@ -792,7 +792,7 @@ void LLParticlePartition::rebuildGeom(LLSpatialGroup* group) else { group->mVertexBuffer = NULL; - group->mBufferMap.clear(); + group->mBufferVec.clear(); } group->mLastUpdateTime = gFrameTimeSeconds; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index c927341e2..914ba89b7 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -5722,7 +5722,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac LLFace** face_iter = faces; LLFace** end_faces = faces+face_count; - LLSpatialGroup::buffer_map_t buffer_map; + LLSpatialGroup::buffer_vec_t buffer_vec; S32 texture_index_channels = llmax(LLGLSLShader::sIndexedTextureChannels-1,1); //always reserve one for shiny for now just for simplicity @@ -6016,8 +6016,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac group->mGeometryBytes += buffer->getSize() + buffer->getIndicesSize(); - - buffer_map[mask][*face_iter].push_back(buffer); + get_val_in_pair_vec(get_val_in_pair_vec(buffer_vec, mask),*face_iter).push_back(buffer); //add face geometry @@ -6511,10 +6510,12 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac buffer->flush(); } - group->mBufferMap[mask].clear(); - for (LLSpatialGroup::buffer_texture_map_t::iterator i = buffer_map[mask].begin(); i != buffer_map[mask].end(); ++i) + auto buffVec = get_val_in_pair_vec(group->mBufferVec, mask); + buffVec.clear(); + auto map = get_val_in_pair_vec(buffer_vec, mask); + for (LLSpatialGroup::buffer_texture_vec_t::iterator i = map.begin(); i != map.end(); ++i) { - group->mBufferMap[mask][i->first] = i->second; + get_val_in_pair_vec(buffVec, i->first) = i->second; } }