Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
pixelpipe_cache.h File Reference

Pixelpipe cache for storing intermediate results in the pixelpipe. More...

#include "system/memory_arena.h"
#include "system/atomic.h"
#include "pixel/format.h"
#include <inttypes.h>
#include <glib.h>
#include <stddef.h>
+ Include dependency graph for pixelpipe_cache.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  dt_pixel_cache_stats_device_t
 
struct  dt_pixel_cache_stats_entry_t
 
struct  dt_pixel_cache_entry_t
 
struct  dt_pixelpipe_cache_observer_t
 The supervisor's view of the cache. All four may be NULL; active gates the other three so the cache pays one predicted-false branch when nobody is watching. More...
 

Macros

#define DT_PIXELPIPE_CACHE_HASH_INVALID   ((uint64_t)-1)
 

Typedefs

typedef struct dt_dev_pixelpipe_cache_t dt_dev_pixelpipe_cache_t
 
typedef enum dt_dev_pixelpipe_cache_writable_status_t dt_dev_pixelpipe_cache_writable_status_t
 
typedef struct dt_pixel_cache_stats_device_t dt_pixel_cache_stats_device_t
 
typedef struct dt_pixel_cache_stats_entry_t dt_pixel_cache_stats_entry_t
 
typedef struct dt_pixel_cache_entry_t dt_pixel_cache_entry_t
 
typedef void(* dt_pixelpipe_cache_warn_handler_t) (const char *message)
 Tell the user something that is fine to miss: the cache went over its budget, but the allocation went ahead. Called with an already-translated, already-formatted string; the cache does not know what a toast is.
 
typedef void(* dt_pixelpipe_cache_alert_handler_t) (const char *message, const char *item)
 Tell the user something that must not go unseen: what it says stays true after a toast would have gone. Same contract as dt_control_alert(): message is the kind of failure, the same text at every call; what was refused – its size, its module – is item, one line, already translated and formatted, NULL when unknown.
 
typedef void(* dt_pixelpipe_cache_ready_handler_t) (uint64_t hash, uint64_t producer_node_key)
 A cacheline finished and is readable.
 
typedef struct dt_pixelpipe_cache_observer_t dt_pixelpipe_cache_observer_t
 The supervisor's view of the cache. All four may be NULL; ::active gates the other three so the cache pays one predicted-false branch when nobody is watching.
 

Enumerations

enum  dt_dev_pixelpipe_cache_writable_status_t {
  DT_DEV_PIXELPIPE_CACHE_WRITABLE_ERROR = -1 ,
  DT_DEV_PIXELPIPE_CACHE_WRITABLE_EXACT_HIT = -2 ,
  DT_DEV_PIXELPIPE_CACHE_WRITABLE_CREATED = 1 ,
  DT_DEV_PIXELPIPE_CACHE_WRITABLE_REKEYED = 2
}
 

Functions

gboolean dt_dev_pixelpipe_cache_init (size_t max_memory, const gboolean verbose, const gboolean verbose_detail)
 Reserve the cache's arena and start it.
 
gboolean dt_dev_pixelpipe_cache_is_ready (void)
 Has the pixelpipe cache been initialised? Callers that run before dt_dev_pixelpipe_cache_init() succeeds, or after its cleanup, ask this rather than testing a handle they should not hold.
 
void dt_dev_pixelpipe_cache_cleanup (void)
 Release everything dt_dev_pixelpipe_cache_init() created, the instance included. Only after a successful init; dt_dev_pixelpipe_cache_is_ready() answers FALSE afterwards.
 
void dt_dev_pixelpipe_cache_get_usage (size_t *current, size_t *max)
 
size_t dt_dev_pixelpipe_cache_get_max_memory (void)
 
size_t dt_dev_pixelpipe_cache_get_available (void)
 
size_t dt_pixelpipe_cache_get_largest_free_run (void)
 
GArray * dt_dev_pixelpipe_cache_get_entries_stats (void)
 
const char * dt_pixelpipe_cache_set_current_module (const char *module)
 Set the current module name for cache diagnostics (thread-local).
 
const char * dt_pixelpipe_cache_set_current_image (const char *image)
 Set the image the current module runs on, for the message that reports a refused allocation (thread-local).
 
uint32_t dt_pixelpipe_cache_get_alloc_refusals (void)
 Count the allocations the cache refused to the calling thread for lack of memory (thread-local).
 
struct dt_pixel_cache_entry_t * dt_dev_pixelpipe_cache_get_entry (const uint64_t hash)
 Get an internal reference to the cache entry matching hash. If you are going to access this entry more than once, keeping the reference and using it instead of hashes will prevent redundant lookups.
 
struct dt_pixel_cache_entry_t * dt_dev_pixelpipe_cache_get_entry_by_data (void *data)
 
int dt_dev_pixelpipe_cache_get (const uint64_t hash, const size_t size, const char *name, const int id, const gboolean alloc, void **data, struct dt_pixel_cache_entry_t **entry)
 Get a cache line from the cache.
 
dt_dev_pixelpipe_cache_writable_status_t dt_dev_pixelpipe_cache_get_writable (const uint64_t hash, const size_t size, const char *name, const int id, const gboolean alloc, const gboolean allow_rekey_reuse, const struct dt_pixel_cache_entry_t *reuse_hint, const struct dt_pixel_cache_entry_t *reuse_hint_prev, void **data, struct dt_pixel_cache_entry_t **entry)
 Acquire a writable cache line for module output.
 
void * dt_dev_pixelpipe_cache_borrow_cl_payload (struct dt_pixel_cache_entry_t *entry, int devid, int width, int height, int bpp)
 Borrow a cached OpenCL payload attached to a cache entry.
 
void dt_dev_pixelpipe_cache_return_cl_payload (struct dt_pixel_cache_entry_t *entry, void *mem)
 Return a borrowed cached OpenCL payload to its cache entry.
 
void dt_dev_pixelpipe_cache_flush_entry_clmem (struct dt_pixel_cache_entry_t *entry)
 Flush all reusable OpenCL payloads cached on one cache entry.
 
gboolean dt_dev_pixelpipe_cache_restore_host_payload (struct dt_pixel_cache_entry_t *entry, int preferred_devid, void **data)
 Materialize a host payload for a live cache entry from its cached device payload.
 
void * dt_dev_pixelpipe_cache_get_pinned_image (void *host_ptr, struct dt_pixel_cache_entry_t *entry_hint, int devid, int width, int height, int bpp, int flags, gboolean *out_reused)
 Acquire a pinned OpenCL image for a host buffer tracked by the pixelpipe cache.
 
void dt_dev_pixelpipe_cache_put_pinned_image (void *host_ptr, struct dt_pixel_cache_entry_t *entry_hint, void **mem)
 Release or cache a pinned OpenCL image acquired with dt_dev_pixelpipe_cache_get_pinned_image().
 
gboolean dt_dev_pixelpipe_cache_flush_host_pinned_image (void *host_ptr, struct dt_pixel_cache_entry_t *entry_hint, int devid)
 Drop cached pinned OpenCL images associated with a given host buffer.
 
void * dt_dev_pixelpipe_cache_get_cl_buffer (int devid, void *host_ptr, const struct dt_iop_roi_t *roi, size_t bpp, struct dt_iop_module_t *module, const char *message, struct dt_pixel_cache_entry_t *entry, gboolean *out_reused, void *keep)
 Allocate or reuse an OpenCL buffer for one cache entry payload.
 
void * dt_dev_pixelpipe_cache_alloc_cl_device_buffer (int devid, const struct dt_iop_roi_t *roi, size_t bpp, const struct dt_iop_module_t *module, const char *message, void *keep)
 Allocate a temporary device-only OpenCL image, retrying once after cache flush.
 
void dt_dev_pixelpipe_cache_release_cl_buffer (void **cl_mem_buffer, struct dt_pixel_cache_entry_t *entry, void *host_ptr, gboolean cache_device)
 Release or cache an OpenCL image associated with one cache entry.
 
int dt_dev_pixelpipe_cache_sync_cl_buffer (int devid, void *host_ptr, void *cl_mem_buffer, const struct dt_iop_roi_t *roi, int cl_mode, size_t bpp, struct dt_iop_module_t *module, const char *message)
 Synchronize between host memory and a pinned OpenCL image.
 
float * dt_dev_pixelpipe_cache_restore_cl_buffer (struct dt_dev_pixelpipe_t *pipe, float *input, void *cl_mem_input, const struct dt_iop_roi_t *roi_in, struct dt_iop_module_t *module, size_t in_bpp, struct dt_pixel_cache_entry_t *input_entry, const char *message)
 Resynchronize one OpenCL input payload back into its cache-backed host buffer.
 
int dt_dev_pixelpipe_cache_prepare_cl_input (struct dt_dev_pixelpipe_t *pipe, struct dt_iop_module_t *module, float *input, void **cl_mem_input, const struct dt_iop_roi_t *roi_in, size_t in_bpp, struct dt_pixel_cache_entry_t *input_entry, struct dt_pixel_cache_entry_t **locked_input_entry, void *keep)
 Prepare the OpenCL input image corresponding to one cache-backed module input.
 
