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:
authorBastien Montagne <b.mont29@gmail.com>2020-03-17 14:29:36 +0300
committerBastien Montagne <b.mont29@gmail.com>2020-03-17 17:02:05 +0300
commitb852db57ba24adfcfaa0ada7e9ff513a79a399a2 (patch)
tree19d2a41451ecf6a3d07a53c98bb0cd4ad76c77e6 /source/blender/blenkernel/intern/blendfile.c
parent9ce38909500a47beff87081147178d7a52449df7 (diff)
Add experimental global undo speedup.
The feature is hidden behind an experimental option, you'll have to enable it in the preferences to try it. This feature is not yet considered fully stable, crashes may happen, as well as .blend file corruptions (very unlikely, but still possible). In a nutshell, the ideas behind this code are to: * Detect unchanged IDs across an undo step. * Reuse as much as possible existing IDs memory, even when its content did change. * Re-use existing depsgraphs instead of building new ones from scratch. * Store accumulated recalc flags, to avoid needless re-compute of things that did not change, when the ID itself is detected as modified. See T60695 and D6580 for more technical details.
Diffstat (limited to 'source/blender/blenkernel/intern/blendfile.c')
-rw-r--r--source/blender/blenkernel/intern/blendfile.c38
1 files changed, 21 insertions, 17 deletions
diff --git a/source/blender/blenkernel/intern/blendfile.c b/source/blender/blenkernel/intern/blendfile.c
index efab2039dc3..3890bf4e7f8 100644
--- a/source/blender/blenkernel/intern/blendfile.c
+++ b/source/blender/blenkernel/intern/blendfile.c
@@ -134,26 +134,29 @@ static void setup_app_userdef(BlendFileData *bfd)
static void setup_app_data(bContext *C,
BlendFileData *bfd,
const char *filepath,
- const bool is_startup,
+ const struct BlendFileReadParams *params,
ReportList *reports)
{
Main *bmain = G_MAIN;
Scene *curscene = NULL;
const bool recover = (G.fileflags & G_FILE_RECOVER) != 0;
+ const bool is_startup = params->is_startup;
enum {
LOAD_UI = 1,
LOAD_UI_OFF,
LOAD_UNDO,
} mode;
- /* may happen with library files - UNDO file should never have NULL cursccene... */
- if (ELEM(NULL, bfd->curscreen, bfd->curscene)) {
+ if (params->undo_direction != 0) {
+ BLI_assert(bfd->curscene != NULL);
+ mode = LOAD_UNDO;
+ }
+ /* may happen with library files - UNDO file should never have NULL curscene (but may have a
+ * NULL curscreen)... */
+ else if (ELEM(NULL, bfd->curscreen, bfd->curscene)) {
BKE_report(reports, RPT_WARNING, "Library file, loading empty scene");
mode = LOAD_UI_OFF;
}
- else if (BLI_listbase_is_empty(&bfd->main->screens)) {
- mode = LOAD_UNDO;
- }
else if (G.fileflags & G_FILE_NO_UI) {
mode = LOAD_UI_OFF;
}
@@ -371,7 +374,9 @@ static void setup_app_data(bContext *C,
* means that we do not reset their user count, however we do increase that one when doing
* lib_link on local IDs using linked ones.
* There is no real way to predict amount of changes here, so we have to fully redo
- * refcounting . */
+ * refcounting.
+ * Now that we re-use (and do not liblink in readfile.c) most local datablocks as well, we have
+ * to recompute refcount for all local IDs too. */
BKE_main_id_refcount_recompute(bmain, false);
}
}
@@ -386,7 +391,7 @@ static void setup_app_blend_file_data(bContext *C,
setup_app_userdef(bfd);
}
if ((params->skip_flags & BLO_READ_SKIP_DATA) == 0) {
- setup_app_data(C, bfd, filepath, params->is_startup, reports);
+ setup_app_data(C, bfd, filepath, params, reports);
}
}
@@ -473,16 +478,15 @@ bool BKE_blendfile_read_from_memfile(bContext *C,
Main *bmain = CTX_data_main(C);
BlendFileData *bfd;
- bfd = BLO_read_from_memfile(
- bmain, BKE_main_blendfile_path(bmain), memfile, params->skip_flags, reports);
+ bfd = BLO_read_from_memfile(bmain, BKE_main_blendfile_path(bmain), memfile, params, reports);
if (bfd) {
- /* remove the unused screens and wm */
- while (bfd->main->wm.first) {
- BKE_id_free(bfd->main, bfd->main->wm.first);
- }
- while (bfd->main->screens.first) {
- BKE_id_free(bfd->main, bfd->main->screens.first);
- }
+ /* Removing the unused workspaces, screens and wm is useless here, setup_app_data will switch
+ * those lists with the ones from old bmain, which freeing is much more efficient than
+ * individual calls to `BKE_id_free()`.
+ * Further more, those are expected to be empty anyway with new memfile reading code. */
+ BLI_assert(BLI_listbase_is_empty(&bfd->main->wm));
+ BLI_assert(BLI_listbase_is_empty(&bfd->main->workspaces));
+ BLI_assert(BLI_listbase_is_empty(&bfd->main->screens));
setup_app_blend_file_data(C, bfd, "<memory1>", params, reports);
BLO_blendfiledata_free(bfd);