Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
darktable.h
Go to the documentation of this file.
1/*
2 This file is part of darktable,
3 Copyright (C) 2009-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// just to be sure. the build system should set this for us already:
22#if defined __DragonFly__ || defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__
23#define _WITH_DPRINTF
24#define _WITH_GETLINE
25#elif !defined _XOPEN_SOURCE && !defined _WIN32
26#define _XOPEN_SOURCE 700 // for localtime_r and dprintf
27#endif
28
29// needs to be defined before any system header includes for control/conf.h to work in C++ code
30#define __STDC_FORMAT_MACROS
31
32#if !defined(O_BINARY)
33// To have portable g_open() on *nix and on Windows
34#define O_BINARY 0
35#endif
36
37#include "external/ThreadSafetyAnalysis.h"
38
39#ifdef HAVE_CONFIG_H
40#include "config.h"
41#endif
42#include "common/database.h"
43#include "common/dtpthread.h"
44#include "common/utility.h"
45#ifdef _WIN32
46#include "win/getrusage.h"
47#else
48#include <sys/resource.h>
49#endif
50#include <stdint.h>
51#include <glib.h>
52#include <glib/gstdio.h>
53#include <glib/gi18n.h>
54#include <inttypes.h>
55#include <json-glib/json-glib.h>
56#include <lua/lua.h>
57#include <math.h>
58#include <sqlite3.h>
59#include <stdio.h>
60#include <sys/time.h>
61#include <sys/types.h>
62#include <unistd.h>
63
64#ifndef _RELEASE
65#include "common/poison.h"
66#endif
67
69
70// for signal debugging symbols
71#include "control/signal.h"
72
73#ifdef __cplusplus
74extern "C" {
75#endif
76
77#define DT_MODULE_VERSION 23 // version of dt's module interface
78
79// version of current performance configuration version
80// if you want to run an updated version of the performance configuration later
81// bump this number and make sure you have an updated logic in dt_configure_performance()
82#define DT_CURRENT_PERFORMANCE_CONFIGURE_VERSION 11
83#define DT_PERF_INFOSIZE 4096
84
85// every module has to define this:
86#ifdef _DEBUG
87#define DT_MODULE(MODVER) \
88 int dt_module_dt_version() \
89 { \
90 return -DT_MODULE_VERSION; \
91 } \
92 int dt_module_mod_version() \
93 { \
94 return MODVER; \
95 }
96#else
97#define DT_MODULE(MODVER) \
98 int dt_module_dt_version() \
99 { \
100 return DT_MODULE_VERSION; \
101 } \
102 int dt_module_mod_version() \
103 { \
104 return MODVER; \
105 }
106#endif
107
108#define DT_MODULE_INTROSPECTION(MODVER, PARAMSTYPE) DT_MODULE(MODVER)
109
110// ..to be able to compare it against this:
111static inline int dt_version()
112{
113#ifdef _DEBUG
114 return -DT_MODULE_VERSION;
115#else
116 return DT_MODULE_VERSION;
117#endif
118}
119
120// returns the darktable version as <major>.<minor>
122
123#undef STR_HELPER
124#define STR_HELPER(x) #x
125
126#undef STR
127#define STR(x) STR_HELPER(x)
128
129#define DT_IMAGE_DBLOCKS 64
130
131// When included by a C++ file, restrict qualifiers are not allowed
132#ifdef __cplusplus
133#define DT_RESTRICT
134#else
135#define DT_RESTRICT restrict
136#endif
137
138// Default code for imgid meaning the picture is unknown or invalid
139#define UNKNOWN_IMAGE -1
140
141#ifdef __cplusplus
142}
143#endif
144
145/********************************* */
146
153#if defined _WIN32
154#include "win/win.h"
155#endif
156
157#ifdef __APPLE__
158#include <mach/mach.h>
159#include <sys/sysctl.h>
160#endif
161
162#if defined(__DragonFly__) || defined(__FreeBSD__)
163typedef unsigned int u_int;
164#include <sys/sysctl.h>
165#include <sys/types.h>
166#endif
167#if defined(__NetBSD__) || defined(__OpenBSD__)
168#include <sys/param.h>
169#include <sys/sysctl.h>
170#endif
171
172#if defined(__aarch64__)
173#include <arm_neon.h>
174#endif
175
176#if defined(__SSE__)
177#include <xmmintrin.h> // needed for _mm_stream_ps
178#endif
179
180#ifdef _OPENMP
181# include <omp.h>
182
183/* See https://redmine.darktable.org/issues/12568#note-14 */
184# ifdef HAVE_OMP_FIRSTPRIVATE_WITH_CONST
185 /* If the compiler correctly supports firstprivate, use it. */
186# define dt_omp_firstprivate(...) firstprivate(__VA_ARGS__)
187# else /* HAVE_OMP_FIRSTPRIVATE_WITH_CONST */
188 /* This is needed for clang < 7.0 */
189# define dt_omp_firstprivate(...)
190# endif/* HAVE_OMP_FIRSTPRIVATE_WITH_CONST */
191
192#ifndef dt_omp_sharedconst
193#ifdef _OPENMP
194#if defined(__clang__) || __GNUC__ > 8
195# define dt_omp_sharedconst(...) shared(__VA_ARGS__)
196#else
197 // GCC 8.4 throws string of errors "'x' is predetermined 'shared' for 'shared'" if we explicitly declare
198 // 'const' variables as shared
199# define dt_omp_sharedconst(var, ...)
200#endif
201#endif /* _OPENMP */
202#endif /* dt_omp_sharedconst */
203
204#ifndef dt_omp_nontemporal
205// Clang 10+ supports the nontemporal() OpenMP directive
206// GCC 9 recognizes it as valid, but does not do anything with it
207// GCC 10+ ???
208#if (__clang__+0 >= 10 || __GNUC__ >= 9)
209# define dt_omp_nontemporal(...) nontemporal(__VA_ARGS__)
210#else
211// GCC7/8 only support OpenMP 4.5, which does not have the nontemporal() directive.
212# define dt_omp_nontemporal(var, ...)
213#endif
214#endif /* dt_omp_nontemporal */
215
216#else /* _OPENMP */
217
218# define omp_get_max_threads() 1
219# define omp_get_thread_num() 0
220
221#endif /* _OPENMP */
222
223#ifdef __cplusplus
224extern "C" {
225#endif
226
227static inline int dt_get_thread_num()
228{
229#ifdef _OPENMP
230 return omp_get_thread_num();
231#else
232 return 0;
233#endif
234}
235
236/* Create cloned functions for various CPU SSE generations */
237/* See for instructions https://hannes.hauswedell.net/post/2017/12/09/fmv/ */
238/* TL;DR : use only on SIMD functions containing low-level paralellized/vectorized loops */
239#if __has_attribute(target_clones) && !defined(_WIN32) && !defined(__APPLE__) && !defined(NATIVE_ARCH)
240 # if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64)
241 #define __DT_CLONE_TARGETS__ __attribute__((target_clones("default", "sse2", "sse3", "sse4.1", "sse4.2", "popcnt", "avx", "avx2", "avx512f", "fma4")))
242 # elif defined(__PPC64__)
243 /* __PPC64__ is the only macro tested for in is_supported_platform.h, other macros would fail there anyway. */
244 #define __DT_CLONE_TARGETS__ __attribute__((target_clones("default","cpu=power9")))
245 # else
246 #define __DT_CLONE_TARGETS__
247 # endif
248#else
249 #define __DT_CLONE_TARGETS__
250#endif
251
252/* Helper to force stack vectors to be aligned on DT_CACHELINE_BYTES blocks to enable AVX2 */
253#define DT_IS_ALIGNED(x) __builtin_assume_aligned(x, DT_CACHELINE_BYTES)
254
255// Configure the size of a CPU cacheline in bytes, floats, and pixels. On most current architectures,
256// a cacheline contains 64 bytes, but Apple Silicon (M-series processors) uses 128-byte cache lines.
257#if defined(__APPLE__) && defined(__aarch64__)
258 #define DT_CACHELINE_BYTES 128
259 #define DT_CACHELINE_FLOATS 32
260 #define DT_CACHELINE_PIXELS 8
261#else
262 #define DT_CACHELINE_BYTES 64
263 #define DT_CACHELINE_FLOATS 16
264 #define DT_CACHELINE_PIXELS 4
265#endif /* __APPLE__ && __aarch64__ */
266
267// Helper to force heap vectors to be aligned on 64 byte blocks to enable AVX2
268// If this is applied to a struct member and the struct is allocated on the heap, then it must be allocated
269// on a 64 byte boundary to avoid crashes or undefined behavior because of unaligned memory access.
270#define DT_ALIGNED_ARRAY __attribute__((aligned(DT_CACHELINE_BYTES)))
271#define DT_ALIGNED_PIXEL __attribute__((aligned(16)))
272
273
274static inline gboolean dt_is_aligned(const void *pointer, size_t byte_count)
275{
276 return (uintptr_t)pointer % byte_count == 0;
277}
278
279static inline size_t dt_round_size(const size_t size, const size_t alignment)
280{
281 // Round the size of a buffer to the closest higher multiple
282 return ((size % alignment) == 0) ? size : ((size - 1) / alignment + 1) * alignment;
283}
284
285static inline size_t dt_round_size_sse(const size_t size)
286{
287 // Round the size of a buffer to the closest 64 higher multiple
288 return dt_round_size(size, 64);
289}
290
291static inline void *dt_alloc_align_internal(size_t size)
292{
293 const size_t alignment = DT_CACHELINE_BYTES;
294 const size_t aligned_size = dt_round_size(size, alignment);
295#if defined(__FreeBSD_version) && __FreeBSD_version < 700013
296 return malloc(aligned_size);
297#elif defined(_WIN32)
298 return _aligned_malloc(aligned_size, alignment);
299#elif defined(_DEBUG)
300 // for a debug build, ensure that we get a crash if we use plain free() to release the allocated memory, by
301 // returning a pointer which isn't a valid memory block address
302 void *ptr = NULL;
303 if(posix_memalign(&ptr, alignment, aligned_size + alignment)) return NULL;
304 short *offset = (short*)(((char*)ptr) + alignment - sizeof(short));
305 *offset = alignment;
306 return ((char*)ptr) + alignment ;
307#else
308 void *ptr = NULL;
309 if(posix_memalign(&ptr, alignment, aligned_size)) return NULL;
310 return ptr;
311#endif
312}
313
314void *dt_alloc_align(size_t size);
315
316#ifdef _WIN32
317 static inline void dt_free_align(void *mem)
318 {
319 _aligned_free(mem);
320 }
321 #define dt_free_align_ptr dt_free_align
322#elif _DEBUG // debug build makes sure that we get a crash on using plain free() on an aligned allocation
323 static inline void dt_free_align(void *mem)
324 {
325 // on a debug build, we deliberately offset the returned pointer from dt_alloc_align, so eliminate the offset
326 if (mem)
327 {
328 short offset = ((short*)mem)[-1];
329 free(((char*)mem)-offset);
330 }
331 }
332 #define dt_free_align_ptr dt_free_align
333#else
334 #define dt_free_align(A) if(A) free(A)
335 #define dt_free_align_ptr free
336#endif
337
338
339static inline void* dt_calloc_align(size_t size)
340{
341 void *buf = dt_alloc_align(size);
342 if(buf) memset(buf, 0, size);
343 return buf;
344}
345static inline float *dt_alloc_align_float(size_t pixels)
346{
347 return (float*)__builtin_assume_aligned(dt_alloc_align(pixels * sizeof(float)), DT_CACHELINE_BYTES);
348}
349static inline float *dt_calloc_align_float(size_t pixels)
350{
351 float *const buf = (float*)dt_alloc_align(pixels * sizeof(float));
352 if(buf) memset(buf, 0, pixels * sizeof(float));
353 return (float*)__builtin_assume_aligned(buf, DT_CACHELINE_BYTES);
354}
355
356static inline void * dt_alloc_sse_ps(size_t pixels)
357{
358 return __builtin_assume_aligned(dt_alloc_align(pixels * sizeof(float)), DT_CACHELINE_BYTES);
359}
360
361static inline void * dt_check_sse_aligned(void * pointer)
362{
364 return __builtin_assume_aligned(pointer, DT_CACHELINE_BYTES);
365 else
366 return NULL;
367}
368
369// Most code in dt assumes that the compiler is capable of auto-vectorization. In some cases, this will yield
370// suboptimal code if the compiler in fact does NOT auto-vectorize. Uncomment the following line for such a
371// compiler.
372//#define DT_NO_VECTORIZATION
373
374// For some combinations of compiler and architecture, the compiler may actually emit inferior code if given
375// a hint to vectorize a loop. Uncomment the following line if such a combination is the compilation target.
376//#define DT_NO_SIMD_HINTS
377
378// utility type to ease declaration of aligned small arrays to hold a pixel (and document their purpose)
379typedef DT_ALIGNED_PIXEL float dt_aligned_pixel_t[4];
380
381// To be able to vectorize per-pixel loops, we need to operate on all four channels, but if the compiler does
382// not auto-vectorize, doing so increases computation by 1/3 for a channel which typically is ignored anyway.
383// Select the appropriate number of channels over which to loop to produce the fastest code.
384#ifdef DT_NO_VECTORIZATION
385#define DT_PIXEL_SIMD_CHANNELS 3
386#else
387#define DT_PIXEL_SIMD_CHANNELS 4
388#endif
389
390// A macro which gives us a configurable shorthand to produce the optimal performance when processing all of the
391// channels in a pixel. Its first argument is the name of the variable to be used inside the 'for' loop it creates,
392// while the optional second argument is a set of OpenMP directives, typically specifying variable alignment.
393// If indexing off of the begining of any buffer allocated with dt's image or aligned allocation functions, the
394// alignment to specify is 64; otherwise, use 16, as there may have been an odd number of pixels from the start.
395// Sample usage:
396// for_each_channel(k,aligned(src,dest:16))
397// {
398// src[k] = dest[k] / 3.0f;
399// }
400#if defined(_OPENMP) && defined(OPENMP_SIMD_) && !defined(DT_NO_SIMD_HINTS)
401//https://stackoverflow.com/questions/45762357/how-to-concatenate-strings-in-the-arguments-of-pragma
402#define _DT_Pragma_(x) _Pragma(#x)
403#define _DT_Pragma(x) _DT_Pragma_(x)
404#define for_each_channel(_var, ...) \
405 _DT_Pragma(omp simd __VA_ARGS__) \
406 for (size_t _var = 0; _var < DT_PIXEL_SIMD_CHANNELS; _var++)
407#define for_four_channels(_var, ...) \
408 _DT_Pragma(omp simd __VA_ARGS__) \
409 for (size_t _var = 0; _var < 4; _var++)
410#else
411#define for_each_channel(_var, ...) \
412 for (size_t _var = 0; _var < DT_PIXEL_SIMD_CHANNELS; _var++)
413#define for_four_channels(_var, ...) \
414 for (size_t _var = 0; _var < 4; _var++)
415#endif
416
417
418// copy the RGB channels of a pixel using nontemporal stores if
419// possible; includes the 'alpha' channel as well if faster due to
420// vectorization, but subsequent code should ignore the value of the
421// alpha unless explicitly set afterwards (since it might not have
422// been copied). NOTE: nontemporal stores will actually be *slower*
423// if we immediately access the pixel again. This function should
424// only be used when processing an entire image before doing anything
425// else with the destination buffer.
426static inline void copy_pixel_nontemporal(
427 float *const __restrict__ out,
428 const float *const __restrict__ in)
429{
430#if defined(__SSE__)
431 _mm_stream_ps(out, *((__m128*)in));
432#elif defined(__aarch64__)
433 vst1q_f32(out, *((float32x4_t *)in));
434#elif (__clang__+0 > 7) && (__clang__+0 < 10)
435 for_each_channel(k,aligned(in,out:16)) __builtin_nontemporal_store(in[k],out[k]);
436#else
437 for_each_channel(k,aligned(in,out:16) dt_omp_nontemporal(out)) out[k] = in[k];
438#endif
439}
440
441
442// copy the RGB channels of a pixel; includes the 'alpha' channel as well if faster due to vectorization, but
443// subsequent code should ignore the value of the alpha unless explicitly set afterwards (since it might not have
444// been copied)
445static inline void copy_pixel(float *const __restrict__ out, const float *const __restrict__ in)
446{
447 for_each_channel(k,aligned(in,out:16)) out[k] = in[k];
448}
449
450
451/********************************* */
452
453struct dt_gui_gtk_t;
454struct dt_control_t;
455struct dt_develop_t;
456struct dt_mipmap_cache_t;
457struct dt_image_cache_t;
458struct dt_lib_t;
459struct dt_conf_t;
460struct dt_points_t;
461struct dt_imageio_t;
462struct dt_bauhaus_t;
463struct dt_undo_t;
464struct dt_colorspaces_t;
465struct dt_l10n_t;
466
467typedef float dt_boundingbox_t[4]; //(x,y) of upperleft, then (x,y) of lowerright
468
501
502typedef struct dt_codepath_t
503{
504 unsigned int SSE2 : 1;
505 unsigned int _no_intrinsics : 1;
506 unsigned int OPENMP_SIMD : 1; // always stays the last one
508
509typedef struct dt_sys_resources_t
510{
511 size_t total_memory; // All RAM on system
512 size_t mipmap_memory; // RAM allocated to mipmap cache
513 size_t headroom_memory; // RAM left to OS & other Apps
514 size_t pixelpipe_memory; // RAM used by the pixelpipe cache (approx.)
515 size_t buffer_memory; // Max size of a single image buffer, fraction of available_memory
516
517 // pixel size of a main darkroom image cache line
520
521typedef struct darktable_t
522{
525
526 int32_t unmuted;
527 GList *iop;
530
531 // Keep track of optional features that may depend on environnement
532 // ond compiling options : OpenCL, libsecret, kwallet
537 struct dt_lib_t *lib;
545 const struct dt_database_t *db;
557
558 // Protects from concurrent writing at export time
559 dt_pthread_mutex_t plugin_threadsafe;
560
561 // Protect appending/removing GList links to the darktable.capabilities list
562 dt_pthread_mutex_t capabilities_threadsafe;
563
564 // Exiv2 readMetadata() was not thread-safe prior to 0.27
565 // FIXME: Is it now ?
566 dt_pthread_mutex_t exiv2_threadsafe;
567
568 // RawSpeed readFile() method is apparently not thread-safe
569 dt_pthread_mutex_t readFile_mutex;
570
571 // Prevent concurrent export/thumbnail pipelines from runnnig at the same time
572 // It brings no additional performance since the CPU is our bottleneck,
573 // and CPU pixel code is already multi-threaded internally through OpenMP
574 dt_pthread_mutex_t pipeline_threadsafe;
575
576 // Building SQL transactions through `dt_database_start_transaction_debug()`
577 // from "too many" threads (like loading all thumbnails from a new collection)
578 // leads to SQL error:
579 // `BEGIN": cannot start a transaction within a transaction`
580 // Also, we need to ensure that image metadata/history reads & writes
581 // happen each in their all time, from all pipeline jobs/threads.
583
584 char *progname;
585 char *datadir;
586 char *sharedir;
589 char *tmpdir;
591 char *cachedir;
594 GList *guides;
596 GList *themes;
599 GTimeZone *utc_tz;
600 GDateTime *origin_gdt;
603
604typedef struct
605{
606 double clock;
607 double user;
608} dt_times_t;
609
611
612int dt_init(int argc, char *argv[], const gboolean init_gui, const gboolean load_data, lua_State *L);
613void dt_cleanup();
614void dt_print(dt_debug_thread_t thread, const char *msg, ...) __attribute__((format(printf, 2, 3)));
615/* same as above but without time stamp : nts = no time stamp */
616void dt_print_nts(dt_debug_thread_t thread, const char *msg, ...) __attribute__((format(printf, 2, 3)));
617/* same as above but requires additional DT_DEBUG_VERBOSE flag to be true */
618void dt_vprint(dt_debug_thread_t thread, const char *msg, ...) __attribute__((format(printf, 2, 3)));
619
620// Maximum number of workers for background threads, depending on
621// CPU number of cores and available memory.
622// Note that we allow at most 2 pixelpipes running concurrently
623// (when in darkroom: (preview or main) and export),
624// because all pipelines share the CPU at some point, so parallelizing
625// pipelines only increases memory contention at the CPU bottleneck,
626// and leads to no performance increase (quite the opposite).
627// There is also the issue of SQL database locking: SQLite errors
628// when trying to write several image histories at once, which happens
629// on refreshing the thumbnails when entering a newly imported lighttable collection. So we allow
630// only one thumbnail export to run at a time (and again, pixel ops don't go faster
631// with parallel pipelines anyway).
632// Parallel workers are mostly useful to defer expensive I/O, like writing XMP
633// or copying files on remote storages, where the bottleneck is filesystem or network I/O
634// rather than CPU or RAM I/O.
636
637// Get the remaining memory available for pipeline allocations,
638// once we subtracted caches memory and headroom from system memory
639size_t dt_get_available_mem();
640
641// Get the maximum size of allocation of a single image buffer
643
644// Get the maximum size for the whole mipmap cache
645size_t dt_get_mipmap_mem();
646
653static inline void memset_zero(void *const buffer, size_t size)
654{
655 // Same as memset_s in C11. memset might be optimized away by compilers, this will not.
656 // Not parallelized or vectorized since it's applied only on "small" tiles.
657 for(size_t k = 0; k < size / sizeof(unsigned char); k++) {
658 unsigned char *const item = (unsigned char *const)buffer + k;
659 *item = 0;
660 }
661}
662
663// check whether the specified mask of modifier keys exactly matches, among the set Shift+Control+(Alt/Meta).
664// ignores the state of any other shifting keys
665static inline gboolean dt_modifier_is(const GdkModifierType state, const GdkModifierType desired_modifier_mask)
666{
667 const GdkModifierType modifiers = gtk_accelerator_get_default_mod_mask();
668//TODO: on Macs, remap the GDK_CONTROL_MASK bit in desired_modifier_mask to be the bit for the Cmd key
669 return (state & modifiers) == desired_modifier_mask;
670}
671
672// check whether the given modifier state includes AT LEAST the specified mask of modifier keys
673static inline gboolean dt_modifiers_include(const GdkModifierType state, const GdkModifierType desired_modifier_mask)
674{
675//TODO: on Macs, remap the GDK_CONTROL_MASK bit in desired_modifier_mask to be the bit for the Cmd key
676 const GdkModifierType modifiers = gtk_accelerator_get_default_mod_mask();
677 // check whether all modifier bits of interest are turned on
678 return (state & (modifiers & desired_modifier_mask)) == desired_modifier_mask;
679}
680
681int dt_capabilities_check(char *capability);
682void dt_capabilities_add(char *capability);
683void dt_capabilities_remove(char *capability);
685
686static inline double dt_get_wtime(void)
687{
688 struct timeval time;
689 gettimeofday(&time, NULL);
690 return time.tv_sec - 1290608000 + (1.0 / 1000000.0) * time.tv_usec;
691}
692
693static inline void dt_get_times(dt_times_t *t)
694{
695 struct rusage ru;
696
698 t->clock = dt_get_wtime();
699 t->user = ru.ru_utime.tv_sec + ru.ru_utime.tv_usec * (1.0 / 1000000.0);
700}
701
702void dt_show_times(const dt_times_t *start, const char *prefix);
703
704void dt_show_times_f(const dt_times_t *start, const char *prefix, const char *suffix, ...) __attribute__((format(printf, 3, 4)));
705
707gboolean dt_supported_image(const gchar *filename);
708
709// a few macros and helper functions to speed up certain frequently-used GLib operations
710#define g_list_is_singleton(list) ((list) && (!(list)->next))
711static inline gboolean g_list_shorter_than(const GList *list, unsigned len)
712{
713 // instead of scanning the full list to compute its length and then comparing against the limit,
714 // bail out as soon as the limit is reached. Usage: g_list_shorter_than(l,4) instead of g_list_length(l)<4
715 while (len-- > 0)
716 {
717 if (!list) return TRUE;
718 list = g_list_next(list);
719 }
720 return FALSE;
721}
722
723// advance the list by one position, unless already at the final node
724static inline GList *g_list_next_bounded(GList *list)
725{
726 return g_list_next(list) ? g_list_next(list) : list;
727}
728
729static inline const GList *g_list_next_wraparound(const GList *list, const GList *head)
730{
731 return g_list_next(list) ? g_list_next(list) : head;
732}
733
734static inline const GList *g_list_prev_wraparound(const GList *list)
735{
736 // return the prior element of the list, unless already on the first element; in that case, return the last
737 // element of the list.
738 return g_list_previous(list) ? g_list_previous(list) : g_list_last((GList*)list);
739}
740
741void dt_print_mem_usage();
742
743void dt_configure_runtime_performance(dt_sys_resources_t *resources, gboolean init_gui);
744
745// helper function which loads whatever image_to_load points to: single image files or whole directories
746// it tells you if it was a single image or a directory in single_image (when it's not NULL)
747int dt_load_from_string(const gchar *image_to_load, gboolean open_image_in_dr, gboolean *single_image);
748
749#define dt_unreachable_codepath_with_desc(D) \
750 dt_unreachable_codepath_with_caller(D, __FILE__, __LINE__, __FUNCTION__)
751#define dt_unreachable_codepath() dt_unreachable_codepath_with_caller("unreachable", __FILE__, __LINE__, __FUNCTION__)
752static inline void dt_unreachable_codepath_with_caller(const char *description, const char *file,
753 const int line, const char *function)
754{
755 fprintf(stderr, "[dt_unreachable_codepath] {%s} %s:%d (%s) - we should not be here. please report this to "
756 "the developers.",
757 description, file, line, function);
758 __builtin_unreachable();
759}
760
761// Allocate a buffer for 'n' objects each of size 'objsize' bytes for each of the program's threads.
762// Ensures that there is no false sharing among threads by aligning and rounding up the allocation to
763// a multiple of the cache line size. Returns a pointer to the allocated pool and the adjusted number
764// of objects in each thread's buffer. Use dt_get_perthread or dt_get_bythread (see below) to access
765// a specific thread's buffer.
766static inline void *dt_alloc_perthread(const size_t n, const size_t objsize, size_t* padded_size)
767{
768 const size_t alloc_size = n * objsize;
769 const size_t cache_lines = (alloc_size + DT_CACHELINE_BYTES - 1) / DT_CACHELINE_BYTES;
770 *padded_size = DT_CACHELINE_BYTES * cache_lines / objsize;
771 return __builtin_assume_aligned(dt_alloc_align(DT_CACHELINE_BYTES * cache_lines * darktable.num_openmp_threads), DT_CACHELINE_BYTES);
772}
773static inline void *dt_calloc_perthread(const size_t n, const size_t objsize, size_t* padded_size)
774{
775 void *const buf = (float*)dt_alloc_perthread(n, objsize, padded_size);
776 memset(buf, 0, *padded_size * darktable.num_openmp_threads * objsize);
777 return buf;
778}
779// Same as dt_alloc_perthread, but the object is a float.
780static inline float *dt_alloc_perthread_float(const size_t n, size_t* padded_size)
781{
782 return (float*)dt_alloc_perthread(n, sizeof(float), padded_size);
783}
784// Allocate floats, cleared to zero
785static inline float *dt_calloc_perthread_float(const size_t n, size_t* padded_size)
786{
787 float *const buf = (float*)dt_alloc_perthread(n, sizeof(float), padded_size);
788 if (buf)
789 {
790 for (size_t i = 0; i < *padded_size * darktable.num_openmp_threads; i++)
791 buf[i] = 0.0f;
792 }
793 return buf;
794}
795
796// Given the buffer and object count returned by dt_alloc_perthread, return the current thread's private buffer.
797#define dt_get_perthread(buf, padsize) DT_IS_ALIGNED((buf) + ((padsize) * dt_get_thread_num()))
798// Given the buffer and object count returned by dt_alloc_perthread and a thread count in 0..darktable.num_openmp_threads,
799// return a pointer to the indicated thread's private buffer.
800#define dt_get_bythread(buf, padsize, tnum) DT_IS_ALIGNED((buf) + ((padsize) * (tnum)))
801
802// Scramble bits in str to create an (hopefully) unique hash representing the state of str
803// Dan Bernstein algo v2 http://www.cse.yorku.ca/~oz/hash.html
804// hash should be inited to 5381 if first run, or from a previous hash computed with this function.
805static inline uint64_t dt_hash(uint64_t hash, const char *str, size_t size)
806{
807 for(size_t i = 0; i < size; i++)
808 hash = ((hash << 5) + hash) ^ str[i];
809
810 return hash;
811}
812
814#define DT_MAX_FILENAME_LEN 256
815
816#ifndef PATH_MAX
817/*
818 * from /usr/include/linux/limits.h (Linux 3.16.5)
819 * Some systems might not define it (e.g. Hurd)
820 *
821 * We do NOT depend on any specific value of this env variable.
822 * If you want constant value across all systems, use DT_MAX_PATH_FOR_PARAMS!
823 */
824#define PATH_MAX 4096
825#endif
826
827/*
828 * ONLY TO BE USED FOR PARAMS!!! (e.g. dt_imageio_disk_t)
829 *
830 * WARNING: this should *NEVER* be changed, as it will break params,
831 * created with previous DT_MAX_PATH_FOR_PARAMS.
832 */
833#define DT_MAX_PATH_FOR_PARAMS 4096
834
835static inline gchar *dt_string_replace(const char *string, const char *to_replace)
836{
837 if(!string || !to_replace) return NULL;
838 gchar **split = g_strsplit(string, to_replace, -1);
839 gchar *text = g_strjoinv("", split);
840 g_strfreev(split);
841 return text;
842}
843
844// Remove underscore from GUI labels containing mnemonics
845static inline gchar *delete_underscore(const char *s)
846{
847 return dt_string_replace(s, "_");
848}
849
857static inline gchar *strip_markup(const char *s)
858{
859 PangoAttrList *attrs = NULL;
860 gchar *plain = NULL;
861
862 const gchar *underscore = "_";
863 gunichar mnemonic = underscore[0];
864 if(!pango_parse_markup(s, -1, mnemonic, &attrs, &plain, NULL, NULL))
865 plain = delete_underscore(s);
866
867 pango_attr_list_unref(attrs);
868 return plain;
869}
870
871#ifdef __cplusplus
872}
873#endif
874
875// clang-format off
876// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
877// vim: shiftwidth=2 expandtab tabstop=2 cindent
878// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
879// clang-format on
const char ** description(struct dt_iop_module_t *self)
Definition ashift.c:129
#define TRUE
Definition ashift_lsd.c:151
#define FALSE
Definition ashift_lsd.c:147
#define DT_ALIGNED_PIXEL
Definition darktable.h:271
static void memset_zero(void *const buffer, size_t size)
Set the memory buffer to zero as a pack of unsigned char.
Definition darktable.h:653
void dt_show_times(const dt_times_t *start, const char *prefix)
Definition darktable.c:1433
static gchar * dt_string_replace(const char *string, const char *to_replace)
Definition darktable.h:835
static float * dt_calloc_align_float(size_t pixels)
Definition darktable.h:349
static void * dt_calloc_align(size_t size)
Definition darktable.h:339
static gboolean dt_modifiers_include(const GdkModifierType state, const GdkModifierType desired_modifier_mask)
Definition darktable.h:673
dt_debug_thread_t
Definition darktable.h:470
@ DT_DEBUG_LIGHTTABLE
Definition darktable.h:481
@ DT_DEBUG_UNDO
Definition darktable.h:490
@ DT_DEBUG_INPUT
Definition darktable.h:485
@ DT_DEBUG_PRINT
Definition darktable.h:486
@ DT_DEBUG_OPENCL
Definition darktable.h:478
@ DT_DEBUG_PIPE
Definition darktable.h:497
@ DT_DEBUG_HISTORY
Definition darktable.h:496
@ DT_DEBUG_CAMERA_SUPPORT
Definition darktable.h:487
@ DT_DEBUG_NAN
Definition darktable.h:482
@ DT_DEBUG_DEMOSAIC
Definition darktable.h:493
@ DT_DEBUG_MEMORY
Definition darktable.h:480
@ DT_DEBUG_PERF
Definition darktable.h:475
@ DT_DEBUG_VERBOSE
Definition darktable.h:499
@ DT_DEBUG_PARAMS
Definition darktable.h:492
@ DT_DEBUG_CONTROL
Definition darktable.h:473
@ DT_DEBUG_CACHE
Definition darktable.h:472
@ DT_DEBUG_SIGNAL
Definition darktable.h:491
@ DT_DEBUG_PWSTORAGE
Definition darktable.h:477
@ DT_DEBUG_SHORTCUTS
Definition darktable.h:494
@ DT_DEBUG_IMAGEIO
Definition darktable.h:489
@ DT_DEBUG_DEV
Definition darktable.h:474
@ DT_DEBUG_CAMCTL
Definition darktable.h:476
@ DT_DEBUG_IMPORT
Definition darktable.h:498
@ DT_DEBUG_IOPORDER
Definition darktable.h:488
@ DT_DEBUG_MASKS
Definition darktable.h:483
@ DT_DEBUG_TILING
Definition darktable.h:495
@ DT_DEBUG_SQL
Definition darktable.h:479
@ DT_DEBUG_LUA
Definition darktable.h:484
void dt_cleanup()
Definition darktable.c:1248
void gboolean dt_supported_image(const gchar *filename)
check if file is a supported image
Definition darktable.c:199
static void copy_pixel(float *const __restrict__ out, const float *const __restrict__ in)
Definition darktable.h:445
int dt_init(int argc, char *argv[], const gboolean init_gui, const gboolean load_data, lua_State *L)
Definition darktable.c:389
#define for_each_channel(_var,...)
Definition darktable.h:411
float dt_boundingbox_t[4]
Definition darktable.h:467
static float * dt_alloc_align_float(size_t pixels)
Definition darktable.h:345
static size_t dt_round_size_sse(const size_t size)
Definition darktable.h:285
void void dt_print_nts(dt_debug_thread_t thread, const char *msg,...) __attribute__((format(printf
static void * dt_check_sse_aligned(void *pointer)
Definition darktable.h:361
static gchar * strip_markup(const char *s)
Remove Pango/Gtk markup and accels mnemonics from text labels. If the markup parsing fails,...
Definition darktable.h:857
darktable_t darktable
Definition darktable.c:111
static void * dt_alloc_align_internal(size_t size)
Definition darktable.h:291
void dt_print_mem_usage()
Definition darktable.c:1686
static void * dt_alloc_perthread(const size_t n, const size_t objsize, size_t *padded_size)
Definition darktable.h:766
static void copy_pixel_nontemporal(float *const __restrict__ out, const float *const __restrict__ in)
Definition darktable.h:426
void void void int dt_worker_threads()
Definition darktable.c:1530
static const GList * g_list_next_wraparound(const GList *list, const GList *head)
Definition darktable.h:729
static int dt_get_thread_num()
Definition darktable.h:227
size_t dt_get_singlebuffer_mem()
Definition darktable.c:1548
void dt_capabilities_remove(char *capability)
Definition darktable.c:1669
void dt_print(dt_debug_thread_t thread, const char *msg,...) __attribute__((format(printf
static void dt_get_times(dt_times_t *t)
Definition darktable.h:693
#define omp_get_thread_num()
Definition darktable.h:219
static const GList * g_list_prev_wraparound(const GList *list)
Definition darktable.h:734
void void void dt_vprint(dt_debug_thread_t thread, const char *msg,...) __attribute__((format(printf
static float * dt_calloc_perthread_float(const size_t n, size_t *padded_size)
Definition darktable.h:785
static int dt_version()
Definition darktable.h:111
static gchar * delete_underscore(const char *s)
Definition darktable.h:845
static uint64_t dt_hash(uint64_t hash, const char *str, size_t size)
Definition darktable.h:805
size_t dt_get_mipmap_mem()
Definition darktable.c:1553
static size_t dt_round_size(const size_t size, const size_t alignment)
Definition darktable.h:279
static void dt_unreachable_codepath_with_caller(const char *description, const char *file, const int line, const char *function)
Definition darktable.h:752
int dt_load_from_string(const gchar *image_to_load, gboolean open_image_in_dr, gboolean *single_image)
Definition darktable.c:215
#define DT_MODULE_VERSION
Definition darktable.h:77
static GList * g_list_next_bounded(GList *list)
Definition darktable.h:724
char * dt_version_major_minor()
Definition darktable.c:168
void dt_configure_runtime_performance(dt_sys_resources_t *resources, gboolean init_gui)
Definition darktable.c:1558
#define dt_free_align(A)
Definition darktable.h:334
void dt_capabilities_add(char *capability)
Definition darktable.c:1658
static double dt_get_wtime(void)
Definition darktable.h:686
void dt_capabilities_cleanup()
Definition darktable.c:1679
static gboolean dt_is_aligned(const void *pointer, size_t byte_count)
Definition darktable.h:274
typedef __attribute__((aligned(16))) float dt_aligned_pixel_t[4]
static gboolean dt_modifier_is(const GdkModifierType state, const GdkModifierType desired_modifier_mask)
Definition darktable.h:665
void dt_show_times_f(const dt_times_t *start, const char *prefix, const char *suffix,...) __attribute__((format(printf
size_t dt_get_available_mem()
Definition darktable.c:1535
int dt_capabilities_check(char *capability)
Definition darktable.c:1645
static float * dt_alloc_perthread_float(const size_t n, size_t *padded_size)
Definition darktable.h:780
static void * dt_calloc_perthread(const size_t n, const size_t objsize, size_t *padded_size)
Definition darktable.h:773
static void * dt_alloc_sse_ps(size_t pixels)
Definition darktable.h:356
#define DT_CACHELINE_BYTES
Definition darktable.h:262
static gboolean g_list_shorter_than(const GList *list, unsigned len)
Definition darktable.h:711
#define dt_pthread_rwlock_t
Definition dtpthread.h:336
int getrusage(int who, struct rusage *usage)
Definition getrusage.c:53
#define RUSAGE_SELF
Definition getrusage.h:50
int lua_State
Definition lua.h:90
size_t size
Definition mipmap_cache.c:3
@ DT_SIGNAL_COUNT
Definition signal.h:250
unsigned __int64 uint64_t
Definition strptime.c:71
Definition darktable.h:522
struct dt_dbus_t * dbus
Definition darktable.h:552
struct dt_undo_t * undo
Definition darktable.h:553
char * tmpdir
Definition darktable.h:589
dt_pthread_mutex_t readFile_mutex
Definition darktable.h:569
char * cachedir
Definition darktable.h:591
dt_codepath_t codepath
Definition darktable.h:523
struct dt_lib_t * lib
Definition darktable.h:537
int32_t unmuted_signal_dbg_acts
Definition darktable.h:597
struct dt_imageio_t * imageio
Definition darktable.h:550
struct dt_dev_pixelpipe_cache_t * pixelpipe_cache
Definition darktable.h:556
int32_t num_openmp_threads
Definition darktable.h:524
struct dt_l10n_t * l10n
Definition darktable.h:555
struct dt_gui_gtk_t * gui
Definition darktable.h:541
dt_pthread_rwlock_t database_threadsafe
Definition darktable.h:582
struct dt_colorspaces_t * color_profiles
Definition darktable.h:554
GList * capabilities
Definition darktable.h:533
GTimeZone * utc_tz
Definition darktable.h:599
char * sharedir
Definition darktable.h:586
struct dt_collection_t * collection
Definition darktable.h:547
struct dt_mipmap_cache_t * mipmap_cache
Definition darktable.h:542
struct dt_selection_t * selection
Definition darktable.h:548
GList * iop
Definition darktable.h:527
dt_pthread_mutex_t exiv2_threadsafe
Definition darktable.h:566
struct dt_sys_resources_t dtresources
Definition darktable.h:601
dt_pthread_mutex_t plugin_threadsafe
Definition darktable.h:559
dt_lua_state_t lua_state
Definition darktable.h:593
char * moduledir
Definition darktable.h:587
dt_pthread_mutex_t capabilities_threadsafe
Definition darktable.h:562
GList * iop_order_list
Definition darktable.h:528
const struct dt_database_t * db
Definition darktable.h:545
GList * iop_order_rules
Definition darktable.h:529
struct dt_control_signal_t * signals
Definition darktable.h:540
struct dt_bauhaus_t * bauhaus
Definition darktable.h:544
struct dt_opencl_t * opencl
Definition darktable.h:551
char * configdir
Definition darktable.h:590
char * datadir
Definition darktable.h:585
GList * themes
Definition darktable.h:596
int32_t unmuted
Definition darktable.h:526
struct dt_image_cache_t * image_cache
Definition darktable.h:543
struct dt_develop_t * develop
Definition darktable.h:536
struct dt_points_t * points
Definition darktable.h:549
char * localedir
Definition darktable.h:588
dt_pthread_mutex_t pipeline_threadsafe
Definition darktable.h:574
struct dt_view_manager_t * view_manager
Definition darktable.h:538
char * kerneldir
Definition darktable.h:592
JsonParser * noiseprofile_parser
Definition darktable.h:534
GList * guides
Definition darktable.h:594
gboolean unmuted_signal_dbg[DT_SIGNAL_COUNT]
Definition darktable.h:598
char * progname
Definition darktable.h:584
struct dt_conf_t * conf
Definition darktable.h:535
GDateTime * origin_gdt
Definition darktable.h:600
const struct dt_pwstorage_t * pwstorage
Definition darktable.h:546
double start_wtime
Definition darktable.h:595
struct dt_control_t * control
Definition darktable.h:539
Definition bauhaus.h:215
Definition darktable.h:503
unsigned int OPENMP_SIMD
Definition darktable.h:506
unsigned int _no_intrinsics
Definition darktable.h:505
unsigned int SSE2
Definition darktable.h:504
Definition collection.h:142
Definition colorspaces.h:152
Definition conf.h:58
Definition signal.c:28
Definition control.h:129
Definition common/database.c:60
Definition dbus.h:25
Definition pixelpipe_cache.h:40
Definition develop.h:143
Definition gtk.h:88
Definition image_cache.h:29
Definition imageio_module.h:114
Definition l10n.h:31
Definition libs/lib.h:42
Definition lua.h:95
Definition mipmap_cache.h:83
Definition opencl.h:494
Definition points.h:38
Definition pwstorage.h:30
Definition selection.c:27
Definition darktable.h:510
size_t headroom_memory
Definition darktable.h:513
size_t total_memory
Definition darktable.h:511
size_t mipmap_memory
Definition darktable.h:512
size_t pixelpipe_memory
Definition darktable.h:514
size_t buffer_memory
Definition darktable.h:515
size_t darkroom_cache
Definition darktable.h:518
Definition darktable.h:605
double clock
Definition darktable.h:606
double user
Definition darktable.h:607
Definition undo.h:58
Definition views/view.h:139
Definition getrusage.h:30
struct timeval ru_utime
Definition getrusage.h:31
#define dt_alloc_align(B)
Definition tests/cache.c:22