Blender V4.3
disk_cache.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2021 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include <cstddef>
10#include <ctime>
11#include <memory.h>
12
13#include "MEM_guardedalloc.h"
14
15#include "DNA_scene_types.h"
16#include "DNA_sequence_types.h"
17
19#include "IMB_imbuf.hh"
20#include "IMB_imbuf_types.hh"
21
22#include "BLI_blenlib.h"
23#include "BLI_endian_defines.h"
24#include "BLI_endian_switch.h"
25#include "BLI_fileops.h"
26#include "BLI_fileops_types.h"
27#include "BLI_listbase.h"
28#include "BLI_path_utils.hh"
29#include "BLI_threads.h"
30
31#include "BKE_main.hh"
32
33#include "SEQ_render.hh"
34#include "SEQ_time.hh"
35
36#include "disk_cache.hh"
37#include "image_cache.hh"
38
56/* Format string:
57 * `<cache type>-<resolution X>x<resolution Y>-<rendersize>%(<view_id>)-<frame no>.dcf`. */
58#define DCACHE_FNAME_FORMAT "%d-%dx%d-%d%%(%d)-%d.dcf"
59#define DCACHE_IMAGES_PER_FILE 100
60#define DCACHE_CURRENT_VERSION 2
61#define COLORSPACE_NAME_MAX 64 /* XXX: defined in IMB intern. */
62
71
75
83
97
99
100static const char *seq_disk_cache_base_dir()
101{
102 return U.sequencer_disk_cache_dir;
103}
104
106{
107 switch (U.sequencer_disk_cache_compression) {
109 return 0;
111 return 1;
113 return 9;
114 }
115
116 return U.sequencer_disk_cache_compression;
117}
118
120{
121 return size_t(U.sequencer_disk_cache_size_limit) * (1024 * 1024 * 1024);
122}
123
125{
126 return (U.sequencer_disk_cache_dir[0] != '\0' && U.sequencer_disk_cache_size_limit != 0 &&
127 (U.sequencer_disk_cache_flag & SEQ_CACHE_DISK_CACHE_ENABLE) != 0 &&
128 bmain->filepath[0] != '\0');
129}
130
132 const char *filepath)
133{
134
135 DiskCacheFile *cache_file = static_cast<DiskCacheFile *>(
136 MEM_callocN(sizeof(DiskCacheFile), "SeqDiskCacheFile"));
137 char dir[FILE_MAXDIR], file[FILE_MAX];
138 BLI_path_split_dir_file(filepath, dir, sizeof(dir), file, sizeof(file));
139 STRNCPY(cache_file->filepath, filepath);
140 STRNCPY(cache_file->dir, dir);
141 STRNCPY(cache_file->file, file);
142 sscanf(file,
144 &cache_file->cache_type,
145 &cache_file->rectx,
146 &cache_file->recty,
147 &cache_file->render_size,
148 &cache_file->view_id,
149 &cache_file->start_frame);
150 cache_file->start_frame *= DCACHE_IMAGES_PER_FILE;
151 BLI_addtail(&disk_cache->files, cache_file);
152 return cache_file;
153}
154
155static void seq_disk_cache_get_files(SeqDiskCache *disk_cache, const char *dirpath)
156{
157 direntry *filelist, *fl;
158 uint i;
159 disk_cache->size_total = 0;
160
161 const int filelist_num = BLI_filelist_dir_contents(dirpath, &filelist);
162 i = filelist_num;
163 fl = filelist;
164 while (i--) {
165 /* Don't follow links. */
166 const eFileAttributes file_attrs = BLI_file_attributes(fl->path);
167 if (file_attrs & FILE_ATTR_ANY_LINK) {
168 fl++;
169 continue;
170 }
171
172 char file[FILE_MAX];
173 BLI_path_split_file_part(fl->path, file, sizeof(file));
174
175 bool is_dir = BLI_is_dir(fl->path);
176 if (is_dir && !FILENAME_IS_CURRPAR(file)) {
177 char subpath[FILE_MAX];
178 STRNCPY(subpath, fl->path);
179 BLI_path_slash_ensure(subpath, sizeof(subpath));
180 seq_disk_cache_get_files(disk_cache, subpath);
181 }
182
183 if (!is_dir) {
184 const char *ext = BLI_path_extension(fl->path);
185 if (ext && ext[1] == 'd' && ext[2] == 'c' && ext[3] == 'f') {
186 DiskCacheFile *cache_file = seq_disk_cache_add_file_to_list(disk_cache, fl->path);
187 cache_file->fstat = fl->s;
188 disk_cache->size_total += cache_file->fstat.st_size;
189 }
190 }
191 fl++;
192 }
193 BLI_filelist_free(filelist, filelist_num);
194}
195
197{
198 DiskCacheFile *oldest_file = static_cast<DiskCacheFile *>(disk_cache->files.first);
199 if (oldest_file == nullptr) {
200 return nullptr;
201 }
202 for (DiskCacheFile *cache_file = oldest_file->next; cache_file; cache_file = cache_file->next) {
203 if (cache_file->fstat.st_mtime < oldest_file->fstat.st_mtime) {
204 oldest_file = cache_file;
205 }
206 }
207
208 return oldest_file;
209}
210
212{
213 disk_cache->size_total -= file->fstat.st_size;
214 BLI_delete(file->filepath, false, false);
215 BLI_remlink(&disk_cache->files, file);
216 MEM_freeN(file);
217}
218
220{
221 BLI_mutex_lock(&disk_cache->read_write_mutex);
222 while (disk_cache->size_total > seq_disk_cache_size_limit()) {
223 DiskCacheFile *oldest_file = seq_disk_cache_get_oldest_file(disk_cache);
224
225 if (!oldest_file) {
226 /* We shouldn't enforce limits with no files, do re-scan. */
228 continue;
229 }
230
231 if (BLI_exists(oldest_file->filepath) == 0) {
232 /* File may have been manually deleted during runtime, do re-scan. */
233 BLI_freelistN(&disk_cache->files);
235 continue;
236 }
237
238 seq_disk_cache_delete_file(disk_cache, oldest_file);
239 }
241
242 return true;
243}
244
246 const char *filepath)
247{
248 DiskCacheFile *cache_file = static_cast<DiskCacheFile *>(disk_cache->files.first);
249
250 for (; cache_file; cache_file = cache_file->next) {
251 if (BLI_strcasecmp(cache_file->filepath, filepath) == 0) {
252 return cache_file;
253 }
254 }
255
256 return nullptr;
257}
258
259/* Update file size and timestamp. */
260static void seq_disk_cache_update_file(SeqDiskCache *disk_cache, const char *filepath)
261{
262 DiskCacheFile *cache_file;
263 int64_t size_before;
264 int64_t size_after;
265
266 cache_file = seq_disk_cache_get_file_entry_by_path(disk_cache, filepath);
267 size_before = cache_file->fstat.st_size;
268
269 if (BLI_stat(filepath, &cache_file->fstat) == -1) {
270 BLI_assert(false);
271 memset(&cache_file->fstat, 0, sizeof(BLI_stat_t));
272 }
273
274 size_after = cache_file->fstat.st_size;
275 disk_cache->size_total += size_after - size_before;
276}
277
278/* Path format:
279 * <cache dir>/<project name>_seq_cache/<scene name>-<timestamp>/<seq name>/DCACHE_FNAME_FORMAT
280 */
281
283 char *dirpath,
284 size_t dirpath_maxncpy)
285{
286 char cache_dir[FILE_MAX];
287 const char *blendfile_path = BKE_main_blendfile_path(disk_cache->bmain);
288 /* Use suffix, so that the cache directory name does not conflict with the bmain's blend file. */
289 SNPRINTF(cache_dir, "%s_seq_cache", BLI_path_basename(blendfile_path));
290 BLI_path_join(dirpath, dirpath_maxncpy, seq_disk_cache_base_dir(), cache_dir);
291}
292
294 SeqDiskCache *disk_cache, Scene *scene, Sequence *seq, char *dirpath, size_t dirpath_maxncpy)
295{
296 char scene_name[MAX_ID_NAME + 22]; /* + -%PRId64 */
297 char seq_name[SEQ_NAME_MAXSTR];
298 char project_dir[FILE_MAX];
299
300 seq_disk_cache_get_project_dir(disk_cache, project_dir, sizeof(project_dir));
301 SNPRINTF(scene_name, "%s-%" PRId64, scene->id.name, disk_cache->timestamp);
302 STRNCPY(seq_name, seq->name);
303 BLI_path_make_safe_filename(scene_name);
305
306 BLI_path_join(dirpath, dirpath_maxncpy, project_dir, scene_name, seq_name);
307}
308
310 SeqCacheKey *key,
311 char *filepath,
312 size_t filepath_maxncpy)
313{
314 seq_disk_cache_get_dir(disk_cache, key->context.scene, key->seq, filepath, filepath_maxncpy);
315 int frameno = int(key->frame_index) / DCACHE_IMAGES_PER_FILE;
316 char cache_filename[FILE_MAXFILE];
317 SNPRINTF(cache_filename,
319 key->type,
320 key->context.rectx,
321 key->context.recty,
323 key->context.view_id,
324 frameno);
325
326 BLI_path_append(filepath, filepath_maxncpy, cache_filename);
327}
328
329static void seq_disk_cache_create_version_file(const char *filepath)
330{
332
333 FILE *file = BLI_fopen(filepath, "w");
334 if (file) {
335 fprintf(file, "%d", DCACHE_CURRENT_VERSION);
336 fclose(file);
337 }
338}
339
341{
342 char dirpath[FILE_MAX];
343 char path_version_file[FILE_MAX];
344 int version = 0;
345
346 seq_disk_cache_get_project_dir(disk_cache, dirpath, sizeof(dirpath));
347 BLI_path_join(path_version_file, sizeof(path_version_file), dirpath, "cache_version");
348
349 if (BLI_exists(dirpath) && BLI_is_dir(dirpath)) {
350 FILE *file = BLI_fopen(path_version_file, "r");
351
352 if (file) {
353 const int num_items_read = fscanf(file, "%d", &version);
354 if (num_items_read == 0) {
355 version = -1;
356 }
357 fclose(file);
358 }
359
360 if (version != DCACHE_CURRENT_VERSION) {
361 BLI_delete(dirpath, true, true);
362 seq_disk_cache_create_version_file(path_version_file);
363 }
364 }
365 else {
366 seq_disk_cache_create_version_file(path_version_file);
367 }
368}
369
371 Scene *scene,
372 Sequence *seq,
373 int invalidate_types,
374 int range_start,
375 int range_end)
376{
377 DiskCacheFile *next_file, *cache_file = static_cast<DiskCacheFile *>(disk_cache->files.first);
378 char cache_dir[FILE_MAX];
379 seq_disk_cache_get_dir(disk_cache, scene, seq, cache_dir, sizeof(cache_dir));
380 BLI_path_slash_ensure(cache_dir, sizeof(cache_dir));
381
382 while (cache_file) {
383 next_file = cache_file->next;
384 if (cache_file->cache_type & invalidate_types) {
385 if (STREQ(cache_dir, cache_file->dir)) {
386 int timeline_frame_start = seq_cache_frame_index_to_timeline_frame(
387 seq, cache_file->start_frame);
388 if (timeline_frame_start > range_start && timeline_frame_start <= range_end) {
389 seq_disk_cache_delete_file(disk_cache, cache_file);
390 }
391 }
392 }
393 cache_file = next_file;
394 }
395}
396
398 Scene *scene,
399 Sequence *seq,
400 Sequence *seq_changed,
401 int invalidate_types)
402{
403 int start;
404 int end;
405
406 BLI_mutex_lock(&disk_cache->read_write_mutex);
407
408 start = SEQ_time_left_handle_frame_get(scene, seq_changed) - DCACHE_IMAGES_PER_FILE;
409 end = SEQ_time_right_handle_frame_get(scene, seq_changed);
410
411 seq_disk_cache_delete_invalid_files(disk_cache, scene, seq, invalidate_types, start, end);
412
414}
415
416static size_t deflate_imbuf_to_file(ImBuf *ibuf,
417 FILE *file,
418 int level,
419 DiskCacheHeaderEntry *header_entry)
420{
421 void *data = (ibuf->byte_buffer.data != nullptr) ? (void *)ibuf->byte_buffer.data :
422 (void *)ibuf->float_buffer.data;
423
424 /* Apply compression if wanted, otherwise just write directly to the file. */
425 if (level > 0) {
427 data, header_entry->size_raw, file, header_entry->offset, level);
428 }
429
430 fseek(file, header_entry->offset, SEEK_SET);
431 return fwrite(data, 1, header_entry->size_raw, file);
432}
433
434static size_t inflate_file_to_imbuf(ImBuf *ibuf, FILE *file, DiskCacheHeaderEntry *header_entry)
435{
436 void *data = (ibuf->byte_buffer.data != nullptr) ? (void *)ibuf->byte_buffer.data :
437 (void *)ibuf->float_buffer.data;
438 char header[4];
439 fseek(file, header_entry->offset, SEEK_SET);
440 if (fread(header, 1, sizeof(header), file) != sizeof(header)) {
441 return 0;
442 }
443
444 /* Check if the data is compressed or raw. */
445 if (BLI_file_magic_is_zstd(header)) {
446 return BLI_file_unzstd_to_mem_at_pos(data, header_entry->size_raw, file, header_entry->offset);
447 }
448
449 fseek(file, header_entry->offset, SEEK_SET);
450 return fread(data, 1, header_entry->size_raw, file);
451}
452
453static bool seq_disk_cache_read_header(FILE *file, DiskCacheHeader *header)
454{
455 BLI_fseek(file, 0LL, SEEK_SET);
456 const size_t num_items_read = fread(header, sizeof(*header), 1, file);
457 if (num_items_read < 1) {
458 BLI_assert_msg(0, "unable to read disk cache header");
459 perror("unable to read disk cache header");
460 return false;
461 }
462
463 for (int i = 0; i < DCACHE_IMAGES_PER_FILE; i++) {
464 if ((ENDIAN_ORDER == B_ENDIAN) && header->entry[i].encoding == 0) {
469 }
470 }
471
472 return true;
473}
474
475static size_t seq_disk_cache_write_header(FILE *file, const DiskCacheHeader *header)
476{
477 BLI_fseek(file, 0LL, SEEK_SET);
478 return fwrite(header, sizeof(*header), 1, file);
479}
480
482 ImBuf *ibuf,
483 DiskCacheHeader *header)
484{
485 int i;
486 uint64_t offset = sizeof(*header);
487
488 /* Lookup free entry, get offset for new data. */
489 for (i = 0; i < DCACHE_IMAGES_PER_FILE; i++) {
490 if (header->entry[i].size_compressed == 0) {
491 break;
492 }
493 }
494
495 /* Attempt to write beyond set entry limit.
496 * Reset file header and start writing from beginning.
497 */
498 if (i == DCACHE_IMAGES_PER_FILE) {
499 i = 0;
500 memset(header, 0, sizeof(*header));
501 }
502
503 /* Calculate offset for image data. */
504 if (i > 0) {
505 offset = header->entry[i - 1].offset + header->entry[i - 1].size_compressed;
506 }
507
508 if (ENDIAN_ORDER == B_ENDIAN) {
509 header->entry[i].encoding = 255;
510 }
511 else {
512 header->entry[i].encoding = 0;
513 }
514
515 header->entry[i].offset = offset;
516 header->entry[i].frameno = key->frame_index;
517
518 /* Store colorspace name of ibuf. */
519 const char *colorspace_name;
520 if (ibuf->byte_buffer.data) {
521 header->entry[i].size_raw = int64_t(ibuf->x) * ibuf->y * ibuf->channels;
522 colorspace_name = IMB_colormanagement_get_rect_colorspace(ibuf);
523 }
524 else {
525 header->entry[i].size_raw = int64_t(ibuf->x) * ibuf->y * ibuf->channels * 4;
526 colorspace_name = IMB_colormanagement_get_float_colorspace(ibuf);
527 }
528 STRNCPY(header->entry[i].colorspace_name, colorspace_name);
529
530 return i;
531}
532
534{
535 for (int i = 0; i < DCACHE_IMAGES_PER_FILE; i++) {
536 if (header->entry[i].frameno == key->frame_index) {
537 return i;
538 }
539 }
540
541 return -1;
542}
543
545{
546 BLI_mutex_lock(&disk_cache->read_write_mutex);
547
548 char filepath[FILE_MAX];
549
550 seq_disk_cache_get_file_path(disk_cache, key, filepath, sizeof(filepath));
552
553 /* Touch the file. */
554 FILE *file = BLI_fopen(filepath, "rb+");
555 if (!file) {
556 file = BLI_fopen(filepath, "wb+");
557 if (!file) {
559 return false;
560 }
561 seq_disk_cache_add_file_to_list(disk_cache, filepath);
562 }
563
564 DiskCacheFile *cache_file = seq_disk_cache_get_file_entry_by_path(disk_cache, filepath);
565 DiskCacheHeader header;
566 memset(&header, 0, sizeof(header));
567 /* The file may be empty when touched (above).
568 * This is fine, don't attempt reading the header in that case. */
569 if (cache_file->fstat.st_size != 0 && !seq_disk_cache_read_header(file, &header)) {
570 fclose(file);
571 seq_disk_cache_delete_file(disk_cache, cache_file);
573 return false;
574 }
575 int entry_index = seq_disk_cache_add_header_entry(key, ibuf, &header);
576
577 size_t bytes_written = deflate_imbuf_to_file(
578 ibuf, file, seq_disk_cache_compression_level(), &header.entry[entry_index]);
579
580 if (bytes_written != 0) {
581 /* Last step is writing header, as image data can be overwritten,
582 * but missing data would cause problems.
583 */
584 header.entry[entry_index].size_compressed = bytes_written;
585 seq_disk_cache_write_header(file, &header);
586 seq_disk_cache_update_file(disk_cache, filepath);
587 fclose(file);
588
590 return true;
591 }
592
594 return false;
595}
596
598{
599 BLI_mutex_lock(&disk_cache->read_write_mutex);
600
601 char filepath[FILE_MAX];
602 DiskCacheHeader header;
603
604 seq_disk_cache_get_file_path(disk_cache, key, filepath, sizeof(filepath));
606
607 FILE *file = BLI_fopen(filepath, "rb");
608 if (!file) {
610 return nullptr;
611 }
612
613 if (!seq_disk_cache_read_header(file, &header)) {
614 fclose(file);
616 return nullptr;
617 }
618 int entry_index = seq_disk_cache_get_header_entry(key, &header);
619
620 /* Item not found. */
621 if (entry_index < 0) {
622 fclose(file);
624 return nullptr;
625 }
626
627 ImBuf *ibuf;
628 uint64_t size_char = uint64_t(key->context.rectx) * key->context.recty * 4;
629 uint64_t size_float = uint64_t(key->context.rectx) * key->context.recty * 16;
630 size_t expected_size;
631
632 if (header.entry[entry_index].size_raw == size_char) {
633 expected_size = size_char;
634 ibuf = IMB_allocImBuf(
637 }
638 else if (header.entry[entry_index].size_raw == size_float) {
639 expected_size = size_float;
640 ibuf = IMB_allocImBuf(
643 }
644 else {
645 fclose(file);
647 return nullptr;
648 }
649
650 size_t bytes_read = inflate_file_to_imbuf(ibuf, file, &header.entry[entry_index]);
651
652 /* Sanity check. */
653 if (bytes_read != expected_size) {
654 fclose(file);
655 IMB_freeImBuf(ibuf);
657 return nullptr;
658 }
659 BLI_file_touch(filepath);
660 seq_disk_cache_update_file(disk_cache, filepath);
661 fclose(file);
662
664 return ibuf;
665}
666
668{
669 SeqDiskCache *disk_cache = static_cast<SeqDiskCache *>(
670 MEM_callocN(sizeof(SeqDiskCache), "SeqDiskCache"));
671 disk_cache->bmain = bmain;
672 BLI_mutex_init(&disk_cache->read_write_mutex);
675 disk_cache->timestamp = scene->ed->disk_cache_timestamp;
677 return disk_cache;
678}
679
681{
682 BLI_freelistN(&disk_cache->files);
683 BLI_mutex_end(&disk_cache->read_write_mutex);
684 MEM_freeN(disk_cache);
685}
const char * BKE_main_blendfile_path(const Main *bmain) ATTR_NONNULL()
Definition main.cc:832
#define BLI_assert(a)
Definition BLI_assert.h:50
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:57
#define B_ENDIAN
#define ENDIAN_ORDER
BLI_INLINE void BLI_endian_switch_uint64(uint64_t *val) ATTR_NONNULL(1)
File and directory operations.
bool BLI_file_touch(const char *filepath) ATTR_NONNULL(1)
Definition fileops_c.cc:316
eFileAttributes BLI_file_attributes(const char *path)
Definition storage.cc:226
int BLI_exists(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition storage.cc:350
size_t BLI_file_zstd_from_mem_at_pos(void *buf, size_t len, FILE *file, size_t file_offset, int compression_level) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition fileops_c.cc:173
#define FILE_ATTR_ANY_LINK
FILE * BLI_fopen(const char *filepath, const char *mode) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
int BLI_stat(const char *path, BLI_stat_t *buffer) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
unsigned int BLI_filelist_dir_contents(const char *dirname, struct direntry **r_filelist)
int BLI_delete(const char *path, bool dir, bool recursive) ATTR_NONNULL()
size_t BLI_file_unzstd_to_mem_at_pos(void *buf, size_t len, FILE *file, size_t file_offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition fileops_c.cc:220
bool BLI_file_magic_is_zstd(const char header[4])
Definition fileops_c.cc:264
struct stat BLI_stat_t
bool BLI_is_dir(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition storage.cc:433
void BLI_filelist_free(struct direntry *filelist, unsigned int nrentries)
eFileAttributes
int BLI_fseek(FILE *stream, int64_t offset, int whence)
Definition storage.cc:188
bool BLI_file_ensure_parent_dir_exists(const char *filepath) ATTR_NONNULL(1)
Definition fileops_c.cc:429
Some types for dealing with directories.
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition listbase.cc:496
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:110
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:130
size_t BLI_path_append(char *__restrict dst, size_t dst_maxncpy, const char *__restrict file) ATTR_NONNULL(1
void void void const char * BLI_path_basename(const char *path) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT
#define FILE_MAXFILE
#define FILE_MAX
#define BLI_path_join(...)
#define FILENAME_IS_CURRPAR(_n)
void void void BLI_path_split_file_part(const char *filepath, char *file, size_t file_maxncpy) ATTR_NONNULL(1
void BLI_path_split_dir_file(const char *filepath, char *dir, size_t dir_maxncpy, char *file, size_t file_maxncpy) ATTR_NONNULL(1
int BLI_path_slash_ensure(char *path, size_t path_maxncpy) ATTR_NONNULL(1)
bool BLI_path_make_safe_filename(char *filename) ATTR_NONNULL(1)
const char * BLI_path_extension(const char *filepath) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT
#define FILE_MAXDIR
#define STRNCPY(dst, src)
Definition BLI_string.h:593
#define SNPRINTF(dst, format,...)
Definition BLI_string.h:597
int char char int BLI_strcasecmp(const char *s1, const char *s2) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1
unsigned char uchar
unsigned int uint
void BLI_mutex_end(ThreadMutex *mutex)
Definition threads.cc:360
void BLI_mutex_init(ThreadMutex *mutex)
Definition threads.cc:340
#define BLI_MUTEX_INITIALIZER
Definition BLI_threads.h:84
void BLI_mutex_lock(ThreadMutex *mutex)
Definition threads.cc:345
void BLI_mutex_unlock(ThreadMutex *mutex)
Definition threads.cc:350
pthread_mutex_t ThreadMutex
Definition BLI_threads.h:83
#define STREQ(a, b)
#define MAX_ID_NAME
Definition DNA_ID.h:377
@ SEQ_CACHE_DISK_CACHE_ENABLE
#define SEQ_NAME_MAXSTR
@ USER_SEQ_DISK_CACHE_COMPRESSION_HIGH
@ USER_SEQ_DISK_CACHE_COMPRESSION_LOW
@ USER_SEQ_DISK_CACHE_COMPRESSION_NONE
void IMB_colormanagement_assign_byte_colorspace(ImBuf *ibuf, const char *name)
void IMB_colormanagement_assign_float_colorspace(ImBuf *ibuf, const char *name)
const char * IMB_colormanagement_get_rect_colorspace(ImBuf *ibuf)
const char * IMB_colormanagement_get_float_colorspace(ImBuf *ibuf)
Contains defines and structs used throughout the imbuf module.
@ IB_rectfloat
@ IB_uninitialized_pixels
@ IB_rect
Read Guarded memory(de)allocation.
unsigned int U
Definition btGjkEpa3.h:78
static size_t seq_disk_cache_write_header(FILE *file, const DiskCacheHeader *header)
#define DCACHE_IMAGES_PER_FILE
Definition disk_cache.cc:59
static size_t seq_disk_cache_size_limit()
static int seq_disk_cache_compression_level()
static void seq_disk_cache_handle_versioning(SeqDiskCache *disk_cache)
static void seq_disk_cache_update_file(SeqDiskCache *disk_cache, const char *filepath)
static void seq_disk_cache_delete_invalid_files(SeqDiskCache *disk_cache, Scene *scene, Sequence *seq, int invalidate_types, int range_start, int range_end)
ImBuf * seq_disk_cache_read_file(SeqDiskCache *disk_cache, SeqCacheKey *key)
static int seq_disk_cache_get_header_entry(const SeqCacheKey *key, const DiskCacheHeader *header)
static DiskCacheFile * seq_disk_cache_add_file_to_list(SeqDiskCache *disk_cache, const char *filepath)
static int seq_disk_cache_add_header_entry(const SeqCacheKey *key, ImBuf *ibuf, DiskCacheHeader *header)
static void seq_disk_cache_get_project_dir(SeqDiskCache *disk_cache, char *dirpath, size_t dirpath_maxncpy)
static void seq_disk_cache_delete_file(SeqDiskCache *disk_cache, DiskCacheFile *file)
static bool seq_disk_cache_read_header(FILE *file, DiskCacheHeader *header)
#define COLORSPACE_NAME_MAX
Definition disk_cache.cc:61
static const char * seq_disk_cache_base_dir()
void seq_disk_cache_invalidate(SeqDiskCache *disk_cache, Scene *scene, Sequence *seq, Sequence *seq_changed, int invalidate_types)
static void seq_disk_cache_get_file_path(SeqDiskCache *disk_cache, SeqCacheKey *key, char *filepath, size_t filepath_maxncpy)
static size_t deflate_imbuf_to_file(ImBuf *ibuf, FILE *file, int level, DiskCacheHeaderEntry *header_entry)
static ThreadMutex cache_create_lock
Definition disk_cache.cc:98
static void seq_disk_cache_get_dir(SeqDiskCache *disk_cache, Scene *scene, Sequence *seq, char *dirpath, size_t dirpath_maxncpy)
static DiskCacheFile * seq_disk_cache_get_oldest_file(SeqDiskCache *disk_cache)
static void seq_disk_cache_create_version_file(const char *filepath)
#define DCACHE_FNAME_FORMAT
Definition disk_cache.cc:58
SeqDiskCache * seq_disk_cache_create(Main *bmain, Scene *scene)
static size_t inflate_file_to_imbuf(ImBuf *ibuf, FILE *file, DiskCacheHeaderEntry *header_entry)
void seq_disk_cache_free(SeqDiskCache *disk_cache)
#define DCACHE_CURRENT_VERSION
Definition disk_cache.cc:60
static void seq_disk_cache_get_files(SeqDiskCache *disk_cache, const char *dirpath)
bool seq_disk_cache_enforce_limits(SeqDiskCache *disk_cache)
bool seq_disk_cache_write_file(SeqDiskCache *disk_cache, SeqCacheKey *key, ImBuf *ibuf)
static DiskCacheFile * seq_disk_cache_get_file_entry_by_path(SeqDiskCache *disk_cache, const char *filepath)
bool seq_disk_cache_is_enabled(Main *bmain)
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
struct ImBuf * IMB_allocImBuf(unsigned int, unsigned int, unsigned char, unsigned int)
void IMB_freeImBuf(ImBuf *)
float seq_cache_frame_index_to_timeline_frame(Sequence *seq, float frame_index)
#define PRId64
Definition inttypes.h:78
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
__int64 int64_t
Definition stdint.h:89
unsigned __int64 uint64_t
Definition stdint.h:90
int SEQ_time_left_handle_frame_get(const Scene *, const Sequence *seq)
int SEQ_time_right_handle_frame_get(const Scene *scene, const Sequence *seq)
char file[FILE_MAX]
Definition disk_cache.cc:88
DiskCacheFile * next
Definition disk_cache.cc:85
char dir[FILE_MAXDIR]
Definition disk_cache.cc:87
char filepath[FILE_MAX]
Definition disk_cache.cc:86
BLI_stat_t fstat
Definition disk_cache.cc:89
DiskCacheFile * prev
Definition disk_cache.cc:85
char colorspace_name[COLORSPACE_NAME_MAX]
Definition disk_cache.cc:69
DiskCacheHeaderEntry entry[DCACHE_IMAGES_PER_FILE]
Definition disk_cache.cc:73
ImBufFloatBuffer float_buffer
ImBufByteBuffer byte_buffer
void * first
char filepath[1024]
Definition BKE_main.hh:136
float frame_index
SeqRenderData context
Sequence * seq
int64_t timestamp
Definition disk_cache.cc:78
ThreadMutex read_write_mutex
Definition disk_cache.cc:80
size_t size_total
Definition disk_cache.cc:81
ListBase files
Definition disk_cache.cc:79
int preview_render_size
Definition SEQ_render.hh:32
Scene * scene
Definition SEQ_render.hh:29
struct stat s
const char * path