Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
dev_history.h File Reference
#include "system/atomic.h"
#include "history/history.h"
#include "develop/history_merge.h"
#include <glib.h>
+ Include dependency graph for dev_history.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  dt_dev_history_item_t
 
struct  dt_dev_history_snapshot_t
 A reference-sharing snapshot of dev->history, for readers that outlive a lock. More...
 

Macros

#define DT_IOP_PARAMS_T
 
#define dt_dev_add_history_item(dev, module, enable, redraw)   DT_DEBUG_TRACE_WRAPPER(DT_DEBUG_DEV, dt_dev_add_history_item_real, (dev), (module), (enable), (redraw))
 

Typedefs

typedef void dt_iop_params_t
 
typedef struct dt_dev_history_item_t dt_dev_history_item_t
 
typedef struct dt_dev_history_snapshot_t dt_dev_history_snapshot_t
 A reference-sharing snapshot of dev->history, for readers that outlive a lock.
 
typedef void(* dt_dev_history_undo_restore_gui_handler_t) (struct dt_develop_t *dev, int mask_edit_mode, int request_mask_display)
 Restores the presentation half of an undo record: the blending panel's mask toggles for the focused module.
 
typedef void(* dt_dev_history_commit_gui_handler_t) (struct dt_develop_t *dev, struct dt_iop_module_t *module)
 Post-commit presentation work: viewport-size refresh for geometry-changing modules, and the enable-toggle sync a param edit may have flipped. Installed by dt_dev_history_gui_init(); the engine calls it after each immediate commit.
 

Functions

void dt_dev_history_free_history (struct dt_develop_t *dev)
 Free the whole history list attached to dev->history.
 
dt_dev_history_item_tdt_dev_history_item_create (void)
 Allocate a fresh, blank history item with refcount 1.
 
void dt_dev_free_history_item (gpointer data)
 Release a reference to a history item (used as GList free callback).
 
dt_dev_history_item_tdt_dev_history_item_ref (dt_dev_history_item_t *item)
 Take a reference on a history item. Pair with dt_dev_free_history_item().
 
dt_dev_history_item_tdt_dev_history_cow_touch (struct dt_develop_t *dev, dt_dev_history_item_t *hist)
 Copy-on-write gate for mutating a history item in place.
 
void dt_dev_history_snapshot_take (struct dt_develop_t *dev, dt_dev_history_snapshot_t *snapshot)
 Take a snapshot of dev->history. Caller holds history_mutex (reader suffices).
 
void dt_dev_history_snapshot_release (dt_dev_history_snapshot_t *snapshot)
 Release every reference a snapshot holds and reset it. Needs no lock.
 
gboolean dt_dev_history_item_update_from_params (struct dt_develop_t *dev, dt_dev_history_item_t *hist, struct dt_iop_module_t *module, gboolean enabled, const void *params, const int32_t params_size, const struct dt_develop_blend_params_t *blend_params, GList *forms)
 Fill/refresh a history item from explicit params and apply them to the module.
 
int dt_dev_next_multi_priority_for_op (struct dt_develop_t *dev, const char *op)
 Return the next available multi_priority for an operation.
 
struct dt_iop_module_tdt_dev_get_module_instance (struct dt_develop_t *dev, const char *op, const char *multi_name, const int multi_priority)
 Find a module instance by op name and instance metadata.
 
struct dt_iop_module_tdt_dev_create_module_instance (struct dt_develop_t *dev, const char *op, const char *multi_name, const int multi_priority, gboolean use_next_priority)
 Create a new module instance from an existing base .so.
 
int dt_dev_copy_module_contents (struct dt_develop_t *dev_dest, struct dt_develop_t *dev_src, struct dt_iop_module_t *mod_dest, const struct dt_iop_module_t *mod_src)
 Copy params/blend params from one module instance to another.
 
int dt_dev_history_item_from_source_history_item (struct dt_develop_t *dev_dest, struct dt_develop_t *dev_src, const struct dt_dev_history_item_t *hist_src, struct dt_iop_module_t *mod_dest, struct dt_dev_history_item_t **out_hist)
 Create a history item from another history item, using a destination module.
 
int dt_dev_merge_history_into_image (struct dt_develop_t *dev_src, int32_t dest_imgid, const GList *mod_list, gboolean merge_iop_order, const dt_history_merge_strategy_t mode, const gboolean paste_instances, const char *source_label, dt_hm_batch_state_t *batch)
 Merge a list of modules into a destination image history via dt_history_merge().
 
int dt_dev_replace_history_on_image (struct dt_develop_t *dev_src, const int32_t dest_imgid, const gboolean reload_defaults, const char *msg)
 Replace an image history with the content of dev_src.
 
gboolean dt_dev_add_history_item_ext (struct dt_develop_t *dev, struct dt_iop_module_t *module, gboolean enable, gboolean force_new_item)
 Append or update a history item for a module.
 
void dt_dev_add_history_item_real (struct dt_develop_t *dev, struct dt_iop_module_t *module, gboolean enable, gboolean redraw)
 Thread-safe wrapper around dt_dev_add_history_item_ext().
 
void dt_dev_history_flush_pending_commits (struct dt_develop_t *dev)
 Run every history commit still queued for dev, now.
 
void dt_dev_history_drop_pending_commits (struct dt_develop_t *dev)
 Discard every history commit still queued for dev, without running it.
 
void dt_dev_write_history_ext (struct dt_develop_t *dev, const int32_t imgid)
 Write dev->history to DB and XMP for a given image id.
 
void dt_dev_write_history (struct dt_develop_t *dev, gboolean async)
 Thread-safe wrapper around dt_dev_write_history_ext() for dev->image_storage.id.
 
void dt_dev_history_gui_update (struct dt_develop_t *dev)
 Apply history-loaded params to module GUIs.
 
void dt_dev_history_commit_item_now (struct dt_develop_t *dev, struct dt_iop_module_t *module, gboolean enable)
 Commit one history item immediately – record undo, take history_mutex as writer, write through, resync the pipes.
 
void dt_dev_history_set_undo_restore_gui_handler (dt_dev_history_undo_restore_gui_handler_t handler)
 
