Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Leung <aligorith@gmail.com>2011-07-24 08:34:46 +0400
committerJoshua Leung <aligorith@gmail.com>2011-07-24 08:34:46 +0400
commit6a392e8cb505b753a0bac24e42778306007c45b8 (patch)
tree6d34591894fec168b8535fae88455ef8446f0a2a /source/blender
parentc22f26d2032b7116477e6a378407a10b6d7e3276 (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')
-rw-r--r--source/blender/blenkernel/BKE_animsys.h4
-rw-r--r--source/blender/blenkernel/intern/action.c2
-rw-r--r--source/blender/blenkernel/intern/anim.c4
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c34
-rw-r--r--source/blender/blenkernel/intern/blender.c5
-rw-r--r--source/blender/blenkernel/intern/key.c2
-rw-r--r--source/blender/blenkernel/intern/object.c4
-rw-r--r--source/blender/blenkernel/intern/particle_system.c8
-rw-r--r--source/blender/blenkernel/intern/scene.c10
-rw-r--r--source/blender/blenkernel/intern/sequencer.c4
-rw-r--r--source/blender/editors/space_view3d/drawanimviz.c8
-rw-r--r--source/blender/editors/space_view3d/drawarmature.c8
-rw-r--r--source/blender/makesrna/RNA_access.h4
-rw-r--r--source/blender/makesrna/intern/rna_access.c110
-rw-r--r--source/blender/render/intern/source/pipeline.c2
15 files changed, 174 insertions, 35 deletions
diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h
index 228a359c81d..bf619d76e68 100644
--- a/source/blender/blenkernel/BKE_animsys.h
+++ b/source/blender/blenkernel/BKE_animsys.h
@@ -140,10 +140,10 @@ void BKE_animdata_main_cb(struct Main *main, ID_AnimData_Edit_Callback func, voi
/* In general, these ones should be called to do all animation evaluation */
/* Evaluation loop for evaluating animation data */
-void BKE_animsys_evaluate_animdata(struct ID *id, struct AnimData *adt, float ctime, short recalc);
+void BKE_animsys_evaluate_animdata(struct Scene *scene, struct ID *id, struct AnimData *adt, float ctime, short recalc);
/* Evaluation of all ID-blocks with Animation Data blocks - Animation Data Only */
-void BKE_animsys_evaluate_all_animation(struct Main *main, float ctime);
+void BKE_animsys_evaluate_all_animation(struct Main *main, struct Scene *scene, float ctime);
/* ------------ Specialised API --------------- */
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
diff --git a/source/blender/editors/space_view3d/drawanimviz.c b/source/blender/editors/space_view3d/drawanimviz.c
index aa3ba1a3062..4a51cb3be09 100644
--- a/source/blender/editors/space_view3d/drawanimviz.c
+++ b/source/blender/editors/space_view3d/drawanimviz.c
@@ -393,7 +393,7 @@ static void draw_ghost_poses_range(Scene *scene, View3D *v3d, ARegion *ar, Base
colfac = (end - (float)CFRA) / range;
UI_ThemeColorShadeAlpha(TH_WIRE, 0, -128-(int)(120.0*sqrt(colfac)));
- BKE_animsys_evaluate_animdata(&ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
+ BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
where_is_pose(scene, ob);
draw_pose_bones(scene, v3d, ar, base, OB_WIRE);
}
@@ -472,7 +472,7 @@ static void draw_ghost_poses_keys(Scene *scene, View3D *v3d, ARegion *ar, Base *
CFRA= (int)ak->cfra;
- BKE_animsys_evaluate_animdata(&ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
+ BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
where_is_pose(scene, ob);
draw_pose_bones(scene, v3d, ar, base, OB_WIRE);
}
@@ -542,7 +542,7 @@ static void draw_ghost_poses(Scene *scene, View3D *v3d, ARegion *ar, Base *base)
CFRA= (int)BKE_nla_tweakedit_remap(adt, actframe+ctime, NLATIME_CONVERT_MAP);
if (CFRA != cfrao) {
- BKE_animsys_evaluate_animdata(&ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
+ BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
where_is_pose(scene, ob);
draw_pose_bones(scene, v3d, ar, base, OB_WIRE);
}
@@ -557,7 +557,7 @@ static void draw_ghost_poses(Scene *scene, View3D *v3d, ARegion *ar, Base *base)
CFRA= (int)BKE_nla_tweakedit_remap(adt, actframe-ctime, NLATIME_CONVERT_MAP);
if (CFRA != cfrao) {
- BKE_animsys_evaluate_animdata(&ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
+ BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
where_is_pose(scene, ob);
draw_pose_bones(scene, v3d, ar, base, OB_WIRE);
}
diff --git a/source/blender/editors/space_view3d/drawarmature.c b/source/blender/editors/space_view3d/drawarmature.c
index 1087284e2e5..de35be13c43 100644
--- a/source/blender/editors/space_view3d/drawarmature.c
+++ b/source/blender/editors/space_view3d/drawarmature.c
@@ -2339,7 +2339,7 @@ static void draw_ghost_poses_range(Scene *scene, View3D *v3d, ARegion *ar, Base
colfac = (end - (float)CFRA) / range;
UI_ThemeColorShadeAlpha(TH_WIRE, 0, -128-(int)(120.0*sqrt(colfac)));
- BKE_animsys_evaluate_animdata(&ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
+ BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
where_is_pose(scene, ob);
draw_pose_bones(scene, v3d, ar, base, OB_WIRE, TRUE, FALSE);
}
@@ -2418,7 +2418,7 @@ static void draw_ghost_poses_keys(Scene *scene, View3D *v3d, ARegion *ar, Base *
CFRA= (int)ak->cfra;
- BKE_animsys_evaluate_animdata(&ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
+ BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
where_is_pose(scene, ob);
draw_pose_bones(scene, v3d, ar, base, OB_WIRE, TRUE, FALSE);
}
@@ -2488,7 +2488,7 @@ static void draw_ghost_poses(Scene *scene, View3D *v3d, ARegion *ar, Base *base)
CFRA= (int)BKE_nla_tweakedit_remap(adt, actframe+ctime, NLATIME_CONVERT_MAP);
if (CFRA != cfrao) {
- BKE_animsys_evaluate_animdata(&ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
+ BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
where_is_pose(scene, ob);
draw_pose_bones(scene, v3d, ar, base, OB_WIRE, TRUE, FALSE);
}
@@ -2503,7 +2503,7 @@ static void draw_ghost_poses(Scene *scene, View3D *v3d, ARegion *ar, Base *base)
CFRA= (int)BKE_nla_tweakedit_remap(adt, actframe-ctime, NLATIME_CONVERT_MAP);
if (CFRA != cfrao) {
- BKE_animsys_evaluate_animdata(&ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
+ BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
where_is_pose(scene, ob);
draw_pose_bones(scene, v3d, ar, base, OB_WIRE, TRUE, FALSE);
}
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index 49bc10a0675..f5d73bddc3b 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -702,6 +702,10 @@ void RNA_property_update(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop)
void RNA_property_update_main(struct Main *bmain, struct Scene *scene, PointerRNA *ptr, PropertyRNA *prop);
int RNA_property_update_check(struct PropertyRNA *prop);
+void RNA_property_update_cache_add(PointerRNA *ptr, PropertyRNA *prop);
+void RNA_property_update_cache_flush(struct Main *bmain, struct Scene *scene);
+void RNA_property_update_cache_free(void);
+
/* Property Data */
int RNA_property_boolean_get(PointerRNA *ptr, PropertyRNA *prop);
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index 285e8ca39ba..7936fc4c280 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -85,7 +85,9 @@ void RNA_init(void)
void RNA_exit(void)
{
StructRNA *srna;
-
+
+ RNA_property_update_cache_free();
+
for(srna=BLENDER_RNA.structs.first; srna; srna=srna->cont.next) {
if(srna->cont.prophash) {
BLI_ghash_free(srna->cont.prophash, NULL, NULL);
@@ -1391,6 +1393,112 @@ void RNA_property_update_main(Main *bmain, Scene *scene, PointerRNA *ptr, Proper
rna_property_update(NULL, bmain, scene, ptr, prop);
}
+
+/* RNA Updates Cache ------------------------ */
+/* Overview of RNA Update cache system:
+ *
+ * RNA Update calls need to be cached in order to maintain reasonable performance
+ * of the animation system (i.e. maintaining a somewhat interactive framerate)
+ * while still allowing updates to be called (necessary in particular for modifier
+ * property updates to actually work).
+ *
+ * The cache is structured with a dual-layer structure
+ * - L1 = PointerRNA used as key; id.data is used (it should always be defined,
+ * and most updates end up using just that anyways)
+ * - L2 = Update functions to be called on those PointerRNA's
+ */
+
+/* cache element */
+typedef struct tRnaUpdateCacheElem {
+ struct tRnaUpdateCacheElem *next, *prev;
+
+ PointerRNA ptr; /* L1 key - id as primary, data secondary/ignored? */
+ ListBase L2Funcs; /* L2 functions (LinkData<RnaUpdateFuncRef>) */
+} tRnaUpdateCacheElem;
+
+/* cache global (tRnaUpdateCacheElem's) - only accessible using these API calls */
+static ListBase rna_updates_cache = {NULL, NULL};
+
+/* ........................... */
+
+void RNA_property_update_cache_add(PointerRNA *ptr, PropertyRNA *prop)
+{
+ tRnaUpdateCacheElem *uce = NULL;
+ UpdateFunc fn = NULL;
+ LinkData *ld;
+ short is_rna = (prop->magic == RNA_MAGIC);
+
+ /* sanity check */
+ if (ELEM(NULL, ptr, prop))
+ return;
+
+ prop= rna_ensure_property(prop);
+
+ /* we can only handle update calls with no context args for now (makes animsys updates easier) */
+ if ((is_rna == 0) || (prop->update == NULL) || (prop->flag & PROP_CONTEXT_UPDATE))
+ return;
+ fn = prop->update;
+
+ /* find cache element for which key matches... */
+ for (uce = rna_updates_cache.first; uce; uce = uce->next) {
+ /* just match by id only for now, since most update calls that we'll encounter only really care about this */
+ // TODO: later, the cache might need to have some nesting on L1 to cope better with these problems + some tagging to indicate we need this
+ if (uce->ptr.id.data == ptr->id.data)
+ break;
+ }
+ if (uce == NULL) {
+ /* create new instance */
+ uce = MEM_callocN(sizeof(tRnaUpdateCacheElem), "tRnaUpdateCacheElem");
+ BLI_addtail(&rna_updates_cache, uce);
+
+ /* copy pointer */
+ RNA_pointer_create(ptr->id.data, ptr->type, ptr->data, &uce->ptr);
+ }
+
+ /* check on the update func */
+ for (ld = uce->L2Funcs.first; ld; ld = ld->next) {
+ /* stop on match - function already cached */
+ if (fn == ld->data)
+ return;
+ }
+ /* else... if still here, we need to add it */
+ BLI_addtail(&uce->L2Funcs, BLI_genericNodeN(fn));
+}
+
+void RNA_property_update_cache_flush(Main *bmain, Scene *scene)
+{
+ tRnaUpdateCacheElem *uce;
+
+ // TODO: should we check that bmain and scene are valid? The above stuff doesn't!
+
+ /* execute the cached updates */
+ for (uce = rna_updates_cache.first; uce; uce = uce->next) {
+ LinkData *ld;
+
+ for (ld = uce->L2Funcs.first; ld; ld = ld->next) {
+ UpdateFunc fn = (UpdateFunc)ld->data;
+ fn(bmain, scene, &uce->ptr);
+ }
+ }
+}
+
+void RNA_property_update_cache_free(void)
+{
+ tRnaUpdateCacheElem *uce, *ucn;
+
+ for (uce = rna_updates_cache.first; uce; uce = ucn) {
+ ucn = uce->next;
+
+ /* free L2 cache */
+ BLI_freelistN(&uce->L2Funcs);
+
+ /* remove self */
+ BLI_freelinkN(&rna_updates_cache, uce);
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
/* Property Data */
int RNA_property_boolean_get(PointerRNA *ptr, PropertyRNA *prop)
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index b9006b390ab..0afbffc5fd5 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -2525,7 +2525,7 @@ static void do_render_seq(Render * re)
if(recurs_depth==0) {
/* otherwise sequencer animation isnt updated */
- BKE_animsys_evaluate_all_animation(re->main, (float)cfra); // XXX, was BKE_curframe(re->scene)
+ BKE_animsys_evaluate_all_animation(re->main, re->scene, (float)cfra); // XXX, was BKE_curframe(re->scene)
}
recurs_depth++;