Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
dev_pixelpipe.c File Reference
#include "widgets/widget_settings.h"
#include "common/conf.h"
#include "system/macros.h"
#include "develop/pipe_cache_policy.h"
#include "system/mem_alloc.h"
#include "common/hash.h"
#include "common/logging.h"
#include "common/times.h"
#include "common/paths.h"
#include "gui/application.h"
#include "system/dtpthread.h"
#include "system/atomic.h"
#include "develop/dev_history.h"
#include "develop/geometry/geometry.h"
#include "develop/imageop.h"
#include "develop/pixelpipe.h"
#include "caches/pixelpipe_cache.h"
#include "develop/supervisor.h"
#include "develop/blend.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.

Functions

static void _sync_pipe_nodes_from_history_from_node (dt_dev_pixelpipe_t *pipe, GList *history_list, const uint32_t history_end, GList *start_node, const char *debug_label)
 
static void _dt_dev_pixelpipe_cache_wait_ready_callback (gpointer instance, const guint64 hash, const guint64 producer_node_key, gpointer user_data)
 Serve queued GUI cache waiters matching one published cacheline hash.
 
static gboolean _cache_wait_cursor_progress (gpointer user_data)
 
static gboolean _cache_wait_cursor_restore (gpointer user_data)
 
static void _dump_one_pending (const dt_dev_pixelpipe_cache_wait_t *wait, const int64_t age_us, gpointer user_data)
 
void dt_dev_pixelpipe_cache_wait_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 gboolean _module_feeds_color_picker (const dt_dev_pixelpipe_t *pipe, const dt_iop_module_t *module, const dt_iop_module_t *picker_module)
 Is module the one a picker samples, or the one feeding it?
 
static 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 void _pipe_set_last_history_item (dt_dev_pixelpipe_t *pipe, dt_dev_history_item_t *hist)
 Re-commit the focused module's piece in place from transient (or realtime) params.
 
static gboolean _sync_focused_in_place (dt_dev_pixelpipe_t *pipe, const dt_dev_history_snapshot_t *snap)
 
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)
 
static gboolean _peek_gui (dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, void **data, dt_pixel_cache_entry_t **cache_entry, dt_dev_pixelpipe_cache_wait_t *wait, dt_dev_pixelpipe_cache_ready_callback_t restart, gpointer restart_data, const gboolean retain)
 
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)
 
gboolean dt_dev_pixelpipe_cache_peek_gui_retained (dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, void **data, dt_pixel_cache_entry_t **cache_entry, dt_dev_pixelpipe_cache_wait_t *wait, dt_dev_pixelpipe_cache_ready_callback_t restart, gpointer restart_data)
 
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, GList *history_list, const uint32_t history_end, const char *debug_label)
 
void dt_pixelpipe_get_global_hash (dt_dev_pixelpipe_t *pipe)
 
static void _synch_all_snapshot (dt_dev_pixelpipe_t *pipe, const dt_dev_history_snapshot_t *snap, const char *caller_func)
 Find the last history item matching each pipeline node (module), in the order of pipeline execution. 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_all_real (dt_dev_pixelpipe_t *pipe, const char *caller_func)
 
static void _synch_top_snapshot (dt_dev_pixelpipe_t *pipe, const dt_dev_history_snapshot_t *snap)
 
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)
 
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 gboolean _cache_wait_connected = FALSE
 
static gboolean _cache_wait_cursor_active = FALSE
 

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

◆ _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,
const guint64  producer_node_key,
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 every waiter whose requested hash matches hash or whose target module matches the producing node producer_node_key,
  3. disconnect the global signal and clear the busy cursor when the queue becomes empty,
  4. release the lock before running restart callbacks.

