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:
authorMonique Dewanchand <mdewanchand>2022-09-14 22:33:51 +0300
committerMonique <mdewanchand@atmind.nl>2022-09-14 22:34:38 +0300
commit68589a31ebfb79165f99a979357d237e5413e904 (patch)
treea942e56d53f300b918ebf2597ee0895274d8e65a /source/blender/editors/animation
parent23276bcc37acc54f1e1814abdf482a432523c3a6 (diff)
ViewLayer: Lazy sync of scene data.
When a change happens which invalidates view layers the syncing will be postponed until the first usage. This will improve importing or adding many objects in a single operation/script. `BKE_view_layer_need_resync_tag` is used to tag the view layer to be out of sync. Before accessing `BKE_view_layer_active_base_get`, `BKE_view_layer_active_object_get`, `BKE_view_layer_active_collection` or `BKE_view_layer_object_bases` the caller should call `BKE_view_layer_synced_ensure`. Having two functions ensures that partial syncing could be added as smaller patches in the future. Tagging a view layer out of sync could be replaced with a partial sync. Eventually the number of full resyncs could be reduced. After all tagging has been replaced with partial syncs the ensure_sync could be phased out. This patch has been added to discuss the details and consequences of the current approach. For clarity the call to BKE_view_layer_ensure_sync is placed close to the getters. In the future this could be placed in more strategical places to reduce the number of calls or improve performance. Finding those strategical places isn't that clear. When multiple operations are grouped in a single script you might want to always check for resync. Some areas found that can be improved. This list isn't complete. These areas aren't addressed by this patch as these changes would be hard to detect to the reviewer. The idea is to add changes to these areas as a separate patch. It might be that the initial commit would reduce performance compared to master, but will be fixed by the additional patches. **Object duplication** During object duplication the syncing is temporarily disabled. With this patch this isn't useful as when disabled the view_layer is accessed to locate bases. This can be improved by first locating the source bases, then duplicate and sync and locate the new bases. Will be solved in a separate patch for clarity reasons ({D15886}). **Object add** `BKE_object_add` not only adds a new object, but also selects and activates the new base. This requires the view_layer to be resynced. Some callers reverse the selection and activation (See `get_new_constraint_target`). We should make the selection and activation optional. This would make it possible to add multiple objects without having to resync per object. **Postpone Activate Base** Setting the basact is done in many locations. They follow a rule as after an action find the base and set the basact. Finding the base could require a resync. The idea is to store in the view_layer the object which base will be set in the basact during the next sync, reducing the times resyncing needs to happen. Reviewed By: mont29 Maniphest Tasks: T73411 Differential Revision: https://developer.blender.org/D15885
Diffstat (limited to 'source/blender/editors/animation')
-rw-r--r--source/blender/editors/animation/anim_channels_edit.c7
-rw-r--r--source/blender/editors/animation/anim_filter.c28
-rw-r--r--source/blender/editors/animation/anim_markers.c1
3 files changed, 24 insertions, 12 deletions
diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c
index 06a62b7a9de..ea631da27af 100644
--- a/source/blender/editors/animation/anim_channels_edit.c
+++ b/source/blender/editors/animation/anim_channels_edit.c
@@ -31,6 +31,7 @@
#include "BKE_fcurve.h"
#include "BKE_global.h"
#include "BKE_gpencil.h"
+#include "BKE_layer.h"
#include "BKE_lib_id.h"
#include "BKE_mask.h"
#include "BKE_nla.h"
@@ -2953,6 +2954,7 @@ static int click_select_channel_object(bContext *C,
bAnimListElem *ale,
const short /* eEditKeyframes_Select or -1 */ selectmode)
{
+ Scene *scene = ac->scene;
ViewLayer *view_layer = ac->view_layer;
Base *base = (Base *)ale->data;
Object *ob = base->object;
@@ -2971,11 +2973,10 @@ static int click_select_channel_object(bContext *C,
}
}
else {
- Base *b;
-
/* deselect all */
+ BKE_view_layer_synced_ensure(scene, view_layer);
/* TODO: should this deselect all other types of channels too? */
- for (b = view_layer->object_bases.first; b; b = b->next) {
+ LISTBASE_FOREACH (Base *, b, BKE_view_layer_object_bases_get(view_layer)) {
ED_object_base_select(b, BA_DESELECT);
if (b->object->adt) {
b->object->adt->flag &= ~(ADT_UI_SELECTED | ADT_UI_ACTIVE);
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c
index 6dc11292a3a..5b4d436b0e0 100644
--- a/source/blender/editors/animation/anim_filter.c
+++ b/source/blender/editors/animation/anim_filter.c
@@ -118,10 +118,12 @@ static void animedit_get_yscale_factor(bAnimContext *ac)
/* NOTE: there's a similar function in key.c #BKE_key_from_object. */
static Key *actedit_get_shapekeys(bAnimContext *ac)
{
+ Scene *scene = ac->scene;
ViewLayer *view_layer = ac->view_layer;
Object *ob;
Key *key;
+ BKE_view_layer_synced_ensure(scene, view_layer);
ob = BKE_view_layer_active_object_get(view_layer);
if (ob == NULL) {
return NULL;
@@ -393,12 +395,13 @@ bool ANIM_animdata_get_context(const bContext *C, bAnimContext *ac)
/* get useful default context settings from context */
ac->bmain = bmain;
ac->scene = scene;
+ ac->view_layer = CTX_data_view_layer(C);
if (scene) {
ac->markers = ED_context_get_markers(C);
+ BKE_view_layer_synced_ensure(ac->scene, ac->view_layer);
}
- ac->view_layer = CTX_data_view_layer(C);
ac->depsgraph = CTX_data_depsgraph_pointer(C);
- ac->obact = (ac->view_layer->basact) ? ac->view_layer->basact->object : NULL;
+ ac->obact = BKE_view_layer_active_object_get(ac->view_layer);
ac->area = area;
ac->region = region;
ac->sl = sl;
@@ -1846,8 +1849,8 @@ static size_t animdata_filter_gpencil(bAnimContext *ac,
bDopeSheet *ads = ac->ads;
size_t items = 0;
+ Scene *scene = ac->scene;
ViewLayer *view_layer = (ViewLayer *)ac->view_layer;
- Base *base;
/* Include all annotation datablocks. */
if (((ads->filterflag & ADS_FILTER_ONLYSEL) == 0) ||
@@ -1859,7 +1862,8 @@ static size_t animdata_filter_gpencil(bAnimContext *ac,
}
}
/* Objects in the scene */
- for (base = view_layer->object_bases.first; base; base = base->next) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
/* Only consider this object if it has got some GP data (saving on all the other tests) */
if (base->object && (base->object->type == OB_GPENCIL)) {
Object *ob = base->object;
@@ -3170,16 +3174,19 @@ static int ds_base_sorting_cmp(const void *base1_ptr, const void *base2_ptr)
/* Get a sorted list of all the bases - for inclusion in dopesheet (when drawing channels) */
static Base **animdata_filter_ds_sorted_bases(bDopeSheet *ads,
+ const Scene *scene,
ViewLayer *view_layer,
int filter_mode,
size_t *r_usable_bases)
{
/* Create an array with space for all the bases, but only containing the usable ones */
- size_t tot_bases = BLI_listbase_count(&view_layer->object_bases);
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ ListBase *object_bases = BKE_view_layer_object_bases_get(view_layer);
+ size_t tot_bases = BLI_listbase_count(object_bases);
size_t num_bases = 0;
Base **sorted_bases = MEM_mallocN(sizeof(Base *) * tot_bases, "Dopesheet Usable Sorted Bases");
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ LISTBASE_FOREACH (Base *, base, object_bases) {
if (animdata_filter_base_is_ok(ads, base, OB_MODE_OBJECT, filter_mode)) {
sorted_bases[num_bases++] = base;
}
@@ -3249,14 +3256,17 @@ static size_t animdata_filter_dopesheet(bAnimContext *ac,
* - Don't do this if this behavior has been turned off (i.e. due to it being too slow)
* - Don't do this if there's just a single object
*/
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ ListBase *object_bases = BKE_view_layer_object_bases_get(view_layer);
if ((filter_mode & ANIMFILTER_LIST_CHANNELS) && !(ads->flag & ADS_FLAG_NO_DB_SORT) &&
- (view_layer->object_bases.first != view_layer->object_bases.last)) {
+ (object_bases->first != object_bases->last)) {
/* Filter list of bases (i.e. objects), sort them, then add their contents normally... */
/* TODO: Cache the old sorted order - if the set of bases hasn't changed, don't re-sort... */
Base **sorted_bases;
size_t num_bases;
- sorted_bases = animdata_filter_ds_sorted_bases(ads, view_layer, filter_mode, &num_bases);
+ sorted_bases = animdata_filter_ds_sorted_bases(
+ ads, scene, view_layer, filter_mode, &num_bases);
if (sorted_bases) {
/* Add the necessary channels for these bases... */
for (size_t i = 0; i < num_bases; i++) {
@@ -3275,7 +3285,7 @@ static size_t animdata_filter_dopesheet(bAnimContext *ac,
*/
Object *obact = BKE_view_layer_active_object_get(view_layer);
const eObjectMode object_mode = obact ? obact->mode : OB_MODE_OBJECT;
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ LISTBASE_FOREACH (Base *, base, object_bases) {
if (animdata_filter_base_is_ok(ads, base, object_mode, filter_mode)) {
/* since we're still here, this object should be usable */
items += animdata_filter_dopesheet_ob(ac, anim_data, ads, base, filter_mode);
diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c
index 8e6f2bdc66c..726724181a9 100644
--- a/source/blender/editors/animation/anim_markers.c
+++ b/source/blender/editors/animation/anim_markers.c
@@ -1291,6 +1291,7 @@ static void select_marker_camera_switch(
}
}
+ BKE_view_layer_synced_ensure(scene, view_layer);
for (marker = markers->first; marker; marker = marker->next) {
if (marker->camera) {
if (marker->frame == cfra) {