]> git.lizzy.rs Git - minetest.git/blobdiff - src/client/mesh_generator_thread.h
8x block meshes (#13133)
[minetest.git] / src / client / mesh_generator_thread.h
index 4371b839099e1693710738dde2eadcc53c95a031..3097f3704f3589a4398d4fb8b3c51e8ef1355837 100644 (file)
@@ -21,28 +21,24 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #include <ctime>
 #include <mutex>
+#include <unordered_map>
+#include <unordered_set>
 #include "mapblock_mesh.h"
 #include "threading/mutex_auto_lock.h"
 #include "util/thread.h"
-
-struct CachedMapBlockData
-{
-       v3s16 p = v3s16(-1337, -1337, -1337);
-       MapNode *data = nullptr; // A copy of the MapBlock's data member
-       int refcount_from_queue = 0;
-       std::time_t last_used_timestamp = std::time(0);
-
-       CachedMapBlockData() = default;
-       ~CachedMapBlockData();
-};
+#include <vector>
+#include <memory>
+#include <unordered_map>
 
 struct QueuedMeshUpdate
 {
        v3s16 p = v3s16(-1337, -1337, -1337);
-       bool ack_block_to_server = false;
+       std::vector<v3s16> ack_list;
        int crack_level = -1;
        v3s16 crack_pos;
        MeshMakeData *data = nullptr; // This is generated in MeshUpdateQueue::pop()
+       std::vector<MapBlock *> map_blocks;
+       bool urgent = false;
 
        QueuedMeshUpdate() = default;
        ~QueuedMeshUpdate();
@@ -66,12 +62,15 @@ class MeshUpdateQueue
 
        // Caches the block at p and its neighbors (if needed) and queues a mesh
        // update for the block at p
-       void addBlock(Map *map, v3s16 p, bool ack_block_to_server, bool urgent);
+       bool addBlock(Map *map, v3s16 p, bool ack_block_to_server, bool urgent);
 
        // Returned pointer must be deleted
        // Returns NULL if queue is empty
        QueuedMeshUpdate *pop();
 
+       // Marks a position as finished, unblocking the next update
+       void done(v3s16 pos);
+
        u32 size()
        {
                MutexAutoLock lock(m_mutex);
@@ -81,8 +80,8 @@ class MeshUpdateQueue
 private:
        Client *m_client;
        std::vector<QueuedMeshUpdate *> m_queue;
-       std::set<v3s16> m_urgents;
-       std::map<v3s16, CachedMapBlockData *> m_cache;
+       std::unordered_set<v3s16> m_urgents;
+       std::unordered_set<v3s16> m_inflight_blocks;
        std::mutex m_mutex;
 
        // TODO: Add callback to update these when g_settings changes
@@ -90,10 +89,7 @@ class MeshUpdateQueue
        bool m_cache_smooth_lighting;
        int m_meshgen_block_cache_size;
 
-       CachedMapBlockData *cacheBlock(Map *map, v3s16 p, UpdateMode mode,
-                       size_t *cache_hit_counter = NULL);
-       CachedMapBlockData *getCachedBlock(const v3s16 &p);
-       void fillDataFromMapBlockCache(QueuedMeshUpdate *q);
+       void fillDataFromMapBlocks(QueuedMeshUpdate *q);
        void cleanupCache();
 };
 
@@ -101,29 +97,61 @@ struct MeshUpdateResult
 {
        v3s16 p = v3s16(-1338, -1338, -1338);
        MapBlockMesh *mesh = nullptr;
-       bool ack_block_to_server = false;
+       std::unordered_map<v3s16, u8> solid_sides;
+       std::vector<v3s16> ack_list;
+       bool urgent = false;
+       std::vector<MapBlock *> map_blocks;
 
        MeshUpdateResult() = default;
 };
 
-class MeshUpdateThread : public UpdateThread
+class MeshUpdateManager;
+
+class MeshUpdateWorkerThread : public UpdateThread
 {
 public:
-       MeshUpdateThread(Client *client);
+       MeshUpdateWorkerThread(MeshUpdateQueue *queue_in, MeshUpdateManager *manager, v3s16 *camera_offset);
+
+protected:
+       virtual void doUpdate();
+
+private:
+       MeshUpdateQueue *m_queue_in;
+       MeshUpdateManager *m_manager;
+       v3s16 *m_camera_offset;
+
+       // TODO: Add callback to update these when g_settings changes
+       int m_generation_interval;
+};
+
+class MeshUpdateManager
+{
+public:
+       MeshUpdateManager(Client *client);
 
        // Caches the block at p and its neighbors (if needed) and queues a mesh
        // update for the block at p
-       void updateBlock(Map *map, v3s16 p, bool ack_block_to_server, bool urgent);
+       void updateBlock(Map *map, v3s16 p, bool ack_block_to_server, bool urgent,
+                       bool update_neighbors = false);
+       void putResult(const MeshUpdateResult &r);
+       bool getNextResult(MeshUpdateResult &r);
+
 
        v3s16 m_camera_offset;
-       MutexedQueue<MeshUpdateResult> m_queue_out;
+
+       void start();
+       void stop();
+       void wait();
+
+       bool isRunning();
 
 private:
-       MeshUpdateQueue m_queue_in;
+       void deferUpdate();
 
-       // TODO: Add callback to update these when g_settings changes
-       int m_generation_interval;
 
-protected:
-       virtual void doUpdate();
+       MeshUpdateQueue m_queue_in;
+       MutexedQueue<MeshUpdateResult> m_queue_out;
+       MutexedQueue<MeshUpdateResult> m_queue_out_urgent;
+
+       std::vector<std::unique_ptr<MeshUpdateWorkerThread>> m_workers;
 };