diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/BKE_animsys.h | 4 | ||||
-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 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/drawanimviz.c | 8 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/drawarmature.c | 8 | ||||
-rw-r--r-- | source/blender/makesrna/RNA_access.h | 4 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_access.c | 110 | ||||
-rw-r--r-- | source/blender/render/intern/source/pipeline.c | 2 |
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++; |