Blender  V2.93
Classes | Macros | Typedefs | Functions | Variables
image_cache.c File Reference
#include <memory.h>
#include <stddef.h>
#include <time.h>
#include "MEM_guardedalloc.h"
#include "DNA_scene_types.h"
#include "DNA_sequence_types.h"
#include "DNA_space_types.h"
#include "IMB_colormanagement.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
#include "BLI_blenlib.h"
#include "BLI_endian_switch.h"
#include "BLI_fileops.h"
#include "BLI_fileops_types.h"
#include "BLI_ghash.h"
#include "BLI_listbase.h"
#include "BLI_mempool.h"
#include "BLI_path_util.h"
#include "BLI_threads.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_scene.h"
#include "SEQ_prefetch.h"
#include "SEQ_relations.h"
#include "SEQ_render.h"
#include "SEQ_sequencer.h"
#include "image_cache.h"
#include "prefetch.h"
#include "strip_time.h"

Go to the source code of this file.

Classes

struct  DiskCacheHeaderEntry
 
struct  DiskCacheHeader
 
struct  SeqDiskCache
 
struct  DiskCacheFile
 
struct  SeqCache
 
struct  SeqCacheItem
 
struct  SeqCacheKey
 

Macros

#define DCACHE_FNAME_FORMAT   "%d-%dx%d-%d%%(%d)-%d.dcf"
 
#define DCACHE_IMAGES_PER_FILE   100
 
#define DCACHE_CURRENT_VERSION   1
 
#define COLORSPACE_NAME_MAX   64 /* XXX: defined in imb intern */
 

Typedefs

typedef struct DiskCacheHeaderEntry DiskCacheHeaderEntry
 
typedef struct DiskCacheHeader DiskCacheHeader
 
typedef struct SeqDiskCache SeqDiskCache
 
typedef struct DiskCacheFile DiskCacheFile
 
typedef struct SeqCache SeqCache
 
typedef struct SeqCacheItem SeqCacheItem
 
typedef struct SeqCacheKey SeqCacheKey
 

Functions

static float seq_cache_timeline_frame_to_frame_index (Sequence *seq, float timeline_frame, int type)
 
static float seq_cache_frame_index_to_timeline_frame (Sequence *seq, float frame_index)
 
static char * seq_disk_cache_base_dir (void)
 
static int seq_disk_cache_compression_level (void)
 
static size_t seq_disk_cache_size_limit (void)
 
static bool seq_disk_cache_is_enabled (Main *bmain)
 
static DiskCacheFileseq_disk_cache_add_file_to_list (SeqDiskCache *disk_cache, const char *path)
 
static void seq_disk_cache_get_files (SeqDiskCache *disk_cache, char *path)
 
static DiskCacheFileseq_disk_cache_get_oldest_file (SeqDiskCache *disk_cache)
 
static void seq_disk_cache_delete_file (SeqDiskCache *disk_cache, DiskCacheFile *file)
 
static bool seq_disk_cache_enforce_limits (SeqDiskCache *disk_cache)
 
static DiskCacheFileseq_disk_cache_get_file_entry_by_path (SeqDiskCache *disk_cache, char *path)
 
static void seq_disk_cache_update_file (SeqDiskCache *disk_cache, char *path)
 
static void seq_disk_cache_get_project_dir (SeqDiskCache *disk_cache, char *path, size_t path_len)
 
static void seq_disk_cache_get_dir (SeqDiskCache *disk_cache, Scene *scene, Sequence *seq, char *path, size_t path_len)
 
static void seq_disk_cache_get_file_path (SeqDiskCache *disk_cache, SeqCacheKey *key, char *path, size_t path_len)
 
static void seq_disk_cache_create_version_file (char *path)
 
static void seq_disk_cache_handle_versioning (SeqDiskCache *disk_cache)
 
static void seq_disk_cache_delete_invalid_files (SeqDiskCache *disk_cache, Scene *scene, Sequence *seq, int invalidate_types, int range_start, int range_end)
 
static void seq_disk_cache_invalidate (Scene *scene, Sequence *seq, Sequence *seq_changed, int invalidate_types)
 
static size_t deflate_imbuf_to_file (ImBuf *ibuf, FILE *file, int level, DiskCacheHeaderEntry *header_entry)
 
static size_t inflate_file_to_imbuf (ImBuf *ibuf, FILE *file, DiskCacheHeaderEntry *header_entry)
 
