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 "common/memory_arena.h"
#include "common/atomic.h"
#include "develop/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_dev_pixelpipe_cache_t
 
struct  dt_pixel_cache_entry_t
 

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_entry_t dt_pixel_cache_entry_t
 

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

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)
 
const char * dt_pixelpipe_cache_set_current_module (const char *module)
 Set the current module name for cache diagnostics (thread-local).
 
struct 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.
 
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.
 
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 struct dt_pixel_cache_entry_t *reuse_hint, void **data, struct dt_pixel_cache_entry_t **entry)
 Acquire a writable cache line for module output.
 
voiddt_pixel_cache_clmem_get (struct dt_pixel_cache_entry_t *entry, void *host_ptr, int devid, int width, int height, int bpp, int flags)
 
voiddt_pixel_cache_clmem_ref (struct dt_pixel_cache_entry_t *entry, void *host_ptr, int devid, int width, int height, int bpp, int flags)
 
void dt_pixel_cache_clmem_unref (struct dt_pixel_cache_entry_t *entry, void *mem)
 
void dt_pixel_cache_clmem_put (struct dt_pixel_cache_entry_t *entry, void *host_ptr, int devid, int width, int height, int bpp, int flags, void *mem)
 
void dt_pixel_cache_clmem_remove (struct dt_pixel_cache_entry_t *entry, void *mem)
 
void dt_pixel_cache_clmem_flush (struct dt_pixel_cache_entry_t *entry)
 
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.
 
voiddt_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.
 
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().
 
void 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.
 
void dt_dev_pixelpipe_cache_resync_host_pinned_image (dt_dev_pixelpipe_cache_t *cache, void *host_ptr, struct dt_pixel_cache_entry_t *entry_hint, int devid)
 Resynchronize cached pinned OpenCL images from an authoritative host buffer.
 
struct 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.
 
voiddt_pixel_cache_entry_get_data (struct dt_pixel_cache_entry_t *entry)
 
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.
 
voiddt_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.
 
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.
 
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.
 
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.
 
void dt_dev_pixelpipe_cache_flush_clmem (dt_dev_pixelpipe_cache_t *cache, const int devid, void *keep)
 Release cached OpenCL buffers for a device (-1 for all).
 
int dt_dev_pixelpipe_cache_flush_old (dt_dev_pixelpipe_cache_t *cache)
 Free cache entries older than 3 min, that are not locked and have been used 3 times or less.
 
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.
 
void dt_dev_pixelpipe_cache_print (dt_dev_pixelpipe_cache_t *cache)
 
int dt_dev_pixel_pipe_cache_remove_lru (dt_dev_pixelpipe_cache_t *cache)
 
void dt_dev_pixelpipe_cache_ref_count_entry (dt_dev_pixelpipe_cache_t *cache, gboolean lock, struct dt_pixel_cache_entry_t *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, struct dt_pixel_cache_entry_t *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, struct dt_pixel_cache_entry_t *entry)
 Lock or release the read lock on the entry.
 
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.
 
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 will not check reference count nor read/write locks, so it has to happen in the thread that created the entry, flagged it and owns it. Ensure your hashes are truly unique and not shared between pipelines to ensure another thread will not free this or that another thread ends up using it.
 
voiddt_dev_pixelpipe_cache_get_read_only (dt_dev_pixelpipe_cache_t *cache, const uint64_t hash, struct dt_pixel_cache_entry_t **cache_entry)
 Find the existing cache entry linked to hash if any, lock it in read mode and increase its ref_count all at once.
 
void dt_dev_pixelpipe_cache_close_read_only (dt_dev_pixelpipe_cache_t *cache, const uint64_t hash, struct dt_pixel_cache_entry_t *cache_entry)
 Decrease the ref_count and release the read lock over cache_entry all at once.
 
voiddt_dev_pixelpipe_cache_get_ref_unlocked (dt_dev_pixelpipe_cache_t *cache, const uint64_t hash, struct dt_pixel_cache_entry_t **cache_entry)
 Find an existing cache entry, synchronize once with a short read lock, then keep only a refcount (no long-lived read lock).
 
