[Bf-blender-cvs] [6d73d98fb62] master: BMesh: use threading to count total selection.

Jeroen Bakker noreply at git.blender.org
Fri Jun 18 16:06:37 CEST 2021


Commit: 6d73d98fb62df19c03fb665cd37ff214458d7a70
Author: Jeroen Bakker
Date:   Fri Jun 18 15:51:18 2021 +0200
Branches: master
https://developer.blender.org/rB6d73d98fb62df19c03fb665cd37ff214458d7a70

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

===================================================================

M	source/blender/bmesh/intern/bmesh_marking.c

===================================================================

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.
  * \{ */



More information about the Bf-blender-cvs mailing list