From 89562b66dfe916e41378ea87d14b071ee79e8a09 Mon Sep 17 00:00:00 2001
From: Rye Mutt <rye@alchemyviewer.org>
Date: Tue, 7 Mar 2023 00:25:28 -0500
Subject: [PATCH] Small VBO opts

---
 indra/llrender/llrender.cpp       |  9 +++++----
 indra/llrender/llvertexbuffer.cpp | 16 ++++++++++------
 2 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index 931c22bbac5..9ab8d166c0c 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -86,7 +86,7 @@ struct LLVBCache
     std::chrono::steady_clock::time_point touched;
 };
 
-static std::unordered_map<U64, LLVBCache> sVBCache;
+static boost::unordered_flat_map<U64, LLVBCache> sVBCache;
 
 static const GLenum sGLTextureType[] =
 {
@@ -1720,7 +1720,7 @@ void LLRender::flush()
             // To leverage this, we maintain a running hash of the vertex stream being
             // built up before a flush, and then check that hash against a VB 
             // cache just before creating a vertex buffer in VRAM
-            std::unordered_map<U64, LLVBCache>::iterator cache = sVBCache.find(vhash);
+            auto cache = sVBCache.find(vhash);
 
             LLPointer<LLVertexBuffer> vb;
 
@@ -1765,11 +1765,12 @@ void LLRender::flush()
 
                     using namespace std::chrono_literals;
                     // every 1024 misses, clean the cache of any VBs that haven't been touched in the last second
-                    for (std::unordered_map<U64, LLVBCache>::iterator iter = sVBCache.begin(); iter != sVBCache.end(); )
+                    for (auto iter = sVBCache.begin(); iter != sVBCache.end(); )
                     {
                         if (now - iter->second.touched > 1s)
                         {
-                            iter = sVBCache.erase(iter);
+							auto old_iter = iter++;
+                            sVBCache.erase(old_iter);
                         }
                         else
                         {
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index b2267c7c479..c7fcce2381e 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -307,7 +307,7 @@ class LLVBOPool
         clear();
     }
 
-    typedef std::unordered_map<U32, std::list<Entry>> Pool;
+    typedef boost::unordered_flat_map<U32, std::list<Entry>> Pool;
 
     Pool mVBOPool;
     Pool mIBOPool;
@@ -447,12 +447,13 @@ class LLVBOPool
 
         LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX;
 
-        std::unordered_map<U32, std::list<Entry>>* pools[] = { &mVBOPool, &mIBOPool };
+        boost::unordered_flat_map<U32, std::list<Entry>>* pools[] = { &mVBOPool, &mIBOPool };
 
         using namespace std::chrono_literals;
 
         Time cutoff = std::chrono::steady_clock::now() - 5s;
 
+        std::vector<GLuint> names_to_free;
         for (auto* pool : pools)
         {
             for (Pool::iterator iter = pool->begin(); iter != pool->end(); )
@@ -464,7 +465,7 @@ class LLVBOPool
                     LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("vbo cache timeout");
                     auto& entry = entries.back();
                     ll_aligned_free_16(entry.mData);
-                    glDeleteBuffers(1, &entry.mGLName);
+                    names_to_free.push_back(entry.mGLName);
 #if ANALYZE_VBO_POOL
                     llassert(mReserved >= iter->first);
                     mReserved -= iter->first;
@@ -475,7 +476,7 @@ class LLVBOPool
 
                 if (entries.empty())
                 {
-                    iter = pool->erase(iter);
+                    pool->erase(iter++);
                 }
                 else
                 {
@@ -483,6 +484,7 @@ class LLVBOPool
                 }
             }
         }
+        if(!names_to_free.empty()) glDeleteBuffers(names_to_free.size(), names_to_free.data());
 
 #if ANALYZE_VBO_POOL
         LL_INFOS() << llformat("(%d/%d)/%d MB (distributed/allocated)/total in VBO Pool. Overhead: %d percent. Hit rate: %d percent", 
@@ -497,12 +499,13 @@ class LLVBOPool
 
     void clear()
     {
+        std::vector<GLuint> names_to_free;
         for (auto& entries : mIBOPool)
         {
             for (auto& entry : entries.second)
             {
                 ll_aligned_free_16(entry.mData);
-                glDeleteBuffers(1, &entry.mGLName);
+                names_to_free.push_back(entry.mGLName);
             }
         }
 
@@ -511,9 +514,10 @@ class LLVBOPool
             for (auto& entry : entries.second)
             {
                 ll_aligned_free_16(entry.mData);
-                glDeleteBuffers(1, &entry.mGLName);
+                names_to_free.push_back(entry.mGLName);
             }
         }
+        if(!names_to_free.empty()) glDeleteBuffers(names_to_free.size(), names_to_free.data());
 
 #if ANALYZE_VBO_POOL
         mReserved = 0;
-- 
GitLab