diff options
author | Joshua Leung <aligorith@gmail.com> | 2011-07-24 08:34:46 +0400 |
---|---|---|
committer | Joshua Leung <aligorith@gmail.com> | 2011-07-24 08:34:46 +0400 |
commit | 6a392e8cb505b753a0bac24e42778306007c45b8 (patch) | |
tree | 6d34591894fec168b8535fae88455ef8446f0a2a /source/blender/blenkernel/intern | |
parent | c22f26d2032b7116477e6a378407a10b6d7e3276 (diff) |
== RNA Property Updates get called by Animation System now ==
This fixes bug #26764 and several others like it, where modifier
properties (and others, but most visibly modifiers) would not do
anything when animated or driven, as modifier properties require the
RNA update calls to tag the modifiers to get recalculated.
While just adding a call to RNA_property_update() could have gotten
this working (as per the Campbell's patch attached in the report, and
also my own attempt #25881). However, on production rigs, the
performance cost of this is untenatable (on my own tests, without
these updates, I was getting ~5fps on such a rig, but only 0.9fps or
possibly even worse with the updates added).
Hence, this commit adds a property-update caching system to the RNA
level, which aims to reduce to the number of times that the update
functions end up needing to get called.
While this is much faster than without the caching, I also added an
optimisation for pose bones (which are numerous in production rigs) so
that their property updates are skipped, since they are useless to the
animsys (they only tag the depsgraph for updating). This gets things
moving at a more acceptable framerate.
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r-- | source/blender/blenkernel/intern/action.c | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/anim.c | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/anim_sys.c | 34 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/blender.c | 5 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/key.c | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/object.c | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/particle_system.c | 8 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/scene.c | 10 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/sequencer.c | 4 |
9 files changed, 50 insertions, 23 deletions
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index e69ff5df913..a6539f00605 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -1197,7 +1197,7 @@ void what_does_obaction (Object *ob, Object *workob, bPose *pose, bAction *act, adt.action= act; /* execute effects of Action on to workob (or it's PoseChannels) */ - BKE_animsys_evaluate_animdata(&workob->id, &adt, cframe, ADT_RECALC_ANIM); + BKE_animsys_evaluate_animdata(NULL, &workob->id, &adt, cframe, ADT_RECALC_ANIM); } } diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index 3300c82cae2..7ddb078ef8e 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -796,7 +796,7 @@ static void frames_duplilist(ListBase *lb, Scene *scene, Object *ob, int level, * and/or other objects which may affect this object's transforms are not updated either. * However, this has always been the way that this worked (i.e. pre 2.5), so I guess that it'll be fine! */ - BKE_animsys_evaluate_animdata(&ob->id, ob->adt, (float)scene->r.cfra, ADT_RECALC_ANIM); /* ob-eval will do drivers, so we don't need to do them */ + BKE_animsys_evaluate_animdata(scene, &ob->id, ob->adt, (float)scene->r.cfra, ADT_RECALC_ANIM); /* ob-eval will do drivers, so we don't need to do them */ where_is_object_time(scene, ob, (float)scene->r.cfra); dob= new_dupli_object(lb, ob, ob->obmat, ob->lay, scene->r.cfra, OB_DUPLIFRAMES, animated); @@ -811,7 +811,7 @@ static void frames_duplilist(ListBase *lb, Scene *scene, Object *ob, int level, */ scene->r.cfra= cfrao; - BKE_animsys_evaluate_animdata(&ob->id, ob->adt, (float)scene->r.cfra, ADT_RECALC_ANIM); /* ob-eval will do drivers, so we don't need to do them */ + BKE_animsys_evaluate_animdata(scene, &ob->id, ob->adt, (float)scene->r.cfra, ADT_RECALC_ANIM); /* ob-eval will do drivers, so we don't need to do them */ where_is_object_time(scene, ob, (float)scene->r.cfra); /* but, to make sure unkeyed object transforms are still sane, diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index 69458ec7401..3e59accc599 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -1116,7 +1116,7 @@ static short animsys_write_rna_setting (PointerRNA *ptr, char *path, int array_i { int array_len= RNA_property_array_length(&new_ptr, prop); - if(array_len && array_index >= array_len) + if (array_len && array_index >= array_len) { if (G.f & G_DEBUG) { printf("Animato: Invalid array index. ID = '%s', '%s[%d]', array length is %d \n", @@ -1154,6 +1154,23 @@ static short animsys_write_rna_setting (PointerRNA *ptr, char *path, int array_i /* nothing can be done here... so it is unsuccessful? */ return 0; } + + /* buffer property update for later flushing */ + if (RNA_property_update_check(prop)) { + short skip_updates_hack = 0; + + /* optimisation hacks: skip property updates for those properties + * for we know that which the updates in RNA were really just for + * flushing property editing via UI/Py + */ + if (RNA_struct_is_a(new_ptr.type, &RNA_PoseBone)) { + /* bone transforms - update pose (i.e. tag depsgraph) */ + skip_updates_hack = 1; + } + + if (skip_updates_hack == 0) + RNA_property_update_cache_add(&new_ptr, prop); + } } /* successful */ @@ -2132,8 +2149,9 @@ static void animsys_evaluate_overrides (PointerRNA *ptr, AnimData *adt) * and that the flags for which parts of the anim-data settings need to be recalculated * have been set already by the depsgraph. Now, we use the recalc */ -void BKE_animsys_evaluate_animdata (ID *id, AnimData *adt, float ctime, short recalc) +void BKE_animsys_evaluate_animdata (Scene *scene, ID *id, AnimData *adt, float ctime, short recalc) { + Main *bmain = G.main; // xxx - to get passed in! PointerRNA id_ptr; /* sanity checks */ @@ -2184,6 +2202,10 @@ void BKE_animsys_evaluate_animdata (ID *id, AnimData *adt, float ctime, short re */ animsys_evaluate_overrides(&id_ptr, adt); + /* execute and clear all cached property update functions */ + RNA_property_update_cache_flush(bmain, scene); + RNA_property_update_cache_free(); + /* clear recalc flag now */ adt->recalc= 0; } @@ -2195,7 +2217,7 @@ void BKE_animsys_evaluate_animdata (ID *id, AnimData *adt, float ctime, short re * 'local' (i.e. belonging in the nearest ID-block that setting is related to, not a * standard 'root') block are overridden by a larger 'user' */ -void BKE_animsys_evaluate_all_animation (Main *main, float ctime) +void BKE_animsys_evaluate_all_animation (Main *main, Scene *scene, float ctime) { ID *id; @@ -2211,7 +2233,7 @@ void BKE_animsys_evaluate_all_animation (Main *main, float ctime) for (id= first; id; id= id->next) { \ if (ID_REAL_USERS(id) > 0) { \ AnimData *adt= BKE_animdata_from_id(id); \ - BKE_animsys_evaluate_animdata(id, adt, ctime, aflag); \ + BKE_animsys_evaluate_animdata(scene, id, adt, ctime, aflag); \ } \ } /* another macro for the "embedded" nodetree cases @@ -2227,9 +2249,9 @@ void BKE_animsys_evaluate_all_animation (Main *main, float ctime) NtId_Type *ntp= (NtId_Type *)id; \ if (ntp->nodetree) { \ AnimData *adt2= BKE_animdata_from_id((ID *)ntp->nodetree); \ - BKE_animsys_evaluate_animdata((ID *)ntp->nodetree, adt2, ctime, ADT_RECALC_ANIM); \ + BKE_animsys_evaluate_animdata(scene, (ID *)ntp->nodetree, adt2, ctime, ADT_RECALC_ANIM); \ } \ - BKE_animsys_evaluate_animdata(id, adt, ctime, aflag); \ + BKE_animsys_evaluate_animdata(scene, id, adt, ctime, aflag); \ } \ } diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 8b4bbbd3c83..d573da603f6 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -90,6 +90,8 @@ #include "BKE_utildefines.h" +#include "RNA_access.h" + #include "WM_api.h" // XXXXX BAD, very BAD dependency (bad level call) - remove asap, elubie Global G; @@ -239,6 +241,9 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath // CTX_wm_manager_set(C, NULL); clear_global(); + /* clear old property update cache, in case some old references are left dangling */ + RNA_property_update_cache_free(); + G.main= bfd->main; CTX_data_main_set(C, G.main); diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c index 8b0cfb1d156..50c120a3ec1 100644 --- a/source/blender/blenkernel/intern/key.c +++ b/source/blender/blenkernel/intern/key.c @@ -1400,7 +1400,7 @@ float *do_ob_key(Scene *scene, Object *ob) /* do shapekey local drivers */ float ctime= (float)scene->r.cfra; // XXX this needs to be checked - BKE_animsys_evaluate_animdata(&key->id, key->adt, ctime, ADT_RECALC_DRIVERS); + BKE_animsys_evaluate_animdata(scene, &key->id, key->adt, ctime, ADT_RECALC_DRIVERS); if(ob->type==OB_MESH) do_mesh_key(scene, ob, key, out, tot); else if(ob->type==OB_LATTICE) do_latt_key(scene, ob, key, out, tot); diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index dff62b05bd3..862d583bd34 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -2084,7 +2084,7 @@ void where_is_object_time(Scene *scene, Object *ob, float ctime) if(ob==NULL) return; /* execute drivers only, as animation has already been done */ - BKE_animsys_evaluate_animdata(&ob->id, ob->adt, ctime, ADT_RECALC_DRIVERS); + BKE_animsys_evaluate_animdata(scene, &ob->id, ob->adt, ctime, ADT_RECALC_DRIVERS); if(ob->parent) { Object *par= ob->parent; @@ -2623,7 +2623,7 @@ void object_handle_update(Scene *scene, Object *ob) if(adt) { /* evaluate drivers */ // XXX: for mesh types, should we push this to derivedmesh instead? - BKE_animsys_evaluate_animdata(data_id, adt, ctime, ADT_RECALC_DRIVERS); + BKE_animsys_evaluate_animdata(scene, data_id, adt, ctime, ADT_RECALC_DRIVERS); } /* includes all keys and modifiers */ diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 1423f520b95..f62ba2be193 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -1801,7 +1801,7 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime, if(part->type!=PART_HAIR && dtime > 0.f && pa->time < cfra && pa->time >= sim->psys->cfra) { /* we have to force RECALC_ANIM here since where_is_objec_time only does drivers */ while(ob) { - BKE_animsys_evaluate_animdata(&ob->id, ob->adt, pa->time, ADT_RECALC_ANIM); + BKE_animsys_evaluate_animdata(sim->scene, &ob->id, ob->adt, pa->time, ADT_RECALC_ANIM); ob = ob->parent; } ob = sim->ob; @@ -4253,7 +4253,7 @@ void particle_system_update(Scene *scene, Object *ob, ParticleSystem *psys) return; /* execute drivers only, as animation has already been done */ - BKE_animsys_evaluate_animdata(&part->id, part->adt, cfra, ADT_RECALC_DRIVERS); + BKE_animsys_evaluate_animdata(scene, &part->id, part->adt, cfra, ADT_RECALC_DRIVERS); if(psys->recalc & PSYS_RECALC_TYPE) psys_changed_type(&sim); @@ -4291,7 +4291,7 @@ void particle_system_update(Scene *scene, Object *ob, ParticleSystem *psys) for(i=0; i<=part->hair_step; i++){ hcfra=100.0f*(float)i/(float)psys->part->hair_step; if((part->flag & PART_HAIR_REGROW)==0) - BKE_animsys_evaluate_animdata(&part->id, part->adt, hcfra, ADT_RECALC_ANIM); + BKE_animsys_evaluate_animdata(scene, &part->id, part->adt, hcfra, ADT_RECALC_ANIM); system_step(&sim, hcfra); psys->cfra = hcfra; psys->recalc = 0; @@ -4369,7 +4369,7 @@ void particle_system_update(Scene *scene, Object *ob, ParticleSystem *psys) if(psys->cfra < cfra) { /* make sure emitter is left at correct time (particle emission can change this) */ while(ob) { - BKE_animsys_evaluate_animdata(&ob->id, ob->adt, cfra, ADT_RECALC_ANIM); + BKE_animsys_evaluate_animdata(scene, &ob->id, ob->adt, cfra, ADT_RECALC_ANIM); ob = ob->parent; } ob = sim.ob; diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index e045bd0fb82..42793e4b4a4 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -915,7 +915,7 @@ static void scene_update_drivers(Main *UNUSED(bmain), Scene *scene) /* scene itself */ if (scene->adt && scene->adt->drivers.first) { - BKE_animsys_evaluate_animdata(&scene->id, scene->adt, ctime, ADT_RECALC_DRIVERS); + BKE_animsys_evaluate_animdata(scene, &scene->id, scene->adt, ctime, ADT_RECALC_DRIVERS); } /* world */ @@ -925,7 +925,7 @@ static void scene_update_drivers(Main *UNUSED(bmain), Scene *scene) AnimData *adt= BKE_animdata_from_id(wid); if (adt && adt->drivers.first) - BKE_animsys_evaluate_animdata(wid, adt, ctime, ADT_RECALC_DRIVERS); + BKE_animsys_evaluate_animdata(scene, wid, adt, ctime, ADT_RECALC_DRIVERS); } /* nodes */ @@ -934,7 +934,7 @@ static void scene_update_drivers(Main *UNUSED(bmain), Scene *scene) AnimData *adt= BKE_animdata_from_id(nid); if (adt && adt->drivers.first) - BKE_animsys_evaluate_animdata(nid, adt, ctime, ADT_RECALC_DRIVERS); + BKE_animsys_evaluate_animdata(scene, nid, adt, ctime, ADT_RECALC_DRIVERS); } } @@ -985,7 +985,7 @@ void scene_update_tagged(Main *bmain, Scene *scene) float ctime = BKE_curframe(scene); if (adt && (adt->recalc & ADT_RECALC_ANIM)) - BKE_animsys_evaluate_animdata(&scene->id, adt, ctime, 0); + BKE_animsys_evaluate_animdata(scene, &scene->id, adt, ctime, 0); } if (scene->physics_settings.quick_cache_step) @@ -1020,7 +1020,7 @@ void scene_update_for_newframe(Main *bmain, Scene *sce, unsigned int lay) * can be overridden by settings from Scene, which owns the Texture through a hierarchy * such as Scene->World->MTex/Texture) can still get correctly overridden. */ - BKE_animsys_evaluate_all_animation(bmain, ctime); + BKE_animsys_evaluate_all_animation(bmain, sce, ctime); /*...done with recusrive funcs */ /* object_handle_update() on all objects, groups and sets */ diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 5da70f97314..9673fee0b63 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -2123,7 +2123,7 @@ static ImBuf * seq_render_strip(SeqRenderData context, Sequence * seq, float cfr ibuf = seq_render_scene_strip_impl(context, seq, nr); /* Scene strips update all animation, so we need to restore original state.*/ - BKE_animsys_evaluate_all_animation(context.bmain, cfra); + BKE_animsys_evaluate_all_animation(context.bmain, context.scene, cfra); copy_to_ibuf_still(context, seq, nr, ibuf); break; @@ -2200,7 +2200,7 @@ static ImBuf* seq_render_strip_stack( if(scene->r.cfra != cfra) { // XXX for prefetch and overlay offset!..., very bad!!! AnimData *adt= BKE_animdata_from_id(&scene->id); - BKE_animsys_evaluate_animdata(&scene->id, adt, cfra, ADT_RECALC_ANIM); + BKE_animsys_evaluate_animdata(scene, &scene->id, adt, cfra, ADT_RECALC_ANIM); } #endif |