Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
dev_pixelpipe.c File Reference
#include "common/debug.h"
#include "common/darktable.h"
#include "common/dtpthread.h"
#include "develop/imageop.h"
#include "develop/pixelpipe.h"
#include "develop/pixelpipe_cache.h"
#include "develop/blend.h"
#include "gui/color_picker_proxy.h"
#include "control/control.h"
#include "control/signal.h"
#include <stdint.h>
#include <stdlib.h>
+ Include dependency graph for dev_pixelpipe.c:

Go to the source code of this file.

Data Structures

struct  dt_dev_pixelpipe_cache_wait_record_t
 
struct  dt_dev_pixelpipe_cache_wait_manager_t
 

Typedefs

typedef struct dt_dev_pixelpipe_cache_wait_record_t dt_dev_pixelpipe_cache_wait_record_t
 
typedef struct dt_dev_pixelpipe_cache_wait_manager_t dt_dev_pixelpipe_cache_wait_manager_t
 

Functions

static void _sync_virtual_pipe (dt_develop_t *dev, dt_dev_pixelpipe_change_t flag)
 
static void _sync_pipe_nodes_from_history_from_node (dt_dev_pixelpipe_t *pipe, const uint32_t history_end, GList *start_node, const char *debug_label)
 
static void _dt_dev_pixelpipe_cache_wait_ready_callback (gpointer instance, const guint64 hash, gpointer user_data)
 Serve queued GUI cache waiters matching one published cacheline hash.
 
static gboolean _cache_wait_cursor_progress (gpointer user_data)
 
static gboolean _cache_wait_cursor_restore (gpointer user_data)
 
static dt_dev_pixelpipe_cache_wait_record_t_cache_wait_manager_remove_wait_locked (dt_dev_pixelpipe_cache_wait_t *wait)
 
void dt_dev_pixelpipe_cache_wait_dump_pending (const char *reason)
 Dump pending GUI cache wait requests for lifecycle debugging.
 
static gboolean _module_requires_global_histogram_output_cache (const dt_dev_pixelpipe_t *pipe, const dt_iop_module_t *module)
 
static gboolean _module_requires_global_histogram_input_cache (const dt_dev_pixelpipe_t *pipe, const dt_iop_module_t *module)
 
static gchar * _get_debug_pipe_name (const dt_dev_pixelpipe_t *pipe, const dt_develop_t *dev)
 
static GList * _find_detailmask_node (dt_dev_pixelpipe_t *pipe)
 
static void _refresh_pipe_detail_mask_state (dt_dev_pixelpipe_t *pipe)
 
static void _change_pipe (dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_change_t flag)
 
static gboolean _sync_focused_in_place (dt_dev_pixelpipe_t *pipe)
 Re-commit the focused module's piece in place from transient (or realtime) params.
 
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_rebuild_all_real (dt_develop_t *dev)
 
void dt_dev_pixelpipe_resync_history_main_real (dt_develop_t *dev)
 
void dt_dev_pixelpipe_resync_history_preview_real (dt_develop_t *dev)
 
void dt_dev_pixelpipe_resync_history_all_real (dt_develop_t *dev)
 
void dt_dev_pixelpipe_update_history_main_real (dt_develop_t *dev)
 
void dt_dev_pixelpipe_update_history_preview_real (dt_develop_t *dev)
 
void dt_dev_pixelpipe_update_history_all_real (dt_develop_t *dev)
 
void dt_dev_pixelpipe_update_zoom_preview_real (dt_develop_t *dev)
 
void dt_dev_pixelpipe_update_zoom_main_real (dt_develop_t *dev)
 
void dt_dev_pixelpipe_reset_all (dt_develop_t *dev)
 
void dt_dev_pixelpipe_change_zoom_main (dt_develop_t *dev)
 
gboolean dt_dev_pixelpipe_activemodule_disables_currentmodule (struct dt_develop_t *dev, struct dt_iop_module_t *current_module)
 
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_get_roi_in (dt_dev_pixelpipe_t *pipe, const struct dt_iop_roi_t roi_out)
 
static uint64_t _default_pipe_hash (dt_dev_pixelpipe_t *pipe)
 
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_tdt_dev_pixelpipe_get_module_piece (const dt_dev_pixelpipe_t *pipe, const dt_iop_module_t *module)
 
const dt_dev_pixelpipe_iop_tdt_dev_pixelpipe_get_prev_enabled_piece (const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece)
 
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)
 
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.
 
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.
 
