Fix 48831, Step I: Mismatch issues bewteen ID icon and preview system.
- icon_id from ID and PreviewImage were not guaranteed to be in sync. - PreviewImage one was not reset on file read. - Through RNA e.g., it was possible to ensure an ID icon via its preview image, which was running code designed for custom previews/icons system, instead of generating correct 'auto ID icon'.
This commit is contained in:
@@ -55,7 +55,7 @@ void BKE_icons_init(int first_dyn_id);
|
||||
/* return icon id for library object or create new icon if not found */
|
||||
int BKE_icon_id_ensure(struct ID *id);
|
||||
|
||||
int BKE_icon_preview_ensure(struct PreviewImage *preview);
|
||||
int BKE_icon_preview_ensure(struct ID *id, struct PreviewImage *preview);
|
||||
|
||||
/* retrieve icon for id */
|
||||
struct Icon *BKE_icon_get(int icon_id);
|
||||
|
||||
@@ -423,10 +423,26 @@ void BKE_icon_changed(int id)
|
||||
}
|
||||
}
|
||||
|
||||
int BKE_icon_id_ensure(struct ID *id)
|
||||
static int icon_id_ensure_create_icon(struct ID *id)
|
||||
{
|
||||
Icon *new_icon = NULL;
|
||||
|
||||
new_icon = MEM_mallocN(sizeof(Icon), __func__);
|
||||
|
||||
new_icon->obj = id;
|
||||
new_icon->type = GS(id->name);
|
||||
|
||||
/* next two lines make sure image gets created */
|
||||
new_icon->drawinfo = NULL;
|
||||
new_icon->drawinfo_free = NULL;
|
||||
|
||||
BLI_ghash_insert(gIcons, SET_INT_IN_POINTER(id->icon_id), new_icon);
|
||||
|
||||
return id->icon_id;
|
||||
}
|
||||
|
||||
int BKE_icon_id_ensure(struct ID *id)
|
||||
{
|
||||
if (!id || G.background)
|
||||
return 0;
|
||||
|
||||
@@ -440,32 +456,39 @@ int BKE_icon_id_ensure(struct ID *id)
|
||||
return 0;
|
||||
}
|
||||
|
||||
new_icon = MEM_mallocN(sizeof(Icon), __func__);
|
||||
/* Ensure we synchronize ID icon_id with its previewimage if it has one. */
|
||||
PreviewImage **p_prv = BKE_previewimg_id_get_p(id);
|
||||
if (p_prv && *p_prv) {
|
||||
BLI_assert(ELEM((*p_prv)->icon_id, 0, id->icon_id));
|
||||
(*p_prv)->icon_id = id->icon_id;
|
||||
}
|
||||
|
||||
new_icon->obj = id;
|
||||
new_icon->type = GS(id->name);
|
||||
|
||||
/* next two lines make sure image gets created */
|
||||
new_icon->drawinfo = NULL;
|
||||
new_icon->drawinfo_free = NULL;
|
||||
|
||||
BLI_ghash_insert(gIcons, SET_INT_IN_POINTER(id->icon_id), new_icon);
|
||||
|
||||
return id->icon_id;
|
||||
return icon_id_ensure_create_icon(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return icon id of given preview, or create new icon if not found.
|
||||
*/
|
||||
int BKE_icon_preview_ensure(PreviewImage *preview)
|
||||
int BKE_icon_preview_ensure(ID *id, PreviewImage *preview)
|
||||
{
|
||||
Icon *new_icon = NULL;
|
||||
|
||||
if (!preview || G.background)
|
||||
return 0;
|
||||
|
||||
if (preview->icon_id)
|
||||
if (id) {
|
||||
BLI_assert(BKE_previewimg_id_ensure(id) == preview);
|
||||
}
|
||||
|
||||
if (preview->icon_id) {
|
||||
BLI_assert(!id || !id->icon_id || id->icon_id == preview->icon_id);
|
||||
return preview->icon_id;
|
||||
}
|
||||
|
||||
if (id && id->icon_id) {
|
||||
preview->icon_id = id->icon_id;
|
||||
return preview->icon_id;
|
||||
}
|
||||
|
||||
preview->icon_id = get_next_free_id();
|
||||
|
||||
@@ -474,6 +497,12 @@ int BKE_icon_preview_ensure(PreviewImage *preview)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Ensure we synchronize ID icon_id with its previewimage if available, and generate suitable 'ID' icon. */
|
||||
if (id) {
|
||||
id->icon_id = preview->icon_id;
|
||||
return icon_id_ensure_create_icon(id);
|
||||
}
|
||||
|
||||
new_icon = MEM_mallocN(sizeof(Icon), __func__);
|
||||
|
||||
new_icon->obj = preview;
|
||||
|
||||
@@ -2144,6 +2144,7 @@ static PreviewImage *direct_link_preview_image(FileData *fd, PreviewImage *old_p
|
||||
}
|
||||
prv->gputexture[i] = NULL;
|
||||
}
|
||||
prv->icon_id = 0;
|
||||
}
|
||||
|
||||
return prv;
|
||||
|
||||
@@ -698,7 +698,7 @@ static void rna_ImagePreview_icon_pixels_float_set(PointerRNA *ptr, const float
|
||||
static int rna_ImagePreview_icon_id_get(PointerRNA *ptr)
|
||||
{
|
||||
/* Using a callback here allows us to only generate icon matching that preview when icon_id is requested. */
|
||||
return BKE_icon_preview_ensure((PreviewImage *)(ptr->data));
|
||||
return BKE_icon_preview_ensure(ptr->id.data, (PreviewImage *)(ptr->data));
|
||||
}
|
||||
static void rna_ImagePreview_icon_reload(PreviewImage *prv)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user