Commit: 489260198e9654aaf5922e64fbe36b335bcb8e1b Author: Julian Eisel Date: Tue Oct 18 15:05:53 2022 +0200 Branches: master https://developer.blender.org/rB489260198e9654aaf5922e64fbe36b335bcb8e1b
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 =================================================================== M source/blender/blenloader/BLO_readfile.h M source/blender/blenloader/intern/readblenentry.cc M source/blender/editors/space_file/filelist.cc M source/blender/makesdna/DNA_space_types.h =================================================================== 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, }; /** \} */ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs