1 /*
2     This file is part of darktable,
3     Copyright (C) 2011-2021 darktable developers.
4 
5     darktable is free software: you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation, either version 3 of the License, or
8     (at your option) any later version.
9 
10     darktable is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14 
15     You should have received a copy of the GNU General Public License
16     along with darktable.  If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #pragma once
20 
21 #include "common/cache.h"
22 #include "common/colorspaces.h"
23 #include "common/image.h"
24 
25 // sizes stored in the mipmap cache, set to fixed values in mipmap_cache.c
26 typedef enum dt_mipmap_size_t {
27   DT_MIPMAP_0 = 0,
28   DT_MIPMAP_1,
29   DT_MIPMAP_2,
30   DT_MIPMAP_3,
31   DT_MIPMAP_4,
32   DT_MIPMAP_5,
33   DT_MIPMAP_6,
34   DT_MIPMAP_7,
35   DT_MIPMAP_8,
36   DT_MIPMAP_F,
37   DT_MIPMAP_FULL,
38   DT_MIPMAP_NONE
39 } dt_mipmap_size_t;
40 
41 // type to be passed to getter functions
42 typedef enum dt_mipmap_get_flags_t
43 {
44   // gives you what you requested or a smaller mip,
45   // or NULL if none could be found
46   // also NULL is the fallback for _F and _FULL buffers.
47   DT_MIPMAP_BEST_EFFORT = 0,
48   // actually don't lock and return a buffer, but only
49   // start a bg job to load it, if it's not in cache already.
50   DT_MIPMAP_PREFETCH = 1,
51   // similar to prefetching, but only prefetch in case
52   // we hit the disk cache (don't run the more expensive pipeline)
53   DT_MIPMAP_PREFETCH_DISK = 2,
54   // only return when the requested buffer is loaded.
55   // blocks until that happens.
56   DT_MIPMAP_BLOCKING = 3,
57   // don't actually acquire the lock if it is not
58   // in cache (i.e. would have to be loaded first)
59   DT_MIPMAP_TESTLOCK = 4
60 } dt_mipmap_get_flags_t;
61 
62 // struct to be alloc'ed by the client, filled by dt_mipmap_cache_get()
63 typedef struct dt_mipmap_buffer_t
64 {
65   dt_mipmap_size_t size;
66   uint32_t imgid;
67   int32_t width, height;
68   float iscale;
69   uint8_t *buf;
70   dt_colorspaces_color_profile_type_t color_space;
71   dt_cache_entry_t *cache_entry;
72 } dt_mipmap_buffer_t;
73 
74 typedef struct dt_mipmap_cache_one_t
75 {
76   // one cache per mipmap scale!
77   dt_cache_t cache;
78 
79   // a few stats on usage in this run.
80   // long int to give 32-bits on old archs, so __sync* calls will work.
81   long int stats_requests;   // number of total requests
82   long int stats_near_match; // served with smaller mip res
83   long int stats_misses;     // nothing returned at all.
84   long int stats_fetches;    // texture was fetched (either as a stand-in or as per request)
85   long int stats_standin;    // texture used as stand-in
86 } dt_mipmap_cache_one_t;
87 
88 typedef struct dt_mipmap_cache_t
89 {
90   // real width and height are stored per element
91   // (could be smaller than the max for this mip level,
92   // due to aspect ratio)
93   uint32_t max_width[DT_MIPMAP_NONE], max_height[DT_MIPMAP_NONE];
94   // size of an element inside buf
95   size_t buffer_size[DT_MIPMAP_NONE];
96 
97   // one cache per mipmap level
98   dt_mipmap_cache_one_t mip_thumbs;
99   dt_mipmap_cache_one_t mip_f;
100   dt_mipmap_cache_one_t mip_full;
101   char cachedir[PATH_MAX]; // cached sha1sum filename for faster access
102 } dt_mipmap_cache_t;
103 
104 // dynamic memory allocation interface for imageio backend: a write locked
105 // mipmap buffer is passed in, it might already contain a valid buffer. this
106 // function takes care of re-allocating, if necessary.
107 void *dt_mipmap_cache_alloc(dt_mipmap_buffer_t *buf, const dt_image_t *img);
108 
109 void dt_mipmap_cache_init(dt_mipmap_cache_t *cache);
110 void dt_mipmap_cache_cleanup(dt_mipmap_cache_t *cache);
111 void dt_mipmap_cache_print(dt_mipmap_cache_t *cache);
112 
113 // get a buffer and lock according to mode ('r' or 'w').
114 // see dt_mipmap_get_flags_t for explanation of the exact
115 // behaviour. pass 0 as flags for the default (best effort)
116 #define dt_mipmap_cache_get(A,B,C,D,E,F) dt_mipmap_cache_get_with_caller(A,B,C,D,E,F,__FILE__,__LINE__)
117 void dt_mipmap_cache_get_with_caller(
118     dt_mipmap_cache_t *cache,
119     dt_mipmap_buffer_t *buf,
120     const uint32_t imgid,
121     const dt_mipmap_size_t mip,
122     const dt_mipmap_get_flags_t flags,
123     const char mode,
124     const char *file,
125     int line);
126 
127 // convenience function with fewer params
128 #define dt_mipmap_cache_write_get(A,B,C,D) dt_mipmap_cache_write_get_with_caller(A,B,C,D,__FILE__,__LINE__)
129 void dt_mipmap_cache_write_get_with_caller(
130     dt_mipmap_cache_t *cache,
131     dt_mipmap_buffer_t *buf,
132     const uint32_t imgid,
133     const int mip,
134     const char *file,
135     int line);
136 
137 // drop a lock
138 #define dt_mipmap_cache_release(A, B) dt_mipmap_cache_release_with_caller(A, B, __FILE__, __LINE__)
139 void dt_mipmap_cache_release_with_caller(dt_mipmap_cache_t *cache, dt_mipmap_buffer_t *buf, const char *file,
140                                          int line);
141 
142 // remove thumbnails, so they will be regenerated:
143 void dt_mipmap_cache_remove(dt_mipmap_cache_t *cache, const uint32_t imgid);
144 void dt_mipmap_cache_remove_at_size(dt_mipmap_cache_t *cache, const uint32_t imgid, const dt_mipmap_size_t mip);
145 
146 // evict thumbnails from cache. They will be written to disc if not existing
147 void dt_mimap_cache_evict(dt_mipmap_cache_t *cache, const uint32_t imgid);
148 void dt_mipmap_cache_evict_at_size(dt_mipmap_cache_t *cache, const uint32_t imgid, const dt_mipmap_size_t mip);
149 
150 // return the closest mipmap size
151 // for the given window you wish to draw.
152 // a dt_mipmap_size_t has always a fixed resolution associated with it,
153 // depending on the user parameter for the maximum thumbnail dimensions.
154 // actual resolution depends on the image and is only known after
155 // the thumbnail is loaded.
156 dt_mipmap_size_t dt_mipmap_cache_get_matching_size(
157     const dt_mipmap_cache_t *cache,
158     const int32_t width,
159     const int32_t height);
160 
161 // returns the colorspace to use for created thumbnails, takes config into account
162 dt_colorspaces_color_profile_type_t dt_mipmap_cache_get_colorspace();
163 
164 // copy over thumbnails. used by file operation that copies raw files, to speed up thumbnail generation.
165 // only copies over the jpg backend on disk, doesn't directly affect the in-memory cache.
166 void dt_mipmap_cache_copy_thumbnails(const dt_mipmap_cache_t *cache, const uint32_t dst_imgid, const uint32_t src_imgid);
167 
168 // return the mipmap corresponding to text value saved in prefs
169 dt_mipmap_size_t dt_mipmap_cache_get_min_mip_from_pref(char *value);
170 // modelines: These editor modelines have been set for all relevant files by tools/update_modelines.sh
171 // vim: shiftwidth=2 expandtab tabstop=2 cindent
172 // kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
173