]> git.lizzy.rs Git - dragonfireclient.git/blobdiff - src/client/game.cpp
Periodically release all mesh HW buffers to avoid an Irrlicht bottleneck.
[dragonfireclient.git] / src / client / game.cpp
index 309a8e194bc8e742fd20c0c4b15965e30c7740d9..a7e367ae2342dc177694c1bfd9a31afba1f22083 100644 (file)
@@ -909,6 +909,7 @@ class Game {
 
        bool m_does_lost_focus_pause_game = false;
 
+       int m_reset_HW_buffer_counter = 0;
 #ifdef __ANDROID__
        bool m_cache_hold_aux1;
        bool m_android_chat_open;
@@ -3686,7 +3687,6 @@ void Game::handleDigging(const PointedThing &pointed, const v3s16 &nodepos,
        camera->setDigging(0);  // Dig animation
 }
 
-
 void Game::updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime,
                const CameraOrientation &cam)
 {
@@ -3937,6 +3937,27 @@ void Game::updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime,
        /*
                End scene
        */
+       if (++m_reset_HW_buffer_counter > 500) {
+               /*
+                 Periodically remove all mesh HW buffers.
+
+                 Work around for a quirk in Irrlicht where a HW buffer is only
+                 released after 20000 iterations (triggered from endScene()).
+
+                 Without this, all loaded but unused meshes will retain their HW
+                 buffers for at least 5 minutes, at which point looking up the HW buffers
+                 becomes a bottleneck and the framerate drops (as much as 30%).
+
+                 Tests showed that numbers between 50 and 1000 are good, so picked 500.
+                 There are no other public Irrlicht APIs that allow interacting with the
+                 HW buffers without tracking the status of every individual mesh.
+
+                 The HW buffers for _visible_ meshes will be reinitialized in the next frame.
+               */
+               infostream << "Game::updateFrame(): Removing all HW buffers." << std::endl;
+               driver->removeAllHardwareBuffers();
+               m_reset_HW_buffer_counter = 0;
+       }
        driver->endScene();
 
        stats->drawtime = tt_draw.stop(true);