Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
mipmap_cache.h
Go to the documentation of this file.
1/*
2 This file is part of darktable,
3 Copyright (C) 2009-2014, 2016 johannes hanika.
4 Copyright (C) 2012 Richard Wonka.
5 Copyright (C) 2012, 2014-2016 Tobias Ellinghaus.
6 Copyright (C) 2014-2015 Pedro Côrte-Real.
7 Copyright (C) 2014-2016 Roman Lebedev.
8 Copyright (C) 2019, 2021 Aldric Renaudin.
9 Copyright (C) 2020-2021 Pascal Obry.
10 Copyright (C) 2021 Ralf Brown.
11 Copyright (C) 2022 Martin Bařinka.
12 Copyright (C) 2025 Alynx Zhou.
13 Copyright (C) 2025-2026 Aurélien PIERRE.
14 Copyright (C) 2026 Guillaume Stutin.
15
16 darktable is free software: you can redistribute it and/or modify
17 it under the terms of the GNU General Public License as published by
18 the Free Software Foundation, either version 3 of the License, or
19 (at your option) any later version.
20
21 darktable is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 GNU General Public License for more details.
25
26 You should have received a copy of the GNU General Public License
27 along with darktable. If not, see <http://www.gnu.org/licenses/>.
28*/
29
30#ifndef DT_CACHES_MIPMAP_CACHE_H
31#define DT_CACHES_MIPMAP_CACHE_H
32
33#include "system/atomic.h"
34#include "common/paths.h" // DT_PATH_MAX
35#include "caches/cache.h"
37#include "common/image.h"
38
39#ifdef __cplusplus
40extern "C" {
41#endif
42
43// sizes stored in the mipmap cache, set to fixed values in mipmap_cache.c
44typedef enum dt_mipmap_size_t {
45 DT_MIPMAP_0, // 360x225 px
46 DT_MIPMAP_1, // 720x450 px
47 DT_MIPMAP_2, // 1440x900 px
48 DT_MIPMAP_3, // Full HD 1080p
49 DT_MIPMAP_4, // 2560x1440 px
50 DT_MIPMAP_5, // 4K/UHD -
54 DT_MIPMAP_F, // unprocessed input float image downscaled to 720x450 or 1440x900 px for performance
55 DT_MIPMAP_FULL, // unprocessed input float image at original resolation
58
59// type to be passed to getter functions
61{
62 // only return when the requested buffer is loaded.
63 // blocks until that happens.
65 // don't actually acquire the lock if it is not
66 // in cache (i.e. would have to be loaded first)
69
70// struct to be alloc'ed by the client, filled by dt_mipmap_cache_get()
87
89
90/* The cache instance is a file-static in mipmap_cache.c and there is no accessor for it: no
91 * function below takes one, so nothing outside needs the handle. The type survives only
92 * because dt_mipmap_cache_one_t names it; both are opaque. */
94
95// dynamic memory allocation interface for imageio backend: a write locked
96// mipmap buffer is passed in, it might already contain a valid buffer. this
97// function takes care of re-allocating, if necessary.
99
120
136
142
153void dt_mipmap_cache_init(const dt_mipmap_cache_settings_t *settings, const gboolean verbose);
154
164void dt_mipmap_cache_cleanup(void);
165void dt_mipmap_cache_print(void);
166
167// Interim accessor (Strategy B, doc/globals-migration.md): implemented by the orchestrator; long-term the handle should be carried on the job/view context (Strategy C).
168
169// One cached mipmap buffer, for the GUI memory view.
171{
172 int32_t imgid;
173 int mip; // dt_mipmap_size_t
174 size_t size; // bytes
176
177// Current/max bytes used across all mipmap sub-caches.
178void dt_mipmap_cache_get_usage(size_t *current, size_t *max);
179
180// Snapshot of all cached buffers (newly-allocated GArray of
181// dt_mipmap_cache_stats_entry_t; free with g_array_free()).
183
184// get a buffer and lock according to mode ('r' or 'w').
185// see dt_mipmap_get_flags_t for explanation of the exact
186// behaviour. pass 0 as flags for the default (best effort)
187#define dt_mipmap_cache_get(B,C,D,E,F) dt_mipmap_cache_get_with_caller(B,C,D,E,F,__FILE__,__LINE__)
190 const int32_t imgid,
191 const dt_mipmap_size_t mip,
193 const char mode,
194 const char *file,
195 int line);
196
197#define dt_mipmap_cache_get_with_shutdown(B,C,D,E,F,G) \
198 dt_mipmap_cache_get_with_caller_and_shutdown(B,C,D,E,F,G,__FILE__,__LINE__)
201 const int32_t imgid,
202 const dt_mipmap_size_t mip,
204 const char mode,
205 dt_atomic_int *shutdown,
206 const char *file,
207 int line);
208
209// convenience function with fewer params
210#define dt_mipmap_cache_write_get(B,C,D) dt_mipmap_cache_write_get_with_caller(B,C,D,__FILE__,__LINE__)
213 const int32_t imgid,
214 const int mip,
215 const char *file,
216 int line);
217
218// drop a lock
219#define dt_mipmap_cache_release(B) dt_mipmap_cache_release_with_caller(B, __FILE__, __LINE__)
221 int line);
222
223// remove thumbnails, so they will be regenerated, and a full-size load that failed, so it is tried again:
224void dt_mipmap_cache_remove(const int32_t imgid, const gboolean flush_disk);
225void dt_mipmap_cache_remove_at_size(const int32_t imgid, const dt_mipmap_size_t mip, const gboolean flush_disk);
226
227/* Every buffer this image owns, the decoded raw input (DT_MIPMAP_F, DT_MIPMAP_FULL) included.
228 *
229 * The two are deliberately outside dt_mipmap_cache_remove(), which exists for a development
230 * change: the decoded raw does not depend on the history, and dropping it there would re-read
231 * and re-demosaic the file on every commit. They are equally deliberately outside
232 * dt_mipmap_cache_remove_at_size(), which refuses them outright, so before this there was no
233 * way to drop them for one image and nothing but memory pressure ever did.
234 *
235 * An image leaving the library is the case that needs it. Its input buffer outlives the row,
236 * and if the image comes back -- "remove from library" is undoable -- the pipeline is handed
237 * that stale entry, basebuffer slices a zero-sized buffer out of it, and the thumbnail is a
238 * husk no later render replaces. Only a developed image shows it: an unaltered one is drawn
239 * from the embedded JPEG and never asks for the input at all. */
240void dt_mipmap_cache_remove_all_sizes(const int32_t imgid, const gboolean flush_disk);
241
242// evict thumbnails from cache. They will be written to disc if not existing
243void dt_mimap_cache_evict(const int32_t imgid);
244
245// return the closest mipmap size
246// for the given window you wish to draw.
247// a dt_mipmap_size_t has always a fixed resolution associated with it,
248// depending on the user parameter for the maximum thumbnail dimensions.
249// actual resolution depends on the image and is only known after
250// the thumbnail is loaded.
251dt_mipmap_size_t dt_mipmap_cache_get_matching_size( const int32_t width, const int32_t height, const uint32_t imgid);
252
253// return the closest mipmap size fitting within the width × height boundary box.
254// Use that to flush a darkroom pipeline output into a cache line
256 const int32_t height, const uint32_t imgid);
257
258// Manually swap the image buffer of a mipmap cacheline from an existing uint8_t image
259void dt_mipmap_cache_swap_at_size(const int32_t imgid,
260 const dt_mipmap_size_t mip, const uint8_t *const buffer,
261 const int32_t width, const int32_t height, dt_colorspaces_color_profile_type_t profile);
262
263// copy over thumbnails. used by file operation that copies raw files, to speed up thumbnail generation.
264// only copies over the jpg backend on disk, doesn't directly affect the in-memory cache.
265void dt_mipmap_cache_copy_thumbnails(const uint32_t dst_imgid, const uint32_t src_imgid);
266
267// get the full path of a cached thumbnail
268void dt_mipmap_get_cache_filename(char path[DT_PATH_MAX], dt_mipmap_size_t mip, const int32_t imgid);
269
270// get just the dir
272
273
274#ifdef __cplusplus
275}
276#endif
277
278#endif // DT_CACHES_MIPMAP_CACHE_H
279
280// clang-format off
281// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
282// vim: shiftwidth=2 expandtab tabstop=2 cindent
283// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
284// clang-format on
atomic_int dt_atomic_int
Definition atomic.h:68
const float max
dt_imageio_retval_t
Return value of image io functions: loading, exporting, and making a thumbnail.
Definition image.h:97
uint32_t width
Definition mipmap_cache.c:0
uint32_t height
Definition mipmap_cache.c:1
dt_mipmap_buffer_dsc_flags flags
Definition mipmap_cache.c:4
void * dt_mipmap_cache_alloc(dt_mipmap_buffer_t *buf, const dt_image_t *img)
dt_mipmap_size_t dt_mipmap_cache_get_fitting_size(const int32_t width, const int32_t height, const uint32_t imgid)
void dt_mipmap_cache_get_usage(size_t *current, size_t *max)
void dt_mipmap_cache_get_with_caller(dt_mipmap_buffer_t *buf, const int32_t imgid, const dt_mipmap_size_t mip, const dt_mipmap_get_flags_t flags, const char mode, const char *file, int line)
void dt_mipmap_cache_init(const dt_mipmap_cache_settings_t *settings, const gboolean verbose)
Initialise the cache.
void dt_mipmap_cache_cleanup(void)
void dt_mipmap_cache_release_with_caller(dt_mipmap_buffer_t *buf, const char *file, int line)
void dt_mipmap_cache_write_get_with_caller(dt_mipmap_buffer_t *buf, const int32_t imgid, const int mip, const char *file, int line)
void dt_mipmap_cache_remove(const int32_t imgid, const gboolean flush_disk)
void dt_mipmap_cache_remove_all_sizes(const int32_t imgid, const gboolean flush_disk)
void dt_mipmap_cache_copy_thumbnails(const uint32_t dst_imgid, const uint32_t src_imgid)
dt_mipmap_get_flags_t
@ DT_MIPMAP_BLOCKING
@ DT_MIPMAP_TESTLOCK
void dt_mipmap_get_cache_dir(char path[DT_PATH_MAX], dt_mipmap_size_t mip)
void dt_mipmap_cache_get_settings(dt_mipmap_cache_settings_t *settings)
Read back the settings in force. Snapshot, taken under the same lock the setter takes,...
void dt_mipmap_cache_remove_at_size(const int32_t imgid, const dt_mipmap_size_t mip, const gboolean flush_disk)
void dt_mipmap_cache_print(void)
void dt_mipmap_cache_get_with_caller_and_shutdown(dt_mipmap_buffer_t *buf, const int32_t imgid, const dt_mipmap_size_t mip, const dt_mipmap_get_flags_t flags, const char mode, dt_atomic_int *shutdown, const char *file, int line)
void dt_mipmap_cache_set_settings(const dt_mipmap_cache_settings_t *settings)
Apply new settings to a running cache.
void dt_mimap_cache_evict(const int32_t imgid)
void dt_mipmap_cache_flush_to_disk(void)
Write the resident thumbnails to the disk cache and drop them from RAM; the cache stays usable.
void dt_mipmap_cache_swap_at_size(const int32_t imgid, const dt_mipmap_size_t mip, const uint8_t *const buffer, const int32_t width, const int32_t height, dt_colorspaces_color_profile_type_t profile)
GArray * dt_mipmap_cache_get_entries_stats(void)
dt_mipmap_size_t dt_mipmap_cache_get_matching_size(const int32_t width, const int32_t height, const uint32_t imgid)
dt_mipmap_size_t
@ DT_MIPMAP_6
@ DT_MIPMAP_1
@ DT_MIPMAP_4
@ DT_MIPMAP_F
@ DT_MIPMAP_7
@ DT_MIPMAP_0
@ DT_MIPMAP_5
@ DT_MIPMAP_2
@ DT_MIPMAP_NONE
@ DT_MIPMAP_3
@ DT_MIPMAP_FULL
@ DT_MIPMAP_8
void dt_mipmap_get_cache_filename(char path[DT_PATH_MAX], dt_mipmap_size_t mip, const int32_t imgid)
#define DT_PATH_MAX
Buffer size for a filesystem path anywhere in Ansel.
Definition paths.h:57
The colour-profile vocabulary, and nothing else.
dt_colorspaces_color_profile_type_t
dt_colorspaces_color_profile_type_t color_space
dt_cache_entry_t * cache_entry
NULL with a non-NULL buf when a blocking get could not allocate the thumbnail's entry: buf is then a ...
dt_mipmap_size_t size
dt_imageio_retval_t status
Why the entry holds no image: a thumbnail drawn as a skull, or a full-size input with no pixels....
Everything about the mipmap cache that the USER decides.
size_t max_memory
RAM budget for the thumbnail LRU, in bytes. A soft quota, not a hard limit.
int embedded_jpg
Whether to prefer the embedded JPEG over decoding (lighttable/embedded_jpg).
int cache_quality
JPEG quality for thumbnails written to disk (database_cache_quality).
gboolean disk_backend
Write generated thumbnails to the on-disk cache (cache_disk_backend).
int mip
size_t size
int32_t imgid