void dt_dev_history_set_commit_gui_handler (dt_dev_history_commit_gui_handler_t handler)
 
void dt_dev_history_pixelpipe_update (struct dt_develop_t *dev, gboolean rebuild)
 Rebuild or resync pixelpipes after backend history changes.
 
gboolean dt_dev_history_is_image_in_dev (GList *imgs)
 Check whether any image of the list is the one currently loaded in the darkroom.
 
void dt_apply_dev_history_update (struct dt_develop_t *dev)
 Reload the current darkroom history and refresh every dependent GUI.
 
void dt_dev_history_notify_change (struct dt_develop_t *dev, const int32_t imgid)
 Notify the rest of the app that history changes were written.
 
void dt_dev_history_undo_start_record (struct dt_develop_t *dev)
 Start an undo record for history changes.
 
void dt_dev_history_undo_end_record (struct dt_develop_t *dev)
 Finish an undo record for history changes.
 
void dt_dev_history_undo_start_record_locked (struct dt_develop_t *dev)
 Start an undo record with history_mutex already locked.
 
void dt_dev_history_undo_end_record_locked (struct dt_develop_t *dev)
 Finish an undo record with history_mutex already locked.
 
void dt_dev_history_undo_invalidate_module (struct dt_iop_module_t *module)
 Invalidate a module pointer inside undo snapshots.
 
gboolean dt_dev_read_history_ext (struct dt_develop_t *dev, const int32_t imgid)
 Read history and masks from DB and populate dev->history.
 
void dt_dev_pop_history_items_ext (struct dt_develop_t *dev)
 Apply history items to module params up to dev->history_end.
 
void dt_dev_pop_history_items (struct dt_develop_t *dev)
 Thread-safe wrapper around dt_dev_pop_history_items_ext(), then update GUI.
 
gboolean dt_dev_reload_history_items (struct dt_develop_t *dev, const int32_t imgid)
 Reload history from DB and rebuild pipelines/GUI state.
 
void dt_dev_invalidate_history_module (GList *list, struct dt_iop_module_t *module)
 Remove a module pointer from a history list.
 
uint64_t dt_dev_history_compute_hash (struct dt_develop_t *dev)
 Get the integrity checksum of the whole history stack. This should be done ONLY when history is changed, read or written.
 
int32_t dt_dev_get_history_end_ext (struct dt_develop_t *dev)
 Get the current history end index (GUI perspective).
 
void dt_dev_set_history_end_ext (struct dt_develop_t *dev, const uint32_t index)
 Set the history end index (GUI perspective).
 
gboolean dt_history_module_skip_copy (const int flags)
 Determine whether a module should be skipped during history copy.
 
int dt_history_merge_module_into_history (struct dt_develop_t *dev_dest, struct dt_develop_t *dev_src, struct dt_iop_module_t *mod_src)
 Merge a single module instance into a destination history.
 
void dt_dev_history_compress (struct dt_develop_t *dev)
 Compress an history from a loaded pipeline, aka simply take a snapshot of all modules parameters. This assumes the history end is properly set, which always happens after calling _pop_history_item.
 
void dt_dev_history_compress_ext (struct dt_develop_t *dev, gboolean write_history)
 Variant of history compression that optionally skips DB writeback.
 
void dt_dev_history_compress_or_truncate (struct dt_develop_t *dev)
 Compress history if history_end is at top, otherwise truncate.
 
void dt_dev_history_cleanup (void)
 Cleanup cached statements or state used by history I/O.
 
gboolean dt_dev_init_default_history (struct dt_develop_t *dev, const int32_t imgid, gboolean apply_auto_presets)
 Initialize module defaults and insert required default modules.
 
dt_dev_history_item_tdt_dev_history_get_first_item_by_module (GList *history_list, struct dt_iop_module_t *module)
 Find the first history item referencing a module.
 
dt_dev_history_item_tdt_dev_history_get_last_item_by_module (GList *history_list, struct dt_iop_module_t *module, int history_end)
 Find the last history item referencing a module up to history_end.
 
int dt_dev_history_refresh_nodes_ext (struct dt_develop_t *dev, GList **iop, GList *history, GList **removed_gui_modules)
 Refresh GUI module nodes to match history state.
 
void dt_dev_history_truncate (struct dt_develop_t *dev, const int32_t imgid)
 
void dt_dev_transient_params_set (struct dt_iop_module_t *module, const void *params, size_t params_size, const void *blend_params, size_t blend_size)
 Out-of-history transient param channel.
 
void dt_dev_transient_params_clear (struct dt_iop_module_t *module)
 Drop the transient slot if it belongs to module.
 
gboolean dt_dev_transient_params_get (struct dt_develop_t *dev, const struct dt_iop_module_t *module, void *out_params, size_t out_params_size, void *out_blend, size_t out_blend_size, gboolean *out_has_blend)
 Copy the active transient params for module into caller buffers (pipeline thread).
 
gboolean dt_dev_transient_params_active (struct dt_develop_t *dev, const struct dt_iop_module_t *module)
 Whether a transient slot is currently active for module (cheap, locked read).
 
GList * dt_history_duplicate (GList *hist)
 Deep-copy a history list.
 

Detailed Description

The history/history.h defines methods to handle histories from/to database. They work out of any GUI or development stack, so they don't care about modules .so. This file defines binders between that and the GUI/dev objects.

Definition in file dev_history.h.

Macro Definition Documentation

◆ dt_dev_add_history_item

#define dt_dev_add_history_item (   dev,
  module,
  enable,
  redraw 
)    DT_DEBUG_TRACE_WRAPPER(DT_DEBUG_DEV, dt_dev_add_history_item_real, (dev), (module), (enable), (redraw))

Definition at line 333 of file dev_history.h.

◆ DT_IOP_PARAMS_T

#define DT_IOP_PARAMS_T

Definition at line 42 of file dev_history.h.

Typedef Documentation

◆ dt_dev_history_commit_gui_handler_t

typedef void(* dt_dev_history_commit_gui_handler_t) (struct dt_develop_t *dev, struct dt_iop_module_t *module)

