Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeroen Bakker <jbakker>2021-06-18 16:51:18 +0300
committerJeroen Bakker <jeroen@blender.org>2021-06-18 17:06:36 +0300
commit6d73d98fb62df19c03fb665cd37ff214458d7a70 (patch)
tree1de9e70ba477ca4e55a695c46ca80d54b0bd8e72
parent03a83b4eb5bc87dd30625d35022b6bc5e4edd8fd (diff)
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
-rw-r--r--source/blender/bmesh/intern/bmesh_marking.c92
1 files changed, 83 insertions, 9 deletions
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.
* \{ */