[Bf-blender-cvs] [2d4ec904974] master: Transform: support multi-threading for most modes

Campbell Barton noreply at git.blender.org
Wed Jun 30 08:56:24 CEST 2021


Commit: 2d4ec90497443dc28e342c539e65010c7f4a04bb
Author: Campbell Barton
Date:   Tue Jun 29 16:18:26 2021 +1000
Branches: master
https://developer.blender.org/rB2d4ec90497443dc28e342c539e65010c7f4a04bb

Transform: support multi-threading for most modes

Multi-threading support for transform modes: bevel-weight, crease,
push-pull, rotate, shear, shrink-fatten, skin-resize, to-sphere,
trackball & translate.

This is done using a parallel loop over transform data.

>From testing a 1.5million polygon mesh on a 32 core system
the overall performance gains were between ~20-28%

To ensure the code is thread-safe arguments to shared data are const.

Reviewed By: mano-wii

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

M	source/blender/editors/transform/transform_data.h
M	source/blender/editors/transform/transform_mode_edge_bevelweight.c
M	source/blender/editors/transform/transform_mode_edge_crease.c
M	source/blender/editors/transform/transform_mode_push_pull.c
M	source/blender/editors/transform/transform_mode_resize.c
M	source/blender/editors/transform/transform_mode_rotate.c
M	source/blender/editors/transform/transform_mode_shear.c
M	source/blender/editors/transform/transform_mode_shrink_fatten.c
M	source/blender/editors/transform/transform_mode_skin_resize.c
M	source/blender/editors/transform/transform_mode_tosphere.c
M	source/blender/editors/transform/transform_mode_trackball.c
M	source/blender/editors/transform/transform_mode_translate.c

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

diff --git a/source/blender/editors/transform/transform_data.h b/source/blender/editors/transform/transform_data.h
index 59b76c2eec5..606453e356b 100644
--- a/source/blender/editors/transform/transform_data.h
+++ b/source/blender/editors/transform/transform_data.h
@@ -149,6 +149,8 @@ typedef struct TransData {
   short protectflag;
 } TransData;
 