Post-commit presentation work: viewport-size refresh for geometry-changing modules, and the enable-toggle sync a param edit may have flipped. Installed by dt_dev_history_gui_init(); the engine calls it after each immediate commit.

Definition at line 422 of file dev_history.h.

◆ dt_dev_history_item_t

◆ dt_dev_history_snapshot_t

A reference-sharing snapshot of dev->history, for readers that outlive a lock.

The pipe resync is O(nodes x history) and runs every module's commit_params(): tens of ms routinely, over 200 ms under mask-heavy history. Holding history_mutex as reader for all of it starves the GUI thread's writer for the same duration on every edit, and glibc's writer-preferring policy then blocks every NEW reader too, so one slow resync stalls the whole application on the next commit. A snapshot ends that: take the read lock, copy the list and reference each item, capture history_end and the hash that were written together with it, release the lock – microseconds – and resync against the snapshot instead.

Nothing is deep-copied. dt_dev_history_cow_touch() is the writer's side of this contract: an item whose refcount is above 1 is cloned before it is mutated in place, so a snapshot never observes a half-rewritten item, and dt_history_duplicate() is not needed here.

history_end and history_hash are captured under the same lock as the list because dt_dev_set_history_end_ext() writes them together: the three describe one committed state. Reading the hash after releasing the lock would let a commit land in between and mark the pipe as synced to history it never resynced against.

◆ dt_dev_history_undo_restore_gui_handler_t

typedef void(* dt_dev_history_undo_restore_gui_handler_t) (struct dt_develop_t *dev, int mask_edit_mode, int request_mask_display)

Restores the presentation half of an undo record: the blending panel's mask toggles for the focused module.

Undo records capture mask_edit_mode and request_mask_display alongside the history snapshot, because undoing an edit should also undo what the user was LOOKING at. Restoring the data half is the engine's job; restoring the widgets is not, so the engine calls this handler – installed by dt_dev_history_gui_init(), absent headless – with the recorded values (dt_masks_edit_mode_t and dt_dev_pixelpipe_display_mask_t, widened to int so this header does not need their enums).

Definition at line 414 of file dev_history.h.

◆ dt_iop_params_t

Definition at line 43 of file dev_history.h.

Function Documentation

◆ dt_apply_dev_history_update()

void dt_apply_dev_history_update ( struct dt_develop_t dev)

◆ dt_dev_add_history_item_ext()

gboolean dt_dev_add_history_item_ext ( struct dt_develop_t dev,
struct dt_iop_module_t module,
gboolean  enable,
gboolean  force_new_item 
)

Append or update a history item for a module.

If the last history item matches the module and force_new_item is FALSE, the existing item is reused. Otherwise a new entry is appended. If history items exist after dev->history_end, they may be removed depending on module rules (see dev_history.c).

Parameters
dev
module
enable
force_new_item
Returns
TRUE if the pipeline topology may need to be updated (new module node).
Todo:
: this copies ALL drawn masks AND masks groups used by all modules to any module history using masks.

Definition at line 861 of file dev_history.c.

References _remove_history_leaks(), dt_dev_history_item_t::blend_params, DT_DEBUG_HISTORY, dt_dev_history_cow_touch(), dt_dev_history_get_last_item_by_module(), dt_dev_history_item_create(), dt_dev_history_item_update_from_params(), dt_dev_set_history_end_ext(), dt_iop_check_modules_equal(), dt_iop_module_needs_mask_history(), dt_masks_get_from_id(), dt_masks_snapshot_current_forms(), dt_print(), dt_supervisor_active(), dt_supervisor_history(), dt_supervisor_rekey(), DT_SV_CREATE, DT_SV_UPDATE, enable(), dt_dev_history_item_t::enabled, dt_iop_module_t::enabled, FALSE, dt_dev_history_item_t::forms, dt_dev_history_item_t::hash, IS_NULL_PTR, dt_dev_history_item_t::num, dt_dev_history_item_t::params, dt_iop_module_t::params, dt_masks_form_t::points, and TRUE.

Referenced by _dev_history_add_filtered(), _insert_default_modules(), dt_dev_history_commit_item_now(), dt_drawlayer_commit_dabs(), dt_history_merge_module_into_history(), and gui_focus().

◆ dt_dev_add_history_item_real()

void dt_dev_add_history_item_real ( struct dt_develop_t dev,
struct dt_iop_module_t module,
gboolean  enable,
gboolean  redraw 
)

Thread-safe wrapper around dt_dev_add_history_item_ext().

Locks history mutex, invalidates pipelines, triggers recomputation and saves history. This is the typical entry point for GUI actions.

Parameters
devDevelop context.
moduleModule instance.
enableEnable state.
redrawWhether to force a GUI redraw.

Definition at line 283 of file dev_history_gui.c.

References _queue_pending_commit(), enable(), and void().

◆ dt_dev_copy_module_contents()

int dt_dev_copy_module_contents ( struct dt_develop_t dev_dest,
struct dt_develop_t dev_src,
struct dt_iop_module_t mod_dest,
const struct dt_iop_module_t mod_src 
)

Copy params/blend params from one module instance to another.

Optionally copies the drawn masks used by mod_src from dev_src into dev_dest (if dev_src is non-NULL).

Parameters
dev_destDestination develop context.
dev_srcSource develop context (may be NULL to skip mask copy).
mod_destDestination module instance.
mod_srcSource module instance.
Returns
0 on success, non-zero on allocation failure.

◆ dt_dev_create_module_instance()

struct dt_iop_module_t * dt_dev_create_module_instance ( struct dt_develop_t dev,
const char *  op,
const char *  multi_name,
const int  multi_priority,
gboolean  use_next_priority 
)

Create a new module instance from an existing base .so.

Parameters
devDevelop context.
opOperation name.
multi_nameInstance name (may be NULL/empty).
multi_priorityInstance priority.
use_next_priorityIf TRUE, auto-pick the next priority for this op.
Returns
New module instance or NULL on failure.

Definition at line 256 of file dev_history.c.

References dt_free, dt_iop_get_module_by_op_priority(), dt_iop_load_module(), dt_develop_t::iop, IOP_FLAGS_ONE_INSTANCE, IS_NULL_PTR, and dt_iop_module_t::so.

