95 const char *phase,
const char *slot,
const uint64_t requested_hash,
97 const gboolean verbose)
103 "[pixelpipe_owner] pipe=%s module=%s phase=%s slot=%s req=%" PRIu64
104 " entry=%" PRIu64
"/%" PRIu64
" refs=%i auto=%i data=%p buf=%p name=%s\n",
106 module ? module->op : "base",
110 entry ? entry->hash : DT_PIXELPIPE_CACHE_HASH_INVALID,
111 entry ? entry->serial : 0,
112 entry ? dt_atomic_get_int((dt_atomic_int *)&entry->refcount) : -1,
113 entry ? entry->auto_destroy : -1,
114 entry ? entry->data : NULL,
116 (entry && entry->name) ? entry->name : "-");
121 const char *phase,
const void *buffer,
129 const size_t pixels = (size_t)roi->
width * (
size_t)roi->
height;
130 const unsigned int channels = format->
channels;
134 const float *in = (
const float *)buffer;
135 float minv[4] = { FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX };
136 float maxv[4] = { -FLT_MAX, -FLT_MAX, -FLT_MAX, -FLT_MAX };
137 size_t nonfinite = 0;
138 size_t near_black = 0;
140 for(
size_t k = 0;
k < pixels;
k++, in += channels)
142 gboolean finite =
TRUE;
143 for(
unsigned int c = 0; c <
MIN(channels, 4U); c++)
150 minv[c] = fminf(minv[c], in[c]);
151 maxv[c] = fmaxf(maxv[c], in[c]);
160 const float energy = fabsf(in[0]) + ((channels > 1) ? fabsf(in[1]) : 0.0f)
161 + ((channels > 2) ? fabsf(in[2]) : 0.0f);
162 if(energy < 1e-6f) near_black++;
165 const uint64_t content_hash =
dt_hash(5381, (
const char *)buffer, pixels * channels *
sizeof(
float));
168 "[pixelpipe_stats] pipe=%s module=%s phase=%s type=float ch=%u roi=%dx%d ptr=%p "
169 "content_hash=%" PRIu64
" "
170 "rgb_min=(%g,%g,%g) rgb_max=(%g,%g,%g) a_min=%g a_max=%g near_black=%" G_GSIZE_FORMAT
"/%" G_GSIZE_FORMAT
" nonfinite=%" G_GSIZE_FORMAT
"\n",
172 channels, roi->
width, roi->
height, buffer, content_hash,
173 minv[0], (channels > 1) ? minv[1] : 0.0f, (channels > 2) ? minv[2] : 0.0f,
174 maxv[0], (channels > 1) ? maxv[1] : 0.0f, (channels > 2) ? maxv[2] : 0.0f,
175 (channels > 3) ? minv[3] : 0.0f, (channels > 3) ? maxv[3] : 0.0f,
176 near_black, pixels, nonfinite);
180 const uint8_t *in = (
const uint8_t *)buffer;
181 int minv[4] = { 255, 255, 255, 255 };
182 int maxv[4] = { 0, 0, 0, 0 };
183 size_t near_black = 0;
185 for(
size_t k = 0;
k < pixels;
k++, in += channels)
187 for(
unsigned int c = 0; c <
MIN(channels, 4U); c++)
189 minv[c] =
MIN(minv[c], in[c]);
190 maxv[c] =
MAX(maxv[c], in[c]);
193 const int energy = in[0] + ((channels > 1) ? in[1] : 0) + ((channels > 2) ? in[2] : 0);
194 if(energy == 0) near_black++;
197 const uint64_t content_hash =
dt_hash(5381, (
const char *)buffer, pixels * channels *
sizeof(uint8_t));
200 "[pixelpipe_stats] pipe=%s module=%s phase=%s type=u8 ch=%u roi=%dx%d ptr=%p "
201 "content_hash=%" PRIu64
" "
202 "rgb_min=(%d,%d,%d) rgb_max=(%d,%d,%d) a_min=%d a_max=%d near_black=%" G_GSIZE_FORMAT
"/%" G_GSIZE_FORMAT
"\n",
204 channels, roi->
width, roi->
height, buffer, content_hash,
205 minv[0], (channels > 1) ? minv[1] : 0, (channels > 2) ? minv[2] : 0,
206 maxv[0], (channels > 1) ? maxv[1] : 0, (channels > 2) ? maxv[2] : 0,
207 (channels > 3) ? minv[3] : 0, (channels > 3) ? maxv[3] : 0,
215 const uint64_t output_hash,
void **output,
220 output ? *output : NULL, output_entry,
FALSE);
238 if(output) *output = NULL;
251 && pipe->
realtime && dev &&
module && dev->gui_module == module;
289 const size_t width,
const size_t height,
const size_t chan)
294 const size_t index =
k * chan;
296 output[index + 0] = (float)input[index + 2] / 255.f;
297 output[index + 1] = (float)input[index + 1] / 255.f;
298 output[index + 2] = (float)input[index + 0] / 255.f;
299 output[index + 3] = 0.f;
314 return "display-rgb";
345 const gboolean is_cl,
348 const size_t in_bpp,
const size_t out_bpp,
349 const int cst_before,
const int cst_after)
353 const char *module_name =
module ? module->op : "base";
355 const char *stage_name = stage ? stage :
"process";
360 "[pixelpipe] %s %s %s %s: in cst=%s->%s ch=%d type=%s bpp=%" G_GSIZE_FORMAT
" roi=%dx%d | "
361 "out cst=%s ch=%d type=%s bpp=%" G_GSIZE_FORMAT
" roi=%dx%d\n",
362 pipe_name, module_name, is_cl ?
"cl" :
"cpu", stage_name,
365 roi_in ? roi_in->
width : 0, roi_in ? roi_in->
height : 0,
367 out_bpp, roi_out ? roi_out->
width : 0, roi_out ? roi_out->
height : 0);
372 "[pixelpipe] %s %s %s %s: out cst=%s ch=%d type=%s bpp=%" G_GSIZE_FORMAT
" roi=%dx%d\n",
373 pipe_name, module_name, is_cl ?
"cl" :
"cpu", stage_name,
375 out_bpp, roi_out ? roi_out->
width : 0, roi_out ? roi_out->
height : 0);
523 for(GList *nodes = g_list_first(pipe->
nodes); nodes; nodes = g_list_next(nodes))
537 pipe->
icc_filename = g_strdup(icc_filename ? icc_filename :
"");
567 if(old_backbuf_entry)
650 for(GList *nodes = g_list_first(pipe->
nodes); nodes; nodes = g_list_next(nodes))
659 piece->module->op, piece->module->multi_priority, piece->module->iop_order,
670 piece->module = NULL;
678 g_list_free(pipe->
nodes);
695 for(GList *modules = g_list_first(pipe->
dev->
iop); modules; modules = g_list_next(modules))
700 piece->
enabled =
module->enabled;
702 piece->histogram_params.bins_count = 256;
703 piece->iwidth = pipe->
iwidth;
704 piece->iheight = pipe->
iheight;
705 piece->module =
module;
711 piece->cache_output_on_ram =
TRUE;
714 piece->dsc_mask.channels = 1;
720 pipe->
nodes = g_list_append(pipe->
nodes, piece);
732 module->iop_order, pipe->
type, pipe->
imgid);
734 prev_module =
module;
752 if(output_dsc->
cst != blend_cst
759#define KILL_SWITCH_ABORT \
760 if(dt_dev_pixelpipe_has_shutdown(pipe)) \
762 if(!IS_NULL_PTR(cl_mem_output)) \
764 dt_dev_pixelpipe_cache_release_cl_buffer(&cl_mem_output, NULL, NULL, FALSE); \
771#define KILL_SWITCH_AND_FLUSH_CACHE \
772 if(dt_dev_pixelpipe_has_shutdown(pipe)) \
774 return _abort_module_shutdown_cleanup(pipe, piece, module, input_hash, input, input_entry, hash, &output, \
775 &cl_mem_output, output_entry); \
780 const gboolean recycled_output_cacheline,
dt_times_t *start)
782 char histogram_log[32] =
"";
785 snprintf(histogram_log,
sizeof(histogram_log),
", collected histogram on %s",
797 start,
"[dev_pixelpipe]",
"processed `%s' on %s%s%s%s, %s [%s]", module_label,
802 recycled_output_cacheline ?
", recycled cacheline" :
"",
824 int hasinf = 0, hasnan = 0;
832 float f = ((
float *)(output))[
k];
835 else if(!isfinite(
f))
845 fprintf(stderr,
"[dev_pixelpipe] module `%s' outputs NaNs! [%s]\n", module_label,
848 fprintf(stderr,
"[dev_pixelpipe] module `%s' outputs non-finite floats! [%s]\n", module_label,
850 fprintf(stderr,
"[dev_pixelpipe] module `%s' min: (%f; %f; %f) max: (%f; %f; %f) [%s]\n", module_label,
855 int hasinf = 0, hasnan = 0;
861 float f = ((
float *)(output))[
k];
864 else if(!isfinite(
f))
873 fprintf(stderr,
"[dev_pixelpipe] module `%s' outputs NaNs! [%s]\n", module_label,
876 fprintf(stderr,
"[dev_pixelpipe] module `%s' outputs non-finite floats! [%s]\n", module_label,
878 fprintf(stderr,
"[dev_pixelpipe] module `%s' min: (%f) max: (%f) [%s]\n", module_label,
min,
max,
888 GList *pieces,
int pos)
895 void *cl_mem_output = NULL;
915 module = piece->module;
929 void *existing_output = NULL;
934 const gboolean exact_output_cache_hit
937 &existing_output, &existing_cache)
940 if(exact_output_cache_hit)
947 else if(existing_cache)
961 "[pipeline] module=%s child recursion failed input_hash=%" PRIu64
" output_hash=%" PRIu64
"\n",
962 module->op, input_hash, hash);
979 "[pipeline] module=%s input cache entry missing input_hash=%" PRIu64
" output_hash=%" PRIu64
980 " prev_module=%s prev_hash=%" PRIu64
"\n",
981 module->op, input_hash, hash,
982 !
IS_NULL_PTR(previous_piece) ? previous_piece->module->op :
"",
990 const size_t bufsize = (size_t)piece->dsc_out.bpp * piece->roi_out.width * piece->roi_out.height;
1005 && (piece->dsc_in.bpp == piece->dsc_out.bpp)
1006 && !memcmp(&piece->roi_in, &piece->roi_out,
sizeof(
struct dt_iop_roi_t)))
1013 *out_hash = input_hash;
1014 *out_piece = previous_piece;
1023 piece->roi_out.width, piece->roi_out.height,
1024 piece->roi_out.scale * 100.f);
1033 gchar *
name = g_strdup_printf(
"module %s (%s) for pipe %s", module->op, module->multi_name,
type);
1040 gboolean cache_ram_output
1041 = piece->cache_output_on_ram && (!
_bypass_cache(pipe, piece) || keep_final_output);
1050 cache_ram_output, allow_rekey_reuse,
1051 &piece->cache_entry,
1052 &output, &output_entry);
1065 "[pipeline] module=%s exact-hit entry missing output_hash=%" PRIu64
"\n",
1079 "[pipeline] module=%s writable-exact-hit output_hash=%" PRIu64
" has_host_data=%d"
1080 " cache_ram_output=%d devid=%d\n",
1093 void *restored = NULL;
1094 const gboolean restored_ok
1098 "[pipeline] module=%s exact-hit was device-only, host materialize %s output_hash=%" PRIu64
"\n",
1099 module->op, restored_ok ?
"succeeded" :
"failed", hash);
1114 "[pipeline] module=%s writable output acquisition failed output_hash=%" PRIu64
1115 " acquire_status=%d\n",
1116 module->op, hash, acquire_status);
1123 : (new_entry ?
"acquire-new" :
"acquire-existing"),
1124 "output", hash, output, output_entry,
FALSE);
1129 module->tiling_callback(module, pipe, piece, &tiling);
1153 assert(
tiling.factor > 0.0f);
1154 assert(
tiling.factor_cl > 0.0f);
1166 input_entry, output_entry);
1170 input_entry, output_entry);
1184 "[pipeline] module=%s backend processing failed input_hash=%" PRIu64
" output_hash=%" PRIu64
1185 " input_cst=%d output_cst=%d roi_in=%dx%d roi_out=%dx%d\n",
1186 module->op, input_hash, hash, piece->dsc_in.cst, piece->dsc_out.cst,
1187 piece->roi_in.width, piece->roi_in.height, piece->roi_out.width, piece->roi_out.height);
1213 piece->cache_entry = *output_entry;
1250 piece->hash, input_hash, module->op, module->multi_priority,
1251 module->iop_order, pipe->
type, pipe->
imgid, piece->roi_out.width,
1252 piece->roi_out.height, pipe->
devid,
1278 _print_nan_debug(pipe, cl_mem_output, output, &piece->roi_out, &piece->dsc_out, module);
1291 GList *nodes = g_list_last(pipe->
nodes);
1293 while(strcmp(piece->module->op, op))
1297 nodes = g_list_previous(nodes);
1305 GList *nodes = pipe->
nodes;
1307 while(strcmp(piece->module->op, op))
1311 nodes = g_list_next(nodes);
1317#define KILL_SWITCH_PIPE \
1318 if(dt_dev_pixelpipe_has_shutdown(pipe)) \
1320 if(pipe->devid >= 0) \
1322 dt_opencl_release_device(pipe->devid); \
1327 g_list_free_full(pipe->forms, (void (*)(void *))dt_masks_form_unref); \
1328 pipe->forms = NULL; \
1330 dt_pthread_mutex_unlock(dt_pipeline_threadsafe_mutex()); \
1345 "[opencl] Too many opencl errors; disabling opencl for this session!\n");
1346 dt_pipeline_message(_(
"Ansel discovered problems with your OpenCL setup; disabling OpenCL for this session!"));
1359 entry ? entry->
data : NULL, entry,
FALSE);
1363 || entry_hash != requested_hash)
1409 const size_t pixels = (size_t)roi.
width * (
size_t)roi.
height;
1410 bpp = (int)(entry_size / pixels);
1413 if(entry_size < pixels * 4)
1416 "[pixelpipe] BACKBUF TOO SMALL on pipe %s: roi %dx%d needs %llu bytes, cacheline holds "
1417 "%llu; hash %" PRIu64
"\n",
1419 (
unsigned long long)(pixels * 4), (
unsigned long long)entry_size, (
uint64_t)entry_hash);
1431 const GList *
const last = g_list_last(pipe->
nodes);
1437 "[pixelpipe] BACKBUF SHAPE MISMATCH on pipe %s: advertising %dx%d but %s produced "
1438 "%dx%d; hash %" PRIu64
"\n",
1461 int current_pos = 1;
1462 for(GList *node = g_list_first(pipe->
nodes); node; node = g_list_next(node), current_pos++)
1465 if(piece && piece->
enabled && piece->module == module)
1467 if(pos) *pos = current_pos;
1485 const char *pl =
"other";
1500 fprintf(stderr,
"[memory] before pixelpipe process\n");
1517 const guint pos = g_list_length(pipe->
dev->
iop);
1527 for(GList *node = g_list_first(pipe->
nodes); node; node = g_list_next(node))
1532 GHashTableIter mask_iter;
1533 gpointer mask_key = NULL;
1535 g_hash_table_iter_init(&mask_iter, piece->module->raster_mask.source.masks);
1536 while(g_hash_table_iter_next(&mask_iter, &mask_key, &
mask_name))
1538 const int mask_id = GPOINTER_TO_INT(mask_key);
1545 mask_hash, NULL, NULL))
1550 for(guint
k = 0;
k < previous_raster_refs;
k++)
1555 if(previous_raster_refs > 0)
1562 GList *requested_pieces = g_list_last(pipe->
nodes);
1563 int requested_pos = (int)pos;
1565 gboolean requested_backbuf =
TRUE;
1570 if(requested_pieces)
1572 requested_piece = requested_pieces->
data;
1573 requested_backbuf =
FALSE;
1577 dt_print(
DT_DEBUG_DEV,
"[pixelpipe/gui] requested module cache target disappeared pipe=%s module=%s\n",
1597 if(requested_backbuf)
1615 requested_piece->module->multi_priority)
1632 GList *pieces = g_list_last(pipe->
nodes);
1643 const guint node_count = g_list_length(pipe->
nodes);
1645 size_t invalidated_count = 0;
1646 gboolean reached_provider =
FALSE;
1659 for(GList *node = g_list_first(pipe->
nodes); node; node = g_list_next(node))
1665 if(reached_provider)
1666 invalidated_hashes[invalidated_count++] = piece->
global_hash;
1670 invalidated_hashes, invalidated_count);
1672 "[raster masks] invalidated %" G_GSIZE_FORMAT
" cache states at retry from provider=%" PRIu64
1673 " retained=%d pipe=%s\n",
1683 if(pipe->
devid > -1)
1693 gboolean keep_running =
TRUE;
1695 int opencl_error = 0;
1698 while(keep_running && runs < 3)
1718 requested_backbuf ? pieces : requested_pieces,
1719 requested_backbuf ? pos : requested_pos);
1731 keep_running = (oclerr || (err && pipe->
opencl_error));
1750 void *final_buf = NULL;
1751 if(!requested_backbuf)
1756 &final_entry, pipe->
devid, NULL)
1765 "[picker/rec] final output cache missing pipe=%s hash=%" PRIu64
" history=%" PRIu64
1766 " devid=%d err=%d\n",
1785 if(pipe->
devid >= 0)
static void error(char *msg)
void dt_atomic_set_int(dt_atomic_int *var, int value)
int dt_atomic_get_int(dt_atomic_int *var)
static void * dt_atomic_exch_ptr(dt_atomic_ptr *var, void *value)
int levels(struct dt_imageio_module_data_t *data)
void tiling_callback_blendop(struct dt_iop_module_t *self, const struct dt_dev_pixelpipe_t *pipe, const struct dt_dev_pixelpipe_iop_t *piece, struct dt_develop_tiling_t *tiling)
dt_iop_colorspace_type_t dt_develop_blend_colorspace(const dt_dev_pixelpipe_iop_t *const piece, dt_iop_colorspace_type_t cst)
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
void dt_ioppr_cleanup_profile_info(dt_iop_order_iccprofile_info_t **profile_info)
Release a profile info: its tone-curve LUTs, the struct itself, and the caller's pointer – must be ca...
static const float const float const float min
void dt_print_mem_usage()
void dt_dev_free_history_item(gpointer data)
Release a reference to a history item (used as GList free callback).
uint64_t dt_dev_pixelpipe_node_hash(dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, const dt_iop_roi_t roi_out, const int pos)
void dt_pixelpipe_get_global_hash(dt_dev_pixelpipe_t *pipe)
void dt_dev_pixelpipe_get_roi_in(dt_dev_pixelpipe_t *pipe, const struct dt_iop_roi_t roi_out)
dt_dev_roi_request_t dt_dev_roi_request_neutral(void)
The value a pipe carries before the worker has latched anything.
void dt_dev_set_backbuf(dt_backbuf_t *backbuf, const int width, const int height, const size_t bpp, const int64_t hash, const int64_t history_hash)
gchar * dt_history_item_get_name(const struct dt_iop_module_t *module)
@ DT_DEV_PIXELPIPE_DISPLAY_NONE
static int dt_pthread_mutex_unlock(dt_pthread_mutex_t *mutex) RELEASE(mutex) NO_THREAD_SAFETY_ANALYSIS
static int dt_pthread_mutex_init(dt_pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr)
Initialise a mutex. With mutexattr NULL – which is how 54 of the 56 call sites in this tree spell it ...
static int dt_pthread_mutex_destroy(dt_pthread_mutex_t *mutex)
static int dt_pthread_mutex_lock(dt_pthread_mutex_t *mutex) ACQUIRE(mutex) NO_THREAD_SAFETY_ANALYSIS
dt_pthread_mutex_t * dt_pipeline_threadsafe_mutex(void)
static uint64_t dt_hash(uint64_t hash, const char *str, size_t size)
gboolean dt_iop_is_raster_mask_used(dt_iop_module_t *module, int id)
void dt_iop_init_pipe(struct dt_iop_module_t *module, struct dt_dev_pixelpipe_t *pipe, struct dt_dev_pixelpipe_iop_t *piece)
Build one pixelpipe node's module-owned storage.
void dt_iop_cleanup_pipe(struct dt_iop_module_t *module, struct dt_dev_pixelpipe_t *pipe, struct dt_dev_pixelpipe_iop_t *piece)
Release module-owned resources for one pixelpipe node.
@ IOP_FLAGS_SUPPORTS_BLENDING
@ IOP_FLAGS_TAKE_NO_INPUT
@ IOP_FLAGS_CPU_WRITES_OPENCL
GList * dt_ioppr_iop_order_copy_deep(GList *iop_order_list)
Deep-copy an order list.
_lib_location_type_t type
int32_t dt_get_debug_flags(void)
void dt_print(dt_debug_thread_t thread, const char *msg,...) __attribute__((format(printf
Print to stdout when thread is enabled, prefixed with seconds since startup.
float *const restrict const size_t k
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
GList * dt_masks_snapshot_current_forms(dt_develop_t *dev, gboolean reset_changed)
void dt_masks_form_unref(dt_masks_form_t *form)
static void dt_free_gpointer(gpointer ptr)
g_free() one pointer, with the signature GDestroyNotify wants.
#define dt_free(ptr)
g_free() ptr and set it to NULL, skipping both if it is already NULL.
void dt_opencl_events_reset(const int devid)
cl_int dt_opencl_events_flush(const int devid, const int reset)
void dt_opencl_check_tuning(const int devid)
int dt_opencl_report_pipe_error(void)
Record that a pipe run failed on OpenCL, and decide whether to give up on it.
int dt_opencl_reserve_device_for_pipe(const int pipetype)
Reserve a device for a pipe run: choose a free one by the pipe's priority list and take its lock....
int dt_opencl_update_settings(void)
void dt_opencl_release_device(const int devid)
Release a device reserved by either reserve function.
#define __OMP_FOR_SIMD__(...)
void dt_pipeline_message(const char *format,...)
void dt_pipeline_busy_printf(const char *format,...)
void dt_pipeline_busy_clear(void)
Processing finished; clear the banner.
Everything the pixel pipeline says to whoever is watching: messages for the user, and the busy banner...
uint64_t dt_dev_pixelpipe_raster_mask_hash(const dt_dev_pixelpipe_iop_t *piece, const int raster_mask_id)
void dt_dev_clear_rawdetail_mask(dt_dev_pixelpipe_t *pipe)
Release the side-band detail mask cache reference currently owned by the pipeline.
@ DT_DEV_PIXELPIPE_THUMBNAIL
@ DT_DEV_PIXELPIPE_EXPORT
@ DT_DEV_PIXELPIPE_PREVIEW
void dt_dev_pixelpipe_cache_wrlock_entry(gboolean lock, dt_pixel_cache_entry_t *cache_entry)
Lock or release the write lock on the entry.
int dt_dev_pixelpipe_cache_invalidate_hashes(const uint64_t *hashes, const size_t count)
Invalidate cache lines matching an explicit list of hashes.
void dt_dev_pixelpipe_cache_auto_destroy_apply(dt_pixel_cache_entry_t *cache_entry)
Free the entry if it has the flag "auto_destroy". See dt_dev_pixelpipe_cache_flag_auto_destroy()....
void * dt_pixel_cache_entry_get_data(dt_pixel_cache_entry_t *entry)
void dt_dev_pixelpipe_cache_ref_count_entry(gboolean lock, dt_pixel_cache_entry_t *cache_entry)
Increase/Decrease the reference count on the cache line as to prevent LRU item removal....
gboolean dt_dev_pixelpipe_cache_peek(const uint64_t hash, void **data, dt_pixel_cache_entry_t **entry, const int preferred_devid, void **cl_mem_output)
Non-owning lookup of an existing cache line.
void dt_dev_pixelpipe_cache_rdlock_entry(gboolean lock, dt_pixel_cache_entry_t *cache_entry)
Lock or release the read lock on the entry.
void dt_dev_pixelpipe_cache_flush_clmem_for_pipe(const int devid)
Like dt_dev_pixelpipe_cache_flush_clmem(), for callers that do not hold the device lock (dt_opencl_re...
void dt_dev_pixelpipe_cache_release_cl_buffer(void **cl_mem_buffer, dt_pixel_cache_entry_t *cache_entry, void *host_ptr, const gboolean cache_device)
Release or cache an OpenCL image associated with a host cache line.
void dt_dev_pixelpipe_cache_print(void)
void dt_dev_pixelpipe_cache_flush_entry_clmem(dt_pixel_cache_entry_t *entry)
Flush all reusable OpenCL payloads cached on one cache entry.
gboolean dt_dev_pixelpipe_cache_restore_host_payload(dt_pixel_cache_entry_t *cache_entry, const int preferred_devid, void **data)
Materialize a host payload for a live cache entry from its cached device payload.
dt_pixel_cache_entry_t * dt_dev_pixelpipe_cache_get_entry(const uint64_t hash)
Get an internal reference to the cache entry matching hash. If you are going to access this entry mor...
dt_dev_pixelpipe_cache_writable_status_t dt_dev_pixelpipe_cache_get_writable(const uint64_t hash, const size_t size, const char *name, const int id, const gboolean alloc, const gboolean allow_rekey_reuse, const dt_pixel_cache_entry_t *reuse_hint, void **data, dt_pixel_cache_entry_t **entry)
int dt_dev_pixelpipe_cache_remove(const gboolean force, dt_pixel_cache_entry_t *cache_entry)
Arbitrarily remove the cache entry matching hash. Entries having a reference count > 0 (inter-thread ...
size_t dt_pixel_cache_entry_get_size(dt_pixel_cache_entry_t *entry)
Peek the size (in bytes) reserved for the host buffer of a cache entry.
void dt_dev_pixelpipe_cache_unref_hash(const uint64_t hash)
Find the entry matching hash, and decrease its ref_count if found.
gboolean dt_dev_pixelpipe_cache_ref_entry_by_hash(const uint64_t hash, void **data, dt_pixel_cache_entry_t **entry)
Resolve and retain an existing cache entry by hash.
void dt_dev_pixelpipe_cache_flag_auto_destroy(dt_pixel_cache_entry_t *cache_entry)
Flag the cache entry as "auto_destroy". This is useful for short-lived/disposable cache entries,...
const char * dt_pixelpipe_cache_set_current_module(const char *module)
Set the current module name for cache diagnostics (thread-local).
Pixelpipe cache for storing intermediate results in the pixelpipe.
#define DT_PIXELPIPE_CACHE_HASH_INVALID
dt_dev_pixelpipe_cache_writable_status_t
@ DT_DEV_PIXELPIPE_CACHE_WRITABLE_REKEYED
@ DT_DEV_PIXELPIPE_CACHE_WRITABLE_CREATED
@ DT_DEV_PIXELPIPE_CACHE_WRITABLE_EXACT_HIT
int pixelpipe_process_on_CPU(dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, const dt_dev_pixelpipe_iop_t *previous_piece, dt_develop_tiling_t *tiling, dt_pixelpipe_flow_t *pixelpipe_flow, gboolean *const cache_output, dt_pixel_cache_entry_t *input_entry, dt_pixel_cache_entry_t *output_entry)
int pixelpipe_process_on_GPU(dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, const dt_dev_pixelpipe_iop_t *previous_piece, dt_develop_tiling_t *tiling, dt_pixelpipe_flow_t *pixelpipe_flow, gboolean *const cache_output, dt_pixel_cache_entry_t *input_entry, dt_pixel_cache_entry_t *output_entry)
void dt_dev_pixelpipe_gpu_flush_host_pinned_images(dt_dev_pixelpipe_t *pipe, void *host_ptr, dt_pixel_cache_entry_t *cache_entry, const char *reason)
void dt_dev_pixelpipe_set_input(dt_dev_pixelpipe_t *pipe, int32_t imgid, int width, int height, float iscale, dt_mipmap_size_t size)
dt_pixelpipe_blend_transform_t dt_dev_pixelpipe_transform_for_blend(const dt_iop_module_t *const self, const dt_dev_pixelpipe_iop_t *const piece, const dt_iop_buffer_dsc_t *const output_dsc)
static void _trace_buffer_content(const dt_dev_pixelpipe_t *pipe, const dt_iop_module_t *module, const char *phase, const void *buffer, const dt_iop_buffer_dsc_t *format, const dt_iop_roi_t *roi)
void dt_dev_pixelpipe_disable_before(dt_dev_pixelpipe_t *pipe, const char *op)
int dt_dev_pixelpipe_init_dummy(dt_dev_pixelpipe_t *pipe, dt_develop_t *dev)
static gboolean _is_focused_realtime_gui_module(const dt_dev_pixelpipe_t *pipe, const dt_develop_t *dev, const dt_iop_module_t *module)
void dt_dev_pixelpipe_reset_reentry(dt_dev_pixelpipe_t *pipe)
int dt_dev_pixelpipe_init_cached(dt_dev_pixelpipe_t *pipe)
static void _update_backbuf_cache_reference(dt_dev_pixelpipe_t *pipe, dt_iop_roi_t roi, dt_pixel_cache_entry_t *entry)
gboolean dt_dev_pixelpipe_has_reentry(dt_dev_pixelpipe_t *pipe)
void dt_dev_pixelpipe_disable_after(dt_dev_pixelpipe_t *pipe, const char *op)
int dt_dev_pixelpipe_init(dt_dev_pixelpipe_t *pipe, dt_develop_t *dev)
gboolean dt_dev_pixelpipe_cache_gpu_device_buffer(const dt_dev_pixelpipe_t *pipe, const dt_pixel_cache_entry_t *cache_entry)
gboolean dt_dev_pixelpipe_get_realtime(const dt_dev_pixelpipe_t *pipe)
static const char * _debug_type_to_string(const dt_iop_buffer_type_t type)
static const char * _debug_cst_to_string(const int cst)
#define KILL_SWITCH_ABORT
void dt_dev_pixelpipe_set_icc(dt_dev_pixelpipe_t *pipe, dt_colorspaces_color_profile_type_t icc_type, const gchar *icc_filename, dt_iop_color_intent_t icc_intent)
static int _abort_module_shutdown_cleanup(dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece, dt_iop_module_t *module, const uint64_t input_hash, const void *input, dt_pixel_cache_entry_t *input_entry, const uint64_t output_hash, void **output, void **cl_mem_output, dt_pixel_cache_entry_t *output_entry)
static int dt_dev_pixelpipe_process_rec(dt_dev_pixelpipe_t *pipe, uint64_t *out_hash, const dt_dev_pixelpipe_iop_t **out_piece, GList *pieces, int pos)
char * dt_pixelpipe_get_pipe_name(dt_dev_pixelpipe_type_t pipe_type)
static void _print_opencl_errors(int error, dt_dev_pixelpipe_t *pipe)
static void _trace_cache_owner(const dt_dev_pixelpipe_t *pipe, const dt_iop_module_t *module, const char *phase, const char *slot, const uint64_t requested_hash, const void *buffer, const dt_pixel_cache_entry_t *entry, const gboolean verbose)
static GList * _get_requested_piece_node(const dt_dev_pixelpipe_t *pipe, const dt_iop_module_t *module, int *pos)
int dt_dev_pixelpipe_init_preview(dt_dev_pixelpipe_t *pipe, dt_develop_t *dev)
static void _print_nan_debug(dt_dev_pixelpipe_t *pipe, void *cl_mem_output, void *output, const dt_iop_roi_t *roi_out, dt_iop_buffer_dsc_t *out_format, dt_iop_module_t *module)
void dt_dev_pixelpipe_create_nodes(dt_dev_pixelpipe_t *pipe)
int dt_dev_pixelpipe_init_thumbnail(dt_dev_pixelpipe_t *pipe, dt_develop_t *dev)
int dt_dev_pixelpipe_init_export(dt_dev_pixelpipe_t *pipe, dt_develop_t *dev, int levels, gboolean store_masks)
void dt_dev_pixelpipe_cleanup(dt_dev_pixelpipe_t *pipe)
gboolean dt_dev_pixelpipe_unset_reentry(dt_dev_pixelpipe_t *pipe, uint64_t hash)
Remove the re-entry pipeline flag, only if the object identifier is the one that set it....
int dt_dev_pixelpipe_process(dt_dev_pixelpipe_t *pipe, dt_iop_roi_t roi)
void dt_dev_pixelpipe_set_mask_rasterization_step(dt_dev_pixelpipe_t *pipe, const int step)
Set the drawn-mask rasterisation step for the frame this pipe is about to run.
static void _print_perf_debug(dt_dev_pixelpipe_t *pipe, const dt_pixelpipe_flow_t pixelpipe_flow, dt_dev_pixelpipe_iop_t *piece, dt_iop_module_t *module, const gboolean recycled_output_cacheline, dt_times_t *start)
static void _uint8_to_float(const uint8_t *const input, float *const output, const size_t width, const size_t height, const size_t chan)
void dt_dev_pixelpipe_debug_dump_module_io(dt_dev_pixelpipe_t *pipe, dt_iop_module_t *module, const char *stage, const gboolean is_cl, const dt_iop_buffer_dsc_t *in_dsc, const dt_iop_buffer_dsc_t *out_dsc, const dt_iop_roi_t *roi_in, const dt_iop_roi_t *roi_out, const size_t in_bpp, const size_t out_bpp, const int cst_before, const int cst_after)
#define KILL_SWITCH_AND_FLUSH_CACHE
gboolean dt_dev_pixelpipe_set_reentry(dt_dev_pixelpipe_t *pipe, uint64_t hash)
Set the re-entry pipeline flag, only if no object is already capturing it.
void dt_dev_pixelpipe_set_realtime(dt_dev_pixelpipe_t *pipe, gboolean state)
void dt_dev_pixelpipe_cleanup_nodes(dt_dev_pixelpipe_t *pipe)
static dt_dev_pixelpipe_cache_request_t dt_dev_pixelpipe_get_cache_request(const dt_dev_pixelpipe_t *pipe)
static void dt_dev_pixelpipe_set_hash(dt_dev_pixelpipe_t *pipe, const uint64_t hash)
static const struct dt_iop_module_t * dt_dev_pixelpipe_get_cache_request_module(const dt_dev_pixelpipe_t *pipe)
static uint64_t dt_dev_pixelpipe_get_hash(const dt_dev_pixelpipe_t *pipe)
static void dt_dev_pixelpipe_reset_cache_request(dt_dev_pixelpipe_t *pipe)
static uint64_t dt_dev_pixelpipe_get_history_hash(const dt_dev_pixelpipe_t *pipe)
static void dt_dev_pixelpipe_set_history_hash(dt_dev_pixelpipe_t *pipe, const uint64_t history_hash)
static uint64_t dt_dev_backbuf_get_hash(const dt_backbuf_t *backbuf)
dt_dev_pixelpipe_cache_request_t
@ DT_DEV_PIXELPIPE_CACHE_REQUEST_NONE
@ DT_DEV_PIXELPIPE_CACHE_REQUEST_MODULE
static void dt_dev_pixelpipe_set_changed(dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_change_t v)
static gboolean dt_dev_pixelpipe_has_shutdown(const dt_dev_pixelpipe_t *pipe)
@ PIXELPIPE_FLOW_HISTOGRAM_ON_GPU
@ PIXELPIPE_FLOW_HISTOGRAM_NONE
@ PIXELPIPE_FLOW_PROCESSED_ON_CPU
@ PIXELPIPE_FLOW_PROCESSED_WITH_TILING
@ PIXELPIPE_FLOW_PROCESSED_ON_GPU
@ PIXELPIPE_FLOW_BLENDED_ON_CPU
@ PIXELPIPE_FLOW_HISTOGRAM_ON_CPU
@ PIXELPIPE_FLOW_BLENDED_ON_GPU
static void _reset_piece_cache_entry(dt_dev_pixelpipe_iop_t *piece)
Drop the writable-reuse snapshot attached to a pipeline piece.
static gboolean _bypass_cache(const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece)
Tell whether the current pipeline state forbids keeping this module output in cache.
dt_pixelpipe_blend_transform_t
@ DT_DEV_PIXELPIPE_BLEND_TRANSFORM_INPUT
@ DT_DEV_PIXELPIPE_BLEND_TRANSFORM_NONE
@ DT_DEV_PIXELPIPE_BLEND_TRANSFORM_OUTPUT
Raster-mask retrieval and transport through already-processed pipeline nodes.
Raw-detail mask transport helpers.
The colour-profile vocabulary, and nothing else.
dt_iop_color_intent_t
ICC rendering intent, as stored in iop params and in conf.
@ DT_INTENT_LAST
Count of real intents, and the codebase's "unset" marker – never a user choice.
dt_colorspaces_color_profile_type_t
@ DT_COLORSPACE_NONE
No profile / "take it from the image settings". Never matches a list entry.
void dt_sentry_set_processed_image(const struct dt_image_t *img, const char *pipeline)
#define DT_DEBUG_CONTROL_SIGNAL_RAISE(ctlsig, signal,...)
struct dt_control_signal_t * dt_control_signal_get_global(void)
@ DT_SIGNAL_CACHELINE_READY
This signal is raised when one cacheline write lock is released. 1 : uint64_t cacheline hash no retur...
DT_ALIGNED_PIXEL float dt_aligned_pixel_t[4]
const float uint32_t state[4]
unsigned __int64 uint64_t
dt_dev_request_flags_t request_histogram
dt_iop_buffer_dsc_t dsc_in
struct dt_iop_module_t *void * data
dt_atomic_ptr last_history_item
dt_colorspaces_color_profile_type_t icc_type
struct dt_iop_order_iccprofile_info_t * input_profile_info
gboolean gui_observable_source
uint64_t last_history_hash
dt_pthread_mutex_t busy_mutex
dt_imageio_levels_t levels
dt_iop_color_intent_t icc_intent
int mask_rasterization_step
Rasterisation step for drawn masks, in image pixels. Always >= 1.
dt_dev_pixelpipe_type_t type
gboolean store_all_raster_masks
uint64_t rawdetail_mask_hash
GArray * raster_mask_hashes
dt_dev_roi_request_store_t roi_request
The viewport snapshot this run was planned from.
struct dt_develop_t * dev
struct dt_iop_order_iccprofile_info_t * owned_input_profile_info
dt_dev_roi_request_t value
struct dt_develop_t::@13 color_picker
Authoritative darkroom color-picker state.
struct dt_develop_t::@20 progress
struct dt_iop_module_t * pending_module
struct dt_dev_pixelpipe_t * pending_pipe
dt_iop_buffer_type_t datatype
Region of interest passed through the pixelpipe.
uint64_t producer_node_key
uint64_t dt_supervisor_node_key(const int pipe_type, const char *op_name, const int multi_priority)
void dt_supervisor_cacheline_create(const uint64_t hash, const uint64_t node_hash, const uint64_t param_hash, const uint64_t input_hash, const char *op_name, const int multi_priority, const int iop_order, const int pipe_type, const int32_t imgid, const int roi_w, const int roi_h, const int devid, const size_t size, const char *name)
void dt_supervisor_node(const dt_sv_op_t op, const uint64_t node_hash, const uint64_t param_hash, const uint64_t predecessor_hash, const char *op_name, const int multi_priority, const int iop_order, const int pipe_type, const int32_t imgid)
void dt_supervisor_backbuf(const dt_sv_op_t op, const uint64_t hash, const uint64_t history_hash, const int w, const int h, const int bpp, const int pipe_type, const int devid)
static gboolean dt_supervisor_active(void)
void dt_telemetry_record_file_type(const struct dt_image_t *img, const char *pipeline)
void dt_show_times(const dt_times_t *start, const char *prefix)
static void dt_get_times(dt_times_t *t)
void dt_show_times_f(const dt_times_t *start, const char *prefix, const char *suffix,...) __attribute__((format(printf
static const char * mask_name