Fix T49829: Removal of custom icon previews during add-on unregister crashes Blender.

Issue was happening when removal of custom icons was done while they
were still being rendered by preview job.

Now add a 'deffered deletion' system, to prevent main thread to delete
preview image until loading thread is done with them.

Note that ideally, calling `ED_preview_kill_jobs()` on custom icon
removal would have been simpler, but we don't have easy access to
context here...
This commit is contained in:
2016-10-27 09:51:10 +02:00
parent f11298692b
commit 5f0933f07a
6 changed files with 54 additions and 14 deletions

View File

@@ -143,7 +143,7 @@ static PreviewImage *previewimg_create_ex(size_t deferred_data_size)
memset(prv_img, 0, sizeof(*prv_img)); /* leave deferred data dirty */
if (deferred_data_size) {
prv_img->use_deferred = true;
prv_img->tag |= PRV_TAG_DEFFERED;
}
for (i = 0; i < NUM_ICON_SIZES; ++i) {
@@ -355,11 +355,14 @@ PreviewImage *BKE_previewimg_cached_thumbnail_read(
return prv;
}
void BKE_previewimg_cached_release(const char *name)
void BKE_previewimg_cached_release_pointer(PreviewImage *prv)
{
PreviewImage *prv = BLI_ghash_popkey(gCachedPreviews, name, MEM_freeN);
if (prv) {
if (prv->tag & PRV_TAG_DEFFERED_RENDERING) {
/* We cannot delete the preview while it is being loaded in another thread... */
prv->tag |= PRV_TAG_DEFFERED_DELETE;
return;
}
if (prv->icon_id) {
BKE_icon_delete(prv->icon_id);
}
@@ -367,11 +370,18 @@ void BKE_previewimg_cached_release(const char *name)
}
}
void BKE_previewimg_cached_release(const char *name)
{
PreviewImage *prv = BLI_ghash_popkey(gCachedPreviews, name, MEM_freeN);
BKE_previewimg_cached_release_pointer(prv);
}
/** Handle deferred (lazy) loading/generation of preview image, if needed.
* For now, only used with file thumbnails. */
void BKE_previewimg_ensure(PreviewImage *prv, const int size)
{
if (prv->use_deferred) {
if ((prv->tag & PRV_TAG_DEFFERED) != 0) {
const bool do_icon = ((size == ICON_SIZE_ICON) && !prv->rect[ICON_SIZE_ICON]);
const bool do_preview = ((size == ICON_SIZE_PREVIEW) && !prv->rect[ICON_SIZE_PREVIEW]);