diff options
Diffstat (limited to 'source/blender/editors')
-rw-r--r-- | source/blender/editors/include/ED_render.h | 10 | ||||
-rw-r--r-- | source/blender/editors/include/UI_interface_icons.h | 2 | ||||
-rw-r--r-- | source/blender/editors/interface/interface.c | 41 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_icons.c | 151 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_intern.h | 3 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_templates.c | 14 | ||||
-rw-r--r-- | source/blender/editors/render/render_preview.c | 149 | ||||
-rw-r--r-- | source/blender/editors/render/render_update.c | 16 | ||||
-rw-r--r-- | source/blender/editors/space_image/image_ops.c | 2 |
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); |