Fix #25649: Image editor paint icon missing until enter weight paint
Issue was caused by starting Icon Preview render job from two places: - Texture buttons for small icon preview - Properties panel in image editor for large icon of texture This preview job is starting in suspended mode and if new instance of the same job is starting, suspended job will be totally stopped. This is normally for cases when you're changing different settings -- in this case you'd wouldn't want re-render be triggered on every slide change. But what we've have with brush preview is that two instances of this job were creating for large and small icon separately, but because of described policy only one icon was rendered. If suspended job is getting to be stopped, check if it was started for the same icon resolution and if not, that resolution will be also rendered in new job. So it'll be still minimal re-rendering happens, but in cases when job was started from two places for different icon sizes it'll work just fine.
This commit is contained in:
@@ -1013,21 +1013,26 @@ static void icon_draw_size(float x, float y, int icon_id, float aspect, float al
|
||||
}
|
||||
}
|
||||
|
||||
static void ui_id_preview_image_render_size(bContext *C, ID *id, PreviewImage *pi, int size)
|
||||
{
|
||||
if ((pi->changed[size] ||!pi->rect[size])) /* changed only ever set by dynamic icons */
|
||||
{
|
||||
/* create the rect if necessary */
|
||||
icon_set_image(C, id, pi, size);
|
||||
|
||||
pi->changed[size] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void ui_id_icon_render(bContext *C, ID *id, int big)
|
||||
{
|
||||
PreviewImage *pi = BKE_previewimg_get(id);
|
||||
|
||||
if (pi) {
|
||||
if ((pi->changed[0] ||!pi->rect[0])) /* changed only ever set by dynamic icons */
|
||||
{
|
||||
/* create the rect if necessary */
|
||||
|
||||
icon_set_image(C, id, pi, ICON_SIZE_ICON); /* icon size */
|
||||
if (big)
|
||||
icon_set_image(C, id, pi, ICON_SIZE_PREVIEW); /* bigger preview size */
|
||||
|
||||
pi->changed[0] = 0;
|
||||
}
|
||||
PreviewImage *pi = BKE_previewimg_get(id);
|
||||
|
||||
if (pi) {
|
||||
if (big)
|
||||
ui_id_preview_image_render_size(C, id, pi, ICON_SIZE_PREVIEW); /* bigger preview size */
|
||||
else
|
||||
ui_id_preview_image_render_size(C, id, pi, ICON_SIZE_ICON); /* icon size */
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1281,7 +1281,7 @@ static void rna_search_cb(const struct bContext *C, void *arg_but, const char *s
|
||||
BLI_strncpy(name_ui, id->name+2, sizeof(name_ui));
|
||||
#endif
|
||||
name= BLI_strdup(name_ui);
|
||||
iconid= ui_id_icon_get((bContext*)C, id, 1);
|
||||
iconid= ui_id_icon_get((bContext*)C, id, 0);
|
||||
}
|
||||
else {
|
||||
name= RNA_struct_name_get_alloc(&itemptr, NULL, 0, NULL); /* could use the string length here */
|
||||
|
@@ -96,6 +96,7 @@ typedef struct TemplateID {
|
||||
|
||||
ListBase *idlb;
|
||||
int prv_rows, prv_cols;
|
||||
int preview;
|
||||
} TemplateID;
|
||||
|
||||
/* Search browse menu, assign */
|
||||
@@ -143,7 +144,7 @@ static void id_search_cb(const bContext *C, void *arg_template, const char *str,
|
||||
char name_ui[MAX_ID_NAME];
|
||||
name_uiprefix_id(name_ui, id);
|
||||
|
||||
iconid= ui_id_icon_get((bContext*)C, id, 1);
|
||||
iconid= ui_id_icon_get((bContext*)C, id, template->preview);
|
||||
|
||||
if(!uiSearchItemAdd(items, name_ui, id, iconid))
|
||||
break;
|
||||
@@ -370,6 +371,7 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str
|
||||
uiButSetFlag(but, UI_BUT_DISABLED);
|
||||
|
||||
uiLayoutRow(layout, 1);
|
||||
template->preview= 1;
|
||||
}
|
||||
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,
|
||||
|
@@ -164,6 +164,19 @@ typedef struct ShaderPreview {
|
||||
|
||||
} ShaderPreview;
|
||||
|
||||
typedef struct IconPreviewSize {
|
||||
struct IconPreviewSize *next, *prev;
|
||||
int sizex, sizey;
|
||||
unsigned int *rect;
|
||||
} IconPreviewSize;
|
||||
|
||||
typedef struct IconPreview {
|
||||
Scene *scene;
|
||||
void *owner;
|
||||
ID *id;
|
||||
ListBase sizes;
|
||||
} IconPreview;
|
||||
|
||||
/* *************************** Preview for buttons *********************** */
|
||||
|
||||
static Main *pr_main= NULL;
|
||||
@@ -944,38 +957,96 @@ static void common_preview_startjob(void *customdata, short *stop, short *do_upd
|
||||
shader_preview_startjob(customdata, stop, do_update);
|
||||
}
|
||||
|
||||
static void common_preview_endjob(void *customdata)
|
||||
{
|
||||
ShaderPreview *sp= customdata;
|
||||
/* exported functions */
|
||||
|
||||
if(sp->id && GS(sp->id->name) == ID_BR)
|
||||
WM_main_add_notifier(NC_BRUSH|NA_EDITED, sp->id);
|
||||
static void icon_preview_add_size(IconPreview *ip, unsigned int *rect, int sizex, int sizey)
|
||||
{
|
||||
IconPreviewSize *cur_size = ip->sizes.first, *new_size;
|
||||
|
||||
while (cur_size) {
|
||||
if (cur_size->sizex == sizex && cur_size->sizey == sizey) {
|
||||
/* requested size is already in list, no need to add it again */
|
||||
return;
|
||||
}
|
||||
|
||||
cur_size = cur_size->next;
|
||||
}
|
||||
|
||||
new_size = MEM_callocN(sizeof(IconPreviewSize), "IconPreviewSize");
|
||||
new_size->sizex = sizex;
|
||||
new_size->sizey = sizey;
|
||||
new_size->rect = rect;
|
||||
|
||||
BLI_addtail(&ip->sizes, new_size);
|
||||
}
|
||||
|
||||
/* exported functions */
|
||||
static void icon_preview_startjob_all_sizes(void *customdata, short *stop, short *do_update, float *progress)
|
||||
{
|
||||
IconPreview *ip = (IconPreview *)customdata;
|
||||
IconPreviewSize *cur_size = ip->sizes.first;
|
||||
|
||||
while (cur_size) {
|
||||
ShaderPreview sp;
|
||||
|
||||
memset(&sp, 0, sizeof(ShaderPreview));
|
||||
|
||||
/* 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_rect= cur_size->rect;
|
||||
sp.id = ip->id;
|
||||
|
||||
common_preview_startjob(&sp, stop, do_update, progress);
|
||||
|
||||
cur_size = cur_size->next;
|
||||
}
|
||||
}
|
||||
|
||||
static void icon_preview_endjob(void *customdata)
|
||||
{
|
||||
IconPreview *ip = customdata;
|
||||
|
||||
if (ip->id && GS(ip->id->name) == ID_BR)
|
||||
WM_main_add_notifier(NC_BRUSH|NA_EDITED, ip->id);
|
||||
}
|
||||
|
||||
static void icon_preview_free(void *customdata)
|
||||
{
|
||||
IconPreview *ip = (IconPreview *)customdata;
|
||||
|
||||
BLI_freelistN(&ip->sizes);
|
||||
MEM_freeN(ip);
|
||||
}
|
||||
|
||||
void ED_preview_icon_job(const bContext *C, void *owner, ID *id, unsigned int *rect, int sizex, int sizey)
|
||||
{
|
||||
wmJob *steve;
|
||||
ShaderPreview *sp;
|
||||
IconPreview *ip, *old_ip;
|
||||
|
||||
/* suspended start means it starts after 1 timer step, see WM_jobs_timer below */
|
||||
steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), owner, "Icon Preview", WM_JOB_EXCL_RENDER|WM_JOB_SUSPEND);
|
||||
sp= MEM_callocN(sizeof(ShaderPreview), "shader preview");
|
||||
|
||||
ip= MEM_callocN(sizeof(IconPreview), "icon preview");
|
||||
|
||||
/* render all resolutions from suspended job too */
|
||||
old_ip= WM_jobs_get_customdata(steve);
|
||||
if (old_ip)
|
||||
BLI_movelisttolist(&ip->sizes, &old_ip->sizes);
|
||||
|
||||
/* customdata for preview thread */
|
||||
sp->scene= CTX_data_scene(C);
|
||||
sp->owner= id;
|
||||
sp->sizex= sizex;
|
||||
sp->sizey= sizey;
|
||||
sp->pr_method= PR_ICON_RENDER;
|
||||
sp->pr_rect= rect;
|
||||
sp->id = id;
|
||||
ip->scene= CTX_data_scene(C);
|
||||
ip->owner= id;
|
||||
ip->id= id;
|
||||
|
||||
icon_preview_add_size(ip, rect, sizex, sizey);
|
||||
|
||||
/* setup job */
|
||||
WM_jobs_customdata(steve, sp, shader_preview_free);
|
||||
WM_jobs_customdata(steve, ip, icon_preview_free);
|
||||
WM_jobs_timer(steve, 0.25, NC_MATERIAL, NC_MATERIAL);
|
||||
WM_jobs_callbacks(steve, common_preview_startjob, NULL, NULL, common_preview_endjob);
|
||||
WM_jobs_callbacks(steve, icon_preview_startjob_all_sizes, NULL, NULL, icon_preview_endjob);
|
||||
|
||||
WM_jobs_start(CTX_wm_manager(C), steve);
|
||||
}
|
||||
|
@@ -873,6 +873,12 @@ static void image_buttons_area_listener(ARegion *ar, wmNotifier *wmn)
|
||||
if(wmn->action==NA_EDITED)
|
||||
ED_region_tag_redraw(ar);
|
||||
break;
|
||||
case NC_TEXTURE:
|
||||
case NC_MATERIAL:
|
||||
/* sending by texture render job and needed to properly update displaying
|
||||
* brush texture icon */
|
||||
ED_region_tag_redraw(ar);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -933,6 +933,7 @@ static void view3d_buttons_area_listener(ARegion *ar, wmNotifier *wmn)
|
||||
ED_region_tag_redraw(ar);
|
||||
break;
|
||||
case NC_TEXTURE:
|
||||
case NC_MATERIAL:
|
||||
/* for brush textures */
|
||||
ED_region_tag_redraw(ar);
|
||||
break;
|
||||
|
Reference in New Issue
Block a user