[Bf-blender-cvs] [a8f610a7e5a] asset-browser: Support dynamically showing local previews as they get finished
Julian Eisel
noreply at git.blender.org
Sat Nov 14 00:35:24 CET 2020
Commit: a8f610a7e5a9114f53ed3857012a0ac9f4d65570
Author: Julian Eisel
Date: Sat Nov 14 00:09:34 2020 +0100
Branches: asset-browser
https://developer.blender.org/rBa8f610a7e5a9114f53ed3857012a0ac9f4d65570
Support dynamically showing local previews as they get finished
The local asset previews can be created on a separate thread now, and the Asset
Browser can start showing them as they get done.
===================================================================
M source/blender/blenkernel/BKE_icons.h
M source/blender/blenkernel/intern/icons.c
M source/blender/blenloader/intern/readblenentry.c
M source/blender/editors/interface/interface_icons.c
M source/blender/editors/render/render_preview.c
M source/blender/editors/space_file/filelist.c
M source/blender/makesdna/DNA_ID.h
===================================================================
diff --git a/source/blender/blenkernel/BKE_icons.h b/source/blender/blenkernel/BKE_icons.h
index 7b418dc288a..f975e308570 100644
--- a/source/blender/blenkernel/BKE_icons.h
+++ b/source/blender/blenkernel/BKE_icons.h
@@ -151,6 +151,9 @@ void BKE_previewimg_ensure(struct PreviewImage *prv, const int size);
struct ImBuf *BKE_previewimg_to_imbuf(struct PreviewImage *prv, const int size);
+void BKE_previewimg_finish(struct PreviewImage *prv, const int size);
+bool BKE_previewimg_is_finished(const struct PreviewImage *prv, const int size);
+
struct PreviewImage *BKE_previewimg_cached_get(const char *name);
struct PreviewImage *BKE_previewimg_cached_ensure(const char *name);
diff --git a/source/blender/blenkernel/intern/icons.c b/source/blender/blenkernel/intern/icons.c
index aa03b22b443..692312d33b1 100644
--- a/source/blender/blenkernel/intern/icons.c
+++ b/source/blender/blenkernel/intern/icons.c
@@ -61,6 +61,8 @@
#include "BLO_read_write.h"
+#include "atomic_ops.h"
+
/**
* Only allow non-managed icons to be removed (by Python for eg).
* Previews & ID's have their own functions to remove icons.
@@ -224,7 +226,7 @@ static PreviewImage *previewimg_create_ex(size_t deferred_data_size)
}
for (int i = 0; i < NUM_ICON_SIZES; i++) {
- prv_img->flag[i] |= PRV_CHANGED;
+ prv_img->flag[i] |= (PRV_CHANGED | PRV_UNFINISHED);
prv_img->changed_timestamp[i] = 0;
}
return prv_img;
@@ -267,7 +269,7 @@ void BKE_previewimg_clear_single(struct PreviewImage *prv, enum eIconSizes size)
GPU_texture_free(prv->gputexture[size]);
}
prv->h[size] = prv->w[size] = 0;
- prv->flag[size] |= PRV_CHANGED;
+ prv->flag[size] |= (PRV_CHANGED | PRV_UNFINISHED);
prv->flag[size] &= ~PRV_USER_EDITED;
prv->changed_timestamp[size] = 0;
}
@@ -501,7 +503,7 @@ void BKE_previewimg_ensure(PreviewImage *prv, const int size)
prv->w[ICON_SIZE_PREVIEW] = thumb->x;
prv->h[ICON_SIZE_PREVIEW] = thumb->y;
prv->rect[ICON_SIZE_PREVIEW] = MEM_dupallocN(thumb->rect);
- prv->flag[ICON_SIZE_PREVIEW] &= ~(PRV_CHANGED | PRV_USER_EDITED);
+ prv->flag[ICON_SIZE_PREVIEW] &= ~(PRV_CHANGED | PRV_USER_EDITED | PRV_UNFINISHED);
}
if (do_icon) {
if (thumb->x > thumb->y) {
@@ -520,7 +522,7 @@ void BKE_previewimg_ensure(PreviewImage *prv, const int size)
prv->w[ICON_SIZE_ICON] = icon_w;
prv->h[ICON_SIZE_ICON] = icon_h;
prv->rect[ICON_SIZE_ICON] = MEM_dupallocN(thumb->rect);
- prv->flag[ICON_SIZE_ICON] &= ~(PRV_CHANGED | PRV_USER_EDITED);
+ prv->flag[ICON_SIZE_ICON] &= ~(PRV_CHANGED | PRV_USER_EDITED | PRV_UNFINISHED);
}
IMB_freeImBuf(thumb);
}
@@ -549,6 +551,17 @@ ImBuf *BKE_previewimg_to_imbuf(PreviewImage *prv, const int size)
return ima;
}
+void BKE_previewimg_finish(PreviewImage *prv, const int size)
+{
+ /* Previews may be calculated on a thread. */
+ atomic_fetch_and_or_int32(&prv->flag[size], ~PRV_UNFINISHED);
+}
+
+bool BKE_previewimg_is_finished(const PreviewImage *prv, const int size)
+{
+ return (prv->flag[size] & PRV_UNFINISHED) == 0;
+}
+
void BKE_previewimg_blend_write(BlendWriter *writer, const PreviewImage *prv)
{
/* Note we write previews also for undo steps. It takes up some memory,
@@ -586,6 +599,7 @@ void BKE_previewimg_blend_read(BlendDataReader *reader, PreviewImage *prv)
BLO_read_data_address(reader, &prv->rect[i]);
}
prv->gputexture[i] = NULL;
+ prv->flag[i] |= PRV_UNFINISHED;
}
prv->icon_id = 0;
prv->tag = 0;
diff --git a/source/blender/blenloader/intern/readblenentry.c b/source/blender/blenloader/intern/readblenentry.c
index d28c24950d3..011d509f9eb 100644
--- a/source/blender/blenloader/intern/readblenentry.c
+++ b/source/blender/blenloader/intern/readblenentry.c
@@ -242,6 +242,7 @@ LinkNode *BLO_blendhandle_get_previews(BlendHandle *bh, int ofblocktype, int *to
if (looking) {
if (bhead->SDNAnr == DNA_struct_find_nr(fd->filesdna, "PreviewImage")) {
prv = BLO_library_read_struct(fd, bhead, "PreviewImage");
+
if (prv) {
memcpy(new_prv, prv, sizeof(PreviewImage));
if (prv->rect[0] && prv->w[0] && prv->h[0]) {
@@ -256,6 +257,7 @@ LinkNode *BLO_blendhandle_get_previews(BlendHandle *bh, int ofblocktype, int *to
new_prv->rect[0] = NULL;
new_prv->w[0] = new_prv->h[0] = 0;
}
+ prv->flag[0] &= ~PRV_UNFINISHED;
if (prv->rect[1] && prv->w[1] && prv->h[1]) {
bhead = blo_bhead_next(fd, bhead);
@@ -269,6 +271,7 @@ LinkNode *BLO_blendhandle_get_previews(BlendHandle *bh, int ofblocktype, int *to
new_prv->rect[1] = NULL;
new_prv->w[1] = new_prv->h[1] = 0;
}
+ prv->flag[1] &= ~PRV_UNFINISHED;
MEM_freeN(prv);
}
}
diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index 8220e1b17a0..32928603b12 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -1262,7 +1262,7 @@ static void icon_create_rect(struct PreviewImage *prv_img, enum eIconSizes size)
else if (!prv_img->rect[size]) {
prv_img->w[size] = render_size;
prv_img->h[size] = render_size;
- prv_img->flag[size] |= PRV_CHANGED;
+ prv_img->flag[size] |= (PRV_CHANGED | PRV_UNFINISHED);
prv_img->changed_timestamp[size] = 0;
prv_img->rect[size] = MEM_callocN(render_size * render_size * sizeof(uint), "prv_rect");
}
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c
index 64194a5ddd2..9089b2e00e0 100644
--- a/source/blender/editors/render/render_preview.c
+++ b/source/blender/editors/render/render_preview.c
@@ -1347,6 +1347,22 @@ static void icon_preview_add_size(IconPreview *ip, uint *rect, int sizex, int si
BLI_addtail(&ip->sizes, new_size);
}
+/**
+ * Find the index to map \a ip to data in \a preview_image.
+ */
+static int icon_previewimg_size_index_get(const IconPreviewSize *icon_size,
+ const PreviewImage *prv_img)
+{
+ for (int i = 0; i < NUM_ICON_SIZES; i++) {
+ if ((prv_img->w[i] == icon_size->sizex) && (prv_img->h[i] == icon_size->sizey)) {
+ return i;
+ }
+ }
+
+ BLI_assert(false);
+ return -1;
+}
+
static void icon_preview_startjob_all_sizes(void *customdata,
short *stop,
short *do_update,
@@ -1371,6 +1387,13 @@ static void icon_preview_startjob_all_sizes(void *customdata,
continue;
}
+#ifndef NDEBUG
+ {
+ int size_index = icon_previewimg_size_index_get(cur_size, prv);
+ BLI_assert(!BKE_previewimg_is_finished(prv, size_index));
+ }
+#endif
+
if (ELEM(GS(ip->id->name), ID_OB)) {
object_preview_render(ip, cur_size);
continue;
@@ -1443,6 +1466,12 @@ static void icon_preview_endjob(void *customdata)
if (ip->owner) {
PreviewImage *prv_img = ip->owner;
prv_img->tag &= ~PRV_TAG_DEFFERED_RENDERING;
+
+ LISTBASE_FOREACH (IconPreviewSize *, icon_size, &ip->sizes) {
+ int size_index = icon_previewimg_size_index_get(icon_size, prv_img);
+ BKE_previewimg_finish(prv_img, size_index);
+ }
+
if (prv_img->tag & PRV_TAG_DEFFERED_DELETE) {
BLI_assert(prv_img->tag & PRV_TAG_DEFFERED);
BKE_previewimg_cached_release_pointer(prv_img);
diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c
index 12287f25270..8fc7b799e75 100644
--- a/source/blender/editors/space_file/filelist.c
+++ b/source/blender/editors/space_file/filelist.c
@@ -279,6 +279,10 @@ typedef struct FileListEntryPreview {
char path[FILE_MAX];
uint64_t flags;
int index;
+ /* Some file types load the memory from runtime data, not from disk. We just wait until it's done
+ * generating (BKE_previewimg_is_finished()). */
+ PreviewImage *in_memory_preview;
+
ImBuf *img;
} FileListEntryPreview;
@@ -1340,37 +1344,50 @@ static void filelist_cache_preview_runf(TaskPool *__restrict pool, void *taskdat
FileListEntryPreview *preview = preview_taskdata->preview;
ThumbSource source = 0;
+ bool done = false;
// printf("%s: Start (%d)...\n", __func__, threadid);
- // printf("%s: %d - %s - %p\n", __func__, preview->index, preview->path, preview->img);
- BLI_assert(preview->flags &
- (FILE_TYPE_IMAGE | FILE_TYPE_MOVIE | FILE_TYPE_FTFONT | FILE_TYPE_BLENDER |
- FILE_TYPE_BLENDER_BACKUP | FILE_TYPE_BLENDERLIB));
-
- if (preview->flags & FILE_TYPE_IMAGE) {
- source = THB_SOURCE_IMAGE;
- }
- else if (preview->flags &
- (FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP | FILE_TYPE_BLENDERLIB)) {
- source = THB_SOURCE_BLEND;
- }
- else if (preview->flags & FILE_TYPE_MOVIE) {
- source = THB_SOURCE_MOVIE;
- }
- else if (preview->flags & FILE_TYPE_FTFONT) {
- source = THB_SOURCE_FONT;
+ if (preview->in_memory_preview) {
+ if (BKE_previewimg_is_finished(preview->in_memory_preview, ICON_SIZE_PREVIEW)) {
+ preview->img = BKE_previewimg_to_imbuf(preview->in_memory_preview, ICON_SIZE_PREVIEW);
+ done = true;
+ }
}
+ else {
+ // printf("%s: %d - %s - %p\n", __func__, preview->index, preview->path, preview->img);
+ BLI_assert(preview->flags &
+ (FILE_TYPE_IMAGE | FILE_TYPE_MOVIE | FILE_TYPE_FTFONT | FILE_TYPE_BLENDER |
+ FILE_TYPE_BLENDER_BACKUP | FILE_TYPE_BLENDERLIB));
- IMB_thumb_path_lock(preview->path);
- /* Always generate biggest preview size for now, it's simpler and avoids having to re-generate in
- * case user switch to a bigger preview size. */
- preview->img = IMB_thumb_manage(preview->path, THB_LARGE, source);
- IMB_thumb_path_unlock(preview->path);
+ if (preview->flags & FILE_TYPE_IMAGE) {
+ source = THB_SOURCE_IMAGE;
+ }
+ else if (preview->flags &
+ (FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP | FILE_TYPE_BLENDERLIB)) {
+ source = THB_SOURCE_BLEND;
+
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list