[Bf-blender-cvs] [78698a2] master: Add ItemDestroyable to the cache limitor

Sergey Sharybin noreply at git.blender.org
Sun Dec 22 09:46:34 CET 2013


Commit: 78698a2ecf9d17340ce337ecf73ce6e355299f89
Author: Sergey Sharybin
Date:   Tue Dec 10 14:40:09 2013 +0600
http://developer.blender.org/rB78698a2ecf9d17340ce337ecf73ce6e355299f89

Add ItemDestroyable to the cache limitor

This callback is used when cache limiter needs to remove
some cached objects when running out of limit.

>From blender side it's used to keep painted images always
in memory.

This fixes issue when painted images were removing from
the memory after image cache rewrite.

===================================================================

M	intern/memutil/MEM_CacheLimiter.h
M	intern/memutil/MEM_CacheLimiterC-Api.h
M	intern/memutil/intern/MEM_CacheLimiterC-Api.cpp
M	source/blender/imbuf/intern/moviecache.c

===================================================================

diff --git a/intern/memutil/MEM_CacheLimiter.h b/intern/memutil/MEM_CacheLimiter.h
index 32f97a2..88e0683 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 7579dbd..a6a3ec8 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 0e11fbe..6156b51 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 c042831..3718cb2 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)




More information about the Bf-blender-cvs mailing list