[go: up one dir, main page]

Skip to content

Cache

During rendering, images are stored in the cache to allow for faster redrawing when they are viewed repeatedly. Images are stored at various stages of processing, so this is also beneficial when tweaking properties of strips. Cache is also used for storage when prefetching is enabled.

RAM is normally used for storage, but disk cache is implemented to allow storage with greater capacity at expense of performance. Disk cache is designed to be extension of RAM cache on implementation level as well.

Image caching can be configured globally or per strip with developer extras enabled. It is also possible to enable cache overlay in timeline(view->cache menu) to visualize cached(RAM only) images in time and per strip. This is useful for debugging not only cache but also to ensure consistency when doing rendering performance tests.

Stages stored in cache:

  • Raw images: SEQ_CACHE_STORE_RAW.
  • Peprocessed images: SEQ_CACHE_STORE_PREPROCESSED.
  • Composited (2 strips blended together) images: SEQ_CACHE_STORE_COMPOSITE.
  • Final images (last blended image): SEQ_CACHE_STORE_FINAL_OUT. This image is copy of SEQ_CACHE_STORE_COMPOSITE stage and takes no additional memory to be stored.

These are all stages in which image can be changed, however change in lower level will influence all subsequent images. This is handled on 2 levels: By cache invalidation functions, which traverse strips and invalidate(delete) images of dependant strips. Cache also links images within each frame, which helps with invalidation, but it should not be necessary.

RAM cache design

Sequencer cache was originally using MovieCache, which works well with single strip, but it is quite limited otherwise. Main limitation for sequencer is memory usage limiting mechanism, which does free items on simple criteria like their age or distance from current frame. In sequencer however, there are more items that meet this condition and random items are freed. To further complicate this situation, not all images have same size in memory, which means that sometimes image can fail to be cached resulting in uneven caching with random images missing.

This is resolved by 2 changes:

  • Memory limit is not strictly obeyed. All images created during rendering are added to cache, even if the cache is already full. Only before caching SEQ_CACHE_STORE_FINAL_OUT, memory is freed.
  • Cached images for each frame are linked, which makes it possible to free them all at once, even if some of strips use speed effect which causes rendering of different frame number.

To conserve memory usage, not all cached stages should be stored for longer term. Currently SEQ_CACHE_STORE_PREPROCESSED and SEQ_CACHE_STORE_COMPOSITE are marked as temporary, which means they will be freed when next frame is rendered. This still allows these stages to be useful when tweaking strip property and frame does not change for example.

Another limitation was introduction of prefetching system, which works by filling RAM cache as much as possible in advance of current frame. For this to work reliably, change in image freeing priority must change from furthest cached frame to "ideally leftmost cached frame outside of prefetching area, otherwise rightmost frame outside of prefetching area".

Thumbnail cache

Cache for the strip (movie/image) thumbnails is separate from the other strip caches, since usage patterns of it are quite different.

The cache key is composed of:

  • Media file path. If multiple strips use the same input file, they will share cache entries.
  • Frame index within media file. An image strip that spans several timeline frames will have just one thumbnail cache entry.
  • Extra data like stream index for multi-stream videos.

The thumbnail cache interface is in SEQ_thumbnail_cache.hh and implementation in thumbnail_cache.cc.

Cache capacity is fixed at maximum 5000 thumbnails, at up to 256 pixels (on the longer axis) thumbnail image size. Several background threads are used to process the incoming cache requests. For a thumbnail request which has no entry in the cache yet, closest available cached frame of that media file will be returned, until the thumbnail is loaded.

Disk cache design

Disk cache is extension of RAM cache. Storage is configured in user preferences.

Main considerations for disk cache:

  • Images are stored until invalidated or removed due to disk space limits. They do not delete themselves after the file is closed.
  • Disk cache is never written for files that have not been saved at least once.
  • Multiple images are stored in 1 file to reduce cold read delays.
  • It must be possible to write images in random order, because rendering is not always sequential.
  • 2 blend files should never use same disk cache path.
  • It should support most features as RAM cache, for example float images. Images must be recovered without any quality loss.

To write images at random order, each cache file has header that maps file contents. This way file can always be appended.

To ensure maximum possible integrity of cache, file name does contain values used by RAM cache to calculate hash, but these values are human readable. Path to cache files consists of blend file name, scene name and RAM cache creation timestamp and strip name. Example of typical path: untitled.blend_seq_cache/SCScene-1638169261/SQtime.002/8-1920x1080-99%(0)-1.dcf

To future-proof the design, versioning system is implemented. Each blend file cache directory has cache_version file. If version is not matched, all files in cache directory are removed.

Disk cache does support image compression with standard compression algorithms. During testing, these seems to be more effective than image codecs, especially lossless ones.

To avoid unnecessary disk IO, cache directory structure is traversed and DiskCacheFile structure representing each file is stored in RAM. Every new cache file that is created is stored in RAM as well. This helps mainly when cache files are invalidated, so whole tree does not have to be traversed possibly during rendering.