diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index cbf469b3a89..e6d2a0b85b3 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -1297,14 +1297,14 @@ class CyclesPreferences(bpy.types.AddonPreferences): row = layout.row() if self.compute_device_type == 'CUDA' and cuda_devices: - col = row.column(align=True) + box = row.box() for device in cuda_devices: - col.prop(device, "use", text=device.name, toggle=True) + box.prop(device, "use", text=device.name) if self.compute_device_type == 'OPENCL' and opencl_devices: - col = row.column(align=True) + box = row.box() for device in opencl_devices: - col.prop(device, "use", text=device.name, toggle=True) + box.prop(device, "use", text=device.name) def draw(self, context): diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp index 6fa038e8bf0..ed361cc971e 100644 --- a/intern/cycles/blender/blender_curves.cpp +++ b/intern/cycles/blender/blender_curves.cpp @@ -411,7 +411,7 @@ static void ExportCurveTrianglePlanes(Mesh *mesh, ParticleCurveData *CData, } } - mesh->resize_mesh(mesh->verts.size(), mesh->triangles.size()); + mesh->resize_mesh(mesh->verts.size(), mesh->num_triangles()); mesh->attributes.remove(ATTR_STD_VERTEX_NORMAL); mesh->attributes.remove(ATTR_STD_FACE_NORMAL); mesh->add_face_normals(); @@ -546,7 +546,7 @@ static void ExportCurveTriangleGeometry(Mesh *mesh, } } - mesh->resize_mesh(mesh->verts.size(), mesh->triangles.size()); + mesh->resize_mesh(mesh->verts.size(), mesh->num_triangles()); mesh->attributes.remove(ATTR_STD_VERTEX_NORMAL); mesh->attributes.remove(ATTR_STD_FACE_NORMAL); mesh->add_face_normals(); diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index fea292c1350..b70eb2b503a 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -131,6 +131,7 @@ #endif #include "CCGSubSurf.h" +#include "atomic_ops.h" #include "GPU_lamp.h" @@ -323,19 +324,24 @@ void BKE_object_link_modifiers(struct Object *ob_dst, const struct Object *ob_sr /* free data derived from mesh, called when mesh changes or is freed */ void BKE_object_free_derived_caches(Object *ob) { - /* also serves as signal to remake texspace */ + /* Also serves as signal to remake texspace. + * + * NOTE: This function can be called from threads on different objects + * sharing same data datablock. So we need to ensure atomic nature of + * data modification here. + */ if (ob->type == OB_MESH) { Mesh *me = ob->data; if (me && me->bb) { - me->bb->flag |= BOUNDBOX_DIRTY; + atomic_fetch_and_or_uint32((uint*)&me->bb->flag, BOUNDBOX_DIRTY); } } else if (ELEM(ob->type, OB_SURF, OB_CURVE, OB_FONT)) { Curve *cu = ob->data; if (cu && cu->bb) { - cu->bb->flag |= BOUNDBOX_DIRTY; + atomic_fetch_and_or_uint32((uint*)&cu->bb->flag, BOUNDBOX_DIRTY); } } diff --git a/source/blender/blenlib/intern/threads.c b/source/blender/blenlib/intern/threads.c index 77da3be0600..abf611d1245 100644 --- a/source/blender/blenlib/intern/threads.c +++ b/source/blender/blenlib/intern/threads.c @@ -813,6 +813,11 @@ void BLI_begin_threaded_malloc(void) unsigned int level = atomic_fetch_and_add_u(&thread_levels, 1); if (level == 0) { MEM_set_lock_callback(BLI_lock_malloc_thread, BLI_unlock_malloc_thread); + /* There is a little chance that two threads will meed to acces to a + * scheduler which was not yet created from main thread. which could + * cause scheduler created multiple times. + */ + BLI_task_scheduler_get(); } } diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c index a40af6490fd..8ac223b1389 100644 --- a/source/blender/editors/render/render_opengl.c +++ b/source/blender/editors/render/render_opengl.c @@ -247,10 +247,8 @@ static void screen_opengl_views_setup(OGLRender *oglrender) } } - BLI_lock_thread(LOCK_DRAW_IMAGE); if (!(is_multiview && BKE_scene_multiview_is_stereo3d(rd))) oglrender->iuser.flag &= ~IMA_SHOW_STEREO; - BLI_unlock_thread(LOCK_DRAW_IMAGE); /* will only work for non multiview correctly */ if (v3d) { @@ -866,7 +864,7 @@ static bool screen_opengl_render_anim_initialize(bContext *C, wmOperator *op) typedef struct WriteTaskData { RenderResult *rr; - int cfra; + Scene tmp_scene; } WriteTaskData; static void write_result_func(TaskPool * __restrict pool, @@ -875,10 +873,10 @@ static void write_result_func(TaskPool * __restrict pool, { OGLRender *oglrender = (OGLRender *) BLI_task_pool_userdata(pool); WriteTaskData *task_data = (WriteTaskData *) task_data_v; - Scene *scene = oglrender->scene; + Scene *scene = &task_data->tmp_scene; RenderResult *rr = task_data->rr; const bool is_movie = BKE_imtype_is_movie(scene->r.im_format.imtype); - const int cfra = task_data->cfra; + const int cfra = scene->r.cfra; bool ok; /* Don't attempt to write if we've got an error. */ if (!oglrender->pool_ok) { @@ -900,13 +898,11 @@ static void write_result_func(TaskPool * __restrict pool, * This is because underlying calls do not use r.cfra but use scene * for that. */ - Scene tmp_scene = *scene; - tmp_scene.r.cfra = cfra; if (is_movie) { ok = RE_WriteRenderViewsMovie(&reports, rr, - &tmp_scene, - &tmp_scene.r, + scene, + &scene->r, oglrender->mh, oglrender->movie_ctx_arr, oglrender->totvideos, @@ -926,8 +922,8 @@ static void write_result_func(TaskPool * __restrict pool, true, NULL); - BKE_render_result_stamp_info(&tmp_scene, tmp_scene.camera, rr, false); - ok = RE_WriteRenderViewsImage(NULL, rr, &tmp_scene, true, name); + BKE_render_result_stamp_info(scene, scene->camera, rr, false); + ok = RE_WriteRenderViewsImage(NULL, rr, scene, true, name); if (!ok) { BKE_reportf(&reports, RPT_ERROR, @@ -966,7 +962,7 @@ static bool schedule_write_result(OGLRender *oglrender, RenderResult *rr) Scene *scene = oglrender->scene; WriteTaskData *task_data = MEM_mallocN(sizeof(WriteTaskData), "write task data"); task_data->rr = rr; - task_data->cfra = scene->r.cfra; + task_data->tmp_scene = *scene; BLI_mutex_lock(&oglrender->task_mutex); oglrender->num_scheduled_frames++; if (oglrender->num_scheduled_frames > MAX_SCHEDULED_FRAMES) {