[Bf-blender-cvs] [a67ff7552cb] sculpt-dev: Tune up a few hot loops revealed by profiling.

Joseph Eagar noreply at git.blender.org
Wed Sep 22 11:48:12 CEST 2021


Commit: a67ff7552cb313f3836712d6985ca049ec01d5e7
Author: Joseph Eagar
Date:   Tue Sep 21 02:39:33 2021 -0700
Branches: sculpt-dev
https://developer.blender.org/rBa67ff7552cb313f3836712d6985ca049ec01d5e7

Tune up a few hot loops revealed by profiling.

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

M	release/scripts/startup/bl_ui/properties_paint_common.py
M	source/blender/blenkernel/intern/dyntopo.c
M	source/blender/editors/sculpt_paint/sculpt.c
M	source/blender/editors/sculpt_paint/sculpt_automasking.c

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

diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py
index 8025b17cbed..51356824491 100644
--- a/release/scripts/startup/bl_ui/properties_paint_common.py
+++ b/release/scripts/startup/bl_ui/properties_paint_common.py
@@ -125,8 +125,9 @@ class UnifiedPaintPanel:
 
         row = layout.row(align=True)
 
-        typeprop = "float_value"
 
+        if ch.type == "FLOAT":
+            typeprop = "float_value" if "spacing" in ch.idname else "factor_value"
         if ch.type == "INT":
             typeprop = "int_value"
         elif ch.type == "BOOL":
@@ -139,7 +140,7 @@ class UnifiedPaintPanel:
             typeprop = "color3_value"
         elif ch.type == "VEC4":
             typeprop = "color4_value"
-
+            
         if text is None:
             s = prop_name.lower().replace("_", " ").split(" ");
             text = ''
@@ -191,14 +192,14 @@ class UnifiedPaintPanel:
         #if unified_name and not header:
         #    # NOTE: We don't draw UnifiedPaintSettings in the header to reduce clutter. D5928#136281
         #    row.prop(ups, unified_name, text="", icon='BRUSHES_ALL')
-        if not header and ch.type != "BOOL":
+        if not header: # and ch.type != "BOOL":
             if ch.type == "BITMASK" and not toolsettings_only and ch == finalch:
                 row.prop(ch, "inherit_if_unset", text="Combine With Defaults")
 
             if not toolsettings_only:
                 row.prop(ch, "inherit", text="", icon='BRUSHES_ALL')
 
-            if ch.type == "BITMASK":
+            if ch.type == "BITMASK" or ch.type == "BOOL":
                 return
 
             row.prop(ch, "ui_expanded", text="", icon="TRIA_DOWN" if ch.ui_expanded else "TRIA_RIGHT")
@@ -806,7 +807,16 @@ def brush_settings(layout, context, brush, popover=False):
             box.prop(brush, "ignore_falloff_for_topology_rake")
 
         if context.sculpt_object.use_dynamic_topology_sculpting:
-            layout.prop(brush.dyntopo, "disabled", text="Disable Dyntopo")
+            UnifiedPaintPanel.channel_unified(
+                layout,
+                context,
+                brush,
+                "dyntopo_disabled",
+                #text="Weight By Face Area",
+                slider=True,
+                header=True
+            )
+            #layout.prop(brush.dyntopo, "disabled", text="Disable Dyntopo")
             
         # normal_weight
         if capabilities.has_normal_weight:
@@ -1018,7 +1028,16 @@ def brush_settings(layout, context, brush, popover=False):
             col = layout.column()
             col.prop(brush, "boundary_smooth_factor")
 
-            col.prop(brush, "use_weighted_smooth")
+            UnifiedPaintPanel.channel_unified(
+                layout,
+                context,
+                brush,
+                "use_weighted_smooth",
+                #text="Weight By Face Area",
+                slider=True,
+            )
+
+            #col.prop(brush, "use_weighted_smooth")
             col.prop(brush, "preserve_faceset_boundary")
             if brush.preserve_faceset_boundary:
                 col.prop(brush, "autosmooth_fset_slide")