void dt_dev_pixelpipe_cache_unref_unlocked (dt_dev_pixelpipe_cache_t *cache, const uint64_t hash, struct dt_pixel_cache_entry_t *cache_entry)
 Decrease the refcount of an entry previously acquired with the transient realtime getter above.
 
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, 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.
 

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.

Macro Definition Documentation

◆ DT_PIXELPIPE_CACHE_HASH_INVALID

#define DT_PIXELPIPE_CACHE_HASH_INVALID   ((uint64_t)-1)

Typedef Documentation

◆ dt_dev_pixelpipe_cache_t

◆ dt_dev_pixelpipe_cache_writable_status_t

◆ dt_pixel_cache_entry_t

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 

Function Documentation

◆ 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_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 will not check reference count nor read/write locks, so it has to happen in the thread that created the entry, flagged it and owns it. Ensure your hashes are truly unique and not shared between pipelines to ensure another thread will not free this or that another thread ends up using it.

Parameters
cache

References dt_pixel_cache_entry_t::auto_destroy, dt_pixel_cache_message(), dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), dt_dev_pixelpipe_cache_t::entries, FALSE, dt_pixel_cache_entry_t::hash, dt_dev_pixelpipe_cache_t::lock, and TRUE.

Referenced by _abort_module_shutdown_cleanup(), and dt_dev_pixelpipe_process_rec().

◆ dt_dev_pixelpipe_cache_cleanup()

◆ dt_dev_pixelpipe_cache_close_read_only()

void dt_dev_pixelpipe_cache_close_read_only ( dt_dev_pixelpipe_cache_t cache,
const uint64_t  hash,
struct dt_pixel_cache_entry_t cache_entry 
)

Decrease the ref_count and release the read lock over cache_entry all at once.

Parameters
cache
hash
cache_entry

References dt_dev_pixelpipe_cache_rdlock_entry(), dt_dev_pixelpipe_cache_ref_count_entry(), and FALSE.

Referenced by _lib_navigation_draw_callback(), _pixelpipe_pick_from_image(), _process_histogram(), _process_vectorscope(), and _process_waveform().

◆ 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 dt_pixel_cache_entry_t::auto_destroy, dt_pixel_cache_message(), dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), dt_dev_pixelpipe_cache_t::lock, and TRUE.

Referenced by _abort_module_shutdown_cleanup(), _init_base_buffer(), 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,
void keep 
)

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.

Parameters
keepOpenCL buffer to keep. Typically, you want to keep the input if you are trying to make room for the output.

References _cache_entry_clmem_flush_device(), dt_opencl_events_wait_for(), dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), dt_dev_pixelpipe_cache_t::entries, key, dt_dev_pixelpipe_cache_t::lock, and value.

Referenced by dt_dev_pixelpipe_cleanup(), and leave().

◆ dt_dev_pixelpipe_cache_flush_host_pinned_image()

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

References void().

Referenced by _rekey_shared_base_patch(), dt_dev_pixelpipe_gpu_flush_host_pinned_images(), dt_drawlayer_cache_flush_process_patch_to_base(), dt_drawlayer_cache_populate_process_patch_from_base(), dt_drawlayer_process_state_publish_locked(), and dt_drawlayer_worker_replay_finished_stroke_to_base_patch().

◆ dt_dev_pixelpipe_cache_flush_old()

int dt_dev_pixelpipe_cache_flush_old ( dt_dev_pixelpipe_cache_t cache)

Free cache entries older than 3 min, that are not locked and have been used 3 times or less.

Parameters
cache

References _for_each_remove_old(), dt_pthread_mutex_trylock(), dt_pthread_mutex_unlock(), dt_dev_pixelpipe_cache_t::entries, and dt_dev_pixelpipe_cache_t::lock.

Referenced by dt_dev_pixelpipe_cache_init().

