optimize memory : change alphamaps from std::optional to unique_ptr

This commit is contained in:
T1ti
2024-08-13 23:37:51 +02:00
parent 0c44bc348a
commit f8217e1d5f
15 changed files with 138 additions and 71 deletions

View File

@@ -72,8 +72,14 @@ void Noggit::Action::undo(bool redo)
for (auto& pair : redo ? _chunk_texture_post : _chunk_texture_pre)
{
auto texture_set = pair.first->getTextureSet();
*texture_set->getAlphamaps() = pair.second.alphamaps;
*texture_set->getTempAlphamaps() = pair.second.tmp_edit_values;
texture_set->setAlphamaps(pair.second.alphamaps);
if (pair.second.tmp_edit_values)
texture_set->getTempAlphamaps() = std::make_unique<tmp_edit_alpha_values>(*pair.second.tmp_edit_values);
else
texture_set->getTempAlphamaps() = nullptr;
std::memcpy(texture_set->getMCLYEntries(), &pair.second.layers_info, sizeof(layer_info) * 4);
texture_set->setNTextures(pair.second.n_textures);
@@ -407,8 +413,21 @@ void Noggit::Action::finish()
auto texture_set = pre.first->getTextureSet();
cache.n_textures = texture_set->num();
cache.alphamaps = *texture_set->getAlphamaps();
cache.tmp_edit_values = *texture_set->getTempAlphamaps();
const auto& sourceAlphamaps = *texture_set->getAlphamaps();
for (size_t i = 0; i < MAX_ALPHAMAPS; ++i) {
if (sourceAlphamaps[i])
cache.alphamaps[i] = std::make_unique<Alphamap>(*sourceAlphamaps[i]);
else
cache.alphamaps[i].reset();
}
const auto& source_temp_alphas = texture_set->getTempAlphamaps();
if (source_temp_alphas)
cache.tmp_edit_values = std::make_unique<tmp_edit_alpha_values>(*source_temp_alphas);
else
cache.tmp_edit_values.reset();
std::memcpy(&cache.layers_info, texture_set->getMCLYEntries(), sizeof(layer_info) * 4);
for (int j = 0; j < cache.n_textures; ++j)
@@ -599,8 +618,23 @@ void Noggit::Action::registerChunkTextureChange(MapChunk* chunk)
auto texture_set = chunk->getTextureSet();
cache.n_textures = texture_set->num();
cache.alphamaps = *texture_set->getAlphamaps();
cache.tmp_edit_values = *texture_set->getTempAlphamaps();
// cache.alphamaps = *texture_set->getAlphamaps();
// cache.tmp_edit_values = *texture_set->getTempAlphamaps();
const auto& sourceAlphamaps = *texture_set->getAlphamaps();
for (size_t i = 0; i < MAX_ALPHAMAPS; ++i)
{
if (sourceAlphamaps[i])
cache.alphamaps[i] = std::make_unique<Alphamap>(*sourceAlphamaps[i]);
else
cache.alphamaps[i].reset();
}
const auto& source_temp_alphas = texture_set->getTempAlphamaps();
if (source_temp_alphas)
cache.tmp_edit_values = std::make_unique<tmp_edit_alpha_values>(*source_temp_alphas);
else
cache.tmp_edit_values.reset();
std::memcpy(&cache.layers_info, texture_set->getMCLYEntries(), sizeof(layer_info) * 4);
for (int i = 0; i < cache.n_textures; ++i)

View File

@@ -71,8 +71,8 @@ namespace Noggit
{
size_t n_textures;
std::vector<std::string> textures;
std::array<std::optional<Alphamap>, 3> alphamaps;
std::optional<tmp_edit_alpha_values> tmp_edit_values;
std::array<std::unique_ptr<Alphamap>, MAX_ALPHAMAPS> alphamaps;
std::unique_ptr<tmp_edit_alpha_values> tmp_edit_values;
layer_info layers_info[4];
};

View File

@@ -10,6 +10,8 @@ namespace BlizzardArchive
class ClientFile;
}
static constexpr int MAX_ALPHAMAPS = 3;
class Alphamap
{
public:

View File

@@ -325,7 +325,7 @@ MapChunk::MapChunk(MapTile* maintile, BlizzardArchive::ClientFile* f, bool bigAl
assert(fourcc == 'MCSE');
for (int i = 0; i < tmp_chunk_header.nSndEmitters; i++)
for (unsigned int i = 0; i < tmp_chunk_header.nSndEmitters; i++)
{
ENTRY_MCSE sound_emitter;
f->read(&sound_emitter, sizeof(ENTRY_MCSE));
@@ -1904,9 +1904,9 @@ QImage MapChunk::getHeightmapImage(float min_height, float max_height)
QImage MapChunk::getAlphamapImage(unsigned layer)
{
texture_set->apply_alpha_changes();
auto alphamaps = texture_set->getAlphamaps();
auto& alphamaps = *texture_set->getAlphamaps();
auto alpha_layer = alphamaps->at(layer - 1).value();
auto& alpha_layer = *alphamaps.at(layer - 1);
QImage image(64, 64, QImage::Format_RGBA8888);
@@ -1982,7 +1982,7 @@ void MapChunk::setAlphamapImage(const QImage &image, unsigned int layer)
return;
texture_set->create_temporary_alphamaps_if_needed();
auto& temp_alphamaps = texture_set->getTempAlphamaps()->value();
auto& temp_alphamaps = *texture_set->getTempAlphamaps();
for (int i = 0; i < 64; ++i)
{

View File

@@ -1147,7 +1147,7 @@ QImage MapTile::getAlphamapImage(unsigned layer)
chunk->texture_set->apply_alpha_changes();
auto alphamaps = chunk->texture_set->getAlphamaps();
auto alpha_layer = alphamaps->at(layer - 1).value();
auto alpha_layer = *alphamaps->at(layer - 1);
for (int k = 0; k < 64; ++k)
{
@@ -1210,19 +1210,19 @@ QImage MapTile::getAlphamapImage(std::string const& filename)
{
// WoW calculates layer 0 as 255 - sum(Layer[1]...Layer[3])
int layers_sum = 0;
if (alphamaps->at(0).has_value())
layers_sum += alphamaps->at(0).value().getAlpha(64 * l + k);
if (alphamaps->at(1).has_value())
layers_sum += alphamaps->at(1).value().getAlpha(64 * l + k);
if (alphamaps->at(2).has_value())
layers_sum += alphamaps->at(2).value().getAlpha(64 * l + k);
if (alphamaps->at(0))
layers_sum += alphamaps->at(0)->getAlpha(64 * l + k);
if (alphamaps->at(1))
layers_sum += alphamaps->at(1)->getAlpha(64 * l + k);
if (alphamaps->at(2))
layers_sum += alphamaps->at(2)->getAlpha(64 * l + k);
int value = std::clamp((255 - layers_sum), 0, 255);
image.setPixelColor((i * 64) + k, (j * 64) + l, QColor(value, value, value, 255));
}
else // layer 1-3
{
auto& alpha_layer = alphamaps->at(layer - 1).value();
auto& alpha_layer = *alphamaps->at(layer - 1);
int value = alpha_layer.getAlpha(64 * l + k);
image.setPixelColor((i * 64) + k, (j * 64) + l, QColor(value, value, value, 255));
@@ -1430,7 +1430,7 @@ void MapTile::setAlphaImage(QImage const& baseimage, unsigned layer, bool cleanu
chunk->registerChunkUpdate(ChunkUpdateFlags::ALPHAMAP);
chunk->texture_set->create_temporary_alphamaps_if_needed();
auto& temp_alphamaps = chunk->texture_set->getTempAlphamaps()->value();
auto& temp_alphamaps = *chunk->texture_set->getTempAlphamaps();
for (int i = 0; i < 64; ++i)
{

View File

@@ -25,7 +25,7 @@ namespace Noggit {
{
auto& ts = _chunk->texture_set;
ts->create_temporary_alphamaps_if_needed();
return ts->getTempAlphamaps()->value()[index][_index];
return ts->getTempAlphamaps()->map[index][_index];
}
void tex::set_alpha(int index, float value)
@@ -41,7 +41,7 @@ namespace Noggit {
}
auto& ts = _chunk->texture_set;
ts->create_temporary_alphamaps_if_needed();
ts->getTempAlphamaps()->value()[index][_index] = value;
ts->getTempAlphamaps()->map[index][_index] = value;
}
namespace {

View File

@@ -107,7 +107,7 @@ namespace Noggit
{
if (*iter == -1)
break;
ts->getTempAlphamaps()->value()[index][*iter] = alpha;
ts->getTempAlphamaps()->map[index][*iter] = alpha;
}
}
@@ -137,7 +137,7 @@ namespace Noggit
{
if (*iter == -1)
break;
sum += ts->getTempAlphamaps()->value()[index][*iter];
sum += ts->getTempAlphamaps()->map[index][*iter];
++ctr;
}
return sum / float(ctr);

View File

@@ -54,7 +54,7 @@ TextureSet::TextureSet (MapChunk* chunk, BlizzardArchive::ClientFile* f, size_t
if (_layers_info[layer].flags & FLAG_USE_ALPHA)
{
f->seek (alpha_base + tmp_entry_mcly[layer].ofsAlpha);
alphamaps[layer - 1].emplace(f, _layers_info[layer].flags, use_big_alphamaps, do_not_fix_alpha_map);
alphamaps[layer - 1] = std::make_unique<Alphamap>(f, _layers_info[layer].flags, use_big_alphamaps, do_not_fix_alpha_map);
}
}
@@ -82,12 +82,12 @@ int TextureSet::addTexture (scoped_blp_texture_reference texture)
if (texLevel)
{
alphamaps[texLevel - 1].emplace();
alphamaps[texLevel - 1] = std::make_unique<Alphamap>();
}
if (tmp_edit_values && nTextures == 1)
{
tmp_edit_values.value()[0].fill(255.f);
tmp_edit_values->map[0].fill(255.f);
}
}
@@ -205,7 +205,7 @@ void TextureSet::eraseTextures()
{
if (i > 0)
{
alphamaps[i - 1] = std::nullopt;
alphamaps[i - 1].reset();
}
_layers_info[i] = layer_info();
}
@@ -217,7 +217,7 @@ void TextureSet::eraseTextures()
_chunk->registerChunkUpdate(ChunkUpdateFlags::ALPHAMAP);
_need_lod_texture_map_update = true;
tmp_edit_values = std::nullopt;
tmp_edit_values.reset();
}
void TextureSet::eraseTexture(size_t id)
@@ -232,13 +232,13 @@ void TextureSet::eraseTexture(size_t id)
{
if (i)
{
alphamaps[i - 1] = std::nullopt;
alphamaps[i - 1].reset();
std::swap (alphamaps[i - 1], alphamaps[i]);
}
if (tmp_edit_values)
{
tmp_edit_values.value()[i].swap(tmp_edit_values.value()[i+1]);
tmp_edit_values->map[i].swap(tmp_edit_values->map[i+1]);
}
_layers_info[i] = _layers_info[i + 1];
@@ -246,7 +246,7 @@ void TextureSet::eraseTexture(size_t id)
if (nTextures > 1)
{
alphamaps[nTextures - 2] = std::nullopt;
alphamaps[nTextures - 2].reset();
}
nTextures--;
@@ -258,7 +258,7 @@ void TextureSet::eraseTexture(size_t id)
// set the default values for the temporary alphamap too
if (tmp_edit_values)
{
tmp_edit_values.value()[nTextures].fill(0.f);
tmp_edit_values->map[nTextures].fill(0.f);
}
_chunk->registerChunkUpdate(ChunkUpdateFlags::ALPHAMAP);
@@ -299,7 +299,7 @@ bool TextureSet::eraseUnusedTextures()
if (tmp_edit_values)
{
auto& amaps = tmp_edit_values.value();
auto& amaps = *tmp_edit_values;
for (int layer = 0; layer < nTextures && visible_tex.size() < nTextures; ++layer)
{
@@ -478,7 +478,7 @@ bool TextureSet::stampTexture(float xbase, float zbase, float x, float z, Brush*
radius = brush->getRadius();
create_temporary_alphamaps_if_needed();
auto& amaps = tmp_edit_values.value();
auto& amaps = *tmp_edit_values;
zPos = zbase;
@@ -770,7 +770,7 @@ bool TextureSet::paintTexture(float xbase, float zbase, float x, float z, Brush*
}
create_temporary_alphamaps_if_needed();
auto& amaps = tmp_edit_values.value();
auto& amaps = *tmp_edit_values;
zPos = zbase;
@@ -968,7 +968,7 @@ bool TextureSet::replace_texture( float xbase
}
create_temporary_alphamaps_if_needed();
auto& amap = tmp_edit_values.value();
auto& amap = *tmp_edit_values;
for (int j = 0; j < 64; j++)
{
@@ -1234,7 +1234,7 @@ void TextureSet::merge_layers(size_t id1, size_t id2)
create_temporary_alphamaps_if_needed();
auto& amap = tmp_edit_values.value();
auto& amap = *tmp_edit_values;
for (int i = 0; i < 64 * 64; ++i)
{
@@ -1278,7 +1278,7 @@ void TextureSet::uploadAlphamapData()
if (tmp_edit_values)
{
auto& tmp_amaps = tmp_edit_values.value();
auto& tmp_amaps = *tmp_edit_values;
for (int i = 0; i < 64 * 64; ++i)
{
@@ -1301,10 +1301,14 @@ void TextureSet::uploadAlphamapData()
{
for (int alpha_id = 0; alpha_id < 3; ++alpha_id)
{
amap[i * 3 + alpha_id] = (alpha_id < nTextures - 1)
? *(alpha_ptr[alpha_id]++) / 255.0f
: 0.f
;
if (alpha_id < nTextures - 1)
{
amap[i * 3 + alpha_id] = *(alpha_ptr[alpha_id]++) / 255.0f;
}
else
{
amap[i * 3 + alpha_id] = 0.f;
}
}
}
@@ -1318,12 +1322,12 @@ void TextureSet::uploadAlphamapData()
namespace
{
misc::max_capacity_stack_vector<std::size_t, 4> current_layer_values
(std::uint8_t nTextures, std::optional<Alphamap> const* alphamaps, std::size_t pz, std::size_t px)
(std::uint8_t nTextures, const std::array<std::unique_ptr<Alphamap>, 3>& alphamaps, std::size_t pz, std::size_t px)
{
misc::max_capacity_stack_vector<std::size_t, 4> values (nTextures, 0xFF);
for (std::uint8_t i = 1; i < nTextures; ++i)
{
values[i] = alphamaps[i - 1].value().getAlpha(64 * pz + px);
values[i] = alphamaps[i - 1]->getAlpha(64 * pz + px);
values[0] -= values[i];
}
return values;
@@ -1345,7 +1349,7 @@ void TextureSet::update_lod_texture_map()
{
for (int px = x * 8; px < (x + 1) * 8; ++px)
{
++dominant_square_count[max_element_index (current_layer_values (static_cast<std::uint8_t>(nTextures), alphamaps.data(), pz, px))];
++dominant_square_count[max_element_index (current_layer_values (static_cast<std::uint8_t>(nTextures), alphamaps, pz, px))];
}
}
//lod.push_back (max_element_index (dominant_square_count));
@@ -1548,11 +1552,11 @@ bool TextureSet::apply_alpha_changes()
{
if (!tmp_edit_values || nTextures < 2)
{
tmp_edit_values = std::nullopt;
tmp_edit_values.reset();
return false;
}
auto& new_amaps = tmp_edit_values.value();
auto& new_amaps = *tmp_edit_values;
std::array<std::uint16_t, 64 * 64> totals;
totals.fill(0);
@@ -1579,7 +1583,7 @@ bool TextureSet::apply_alpha_changes()
_chunk->registerChunkUpdate(ChunkUpdateFlags::ALPHAMAP);
_need_lod_texture_map_update = true;
tmp_edit_values = std::nullopt;
tmp_edit_values.reset();
return true;
}
@@ -1591,9 +1595,9 @@ void TextureSet::create_temporary_alphamaps_if_needed()
return;
}
tmp_edit_values.emplace();
tmp_edit_values = std::make_unique<tmp_edit_alpha_values>();
tmp_edit_alpha_values& values = tmp_edit_values.value();
tmp_edit_alpha_values& values = *tmp_edit_values;
for (int i = 0; i < 64 * 64; ++i)
{

View File

@@ -99,8 +99,20 @@ public:
std::array<std::uint16_t, 8> lod_texture_map();
std::array<std::optional<Alphamap>, 3>* getAlphamaps() { return &alphamaps; };
std::optional<tmp_edit_alpha_values>* getTempAlphamaps() { return &tmp_edit_values; };
std::array<std::unique_ptr<Alphamap>, MAX_ALPHAMAPS>* getAlphamaps() { return &alphamaps; };
std::unique_ptr<tmp_edit_alpha_values>& getTempAlphamaps() { return tmp_edit_values; };
void setAlphamaps(const std::array<std::unique_ptr<Alphamap>, MAX_ALPHAMAPS>& newAlphamaps) {
for (int i = 0; i < MAX_ALPHAMAPS; ++i)
{
if (newAlphamaps[i])
{
alphamaps[i] = std::make_unique<Alphamap>(*newAlphamaps[i]);
}
else
alphamaps[i].reset();
}
}
int get_texture_index_or_add (scoped_blp_texture_reference texture, float target);
@@ -137,7 +149,7 @@ private:
MapChunk* _chunk;
std::vector<scoped_blp_texture_reference> textures;
std::array<std::optional<Alphamap>, 3> alphamaps;
std::array<std::unique_ptr<Alphamap>, MAX_ALPHAMAPS> alphamaps;
size_t nTextures;
// byte[8][8] // can store the 2bits value in a byte, but might never be higher than 3 or layer count.
@@ -148,10 +160,9 @@ private:
bool _need_lod_texture_map_update = false;
// ENTRY_MCLY _layers_info[4]; // TODO rework this, don't need to store textureid and offset
layer_info _layers_info[4];
std::optional<tmp_edit_alpha_values> tmp_edit_values;
std::unique_ptr<tmp_edit_alpha_values> tmp_edit_values;
bool _do_not_convert_alphamaps;

View File

@@ -266,12 +266,12 @@ namespace Noggit
{
// WoW calculates layer 0 as 255 - sum(Layer[1]...Layer[3])
int layers_sum = 0;
if (alphamaps->at(0).has_value())
layers_sum += alphamaps->at(0).value().getAlpha(64 * l + k);
if (alphamaps->at(1).has_value())
layers_sum += alphamaps->at(1).value().getAlpha(64 * l + k);
if (alphamaps->at(2).has_value())
layers_sum += alphamaps->at(2).value().getAlpha(64 * l + k);
if (alphamaps->at(0))
layers_sum += alphamaps->at(0)->getAlpha(64 * l + k);
if (alphamaps->at(1))
layers_sum += alphamaps->at(1)->getAlpha(64 * l + k);
if (alphamaps->at(2))
layers_sum += alphamaps->at(2)->getAlpha(64 * l + k);
int value = std::clamp((255 - layers_sum), 0, 255);
image.setPixelColor(k, l, QColor(value, value, value, 255));
@@ -280,7 +280,7 @@ namespace Noggit
}
else // layer 1-3
{
auto& alpha_layer = alphamaps->at(index - 1).value();
auto& alpha_layer = *alphamaps->at(index - 1);
int value = alpha_layer.getAlpha(64 * l + k);
image.setPixelColor(k, l, QColor(value, value, value, 255));

View File

@@ -165,8 +165,23 @@ void ChunkClipboard::copySelected(glm::vec3 const& pos, ChunkCopyFlags flags)
auto texture_set = chunk->getTextureSet();
cache.n_textures = texture_set->num();
cache.alphamaps = *texture_set->getAlphamaps();
cache.tmp_edit_values = *texture_set->getTempAlphamaps();
// cache.alphamaps = *texture_set->getAlphamaps();
// cache.tmp_edit_values = *texture_set->getTempAlphamaps();
const auto& sourceAlphamaps = *texture_set->getAlphamaps();
for (size_t i = 0; i < MAX_ALPHAMAPS; ++i)
{
if (sourceAlphamaps[i])
cache.alphamaps[i] = std::make_unique<Alphamap>(*sourceAlphamaps[i]);
else
cache.alphamaps[i].reset();
}
const auto& source_temp_alphas = texture_set->getTempAlphamaps();
if (source_temp_alphas)
cache.tmp_edit_values = std::make_unique<tmp_edit_alpha_values>(*source_temp_alphas);
else
cache.tmp_edit_values.reset();
std::memcpy(&cache.layers_info, texture_set->getMCLYEntries(), sizeof(layer_info) * 4);
for (int i = 0; i < cache.n_textures; ++i)
@@ -174,7 +189,7 @@ void ChunkClipboard::copySelected(glm::vec3 const& pos, ChunkCopyFlags flags)
cache.textures.push_back(texture_set->filename(i));
}
chunk_cache.textures = cache;
chunk_cache.textures = std::move(cache);
}

View File

@@ -55,8 +55,8 @@ namespace Noggit::Ui::Tools::ChunkManipulator
{
size_t n_textures;
std::vector<std::string> textures;
std::array<std::optional<Alphamap>, 3> alphamaps;
std::optional<tmp_edit_alpha_values> tmp_edit_values;
std::array<std::unique_ptr<Alphamap>, 3> alphamaps;
std::unique_ptr<tmp_edit_alpha_values> tmp_edit_values;
ENTRY_MCLY layers_info[4];
};

View File

@@ -59,7 +59,7 @@ void ChunkGetAlphaLayerNode::compute()
texture_set->apply_alpha_changes();
auto alphamaps = texture_set->getAlphamaps();
auto alpha_layer = alphamaps->at(layer - 1).value();
Alphamap& alpha_layer = *alphamaps->at(layer - 1);
QImage image(64, 64, QImage::Format_RGBA8888);

View File

@@ -65,7 +65,7 @@ void ChunkSetAlphaLayerNode::compute()
}
texture_set->create_temporary_alphamaps_if_needed();
auto& temp_alphamaps = texture_set->getTempAlphamaps()->value();
auto& temp_alphamaps = *texture_set->getTempAlphamaps();
for (int i = 0; i < 64; ++i)
{

View File

@@ -312,6 +312,7 @@ namespace Noggit
_settings->sync();
// calls MapView::onSettingsSave()
emit saved();
}
}