struct dt_pixel_cache_entry_t * dt_dev_pixelpipe_cache_ref_entry_for_host_ptr (void *host_ptr)
 Resolve and retain the cache entry owning a host pointer.
 
gboolean dt_dev_pixelpipe_cache_ref_entry_by_hash (const uint64_t hash, void **data, struct dt_pixel_cache_entry_t **entry)
 Resolve and retain an existing cache entry by hash.
 
gboolean dt_dev_pixelpipe_cache_ref_host_entry_by_hash (const uint64_t hash, void **data, struct dt_pixel_cache_entry_t **entry)
 Resolve and retain an existing cacheline that already holds HOST pixels.
 
void * dt_pixel_cache_entry_get_data (struct dt_pixel_cache_entry_t *entry)
 Peek the host pixels a cache entry holds for its current hash, without allocating.
 
void * dt_pixel_cache_entry_get_buffer (struct dt_pixel_cache_entry_t *entry)
 The host buffer of a cache entry, whatever hash its content describes.
 
void dt_dev_pixelpipe_cache_flag_host_written (struct dt_pixel_cache_entry_t *entry)
 Record that the host buffer of entry now holds the pixels of its current hash.
 
size_t dt_pixel_cache_entry_get_size (const struct dt_pixel_cache_entry_t *entry)
 Peek the size (in bytes) reserved for the host buffer of a cache entry.
 
void * dt_pixel_cache_alloc (struct dt_pixel_cache_entry_t *entry)
 Actually allocate the memory buffer attached to the cache entry once you create it with dt_dev_pixelpipe_cache_get(). Sizes and everything are already saved in the entry, and the cache will have the needed space reserved.
 
void * dt_pixelpipe_cache_alloc_align_cache_impl (size_t size, int id, const char *name)
 Allocate aligned memory tracked by the pixelpipe cache. This allows LRU cache entries to be evicted if needed to make room.
 
void dt_pixelpipe_cache_free_align_cache (void **mem, const char *message)
 Free aligned memory allocated with dt_pixelpipe_cache_alloc_align_cache.
 
gboolean dt_dev_pixelpipe_cache_peek (const uint64_t hash, void **data, struct dt_pixel_cache_entry_t **entry, const int preferred_devid, void **cl_mem_output)
 Non-owning lookup of an existing cache line.
 
void dt_dev_pixelpipe_cache_flush (const int id)
 Remove cache lines matching id. Entries locked in read/write or having reference count greater than 0 are not removed.
 
int dt_dev_pixelpipe_cache_invalidate_hashes (const uint64_t *hashes, const size_t count)
 Invalidate cache lines matching an explicit list of hashes.
 
void dt_dev_pixelpipe_cache_flush_clmem (const int devid)
 Release cached OpenCL buffers for a single device.
 
void dt_dev_pixelpipe_cache_flush_clmem_for_pipe (const int devid)
 Like dt_dev_pixelpipe_cache_flush_clmem(), for callers that do not hold the device lock (dt_opencl_reserve_device_by_id()) (e.g. a pipe's own cleanup after dt_dev_pixelpipe_process() already released it). Takes the lock itself, then delegates. No-op if devid < 0 or OpenCL isn't available.
 
void dt_dev_pixelpipe_cache_print (void)
 
int dt_dev_pixel_pipe_cache_remove_lru (void)
 
void dt_dev_pixelpipe_cache_ref_count_entry (gboolean lock, struct dt_pixel_cache_entry_t *entry)
 Take or release one reference on a cache line. A referenced line is never evicted, rekeyed or removed.
 
void dt_dev_pixelpipe_cache_wrlock_entry (gboolean lock, struct dt_pixel_cache_entry_t *entry)
 Lock or release the write lock on the entry.
 
void dt_dev_pixelpipe_cache_rdlock_entry (gboolean lock, struct dt_pixel_cache_entry_t *entry)
 Lock or release the read lock on the entry.
 
void dt_dev_pixelpipe_cache_flag_auto_destroy (struct dt_pixel_cache_entry_t *entry)
 Flag a cache line as disposable (auto_destroy), for short-lived lines nothing will need again: the release of its last reference removes it, out of the LRU's age-based collection.
 
void dt_dev_pixelpipe_cache_unref_hash (const uint64_t hash)
 Find the entry matching hash, and decrease its ref_count if found.
 
void dt_dev_pixelpipe_cache_unref_entry (struct dt_pixel_cache_entry_t *entry)
 Release one reference held on entry, by POINTER.
 
int dt_dev_pixelpipe_cache_rekey (const uint64_t old_hash, const uint64_t new_hash, struct dt_pixel_cache_entry_t *entry)
 Change the hash/key of an existing cache line in place, without freeing, reallocating or invalidating the underlying entry.
 
void dt_dev_pixelpipe_cache_set_alert_handler (dt_pixelpipe_cache_alert_handler_t alert)
 Install the alert handler. The GUI installs it, once it exists, apart from the others: without a GUI there is nothing to alert with, and an alert is then printed on stderr, the item on the line under the message.
 
void dt_dev_pixelpipe_cache_set_handlers (dt_pixelpipe_cache_warn_handler_t warn, dt_pixelpipe_cache_ready_handler_t ready, const dt_pixelpipe_cache_observer_t *observer)
 Install the handlers. Call once, from the orchestrator, before any pipe runs.
 

Detailed Description

Pixelpipe cache for storing intermediate results in the pixelpipe.

This cache can be used locally (in the pixelpipe) or globally (in the whole app). Current implementation is global, using darktable.pipeline_threadsafe mutex lock to protect cache entries addition/removal accross threads. The mutex lock protects the whole recursive pixelpipe, so no internal locking is needed nor implemented here.

Definition in file pixelpipe_cache.h.

Macro Definition Documentation

◆ DT_PIXELPIPE_CACHE_HASH_INVALID

#define DT_PIXELPIPE_CACHE_HASH_INVALID   ((uint64_t)-1)

Definition at line 52 of file pixelpipe_cache.h.

Typedef Documentation

◆ dt_dev_pixelpipe_cache_t

Definition at line 66 of file pixelpipe_cache.h.

◆ dt_dev_pixelpipe_cache_writable_status_t

◆ dt_pixel_cache_entry_t

◆ dt_pixel_cache_stats_device_t

◆ dt_pixel_cache_stats_entry_t

◆ dt_pixelpipe_cache_alert_handler_t

typedef void(* dt_pixelpipe_cache_alert_handler_t) (const char *message, const char *item)

Tell the user something that must not go unseen: what it says stays true after a toast would have gone. Same contract as dt_control_alert(): message is the kind of failure, the same text at every call; what was refused – its size, its module – is item, one line, already translated and formatted, NULL when unknown.

Definition at line 925 of file pixelpipe_cache.h.

◆ dt_pixelpipe_cache_observer_t

The supervisor's view of the cache. All four may be NULL; ::active gates the other three so the cache pays one predicted-false branch when nobody is watching.

◆ dt_pixelpipe_cache_ready_handler_t

typedef void(* dt_pixelpipe_cache_ready_handler_t) (uint64_t hash, uint64_t producer_node_key)

A cacheline finished and is readable.

Parameters
hashits content hash,
producer_node_keywhich node published it. Waiters key on both.

Definition at line 935 of file pixelpipe_cache.h.

◆ dt_pixelpipe_cache_warn_handler_t

typedef void(* dt_pixelpipe_cache_warn_handler_t) (const char *message)

Tell the user something that is fine to miss: the cache went over its budget, but the allocation went ahead. Called with an already-translated, already-formatted string; the cache does not know what a toast is.

Definition at line 919 of file pixelpipe_cache.h.

Enumeration Type Documentation

◆ dt_dev_pixelpipe_cache_writable_status_t

Enumerator
DT_DEV_PIXELPIPE_CACHE_WRITABLE_ERROR 
DT_DEV_PIXELPIPE_CACHE_WRITABLE_EXACT_HIT 
DT_DEV_PIXELPIPE_CACHE_WRITABLE_CREATED 
DT_DEV_PIXELPIPE_CACHE_WRITABLE_REKEYED 

Definition at line 68 of file pixelpipe_cache.h.

Function Documentation

◆ dt_dev_pixel_pipe_cache_remove_lru()

int dt_dev_pixel_pipe_cache_remove_lru ( void  )

remove the least used cache entry

Returns
0 on success, 1 on error

Definition at line 935 of file pixelpipe_cache.c.

References _non_thread_safe_pixel_pipe_cache_remove_lru(), _pixelpipe_cache, dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), error(), FALSE, and dt_dev_pixelpipe_cache_t::lock.

Referenced by dt_tiling_piece_fits_host_memory().

◆ dt_dev_pixelpipe_cache_alloc_cl_device_buffer()

