Fix: Memory leak and race condition with particle effector RNG
Store RNG on per thread data, instead of the effector itself which may be used by multiple objects evaluated in different threads. This has been causing the blendfile_versioning test to fail randomly. Thanks Ray and Aras for helping track this down. Pull Request: https://projects.blender.org/blender/blender/pulls/119967
This commit is contained in:
parent
d2b38a475f
commit
8682ad1908
|
@ -16,6 +16,7 @@ extern "C" {
|
|||
struct Collection;
|
||||
struct Depsgraph;
|
||||
struct ListBase;
|
||||
struct RNG;
|
||||
struct Object;
|
||||
struct ParticleData;
|
||||
struct ParticleKey;
|
||||
|
@ -78,6 +79,9 @@ typedef struct EffectorCache {
|
|||
|
||||
struct PartDeflect *pd;
|
||||
|
||||
/** Random noise generator for e.g. wind. */
|
||||
struct RNG *rng;
|
||||
|
||||
/* precalculated for guides */
|
||||
struct GuideEffectorData *guide_data;
|
||||
float guide_loc[4], guide_dir[3], guide_radius;
|
||||
|
|
|
@ -113,9 +113,6 @@ PartDeflect *BKE_partdeflect_copy(const PartDeflect *pd_src)
|
|||
return nullptr;
|
||||
}
|
||||
PartDeflect *pd_dst = static_cast<PartDeflect *>(MEM_dupallocN(pd_src));
|
||||
if (pd_dst->rng != nullptr) {
|
||||
pd_dst->rng = BLI_rng_copy(pd_dst->rng);
|
||||
}
|
||||
return pd_dst;
|
||||
}
|
||||
|
||||
|
@ -124,9 +121,6 @@ void BKE_partdeflect_free(PartDeflect *pd)
|
|||
if (!pd) {
|
||||
return;
|
||||
}
|
||||
if (pd->rng) {
|
||||
BLI_rng_free(pd->rng);
|
||||
}
|
||||
MEM_freeN(pd);
|
||||
}
|
||||
|
||||
|
@ -136,12 +130,8 @@ static void precalculate_effector(Depsgraph *depsgraph, EffectorCache *eff)
|
|||
{
|
||||
float ctime = DEG_get_ctime(depsgraph);
|
||||
uint cfra = uint(ctime >= 0 ? ctime : -ctime);
|
||||
if (!eff->pd->rng) {
|
||||
eff->pd->rng = BLI_rng_new(eff->pd->seed + cfra);
|
||||
}
|
||||
else {
|
||||
BLI_rng_srandom(eff->pd->rng, eff->pd->seed + cfra);
|
||||
}
|
||||
|
||||
eff->rng = BLI_rng_new(eff->pd->seed + cfra);
|
||||
|
||||
if (eff->pd->forcefield == PFIELD_GUIDE && eff->ob->type == OB_CURVES_LEGACY) {
|
||||
Curve *cu = static_cast<Curve *>(eff->ob->data);
|
||||
|
@ -375,6 +365,9 @@ void BKE_effectors_free(ListBase *lb)
|
|||
{
|
||||
if (lb) {
|
||||
LISTBASE_FOREACH (EffectorCache *, eff, lb) {
|
||||
if (eff->rng) {
|
||||
BLI_rng_free(eff->rng);
|
||||
}
|
||||
if (eff->guide_data) {
|
||||
MEM_freeN(eff->guide_data);
|
||||
}
|
||||
|
@ -960,7 +953,7 @@ static void do_physical_effector(EffectorCache *eff,
|
|||
float *total_force)
|
||||
{
|
||||
PartDeflect *pd = eff->pd;
|
||||
RNG *rng = pd->rng;
|
||||
RNG *rng = eff->rng;
|
||||
float force[3] = {0, 0, 0};
|
||||
float temp[3];
|
||||
float fac;
|
||||
|
|
|
@ -245,9 +245,6 @@ static void object_copy_data(Main *bmain,
|
|||
|
||||
if (ob_src->pd) {
|
||||
ob_dst->pd = (PartDeflect *)MEM_dupallocN(ob_src->pd);
|
||||
if (ob_dst->pd->rng) {
|
||||
ob_dst->pd->rng = (RNG *)MEM_dupallocN(ob_src->pd->rng);
|
||||
}
|
||||
}
|
||||
BKE_rigidbody_object_copy(bmain, ob_dst, ob_src, flag_subdata);
|
||||
|
||||
|
|
|
@ -313,11 +313,8 @@ static void particle_settings_blend_write(BlendWriter *writer, ID *id, const voi
|
|||
}
|
||||
}
|
||||
|
||||
void BKE_particle_partdeflect_blend_read_data(BlendDataReader * /*reader*/, PartDeflect *pd)
|
||||
void BKE_particle_partdeflect_blend_read_data(BlendDataReader * /*reader*/, PartDeflect * /*pd*/)
|
||||
{
|
||||
if (pd) {
|
||||
pd->rng = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
static void particle_settings_blend_read_data(BlendDataReader *reader, ID *id)
|
||||
|
|
|
@ -131,8 +131,6 @@ typedef struct PartDeflect {
|
|||
struct Tex *tex;
|
||||
|
||||
/* effector noise */
|
||||
/** Random noise generator for e.g. wind. */
|
||||
struct RNG *rng;
|
||||
/** Noise of force. */
|
||||
float f_noise;
|
||||
/** Noise random seed. */
|
||||
|
|
Loading…
Reference in New Issue