From f462e8a9c826a308a454f13bb867083e866b9877 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 12 Feb 2014 21:49:34 +0100 Subject: Fix T38332, Fix T38607: cycles render crash with motion blur. It wasn't working together well with the python thread state changes after the depsgraph multithreading. --- intern/cycles/blender/blender_object.cpp | 10 ++++++++++ intern/cycles/blender/blender_python.cpp | 29 +++++++++++++++++++++-------- intern/cycles/blender/blender_util.h | 3 +++ 3 files changed, 34 insertions(+), 8 deletions(-) (limited to 'intern') diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index 0df8939bc18..c8a2f080bba 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -532,7 +532,12 @@ void BlenderSync::sync_motion(BL::SpaceView3D b_v3d, BL::Object b_override) int frame = b_scene.frame_current(); for(int motion = -1; motion <= 1; motion += 2) { + /* we need to set the python thread state again because this + * function assumes it is being executed from python and will + * try to save the thread state */ + python_thread_state_restore(); b_scene.frame_set(frame + motion, 0.0f); + python_thread_state_save(); /* camera object */ if(b_cam) @@ -542,7 +547,12 @@ void BlenderSync::sync_motion(BL::SpaceView3D b_v3d, BL::Object b_override) sync_objects(b_v3d, motion); } + /* we need to set the python thread state again because this + * function assumes it is being executed from python and will + * try to save the thread state */ + python_thread_state_restore(); b_scene.frame_set(frame, 0.0f); + python_thread_state_save(); /* tag camera for motion update */ if(scene->camera->motion_modified(prevcam)) diff --git a/intern/cycles/blender/blender_python.cpp b/intern/cycles/blender/blender_python.cpp index 22c425aa332..6c9f1dc080f 100644 --- a/intern/cycles/blender/blender_python.cpp +++ b/intern/cycles/blender/blender_python.cpp @@ -35,6 +35,19 @@ CCL_NAMESPACE_BEGIN +static PyThreadState *python_thread_state = NULL; + +void python_thread_state_save() +{ + python_thread_state = PyEval_SaveThread(); +} + +void python_thread_state_restore() +{ + PyEval_RestoreThread(python_thread_state); + python_thread_state = NULL; +} + static PyObject *init_func(PyObject *self, PyObject *args) { const char *path, *user_path; @@ -87,7 +100,7 @@ static PyObject *create_func(PyObject *self, PyObject *args) /* create session */ BlenderSession *session; - Py_BEGIN_ALLOW_THREADS + python_thread_state_save(); if(rv3d) { /* interactive viewport session */ @@ -109,7 +122,7 @@ static PyObject *create_func(PyObject *self, PyObject *args) session = new BlenderSession(engine, userpref, data, scene); } - Py_END_ALLOW_THREADS + python_thread_state_restore(); return PyLong_FromVoidPtr(session); } @@ -123,12 +136,12 @@ static PyObject *free_func(PyObject *self, PyObject *value) static PyObject *render_func(PyObject *self, PyObject *value) { - Py_BEGIN_ALLOW_THREADS + python_thread_state_save(); BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(value); session->render(); - Py_END_ALLOW_THREADS + python_thread_state_restore(); Py_RETURN_NONE; } @@ -170,23 +183,23 @@ static PyObject *reset_func(PyObject *self, PyObject *args) RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pyscene), &sceneptr); BL::Scene b_scene(sceneptr); - Py_BEGIN_ALLOW_THREADS + python_thread_state_save(); session->reset_session(b_data, b_scene); - Py_END_ALLOW_THREADS + python_thread_state_restore(); Py_RETURN_NONE; } static PyObject *sync_func(PyObject *self, PyObject *value) { - Py_BEGIN_ALLOW_THREADS + python_thread_state_save(); BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(value); session->synchronize(); - Py_END_ALLOW_THREADS + python_thread_state_restore(); Py_RETURN_NONE; } diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h index cb0f7b76d56..c9048cd8a28 100644 --- a/intern/cycles/blender/blender_util.h +++ b/intern/cycles/blender/blender_util.h @@ -37,6 +37,9 @@ float *BKE_image_get_float_pixels_for_frame(void *image, int frame); CCL_NAMESPACE_BEGIN +void python_thread_state_save(); +void python_thread_state_restore(); + static inline BL::Mesh object_to_mesh(BL::BlendData data, BL::Object object, BL::Scene scene, bool apply_modifiers, bool render, bool calc_undeformed) { return data.meshes.new_from_object(scene, object, apply_modifiers, (render)? 2: 1, true, calc_undeformed); -- cgit v1.2.3