66 if (*cache ==
nullptr) {
67 *cache = MEM_new<FinalImageCache>(__func__);
74 if (scene ==
nullptr || scene->
ed ==
nullptr) {
82 const float timeline_frame,
84 const int display_channel)
86 const FinalImageCache::Key key = {
87 seqbasep, int(
math::round(timeline_frame)), view_id, display_channel};
93 if (cache ==
nullptr) {
96 res = cache->
map_.lookup_default(key,
nullptr);
107 const float timeline_frame,
109 const int display_channel,
112 const FinalImageCache::Key key = {
113 seqbasep, int(
math::round(timeline_frame)), view_id, display_channel};
120 cache->
map_.add_or_modify(
122 [&](
ImBuf **value) { *value = image; },
123 [&](
ImBuf **existing) {
132 const float timeline_frame_start,
133 const float timeline_frame_end)
137 if (cache ==
nullptr) {
141 const int key_start = int(
math::floor(timeline_frame_start));
142 const int key_end = int(
math::ceil(timeline_frame_end));
144 for (
auto it = cache->
map_.items().begin(); it != cache->
map_.items().end(); it++) {
145 const int key = (*it).key.timeline_frame;
146 if (key >= key_start && key <= key_end) {
148 cache->
map_.remove(it);
157 if (cache !=
nullptr) {
166 if (cache !=
nullptr) {
175 void callback_iter(
void *userdata,
int timeline_frame))
179 if (cache ==
nullptr) {
182 for (
const FinalImageCache::Key &frame_view : cache->
map_.keys()) {
183 callback_iter(userdata, frame_view.timeline_frame);
191 if (cache ==
nullptr) {
195 for (
ImBuf *frame : cache->
map_.values()) {
205 if (cache ==
nullptr) {
208 return cache->
map_.size();
215 if (cache ==
nullptr) {
225 int cur_prefetch_start = std::numeric_limits<int>::min();
226 int cur_prefetch_end = std::numeric_limits<int>::min();
229 const int cur_frame = scene->
r.cfra;
230 FinalImageCache::Key best_key = {};
231 ImBuf *best_item =
nullptr;
233 for (
const auto &item : cache->
map_.items()) {
234 const int item_frame = item.key.timeline_frame;
235 if (item_frame >= cur_prefetch_start && item_frame <= cur_prefetch_end) {
241 if (item_frame < cur_frame) {
242 score = (cur_frame - item_frame) * 2;
244 else if (item_frame > cur_frame) {
245 score = item_frame - cur_frame;
247 if (score > best_score) {
249 best_item = item.value;
255 if (best_item !=
nullptr) {
257 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)
void final_image_cache_put(Scene *scene, const ListBase *seqbasep, const float timeline_frame, const int view_id, const int display_channel, ImBuf *image)
bool final_image_cache_evict(Scene *scene)
ImBuf * final_image_cache_get(Scene *scene, const ListBase *seqbasep, const float timeline_frame, const int view_id, const int display_channel)
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)
FinalImageCache * final_image_cache
bool operator==(const Key &other) const
const uint64_t hash() const
const ListBase * seqbasep