From e28fcec04201fb3be19960a0b91fcb20f8d6c56d Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Mon, 13 Aug 2012 10:56:36 +0000 Subject: Fix for [#32220] regression - DistortionCache is never freed. * at max 10 cache items will be available. Items will be removed by latest usage. * number of cached items can be adjusted in code * added deinitialization of compositor when blender exists. * updated scons and cmake build files --- source/blender/compositor/COM_compositor.h | 5 ++++ .../blender/compositor/intern/COM_compositor.cpp | 28 +++++++++++++++------ .../operations/COM_MovieDistortionOperation.cpp | 28 ++++++++++++++++++++- .../operations/COM_MovieDistortionOperation.h | 29 ++++++++++++++++++++++ source/blender/windowmanager/CMakeLists.txt | 2 ++ source/blender/windowmanager/SConscript | 2 +- source/blender/windowmanager/intern/wm_init_exit.c | 6 ++++- 7 files changed, 90 insertions(+), 10 deletions(-) (limited to 'source/blender') diff --git a/source/blender/compositor/COM_compositor.h b/source/blender/compositor/COM_compositor.h index 4e955ea3df1..982c3764c62 100644 --- a/source/blender/compositor/COM_compositor.h +++ b/source/blender/compositor/COM_compositor.h @@ -299,6 +299,11 @@ extern "C" { */ void COM_execute(RenderData *rd, bNodeTree *editingtree, int rendering); +/** + * @brief Deinitialize the compositor caches and allocated memory. + */ +void COM_deinitialize(); + /** * @brief Return a list of highlighted bnodes pointers. * @return diff --git a/source/blender/compositor/intern/COM_compositor.cpp b/source/blender/compositor/intern/COM_compositor.cpp index 2402f9a1163..7dcb3572a14 100644 --- a/source/blender/compositor/intern/COM_compositor.cpp +++ b/source/blender/compositor/intern/COM_compositor.cpp @@ -32,23 +32,24 @@ extern "C" { #include "COM_ExecutionSystem.h" #include "COM_WorkScheduler.h" #include "OCL_opencl.h" +#include "COM_MovieDistortionOperation.h" -static ThreadMutex compositorMutex; +static ThreadMutex s_compositorMutex; static char is_compositorMutex_init = FALSE; void COM_execute(RenderData *rd, bNodeTree *editingtree, int rendering) { if (is_compositorMutex_init == FALSE) { /// TODO: move to blender startup phase - memset(&compositorMutex, 0, sizeof(compositorMutex)); - BLI_mutex_init(&compositorMutex); + memset(&s_compositorMutex, 0, sizeof(s_compositorMutex)); + BLI_mutex_init(&s_compositorMutex); OCL_init(); WorkScheduler::initialize(); ///TODO: call workscheduler.deinitialize somewhere is_compositorMutex_init = TRUE; } - BLI_mutex_lock(&compositorMutex); + BLI_mutex_lock(&s_compositorMutex); if (editingtree->test_break(editingtree->tbh)) { // during editing multiple calls to this method can be triggered. // make sure one the last one will be doing the work. - BLI_mutex_unlock(&compositorMutex); + BLI_mutex_unlock(&s_compositorMutex); return; } @@ -67,7 +68,7 @@ void COM_execute(RenderData *rd, bNodeTree *editingtree, int rendering) if (editingtree->test_break(editingtree->tbh)) { // during editing multiple calls to this method can be triggered. // make sure one the last one will be doing the work. - BLI_mutex_unlock(&compositorMutex); + BLI_mutex_unlock(&s_compositorMutex); return; } } @@ -77,5 +78,18 @@ void COM_execute(RenderData *rd, bNodeTree *editingtree, int rendering) system->execute(); delete system; - BLI_mutex_unlock(&compositorMutex); + BLI_mutex_unlock(&s_compositorMutex); +} + +void COM_deinitialize() +{ + if (is_compositorMutex_init) + { + BLI_mutex_lock(&s_compositorMutex); + deintializeDistortionCache(); + WorkScheduler::deinitialize(); + is_compositorMutex_init = FALSE; + BLI_mutex_unlock(&s_compositorMutex); + BLI_mutex_end(&s_compositorMutex); + } } diff --git a/source/blender/compositor/operations/COM_MovieDistortionOperation.cpp b/source/blender/compositor/operations/COM_MovieDistortionOperation.cpp index 8150e3eda75..a3e00e9325b 100644 --- a/source/blender/compositor/operations/COM_MovieDistortionOperation.cpp +++ b/source/blender/compositor/operations/COM_MovieDistortionOperation.cpp @@ -31,6 +31,15 @@ extern "C" { vector s_cache; +void deintializeDistortionCache(void) +{ + while (s_cache.size()>0) + { + DistortionCache * cache = s_cache.back(); + s_cache.pop_back(); + delete cache; + } +} MovieDistortionOperation::MovieDistortionOperation(bool distortion) : NodeOperation() { @@ -52,12 +61,14 @@ void MovieDistortionOperation::initExecution() BKE_movieclip_user_set_frame(&clipUser, this->m_framenumber); BKE_movieclip_get_size(this->m_movieClip, &clipUser, &calibration_width, &calibration_height); - for (unsigned int i = 0; i < s_cache.size(); i++) { + for (unsigned int i = 0; i < s_cache.size(); i++) + { DistortionCache *c = (DistortionCache *)s_cache[i]; if (c->isCacheFor(this->m_movieClip, this->m_width, this->m_height, calibration_width, calibration_height, this->m_distortion)) { this->m_cache = c; + this->m_cache->updateLastUsage(); return; } } @@ -75,6 +86,21 @@ void MovieDistortionOperation::deinitExecution() { this->m_inputOperation = NULL; this->m_movieClip = NULL; + while (s_cache.size() > COM_DISTORTIONCACHE_MAXSIZE) + { + double minTime = PIL_check_seconds_timer(); + vector::iterator minTimeIterator = s_cache.begin(); + for (vector::iterator it = s_cache.begin(); it < s_cache.end(); it ++) + { + DistortionCache * cache = *it; + if (cache->getTimeLastUsage()getTimeLastUsage(); + minTimeIterator = it; + } + } + s_cache.erase(minTimeIterator); + } } diff --git a/source/blender/compositor/operations/COM_MovieDistortionOperation.h b/source/blender/compositor/operations/COM_MovieDistortionOperation.h index a58349f9324..00723d92a84 100644 --- a/source/blender/compositor/operations/COM_MovieDistortionOperation.h +++ b/source/blender/compositor/operations/COM_MovieDistortionOperation.h @@ -27,8 +27,11 @@ #include "DNA_movieclip_types.h" extern "C" { #include "BKE_tracking.h" + #include "PIL_time.h" } +#define COM_DISTORTIONCACHE_MAXSIZE 10 + class DistortionCache { private: float m_k1; @@ -44,6 +47,8 @@ private: bool m_inverted; float *m_buffer; int *m_bufferCalculated; + double timeLastUsage; + public: DistortionCache(MovieClip *movieclip, int width, int height, int calibration_width, int calibration_height, bool inverted) { this->m_k1 = movieclip->tracking.camera.k1; @@ -62,7 +67,29 @@ public: for (int i = 0; i < this->m_width * this->m_height; i++) { this->m_bufferCalculated[i] = 0; } + this->updateLastUsage(); + } + + ~DistortionCache() { + if (this->m_buffer) { + delete[] this->m_buffer; + this->m_buffer = NULL; + } + + if (this->m_bufferCalculated) { + delete[] this->m_bufferCalculated; + this->m_bufferCalculated = NULL; + } } + + void updateLastUsage() { + this->timeLastUsage = PIL_check_seconds_timer(); + } + + inline double getTimeLastUsage() { + return this->timeLastUsage; + } + bool isCacheFor(MovieClip *movieclip, int width, int height, int calibration_width, int claibration_height, bool inverted) { return this->m_k1 == movieclip->tracking.camera.k1 && this->m_k2 == movieclip->tracking.camera.k2 && @@ -139,4 +166,6 @@ public: void setFramenumber(int framenumber) { this->m_framenumber = framenumber; } }; +void deintializeDistortionCache(void); + #endif diff --git a/source/blender/windowmanager/CMakeLists.txt b/source/blender/windowmanager/CMakeLists.txt index f44ec2f5dc8..a73d33e6b66 100644 --- a/source/blender/windowmanager/CMakeLists.txt +++ b/source/blender/windowmanager/CMakeLists.txt @@ -36,6 +36,8 @@ set(INC ../makesdna ../makesrna ../nodes + ../compositor + ../opencl ../render/extern/include ../../gameengine/BlenderRoutines ../../../intern/elbeem/extern diff --git a/source/blender/windowmanager/SConscript b/source/blender/windowmanager/SConscript index bf219bb9c06..68fdbec2cfa 100644 --- a/source/blender/windowmanager/SConscript +++ b/source/blender/windowmanager/SConscript @@ -10,7 +10,7 @@ sources = env.Glob('intern/*.c') incs = '. ../editors/include ../python ../makesdna ../blenlib ../blenkernel' incs += ' ../nodes ../imbuf ../blenloader ../render/extern/include' incs += ' ../radiosity/extern/include' -incs += ' ../makesrna ../gpu ../blenfont ../bmesh' +incs += ' ../makesrna ../gpu ../blenfont ../bmesh ../compositor' incs += ' #/intern/guardedalloc #/intern/memutil #/intern/ghost' incs += ' #/intern/elbeem #/extern/glew/include' diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index ac9b44fddb0..9047532c92c 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -113,6 +113,7 @@ #include "BKE_depsgraph.h" #include "BKE_sound.h" +#include "COM_compositor.h" static void wm_init_reports(bContext *C) { @@ -211,7 +212,6 @@ void WM_init(bContext *C, int argc, const char **argv) #ifdef WITH_COMPOSITOR if (1) { extern void *COM_linker_hack; - extern void *COM_execute; COM_linker_hack = COM_execute; } #endif @@ -414,6 +414,10 @@ void WM_exit_ext(bContext *C, const short do_python) BKE_sequencer_free_clipboard(); /* sequencer.c */ BKE_tracking_clipboard_free(); +#ifdef WITH_COMPOSITOR + COM_deinitialize(); +#endif + free_blender(); /* blender.c, does entire library and spacetypes */ // free_matcopybuf(); free_anim_copybuf(); -- cgit v1.2.3