65 if (*cache ==
nullptr) {
66 *cache = MEM_new<FinalImageCache>(__func__);
73 if (scene ==
nullptr || scene->
ed ==
nullptr) {
81 const FinalImageCache::Key key = {int(
math::round(timeline_frame)), view_id, display_channel};
87 if (cache ==
nullptr) {
90 res = cache->
map_.lookup_default(key,
nullptr);
100 Scene *scene,
float timeline_frame,
int view_id,
int display_channel,
ImBuf *image)
102 const FinalImageCache::Key key = {int(
math::round(timeline_frame)), view_id, display_channel};
109 cache->
map_.add_or_modify(
111 [&](
ImBuf **value) { *value = image; },
112 [&](
ImBuf **existing) {
121 const float timeline_frame_start,
122 const float timeline_frame_end)
126 if (cache ==
nullptr) {
130 const int key_start = int(
math::floor(timeline_frame_start));
131 const int key_end = int(
math::ceil(timeline_frame_end));
133 for (
auto it = cache->
map_.items().begin(); it != cache->
map_.items().end(); it++) {
134 const int key = (*it).key.timeline_frame;
135 if (key >= key_start && key <= key_end) {
137 cache->
map_.remove(it);
146 if (cache !=
nullptr) {
155 if (cache !=
nullptr) {
164 void callback_iter(
void *userdata,
int timeline_frame))
168 if (cache ==
nullptr) {
171 for (
const FinalImageCache::Key &frame_view : cache->
map_.keys()) {
172 callback_iter(userdata, frame_view.timeline_frame);
180 if (cache ==
nullptr) {
184 for (
ImBuf *frame : cache->
map_.values()) {
194 if (cache ==
nullptr) {
197 return cache->
map_.size();
204 if (cache ==
nullptr) {
214 int cur_prefetch_start = std::numeric_limits<int>::min();
215 int cur_prefetch_end = std::numeric_limits<int>::min();
220 const bool prefetch_loops_around = cur_prefetch_start > cur_prefetch_end;
222 const int timeline_start =
PSFRA;
223 const int timeline_end =
PEFRA;
226 const int cur_frame = prefetch_loops_around ? timeline_start : scene->
r.cfra;
228 FinalImageCache::Key best_key = {};
229 ImBuf *best_item =
nullptr;
231 for (
const auto &item : cache->
map_.items()) {
232 const int item_frame = item.key.timeline_frame;
233 if (prefetch_loops_around) {
234 if (item_frame >= timeline_start && item_frame <= cur_prefetch_end) {
237 if (item_frame >= cur_prefetch_start && item_frame <= timeline_end) {
241 else if (item_frame >= cur_prefetch_start && item_frame <= cur_prefetch_end) {
247 if (item_frame < cur_frame) {
248 score = (cur_frame - item_frame) * 2;
250 else if (item_frame > cur_frame) {
251 score = item_frame - cur_frame;
253 if (score > best_score) {
255 best_item = item.value;
261 if (best_item !=
nullptr) {
263 cache->
map_.remove(best_key);
@ SEQ_CACHE_STORE_FINAL_OUT
void IMB_freeImBuf(ImBuf *ibuf)
void IMB_refImBuf(ImBuf *ibuf)
size_t IMB_get_size_in_memory(const ImBuf *ibuf)
unsigned long long int uint64_t
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
static Mutex final_image_cache_mutex
size_t final_image_cache_calc_memory_size(const Scene *scene)
static FinalImageCache * ensure_final_image_cache(Scene *scene)
ImBuf * final_image_cache_get(Scene *scene, float timeline_frame, int view_id, int display_channel)
void final_image_cache_invalidate_frame_range(Scene *scene, const float timeline_frame_start, const float timeline_frame_end)
void final_image_cache_iterate(Scene *scene, void *userdata, void callback_iter(void *userdata, int timeline_frame))
void final_image_cache_destroy(Scene *scene)
void final_image_cache_clear(Scene *scene)
bool final_image_cache_evict(Scene *scene)
size_t final_image_cache_get_image_count(const Scene *scene)
void final_image_cache_put(Scene *scene, float timeline_frame, int view_id, int display_channel, ImBuf *image)
static FinalImageCache * query_final_image_cache(const Scene *scene)
void seq_prefetch_get_time_range(Scene *scene, int *r_start, int *r_end)
uint64_t get_default_hash(const T &v, const Args &...args)
FinalImageCache * final_image_cache
bool operator==(const Key &other) const