[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [50780] trunk/blender: Fix #32579: Sequencer crash when changing render dimensions

Sergey Sharybin sergey.vfx at gmail.com
Thu Sep 20 14:59:17 CEST 2012


Revision: 50780
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=50780
Author:   nazgul
Date:     2012-09-20 12:59:16 +0000 (Thu, 20 Sep 2012)
Log Message:
-----------
Fix #32579: Sequencer crash when changing render dimensions

Memory limitor's queue could be affected when it's being iterated
on enforcing limits -- that's because iteration could free color
managed image buffers.

Fixed by getting least priority element after every element was
freed. Could be optimized a bit, but it anyway shouldn't be so
slow due to specific of cache limiting and limit enforcing finish
condition.

Modified Paths:
--------------
    trunk/blender/intern/memutil/MEM_CacheLimiter.h
    trunk/blender/source/blender/imbuf/intern/moviecache.c

Modified: trunk/blender/intern/memutil/MEM_CacheLimiter.h
===================================================================
--- trunk/blender/intern/memutil/MEM_CacheLimiter.h	2012-09-20 12:42:22 UTC (rev 50779)
+++ trunk/blender/intern/memutil/MEM_CacheLimiter.h	2012-09-20 12:59:16 UTC (rev 50780)
@@ -123,20 +123,11 @@
 		parent->touch(this);
 	}
 
-	void set_priority(int priority) {
-		this->priority = priority;
-	}
-
-	int get_priority(void) {
-		return this->priority;
-	}
-
 private:
 	friend class MEM_CacheLimiter<T>;
 
 	T * data;
 	int refcount;
-	int priority;
 	typename std::list<MEM_CacheLimiterHandle<T> *, MEM_Allocator<MEM_CacheLimiterHandle<T> *> >::iterator me;
 	MEM_CacheLimiter<T> * parent;
 };
@@ -171,7 +162,6 @@
 	}
 
 	void enforce_limits() {
-		MEM_CachePriorityQueue priority_queue;
 		size_t max = MEM_CacheLimiter_get_maximum();
 		size_t mem_in_use, cur_size;
 
@@ -190,13 +180,12 @@
 			return;
 		}
 
-		priority_queue = get_priority_queue();
+		while (!queue.empty() && mem_in_use > max) {
+			MEM_CacheElementPtr elem = get_least_priority_destroyable_element();
 
-		while (!priority_queue.empty() && mem_in_use > max) {
-			MEM_CacheElementPtr elem = priority_queue.top();
+			if (!elem)
+				break;
 
-			priority_queue.pop();
-
 			if (getDataSize) {
 				cur_size = getDataSize(elem->get()->get_data());
 			}
@@ -232,14 +221,6 @@
 	typedef std::list<MEM_CacheElementPtr, MEM_Allocator<MEM_CacheElementPtr> > MEM_CacheQueue;
 	typedef typename MEM_CacheQueue::iterator iterator;
 
-	struct compare_element_priority : public std::binary_function<MEM_CacheElementPtr, MEM_CacheElementPtr, bool> {
-		bool operator()(const MEM_CacheElementPtr left_elem, const MEM_CacheElementPtr right_elem) const {
-			return left_elem->get_priority() > right_elem->get_priority();
-		}
-	};
-
-	typedef std::priority_queue<MEM_CacheElementPtr, std::vector<MEM_CacheElementPtr>, compare_element_priority > MEM_CachePriorityQueue;
-
 	size_t total_size() {
 		size_t size = 0;
 		for (iterator it = queue.begin(); it != queue.end(); it++) {
@@ -248,28 +229,35 @@
 		return size;
 	}
 
-	MEM_CachePriorityQueue get_priority_queue(void) {
-		MEM_CachePriorityQueue priority_queue;
+	MEM_CacheElementPtr get_least_priority_destroyable_element(void) {
+		if (queue.empty())
+			return NULL;
+
+		if (!getItemPriority)
+			return *queue.begin();
+
+		MEM_CacheElementPtr best_match_elem = NULL;
+		int best_match_priority = 0;
 		iterator it;
 		int i;
 
 		for (it = queue.begin(), i = 0; it != queue.end(); it++, i++) {
 			MEM_CacheElementPtr elem = *it;
-			int priority;
 
+			if (!elem->can_destroy())
+				continue;
+
 			/* by default 0 means higherst priority element */
-			priority = -(queue.size() - i - 1);
+			int priority = -(queue.size() - i - 1);
+			priority = getItemPriority(elem->get()->get_data(), priority);
 
-			if (getItemPriority) {
-				priority = getItemPriority(elem->get()->get_data(), priority);
+			if (priority < best_match_priority || best_match_elem == NULL) {
+				best_match_priority = priority;
+				best_match_elem = elem;
 			}
-
-			elem->set_priority(priority);
-
-			priority_queue.push(elem);
 		}
 
-		return priority_queue;
+		return best_match_elem;
 	}
 
 	MEM_CacheQueue queue;

Modified: trunk/blender/source/blender/imbuf/intern/moviecache.c
===================================================================
--- trunk/blender/source/blender/imbuf/intern/moviecache.c	2012-09-20 12:42:22 UTC (rev 50779)
+++ trunk/blender/source/blender/imbuf/intern/moviecache.c	2012-09-20 12:59:16 UTC (rev 50780)
@@ -386,7 +386,7 @@
 
 void IMB_moviecache_free(MovieCache *cache)
 {
-	PRINT("%s: create '%s' free\n", __func__, cache->name);
+	PRINT("%s: cache '%s' free\n", __func__, cache->name);
 
 	BLI_ghash_free(cache->hash, moviecache_keyfree, moviecache_valfree);
 




More information about the Bf-blender-cvs mailing list