Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--intern/memutil/MEM_CacheLimiter.h23
-rw-r--r--intern/memutil/MEM_CacheLimiterC-Api.h6
-rw-r--r--intern/memutil/intern/MEM_CacheLimiterC-Api.cpp6
-rw-r--r--source/blender/imbuf/intern/moviecache.c15
4 files changed, 48 insertions, 2 deletions
diff --git a/intern/memutil/MEM_CacheLimiter.h b/intern/memutil/MEM_CacheLimiter.h
index 32f97a21815..88e06833b4a 100644
--- a/intern/memutil/MEM_CacheLimiter.h
+++ b/intern/memutil/MEM_CacheLimiter.h
@@ -137,6 +137,7 @@ class MEM_CacheLimiter {
public:
typedef size_t (*MEM_CacheLimiter_DataSize_Func) (void *data);
typedef int (*MEM_CacheLimiter_ItemPriority_Func) (void *item, int default_priority);
+ typedef bool (*MEM_CacheLimiter_ItemDestroyable_Func) (void *item);
MEM_CacheLimiter(MEM_CacheLimiter_DataSize_Func data_size_func)
: data_size_func(data_size_func) {
@@ -230,11 +231,28 @@ public:
this->item_priority_func = item_priority_func;
}
+ void set_item_destroyable_func(MEM_CacheLimiter_ItemDestroyable_Func item_destroyable_func) {
+ this->item_destroyable_func = item_destroyable_func;
+ }
+
private:
typedef MEM_CacheLimiterHandle<T> *MEM_CacheElementPtr;
typedef std::list<MEM_CacheElementPtr, MEM_Allocator<MEM_CacheElementPtr> > MEM_CacheQueue;
typedef typename MEM_CacheQueue::iterator iterator;
+ /* Check whether element can be destroyed when enforcing cache limits */
+ bool can_destroy_element(MEM_CacheElementPtr &elem) {
+ if (!elem->can_destroy()) {
+ /* Element is referenced */
+ return false;
+ }
+ if (item_destroyable_func) {
+ if (!item_destroyable_func(elem->get()->get_data()))
+ return false;
+ }
+ return true;
+ }
+
MEM_CacheElementPtr get_least_priority_destroyable_element(void) {
if (queue.empty())
return NULL;
@@ -244,7 +262,7 @@ private:
if (!item_priority_func) {
for (iterator it = queue.begin(); it != queue.end(); it++) {
MEM_CacheElementPtr elem = *it;
- if (!elem->can_destroy())
+ if (!can_destroy_element(elem))
continue;
best_match_elem = elem;
break;
@@ -258,7 +276,7 @@ private:
for (it = queue.begin(), i = 0; it != queue.end(); it++, i++) {
MEM_CacheElementPtr elem = *it;
- if (!elem->can_destroy())
+ if (!can_destroy_element(elem))
continue;
/* by default 0 means highest priority element */
@@ -280,6 +298,7 @@ private:
MEM_CacheQueue queue;
MEM_CacheLimiter_DataSize_Func data_size_func;
MEM_CacheLimiter_ItemPriority_Func item_priority_func;
+ MEM_CacheLimiter_ItemDestroyable_Func item_destroyable_func;
};
#endif // __MEM_CACHELIMITER_H__
diff --git a/intern/memutil/MEM_CacheLimiterC-Api.h b/intern/memutil/MEM_CacheLimiterC-Api.h
index 7579dbdd4d1..a6a3ec85777 100644
--- a/intern/memutil/MEM_CacheLimiterC-Api.h
+++ b/intern/memutil/MEM_CacheLimiterC-Api.h
@@ -47,6 +47,9 @@ typedef size_t (*MEM_CacheLimiter_DataSize_Func) (void*);
/* function used to measure priority of item when freeing memory */
typedef int (*MEM_CacheLimiter_ItemPriority_Func) (void*, int);
+/* function to check whether item could be destroyed */
+typedef bool (*MEM_CacheLimiter_ItemDestroyable_Func) (void*);
+
#ifndef __MEM_CACHELIMITER_H__
void MEM_CacheLimiter_set_maximum(size_t m);
size_t MEM_CacheLimiter_get_maximum(void);
@@ -145,6 +148,9 @@ void *MEM_CacheLimiter_get(MEM_CacheLimiterHandleC *handle);
void MEM_CacheLimiter_ItemPriority_Func_set(MEM_CacheLimiterC *This,
MEM_CacheLimiter_ItemPriority_Func item_priority_func);
+void MEM_CacheLimiter_ItemDestroyable_Func_set(MEM_CacheLimiterC *This,
+ MEM_CacheLimiter_ItemDestroyable_Func item_destroyable_func);
+
size_t MEM_CacheLimiter_get_memory_in_use(MEM_CacheLimiterC *This);
#ifdef __cplusplus
diff --git a/intern/memutil/intern/MEM_CacheLimiterC-Api.cpp b/intern/memutil/intern/MEM_CacheLimiterC-Api.cpp
index 0e11fbed4e7..6156b511f01 100644
--- a/intern/memutil/intern/MEM_CacheLimiterC-Api.cpp
+++ b/intern/memutil/intern/MEM_CacheLimiterC-Api.cpp
@@ -203,6 +203,12 @@ void MEM_CacheLimiter_ItemPriority_Func_set(MEM_CacheLimiterC *This,
cast(This)->get_cache()->set_item_priority_func(item_priority_func);
}
+void MEM_CacheLimiter_ItemDestroyable_Func_set(MEM_CacheLimiterC *This,
+ MEM_CacheLimiter_ItemDestroyable_Func item_destroyable_func)
+{
+ cast(This)->get_cache()->set_item_destroyable_func(item_destroyable_func);
+}
+
size_t MEM_CacheLimiter_get_memory_in_use(MEM_CacheLimiterC *This)
{
return cast(This)->get_cache()->get_memory_in_use();
diff --git a/source/blender/imbuf/intern/moviecache.c b/source/blender/imbuf/intern/moviecache.c
index c042831a93f..3718cb270c9 100644
--- a/source/blender/imbuf/intern/moviecache.c
+++ b/source/blender/imbuf/intern/moviecache.c
@@ -254,11 +254,26 @@ static int get_item_priority(void *item_v, int default_priority)
return priority;
}
+static bool get_item_destroyable(void *item_v)
+{
+ MovieCacheItem *item = (MovieCacheItem *) item_v;
+ /* IB_BITMAPDIRTY means image was modified from inside blender and
+ * changes are not saved to disk.
+ *
+ * Such buffers are never to be freed.
+ */
+ if (item->ibuf->userflags & IB_BITMAPDIRTY) {
+ return false;
+ }
+ return true;
+}
+
void IMB_moviecache_init(void)
{
limitor = new_MEM_CacheLimiter(IMB_moviecache_destructor, get_item_size);
MEM_CacheLimiter_ItemPriority_Func_set(limitor, get_item_priority);
+ MEM_CacheLimiter_ItemDestroyable_Func_set(limitor, get_item_destroyable);
}
void IMB_moviecache_destruct(void)