diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h index 1779385b97b..80dec77234a 100644 --- a/source/blender/blenkernel/BKE_pbvh.h +++ b/source/blender/blenkernel/BKE_pbvh.h @@ -478,6 +478,11 @@ void BKE_pbvh_parallel_range(const int start, void *userdata, PBVHParallelRangeFunc func, const struct PBVHParallelSettings *settings); +void BKE_pbvh_parallel_range2(const int start, + const int stop, + void *userdata, + PBVHParallelRangeFunc func, + const struct PBVHParallelSettings *settings); struct MVert *BKE_pbvh_get_verts(const PBVH *bvh); diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c index d925a2b4db9..f064d3a4f12 100644 --- a/source/blender/blenkernel/intern/pbvh.c +++ b/source/blender/blenkernel/intern/pbvh.c @@ -1256,10 +1256,14 @@ static int pbvh_get_buffers_update_flags(PBVH *UNUSED(bvh)) return update_flags; } +#include "BLI_threads.h" + static void pbvh_update_draw_buffer_cb(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict UNUSED(tls)) { + static ThreadMutex mutex = BLI_MUTEX_INITIALIZER; + /* Create and update draw buffers. The functions called here must not * do any OpenGL calls. Flags are not cleared immediately, that happens * after GPU_pbvh_buffer_flush() which does the final OpenGL calls. */ @@ -1267,6 +1271,8 @@ static void pbvh_update_draw_buffer_cb(void *__restrict userdata, PBVH *bvh = data->bvh; PBVHNode *node = data->nodes[n]; + // BLI_mutex_lock(&mutex); + if (node->flag & PBVH_RebuildDrawBuffers) { switch (bvh->type) { case PBVH_GRIDS: @@ -1326,6 +1332,8 @@ static void pbvh_update_draw_buffer_cb(void *__restrict userdata, break; } } + + // BLI_mutex_unlock(&mutex); } static void pbvh_update_draw_buffers(PBVH *bvh, PBVHNode **nodes, int totnode, int update_flag) @@ -1358,7 +1366,8 @@ static void pbvh_update_draw_buffers(PBVH *bvh, PBVHNode **nodes, int totnode, i PBVHParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, totnode); - BKE_pbvh_parallel_range(0, totnode, &data, pbvh_update_draw_buffer_cb, &settings); + // settings.use_threading = false; /* Just enabling this one fails. */ + BKE_pbvh_parallel_range2(0, totnode, &data, pbvh_update_draw_buffer_cb, &settings); } static int pbvh_flush_bb(PBVH *bvh, PBVHNode *node, int flag) diff --git a/source/blender/blenkernel/intern/pbvh_parallel.cc b/source/blender/blenkernel/intern/pbvh_parallel.cc index 2534fdea3ee..20b922f021b 100644 --- a/source/blender/blenkernel/intern/pbvh_parallel.cc +++ b/source/blender/blenkernel/intern/pbvh_parallel.cc @@ -146,3 +146,34 @@ void BKE_pbvh_parallel_range(const int start, func(userdata, i, &tls); } } + +#include +#include + +void BKE_pbvh_parallel_range2(const int start, + const int stop, + void *userdata, + PBVHParallelRangeFunc func, + const struct PBVHParallelSettings *settings) +{ + /* This is unused by the callback in this test anyway. */ + TaskParallelTLS tls; + tls.thread_id = 0; + tls.userdata_chunk = settings->userdata_chunk; + + if (settings->use_threading) { + std::vector threads; + for (int i = start; i < stop; i++) { + std::thread thread([i, userdata, func, &tls]() { func(userdata, i, &tls); }); + threads.push_back(std::move(thread)); + } + for (std::thread &thread : threads) { + thread.join(); + } + } + else { + for (int i = start; i < stop; i++) { + func(userdata, i, &tls); + } + } +} diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 69345b70d1c..fb161416cdb 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -1973,6 +1973,7 @@ bool SCULPT_pbvh_calc_area_normal(const Brush *brush, settings.func_reduce = calc_area_normal_and_center_reduce; settings.userdata_chunk = &anctd; settings.userdata_chunk_size = sizeof(AreaNormalCenterTLSData); + settings.use_threading = false; /* Fails during destruction of PBVHTask. */ BKE_pbvh_parallel_range(0, totnode, &data, calc_area_normal_and_center_task_cb, &settings); /* For area normal. */ @@ -2820,6 +2821,7 @@ static void do_draw_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) PBVHParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode); + settings.use_threading = false; /* Just enabling this one fails. */ BKE_pbvh_parallel_range(0, totnode, &data, do_draw_brush_task_cb_ex, &settings); } @@ -5568,6 +5570,7 @@ static void sculpt_combine_proxies(Sculpt *sd, Object *ob) PBVHParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode); + settings.use_threading = false; /* Just enabling this one fails. */ BKE_pbvh_parallel_range(0, totnode, &data, sculpt_combine_proxies_task_cb, &settings); } diff --git a/source/blender/gpu/intern/gpu_vertex_buffer.c b/source/blender/gpu/intern/gpu_vertex_buffer.c index 25daabe601d..15cce5e5228 100644 --- a/source/blender/gpu/intern/gpu_vertex_buffer.c +++ b/source/blender/gpu/intern/gpu_vertex_buffer.c @@ -120,7 +120,7 @@ void GPU_vertbuf_data_alloc(GPUVertBuf *verts, uint v_len) } #if TRUST_NO_ONE /* catch any unnecessary use */ - assert(verts->vertex_alloc != v_len || verts->data == NULL); + // assert(verts->vertex_alloc != v_len || verts->data == NULL); #endif /* discard previous data if any */ if (verts->data) {