void * dt_dev_pixelpipe_cache_alloc_cl_device_buffer ( int  devid,
const struct dt_iop_roi_t *  roi,
size_t  bpp,
const struct dt_iop_module_t *  module,
const char *  message,
void *  keep 
)

Allocate a temporary device-only OpenCL image, retrying once after cache flush.

Parameters
devidOpenCL device id.
roiBuffer dimensions.
bppBytes per pixel.
moduleModule for debug messages.
messageHuman-readable allocation context.
keepOptional OpenCL buffer that must not be flushed during retry.
Returns
void* OpenCL image (cl_mem) or NULL on failure.

◆ dt_dev_pixelpipe_cache_borrow_cl_payload()

void * dt_dev_pixelpipe_cache_borrow_cl_payload ( struct dt_pixel_cache_entry_t *  entry,
int  devid,
int  width,
int  height,
int  bpp 
)

Borrow a cached OpenCL payload attached to a cache entry.

This reopens a cached cl_mem image already tracked by the cache entry and increments its internal borrow counter so cache flush/eviction paths will keep it alive until the caller returns it with dt_dev_pixelpipe_cache_return_cl_payload().

Parameters
entryCache entry owning the payload.
host_ptrHost pointer key for pinned payloads, or NULL for device-only payloads.
devidOpenCL device id.
widthImage width.
heightImage height.
bppBytes per pixel.
flagsTracked OpenCL flags used when the payload was cached.
Returns
void* Borrowed cl_mem, or NULL if no matching cached payload exists.

Definition at line 994 of file pixelpipe_cache.c.

References _pixel_cache_touch(), bpp, dt_pixel_cache_entry_t::cl_mem_list, dt_pixel_cache_entry_t::cl_mem_lock, dt_opencl_get_image_element_size(), dt_opencl_get_image_height(), dt_opencl_get_image_width(), dt_opencl_get_mem_context_id(), dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), height, and width.

Referenced by pixelpipe_process_on_GPU().

◆ dt_dev_pixelpipe_cache_cleanup()

◆ dt_dev_pixelpipe_cache_flag_auto_destroy()

void dt_dev_pixelpipe_cache_flag_auto_destroy ( struct dt_pixel_cache_entry_t *  entry)

Flag a cache line as disposable (auto_destroy), for short-lived lines nothing will need again: the release of its last reference removes it, out of the LRU's age-based collection.

This is how a holder drops a line: flag it while still holding it, then release it with dt_dev_pixelpipe_cache_ref_count_entry(). A line still held by someone else is removed by the last of them; one still locked when released is left to the LRU.

Parameters
entryThe cache line, held by the caller. NULL is a no-op.

Definition at line 3273 of file pixelpipe_cache.c.

References _pixel_cache_message(), _pixelpipe_cache, dt_pixel_cache_entry_t::auto_destroy, dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), IS_NULL_PTR, dt_dev_pixelpipe_cache_t::lock, and TRUE.

Referenced by _abort_module_shutdown_cleanup(), _develop_blend_release_mask_entry(), _flagged_line_goes_with_its_last_holder(), _flagged_line_goes_with_its_release(), _group_publish_prefix(), dt_dev_pixelpipe_cleanup(), dt_dev_pixelpipe_process_rec(), process(), process_cl(), and rt_scaled_mask_publish().

◆ dt_dev_pixelpipe_cache_flag_host_written()

void dt_dev_pixelpipe_cache_flag_host_written ( struct dt_pixel_cache_entry_t *  entry)

Record that the host buffer of entry now holds the pixels of its current hash.

Called by the producer before it releases the write lock, when it wrote the host buffer or copied its device output back into it. Without it, an entry rekeyed in place keeps reporting no host pixels (dt_pixel_cache_entry_get_data() returns NULL).

Definition at line 2125 of file pixelpipe_cache.c.

References dt_atomic_set_int(), FALSE, and dt_pixel_cache_entry_t::host_stale.

Referenced by _gpu_init_input(), _produce(), dt_dev_pixelpipe_cache_restore_cl_buffer(), and dt_dev_pixelpipe_process_rec().

◆ dt_dev_pixelpipe_cache_flush()

void dt_dev_pixelpipe_cache_flush ( const int  id)

Remove cache lines matching id. Entries locked in read/write or having reference count greater than 0 are not removed.

Parameters
cache
idID of the pipeline owning the cache line, or -1 to remove all lines.

Definition at line 3017 of file pixelpipe_cache.c.

References _for_each_remove(), _pixelpipe_cache, dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), dt_dev_pixelpipe_cache_t::entries, and dt_dev_pixelpipe_cache_t::lock.

Referenced by _held_line_survives_the_flush(), _released_line_goes_with_the_flush(), _released_masks_go_with_the_flush(), and dt_dev_pixelpipe_reset_all().

◆ dt_dev_pixelpipe_cache_flush_clmem()

void dt_dev_pixelpipe_cache_flush_clmem ( const int  devid)

Release cached OpenCL buffers for a single device.

This is intentionally a lightweight VRAM-pressure/retry helper: it drops cached cl_mem objects without taking per-entry write locks. Realtime paths rely on it to free scratch OpenCL buffers without stalling in-flight renders.

Parameters
devidDevice to flush, or a negative value for a no-op (e.g. a pipe that never used OpenCL). The caller must already hold the device lock (dt_opencl_reserve_device_by_id()) – this is the case for the pixelpipe currently running on that device. Callers that don't hold it (e.g. cleaning up a pipe after it finished) must use dt_dev_pixelpipe_cache_flush_clmem_for_pipe() instead.

Definition at line 741 of file pixelpipe_cache.c.

References _cache_entry_clmem_flush_device(), _cache_print, _pixelpipe_cache, _verbose, _verbose_detail, dt_atomic_get_int(), DT_DEBUG_OPENCL, dt_opencl_events_wait_for(), dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), dt_pthread_rwlock_trywrlock(), dt_pthread_rwlock_unlock(), dt_dev_pixelpipe_cache_t::entries, dt_pixel_cache_entry_t::hash, key, dt_dev_pixelpipe_cache_t::lock, dt_pixel_cache_entry_t::lock, dt_pixel_cache_entry_t::refcount, and value.

Referenced by _dt_opencl_alloc_image2d(), dt_dev_pixelpipe_cache_flush_clmem_for_pipe(), dt_opencl_alloc_device_buffer_with_flags(), guided_filter_cl(), and pixelpipe_process_on_GPU().

◆ dt_dev_pixelpipe_cache_flush_clmem_for_pipe()

void dt_dev_pixelpipe_cache_flush_clmem_for_pipe ( const int  devid)

Like dt_dev_pixelpipe_cache_flush_clmem(), for callers that do not hold the device lock (dt_opencl_reserve_device_by_id()) (e.g. a pipe's own cleanup after dt_dev_pixelpipe_process() already released it). Takes the lock itself, then delegates. No-op if devid < 0 or OpenCL isn't available.

Definition at line 811 of file pixelpipe_cache.c.

References dt_dev_pixelpipe_cache_flush_clmem(), dt_opencl_is_inited(), dt_opencl_release_device(), and dt_opencl_reserve_device_by_id().

Referenced by _studio_dev_teardown(), dt_dev_pixelpipe_cleanup(), and leave().

◆ dt_dev_pixelpipe_cache_flush_entry_clmem()

void dt_dev_pixelpipe_cache_flush_entry_clmem ( struct dt_pixel_cache_entry_t *  entry)

Flush all reusable OpenCL payloads cached on one cache entry.

Borrowed payloads are preserved until all borrowers returned them.

Parameters
entryCache entry whose cached cl_mem payloads should be flushed.

Definition at line 1121 of file pixelpipe_cache.c.

References dt_pixel_cache_entry_t::cl_mem_list, dt_pixel_cache_entry_t::cl_mem_lock, dt_free, dt_opencl_release_mem_object(), dt_pthread_mutex_lock(), and dt_pthread_mutex_unlock().

Referenced by _free_cache_entry(), dt_dev_pixelpipe_cache_rekey(), and dt_dev_pixelpipe_process_rec().

◆ dt_dev_pixelpipe_cache_flush_host_pinned_image()

gboolean dt_dev_pixelpipe_cache_flush_host_pinned_image ( void *  host_ptr,
struct dt_pixel_cache_entry_t *  entry_hint,
int  devid 
)

Drop cached pinned OpenCL images associated with a given host buffer.

This is meant for host buffers that remain alive and continue to be mutated by the CPU (for example, privately owned working patches). Reusing a stale CL_MEM_USE_HOST_PTR image for such buffers can hide later host-side edits on some drivers. Flushing the cached pinned images forces the next use to rebind the host storage.

Parameters
cachePixelpipe cache.
host_ptrHost-backed image data.
entry_hintOptional owning cache entry for regular cache lines, or NULL.
devidDevice id to flush, or -1 for all cached devices for that host buffer.
Returns
gboolean TRUE if at least one pinned image was flushed, FALSE otherwise.

Definition at line 1236 of file pixelpipe_cache.c.

References _cache_entry_clmem_flush_host_pinned_locked(), _cache_entry_clmem_has_host_pinned_locked(), _cache_entry_for_host_ptr_locked(), _pixelpipe_cache, dt_dev_pixelpipe_cache_ref_count_entry(), dt_opencl_events_wait_for(), dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), FALSE, IS_NULL_PTR, dt_dev_pixelpipe_cache_t::lock, and TRUE.

