Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
pixelpipe_cache.c File Reference
#include <inttypes.h>
#include <glib.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include "control/control.h"
#include "develop/pixelpipe_cache.h"
#include "develop/pixelpipe.h"
#include "common/darktable.h"
#include "common/debug.h"
#include "common/opencl.h"
#include "develop/format.h"
+ Include dependency graph for pixelpipe_cache.c:

Data Structures

struct  dt_cache_clmem_t
 
struct  _cache_lru_t
 
struct  _cache_invalidate_t
 

Typedefs

typedef struct dt_cache_clmem_t dt_cache_clmem_t
 
typedef enum dt_pixel_cache_materialize_source_rank_t dt_pixel_cache_materialize_source_rank_t
 
typedef struct _cache_lru_t _cache_lru_t
 
typedef struct _cache_invalidate_t _cache_invalidate_t
 

Enumerations

enum  dt_pixel_cache_materialize_source_rank_t {
  DT_PIXEL_CACHE_MATERIALIZE_SOURCE_NONE = 0 ,
  DT_PIXEL_CACHE_MATERIALIZE_SOURCE_SECONDARY_ANY = 1 ,
  DT_PIXEL_CACHE_MATERIALIZE_SOURCE_SECONDARY_PREFERRED = 2 ,
  DT_PIXEL_CACHE_MATERIALIZE_SOURCE_PRIMARY_ANY = 3 ,
  DT_PIXEL_CACHE_MATERIALIZE_SOURCE_PRIMARY_PREFERRED = 4
}
 

Functions

static dt_pixel_cache_entry_t_non_threadsafe_cache_get_entry (dt_dev_pixelpipe_cache_t *cache, GHashTable *table, const uint64_t key)
 
static const char * _cache_debug_module_name (void)
 
static void _trace_exact_hit (const char *phase, const uint64_t hash, dt_pixel_cache_entry_t *cache_entry, void *data, void *cl_mem_output, const int preferred_devid, const gboolean verbose)
 
const char * dt_pixelpipe_cache_set_current_module (const char *module)
 Set the current module name for cache diagnostics (thread-local).
 
void _non_thread_safe_cache_ref_count_entry (dt_dev_pixelpipe_cache_t *cache, gboolean lock, dt_pixel_cache_entry_t *cache_entry)
 
static void _free_cache_entry (dt_pixel_cache_entry_t *cache_entry)
 
static void _pixelpipe_cache_finalize_entry (dt_pixel_cache_entry_t *cache_entry, void **data, const char *message)
 
int _non_thread_safe_cache_remove (dt_dev_pixelpipe_cache_t *cache, const gboolean force, dt_pixel_cache_entry_t *cache_entry, GHashTable *table)
 
static dt_pixel_cache_entry_t_pixelpipe_cache_create_entry_locked (dt_dev_pixelpipe_cache_t *cache, const uint64_t hash, const size_t size, const char *name, const int id)
 
static dt_pixel_cache_entry_tdt_pixel_cache_new_entry (const uint64_t hash, const size_t size, const char *name, const int id, dt_dev_pixelpipe_cache_t *cache, gboolean alloc, GHashTable *table)
 
static void _cache_entry_clmem_flush_device (dt_pixel_cache_entry_t *entry, const int devid)
 
static gboolean _cache_entry_materialize_host_data_locked (dt_pixel_cache_entry_t *entry, int preferred_devid, gboolean prefer_device_payload)
 
static int dt_dev_pixelpipe_cache_flush_old (dt_dev_pixelpipe_cache_t *cache)
 
static gboolean _cache_entry_clmem_flush_host_pinned_locked (dt_pixel_cache_entry_t *entry, void *host_ptr, int devid)
 
static dt_pixel_cache_entry_t_cache_entry_for_host_ptr_locked (dt_dev_pixelpipe_cache_t *cache, void *host_ptr)
 
