TileLayer: use shared_ptr for FrameSpec vector (#6171)
authorLoïc Blot <nerzhul@users.noreply.github.com>
Wed, 26 Jul 2017 18:12:48 +0000 (20:12 +0200)
committerGitHub <noreply@github.com>
Wed, 26 Jul 2017 18:12:48 +0000 (20:12 +0200)
* TileLayer: use shared_ptr for vector framespec
This reduce memory copy of TileLayer from (4 to 16) * FrameSpec where FrameSpec = (sizeof(int) + 3 * sizeof(ptr)) to int + sizeof(ptr)

Callgrind difference

Before: https://lut.im/RGkiJqQb8T/LeQIEXpAuRzfl7gd.png\ f
After: https://lut.im/bcqmwee1xu/cTwtptY5tRuS9lp0.png

* Fix one push_back to use vector::emplace_back & optimize inclusions

src/client/tile.h
src/mapblock_mesh.cpp
src/nodedef.cpp
src/particles.cpp
src/wieldmesh.cpp

index aadc3e15620a626a3b4d72daf11d18767c799e37..cfdcf30bd90b02b5cc984e317880424b2b0f834e 100644 (file)
@@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include <string>
 #include <vector>
 #include <SMaterial.h>
+#include <memory>
 #include "util/numeric.h"
 
 class IGameDef;
@@ -284,7 +285,7 @@ struct TileLayer
        //! If true, the tile has its own color.
        bool has_color = false;
 
-       std::vector<FrameSpec> frames;
+       std::shared_ptr<std::vector<FrameSpec>> frames = nullptr;
 
        /*!
         * The color of the tile, or if the tile does not own
index e854127c0b4d8725a682c05c0009788db61ac430..67195cab3696469a35972f9a085af0706979b4dc 100644 (file)
@@ -18,17 +18,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 */
 
 #include "mapblock_mesh.h"
-#include "light.h"
 #include "mapblock.h"
 #include "map.h"
 #include "profiler.h"
-#include "nodedef.h"
 #include "mesh.h"
 #include "minimap.h"
 #include "content_mapblock.h"
-#include "noise.h"
-#include "shader.h"
-#include "settings.h"
 #include "util/directiontables.h"
 #include "client/renderingengine.h"
 
@@ -602,7 +597,8 @@ static void makeFastFace(const TileSpec &tile, u16 li0, u16 li1, u16 li2, u16 li
                if (layer->texture_id == 0)
                        continue;
 
-               dest.push_back(FastFace());
+               // equivalent to dest.push_back(FastFace()) but faster
+               dest.emplace_back();
                FastFace& face = *dest.rbegin();
 
                for (u8 i = 0; i < 4; i++) {
@@ -1126,7 +1122,7 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
                                        m_animation_frame_offsets[std::pair<u8, u32>(layer, i)] = 0;
                                }
                                // Replace tile texture with the first animation frame
-                               p.layer.texture = p.layer.frames[0].texture;
+                               p.layer.texture = (*p.layer.frames)[0].texture;
                        }
 
                        if (!m_enable_shaders) {
@@ -1314,7 +1310,7 @@ bool MapBlockMesh::animate(bool faraway, float time, int crack, u32 daynight_rat
                scene::IMeshBuffer *buf = m_mesh[i->first.first]->
                        getMeshBuffer(i->first.second);
 
-               const FrameSpec &animation_frame = tile.frames[frame];
+               const FrameSpec &animation_frame = (*tile.frames)[frame];
                buf->getMaterial().setTexture(0, animation_frame.texture);
                if (m_enable_shaders) {
                        if (animation_frame.normal_texture) {
index 6bb2bf9047792cac1c699f1fd86a4f6a89b5f55b..fc404f252a73da4d789e3908edfbe9bf83c1d11b 100644 (file)
@@ -637,7 +637,10 @@ void ContentFeatures::fillTileAttribs(ITextureSource *tsrc, TileLayer *tile,
                tile->material_flags &= ~MATERIAL_FLAG_ANIMATION;
        } else {
                std::ostringstream os(std::ios::binary);
-               tile->frames.resize(frame_count);
+               if (!tile->frames) {
+                       tile->frames = std::make_shared<std::vector<FrameSpec>>();
+               }
+               tile->frames->resize(frame_count);
 
                for (int i = 0; i < frame_count; i++) {
 
@@ -652,7 +655,7 @@ void ContentFeatures::fillTileAttribs(ITextureSource *tsrc, TileLayer *tile,
                        if (tile->normal_texture)
                                frame.normal_texture = tsrc->getNormalTexture(os.str());
                        frame.flags_texture = tile->flags_texture;
-                       tile->frames[i] = frame;
+                       (*tile->frames)[i] = frame;
                }
        }
 }
index 10b9811bb4aea98ae38f0f00d913327f0dc2e7e6..b86266f42fdb631cd86c5874a79fa85eab6ae951 100644 (file)
@@ -631,7 +631,7 @@ void ParticleManager::addNodeParticle(IGameDef* gamedef,
 
        // Only use first frame of animated texture
        if (tile.material_flags & MATERIAL_FLAG_ANIMATION)
-               texture = tile.frames[0].texture;
+               texture = (*tile.frames)[0].texture;
        else
                texture = tile.texture;
 
index e0d6b7e0dc70e104b969aab7e901bef1c43cbf27..c532a048c0d0327ce737561808e725af1dafdcf1 100644 (file)
@@ -593,7 +593,7 @@ void postProcessNodeMesh(scene::SMesh *mesh, const ContentFeatures &f,
                                material.MaterialType = *mattype;
                        }
                        if (layer->animation_frame_count > 1) {
-                               FrameSpec animation_frame = layer->frames[0];
+                               const FrameSpec &animation_frame = (*layer->frames)[0];
                                material.setTexture(0, animation_frame.texture);
                        } else {
                                material.setTexture(0, layer->texture);
@@ -601,7 +601,7 @@ void postProcessNodeMesh(scene::SMesh *mesh, const ContentFeatures &f,
                        if (use_shaders) {
                                if (layer->normal_texture) {
                                        if (layer->animation_frame_count > 1) {
-                                               FrameSpec animation_frame = layer->frames[0];
+                                               const FrameSpec &animation_frame = (*layer->frames)[0];
                                                material.setTexture(1, animation_frame.normal_texture);
                                        } else
                                                material.setTexture(1, layer->normal_texture);