[Bf-blender-cvs] [d6e19e73b82] asset-browser: Fix invalid memory use of "Current File" after undo & deleting data-blocks
Julian Eisel
noreply at git.blender.org
Thu Dec 10 20:30:49 CET 2020
Commit: d6e19e73b829e4b9e7f251237615eb7c2f0e30a3
Author: Julian Eisel
Date: Thu Dec 10 17:12:56 2020 +0100
Branches: asset-browser
https://developer.blender.org/rBd6e19e73b829e4b9e7f251237615eb7c2f0e30a3
Fix invalid memory use of "Current File" after undo & deleting data-blocks
Implement proper mechanisms to ensure the file list is recreated after undo,
data-blocks are removed, assets created/removed or file loading without UI.
This could be further improved (e.g. don't recreate it if no asset data-block
is affected by undo or deletion).
Addresses T82886 & T83242.
===================================================================
M source/blender/blenkernel/intern/screen.c
M source/blender/blenloader/intern/readfile.c
M source/blender/editors/space_file/filelist.c
M source/blender/editors/space_file/filelist.h
M source/blender/editors/space_file/space_file.c
M source/blender/makesdna/DNA_space_types.h
===================================================================
diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c
index 59d61debd6c..6df6376219c 100644
--- a/source/blender/blenkernel/intern/screen.c
+++ b/source/blender/blenkernel/intern/screen.c
@@ -1670,6 +1670,7 @@ static void direct_link_area(BlendDataReader *reader, ScrArea *area)
sfile->layout = NULL;
sfile->op = NULL;
sfile->previews_timer = NULL;
+ sfile->rebuild_flag = 0;
BLO_read_data_address(reader, &sfile->params);
BLO_read_data_address(reader, &sfile->asset_params);
}
@@ -1755,8 +1756,11 @@ void BKE_screen_area_blend_read_lib(BlendLibReader *reader, ID *parent_id, ScrAr
}
break;
}
- case SPACE_FILE:
+ case SPACE_FILE: {
+ SpaceFile *sfile = (SpaceFile *)sl;
+ sfile->rebuild_flag |= FILE_REBUILD_MAIN_FILES;
break;
+ }
case SPACE_ACTION: {
SpaceAction *saction = (SpaceAction *)sl;
bDopeSheet *ads = &saction->ads;
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 3979cfb2b4f..f43cb690a67 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -2749,6 +2749,7 @@ static void lib_link_workspace_layout_restore(struct IDNameLib_Map *id_map,
SpaceFile *sfile = (SpaceFile *)sl;
sfile->op = NULL;
sfile->previews_timer = NULL;
+ sfile->rebuild_flag = FILE_REBUILD_MAIN_FILES;
}
else if (sl->spacetype == SPACE_ACTION) {
SpaceAction *saction = (SpaceAction *)sl;
diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c
index 8a1e0daf93b..8cf7fff2b6c 100644
--- a/source/blender/editors/space_file/filelist.c
+++ b/source/blender/editors/space_file/filelist.c
@@ -413,6 +413,9 @@ typedef struct FileList {
/* Filter an entry of current filelist. */
bool (*filterf)(struct FileListInternEntry *, const char *, FileListFilter *);
+
+ /* Flags for the list-type, only set/changed when the type changes (#filelist_settype()). */
+ short type_flags; /* FileList.type_flags */
} FileList;
/* FileList.flags */
@@ -425,6 +428,11 @@ enum {
FL_SORT_INVERT = 1 << 5,
};
+/* FileList.type_flags */
+enum FileListTypeFlags {
+ FL_USES_MAIN_DATA = (1 << 0),
+};
+
#define SPECIAL_IMG_SIZE 256
#define SPECIAL_IMG_ROWS 1
#define SPECIAL_IMG_COLS 7
@@ -1712,6 +1720,7 @@ void filelist_settype(FileList *filelist, short type)
}
filelist->type = type;
+ filelist->type_flags = 0;
switch (filelist->type) {
case FILE_MAIN:
filelist->checkdirf = filelist_checkdir_main;
@@ -1728,6 +1737,7 @@ void filelist_settype(FileList *filelist, short type)
filelist->checkdirf = filelist_checkdir_main_assets;
filelist->read_jobf = filelist_readjob_main_assets;
filelist->filterf = is_filtered_main_assets;
+ filelist->type_flags |= FL_USES_MAIN_DATA;
break;
default:
filelist->checkdirf = filelist_checkdir_dir;
@@ -1897,6 +1907,11 @@ bool filelist_pending(struct FileList *filelist)
return (filelist->flags & FL_IS_PENDING) != 0;
}
+bool filelist_needs_reset_on_main_changes(const FileList *filelist)
+{
+ return (filelist->type_flags & FL_USES_MAIN_DATA) != 0;
+}
+
/**
* Limited version of full update done by space_file's file_refresh(),
* to be used by operators and such.
@@ -2872,6 +2887,7 @@ static int filelist_readjob_list_lib(const char *root, ListBase *entries, const
entry->typeflag |= FILE_TYPE_BLENDERLIB;
if (info && info->asset_data) {
entry->typeflag |= FILE_TYPE_ASSET | FILE_TYPE_ASSET_EXTERNAL;
+ /* Moves ownership! */
entry->asset_data = info->asset_data;
}
if (!(group && idcode)) {
diff --git a/source/blender/editors/space_file/filelist.h b/source/blender/editors/space_file/filelist.h
index d35a77e7816..563e35da352 100644
--- a/source/blender/editors/space_file/filelist.h
+++ b/source/blender/editors/space_file/filelist.h
@@ -105,6 +105,7 @@ bool filelist_file_cache_block(struct FileList *filelist, const int index);
bool filelist_needs_force_reset(struct FileList *filelist);
void filelist_tag_force_reset(struct FileList *filelist);
bool filelist_pending(struct FileList *filelist);
+bool filelist_needs_reset_on_main_changes(const struct FileList *filelist);
bool filelist_is_ready(struct FileList *filelist);
unsigned int filelist_entry_select_set(const struct FileList *filelist,
diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c
index ebc71fc61fb..353f55873b5 100644
--- a/source/blender/editors/space_file/space_file.c
+++ b/source/blender/editors/space_file/space_file.c
@@ -279,6 +279,12 @@ static void file_refresh(const bContext *C, ScrArea *area)
fileselect_refresh_params(sfile);
folder_history_list_ensure_for_active_browse_mode(sfile);
+ if (sfile->files && (sfile->rebuild_flag & FILE_REBUILD_MAIN_FILES) &&
+ filelist_needs_reset_on_main_changes(sfile->files)) {
+ filelist_tag_force_reset(sfile->files);
+ }
+ sfile->rebuild_flag &= ~FILE_REBUILD_MAIN_FILES;
+
if (!sfile->files) {
sfile->files = filelist_new(params->type);
params->highlight_file = -1; /* added this so it opens nicer (ton) */
@@ -372,8 +378,7 @@ static void file_listener(wmWindow *UNUSED(win),
}
break;
case NC_ASSET: {
- FileAssetSelectParams *asset_params = ED_fileselect_get_asset_params(sfile);
- if (asset_params && (asset_params->asset_library.type == FILE_ASSET_LIBRARY_LOCAL)) {
+ if (sfile->files && filelist_needs_reset_on_main_changes(sfile->files)) {
/* Full refresh of the file list if local asset data was changed. Refreshing this view is
* cheap and users expect this to be updated immediately. */
file_tag_reset_list(area, sfile);
@@ -457,6 +462,22 @@ static void file_main_region_message_subscribe(const struct bContext *UNUSED(C),
}
}
+static bool file_main_region_needs_refresh_before_draw(SpaceFile *sfile)
+{
+ /* Needed, because filelist is not initialized on loading */
+ if (!sfile->files || filelist_needs_reading(sfile->files)) {
+ return true;
+ }
+
+ /* File reading tagged the space because main data changed that may require a filelist reset. */
+ if (filelist_needs_reset_on_main_changes(sfile->files) &&
+ (sfile->rebuild_flag & FILE_REBUILD_MAIN_FILES)) {
+ return true;
+ }
+
+ return false;
+}
+
static void file_main_region_draw(const bContext *C, ARegion *region)
{
/* draw entirely, view changes should be handled here */
@@ -465,8 +486,7 @@ static void file_main_region_draw(const bContext *C, ARegion *region)
View2D *v2d = ®ion->v2d;
- /* Needed, because filelist is not initialized on loading */
- if (!sfile->files || filelist_needs_reading(sfile->files)) {
+ if (file_main_region_needs_refresh_before_draw(sfile)) {
file_refresh(C, NULL);
}
@@ -729,6 +749,19 @@ static int /*eContextResult*/ file_context(const bContext *C,
return CTX_RESULT_MEMBER_NOT_FOUND;
}
+static void file_id_remap(ScrArea *area, SpaceLink *sl, ID *UNUSED(old_id), ID *UNUSED(new_id))
+{
+ SpaceFile *sfile = (SpaceFile *)sl;
+
+ /* If the file shows main data (IDs), tag it for reset. */
+ if (sfile->files && filelist_needs_reset_on_main_changes(sfile->files)) {
+ /* Full refresh of the file list if main data was changed, don't even attempt remap pointers.
+ * We could give file list types a id-remap callback, but it's probably not worth it.
+ * Refreshing local file lists is relatively cheap. */
+ file_tag_reset_list(area, sfile);
+ }
+}
+
/* only called once, from space/spacetypes.c */
void ED_spacetype_file(void)
{
@@ -749,6 +782,7 @@ void ED_spacetype_file(void)
st->keymap = file_keymap;
st->dropboxes = file_dropboxes;
st->context = file_context;
+ st->id_remap = file_id_remap;
/* regions: main window */
art = MEM_callocN(sizeof(ARegionType), "spacetype file region");
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index dd24195e648..cf037118cd7 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -777,10 +777,13 @@ typedef struct SpaceFile {
char _pad0[6];
/* End 'SpaceLink' header. */
- /* Is this a File Browser or an Asset Browser? */
+ /** Is this a File Browser or an Asset Browser? */
char browse_mode; /* eFileBrowse_Mode */
- char _pad1[3];
+ /** Runtime flags to notify about changed data that may require rebuilding. */
+ char rebuild_flag;
+ char _pad1[2];
+
int scroll_offset;
/** Config and input for file select. One for each browse-mode, to keep them independent. */
@@ -880,6 +883,13 @@ enum eFileSortType {
FILE_SORT_SIZE = 4,
};
+/* SpaceFile.rebuild_flag */
+enum eFileRebuildFlags {
+ /** Tag the space as having to update files representing or containing main data. Must be set
+ * after file read and undo/redo. */
+ FILE_REBUILD_MAIN_FILES = (1 << 0),
+};
+
/* FileSelectParams.details_flags */
enum eFileDetails {
FILE_DETAILS_SIZE = (1 << 0),
@@ -1073,8 +1083,6 @@ typedef struct FileDirEntry {
/** ID type, in case typeflag has FILE_TYPE_BLENDERLIB set. */
int blentype;
- struct AssetMetaData *asset_data;
-
/* Path to item that is relative to current folder root. */
char *relpath;
/** Optional argument for shortcuts, aliases etc. */
@@ -1082,6 +1090,10 @@ typedef struct FileDirEntry {
/** When showing local IDs (FILE_MAIN, FILE_MAIN_ASSET), UUID of the ID this file represents. */
uint id_session_uuid;
+ /** If this file represents an asset, its asset data is here. Note that we may show assets of
+ * external files (#FILE_TYPE_ASSET_EXTERNAL) in which case this is set but not the id above. */
+ struct AssetMetaData *asset_data;
+
/* The icon_id for the preview image. */
int preview_icon_id;
More information about the Bf-blender-cvs
mailing list