static const char * _dsc_cst_name (const int cst)
 
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)
 
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)
 
void dt_dev_pixelpipe_propagate_formats (dt_dev_pixelpipe_t *pipe)
 
static void _sync_pipe_nodes_from_history (dt_dev_pixelpipe_t *pipe, dt_develop_t *dev, const uint32_t history_end, const char *debug_label)
 
void dt_pixelpipe_get_global_hash (dt_dev_pixelpipe_t *pipe)
 
void dt_dev_pixelpipe_synch_all_real (dt_dev_pixelpipe_t *pipe, const char *caller_func)
 Find the last history item matching each pipeline node (module), in the order of pipeline execution. This is super important because modules providing raster masks need to be inited before modules using them, in the order of pipeline nodes. But history holds no guaranty that raster masks providers will be older than raster masks users, especially after history compression. So reading in history order is not an option.
 
void dt_dev_pixelpipe_synch_top (dt_dev_pixelpipe_t *pipe)
 
void dt_dev_pixelpipe_sync_no_history (dt_dev_pixelpipe_t *pipe)
 
void dt_dev_pixelpipe_change (dt_dev_pixelpipe_t *pipe)
 
void dt_dev_pixelpipe_sync_virtual (dt_develop_t *dev, dt_dev_pixelpipe_change_t flag)
 
gboolean dt_dev_pixelpipe_is_backbufer_valid (dt_dev_pixelpipe_t *pipe)
 
gboolean dt_dev_pixelpipe_is_pipeline_valid (dt_dev_pixelpipe_t *pipe)
 

Variables

static dt_dev_pixelpipe_cache_wait_manager_t _cache_wait_manager
 

Typedef Documentation

◆ dt_dev_pixelpipe_cache_wait_manager_t

◆ dt_dev_pixelpipe_cache_wait_record_t

Function Documentation

◆ _cache_wait_cursor_progress()

static gboolean _cache_wait_cursor_progress ( gpointer  user_data)
static

◆ _cache_wait_cursor_restore()

static gboolean _cache_wait_cursor_restore ( gpointer  user_data)
static

◆ _cache_wait_manager_remove_wait_locked()

◆ _change_pipe()

◆ _commit_piece_contract()

◆ _default_pipe_hash()

◆ _dsc_cst_name()

static const char * _dsc_cst_name ( const int  cst)
static

◆ _dt_dev_pixelpipe_cache_wait_ready_callback()

static void _dt_dev_pixelpipe_cache_wait_ready_callback ( gpointer  instance,
const guint64  hash,
gpointer  user_data 
)
static

Serve queued GUI cache waiters matching one published cacheline hash.

DT_SIGNAL_CACHELINE_READY may wake several GUI consumers at once (pickers, histograms, darkroom surfaces, autoset). We therefore:

  1. iterate the pending wait list under the manager lock,
  2. extract only waiters whose requested hash matches hash,
  3. disconnect the global signal and clear the busy cursor when the queue becomes empty,
  4. release the lock before running restart callbacks.

Keeping callbacks out of the critical section is intentional: restart handlers can queue redraws or request new cachelines, so running them under lock would serialize unrelated GUI wakeups and risks re-entrant lock contention.

Definition at line 850 of file dev_pixelpipe.c.

References _cache_wait_cursor_restore(), _cache_wait_manager, _dt_dev_pixelpipe_cache_wait_ready_callback(), dt_dev_pixelpipe_cache_wait_manager_t::connected, dt_dev_pixelpipe_cache_wait_t::connected, darktable, DT_DEBUG_CONTROL_SIGNAL_DISCONNECT, DT_DEBUG_PIPECACHE, dt_free, DT_PIXELPIPE_CACHE_HASH_INVALID, dt_print(), dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), FALSE, dt_dev_pixelpipe_cache_wait_t::hash, IS_NULL_PTR, dt_dev_pixelpipe_cache_wait_manager_t::lock, dt_dev_pixelpipe_cache_wait_t::owner_tag, dt_dev_pixelpipe_cache_wait_manager_t::pending, dt_dev_pixelpipe_cache_wait_t::pipe, dt_dev_pixelpipe_cache_wait_t::request_id, dt_dev_pixelpipe_cache_wait_t::restart, dt_dev_pixelpipe_cache_wait_manager_t::served_requests, darktable_t::signals, TRUE, dt_dev_pixelpipe_cache_wait_t::user_data, dt_dev_pixelpipe_cache_wait_record_t::wait, and dt_dev_pixelpipe_cache_wait_manager_t::wait_cursor_active.