◆ 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(), _pixelpipe_cache_create_entry_locked(), _pixelpipe_cache_finalize_entry(), dt_pixel_cache_entry_t::auto_destroy, dt_pixel_cache_entry_t::data, DT_DEBUG_CACHE, dt_dev_pixelpipe_cache_wrlock_entry(), dt_pixel_cache_alloc(), dt_pixel_cache_message(), 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, dt_dev_pixelpipe_cache_t::lock, name, dt_dev_pixelpipe_cache_t::queries, size, and TRUE.

Referenced by _init_base_buffer(), dt_drawlayer_cache_patch_alloc_shared(), and toneeq_process().

◆ dt_dev_pixelpipe_cache_get_entry()

struct 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(), _refresh_global_histogram_backbuf(), dt_dev_pixelpipe_cleanup(), and dt_dev_pixelpipe_process_rec().

◆ 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 bpp, FALSE, flags, height, void(), and width.

◆ dt_dev_pixelpipe_cache_get_read_only()

void * dt_dev_pixelpipe_cache_get_read_only ( dt_dev_pixelpipe_cache_t cache,
const uint64_t  hash,
struct dt_pixel_cache_entry_t **  cache_entry 
)

Find the existing cache entry linked to hash if any, lock it in read mode and increase its ref_count all at once.

Parameters
cache
hash
cache_entryFound cache entry if any, this is written by the function
pipePixelpipe to recompute if we fail to find the cacheline associated to the hash
Returns
void* Data buffer associated with the cache entry, or NULL.

References DT_CACHELINE_BYTES, dt_dev_pixelpipe_cache_peek(), dt_dev_pixelpipe_cache_ref_count_entry(), DT_PIXELPIPE_CACHE_HASH_INVALID, dt_pthread_rwlock_tryrdlock, and TRUE.

Referenced by _lib_navigation_draw_callback(), _pixelpipe_pick_from_image(), _process_histogram(), _process_vectorscope(), and _process_waveform().

◆ dt_dev_pixelpipe_cache_get_ref_unlocked()

void * dt_dev_pixelpipe_cache_get_ref_unlocked ( dt_dev_pixelpipe_cache_t cache,
const uint64_t  hash,
struct dt_pixel_cache_entry_t **  cache_entry 
)

Find an existing cache entry, synchronize once with a short read lock, then keep only a refcount (no long-lived read lock).

Intended for best-effort realtime display paths where pointer stability is preferred over lock contention:

  • we attempt tryrdlock + immediate unlock as a synchronization point,
  • then keep the entry alive via refcount only.
  • if tryrdlock fails (writer active), we still return the refcounted pointer in best-effort mode to avoid stalling/dropping realtime redraws.

Consumers must tolerate concurrent writes after acquisition.

Parameters
cache
hash
cache_entryFound cache entry if any, written by the function.
Returns
void* Data buffer associated with the cache entry, or NULL.

References DT_CACHELINE_BYTES, dt_dev_pixelpipe_cache_peek(), dt_dev_pixelpipe_cache_ref_count_entry(), DT_PIXELPIPE_CACHE_HASH_INVALID, dt_pthread_rwlock_tryrdlock, dt_pthread_rwlock_unlock, and TRUE.

Referenced by _lock_pipe_surface().

◆ dt_dev_pixelpipe_cache_get_writable()

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 struct dt_pixel_cache_entry_t reuse_hint,
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,
  • 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,
  • else, a new cacheline is created.

In all successful cases:

  • 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 write lock and refcount 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.
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()

◆ 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 cl_mem_output != NULL, 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_clear_lookup_outputs(), _cache_entry_has_device_payload(), _cache_entry_has_host_payload_ptr(), _cache_lookup_existing(), _cache_remove_invalid_exact_hit(), _cache_try_restore_device_payload(), _cache_try_restore_host_payload(), _trace_exact_hit(), dt_pixel_cache_entry_t::auto_destroy, dt_pixel_cache_entry_get_data(), DT_PIXELPIPE_CACHE_HASH_INVALID, dt_pthread_rwlock_tryrdlock, dt_pthread_rwlock_unlock, FALSE, dt_pixel_cache_entry_t::lock, and TRUE.