static bool seq_disk_cache_read_header (FILE *file, DiskCacheHeader *header)
 
static size_t seq_disk_cache_write_header (FILE *file, DiskCacheHeader *header)
 
static int seq_disk_cache_add_header_entry (SeqCacheKey *key, ImBuf *ibuf, DiskCacheHeader *header)
 
static int seq_disk_cache_get_header_entry (SeqCacheKey *key, DiskCacheHeader *header)
 
static bool seq_disk_cache_write_file (SeqDiskCache *disk_cache, SeqCacheKey *key, ImBuf *ibuf)
 
static ImBufseq_disk_cache_read_file (SeqDiskCache *disk_cache, SeqCacheKey *key)
 
static bool seq_cmp_render_data (const SeqRenderData *a, const SeqRenderData *b)
 
static unsigned int seq_hash_render_data (const SeqRenderData *a)
 
static unsigned int seq_cache_hashhash (const void *key_)
 
static bool seq_cache_hashcmp (const void *a_, const void *b_)
 
static SeqCacheseq_cache_get_from_scene (Scene *scene)
 
static void seq_cache_lock (Scene *scene)
 
static void seq_cache_unlock (Scene *scene)
 
static size_t seq_cache_get_mem_total (void)
 
static void seq_cache_keyfree (void *val)
 
static void seq_cache_valfree (void *val)
 
static int get_stored_types_flag (Scene *scene, SeqCacheKey *key)
 
static void seq_cache_put_ex (Scene *scene, SeqCacheKey *key, ImBuf *ibuf)
 
static ImBufseq_cache_get_ex (SeqCache *cache, SeqCacheKey *key)
 
static void seq_cache_relink_keys (SeqCacheKey *link_next, SeqCacheKey *link_prev)
 
static SeqCacheKeyseq_cache_choose_key (Scene *scene, SeqCacheKey *lkey, SeqCacheKey *rkey)
 
static void seq_cache_recycle_linked (Scene *scene, SeqCacheKey *base)
 
static SeqCacheKeyseq_cache_get_item_for_removal (Scene *scene)
 
bool seq_cache_recycle_item (Scene *scene)
 
static void seq_cache_set_temp_cache_linked (Scene *scene, SeqCacheKey *base)
 
static void seq_disk_cache_create (Main *bmain, Scene *scene)
 
static void seq_cache_create (Main *bmain, Scene *scene)
 
static void seq_cache_populate_key (SeqCacheKey *key, const SeqRenderData *context, Sequence *seq, const float timeline_frame, const int type)
 
static SeqCacheKeyseq_cache_allocate_key (SeqCache *cache, const SeqRenderData *context, Sequence *seq, const float timeline_frame, const int type)
 
void seq_cache_free_temp_cache (Scene *scene, short id, int timeline_frame)
 
void seq_cache_destruct (Scene *scene)
 
void seq_cache_cleanup_all (Main *bmain)
 
void SEQ_cache_cleanup (Scene *scene)
 
void seq_cache_cleanup_sequence (Scene *scene, Sequence *seq, Sequence *seq_changed, int invalidate_types, bool force_seq_changed_range)
 
struct ImBufseq_cache_get (const SeqRenderData *context, Sequence *seq, float timeline_frame, int type)
 
bool seq_cache_put_if_possible (const SeqRenderData *context, Sequence *seq, float timeline_frame, int type, ImBuf *ibuf)
 
void seq_cache_put (const SeqRenderData *context, Sequence *seq, float timeline_frame, int type, ImBuf *i)
 
void SEQ_cache_iterate (struct Scene *scene, void *userdata, bool callback_init(void *userdata, size_t item_count), bool callback_iter(void *userdata, struct Sequence *seq, int timeline_frame, int cache_type))
 
bool seq_cache_is_full (void)
 

Variables

static ThreadMutex cache_create_lock = BLI_MUTEX_INITIALIZER
 

Macro Definition Documentation

◆ COLORSPACE_NAME_MAX

#define COLORSPACE_NAME_MAX   64 /* XXX: defined in imb intern */

Definition at line 106 of file image_cache.c.

◆ DCACHE_CURRENT_VERSION

#define DCACHE_CURRENT_VERSION   1

Definition at line 105 of file image_cache.c.

◆ DCACHE_FNAME_FORMAT