Referenced by _rasterize_pending_dab_batch(), dt_dev_pixelpipe_gpu_flush_host_pinned_images(), and dt_drawlayer_rekey_shared_base_patch().

◆ dt_dev_pixelpipe_cache_get()

int dt_dev_pixelpipe_cache_get ( const uint64_t  hash,
const size_t  size,
const char *  name,
const int  id,
const gboolean  alloc,
void **  data,
struct dt_pixel_cache_entry_t **  entry 
)

Get a cache line from the cache.

WARNING: This internally increases the reference count, so you have to manually decrease it using dt_dev_pixelpipe_ref_count_entry() once the cache line content has been consumed or it will never be freed.

WARNING: if the cache line was newly allocated, a write lock is put on straight away. You will have to release it from the same calling thread next, to avoid dead locks.

Parameters
cache
hashState checksum of the cache line.
sizeBuffer size in bytes.
nameName of the cache line (for debugging).
idID of the pipeline owning the cache line.
dataPointer to the buffer pointer (returned).
allocWhether or not we should actually alloc the buffer, or simply reserve it. If FALSE use dt_pixel_cache_alloc() when you actually need the buffer.
cache_entrya reference to the cache entry, to be reused later. Can be NULL. The caller doesn't own the data and shouldn't free it.
Returns
int 1 if the cache line was freshly allocated, 0 if it was found in the cache.

Definition at line 2662 of file pixelpipe_cache.c.

References _cache_print, _non_thread_safe_cache_ref_count_entry(), _non_thread_safe_cache_remove(), _non_threadsafe_cache_get_entry(), _observe_read(), _pixel_cache_message(), _pixelpipe_cache, _pixelpipe_cache_create_entry_locked(), _pixelpipe_cache_finalize_entry(), dt_pixel_cache_entry_t::auto_destroy, dt_pixel_cache_entry_t::data, DT_DEBUG_PIPECACHE, dt_dev_pixelpipe_cache_wrlock_entry(), dt_pixel_cache_alloc(), DT_PIXELPIPE_CACHE_HASH_INVALID, dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), dt_dev_pixelpipe_cache_t::entries, FALSE, hash, dt_dev_pixelpipe_cache_t::hits, dt_pixel_cache_entry_t::hits, IS_NULL_PTR, dt_dev_pixelpipe_cache_t::lock, name, dt_dev_pixelpipe_cache_t::queries, size, dt_pixel_cache_entry_t::size, and TRUE.

Referenced by _create(), _create_held(), _group_publish_prefix(), _publish(), dt_develop_blend_process(), dt_develop_blend_process_cl(), dt_drawlayer_cache_patch_alloc_shared(), process(), process_cl(), rt_scaled_mask_publish(), and rt_shape_box().

◆ dt_dev_pixelpipe_cache_get_available()

size_t dt_dev_pixelpipe_cache_get_available ( void  )

What an allocation made now could get, in bytes, by the rules that grant or refuse it: the room the plan and the system's available RAM over the pressure floor leave, counting what eviction can take back – lines nobody holds, and of the system's share only their host RAM. Tile planners size working sets against it.

Definition at line 3426 of file pixelpipe_cache.c.

References _cache_sum_evictable(), _pixelpipe_cache, dt_dev_pixelpipe_cache_t::current_memory, dt_get_memory_pressure_floor(), dt_get_system_available_mem(), dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), dt_dev_pixelpipe_cache_t::entries, dt_dev_pixelpipe_cache_t::lock, dt_dev_pixelpipe_cache_t::max_memory, and MIN.

Referenced by _host_tile_buffer_size(), and dt_tiling_piece_fits_host_memory().

◆ dt_dev_pixelpipe_cache_get_cl_buffer()

void * dt_dev_pixelpipe_cache_get_cl_buffer ( int  devid,
void *  host_ptr,
const struct dt_iop_roi_t *  roi,
size_t  bpp,
struct dt_iop_module_t *  module,
const char *  message,
struct dt_pixel_cache_entry_t *  entry,
gboolean *  out_reused,
void *  keep 
)

Allocate or reuse an OpenCL buffer for one cache entry payload.

This is the cache-owned buffer acquisition helper used by the OpenCL pixelpipe backend:

  • if !IS_NULL_PTR(host_ptr), it may reuse or allocate a pinned CL_MEM_USE_HOST_PTR image,
  • if IS_NULL_PTR(host_ptr), it may reuse or allocate a device-only scratch image,
  • allocation failures may trigger a cache-side cl_mem flush and one retry.
Parameters
devidOpenCL device id.
host_ptrHost backing store for pinned images, or NULL for device-only images.
roiBuffer dimensions.
bppBytes per pixel.
moduleModule for debug messages.
messageHuman-readable allocation context.
entryOwning cache entry.
[out]out_reusedOptional flag set TRUE when the buffer came from cache reuse.
keepOptional OpenCL buffer that must not be flushed during retry.
Returns
void* OpenCL image (cl_mem) or NULL on failure.

◆ dt_dev_pixelpipe_cache_get_entries_stats()

◆ dt_dev_pixelpipe_cache_get_entry()

◆ dt_dev_pixelpipe_cache_get_entry_by_data()

◆ dt_dev_pixelpipe_cache_get_max_memory()

size_t dt_dev_pixelpipe_cache_get_max_memory ( void  )

Definition at line 3449 of file pixelpipe_cache.c.

References _pixelpipe_cache, IS_NULL_PTR, and dt_dev_pixelpipe_cache_t::max_memory.

Referenced by _rebuild_memory().

◆ dt_dev_pixelpipe_cache_get_pinned_image()

void * dt_dev_pixelpipe_cache_get_pinned_image ( void *  host_ptr,
struct dt_pixel_cache_entry_t *  entry_hint,
int  devid,
int  width,
int  height,
int  bpp,
int  flags,
gboolean *  out_reused 
)

Acquire a pinned OpenCL image for a host buffer tracked by the pixelpipe cache.

This is the public helper for modules that manage their own host buffers but still want the pixelpipe cache to own the reusable pinned cl_mem images. The helper accepts an optional cache-entry hint for normal cache lines. If that hint is NULL, it will try to resolve the host pointer against the cache's privately-owned external allocations.

On reuse, the helper synchronizes host memory to the OpenCL image before returning.

Parameters
cachePixelpipe cache.
host_ptrHost-backed image data.
entry_hintOptional owning cache entry for regular cache lines, or NULL.
devidOpenCL device id.
widthImage width.
heightImage height.
bppBytes per pixel.
flagsOpenCL allocation flags (must include CL_MEM_USE_HOST_PTR).
[out]out_reusedOptional flag set TRUE when an existing pinned image was reused.
Returns
void* OpenCL image (cl_mem) or NULL on failure.

Definition at line 1143 of file pixelpipe_cache.c.

References _cache_entry_for_host_ptr_locked(), _cache_print, _pixel_cache_clmem_get(), _pixel_cache_clmem_remove(), _pixelpipe_cache, bpp, DT_DEBUG_OPENCL, dt_opencl_alloc_device_use_host_pointer(), dt_opencl_is_pinned_memory(), dt_opencl_map_image(), dt_opencl_release_mem_object(), dt_opencl_unmap_mem_object(), dt_opencl_use_pinned_memory(), dt_opencl_write_host_to_device(), dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), FALSE, flags, height, IS_NULL_PTR, dt_dev_pixelpipe_cache_t::lock, TRUE, and width.

Referenced by _blend_layer_over_input_cl(), and _drawlayer_acquire_source_image().

◆ dt_dev_pixelpipe_cache_get_usage()

◆ dt_dev_pixelpipe_cache_get_writable()

dt_dev_pixelpipe_cache_writable_status_t dt_dev_pixelpipe_cache_get_writable ( const uint64_t  hash,
const size_t  size,
const char *  name,
const int  id,
const gboolean  alloc,
const gboolean  allow_rekey_reuse,
const struct dt_pixel_cache_entry_t *  reuse_hint,
const struct dt_pixel_cache_entry_t *  reuse_hint_prev,
void **  data,
struct dt_pixel_cache_entry_t **  entry 
)

Acquire a writable cache line for module output.

This is the cache-side companion of pixelpipe output computation. The caller already decided that the published output for hash is not immediately reusable and needs to be overwritten.

