Blender  V3.3
image_cache.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2010 Peter Schlaile <peter [at] schlaile [dot] de>. */
3 
8 #include <memory.h>
9 #include <stddef.h>
10 #include <time.h>
11 
12 #include "MEM_guardedalloc.h"
13 
14 #include "DNA_scene_types.h"
15 #include "DNA_sequence_types.h"
16 #include "DNA_space_types.h" /* for FILE_MAX. */
17 
18 #include "IMB_colormanagement.h"
19 #include "IMB_imbuf.h"
20 #include "IMB_imbuf_types.h"
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_ghash.h"
28 #include "BLI_listbase.h"
29 #include "BLI_mempool.h"
30 #include "BLI_path_util.h"
31 #include "BLI_threads.h"
32 
33 #include "BKE_main.h"
34 #include "BKE_scene.h"
35 
36 #include "SEQ_prefetch.h"
37 #include "SEQ_relations.h"
38 #include "SEQ_sequencer.h"
39 #include "SEQ_time.h"
40 
41 #include "disk_cache.h"
42 #include "image_cache.h"
43 #include "prefetch.h"
44 #include "strip_time.h"
45 
72 #define THUMB_CACHE_LIMIT 5000
73 
74 typedef struct SeqCache {
76  struct GHash *hash;
84 
85 typedef struct SeqCacheItem {
87  struct ImBuf *ibuf;
89 
91 
92 static bool seq_cmp_render_data(const SeqRenderData *a, const SeqRenderData *b)
93 {
94  return ((a->preview_render_size != b->preview_render_size) || (a->rectx != b->rectx) ||
95  (a->recty != b->recty) || (a->bmain != b->bmain) || (a->scene != b->scene) ||
96  (a->motion_blur_shutter != b->motion_blur_shutter) ||
97  (a->motion_blur_samples != b->motion_blur_samples) ||
98  (a->scene->r.views_format != b->scene->r.views_format) || (a->view_id != b->view_id));
99 }
100 
101 static unsigned int seq_hash_render_data(const SeqRenderData *a)
102 {
103  unsigned int rval = a->rectx + a->recty;
104 
105  rval ^= a->preview_render_size;
106  rval ^= ((intptr_t)a->bmain) << 6;
107  rval ^= ((intptr_t)a->scene) << 6;
108  rval ^= (int)(a->motion_blur_shutter * 100.0f) << 10;
109  rval ^= a->motion_blur_samples << 16;
110  rval ^= ((a->scene->r.views_format * 2) + a->view_id) << 24;
111 
112  return rval;
113 }
114 
115 static unsigned int seq_cache_hashhash(const void *key_)
116 {
117  const SeqCacheKey *key = key_;
118  unsigned int rval = seq_hash_render_data(&key->context);
119 
120  rval ^= *(const unsigned int *)&key->frame_index;
121  rval += key->type;
122  rval ^= ((intptr_t)key->seq) << 6;
123 
124  return rval;
125 }
126 
127 static bool seq_cache_hashcmp(const void *a_, const void *b_)
128 {
129  const SeqCacheKey *a = a_;
130  const SeqCacheKey *b = b_;
131 
132  return ((a->seq != b->seq) || (a->frame_index != b->frame_index) || (a->type != b->type) ||
133  seq_cmp_render_data(&a->context, &b->context));
134 }
135 
137  Sequence *seq,
138  float timeline_frame,
139  int type)
140 {
141  /* With raw images, map timeline_frame to strip input media frame range. This means that static
142  * images or extended frame range of movies will only generate one cache entry. No special
143  * treatment in converting frame index to timeline_frame is needed. */
145  return seq_give_frame_index(scene, seq, timeline_frame);
146  }
147 
148  return timeline_frame - SEQ_time_start_frame_get(seq);
149 }
150 
151 float seq_cache_frame_index_to_timeline_frame(Sequence *seq, float frame_index)
152 {
153  return frame_index + SEQ_time_start_frame_get(seq);
154 }
155 
157 {
158  if (scene && scene->ed && scene->ed->cache) {
159  return scene->ed->cache;
160  }
161 
162  return NULL;
163 }
164 
166 {
168 
169  if (cache) {
171  }
172 }
173 
175 {
177 
178  if (cache) {
180  }
181 }
182 
183 static size_t seq_cache_get_mem_total(void)
184 {
185  return ((size_t)U.memcachelimit) * 1024 * 1024;
186 }
187 
188 static void seq_cache_keyfree(void *val)
189 {
190  SeqCacheKey *key = val;
192 }
193 
194 static void seq_cache_valfree(void *val)
195 {
196  SeqCacheItem *item = (SeqCacheItem *)val;
197 
198  if (item->ibuf) {
199  IMB_freeImBuf(item->ibuf);
200  }
201 
203 }
204 
206 {
207  int flag;
208  if (key->seq->cache_flag & SEQ_CACHE_OVERRIDE) {
209  flag = key->seq->cache_flag;
210  }
211  else {
212  flag = scene->ed->cache_flag;
213  }
214 
215  /* SEQ_CACHE_STORE_FINAL_OUT can not be overridden by strip cache */
217 
218  return flag;
219 }
220 
221 static void seq_cache_put_ex(Scene *scene, SeqCacheKey *key, ImBuf *ibuf)
222 {
224  SeqCacheItem *item;
225  item = BLI_mempool_alloc(cache->items_pool);
226  item->cache_owner = cache;
227  item->ibuf = ibuf;
228 
229  const int stored_types_flag = get_stored_types_flag(scene, key);
230 
231  /* Item stored for later use. */
232  if (stored_types_flag & key->type) {
233  key->is_temp_cache = false;
234  key->link_prev = cache->last_key;
235  }
236 
237  /* Store pointer to last cached key. */
238  SeqCacheKey *temp_last_key = cache->last_key;
239 
240  if (BLI_ghash_reinsert(cache->hash, key, item, seq_cache_keyfree, seq_cache_valfree)) {
241  IMB_refImBuf(ibuf);
242 
243  if (!key->is_temp_cache || key->type != SEQ_CACHE_STORE_THUMBNAIL) {
244  cache->last_key = key;
245  }
246  }
247 
248  /* Set last_key's reference to this key so we can look up chain backwards.
249  * Item is already put in cache, so cache->last_key points to current key.
250  */
251  if (!key->is_temp_cache && temp_last_key) {
252  temp_last_key->link_next = cache->last_key;
253  }
254 
255  /* Reset linking. */
256  if (key->type == SEQ_CACHE_STORE_FINAL_OUT) {
257  cache->last_key = NULL;
258  }
259 }
260 
262 {
263  SeqCacheItem *item = BLI_ghash_lookup(cache->hash, key);
264 
265  if (item && item->ibuf) {
266  IMB_refImBuf(item->ibuf);
267 
268  return item->ibuf;
269  }
270 
271  return NULL;
272 }
273 
274 static void seq_cache_relink_keys(SeqCacheKey *link_next, SeqCacheKey *link_prev)
275 {
276  if (link_next) {
277  link_next->link_prev = link_prev;
278  }
279  if (link_prev) {
280  link_prev->link_next = link_next;
281  }
282 }
283 
284 /* Choose a key out of 2 candidates(leftmost and rightmost items)
285  * to recycle based on currently used strategy */
287 {
288  SeqCacheKey *finalkey = NULL;
289 
290  /* Ideally, cache would not need to check the state of prefetching task
291  * that is tricky to do however, because prefetch would need to know,
292  * if a key, that is about to be created would be removed by itself.
293  *
294  * This can happen because only FINAL_OUT item insertion will trigger recycling
295  * but that is also the point, where prefetch can be suspended.
296  *
297  * We could use temp cache as a shield and later make it a non-temporary entry,
298  * but it is not worth of increasing system complexity.
299  */
301  int pfjob_start, pfjob_end;
302  seq_prefetch_get_time_range(scene, &pfjob_start, &pfjob_end);
303 
304  if (lkey) {
305  if (lkey->timeline_frame < pfjob_start || lkey->timeline_frame > pfjob_end) {
306  return lkey;
307  }
308  }
309 
310  if (rkey) {
311  if (rkey->timeline_frame < pfjob_start || rkey->timeline_frame > pfjob_end) {
312  return rkey;
313  }
314  }
315 
316  return NULL;
317  }
318 
319  if (rkey && lkey) {
320  if (lkey->timeline_frame > rkey->timeline_frame) {
321  SeqCacheKey *swapkey = lkey;
322  lkey = rkey;
323  rkey = swapkey;
324  }
325 
326  int l_diff = scene->r.cfra - lkey->timeline_frame;
327  int r_diff = rkey->timeline_frame - scene->r.cfra;
328 
329  if (l_diff > r_diff) {
330  finalkey = lkey;
331  }
332  else {
333  finalkey = rkey;
334  }
335  }
336  else {
337  if (lkey) {
338  finalkey = lkey;
339  }
340  else {
341  finalkey = rkey;
342  }
343  }
344  return finalkey;
345 }
346 
348 {
350  if (!cache) {
351  return;
352  }
353 
354  SeqCacheKey *next = base->link_next;
355 
356  while (base) {
357  if (!BLI_ghash_haskey(cache->hash, base)) {
358  break; /* Key has already been removed from cache. */
359  }
360 
361  SeqCacheKey *prev = base->link_prev;
362  if (prev != NULL && prev->link_next != base) {
363  /* Key has been removed and replaced and doesn't belong to this chain anymore. */
364  base->link_prev = NULL;
365  break;
366  }
367 
369  base = prev;
370  }
371 
372  base = next;
373  while (base) {
374  if (!BLI_ghash_haskey(cache->hash, base)) {
375  break; /* Key has already been removed from cache. */
376  }
377 
378  next = base->link_next;
379  if (next != NULL && next->link_prev != base) {
380  /* Key has been removed and replaced and doesn't belong to this chain anymore. */
381  base->link_next = NULL;
382  break;
383  }
384 
386  base = next;
387  }
388 }
389 
391 {
393  SeqCacheKey *finalkey = NULL;
394  /* Leftmost key. */
395  SeqCacheKey *lkey = NULL;
396  /* Rightmost key. */
397  SeqCacheKey *rkey = NULL;
398  SeqCacheKey *key = NULL;
399 
400  GHashIterator gh_iter;
401  BLI_ghashIterator_init(&gh_iter, cache->hash);
402  int total_count = 0;
403 
404  while (!BLI_ghashIterator_done(&gh_iter)) {
405  key = BLI_ghashIterator_getKey(&gh_iter);
406  SeqCacheItem *item = BLI_ghashIterator_getValue(&gh_iter);
407  BLI_ghashIterator_step(&gh_iter);
408 
409  /* This shouldn't happen, but better be safe than sorry. */
410  if (!item->ibuf) {
412  /* Can not continue iterating after linked remove. */
413  BLI_ghashIterator_init(&gh_iter, cache->hash);
414  continue;
415  }
416 
417  if (key->is_temp_cache || key->link_next != NULL) {
418  continue;
419  }
420 
421  total_count++;
422 
423  if (lkey) {
424  if (key->timeline_frame < lkey->timeline_frame) {
425  lkey = key;
426  }
427  }
428  else {
429  lkey = key;
430  }
431  if (rkey) {
432  if (key->timeline_frame > rkey->timeline_frame) {
433  rkey = key;
434  }
435  }
436  else {
437  rkey = key;
438  }
439  }
440 
441  finalkey = seq_cache_choose_key(scene, lkey, rkey);
442 
443  return finalkey;
444 }
445 
447 {
449  if (!cache) {
450  return false;
451  }
452 
454 
455  while (seq_cache_is_full()) {
457 
458  if (finalkey) {
459  seq_cache_recycle_linked(scene, finalkey);
460  }
461  else {
463  return false;
464  }
465  }
467  return true;
468 }
469 
471 {
473 
474  if (!cache || !base) {
475  return;
476  }
477 
478  SeqCacheKey *next = base->link_next;
479 
480  while (base) {
481  SeqCacheKey *prev = base->link_prev;
482  base->is_temp_cache = true;
483  base = prev;
484  }
485 
486  base = next;
487  while (base) {
488  next = base->link_next;
489  base->is_temp_cache = true;
490  base = next;
491  }
492 }
493 
494 static void seq_cache_create(Main *bmain, Scene *scene)
495 {
497  if (scene->ed->cache == NULL) {
498  SeqCache *cache = MEM_callocN(sizeof(SeqCache), "SeqCache");
499  cache->keys_pool = BLI_mempool_create(sizeof(SeqCacheKey), 0, 64, BLI_MEMPOOL_NOP);
500  cache->items_pool = BLI_mempool_create(sizeof(SeqCacheItem), 0, 64, BLI_MEMPOOL_NOP);
501  cache->hash = BLI_ghash_new(seq_cache_hashhash, seq_cache_hashcmp, "SeqCache hash");
502  cache->last_key = NULL;
503  cache->bmain = bmain;
504  cache->thumbnail_count = 0;
506  scene->ed->cache = cache;
507 
508  if (scene->ed->disk_cache_timestamp == 0) {
510  }
511  }
513 }
514 
516  const SeqRenderData *context,
517  Sequence *seq,
518  const float timeline_frame,
519  const int type)
520 {
522  key->seq = seq;
523  key->context = *context;
525  context->scene, seq, timeline_frame, type);
526  key->timeline_frame = timeline_frame;
527  key->type = type;
528  key->link_prev = NULL;
529  key->link_next = NULL;
530  key->is_temp_cache = true;
531  key->task_id = context->task_id;
532 }
533 
535  const SeqRenderData *context,
536  Sequence *seq,
537  const float timeline_frame,
538  const int type)
539 {
540  SeqCacheKey *key = BLI_mempool_alloc(cache->keys_pool);
541  seq_cache_populate_key(key, context, seq, timeline_frame, type);
542  return key;
543 }
544 
545 /* ***************************** API ****************************** */
546 
547 void seq_cache_free_temp_cache(Scene *scene, short id, int timeline_frame)
548 {
550  if (!cache) {
551  return;
552  }
553 
555 
556  GHashIterator gh_iter;
557  BLI_ghashIterator_init(&gh_iter, cache->hash);
558  while (!BLI_ghashIterator_done(&gh_iter)) {
559  SeqCacheKey *key = BLI_ghashIterator_getKey(&gh_iter);
560  BLI_ghashIterator_step(&gh_iter);
561 
562  if (key->is_temp_cache && key->task_id == id && key->type != SEQ_CACHE_STORE_THUMBNAIL) {
563  /* Use frame_index here to avoid freeing raw images if they are used for multiple frames. */
564  float frame_index = seq_cache_timeline_frame_to_frame_index(
565  scene, key->seq, timeline_frame, key->type);
566  if (frame_index != key->frame_index ||
567  timeline_frame > SEQ_time_right_handle_frame_get(scene, key->seq) ||
568  timeline_frame < SEQ_time_left_handle_frame_get(scene, key->seq)) {
570  }
571  }
572  }
574 }
575 
577 {
579  if (!cache) {
580  return;
581  }
582 
586  BLI_mutex_end(&cache->iterator_mutex);
587 
588  if (cache->disk_cache != NULL) {
590  }
591 
592  MEM_freeN(cache);
593  scene->ed->cache = NULL;
594 }
595 
597 {
598  for (Scene *scene = bmain->scenes.first; scene != NULL; scene = scene->id.next) {
600  }
601 }
603 {
605 
607  if (!cache) {
608  return;
609  }
610 
612 
613  GHashIterator gh_iter;
614  BLI_ghashIterator_init(&gh_iter, cache->hash);
615  while (!BLI_ghashIterator_done(&gh_iter)) {
616  SeqCacheKey *key = BLI_ghashIterator_getKey(&gh_iter);
617 
618  BLI_ghashIterator_step(&gh_iter);
620  }
621  cache->last_key = NULL;
622  cache->thumbnail_count = 0;
624 }
625 
627  Sequence *seq,
628  Sequence *seq_changed,
629  int invalidate_types,
630  bool force_seq_changed_range)
631 {
633  if (!cache) {
634  return;
635  }
636 
637  if (seq_disk_cache_is_enabled(cache->bmain) && cache->disk_cache != NULL) {
638  seq_disk_cache_invalidate(cache->disk_cache, scene, seq, seq_changed, invalidate_types);
639  }
640 
642 
643  int range_start = SEQ_time_left_handle_frame_get(scene, seq_changed);
644  int range_end = SEQ_time_right_handle_frame_get(scene, seq_changed);
645 
646  if (!force_seq_changed_range) {
647  range_start = max_ii(range_start, SEQ_time_left_handle_frame_get(scene, seq));
648  range_end = min_ii(range_end, SEQ_time_right_handle_frame_get(scene, seq));
649  }
650 
651  int invalidate_composite = invalidate_types & SEQ_CACHE_STORE_FINAL_OUT;
652  int invalidate_source = invalidate_types & (SEQ_CACHE_STORE_RAW | SEQ_CACHE_STORE_PREPROCESSED |
654 
655  GHashIterator gh_iter;
656  BLI_ghashIterator_init(&gh_iter, cache->hash);
657  while (!BLI_ghashIterator_done(&gh_iter)) {
658  SeqCacheKey *key = BLI_ghashIterator_getKey(&gh_iter);
659  BLI_ghashIterator_step(&gh_iter);
660 
661  /* Clean all final and composite in intersection of seq and seq_changed. */
662  if (key->type & invalidate_composite && key->timeline_frame >= range_start &&
663  key->timeline_frame <= range_end) {
664  if (key->link_next || key->link_prev) {
666  }
667 
669  }
670 
671  if (key->type & invalidate_source && key->seq == seq &&
672  key->timeline_frame >= SEQ_time_left_handle_frame_get(scene, seq_changed) &&
673  key->timeline_frame <= SEQ_time_right_handle_frame_get(scene, seq_changed)) {
674  if (key->link_next || key->link_prev) {
676  }
677 
679  }
680  }
681  cache->last_key = NULL;
683 }
684 
686 {
687  /* Add offsets to the left and right end to keep some frames in cache. */
688  view_area_safe->xmax += 200;
689  view_area_safe->xmin -= 200;
690  view_area_safe->ymin -= 1;
691  view_area_safe->ymax += 1;
692 
694  if (!cache) {
695  return;
696  }
697 
698  GHashIterator gh_iter;
699  BLI_ghashIterator_init(&gh_iter, cache->hash);
700  while (!BLI_ghashIterator_done(&gh_iter)) {
701  SeqCacheKey *key = BLI_ghashIterator_getKey(&gh_iter);
702  BLI_ghashIterator_step(&gh_iter);
703 
704  const int frame_index = key->timeline_frame - SEQ_time_left_handle_frame_get(scene, key->seq);
705  const int frame_step = SEQ_render_thumbnails_guaranteed_set_frame_step_get(scene, key->seq);
706  const int relative_base_frame = round_fl_to_int((frame_index / (float)frame_step)) *
707  frame_step;
708  const int nearest_guaranted_absolute_frame = relative_base_frame +
710 
711  if (nearest_guaranted_absolute_frame == key->timeline_frame) {
712  continue;
713  }
714 
715  if ((key->type & SEQ_CACHE_STORE_THUMBNAIL) &&
716  (key->timeline_frame > view_area_safe->xmax ||
717  key->timeline_frame < view_area_safe->xmin || key->seq->machine > view_area_safe->ymax ||
718  key->seq->machine < view_area_safe->ymin)) {
720  cache->thumbnail_count--;
721  }
722  }
723  cache->last_key = NULL;
724 }
725 
727  Sequence *seq,
728  float timeline_frame,
729  int type)
730 {
731 
732  if (context->skip_cache || context->is_proxy_render || !seq) {
733  return NULL;
734  }
735 
736  Scene *scene = context->scene;
737 
738  if (context->is_prefetch_render) {
740  scene = context->scene;
742  }
743 
744  if (!seq) {
745  return NULL;
746  }
747 
748  if (!scene->ed->cache) {
749  seq_cache_create(context->bmain, scene);
750  }
751 
754  ImBuf *ibuf = NULL;
755  SeqCacheKey key;
756 
757  /* Try RAM cache: */
758  if (cache && seq) {
759  seq_cache_populate_key(&key, context, seq, timeline_frame, type);
760  ibuf = seq_cache_get_ex(cache, &key);
761  }
763 
764  if (ibuf) {
765  return ibuf;
766  }
767 
768  /* Try disk cache: */
769  if (seq_disk_cache_is_enabled(context->bmain)) {
770  if (cache->disk_cache == NULL) {
771  cache->disk_cache = seq_disk_cache_create(context->bmain, context->scene);
772  }
773 
774  ibuf = seq_disk_cache_read_file(cache->disk_cache, &key);
775 
776  if (ibuf == NULL) {
777  return NULL;
778  }
779 
780  /* Store read image in RAM. Only recycle item for final type. */
782  SeqCacheKey *new_key = seq_cache_allocate_key(cache, context, seq, timeline_frame, type);
783  seq_cache_put_ex(scene, new_key, ibuf);
784  }
785  }
786 
787  return ibuf;
788 }
789 
791  const SeqRenderData *context, Sequence *seq, float timeline_frame, int type, ImBuf *ibuf)
792 {
793  Scene *scene = context->scene;
794 
795  if (context->is_prefetch_render) {
797  scene = context->scene;
799  }
800 
801  if (!seq) {
802  return false;
803  }
804 
806  seq_cache_put(context, seq, timeline_frame, type, ibuf);
807  return true;
808  }
809 
811  scene->ed->cache->last_key = NULL;
812  return false;
813 }
814 
816  const SeqRenderData *context, Sequence *seq, float timeline_frame, ImBuf *i, rctf *view_area)
817 {
818  Scene *scene = context->scene;
819 
820  if (!scene->ed->cache) {
821  seq_cache_create(context->bmain, scene);
822  }
823 
827  cache, context, seq, timeline_frame, SEQ_CACHE_STORE_THUMBNAIL);
828 
829  /* Prevent reinserting, it breaks cache key linking. */
830  if (BLI_ghash_haskey(cache->hash, key)) {
832  return;
833  }
834 
835  /* Limit cache to THUMB_CACHE_LIMIT (5000) images stored. */
836  if (cache->thumbnail_count >= THUMB_CACHE_LIMIT) {
837  rctf view_area_safe = *view_area;
838  seq_cache_thumbnail_cleanup(scene, &view_area_safe);
839  }
840 
841  seq_cache_put_ex(scene, key, i);
842  cache->thumbnail_count++;
844 }
845 
847  const SeqRenderData *context, Sequence *seq, float timeline_frame, int type, ImBuf *i)
848 {
849  if (i == NULL || context->skip_cache || context->is_proxy_render || !seq) {
850  return;
851  }
852 
853  Scene *scene = context->scene;
854 
855  if (context->is_prefetch_render) {
857  scene = context->scene;
859  BLI_assert(seq != NULL);
860  }
861 
862  /* Prevent reinserting, it breaks cache key linking. */
863  ImBuf *test = seq_cache_get(context, seq, timeline_frame, type);
864  if (test) {
865  IMB_freeImBuf(test);
866  return;
867  }
868 
869  if (!scene->ed->cache) {
870  seq_cache_create(context->bmain, scene);
871  }
872 
875  SeqCacheKey *key = seq_cache_allocate_key(cache, context, seq, timeline_frame, type);
876  seq_cache_put_ex(scene, key, i);
878 
879  if (!key->is_temp_cache) {
880  if (seq_disk_cache_is_enabled(context->bmain)) {
881  if (cache->disk_cache == NULL) {
882  seq_disk_cache_create(context->bmain, context->scene);
883  }
884 
885  seq_disk_cache_write_file(cache->disk_cache, key, i);
887  }
888  }
889 }
890 
892  struct Scene *scene,
893  void *userdata,
894  bool callback_init(void *userdata, size_t item_count),
895  bool callback_iter(void *userdata, struct Sequence *seq, int timeline_frame, int cache_type))
896 {
898  if (!cache) {
899  return;
900  }
901 
903  bool interrupt = callback_init(userdata, BLI_ghash_len(cache->hash));
904 
905  GHashIterator gh_iter;
906  BLI_ghashIterator_init(&gh_iter, cache->hash);
907 
908  while (!BLI_ghashIterator_done(&gh_iter) && !interrupt) {
909  SeqCacheKey *key = BLI_ghashIterator_getKey(&gh_iter);
910  BLI_ghashIterator_step(&gh_iter);
911 
912  interrupt = callback_iter(userdata, key->seq, key->timeline_frame, key->type);
913  }
914 
915  cache->last_key = NULL;
917 }
918 
920 {
922 }
#define BLI_assert(a)
Definition: BLI_assert.h:46
File and directory operations.
Some types for dealing with directories.
BLI_INLINE void * BLI_ghashIterator_getKey(GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.h:298
bool BLI_ghash_haskey(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:822
bool BLI_ghash_reinsert(GHash *gh, void *key, void *val, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:715
void BLI_ghashIterator_step(GHashIterator *ghi)
Definition: BLI_ghash.c:914
BLI_INLINE void * BLI_ghashIterator_getValue(GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.h:302
GHash * BLI_ghash_new(GHashHashFP hashfp, GHashCmpFP cmpfp, const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:689
void * BLI_ghash_lookup(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:734
unsigned int BLI_ghash_len(const GHash *gh) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:705
bool BLI_ghash_remove(GHash *gh, const void *key, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:790
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:863
void BLI_ghashIterator_init(GHashIterator *ghi, GHash *gh)
Definition: BLI_ghash.c:898
BLI_INLINE bool BLI_ghashIterator_done(const GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.h:310
MINLINE int round_fl_to_int(float a)
MINLINE int min_ii(int a, int b)
MINLINE int max_ii(int a, int b)
@ BLI_MEMPOOL_NOP
Definition: BLI_mempool.h:99
void BLI_mempool_free(BLI_mempool *pool, void *addr) ATTR_NONNULL(1
BLI_mempool * BLI_mempool_create(unsigned int esize, unsigned int elem_num, unsigned int pchunk, unsigned int flag) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL
Definition: BLI_mempool.c:253
void * BLI_mempool_alloc(BLI_mempool *pool) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL ATTR_NONNULL(1)
Definition: BLI_mempool.c:319
void BLI_mempool_destroy(BLI_mempool *pool) ATTR_NONNULL(1)
Definition: BLI_mempool.c:707
void BLI_mutex_end(ThreadMutex *mutex)
Definition: threads.cc:388
void BLI_mutex_init(ThreadMutex *mutex)
Definition: threads.cc:368
#define BLI_MUTEX_INITIALIZER
Definition: BLI_threads.h:83
void BLI_mutex_lock(ThreadMutex *mutex)
Definition: threads.cc:373
void BLI_mutex_unlock(ThreadMutex *mutex)
Definition: threads.cc:378
pthread_mutex_t ThreadMutex
Definition: BLI_threads.h:82
#define ELEM(...)
@ SEQ_CACHE_STORE_PREPROCESSED
@ SEQ_CACHE_STORE_RAW
@ SEQ_CACHE_STORE_THUMBNAIL
@ SEQ_CACHE_STORE_FINAL_OUT
@ SEQ_CACHE_STORE_COMPOSITE
@ SEQ_CACHE_PREFETCH_ENABLE
@ SEQ_CACHE_OVERRIDE
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
void IMB_refImBuf(struct ImBuf *ibuf)
Definition: allocimbuf.c:220
Contains defines and structs used throughout the imbuf module.
Read Guarded memory(de)allocation.
unsigned int U
Definition: btGjkEpa3.h:78
double time
Scene scene
SeqDiskCache * seq_disk_cache_create(Main *bmain, Scene *scene)
Definition: disk_cache.c:668
ImBuf * seq_disk_cache_read_file(SeqDiskCache *disk_cache, SeqCacheKey *key)
Definition: disk_cache.c:600
void seq_disk_cache_invalidate(SeqDiskCache *disk_cache, Scene *scene, Sequence *seq, Sequence *seq_changed, int invalidate_types)
Definition: disk_cache.c:404
void seq_disk_cache_free(SeqDiskCache *disk_cache)
Definition: disk_cache.c:680
bool seq_disk_cache_enforce_limits(SeqDiskCache *disk_cache)
Definition: disk_cache.c:225
bool seq_disk_cache_write_file(SeqDiskCache *disk_cache, SeqCacheKey *key, ImBuf *ibuf)
Definition: disk_cache.c:548
bool seq_disk_cache_is_enabled(Main *bmain)
Definition: disk_cache.c:132
void IMB_freeImBuf(ImBuf *UNUSED(ibuf))
void seq_cache_thumbnail_put(const SeqRenderData *context, Sequence *seq, float timeline_frame, ImBuf *i, rctf *view_area)
Definition: image_cache.c:815
static unsigned int seq_cache_hashhash(const void *key_)
Definition: image_cache.c:115
static void seq_cache_recycle_linked(Scene *scene, SeqCacheKey *base)
Definition: image_cache.c:347
void SEQ_cache_cleanup(Scene *scene)
Definition: image_cache.c:602
static void seq_cache_create(Main *bmain, Scene *scene)
Definition: image_cache.c:494
static void seq_cache_unlock(Scene *scene)
Definition: image_cache.c:174
bool seq_cache_put_if_possible(const SeqRenderData *context, Sequence *seq, float timeline_frame, int type, ImBuf *ibuf)
Definition: image_cache.c:790
bool seq_cache_is_full(void)
Definition: image_cache.c:919
static int get_stored_types_flag(Scene *scene, SeqCacheKey *key)
Definition: image_cache.c:205
static void seq_cache_set_temp_cache_linked(Scene *scene, SeqCacheKey *base)
Definition: image_cache.c:470
static unsigned int seq_hash_render_data(const SeqRenderData *a)
Definition: image_cache.c:101
static void seq_cache_valfree(void *val)
Definition: image_cache.c:194
#define THUMB_CACHE_LIMIT
Definition: image_cache.c:72
void seq_cache_put(const SeqRenderData *context, Sequence *seq, float timeline_frame, int type, ImBuf *i)
Definition: image_cache.c:846
static SeqCache * seq_cache_get_from_scene(Scene *scene)
Definition: image_cache.c:156
static SeqCacheKey * seq_cache_allocate_key(SeqCache *cache, const SeqRenderData *context, Sequence *seq, const float timeline_frame, const int type)
Definition: image_cache.c:534
static ImBuf * seq_cache_get_ex(SeqCache *cache, SeqCacheKey *key)
Definition: image_cache.c:261
static SeqCacheKey * seq_cache_get_item_for_removal(Scene *scene)
Definition: image_cache.c:390
static void seq_cache_relink_keys(SeqCacheKey *link_next, SeqCacheKey *link_prev)
Definition: image_cache.c:274
void seq_cache_free_temp_cache(Scene *scene, short id, int timeline_frame)
Definition: image_cache.c:547
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))
Definition: image_cache.c:891
static float seq_cache_timeline_frame_to_frame_index(Scene *scene, Sequence *seq, float timeline_frame, int type)
Definition: image_cache.c:136
static SeqCacheKey * seq_cache_choose_key(Scene *scene, SeqCacheKey *lkey, SeqCacheKey *rkey)
Definition: image_cache.c:286
static ThreadMutex cache_create_lock
Definition: image_cache.c:90
static bool seq_cmp_render_data(const SeqRenderData *a, const SeqRenderData *b)
Definition: image_cache.c:92
struct ImBuf * seq_cache_get(const SeqRenderData *context, Sequence *seq, float timeline_frame, int type)
Definition: image_cache.c:726
static void seq_cache_keyfree(void *val)
Definition: image_cache.c:188
static void seq_cache_put_ex(Scene *scene, SeqCacheKey *key, ImBuf *ibuf)
Definition: image_cache.c:221
void seq_cache_cleanup_sequence(Scene *scene, Sequence *seq, Sequence *seq_changed, int invalidate_types, bool force_seq_changed_range)
Definition: image_cache.c:626
float seq_cache_frame_index_to_timeline_frame(Sequence *seq, float frame_index)
Definition: image_cache.c:151
static bool seq_cache_hashcmp(const void *a_, const void *b_)
Definition: image_cache.c:127
void seq_cache_cleanup_all(Main *bmain)
Definition: image_cache.c:596
static void seq_cache_lock(Scene *scene)
Definition: image_cache.c:165
void seq_cache_destruct(Scene *scene)
Definition: image_cache.c:576
static void seq_cache_populate_key(SeqCacheKey *key, const SeqRenderData *context, Sequence *seq, const float timeline_frame, const int type)
Definition: image_cache.c:515
static size_t seq_cache_get_mem_total(void)
Definition: image_cache.c:183
void seq_cache_thumbnail_cleanup(Scene *scene, rctf *view_area_safe)
Definition: image_cache.c:685
struct SeqCache SeqCache
bool seq_cache_recycle_item(Scene *scene)
Definition: image_cache.c:446
struct SeqCacheItem SeqCacheItem
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
size_t(* MEM_get_memory_in_use)(void)
Definition: mallocn.c:45
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
static ulong * next
static unsigned a[3]
Definition: RandGen.cpp:78
SymEdge< T > * prev(const SymEdge< T > *se)
Definition: delaunay_2d.cc:105
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
void seq_prefetch_get_time_range(Scene *scene, int *start, int *end)
Definition: prefetch.c:183
bool seq_prefetch_job_is_running(Scene *scene)
Definition: prefetch.c:110
void SEQ_prefetch_stop(Scene *scene)
Definition: prefetch.c:254
Sequence * seq_prefetch_get_original_sequence(Sequence *seq, Scene *scene)
Definition: prefetch.c:150
SeqRenderData * seq_prefetch_get_original_context(const SeqRenderData *context)
Definition: prefetch.c:156
int SEQ_render_thumbnails_guaranteed_set_frame_step_get(const Scene *scene, const Sequence *seq)
Definition: render.c:2142
_W64 int intptr_t
Definition: stdint.h:118
int SEQ_time_left_handle_frame_get(const Scene *UNUSED(scene), const Sequence *seq)
Definition: strip_time.c:506
float seq_give_frame_index(const Scene *scene, Sequence *seq, float timeline_frame)
Definition: strip_time.c:52
float SEQ_time_start_frame_get(const Sequence *seq)
Definition: strip_time.c:494
int SEQ_time_right_handle_frame_get(const Scene *scene, const Sequence *seq)
Definition: strip_time.c:515
int64_t disk_cache_timestamp
struct SeqCache * cache
void * next
Definition: DNA_ID.h:369
void * userdata
void * first
Definition: DNA_listBase.h:31
Definition: BKE_main.h:121
ListBase scenes
Definition: BKE_main.h:168
struct Editing * ed
struct RenderData r
struct SeqCache * cache_owner
Definition: image_cache.c:86
struct ImBuf * ibuf
Definition: image_cache.c:87
struct SeqCacheKey * link_next
Definition: image_cache.h:26
float timeline_frame
Definition: image_cache.h:30
float frame_index
Definition: image_cache.h:29
eSeqTaskId task_id
Definition: image_cache.h:34
struct Sequence * seq
Definition: image_cache.h:27
bool is_temp_cache
Definition: image_cache.h:32
struct SeqRenderData context
Definition: image_cache.h:28
struct SeqCache * cache_owner
Definition: image_cache.h:23
struct SeqCacheKey * link_prev
Definition: image_cache.h:25
ThreadMutex iterator_mutex
Definition: image_cache.c:77
struct GHash * hash
Definition: image_cache.c:76
int thumbnail_count
Definition: image_cache.c:82
struct SeqCacheKey * last_key
Definition: image_cache.c:80
struct SeqDiskCache * disk_cache
Definition: image_cache.c:81
struct BLI_mempool * items_pool
Definition: image_cache.c:79
struct BLI_mempool * keys_pool
Definition: image_cache.c:78
Main * bmain
Definition: image_cache.c:75
float xmax
Definition: DNA_vec_types.h:69
float xmin
Definition: DNA_vec_types.h:69
float ymax
Definition: DNA_vec_types.h:70
float ymin
Definition: DNA_vec_types.h:70