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:
Diffstat (limited to 'source/blender/editors')
-rw-r--r--source/blender/editors/include/ED_render.h10
-rw-r--r--source/blender/editors/include/UI_interface_icons.h2
-rw-r--r--source/blender/editors/interface/interface.c41
-rw-r--r--source/blender/editors/interface/interface_icons.c151
-rw-r--r--source/blender/editors/interface/interface_intern.h3
-rw-r--r--source/blender/editors/interface/interface_templates.c14
-rw-r--r--source/blender/editors/render/render_preview.c149
-rw-r--r--source/blender/editors/render/render_update.c16
-rw-r--r--source/blender/editors/space_image/image_ops.c2
9 files changed, 251 insertions, 137 deletions
diff --git a/source/blender/editors/include/ED_render.h b/source/blender/editors/include/ED_render.h
index 2bc0566f4a6..414126cac13 100644
--- a/source/blender/editors/include/ED_render.h
+++ b/source/blender/editors/include/ED_render.h
@@ -60,11 +60,15 @@ struct Scene *ED_render_job_get_current_scene(const struct bContext *C);
* - PR_BUTS_RENDER: preview is rendered for buttons window
* - PR_ICON_RENDER: preview is rendered for icons. hopefully fast enough for at least 32x32
* - PR_NODE_RENDER: preview is rendered for node editor
+ * - PR_ICON_DEFERRED: No render, we just ensure deferred icon data gets generated.
*/
-#define PR_BUTS_RENDER 0
-#define PR_ICON_RENDER 1
-#define PR_NODE_RENDER 2
+enum {
+ PR_BUTS_RENDER = 0,
+ PR_ICON_RENDER = 1,
+ PR_NODE_RENDER = 2,
+ PR_ICON_DEFERRED = 3,
+};
void ED_preview_init_dbase(void);
void ED_preview_free_dbase(void);
diff --git a/source/blender/editors/include/UI_interface_icons.h b/source/blender/editors/include/UI_interface_icons.h
index 9d190fa81c7..92f3b0180c6 100644
--- a/source/blender/editors/include/UI_interface_icons.h
+++ b/source/blender/editors/include/UI_interface_icons.h
@@ -49,7 +49,7 @@ typedef struct IconFile {
#define ICON_DEFAULT_HEIGHT_SCALE ((int)(UI_UNIT_Y * 0.8f))
#define ICON_DEFAULT_WIDTH_SCALE ((int)(UI_UNIT_X * 0.8f))
-#define PREVIEW_DEFAULT_HEIGHT 96
+#define PREVIEW_DEFAULT_HEIGHT 128
/*
* Resizable Icons for Blender
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index b63871f5c82..a9cc926b275 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -3237,6 +3237,18 @@ static uiBut *ui_def_but(
return but;
}
+void ui_def_but_icon(uiBut *but, const int icon, const int flag) {
+ if (icon) {
+ ui_icon_ensure_deferred(but->block->evil_C, icon, (flag & UI_BUT_ICON_PREVIEW) != 0);
+ }
+ but->icon = (BIFIconID)icon;
+ but->flag |= flag;
+
+ if (but->str && but->str[0]) {
+ but->drawflag |= UI_BUT_ICON_LEFT;
+ }
+}
+
static void ui_def_but_rna__disable(uiBut *but)
{
but->flag |= UI_BUT_DISABLED;
@@ -3500,11 +3512,7 @@ static uiBut *ui_def_but_rna(
but->rnaindex = 0;
if (icon) {
- but->icon = (BIFIconID)icon;
- but->flag |= UI_HAS_ICON;
- if (str[0]) {
- but->drawflag |= UI_BUT_ICON_LEFT;
- }
+ ui_def_but_icon(but, icon, UI_HAS_ICON);
}
if ((type == UI_BTYPE_MENU) && (but->dt == UI_EMBOSS_PULLDOWN)) {
@@ -3691,8 +3699,7 @@ int UI_autocomplete_end(AutoComplete *autocpl, char *autoname)
static void ui_but_update_and_icon_set(uiBut *but, int icon)
{
if (icon) {
- but->icon = (BIFIconID) icon;
- but->flag |= UI_HAS_ICON;
+ ui_def_but_icon(but, icon, UI_HAS_ICON);
}
ui_but_update(but);
@@ -4066,7 +4073,7 @@ void UI_but_drag_set_value(uiBut *but)
void UI_but_drag_set_image(uiBut *but, const char *path, int icon, struct ImBuf *imb, float scale)
{
but->dragtype = WM_DRAG_PATH;
- but->icon = icon; /* no flag UI_HAS_ICON, so icon doesnt draw in button */
+ ui_def_but_icon(but, icon, 0); /* no flag UI_HAS_ICON, so icon doesnt draw in button */
but->dragpoin = (void *)path;
but->imb = imb;
but->imb_scale = scale;
@@ -4220,8 +4227,7 @@ uiBut *uiDefIconTextMenuBut(uiBlock *block, uiMenuCreateFunc func, void *arg, in
{
uiBut *but = ui_def_but(block, UI_BTYPE_PULLDOWN, 0, str, x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip);
- but->icon = (BIFIconID) icon;
- but->flag |= UI_HAS_ICON;
+ ui_def_but_icon(but, icon, UI_HAS_ICON);
but->drawflag |= UI_BUT_ICON_LEFT;
but->flag |= UI_BUT_ICON_SUBMENU;
@@ -4236,8 +4242,7 @@ uiBut *uiDefIconMenuBut(uiBlock *block, uiMenuCreateFunc func, void *arg, int ic
{
uiBut *but = ui_def_but(block, UI_BTYPE_PULLDOWN, 0, "", x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip);
- but->icon = (BIFIconID) icon;
- but->flag |= UI_HAS_ICON;
+ ui_def_but_icon(but, icon, UI_HAS_ICON);
but->drawflag &= ~UI_BUT_ICON_LEFT;
but->menu_create_func = func;
@@ -4253,7 +4258,7 @@ uiBut *uiDefIconTextBlockBut(uiBlock *block, uiBlockCreateFunc func, void *arg,
/* XXX temp, old menu calls pass on icon arrow, which is now UI_BUT_ICON_SUBMENU flag */
if (icon != ICON_RIGHTARROW_THIN) {
- but->icon = (BIFIconID) icon;
+ ui_def_but_icon(but, icon, 0);
but->drawflag |= UI_BUT_ICON_LEFT;
}
but->flag |= UI_HAS_ICON;
@@ -4270,9 +4275,8 @@ uiBut *uiDefIconBlockBut(uiBlock *block, uiBlockCreateFunc func, void *arg, int
{
uiBut *but = ui_def_but(block, UI_BTYPE_BLOCK, retval, "", x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip);
- but->icon = (BIFIconID) icon;
- but->flag |= UI_HAS_ICON;
-
+ ui_def_but_icon(but, icon, UI_HAS_ICON);
+
but->drawflag |= UI_BUT_ICON_LEFT;
but->block_create_func = func;
@@ -4305,9 +4309,8 @@ uiBut *uiDefSearchBut(uiBlock *block, void *arg, int retval, int icon, int maxle
{
uiBut *but = ui_def_but(block, UI_BTYPE_SEARCH_MENU, retval, "", x, y, width, height, arg, 0.0, maxlen, a1, a2, tip);
- but->icon = (BIFIconID) icon;
- but->flag |= UI_HAS_ICON;
-
+ ui_def_but_icon(but, icon, UI_HAS_ICON);
+
but->drawflag |= UI_BUT_ICON_LEFT | UI_BUT_TEXT_LEFT;
ui_but_update(but);
diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index 6536c0a869e..7c05d5f4378 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -55,6 +55,7 @@
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
+#include "IMB_thumbs.h"
#include "BIF_gl.h"
#include "BIF_glutil.h"
@@ -904,10 +905,13 @@ void UI_icons_init(int first_dyn_id)
static int preview_render_size(enum eIconSizes size)
{
switch (size) {
- case ICON_SIZE_ICON: return 32;
- case ICON_SIZE_PREVIEW: return PREVIEW_DEFAULT_HEIGHT;
+ case ICON_SIZE_ICON:
+ return ICON_RENDER_DEFAULT_HEIGHT;
+ case ICON_SIZE_PREVIEW:
+ return PREVIEW_RENDER_DEFAULT_HEIGHT;
+ default:
+ return 0;
}
- return 0;
}
/* Create rect for the icon
@@ -923,12 +927,49 @@ 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->changed[size] = 1;
+ prv_img->flag[size] |= PRV_CHANGED;
prv_img->changed_timestamp[size] = 0;
prv_img->rect[size] = MEM_callocN(render_size * render_size * sizeof(unsigned int), "prv_rect");
}
}
+void ui_icon_ensure_deferred(const bContext *C, const int icon_id, const bool big)
+{
+ Icon *icon = BKE_icon_get(icon_id);
+
+ if (icon) {
+ DrawInfo *di = (DrawInfo *)icon->drawinfo;
+
+ if (!di) {
+ di = icon_create_drawinfo();
+
+ icon->drawinfo = di;
+ icon->drawinfo_free = UI_icons_free_drawinfo;
+ }
+
+ if (di) {
+ if (di->type == ICON_TYPE_PREVIEW) {
+ PreviewImage *prv = (icon->type != 0) ? BKE_previewimg_id_ensure((ID *)icon->obj) : icon->obj;
+
+ if (prv) {
+ const int size = big ? ICON_SIZE_PREVIEW : ICON_SIZE_ICON;
+
+ if (!prv->use_deferred || prv->rect[size] || (prv->flag[size] & PRV_USER_EDITED)) {
+ return;
+ }
+
+ icon_create_rect(prv, size);
+
+ /* Always using job (background) version. */
+ ED_preview_icon_job(C, prv, NULL, prv->rect[size], prv->w[size], prv->h[size]);
+
+ prv->flag[size] &= ~PRV_CHANGED;
+ }
+ }
+ }
+ }
+}
+
/* only called when icon has changed */
/* only call with valid pointer from UI_icon_draw */
static void icon_set_image(
@@ -940,6 +981,11 @@ static void icon_set_image(
return;
}
+ if (prv_img->flag[size] & PRV_USER_EDITED) {
+ /* user-edited preview, do not auto-update! */
+ return;
+ }
+
icon_create_rect(prv_img, size);
if (use_job) {
@@ -961,22 +1007,32 @@ PreviewImage *UI_icon_to_preview(int icon_id)
if (icon) {
DrawInfo *di = (DrawInfo *)icon->drawinfo;
- if (di && di->data.buffer.image) {
- ImBuf *bbuf;
-
- bbuf = IMB_ibImageFromMemory(di->data.buffer.image->datatoc_rect, di->data.buffer.image->datatoc_size, IB_rect, NULL, "<matcap buffer>");
- if (bbuf) {
- PreviewImage *prv = BKE_previewimg_create();
-
- prv->rect[0] = bbuf->rect;
+ if (di) {
+ if (di->type == ICON_TYPE_PREVIEW) {
+ PreviewImage *prv = (icon->type != 0) ? BKE_previewimg_id_ensure((ID *)icon->obj) : icon->obj;
- prv->w[0] = bbuf->x;
- prv->h[0] = bbuf->y;
-
- bbuf->rect = NULL;
- IMB_freeImBuf(bbuf);
-
- return prv;
+ if (prv) {
+ return BKE_previewimg_copy(prv);
+ }
+ }
+ else if (di->data.buffer.image) {
+ ImBuf *bbuf;
+
+ bbuf = IMB_ibImageFromMemory(di->data.buffer.image->datatoc_rect, di->data.buffer.image->datatoc_size,
+ IB_rect, NULL, __func__);
+ if (bbuf) {
+ PreviewImage *prv = BKE_previewimg_create();
+
+ prv->rect[0] = bbuf->rect;
+
+ prv->w[0] = bbuf->x;
+ prv->h[0] = bbuf->y;
+
+ bbuf->rect = NULL;
+ IMB_freeImBuf(bbuf);
+
+ return prv;
+ }
}
}
}
@@ -987,6 +1043,10 @@ static void icon_draw_rect(float x, float y, int w, int h, float UNUSED(aspect),
unsigned int *rect, float alpha, const float rgb[3], const bool is_preview)
{
ImBuf *ima = NULL;
+ int draw_w = w;
+ int draw_h = h;
+ int draw_x = x;
+ int draw_y = y;
/* sanity check */
if (w <= 0 || h <= 0 || w > 2000 || h > 2000) {
@@ -1006,21 +1066,34 @@ static void icon_draw_rect(float x, float y, int w, int h, float UNUSED(aspect),
}
/* rect contains image in 'rendersize', we only scale if needed */
- if (rw != w && rh != h) {
+ if (rw != w || rh != h) {
+ /* preserve aspect ratio and center */
+ if (rw > rh) {
+ draw_w = w;
+ draw_h = (int)(((float)rh / (float)rw) * (float)w);
+ draw_y += (h - draw_h) / 2;
+ }
+ else if (rw < rh) {
+ draw_w = (int)(((float)rw / (float)rh) * (float)h);
+ draw_h = h;
+ draw_x += (w - draw_w) / 2;
+ }
+ /* if the image is squared, the draw_ initialization values are good */
+
/* first allocate imbuf for scaling and copy preview into it */
ima = IMB_allocImBuf(rw, rh, 32, IB_rect);
memcpy(ima->rect, rect, rw * rh * sizeof(unsigned int));
- IMB_scaleImBuf(ima, w, h); /* scale it */
+ IMB_scaleImBuf(ima, draw_w, draw_h); /* scale it */
rect = ima->rect;
}
/* draw */
if (is_preview) {
- glaDrawPixelsSafe(x, y, w, h, w, GL_RGBA, GL_UNSIGNED_BYTE, rect);
+ glaDrawPixelsSafe(draw_x, draw_y, draw_w, draw_h, draw_w, GL_RGBA, GL_UNSIGNED_BYTE, rect);
}
else {
- glRasterPos2f(x, y);
- glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, rect);
+ glRasterPos2f(draw_x, draw_y);
+ glDrawPixels(draw_w, draw_h, GL_RGBA, GL_UNSIGNED_BYTE, rect);
}
if (ima)
@@ -1081,10 +1154,13 @@ static void icon_draw_texture(
static int get_draw_size(enum eIconSizes size)
{
switch (size) {
- case ICON_SIZE_ICON: return ICON_DEFAULT_HEIGHT;
- case ICON_SIZE_PREVIEW: return PREVIEW_DEFAULT_HEIGHT;
+ case ICON_SIZE_ICON:
+ return ICON_DEFAULT_HEIGHT;
+ case ICON_SIZE_PREVIEW:
+ return PREVIEW_DEFAULT_HEIGHT;
+ default:
+ return 0;
}
- return 0;
}
@@ -1147,9 +1223,12 @@ static void icon_draw_size(
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
else if (di->type == ICON_TYPE_PREVIEW) {
- PreviewImage *pi = BKE_previewimg_get((ID *)icon->obj);
+ PreviewImage *pi = (icon->type != 0) ? BKE_previewimg_id_ensure((ID *)icon->obj) : icon->obj;
if (pi) {
+ /* Do deferred loading/generation if needed. */
+// BKE_previewimg_ensure(pi, size);
+
/* no create icon on this level in code */
if (!pi->rect[size]) return; /* something has gone wrong! */
@@ -1164,17 +1243,17 @@ static void icon_draw_size(
static void ui_id_preview_image_render_size(
const bContext *C, Scene *scene, ID *id, PreviewImage *pi, int size, const bool use_job)
{
- if ((pi->changed[size] || !pi->rect[size])) { /* changed only ever set by dynamic icons */
+ if (((pi->flag[size] & PRV_CHANGED) || !pi->rect[size])) { /* changed only ever set by dynamic icons */
/* create the rect if necessary */
icon_set_image(C, scene, id, pi, size, use_job);
- pi->changed[size] = 0;
+ pi->flag[size] &= ~PRV_CHANGED;
}
}
void UI_id_icon_render(const bContext *C, Scene *scene, ID *id, const bool big, const bool use_job)
{
- PreviewImage *pi = BKE_previewimg_get(id);
+ PreviewImage *pi = BKE_previewimg_id_ensure(id);
if (pi) {
if (big)
@@ -1186,7 +1265,7 @@ void UI_id_icon_render(const bContext *C, Scene *scene, ID *id, const bool big,
static void ui_id_brush_render(const bContext *C, ID *id)
{
- PreviewImage *pi = BKE_previewimg_get(id);
+ PreviewImage *pi = BKE_previewimg_id_ensure(id);
enum eIconSizes i;
if (!pi)
@@ -1195,9 +1274,9 @@ static void ui_id_brush_render(const bContext *C, ID *id)
for (i = 0; i < NUM_ICON_SIZES; i++) {
/* check if rect needs to be created; changed
* only set by dynamic icons */
- if ((pi->changed[i] || !pi->rect[i])) {
+ if (((pi->flag[i] & PRV_CHANGED) || !pi->rect[i])) {
icon_set_image(C, NULL, id, pi, i, true);
- pi->changed[i] = 0;
+ pi->flag[i] &= ~PRV_CHANGED;
}
}
}
@@ -1208,7 +1287,7 @@ static int ui_id_brush_get_icon(const bContext *C, ID *id)
Brush *br = (Brush *)id;
if (br->flag & BRUSH_CUSTOM_ICON) {
- BKE_icon_getid(id);
+ BKE_icon_id_ensure(id);
ui_id_brush_render(C, id);
}
else {
@@ -1270,7 +1349,7 @@ int ui_id_icon_get(const bContext *C, ID *id, const bool big)
case ID_IM: /* fall through */
case ID_WO: /* fall through */
case ID_LA: /* fall through */
- iconid = BKE_icon_getid(id);
+ iconid = BKE_icon_id_ensure(id);
/* checks if not exists, or changed */
UI_id_icon_render(C, NULL, id, big, true);
break;
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index a3192d3b8d0..9461547a164 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -465,6 +465,8 @@ extern bool ui_but_string_set(struct bContext *C, uiBut *but, const char *str) A
extern bool ui_but_string_set_eval_num(struct bContext *C, uiBut *but, const char *str, double *value) ATTR_NONNULL();
extern int ui_but_string_get_max_length(uiBut *but);
extern uiBut *ui_but_drag_multi_edit_get(uiBut *but);
+
+void ui_def_but_icon(uiBut *but, const int icon, const int flag);
extern uiButExtraIconType ui_but_icon_extra_get(uiBut *but);
extern void ui_but_default_set(struct bContext *C, const bool all, const bool use_afterfunc);
@@ -673,6 +675,7 @@ void ui_draw_preview_item(struct uiFontStyle *fstyle, rcti *rect, const char *na
void uiStyleInit(void);
/* interface_icons.c */
+void ui_icon_ensure_deferred(const struct bContext *C, const int icon_id, const bool big);
int ui_id_icon_get(const struct bContext *C, struct ID *id, const bool big);
/* resources.c */
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index fe1a1b9096d..9a34e4be980 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -430,8 +430,8 @@ static void template_ID(
but = uiDefBlockButN(block, id_search_menu, MEM_dupallocN(template), "", 0, 0, UI_UNIT_X * 6, UI_UNIT_Y * 6,
TIP_(template_id_browse_tip(type)));
- but->icon = id ? ui_id_icon_get(C, id, true) : RNA_struct_ui_icon(type);
- UI_but_flag_enable(but, UI_HAS_ICON | UI_BUT_ICON_PREVIEW);
+ ui_def_but_icon(but, id ? ui_id_icon_get(C, id, true) : RNA_struct_ui_icon(type),
+ UI_HAS_ICON | UI_BUT_ICON_PREVIEW);
if ((idfrom && idfrom->lib) || !editable)
UI_but_flag_enable(but, UI_BUT_DISABLED);
@@ -441,10 +441,9 @@ static void template_ID(
else if (flag & UI_ID_BROWSE) {
but = uiDefBlockButN(block, id_search_menu, MEM_dupallocN(template), "", 0, 0, UI_UNIT_X * 1.6, UI_UNIT_Y,
TIP_(template_id_browse_tip(type)));
- but->icon = RNA_struct_ui_icon(type);
+ ui_def_but_icon(but, RNA_struct_ui_icon(type), UI_HAS_ICON);
/* default dragging of icon for id browse buttons */
UI_but_drag_set_id(but, id);
- UI_but_flag_enable(but, UI_HAS_ICON);
UI_but_drawflag_enable(but, UI_BUT_ICON_LEFT);
if ((idfrom && idfrom->lib) || !editable)
@@ -1666,9 +1665,9 @@ static uiBlock *ui_icon_view_menu_cb(bContext *C, ARegion *ar, void *arg_litem)
icon = item[a].icon;
value = item[a].value;
- but = uiDefIconButR_prop(block, UI_BTYPE_ROW, 0, icon, x, y, UI_UNIT_X * 5, UI_UNIT_Y * 5,
+ but = uiDefIconButR_prop(block, UI_BTYPE_ROW, 0, ICON_NONE, x, y, UI_UNIT_X * 5, UI_UNIT_Y * 5,
&cb.ptr, cb.prop, -1, 0, value, -1, -1, NULL);
- UI_but_flag_enable(but, UI_HAS_ICON | UI_BUT_ICON_PREVIEW);
+ ui_def_but_icon(but, icon, UI_HAS_ICON | UI_BUT_ICON_PREVIEW);
}
UI_block_bounds_set_normal(block, 0.3f * U.widget_unit);
@@ -1708,8 +1707,7 @@ void uiTemplateIconView(uiLayout *layout, PointerRNA *ptr, const char *propname)
but = uiDefBlockButN(block, ui_icon_view_menu_cb, cb, "", 0, 0, UI_UNIT_X * 6, UI_UNIT_Y * 6, "");
- but->icon = icon;
- UI_but_flag_enable(but, UI_HAS_ICON | UI_BUT_ICON_PREVIEW);
+ ui_def_but_icon(but, icon, UI_HAS_ICON | UI_BUT_ICON_PREVIEW);
if (free_items) {
MEM_freeN(items);
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c
index 65d4c2301a9..5112cd84d09 100644
--- a/source/blender/editors/render/render_preview.c
+++ b/source/blender/editors/render/render_preview.c
@@ -79,7 +79,7 @@
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
-
+#include "IMB_thumbs.h"
#include "BIF_gl.h"
#include "BIF_glutil.h"
@@ -128,7 +128,7 @@ ImBuf *get_brush_icon(Brush *brush)
}
if (brush->icon_imbuf)
- BKE_icon_changed(BKE_icon_getid(&brush->id));
+ BKE_icon_changed(BKE_icon_id_ensure(&brush->id));
}
}
}
@@ -935,65 +935,87 @@ static void set_alpha(char *cp, int sizex, int sizey, char alpha)
static void icon_preview_startjob(void *customdata, short *stop, short *do_update)
{
ShaderPreview *sp = customdata;
- ID *id = sp->id;
- short idtype = GS(id->name);
-
- if (idtype == ID_IM) {
- Image *ima = (Image *)id;
- ImBuf *ibuf = NULL;
- ImageUser iuser = {NULL};
- /* ima->ok is zero when Image cannot load */
- if (ima == NULL || ima->ok == 0)
- return;
+ if (sp->pr_method == PR_ICON_DEFERRED) {
+ PreviewImage *prv = sp->owner;
+ ImBuf *thumb;
+ char *deferred_data = PRV_DEFERRED_DATA(prv);
+ int source = deferred_data[0];
+ char *path = &deferred_data[1];
- /* setup dummy image user */
- iuser.ok = iuser.framenr = 1;
- iuser.scene = sp->scene;
-
- /* elubie: this needs to be changed: here image is always loaded if not
- * already there. Very expensive for large images. Need to find a way to
- * only get existing ibuf */
- ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL);
- if (ibuf == NULL || ibuf->rect == NULL) {
- BKE_image_release_ibuf(ima, ibuf, NULL);
- return;
- }
-
- icon_copy_rect(ibuf, sp->sizex, sp->sizey, sp->pr_rect);
+// printf("generating deferred %d×%d preview for %s\n", sp->sizex, sp->sizey, path);
+
+ thumb = IMB_thumb_manage(path, THB_LARGE, source);
- *do_update = true;
+ if (thumb) {
+ /* PreviewImage assumes premultiplied alhpa... */
+ IMB_premultiply_alpha(thumb);
- BKE_image_release_ibuf(ima, ibuf, NULL);
+ icon_copy_rect(thumb, sp->sizex, sp->sizey, sp->pr_rect);
+ IMB_freeImBuf(thumb);
+ }
}
- else if (idtype == ID_BR) {
- Brush *br = (Brush *)id;
+ else {
+ ID *id = sp->id;
+ short idtype = GS(id->name);
+
+ if (idtype == ID_IM) {
+ Image *ima = (Image *)id;
+ ImBuf *ibuf = NULL;
+ ImageUser iuser = {NULL};
+
+ /* ima->ok is zero when Image cannot load */
+ if (ima == NULL || ima->ok == 0)
+ return;
+
+ /* setup dummy image user */
+ iuser.ok = iuser.framenr = 1;
+ iuser.scene = sp->scene;
+
+ /* elubie: this needs to be changed: here image is always loaded if not
+ * already there. Very expensive for large images. Need to find a way to
+ * only get existing ibuf */
+ ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL);
+ if (ibuf == NULL || ibuf->rect == NULL) {
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ return;
+ }
- br->icon_imbuf = get_brush_icon(br);
+ icon_copy_rect(ibuf, sp->sizex, sp->sizey, sp->pr_rect);
- memset(sp->pr_rect, 0x88, sp->sizex * sp->sizey * sizeof(unsigned int));
+ *do_update = true;
- if (!(br->icon_imbuf) || !(br->icon_imbuf->rect))
- return;
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ }
+ else if (idtype == ID_BR) {
+ Brush *br = (Brush *)id;
- icon_copy_rect(br->icon_imbuf, sp->sizex, sp->sizey, sp->pr_rect);
+ br->icon_imbuf = get_brush_icon(br);
- *do_update = true;
- }
- else {
- /* re-use shader job */
- shader_preview_startjob(customdata, stop, do_update);
+ memset(sp->pr_rect, 0x88, sp->sizex * sp->sizey * sizeof(unsigned int));
+
+ if (!(br->icon_imbuf) || !(br->icon_imbuf->rect))
+ return;
- /* world is rendered with alpha=0, so it wasn't displayed
- * this could be render option for sky to, for later */
- if (idtype == ID_WO) {
- set_alpha((char *)sp->pr_rect, sp->sizex, sp->sizey, 255);
+ icon_copy_rect(br->icon_imbuf, sp->sizex, sp->sizey, sp->pr_rect);
+
+ *do_update = true;
}
- else if (idtype == ID_MA) {
- Material *ma = (Material *)id;
+ else {
+ /* re-use shader job */
+ shader_preview_startjob(customdata, stop, do_update);
- if (ma->material_type == MA_TYPE_HALO)
+ /* world is rendered with alpha=0, so it wasn't displayed
+ * this could be render option for sky to, for later */
+ if (idtype == ID_WO) {
set_alpha((char *)sp->pr_rect, sp->sizex, sp->sizey, 255);
+ }
+ else if (idtype == ID_MA) {
+ Material *ma = (Material *)id;
+
+ if (ma->material_type == MA_TYPE_HALO)
+ set_alpha((char *)sp->pr_rect, sp->sizex, sp->sizey, 255);
+ }
}
}
}
@@ -1005,7 +1027,7 @@ static void common_preview_startjob(void *customdata, short *stop, short *do_upd
{
ShaderPreview *sp = customdata;
- if (sp->pr_method == PR_ICON_RENDER)
+ if (ELEM(sp->pr_method, PR_ICON_RENDER, PR_ICON_DEFERRED))
icon_preview_startjob(customdata, stop, do_update);
else
shader_preview_startjob(customdata, stop, do_update);
@@ -1041,29 +1063,34 @@ static void icon_preview_startjob_all_sizes(void *customdata, short *stop, short
const bool use_new_shading = BKE_scene_use_new_shading_nodes(ip->scene);
while (cur_size) {
+ PreviewImage *prv = ip->owner;
ShaderPreview *sp = MEM_callocN(sizeof(ShaderPreview), "Icon ShaderPreview");
+ const bool is_render = !prv->use_deferred;
/* construct shader preview from image size and previewcustomdata */
sp->scene = ip->scene;
sp->owner = ip->owner;
sp->sizex = cur_size->sizex;
sp->sizey = cur_size->sizey;
- sp->pr_method = PR_ICON_RENDER;
+ sp->pr_method = is_render ? PR_ICON_RENDER : PR_ICON_DEFERRED;
sp->pr_rect = cur_size->rect;
sp->id = ip->id;
- if (use_new_shading) {
- /* texture icon rendering is hardcoded to use BI,
- * so don't even think of using cycle's bmain for
- * texture icons
- */
- if (GS(ip->id->name) != ID_TE)
- sp->pr_main = G_pr_main_cycles;
- else
+ if (is_render) {
+ BLI_assert(ip->id);
+ if (use_new_shading) {
+ /* texture icon rendering is hardcoded to use BI,
+ * so don't even think of using cycle's bmain for
+ * texture icons
+ */
+ if (GS(ip->id->name) != ID_TE)
+ sp->pr_main = G_pr_main_cycles;
+ else
+ sp->pr_main = G_pr_main;
+ }
+ else {
sp->pr_main = G_pr_main;
- }
- else {
- sp->pr_main = G_pr_main;
+ }
}
common_preview_startjob(sp, stop, do_update, progress);
@@ -1145,7 +1172,7 @@ void ED_preview_icon_job(const bContext *C, void *owner, ID *id, unsigned int *r
/* customdata for preview thread */
ip->scene = CTX_data_scene(C);
- ip->owner = id;
+ ip->owner = owner;
ip->id = id;
icon_preview_add_size(ip, rect, sizex, sizey);
diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c
index d3d5cb12ac8..dedcbb144aa 100644
--- a/source/blender/editors/render/render_update.c
+++ b/source/blender/editors/render/render_update.c
@@ -270,7 +270,7 @@ static void material_changed(Main *bmain, Material *ma)
int texture_draw = false;
/* icons */
- BKE_icon_changed(BKE_icon_getid(&ma->id));
+ BKE_icon_changed(BKE_icon_id_ensure(&ma->id));
/* glsl */
if (ma->gpumaterial.first)
@@ -285,7 +285,7 @@ static void material_changed(Main *bmain, Material *ma)
continue;
}
- BKE_icon_changed(BKE_icon_getid(&parent->id));
+ BKE_icon_changed(BKE_icon_id_ensure(&parent->id));
if (parent->gpumaterial.first)
GPU_material_free(&parent->gpumaterial);
@@ -325,7 +325,7 @@ static void lamp_changed(Main *bmain, Lamp *la)
Material *ma;
/* icons */
- BKE_icon_changed(BKE_icon_getid(&la->id));
+ BKE_icon_changed(BKE_icon_id_ensure(&la->id));
/* glsl */
for (ob = bmain->object.first; ob; ob = ob->id.next)
@@ -361,7 +361,7 @@ static void texture_changed(Main *bmain, Tex *tex)
bool texture_draw = false;
/* icons */
- BKE_icon_changed(BKE_icon_getid(&tex->id));
+ BKE_icon_changed(BKE_icon_id_ensure(&tex->id));
/* paint overlays */
for (scene = bmain->scene.first; scene; scene = scene->id.next)
@@ -372,7 +372,7 @@ static void texture_changed(Main *bmain, Tex *tex)
if (!material_uses_texture(ma, tex))
continue;
- BKE_icon_changed(BKE_icon_getid(&ma->id));
+ BKE_icon_changed(BKE_icon_id_ensure(&ma->id));
if (ma->gpumaterial.first)
GPU_material_free(&ma->gpumaterial);
@@ -403,7 +403,7 @@ static void texture_changed(Main *bmain, Tex *tex)
continue;
}
- BKE_icon_changed(BKE_icon_getid(&wo->id));
+ BKE_icon_changed(BKE_icon_id_ensure(&wo->id));
if (wo->gpumaterial.first)
GPU_material_free(&wo->gpumaterial);
@@ -451,7 +451,7 @@ static void world_changed(Main *bmain, World *wo)
Material *ma;
/* icons */
- BKE_icon_changed(BKE_icon_getid(&wo->id));
+ BKE_icon_changed(BKE_icon_id_ensure(&wo->id));
/* glsl */
for (ma = bmain->mat.first; ma; ma = ma->id.next)
@@ -470,7 +470,7 @@ static void image_changed(Main *bmain, Image *ima)
Tex *tex;
/* icons */
- BKE_icon_changed(BKE_icon_getid(&ima->id));
+ BKE_icon_changed(BKE_icon_id_ensure(&ima->id));
/* textures */
for (tex = bmain->tex.first; tex; tex = tex->id.next)
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index 75e6f77ba49..ddb1cec9180 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -1346,7 +1346,7 @@ static int image_replace_exec(bContext *C, wmOperator *op)
/* XXX unpackImage frees image buffers */
ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
- BKE_icon_changed(BKE_icon_getid(&sima->image->id));
+ BKE_icon_changed(BKE_icon_id_ensure(&sima->image->id));
BKE_image_signal(sima->image, &sima->iuser, IMA_SIGNAL_RELOAD);
WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, sima->image);