The cache then resolves how to provide that writable line:

  • if an entry already exists at hash, that hash is already published and must not be overwritten. The caller must exact-hit it instead of recomputing. The entry is returned with its refcount incremented, under the same hold of the cache lock as the lookup, and without a lock of its own: its producer may still be writing it,
  • else, if allow_rekey_reuse is TRUE and reuse_hint still points to a live cacheline with the right size, that old cacheline is rekeyed to hash, write-locked, and returned. Its host buffer still holds the previous hash's pixels, so it reports none until the caller calls dt_dev_pixelpipe_cache_flag_host_written(),
  • else, a new cacheline is created.

When the entry is created or rekeyed:

  • the returned entry refcount is incremented,
  • the returned entry is write-locked,
  • and alloc may materialize the host buffer if requested.

The caller must later release the refcount, and the write lock when it holds one, from the same control flow.

Parameters
cachePixelpipe cache.
hashTarget output hash for the module output.
sizeRequired buffer size in bytes.
nameDebug label for the cache line.
idOwning pipeline id.
allocWhether a host buffer must be materialized immediately.
allow_rekey_reuseWhether the cache may reuse the piece-local cached output line by rekeying it.
reuse_hintSnapshot of the previously attached piece cacheline metadata, or NULL.
[out]dataReturned host pointer when available.
[out]entryReturned cache entry, referenced for every status except DT_DEV_PIXELPIPE_CACHE_WRITABLE_ERROR.
Returns
dt_dev_pixelpipe_cache_writable_status_t DT_DEV_PIXELPIPE_CACHE_WRITABLE_CREATED when creating a new entry, DT_DEV_PIXELPIPE_CACHE_WRITABLE_REKEYED when rekeying reuse_hint, DT_DEV_PIXELPIPE_CACHE_WRITABLE_EXACT_HIT when a published entry already exists at hash and the caller must exact-hit it, DT_DEV_PIXELPIPE_CACHE_WRITABLE_ERROR on error.

◆ dt_dev_pixelpipe_cache_init()

gboolean dt_dev_pixelpipe_cache_init ( size_t  max_memory,
const gboolean  verbose,
const gboolean  verbose_detail 
)

Reserve the cache's arena and start it.

constructs a new cache with given cache line count (entries) and float buffer entry size in bytes.

Parameters
[out]returns0 if fail to allocate mem cache.
max_memoryarena size in bytes. A session constant: the orchestrator decides it from the resource plan and retries smaller on failure, which is resource policy.
verbosewhether the cache traces at all (was -d pipecache).
verbose_detailwhether it traces in detail (was -d verbose). Ignored when verbose is FALSE, matching the old two-level gate.

Both flags are read ONCE, here, from the session's debug flags by the orchestrator. The cache does not consult them at runtime: a cache that changes what it does halfway through a session because a global moved is harder to reason about than one told at startup, and it keeps the debug machinery out of a storage module.

Definition at line 2466 of file pixelpipe_cache.c.

References _free_cache_entry(), _memory_pressure_shedder(), _pixelpipe_cache, _pressure_wake(), _verbose, _verbose_detail, dt_dev_pixelpipe_cache_t::arena, dt_dev_pixelpipe_cache_t::current_memory, dt_cache_arena_init(), dt_dev_pixelpipe_cache_flush_old(), dt_free, dt_free_gpointer(), dt_pixelpipe_cache_pressure_monitor_init(), dt_pixelpipe_cache_pressure_watch_start(), dt_pthread_mutex_destroy(), dt_pthread_mutex_init(), dt_dev_pixelpipe_cache_t::entries, dt_dev_pixelpipe_cache_t::external_entries, FALSE, garbage_collection, dt_dev_pixelpipe_cache_t::hits, IS_NULL_PTR, dt_dev_pixelpipe_cache_t::lock, dt_dev_pixelpipe_cache_t::max_memory, dt_dev_pixelpipe_cache_t::next_serial, dt_dev_pixelpipe_cache_t::pressure_alerts, pressure_shedding, dt_dev_pixelpipe_cache_t::psi, dt_dev_pixelpipe_cache_t::queries, dt_dev_pixelpipe_cache_t::sys_available_est, dt_dev_pixelpipe_cache_t::sys_probe_time_us, dt_dev_pixelpipe_cache_t::sys_probe_valid, and TRUE.

Referenced by _setup(), _setup(), _setup(), _setup(), _setup(), and dt_init().

◆ dt_dev_pixelpipe_cache_invalidate_hashes()

int dt_dev_pixelpipe_cache_invalidate_hashes ( const uint64_t *  hashes,
const size_t  count 
)

Invalidate cache lines matching an explicit list of hashes.

Entries which are not in use are removed immediately. Entries still referenced or locked are left untouched because they may be published backbuffers owned by another pipeline.

This targets shared cache states independently of the pipeline which created them, while preserving every cache line not named by hashes.

Parameters
cachePixelpipe cache to update.
hashesCache keys to invalidate.
countNumber of keys in hashes.
Returns
int Number of matching entries which could not be removed.

Definition at line 3025 of file pixelpipe_cache.c.

References _non_thread_safe_cache_remove(), _non_threadsafe_cache_get_entry(), _pixelpipe_cache, DT_PIXELPIPE_CACHE_HASH_INVALID, dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), dt_dev_pixelpipe_cache_t::entries, FALSE, IS_NULL_PTR, k, and dt_dev_pixelpipe_cache_t::lock.

Referenced by dt_dev_pixelpipe_process(), and dt_dev_pixelpipe_rawdetail_mask_check_hit().

◆ dt_dev_pixelpipe_cache_is_ready()

gboolean dt_dev_pixelpipe_cache_is_ready ( void  )

Has the pixelpipe cache been initialised? Callers that run before dt_dev_pixelpipe_cache_init() succeeds, or after its cleanup, ask this rather than testing a handle they should not hold.

The application-wide pixelpipe cache singleton. DECLARED here because it is this module's object; BOUND by the orchestrator (darktable.c), so this header never needs to see the application struct.

Definition at line 104 of file pixelpipe_cache.c.

References _pixelpipe_cache, and IS_NULL_PTR.

Referenced by dt_cleanup(), and dt_init().

◆ dt_dev_pixelpipe_cache_peek()

gboolean dt_dev_pixelpipe_cache_peek ( const uint64_t  hash,
void **  data,
struct dt_pixel_cache_entry_t **  entry,
const int  preferred_devid,
void **  cl_mem_output 
)

Non-owning lookup of an existing cache line.

This does not create a new cache line and does not change reference counts or entry locks. Callers that need lifetime guarantees must retain the entry explicitly with dt_dev_pixelpipe_cache_ref_count_entry() and/or dt_dev_pixelpipe_cache_rdlock_entry().

If !IS_NULL_PTR(cl_mem_output), the lookup becomes authoritative for exact-hit consumers:

  • write-locked / auto-destroy entries are rejected,
  • host data is restored from cached device state when possible,
  • device data is restored into cl_mem_output when requested,
  • broken entries with neither authoritative RAM nor vRAM payload are removed.

Definition at line 2896 of file pixelpipe_cache.c.

References _cache_lookup_existing(), _cache_print, _cache_try_restore_device_payload(), _non_thread_safe_cache_remove(), _non_threadsafe_cache_get_entry(), _pixelpipe_cache, _trace_exact_hit(), dt_pixel_cache_entry_t::auto_destroy, DT_DEBUG_PIPECACHE, dt_dev_pixelpipe_cache_restore_host_payload(), dt_pixel_cache_entry_get_data(), DT_PIXELPIPE_CACHE_HASH_INVALID, dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), dt_pthread_rwlock_tryrdlock(), dt_pthread_rwlock_unlock(), dt_dev_pixelpipe_cache_t::entries, FALSE, hash, IS_NULL_PTR, dt_dev_pixelpipe_cache_t::lock, dt_pixel_cache_entry_t::lock, and TRUE.

Referenced by _peek_gui(), _rekeyed_line_publishes_no_host_pixels(), and dt_dev_retrieve_rawdetail_mask().

◆ dt_dev_pixelpipe_cache_prepare_cl_input()

int dt_dev_pixelpipe_cache_prepare_cl_input ( struct dt_dev_pixelpipe_t *  pipe,
struct dt_iop_module_t *  module,
float *  input,
void **  cl_mem_input,
const struct dt_iop_roi_t *  roi_in,
size_t  in_bpp,
struct dt_pixel_cache_entry_t *  input_entry,
struct dt_pixel_cache_entry_t **  locked_input_entry,
void *  keep 
)

Prepare the OpenCL input image corresponding to one cache-backed module input.

This centralizes the decision tree for:

  • continuing from an already-live GPU payload,
  • reopening or allocating a pinned input image from host RAM,
  • taking the read lock required by true zero-copy buffers,
  • and pushing host→device sync only when needed.
Parameters
pipeCurrent pixelpipe.
moduleModule being processed.
inputHost input pointer.
[in,out]cl_mem_inputOpenCL input image.
roi_inBuffer dimensions.
in_bppBytes per pixel.
input_entryOwning cache entry.
[out]locked_input_entryReturned cache entry that stayed read-locked for zero-copy safety.
keepOptional OpenCL buffer that must not be flushed during retry.
Returns
int 0 on success, 1 on failure.