#define DCACHE_FNAME_FORMAT   "%d-%dx%d-%d%%(%d)-%d.dcf"

Sequencer Cache Design Notes

Function: All images created during rendering are added to cache, even if the cache is already full. This is because:

  • one image may be needed multiple times during rendering.
  • keeping the last rendered frame allows us for faster re-render when user edits strip in stack
  • we can decide if we keep frame only when it's completely rendered. Otherwise we risk having "holes" in the cache, which can be annoying If the cache is full all entries for pending frame will have is_temp_cache set.

Linking: We use links to reduce number of iterations over entries needed to manage cache. Entries are linked in order as they are put into cache. Only permanent (is_temp_cache = 0) cache entries are linked. Putting SEQ_CACHE_STORE_FINAL_OUT will reset linking

Only entire frame can be freed to release resources for new entries (recycling). Once again, this is to reduce number of iterations, but also more controllable than removing entries one by one in reverse order to their creation.

User can exclude caching of some images. Such entries will have is_temp_cache set.

Disk Cache Design Notes

Disk cache uses directory specified in user preferences For each cached non-temp image, image data and supplementary info are written to HDD. Multiple(DCACHE_IMAGES_PER_FILE) images share the same file. Each of these files contains header DiskCacheHeader followed by image data. Zlib compression with user definable level can be used to compress image data(per image) Images are written in order in which they are rendered. Overwriting of individual entry is not possible. Stored images are deleted by invalidation, or when size of all files exceeds maximum size specified in user preferences. To distinguish 2 blend files with same name, scene->ed->disk_cache_timestamp is used as UID. Blend file can still be copied manually which may cause conflict.

Definition at line 103 of file image_cache.c.

◆ DCACHE_IMAGES_PER_FILE

#define DCACHE_IMAGES_PER_FILE   100

Definition at line 104 of file image_cache.c.

Typedef Documentation

◆ DiskCacheFile

typedef struct DiskCacheFile DiskCacheFile

◆ DiskCacheHeader

◆ DiskCacheHeaderEntry

◆ SeqCache

typedef struct SeqCache SeqCache

◆ SeqCacheItem

typedef struct SeqCacheItem SeqCacheItem

◆ SeqCacheKey

typedef struct SeqCacheKey SeqCacheKey

◆ SeqDiskCache

typedef struct SeqDiskCache SeqDiskCache

Function Documentation

◆ deflate_imbuf_to_file()

static size_t deflate_imbuf_to_file ( ImBuf ibuf,
FILE *  file,
int  level,
DiskCacheHeaderEntry header_entry 
)
static

◆ get_stored_types_flag()

static int get_stored_types_flag ( Scene scene,
SeqCacheKey key 
)
static

◆ inflate_file_to_imbuf()

static size_t inflate_file_to_imbuf ( ImBuf ibuf,
FILE *  file,
DiskCacheHeaderEntry header_entry 
)
static

◆ seq_cache_allocate_key()

static SeqCacheKey* seq_cache_allocate_key ( SeqCache cache,
const SeqRenderData context,
Sequence seq,
const float  timeline_frame,
const int  type 
)
static

◆ seq_cache_choose_key()

static SeqCacheKey* seq_cache_choose_key ( Scene scene,
SeqCacheKey lkey,
SeqCacheKey rkey 
)
static

◆ SEQ_cache_cleanup()

void SEQ_cache_cleanup ( Scene scene)

◆ seq_cache_cleanup_all()

void seq_cache_cleanup_all ( Main bmain)

Definition at line 1245 of file image_cache.c.

References ListBase::first, Scene::id, ID::next, NULL, scene, Main::scenes, and SEQ_cache_cleanup().

◆ seq_cache_cleanup_sequence()

void seq_cache_cleanup_sequence ( Scene scene,
Sequence seq,
Sequence seq_changed,
int  invalidate_types,
bool  force_seq_changed_range 
)

◆ seq_cache_create()

static void seq_cache_create ( Main bmain,
Scene scene 
)
static

◆ seq_cache_destruct()

void seq_cache_destruct ( Scene scene)

◆ seq_cache_frame_index_to_timeline_frame()

static float seq_cache_frame_index_to_timeline_frame ( Sequence seq,
float  frame_index 
)
static

Definition at line 776 of file image_cache.c.

References Sequence::start.

Referenced by seq_disk_cache_delete_invalid_files().

◆ seq_cache_free_temp_cache()