Referenced by _dt_dev_pixelpipe_cache_wait_ready_callback(), dt_dev_pixelpipe_cache_peek_gui(), and dt_dev_pixelpipe_cache_wait_cleanup().

◆ _find_detailmask_node()

static GList * _find_detailmask_node ( dt_dev_pixelpipe_t pipe)
static

◆ _get_debug_pipe_name()

◆ _module_requires_global_histogram_input_cache()

static gboolean _module_requires_global_histogram_input_cache ( const dt_dev_pixelpipe_t pipe,
const dt_iop_module_t module 
)
static

◆ _module_requires_global_histogram_output_cache()

static gboolean _module_requires_global_histogram_output_cache ( const dt_dev_pixelpipe_t pipe,
const dt_iop_module_t module 
)
static

◆ _prepare_piece_input_contract()

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 
)
static

◆ _refresh_pipe_detail_mask_state()

◆ _seal_opencl_cache_policy()

static void _seal_opencl_cache_policy ( dt_dev_pixelpipe_t pipe)
static

Seal host-cache retention policy on synchronized pieces before processing starts.

piece->cache_output_on_ram is part of the sealed runtime contract: the processing recursion only consumes it and must not infer GUI/runtime heuristics while running. This pass therefore authors all host-cache retention requests immediately after history synchronization, while the live pipe graph and current GUI state are both known.

The reverse walk carries one upstream requirement: "the previous enabled module must keep its output on host because the current enabled module will read from RAM instead of OpenCL".

Keep that carry explicit: we only cache module outputs, so any consumer that needs the current module input must author a requirement on the previous enabled module, not on the current one.

We add to that:

  • the module's own authored cache_output_on_ram,
  • user cache preferences,
  • active color-picker sampling,
  • global histogram stages sampling their output,
  • active GUI editing on the module itself.

GUI cache requests are intentionally not turned into eager host retention here. dt_dev_pixelpipe_cache_peek_gui() can already reopen a device-only cacheline and materialize RAM on demand, so keeping the one-shot request out of this policy avoids forcing stale module-output cachelines to be published to host just because a transient GUI reader missed once.

Definition at line 331 of file dev_pixelpipe.c.

References _module_requires_global_histogram_input_cache(), _module_requires_global_histogram_output_cache(), dt_dev_pixelpipe_t::autoset, dt_dev_pixelpipe_iop_t::cache_output_on_ram, dt_dev_pixelpipe_iop_t::data, dt_dev_pixelpipe_t::dev, dt_conf_get_bool(), dt_conf_key_exists(), dt_conf_key_not_empty(), dt_conf_set_bool(), DT_DEV_PIXELPIPE_FULL, dt_dev_pixelpipe_get_realtime(), DT_DEV_PIXELPIPE_PREVIEW, dt_free, dt_iop_color_picker_force_cache(), dt_opencl_is_inited(), DT_REQUEST_ON, DT_REQUEST_ONLY_IN_GUI, dt_dev_pixelpipe_iop_t::enabled, FALSE, dt_develop_t::gui_attached, dt_develop_t::gui_module, dt_dev_pixelpipe_t::gui_observable_source, IS_NULL_PTR, dt_dev_pixelpipe_t::nodes, dt_dev_pixelpipe_iop_t::process_cl_ready, dt_dev_pixelpipe_iop_t::request_histogram, TRUE, and dt_dev_pixelpipe_t::type.

Referenced by dt_dev_pixelpipe_change().

◆ _sync_focused_in_place()

static gboolean _sync_focused_in_place ( dt_dev_pixelpipe_t pipe)
static

Re-commit the focused module's piece in place from transient (or realtime) params.

Interactive editing (drawlayer realtime stroke, ashift/crop edit mode) keeps changing the focused module's params while the pipe is already instantiated. Rather than replaying the generic synch_top() walk, we refresh just that one piece and recompute the cumulative global hash, which naturally re-keys the focused piece and every downstream piece in the pixelpipe cache.

The params come from the thread-safe transient channel when the focused module has published one (dt_dev_transient_params_*), otherwise from the module's history snapshot. We never read the GUI-owned module->params from this (pipeline) thread. The module's enable/blend state is taken from its history item, since transient edits change params only.

