46 const uint32_t history_end, GList *start_node,
47 const char *debug_label);
52 const guint64 producer_node_key,
70 return G_SOURCE_REMOVE;
73 return G_SOURCE_REMOVE;
79 return G_SOURCE_REMOVE;
83 return G_SOURCE_REMOVE;
91 "[cache-wait] pending id=%" PRIu64
" owner=%s hash=%" PRIu64
92 " target=%s connected=%d age_ms=%" PRId64
"\n",
98 MAX(age_us / 1000, 0));
103 const char *context = !
IS_NULL_PTR(reason) ? reason :
"unspecified";
105 uint64_t queued = 0, served = 0, cancelled = 0, immediate = 0, misses = 0;
109 "[cache-wait] dump reason=%s pending=%u queued=%" PRIu64
" served=%" PRIu64
110 " cancelled=%" PRIu64
" immediate=%" PRIu64
" misses=%" PRIu64
"\n",
125 return !strcmp(module->
op,
"initialscale") || !strcmp(module->
op,
"colorout");
136 return !strcmp(module->
op,
"gamma");
156 if(module == picker_module)
return TRUE;
161 return !
IS_NULL_PTR(previous_piece) && previous_piece->module ==
module;
172 for(GList *nodes = g_list_first(
pipe->
nodes); nodes; nodes = g_list_next(nodes))
186 for(GList *nodes = g_list_first(
pipe->
nodes); nodes; nodes = g_list_next(nodes))
191 if(!strcmp(
piece->module->op,
"detailmask")) detailmask_piece =
piece;
192 if(
piece->detail_mask)
262 if(!transient && !realtime)
return FALSE;
264 const uint32_t history_end = (uint32_t)snap->
history_end;
265 if(history_end == 0)
return FALSE;
279 gboolean used_transient =
FALSE;
288 used_transient =
TRUE;
330 GList *last_item = g_list_nth(snap->
items, history_end - 1);
389 gboolean current_output_must_cache_host =
TRUE;
391 for(GList *pieces = g_list_last(
pipe->
nodes); pieces; pieces = g_list_previous(pieces))
397 gboolean supports_opencl =
FALSE;
402 gchar *
string = g_strdup_printf(
"/plugins/%s/cache", module->op);
406 const gboolean authored_cache =
piece->cache_output_on_ram;
411 const gboolean global_hist_output_on
413 const gboolean global_hist_input_on
415 const gboolean module_hist_on
421 const gboolean active_in_gui
423 && focused_module == module;
431 .user_requested_cache = user_requested_cache,
432 .supports_opencl = supports_opencl,
433 .color_picker_on = color_picker_on,
434 .global_hist_output_on = global_hist_output_on,
435 .global_hist_input_on = global_hist_input_on,
436 .module_hist_on = module_hist_on,
437 .active_in_gui = active_in_gui,
438 .has_autoset = has_autoset };
442 piece->cache_output_on_ram
444 ¤t_output_must_cache_host);
552 && dev->
gui_module->operation_tags_filter() & current_module->operation_tags())
560 const int width_in,
const int height_in,
565 gchar *pipe_name = NULL;
569 for(GList *nodes = g_list_first(
pipe->
nodes); nodes; nodes = g_list_next(nodes))
574 piece->buf_in = roi_in;
583 module->modify_roi_out(module, pipe, piece, &roi_out, &roi_in);
592 "[roi-out] pipe=%-15s module=%-18s enabled=%d in =(x=%5d y=%5d w=%5d h=%5d scale=%2.2f)"
593 " out=(x=%5d y=%5d w=%5d h=%5d scale=%2.2f)\n",
594 pipe_name, module->op,
piece->enabled,
598 piece->buf_out = roi_out;
602 if(pipe_name)
dt_free(pipe_name);
625 for(GList *node = g_list_first(
pipe->
nodes); node; node = g_list_next(node))
630 piece->upstream_hash = upstream;
638 upstream =
dt_hash(upstream, (
const char *)&bypass_distort,
sizeof(
int));
667 gchar *pipe_name = NULL;
675 for(GList *nodes = g_list_last(
pipe->
nodes); nodes; nodes = g_list_previous(nodes))
680 piece->roi_out = roi_out_temp;
691 module->modify_roi_in(module, pipe, piece, &roi_out_temp, &roi_in);
695 roi_in = roi_out_temp;
703 "[roi-in ] pipe=%-15s module=%-18s enabled=%d out=(x=%5d y=%5d w=%5d h=%5d scale=%2.2f)"
704 " in=(x=%5d y=%5d w=%5d h=%5d scale=%2.2f)\n",
705 pipe_name, module->op,
piece->enabled,
706 roi_out_temp.
x, roi_out_temp.
y, roi_out_temp.
width, roi_out_temp.
height, roi_out_temp.
scale,
709 piece->roi_in = roi_in;
710 roi_out_temp = roi_in;
715 if(pipe_name)
dt_free(pipe_name);
723 for(GList *nodes = g_list_first(
pipe->
nodes); nodes; nodes = g_list_next(nodes))
730 memcpy(
piece->dsc_in.xtrans, upstream_dsc.
xtrans,
sizeof(
piece->dsc_in.xtrans));
734 && (!
piece->enabled || strcmp(
piece->module->op,
"rawprepare")))
736 piece->dsc_out.filters =
piece->dsc_in.filters;
737 memcpy(
piece->dsc_out.xtrans,
piece->dsc_in.xtrans,
sizeof(
piece->dsc_out.xtrans));
740 upstream_dsc =
piece->dsc_out;
753 return piece->global_hash;
760 return dt_hash(
hash, (
const char *)&pos,
sizeof(
int));
769 for(GList *node = g_list_first(
pipe->
nodes); node; node = g_list_next(node))
787 for(node = g_list_previous(node); node; node = g_list_previous(node))
790 if(previous && previous->
enabled)
801 gpointer restart_data,
const gboolean retain)
860 if(!
IS_NULL_PTR(cache_entry)) *cache_entry = entry;
875 gboolean request_cacheline =
TRUE;
878 const gboolean changed_target = !wait->
connected
885 gboolean activate_wait_cursor =
FALSE;
914 piece->module->multi_priority)
928 if(queue_became_busy)
939 activate_wait_cursor =
TRUE;
942 if(activate_wait_cursor)
946 "[cache-wait] queued id=%" PRIu64
" owner=%s hash=%" PRIu64
" target=%s\n",
963 request_cacheline =
FALSE;
977 if(request_cacheline)
985 dt_print(
DT_DEBUG_DEV,
"[pixelpipe/gui] request host cache pipe=%s target=%s hash=%" PRIu64
"\n",
997 gpointer restart_data)
1006 gpointer restart_data)
1040 const guint64 producer_node_key,
1043 gboolean restore_wait_cursor =
FALSE;
1044 gboolean drained =
FALSE;
1060 restore_wait_cursor =
TRUE;
1062 if(restore_wait_cursor)
1065 for(GList *iter = to_restart; iter; iter = g_list_next(iter))
1069 gpointer restart_data = wait->
user_data;
1073 const gboolean drift_serve = wait->
hash !=
hash;
1076 "[cache-wait] served id=%" PRIu64
" owner=%s awaited=%" PRIu64
" published=%" PRIu64
1082 drift_serve ?
" (drift: node-key)" :
"");
1090 drift_serve ?
"served (drift: node-key)" :
"served");
1093 wait->module = NULL;
1102 g_list_free(to_restart);
1108 gboolean restore_wait_cursor =
FALSE;
1111 const char *owner_tag = wait->
owner_tag;
1115 const gboolean had_module = !
IS_NULL_PTR(wait->module);
1117 const char *module_op = had_module ? wait->
module_op : NULL;
1119 const int cancel_pipe_type = wait->
pipe_type;
1120 const int32_t cancel_pipe_imgid = wait->
pipe_imgid;
1121 const char *cancel_reason = !
IS_NULL_PTR(reason) ? reason :
"unspecified";
1123 gboolean drained =
FALSE;
1135 restore_wait_cursor =
TRUE;
1137 if(restore_wait_cursor)
1142 const int64_t age_ms = -1;
1144 "[cache-wait] cancelled id=%" PRIu64
" owner=%s hash=%" PRIu64
1145 " target=%s age_ms=%" PRId64
" reason=%s\n",
1147 !
IS_NULL_PTR(owner_tag) ? owner_tag :
"(unknown)",
1149 had_module ? module_op :
"backbuf",
1156 g_snprintf(note,
sizeof(note),
"cancelled: %s", cancel_reason);
1158 module_op, module_multi_priority,
1159 had_pipe ? cancel_pipe_type : -1,
1160 had_pipe ? cancel_pipe_imgid : -1,
FALSE, note);
1164 wait->module = NULL;
1174 const char *owner_tag,
1175 gpointer owner_object)
1206 default:
return "?";
1213 piece->dsc_in = *upstream_dsc;
1214 piece->dsc_out = *upstream_dsc;
1221 if(!
piece->enabled)
return;
1251 piece->dsc_in = actual_input_dsc;
1252 piece->dsc_out = actual_input_dsc;
1257 *upstream_dsc =
piece->dsc_out;
1289 for(GList *nodes = g_list_first(
pipe->
nodes); nodes; nodes = g_list_next(nodes))
1299 piece->dsc_in = actual_input_dsc;
1300 piece->dsc_out = actual_input_dsc;
1319 const gboolean input_mismatch
1320 = (declared_in.
bpp != actual_input_dsc.
bpp
1326 dt_control_log(_(
"disabled module `%s`: unexpected input buffer format"),
1327 piece->module->name());
1329 "[pixelpipe] disabling module %s because input format expects %" G_GSIZE_FORMAT
1330 " B/px, %u channels, filters %u but upstream publishes %" G_GSIZE_FORMAT
1331 " B/px, %u channels, filters %u\n",
1341 piece->dsc_in = actual_input_dsc;
1342 piece->dsc_out = actual_input_dsc;
1360 piece->dsc_in = declared_in;
1367 "[dsc] pipe=%s module=%s enabled=%d in=(cst=%s ch=%i bpp=%" G_GSIZE_FORMAT
1368 " filters=%u) out=(cst=%s ch=%i bpp=%" G_GSIZE_FORMAT
" filters=%u)\n",
1369 pipe_name,
piece->module->op,
piece->enabled,
1373 upstream_dsc =
piece->dsc_out;
1383 const uint32_t history_end,
const char *debug_label)
1388 for(GList *nodes = g_list_first(
pipe->
nodes); nodes; nodes = g_list_next(nodes))
1398 piece->enabled =
piece->module->default_enabled;
1404 gboolean found_history =
FALSE;
1406 for(GList *history = g_list_nth(history_list, history_end - 1);
1408 history = g_list_previous(history))
1411 if(
piece->module == hist->module)
1416 history_param_hash = hist->
hash;
1417 found_history =
TRUE;
1422 piece->detail_mask = blend_params && blend_params->
details != 0.0f;
1423 if(!strcmp(
piece->module->op,
"detailmask"))
1439 piece->module->op,
piece->module->multi_name, debug_label);
1452 const uint32_t history_end, GList *start_node,
1453 const char *debug_label)
1459 for(GList *node = g_list_first(
pipe->
nodes); node && node != start_node; node = g_list_next(node))
1464 upstream_dsc =
piece->dsc_out;
1467 for(GList *nodes = start_node; nodes; nodes = g_list_next(nodes))
1478 piece->enabled =
piece->module->default_enabled;
1484 gboolean found_history =
FALSE;
1486 for(GList *history = g_list_nth(history_list, history_end - 1);
1488 history = g_list_previous(history))
1491 if(
piece->module == hist->module)
1496 history_param_hash = hist->
hash;
1497 found_history =
TRUE;
1502 piece->detail_mask = blend_params && blend_params->
details != 0.0f;
1503 if(!strcmp(
piece->module->op,
"detailmask"))
1519 piece->module->op,
piece->module->multi_name, debug_label);
1526 if(detailmask_node && detailmask_node != start_node)
1542 gboolean passthrough_preview =
FALSE;
1551 gboolean bypass_cache =
FALSE;
1553 for(GList *node = g_list_first(
pipe->
nodes); node; node = g_list_next(node))
1556 if(!
piece->enabled)
continue;
1569 if(passthrough_preview
1639 local_hash =
dt_hash(local_hash, (
const char *)&
piece->module->request_mask_display,
sizeof(
int));
1649 local_hash =
dt_hash(local_hash, (
const char *)&revision,
sizeof(revision));
1661 local_hash =
dt_hash(local_hash, (
const char *)&
piece->module->bypass_cache_variant,
sizeof(
int));
1666 local_hash =
dt_hash(local_hash, (
const char *)&zero,
sizeof(
int));
1667 local_hash =
dt_hash(local_hash, (
const char *)&zero,
sizeof(
int));
1675 local_hash =
dt_hash(local_hash, (
const char *)&bypass_distort,
sizeof(
int));
1688 "[pixelpipe] global hash for %20s (%s) in pipe %s enabled=%d bypass_cache=%d with hash %lu\n",
1690 (
long unsigned int)
hash);
1711 passthrough_preview =
TRUE;
1734 const char *caller_func)
1737 dt_print(
DT_DEBUG_DEV,
"[pixelpipe] synch all modules with history for pipe %s called from %s\n",
type, caller_func);
1739 const uint32_t history_end = (uint32_t)snap->
history_end;
1743 GList *last_item = g_list_nth(snap->
items, history_end - 1);
1784 const uint32_t history_end = (uint32_t)snap->
history_end;
1785 GList *last_item = g_list_nth(snap->
items, history_end - 1);
1794 GList *first_item = NULL;
1795 for(GList *history = last_item; history; history = g_list_previous(history))
1798 first_item = history;
1804 GList *fence_item = g_list_nth(snap->
items, history_end);
1805 for(GList *history = first_item; history && history != fence_item; history = g_list_next(history))
1808 if(!hist || !hist->module)
continue;
1811 for(GList *nodes = g_list_last(
pipe->
nodes); nodes; nodes = g_list_previous(nodes))
1851 for(GList *nodes = g_list_first(
pipe->
nodes); nodes; nodes = g_list_next(nodes))
1878 char *status_str = g_strdup_printf(
"%s%s%s%s%s%s%s%s",
1888 dt_print(
DT_DEBUG_DEV,
"[dt_dev_pixelpipe_change] pipeline state changing for pipe %s, flag %s\n",
1923 const double _history_mutex_hold_start =
dt_get_wtime();
1928 const double _history_mutex_hold_ms = (
dt_get_wtime() - _history_mutex_hold_start) * 1000.0;
1929 if(_history_mutex_hold_ms > 1.0)
1931 "[dt_dev_pixelpipe_change] tid %lu pipe %s held history_mutex for %.2f ms (status 0x%x)\n",
1932 (
unsigned long)pthread_self(),
type, _history_mutex_hold_ms, (
unsigned)
status);
1937 gboolean formats_propagated =
FALSE;
1959 formats_propagated =
TRUE;
1977 const double _resync_ms = (
dt_get_wtime() - _history_mutex_hold_start) * 1000.0;
1978 if(_resync_ms > 1.0)
1980 "[dt_dev_pixelpipe_change] tid %lu pipe %s resynced from snapshot in %.2f ms, lock-free (status 0x%x)\n",
1981 (
unsigned long)pthread_self(),
type, _resync_ms, (
unsigned)
status);
1988 if(!formats_propagated)
1999 dt_show_times_f(&start,
"[dev_pixelpipe] pipeline resync with history",
"for pipe %s",
type);
struct dt_ui_t * dt_gui_get_ui(void)
GtkWidget * dt_gui_center_widget(void)
void dt_atomic_set_int(dt_atomic_int *var, int value)
int dt_atomic_get_int(dt_atomic_int *var)
int dt_atomic_exch_int(dt_atomic_int *var, int value)
static void * dt_atomic_exch_ptr(dt_atomic_ptr *var, void *value)
static void * dt_atomic_get_ptr(const dt_atomic_ptr *var)
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
void dt_conf_set_bool(const char *name, int val)
int dt_conf_get_bool(const char *name)
int dt_conf_key_exists(const char *key)
Does key have a value?
gboolean dt_conf_key_not_empty(const char *name)
void dt_control_log(const char *msg,...)
void dt_control_queue_redraw_center()
Request a redraw of the centre view.
void dt_control_change_cursor_by_name_and_flush(const char *curs_str)
Apply a named cursor immediatelly and flush display updates for immediate feedback.
void dt_control_commit_cursor()
void dt_control_navigation_redraw()
Request a redraw of the navigation module's widget.
struct dt_control_t * dt_control_get_global(void)
struct dt_gui_gtk_t * dt_gui_get_global(void)
gboolean dt_dev_transient_params_get(dt_develop_t *dev, const dt_iop_module_t *module, void *out_params, const size_t out_params_size, void *out_blend, const size_t out_blend_size, gboolean *out_has_blend, uint64_t *out_serial)
void dt_dev_history_snapshot_release(dt_dev_history_snapshot_t *snapshot)
Release every reference a snapshot holds and reset it. Needs no lock.
void dt_dev_free_history_item(gpointer data)
Release a reference to a history item (used as GList free callback).
dt_dev_history_item_t * dt_dev_history_item_ref(dt_dev_history_item_t *item)
Take a reference on a history item. Pair with dt_dev_free_history_item().
void dt_dev_history_snapshot_take(dt_develop_t *dev, dt_dev_history_snapshot_t *snapshot) REQUIRES_SHARED(dev -> history_mutex)
Take a snapshot of dev->history. Caller holds history_mutex (reader suffices).
dt_dev_history_item_t * dt_dev_history_get_last_item_by_module(GList *history_list, dt_iop_module_t *module, int history_end)
Find the last history item referencing a module up to history_end.
gboolean dt_dev_transient_params_active(dt_develop_t *dev, const dt_iop_module_t *module)
void dt_dev_pixelpipe_propagate_formats(dt_dev_pixelpipe_t *pipe)
void dt_dev_pixelpipe_update_zoom_main_real(dt_develop_t *dev)
static gboolean _cache_wait_cursor_restore(gpointer user_data)
static void _prepare_piece_input_contract(dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece, const dt_iop_buffer_dsc_t *upstream_dsc)
void dt_dev_pixelpipe_update_history_all_real(dt_develop_t *dev)
const dt_dev_pixelpipe_iop_t * dt_dev_pixelpipe_get_module_piece(const dt_dev_pixelpipe_t *pipe, const dt_iop_module_t *module)
static void _sync_pipe_nodes_from_history_from_node(dt_dev_pixelpipe_t *pipe, GList *history_list, const uint32_t history_end, GList *start_node, const char *debug_label)
void dt_dev_pixelpipe_update_history_main_real(dt_develop_t *dev)
void dt_dev_pixelpipe_synch_top(dt_dev_pixelpipe_t *pipe)
static void _refresh_pipe_detail_mask_state(dt_dev_pixelpipe_t *pipe)
static gboolean _module_feeds_color_picker(const dt_dev_pixelpipe_t *pipe, const dt_iop_module_t *module, const dt_iop_module_t *picker_module)
Is module the one a picker samples, or the one feeding it?
static void _dump_one_pending(const dt_dev_pixelpipe_cache_wait_t *wait, const int64_t age_us, gpointer user_data)
void dt_dev_pixelpipe_cache_wait_cleanup(dt_dev_pixelpipe_cache_wait_t *wait, const char *reason)
Cancel one pending GUI cache wait request and clear its runtime state.
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)
const dt_dev_pixelpipe_iop_t * dt_dev_pixelpipe_get_prev_enabled_piece(const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece)
static gboolean _sync_focused_in_place(dt_dev_pixelpipe_t *pipe, const dt_dev_history_snapshot_t *snap)
static void _pipe_set_last_history_item(dt_dev_pixelpipe_t *pipe, dt_dev_history_item_t *hist)
Re-commit the focused module's piece in place from transient (or realtime) params.
void dt_pixelpipe_get_global_hash(dt_dev_pixelpipe_t *pipe)
gboolean dt_dev_pixelpipe_is_backbufer_valid(dt_dev_pixelpipe_t *pipe)
void dt_dev_pixelpipe_reset_all(dt_develop_t *dev)
static void _commit_piece_contract(dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece, dt_iop_params_t *params, dt_develop_blend_params_t *blend_params, dt_iop_buffer_dsc_t *upstream_dsc)
static gboolean _cache_wait_connected
void dt_dev_pixelpipe_get_roi_out(dt_dev_pixelpipe_t *pipe, const int width_in, const int height_in, int *width, int *height)
void dt_dev_pixelpipe_change(dt_dev_pixelpipe_t *pipe)
static const char * _dsc_cst_name(const int cst)
void dt_dev_pixelpipe_cache_wait_dump_pending(const char *reason)
Dump pending GUI cache wait requests for lifecycle debugging.
static gboolean _peek_gui(dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, void **data, dt_pixel_cache_entry_t **cache_entry, dt_dev_pixelpipe_cache_wait_t *wait, dt_dev_pixelpipe_cache_ready_callback_t restart, gpointer restart_data, const gboolean retain)
static gchar * _get_debug_pipe_name(const dt_dev_pixelpipe_t *pipe, const dt_develop_t *dev)
static void _change_pipe(dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_change_t flag)
static void _synch_top_snapshot(dt_dev_pixelpipe_t *pipe, const dt_dev_history_snapshot_t *snap)
void dt_dev_pixelpipe_change_zoom_main(dt_develop_t *dev)
void dt_dev_pixelpipe_synch_all_real(dt_dev_pixelpipe_t *pipe, const char *caller_func)
void dt_dev_pixelpipe_sync_no_history(dt_dev_pixelpipe_t *pipe)
static GList * _find_detailmask_node(dt_dev_pixelpipe_t *pipe)
void dt_dev_pixelpipe_rebuild_all_real(dt_develop_t *dev)
static void _dt_dev_pixelpipe_cache_wait_ready_callback(gpointer instance, const guint64 hash, const guint64 producer_node_key, gpointer user_data)
Serve queued GUI cache waiters matching one published cacheline hash.
void dt_dev_pixelpipe_cache_wait_set_owner(dt_dev_pixelpipe_cache_wait_t *wait, const char *owner_tag, gpointer owner_object)
Attach debug ownership metadata to one cache wait request.
void dt_dev_pixelpipe_get_roi_in(dt_dev_pixelpipe_t *pipe, const struct dt_iop_roi_t roi_out)
static void _seal_opencl_cache_policy(dt_dev_pixelpipe_t *pipe)
Seal host-cache retention policy on synchronized pieces before processing starts.
void dt_dev_pixelpipe_update_history_preview_real(dt_develop_t *dev)
void dt_dev_pixelpipe_update_zoom_preview_real(dt_develop_t *dev)
static void _sync_pipe_nodes_from_history(dt_dev_pixelpipe_t *pipe, GList *history_list, const uint32_t history_end, const char *debug_label)
gboolean dt_dev_pixelpipe_is_pipeline_valid(dt_dev_pixelpipe_t *pipe)
static uint64_t _default_pipe_hash(dt_dev_pixelpipe_t *pipe)
static gboolean _cache_wait_cursor_progress(gpointer user_data)
void dt_dev_pixelpipe_resync_history_all_real(dt_develop_t *dev)
gboolean dt_dev_pixelpipe_cache_peek_gui_retained(dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, void **data, dt_pixel_cache_entry_t **cache_entry, dt_dev_pixelpipe_cache_wait_t *wait, dt_dev_pixelpipe_cache_ready_callback_t restart, gpointer restart_data)
gboolean dt_dev_pixelpipe_activemodule_disables_currentmodule(struct dt_develop_t *dev, struct dt_iop_module_t *current_module)
static gboolean _module_requires_global_histogram_output_cache(const dt_dev_pixelpipe_t *pipe, const dt_iop_module_t *module)
void dt_dev_pixelpipe_resync_history_main_real(dt_develop_t *dev)
void dt_dev_pixelpipe_resync_history_preview_real(dt_develop_t *dev)
static void _publish_upstream_hashes(dt_dev_pixelpipe_t *pipe)
static gboolean _module_requires_global_histogram_input_cache(const dt_dev_pixelpipe_t *pipe, const dt_iop_module_t *module)
static void _synch_all_snapshot(dt_dev_pixelpipe_t *pipe, const dt_dev_history_snapshot_t *snap, const char *caller_func)
Find the last history item matching each pipeline node (module), in the order of pipeline execution....
gboolean dt_dev_pixelpipe_cache_peek_gui(dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, void **data, dt_pixel_cache_entry_t **cache_entry, dt_dev_pixelpipe_cache_wait_t *wait, dt_dev_pixelpipe_cache_ready_callback_t restart, gpointer restart_data)
static gboolean _cache_wait_cursor_active
#define dt_dev_pixelpipe_rebuild_all(dev)
#define dt_dev_pixelpipe_resync_history_preview(dev)
#define dt_dev_pixelpipe_resync_history_main(dev)
dt_pixelpipe_cache_ready_callback_t dt_dev_pixelpipe_cache_ready_callback_t
#define dt_dev_pixelpipe_update_history_main(dev)
#define dt_dev_pixelpipe_update_zoom_main(dev)
#define dt_dev_pixelpipe_update_history_preview(dev)
void dt_dev_update_mouse_effect_radius(dt_develop_t *dev)
Convert absolute output-image coordinates to input image space by calling dt_dev_coordinates_image_ab...
static uint64_t dt_dev_get_history_hash(const dt_develop_t *dev)
@ DT_DEV_PIXELPIPE_DISPLAY_NONE
@ DT_DEV_DETAIL_MASK_ENABLED
@ DT_DEV_DETAIL_MASK_NONE
gboolean enabled
–doc was passed on the command line
static int dt_pthread_rwlock_unlock(dt_pthread_rwlock_t *rwlock) RELEASE_GENERIC(rwlock) NO_THREAD_SAFETY_ANALYSIS
static int dt_pthread_rwlock_rdlock(dt_pthread_rwlock_t *rwlock) ACQUIRE_SHARED(rwlock) NO_THREAD_SAFETY_ANALYSIS
void dt_geometry_chain_rebuild(dt_develop_t *dev)
Rebuild the chain from the dev's current modules and history. GUI thread only.
Where things are on the image, answered without a pipeline.
static uint64_t dt_hash(uint64_t hash, const char *str, size_t size)
void dt_iop_commit_params(dt_iop_module_t *module, dt_iop_params_t *params, dt_develop_blend_params_t *blendop_params, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
Copy params into the pipeline piece, so the next render uses them.
gboolean dt_iop_get_cache_bypass(dt_iop_module_t *module)
@ IOP_FLAGS_NO_HISTORY_STACK
static const dt_dev_pixelpipe_t * pipe
static const dt_dev_pixelpipe_t const dt_dev_pixelpipe_iop_t * piece
static const dt_iop_drawlayer_params_t * params
_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.
#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_forms_snapshot_release(GList **snapshot)
#define dt_free(ptr)
g_free() ptr and set it to NULL, skipping both if it is already NULL.
dt_imageio_retval_t status
int dt_opencl_is_inited(void)
#define DT_MAX_FILENAME_LEN
Whether one pipeline node must keep a host-RAM copy of its output.
static gboolean dt_dev_pipe_cache_policy_decide(const dt_dev_pipe_cache_policy_inputs_t *in, const gboolean inherited_requirement, gboolean *upstream_requirement)
Decide one node's host-cache requirement, walking the pipe from the end backwards.
@ DT_DEV_PIXELPIPE_PREVIEW
const char * dt_pixelpipe_cache_set_current_image(const char *image)
Set the image the current module runs on, for the message that reports a refused allocation (thread-l...
void dt_dev_pixelpipe_cache_ref_count_entry(gboolean lock, dt_pixel_cache_entry_t *cache_entry)
Take or release one reference on a cache line. A referenced line is never evicted,...
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_flush(const int id)
Remove cache lines matching id. Entries locked in read/write or having reference count greater than 0...
gboolean dt_dev_pixelpipe_cache_ref_host_entry_by_hash(const uint64_t hash, void **data, dt_pixel_cache_entry_t **entry)
Resolve and retain an existing cacheline that already holds HOST pixels.
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
guint dt_pixelpipe_cache_wait_pending_count(void)
How many requests are outstanding. Diagnostics only.
void dt_pixelpipe_cache_wait_foreach_pending(dt_pixelpipe_cache_wait_visitor_t callback, gpointer user_data)
gboolean dt_pixelpipe_cache_wait_cancel(dt_pixelpipe_cache_wait_t *wait, gboolean *drained)
Remove wait from the queue if it is there, and reset it to an inert state.
GList * dt_pixelpipe_cache_wait_take_matching(const uint64_t hash, const uint64_t producer_node_key, gboolean *drained)
Take every waiter satisfied by a publication of hash from node producer_node_key.
gboolean dt_pixelpipe_cache_wait_enqueue(dt_pixelpipe_cache_wait_t *wait)
Queue wait, or refresh it in place if it is already queued for the same target.
void dt_pixelpipe_cache_wait_count_immediate_hit(void)
Count one cache hit that never needed to queue.
void dt_pixelpipe_cache_wait_get_stats(uint64_t *queued, uint64_t *served, uint64_t *cancelled, uint64_t *immediate_hits, uint64_t *misses)
Snapshot of the lifetime counters, for the dump. Any pointer may be NULL.
void dt_pixelpipe_cache_wait_count_miss(void)
Count one miss that is about to queue.
gboolean dt_dev_pixelpipe_get_realtime(const dt_dev_pixelpipe_t *pipe)
char * dt_pixelpipe_get_pipe_name(dt_dev_pixelpipe_type_t pipe_type)
void dt_dev_pixelpipe_create_nodes(dt_dev_pixelpipe_t *pipe)
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 void dt_dev_pixelpipe_set_hash(dt_dev_pixelpipe_t *pipe, const uint64_t hash)
static uint64_t dt_dev_backbuf_get_history_hash(const dt_backbuf_t *backbuf)
static uint64_t dt_dev_pixelpipe_get_hash(const dt_dev_pixelpipe_t *pipe)
static void dt_dev_pixelpipe_or_changed(dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_change_t flags)
static void dt_dev_pixelpipe_set_cache_request(dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_cache_request_t request, const struct dt_iop_module_t *module)
dt_dev_pixelpipe_change_t
@ DT_DEV_PIPE_CACHE_REQUEST
@ DT_DEV_PIPE_TOP_CHANGED
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_BACKBUF
@ DT_DEV_PIXELPIPE_CACHE_REQUEST_MODULE
#define DT_DEBUG_CONTROL_SIGNAL_DISCONNECT(ctlsig, cb, user_data)
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...
#define DT_DEBUG_CONTROL_SIGNAL_CONNECT(ctlsig, signal, cb, user_data)
unsigned __int64 uint64_t
struct dt_develop_blend_params_t * blend_params
struct dt_iop_module_t *gboolean enabled
A reference-sharing snapshot of dev->history, for readers that outlive a lock.
dt_iop_buffer_dsc_t dsc_in
struct dt_iop_module_t *void * data
dt_atomic_ptr last_history_item
gboolean gui_observable_source
uint64_t last_history_hash
int mask_rasterization_step
Rasterisation step for drawn masks, in image pixels. Always >= 1.
dt_dev_pixelpipe_type_t type
struct dt_develop_t * dev
struct dt_develop_t::@13 color_picker
Authoritative darkroom color-picker state.
struct dt_iop_module_t * gui_module
dt_pthread_rwlock_t history_mutex
struct dt_dev_pixelpipe_t * preview_pipe
dt_atomic_int mask_preview_settings_revision
Revision of the global mask-preview appearance.
struct dt_dev_pixelpipe_t * pipe
char filename[DT_MAX_FILENAME_LEN]
dt_iop_buffer_type_t datatype
Region of interest passed through the pixelpipe.
One consumer's outstanding request, owned by that consumer, not by the queue.
dt_pixelpipe_cache_ready_callback_t restart
int module_multi_priority
const void *char module_op[20]
void dt_supervisor_cache_wait(const dt_sv_op_t op, const uint64_t request_id, const uint64_t awaited_hash, const char *owner_tag, const char *op_name, const int multi_priority, const int pipe_type, const int32_t imgid, const gboolean request_emitted, const char *note)
uint64_t dt_supervisor_node_key(const int pipe_type, const char *op_name, const int multi_priority)
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)
static gboolean dt_supervisor_active(void)
static void dt_get_times(dt_times_t *t)
static double dt_get_wtime(void)
void dt_show_times_f(const dt_times_t *start, const char *prefix, const char *suffix,...) __attribute__((format(printf