Referenced by _lock_pipe_surface(), _sample_picker_from_cache(), _sync_private_buffer_from_preview_cache(), dt_dev_pixelpipe_cache_get_read_only(), dt_dev_pixelpipe_cache_get_ref_unlocked(), dt_dev_pixelpipe_process(), dt_dev_pixelpipe_process_rec(), dt_dev_refresh_module_histogram(), dt_imageio_export_with_flags(), and gui_focus().

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

References void().

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

struct 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(), dt_dev_pixelpipe_cache_t::lock, and TRUE.

Referenced by _ensure_external_patch_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, c, 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_CACHE, dt_pixel_cache_clmem_flush(), dt_print(), dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), dt_dev_pixelpipe_cache_t::entries, dt_pixel_cache_entry_t::hash, 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_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(), _cache_remove_invalid_exact_hit(), _do_get_structure_auto(), _do_get_structure_lines(), _do_get_structure_quad(), dt_dev_pixelpipe_cleanup(), dt_dev_pixelpipe_process_rec(), and toneeq_process().

◆ 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_has_host_payload_ptr(), _cache_try_restore_host_payload(), dt_pixel_cache_entry_get_data(), FALSE, and TRUE.

◆ dt_dev_pixelpipe_cache_resync_host_pinned_image()

void dt_dev_pixelpipe_cache_resync_host_pinned_image ( dt_dev_pixelpipe_cache_t cache,
void host_ptr,
struct dt_pixel_cache_entry_t entry_hint,
int  devid 
)

Resynchronize cached pinned OpenCL images from an authoritative host buffer.

This is meant for host-backed cachelines that stay valid but are rewritten in place by the CPU. Unlike dt_dev_pixelpipe_cache_flush_host_pinned_image(), this preserves reusable pinned CL_MEM_USE_HOST_PTR images when possible by pushing current host contents back to the cached OpenCL image objects. Any cached image that cannot be synchronized is dropped individually.

Parameters
cachePixelpipe cache.
host_ptrHost-backed image data.
entry_hintOptional owning cache entry for regular cache lines, or NULL.
devidDevice id to resynchronize, or -1 for all cached devices for that host buffer.

References void().

◆ dt_dev_pixelpipe_cache_unref_hash()

◆ dt_dev_pixelpipe_cache_unref_unlocked()

void dt_dev_pixelpipe_cache_unref_unlocked ( dt_dev_pixelpipe_cache_t cache,
const uint64_t  hash,
struct dt_pixel_cache_entry_t cache_entry 
)

Decrease the refcount of an entry previously acquired with the transient realtime getter above.

References dt_dev_pixelpipe_cache_ref_count_entry(), and FALSE.

Referenced by _lock_pipe_surface(), and _release_locked_surface().

◆ 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, dt_pixel_cache_entry_t::name, and dt_pixel_cache_entry_t::size.

Referenced by _cache_entry_materialize_host_data(), dt_dev_pixelpipe_cache_get(), dt_dev_pixelpipe_cache_get_writable(), dt_pixel_cache_new_entry(), and pixelpipe_process_on_CPU().

◆ dt_pixel_cache_clmem_flush()

◆ dt_pixel_cache_clmem_get()

void * dt_pixel_cache_clmem_get ( struct dt_pixel_cache_entry_t entry,
void host_ptr,
int  devid,
int  width,
int  height,
int  bpp,
int  flags 
)

◆ dt_pixel_cache_clmem_put()

void dt_pixel_cache_clmem_put ( struct dt_pixel_cache_entry_t entry,
void host_ptr,
int  devid,
int  width,
int  height,
int  bpp,
int  flags,
void mem 
)

◆ dt_pixel_cache_clmem_ref()

void * dt_pixel_cache_clmem_ref ( struct dt_pixel_cache_entry_t entry,
void host_ptr,
int  devid,
int  width,
int  height,
int  bpp,
int  flags 
)

◆ dt_pixel_cache_clmem_remove()

◆ dt_pixel_cache_clmem_unref()

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

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

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