diff options
Diffstat (limited to 'intern')
-rw-r--r-- | intern/cycles/CMakeLists.txt | 1 | ||||
-rw-r--r-- | intern/cycles/blender/addon/__init__.py | 11 | ||||
-rw-r--r-- | intern/cycles/blender/addon/engine.py | 4 | ||||
-rw-r--r-- | intern/cycles/blender/blender_python.cpp | 19 | ||||
-rw-r--r-- | intern/cycles/device/device.cpp | 12 | ||||
-rw-r--r-- | intern/cycles/device/device.h | 3 | ||||
-rw-r--r-- | intern/cycles/render/scene.cpp | 9 | ||||
-rw-r--r-- | intern/cycles/render/shader.cpp | 5 | ||||
-rw-r--r-- | intern/cycles/render/shader.h | 2 | ||||
-rw-r--r-- | intern/cycles/util/CMakeLists.txt | 11 | ||||
-rw-r--r-- | intern/cycles/util/util_guarded_allocator.h | 85 | ||||
-rw-r--r-- | intern/cycles/util/util_task.cpp | 6 | ||||
-rw-r--r-- | intern/cycles/util/util_task.h | 1 | ||||
-rw-r--r-- | intern/cycles/util/util_vector.h | 15 |
14 files changed, 125 insertions, 59 deletions
diff --git a/intern/cycles/CMakeLists.txt b/intern/cycles/CMakeLists.txt index 2a0894522eb..179cba2ae5f 100644 --- a/intern/cycles/CMakeLists.txt +++ b/intern/cycles/CMakeLists.txt @@ -210,6 +210,7 @@ endif() # Subdirectories if(WITH_CYCLES_BLENDER) + add_definitions(-DWITH_BLENDER_GUARDEDALLOC) add_subdirectory(blender) endif() diff --git a/intern/cycles/blender/addon/__init__.py b/intern/cycles/blender/addon/__init__.py index c4ae6f90521..8d4438cae24 100644 --- a/intern/cycles/blender/addon/__init__.py +++ b/intern/cycles/blender/addon/__init__.py @@ -88,10 +88,17 @@ class CyclesRender(bpy.types.RenderEngine): self.report({'ERROR'}, "OSL support disabled in this build.") +def engine_exit(): + engine.exit() + + def register(): from . import ui from . import properties from . import presets + import atexit + + atexit.register(engine_exit) engine.init() @@ -107,6 +114,7 @@ def unregister(): from . import ui from . import properties from . import presets + import atexit bpy.app.handlers.version_update.remove(version_update.do_versions) @@ -114,3 +122,6 @@ def unregister(): properties.unregister() presets.unregister() bpy.utils.unregister_module(__name__) + + atexit.unregister(engine_exit) + engine_exit() diff --git a/intern/cycles/blender/addon/engine.py b/intern/cycles/blender/addon/engine.py index 42ec253613f..96dc3a59ef2 100644 --- a/intern/cycles/blender/addon/engine.py +++ b/intern/cycles/blender/addon/engine.py @@ -74,6 +74,10 @@ def init(): _cycles.init(path, user_path, bpy.app.background) +def exit(): + import _cycles + _cycles.exit() + def create(engine, data, scene, region=None, v3d=None, rv3d=None, preview_osl=False): import bpy import _cycles diff --git a/intern/cycles/blender/blender_python.cpp b/intern/cycles/blender/blender_python.cpp index 4792f9612a9..27eab0c7f68 100644 --- a/intern/cycles/blender/blender_python.cpp +++ b/intern/cycles/blender/blender_python.cpp @@ -39,6 +39,10 @@ CCL_NAMESPACE_BEGIN namespace { +/* Device list stored static (used by compute_device_list()). */ +static ccl::vector<CCLDeviceInfo> device_list; +static ccl::DeviceType device_type = DEVICE_NONE; + /* Flag describing whether debug flags were synchronized from scene. */ bool debug_flags_set = false; @@ -172,6 +176,16 @@ static PyObject *init_func(PyObject * /*self*/, PyObject *args) Py_RETURN_NONE; } + +static PyObject *exit_func(PyObject * /*self*/, PyObject * /*args*/) +{ + ShaderManager::free_memory(); + TaskScheduler::free_memory(); + Device::free_memory(); + device_list.free_memory(); + Py_RETURN_NONE; +} + static PyObject *create_func(PyObject * /*self*/, PyObject *args) { PyObject *pyengine, *pyuserpref, *pydata, *pyscene, *pyregion, *pyv3d, *pyrv3d; @@ -616,6 +630,7 @@ static PyObject *debug_flags_reset_func(PyObject * /*self*/, PyObject * /*args*/ static PyMethodDef methods[] = { {"init", init_func, METH_VARARGS, ""}, + {"exit", exit_func, METH_VARARGS, ""}, {"create", create_func, METH_VARARGS, ""}, {"free", free_func, METH_O, ""}, {"render", render_func, METH_O, ""}, @@ -648,10 +663,6 @@ static struct PyModuleDef module = { static CCLDeviceInfo *compute_device_list(DeviceType type) { - /* device list stored static */ - static ccl::vector<CCLDeviceInfo> device_list; - static ccl::DeviceType device_type = DEVICE_NONE; - /* create device list if it's not already done */ if(type != device_type) { ccl::vector<DeviceInfo>& devices = ccl::Device::available_devices(); diff --git a/intern/cycles/device/device.cpp b/intern/cycles/device/device.cpp index 02e9b0551c9..90211b23aa1 100644 --- a/intern/cycles/device/device.cpp +++ b/intern/cycles/device/device.cpp @@ -34,6 +34,8 @@ CCL_NAMESPACE_BEGIN bool Device::need_types_update = true; bool Device::need_devices_update = true; +vector<DeviceType> Device::types; +vector<DeviceInfo> Device::devices; /* Device Requested Features */ @@ -280,8 +282,6 @@ string Device::string_from_type(DeviceType type) vector<DeviceType>& Device::available_types() { - static vector<DeviceType> types; - if(need_types_update) { types.clear(); types.push_back(DEVICE_CPU); @@ -311,8 +311,6 @@ vector<DeviceType>& Device::available_types() vector<DeviceInfo>& Device::available_devices() { - static vector<DeviceInfo> devices; - if(need_devices_update) { devices.clear(); #ifdef WITH_CUDA @@ -368,4 +366,10 @@ void Device::tag_update() need_devices_update = true; } +void Device::free_memory() +{ + types.free_memory(); + devices.free_memory(); +} + CCL_NAMESPACE_END diff --git a/intern/cycles/device/device.h b/intern/cycles/device/device.h index c53cd888775..30d0003b940 100644 --- a/intern/cycles/device/device.h +++ b/intern/cycles/device/device.h @@ -269,9 +269,12 @@ public: /* Tag devices lists for update. */ static void tag_update(); + static void free_memory(); private: /* Indicted whether device types and devices lists were initialized. */ static bool need_types_update, need_devices_update; + static vector<DeviceType> types; + static vector<DeviceInfo> devices; }; CCL_NAMESPACE_END diff --git a/intern/cycles/render/scene.cpp b/intern/cycles/render/scene.cpp index 25f812221ac..62951af7f6b 100644 --- a/intern/cycles/render/scene.cpp +++ b/intern/cycles/render/scene.cpp @@ -34,13 +34,10 @@ #include "tables.h" #include "util_foreach.h" +#include "util_guarded_allocator.h" +#include "util_logging.h" #include "util_progress.h" -#ifdef WITH_CYCLES_DEBUG -# include "util_guarded_allocator.h" -# include "util_logging.h" -#endif - CCL_NAMESPACE_BEGIN Scene::Scene(const SceneParams& params_, const DeviceInfo& device_info_) @@ -245,11 +242,9 @@ void Scene::device_update(Device *device_, Progress& progress) device->const_copy_to("__data", &dscene.data, sizeof(dscene.data)); } -#ifdef WITH_CYCLES_DEBUG VLOG(1) << "System memory statistics after full device sync:\n" << " Usage: " << util_guarded_get_mem_used() << "\n" << " Peak: " << util_guarded_get_mem_peak(); -#endif } Scene::MotionType Scene::need_motion(bool advanced_shading) diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp index 0b3509fa1b1..09a6061abea 100644 --- a/intern/cycles/render/shader.cpp +++ b/intern/cycles/render/shader.cpp @@ -531,5 +531,10 @@ void ShaderManager::get_requested_features(Scene *scene, } } +void ShaderManager::free_memory() +{ + beckmann_table.free_memory(); +} + CCL_NAMESPACE_END diff --git a/intern/cycles/render/shader.h b/intern/cycles/render/shader.h index 8b3969de88e..d7692a2b6f5 100644 --- a/intern/cycles/render/shader.h +++ b/intern/cycles/render/shader.h @@ -169,6 +169,8 @@ public: void get_requested_features(Scene *scene, DeviceRequestedFeatures *requested_features); + static void free_memory(); + protected: ShaderManager(); diff --git a/intern/cycles/util/CMakeLists.txt b/intern/cycles/util/CMakeLists.txt index 8367d21bfc6..d4f6a49953b 100644 --- a/intern/cycles/util/CMakeLists.txt +++ b/intern/cycles/util/CMakeLists.txt @@ -40,8 +40,10 @@ set(SRC_HEADERS util_atomic.h util_boundbox.h util_debug.h + util_guarded_allocator.cpp util_foreach.h util_function.h + util_guarded_allocator.h util_half.h util_hash.h util_image.h @@ -77,15 +79,6 @@ set(SRC_HEADERS util_xml.h ) -if(WITH_CYCLES_DEBUG) - list(APPEND SRC - util_guarded_allocator.cpp - ) - list(APPEND SRC_HEADERS - util_guarded_allocator.h - ) -endif() - include_directories(${INC}) include_directories(SYSTEM ${INC_SYS}) diff --git a/intern/cycles/util/util_guarded_allocator.h b/intern/cycles/util/util_guarded_allocator.h index 2df717253e3..2cef1494369 100644 --- a/intern/cycles/util/util_guarded_allocator.h +++ b/intern/cycles/util/util_guarded_allocator.h @@ -17,17 +17,10 @@ #ifndef __UTIL_GUARDED_ALLOCATOR_H__ #define __UTIL_GUARDED_ALLOCATOR_H__ -/* Define this in order to use Blender's guarded allocator to keep - * track of allocated buffers, their sizes and peak memory usage. - * - * This is usually a bad level call, but it's really handy to keep - * track of overall peak memory consumption during the scene - * synchronization step. - */ -#undef WITH_BLENDER_GUARDEDALLOC - +#include <cstddef> #include <memory> +#include "util_debug.h" #include "util_types.h" #ifdef WITH_BLENDER_GUARDEDALLOC @@ -42,39 +35,85 @@ void util_guarded_mem_free(size_t n); /* Guarded allocator for the use with STL. */ template <typename T> -class GuardedAllocator : public std::allocator<T> { +class GuardedAllocator { public: - template<typename _Tp1> - struct rebind { - typedef GuardedAllocator<_Tp1> other; - }; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef T *pointer; + typedef const T *const_pointer; + typedef T& reference; + typedef const T& const_reference; + typedef T value_type; + + GuardedAllocator() {} + GuardedAllocator(const GuardedAllocator&) {} T *allocate(size_t n, const void *hint = 0) { util_guarded_mem_alloc(n * sizeof(T)); -#ifdef WITH_BLENDER_GUARDEDALLOC (void)hint; - return (T*)MEM_mallocN_aligned(n * sizeof(T), 16, "Cycles Alloc"); +#ifdef WITH_BLENDER_GUARDEDALLOC + if(n == 0) { + return NULL; + } + return (T*)MEM_mallocN(n * sizeof(T), "Cycles Alloc"); #else - return std::allocator<T>::allocate(n, hint); + return (T*)malloc(n * sizeof(T)); #endif } void deallocate(T *p, size_t n) { util_guarded_mem_free(n * sizeof(T)); + if(p != NULL) { #ifdef WITH_BLENDER_GUARDEDALLOC - MEM_freeN((void*)p); + MEM_freeN(p); #else - std::allocator<T>::deallocate(p, n); + free(p); #endif + } + } + + T *address(T& x) const + { + return &x; + } + + const T *address(const T& x) const + { + return &x; + } + + GuardedAllocator<T>& operator=(const GuardedAllocator&) + { + return *this; + } + + void construct(T *p, const T& val) + { + new ((T *)p) T(val); + } + + void destroy(T *p) + { + p->~T(); + } + + size_t max_size() const + { + return size_t(-1); } - GuardedAllocator() : std::allocator<T>() { } - GuardedAllocator(const GuardedAllocator &a) : std::allocator<T>(a) { } template <class U> - GuardedAllocator(const GuardedAllocator<U> &a) : std::allocator<T>(a) { } - ~GuardedAllocator() { } + struct rebind { + typedef GuardedAllocator<U> other; + }; + + template <class U> + GuardedAllocator(const GuardedAllocator<U>&) {} + + template <class U> + GuardedAllocator& operator=(const GuardedAllocator<U>&) { return *this; } }; /* Get memory usage and peak from the guarded STL allocator. */ diff --git a/intern/cycles/util/util_task.cpp b/intern/cycles/util/util_task.cpp index d56553d1d4a..5523f373824 100644 --- a/intern/cycles/util/util_task.cpp +++ b/intern/cycles/util/util_task.cpp @@ -219,6 +219,12 @@ void TaskScheduler::exit() } } +void TaskScheduler::free_memory() +{ + assert(users == 0); + threads.free_memory(); +} + bool TaskScheduler::thread_wait_pop(Entry& entry) { thread_scoped_lock queue_lock(queue_mutex); diff --git a/intern/cycles/util/util_task.h b/intern/cycles/util/util_task.h index debcff3b776..a8e1963252a 100644 --- a/intern/cycles/util/util_task.h +++ b/intern/cycles/util/util_task.h @@ -91,6 +91,7 @@ class TaskScheduler public: static void init(int num_threads = 0); static void exit(); + static void free_memory(); /* number of threads that can work on task */ static int num_threads() { return threads.size(); } diff --git a/intern/cycles/util/util_vector.h b/intern/cycles/util/util_vector.h index 623436483a0..830aa15291d 100644 --- a/intern/cycles/util/util_vector.h +++ b/intern/cycles/util/util_vector.h @@ -24,30 +24,21 @@ #include <vector> #include "util_aligned_malloc.h" +#include "util_guarded_allocator.h" #include "util_types.h" -#ifdef WITH_CYCLES_DEBUG -# include "util_guarded_allocator.h" -#endif - CCL_NAMESPACE_BEGIN /* Vector * * Own subclass-ed vestion of std::vector. Subclass is needed because: * - * - When building with WITH_CYCLES_DEBUG we need to use own allocator which - * keeps track of used/peak memory. + * - Use own allocator which keeps track of used/peak memory. * * - Have method to ensure capacity is re-set to 0. */ template<typename value_type, -#ifdef WITH_CYCLES_DEBUG - typename allocator_type = GuardedAllocator<value_type> -#else - typename allocator_type = std::allocator<value_type> -#endif - > + typename allocator_type = GuardedAllocator<value_type> > class vector : public std::vector<value_type, allocator_type> { public: |