Referenced by _hm_topo_apply_solution(), and dt_dev_snapshot_capture().

◆ dt_dev_free_history_item()

◆ dt_dev_get_history_end_ext()

◆ dt_dev_get_module_instance()

struct dt_iop_module_t * dt_dev_get_module_instance ( struct dt_develop_t dev,
const char *  op,
const char *  multi_name,
const int  multi_priority 
)

Find a module instance by op name and instance metadata.

Tries multi_name first, then falls back to matching multi_priority.

Parameters
devDevelop context.
opOperation name.
multi_nameInstance name (may be NULL/empty).
multi_priorityInstance priority.
Returns
Matching module instance or NULL.

Definition at line 244 of file dev_history.c.

References IS_NULL_PTR, and name.

Referenced by _hm_topo_apply_solution(), dt_dev_snapshot_capture(), and dt_history_merge().

◆ dt_dev_history_cleanup()

void dt_dev_history_cleanup ( void  )

Cleanup cached statements or state used by history I/O.

Definition at line 1572 of file dev_history.c.

Referenced by dt_cleanup().

◆ dt_dev_history_commit_item_now()

void dt_dev_history_commit_item_now ( struct dt_develop_t dev,
struct dt_iop_module_t module,
gboolean  enable 
)

◆ dt_dev_history_compress()

void dt_dev_history_compress ( struct dt_develop_t dev)

Compress an history from a loaded pipeline, aka simply take a snapshot of all modules parameters. This assumes the history end is properly set, which always happens after calling _pop_history_item.

Parameters
dev

Definition at line 2599 of file dev_history.c.

References _dt_dev_history_compress_internal(), and TRUE.

Referenced by dt_dev_history_compress_or_truncate().

◆ dt_dev_history_compress_ext()

void dt_dev_history_compress_ext ( struct dt_develop_t dev,
gboolean  write_history 
)

Variant of history compression that optionally skips DB writeback.

Parameters
devDevelop context.
write_historyIf TRUE, write history to DB/XMP after compression.

Definition at line 2594 of file dev_history.c.

References _dt_dev_history_compress_internal().

Referenced by _styles_rebuild_history_from_items().

◆ dt_dev_history_compress_or_truncate()

void dt_dev_history_compress_or_truncate ( struct dt_develop_t dev)

Compress history if history_end is at top, otherwise truncate.

Parameters
devDevelop context.

Definition at line 2640 of file dev_history.c.

References dt_dev_get_history_end_ext(), dt_dev_history_compress(), and dt_dev_history_truncate().

Referenced by _history_compress_apply().

◆ dt_dev_history_compute_hash()

uint64_t dt_dev_history_compute_hash ( struct dt_develop_t dev)

Get the integrity checksum of the whole history stack. This should be done ONLY when history is changed, read or written.

Parameters
dev
Returns
uint64_t

Definition at line 1005 of file dev_history.c.

References DT_DEBUG_HISTORY, dt_dev_get_history_end_ext(), dt_hash(), dt_print(), and dt_dev_history_item_t::hash.

Referenced by _history_write_state_take(), dt_dev_history_commit_item_now(), dt_dev_pop_history_items_ext(), dt_dev_set_history_end_ext(), dt_dev_snapshot_capture(), dt_drawlayer_commit_dabs(), and gui_focus().

◆ dt_dev_history_cow_touch()

dt_dev_history_item_t * dt_dev_history_cow_touch ( struct dt_develop_t dev,
dt_dev_history_item_t hist 
)

Copy-on-write gate for mutating a history item in place.

If hist is exclusively owned by dev->history (refcount <= 1), returns it unchanged – safe to mutate directly. If it's shared with an outstanding snapshot (a slow reader like a pipe resync or the background DB-write job), clones it, splices the clone into dev->history in place of the original (and re-points any pipe's last_history_item that referenced it), releases the original reference, and returns the clone. Callers must mutate the returned pointer, never the one passed in.

Definition at line 1191 of file dev_history.c.

References _dt_dev_history_item_duplicate_one(), dt_atomic_exch_ptr(), dt_atomic_get_int(), dt_atomic_get_ptr(), dt_dev_free_history_item(), dt_dev_history_item_ref(), dt_pthread_rwlock_unlock(), dt_pthread_rwlock_wrlock(), dt_develop_t::history, dt_develop_t::history_mutex, i, IS_NULL_PTR, dt_develop_t::pipe, dt_develop_t::preview_pipe, and dt_dev_history_item_t::refcount.

Referenced by _cow_touch_clones_an_item_a_snapshot_is_holding(), _cow_touch_ignores_a_marker_naming_a_different_item(), _cow_touch_leaves_an_exclusively_owned_item_alone(), _cow_touch_repoints_the_pipe_marker_and_balances_every_reference(), and dt_dev_add_history_item_ext().

◆ dt_dev_history_drop_pending_commits()

void dt_dev_history_drop_pending_commits ( struct dt_develop_t dev)

Discard every history commit still queued for dev, without running it.

Last-resort counterpart to dt_dev_history_flush_pending_commits(), for a dev already too far torn down to commit to. Prefer the flush wherever the edit can still be saved.

Parameters
devthe develop context, or NULL to drop every pending request.

Definition at line 254 of file dev_history_gui.c.

References _pending_commit_source, _pending_commits, dt_dev_pending_commit_t::dev, dt_free, and IS_NULL_PTR.

Referenced by cleanup(), and dt_dev_cleanup().

◆ dt_dev_history_flush_pending_commits()

void dt_dev_history_flush_pending_commits ( struct dt_develop_t dev)

Run every history commit still queued for dev, now.

dt_dev_add_history_item_real() queues its commit rather than running it, so that a slider drag or a combobox scroll does not run one per step. A queued request IS the user's last edit, so it is run here, not discarded.

Any code about to tear down dev's pipe nodes, iop list or history MUST call this while dev is still whole – it is the last moment at which committing is safe, and a request draining after teardown is the darkroom race described in CLAUDE.md, which crashes far from where it is caused.