void seq_cache_free_temp_cache ( Scene scene,
short  id,
int  timeline_frame 
)

◆ seq_cache_get()

struct ImBuf* seq_cache_get ( const SeqRenderData context,
Sequence seq,
float  timeline_frame,
int  type 
)

◆ seq_cache_get_ex()

static ImBuf* seq_cache_get_ex ( SeqCache cache,
SeqCacheKey key 
)
static

Definition at line 886 of file image_cache.c.

References BLI_ghash_lookup(), SeqCache::hash, SeqCacheItem::ibuf, IMB_refImBuf(), and NULL.

Referenced by seq_cache_get().

◆ seq_cache_get_from_scene()

static SeqCache* seq_cache_get_from_scene ( Scene scene)
static

◆ seq_cache_get_item_for_removal()

static SeqCacheKey* seq_cache_get_item_for_removal ( Scene scene)
static

◆ seq_cache_get_mem_total()

static size_t seq_cache_get_mem_total ( void  )
static

Definition at line 808 of file image_cache.c.

Referenced by seq_cache_is_full().

◆ seq_cache_hashcmp()

static bool seq_cache_hashcmp ( const void *  a_,
const void *  b_ 
)
static

◆ seq_cache_hashhash()

static unsigned int seq_cache_hashhash ( const void *  key_)
static

◆ seq_cache_is_full()

bool seq_cache_is_full ( void  )

◆ SEQ_cache_iterate()

void SEQ_cache_iterate ( struct Scene scene,
void *  userdata,
bool   callback_initvoid *userdata, size_t item_count,
bool   callback_itervoid *userdata, struct Sequence *seq, int timeline_frame, int cache_type 
)

◆ seq_cache_keyfree()

static void seq_cache_keyfree ( void *  val)
static

◆ seq_cache_lock()

static void seq_cache_lock ( Scene scene)
static

◆ seq_cache_populate_key()

static void seq_cache_populate_key ( SeqCacheKey key,
const SeqRenderData context,
Sequence seq,
const float  timeline_frame,
const int  type 
)
static

◆ seq_cache_put()

void seq_cache_put ( const SeqRenderData context,
Sequence seq,
float  timeline_frame,
int  type,
ImBuf i 
)

◆ seq_cache_put_ex()

static void seq_cache_put_ex ( Scene scene,
SeqCacheKey key,
ImBuf ibuf 
)
static

◆ seq_cache_put_if_possible()

bool seq_cache_put_if_possible ( const SeqRenderData context,
Sequence seq,
float  timeline_frame,
int  type,
ImBuf ibuf 
)

◆ seq_cache_recycle_item()

bool seq_cache_recycle_item ( Scene scene)

◆ seq_cache_recycle_linked()

static void seq_cache_recycle_linked ( Scene scene,
SeqCacheKey base 
)
static

◆ seq_cache_relink_keys()

static void seq_cache_relink_keys ( SeqCacheKey link_next,
SeqCacheKey link_prev 
)
static

Definition at line 899 of file image_cache.c.

References SeqCacheKey::link_next, and SeqCacheKey::link_prev.

Referenced by seq_cache_cleanup_sequence().

◆ seq_cache_set_temp_cache_linked()

static void seq_cache_set_temp_cache_linked ( Scene scene,
SeqCacheKey base 
)
static

◆ seq_cache_timeline_frame_to_frame_index()

static float seq_cache_timeline_frame_to_frame_index ( Sequence seq,
float  timeline_frame,
int  type 
)
static

◆ seq_cache_unlock()

static void seq_cache_unlock ( Scene scene)
static

◆ seq_cache_valfree()

static void seq_cache_valfree ( void *  val)
static

◆ seq_cmp_render_data()

static bool seq_cmp_render_data ( const SeqRenderData a,
const SeqRenderData b 
)
static

◆ seq_disk_cache_add_file_to_list()

static DiskCacheFile* seq_disk_cache_add_file_to_list ( SeqDiskCache disk_cache,
const char *  path 
)
static

◆ seq_disk_cache_add_header_entry()

static int seq_disk_cache_add_header_entry ( SeqCacheKey key,
ImBuf ibuf,
DiskCacheHeader header 
)
static

◆ seq_disk_cache_base_dir()

static char* seq_disk_cache_base_dir ( void  )
static

◆ seq_disk_cache_compression_level()

