69 if (*cache ==
nullptr) {
70 *cache = MEM_new<FinalImageCache>(__func__);
77 if (scene ==
nullptr || scene->
ed ==
nullptr) {
90 const FinalImageCache::Key key = {
91 seqbasep, int(
math::round(timeline_frame)), view_id, display_channel, image_size};
97 if (cache ==
nullptr) {
100 res = cache->
map_.lookup_default(key,
nullptr);
111 const float timeline_frame,
113 const int display_channel,
117 const FinalImageCache::Key key = {
118 seqbasep, int(
math::round(timeline_frame)), view_id, display_channel, image_size};
125 cache->
map_.add_or_modify(
127 [&](
ImBuf **value) { *value = image; },
128 [&](
ImBuf **existing) {
137 const float timeline_frame_start,
138 const float timeline_frame_end)
142 if (cache ==
nullptr) {
146 const int key_start = int(
math::floor(timeline_frame_start));
147 const int key_end = int(
math::ceil(timeline_frame_end));
149 for (
auto it = cache->
map_.items().begin(); it != cache->
map_.items().end(); it++) {
150 const int key = (*it).key.timeline_frame;
151 if (key >= key_start && key <= key_end) {
153 cache->
map_.remove(it);
162 if (cache !=
nullptr) {
171 if (cache !=
nullptr) {
180 void callback_iter(
void *userdata,
int timeline_frame))
184 if (cache ==
nullptr) {
187 for (
const FinalImageCache::Key &frame_view : cache->
map_.keys()) {
188 callback_iter(userdata, frame_view.timeline_frame);
196 if (cache ==
nullptr) {
200 for (
ImBuf *frame : cache->
map_.values()) {
210 if (cache ==
nullptr) {
213 return cache->
map_.size();
220 if (cache ==
nullptr) {
230 int cur_prefetch_start = std::numeric_limits<int>::min();
231 int cur_prefetch_end = std::numeric_limits<int>::min();
234 const int cur_frame = scene->
r.cfra;
235 FinalImageCache::Key best_key = {};
236 ImBuf *best_item =
nullptr;
238 for (
const auto &item : cache->
map_.items()) {
239 const int item_frame = item.key.timeline_frame;
240 if (item_frame >= cur_prefetch_start && item_frame <= cur_prefetch_end) {
246 if (item_frame < cur_frame) {
247 score = (cur_frame - item_frame) * 2;
249 else if (item_frame > cur_frame) {
250 score = item_frame - cur_frame;
252 if (score > best_score) {
254 best_item = item.value;
260 if (best_item !=
nullptr) {
262 cache->
map_.remove(best_key);
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)
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)
ImBuf * final_image_cache_get(Scene *scene, const ListBase *seqbasep, float timeline_frame, int view_id, int display_channel, int2 image_size)
bool final_image_cache_evict(Scene *scene)
void final_image_cache_put(Scene *scene, const ListBase *seqbasep, const float timeline_frame, const int view_id, const int display_channel, int2 image_size, ImBuf *image)
size_t final_image_cache_get_image_count(const Scene *scene)
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)
VecBase< int32_t, 2 > int2
FinalImageCache * final_image_cache
bool operator==(const Key &other) const
const ListBase * seqbasep