Fix T53115: Memleak with instanced groups and Cycles

The issue was caused by Cycles allocating ID property in a temporary object
which gets overwritten and thrown away every so often.

Now dependency graph will try to reliably check whether ID properties from
a temp object are to be freed.
This commit is contained in:
2018-01-24 15:46:34 +01:00
parent 9f713ec962
commit ca088a7b12

View File

@@ -58,6 +58,30 @@ extern "C" {
/* ************************ DEG ITERATORS ********************* */ /* ************************ DEG ITERATORS ********************* */
static void verify_id_proeprties_freed(DEGObjectIterData *data)
{
if (data->dupli_object_current == NULL) {
// We didn't enter duplication yet, so we can't have any dangling
// pointers.
return;
}
const Object *dupli_object = data->dupli_object_current->ob;
Object *temp_dupli_object = &data->temp_dupli_object;
if (temp_dupli_object->id.properties == NULL) {
// No ID proeprties in temp datablock -- no leak is possible.
return;
}
if (temp_dupli_object->id.properties == dupli_object->id.properties) {
// Temp copy of object did not modify ID properties.
return;
}
// Free memory which is owned by temporary storage which is about to
// get overwritten.
IDP_FreeProperty(temp_dupli_object->id.properties);
MEM_freeN(temp_dupli_object->id.properties);
temp_dupli_object->id.properties = NULL;
}
static bool deg_objects_dupli_iterator_next(BLI_Iterator *iter) static bool deg_objects_dupli_iterator_next(BLI_Iterator *iter)
{ {
DEGObjectIterData *data = (DEGObjectIterData *)iter->data; DEGObjectIterData *data = (DEGObjectIterData *)iter->data;
@@ -78,6 +102,8 @@ static bool deg_objects_dupli_iterator_next(BLI_Iterator *iter)
continue; continue;
} }
verify_id_proeprties_freed(data);
data->dupli_object_current = dob; data->dupli_object_current = dob;
/* Temporary object to evaluate. */ /* Temporary object to evaluate. */
@@ -215,6 +241,7 @@ void DEG_iterator_objects_next(BLI_Iterator *iter)
return; return;
} }
else { else {
verify_id_proeprties_freed(data);
free_object_duplilist(data->dupli_list); free_object_duplilist(data->dupli_list);
data->dupli_parent = NULL; data->dupli_parent = NULL;
data->dupli_list = NULL; data->dupli_list = NULL;