![]() |
Ansel 0.0
A darktable fork - bloat + design vision
|
Pixelpipe GUI sampling helpers (histograms + color picker). More...
#include "common/color_picker.h"#include "common/darktable.h"#include "common/histogram.h"#include "common/iop_order.h"#include "control/signal.h"#include "develop/blend.h"#include "develop/pixelpipe.h"#include "develop/pixelpipe_cache.h"#include "gui/color_picker_proxy.h"#include "libs/colorpicker.h"#include <math.h>#include <string.h>
Include dependency graph for pixelpipe_gui.c:
This graph shows which files directly or indirectly include this file:Go to the source code of this file.
Typedefs | |
| typedef enum dt_pixelpipe_picker_source_t | dt_pixelpipe_picker_source_t |
| Identify whether the picker sampling is applied on the module input or output. | |
Enumerations | |
| enum | dt_pixelpipe_picker_source_t { PIXELPIPE_PICKER_INPUT = 0 , PIXELPIPE_PICKER_OUTPUT = 1 } |
| Identify whether the picker sampling is applied on the module input or output. More... | |
Functions | |
| static void | histogram_collect (dt_dev_pixelpipe_iop_t *piece, const void *pixel, const dt_iop_roi_t roi, uint32_t **histogram, uint32_t *histogram_max) |
| Compute a histogram for a given module piece. | |
| static dt_backbuf_t * | _get_backuf (dt_develop_t *dev, const char *op) |
| Map an op name to the corresponding global histogram backbuffer. | |
| static void | pixelpipe_get_histogram_backbuf (dt_develop_t *dev, const dt_iop_roi_t roi, dt_pixel_cache_entry_t *entry, dt_iop_module_t *module, const uint64_t hash) |
| Update the global histogram backbuffer to reference a specific cache entry. | |
| static gboolean | _pipe_tracks_gui_observables (const dt_dev_pixelpipe_t *pipe, const dt_develop_t *dev) |
| static gboolean | _module_requests_color_picker (const dt_develop_t *dev, const dt_iop_module_t *module) |
| static gboolean | _module_requests_input_histogram (const dt_develop_t *dev, const dt_dev_pixelpipe_iop_t *piece) |
| static gboolean | _module_needs_gui_host_input_sampling (const dt_dev_pixelpipe_t *pipe, const dt_develop_t *dev, const dt_iop_module_t *module, const dt_dev_pixelpipe_iop_t *piece) |
| static gboolean | _module_needs_gui_output_backbuf_sync (const dt_dev_pixelpipe_t *pipe, const dt_develop_t *dev, const dt_iop_module_t *module) |
| static gboolean | _module_needs_gui_input_backbuf_sync (const dt_dev_pixelpipe_t *pipe, const dt_develop_t *dev, const dt_iop_module_t *module) |
| static gboolean | _pipe_needs_gui_sampling_traversal (const dt_dev_pixelpipe_t *pipe, const dt_develop_t *dev) |
| static gboolean | _module_exact_hit_must_recurse_for_picker (const dt_dev_pixelpipe_t *pipe, const dt_develop_t *dev, const dt_iop_module_t *module) |
| Tell whether an exact cache hit must still recurse to reach the active color picker module. | |
| static void | _sync_module_output_backbuf_on_exact_hit (dt_dev_pixelpipe_t *pipe, dt_develop_t *dev, dt_iop_module_t *module, dt_dev_pixelpipe_iop_t *piece, dt_pixel_cache_entry_t *output_entry, const dt_iop_roi_t roi_out, const uint64_t hash) |
| static int | pixelpipe_picker_helper (dt_iop_module_t *module, const dt_iop_roi_t roi, dt_aligned_pixel_t picked_color, dt_aligned_pixel_t picked_color_min, dt_aligned_pixel_t picked_color_max, dt_pixelpipe_picker_source_t picker_source, int *box) |
| Compute the sampling box in module coordinates for the interactive color picker. | |
| static void | pixelpipe_picker (dt_iop_module_t *module, dt_dev_pixelpipe_iop_t *piece, dt_iop_buffer_dsc_t *dsc, const float *pixel, const dt_iop_roi_t roi, float *picked_color, float *picked_color_min, float *picked_color_max, const dt_iop_colorspace_type_t image_cst, dt_pixelpipe_picker_source_t picker_source) |
| Sample the color picker values (avg/min/max) from a pixel buffer. | |
| static dt_iop_colorspace_type_t | _transform_for_picker (dt_iop_module_t *self, const dt_iop_colorspace_type_t cst) |
| Select a safe colorspace for picker sampling. | |
| static void | collect_histogram_on_CPU (dt_dev_pixelpipe_t *pipe, dt_develop_t *dev, float *input, const dt_iop_roi_t roi_in, dt_iop_buffer_dsc_t *input_format, dt_iop_module_t *module, dt_dev_pixelpipe_iop_t *piece) |
| Collect the per-module histogram on CPU for GUI display. | |
| static void | _sample_color_picker (dt_dev_pixelpipe_t *pipe, dt_develop_t *dev, float *input, dt_iop_buffer_dsc_t *input_format, const dt_iop_roi_t roi_in, void **output, dt_iop_buffer_dsc_t **out_format, const dt_iop_roi_t roi_out, dt_iop_module_t *module, dt_dev_pixelpipe_iop_t *piece) |
| Sample the interactive color picker for the currently edited module. | |
| static void | _sample_gui (dt_dev_pixelpipe_t *pipe, dt_develop_t *dev, void *input, void **output, const dt_iop_roi_t roi_in, const dt_iop_roi_t roi_out, dt_iop_buffer_dsc_t *input_format, dt_iop_buffer_dsc_t **output_format, dt_iop_module_t *module, dt_dev_pixelpipe_iop_t *piece, const uint64_t input_hash, const uint64_t hash, const size_t in_bpp, const size_t bpp, dt_pixel_cache_entry_t *const input_entry, dt_pixel_cache_entry_t *const output_entry) |
| Sample all GUI observables for a processed module node. | |
| static gboolean | _resync_global_histograms (dt_dev_pixelpipe_t *pipe, dt_develop_t *dev) |
| Re-sync the global histogram cache references on a pure cache hit. | |
Pixelpipe GUI sampling helpers (histograms + color picker).
This file centralizes the code paths that exist only to feed the GUI:
dt_develop_t,The pixelpipe (in pixelpipe_hb.c) is primarily a functional pipeline: "given an input buffer + module params → compute an output buffer".
GUI sampling is different:
gamma outputs uint8_t, but we want float32 for histograms),This means it adds complexity and cross-cutting concerns that should not pollute the main processing code.
1) GUI-observable pipes only These helpers are intended for pipes advertising pipe->gui_observable_source when dev->gui_attached is true. They must not be invoked for exports or background processing.
2) Cache entries are the source of truth The GUI should never access transient buffers directly. We always sample through cache entries, with appropriate cache locks, because the cache controls lifetime and eviction.
3) Gamma special case The gamma module produces uint8 output for display. Histograms and picker sampling expect float buffers. Therefore global histogram sampling for gamma uses the input cache entry, not the output.
4) Distortion backtransform for picker The picker position is expressed in final preview coordinates. We must backtransform it to the module coordinates, and the transform direction depends on whether we sample input or output.
5) OpenCL is not involved here GUI sampling runs on host buffers (RAM). Any OpenCL device buffers must have been synchronized into the cache earlier in the control flow (by design, the GUI always samples cache-backed host buffers).
6) In-place colorspace conversions Some sampling paths perform colorspace conversions in-place to make values meaningful to the user. This relies on higher-level pixelpipe control flow ensuring those buffers are not used afterward in a way that would be corrupted by the conversion (typically this is guarded by module activation / forced caching). If you change where these helpers are called, revisit those assumptions.
| typedef enum dt_pixelpipe_picker_source_t dt_pixelpipe_picker_source_t |
Identify whether the picker sampling is applied on the module input or output.
The GUI lets users request either:
This choice affects:
input vs *output),Identify whether the picker sampling is applied on the module input or output.
The GUI lets users request either:
This choice affects:
input vs *output),| Enumerator | |
|---|---|
| PIXELPIPE_PICKER_INPUT | |
| PIXELPIPE_PICKER_OUTPUT | |
|
static |
Map an op name to the corresponding global histogram backbuffer.
dev->raw_histogram, dev->output_histogram, dev->display_histogram, or NULL if the module is not wired to a global histogram.The develop module maintains three global histograms for UI display. We keep references to the cache entries feeding those histograms so that the underlying buffers are not evicted while the GUI reads them.
References dt_develop_t::display_histogram, dt_develop_t::output_histogram, and dt_develop_t::raw_histogram.
Referenced by _resync_global_histograms(), _set_opencl_cache(), and pixelpipe_get_histogram_backbuf().
|
inlinestatic |
Tell whether an exact cache hit must still recurse to reach the active color picker module.
Moving a picker changes only the sampled coordinates, not the module output hashes. This means downstream modules can exact-hit in cache while an upstream GUI module still needs fresh host-buffer sampling to emit DT_SIGNAL_CONTROL_PICKERDATA_READY.
If we returned early from those downstream exact hits, the recursion would never reach the active GUI module and the picker would move on screen without updating any parameter.
References _pipe_tracks_gui_observables().
Referenced by dt_dev_pixelpipe_process_rec().
|
inlinestatic |
References _module_requests_color_picker(), _module_requests_input_histogram(), and _pipe_tracks_gui_observables().
Referenced by _pipe_needs_gui_sampling_traversal().
|
inlinestatic |
References _pipe_tracks_gui_observables(), and dt_dev_pixelpipe_get_realtime().
|
inlinestatic |
References _pipe_tracks_gui_observables(), and dt_dev_pixelpipe_get_realtime().
Referenced by _sync_module_output_backbuf_on_exact_hit().
|
inlinestatic |
Referenced by _module_needs_gui_host_input_sampling().
|
inlinestatic |
References DT_REQUEST_ON, DT_REQUEST_ONLY_IN_GUI, dt_develop_t::gui_attached, and dt_dev_pixelpipe_iop_t::request_histogram.
Referenced by _module_needs_gui_host_input_sampling().
|
static |
|
inlinestatic |
References dt_develop_t::gui_attached, and dt_dev_pixelpipe_t::gui_observable_source.
Referenced by _module_exact_hit_must_recurse_for_picker(), _module_needs_gui_host_input_sampling(), _module_needs_gui_input_backbuf_sync(), _module_needs_gui_output_backbuf_sync(), _pipe_needs_gui_sampling_traversal(), _resync_global_histograms(), and _sample_gui().
|
static |
Re-sync the global histogram cache references on a pure cache hit.
A GUI-observable pipe can exit early if the final output cache entry is valid. When that happens, we still need to update the global histogram backbuffers to point at the right cache entries for demosaic/colorout/gamma. Realtime mode explicitly skips this path to avoid histogram sampling overhead.
If any required cache line is missing, we return FALSE so the caller recomputes the pipeline.
References _get_backuf(), _pipe_tracks_gui_observables(), darktable, dt_dev_pixelpipe_iop_t::data, dt_dev_pixelpipe_cache_peek(), dt_dev_pixelpipe_get_realtime(), dt_dev_pixelpipe_iop_t::enabled, dt_dev_pixelpipe_iop_t::global_hash, dt_dev_pixelpipe_t::nodes, darktable_t::pixelpipe_cache, pixelpipe_get_histogram_backbuf(), dt_dev_pixelpipe_iop_t::planned_roi_in, and dt_dev_pixelpipe_iop_t::planned_roi_out.
Referenced by dt_dev_pixelpipe_process().
|
static |
Sample the interactive color picker for the currently edited module.
This is strictly GUI-only and only applies to the module currently being edited (dev->gui_module). We may perform colorspace conversions in-place to match the picker expectations.
References _transform_for_picker(), dt_lib_t::colorpicker, dt_iop_buffer_dsc_t::cst, darktable, dt_dev_pixelpipe_t::dsc, dt_dev_pixelpipe_iop_t::dsc_in, DT_DEBUG_CONTROL_SIGNAL_RAISE, dt_ioppr_get_pipe_work_profile_info(), dt_ioppr_transform_image_colorspace(), DT_REQUEST_COLORPICK_OFF, DT_SIGNAL_CONTROL_PICKERDATA_READY, dt_iop_module_t::enabled, dt_develop_t::gui_module, dt_iop_roi_t::height, IOP_CS_RAW, darktable_t::lib, dt_iop_module_t::picked_color, dt_iop_module_t::picked_color_max, dt_iop_module_t::picked_color_min, dt_iop_module_t::picked_output_color, dt_iop_module_t::picked_output_color_max, dt_iop_module_t::picked_output_color_min, dt_lib_t::picker_proxy, pixelpipe_picker(), PIXELPIPE_PICKER_INPUT, PIXELPIPE_PICKER_OUTPUT, dt_lib_t::proxy, dt_iop_module_t::request_color_pick, darktable_t::signals, and dt_iop_roi_t::width.
Referenced by _sample_gui().
|
static |
Sample all GUI observables for a processed module node.
This function is called after a module was processed and its input/output are available in the cache.
It performs:
It locks the relevant cache entries for reading while sampling.
References _pipe_tracks_gui_observables(), _sample_color_picker(), bpp, collect_histogram_on_CPU(), darktable, dt_dev_pixelpipe_cache_rdlock_entry(), dt_dev_pixelpipe_get_realtime(), DT_PIXELPIPE_CACHE_HASH_INVALID, FALSE, dt_iop_module_t::op, output_format(), darktable_t::pixelpipe_cache, pixelpipe_get_histogram_backbuf(), TRUE, and void().
Referenced by dt_dev_pixelpipe_process_rec().
|
static |
References _module_needs_gui_output_backbuf_sync(), and pixelpipe_get_histogram_backbuf().
Referenced by dt_dev_pixelpipe_process_rec().
|
static |
Select a safe colorspace for picker sampling.
Some modules operate in RAW or specialized spaces. The picker wants meaningful values in an RGB-like space. This helper maps the active picker colorspace request to a safe in-pipe colorspace, falling back to the pipe colorspace when needed.
References dt_iop_color_picker_get_active_cst(), IOP_CS_HSL, IOP_CS_JZCZHZ, IOP_CS_LAB, IOP_CS_NONE, and IOP_CS_RGB.
Referenced by _sample_color_picker().
|
static |
Collect the per-module histogram on CPU for GUI display.
This is gated by:
DT_REQUEST_ONLY_IN_GUI),The histogram is stored both in the piece (for internal use) and optionally copied to the module (for UI).
References dt_dev_histogram_stats_t::bins_count, dt_iop_buffer_dsc_t::cst, dt_control_queue_redraw_widget(), dt_ioppr_get_pipe_work_profile_info(), dt_ioppr_transform_image_colorspace(), DT_REQUEST_ON, DT_REQUEST_ONLY_IN_GUI, dt_develop_t::gui_attached, dt_iop_roi_t::height, dt_iop_module_t::histogram, dt_dev_pixelpipe_iop_t::histogram, histogram_collect(), dt_iop_module_t::histogram_max, dt_dev_pixelpipe_iop_t::histogram_max, dt_dev_pixelpipe_iop_t::histogram_stats, IOP_CS_RAW, dt_iop_module_t::request_histogram, dt_dev_pixelpipe_iop_t::request_histogram, dt_iop_module_t::widget, and dt_iop_roi_t::width.
Referenced by _sample_gui().
|
static |
Compute a histogram for a given module piece.
This is the per-module histogram that can be shown in module UIs. Each module may set piece->histogram_params to define a ROI. If no ROI is specified, we use the full ROI.
References dt_histogram_helper(), dt_histogram_max_helper(), dt_ioppr_get_pipe_work_profile_info(), dt_iop_roi_t::height, dt_dev_pixelpipe_iop_t::histogram_params, dt_dev_pixelpipe_iop_t::histogram_stats, dt_dev_pixelpipe_iop_t::pipe, dt_dev_histogram_collection_params_t::roi, dt_histogram_roi_t::width, and dt_iop_roi_t::width.
Referenced by collect_histogram_on_CPU().
|
static |
Update the global histogram backbuffer to reference a specific cache entry.
Global histograms are displayed outside of the pixelpipe processing call stack, so we must keep a cache reference (refcount increment) to prevent eviction of the buffer being displayed.
When the hash changes, we decrement the refcount of the previous entry and increment the refcount of the new one.
References _get_backuf(), bpp, darktable, dt_dev_backbuf_get_hash(), dt_dev_pixelpipe_cache_peek(), dt_dev_pixelpipe_cache_ref_count_entry(), dt_dev_set_backbuf(), dt_pixel_cache_entry_get_size(), DT_PIXELPIPE_CACHE_HASH_INVALID, FALSE, dt_iop_roi_t::height, dt_iop_module_t::op, darktable_t::pixelpipe_cache, TRUE, and dt_iop_roi_t::width.
Referenced by _resync_global_histograms(), _sample_gui(), and _sync_module_output_backbuf_on_exact_hit().
|
static |
Sample the color picker values (avg/min/max) from a pixel buffer.
The picker expects float buffers with known colorspace metadata. This function delegates the pixel aggregation to dt_color_picker_helper().
References dt_color_picker_helper(), dt_iop_color_picker_get_active_cst(), dt_ioppr_get_pipe_work_profile_info(), max, min, dt_dev_pixelpipe_iop_t::pipe, and pixelpipe_picker_helper().
Referenced by _sample_color_picker().
|
static |
Compute the sampling box in module coordinates for the interactive color picker.
The GUI defines picker samples in normalized preview coordinates. We must convert them to pixel coordinates, then backtransform them to the current module coordinate system.
References dt_colorpicker_sample_t::box, dt_lib_t::colorpicker, darktable, darktable_t::develop, dt_dev_coordinates_image_norm_to_preview_abs(), dt_dev_distort_backtransform_plus(), DT_DEV_TRANSFORM_DIR_FORW_EXCL, DT_DEV_TRANSFORM_DIR_FORW_INCL, DT_LIB_COLORPICKER_SIZE_BOX, DT_LIB_COLORPICKER_SIZE_POINT, dt_develop_t::gui_module, height, dt_iop_roi_t::height, dt_iop_module_t::iop_order, darktable_t::lib, MAX, MIN, PIXELPIPE_PICKER_INPUT, dt_colorpicker_sample_t::point, dt_develop_t::preview_pipe, dt_lib_t::primary_sample, dt_lib_t::proxy, dt_colorpicker_sample_t::size, width, dt_iop_roi_t::width, dt_iop_roi_t::x, and dt_iop_roi_t::y.
Referenced by pixelpipe_picker().