Parameters
devthe develop context, or NULL to flush every pending request.

Definition at line 218 of file dev_history_gui.c.

References _drain_pending_commits(), _pending_commit_source, _pending_commits, dt_dev_pending_commit_t::dev, dt_dev_history_commit_item_now(), dt_free, dt_gui_throttle_get_timeout_ms(), dt_dev_pending_commit_t::enable, and IS_NULL_PTR.

Referenced by dt_iop_gui_duplicate(), and leave().

◆ dt_dev_history_free_history()

◆ dt_dev_history_get_first_item_by_module()

dt_dev_history_item_t * dt_dev_history_get_first_item_by_module ( GList *  history_list,
struct dt_iop_module_t module 
)

Find the first history item referencing a module.

Parameters
history_listHistory list.
moduleModule instance.
Returns
First matching history item or NULL.

Definition at line 139 of file dev_history.c.

Referenced by _check_deleted_instances(), _get_user_mod_list(), and _insert_default_modules().

◆ dt_dev_history_get_last_item_by_module()

dt_dev_history_item_t * dt_dev_history_get_last_item_by_module ( GList *  history_list,
struct dt_iop_module_t module,
int  history_end 
)

Find the last history item referencing a module up to history_end.

Parameters
history_listHistory list.
moduleModule instance.
history_endUpper bound index (GUI perspective).
Returns
Last matching history item or NULL.

Definition at line 155 of file dev_history.c.

Referenced by _hm_build_last_history_by_id(), _hm_build_override_map(), _sync_focused_in_place(), dt_dev_add_history_item_ext(), dt_history_merge(), and dt_iop_module_instance_exists().

◆ dt_dev_history_gui_update()

◆ dt_dev_history_is_image_in_dev()

gboolean dt_dev_history_is_image_in_dev ( GList *  imgs)

Check whether any image of the list is the one currently loaded in the darkroom.

Parameters
imgsList of image ids (GINT_TO_POINTER).
Returns
TRUE if darktable.develop is attached to one of them.

Definition at line 1466 of file dev_history.c.

References dt_dev_get_global(), dt_image_t::id, dt_develop_t::image_storage, and IS_NULL_PTR.

Referenced by _styles_apply_callback(), compress_history_callback(), copy_callback(), copy_parts_callback(), delete_history_callback(), duplicate_callback(), load_xmp_callback(), new_history_callback(), paste_all_callback(), and paste_parts_callback().

◆ dt_dev_history_item_create()

dt_dev_history_item_t * dt_dev_history_item_create ( void  )

Allocate a fresh, blank history item with refcount 1.

The only correct way to create a new (not duplicated-from-an-existing-one) history item – centralizes the calloc + refcount init so no caller pokes dt_dev_history_item_t::refcount directly. Returns NULL on allocation failure.

Definition at line 1124 of file dev_history.c.

References dt_atomic_set_int(), IS_NULL_PTR, and dt_dev_history_item_t::refcount.

Referenced by _append(), _process_history_db_entry(), _styles_rebuild_history_from_items(), dt_dev_add_history_item_ext(), and dt_dev_history_item_from_source_history_item().

◆ dt_dev_history_item_from_source_history_item()

int dt_dev_history_item_from_source_history_item ( struct dt_develop_t dev_dest,
struct dt_develop_t dev_src,
const struct dt_dev_history_item_t hist_src,
struct dt_iop_module_t mod_dest,
struct dt_dev_history_item_t **  out_hist 
)

Create a history item from another history item, using a destination module.

Copies params/blend params, updates module ordering metadata, and snapshots masks if needed by the source module.

Parameters
dev_destDestination develop context (receives masks).
dev_srcSource develop context (provides masks).
hist_srcSource history item.
mod_destDestination module instance.
out_histOutput history item (allocated on success).
Returns
0 on success, non-zero on allocation failure.

◆ dt_dev_history_item_ref()

◆ dt_dev_history_item_update_from_params()

gboolean dt_dev_history_item_update_from_params ( struct dt_develop_t dev,
dt_dev_history_item_t hist,
struct dt_iop_module_t module,
gboolean  enabled,
const void params,
const int32_t  params_size,
const struct dt_develop_blend_params_t blend_params,
GList *  forms 
)

Fill/refresh a history item from explicit params and apply them to the module.

This helper exists to share code between regular history edits and history merge logic. It will:

  • allocate hist->params and hist->blend_params if needed,
  • free and replace hist->forms with forms (ownership transferred),
  • sync history metadata from module (op_name, multi_name, iop_order, multi_priority),
  • copy params/blend_params into the history buffers (params size is clamped),
  • apply params/blend_params to the module and recompute the hash.
Parameters
devdevelop context (currently unused, reserved for future).
histhistory item to update (must be non-NULL).
moduledestination module instance (must be non-NULL).
enabledenabled state to store/apply.
paramsparams buffer (if NULL, uses module->params).
params_sizesize of params in bytes (ignored if params is NULL).
blend_paramsblend params buffer (if NULL, uses module->blend_params).
formsmask forms snapshot for this history item (ownership transferred; may be NULL).
Returns
TRUE on success, FALSE on allocation failure/invalid args.

Populate a history item from module parameters and recompute hashes.

This allocates the history buffers if needed, copies params/blend params, assigns module metadata (op name, instance data), applies the values back to the module to keep hashes in sync, and computes the history hash using the provided mask snapshot.

Parameters
devDevelop context (currently unused, reserved for future use).
histHistory item to update.
moduleDestination module instance.
enabledEnabled state to store.
paramsOptional params buffer (NULL uses module->params).
params_sizeSize of params in bytes (ignored if params is NULL).
blend_paramsOptional blend params buffer (NULL uses module->blend_params).
formsMask snapshot to attach (ownership transferred, may be NULL).
Returns
TRUE on success, FALSE on allocation/argument failure.

◆ dt_dev_history_notify_change()

void dt_dev_history_notify_change ( struct dt_develop_t dev,
const int32_t  imgid 
)

Notify the rest of the app that history changes were written.

Updates thumbnails and emits user-visible notices when needed.

Parameters
devDevelop context.
imgidImage id.

