diff --git a/source/blender/editors/asset/ED_asset_list.hh b/source/blender/editors/asset/ED_asset_list.hh index 034d941de19..28c134afcb0 100644 --- a/source/blender/editors/asset/ED_asset_list.hh +++ b/source/blender/editors/asset/ED_asset_list.hh @@ -69,7 +69,7 @@ void iterate(const AssetLibraryReference &library_reference, AssetListIterFn fn) */ void storage_fetch(const AssetLibraryReference *library_reference, const bContext *C); bool is_loaded(const AssetLibraryReference *library_reference); -void ensure_previews_job(const AssetLibraryReference *library_reference, const bContext *C); +void previews_fetch(const AssetLibraryReference *library_reference, const bContext *C); /** * Clears this asset library and the "All" asset library for reload in both the static asset list * storage, as well as for all open asset browsers. Call this whenever the content of the given @@ -109,6 +109,9 @@ asset_system::AssetRepresentation *asset_get_by_index( bool asset_image_is_loading(const AssetLibraryReference *library_reference, const AssetHandle *asset_handle); +void asset_preview_ensure_requested(const bContext &C, + const AssetLibraryReference *library_reference, + AssetHandle *asset_handle); ImBuf *asset_image_get(const AssetHandle *asset_handle); /** diff --git a/source/blender/editors/asset/intern/asset_list.cc b/source/blender/editors/asset/intern/asset_list.cc index a247da4f089..e4eeada8bbb 100644 --- a/source/blender/editors/asset/intern/asset_list.cc +++ b/source/blender/editors/asset/intern/asset_list.cc @@ -114,14 +114,16 @@ class AssetList : NonCopyable { void setup(); void fetch(const bContext &C); - void ensure_previews_job(const bContext *C); + void update_previews(const bContext &C); void clear(const bContext *C); AssetHandle asset_get_by_index(int index) const; + void previews_job_update(const bContext *C); bool needs_refetch() const; bool is_loaded() const; bool is_asset_preview_loading(const AssetHandle &asset) const; + void ensure_asset_preview_requested(const bContext &C, AssetHandle &asset); asset_system::AssetLibrary *asset_library() const; void iterate(AssetListHandleIterFn fn, FunctionRef prefilter_fn) const; @@ -156,6 +158,7 @@ void AssetList::setup() true, "", ""); + filelist_set_no_preview_auto_cache(files); const bool use_asset_indexer = !USER_EXPERIMENTAL_TEST(&U, no_asset_indexing); filelist_setindexer(files, use_asset_indexer ? &index::file_indexer_asset : &file_indexer_noop); @@ -185,6 +188,16 @@ void AssetList::fetch(const bContext &C) filelist_filter(files); } +void AssetList::update_previews(const bContext &C) +{ + if (filelist_cache_previews_enabled(filelist_)) { + /* Get newest loaded previews from the background thread queue. */ + filelist_cache_previews_update(filelist_); + } + /* Update preview job, it might have to be stopped. */ + this->previews_job_update(&C); +} + bool AssetList::needs_refetch() const { return filelist_needs_force_reset(filelist_) || filelist_needs_reading(filelist_); @@ -195,6 +208,18 @@ bool AssetList::is_loaded() const return filelist_is_ready(filelist_); } +void AssetList::ensure_asset_preview_requested(const bContext &C, AssetHandle &asset) +{ + /* Ensure previews are enabled. */ + filelist_cache_previews_set(filelist_, true); + + if (filelist_file_ensure_preview_requested(filelist_, + const_cast(asset.file_data))) + { + previews_timer_.ensure_running(&C); + } +} + bool AssetList::is_asset_preview_loading(const AssetHandle &asset) const { return filelist_file_is_preview_pending(filelist_, asset.file_data); @@ -248,17 +273,14 @@ void AssetList::iterate(AssetListIterFn fn) const } } -void AssetList::ensure_previews_job(const bContext *C) +void AssetList::previews_job_update(const bContext *C) { FileList *files = filelist_; - int numfiles = filelist_files_ensure(files); - filelist_cache_previews_set(files, true); - /* TODO fetch all previews for now. */ - /* Add one extra entry to ensure nothing is lost because of integer division. */ - filelist_file_cache_slidingwindow_set(files, numfiles / 2 + 1); - filelist_file_cache_block(files, 0); - filelist_cache_previews_update(files); + if (!filelist_cache_previews_enabled(files)) { + previews_timer_.stop(C); + return; + } { const bool previews_running = filelist_cache_previews_running(files) && @@ -416,7 +438,7 @@ void asset_reading_region_listen_fn(const wmRegionListenerParams *params) switch (wmn->category) { case NC_ASSET: - if (wmn->data == ND_ASSET_LIST_READING) { + if (ELEM(wmn->data, ND_ASSET_LIST_READING, ND_ASSET_LIST_PREVIEW)) { ED_region_tag_refresh_ui(region); } break; @@ -453,11 +475,11 @@ bool is_loaded(const AssetLibraryReference *library_reference) return list->is_loaded(); } -void ensure_previews_job(const AssetLibraryReference *library_reference, const bContext *C) +void previews_fetch(const AssetLibraryReference *library_reference, const bContext *C) { AssetList *list = lookup_list(*library_reference); if (list) { - list->ensure_previews_job(C); + list->update_previews(*C); } } @@ -552,6 +574,14 @@ bool asset_image_is_loading(const AssetLibraryReference *library_reference, return list->is_asset_preview_loading(*asset_handle); } +void asset_preview_ensure_requested(const bContext &C, + const AssetLibraryReference *library_reference, + AssetHandle *asset_handle) +{ + AssetList *list = lookup_list(*library_reference); + list->ensure_asset_preview_requested(C, *asset_handle); +} + ImBuf *asset_image_get(const AssetHandle *asset_handle) { ImBuf *imbuf = filelist_file_getimage(asset_handle->file_data); diff --git a/source/blender/editors/asset/intern/asset_shelf_asset_view.cc b/source/blender/editors/asset/intern/asset_shelf_asset_view.cc index e1be723edc7..f91410bef67 100644 --- a/source/blender/editors/asset/intern/asset_shelf_asset_view.cc +++ b/source/blender/editors/asset/intern/asset_shelf_asset_view.cc @@ -65,7 +65,7 @@ class AssetViewItem : public ui::PreviewGridItem { int preview_icon_id); void disable_asset_drag(); - void build_grid_tile(uiLayout &layout) const override; + void build_grid_tile(const bContext &C, uiLayout &layout) const override; void build_context_menu(bContext &C, uiLayout &column) const override; std::optional should_be_active() const override; void on_activate(bContext &C) override; @@ -111,12 +111,7 @@ void AssetView::build_items() const bool show_names = (shelf_.settings.display_flag & ASSETSHELF_SHOW_NAMES); const StringRef identifier = asset->library_relative_identifier(); - const int preview_id = [&]() -> int { - if (list::asset_image_is_loading(&library_ref_, &asset_handle)) { - return ICON_TEMP; - } - return handle_get_preview_or_type_icon_id(&asset_handle); - }(); + const int preview_id = handle_get_preview_or_type_icon_id(&asset_handle); AssetViewItem &item = this->add_item( asset_handle, identifier, asset->get_name(), preview_id); @@ -220,7 +215,7 @@ static std::optional create_activate_operator_params( return wmOperatorCallParams{ot, op_props, WM_OP_INVOKE_REGION_WIN}; } -void AssetViewItem::build_grid_tile(uiLayout &layout) const +void AssetViewItem::build_grid_tile(const bContext &C, uiLayout &layout) const { const AssetView &asset_view = reinterpret_cast(this->get_view()); const AssetShelfType &shelf_type = *asset_view.shelf_.type; @@ -263,7 +258,20 @@ void AssetViewItem::build_grid_tile(uiLayout &layout) const const_cast(asset), nullptr); - ui::PreviewGridItem::build_grid_tile_button(layout); + /* Request preview when drawing. Grid views have an optimization to only draw items that are + * actually visible, so only previews scrolled into view will be loaded this way. This reduces + * total loading time and memory footprint. */ + list::asset_preview_ensure_requested( + C, &asset_view.library_ref_, const_cast(&asset_)); + + const int preview_id = [&]() -> int { + if (list::asset_image_is_loading(&asset_view.library_ref_, &asset_)) { + return ICON_TEMP; + } + return handle_get_preview_or_type_icon_id(&asset_); + }(); + + ui::PreviewGridItem::build_grid_tile_button(layout, preview_id); } void AssetViewItem::build_context_menu(bContext &C, uiLayout &column) const @@ -341,7 +349,7 @@ void build_asset_view(uiLayout &layout, const ARegion ®ion) { list::storage_fetch(&library_ref, &C); - list::ensure_previews_job(&library_ref, &C); + list::previews_fetch(&library_ref, &C); const asset_system::AssetLibrary *library = list::library_get_once_available(library_ref); if (!library) { @@ -363,7 +371,7 @@ void build_asset_view(uiLayout &layout, grid_view->set_context_menu_title("Asset Shelf"); ui::GridViewBuilder builder(*block); - builder.build_grid_view(*grid_view, region.v2d, layout, filter_string_get(shelf)); + builder.build_grid_view(C, *grid_view, region.v2d, layout, filter_string_get(shelf)); } /* ---------------------------------------------------------------------- */ diff --git a/source/blender/editors/include/UI_grid_view.hh b/source/blender/editors/include/UI_grid_view.hh index 360f3f39ef1..9112146f443 100644 --- a/source/blender/editors/include/UI_grid_view.hh +++ b/source/blender/editors/include/UI_grid_view.hh @@ -45,7 +45,7 @@ class AbstractGridViewItem : public AbstractViewItem { public: /* virtual */ ~AbstractGridViewItem() override = default; - virtual void build_grid_tile(uiLayout &layout) const = 0; + virtual void build_grid_tile(const bContext &C, uiLayout &layout) const = 0; /* virtual */ std::optional debug_name() const override; @@ -170,7 +170,8 @@ class GridViewBuilder { public: GridViewBuilder(uiBlock &block); - void build_grid_view(AbstractGridView &grid_view, + void build_grid_view(const bContext &C, + AbstractGridView &grid_view, const View2D &v2d, uiLayout &layout, std::optional search_string = {}); @@ -206,9 +207,10 @@ class PreviewGridItem : public AbstractGridViewItem { PreviewGridItem(StringRef identifier, StringRef label, int preview_icon_id); - void build_grid_tile(uiLayout &layout) const override; + void build_grid_tile(const bContext &C, uiLayout &layout) const override; - void build_grid_tile_button(uiLayout &layout) const; + void build_grid_tile_button(uiLayout &layout, + BIFIconID override_preview_icon_id = ICON_NONE) const; /** * Set a custom callback to execute when activating this view item. This way users don't have to diff --git a/source/blender/editors/interface/templates/interface_template_asset_view.cc b/source/blender/editors/interface/templates/interface_template_asset_view.cc index 623a4bf8d4e..8810ad1124a 100644 --- a/source/blender/editors/interface/templates/interface_template_asset_view.cc +++ b/source/blender/editors/interface/templates/interface_template_asset_view.cc @@ -62,7 +62,7 @@ static void asset_view_item_but_drag_set(uiBut *but, AssetHandle *asset_handle) } static void asset_view_draw_item(uiList *ui_list, - const bContext * /*C*/, + const bContext *C, uiLayout *layout, PointerRNA * /*dataptr*/, PointerRNA * /*itemptr*/, @@ -82,6 +82,8 @@ static void asset_view_draw_item(uiList *ui_list, const_cast(asset_handle.file_data)); uiLayoutSetContextPointer(layout, "active_file", &file_ptr); + asset::list::asset_preview_ensure_requested(*C, &list_data->asset_library_ref, &asset_handle); + uiBlock *block = uiLayoutGetBlock(layout); const bool show_names = list_data->show_names; const float size_x = UI_preview_tile_size_x(); @@ -252,7 +254,7 @@ void uiTemplateAssetView(uiLayout *layout, } asset::list::storage_fetch(&asset_library_ref, C); - asset::list::ensure_previews_job(&asset_library_ref, C); + asset::list::previews_fetch(&asset_library_ref, C); const int tot_items = asset::list::size(&asset_library_ref); populate_asset_collection(asset_library_ref, *assets_dataptr, assets_propname); diff --git a/source/blender/editors/interface/views/grid_view.cc b/source/blender/editors/interface/views/grid_view.cc index 28c78e60364..60aee315ddd 100644 --- a/source/blender/editors/interface/views/grid_view.cc +++ b/source/blender/editors/interface/views/grid_view.cc @@ -368,10 +368,12 @@ class GridViewLayoutBuilder { public: GridViewLayoutBuilder(uiLayout &layout); - void build_from_view(const AbstractGridView &grid_view, const View2D &v2d) const; + void build_from_view(const bContext &C, + const AbstractGridView &grid_view, + const View2D &v2d) const; private: - void build_grid_tile(uiLayout &grid_layout, AbstractGridViewItem &item) const; + void build_grid_tile(const bContext &C, uiLayout &grid_layout, AbstractGridViewItem &item) const; uiLayout *current_layout() const; }; @@ -380,17 +382,19 @@ GridViewLayoutBuilder::GridViewLayoutBuilder(uiLayout &layout) : block_(*uiLayou { } -void GridViewLayoutBuilder::build_grid_tile(uiLayout &grid_layout, +void GridViewLayoutBuilder::build_grid_tile(const bContext &C, + uiLayout &grid_layout, AbstractGridViewItem &item) const { uiLayout *overlap = uiLayoutOverlap(&grid_layout); uiLayoutSetFixedSize(overlap, true); item.add_grid_tile_button(block_); - item.build_grid_tile(*uiLayoutRow(overlap, false)); + item.build_grid_tile(C, *uiLayoutRow(overlap, false)); } -void GridViewLayoutBuilder::build_from_view(const AbstractGridView &grid_view, +void GridViewLayoutBuilder::build_from_view(const bContext &C, + const AbstractGridView &grid_view, const View2D &v2d) const { uiLayout *parent_layout = this->current_layout(); @@ -428,7 +432,7 @@ void GridViewLayoutBuilder::build_from_view(const AbstractGridView &grid_view, row = uiLayoutRow(&layout, true); } - this->build_grid_tile(*row, item); + this->build_grid_tile(C, *row, item); item_idx++; }); @@ -446,7 +450,8 @@ uiLayout *GridViewLayoutBuilder::current_layout() const GridViewBuilder::GridViewBuilder(uiBlock & /*block*/) {} -void GridViewBuilder::build_grid_view(AbstractGridView &grid_view, +void GridViewBuilder::build_grid_view(const bContext &C, + AbstractGridView &grid_view, const View2D &v2d, uiLayout &layout, std::optional search_string) @@ -462,7 +467,7 @@ void GridViewBuilder::build_grid_view(AbstractGridView &grid_view, UI_block_layout_set_current(&block, &layout); GridViewLayoutBuilder builder(layout); - builder.build_from_view(grid_view, v2d); + builder.build_from_view(C, grid_view, v2d); } /* ---------------------------------------------------------------------- */ @@ -472,7 +477,8 @@ PreviewGridItem::PreviewGridItem(StringRef identifier, StringRef label, int prev { } -void PreviewGridItem::build_grid_tile_button(uiLayout &layout) const +void PreviewGridItem::build_grid_tile_button(uiLayout &layout, + BIFIconID override_preview_icon_id) const { const GridViewStyle &style = this->get_view().get_style(); uiBlock *block = uiLayoutGetBlock(&layout); @@ -493,20 +499,21 @@ void PreviewGridItem::build_grid_tile_button(uiLayout &layout) const 0, ""); + const BIFIconID icon_id = override_preview_icon_id ? override_preview_icon_id : preview_icon_id; + /* Draw icons that are not previews or images as normal icons with a fixed icon size. Otherwise * they will be upscaled to the button size. Should probably be done by the widget code. */ - const int is_preview_flag = (BKE_icon_is_preview(preview_icon_id) || - BKE_icon_is_image(preview_icon_id)) ? + const int is_preview_flag = (BKE_icon_is_preview(icon_id) || BKE_icon_is_image(icon_id)) ? int(UI_BUT_ICON_PREVIEW) : 0; ui_def_but_icon(but, - preview_icon_id, + icon_id, /* NOLINTNEXTLINE: bugprone-suspicious-enum-usage */ UI_HAS_ICON | is_preview_flag); but->emboss = UI_EMBOSS_NONE; } -void PreviewGridItem::build_grid_tile(uiLayout &layout) const +void PreviewGridItem::build_grid_tile(const bContext & /*C*/, uiLayout &layout) const { this->build_grid_tile_button(layout); } diff --git a/source/blender/editors/space_file/filelist.cc b/source/blender/editors/space_file/filelist.cc index fdaa7a5dddb..a64831338a4 100644 --- a/source/blender/editors/space_file/filelist.cc +++ b/source/blender/editors/space_file/filelist.cc @@ -303,6 +303,12 @@ enum { FL_NEED_SORTING = 1 << 4, FL_NEED_FILTERING = 1 << 5, FL_SORT_INVERT = 1 << 6, + /** + * By default, #filelist_file_cache_block() will attempt to load previews around the visible + * "window" of visible files. When this flag is set it won't do so, and each preview has to be + * queried through a #filelist_cache_previews_push() call. + */ + FL_PREVIEWS_NO_AUTO_CACHE = 1 << 7, }; /** #FileList.tags */ @@ -353,6 +359,8 @@ static int groupname_to_code(const char *group); static void filelist_cache_clear(FileListEntryCache *cache, size_t new_size); static bool filelist_intern_entry_is_main_file(const FileListInternEntry *intern_entry); +static bool filelist_cache_previews_push(FileList *filelist, FileDirEntry *entry, const int index); +static bool filelist_file_preview_load_poll(const FileDirEntry *entry); /* ********** Sort helpers ********** */ @@ -1157,6 +1165,35 @@ bool filelist_file_is_preview_pending(const FileList *filelist, const FileDirEnt return !filelist_ready || file->flags & FILE_ENTRY_PREVIEW_LOADING; } +bool filelist_file_ensure_preview_requested(FileList *filelist, FileDirEntry *file) +{ + if (file->preview_icon_id) { + /* Already loaded. */ + return false; + } + + /* Wait with requests until file list reading is done, and previews may be loaded. */ + if (!filelist_cache_previews_enabled(filelist)) { + return false; + } + /* #filelist_cache_previews_push() will repeat this, do here already to avoid lookup below. */ + if (!filelist_file_preview_load_poll(file)) { + return false; + } + + const int numfiles = filelist_files_ensure(filelist); + for (int i = 0; i < numfiles; i++) { + if (filelist->filelist_intern.filtered[i]->uid == file->uid) { + if (filelist_cache_previews_push(filelist, file, i)) { + return true; + } + break; + } + } + + return false; +} + static FileDirEntry *filelist_geticon_get_file(FileList *filelist, const int index) { BLI_assert(G.background == false); @@ -1620,25 +1657,22 @@ static void filelist_cache_previews_free(FileListEntryCache *cache) cache->flags &= ~FLC_PREVIEWS_ACTIVE; } -static void filelist_cache_previews_push(FileList *filelist, FileDirEntry *entry, const int index) +/** + * Check if a preview for \a entry may be requested. Further conditions may apply, this just helps + * to skip plenty of entries where it's easy to tell that no valid preview will be available or is + * being loaded already. + */ +static bool filelist_file_preview_load_poll(const FileDirEntry *entry) { - FileListEntryCache *cache = &filelist->filelist_cache; - - BLI_assert(cache->flags & FLC_PREVIEWS_ACTIVE); - - if (entry->preview_icon_id) { - return; - } - if (entry->flags & (FILE_ENTRY_INVALID_PREVIEW | FILE_ENTRY_PREVIEW_LOADING)) { - return; + return false; } if (!(entry->typeflag & (FILE_TYPE_IMAGE | FILE_TYPE_MOVIE | FILE_TYPE_FTFONT | FILE_TYPE_OBJECT_IO | FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP | FILE_TYPE_BLENDERLIB))) { - return; + return false; } /* If we know this is an external ID without a preview, skip loading the preview. Can save quite @@ -1647,21 +1681,42 @@ static void filelist_cache_previews_push(FileList *filelist, FileDirEntry *entry if ((entry->typeflag & FILE_TYPE_BLENDERLIB) && (entry->flags & FILE_ENTRY_BLENDERLIB_NO_PREVIEW)) { - return; + return false; } /* External ID that is also a directory is never previewed. */ if ((entry->typeflag & (FILE_TYPE_BLENDERLIB | FILE_TYPE_DIR)) == (FILE_TYPE_BLENDERLIB | FILE_TYPE_DIR)) { - return; + return false; + } + + return true; +} + +/** + * \return True if a new preview request was pushed, false otherwise (e.g. because the preview is + * already loaded, invalid or not supported). + */ +static bool filelist_cache_previews_push(FileList *filelist, FileDirEntry *entry, const int index) +{ + FileListEntryCache *cache = &filelist->filelist_cache; + + BLI_assert(cache->flags & FLC_PREVIEWS_ACTIVE); + + if (entry->preview_icon_id) { + return false; + } + + if (!filelist_file_preview_load_poll(entry)) { + return false; } FileListInternEntry *intern_entry = filelist->filelist_intern.filtered[index]; PreviewImage *preview_in_memory = intern_entry->local_data.preview_image; if (preview_in_memory && !BKE_previewimg_is_finished(preview_in_memory, ICON_SIZE_PREVIEW)) { /* Nothing to set yet. Wait for next call. */ - return; + return false; } filelist_cache_preview_ensure_running(cache); @@ -1701,6 +1756,8 @@ static void filelist_cache_previews_push(FileList *filelist, FileDirEntry *entry filelist_cache_preview_freef); } cache->previews_todo_count++; + + return true; } static void filelist_cache_init(FileListEntryCache *cache, size_t cache_size) @@ -2057,6 +2114,11 @@ void filelist_setrecursion(FileList *filelist, const int recursion_level) } } +void filelist_set_no_preview_auto_cache(FileList *filelist) +{ + filelist->flags |= FL_PREVIEWS_NO_AUTO_CACHE; +} + bool filelist_needs_force_reset(const FileList *filelist) { return (filelist->flags & (FL_FORCE_RESET | FL_FORCE_RESET_MAIN_FILES)) != 0; @@ -2555,7 +2617,7 @@ bool filelist_file_cache_block(FileList *filelist, const int index) // printf("Re-queueing previews...\n"); - if (cache->flags & FLC_PREVIEWS_ACTIVE) { + if ((cache->flags & FLC_PREVIEWS_ACTIVE) && !(filelist->flags & FL_PREVIEWS_NO_AUTO_CACHE)) { /* Note we try to preview first images around given index - i.e. assumed visible ones. */ int block_index = cache->block_cursor + (index - start_index); int offs_max = max_ii(end_index - index, index - start_index); @@ -2578,6 +2640,11 @@ bool filelist_file_cache_block(FileList *filelist, const int index) return true; } +bool filelist_cache_previews_enabled(const FileList *filelist) +{ + return (filelist->filelist_cache.flags & FLC_PREVIEWS_ACTIVE) != 0; +} + void filelist_cache_previews_set(FileList *filelist, const bool use_previews) { FileListEntryCache *cache = &filelist->filelist_cache; @@ -2603,6 +2670,11 @@ void filelist_cache_previews_set(FileList *filelist, const bool use_previews) } } +void filelist_cache_previews_ensure_running(FileList *filelist) +{ + filelist_cache_preview_ensure_running(&filelist->filelist_cache); +} + bool filelist_cache_previews_update(FileList *filelist) { FileListEntryCache *cache = &filelist->filelist_cache; diff --git a/source/blender/editors/space_file/filelist.hh b/source/blender/editors/space_file/filelist.hh index a9c46f1034f..8635772ff40 100644 --- a/source/blender/editors/space_file/filelist.hh +++ b/source/blender/editors/space_file/filelist.hh @@ -78,6 +78,11 @@ void filelist_file_get_full_path(const FileList *filelist, const FileDirEntry *file, char r_filepath[/*FILE_MAX_LIBEXTRA*/]); bool filelist_file_is_preview_pending(const FileList *filelist, const FileDirEntry *file); +/** + * \return True if a new preview request was pushed, false otherwise (e.g. because the preview is + * already loaded, invalid or not supported). + */ +bool filelist_file_ensure_preview_requested(FileList *filelist, FileDirEntry *file); ImBuf *filelist_getimage(FileList *filelist, int index); ImBuf *filelist_file_getimage(const FileDirEntry *file); ImBuf *filelist_geticon_image_ex(const FileDirEntry *file); @@ -163,6 +168,8 @@ void filelist_file_cache_slidingwindow_set(FileList *filelist, size_t window_siz */ bool filelist_file_cache_block(FileList *filelist, int index); +void filelist_set_no_preview_auto_cache(FileList *filelist); + bool filelist_needs_force_reset(const FileList *filelist); void filelist_tag_force_reset(FileList *filelist); void filelist_tag_force_reset_mainfiles(FileList *filelist); @@ -221,7 +228,9 @@ void filelist_readjob_start(FileList *filelist, int space_notifier, const bConte void filelist_readjob_stop(FileList *filelist, wmWindowManager *wm); int filelist_readjob_running(FileList *filelist, wmWindowManager *wm); +void filelist_cache_previews_ensure_running(FileList *filelist); bool filelist_cache_previews_update(FileList *filelist); +bool filelist_cache_previews_enabled(const FileList *filelist); void filelist_cache_previews_set(FileList *filelist, bool use_previews); bool filelist_cache_previews_running(FileList *filelist); bool filelist_cache_previews_done(FileList *filelist);