Let UI do lazy-loading of previews, rather than file-list cache
This is an important step to decouple the asset-views from the file browser backend. One downside is that the UI preview loading is much slower than the file browser one, however, I'm pretty sure I know how to address this.
This commit is contained in:
parent
ef58467594
commit
39eab45c8e
|
@ -27,7 +27,6 @@ const char *ED_asset_handle_get_identifier(const struct AssetHandle *asset);
|
|||
struct AssetMetaData *ED_asset_handle_get_metadata(const struct AssetHandle *asset);
|
||||
struct ID *ED_asset_handle_get_local_id(const struct AssetHandle *asset);
|
||||
ID_Type ED_asset_handle_get_id_type(const struct AssetHandle *asset);
|
||||
int ED_asset_handle_get_preview_icon_id(const struct AssetHandle *asset);
|
||||
void ED_asset_handle_get_full_library_path(const struct bContext *C,
|
||||
const struct AssetLibraryReference *asset_library_ref,
|
||||
const struct AssetHandle *asset,
|
||||
|
|
|
@ -51,6 +51,10 @@ void ED_assetlist_storage_id_remap(struct ID *id_old, struct ID *id_new);
|
|||
*/
|
||||
void ED_assetlist_storage_exit(void);
|
||||
|
||||
struct PreviewImage *ED_assetlist_asset_preview_request(
|
||||
const struct AssetLibraryReference *library_reference, AssetHandle *asset_handle);
|
||||
int ED_assetlist_asset_preview_icon_id_request(const AssetLibraryReference *library_reference,
|
||||
AssetHandle *asset_handle);
|
||||
struct ImBuf *ED_assetlist_asset_image_get(const AssetHandle *asset_handle);
|
||||
const char *ED_assetlist_library_path(const struct AssetLibraryReference *library_reference);
|
||||
|
||||
|
|
|
@ -38,11 +38,6 @@ ID_Type ED_asset_handle_get_id_type(const AssetHandle *asset)
|
|||
return static_cast<ID_Type>(asset->file_data->blentype);
|
||||
}
|
||||
|
||||
int ED_asset_handle_get_preview_icon_id(const AssetHandle *asset)
|
||||
{
|
||||
return asset->file_data->preview_icon_id;
|
||||
}
|
||||
|
||||
void ED_asset_handle_get_full_library_path(const bContext *C,
|
||||
const AssetLibraryReference *asset_library_ref,
|
||||
const AssetHandle *asset,
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include "DNA_space_types.h"
|
||||
|
||||
#include "BKE_icons.h"
|
||||
#include "BKE_preferences.h"
|
||||
|
||||
#include "ED_fileselect.h"
|
||||
|
@ -99,8 +100,10 @@ class PreviewTimer {
|
|||
|
||||
class AssetList : NonCopyable {
|
||||
FileListWrapper filelist_;
|
||||
/** Storage for asset handles, items are lazy-created on request. */
|
||||
mutable Map<const FileDirEntry *, AssetHandle> asset_handle_map_;
|
||||
/** Storage for asset handles, items are lazy-created on request.
|
||||
* Asset handles are stored as a pointer here, to ensure a consistent memory address (address
|
||||
* inside the map changes as the map changes). */
|
||||
mutable Map<const FileDirEntry *, std::unique_ptr<AssetHandle>> asset_handle_map_;
|
||||
AssetLibraryReference library_ref_;
|
||||
PreviewTimer previews_timer_;
|
||||
|
||||
|
@ -207,7 +210,8 @@ bool AssetList::needsRefetch() const
|
|||
|
||||
AssetHandle &AssetList::asset_handle_from_file(const FileDirEntry &file) const
|
||||
{
|
||||
return asset_handle_map_.lookup_or_add(&file, AssetHandle{&file});
|
||||
return *asset_handle_map_.lookup_or_add(&file,
|
||||
std::make_unique<AssetHandle>(AssetHandle{&file}));
|
||||
}
|
||||
|
||||
void AssetList::iterate(AssetListIterFn fn) const
|
||||
|
@ -529,6 +533,37 @@ std::string ED_assetlist_asset_filepath_get(const bContext *C,
|
|||
return path;
|
||||
}
|
||||
|
||||
PreviewImage *ED_assetlist_asset_preview_request(const AssetLibraryReference *library_reference,
|
||||
AssetHandle *asset_handle)
|
||||
{
|
||||
if (asset_handle->preview) {
|
||||
return asset_handle->preview;
|
||||
}
|
||||
|
||||
if (ID *local_id = ED_asset_handle_get_local_id(asset_handle)) {
|
||||
asset_handle->preview = BKE_previewimg_id_get(local_id);
|
||||
}
|
||||
else {
|
||||
const char *asset_identifier = ED_asset_handle_get_identifier(asset_handle);
|
||||
const int source = filelist_preview_source_get(asset_handle->file_data->typeflag);
|
||||
const std::string asset_path = ED_assetlist_asset_filepath_get(
|
||||
nullptr, *library_reference, *asset_handle);
|
||||
|
||||
asset_handle->preview = BKE_previewimg_cached_thumbnail_read(
|
||||
asset_identifier, asset_path.c_str(), source, false);
|
||||
}
|
||||
|
||||
return asset_handle->preview;
|
||||
}
|
||||
|
||||
int ED_assetlist_asset_preview_icon_id_request(const AssetLibraryReference *library_reference,
|
||||
AssetHandle *asset_handle)
|
||||
{
|
||||
PreviewImage *preview = ED_assetlist_asset_preview_request(library_reference, asset_handle);
|
||||
ID *local_id = ED_asset_handle_get_local_id(asset_handle);
|
||||
return BKE_icon_preview_ensure(local_id, preview);
|
||||
}
|
||||
|
||||
ImBuf *ED_assetlist_asset_image_get(const AssetHandle *asset_handle)
|
||||
{
|
||||
ImBuf *imbuf = filelist_file_getimage(asset_handle->file_data);
|
||||
|
|
|
@ -459,21 +459,21 @@ void PreviewGridItem::build_grid_tile(uiLayout &layout) const
|
|||
{
|
||||
const GridViewStyle &style = get_view().get_style();
|
||||
uiBlock *block = uiLayoutGetBlock(&layout);
|
||||
uiBut *but = uiDefIconTextBut(block,
|
||||
UI_BTYPE_PREVIEW_TILE,
|
||||
0,
|
||||
preview_icon_id,
|
||||
label_.c_str(),
|
||||
0,
|
||||
0,
|
||||
style.tile_width,
|
||||
style.tile_height,
|
||||
nullptr,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
"");
|
||||
|
||||
uiBut *but = uiDefBut(block,
|
||||
UI_BTYPE_PREVIEW_TILE,
|
||||
0,
|
||||
label_.c_str(),
|
||||
0,
|
||||
0,
|
||||
style.tile_width,
|
||||
style.tile_height,
|
||||
nullptr,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
"");
|
||||
ui_def_but_icon(but,
|
||||
preview_icon_id,
|
||||
/* NOLINTNEXTLINE: bugprone-suspicious-enum-usage */
|
||||
|
|
|
@ -53,14 +53,15 @@ static void asset_view_item_but_drag_set(uiBut *but,
|
|||
|
||||
if (blend_path[0]) {
|
||||
ImBuf *imbuf = ED_assetlist_asset_image_get(asset_handle);
|
||||
UI_but_drag_set_asset(but,
|
||||
asset_handle,
|
||||
BLI_strdup(blend_path),
|
||||
ED_asset_handle_get_metadata(asset_handle),
|
||||
FILE_ASSET_IMPORT_APPEND,
|
||||
ED_asset_handle_get_preview_icon_id(asset_handle),
|
||||
imbuf,
|
||||
1.0f);
|
||||
UI_but_drag_set_asset(
|
||||
but,
|
||||
asset_handle,
|
||||
BLI_strdup(blend_path),
|
||||
ED_asset_handle_get_metadata(asset_handle),
|
||||
FILE_ASSET_IMPORT_APPEND,
|
||||
ED_assetlist_asset_preview_icon_id_request(&list_data->asset_library_ref, asset_handle),
|
||||
imbuf,
|
||||
1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,25 +87,27 @@ static void asset_view_draw_item(uiList *ui_list,
|
|||
const bool show_names = list_data->show_names;
|
||||
const int size_x = UI_preview_tile_size_x();
|
||||
const int size_y = show_names ? UI_preview_tile_size_y() : UI_preview_tile_size_y_no_label();
|
||||
uiBut *but = uiDefIconTextBut(block,
|
||||
UI_BTYPE_PREVIEW_TILE,
|
||||
0,
|
||||
ED_asset_handle_get_preview_icon_id(asset_handle),
|
||||
show_names ? ED_asset_handle_get_name(asset_handle) : "",
|
||||
0,
|
||||
0,
|
||||
size_x,
|
||||
size_y,
|
||||
nullptr,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
"");
|
||||
ui_def_but_icon(but,
|
||||
ED_asset_handle_get_preview_icon_id(asset_handle),
|
||||
/* NOLINTNEXTLINE: bugprone-suspicious-enum-usage */
|
||||
UI_HAS_ICON | UI_BUT_ICON_PREVIEW);
|
||||
uiBut *but = uiDefIconTextBut(
|
||||
block,
|
||||
UI_BTYPE_PREVIEW_TILE,
|
||||
0,
|
||||
ED_assetlist_asset_preview_icon_id_request(&list_data->asset_library_ref, asset_handle),
|
||||
show_names ? ED_asset_handle_get_name(asset_handle) : "",
|
||||
0,
|
||||
0,
|
||||
size_x,
|
||||
size_y,
|
||||
nullptr,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
"");
|
||||
ui_def_but_icon(
|
||||
but,
|
||||
ED_assetlist_asset_preview_icon_id_request(&list_data->asset_library_ref, asset_handle),
|
||||
/* NOLINTNEXTLINE: bugprone-suspicious-enum-usage */
|
||||
UI_HAS_ICON | UI_BUT_ICON_PREVIEW);
|
||||
if (!ui_list->dyn_data->custom_drag_optype) {
|
||||
asset_view_item_but_drag_set(but, list_data, asset_handle);
|
||||
}
|
||||
|
|
|
@ -19,8 +19,6 @@
|
|||
*/
|
||||
#include "BKE_context.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "DNA_asset_types.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
|
@ -52,7 +50,7 @@ void AssetGridView::build_items()
|
|||
{
|
||||
int idx = 0;
|
||||
ED_assetlist_iterate(asset_library_ref_, [this, &idx](AssetHandle &asset) {
|
||||
AssetGridViewItem &item = add_item<AssetGridViewItem>(asset);
|
||||
AssetGridViewItem &item = add_item<AssetGridViewItem>(asset_library_ref_, asset);
|
||||
|
||||
item.set_is_active_fn([this, idx]() -> bool {
|
||||
return idx == RNA_property_int_get(&active_asset_idx_owner_, &active_asset_idx_prop_);
|
||||
|
@ -74,18 +72,19 @@ bool AssetGridView::listen(const wmNotifier ¬ifier) const
|
|||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
AssetGridViewItem::AssetGridViewItem(AssetHandle &asset)
|
||||
AssetGridViewItem::AssetGridViewItem(const AssetLibraryReference &asset_library_ref,
|
||||
AssetHandle &asset)
|
||||
: ui::PreviewGridItem(ED_asset_handle_get_name(&asset),
|
||||
ED_asset_handle_get_preview_icon_id(&asset)),
|
||||
asset_(asset),
|
||||
asset_identifier(ED_asset_handle_get_identifier(&asset))
|
||||
ED_assetlist_asset_preview_icon_id_request(&asset_library_ref, &asset)),
|
||||
asset_(asset)
|
||||
{
|
||||
}
|
||||
|
||||
bool AssetGridViewItem::matches(const ui::AbstractGridViewItem &other) const
|
||||
{
|
||||
const AssetGridViewItem &other_item = dynamic_cast<const AssetGridViewItem &>(other);
|
||||
return StringRef(asset_identifier) == StringRef(other_item.asset_identifier);
|
||||
return StringRef(ED_asset_handle_get_identifier(&asset_)) ==
|
||||
StringRef(ED_asset_handle_get_identifier(&other_item.asset_));
|
||||
}
|
||||
|
||||
AssetHandle &AssetGridViewItem::get_asset()
|
||||
|
|
|
@ -54,10 +54,9 @@ class AssetGridView : public blender::ui::AbstractGridView {
|
|||
|
||||
class AssetGridViewItem : public ui::PreviewGridItem {
|
||||
AssetHandle &asset_;
|
||||
std::string asset_identifier;
|
||||
|
||||
public:
|
||||
AssetGridViewItem(AssetHandle &);
|
||||
AssetGridViewItem(const AssetLibraryReference &asset_library_ref, AssetHandle &);
|
||||
|
||||
bool matches(const AbstractGridViewItem &other) const override;
|
||||
|
||||
|
|
|
@ -1159,10 +1159,9 @@ void filelist_setindexer(FileList *filelist, const FileIndexerType *indexer)
|
|||
filelist->indexer = indexer;
|
||||
}
|
||||
|
||||
void filelist_set_asset_catalog_filter_options(
|
||||
FileList *filelist,
|
||||
AssetCatalogFilterMode catalog_visibility,
|
||||
const bUUID *catalog_id)
|
||||
void filelist_set_asset_catalog_filter_options(FileList *filelist,
|
||||
AssetCatalogFilterMode catalog_visibility,
|
||||
const bUUID *catalog_id)
|
||||
{
|
||||
if (!filelist->filter_data.asset_catalog_filter) {
|
||||
/* There's no filter data yet. */
|
||||
|
@ -1594,34 +1593,37 @@ static int filelist_intern_free_main_files(FileListIntern *filelist_intern)
|
|||
return removed_counter;
|
||||
}
|
||||
|
||||
int /* ThumbSource */ filelist_preview_source_get(int /* eFileSel_File_Types */ file_type)
|
||||
{
|
||||
if (file_type & FILE_TYPE_IMAGE) {
|
||||
return THB_SOURCE_IMAGE;
|
||||
}
|
||||
else if (file_type & (FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP | FILE_TYPE_BLENDERLIB)) {
|
||||
return THB_SOURCE_BLEND;
|
||||
}
|
||||
else if (file_type & FILE_TYPE_MOVIE) {
|
||||
return THB_SOURCE_MOVIE;
|
||||
}
|
||||
else if (file_type & FILE_TYPE_FTFONT) {
|
||||
return THB_SOURCE_FONT;
|
||||
}
|
||||
else {
|
||||
BLI_assert_unreachable();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void filelist_cache_preview_runf(TaskPool *__restrict pool, void *taskdata)
|
||||
{
|
||||
FileListEntryCache *cache = BLI_task_pool_user_data(pool);
|
||||
FileListEntryPreviewTaskData *preview_taskdata = taskdata;
|
||||
FileListEntryPreview *preview = preview_taskdata->preview;
|
||||
|
||||
ThumbSource source = 0;
|
||||
ThumbSource source = filelist_preview_source_get(preview->flags);
|
||||
|
||||
// printf("%s: Start (%d)...\n", __func__, threadid);
|
||||
|
||||
// printf("%s: %d - %s - %p\n", __func__, preview->index, preview->path, preview->img);
|
||||
BLI_assert(preview->flags &
|
||||
(FILE_TYPE_IMAGE | FILE_TYPE_MOVIE | FILE_TYPE_FTFONT | FILE_TYPE_BLENDER |
|
||||
FILE_TYPE_BLENDER_BACKUP | FILE_TYPE_BLENDERLIB));
|
||||
|
||||
if (preview->flags & FILE_TYPE_IMAGE) {
|
||||
source = THB_SOURCE_IMAGE;
|
||||
}
|
||||
else if (preview->flags &
|
||||
(FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP | FILE_TYPE_BLENDERLIB)) {
|
||||
source = THB_SOURCE_BLEND;
|
||||
}
|
||||
else if (preview->flags & FILE_TYPE_MOVIE) {
|
||||
source = THB_SOURCE_MOVIE;
|
||||
}
|
||||
else if (preview->flags & FILE_TYPE_FTFONT) {
|
||||
source = THB_SOURCE_FONT;
|
||||
}
|
||||
|
||||
IMB_thumb_path_lock(preview->path);
|
||||
/* Always generate biggest preview size for now, it's simpler and avoids having to re-generate
|
||||
|
|
|
@ -68,10 +68,9 @@ void filelist_setindexer(struct FileList *filelist, const struct FileIndexerType
|
|||
* \param catalog_id: The catalog that should be filtered by if \a catalog_visibility is
|
||||
* #ASSET_CATALOG_SHOW_ASSETS_FROM_CATALOG. May be NULL otherwise.
|
||||
*/
|
||||
void filelist_set_asset_catalog_filter_options(
|
||||
struct FileList *filelist,
|
||||
AssetCatalogFilterMode catalog_visibility,
|
||||
const struct bUUID *catalog_id);
|
||||
void filelist_set_asset_catalog_filter_options(struct FileList *filelist,
|
||||
AssetCatalogFilterMode catalog_visibility,
|
||||
const struct bUUID *catalog_id);
|
||||
void filelist_tag_needs_filtering(struct FileList *filelist);
|
||||
void filelist_filter(struct FileList *filelist);
|
||||
/**
|
||||
|
@ -87,6 +86,7 @@ struct ImBuf *filelist_file_getimage(const FileDirEntry *file);
|
|||
struct ImBuf *filelist_geticon_image_ex(const FileDirEntry *file);
|
||||
struct ImBuf *filelist_geticon_image(struct FileList *filelist, int index);
|
||||
int filelist_geticon(struct FileList *filelist, int index, bool is_main);
|
||||
int /* ThumbSource */ filelist_preview_source_get(int /* eFileSel_File_Types */ file_type);
|
||||
|
||||
struct FileList *filelist_new(short type);
|
||||
void filelist_settype(struct FileList *filelist, short type);
|
||||
|
|
|
@ -122,6 +122,7 @@ typedef struct AssetLibraryReference {
|
|||
#
|
||||
typedef struct AssetHandle {
|
||||
const struct FileDirEntry *file_data;
|
||||
struct PreviewImage *preview;
|
||||
} AssetHandle;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
Loading…
Reference in New Issue