Definition at line 1511 of file dev_history.c.

References dt_dev_mask_history_overload(), dt_history_toast(), dt_image_history_changed(), dt_pthread_rwlock_rdlock(), dt_pthread_rwlock_unlock(), FALSE, dt_develop_t::gui_attached, dt_develop_t::history, dt_develop_t::history_mutex, and IS_NULL_PTR.

Referenced by _dt_dev_write_history_job_run(), dt_dev_load_image(), dt_dev_write_history(), dt_drawlayer_commit_dabs(), dt_ioppr_migrate_iop_order(), dt_lightroom_import(), and gui_focus().

◆ dt_dev_history_pixelpipe_update()

void dt_dev_history_pixelpipe_update ( struct dt_develop_t dev,
gboolean  rebuild 
)

Rebuild or resync pixelpipes after backend history changes.

Parameters
devDevelop context.
rebuildTRUE to rebuild pipeline topology, FALSE to resync only.

Definition at line 1456 of file dev_history.c.

References dt_dev_pixelpipe_rebuild_all, dt_dev_pixelpipe_resync_history_all, and dt_develop_t::gui_attached.

Referenced by _history_apply_history_end(), _pop_undo(), _studio_history_changed_callback(), dt_apply_dev_history_update(), dt_ioppr_migrate_iop_order(), and dt_lightroom_import().

◆ dt_dev_history_refresh_nodes_ext()

int dt_dev_history_refresh_nodes_ext ( struct dt_develop_t dev,
GList **  iop,
GList *  history,
GList **  removed_gui_modules 
)

Refresh GUI module nodes to match history state.

Removes modules without history, creates missing instances, and reorders the GUI list according to history/pipeline ordering.

Parameters
devDevelop context.
iopModule list pointer.
historyHistory list.
Returns
0 on success, non-zero on error.
Parameters
removed_gui_modulesWhen non-NULL, receives the instances unlinked from iop. Their widgets are NOT touched here – they used to be destroyed inside history_mutex, which is exactly the GTK-inside-the-engine-lock hazard this parameter removes. The caller (dt_dev_history_gui_update() in dev_history_gui.c) destroys them after unlock and frees the list; the modules themselves stay parked in dev->alliop.

Definition at line 2896 of file dev_history.c.

References _check_deleted_instances(), _create_deleted_modules(), _rebuild_multi_priority(), dt_dev_signal_modules_moved(), and dt_sort_iop_by_order().

Referenced by dt_dev_history_gui_update().

◆ dt_dev_history_set_commit_gui_handler()

void dt_dev_history_set_commit_gui_handler ( dt_dev_history_commit_gui_handler_t  handler)

Definition at line 571 of file dev_history.c.

References _commit_gui_handler.

Referenced by dt_dev_history_gui_init().

◆ dt_dev_history_set_undo_restore_gui_handler()

void dt_dev_history_set_undo_restore_gui_handler ( dt_dev_history_undo_restore_gui_handler_t  handler)

Definition at line 578 of file dev_history.c.

References _undo_restore_gui_handler.

Referenced by dt_dev_history_gui_init().

◆ dt_dev_history_snapshot_release()

◆ dt_dev_history_snapshot_take()

◆ dt_dev_history_truncate()

◆ dt_dev_history_undo_end_record()

void dt_dev_history_undo_end_record ( struct dt_develop_t dev)

Finish an undo record for history changes.

Parameters
devDevelop context.

Definition at line 745 of file dev_history.c.

References dt_dev_history_undo_end_record_locked(), dt_pthread_rwlock_rdlock(), dt_pthread_rwlock_unlock(), dt_develop_t::history_mutex, and IS_NULL_PTR.

Referenced by dt_dev_undo_end_record().

◆ dt_dev_history_undo_end_record_locked()

◆ dt_dev_history_undo_invalidate_module()

void dt_dev_history_undo_invalidate_module ( struct dt_iop_module_t module)

Invalidate a module pointer inside undo snapshots.

Used when module instances are destroyed or replaced.

Parameters
moduleModule to invalidate.

Definition at line 613 of file dev_history.c.

References _history_invalidate_cb(), dt_undo_get_global(), DT_UNDO_HISTORY, dt_undo_iterate_internal(), and IS_NULL_PTR.

Referenced by dt_dev_module_remove().

◆ dt_dev_history_undo_start_record()

void dt_dev_history_undo_start_record ( struct dt_develop_t dev)

Start an undo record for history changes.

Called by the develop undo framework.

Parameters
devDevelop context.

Definition at line 717 of file dev_history.c.

References dt_dev_history_undo_start_record_locked(), dt_pthread_rwlock_rdlock(), dt_pthread_rwlock_unlock(), dt_develop_t::history_mutex, and IS_NULL_PTR.

Referenced by dt_dev_undo_start_record().

◆ dt_dev_history_undo_start_record_locked()

void dt_dev_history_undo_start_record_locked ( struct dt_develop_t dev)

Start an undo record with history_mutex already locked.

Caller must hold dev->history_mutex (read or write).

Parameters
devDevelop context.

Definition at line 725 of file dev_history.c.

References dt_dev_free_history_item(), dt_dev_get_history_end_ext(), dt_free_gpointer(), dt_history_duplicate(), dt_ioppr_iop_order_copy_deep(), and IS_NULL_PTR.

Referenced by dt_dev_history_undo_start_record(), and dt_dev_module_remove().

◆ dt_dev_init_default_history()

gboolean dt_dev_init_default_history ( struct dt_develop_t dev,
const int32_t  imgid,
gboolean  apply_auto_presets 
)

Initialize module defaults and insert required default modules.

This does not read the database history. It only loads defaults and optionally applies auto-presets, mirroring the internal init path used by dt_dev_read_history_ext().

Parameters
devDevelop context.
imgidImage id.
apply_auto_presetsWhether to apply auto-presets.
Returns
TRUE if this was the first initialization for the image.

Definition at line 1890 of file dev_history.c.

References _dev_auto_apply_presets(), _insert_default_modules(), dt_conf_set_string(), DT_DEBUG_HISTORY, DT_IMAGE_AUTO_PRESETS_APPLIED, dt_iop_reload_defaults(), and dt_print().

