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
path: root/source
diff options
context:
space:
mode:
authorJulian Eisel <julian@blender.org>2022-10-18 16:05:53 +0300
committerJulian Eisel <julian@blender.org>2022-10-18 16:10:59 +0300
commit489260198e9654aaf5922e64fbe36b335bcb8e1b (patch)
treeb7a4d85adca968240507b9d9e1fdd5f559274a0c /source
parentc2fe3872445d96325c2accb654b1c39a195a31d1 (diff)
File Browser: Fix slowdown with non-existing ID previews in big files
When the File (or Asset) Browser would display data-blocks without previews in a heavy .blend file, there would be a drastic slowdown. See patch for details and comparison videos. Differential Revision: https://developer.blender.org/D16273 Reviewed by: Bastien Montagne
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenloader/BLO_readfile.h5
-rw-r--r--source/blender/blenloader/intern/readblenentry.cc15
-rw-r--r--source/blender/editors/space_file/filelist.cc27
-rw-r--r--source/blender/makesdna/DNA_space_types.h4
4 files changed, 47 insertions, 4 deletions
diff --git a/source/blender/blenloader/BLO_readfile.h b/source/blender/blenloader/BLO_readfile.h
index 93040fa01ee..75a1956ce12 100644
--- a/source/blender/blenloader/BLO_readfile.h
+++ b/source/blender/blenloader/BLO_readfile.h
@@ -182,6 +182,11 @@ void BLO_blendfiledata_free(BlendFileData *bfd);
typedef struct BLODataBlockInfo {
char name[64]; /* MAX_NAME */
struct AssetMetaData *asset_data;
+ /* Optimization: Tag data-blocks for which we know there is no preview.
+ * Knowing this can be used to skip the (potentially expensive) preview loading process. If this
+ * is set to true it means we looked for a preview and couldn't find one. False may mean that
+ * either no preview was found, or that it wasn't looked for in the first place. */
+ bool no_preview_found;
} BLODataBlockInfo;
/**
diff --git a/source/blender/blenloader/intern/readblenentry.cc b/source/blender/blenloader/intern/readblenentry.cc
index 55ac2d31277..ead796c0e28 100644
--- a/source/blender/blenloader/intern/readblenentry.cc
+++ b/source/blender/blenloader/intern/readblenentry.cc
@@ -138,11 +138,15 @@ LinkNode *BLO_blendhandle_get_datablock_info(BlendHandle *bh,
BHead *bhead;
int tot = 0;
+ const int sdna_nr_preview_image = DNA_struct_find_nr(fd->filesdna, "PreviewImage");
+
for (bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) {
if (bhead->code == ENDB) {
break;
}
if (bhead->code == ofblocktype) {
+ BHead *id_bhead = bhead;
+
const char *name = blo_bhead_id_name(fd, bhead) + 2;
AssetMetaData *asset_meta_data = blo_bhead_id_asset_data_address(fd, bhead);
@@ -165,6 +169,17 @@ LinkNode *BLO_blendhandle_get_datablock_info(BlendHandle *bh,
STRNCPY(info->name, name);
info->asset_data = asset_meta_data;
+ bool has_preview = false;
+ /* See if we can find a preview in the data of this ID. */
+ for (BHead *data_bhead = blo_bhead_next(fd, id_bhead); data_bhead->code == DATA;
+ data_bhead = blo_bhead_next(fd, data_bhead)) {
+ if (data_bhead->SDNAnr == sdna_nr_preview_image) {
+ has_preview = true;
+ break;
+ }
+ }
+ info->no_preview_found = !has_preview;
+
BLI_linklist_prepend(&infos, info);
tot++;
}
diff --git a/source/blender/editors/space_file/filelist.cc b/source/blender/editors/space_file/filelist.cc
index b6f6ab39438..f177eebf6f2 100644
--- a/source/blender/editors/space_file/filelist.cc
+++ b/source/blender/editors/space_file/filelist.cc
@@ -115,6 +115,9 @@ struct FileListInternEntry {
* Owning pointer. */
AssetMetaData *imported_asset_data;
+ /* See #FILE_ENTRY_BLENDERLIB_NO_PREVIEW. */
+ bool blenderlib_has_no_preview;
+
/** Defined in BLI_fileops.h */
eFileAttributes attributes;
BLI_stat_t st;
@@ -1575,6 +1578,14 @@ static void filelist_cache_previews_push(FileList *filelist, FileDirEntry *entry
return;
}
+ /* If we know this is an external ID without a preview, skip loading the preview. Can save quite
+ * some time in heavy files, because otherwise for each missing preview and for each preview
+ * reload, we'd reopen the .blend to look for the preview. */
+ if ((entry->typeflag & FILE_TYPE_BLENDERLIB) &&
+ (entry->flags & FILE_ENTRY_BLENDERLIB_NO_PREVIEW)) {
+ return;
+ }
+
FileListInternEntry *intern_entry = filelist->filelist_intern.filtered[index];
PreviewImage *preview_in_memory = intern_entry->local_data.preview_image;
if (preview_in_memory && !BKE_previewimg_is_finished(preview_in_memory, ICON_SIZE_PREVIEW)) {
@@ -2042,6 +2053,9 @@ static FileDirEntry *filelist_file_create_entry(FileList *filelist, const int in
ret->preview_icon_id = BKE_icon_imbuf_create(ibuf);
}
}
+ if (entry->blenderlib_has_no_preview) {
+ ret->flags |= FILE_ENTRY_BLENDERLIB_NO_PREVIEW;
+ }
BLI_addtail(&cache->cached_entries, ret);
return ret;
}
@@ -2995,10 +3009,15 @@ static void filelist_readjob_list_lib_add_datablock(ListBase *entries,
entry->relpath = BLI_strdup(datablock_info->name);
}
entry->typeflag |= FILE_TYPE_BLENDERLIB;
- if (datablock_info && datablock_info->asset_data) {
- entry->typeflag |= FILE_TYPE_ASSET;
- /* Moves ownership! */
- entry->imported_asset_data = datablock_info->asset_data;
+
+ if (datablock_info) {
+ entry->blenderlib_has_no_preview = datablock_info->no_preview_found;
+
+ if (datablock_info->asset_data) {
+ entry->typeflag |= FILE_TYPE_ASSET;
+ /* Moves ownership! */
+ entry->imported_asset_data = datablock_info->asset_data;
+ }
}
entry->blentype = idcode;
BLI_addtail(entries, entry);
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index 809c8be7bc4..d2d20bcde78 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -1169,6 +1169,10 @@ enum {
FILE_ENTRY_NAME_FREE = 1 << 1,
/* The preview for this entry is being loaded on another thread. */
FILE_ENTRY_PREVIEW_LOADING = 1 << 2,
+ /** For #FILE_TYPE_BLENDERLIB only: Denotes that the ID is known to not have a preview (none was
+ * found in the .blend). Stored so we don't keep trying to find non-existent previews every time
+ * we reload previews. When dealing with heavy files this can have quite an impact. */
+ FILE_ENTRY_BLENDERLIB_NO_PREVIEW = 1 << 3,
};
/** \} */