The producer-node match (step 2) is what makes the protocol robust to hash drift: a waiter registers the hash it predicted on the GUI thread, but the worker recomputes all hashes and may publish a different one for the same module output (doc/pipeline-cache.md ยง8). Matching on the producing node then still serves the right consumer; its restart re-reads the module's current output hash and hits. The exact-hash match is kept as the fast common path and because it is a pure value comparison (independent of the just-published entry, which may already be evicted by the time this GUI-thread callback runs), so the existing served-then-re-miss self-healing is preserved.

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 956 of file dev_pixelpipe.c.

References _cache_wait_connected, _cache_wait_cursor_active, _cache_wait_cursor_restore(), _dt_dev_pixelpipe_cache_wait_ready_callback(), dt_control_signal_get_global(), DT_DEBUG_CONTROL_SIGNAL_DISCONNECT, DT_DEBUG_PIPECACHE, DT_PIXELPIPE_CACHE_HASH_INVALID, dt_pixelpipe_cache_wait_take_matching(), dt_print(), dt_supervisor_active(), dt_supervisor_cache_wait(), DT_SV_DELETE, FALSE, dt_pixelpipe_cache_wait_t::hash, IS_NULL_PTR, dt_pixelpipe_cache_wait_t::module_multi_priority, dt_pixelpipe_cache_wait_t::module_op, dt_pixelpipe_cache_wait_t::owner_tag, dt_pixelpipe_cache_wait_t::pipe, dt_pixelpipe_cache_wait_t::pipe_imgid, dt_pixelpipe_cache_wait_t::pipe_type, dt_pixelpipe_cache_wait_t::request_id, dt_pixelpipe_cache_wait_t::restart, dt_pixelpipe_cache_wait_t::target_node_key, TRUE, and dt_pixelpipe_cache_wait_t::user_data.

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

◆ _dump_one_pending()

◆ _find_detailmask_node()

static GList * _find_detailmask_node ( dt_dev_pixelpipe_t pipe)
static

◆ _get_debug_pipe_name()

◆ _module_feeds_color_picker()

static gboolean _module_feeds_color_picker ( const dt_dev_pixelpipe_t pipe,
const dt_iop_module_t module,
const dt_iop_module_t picker_module 
)
static

Is module the one a picker samples, or the one feeding it?

A picker reads its module's OUTPUT and the output of the enabled module before it (its own input), so both must keep a host copy. picker_module is the identity the caller sampled once for the whole walk, not the live dev field – and it is only ever compared here, never followed, so a module torn down since the sample cannot be dereferenced through it.

This was dt_iop_color_picker_force_cache() in gui/color_picker_proxy.c, which read pipe->dev->color_picker.module itself. Nothing about it was GUI code: it walks pipe nodes and compares module identities, and the seal was its only caller.

Definition at line 150 of file dev_pixelpipe.c.

References dt_dev_pixelpipe_get_module_piece(), dt_dev_pixelpipe_get_prev_enabled_piece(), FALSE, IS_NULL_PTR, and TRUE.

Referenced by _seal_opencl_cache_policy().

◆ _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

◆ _peek_gui()

static gboolean _peek_gui ( dt_dev_pixelpipe_t pipe,
const dt_dev_pixelpipe_iop_t piece,
void **  data,
dt_pixel_cache_entry_t **  cache_entry,
dt_dev_pixelpipe_cache_wait_t wait,
dt_dev_pixelpipe_cache_ready_callback_t  restart,
gpointer  restart_data,
const gboolean  retain 
)
static

Definition at line 714 of file dev_pixelpipe.c.

