diff --git a/source/blender/editors/include/ED_render.hh b/source/blender/editors/include/ED_render.hh index b0c0d9d67b6..753321eebdc 100644 --- a/source/blender/editors/include/ED_render.hh +++ b/source/blender/editors/include/ED_render.hh @@ -73,6 +73,12 @@ const char *ED_preview_collection_name(ePreviewType pr_type); void ED_preview_ensure_dbase(bool with_gpencil); void ED_preview_free_dbase(); +/** + * For preview icons loaded from disk (deferred loading), use the size of the source image, and + * only scale to the display size when drawing. Then we actually know the final display size + * (so we don't scale twice), and can scale on the GPU while drawing. + */ +bool ED_preview_use_image_size(const PreviewImage *preview, eIconSizes size); /** * Check if \a id is supported by the automatic preview render. */ diff --git a/source/blender/editors/interface/interface_icons.cc b/source/blender/editors/interface/interface_icons.cc index 3dd0bf2b22c..2294b0f9b54 100644 --- a/source/blender/editors/interface/interface_icons.cc +++ b/source/blender/editors/interface/interface_icons.cc @@ -1004,12 +1004,14 @@ static void icon_create_rect(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->flag[size] |= PRV_CHANGED; prv_img->changed_timestamp[size] = 0; - prv_img->rect[size] = static_cast( - MEM_callocN(render_size * render_size * sizeof(uint), "prv_rect")); + if (!ED_preview_use_image_size(prv_img, size)) { + prv_img->w[size] = render_size; + prv_img->h[size] = render_size; + prv_img->rect[size] = static_cast( + MEM_callocN(render_size * render_size * sizeof(uint), "prv_rect")); + } } } diff --git a/source/blender/editors/render/render_preview.cc b/source/blender/editors/render/render_preview.cc index b9d6628b08c..6a7c6d4dcb2 100644 --- a/source/blender/editors/render/render_preview.cc +++ b/source/blender/editors/render/render_preview.cc @@ -1834,13 +1834,21 @@ void PreviewLoadJob::run_fn(void *customdata, wmJobWorkerStatus *worker_status) IMB_thumb_path_unlock(filepath); if (thumb) { - /* PreviewImage assumes premultiplied alpha... */ + /* PreviewImage assumes premultiplied alpha. */ IMB_premultiply_alpha(thumb); - icon_copy_rect(thumb, - preview->w[request->icon_size], - preview->h[request->icon_size], - preview->rect[request->icon_size]); + if (ED_preview_use_image_size(preview, request->icon_size)) { + preview->w[request->icon_size] = thumb->x; + preview->h[request->icon_size] = thumb->y; + BLI_assert(preview->rect[request->icon_size] == nullptr); + preview->rect[request->icon_size] = (uint *)MEM_dupallocN(thumb->byte_buffer.data); + } + else { + icon_copy_rect(thumb, + preview->w[request->icon_size], + preview->h[request->icon_size], + preview->rect[request->icon_size]); + } IMB_freeImBuf(thumb); } @@ -1915,6 +1923,11 @@ static void icon_preview_free(void *customdata) MEM_freeN(ip); } +bool ED_preview_use_image_size(const PreviewImage *preview, eIconSizes size) +{ + return size == ICON_SIZE_PREVIEW && preview->runtime->deferred_loading_data; +} + bool ED_preview_id_is_supported(const ID *id, const char **r_disabled_hint) { if (id == nullptr) {