From 73180a73da9b290e2da8629799696cd8c4eab268 Mon Sep 17 00:00:00 2001 From: sfan5 Date: Sat, 25 Apr 2020 12:39:17 +0200 Subject: [PATCH] mapblock_mesh: Optimize a few things (#9713) --- src/client/mapblock_mesh.cpp | 91 +++++++++++++++++------------------- 1 file changed, 44 insertions(+), 47 deletions(-) diff --git a/src/client/mapblock_mesh.cpp b/src/client/mapblock_mesh.cpp index a5bee6b88..0a1619b3f 100644 --- a/src/client/mapblock_mesh.cpp +++ b/src/client/mapblock_mesh.cpp @@ -225,7 +225,7 @@ static u16 getSmoothLightCombined(const v3s16 &p, return f.light_propagates; }; - std::array obstructed = {{ 1, 1, 1, 1 }}; + bool obstructed[4] = { true, true, true, true }; add_node(0); bool opaque1 = !add_node(1); bool opaque2 = !add_node(2); @@ -372,6 +372,32 @@ void final_color_blend(video::SColor *result, Mesh generation helpers */ +// This table is moved outside getNodeVertexDirs to avoid the compiler using +// a mutex to initialize this table at runtime right in the hot path. +// For details search the internet for "cxa_guard_acquire". +static const v3s16 vertex_dirs_table[] = { + // ( 1, 0, 0) + v3s16( 1,-1, 1), v3s16( 1,-1,-1), + v3s16( 1, 1,-1), v3s16( 1, 1, 1), + // ( 0, 1, 0) + v3s16( 1, 1,-1), v3s16(-1, 1,-1), + v3s16(-1, 1, 1), v3s16( 1, 1, 1), + // ( 0, 0, 1) + v3s16(-1,-1, 1), v3s16( 1,-1, 1), + v3s16( 1, 1, 1), v3s16(-1, 1, 1), + // invalid + v3s16(), v3s16(), v3s16(), v3s16(), + // ( 0, 0,-1) + v3s16( 1,-1,-1), v3s16(-1,-1,-1), + v3s16(-1, 1,-1), v3s16( 1, 1,-1), + // ( 0,-1, 0) + v3s16( 1,-1, 1), v3s16(-1,-1, 1), + v3s16(-1,-1,-1), v3s16( 1,-1,-1), + // (-1, 0, 0) + v3s16(-1,-1,-1), v3s16(-1,-1, 1), + v3s16(-1, 1, 1), v3s16(-1, 1,-1) +}; + /* vertex_dirs: v3s16[4] */ @@ -384,44 +410,16 @@ static void getNodeVertexDirs(const v3s16 &dir, v3s16 *vertex_dirs) 2: top-left 3: top-right */ - if (dir == v3s16(0, 0, 1)) { - // If looking towards z+, this is the face that is behind - // the center point, facing towards z+. - vertex_dirs[0] = v3s16(-1,-1, 1); - vertex_dirs[1] = v3s16( 1,-1, 1); - vertex_dirs[2] = v3s16( 1, 1, 1); - vertex_dirs[3] = v3s16(-1, 1, 1); - } else if (dir == v3s16(0, 0, -1)) { - // faces towards Z- - vertex_dirs[0] = v3s16( 1,-1,-1); - vertex_dirs[1] = v3s16(-1,-1,-1); - vertex_dirs[2] = v3s16(-1, 1,-1); - vertex_dirs[3] = v3s16( 1, 1,-1); - } else if (dir == v3s16(1, 0, 0)) { - // faces towards X+ - vertex_dirs[0] = v3s16( 1,-1, 1); - vertex_dirs[1] = v3s16( 1,-1,-1); - vertex_dirs[2] = v3s16( 1, 1,-1); - vertex_dirs[3] = v3s16( 1, 1, 1); - } else if (dir == v3s16(-1, 0, 0)) { - // faces towards X- - vertex_dirs[0] = v3s16(-1,-1,-1); - vertex_dirs[1] = v3s16(-1,-1, 1); - vertex_dirs[2] = v3s16(-1, 1, 1); - vertex_dirs[3] = v3s16(-1, 1,-1); - } else if (dir == v3s16(0, 1, 0)) { - // faces towards Y+ (assume Z- as "down" in texture) - vertex_dirs[0] = v3s16( 1, 1,-1); - vertex_dirs[1] = v3s16(-1, 1,-1); - vertex_dirs[2] = v3s16(-1, 1, 1); - vertex_dirs[3] = v3s16( 1, 1, 1); - } else if (dir == v3s16(0, -1, 0)) { - // faces towards Y- (assume Z+ as "down" in texture) - vertex_dirs[0] = v3s16( 1,-1, 1); - vertex_dirs[1] = v3s16(-1,-1, 1); - vertex_dirs[2] = v3s16(-1,-1,-1); - vertex_dirs[3] = v3s16( 1,-1,-1); - } + + // Direction must be (1,0,0), (-1,0,0), (0,1,0), (0,-1,0), + // (0,0,1), (0,0,-1) + assert(dir.X * dir.X + dir.Y * dir.Y + dir.Z * dir.Z == 1); + + // Convert direction to single integer for table lookup + u8 idx = (dir.X + 2 * dir.Y + 3 * dir.Z) & 7; + idx = (idx - 1) * 4; + + memcpy(vertex_dirs, &vertex_dirs_table[idx], 4 * sizeof(v3s16)); } static void getNodeTextureCoords(v3f base, const v3f &scale, const v3s16 &dir, float *u, float *v) @@ -892,6 +890,8 @@ static void updateFastFaceRow( u16 lights[4] = {0, 0, 0, 0}; u8 waving; TileSpec tile; + + // Get info of first tile getTileInfo(data, p, face_dir, makes_face, p_corrected, face_dir_corrected, lights, waving, tile); @@ -902,8 +902,6 @@ static void updateFastFaceRow( // If tiling can be done, this is set to false in the next step bool next_is_different = true; - v3s16 p_next; - bool next_makes_face = false; v3s16 next_p_corrected; v3s16 next_face_dir_corrected; @@ -912,9 +910,9 @@ static void updateFastFaceRow( // If at last position, there is nothing to compare to and // the face must be drawn anyway if (j != MAP_BLOCKSIZE - 1) { - p_next = p + translate_dir; + p += translate_dir; - getTileInfo(data, p_next, face_dir, + getTileInfo(data, p, face_dir, next_makes_face, next_p_corrected, next_face_dir_corrected, next_lights, waving, @@ -923,7 +921,7 @@ static void updateFastFaceRow( if (next_makes_face == makes_face && next_p_corrected == p_corrected + translate_dir && next_face_dir_corrected == face_dir_corrected - && memcmp(next_lights, lights, ARRLEN(lights) * sizeof(u16)) == 0 + && memcmp(next_lights, lights, sizeof(lights)) == 0 // Don't apply fast faces to waving water. && (waving != 3 || !waving_liquids) && next_tile.isTileable(tile)) { @@ -961,10 +959,9 @@ static void updateFastFaceRow( makes_face = next_makes_face; p_corrected = next_p_corrected; face_dir_corrected = next_face_dir_corrected; - std::memcpy(lights, next_lights, ARRLEN(lights) * sizeof(u16)); + memcpy(lights, next_lights, sizeof(lights)); if (next_is_different) - tile = next_tile; - p = p_next; + tile = std::move(next_tile); // faster than copy } }