Referenced by _styles_init_source_dev(), dt_dev_read_history_ext(), and dt_dev_replace_history_on_image().

◆ dt_dev_invalidate_history_module()

void dt_dev_invalidate_history_module ( GList *  list,
struct dt_iop_module_t module 
)

Remove a module pointer from a history list.

Used when modules are deleted or re-instantiated.

Parameters
listHistory list.
moduleModule to invalidate.

Definition at line 2412 of file dev_history.c.

Referenced by _history_invalidate_cb().

◆ dt_dev_merge_history_into_image()

int dt_dev_merge_history_into_image ( struct dt_develop_t dev_src,
int32_t  dest_imgid,
const GList *  mod_list,
gboolean  merge_iop_order,
const dt_history_merge_strategy_t  mode,
const gboolean  paste_instances,
const char *  source_label,
dt_hm_batch_state_t batch 
)

Merge a list of modules into a destination image history via dt_history_merge().

Parameters
dev_srcSource develop context (provides module params).
dest_imgidDestination image id.
mod_listList of module instances to merge.
merge_iop_orderWhether to merge pipeline order (TRUE) or preserve destination (FALSE).
modeMerge strategy for history entries.
paste_instancesWhether to paste module instances.
source_labelOptional source label for the merge report header.
Returns
0 on success, non-zero on failure.

Definition at line 374 of file dev_history.c.

References dt_dev_cleanup(), dt_dev_init(), dt_dev_pop_history_items_ext(), dt_dev_reload_history_items(), dt_dev_write_history(), dt_dev_write_history_ext(), dt_history_merge(), dt_image_cache_get(), DT_IMAGE_CACHE_SAFE, dt_image_cache_write_release(), FALSE, dt_develop_t::image_storage, and IS_NULL_PTR.

Referenced by _history_copy_and_paste_on_image_merge(), and dt_styles_apply_to_image_merge().

◆ dt_dev_next_multi_priority_for_op()

int dt_dev_next_multi_priority_for_op ( struct dt_develop_t dev,
const char *  op 
)

Return the next available multi_priority for an operation.

Parameters
devDevelop context.
opOperation name.
Returns
Next available instance priority (>= 1).

Definition at line 232 of file dev_history.c.

References dt_develop_t::iop, m, and MAX.

◆ dt_dev_pop_history_items()

◆ dt_dev_pop_history_items_ext()

◆ dt_dev_read_history_ext()

gboolean dt_dev_read_history_ext ( struct dt_develop_t dev,
const int32_t  imgid 
)

◆ dt_dev_reload_history_items()

gboolean dt_dev_reload_history_items ( struct dt_develop_t dev,
const int32_t  imgid 
)

Reload history from DB and rebuild pipelines/GUI state.

Frees existing history, re-reads from DB, applies to modules, and updates GUI and pipelines. Locks history mutex.

Parameters
devDevelop context.
imgidImage id.
Returns
TRUE if this reload initialized a first-run history.

Definition at line 1289 of file dev_history.c.

References dt_dev_pop_history_items_ext(), dt_dev_read_history_ext(), dt_gui_freeze_begin, dt_gui_freeze_end, dt_gui_get_global(), dt_pthread_rwlock_unlock(), dt_pthread_rwlock_wrlock(), dt_develop_t::gui_attached, and dt_develop_t::history_mutex.

Referenced by _history_compress_apply(), _history_copy_and_paste_on_image_merge(), _studio_history_changed_callback(), dt_apply_dev_history_update(), dt_dev_merge_history_into_image(), dt_ioppr_migrate_iop_order(), and dt_lightroom_import().

◆ dt_dev_replace_history_on_image()

int dt_dev_replace_history_on_image ( struct dt_develop_t dev_src,
const int32_t  dest_imgid,
const gboolean  reload_defaults,
const char *  msg 
)

Replace an image history with the content of dev_src.

Optionally reloads default modules before writing to DB. This is used by history replace and style replace paths.

Parameters
dev_srcSource develop context.
dest_imgidDestination image id.
reload_defaultsWhether to reload default modules before writing.
msgOptional debug message.
Returns
0 on success, non-zero on failure.

Definition at line 1913 of file dev_history.c.

References dt_dev_ensure_image_storage(), dt_dev_init_default_history(), dt_dev_pop_history_items_ext(), dt_dev_write_history(), dt_ioppr_resync_pipeline(), dt_pthread_rwlock_unlock(), dt_pthread_rwlock_wrlock(), FALSE, dt_develop_t::history_mutex, and reload_defaults().

Referenced by _history_copy_and_paste_on_image_merge(), and dt_styles_apply_to_image_merge().

◆ dt_dev_set_history_end_ext()

void dt_dev_set_history_end_ext ( struct dt_develop_t dev,
const uint32_t  index 
)

Set the history end index (GUI perspective).

The index is 1-based with 0 representing the raw input image. The value is sanitized against the actual history length.

Parameters
devDevelop context.
indexNew history end index.

Definition at line 1905 of file develop.c.

References dt_dev_history_compute_hash(), dt_dev_set_history_hash(), dt_develop_t::history, and dt_develop_t::history_end.

Referenced by _dt_dev_history_compress_internal(), _history_apply_history_end(), _hm_restore_dest_from_backup(), _pop_undo(), _styles_rebuild_history_from_items(), dt_dev_add_history_item_ext(), dt_dev_module_remove(), dt_dev_read_history_ext(), dt_dev_snapshot_capture(), and dt_history_merge().

◆ dt_dev_transient_params_active()

gboolean dt_dev_transient_params_active ( struct dt_develop_t dev,
const struct dt_iop_module_t module 
)

Whether a transient slot is currently active for module (cheap, locked read).

◆ dt_dev_transient_params_clear()

void dt_dev_transient_params_clear ( struct dt_iop_module_t module)

Drop the transient slot if it belongs to module.

GUI/worker thread only. Call on commit/cancel/edit-exit/focus-loss. Does NOT trigger a recompute (see _set); the caller re-triggers the pipe so it renders the committed history state.

