63#include <glib/gprintf.h>
96#define DT_IOP_ORDER_INFO (darktable.unmuted & DT_DEBUG_IOPORDER)
107 module = (dt_iop_module_t *)calloc(1, sizeof(dt_iop_module_t));
114 module->global_data = module_so->data;
115 module->so = module_so;
116 iop = g_list_next(iop);
122 module = (dt_iop_module_t *)it->data;
123 it = g_list_next(it);
245 dev->
iop = g_list_delete_link(dev->
iop, dev->
iop);
360 "[pixelpipe] thumbnail sizes raw %dx%d -> processed %dx%d -> preview %dx%d (scale %.5f)\n",
407 const gboolean dims_match
410 if(!dims_match)
return FALSE;
426 float old_scale = *scale;
431 const gboolean preview_pipe = (pipe == dev->
preview_pipe);
441 *wd = roundf(fminf(roi_width, widget_wd));
442 *ht = roundf(fminf(roi_height, widget_ht));
447 *
x = preview_pipe ? 0 : roundf(dev->
roi.
x * roi_width - *wd * .5f);
448 *y = preview_pipe ? 0 : roundf(dev->
roi.
y * roi_height - *ht * .5f);
454 return x_old != *
x || y_old != *y || wd_old != *wd || ht_old != *ht || old_scale != *scale;
461 float preview_scale = 1.0f;
462 float main_scale = 1.0f;
463 int preview_x = 0, preview_y = 0, preview_wd = 0, preview_ht = 0;
464 int main_x = 0, main_y = 0, main_wd = 0, main_ht = 0;
469 return preview_x == main_x && preview_y == main_y && preview_wd == main_wd && preview_ht == main_ht
470 && fabsf(preview_scale - main_scale) < 1e-4f;
486 uint8_t *data = NULL;
506 if(pipe_hash != dev_hash)
513 if(!*needs_update)
return FALSE;
521 gboolean pipe_resynced =
FALSE;
525 pipe_resynced =
TRUE;
532 int x = 0, y = 0, wd = 0, ht = 0;
542 return pipe_resynced;
561 for(
size_t i = 0;
i < G_N_ELEMENTS(pipes);
i++)
562 pipes[
i]->running = 1;
574 for(
size_t i = 0;
i < G_N_ELEMENTS(pipes);
i++)
578 gboolean pipe_needs_update[G_N_ELEMENTS(pipes)] = {
FALSE };
580 gboolean history_resynced =
FALSE;
585 for(
size_t i = 0;
i < G_N_ELEMENTS(pipes);
i++)
608 if(!pipe_needs_update[
i])
continue;
656 const gboolean requested_mask_preview
671 const gint64 process_start_us = g_get_monotonic_time();
673 const gint64 process_runtime_us = g_get_monotonic_time() - process_start_us;
676 gchar *msg = g_strdup_printf(
"[dev_process_%s] pipeline processing thread",
697 const gboolean published_backbuffer
708 if(retrying_raster_mask)
737 && !published_backbuffer)
752 if(published_backbuffer)
777 && !requested_mask_preview
792 for(
size_t i = 0;
i < G_N_ELEMENTS(pipes);
i++)
793 pipes[
i]->running = 0;
872 return storage_status;
876 return storage_status;
927 const dt_iop_roi_t gui_roi = { .
x = 0, .y = 0, .width = wd, .height = ht, .scale = 1.0f };
935 "[pixelpipe] Darkroom requested a %i×%i px widget -> %i×%i px raster preview\n",
955 const float bw = dev->
roi.
width / (proc_w * scale);
956 const float bh = dev->
roi.
height / (proc_h * scale);
959 const float half_bw = bw * 0.5f;
960 const float half_bh = bh * 0.5f;
963 *dev_x = (bw > 1.0f || dev->
roi.
scaling <= 1.0f) ? 0.5f :
CLAMPF(*dev_x, half_bw, 1.0f - half_bw);
964 *dev_y = (bh > 1.0f || dev->
roi.
scaling <= 1.0f) ? 0.5f :
CLAMPF(*dev_y, half_bh, 1.0f - half_bh);
991 if(scale == 0.0f)
return;
995 for(
size_t i = 0;
i < num_points; ++
i)
997 const size_t idx =
i * 2;
998 points[idx + 0] /= scale;
999 points[idx + 1] /= scale;
1008 if(processed_width == 0.0f || processed_height == 0.0f)
return;
1014 const float roi_x = (float)dev->
roi.
x;
1015 const float roi_y = (float)dev->
roi.
y;
1018 const float inv_scaled_width = 1.0f / (processed_width * scale);
1019 const float inv_scaled_height = 1.0f / (processed_height * scale);
1021 for(
size_t i = 0;
i < num_points; ++
i)
1023 const size_t idx =
i * 2;
1024 const float px = points[idx + 0];
1025 const float py = points[idx + 1];
1026 points[idx + 0] = roi_x + (px - center_x) * inv_scaled_width;
1027 points[idx + 1] = roi_y + (py - center_y) * inv_scaled_height;
1036 if(processed_width == 0.0f || processed_height == 0.0f)
return;
1041 const float roi_x = (float)dev->
roi.
x;
1042 const float roi_y = (float)dev->
roi.
y;
1043 const float scaled_width = processed_width * scale;
1044 const float scaled_height = processed_height * scale;
1048 for(
size_t i = 0;
i < num_points; ++
i)
1050 const size_t idx =
i * 2;
1051 const float px = points[idx + 0];
1052 const float py = points[idx + 1];
1053 const float dx = (px - roi_x) * scaled_width;
1054 const float dy = (py - roi_y) * scaled_height;
1055 points[idx + 0] = dx + center_x;
1056 points[idx + 1] = dy + center_y;
1065 if(processed_width == 0.0f || processed_height == 0.0f)
return;
1067 for(
size_t i = 0;
i < num_points; ++
i)
1069 const size_t idx =
i * 2;
1070 points[idx + 0] *= processed_width;
1071 points[idx + 1] *= processed_height;
1080 if(processed_width == 0.0f || processed_height == 0.0f)
return;
1082 const float inv_width = 1.0f / processed_width;
1083 const float inv_height = 1.0f / processed_height;
1084 for(
size_t i = 0;
i < num_points; ++
i)
1086 const size_t idx =
i * 2;
1087 points[idx + 0] *= inv_width;
1088 points[idx + 1] *= inv_height;
1097 if(raw_width == 0.0f || raw_height == 0.0f)
return;
1099 const float inv_width = 1.f / raw_width;
1100 const float inv_height = 1.f / raw_height;
1101 for(
size_t i = 0;
i < num_points;
i++)
1103 const size_t idx =
i * 2;
1104 points[idx + 0] *= inv_width;
1105 points[idx + 1] *= inv_height;
1114 if(raw_width == 0.0f || raw_height == 0.0f)
return;
1116 for(
size_t i = 0;
i < num_points;
i++)
1118 const size_t idx =
i * 2;
1119 points[idx + 0] *= raw_width;
1120 points[idx + 1] *= raw_height;
1149 if(preview_width == 0.0f || preview_height == 0.0f)
return;
1151 for(
size_t i = 0;
i < num_points;
i++)
1153 const size_t idx =
i * 2;
1154 points[idx + 0] *= preview_width;
1155 points[idx + 1] *= preview_height;
1164 if(preview_width == 0.0f || preview_height == 0.0f)
return;
1166 const float inv_width = 1.f / preview_width;
1167 const float inv_height = 1.f / preview_height;
1168 for(
size_t i = 0;
i < num_points;
i++)
1170 const size_t idx =
i * 2;
1171 points[idx + 0] *= inv_width;
1172 points[idx + 1] *= inv_height;
1203 const int selectid,
const int throw_event)
1220 dt_iop_module_t *
module = (dt_iop_module_t *)calloc(1, sizeof(dt_iop_module_t));
1222 module->instance = base->instance;
1226 for(GList *modules = base->
dev->
iop; modules; modules = g_list_next(modules))
1245 int pname =
module->multi_priority;
1250 snprintf(mname,
sizeof(mname),
"%d", pname);
1251 gboolean dup =
FALSE;
1253 for(GList *modules = base->
dev->
iop; modules; modules = g_list_next(modules))
1273 g_strlcpy(module->multi_name, mname,
sizeof(module->multi_name));
1280 fprintf(stderr,
"[dt_dev_module_duplicate] can't move new instance after the base one\n");
1300 int removed_before_end = 0;
1301 int history_pos = 0;
1305 GList *next = g_list_next(elem);
1308 if(module == hist->module)
1314 if(history_pos < history_end) removed_before_end++;
1321 if(removed_before_end > 0)
1330 for(GList *modules = dev->
iop; modules; modules = g_list_next(modules))
1335 dev->
iop = g_list_delete_link(dev->
iop, modules);
1352 const int nb_instances = GPOINTER_TO_INT(
1353 g_hash_table_lookup(
state->instance_counts, GINT_TO_POINTER(module->
instance)));
1358 const gboolean move_next = mod_next
1361 const gboolean move_prev = mod_prev
1365 module->multi_show_new = !(module->flags() & IOP_FLAGS_ONE_INSTANCE);
1367 module->multi_show_close =
1368 (nb_instances > 1 && module->multi_priority > 0 && !(module->flags() & IOP_FLAGS_ONE_INSTANCE));
1370 module->multi_show_up = move_next;
1372 module->multi_show_up = 0;
1374 module->multi_show_down = move_prev;
1376 module->multi_show_down = 0;
1383 && !g_hash_table_contains(
state->modules_in_history, module))
1397 state.modules_in_history = g_hash_table_new(g_direct_hash, g_direct_equal);
1398 state.prev_visible = g_hash_table_new(g_direct_hash, g_direct_equal);
1399 state.next_visible = g_hash_table_new(g_direct_hash, g_direct_equal);
1402 for(GList *modules = dev->
iop; modules; modules = g_list_next(modules))
1406 int count = GPOINTER_TO_INT(g_hash_table_lookup(
state.instance_counts,
key));
1407 g_hash_table_replace(
state.instance_counts,
key, GINT_TO_POINTER(count + 1));
1411 int history_pos = 0;
1412 for(GList *history = g_list_first(dev->
history);
1413 history && history_pos < history_end;
1414 history = g_list_next(history), history_pos++)
1417 if(hist->module) g_hash_table_add(
state.modules_in_history, hist->module);
1422 for(GList *modules = g_list_first(dev->
iop); modules; modules = g_list_next(modules))
1427 g_hash_table_insert(
state.prev_visible, mod, last_visible);
1433 last_visible = NULL;
1434 for(GList *modules = g_list_last(dev->
iop); modules; modules = g_list_previous(modules))
1439 g_hash_table_insert(
state.next_visible, mod, last_visible);
1444 for(GList *modules = dev->
iop; modules; modules = g_list_next(modules))
1452 g_hash_table_destroy(
state.instance_counts);
1453 g_hash_table_destroy(
state.modules_in_history);
1454 g_hash_table_destroy(
state.prev_visible);
1455 g_hash_table_destroy(
state.next_visible);
1463 label = g_strdup(module->name());
1466 label = g_strdup_printf(
"%s %s", module->name(), module->
multi_name);
1473 gboolean has_multi_name = g_strcmp0(module->
multi_name,
"0") != 0 && g_strcmp0(module->
multi_name,
"") != 0;
1474 gchar *label = has_multi_name ? g_strdup(module->
multi_name) : g_strdup(
"");
1482 gboolean has_multi_name = g_strcmp0(module_multi_name,
"") != 0;
1485 gchar *group_name = g_strdup_printf(
"Mask %s", module_label);
1502 label = g_strdup_printf(
"%s %s", clean_name, module->
multi_name);
1515 label = g_markup_escape_text(clean_name, -1);
1517 label = g_markup_printf_escaped(
"%s <span size=\"smaller\">%s</span>", clean_name, module->
multi_name);
1523 const int transf_direction,
float *points,
size_t points_count);
1537 const int transf_direction,
float *points,
size_t points_count)
1539 for(GList *pieces = g_list_first(pipe->
nodes); pieces; pieces = g_list_next(pieces))
1546 || (transf_direction == DT_DEV_TRANSFORM_DIR_FORW_EXCL && module->iop_order > iop_order)
1547 || (transf_direction == DT_DEV_TRANSFORM_DIR_BACK_INCL && module->iop_order <= iop_order)
1548 || (transf_direction == DT_DEV_TRANSFORM_DIR_BACK_EXCL && module->iop_order < iop_order))
1549 && !dt_dev_pixelpipe_activemodule_disables_currentmodule(pipe->dev, module))
1551 module->distort_transform(module, pipe, piece, points, points_count);
1558 float *points,
size_t points_count)
1566 const int transf_direction,
float *points,
size_t points_count)
1568 for(GList *pieces = g_list_last(pipe->
nodes); pieces; pieces = g_list_previous(pieces))
1575 || (transf_direction == DT_DEV_TRANSFORM_DIR_FORW_EXCL && module->iop_order > iop_order)
1576 || (transf_direction == DT_DEV_TRANSFORM_DIR_BACK_INCL && module->iop_order <= iop_order)
1577 || (transf_direction == DT_DEV_TRANSFORM_DIR_BACK_EXCL && module->iop_order < iop_order))
1578 && !dt_dev_pixelpipe_activemodule_disables_currentmodule(pipe->dev, module))
1580 module->distort_backtransform(module, pipe, piece, points, points_count);
1587 float *points,
size_t points_count)
1596 for(
const GList *pieces = g_list_last(pipe->
nodes); pieces; pieces = g_list_previous(pieces))
1599 if(piece->module == module)
1661 const int num_items = g_list_length(dev->
history);
1667 const int num_items = g_list_length(dev->
history);
1684 for(GList *form = g_list_first(dev->
forms); form; form = g_list_next(form))
1739 box[0] = fmaxf(border, 0.5f * (
width - roi_width));
1740 box[1] = fmaxf(border, 0.5f * (
height - roi_height));
1741 box[2] = fminf(
width - 2 * border, roi_width);
1742 box[3] = fminf(
height - 2 * border, roi_height);
1765 if(from == to)
return;
1774 roi_out->
x = lroundf(roi_in->
x *
factor);
1775 roi_out->
y = lroundf(roi_in->
y *
factor);
1787 if(wd == 0.f || ht == 0.f)
return TRUE;
1791 const float roi_width = fminf(
width, wd * zoom_scale);
1792 const float roi_height = fminf(
height, ht * zoom_scale);
1794 const float rec_x = fmaxf(border, (
width - roi_width) * 0.5f);
1795 const float rec_y = fmaxf(border, (
height - roi_height) * 0.5f);
1796 const float rec_w = fminf(
width - 2 * border, roi_width);
1797 const float rec_h = fminf(
height - 2 * border, roi_height);
1799 cairo_rectangle(cr, rec_x, rec_y, rec_w, rec_h);
1812 if(proc_wd == 0.f || proc_ht == 0.f)
return TRUE;
1816 const float tx = 0.5f *
width - dev->
roi.
x * proc_wd * zoom_scale;
1817 const float ty = 0.5f *
height - dev->
roi.
y * proc_ht * zoom_scale;
1819 cairo_translate(cr, tx, ty);
1829 cairo_scale(cr, scale, scale);
1839 cairo_scale(cr, scale, scale);
1849 const float pixel_actual_size = natural_scale * dev->
roi.
scaling;
1850 const float pixel_max_size = 16.f;
1852 if(pixel_actual_size >= pixel_max_size)
1855 dev->
roi.
scaling = pixel_max_size / natural_scale;
1860 const float min_scaling = 0.33f;
1872 if(zoom_level <= 0.f) zoom_level = 1.0f;
1881 "[mouse] effect_radius=%0.3f effect_radius_clamped=%0.3f zoom_level=%0.4f ppd=%0.4f\n",
1887 const int64_t hash,
const int64_t history_hash)
void dt_atomic_set_int(dt_atomic_int *var, int value)
int dt_atomic_get_int(dt_atomic_int *var)
static const float scaling
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
void dt_image_init(dt_image_t *img)
int dt_conf_get_bool(const char *name)
void dt_conf_set_float(const char *name, float val)
float dt_conf_get_float(const char *name)
void dt_conf_set_int(const char *name, int val)
int dt_conf_get_int(const char *name)
void dt_control_queue_redraw_center()
request redraw of center window. This redraws the center view within a gdk critical section to preven...
void dt_control_toast_busy_enter()
void dt_control_log_busy_leave()
void dt_control_log_busy_enter()
void dt_control_toast_busy_leave()
void dt_control_queue_redraw()
request redraw of the workspace. This redraws the whole workspace within a gdk critical section to pr...
void dt_show_times(const dt_times_t *start, const char *prefix)
void dt_show_times_f(const dt_times_t *start, const char *prefix, const char *suffix,...)
void dt_print(dt_debug_thread_t thread, const char *msg,...)
#define dt_free_align(ptr)
static void dt_free_gpointer(gpointer ptr)
static void dt_get_times(dt_times_t *t)
static gchar * delete_underscore(const char *s)
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
void dt_dev_free_history_item(gpointer data)
Free a single history item (used as GList free callback).
void dt_dev_history_undo_invalidate_module(dt_iop_module_t *module)
Invalidate a module pointer inside undo snapshots.
uint64_t dt_dev_history_compute_hash(dt_develop_t *dev)
Get the integrity checksum of the whole history stack. This should be done ONLY when history is chang...
void dt_dev_history_undo_start_record_locked(dt_develop_t *dev)
Start an undo record with history_mutex already locked.
void dt_dev_history_undo_end_record(dt_develop_t *dev)
Finish an undo record for history changes.
void dt_dev_history_undo_end_record_locked(dt_develop_t *dev)
Finish an undo record with history_mutex already locked.
void dt_dev_history_undo_start_record(dt_develop_t *dev)
Start an undo record for history changes.
void dt_dev_write_history_ext(dt_develop_t *dev, const int32_t imgid)
Write dev->history to DB and XMP for a given image id.
void dt_dev_history_notify_change(dt_develop_t *dev, const int32_t imgid)
Notify the rest of the app that history changes were written.
gboolean dt_dev_read_history_ext(dt_develop_t *dev, const int32_t imgid)
Read history and masks from DB and populate dev->history.
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_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)
void dt_dev_pixelpipe_get_roi_in(dt_dev_pixelpipe_t *pipe, const struct dt_iop_roi_t roi_out)
#define dt_dev_pixelpipe_update_zoom_preview(dev)
#define dt_dev_pixelpipe_update_zoom_main(dev)
void dt_dev_signal_modules_moved(dt_develop_t *dev)
dt_job_t * dt_dev_process_job_create(dt_develop_t *dev)
void dt_dev_masks_list_change(dt_develop_t *dev)
static gboolean _dev_translate_roi(dt_develop_t *dev, cairo_t *cr, int32_t width, int32_t height)
void dt_dev_coordinates_image_abs_to_image_norm(dt_develop_t *dev, float *points, size_t num_points)
float dt_dev_get_natural_scale(dt_develop_t *dev)
int dt_dev_distort_transform_locked(const dt_dev_pixelpipe_t *pipe, const double iop_order, const int transf_direction, float *points, size_t points_count)
void dt_dev_get_processed_size(const dt_develop_t *dev, int *procw, int *proch)
dt_dev_pixelpipe_iop_t * dt_dev_distort_get_iop_pipe(struct dt_dev_pixelpipe_t *pipe, struct dt_iop_module_t *module)
void dt_masks_set_lock_mode(dt_develop_t *dev, gboolean mode)
void dt_dev_modulegroups_switch_tab(dt_develop_t *dev, dt_iop_module_t *module)
void dt_dev_coordinates_preview_abs_to_image_norm(dt_develop_t *dev, float *points, size_t num_points)
int dt_dev_get_thumbnail_size(dt_develop_t *dev)
void _dev_module_update_multishow(dt_develop_t *dev, struct dt_iop_module_t *module, const dt_dev_multishow_state_t *state)
void dt_dev_get_image_box_in_widget(const dt_develop_t *dev, const int32_t width, const int32_t height, float *box)
Get the displayed image rectangle in darkroom widget coordinates.
int dt_dev_coordinates_raw_abs_to_image_abs(dt_develop_t *dev, float *points, size_t points_count)
void dt_dev_coordinates_raw_norm_to_raw_abs(dt_develop_t *dev, float *points, size_t num_points)
void dt_dev_get_widget_center(const dt_develop_t *dev, float *point)
Get the center of the darkroom widget in logical coordinates.
void dt_dev_module_remove(dt_develop_t *dev, dt_iop_module_t *module)
void dt_dev_cleanup(dt_develop_t *dev)
static void dt_dev_resync_mipmap_cache(dt_develop_t *dev, dt_dev_pixelpipe_t *pipe, dt_iop_roi_t roi)
int dt_dev_distort_transform_plus(const dt_dev_pixelpipe_t *pipe, const double iop_order, const int transf_direction, float *points, size_t points_count)
float dt_dev_get_overlay_scale(dt_develop_t *dev)
Get the overlay scale factor in GUI logical coordinates.
void dt_dev_append_changed_tag(const int32_t imgid)
dt_dev_image_storage_t dt_dev_load_image(dt_develop_t *dev, const int32_t imgid)
void dt_dev_coordinates_image_norm_to_preview_abs(dt_develop_t *dev, float *points, size_t num_points)
float dt_dev_get_zoom_level(const dt_develop_t *dev)
void dt_dev_coordinates_image_norm_to_widget(dt_develop_t *dev, float *points, size_t num_points)
void dt_dev_masks_selection_change(dt_develop_t *dev, struct dt_iop_module_t *module, const int selectid, const int throw_event)
void dt_dev_init(dt_develop_t *dev, int32_t gui_attached)
int dt_dev_is_current_image(dt_develop_t *dev, int32_t imgid)
void dt_dev_undo_start_record(dt_develop_t *dev)
void dt_dev_snapshot_request(dt_develop_t *dev, const char *filename)
gboolean dt_masks_get_lock_mode(dt_develop_t *dev)
void dt_dev_darkroom_pipeline(dt_develop_t *dev)
Run darkroom preview and main pipelines from one background loop.
gchar * dt_history_item_get_label(const struct dt_iop_module_t *module)
void dt_dev_coordinates_raw_norm_to_image_norm(dt_develop_t *dev, float *points, size_t num_points)
gchar * dt_history_item_get_name_html(const struct dt_iop_module_t *module)
void dt_dev_check_zoom_pos_bounds(dt_develop_t *dev, float *dev_x, float *dev_y, float *box_w, float *box_h)
Ensure that the current ROI position is within allowed bounds .
gboolean dt_dev_check_zoom_scale_bounds(dt_develop_t *dev)
Ensure that the current zoom level is within allowed bounds (for scrolling).
void dt_dev_reset_roi(dt_develop_t *dev)
dt_iop_module_t * dt_dev_module_duplicate(dt_develop_t *dev, dt_iop_module_t *base)
gboolean _resync_pipe_with_history(dt_develop_t *dev, dt_dev_pixelpipe_t *pipe, dt_iop_roi_t *roi, gboolean *needs_update)
GList * dt_dev_load_modules(dt_develop_t *dev)
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)
void dt_dev_set_history_end_ext(dt_develop_t *dev, const uint32_t index)
Set the history end index (GUI perspective).
gboolean dt_dev_rescale_roi_to_input(dt_develop_t *dev, cairo_t *cr, int32_t width, int32_t height)
Scale the ROI to fit the input size within given width/height, centered.
static gboolean _darkroom_pipeline_inputs_ready(const dt_develop_t *dev)
float dt_dev_get_widget_zoom_scale(const dt_develop_t *dev, const float scaling)
Convert a darkroom scaling factor to GUI logical zoom.
float dt_dev_get_zoom_scale(const dt_develop_t *dev, const gboolean preview)
void dt_dev_coordinates_image_norm_to_raw_norm(dt_develop_t *dev, float *points, size_t num_points)
static int dt_dev_distort_backtransform_locked(const dt_dev_pixelpipe_t *pipe, const double iop_order, const int transf_direction, float *points, size_t points_count)
gboolean dt_dev_pipelines_share_preview_output(dt_develop_t *dev)
Tell whether the darkroom main and preview pipes currently target the same GUI output.
void dt_dev_configure_real(dt_develop_t *dev, int wd, int ht)
void dt_dev_masks_update_hash(dt_develop_t *dev)
gboolean dt_dev_clip_roi(dt_develop_t *dev, cairo_t *cr, int32_t width, int32_t height)
Clip the view to the ROI. WARNING: this must be done before any translation.
int dt_dev_coordinates_image_abs_to_raw_abs(dt_develop_t *dev, float *points, size_t points_count)
void dt_dev_undo_end_record(dt_develop_t *dev)
gboolean dt_dev_rescale_roi(dt_develop_t *dev, cairo_t *cr, int32_t width, int32_t height)
Scale the ROI to fit within given width/height, centered.
void dt_dev_coordinates_widget_delta_to_image_delta(dt_develop_t *dev, float *points, size_t num_points)
Convert a widget-space distance to processed-image pixels.
void dt_dev_convert_roi(const dt_develop_t *dev, const dt_iop_roi_t *roi_in, dt_iop_roi_t *roi_out, const dt_dev_roi_space_t from, const dt_dev_roi_space_t to)
Convert a full ROI object between pipeline raster coordinates and GUI logical coordinates.
float dt_dev_get_fit_scale(dt_develop_t *dev)
Get the scale factor that maps preview-buffer pixels to GUI coordinates.
dt_dev_image_storage_t dt_dev_ensure_image_storage(dt_develop_t *dev, const int32_t imgid)
int32_t dt_dev_get_history_end_ext(dt_develop_t *dev)
Get the current history end index (GUI perspective).
void dt_dev_modules_update_multishow(dt_develop_t *dev)
void dt_dev_coordinates_image_norm_to_image_abs(dt_develop_t *dev, float *points, size_t num_points)
static gboolean _update_darkroom_roi(dt_develop_t *dev, dt_dev_pixelpipe_t *pipe, int *x, int *y, int *wd, int *ht, float *scale)
gchar * dt_dev_get_masks_group_name(const struct dt_iop_module_t *module)
gboolean dt_dev_pixelpipe_has_preview_output(const dt_develop_t *dev, const dt_dev_pixelpipe_t *pipe, const dt_iop_roi_t *roi)
void dt_dev_coordinates_widget_to_image_norm(dt_develop_t *dev, float *points, size_t num_points)
Coordinate conversion helpers between widget, normalized image, and absolute image spaces.
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 gboolean _dt_dev_refresh_image_storage(dt_develop_t *dev, const int32_t imgid)
void dt_dev_masks_list_update(dt_develop_t *dev)
static gboolean _dt_dev_mipmap_prefetch_full(dt_develop_t *dev, const int32_t imgid)
static dt_dev_image_storage_t _dt_dev_load_raw(dt_develop_t *dev, const int32_t imgid)
int dt_dev_distort_backtransform_plus(const dt_dev_pixelpipe_t *pipe, const double iop_order, const int transf_direction, float *points, size_t points_count)
gchar * dt_dev_get_multi_name(const struct dt_iop_module_t *module)
void dt_dev_masks_list_remove(dt_develop_t *dev, int formid, int parentid)
static int32_t dt_dev_process_job_run(dt_job_t *job)
void dt_dev_coordinates_raw_abs_to_raw_norm(dt_develop_t *dev, float *points, size_t num_points)
void dt_dev_coordinates_image_abs_to_raw_norm(dt_develop_t *dev, float *points, size_t num_points)
gchar * dt_history_item_get_name(const struct dt_iop_module_t *module)
void dt_dev_start_all_pipelines(dt_develop_t *dev)
static uint64_t dt_dev_get_history_hash(const dt_develop_t *dev)
@ DT_DEV_PIXELPIPE_DISPLAY_NONE
@ DT_DEV_TRANSFORM_DIR_FORW_INCL
@ DT_DEV_TRANSFORM_DIR_ALL
static void dt_dev_set_history_hash(dt_develop_t *dev, const uint64_t history_hash)
@ DT_DEV_IMAGE_STORAGE_DB_NOT_READ
@ DT_DEV_IMAGE_STORAGE_OK
@ DT_DEV_IMAGE_STORAGE_MIPMAP_NOT_FOUND
#define dt_pthread_rwlock_destroy
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)
#define dt_pthread_rwlock_wrlock
static int dt_pthread_mutex_destroy(dt_pthread_mutex_t *mutex)
#define dt_pthread_rwlock_init
#define dt_pthread_rwlock_unlock
static int dt_pthread_mutex_lock(dt_pthread_mutex_t *mutex) ACQUIRE(mutex) NO_THREAD_SAFETY_ANALYSIS
void dt_capitalize_label(gchar *text)
#define DT_PIXEL_APPLY_DPI(value)
void dt_gui_throttle_cancel(gpointer source)
void dt_gui_throttle_record_runtime(const dt_dev_pixelpipe_t *pipe, const gint64 runtime_us)
void dt_image_cache_read_release(dt_image_cache_t *cache, const dt_image_t *img)
dt_image_t * dt_image_cache_get(dt_image_cache_t *cache, const int32_t imgid, char mode)
void dt_image_cache_write_release(dt_image_cache_t *cache, dt_image_t *img, dt_image_cache_write_mode_t mode)
void dt_iop_cleanup_module(dt_iop_module_t *module)
int dt_iop_load_module(dt_iop_module_t *module, dt_iop_module_so_t *module_so, dt_develop_t *dev)
int dt_iop_load_module_by_so(dt_iop_module_t *module, dt_iop_module_so_t *so, dt_develop_t *dev)
void dt_iop_nap(int32_t usec)
gboolean dt_iop_gui_module_is_visible(dt_iop_module_t *module)
void dt_iop_update_multi_priority(dt_iop_module_t *module, int new_priority)
gint dt_sort_iop_by_order(gconstpointer a, gconstpointer b)
Compare two module instances by iop_order for sorting.
gboolean dt_ioppr_check_can_move_before_iop(GList *iop_list, dt_iop_module_t *module, dt_iop_module_t *module_next)
Validate whether module can be moved before module_next.
gboolean dt_ioppr_check_can_move_after_iop(GList *iop_list, dt_iop_module_t *module, dt_iop_module_t *module_prev)
Validate whether module can be moved after module_prev.
gboolean dt_ioppr_move_iop_after(struct dt_develop_t *dev, dt_iop_module_t *module, dt_iop_module_t *module_prev)
Move a module instance after another module in the pipe.
void dt_ioppr_insert_module_instance(struct dt_develop_t *dev, dt_iop_module_t *module)
Ensure a module instance has an entry in dev->iop_order_list.
int dt_ioppr_check_iop_order(dt_develop_t *dev, const int32_t imgid, const char *msg)
Debug helper to validate the current order for a develop context.
void dt_ioppr_cleanup_profile_info(dt_iop_order_iccprofile_info_t *profile_info)
dt_job_t * dt_control_job_create(dt_job_execute_callback execute, const char *msg,...)
int32_t dt_control_add_job_res(dt_control_t *control, _dt_job_t *job, int32_t res)
void * dt_control_job_get_params(const _dt_job_t *job)
void dt_control_job_set_params(_dt_job_t *job, void *params, dt_job_destroy_callback callback)
#define DT_CTL_WORKER_DARKROOM
void dt_masks_free_form(dt_masks_form_t *form)
uint64_t dt_masks_group_get_hash(uint64_t hash, dt_masks_form_t *form)
#define CLAMPF(a, mn, mx)
void dt_mipmap_cache_swap_at_size(dt_mipmap_cache_t *cache, const int32_t imgid, const dt_mipmap_size_t mip, const uint8_t *const in, const int32_t width, const int32_t height, dt_colorspaces_color_profile_type_t profile)
dt_mipmap_size_t dt_mipmap_cache_get_fitting_size(const dt_mipmap_cache_t *cache, const int32_t width, const int32_t height, const uint32_t imgid)
#define dt_mipmap_cache_get(A, B, C, D, E, F)
#define dt_mipmap_cache_release(A, B)
@ DT_DEV_PIXELPIPE_PREVIEW
gboolean dt_dev_pixelpipe_cache_peek(dt_dev_pixelpipe_cache_t *cache, 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(dt_dev_pixelpipe_cache_t *cache, gboolean lock, dt_pixel_cache_entry_t *cache_entry)
Lock or release the read lock on the entry.
Pixelpipe cache for storing intermediate results in the pixelpipe.
#define DT_PIXELPIPE_CACHE_HASH_INVALID
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)
void dt_dev_pixelpipe_reset_reentry(dt_dev_pixelpipe_t *pipe)
gboolean dt_dev_pixelpipe_has_reentry(dt_dev_pixelpipe_t *pipe)
int dt_dev_pixelpipe_init(dt_dev_pixelpipe_t *pipe, dt_develop_t *dev)
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)
int dt_dev_pixelpipe_init_preview(dt_dev_pixelpipe_t *pipe, dt_develop_t *dev)
void dt_dev_pixelpipe_cleanup(dt_dev_pixelpipe_t *pipe)
int dt_dev_pixelpipe_process(dt_dev_pixelpipe_t *pipe, dt_iop_roi_t roi)
static dt_dev_pixelpipe_cache_request_t dt_dev_pixelpipe_get_cache_request(const dt_dev_pixelpipe_t *pipe)
static dt_dev_pixelpipe_change_t dt_dev_pixelpipe_get_changed(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_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_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 void dt_dev_backbuf_set_hash(dt_backbuf_t *backbuf, const uint64_t hash)
static void dt_dev_backbuf_set_history_hash(dt_backbuf_t *backbuf, const uint64_t history_hash)
dt_dev_pixelpipe_cache_request_t
@ DT_DEV_PIXELPIPE_CACHE_REQUEST_BACKBUF
@ DT_DEV_PIXELPIPE_CACHE_REQUEST_NONE
@ DT_DEV_PIXELPIPE_CACHE_REQUEST_MODULE
#define DT_DEBUG_CONTROL_SIGNAL_RAISE(ctlsig, signal,...)
@ DT_SIGNAL_DEVELOP_HISTORY_CHANGE
This signal is raised when develop history is changed no param, no returned value.
@ DT_SIGNAL_DEVELOP_PREVIEW_PIPE_FINISHED
This signal is raised when develop preview pipe process is finished no param, no returned value.
@ DT_SIGNAL_HISTORY_RESYNC
This signal is raised once darkroom history has been resynchronized into all live pipelines....
@ DT_SIGNAL_DEVELOP_UI_PIPE_FINISHED
This signal is raised when pipe is finished and the gui is attached no param, no returned value.
@ DT_SIGNAL_DEVELOP_MODULE_MOVED
This signal is raised when order of modules in pipeline is changed.
@ DT_SIGNAL_DEVELOP_MODULEGROUPS_SET
This signal is raised to request a modulegroups update. 1 : dt_iop_module_t *module,...
@ DT_SIGNAL_TAG_CHANGED
This signal is raised when a tag is added/deleted/changed
const float uint32_t state[4]
unsigned __int64 uint64_t
struct dt_dev_pixelpipe_cache_t * pixelpipe_cache
struct dt_gui_gtk_t * gui
struct dt_colorspaces_t * color_profiles
struct dt_mipmap_cache_t * mipmap_cache
struct dt_control_signal_t * signals
struct dt_image_cache_t * image_cache
struct dt_develop_t * develop
struct dt_view_manager_t * view_manager
struct dt_control_t * control
dt_colorspaces_color_profile_type_t display_type
GHashTable * modules_in_history
GHashTable * prev_visible
GHashTable * next_visible
GHashTable * instance_counts
dt_pthread_mutex_t busy_mutex
dt_dev_pixelpipe_type_t type
struct dt_develop_t * dev
void(* list_update)(struct dt_lib_module_t *self)
int undo_history_before_end
struct dt_develop_t::@19 color_picker
Authoritative darkroom color-picker state.
struct dt_colorpicker_sample_t * primary_sample
GList * undo_history_before_snapshot
dt_backbuf_t display_histogram
uint32_t * histogram_pre_levels
dt_backbuf_t output_histogram
struct dt_develop_t::@18 transient_params
GList * undo_history_before_iop_order_list
gboolean restrict_histogram
void(* list_remove)(struct dt_lib_module_t *self, int formid, int parentid)
struct dt_iop_module_t * gui_module
dt_pthread_rwlock_t history_mutex
gboolean live_samples_enabled
dt_clipping_preview_mode_t mode
struct dt_develop_t::@20::@27 snapshot
struct dt_lib_module_t *void(* list_change)(struct dt_lib_module_t *self)
struct dt_dev_pixelpipe_t * preview_pipe
gboolean pipelines_started
struct dt_dev_pixelpipe_t * virtual_pipe
struct dt_iop_module_t *void * params
dt_aligned_pixel_t wb_coeffs
dt_dev_overexposed_colorscheme_t colorscheme
dt_backbuf_t raw_histogram
struct dt_develop_t::@17 roi
struct dt_develop_t::@20::@28 masks
void(* selection_change)(struct dt_lib_module_t *self, struct dt_iop_module_t *module, const int selectid, const int throw_event)
struct dt_develop_t::@20 proxy
uint32_t * histogram_pre_tonecurve
uint32_t histogram_pre_levels_max
struct dt_iop_module_t * chroma_adaptation
dt_pthread_mutex_t transient_params_mutex
dt_pthread_rwlock_t masks_mutex
struct dt_develop_t::@22 rawoverexposed
uint32_t histogram_pre_tonecurve_max
struct dt_develop_t::@26 progress
struct dt_dev_pixelpipe_t * pipe
struct dt_develop_t::@21 overexposed
struct dt_gui_gtk_t::@47 mouse
float effect_radius_clamped
struct dt_develop_t * dev
Region of interest passed through the pixelpipe.
const dt_view_t * dt_view_manager_get_current_view(dt_view_manager_t *vm)