Fix crash happening in Cycles fcurve modifier
Summary: Crash was happening because of fcurve modifier stack used modifier's DNA to store temporary data. Now made it so storage for such a thing is being allocated locally per object update so multiple objects which shares the same animation wouldn't run into threading conflict anymore. This storage might be a part of EvaluationContext, but that'd mean passing this context all over in object_where_is which will clutter API for now without actual benefit for this. Optimization notes: storage is only being allocated if there're Cycles modifier in the stack, so there're no extra allocations happening in all other cases. To make code a bit less cluttered with this storage passing all over the place added extra callbacks to the FModifier storage which runs evaluation with the given storage. Reviewers: brecht, campbellbarton, aligorith CC: plasmasolutions Differential Revision: https://developer.blender.org/D147
This commit is contained in:
@@ -99,6 +99,8 @@ float driver_get_variable_value(struct ChannelDriver *driver, struct DriverVar *
|
||||
|
||||
/* ************** F-Curve Modifiers *************** */
|
||||
|
||||
typedef struct GHash FModifierStackStorage;
|
||||
|
||||
/* F-Curve Modifier Type-Info (fmi):
|
||||
* This struct provides function pointers for runtime, so that functions can be
|
||||
* written more generally (with fewer/no special exceptions for various modifiers).
|
||||
@@ -134,6 +136,10 @@ typedef struct FModifierTypeInfo {
|
||||
float (*evaluate_modifier_time)(struct FCurve *fcu, struct FModifier *fcm, float cvalue, float evaltime);
|
||||
/* evaluate the modifier for the given time and 'accumulated' value */
|
||||
void (*evaluate_modifier)(struct FCurve *fcu, struct FModifier *fcm, float *cvalue, float evaltime);
|
||||
|
||||
/* Same as above but for modifiers which requires storage */
|
||||
float (*evaluate_modifier_time_storage)(FModifierStackStorage *storage, struct FCurve *fcu, struct FModifier *fcm, float cvalue, float evaltime);
|
||||
void (*evaluate_modifier_storage)(FModifierStackStorage *storage, struct FCurve *fcu, struct FModifier *fcm, float *cvalue, float evaltime);
|
||||
} FModifierTypeInfo;
|
||||
|
||||
/* Values which describe the behavior of a FModifier Type */
|
||||
@@ -157,7 +163,10 @@ typedef enum eFMI_Requirement_Flags {
|
||||
*/
|
||||
FMI_REQUIRES_NOTHING = (1 << 1),
|
||||
/* refer to modifier instance */
|
||||
FMI_REQUIRES_RUNTIME_CHECK = (1 << 2)
|
||||
FMI_REQUIRES_RUNTIME_CHECK = (1 << 2),
|
||||
|
||||
/* Requires to store data shared between time and valua evaluation */
|
||||
FMI_REQUIRES_STORAGE = (1 << 3)
|
||||
} eFMI_Requirement_Flags;
|
||||
|
||||
/* Function Prototypes for FModifierTypeInfo's */
|
||||
@@ -177,8 +186,10 @@ void set_active_fmodifier(ListBase *modifiers, struct FModifier *fcm);
|
||||
|
||||
short list_has_suitable_fmodifier(ListBase *modifiers, int mtype, short acttype);
|
||||
|
||||
float evaluate_time_fmodifiers(ListBase *modifiers, struct FCurve *fcu, float cvalue, float evaltime);
|
||||
void evaluate_value_fmodifiers(ListBase *modifiers, struct FCurve *fcu, float *cvalue, float evaltime);
|
||||
FModifierStackStorage *evaluate_fmodifiers_storage_new(ListBase *modifiers);
|
||||
void evaluate_fmodifiers_storage_free(FModifierStackStorage *storage);
|
||||
float evaluate_time_fmodifiers(FModifierStackStorage *storage, ListBase *modifiers, struct FCurve *fcu, float cvalue, float evaltime);
|
||||
void evaluate_value_fmodifiers(FModifierStackStorage *storage, ListBase *modifiers, struct FCurve *fcu, float *cvalue, float evaltime);
|
||||
|
||||
void fcurve_bake_modifiers(struct FCurve *fcu, int start, int end);
|
||||
|
||||
|
Reference in New Issue
Block a user