]> git.lizzy.rs Git - minetest.git/commitdiff
Reduce server CPU consumed by occlusion culling. (#13260)
authorlhofhansl <larsh@apache.org>
Mon, 6 Mar 2023 05:33:41 +0000 (21:33 -0800)
committerGitHub <noreply@github.com>
Mon, 6 Mar 2023 05:33:41 +0000 (21:33 -0800)
Cache blocks already occluded at a specific distance. The RemoteClient typically visits the same distance multiple time - especially at larger distances, so this saves significant CPU from recalculating the occlusion state of blocks.

src/clientiface.cpp
src/clientiface.h

index bb25a42654518753c093fd1352d4789d5b23713d..49b668cf039b22002133eca3bc21bd199b8d5393 100644 (file)
@@ -328,8 +328,15 @@ void RemoteClient::GetNextBlocks (
                                                continue;
                                }
 
+                               /*
+                                       Check occlusion cache first.
+                                */
+                               if (m_blocks_occ.find(p) != m_blocks_occ.end())
+                                       continue;
+
                                if (m_occ_cull && !block_not_found &&
                                                env->getMap().isBlockOccluded(block, cam_pos_nodes)) {
+                                       m_blocks_occ.insert(p);
                                        continue;
                                }
                        }
@@ -395,8 +402,11 @@ void RemoteClient::GetNextBlocks (
                }
        }
 
-       if (new_nearest_unsent_d != -1)
+       if (new_nearest_unsent_d != -1 && m_nearest_unsent_d != new_nearest_unsent_d) {
                m_nearest_unsent_d = new_nearest_unsent_d;
+               // if the distance has changed, clear the occlusion cache
+               m_blocks_occ.clear();
+       }
 }
 
 void RemoteClient::GotBlock(v3s16 p)
index cda01650b9f4240fa762534d4747cb479020ec57..261c09fce8481a5c9649b6544092e444c9b17791 100644 (file)
@@ -33,6 +33,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include <list>
 #include <vector>
 #include <set>
+#include <unordered_set>
 #include <memory>
 #include <mutex>
 
@@ -379,7 +380,15 @@ class RemoteClient
                List of block positions.
                No MapBlock* is stored here because the blocks can get deleted.
        */
-       std::set<v3s16> m_blocks_sent;
+       std::unordered_set<v3s16> m_blocks_sent;
+
+       /*
+               Cache of blocks that have been occlusion culled at the current distance.
+               As GetNextBlocks traverses the same distance multiple times, this saves
+               significant CPU time.
+        */
+       std::unordered_set<v3s16> m_blocks_occ;
+
        s16 m_nearest_unsent_d = 0;
        v3s16 m_last_center;
        v3f m_last_camera_dir;
@@ -399,7 +408,7 @@ class RemoteClient
                Block is removed when GOTBLOCKS is received.
                Value is time from sending. (not used at the moment)
        */
-       std::map<v3s16, float> m_blocks_sending;
+       std::unordered_map<v3s16, float> m_blocks_sending;
 
        /*
                Blocks that have been modified since blocks were
@@ -409,7 +418,7 @@ class RemoteClient
 
                List of block positions.
        */
-       std::set<v3s16> m_blocks_modified;
+       std::unordered_set<v3s16> m_blocks_modified;
 
        /*
                Count of excess GotBlocks().