diff --git a/source/blender/blenkernel/intern/dyntopo.c b/source/blender/blenkernel/intern/dyntopo.c
index 51757540ba3..af07f0ace81 100644
--- a/source/blender/blenkernel/intern/dyntopo.c
+++ b/source/blender/blenkernel/intern/dyntopo.c
@@ -1628,6 +1628,7 @@ typedef struct EdgeQueueThreadData {
   int totedge;
   int size;
   bool is_collapse;
+  int seed;
 } EdgeQueueThreadData;
 
 static void edge_thread_data_insert(EdgeQueueThreadData *tdata, BMEdge *e)
@@ -1962,6 +1963,16 @@ static void long_edge_queue_edge_add_recursive_2(EdgeQueueThreadData *tdata,
 
 static int _long_edge_queue_task_cb_seed = 0;
 
+BLI_INLINE int dyntopo_thread_rand(int seed)
+{
+  // glibc
+  const uint32_t multiplier = 1103515245;
+  const uint32_t addend = 12345;
+  const uint32_t mask = (1 << 31) - 1;
+
+  return (seed * multiplier + addend) & mask;
+}
+
 static void long_edge_queue_task_cb(void *__restrict userdata,
                                     const int n,
                                     const TaskParallelTLS *__restrict tls)
@@ -1973,18 +1984,43 @@ static void long_edge_queue_task_cb(void *__restrict userdata,
   BMVert **val34 = NULL;
   BLI_array_declare(val34);
 
-  BMFace *f;
+  int seed = tdata->seed + n;
+
+  BMFace *f, **faces = NULL;
+  BLI_array_declare(faces);
   const int cd_dyn_vert = tdata->pbvh->cd_dyn_vert;
 
+#if 1
+#  if 0
+  // try to be nice to branch predictor
+  int off = (seed = dyntopo_thread_rand(seed));
+  int stepi = off & 65535;
+#  endif
+  /*
+  we care more about convergence to accurate results
+  then accuracy in any individual runs.  profiling
+  has shown this loop overwhelms the L3 cache,
+  so randomly skip bits of it.
+  */
   TGSET_ITER (f, node->bm_faces) {
     BMLoop *l = f->l_first;
 
+#  if 0
+    if ((stepi++) & 3) {
+      continue;
+    }
+#  else
+    if ((seed = dyntopo_thread_rand(seed)) & 3) {
+      continue;
+    }
+#  endif
     do {
       l->e->head.hflag &= ~BM_ELEM_TAG;
       l = l->next;
     } while (l != f->l_first);
   }
   TGSET_ITER_END
+#endif
 
   TGSET_ITER (f, node->bm_faces) {
 #ifdef USE_EDGEQUEUE_FRONTFACE
@@ -2014,7 +2050,9 @@ static void long_edge_queue_task_cb(void *__restrict userdata,
 
         // try to improve convergence by applying a small amount of smoothing to topology,
         // but tangentially to surface.
-        if (BLI_rng_get_float(rng) > 0.5) {
+        int randval = (seed = dyntopo_thread_rand(seed)) & 255;
+
+        if (randval > 127) {
           surface_smooth_v_safe(tdata->pbvh, l_iter->v, eq_ctx->surface_smooth_fac);
         }
 
@@ -2040,6 +2078,7 @@ static void long_edge_queue_task_cb(void *__restrict userdata,
   TGSET_ITER_END
 
   BLI_rng_free(rng);
+  BLI_array_free(faces);
 
   tdata->val34_verts = val34;
   tdata->val34_verts_tot = BLI_array_len(val34);
@@ -2055,15 +2094,23 @@ static void short_edge_queue_task_cb(void *__restrict userdata,
 
   BMFace *f;
 
+  int seed = tdata->seed + n;
+
+  // see comment in similar loop in long_edge_queue_task_cb
   TGSET_ITER (f, node->bm_faces) {
+#if 0
+    if ((stepi++) & 3) {
+      continue;
+    }
+#else
+    if ((seed = dyntopo_thread_rand(seed)) & 3) {
+      continue;
+    }
+#endif
+
     BMLoop *l = f->l_first;
 
     do {
-      if (!l->e) {
-        printf("bmesh error! %s\n", __func__);
-        continue;
-      }
-
       l->e->head.hflag &= ~BM_ELEM_TAG;
       l = l->next;
     } while (l != f->l_first);
@@ -2562,30 +2609,41 @@ static void long_edge_queue_create(EdgeQueueContext *eq_ctx,
   EdgeQueueThreadData *tdata = NULL;
   BLI_array_declare(tdata);
 
+  int totleaf = 0;
+
   for (int n = 0; n < pbvh->totnode; n++) {
     PBVHNode *node = &pbvh->nodes[n];
 
+    if (node->flag & PBVH_Leaf) {
+      totleaf++;
+    }
+
     /* Check leaf nodes marked for topology update */
-    if ((node->flag & PBVH_Leaf) && (node->flag & PBVH_UpdateTopology) &&
-        !(node->flag & PBVH_FullyHidden)) {
-      EdgeQueueThreadData td;
+    bool ok = ((node->flag & PBVH_Leaf) && (node->flag & PBVH_UpdateTopology) &&
+               !(node->flag & PBVH_FullyHidden));
 
-      memset(&td, 0, sizeof(td));
+    if (!ok) {
+      continue;
+    }
 
-      td.pbvh = pbvh;
-      td.node = node;
-      td.eq_ctx = eq_ctx;
+    EdgeQueueThreadData td;
 
-      BLI_array_append(tdata, td);
-      /* Check each face */
-      /*
-      BMFace *f;
-      TGSET_ITER (f, node->bm_faces) {
-        long_edge_queue_face_add(eq_ctx, f);
-      }
-      TGSET_ITER_END
-      */
+    memset(&td, 0, sizeof(td));
+
+    td.seed = BLI_thread_rand(0);
+    td.pbvh = pbvh;
+    td.node = node;
+    td.eq_ctx = eq_ctx;
+
+    BLI_array_append(tdata, td);
+    /* Check each face */
+    /*
+    BMFace *f;
+    TGSET_ITER (f, node->bm_faces) {
+      long_edge_queue_face_add(eq_ctx, f);
     }
+    TGSET_ITER_END
+    */
   }
 
   int count = BLI_array_len(tdata);
@@ -2953,9 +3011,11 @@ static void short_edge_queue_create(EdgeQueueContext *eq_ctx,
     if ((node->flag & PBVH_Leaf) && (node->flag & PBVH_UpdateTopology) &&
         !(node->flag & PBVH_FullyHidden)) {
       memset(&td, 0, sizeof(td));
+
       td.pbvh = pbvh;
       td.node = node;
       td.eq_ctx = eq_ctx;
+      td.seed = BLI_thread_rand(0);
 
       BLI_array_append(tdata, td);
     }
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 5feca19a698..df3afa42257 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -1158,22 +1158,35 @@ bool SCULPT_vertex_has_face_set(SculptSession *ss, SculptVertRef index, int face
       return false;
     }
     case PBVH_BMESH: {
-      BMIter iter;
-      BMLoop *l;
+      BMEdge *e;
       BMVert *v = (BMVert *)index.i;
 
       if (ss->cd_faceset_offset == -1) {
         return false;
       }
 
-      BM_ITER_ELEM (l, &iter, v, BM_LOOPS_OF_VERT) {
-        BMFace *f = l->f;
+      e = v->e;
 
-        if (abs(BM_ELEM_CD_GET_INT(f, ss->cd_faceset_offset)) == abs(face_set)) {
-          return true;
-        }
+      if (UNLIKELY(!e)) {
+        return false;
       }
 
+      do {
+        BMLoop *l = e->l;
+
+        if (UNLIKELY(!l)) {
+          continue;
+        }
+
+        do {
+          BMFace *f = l->f;
+
+          if (abs(BM_ELEM_CD_GET_INT(f, ss->cd_faceset_offset)) == abs(face_set)) {
+            return true;
+          }
+        } while ((l = l->radial_next) != e->l);
+      } while ((e = BM_DISK_EDGE_NEXT(e, v)) != v->e);
+
       return false;
     }
     case PBVH_GRIDS: {
@@ -9321,7 +9334,8 @@ ATTR_NO_OPT static void SCULPT_run_command_list(
         break;
       case SCULPT_TOOL_DYNTOPO:
         if (has_dyntopo) {
-          do_symmetrical_brush_actions(sd, ob, sculpt_topology_update, ups);
+          sculpt_topology_update(sd, ob, brush, ups);
+          // do_symmetrical_brush_actions(sd, ob, sculpt_topology_update, ups);
         }
         break;
     }
diff --git a/source/blender/editors/sculpt_paint/sculpt_automasking.c b/source/blender

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list