static int seq_disk_cache_compression_level ( void  )
static

◆ seq_disk_cache_create()

static void seq_disk_cache_create ( Main bmain,
Scene scene 
)
static

◆ seq_disk_cache_create_version_file()

static void seq_disk_cache_create_version_file ( char *  path)
static

◆ seq_disk_cache_delete_file()

static void seq_disk_cache_delete_file ( SeqDiskCache disk_cache,
DiskCacheFile file 
)
static

◆ seq_disk_cache_delete_invalid_files()

static void seq_disk_cache_delete_invalid_files ( SeqDiskCache disk_cache,
Scene scene,
Sequence seq,
int  invalidate_types,
int  range_start,
int  range_end 
)
static

◆ seq_disk_cache_enforce_limits()

static bool seq_disk_cache_enforce_limits ( SeqDiskCache disk_cache)
static

◆ seq_disk_cache_get_dir()

static void seq_disk_cache_get_dir ( SeqDiskCache disk_cache,
Scene scene,
Sequence seq,
char *  path,
size_t  path_len 
)
static

◆ seq_disk_cache_get_file_entry_by_path()

static DiskCacheFile* seq_disk_cache_get_file_entry_by_path ( SeqDiskCache disk_cache,
char *  path 
)
static

◆ seq_disk_cache_get_file_path()

static void seq_disk_cache_get_file_path ( SeqDiskCache disk_cache,
SeqCacheKey key,
char *  path,
size_t  path_len 
)
static

◆ seq_disk_cache_get_files()

static void seq_disk_cache_get_files ( SeqDiskCache disk_cache,
char *  path 
)
static

◆ seq_disk_cache_get_header_entry()

static int seq_disk_cache_get_header_entry ( SeqCacheKey key,
DiskCacheHeader header 
)
static

◆ seq_disk_cache_get_oldest_file()

static DiskCacheFile* seq_disk_cache_get_oldest_file ( SeqDiskCache disk_cache)
static

◆ seq_disk_cache_get_project_dir()

static void seq_disk_cache_get_project_dir ( SeqDiskCache disk_cache,
char *  path,
size_t  path_len 
)
static

◆ seq_disk_cache_handle_versioning()

static void seq_disk_cache_handle_versioning ( SeqDiskCache disk_cache)
static

◆ seq_disk_cache_invalidate()

static void seq_disk_cache_invalidate ( Scene scene,
Sequence seq,
Sequence seq_changed,
int  invalidate_types 
)
static

◆ seq_disk_cache_is_enabled()

static bool seq_disk_cache_is_enabled ( Main bmain)
static

Definition at line 204 of file image_cache.c.

References Main::name, and SEQ_CACHE_DISK_CACHE_ENABLE.

Referenced by seq_cache_cleanup_sequence(), seq_cache_get(), and seq_cache_put().

◆ seq_disk_cache_read_file()

static ImBuf* seq_disk_cache_read_file ( SeqDiskCache disk_cache,
SeqCacheKey key 
)
static

◆ seq_disk_cache_read_header()

static bool seq_disk_cache_read_header ( FILE *  file,
DiskCacheHeader header 
)
static

◆ seq_disk_cache_size_limit()

static size_t seq_disk_cache_size_limit ( void  )
static

Definition at line 199 of file image_cache.c.

Referenced by seq_disk_cache_enforce_limits().

◆ seq_disk_cache_update_file()

static void seq_disk_cache_update_file ( SeqDiskCache disk_cache,
char *  path 
)
static

◆ seq_disk_cache_write_file()

static bool seq_disk_cache_write_file ( SeqDiskCache disk_cache,
SeqCacheKey key,
ImBuf ibuf 
)
static

◆ seq_disk_cache_write_header()

static size_t seq_disk_cache_write_header ( FILE *  file,
DiskCacheHeader header 
)
static

Definition at line 541 of file image_cache.c.

References file.

Referenced by seq_disk_cache_write_file().

◆ seq_hash_render_data()

static unsigned int seq_hash_render_data ( const SeqRenderData a)
static

Definition at line 729 of file image_cache.c.

References Freestyle::a.

Referenced by seq_cache_hashhash().

Variable Documentation

◆ cache_create_lock

ThreadMutex cache_create_lock = BLI_MUTEX_INITIALIZER
static

Definition at line 174 of file image_cache.c.

Referenced by seq_cache_create(), and seq_disk_cache_create().