This helper only replaces the history-tail replay. The rest of dt_dev_pixelpipe_change() still runs afterwards so cache policy and ROI contracts remain sealed for the next processing pass.

Definition at line 241 of file dev_pixelpipe.c.

References _refresh_pipe_detail_mask_state(), dt_dev_history_item_t::blend_params, dt_dev_pixelpipe_iop_t::detail_mask, dt_develop_blend_params_t::details, dt_dev_pixelpipe_t::dev, DT_DEV_DETAIL_MASK_NONE, dt_dev_get_history_end_ext(), dt_dev_history_get_last_item_by_module(), dt_dev_pixelpipe_get_module_piece(), dt_dev_pixelpipe_get_realtime(), dt_dev_pixelpipe_propagate_formats(), dt_dev_transient_params_active(), dt_dev_transient_params_get(), dt_free, dt_iop_commit_params(), dt_pixelpipe_get_global_hash(), dt_dev_history_item_t::enabled, dt_dev_pixelpipe_iop_t::enabled, FALSE, dt_develop_t::gui_module, dt_dev_history_item_t::hash, dt_develop_t::history, IS_NULL_PTR, dt_dev_pixelpipe_t::last_history_hash, dt_dev_pixelpipe_t::last_history_item, dt_dev_history_item_t::params, dt_iop_module_t::params_size, TRUE, and dt_dev_pixelpipe_t::want_detail_mask.

Referenced by dt_dev_pixelpipe_change().

◆ _sync_pipe_nodes_from_history()

◆ _sync_pipe_nodes_from_history_from_node()

◆ _sync_virtual_pipe()

◆ dt_dev_pixelpipe_activemodule_disables_currentmodule()

gboolean dt_dev_pixelpipe_activemodule_disables_currentmodule ( struct dt_develop_t dev,
struct dt_iop_module_t current_module 
)

◆ dt_dev_pixelpipe_cache_peek_gui()

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 
)

Definition at line 687 of file dev_pixelpipe.c.

References _cache_wait_cursor_progress(), _cache_wait_manager, _dt_dev_pixelpipe_cache_wait_ready_callback(), dt_dev_pixelpipe_t::backbuf, dt_dev_pixelpipe_iop_t::bypass_cache, dt_dev_pixelpipe_cache_wait_manager_t::connected, dt_dev_pixelpipe_cache_wait_t::connected, darktable, DT_DEBUG_CONTROL_SIGNAL_CONNECT, DT_DEBUG_DEV, DT_DEBUG_PIPECACHE, dt_dev_backbuf_get_hash(), DT_DEV_PIPE_CACHE_REQUEST, dt_dev_pixelpipe_cache_peek(), DT_DEV_PIXELPIPE_CACHE_REQUEST_BACKBUF, DT_DEV_PIXELPIPE_CACHE_REQUEST_MODULE, dt_dev_pixelpipe_cache_wait_cleanup(), dt_dev_pixelpipe_get_hash(), dt_dev_pixelpipe_get_realtime(), dt_dev_pixelpipe_or_changed(), dt_dev_pixelpipe_set_cache_request(), DT_PIXELPIPE_CACHE_HASH_INVALID, dt_pixelpipe_get_pipe_name(), dt_print(), dt_pthread_mutex_lock(), dt_pthread_mutex_trylock(), dt_pthread_mutex_unlock(), DT_SIGNAL_CACHELINE_READY, FALSE, dt_dev_pixelpipe_iop_t::global_hash, dt_dev_pixelpipe_cache_wait_t::hash, dt_dev_pixelpipe_cache_wait_manager_t::immediate_hits, IS_NULL_PTR, dt_dev_pixelpipe_cache_wait_manager_t::lock, dt_dev_pixelpipe_cache_wait_manager_t::misses, dt_dev_pixelpipe_cache_wait_manager_t::next_request_id, dt_dev_pixelpipe_t::no_cache, dt_dev_pixelpipe_cache_wait_t::owner_object, dt_dev_pixelpipe_cache_wait_t::owner_tag, dt_dev_pixelpipe_cache_wait_manager_t::pending, dt_dev_pixelpipe_cache_wait_t::pipe, darktable_t::pixelpipe_cache, dt_dev_pixelpipe_cache_wait_record_t::queued_at_us, dt_dev_pixelpipe_cache_wait_manager_t::queued_requests, dt_dev_pixelpipe_cache_wait_record_t::request_id, dt_dev_pixelpipe_cache_wait_t::request_id, dt_dev_pixelpipe_cache_wait_t::restart, darktable_t::signals, TRUE, dt_dev_pixelpipe_t::type, dt_dev_pixelpipe_cache_wait_t::user_data, dt_dev_pixelpipe_cache_wait_record_t::wait, and dt_dev_pixelpipe_cache_wait_manager_t::wait_cursor_active.