◆ dt_dev_pixelpipe_cache_print()

◆ dt_dev_pixelpipe_cache_put_pinned_image()

void dt_dev_pixelpipe_cache_put_pinned_image ( void *  host_ptr,
struct dt_pixel_cache_entry_t *  entry_hint,
void **  mem 
)

Release or cache a pinned OpenCL image acquired with dt_dev_pixelpipe_cache_get_pinned_image().

If the image is still a host-backed pinned allocation and an owning cache entry can be resolved, it is returned to that cache entry for reuse. Otherwise it is released.

Parameters
cachePixelpipe cache.
host_ptrHost-backed image data.
entry_hintOptional owning cache entry for regular cache lines, or NULL.
[in,out]memPointer to the cl_mem handle (cleared on return).
Todo:
: is it safe to cache non-pinned vRAM buffers (aka no CL_MEM_USE_HOST_PTR in flags) ?

Definition at line 1217 of file pixelpipe_cache.c.

References _cache_print, _pixel_cache_clmem_put(), _verbose, _verbose_detail, DT_DEBUG_OPENCL, IS_NULL_PTR, and state.

Referenced by _blend_layer_over_input_cl().

◆ dt_dev_pixelpipe_cache_rdlock_entry()

◆ dt_dev_pixelpipe_cache_ref_count_entry()

void dt_dev_pixelpipe_cache_ref_count_entry ( gboolean  lock,
struct dt_pixel_cache_entry_t *  entry 
)

Take or release one reference on a cache line. A referenced line is never evicted, rekeyed or removed.

Releasing the last reference of a line flagged with dt_dev_pixelpipe_cache_flag_auto_destroy() removes it, in the same hold of the cache lock. After its release, the caller may not name the entry again: any thread's eviction can free it from then on.

Parameters
lockTRUE to take a reference, FALSE to release one
entryThe cache line

Definition at line 3212 of file pixelpipe_cache.c.

References _cache_print, _non_thread_safe_cache_ref_count_entry(), _non_thread_safe_cache_remove(), _pixelpipe_cache, dt_pixel_cache_entry_t::auto_destroy, DT_DEBUG_PIPECACHE, dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), dt_dev_pixelpipe_cache_t::entries, FALSE, dt_pixel_cache_entry_t::hash, hash, IS_NULL_PTR, dt_dev_pixelpipe_cache_t::lock, and lock.

Referenced by _abort_module_shutdown_cleanup(), _blend_layer_over_input_cl(), _budget_spent_by_a_line_in_use_is_counted_once(), _develop_blend_release_mask_entry(), _develop_cacheline_ready_callback(), _develop_history_resync_callback(), _flagged_line_goes_with_its_last_holder(), _flagged_line_goes_with_its_release(), _group_get_mask_roi(), _group_publish_prefix(), _locked_bind_entry(), _peek_gui(), _produce(), _refresh_global_histogram_backbuf_for_hash(), _refresh_preview_cursor_sample(), _refresh_preview_module_histogram_for_hash(), _rekeyed_line_publishes_no_host_pixels(), _retain_base_patch_stroke_ref(), _rewritten_line_publishes_its_host_pixels(), _sample_picker_from_cache(), _unflagged_line_outlives_its_release(), _without_rekey_the_previous_output_stays(), color_picker_apply(), dt_dev_backbuf_take_keepalive(), dt_dev_get_raster_mask(), dt_dev_pixelpipe_cache_flush_host_pinned_image(), dt_dev_pixelpipe_cache_unref_entry(), dt_dev_pixelpipe_cache_unref_hash(), dt_dev_pixelpipe_process_rec(), dt_dev_resync_mipmap_cache(), dt_drawlayer_cache_patch_alloc_shared(), dt_drawlayer_cache_patch_clear(), dt_drawlayer_release_all_base_patch_extra_refs(), dt_drawlayer_retain_base_patch_loaded_ref(), dt_imageio_export_with_flags(), dt_iop_autoset_advance(), gui_cleanup(), gui_focus(), gui_post_expose(), invalidate_luminance_cache(), mouse_moved(), process(), process_cl(), rt_release_shape(), rt_scaled_mask_publish(), rt_scaled_mask_take_memo(), rt_shape_box(), scrolled(), and update_histogram().

◆ dt_dev_pixelpipe_cache_ref_entry_by_hash()

gboolean dt_dev_pixelpipe_cache_ref_entry_by_hash ( const uint64_t  hash,
void **  data,
struct dt_pixel_cache_entry_t **  entry 
)

Resolve and retain an existing cache entry by hash.

This is the race-free counterpart to dt_dev_pixelpipe_cache_peek() for GUI code that needs to keep a cacheline past the lookup call. The cache lock is held while the entry is found and its refcount is incremented, so normal cache eviction cannot destroy the returned entry before the caller takes its own read lock.

The function never creates or allocates a cache entry. Release a successful result with dt_dev_pixelpipe_cache_ref_count_entry(cache, FALSE, entry).

Parameters
cachePixelpipe cache.
hashCacheline hash to resolve.
dataReturned current host buffer pointer, if requested.
entryReturned retained cache entry, if requested.
Returns
TRUE when an existing non-auto-destroy entry was retained.

Definition at line 446 of file pixelpipe_cache.c.

References _non_thread_safe_cache_ref_count_entry(), _non_threadsafe_cache_get_entry(), _observe_read(), _pixelpipe_cache, _pixelpipe_cache_finalize_entry(), dt_pixel_cache_entry_t::auto_destroy, DT_PIXELPIPE_CACHE_HASH_INVALID, dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), dt_dev_pixelpipe_cache_t::entries, FALSE, hash, dt_dev_pixelpipe_cache_t::hits, dt_pixel_cache_entry_t::hits, IS_NULL_PTR, dt_dev_pixelpipe_cache_t::lock, dt_dev_pixelpipe_cache_t::queries, dt_pixel_cache_entry_t::size, and TRUE.

Referenced by _develop_cacheline_ready_callback(), _develop_history_resync_callback(), _flagged_line_goes_with_its_last_holder(), _rekeyed_line_publishes_no_host_pixels(), _unflagged_line_outlives_its_release(), dt_dev_get_raster_mask(), dt_dev_pixelpipe_process(), dt_dev_pixelpipe_process_rec(), dt_dev_pixelpipe_rawdetail_mask_check_hit(), dt_dev_resync_mipmap_cache(), dt_dev_retrieve_rawdetail_mask(), dt_imageio_export_with_flags(), gui_focus(), and rt_scaled_mask_take_memo().

◆ dt_dev_pixelpipe_cache_ref_entry_for_host_ptr()

struct dt_pixel_cache_entry_t * dt_dev_pixelpipe_cache_ref_entry_for_host_ptr ( void *  host_ptr)

Resolve and retain the cache entry owning a host pointer.

This helper searches both regular and external pixelpipe cache tables for the entry whose host buffer pointer exactly matches host_ptr.

On success it increments the entry refcount before returning, so callers can safely use the entry across asynchronous OpenCL operations. Release it with: dt_dev_pixelpipe_cache_ref_count_entry(cache, FALSE, entry).

Parameters
cachePixelpipe cache.
host_ptrHost buffer pointer to resolve.
Returns
dt_pixel_cache_entry_t* Owning cache entry with retained refcount, or NULL.

Definition at line 1728 of file pixelpipe_cache.c.

References _cache_entry_for_host_ptr_locked(), _non_thread_safe_cache_ref_count_entry(), _pixelpipe_cache, dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), IS_NULL_PTR, dt_dev_pixelpipe_cache_t::lock, and TRUE.

Referenced by _blend_layer_over_input_cl(), dt_drawlayer_cache_ensure_mask_buffer(), and dt_drawlayer_cache_ensure_process_patch_buffer().

◆ dt_dev_pixelpipe_cache_ref_host_entry_by_hash()

gboolean dt_dev_pixelpipe_cache_ref_host_entry_by_hash ( const uint64_t  hash,
void **  data,
struct dt_pixel_cache_entry_t **  entry 
)

Resolve and retain an existing cacheline that already holds HOST pixels.

The race-free lookup for GUI consumers that sample an intermediate module cacheline – color picker, module histograms, autoset, colorequal. Those cachelines sit at refcount 0 between renders, so the pipeline is free to evict them at any moment: looking one up and THEN taking a reference leaves a window in which it is freed, and the sampling pass then reads a dangling buffer. Here the lookup and the reference happen under one hold of the cache lock, so an entry handed back cannot have been evicted in between.

Unlike dt_dev_pixelpipe_cache_ref_entry_by_hash(), this one additionally requires host pixels to be present (GUI threads own no OpenCL device and must never materialize a device-only payload) and refuses an entry that is currently write-locked. It never allocates and never waits on a lock.