References _cache_wait_connected, _cache_wait_cursor_active, _cache_wait_cursor_progress(), _dt_dev_pixelpipe_cache_wait_ready_callback(), dt_dev_pixelpipe_t::backbuf, dt_dev_pixelpipe_iop_t::bypass_cache, dt_pixelpipe_cache_wait_t::connected, dt_control_signal_get_global(), 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_ref_count_entry(), dt_dev_pixelpipe_cache_ref_host_entry_by_hash(), 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_cache_wait_count_immediate_hit(), dt_pixelpipe_cache_wait_count_miss(), dt_pixelpipe_cache_wait_enqueue(), dt_pixelpipe_get_pipe_name(), dt_print(), DT_SIGNAL_CACHELINE_READY, dt_supervisor_active(), dt_supervisor_cache_wait(), dt_supervisor_node_key(), DT_SV_CREATE, DT_SV_READ, FALSE, dt_dev_pixelpipe_iop_t::global_hash, dt_pixelpipe_cache_wait_t::hash, dt_dev_pixelpipe_t::imgid, IS_NULL_PTR, dt_pixelpipe_cache_wait_t::module_multi_priority, dt_pixelpipe_cache_wait_t::module_op, dt_iop_module_t::multi_priority, dt_dev_pixelpipe_t::no_cache, dt_iop_module_t::op, dt_pixelpipe_cache_wait_t::owner_object, dt_pixelpipe_cache_wait_t::owner_tag, dt_pixelpipe_cache_wait_t::pipe, dt_pixelpipe_cache_wait_t::pipe_imgid, dt_pixelpipe_cache_wait_t::pipe_type, dt_pixelpipe_cache_wait_t::request_id, dt_pixelpipe_cache_wait_t::restart, dt_pixelpipe_cache_wait_t::target_node_key, TRUE, dt_dev_pixelpipe_t::type, and dt_pixelpipe_cache_wait_t::user_data.

Referenced by dt_dev_pixelpipe_cache_peek_gui(), and dt_dev_pixelpipe_cache_peek_gui_retained().

◆ _pipe_set_last_history_item()

static void _pipe_set_last_history_item ( dt_dev_pixelpipe_t pipe,
dt_dev_history_item_t hist 
)
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 243 of file dev_pixelpipe.c.

References dt_atomic_exch_ptr(), dt_dev_free_history_item(), dt_dev_history_item_ref(), IS_NULL_PTR, and dt_dev_pixelpipe_t::last_history_item.

Referenced by _sync_focused_in_place(), _synch_all_snapshot(), and _synch_top_snapshot().

◆ _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 343 of file dev_pixelpipe.c.

References _module_feeds_color_picker(), _module_requires_global_histogram_input_cache(), _module_requires_global_histogram_output_cache(), dt_dev_pipe_cache_policy_inputs_t::authored_cache, dt_dev_pixelpipe_t::autoset, dt_dev_pixelpipe_iop_t::cache_output_on_ram, dt_develop_t::color_picker, 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_pipe_cache_policy_decide(), DT_DEV_PIXELPIPE_FULL, dt_dev_pixelpipe_get_realtime(), DT_DEV_PIXELPIPE_PREVIEW, dt_free, 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()

◆ _sync_pipe_nodes_from_history()

◆ _sync_pipe_nodes_from_history_from_node()

◆ _synch_all_snapshot()

static void _synch_all_snapshot ( dt_dev_pixelpipe_t pipe,
const dt_dev_history_snapshot_t snap,
const char *  caller_func 
)
static

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 1643 of file dev_pixelpipe.c.

References _get_debug_pipe_name(), _pipe_set_last_history_item(), _sync_pipe_nodes_from_history(), dt_dev_pixelpipe_t::dev, DT_DEBUG_DEV, dt_free, DT_PIXELPIPE_CACHE_HASH_INVALID, dt_print(), dt_dev_history_item_t::hash, dt_dev_history_snapshot_t::history_end, dt_dev_history_snapshot_t::items, dt_dev_pixelpipe_t::last_history_hash, and type.

Referenced by dt_dev_pixelpipe_change(), and dt_dev_pixelpipe_synch_all_real().

◆ _synch_top_snapshot()

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

◆ dt_dev_pixelpipe_cache_peek_gui_retained()