dt_pixel_cache_entry_tdt_dev_pixelpipe_cache_get_entry (dt_dev_pixelpipe_cache_t *cache, 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.
 
dt_pixel_cache_entry_tdt_dev_pixelpipe_cache_get_entry_by_data (dt_dev_pixelpipe_cache_t *cache, void *data)
 
static size_t _pixel_cache_get_size (dt_pixel_cache_entry_t *cache_entry)
 
static void _pixel_cache_message (dt_pixel_cache_entry_t *cache_entry, const char *message, gboolean verbose)
 
int dt_dev_pixelpipe_cache_remove (dt_dev_pixelpipe_cache_t *cache, const gboolean force, dt_pixel_cache_entry_t *cache_entry)
 Arbitrarily remove the cache entry matching hash. Entries having a reference count > 0 (inter-thread locked) or being having their read/write lock locked will be ignored. If force is TRUE, we ignore reference count, but not locks.
 
static gboolean _cache_entry_materialize_host_data (dt_dev_pixelpipe_cache_t *cache, int preferred_devid, dt_pixel_cache_entry_t *entry)
 
static gboolean _cache_entry_clmem_has_host_pinned_locked (dt_pixel_cache_entry_t *entry, void *host_ptr, int devid)
 
void dt_dev_pixelpipe_cache_flush_clmem (dt_dev_pixelpipe_cache_t *cache, const int devid)
 Release cached OpenCL buffers for a device (-1 for all).
 
static void _cache_get_oldest (gpointer key, gpointer value, gpointer user_data)
 
static void _print_cache_lines (gpointer key, gpointer value, gpointer user_data)
 
static int _non_thread_safe_pixel_pipe_cache_remove_lru (dt_dev_pixelpipe_cache_t *cache)
 
int dt_dev_pixel_pipe_cache_remove_lru (dt_dev_pixelpipe_cache_t *cache)
 
static void_pixel_cache_clmem_get (dt_pixel_cache_entry_t *entry, void *host_ptr, int devid, int width, int height, int bpp, int flags)
 
voiddt_dev_pixelpipe_cache_borrow_cl_payload (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 (dt_pixel_cache_entry_t *entry, void *mem)
 Return a borrowed cached OpenCL payload to its cache entry.
 
static int _pixel_cache_clmem_put (dt_pixel_cache_entry_t *entry, void *host_ptr, void *mem)
 
static void _pixel_cache_clmem_remove (dt_pixel_cache_entry_t *entry, void *mem)
 
void dt_dev_pixelpipe_cache_flush_entry_clmem (dt_pixel_cache_entry_t *entry)
 Flush all reusable OpenCL payloads cached on one cache entry.
 
voiddt_dev_pixelpipe_cache_get_pinned_image (dt_dev_pixelpipe_cache_t *cache, void *host_ptr, 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 (dt_dev_pixelpipe_cache_t *cache, void *host_ptr, 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 (dt_dev_pixelpipe_cache_t *cache, void *host_ptr, dt_pixel_cache_entry_t *entry_hint, int devid)
 Drop cached pinned OpenCL images associated with a given host buffer.
 
static gboolean _is_gamma_rgba8_output (const dt_iop_module_t *module, const size_t bpp, const char *message)
 
voiddt_dev_pixelpipe_cache_alloc_cl_device_buffer (int devid, const dt_iop_roi_t *roi, const size_t bpp, const dt_iop_module_t *module, const char *message, void *keep)
 
voiddt_dev_pixelpipe_cache_get_cl_buffer (int devid, void *const host_ptr, const dt_iop_roi_t *roi, const size_t bpp, dt_iop_module_t *module, const char *message, dt_pixel_cache_entry_t *cache_entry, gboolean *out_reused, void *keep)
 
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 a host cache line.
 
int dt_dev_pixelpipe_cache_sync_cl_buffer (const int devid, void *host_ptr, void *cl_mem_buffer, const dt_iop_roi_t *roi, int cl_mode, size_t bpp, 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 (dt_dev_pixelpipe_t *pipe, float *input, void *cl_mem_input, const dt_iop_roi_t *roi_in, dt_iop_module_t *module, const size_t in_bpp, dt_pixel_cache_entry_t *input_entry, const char *message)
 Force device → host resynchronization of the pixelpipe input cache line.
 
int dt_dev_pixelpipe_cache_prepare_cl_input (dt_dev_pixelpipe_t *pipe, dt_iop_module_t *module, float *input, void **cl_mem_input, const dt_iop_roi_t *roi_in, const size_t in_bpp, dt_pixel_cache_entry_t *input_entry, dt_pixel_cache_entry_t **locked_input_entry, void *keep)
 Prepare/obtain the OpenCL input image for a module.
 
dt_pixel_cache_entry_tdt_dev_pixelpipe_cache_ref_entry_for_host_ptr (dt_dev_pixelpipe_cache_t *cache, void *host_ptr)
 Resolve and retain the cache entry owning a host pointer.
 
static void_arena_alloc_with_defrag (dt_dev_pixelpipe_cache_t *cache, size_t request_size, size_t *actual_size)
 
static void _arena_stats_bytes (dt_dev_pixelpipe_cache_t *cache, uint32_t *total_pages, uint32_t *largest_pages, size_t *total_bytes, size_t *largest_bytes)
 
static void _log_arena_allocation_failure (dt_dev_pixelpipe_cache_t *cache, size_t request_size, const char *entry_name, const char *module, uint64_t hash, gboolean name_is_file)
 
voiddt_pixel_cache_alloc (dt_dev_pixelpipe_cache_t *cache, dt_pixel_cache_entry_t *cache_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.
 
voiddt_pixel_cache_entry_get_data (dt_pixel_cache_entry_t *entry)
 
size_t dt_pixel_cache_entry_get_size (dt_pixel_cache_entry_t *entry)
 Peek the size (in bytes) reserved for the host buffer of a cache entry.
 
static int _free_space_to_alloc (dt_dev_pixelpipe_cache_t *cache, const size_t size, const uint64_t hash, const char *name)
 
voiddt_pixelpipe_cache_alloc_align_cache_impl (dt_dev_pixelpipe_cache_t *cache, 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 (dt_dev_pixelpipe_cache_t *cache, void **mem, const char *message)
 Free aligned memory allocated with dt_pixelpipe_cache_alloc_align_cache.
 
dt_dev_pixelpipe_cache_tdt_dev_pixelpipe_cache_init (size_t max_memory)
 
void dt_dev_pixelpipe_cache_cleanup (dt_dev_pixelpipe_cache_t *cache)
 
static dt_pixel_cache_entry_t_cache_try_rekey_reuse_locked (dt_dev_pixelpipe_cache_t *cache, const uint64_t new_hash, const size_t size, const dt_pixel_cache_entry_t *reuse_hint)
 
int dt_dev_pixelpipe_cache_get (dt_dev_pixelpipe_cache_t *cache, const uint64_t hash, const size_t size, const char *name, const int id, const gboolean alloc, void **data, 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 (dt_dev_pixelpipe_cache_t *cache, const uint64_t hash, const size_t size, const char *name, const int id, const gboolean alloc, const gboolean allow_rekey_reuse, const dt_pixel_cache_entry_t *reuse_hint, void **data, dt_pixel_cache_entry_t **entry)
 
static dt_pixel_cache_entry_t_cache_lookup_existing (dt_dev_pixelpipe_cache_t *cache, const uint64_t hash, void **data)
 
static gboolean _cache_try_restore_device_payload (dt_pixel_cache_entry_t *cache_entry, const int preferred_devid, void **cl_mem_output)
 
gboolean dt_dev_pixelpipe_cache_restore_host_payload (dt_dev_pixelpipe_cache_t *cache, dt_pixel_cache_entry_t *cache_entry, const int preferred_devid, void **data)
 Materialize a host payload for a live cache entry from its cached device payload.
 
gboolean dt_dev_pixelpipe_cache_peek (dt_dev_pixelpipe_cache_t *cache, const uint64_t hash, void **data, dt_pixel_cache_entry_t **entry, const int preferred_devid, void **cl_mem_output)
 Non-owning lookup of an existing cache line.
 
static gboolean _for_each_remove (gpointer key, gpointer value, gpointer user_data)
 
void dt_dev_pixelpipe_cache_flush (dt_dev_pixelpipe_cache_t *cache, const int id)
 Remove cache lines matching id. Entries locked in read/write or having reference count greater than 0 are not removed.
 
static gboolean _for_each_remove_old (gpointer key, gpointer value, gpointer user_data)
 
void dt_dev_pixelpipe_cache_ref_count_entry (dt_dev_pixelpipe_cache_t *cache, gboolean lock, dt_pixel_cache_entry_t *cache_entry)
 Increase/Decrease the reference count on the cache line as to prevent LRU item removal. This function should be called within a read/write lock-protected section to avoid changing an entry while or after it is deleted in parallel.
 
void dt_dev_pixelpipe_cache_wrlock_entry (dt_dev_pixelpipe_cache_t *cache, gboolean lock, dt_pixel_cache_entry_t *cache_entry)
 Lock or release the write lock on the entry.
 
void dt_dev_pixelpipe_cache_rdlock_entry (dt_dev_pixelpipe_cache_t *cache, gboolean lock, dt_pixel_cache_entry_t *cache_entry)
 Lock or release the read lock on the entry.
 
void dt_dev_pixelpipe_cache_flag_auto_destroy (dt_dev_pixelpipe_cache_t *cache, dt_pixel_cache_entry_t *cache_entry)
 Flag the cache entry as "auto_destroy". This is useful for short-lived/disposable cache entries, that won't be needed in the future. These will be freed out of the typical LRU, aged-based garbage collection. The thread that tagged this entry as "auto_destroy" is responsible for freeing it as soon as it is done with it, using dt_dev_pixelpipe_cache_auto_destroy_apply(). If not manually freed this way, the entry will be caught using the generic LRU garbage collection.
 
void dt_dev_pixelpipe_cache_auto_destroy_apply (dt_dev_pixelpipe_cache_t *cache, dt_pixel_cache_entry_t *cache_entry)
 Free the entry if it has the flag "auto_destroy". See dt_dev_pixelpipe_cache_flag_auto_destroy(). This only removes entries whose reference count already dropped to 0 and whose lock is currently free. Call it right after the final consumer releases its refcount, from the same control flow that flagged the entry for auto-destruction. If another consumer still owns the entry, this becomes a no-op and generic cache eviction or a later explicit retry will reap it once ownership reaches 0.
 
void dt_dev_pixelpipe_cache_unref_hash (dt_dev_pixelpipe_cache_t *cache, const uint64_t hash)
 Find the entry matching hash, and decrease its ref_count if found.
 
int dt_dev_pixelpipe_cache_rekey (dt_dev_pixelpipe_cache_t *cache, const uint64_t old_hash, const uint64_t new_hash, 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_print (dt_dev_pixelpipe_cache_t *cache)
 

Variables

static __thread const char * dt_pixelpipe_cache_current_module = NULL
 
static int garbage_collection = 0
 

Typedef Documentation

◆ _cache_invalidate_t

◆ _cache_lru_t

typedef struct _cache_lru_t _cache_lru_t

◆ dt_cache_clmem_t

◆ dt_pixel_cache_materialize_source_rank_t

Enumeration Type Documentation

◆ dt_pixel_cache_materialize_source_rank_t

Enumerator
DT_PIXEL_CACHE_MATERIALIZE_SOURCE_NONE 
DT_PIXEL_CACHE_MATERIALIZE_SOURCE_SECONDARY_ANY 
DT_PIXEL_CACHE_MATERIALIZE_SOURCE_SECONDARY_PREFERRED 
DT_PIXEL_CACHE_MATERIALIZE_SOURCE_PRIMARY_ANY 
DT_PIXEL_CACHE_MATERIALIZE_SOURCE_PRIMARY_PREFERRED 

Function Documentation

◆ _arena_alloc_with_defrag()

◆ _arena_stats_bytes()

static void _arena_stats_bytes ( dt_dev_pixelpipe_cache_t cache,
uint32_t *  total_pages,
uint32_t *  largest_pages,
size_t *  total_bytes,
size_t *  largest_bytes 
)
inlinestatic

◆ _cache_debug_module_name()

static const char * _cache_debug_module_name ( void  )
inlinestatic

◆ _cache_entry_clmem_flush_device()

◆ _cache_entry_clmem_flush_host_pinned_locked()

◆ _cache_entry_clmem_has_host_pinned_locked()

◆ _cache_entry_for_host_ptr_locked()

◆ _cache_entry_materialize_host_data()

◆ _cache_entry_materialize_host_data_locked()

◆ _cache_get_oldest()

◆ _cache_lookup_existing()

◆ _cache_try_rekey_reuse_locked()

◆ _cache_try_restore_device_payload()

static gboolean _cache_try_restore_device_payload ( dt_pixel_cache_entry_t cache_entry,
const int  preferred_devid,
void **  cl_mem_output 
)
static

◆ _for_each_remove()

static gboolean _for_each_remove ( gpointer  key,
gpointer  value,
gpointer  user_data 
)
static

◆ _for_each_remove_old()

static gboolean _for_each_remove_old ( gpointer  key,
gpointer  value,
gpointer  user_data 
)
static

◆ _free_cache_entry()

◆ _free_space_to_alloc()

◆ _is_gamma_rgba8_output()

static gboolean _is_gamma_rgba8_output ( const dt_iop_module_t module,
const size_t  bpp,
const char *  message 
)
inlinestatic

◆ _log_arena_allocation_failure()

static void _log_arena_allocation_failure ( dt_dev_pixelpipe_cache_t cache,
size_t  request_size,
const char *  entry_name,
const char *  module,
uint64_t  hash,
gboolean  name_is_file 
)
inlinestatic

◆ _non_thread_safe_cache_ref_count_entry()

◆ _non_thread_safe_cache_remove()

◆ _non_thread_safe_pixel_pipe_cache_remove_lru()

◆ _non_threadsafe_cache_get_entry()

◆ _pixel_cache_clmem_get()

◆ _pixel_cache_clmem_put()

static int _pixel_cache_clmem_put ( dt_pixel_cache_entry_t entry,
void host_ptr,
void mem 
)
static
Parameters
entry
host_ptr
mem
Returns
int 3 if the memory was already cached (no-op), 2 if we updated a previous cacheline (same width/height/bpp/devid) with a new buffer, 0 if we failed to create a new cacheline, 1 if we created a new cacheline.

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

Referenced by dt_dev_pixelpipe_cache_put_pinned_image(), and dt_dev_pixelpipe_cache_release_cl_buffer().

◆ _pixel_cache_clmem_remove()

◆ _pixel_cache_get_size()

static size_t _pixel_cache_get_size ( dt_pixel_cache_entry_t cache_entry)
static

◆ _pixel_cache_message()

◆ _pixelpipe_cache_create_entry_locked()

static dt_pixel_cache_entry_t * _pixelpipe_cache_create_entry_locked ( dt_dev_pixelpipe_cache_t cache,
const uint64_t  hash,
const size_t  size,
const char *  name,
const int  id 
)
static

◆ _pixelpipe_cache_finalize_entry()

static void _pixelpipe_cache_finalize_entry ( dt_pixel_cache_entry_t cache_entry,
void **  data,
const char *  message 
)
static

◆ _print_cache_lines()

static void _print_cache_lines ( gpointer  key,
gpointer  value,
gpointer  user_data 
)
static

◆ _trace_exact_hit()

◆ dt_dev_pixel_pipe_cache_remove_lru()

int dt_dev_pixel_pipe_cache_remove_lru ( dt_dev_pixelpipe_cache_t cache)

◆ dt_dev_pixelpipe_cache_alloc_cl_device_buffer()

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

◆ dt_dev_pixelpipe_cache_auto_destroy_apply()

void dt_dev_pixelpipe_cache_auto_destroy_apply ( dt_dev_pixelpipe_cache_t cache,
struct dt_pixel_cache_entry_t entry 
)

Free the entry if it has the flag "auto_destroy". See dt_dev_pixelpipe_cache_flag_auto_destroy(). This only removes entries whose reference count already dropped to 0 and whose lock is currently free. Call it right after the final consumer releases its refcount, from the same control flow that flagged the entry for auto-destruction. If another consumer still owns the entry, this becomes a no-op and generic cache eviction or a later explicit retry will reap it once ownership reaches 0.

Parameters
cache

References _pixel_cache_message(), dt_pixel_cache_entry_t::auto_destroy, dt_atomic_get_int(), dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), dt_pthread_rwlock_trywrlock, dt_pthread_rwlock_unlock, dt_dev_pixelpipe_cache_t::entries, FALSE, dt_pixel_cache_entry_t::hash, IS_NULL_PTR, dt_dev_pixelpipe_cache_t::lock, dt_pixel_cache_entry_t::lock, dt_pixel_cache_entry_t::refcount, and TRUE.

Referenced by _abort_module_shutdown_cleanup(), dt_dev_pixelpipe_cleanup(), and dt_dev_pixelpipe_process_rec().

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

References 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 ( dt_dev_pixelpipe_cache_t cache,
struct dt_pixel_cache_entry_t entry 
)

Flag the cache entry as "auto_destroy". This is useful for short-lived/disposable cache entries, that won't be needed in the future. These will be freed out of the typical LRU, aged-based garbage collection. The thread that tagged this entry as "auto_destroy" is responsible for freeing it as soon as it is done with it, using dt_dev_pixelpipe_cache_auto_destroy_apply(). If not manually freed this way, the entry will be caught using the generic LRU garbage collection.

Parameters
cache

References _pixel_cache_message(), 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(), dt_dev_pixelpipe_cleanup(), and dt_dev_pixelpipe_process_rec().

◆ dt_dev_pixelpipe_cache_flush()

void dt_dev_pixelpipe_cache_flush ( dt_dev_pixelpipe_cache_t cache,
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.

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

Referenced by dt_dev_darkroom_pipeline(), and dt_dev_pixelpipe_reset_all().

◆ dt_dev_pixelpipe_cache_flush_clmem()

void dt_dev_pixelpipe_cache_flush_clmem ( dt_dev_pixelpipe_cache_t cache,
const int  devid 
)

Release cached OpenCL buffers for a device (-1 for all).

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.

References _cache_entry_clmem_flush_device(), darktable, DT_DEBUG_OPENCL, DT_DEBUG_VERBOSE, dt_opencl_events_wait_for(), dt_print(), dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), dt_dev_pixelpipe_cache_t::entries, dt_pixel_cache_entry_t::hash, key, dt_dev_pixelpipe_cache_t::lock, darktable_t::unmuted, and value.

Referenced by _dt_opencl_alloc_image2d(), dt_dev_pixelpipe_cleanup(), dt_opencl_alloc_device_buffer_with_flags(), leave(), and pixelpipe_process_on_GPU().

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

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 ( dt_dev_pixelpipe_cache_t cache,
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.

References _cache_entry_clmem_flush_host_pinned_locked(), _cache_entry_clmem_has_host_pinned_locked(), _cache_entry_for_host_ptr_locked(), 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(), _rekey_shared_base_patch(), dt_dev_pixelpipe_gpu_flush_host_pinned_images(), dt_drawlayer_cache_flush_process_patch_to_base(), and dt_drawlayer_cache_populate_process_patch_from_base().

◆ dt_dev_pixelpipe_cache_flush_old()

◆ dt_dev_pixelpipe_cache_get()

int dt_dev_pixelpipe_cache_get ( dt_dev_pixelpipe_cache_t cache,
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.

References _non_thread_safe_cache_ref_count_entry(), _non_thread_safe_cache_remove(), _non_threadsafe_cache_get_entry(), _pixel_cache_message(), _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_print(), dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), dt_dev_pixelpipe_cache_t::entries, FALSE, 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, and TRUE.

Referenced by dt_drawlayer_cache_patch_alloc_shared(), process(), and process_cl().

◆ dt_dev_pixelpipe_cache_get_cl_buffer()

◆ dt_dev_pixelpipe_cache_get_entry()

dt_pixel_cache_entry_t * dt_dev_pixelpipe_cache_get_entry ( dt_dev_pixelpipe_cache_t cache,
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.

Parameters
cache
hash
Returns
struct dt_pixel_cache_entry_t*

References _non_threadsafe_cache_get_entry(), DT_PIXELPIPE_CACHE_HASH_INVALID, dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), dt_dev_pixelpipe_cache_t::entries, and dt_dev_pixelpipe_cache_t::lock.

Referenced by _do_get_structure_auto(), _do_get_structure_lines(), _do_get_structure_quad(), dt_dev_pixelpipe_cleanup(), dt_dev_pixelpipe_process_rec(), and dt_dev_retrieve_rawdetail_mask().

◆ dt_dev_pixelpipe_cache_get_entry_by_data()

◆ dt_dev_pixelpipe_cache_get_pinned_image()

void * dt_dev_pixelpipe_cache_get_pinned_image ( dt_dev_pixelpipe_cache_t cache,
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.

References _cache_entry_for_host_ptr_locked(), _pixel_cache_clmem_get(), _pixel_cache_clmem_remove(), 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_print(), 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_writable()

◆ dt_dev_pixelpipe_cache_init()

◆ dt_dev_pixelpipe_cache_peek()

gboolean dt_dev_pixelpipe_cache_peek ( dt_dev_pixelpipe_cache_t cache,
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.

References _cache_lookup_existing(), _cache_try_restore_device_payload(), _trace_exact_hit(), dt_pixel_cache_entry_t::auto_destroy, DT_DEBUG_PIPECACHE, dt_dev_pixelpipe_cache_remove(), dt_dev_pixelpipe_cache_restore_host_payload(), dt_pixel_cache_entry_get_data(), DT_PIXELPIPE_CACHE_HASH_INVALID, dt_print(), dt_pthread_rwlock_tryrdlock, dt_pthread_rwlock_unlock, FALSE, IS_NULL_PTR, dt_pixel_cache_entry_t::lock, and TRUE.

Referenced by _develop_cacheline_ready_callback(), _develop_history_resync_callback(), _sync_private_buffer_from_preview_cache(), dt_dev_pixelpipe_cache_peek_gui(), dt_dev_pixelpipe_process(), dt_dev_pixelpipe_process_rec(), dt_dev_resync_mipmap_cache(), dt_dev_retrieve_rawdetail_mask(), dt_imageio_export_with_flags(), and gui_focus().

◆ dt_dev_pixelpipe_cache_prepare_cl_input()

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

Prepare/obtain the OpenCL input image for a module.

Parameters
pipeCurrent pixelpipe (provides device id + global settings).
moduleModule being processed (for debug logs).
inputHost input pointer (may be NULL on GPU-only paths).
[in,out]cl_mem_inputOpenCL input image; may already be set by the previous module.
roi_inROI for the input buffer.
in_bppInput bytes-per-pixel.
input_entryPixelpipe cache entry corresponding to the input hash.
[out]locked_input_entryIf non-NULL on return, the caller must unlock it after GPU work completed.
keepOpenCL buffer to keep alive while flushing device scratch allocations.
Returns
0 on success, 1 on failure.

There are two major cases:

1) !IS_NULL_PTR(*cl_mem_input): The previous module already produced an OpenCL buffer and we are continuing on GPU. We may still need to keep the cache entry write-locked if it is a true zero-copy pinned image, because in-place OpenCL colorspace transforms can mutate the host-backed buffer before the current module runs.

2) IS_NULL_PTR(*cl_mem_input): We start from a host cache buffer (input). We allocate (or reuse) a pinned image backed by that host buffer, and if it is not true zero-copy we push host→device once before running kernels.

References darktable, dt_dev_pixelpipe_t::devid, DT_DEBUG_OPENCL, dt_dev_pixelpipe_cache_get_cl_buffer(), dt_dev_pixelpipe_cache_rdlock_entry(), dt_opencl_events_wait_for(), dt_opencl_is_pinned_memory(), dt_opencl_write_host_to_device(), dt_print(), FALSE, dt_iop_roi_t::height, IS_NULL_PTR, dt_iop_module_t::op, darktable_t::pixelpipe_cache, TRUE, and dt_iop_roi_t::width.

Referenced by pixelpipe_process_on_GPU().

◆ dt_dev_pixelpipe_cache_print()

◆ dt_dev_pixelpipe_cache_put_pinned_image()

void dt_dev_pixelpipe_cache_put_pinned_image ( dt_dev_pixelpipe_cache_t cache,
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) ?

References _pixel_cache_clmem_put(), darktable, DT_DEBUG_OPENCL, DT_DEBUG_VERBOSE, dt_print(), IS_NULL_PTR, state, and darktable_t::unmuted.

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 ( dt_dev_pixelpipe_cache_t cache,
gboolean  lock,
struct dt_pixel_cache_entry_t entry 
)

◆ dt_dev_pixelpipe_cache_ref_entry_for_host_ptr()

dt_pixel_cache_entry_t * dt_dev_pixelpipe_cache_ref_entry_for_host_ptr ( dt_dev_pixelpipe_cache_t cache,
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.

References _cache_entry_for_host_ptr_locked(), _non_thread_safe_cache_ref_count_entry(), 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_rekey()

int dt_dev_pixelpipe_cache_rekey ( dt_dev_pixelpipe_cache_t cache,
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.

References _cache_debug_module_name(), _non_threadsafe_cache_get_entry(), 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_print(), 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 _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 a host cache line.

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.

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_remove()

int dt_dev_pixelpipe_cache_remove ( dt_dev_pixelpipe_cache_t cache,
const gboolean  force,
struct dt_pixel_cache_entry_t entry 
)

Arbitrarily remove the cache entry matching hash. Entries having a reference count > 0 (inter-thread locked) or being having their read/write lock locked will be ignored. If force is TRUE, we ignore reference count, but not locks.

Parameters
cache
force

References _non_thread_safe_cache_remove(), dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), dt_dev_pixelpipe_cache_t::entries, error(), and dt_dev_pixelpipe_cache_t::lock.

Referenced by _abort_module_shutdown_cleanup(), _do_get_structure_auto(), _do_get_structure_lines(), _do_get_structure_quad(), dt_dev_pixelpipe_cache_peek(), dt_dev_pixelpipe_process_rec(), process(), and process_cl().

◆ dt_dev_pixelpipe_cache_restore_cl_buffer()

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

Force device → host resynchronization of the pixelpipe input cache line.

This is used when we are about to switch from GPU processing to CPU processing for a given module. In that scenario, the most recent correct pixels may only exist in cl_mem_input (GPU-only intermediate), while input (host pointer) is either NULL or stale.

The function:

  • write-locks the cache entry (we are modifying host memory),
  • performs a device→host copy (map/unmap if possible, explicit copy otherwise),
  • updates the buffer descriptor colorspace tag.

References darktable, dt_dev_pixelpipe_t::devid, dt_dev_pixelpipe_cache_sync_cl_buffer(), dt_dev_pixelpipe_cache_wrlock_entry(), FALSE, IS_NULL_PTR, darktable_t::pixelpipe_cache, and TRUE.

Referenced by _gpu_early_cpu_fallback_if_unsupported().

◆ dt_dev_pixelpipe_cache_restore_host_payload()

gboolean dt_dev_pixelpipe_cache_restore_host_payload ( dt_dev_pixelpipe_cache_t cache,
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.

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

Referenced by dt_dev_pixelpipe_cache_peek().

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

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_sync_cl_buffer()

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

Synchronize between host memory and a pinned OpenCL image.

Parameters
devidOpenCL device index.
host_ptrHost pointer to read from / write to.
cl_mem_bufferOpenCL image.
roiImage dimensions.
cl_modeCL_MAP_WRITE for host→device, CL_MAP_READ for device→host.
bppBytes per pixel.
moduleModule for debug logs (may be NULL).
messageContext string for debug logs.
Returns
0 on success, 1 on failure.

This function intentionally tries a hierarchy of synchronization mechanisms:

  1. For CL_MEM_USE_HOST_PTR images, we attempt a map/unmap cycle. If the mapped pointer equals host_ptr, we treat it as true zero-copy and the map/unmap acts as a synchronization barrier (fast, avoids extra copies).
  2. Otherwise, we fall back to explicit blocking transfers (dt_opencl_write_host_to_device / dt_opencl_read_host_from_device), which already guarantee that the copied pixels are visible on the host/device side when the helper returns.

The map/unmap approach is used as a synchronization barrier because on many drivers it will:

  • flush CPU caches / invalidate as needed,
  • ensure GPU work touching that memory is completed (for blocking map),
  • and potentially avoid a full copy when true zero-copy is supported.

References bpp, DT_DEBUG_OPENCL, dt_opencl_is_pinned_memory(), dt_opencl_map_image(), dt_opencl_read_host_from_device(), dt_opencl_unmap_mem_object(), dt_opencl_write_host_to_device(), dt_print(), dt_iop_roi_t::height, IS_NULL_PTR, dt_iop_module_t::op, TRUE, and dt_iop_roi_t::width.

Referenced by _gpu_init_input(), dt_dev_pixelpipe_cache_restore_cl_buffer(), and pixelpipe_process_on_GPU().

◆ dt_dev_pixelpipe_cache_unref_hash()

◆ dt_dev_pixelpipe_cache_wrlock_entry()

◆ dt_pixel_cache_alloc()

void * dt_pixel_cache_alloc ( dt_dev_pixelpipe_cache_t cache,
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.

References _arena_alloc_with_defrag(), _log_arena_allocation_failure(), 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(), 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_data()

◆ dt_pixel_cache_entry_get_size()

size_t dt_pixel_cache_entry_get_size ( 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.

References dt_pixel_cache_entry_t::size.

Referenced by _lock_pipe_surface(), and _update_backbuf_cache_reference().

◆ dt_pixel_cache_new_entry()

◆ dt_pixelpipe_cache_alloc_align_cache_impl()

void * dt_pixelpipe_cache_alloc_align_cache_impl ( dt_dev_pixelpipe_cache_t cache,
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.

References _arena_alloc_with_defrag(), _free_space_to_alloc(), _log_arena_allocation_failure(), _non_thread_safe_cache_ref_count_entry(), dt_pixel_cache_entry_t::age, dt_dev_pixelpipe_cache_t::arena, dt_pixel_cache_entry_t::data, dt_cache_arena_free(), DT_CACHELINE_BYTES, dt_pixel_cache_new_entry(), dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), error(), dt_pixel_cache_entry_t::external_alloc, dt_dev_pixelpipe_cache_t::external_entries, FALSE, IS_NULL_PTR, dt_dev_pixelpipe_cache_t::lock, name, size, and TRUE.

Referenced by dt_drawlayer_cache_alloc_temp_buffer(), and dt_pixelpipe_cache_alloc_perthread_impl().

◆ dt_pixelpipe_cache_free_align_cache()

void dt_pixelpipe_cache_free_align_cache ( dt_dev_pixelpipe_cache_t 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.

References _non_thread_safe_cache_ref_count_entry(), _non_threadsafe_cache_get_entry(), dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), dt_pixel_cache_entry_t::external_alloc, dt_dev_pixelpipe_cache_t::external_entries, FALSE, dt_pixel_cache_entry_t::hash, IS_NULL_PTR, and dt_dev_pixelpipe_cache_t::lock.

Referenced by dt_drawlayer_cache_free_temp_buffer(), and dt_drawlayer_cache_patch_clear().

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

References dt_pixelpipe_cache_current_module.

Referenced by dt_dev_pixelpipe_process_rec().

Variable Documentation

◆ dt_pixelpipe_cache_current_module

__thread const char* dt_pixelpipe_cache_current_module = NULL
static

◆ garbage_collection

int garbage_collection = 0
static