Release a successful result with dt_dev_pixelpipe_cache_ref_count_entry(FALSE, entry).

Parameters
hashCacheline hash to resolve.
dataReturned host buffer pointer, if requested. Never NULL on success.
entryReturned retained cache entry, if requested.
Returns
TRUE when a host-resident, unlocked, non-auto-destroy entry was retained.

Definition at line 478 of file pixelpipe_cache.c.

References _non_thread_safe_cache_ref_count_entry(), _non_threadsafe_cache_get_entry(), _observe_read(), _pixelpipe_cache, _pixelpipe_cache_finalize_entry(), dt_pixel_cache_entry_t::auto_destroy, dt_pixel_cache_entry_get_data(), DT_PIXELPIPE_CACHE_HASH_INVALID, dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), dt_pthread_rwlock_tryrdlock(), dt_pthread_rwlock_unlock(), dt_dev_pixelpipe_cache_t::entries, FALSE, hash, dt_dev_pixelpipe_cache_t::hits, dt_pixel_cache_entry_t::hits, IS_NULL_PTR, dt_dev_pixelpipe_cache_t::lock, dt_pixel_cache_entry_t::lock, dt_dev_pixelpipe_cache_t::queries, dt_pixel_cache_entry_t::size, and TRUE.

Referenced by _group_get_mask_roi(), _peek_gui(), _rekeyed_line_publishes_no_host_pixels(), _rewritten_line_publishes_its_host_pixels(), _without_rekey_the_previous_output_stays(), and dt_dev_pixelpipe_process().

◆ dt_dev_pixelpipe_cache_rekey()

int dt_dev_pixelpipe_cache_rekey ( const uint64_t  old_hash,
const uint64_t  new_hash,
struct dt_pixel_cache_entry_t *  entry 
)

Change the hash/key of an existing cache line in place, without freeing, reallocating or invalidating the underlying entry.

This is useful when a cache line remains the authoritative buffer but the caller needs its identity to follow a new logical snapshot (for example a new module-parameter hash). The entry contents, locks, refcount and storage are preserved; only the hash-table key and entry->hash are updated.

The operation fails if:

  • the source entry cannot be found,
  • or another different entry already exists at new_hash.
Parameters
cache
old_hashCurrent key of the entry.
new_hashDesired new key.
entryOptional direct entry reference. May be NULL.
Returns
int 0 on success, 1 on error.

Definition at line 3311 of file pixelpipe_cache.c.

References _cache_debug_module_name(), _cache_print, _non_threadsafe_cache_get_entry(), _observe_rekey(), _pixelpipe_cache, dt_pixel_cache_entry_t::auto_destroy, dt_pixel_cache_entry_t::cl_mem_list, dt_pixel_cache_entry_t::cl_mem_lock, dt_pixel_cache_entry_t::data, dt_atomic_get_int(), DT_DEBUG_PIPECACHE, dt_dev_pixelpipe_cache_flush_entry_clmem(), dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), dt_dev_pixelpipe_cache_t::entries, dt_pixel_cache_entry_t::hash, IS_NULL_PTR, dt_dev_pixelpipe_cache_t::lock, dt_pixel_cache_entry_t::refcount, and dt_pixel_cache_entry_t::serial.

Referenced by dt_drawlayer_rekey_shared_base_patch().

◆ dt_dev_pixelpipe_cache_release_cl_buffer()

void dt_dev_pixelpipe_cache_release_cl_buffer ( void **  cl_mem_buffer,
dt_pixel_cache_entry_t *  cache_entry,
void *  host_ptr,
const gboolean  cache_device 
)

Release or cache an OpenCL image associated with one cache entry.

Pinned host-backed images and reusable device-only images are returned to the cache entry when possible. Otherwise the OpenCL object is released immediately and any stale cache bookkeeping for it is dropped.

Parameters
[in,out]cl_mem_bufferPointer to the cl_mem handle. Cleared on return.
entryOwning cache entry, or NULL when the buffer is not cache-backed.
host_ptrHost pointer backing pinned images, or NULL for device-only images.
cache_deviceWhether device-only images may be kept for reuse.

Release or cache an OpenCL image associated with one cache entry.

Parameters
[in,out]cl_mem_bufferPointer to a cl_mem stored as void*.
cache_entryPixelpipe cache entry the host pointer belongs to (may be NULL).
host_ptrHost pointer backing the OpenCL image (may be NULL).
cache_deviceAllow caching pure device-side buffers for scratch reuse.

This helper is a single point of truth for OpenCL image lifetime management in the pixelpipe:

  • If the image is host-backed (CL_MEM_USE_HOST_PTR) and we have both cache_entry and host_ptr, we put it in the cache entry's cl_mem_list for reuse.
  • Otherwise, we release it immediately.
  • Pure device allocations may also be cached for scratch-pad reuse. When those cached cl_mem objects are later evicted, the cache layer is responsible for materializing host RAM first if no authoritative host buffer exists yet.

Additionally, when we release an image, we must ensure there is no stale pointer in cl_mem_list (for example, if some earlier path cached it and we are now deciding to free it). We call _pixel_cache_clmem_remove() before releasing to keep the cache bookkeeping coherent.

Definition at line 1406 of file pixelpipe_cache.c.

References _pixel_cache_clmem_put(), _pixel_cache_clmem_remove(), dt_opencl_release_mem_object(), and IS_NULL_PTR.

Referenced by _abort_module_shutdown_cleanup(), _blend_layer_over_input_cl(), _drawlayer_acquire_source_image(), _gpu_early_cpu_fallback_if_unsupported(), and pixelpipe_process_on_GPU().

◆ dt_dev_pixelpipe_cache_restore_cl_buffer()

float * dt_dev_pixelpipe_cache_restore_cl_buffer ( struct dt_dev_pixelpipe_t *  pipe,
float *  input,
void *  cl_mem_input,
const struct dt_iop_roi_t *  roi_in,
struct dt_iop_module_t *  module,
size_t  in_bpp,
struct dt_pixel_cache_entry_t *  input_entry,
const char *  message 
)

Resynchronize one OpenCL input payload back into its cache-backed host buffer.

Parameters
pipeCurrent pixelpipe.
inputHost cache buffer.
cl_mem_inputOpenCL image holding the authoritative pixels.
roi_inBuffer dimensions.
moduleModule for debug logs.
in_bppBytes per pixel.
input_entryOwning cache entry.
messageHuman-readable sync context.
Returns
float* input on success, NULL on failure.

◆ dt_dev_pixelpipe_cache_restore_host_payload()

gboolean dt_dev_pixelpipe_cache_restore_host_payload ( struct dt_pixel_cache_entry_t *  entry,
int  preferred_devid,
void **  data 
)

Materialize a host payload for a live cache entry from its cached device payload.

Recursive pixelpipe stages reopen transient upstream cache entries directly, before those entries become valid exact-hits. When such an entry only carries a GPU payload, the caller may still need a host pointer for CPU fallback or for a non-OpenCL module. This helper keeps the recovery local to the cache layer:

  • allocate host RAM for entry when needed,
  • copy the most relevant cached device payload back to host,
  • return the restored host pointer through data.

The function leaves the cache entry owned by the caller. It does not change refcounts.

Parameters
cachePixelpipe cache.
entryLive cache entry to restore.
preferred_devidPreferred OpenCL device id, or -1 for any.
[out]dataRestored host pointer, or NULL on failure.
Returns
gboolean TRUE when host data is available after the call, FALSE otherwise.

Definition at line 2874 of file pixelpipe_cache.c.

References _cache_entry_materialize_host_data(), _pixel_cache_touch(), _pixelpipe_cache, dt_pixel_cache_entry_get_data(), FALSE, IS_NULL_PTR, and TRUE.

Referenced by dt_dev_pixelpipe_cache_peek(), dt_dev_pixelpipe_process(), and dt_dev_pixelpipe_process_rec().

◆ dt_dev_pixelpipe_cache_return_cl_payload()

void dt_dev_pixelpipe_cache_return_cl_payload ( struct dt_pixel_cache_entry_t *  entry,
void *  mem 
)

Return a borrowed cached OpenCL payload to its cache entry.

Parameters
entryCache entry owning the payload.
memBorrowed cl_mem to release back to cache bookkeeping.

Definition at line 1023 of file pixelpipe_cache.c.

References dt_pixel_cache_entry_t::cl_mem_list, dt_pixel_cache_entry_t::cl_mem_lock, dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), IS_NULL_PTR, and void().

Referenced by _gpu_early_cpu_fallback_if_unsupported(), and pixelpipe_process_on_GPU().

◆ dt_dev_pixelpipe_cache_set_alert_handler()

void dt_dev_pixelpipe_cache_set_alert_handler ( dt_pixelpipe_cache_alert_handler_t  alert)

Install the alert handler. The GUI installs it, once it exists, apart from the others: without a GUI there is nothing to alert with, and an alert is then printed on stderr, the item on the line under the message.

