simplify/c++-ize CompressRow code and related areas (less allocations overall)

This commit is contained in:
Jonathan 2022-06-17 12:06:37 -04:00
parent 238a7b8fa7
commit 46aaa81ffd
4 changed files with 41 additions and 44 deletions

View File

@ -543,28 +543,27 @@ void Face_DebugPrint(const mbsp_t *bsp, const mface_t *face)
CompressRow
===============
*/
int CompressRow(const uint8_t *vis, const int numbytes, uint8_t *out)
void CompressRow(const uint8_t *vis, const size_t numbytes, std::back_insert_iterator<std::vector<uint8_t>> it)
{
int i, rep;
uint8_t *dst;
for (size_t i = 0; i < numbytes; i++) {
it++ = vis[i];
dst = out;
for (i = 0; i < numbytes; i++) {
*dst++ = vis[i];
if (vis[i])
if (vis[i]) {
continue;
}
rep = 1;
for (i++; i < numbytes; i++)
if (vis[i] || rep == 255)
int32_t rep = 1;
for (i++; i < numbytes; i++) {
if (vis[i] || rep == 255) {
break;
else
rep++;
*dst++ = rep;
}
rep++;
}
it++ = rep;
i--;
}
return dst - out;
}
/*

View File

@ -81,5 +81,7 @@ std::vector<qvec3f> GLM_FacePoints(const mbsp_t *bsp, const mface_t *face);
qvec3f Face_Centroid(const mbsp_t *bsp, const mface_t *face);
void Face_DebugPrint(const mbsp_t *bsp, const mface_t *face);
int CompressRow(const uint8_t *vis, const int numbytes, uint8_t *out);
#include <vector>
void CompressRow(const uint8_t *vis, const size_t numbytes, std::back_insert_iterator<std::vector<uint8_t>> it);
void DecompressRow(const uint8_t *in, const int numbytes, uint8_t *decompressed);

View File

@ -163,7 +163,7 @@ void CalcPHS(mbsp_t *bsp)
// FIXME: should this use alloca?
uint8_t *uncompressed = new uint8_t[leafbytes];
uint8_t *uncompressed_2 = new uint8_t[leafbytes];
uint8_t *compressed = new uint8_t[leafbytes * 2];
std::vector<uint8_t> compressed(leafbytes * 2);
uint8_t *uncompressed_orig = new uint8_t[leafbytes];
int32_t count = 0;
@ -202,16 +202,16 @@ void CalcPHS(mbsp_t *bsp)
//
// compress the bit string
//
int32_t j = CompressRow(uncompressed, leafbytes, compressed);
compressed.clear();
CompressRow(uncompressed, leafbytes, std::back_inserter(compressed));
bsp->dvis.set_bit_offset(VIS_PHS, i, bsp->dvis.bits.size());
std::copy(compressed, compressed + j, std::back_inserter(bsp->dvis.bits));
std::copy(compressed.begin(), compressed.end(), std::back_inserter(bsp->dvis.bits));
}
delete[] uncompressed;
delete[] uncompressed_2;
delete[] compressed;
delete[] uncompressed_orig;
fmt::print("Average clusters hearable: {}\n", count / portalleafs);

View File

@ -30,9 +30,7 @@ int c_noclip = 0;
bool showgetleaf = true;
static uint8_t *vismap;
static uint8_t *vismap_p;
static uint8_t *vismap_end; // past visfile
static std::vector<uint8_t> vismap;
uint32_t originalvismapsize;
@ -404,14 +402,14 @@ void LeafThread(size_t)
*/
int64_t totalvis;
static std::vector<uint8_t> compressed;
static void ClusterFlow(int clusternum, leafbits_t &buffer, mbsp_t *bsp)
{
leaf_t *leaf;
uint8_t *outbuffer;
uint8_t *compressed;
int i, j, len;
int i, j;
int numvis, numblocks;
uint8_t *dest;
const portal_t *p;
/*
@ -477,23 +475,17 @@ static void ClusterFlow(int clusternum, leafbits_t &buffer, mbsp_t *bsp)
}
}
compressed.clear();
/* Allocate for worst case where RLE might grow the data (unlikely) */
if (bsp->loadversion->game->id == GAME_QUAKE_II) {
compressed = new uint8_t[max(1, (portalleafs * 2) / 8)];
len = CompressRow(outbuffer, (portalleafs + 7) >> 3, compressed);
CompressRow(outbuffer, (portalleafs + 7) >> 3, std::back_inserter(compressed));
} else {
compressed = new uint8_t[max(1, (portalleafs_real * 2) / 8)];
len = CompressRow(outbuffer, (portalleafs_real + 7) >> 3, compressed);
CompressRow(outbuffer, (portalleafs_real + 7) >> 3, std::back_inserter(compressed));
}
dest = vismap_p;
vismap_p += len;
if (vismap_p > vismap_end)
FError("Vismap expansion overflow");
/* leaf 0 is a common solid */
int32_t visofs = dest - vismap;
int32_t visofs = vismap.size();
bsp->dvis.set_bit_offset(VIS_PVS, clusternum, visofs);
@ -512,8 +504,7 @@ static void ClusterFlow(int clusternum, leafbits_t &buffer, mbsp_t *bsp)
}
}
memcpy(dest, compressed, len);
delete[] compressed;
std::copy(compressed.begin(), compressed.end(), std::back_inserter(vismap));
}
/*
@ -617,6 +608,14 @@ static void LoadPortals(const fs::path &name, mbsp_t *bsp)
portalleafs = prtfile.portalleafs;
portalleafs_real = prtfile.portalleafs_real;
/* Allocate for worst case where RLE might grow the data (unlikely) */
if (bsp->loadversion->game->id == GAME_QUAKE_II) {
compressed.reserve(max(1, (portalleafs * 2) / 8));
} else {
compressed.reserve(max(1, (portalleafs_real * 2) / 8));
}
numportals = prtfile.portals.size();
if (bsp->loadversion->game->id != GAME_QUAKE_II) {
@ -648,10 +647,7 @@ static void LoadPortals(const fs::path &name, mbsp_t *bsp)
bsp->dvis.resize(portalleafs);
bsp->dvis.bits.resize(originalvismapsize * 2);
vismap = vismap_p = bsp->dvis.bits.data();
vismap_end = vismap + bsp->dvis.bits.size();
vismap.reserve(originalvismapsize * 2);
for (i = 0, p = portals; i < numportals; i++) {
const auto &sourceportal = prtfile.portals[i];
@ -756,7 +752,7 @@ int vis_main(int argc, const char **argv)
logging::print("c_noclip: {}\n", c_noclip);
logging::print("c_chains: {}\n", c_chains);
bsp.dvis.bits.resize(vismap_p - bsp.dvis.bits.data());
bsp.dvis.bits = std::move(vismap);
bsp.dvis.bits.shrink_to_fit();
logging::print("visdatasize:{} compressed from {}\n", bsp.dvis.bits.size(), originalvismapsize);
}