From 6d73d98fb62df19c03fb665cd37ff214458d7a70 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Fri, 18 Jun 2021 15:51:18 +0200 Subject: BMesh: use threading to count total selection. During selections the total selection is refreshed at the end. This process was done single threaded. This patch will do a parallel iter approach. Master: 0.043612s Threaded 0.017964s. Master: {F10179586} This patch: {F10179587} Reviewed By: mano-wii Differential Revision: https://developer.blender.org/D11622 --- source/blender/bmesh/intern/bmesh_marking.c | 92 ++++++++++++++++++++++++++--- 1 file changed, 83 insertions(+), 9 deletions(-) (limited to 'source/blender') diff --git a/source/blender/bmesh/intern/bmesh_marking.c b/source/blender/bmesh/intern/bmesh_marking.c index 0bb86471cbd..c58aaf17116 100644 --- a/source/blender/bmesh/intern/bmesh_marking.c +++ b/source/blender/bmesh/intern/bmesh_marking.c @@ -33,6 +33,7 @@ #include "BLI_listbase.h" #include "BLI_math.h" +#include "BLI_task.h" #include "bmesh.h" #include "bmesh_structure.h" @@ -40,18 +41,89 @@ /* For '_FLAG_OVERLAP'. */ #include "bmesh_private.h" -static int recount_totsel(BMesh *bm, BMIterType iter_type) +/* -------------------------------------------------------------------- */ +/** \name Recounting total selection. + * \{ */ + +typedef struct SelectionCountChunkData { + int selection_len; +} SelectionCountChunkData; + +static void recount_totsels_range_vert_func(void *UNUSED(userdata), + MempoolIterData *iter, + const TaskParallelTLS *__restrict tls) { - BMIter iter; - BMElem *ele; - int count = 0; + SelectionCountChunkData *count = tls->userdata_chunk; + const BMVert *eve = (const BMVert *)iter; + if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { + count->selection_len += 1; + } +} - BM_ITER_MESH (ele, &iter, bm, iter_type) { - if (BM_elem_flag_test(ele, BM_ELEM_SELECT)) { - count += 1; - } +static void recount_totsels_range_edge_func(void *UNUSED(userdata), + MempoolIterData *iter, + const TaskParallelTLS *__restrict tls) +{ + SelectionCountChunkData *count = tls->userdata_chunk; + const BMEdge *eed = (const BMEdge *)iter; + if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) { + count->selection_len += 1; + } +} + +static void recount_totsels_range_face_func(void *UNUSED(userdata), + MempoolIterData *iter, + const TaskParallelTLS *__restrict tls) +{ + SelectionCountChunkData *count = tls->userdata_chunk; + const BMFace *efa = (const BMFace *)iter; + if (BM_elem_flag_test(efa, BM_ELEM_SELECT)) { + count->selection_len += 1; + } +} + +static void recount_totsels_reduce(const void *__restrict UNUSED(userdata), + void *__restrict chunk_join, + void *__restrict chunk) +{ + SelectionCountChunkData *dst = chunk_join; + const SelectionCountChunkData *src = chunk; + dst->selection_len += src->selection_len; +} + +static TaskParallelMempoolFunc recount_totsels_get_range_func(BMIterType iter_type) +{ + BLI_assert(ELEM(iter_type, BM_VERTS_OF_MESH, BM_EDGES_OF_MESH, BM_FACES_OF_MESH)); + + TaskParallelMempoolFunc range_func = NULL; + if (iter_type == BM_VERTS_OF_MESH) { + range_func = recount_totsels_range_vert_func; + } + else if (iter_type == BM_EDGES_OF_MESH) { + range_func = recount_totsels_range_edge_func; } - return count; + else if (iter_type == BM_FACES_OF_MESH) { + range_func = recount_totsels_range_face_func; + } + return range_func; +} + +static int recount_totsel(BMesh *bm, BMIterType iter_type) +{ + const int MIN_ITER_SIZE = 1024; + + TaskParallelSettings settings; + BLI_parallel_range_settings_defaults(&settings); + settings.func_reduce = recount_totsels_reduce; + settings.min_iter_per_thread = MIN_ITER_SIZE; + + SelectionCountChunkData count = {0}; + settings.userdata_chunk = &count; + settings.userdata_chunk_size = sizeof(count); + + TaskParallelMempoolFunc range_func = recount_totsels_get_range_func(iter_type); + BM_iter_parallel(bm, iter_type, range_func, NULL, &settings); + return count.selection_len; } static void recount_totvertsel(BMesh *bm) @@ -85,6 +157,8 @@ static bool recount_totsels_are_ok(BMesh *bm) } #endif +/** \} */ + /* -------------------------------------------------------------------- */ /** \name BMesh helper functions for selection & hide flushing. * \{ */ -- cgit v1.2.3