Referenced by _lib_navigation_draw_callback(), _lib_navigation_history_resync_callback(), _lock_pipe_surface(), _pixelpipe_pick_from_image(), _process_histogram(), _process_vectorscope(), _refresh_global_histogram_backbuf_for_hash(), _refresh_preview_cursor_sample(), _refresh_preview_module_histogram_for_hash(), _sample_picker_from_cache(), and dt_iop_autoset_advance().

◆ dt_dev_pixelpipe_cache_wait_cleanup()

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.

This removes wait from the shared pending queue (if connected), emits a lifecycle debug log and resets the wait object to an inert state. Callers should pass a short static reason string to make cancellations traceable in logs.

Parameters
waitCaller-owned wait object.
reasonShort static cancellation context label for debug traces.

Definition at line 913 of file dev_pixelpipe.c.

References _cache_wait_cursor_restore(), _cache_wait_manager, _cache_wait_manager_remove_wait_locked(), _dt_dev_pixelpipe_cache_wait_ready_callback(), dt_dev_pixelpipe_cache_wait_manager_t::cancelled_requests, dt_dev_pixelpipe_cache_wait_manager_t::connected, dt_dev_pixelpipe_cache_wait_t::connected, darktable, DT_DEBUG_CONTROL_SIGNAL_DISCONNECT, DT_DEBUG_PIPECACHE, dt_free, DT_PIXELPIPE_CACHE_HASH_INVALID, dt_print(), dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), FALSE, dt_dev_pixelpipe_cache_wait_t::hash, IS_NULL_PTR, dt_dev_pixelpipe_cache_wait_manager_t::lock, MAX, dt_dev_pixelpipe_cache_wait_t::owner_tag, dt_dev_pixelpipe_cache_wait_manager_t::pending, dt_dev_pixelpipe_cache_wait_t::pipe, dt_dev_pixelpipe_cache_wait_record_t::queued_at_us, dt_dev_pixelpipe_cache_wait_t::request_id, dt_dev_pixelpipe_cache_wait_t::restart, darktable_t::signals, TRUE, dt_dev_pixelpipe_cache_wait_t::user_data, and dt_dev_pixelpipe_cache_wait_manager_t::wait_cursor_active.

Referenced by _color_picker_callback_button_press(), _refresh_preview_cursor_sample(), _release_expose_source_caches(), cleanup(), dt_dev_pixelpipe_cache_peek_gui(), dt_iop_autoset_advance(), dt_iop_autoset_build_list(), dt_iop_color_picker_reset(), gui_cleanup(), gui_cleanup(), gui_focus(), leave(), and view_leave().

◆ dt_dev_pixelpipe_cache_wait_dump_pending()

void dt_dev_pixelpipe_cache_wait_dump_pending ( const char *  reason)

Dump pending GUI cache wait requests for lifecycle debugging.

This reports the current queue of not-yet-served cache wait requests, with ownership tags, request ids and target hashes. Callers should use it right before teardown phases (view leave / app shutdown) to identify abandoned waits that never received a cacheline-ready event.

Parameters
reasonShort caller-provided context label for the log entry.

Definition at line 105 of file dev_pixelpipe.c.

References _cache_wait_manager, dt_dev_pixelpipe_cache_wait_manager_t::cancelled_requests, dt_dev_pixelpipe_cache_wait_t::connected, DT_DEBUG_PIPECACHE, dt_print(), dt_pthread_mutex_trylock(), dt_pthread_mutex_unlock(), dt_dev_pixelpipe_cache_wait_t::hash, dt_dev_pixelpipe_cache_wait_manager_t::immediate_hits, IS_NULL_PTR, dt_dev_pixelpipe_cache_wait_manager_t::lock, MAX, dt_dev_pixelpipe_cache_wait_manager_t::misses, dt_dev_pixelpipe_cache_wait_t::owner_tag, dt_dev_pixelpipe_cache_wait_manager_t::pending, dt_dev_pixelpipe_cache_wait_record_t::queued_at_us, dt_dev_pixelpipe_cache_wait_manager_t::queued_requests, dt_dev_pixelpipe_cache_wait_t::request_id, dt_dev_pixelpipe_cache_wait_manager_t::served_requests, and dt_dev_pixelpipe_cache_wait_record_t::wait.