Parameters
alertmay be NULL, which restores that fallback.

Definition at line 125 of file pixelpipe_cache.c.

References _alert_handler.

Referenced by dt_gui_gtk_init().

◆ dt_dev_pixelpipe_cache_set_handlers()

void dt_dev_pixelpipe_cache_set_handlers ( dt_pixelpipe_cache_warn_handler_t  warn,
dt_pixelpipe_cache_ready_handler_t  ready,
const dt_pixelpipe_cache_observer_t *  observer 
)

Install the handlers. Call once, from the orchestrator, before any pipe runs.

Parameters
warnmay be NULL – the warning is then dropped, not printed somewhere else.
readymay be NULL.
observerBORROWED, not copied: it must outlive the cache. Pass NULL to detach.

Definition at line 116 of file pixelpipe_cache.c.

References _observer, _ready_handler, and _warn_handler.

Referenced by dt_init().

◆ dt_dev_pixelpipe_cache_sync_cl_buffer()

int dt_dev_pixelpipe_cache_sync_cl_buffer ( int  devid,
void *  host_ptr,
void *  cl_mem_buffer,
const struct dt_iop_roi_t *  roi,
int  cl_mode,
size_t  bpp,
struct dt_iop_module_t *  module,
const char *  message 
)

Synchronize between host memory and a pinned OpenCL image.

Parameters
devidOpenCL device id.
host_ptrHost pointer to read from / write to.
cl_mem_bufferOpenCL image.
roiBuffer dimensions.
cl_modeCL_MAP_WRITE for host→device, CL_MAP_READ for device→host.
bppBytes per pixel.
moduleModule for debug logs.
messageHuman-readable sync context.
Returns
int 0 on success, 1 on failure.

◆ dt_dev_pixelpipe_cache_unref_entry()

void dt_dev_pixelpipe_cache_unref_entry ( struct dt_pixel_cache_entry_t *  entry)

Release one reference held on entry, by POINTER.

Use this wherever the reference was TAKEN by pointer (dt_dev_pixelpipe_cache_ref_count_entry(TRUE, entry)), which is every long-lived claim in the tree. dt_dev_pixelpipe_cache_unref_hash() resolves the entry by looking its hash up in the cache, so the two are only interchangeable while an entry's hash never changes under its holder – and it does: _cache_try_rekey_reuse_locked() moves a live entry to a new hash in place, which is the whole point of rekey reuse. Released by the old hash afterwards, the lookup finds nothing, the reference is never dropped, and the entry becomes permanently unevictable while its refcount stops meaning anything.

A NULL entry is a no-op, so a holder can release unconditionally.

Definition at line 3289 of file pixelpipe_cache.c.

References dt_dev_pixelpipe_cache_ref_count_entry(), FALSE, and IS_NULL_PTR.

Referenced by _detail_output_with_its_mask_stands(), _detailmask_output(), _held_line_survives_the_flush(), _refresh_global_histogram_backbuf_for_hash(), _released_line_goes_with_the_flush(), dt_dev_backbuf_release_keepalive(), and dt_dev_pixelpipe_process().

◆ dt_dev_pixelpipe_cache_unref_hash()

◆ dt_dev_pixelpipe_cache_wrlock_entry()

◆ dt_pixel_cache_alloc()

void * dt_pixel_cache_alloc ( struct dt_pixel_cache_entry_t *  entry)

Actually allocate the memory buffer attached to the cache entry once you create it with dt_dev_pixelpipe_cache_get(). Sizes and everything are already saved in the entry, and the cache will have the needed space reserved.

Parameters
cache
entrythe cache entry
Returns
void* Pointer to the allocated data buffer.

Definition at line 2095 of file pixelpipe_cache.c.

References _arena_alloc_with_defrag(), _log_arena_allocation_failure(), _pixelpipe_cache, dt_pixel_cache_entry_t::data, FALSE, dt_pixel_cache_entry_t::hash, IS_NULL_PTR, dt_pixel_cache_entry_t::name, and dt_pixel_cache_entry_t::size.

Referenced by _cache_entry_materialize_host_data(), _gpu_early_cpu_fallback_if_unsupported(), _gpu_init_input(), _produce(), dt_dev_pixelpipe_cache_get(), dt_dev_pixelpipe_cache_get_writable(), dt_pixel_cache_new_entry(), pixelpipe_process_on_CPU(), and pixelpipe_process_on_GPU().

◆ dt_pixel_cache_entry_get_buffer()

void * dt_pixel_cache_entry_get_buffer ( struct dt_pixel_cache_entry_t *  entry)

The host buffer of a cache entry, whatever hash its content describes.

For the producer holding the write lock from dt_dev_pixelpipe_cache_get_writable() only: a rekeyed entry's buffer is about to be overwritten, and it still backs the pinned OpenCL image of an output that is not copied back to RAM. Everyone else reads pixels through dt_pixel_cache_entry_get_data().

Definition at line 2120 of file pixelpipe_cache.c.

References dt_pixel_cache_entry_t::data.

Referenced by _rekeyed_line_publishes_no_host_pixels(), and pixelpipe_process_on_GPU().

◆ dt_pixel_cache_entry_get_data()

void * dt_pixel_cache_entry_get_data ( struct dt_pixel_cache_entry_t *  entry)

◆ dt_pixel_cache_entry_get_size()

size_t dt_pixel_cache_entry_get_size ( const struct dt_pixel_cache_entry_t *  entry)

Peek the size (in bytes) reserved for the host buffer of a cache entry.

The pixelpipe cache treats dt_pixel_cache_entry_t as an internal/private structure. External users (such as the pixelpipe implementation) should not access struct fields directly.

This accessor is intentionally "peek-only": it does not allocate and it does not change ownership.

◆ dt_pixelpipe_cache_alloc_align_cache_impl()

void * dt_pixelpipe_cache_alloc_align_cache_impl ( size_t  size,
int  id,
const char *  name 
)

Allocate aligned memory tracked by the pixelpipe cache. This allows LRU cache entries to be evicted if needed to make room.

Parameters
cachePixelpipe cache to manage.
sizeBuffer size in bytes.
idPipeline type owning the buffer.
nameHuman-readable name.
Returns
void* Pointer to the allocated buffer, or NULL on failure.

Definition at line 2242 of file pixelpipe_cache.c.

◆ dt_pixelpipe_cache_free_align_cache()

void dt_pixelpipe_cache_free_align_cache ( void **  mem,
const char *  message 
)

Free aligned memory allocated with dt_pixelpipe_cache_alloc_align_cache.

Parameters
cachePixelpipe cache to manage.
memPointer to the buffer pointer. Set to NULL on successful free.

Definition at line 2292 of file pixelpipe_cache.c.

◆ dt_pixelpipe_cache_get_alloc_refusals()

uint32_t dt_pixelpipe_cache_get_alloc_refusals ( void  )

Count the allocations the cache refused to the calling thread for lack of memory (thread-local).

A refusal is a NULL returned because memory ran short: the cache's budget was spent with every line in use, the arena had no free run long enough, or the system had no RAM left. The count only goes up. A caller that reads it before and after a pixelpipe run learns whether that run was refused memory: the pipe runs on its caller's thread. Allocations made on other threads, such as OpenMP workers, are not counted here.

Returns
uint32_t Refusals so far on this thread.

Definition at line 269 of file pixelpipe_cache.c.

References dt_pixelpipe_cache_alloc_refusals.

Referenced by _budget_spent_by_a_line_in_use_is_counted_once(), _granted_allocation_is_not_counted(), _refusal_on_another_thread_is_not_counted_here(), _refuse_on_this_thread(), _request_larger_than_the_cache_is_counted_once(), and dt_imageio_export_with_flags().

◆ dt_pixelpipe_cache_get_largest_free_run()

size_t dt_pixelpipe_cache_get_largest_free_run ( void  )

◆ dt_pixelpipe_cache_set_current_image()

const char * dt_pixelpipe_cache_set_current_image ( const char *  image)

Set the image the current module runs on, for the message that reports a refused allocation (thread-local).

The image comes as text its caller wrote, as the module comes as its name: the cache prints it, and knows nothing of images. The pointer is kept, not copied.

Parameters
imageThe image as it should read, which must outlive the setting, or NULL to clear.
Returns
const char* Previous image.

Definition at line 262 of file pixelpipe_cache.c.

References dt_pixelpipe_cache_current_image.

Referenced by dt_dev_pixelpipe_get_roi_in(), and dt_dev_pixelpipe_process_rec().

◆ dt_pixelpipe_cache_set_current_module()

const char * dt_pixelpipe_cache_set_current_module ( const char *  module)

Set the current module name for cache diagnostics (thread-local).

Parameters
moduleModule op name or NULL to clear.
Returns
const char* Previous module name.

Definition at line 255 of file pixelpipe_cache.c.

References dt_pixelpipe_cache_current_module.

Referenced by dt_dev_pixelpipe_get_roi_in(), and dt_dev_pixelpipe_process_rec().