UI: Don't re-query invalid preview images from disk

Loading a custom preview/icon from disk can fail, e.g. if the image file
is corrupted. This was never handled that well, and I think since
315e7e04a8 we'd continuously re-query such previews.

Fixes #133617.
Also needed for #131871.

Pull Request: https://projects.blender.org/blender/blender/pulls/133679
This commit is contained in:
Julian Eisel
2025-01-28 19:32:54 +01:00
committed by Julian Eisel
parent 5a0aa0a422
commit 9d83061ed4
5 changed files with 23 additions and 1 deletions

View File

@@ -118,6 +118,11 @@ ImBuf *BKE_previewimg_to_imbuf(const PreviewImage *prv, int size);
void BKE_previewimg_finish(PreviewImage *prv, int size);
bool BKE_previewimg_is_finished(const PreviewImage *prv, int size);
/**
* Deferred preview images may fail to load, e.g. because the image couldn't be found on disk.
* \return true of a deferred preview image could not be loaded.
*/
bool BKE_previewimg_is_invalid(const PreviewImage *prv);
PreviewImage *BKE_previewimg_cached_get(const char *name);

View File

@@ -460,6 +460,11 @@ bool BKE_previewimg_is_finished(const PreviewImage *prv, const int size)
return (prv->flag[size] & PRV_RENDERING) == 0;
}
bool BKE_previewimg_is_invalid(const PreviewImage *prv)
{
return (prv->runtime->tag & PRV_TAG_DEFFERED_INVALID) != 0;
}
void BKE_previewimg_blend_write(BlendWriter *writer, const PreviewImage *prv)
{
/* Note we write previews also for undo steps. It takes up some memory,

View File

@@ -1656,7 +1656,7 @@ static void ui_id_preview_image_render_size(
const bContext *C, Scene *scene, ID *id, PreviewImage *pi, int size, const bool use_job)
{
/* changed only ever set by dynamic icons */
if ((pi->flag[size] & PRV_CHANGED) || !pi->rect[size]) {
if ((pi->flag[size] & PRV_CHANGED) || (!pi->rect[size] && !BKE_previewimg_is_invalid(pi))) {
/* create the rect if necessary */
icon_set_image(C, scene, id, pi, eIconSizes(size), use_job);

View File

@@ -1727,7 +1727,11 @@ class PreviewLoadJob {
PreviewImage *preview;
/** Requested size. */
eIconSizes icon_size;
/** Set to true by if the request was fully handled. */
std::atomic<bool> done = false;
/** Set to true if the request was handled but didn't result in a valid preview.
* #PRV_TAG_DEFFERED_INVALID will be set in response. */
std::atomic<bool> failure = false;
RequestedPreview(PreviewImage *preview, eIconSizes icon_size)
: preview(preview), icon_size(icon_size)
@@ -1855,6 +1859,9 @@ void PreviewLoadJob::run_fn(void *customdata, wmJobWorkerStatus *worker_status)
}
IMB_freeImBuf(thumb);
}
else {
request->failure = true;
}
request->done = true;
worker_status->do_update = true;
@@ -1869,6 +1876,9 @@ void PreviewLoadJob::finish_request(RequestedPreview &request)
PreviewImage *preview = request.preview;
preview->runtime->tag &= ~PRV_TAG_DEFFERED_RENDERING;
if (request.failure) {
preview->runtime->tag |= PRV_TAG_DEFFERED_INVALID;
}
BKE_previewimg_finish(preview, request.icon_size);
BLI_assert_msg(BLI_thread_is_main(),

View File

@@ -592,6 +592,8 @@ enum {
PRV_TAG_DEFFERED_RENDERING = (1 << 1),
/** Deferred preview should be deleted asap. */
PRV_TAG_DEFFERED_DELETE = (1 << 2),
/** This deferred preview could not be loaded (e.g. not found on disk). */
PRV_TAG_DEFFERED_INVALID = (1 << 3),
};
/**