File Browser: Improve usage of threads in the creation of thumbnails

Due to asynchronous process, the preview for a given image may be
generated several times.

This regenerates many thumbs unnecessarily.

The solution is to add the `FILE_ENTRY_PREVIEW_LOADING` flag for file
entries that are still in the thread queue.

So this flag is checked not to redraw the thumb when it is still being
created on a different thread.

Differential Revision: https://developer.blender.org/D11150
This commit is contained in:
Germano Cavalcante 2021-11-16 09:29:09 -03:00 committed by Germano Cavalcante
parent 917218269e
commit 9d7422b817
Notes: blender-bot 2023-02-14 00:44:02 +01:00
Referenced by commit 56f66602c7, Fix (unreported): Local preview icons not loading
2 changed files with 20 additions and 12 deletions

View File

@ -1731,7 +1731,7 @@ static void filelist_cache_previews_push(FileList *filelist, FileDirEntry *entry
return;
}
if (entry->flags & FILE_ENTRY_INVALID_PREVIEW) {
if (entry->flags & (FILE_ENTRY_INVALID_PREVIEW | FILE_ENTRY_PREVIEW_LOADING)) {
return;
}
@ -1762,6 +1762,7 @@ static void filelist_cache_previews_push(FileList *filelist, FileDirEntry *entry
FileListEntryPreviewTaskData *preview_taskdata = MEM_mallocN(sizeof(*preview_taskdata),
__func__);
preview_taskdata->preview = preview;
entry->flags |= FILE_ENTRY_PREVIEW_LOADING;
BLI_task_pool_push(cache->previews_pool,
filelist_cache_preview_runf,
preview_taskdata,
@ -2680,24 +2681,27 @@ bool filelist_cache_previews_update(FileList *filelist)
// printf("%s: %d - %s - %p\n", __func__, preview->index, preview->path, preview->img);
if (preview->icon_id) {
/* Due to asynchronous process, a preview for a given image may be generated several times,
* i.e. entry->image may already be set at this point. */
if (entry && !entry->preview_icon_id) {
if (entry) {
entry->flags &= ~FILE_ENTRY_PREVIEW_LOADING;
if (preview->icon_id) {
/* The FILE_ENTRY_PREVIEW_LOADING flag should have prevented any other asynchronous
* process from trying to generate the same preview icon. */
BLI_assert_msg(!entry->preview_icon_id, "Preview icon should not have been generated yet");
/* Move ownership over icon. */
entry->preview_icon_id = preview->icon_id;
preview->icon_id = 0;
changed = true;
}
else {
BKE_icon_delete(preview->icon_id);
/* We want to avoid re-processing this entry continuously!
* Note that, since entries only live in cache,
* preview will be retried quite often anyway. */
entry->flags |= FILE_ENTRY_INVALID_PREVIEW;
}
}
else if (entry) {
/* We want to avoid re-processing this entry continuously!
* Note that, since entries only live in cache,
* preview will be retried quite often anyway. */
entry->flags |= FILE_ENTRY_INVALID_PREVIEW;
else {
BKE_icon_delete(preview->icon_id);
}
MEM_freeN(preview);

View File

@ -1158,8 +1158,12 @@ typedef struct FileDirEntryArr {
/* FileDirEntry.flags */
enum {
FILE_ENTRY_INVALID_PREVIEW = 1 << 0, /* The preview for this entry could not be generated. */
/* The preview for this entry could not be generated. */
FILE_ENTRY_INVALID_PREVIEW = 1 << 0,
/* The entry name needs to be freed when clearing file list. */
FILE_ENTRY_NAME_FREE = 1 << 1,
/* The preview for this entry is being loaded on another thread. */
FILE_ENTRY_PREVIEW_LOADING = 1 << 2,
};
/** \} */