Referenced by dt_cleanup(), and leave().

◆ dt_dev_pixelpipe_cache_wait_set_owner()

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.

The cache wait manager tracks heterogeneous GUI consumers (pickers, histograms, autoset, darkroom surfaces) in a shared pending queue. This setter lets each caller stamp the wait object with:

  • a stable textual tag ( owner_tag) used in logs,
  • the originating runtime object pointer ( owner_object) used to correlate repeated requests from the same caller.

Ownership metadata does not affect scheduling or locking decisions. It only improves traceability when diagnosing missed/served requests and UI/pipeline desynchronization.

Parameters
waitCaller-owned wait object to annotate.
owner_tagShort static owner label for debug traces.
owner_objectCaller instance pointer associated with the request.

Definition at line 967 of file dev_pixelpipe.c.

References IS_NULL_PTR, dt_dev_pixelpipe_cache_wait_t::owner_object, and dt_dev_pixelpipe_cache_wait_t::owner_tag.

Referenced by _lib_navigation_draw_callback(), _lib_navigation_history_resync_callback(), _lock_pipe_surface(), _pixelpipe_pick_from_image(), _process_histogram(), _process_vectorscope(), _refresh_preview_cursor_sample(), _refresh_preview_module_histogram_for_hash(), _sample_picker_from_cache(), and dt_iop_autoset_advance().

◆ dt_dev_pixelpipe_change()

void dt_dev_pixelpipe_change ( dt_dev_pixelpipe_t pipe)

Consume and clear pending change flags in one atomic step.

The previous get-then-store sequence could lose updates when another thread OR-ed a new flag between the load and the reset. That made history resync requests randomly disappear, especially under fast GUI actions such as toggles or consecutive parameter commits.

Definition at line 1527 of file dev_pixelpipe.c.

References _get_debug_pipe_name(), _refresh_pipe_detail_mask_state(), _seal_opencl_cache_policy(), _sync_focused_in_place(), dt_dev_pixelpipe_t::bypass_blendif, dt_dev_pixelpipe_t::changed, dt_dev_pixelpipe_t::dev, dt_atomic_exch_int(), DT_DEBUG_DEV, DT_DEV_DETAIL_MASK_NONE, dt_dev_get_history_hash(), DT_DEV_PIPE_CACHE_REQUEST, DT_DEV_PIPE_REENTRY, DT_DEV_PIPE_REMOVE, DT_DEV_PIPE_SYNCH, DT_DEV_PIPE_TOP_CHANGED, DT_DEV_PIPE_UNCHANGED, DT_DEV_PIPE_ZOOMED, dt_dev_pixelpipe_cleanup_nodes(), dt_dev_pixelpipe_create_nodes(), DT_DEV_PIXELPIPE_DISPLAY_NONE, dt_dev_pixelpipe_get_roi_out(), dt_dev_pixelpipe_propagate_formats(), dt_dev_pixelpipe_set_history_hash(), dt_dev_pixelpipe_sync_no_history(), dt_dev_pixelpipe_synch_all, dt_dev_pixelpipe_synch_top(), dt_free, dt_get_times(), dt_print(), dt_pthread_rwlock_rdlock, dt_pthread_rwlock_unlock, dt_show_times_f(), FALSE, dt_develop_t::history_mutex, dt_dev_pixelpipe_t::iheight, dt_dev_pixelpipe_t::iwidth, dt_dev_pixelpipe_t::mask_display, dt_dev_pixelpipe_t::nodes, dt_dev_pixelpipe_t::processed_height, dt_dev_pixelpipe_t::processed_width, TRUE, type, and dt_dev_pixelpipe_t::want_detail_mask.

Referenced by _resync_pipe_with_history(), _sync_virtual_pipe(), and dt_dev_get_thumbnail_size().

◆ dt_dev_pixelpipe_change_zoom_main()

◆ dt_dev_pixelpipe_get_module_piece()

◆ dt_dev_pixelpipe_get_prev_enabled_piece()