+#define TRANSDATA_THREAD_LIMIT 1024
+
 /** #TransData.flag */
 enum {
   TD_SELECTED = 1 << 0,
diff --git a/source/blender/editors/transform/transform_mode_edge_bevelweight.c b/source/blender/editors/transform/transform_mode_edge_bevelweight.c
index 3ce52ed3296..425bfec241e 100644
--- a/source/blender/editors/transform/transform_mode_edge_bevelweight.c
+++ b/source/blender/editors/transform/transform_mode_edge_bevelweight.c
@@ -25,6 +25,7 @@
 
 #include "BLI_math.h"
 #include "BLI_string.h"
+#include "BLI_task.h"
 
 #include "BKE_context.h"
 #include "BKE_unit.h"
@@ -39,6 +40,50 @@
 #include "transform_mode.h"
 #include "transform_snap.h"
 
+/* -------------------------------------------------------------------- */
+/** \name Transform (Bevel Weight) Element
+ * \{ */
+
+/**
+ * \note Small arrays / data-structures should be stored copied for faster memory access.
+ */
+struct TransDataArgs_BevelWeight {
+  const TransInfo *t;
+  const TransDataContainer *tc;
+  float weight;
+};
+
+static void transdata_elem_bevel_weight(const TransInfo *UNUSED(t),
+                                        const TransDataContainer *UNUSED(tc),
+                                        TransData *td,
+                                        const float weight)
+{
+  if (td->val == NULL) {
+    return;
+  }
+  *td->val = td->ival + weight * td->factor;
+  if (*td->val < 0.0f) {
+    *td->val = 0.0f;
+  }
+  if (*td->val > 1.0f) {
+    *td->val = 1.0f;
+  }
+}
+
+static void transdata_elem_bevel_weight_fn(void *__restrict iter_data_v,
+                                           const int iter,
+                                           const TaskParallelTLS *__restrict UNUSED(tls))
+{
+  struct TransDataArgs_BevelWeight *data = iter_data_v;
+  TransData *td = &data->tc->data[iter];
+  if (td->flag & TD_SKIP) {
+    return;
+  }
+  transdata_elem_bevel_weight(data->t, data->tc, td, data->weight);
+}
+
+/** \} */
+
 /* -------------------------------------------------------------------- */
 /** \name Transform (Bevel Weight)
  * \{ */
@@ -83,18 +128,25 @@ static void applyBevelWeight(TransInfo *t, const int UNUSED(mval[2]))
   }
 
   FOREACH_TRANS_DATA_CONTAINER (t, tc) {
-    TransData *td = tc->data;
-    for (i = 0; i < tc->data_len; i++, td++) {
-      if (td->val) {
-        *td->val = td->ival + weight * td->factor;
-        if (*td->val < 0.0f) {
-          *td->val = 0.0f;
-        }
-        if (*td->val > 1.0f) {
-          *td->val = 1.0f;
+    if (tc->data_len < TRANSDATA_THREAD_LIMIT) {
+      TransData *td = tc->data;
+      for (i = 0; i < tc->data_len; i++, td++) {
+        if (td->flag & TD_SKIP) {
+          continue;
         }
+        transdata_elem_bevel_weight(t, tc, td, weight);
       }
     }
+    else {
+      struct TransDataArgs_BevelWeight data = {
+          .t = t,
+          .tc = tc,
+          .weight = weight,
+      };
+      TaskParallelSettings settings;
+      BLI_parallel_range_settings_defaults(&settings);
+      BLI_task_parallel_range(0, tc->data_len, &data, transdata_elem_bevel_weight_fn, &settings);
+    }
   }
 
   recalcData(t);
diff --git a/source/blender/editors/transform/transform_mode_edge_crease.c b/source/blender/editors/transform/transform_mode_edge_crease.c
index 23fa20b68ff..91e2507e544 100644
--- a/source/blender/editors/transform/transform_mode_edge_crease.c
+++ b/source/blender/editors/transform/transform_mode_edge_crease.c
@@ -25,6 +25,7 @@
 
 #include "BLI_math.h"
 #include "BLI_string.h"
+#include "BLI_task.h"
 
 #include "BKE_context.h"
 #include "BKE_unit.h"
@@ -39,6 +40,51 @@
 #include "transform_mode.h"
 #include "transform_snap.h"
 
+/* -------------------------------------------------------------------- */
+/** \name Transform (Crease) Element
+ * \{ */
+
+/**
+ * \note Small arrays / data-structures should be stored copied for faster memory access.
+ */
+struct TransDataArgs_Crease {
+  const TransInfo *t;
+  const TransDataContainer *tc;
+  float crease;
+};
+
+static void transdata_elem_crease(const TransInfo *UNUSED(t),
+                                  const TransDataContainer *UNUSED(tc),
+                                  TransData *td,
+                                  const float crease)
+{
+  if (td->val == NULL) {
+    return;
+  }
+
+  *td->val = td->ival + crease * td->factor;
+  if (*td->val < 0.0f) {
+    *td->val = 0.0f;
+  }
+  if (*td->val > 1.0f) {
+    *td->val = 1.0f;
+  }
+}
+
+static void transdata_elem_crease_fn(void *__restrict iter_data_v,
+                                     const int iter,
+                                     const TaskParallelTLS *__restrict UNUSED(tls))
+{
+  struct TransDataArgs_Crease *data = iter_data_v;
+  TransData *td = &data->tc->data[iter];
+  if (td->flag & TD_SKIP) {
+    return;
+  }
+  transdata_elem_crease(data->t, data->tc, td, data->crease);
+}
+
+/** \} */
+
 /* -------------------------------------------------------------------- */
 /** \name Transform (Crease)
  * \{ */
@@ -83,22 +129,25 @@ static void applyCrease(TransInfo *t, const int UNUSED(mval[2]))
   }
 
   FOREACH_TRANS_DATA_CONTAINER (t, tc) {
-    TransData *td = tc->data;
-    for (i = 0; i < tc->data_len; i++, td++) {
-      if (td->flag & TD_SKIP) {
-        continue;
-      }
-
-      if (td->val) {
-        *td->val = td->ival + crease * td->factor;
-        if (*td->val < 0.0f) {
-          *td->val = 0.0f;
-        }
-        if (*td->val > 1.0f) {
-          *td->val = 1.0f;
+    if (tc->data_len < TRANSDATA_THREAD_LIMIT) {
+      TransData *td = tc->data;
+      for (i = 0; i < tc->data_len; i++, td++) {
+        if (td->flag & TD_SKIP) {
+          continue;
         }
+        transdata_elem_crease(t, tc, td, crease);
       }
     }
+    else {
+      struct TransDataArgs_Crease data = {
+          .t = t,
+          .tc = tc,
+          .crease = crease,
+      };
+      TaskParallelSettings settings;
+      BLI_parallel_range_settings_defaults(&settings);
+      BLI_task_parallel_range(0, tc->data_len, &data, transdata_elem_crease_fn, &settings);
+    }
   }
 
   recalcData(t);
@@ -124,4 +173,5 @@ void initCrease(TransInfo *t)
 
   t->flag |= T_NO_CONSTRAINT | T_NO_PROJECT;
 }
+
 /** \} */
diff --git a/source/blender/editors/transform/transform_mode_push_pull.c b/source/blender/editors/transform/transform_mode_push_pull.c
index b08e479a3d0..098698b0e79 100644
--- a/source/blender/editors/transform/transform_mode_push_pull.c
+++ b/source/blender/editors/transform/transform_mode_push_pull.c
@@ -25,6 +25,7 @@
 
 #include "BLI_math.h"
 #include "BLI_string.h"
+#include "BLI_task.h"
 
 #include "BKE_context.h"
 #include "BKE_unit.h"
@@ -40,13 +41,76 @@
 #include "transform_mode.h"
 #include "transform_snap.h"
 
+/* -------------------------------------------------------------------- */
+/** \name Transform (Push/Pull) Element
+ * \{ */
+
+/**
+ * \note Small arrays / data-structures should be stored copied for faster memory access.
+ */
+struct TransDataArgs_PushPull {
+  const TransInfo *t;
+  const TransDataContainer *tc;
+
+  float distance;
+  const float axis_global[3];
+  bool is_data_space;
+};
+
+static void transdata_elem_push_pull(const TransInfo *t,
+                                     const TransDataContainer *tc,
+                                     TransData *td,
+                                     const float distance,
+                                     const float axis_global[3],
+                                     const bool is_data_space)
+{
+  float vec[3];
+  sub_v3_v3v3(vec, tc->center_local, td->center);
+  if (t->con.applyRot && t->con.mode & CON_APPLY) {
+    float axis[3];
+    copy_v3_v3(axis, axis_global);
+    t->con.applyRot(t, tc, td, axis, NULL);
+
+    mul_m3_v3(td->smtx, axis);
+    if (isLockConstraint(t)) {
+      float dvec[3];
+      project_v3_v3v3(dvec, vec, axis);
+      sub_v3_v3(vec, dvec);
+    }
+    else {
+      project_v3_v3v3(vec, vec, axis);
+    }
+  }
+  normalize_v3_length(vec, distance * td->factor);
+  if (is_data_space) {
+    mul_m3_v3(td->smtx, vec);
+  }
+
+  add_v3_v3v3(td->loc, td->iloc, vec);
+}
+
+static void transdata_elem_push_pull_fn(void *__restrict iter_data_v,
+                                        const int iter,
+                                        const TaskParallelTLS *__restrict UNUSED(tls))
+{
+  struct TransDataArgs_PushPull *data = iter_data_v;
+  TransData *td = &data->tc->data[iter];
+  if (td->flag & TD_SKIP) {
+    return;
+  }
+  transdata_elem_push_pull(
+      data->t, data->tc, td, data->distance, data->axis_global, data->is_data_space);
+}
+
+/** \} */
+
 /* -------------------------------------------------------------------- */
 /** \name Transform (Push/Pull)
  * \{ */
 
 static void applyPushPull(TransInfo *t, const int UNUSED(mval[2]))
 {
-  float vec[3], axis_global[3];
+  float axis_global[3];
   float distance;
   int i;
   char str[UI_MAX_DRAW_STR];
@@ -80,34 +144,26 @@ static void applyPushPull(TransInfo *t, const int UNUSED(mval[2]))
   const bool is_data_space = (t->options & CTX_POSE_BONE) != 0;
 
   FOREACH_TRANS_DATA_CONTAINER (t, tc) {
-    TransData *td = tc->data;
-    for (i = 0; i < tc->data_len; i++, td++) {
-      if (td->flag & TD_SKIP) {
-        continue;
-      }
-
-      sub_v3_v3v3(vec, tc->center_local, td->center);
-      if (t->con.applyRot && t->con.mode & CON_APPLY) {
-        float axis[3];
-        copy_v3_v3(axis, axis_global);
-        t->con.applyRot(t, tc, td, axis, NULL);
-
-        mul_m3_v3(td->smtx, axis);
-        if (isLockConstraint(t)) {
-          float dvec[3];
-          project_v3_v3v3(dvec, vec, axis);
-          sub_v3_v3(vec, dvec);
+    if (tc->data_len < TRANSDATA_THREAD_LIMIT) {
+      TransData *td = tc->data;
+      for (i = 0; i < tc->data_len; i++, td++) {
+        if (td->flag & TD_SKIP) {
+          continue;
         }
-        else {
-          project_v3_v

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list