mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2024-11-21 19:45:10 +00:00
Keep the previous dynamic pool in memory
Due to sm64 weirdness, I can't reliably free memory at certain points The hacky solution is to keep the previous dynamic pool in memory, essentially requiring two frees to actually clear all memory from it
This commit is contained in:
parent
c126bf82b3
commit
f53ffcd491
6 changed files with 19 additions and 29 deletions
|
@ -21,18 +21,12 @@ struct ModelInfo {
|
|||
enum ModelPool modelPool;
|
||||
};
|
||||
|
||||
struct ScheduledFreePool {
|
||||
struct DynamicPool* pool;
|
||||
};
|
||||
|
||||
static struct DynamicPool* sModelPools[MODEL_POOL_MAX] = { 0 };
|
||||
|
||||
static std::map<void*, struct ModelInfo> sAssetMap[MODEL_POOL_MAX];
|
||||
static std::map<u32, std::vector<struct ModelInfo>> sIdMap;
|
||||
static std::map<u32, u32> sOverwriteMap;
|
||||
|
||||
static std::vector<struct ScheduledFreePool> sPoolsToFree;
|
||||
|
||||
static u32 find_empty_id() {
|
||||
u32 id = 256;
|
||||
while (true) {
|
||||
|
@ -168,12 +162,7 @@ void DynOS_Model_ClearPool(enum ModelPool aModelPool) {
|
|||
if (!sModelPools[aModelPool]) { return; }
|
||||
|
||||
// schedule pool to be freed
|
||||
sPoolsToFree.push_back({
|
||||
.pool = sModelPools[aModelPool],
|
||||
});
|
||||
|
||||
// clear pointer
|
||||
sModelPools[aModelPool] = NULL;
|
||||
dynamic_pool_free_pool(sModelPools[aModelPool]);
|
||||
|
||||
// clear overwrite
|
||||
if (aModelPool == MODEL_POOL_LEVEL) {
|
||||
|
@ -202,12 +191,4 @@ void DynOS_Model_ClearPool(enum ModelPool aModelPool) {
|
|||
|
||||
void DynOS_Model_Update() {
|
||||
|
||||
// only free a pool when we've scheduled at least 3
|
||||
// this is required because the way that sm64 loads areas is actually insane
|
||||
// if we free immediately, the camera graph node is incorrect on the star selection screen
|
||||
if (sPoolsToFree.size() <= 2) { return; }
|
||||
|
||||
auto& it = sPoolsToFree[0];
|
||||
dynamic_pool_free_pool(it.pool);
|
||||
sPoolsToFree.erase(sPoolsToFree.begin());
|
||||
}
|
|
@ -366,7 +366,6 @@ static void level_reset_globals(void) {
|
|||
// free previous level pool
|
||||
if (gLevelPool != NULL) {
|
||||
dynamic_pool_free_pool(gLevelPool);
|
||||
gLevelPool = NULL;
|
||||
}
|
||||
|
||||
// reset envfx
|
||||
|
|
|
@ -156,11 +156,8 @@ void envfx_update_snowflake_count(s32 mode, Vec3s marioPos) {
|
|||
* Deallocate the buffer storing snow particles and set the environment effect
|
||||
* to none.
|
||||
*/
|
||||
void envfx_cleanup_snow(void *snowParticleArray) {
|
||||
void envfx_cleanup_snow(UNUSED void *snowParticleArray) {
|
||||
if (gEnvFxMode) {
|
||||
if (snowParticleArray) {
|
||||
dynamic_pool_free(gLevelPool, snowParticleArray);
|
||||
}
|
||||
gEnvFxMode = ENVFX_MODE_NONE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ struct DynamicPool* dynamic_pool_init(void) {
|
|||
struct DynamicPool* pool = calloc(1, sizeof(struct DynamicPool));
|
||||
pool->usedSpace = 0;
|
||||
pool->tail = NULL;
|
||||
pool->nextFree = NULL;
|
||||
return pool;
|
||||
}
|
||||
|
||||
|
@ -75,14 +76,19 @@ bool dynamic_pool_contains(struct DynamicPool *pool, void* ptr) {
|
|||
|
||||
void dynamic_pool_free_pool(struct DynamicPool *pool) {
|
||||
if (!pool) { return; }
|
||||
struct DynamicPoolNode* node = pool->tail;
|
||||
|
||||
struct DynamicPoolNode* node = pool->nextFree;
|
||||
while (node) {
|
||||
struct DynamicPoolNode* prev = node->prev;
|
||||
free(node->ptr);
|
||||
free(node);
|
||||
node = prev;
|
||||
}
|
||||
free(pool);
|
||||
|
||||
// schedule current pool to be free'd on the next call
|
||||
pool->nextFree = pool->tail;
|
||||
pool->tail = NULL;
|
||||
pool->usedSpace = 0;
|
||||
}
|
||||
|
||||
//////////////////
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
struct DynamicPool
|
||||
{
|
||||
u32 usedSpace;
|
||||
struct DynamicPoolNode* nextFree;
|
||||
struct DynamicPoolNode* tail;
|
||||
};
|
||||
|
||||
|
|
|
@ -1526,8 +1526,14 @@ Gfx *display_painting_rippling(struct Painting *painting) {
|
|||
}
|
||||
|
||||
// The mesh data is freed every frame.
|
||||
dynamic_pool_free(gLevelPool, painting->ripples.paintingMesh);
|
||||
dynamic_pool_free(gLevelPool, painting->ripples.paintingTriNorms);
|
||||
if (painting->ripples.paintingMesh) {
|
||||
dynamic_pool_free(gLevelPool, painting->ripples.paintingMesh);
|
||||
painting->ripples.paintingMesh = NULL;
|
||||
}
|
||||
if (painting->ripples.paintingTriNorms) {
|
||||
dynamic_pool_free(gLevelPool, painting->ripples.paintingTriNorms);
|
||||
painting->ripples.paintingTriNorms = NULL;
|
||||
}
|
||||
return dlist;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue