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
diff options
context:
space:
mode:
authorJulian Eisel <julian@blender.org>2020-12-14 15:21:58 +0300
committerJulian Eisel <julian@blender.org>2020-12-15 19:03:45 +0300
commit9363132c8601ebca6d89168e09bb10f81d6cb03a (patch)
tree59afa11ef38f56060f1d4c7a35bf23adab31424d /source/blender/editors
parentc25e0310497f5228bd04992d6bcd84481d0b0c5b (diff)
Asset System: Various changes to previews in preparation for Asset Browser
* Support defining (not necessarily rendering) icons in threads. Needed so the File Browser can expose file previews with an icon-id to scripts. ** For that, ported `icons.c` to C++, to be able to use scope based mutex locks (cleaner & safer code). Had to do some cleanups and minor refactoring for that. * Added support for ImBuf icons, as a decent way for icons to hold the file preview buffers. * Tag previews as "unfinished" while they render in a thread, for the File Browser to dynamically load previews as they get finished. * Better handle cases where threaded preview generation is requested, but the ID type doesn't support it (fallback to single threaded). This is for general sanity of the code (as in, safety and cleanness) * Enabled asset notifier for custom preview loading operator, was just disabled because `NC_ASSET` wasn't defined in master yet. Part of the first Asset Browser milestone. Check the #asset_browser_milestone_1 project milestone on developer.blender.org. Differential Revision: https://developer.blender.org/D9719 Reviewed by: Bastien Montagne, Brecht Van Lommel
Diffstat (limited to 'source/blender/editors')
-rw-r--r--source/blender/editors/interface/interface_icons.c45
-rw-r--r--source/blender/editors/render/render_preview.c37
-rw-r--r--source/blender/editors/util/ed_util.c2
3 files changed, 66 insertions, 18 deletions
diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index 90f5172f6ec..1c09dc6f4df 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -100,11 +100,12 @@ typedef void (*VectorDrawFunc)(int x, int y, int w, int h, float alpha);
#define ICON_TYPE_COLOR_TEXTURE 1
#define ICON_TYPE_MONO_TEXTURE 2
#define ICON_TYPE_BUFFER 3
-#define ICON_TYPE_VECTOR 4
-#define ICON_TYPE_GEOM 5
-#define ICON_TYPE_EVENT 6 /* draw keymap entries using custom renderer. */
-#define ICON_TYPE_GPLAYER 7
-#define ICON_TYPE_BLANK 8
+#define ICON_TYPE_IMBUF 4
+#define ICON_TYPE_VECTOR 5
+#define ICON_TYPE_GEOM 6
+#define ICON_TYPE_EVENT 7 /* draw keymap entries using custom renderer. */
+#define ICON_TYPE_GPLAYER 8
+#define ICON_TYPE_BLANK 9
typedef struct DrawInfo {
int type;
@@ -1147,6 +1148,9 @@ static DrawInfo *icon_create_drawinfo(Icon *icon)
if (ELEM(icon_data_type, ICON_DATA_ID, ICON_DATA_PREVIEW)) {
di->type = ICON_TYPE_PREVIEW;
}
+ else if (icon_data_type == ICON_DATA_IMBUF) {
+ di->type = ICON_TYPE_IMBUF;
+ }
else if (icon_data_type == ICON_DATA_GEOM) {
di->type = ICON_TYPE_GEOM;
}
@@ -1262,7 +1266,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");
}
@@ -1384,8 +1388,12 @@ void ui_icon_ensure_deferred(const bContext *C, const int icon_id, const bool bi
}
}
-/* only called when icon has changed */
-/* only call with valid pointer from UI_icon_draw */
+/**
+ * * Only call with valid pointer from UI_icon_draw.
+ * * Only called when icon has changed.
+ *
+ * Note that if an ID doesn't support jobs for preview creation, \a use_job will be ignored.
+ */
static void icon_set_image(const bContext *C,
Scene *scene,
ID *id,
@@ -1408,7 +1416,7 @@ static void icon_set_image(const bContext *C,
const bool delay = prv_img->rect[size] != NULL;
icon_create_rect(prv_img, size);
- if (use_job) {
+ if (use_job && BKE_previewimg_id_supports_jobs(id)) {
/* Job (background) version */
ED_preview_icon_job(
C, prv_img, id, prv_img->rect[size], prv_img->w[size], prv_img->h[size], delay);
@@ -1790,7 +1798,14 @@ static void icon_draw_size(float x,
/* We need to flush widget base first to ensure correct ordering. */
UI_widgetbase_draw_cache_flush();
- if (di->type == ICON_TYPE_VECTOR) {
+ if (di->type == ICON_TYPE_IMBUF) {
+ ImBuf *ibuf = icon->obj;
+
+ GPU_blend(GPU_BLEND_ALPHA_PREMULT);
+ icon_draw_rect(x, y, w, h, aspect, ibuf->x, ibuf->y, ibuf->rect, alpha, desaturate);
+ GPU_blend(GPU_BLEND_ALPHA);
+ }
+ else if (di->type == ICON_TYPE_VECTOR) {
/* vector icons use the uiBlock transformation, they are not drawn
* with untransformed coordinates like the other icons */
di->data.vector.func((int)x, (int)y, w, h, 1.0f);
@@ -1937,6 +1952,9 @@ static void ui_id_preview_image_render_size(
}
}
+/**
+ * Note that if an ID doesn't support jobs for preview creation, \a use_job will be ignored.
+ */
void UI_icon_render_id(const bContext *C, Scene *scene, ID *id, const bool big, const bool use_job)
{
PreviewImage *pi = BKE_previewimg_id_ensure(id);
@@ -1964,12 +1982,7 @@ static void ui_id_icon_render(const bContext *C, ID *id, bool use_jobs)
}
for (enum eIconSizes i = 0; i < NUM_ICON_SIZES; i++) {
- /* check if rect needs to be created; changed
- * only set by dynamic icons */
- if (((pi->flag[i] & PRV_CHANGED) || !pi->rect[i])) {
- icon_set_image(C, NULL, id, pi, i, use_jobs);
- pi->flag[i] &= ~PRV_CHANGED;
- }
+ ui_id_preview_image_render_size(C, NULL, id, pi, i, use_jobs);
}
}
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c
index 3c103f28d93..579fd86077e 100644
--- a/source/blender/editors/render/render_preview.c
+++ b/source/blender/editors/render/render_preview.c
@@ -354,13 +354,15 @@ static ID *duplicate_ids(ID *id, const bool allow_failure)
case ID_TE:
case ID_LA:
case ID_WO: {
+ BLI_assert(BKE_previewimg_id_supports_jobs(id));
ID *id_copy = BKE_id_copy_ex(
NULL, id, NULL, LIB_ID_CREATE_LOCAL | LIB_ID_COPY_LOCALIZE | LIB_ID_COPY_NO_ANIMDATA);
return id_copy;
}
+ /* These support threading, but don't need duplicating. */
case ID_IM:
case ID_BR:
- case ID_SCR:
+ BLI_assert(BKE_previewimg_id_supports_jobs(id));
return NULL;
default:
if (!allow_failure) {
@@ -1374,6 +1376,24 @@ static void other_id_types_preview_render(IconPreview *ip,
shader_preview_free(sp);
}
+/* exported functions */
+
+/**
+ * Find the index to map \a icon_size to data in \a preview_image.
+ */
+static int icon_previewimg_size_index_get(const IconPreviewSize *icon_size,
+ const PreviewImage *preview_image)
+{
+ for (int i = 0; i < NUM_ICON_SIZES; i++) {
+ if ((preview_image->w[i] == icon_size->sizex) && (preview_image->h[i] == icon_size->sizey)) {
+ return i;
+ }
+ }
+
+ BLI_assert(!"The searched icon size does not match any in the preview image");
+ return -1;
+}
+
static void icon_preview_startjob_all_sizes(void *customdata,
short *stop,
short *do_update,
@@ -1398,6 +1418,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 (ip->id && ELEM(GS(ip->id->name), ID_OB)) {
/* Much simpler than the ShaderPreview mess used for other ID types. */
object_preview_render(ip, cur_size);
@@ -1460,6 +1487,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_deferred_release(prv_img);
@@ -1576,6 +1609,8 @@ void ED_preview_shader_job(const bContext *C,
Scene *scene = CTX_data_scene(C);
short id_type = GS(id->name);
+ BLI_assert(BKE_previewimg_id_supports_jobs(id));
+
/* Use workspace render only for buttons Window,
* since the other previews are related to the datablock. */
diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c
index 5e3f443ce9c..6547e42f410 100644
--- a/source/blender/editors/util/ed_util.c
+++ b/source/blender/editors/util/ed_util.c
@@ -546,7 +546,7 @@ static int lib_id_load_custom_preview_exec(bContext *C, wmOperator *op)
BKE_previewimg_id_custom_set(id, path);
- // WM_event_add_notifier(C, NC_ASSET, NULL);
+ WM_event_add_notifier(C, NC_ASSET, NULL);
return OPERATOR_FINISHED;
}