Separate context freeing from task freeing in threaded particle updates
to prevent double-freeing/invalid mem access. This can happen with the "virtual parents" feature, which generates both parent and child paths. Each task free function also freed the shared context, leading to double freeing.
This commit is contained in:
parent
1727a165dd
commit
b292d783f2
|
@ -350,6 +350,7 @@ void psys_get_dupli_path_transform(struct ParticleSimulationData *sim, struct Pa
|
|||
struct ParticleCacheKey *cache, float mat[4][4], float *scale);
|
||||
|
||||
void psys_thread_context_init(struct ParticleThreadContext *ctx, struct ParticleSimulationData *sim);
|
||||
void psys_thread_context_free(struct ParticleThreadContext *ctx);
|
||||
void psys_tasks_create(struct ParticleThreadContext *ctx, int totpart, struct ParticleTask **r_tasks, int *r_numtasks);
|
||||
void psys_tasks_free(struct ParticleTask *tasks, int numtasks);
|
||||
|
||||
|
|
|
@ -2587,6 +2587,8 @@ void psys_cache_child_paths(ParticleSimulationData *sim, float cfra, int editupd
|
|||
|
||||
psys_tasks_free(tasks_parent, numtasks_parent);
|
||||
psys_tasks_free(tasks_child, numtasks_child);
|
||||
|
||||
psys_thread_context_free(&ctx);
|
||||
}
|
||||
|
||||
/* figure out incremental rotations along path starting from unit quat */
|
||||
|
|
|
@ -1140,6 +1140,8 @@ static void distribute_particles_on_dm(ParticleSimulationData *sim, int from)
|
|||
ctx.dm->release(ctx.dm);
|
||||
|
||||
psys_tasks_free(tasks, numtasks);
|
||||
|
||||
psys_thread_context_free(&ctx);
|
||||
}
|
||||
|
||||
/* ready for future use, to emit particles without geometry */
|
||||
|
|
|
@ -471,13 +471,24 @@ void psys_tasks_create(ParticleThreadContext *ctx, int totpart, ParticleTask **r
|
|||
|
||||
void psys_tasks_free(ParticleTask *tasks, int numtasks)
|
||||
{
|
||||
ParticleThreadContext *ctx;
|
||||
int i;
|
||||
|
||||
if (numtasks == 0)
|
||||
return;
|
||||
|
||||
ctx = tasks[0].ctx;
|
||||
/* threads */
|
||||
for (i = 0; i < numtasks; ++i) {
|
||||
if (tasks[i].rng)
|
||||
BLI_rng_free(tasks[i].rng);
|
||||
if (tasks[i].rng_path)
|
||||
BLI_rng_free(tasks[i].rng_path);
|
||||
}
|
||||
|
||||
MEM_freeN(tasks);
|
||||
}
|
||||
|
||||
void psys_thread_context_free(ParticleThreadContext *ctx)
|
||||
{
|
||||
/* path caching */
|
||||
if (ctx->vg_length)
|
||||
MEM_freeN(ctx->vg_length);
|
||||
|
@ -506,16 +517,6 @@ void psys_tasks_free(ParticleTask *tasks, int numtasks)
|
|||
if (ctx->seams) MEM_freeN(ctx->seams);
|
||||
//if (ctx->vertpart) MEM_freeN(ctx->vertpart);
|
||||
BLI_kdtree_free(ctx->tree);
|
||||
|
||||
/* threads */
|
||||
for (i = 0; i < numtasks; ++i) {
|
||||
if (tasks[i].rng)
|
||||
BLI_rng_free(tasks[i].rng);
|
||||
if (tasks[i].rng_path)
|
||||
BLI_rng_free(tasks[i].rng_path);
|
||||
}
|
||||
|
||||
MEM_freeN(tasks);
|
||||
}
|
||||
|
||||
static void initialize_particle_texture(ParticleSimulationData *sim, ParticleData *pa, int p)
|
||||
|
|
Loading…
Reference in New Issue