◆ dt_dev_pixelpipe_get_roi_in()

◆ dt_dev_pixelpipe_get_roi_out()

◆ dt_dev_pixelpipe_is_backbufer_valid()

◆ dt_dev_pixelpipe_is_pipeline_valid()

gboolean dt_dev_pixelpipe_is_pipeline_valid ( dt_dev_pixelpipe_t pipe)

◆ dt_dev_pixelpipe_node_hash()

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 
)

◆ dt_dev_pixelpipe_propagate_formats()

◆ dt_dev_pixelpipe_rebuild_all_real()

◆ dt_dev_pixelpipe_reset_all()

◆ dt_dev_pixelpipe_resync_history_all_real()

void dt_dev_pixelpipe_resync_history_all_real ( dt_develop_t dev)

◆ dt_dev_pixelpipe_resync_history_main_real()

void dt_dev_pixelpipe_resync_history_main_real ( dt_develop_t dev)

◆ dt_dev_pixelpipe_resync_history_preview_real()

void dt_dev_pixelpipe_resync_history_preview_real ( dt_develop_t dev)

◆ dt_dev_pixelpipe_sync_no_history()

void dt_dev_pixelpipe_sync_no_history ( dt_dev_pixelpipe_t pipe)

◆ dt_dev_pixelpipe_sync_virtual()

void dt_dev_pixelpipe_sync_virtual ( dt_develop_t dev,
dt_dev_pixelpipe_change_t  flag 
)

Definition at line 1655 of file dev_pixelpipe.c.

References _sync_virtual_pipe(), and flag.

Referenced by _enter_edit_mode(), do_crop(), gui_post_expose(), and gui_post_expose().

◆ dt_dev_pixelpipe_synch_all_real()

void dt_dev_pixelpipe_synch_all_real ( dt_dev_pixelpipe_t pipe,
const char *  caller_func 
)

Find the last history item matching each pipeline node (module), in the order of pipeline execution. This is super important because modules providing raster masks need to be inited before modules using them, in the order of pipeline nodes. But history holds no guaranty that raster masks providers will be older than raster masks users, especially after history compression. So reading in history order is not an option.

Parameters
pipe
dev
caller_func

Definition at line 1437 of file dev_pixelpipe.c.

References _get_debug_pipe_name(), _sync_pipe_nodes_from_history(), dt_dev_pixelpipe_t::dev, DT_DEBUG_DEV, dt_dev_get_history_end_ext(), dt_free, DT_PIXELPIPE_CACHE_HASH_INVALID, dt_print(), dt_dev_history_item_t::hash, dt_develop_t::history, dt_dev_pixelpipe_t::last_history_hash, dt_dev_pixelpipe_t::last_history_item, and type.

◆ dt_dev_pixelpipe_synch_top()

◆ dt_dev_pixelpipe_update_history_all_real()

void dt_dev_pixelpipe_update_history_all_real ( dt_develop_t dev)

◆ dt_dev_pixelpipe_update_history_main_real()

void dt_dev_pixelpipe_update_history_main_real ( dt_develop_t dev)

◆ dt_dev_pixelpipe_update_history_preview_real()

void dt_dev_pixelpipe_update_history_preview_real ( dt_develop_t dev)

◆ dt_dev_pixelpipe_update_zoom_main_real()

◆ dt_dev_pixelpipe_update_zoom_preview_real()

void dt_dev_pixelpipe_update_zoom_preview_real ( dt_develop_t dev)

◆ dt_pixelpipe_get_global_hash()

Variable Documentation

◆ _cache_wait_manager

dt_dev_pixelpipe_cache_wait_manager_t _cache_wait_manager
static
Initial value:
= { .lock = { PTHREAD_MUTEX_INITIALIZER }, .pending = NULL, .connected = FALSE,
.wait_cursor_active = FALSE,
.next_request_id = 1, .queued_requests = 0, .served_requests = 0,
.cancelled_requests = 0, .immediate_hits = 0, .misses = 0 }
#define FALSE
Definition ashift_lsd.c:158

Definition at line 65 of file dev_pixelpipe.c.

Referenced by _cache_wait_manager_remove_wait_locked(), _dt_dev_pixelpipe_cache_wait_ready_callback(), dt_dev_pixelpipe_cache_peek_gui(), dt_dev_pixelpipe_cache_wait_cleanup(), and dt_dev_pixelpipe_cache_wait_dump_pending().