gboolean dt_dev_pixelpipe_cache_peek_gui_retained ( dt_dev_pixelpipe_t pipe,
const dt_dev_pixelpipe_iop_t piece,
void **  data,
dt_pixel_cache_entry_t **  cache_entry,
dt_dev_pixelpipe_cache_wait_t wait,
dt_dev_pixelpipe_cache_ready_callback_t  restart,
gpointer  restart_data 
)

◆ 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 1022 of file dev_pixelpipe.c.

References _cache_wait_connected, _cache_wait_cursor_active, _cache_wait_cursor_restore(), _dt_dev_pixelpipe_cache_wait_ready_callback(), dt_pixelpipe_cache_wait_t::connected, dt_control_signal_get_global(), DT_DEBUG_CONTROL_SIGNAL_DISCONNECT, DT_DEBUG_PIPECACHE, DT_PIXELPIPE_CACHE_HASH_INVALID, dt_pixelpipe_cache_wait_cancel(), dt_print(), dt_supervisor_active(), dt_supervisor_cache_wait(), DT_SV_DELETE, FALSE, dt_pixelpipe_cache_wait_t::hash, IS_NULL_PTR, dt_pixelpipe_cache_wait_t::module_multi_priority, dt_pixelpipe_cache_wait_t::module_op, dt_pixelpipe_cache_wait_t::owner_tag, dt_pixelpipe_cache_wait_t::pipe, dt_pixelpipe_cache_wait_t::pipe_imgid, dt_pixelpipe_cache_wait_t::pipe_type, dt_pixelpipe_cache_wait_t::request_id, dt_pixelpipe_cache_wait_t::restart, dt_pixelpipe_cache_wait_t::target_node_key, TRUE, and dt_pixelpipe_cache_wait_t::user_data.

Referenced by _color_picker_callback_button_press(), _color_picker_widget_destroy(), _dt_iop_autoset_finish(), _peek_gui(), _refresh_preview_cursor_sample(), _release_expose_source_caches(), _studio_dev_teardown(), cleanup(), 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 100 of file dev_pixelpipe.c.

References _dump_one_pending(), DT_DEBUG_PIPECACHE, dt_pixelpipe_cache_wait_foreach_pending(), dt_pixelpipe_cache_wait_get_stats(), dt_pixelpipe_cache_wait_pending_count(), dt_print(), and IS_NULL_PTR.

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 1090 of file dev_pixelpipe.c.

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

Referenced by _lib_navigation_draw_callback(), _lib_navigation_history_resync_callback(), _pixelpipe_pick_from_image(), _process_histogram(), _process_vectorscope(), _refresh_preview_cursor_sample(), _refresh_preview_module_histogram_for_hash(), _sample_picker_from_cache(), dt_dev_lock_pipe_surface(), 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 1771 of file dev_pixelpipe.c.

References _get_debug_pipe_name(), _refresh_pipe_detail_mask_state(), _seal_opencl_cache_policy(), _sync_focused_in_place(), _synch_all_snapshot(), _synch_top_snapshot(), dt_dev_pixelpipe_t::bypass_blendif, dt_dev_pixelpipe_t::changed, dt_dev_pixelpipe_t::dev, dt_atomic_exch_int(), DT_DEBUG_DEV, DT_DEBUG_HISTORY, DT_DEV_DETAIL_MASK_NONE, dt_dev_history_snapshot_release(), dt_dev_history_snapshot_take(), 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_free, dt_get_times(), dt_get_wtime(), dt_print(), dt_pthread_rwlock_rdlock(), dt_pthread_rwlock_unlock(), dt_show_times_f(), FALSE, dt_dev_history_snapshot_t::history_hash, 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, status, TRUE, type, and dt_dev_pixelpipe_t::want_detail_mask.

Referenced by _process_at_roi(), and _resync_pipe_with_history().

◆ 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_synch_all_real()

◆ 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_connected

gboolean _cache_wait_connected = FALSE
static

◆ _cache_wait_cursor_active

gboolean _cache_wait_cursor_active = FALSE
static