1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-07-22 17:18:39 +00:00

Reduce wasteful memory allocations in update_lighting_nodes()

This commit is contained in:
sfan5 2024-04-23 21:50:47 +02:00
parent c24a04d246
commit e10adf83d5

View file

@ -17,6 +17,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#include <array>
#include "voxelalgorithms.h" #include "voxelalgorithms.h"
#include "nodedef.h" #include "nodedef.h"
#include "mapblock.h" #include "mapblock.h"
@ -51,12 +53,12 @@ typedef v3s16 mapblock_v3;
//! Contains information about a node whose light is about to change. //! Contains information about a node whose light is about to change.
struct ChangingLight { struct ChangingLight {
//! Pointer to the node's block.
MapBlock *block = nullptr;
//! Relative position of the node in its map block. //! Relative position of the node in its map block.
relative_v3 rel_position; relative_v3 rel_position;
//! Position of the node's block. //! Position of the node's block.
mapblock_v3 block_position; mapblock_v3 block_position;
//! Pointer to the node's block.
MapBlock *block = NULL;
/*! /*!
* Direction from the node that caused this node's changing * Direction from the node that caused this node's changing
* to this node. * to this node.
@ -67,9 +69,9 @@ struct ChangingLight {
ChangingLight(relative_v3 rel_pos, mapblock_v3 block_pos, ChangingLight(relative_v3 rel_pos, mapblock_v3 block_pos,
MapBlock *b, direction source_dir) : MapBlock *b, direction source_dir) :
block(b),
rel_position(rel_pos), rel_position(rel_pos),
block_position(block_pos), block_position(block_pos),
block(b),
source_direction(source_dir) source_direction(source_dir)
{} {}
}; };
@ -81,7 +83,7 @@ struct ChangingLight {
*/ */
struct LightQueue { struct LightQueue {
//! For each light level there is a vector. //! For each light level there is a vector.
std::vector<ChangingLight> lights[LIGHT_SUN + 1]; std::array<std::vector<ChangingLight>, LIGHT_SUN + 1> lights;
//! Light of the brightest ChangingLight in the queue. //! Light of the brightest ChangingLight in the queue.
u8 max_light; u8 max_light;
@ -92,9 +94,15 @@ struct LightQueue {
LightQueue(size_t reserve) LightQueue(size_t reserve)
{ {
max_light = LIGHT_SUN; max_light = LIGHT_SUN;
for (u8 i = 0; i <= LIGHT_SUN; i++) { for (auto &l : lights)
lights[i].reserve(reserve); l.reserve(reserve);
} }
//! Clears a LightQueue.
void clear() {
max_light = LIGHT_SUN;
for (auto &l : lights)
l.clear();
} }
/*! /*!
@ -456,7 +464,7 @@ bool is_sunlight_above(Map *map, v3s16 pos, const NodeDefManager *ndef)
return sunlight; return sunlight;
} }
static const LightBank banks[] = { LIGHTBANK_DAY, LIGHTBANK_NIGHT }; static constexpr LightBank banks[] = { LIGHTBANK_DAY, LIGHTBANK_NIGHT };
void update_lighting_nodes(Map *map, void update_lighting_nodes(Map *map,
const std::vector<std::pair<v3s16, MapNode>> &oldnodes, const std::vector<std::pair<v3s16, MapNode>> &oldnodes,
@ -466,10 +474,14 @@ void update_lighting_nodes(Map *map,
// For node getter functions // For node getter functions
bool is_valid_position; bool is_valid_position;
// cached allocations
thread_local UnlightQueue disappearing_lights(1);
thread_local ReLightQueue light_sources(4);
// Process each light bank separately // Process each light bank separately
for (LightBank bank : banks) { for (LightBank bank : banks) {
UnlightQueue disappearing_lights(256); disappearing_lights.clear();
ReLightQueue light_sources(256); light_sources.clear();
// Nodes that are brighter than the brightest modified node was // Nodes that are brighter than the brightest modified node was
// won't change, since they didn't get their light from a // won't change, since they didn't get their light from a
// modified node. // modified node.
@ -634,14 +646,16 @@ void update_lighting_nodes(Map *map,
* Borders of a map block in relative node coordinates. * Borders of a map block in relative node coordinates.
* Compatible with type 'direction'. * Compatible with type 'direction'.
*/ */
const VoxelArea block_borders[] = { #define B_1 (MAP_BLOCKSIZE - 1)
VoxelArea(v3s16(15, 0, 0), v3s16(15, 15, 15)), //X+ const static VoxelArea block_borders[] = {
VoxelArea(v3s16(0, 15, 0), v3s16(15, 15, 15)), //Y+ VoxelArea(v3s16(B_1, 0, 0), v3s16(B_1, B_1, B_1)), //X+
VoxelArea(v3s16(0, 0, 15), v3s16(15, 15, 15)), //Z+ VoxelArea(v3s16(0, B_1, 0), v3s16(B_1, B_1, B_1)), //Y+
VoxelArea(v3s16(0, 0, 0), v3s16(15, 15, 0)), //Z- VoxelArea(v3s16(0, 0, B_1), v3s16(B_1, B_1, B_1)), //Z+
VoxelArea(v3s16(0, 0, 0), v3s16(15, 0, 15)), //Y- VoxelArea(v3s16(0, 0, 0), v3s16(B_1, B_1, 0)), //Z-
VoxelArea(v3s16(0, 0, 0), v3s16(0, 15, 15)) //X- VoxelArea(v3s16(0, 0, 0), v3s16(B_1, 0, B_1)), //Y-
VoxelArea(v3s16(0, 0, 0), v3s16(0, B_1, B_1)) //X-
}; };
#undef B_1
/*! /*!
* Returns true if: * Returns true if:
@ -679,11 +693,14 @@ void update_block_border_lighting(Map *map, MapBlock *block,
std::map<v3s16, MapBlock*> &modified_blocks) std::map<v3s16, MapBlock*> &modified_blocks)
{ {
const NodeDefManager *ndef = map->getNodeDefManager(); const NodeDefManager *ndef = map->getNodeDefManager();
// Since invalid light is not common, do not allocate
// memory if not needed.
UnlightQueue disappearing_lights(0);
ReLightQueue light_sources(0);
for (LightBank bank : banks) { for (LightBank bank : banks) {
// Since invalid light is not common, do not allocate disappearing_lights.clear();
// memory if not needed. light_sources.clear();
UnlightQueue disappearing_lights(0);
ReLightQueue light_sources(0);
// Get incorrect lights // Get incorrect lights
for (direction d = 0; d < 6; d++) { for (direction d = 0; d < 6; d++) {
// For each direction // For each direction