Definition at line 2985 of file dev_history.c.

References dt_develop_t::blend_params, dt_develop_t::blend_size, dt_iop_module_t::dev, dt_free, dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), IS_NULL_PTR, dt_develop_t::params, dt_develop_t::params_size, dt_develop_t::serial, dt_develop_t::transient_params, and dt_develop_t::transient_params_mutex.

Referenced by _delayed_history_commit(), and dt_drawlayer_set_pipeline_realtime_mode().

◆ dt_dev_transient_params_get()

gboolean dt_dev_transient_params_get ( struct dt_develop_t dev,
const struct dt_iop_module_t module,
void out_params,
size_t  out_params_size,
void out_blend,
size_t  out_blend_size,
gboolean *  out_has_blend 
)

Copy the active transient params for module into caller buffers (pipeline thread).

Returns FALSE (and leaves buffers untouched) when no transient slot is active for module or the buffer sizes do not match the published snapshot. When it returns TRUE, out_params holds a private copy safe to pass to commit_params(). out_blend/out_blend_size may be NULL/0 if the caller does not want the transient blend; *out_has_blend (optional) reports whether a transient blend snapshot was present and copied.

◆ dt_dev_transient_params_set()

void dt_dev_transient_params_set ( struct dt_iop_module_t module,
const void params,
size_t  params_size,
const void blend_params,
size_t  blend_size 
)

Out-of-history transient param channel.

Lets a focused module (drawlayer realtime stroke, ashift/crop edit mode) push a thread-safe snapshot of its in-progress parameters to the pipeline for rendering, WITHOUT writing permanent history. module->params belongs to the GUI thread and must never be read from the pipeline; instead the module copies its transient params into this dev-owned slot under a mutex. The pipeline reads them (also under the mutex) and commits them through the normal commit_params() path, so the transient state reaches the cache through the usual piece->global_hash mechanism. Only one module — the focused gui_module — is active at a time. History is touched only at the real commit, so undo/redo is not polluted and the database is not written per frame.

Publish (copy) module's transient params for the pipeline.

GUI/worker thread only. Replaces any previously published slot. blend_params may be NULL to keep using the history blend params. Does NOT trigger a recompute: the caller flags the pipe the way that fits its case — a realtime module raises DT_DEV_PIPE_TOP_CHANGED on the main pipe for a fast focused-piece resync, while a geometry-changing edit (crop/ashift) calls dt_dev_pixelpipe_resync_history_all() so every pipe replans ROI/formats.

Definition at line 2938 of file dev_history.c.

References dt_develop_t::blend_params, dt_develop_t::blend_size, dt_iop_module_t::dev, dt_free, dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), IS_NULL_PTR, dt_develop_t::params, dt_develop_t::params_size, params_size(), dt_develop_t::serial, dt_develop_t::transient_params, and dt_develop_t::transient_params_mutex.

Referenced by _publish_backend_progress(), and _publish_mask_edit_transient().

◆ dt_dev_write_history()

◆ dt_dev_write_history_ext()

void dt_dev_write_history_ext ( struct dt_develop_t dev,
const int32_t  imgid 
)

Write dev->history to DB and XMP for a given image id.

This acquires the database lock in write mode.

Parameters
devDevelop context.
imgidImage id.

Definition at line 1643 of file dev_history.c.

References _history_write_state_release(), _history_write_state_take(), _write_history_from_state(), and state.

Referenced by _dt_dev_history_compress_internal(), _history_compress_apply(), _hm_restore_dest_from_backup(), _pop_undo(), dt_dev_history_truncate(), dt_dev_load_image(), and dt_dev_merge_history_into_image().

◆ dt_history_duplicate()

GList * dt_history_duplicate ( GList *  hist)

Deep-copy a history list.

Deep-copy a history list. Defined in dev_history.c; declared in history/history.h until it was moved here, since it walks dt_dev_history_item_t and resolves modules through dt_iop_get_module() – neither of which layer 1 can see.

Duplicates params, blend params and masks for each history item.

Parameters
histSource history list.
Returns
Newly-allocated history list.

Definition at line 525 of file dev_history.c.

References dt_dev_history_item_t::blend_params, dt_dev_history_item_t::blendop_params_size, dt_atomic_set_int(), dt_masks_form_ref(), dt_dev_history_item_t::forms, IS_NULL_PTR, dt_dev_history_item_t::op_name, dt_dev_history_item_t::params, dt_iop_module_t::params, and dt_dev_history_item_t::params_size.

Referenced by _hm_backup_dest(), _lib_snapshot_capture_state(), _pop_undo(), dt_dev_history_undo_end_record_locked(), and dt_dev_history_undo_start_record_locked().

◆ dt_history_merge_module_into_history()

int dt_history_merge_module_into_history ( struct dt_develop_t dev_dest,
struct dt_develop_t dev_src,
struct dt_iop_module_t mod_src 
)

Merge a single module instance into a destination history.

Creates or reuses a destination module instance and copies its parameters. This does not resync the pipeline or pop history; callers should batch multiple merges and resync once.

Parameters
dev_destDestination develop context.
dev_srcSource develop context (may be NULL to skip mask copy).
mod_srcSource module instance.
Returns
1 on success, 0 on failure.

Definition at line 485 of file dev_history.c.

References DT_DEBUG_HISTORY, dt_dev_add_history_item_ext(), dt_dev_copy_module_contents(), dt_print(), FALSE, IOP_FLAGS_ONE_INSTANCE, and IS_NULL_PTR.

Referenced by dt_styles_apply_style_item().

◆ dt_history_module_skip_copy()

gboolean dt_history_module_skip_copy ( const int  flags)

Determine whether a module should be skipped during history copy.

Evaluates module flags such as deprecated/unsafe/hidden.

Parameters
flagsModule flags.
Returns
TRUE if module should be skipped, FALSE otherwise.

Definition at line 2424 of file dev_history.c.

References flags, IOP_FLAGS_DEPRECATED, IOP_FLAGS_HIDDEN, and IOP_FLAGS_UNSAFE_COPY.

Referenced by _get_user_mod_list(), and dt_gui_hist_dialog_new().