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 Aurélien PIERRE.
14
15 darktable is free software: you can redistribute it and/or modify
16 it under the terms of the GNU General Public License as published by
17 the Free Software Foundation, either version 3 of the License, or
18 (at your option) any later version.
19
20 darktable is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 GNU General Public License for more details.
24
25 You should have received a copy of the GNU General Public License
26 along with darktable. If not, see <http://www.gnu.org/licenses/>.
27*/
28
29#ifndef DT_CACHES_MIPMAP_CACHE_H
30#define DT_CACHES_MIPMAP_CACHE_H
31
32#include "system/atomic.h"
33#include "common/paths.h" // DT_PATH_MAX
34#include "caches/cache.h"
36#include "common/image.h"
37
38#ifdef __cplusplus
39extern "C" {
40#endif
41
42// sizes stored in the mipmap cache, set to fixed values in mipmap_cache.c
43typedef enum dt_mipmap_size_t {
44 DT_MIPMAP_0, // 360x225 px
45 DT_MIPMAP_1, // 720x450 px
46 DT_MIPMAP_2, // 1440x900 px
47 DT_MIPMAP_3, // Full HD 1080p
48 DT_MIPMAP_4, // 2560x1440 px
49 DT_MIPMAP_5, // 4K/UHD -
53 DT_MIPMAP_F, // unprocessed input float image downscaled to 720x450 or 1440x900 px for performance
54 DT_MIPMAP_FULL, // unprocessed input float image at original resolation
57
58// type to be passed to getter functions
60{
61 // only return when the requested buffer is loaded.
62 // blocks until that happens.
64 // don't actually acquire the lock if it is not
65 // in cache (i.e. would have to be loaded first)
68
69// struct to be alloc'ed by the client, filled by dt_mipmap_cache_get()
80
82
83/* The cache instance is a file-static in mipmap_cache.c and there is no accessor for it: no
84 * function below takes one, so nothing outside needs the handle. The type survives only
85 * because dt_mipmap_cache_one_t names it; both are opaque. */
87
88// dynamic memory allocation interface for imageio backend: a write locked
89// mipmap buffer is passed in, it might already contain a valid buffer. this
90// function takes care of re-allocating, if necessary.
92
113
125
131
142void dt_mipmap_cache_init(const dt_mipmap_cache_settings_t *settings, const gboolean verbose);
143void dt_mipmap_cache_cleanup(void);
144void dt_mipmap_cache_print(void);
145
146// 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).
147
148// One cached mipmap buffer, for the GUI memory view.
150{
151 int32_t imgid;
152 int mip; // dt_mipmap_size_t
153 size_t size; // bytes
155
156// Current/max bytes used across all mipmap sub-caches.
157void dt_mipmap_cache_get_usage(size_t *current, size_t *max);
158
159// Snapshot of all cached buffers (newly-allocated GArray of
160// dt_mipmap_cache_stats_entry_t; free with g_array_free()).
162
163// get a buffer and lock according to mode ('r' or 'w').
164// see dt_mipmap_get_flags_t for explanation of the exact
165// behaviour. pass 0 as flags for the default (best effort)
166#define dt_mipmap_cache_get(B,C,D,E,F) dt_mipmap_cache_get_with_caller(B,C,D,E,F,__FILE__,__LINE__)
169 const int32_t imgid,
170 const dt_mipmap_size_t mip,
172 const char mode,
173 const char *file,
174 int line);
175
176#define dt_mipmap_cache_get_with_shutdown(B,C,D,E,F,G) \
177 dt_mipmap_cache_get_with_caller_and_shutdown(B,C,D,E,F,G,__FILE__,__LINE__)
180 const int32_t imgid,
181 const dt_mipmap_size_t mip,
183 const char mode,
184 dt_atomic_int *shutdown,
185 const char *file,
186 int line);
187
188// convenience function with fewer params
189#define dt_mipmap_cache_write_get(B,C,D) dt_mipmap_cache_write_get_with_caller(B,C,D,__FILE__,__LINE__)
192 const int32_t imgid,
193 const int mip,
194 const char *file,
195 int line);
196
197// drop a lock
198#define dt_mipmap_cache_release(B) dt_mipmap_cache_release_with_caller(B, __FILE__, __LINE__)
200 int line);
201
202// remove thumbnails, so they will be regenerated:
203void dt_mipmap_cache_remove(const int32_t imgid, const gboolean flush_disk);
204void dt_mipmap_cache_remove_at_size(const int32_t imgid, const dt_mipmap_size_t mip, const gboolean flush_disk);
205
206/* Every buffer this image owns, the decoded raw input (DT_MIPMAP_F, DT_MIPMAP_FULL) included.
207 *
208 * The two are deliberately outside dt_mipmap_cache_remove(), which exists for a development
209 * change: the decoded raw does not depend on the history, and dropping it there would re-read
210 * and re-demosaic the file on every commit. They are equally deliberately outside
211 * dt_mipmap_cache_remove_at_size(), which refuses them outright, so before this there was no
212 * way to drop them for one image and nothing but memory pressure ever did.
213 *
214 * An image leaving the library is the case that needs it. Its input buffer outlives the row,
215 * and if the image comes back -- "remove from library" is undoable -- the pipeline is handed
216 * that stale entry, basebuffer slices a zero-sized buffer out of it, and the thumbnail is a
217 * husk no later render replaces. Only a developed image shows it: an unaltered one is drawn
218 * from the embedded JPEG and never asks for the input at all. */
219void dt_mipmap_cache_remove_all_sizes(const int32_t imgid, const gboolean flush_disk);
220
221// evict thumbnails from cache. They will be written to disc if not existing
222void dt_mimap_cache_evict(const int32_t imgid);
223
224// return the closest mipmap size
225// for the given window you wish to draw.
226// a dt_mipmap_size_t has always a fixed resolution associated with it,
227// depending on the user parameter for the maximum thumbnail dimensions.
228// actual resolution depends on the image and is only known after
229// the thumbnail is loaded.
230dt_mipmap_size_t dt_mipmap_cache_get_matching_size( const int32_t width, const int32_t height, const uint32_t imgid);
231
232// return the closest mipmap size fitting within the width × height boundary box.
233// Use that to flush a darkroom pipeline output into a cache line
235 const int32_t height, const uint32_t imgid);
236
237// Manually swap the image buffer of a mipmap cacheline from an existing uint8_t image
238void dt_mipmap_cache_swap_at_size(const int32_t imgid,
239 const dt_mipmap_size_t mip, const uint8_t *const buffer,
240 const int32_t width, const int32_t height, dt_colorspaces_color_profile_type_t profile);
241
242// copy over thumbnails. used by file operation that copies raw files, to speed up thumbnail generation.
243// only copies over the jpg backend on disk, doesn't directly affect the in-memory cache.
244void dt_mipmap_cache_copy_thumbnails(const uint32_t dst_imgid, const uint32_t src_imgid);
245
246// get the full path of a cached thumbnail
247void dt_mipmap_get_cache_filename(char path[DT_PATH_MAX], dt_mipmap_size_t mip, const int32_t imgid);
248
249// get just the dir
251
252
253#ifdef __cplusplus
254}
255#endif
256
257#endif // DT_CACHES_MIPMAP_CACHE_H
258
259// clang-format off
260// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
261// vim: shiftwidth=2 expandtab tabstop=2 cindent
262// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
263// clang-format on
atomic_int dt_atomic_int
Definition atomic.h:68
const float max
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_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
dt_mipmap_size_t size
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