Commit: 90cd856ac34011496031eeae5a5e3a5bf2da1107
Author: Bastien Montagne
Date:   Thu Jan 11 19:39:24 2018 +0100
Branches: master
https://developer.blender.org/rB90cd856ac34011496031eeae5a5e3a5bf2da1107

Nuke OMP usage in multires.c.

New code is over three times quicker than old one here (e.g. Suzanne
subdiv level 4, 250k tris, threaded part is now 1.4ms instead of 4.5ms
with OMP).

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

M       source/blender/blenkernel/intern/CCGSubSurf.h
M       source/blender/blenkernel/intern/CCGSubSurf_legacy.c
M       source/blender/blenkernel/intern/multires.c

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

diff --git a/source/blender/blenkernel/intern/CCGSubSurf.h 
b/source/blender/blenkernel/intern/CCGSubSurf.h
index 4c913e79586..8cdbd2a7a98 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf.h
+++ b/source/blender/blenkernel/intern/CCGSubSurf.h
@@ -73,6 +73,9 @@ typedef enum {
 
 #define CCG_OMP_LIMIT  1000000
 
+/* TODO(sergey): This actually depends on subsurf level as well. */
+#define CCG_TASK_LIMIT 16
+
 /***/
 
 CCGSubSurf*    ccgSubSurf_new  (CCGMeshIFC *ifc, int subdivisionLevels, 
CCGAllocatorIFC *allocatorIFC, CCGAllocatorHDL allocator);
diff --git a/source/blender/blenkernel/intern/CCGSubSurf_legacy.c 
b/source/blender/blenkernel/intern/CCGSubSurf_legacy.c
index 2b331eae950..756935b50ba 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf_legacy.c
+++ b/source/blender/blenkernel/intern/CCGSubSurf_legacy.c
@@ -34,9 +34,6 @@
 
 #define FACE_calcIFNo(f, lvl, S, x, y, no)  _face_calcIFNo(f, lvl, S, x, y, 
no, subdivLevels, vertDataSize)
 
-/* TODO(sergey): This actually depends on subsurf level as well. */
-#define CCG_TASK_LIMIT 16
-
 /* TODO(sergey): Deduplicate the following functions/ */
 static void *_edge_getCoVert(CCGEdge *e, CCGVert *v, int lvl, int x, int 
dataSize)
 {
diff --git a/source/blender/blenkernel/intern/multires.c 
b/source/blender/blenkernel/intern/multires.c
index 4eb550a9f4c..6bc4e359bbd 100644
--- a/source/blender/blenkernel/intern/multires.c
+++ b/source/blender/blenkernel/intern/multires.c
@@ -1003,6 +1003,115 @@ static void grid_tangent_matrix(float mat[3][3], const 
CCGKey *key,
        copy_v3_v3(mat[2], CCG_grid_elem_no(key, grid, x, y));
 }
 
+
+typedef struct MultiresDispRunData {
+       DispOp op;
+       CCGElem **gridData, **subGridData;
+       CCGKey *key;
+       MPoly *mpoly;
+       MDisps *mdisps;
+       GridPaintMask *grid_paint_mask;
+       int *gridOffset;
+       int gridSize, dGridSize, dSkip;
+} MultiresDispRunData;
+
+static void multires_disp_run_cb(
+        void *__restrict userdata,
+        const int pidx,
+        const ParallelRangeTLS *__restrict UNUSED(tls))
+{
+       MultiresDispRunData *tdata = userdata;
+
+       DispOp op = tdata->op;
+       CCGElem **gridData = tdata->gridData;
+       CCGElem **subGridData = tdata->subGridData;
+       CCGKey *key = tdata->key;
+       MPoly *mpoly = tdata->mpoly;
+       MDisps *mdisps = tdata->mdisps;
+       GridPaintMask *grid_paint_mask = tdata->grid_paint_mask;
+       int *gridOffset = tdata->gridOffset;
+       int gridSize = tdata->gridSize;
+       int dGridSize = tdata->dGridSize;
+       int dSkip = tdata->dSkip;
+
+       const int numVerts = mpoly[pidx].totloop;
+       int S, x, y, gIndex = gridOffset[pidx];
+
+       for (S = 0; S < numVerts; ++S, ++gIndex) {
+               GridPaintMask *gpm = grid_paint_mask ? &grid_paint_mask[gIndex] 
: NULL;
+               MDisps *mdisp = &mdisps[mpoly[pidx].loopstart + S];
+               CCGElem *grid = gridData[gIndex];
+               CCGElem *subgrid = subGridData[gIndex];
+               float (*dispgrid)[3] = NULL;
+
+               dispgrid = mdisp->disps;
+
+               /* if needed, reallocate multires paint mask */
+               if (gpm && gpm->level < key->level) {
+                       gpm->level = key->level;
+                       if (gpm->data) {
+                               MEM_freeN(gpm->data);
+                       }
+                       gpm->data = MEM_callocN(sizeof(float) * key->grid_area, 
"gpm.data");
+               }
+
+               for (y = 0; y < gridSize; y++) {
+                       for (x = 0; x < gridSize; x++) {
+                               float *co = CCG_grid_elem_co(key, grid, x, y);
+                               float *sco = CCG_grid_elem_co(key, subgrid, x, 
y);
+                               float *data = dispgrid[dGridSize * y * dSkip + 
x * dSkip];
+                               float mat[3][3], disp[3], d[3], mask;
+
+                               /* construct tangent space matrix */
+                               grid_tangent_matrix(mat, key, x, y, subgrid);
+
+                               switch (op) {
+                                       case APPLY_DISPLACEMENTS:
+                                               /* Convert displacement to 
object space
+                                                * and add to grid points */
+                                               mul_v3_m3v3(disp, mat, data);
+                                               add_v3_v3v3(co, sco, disp);
+                                               break;
+                                       case CALC_DISPLACEMENTS:
+                                               /* Calculate displacement 
between new and old
+                                                * grid points and convert to 
tangent space */
+                                               sub_v3_v3v3(disp, co, sco);
+                                               invert_m3(mat);
+                                               mul_v3_m3v3(data, mat, disp);
+                                               break;
+                                       case ADD_DISPLACEMENTS:
+                                               /* Convert subdivided 
displacements to tangent
+                                                * space and add to the 
original displacements */
+                                               invert_m3(mat);
+                                               mul_v3_m3v3(d, mat, co);
+                                               add_v3_v3(data, d);
+                                               break;
+                               }
+
+                               if (gpm) {
+                                       switch (op) {
+                                               case APPLY_DISPLACEMENTS:
+                                                       /* Copy mask from gpm 
to DM */
+                                                       
*CCG_grid_elem_mask(key, grid, x, y) =
+                                                           
paint_grid_paint_mask(gpm, key->level, x, y);
+                                                       break;
+                                               case CALC_DISPLACEMENTS:
+                                                       /* Copy mask from DM to 
gpm */
+                                                       mask = 
*CCG_grid_elem_mask(key, grid, x, y);
+                                                       gpm->data[y * gridSize 
+ x] = CLAMPIS(mask, 0, 1);
+                                                       break;
+                                               case ADD_DISPLACEMENTS:
+                                                       /* Add mask 
displacement to gpm */
+                                                       gpm->data[y * gridSize 
+ x] +=
+                                                           
*CCG_grid_elem_mask(key, grid, x, y);
+                                                       break;
+                                       }
+                               }
+                       }
+               }
+       }
+}
+
 /* XXX WARNING: subsurf elements from dm and oldGridData *must* be of the same 
format (size),
  *              because this code uses CCGKey's info from dm to access 
oldGridData's normals
  *              (through the call to grid_tangent_matrix())! */
@@ -1015,7 +1124,7 @@ static void multiresModifier_disp_run(DerivedMesh *dm, 
Mesh *me, DerivedMesh *dm
        MDisps *mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
        GridPaintMask *grid_paint_mask = NULL;
        int *gridOffset;
-       int i, k, /*numGrids, */ gridSize, dGridSize, dSkip;
+       int i, gridSize, dGridSize, dSkip;
        int totloop, totpoly;
        
        /* this happens in the dm made by bmesh_mdisps_space_set */
@@ -1051,8 +1160,6 @@ static void multiresModifier_disp_run(DerivedMesh *dm, 
Mesh *me, DerivedMesh *dm
        if (key.has_mask)
                grid_paint_mask = CustomData_get_layer(&me->ldata, 
CD_GRID_PAINT_MASK);
 
-       k = 0; /*current loop/mdisp index within the mloop array*/
-
        /* when adding new faces in edit mode, need to allocate disps */
        for (i = 0; i < totloop; ++i) {
                if (mdisps[i].disps == NULL) {
@@ -1061,90 +1168,25 @@ static void multiresModifier_disp_run(DerivedMesh *dm, 
Mesh *me, DerivedMesh *dm
                }
        }
 
-       BLI_begin_threaded_malloc();
-
-#pragma omp parallel for private(i) if (totloop * gridSize * gridSize >= 
CCG_OMP_LIMIT)
-
-       for (i = 0; i < totpoly; ++i) {
-               const int numVerts = mpoly[i].totloop;
-               int S, x, y, gIndex = gridOffset[i];
-
-               for (S = 0; S < numVerts; ++S, ++gIndex, ++k) {
-                       GridPaintMask *gpm = grid_paint_mask ? 
&grid_paint_mask[gIndex] : NULL;
-                       MDisps *mdisp = &mdisps[mpoly[i].loopstart + S];
-                       CCGElem *grid = gridData[gIndex];
-                       CCGElem *subgrid = subGridData[gIndex];
-                       float (*dispgrid)[3] = NULL;
-
-                       dispgrid = mdisp->disps;
-
-                       /* if needed, reallocate multires paint mask */
-                       if (gpm && gpm->level < key.level) {
-                               gpm->level = key.level;
-                               if (gpm->data) {
-                                       MEM_freeN(gpm->data);
-                               }
-                               gpm->data = MEM_callocN(sizeof(float) * 
key.grid_area, "gpm.data");
-                       }
-
-                       for (y = 0; y < gridSize; y++) {
-                               for (x = 0; x < gridSize; x++) {
-                                       float *co = CCG_grid_elem_co(&key, 
grid, x, y);
-                                       float *sco = CCG_grid_elem_co(&key, 
subgrid, x, y);
-                                       float *data = dispgrid[dGridSize * y * 
dSkip + x * dSkip];
-                                       float mat[3][3], disp[3], d[3], mask;
-
-                                       /* construct tangent space matrix */
-                                       grid_tangent_matrix(mat, &key, x, y, 
subgrid);
-
-                                       switch (op) {
-                                               case APPLY_DISPLACEMENTS:
-                                                       /* Convert displacement 
to object space
-                                                        * and add to grid 
points */
-                                                       mul_v3_m3v3(disp, mat, 
data);
-                                                       add_v3_v3v3(co, sco, 
disp);
-                                                       break;
-                                               case CALC_DISPLACEMENTS:
-                                                       /* Calculate 
displacement between new and old
-                                                        * grid points and 
convert to tangent space */
-                                                       sub_v3_v3v3(disp, co, 
sco);
-                                                       invert_m3(mat);
-                                                       mul_v3_m3v3(data, mat, 
disp);
-                                                       break;
-                                               case ADD_DISPLACEMENTS:
-                                                       /* Convert subdivided 
displacements to tangent
-                                                        * space and add to the 
original displacements */
-                                                       invert_m3(mat);
-                                                       mul_v3_m3v3(d, mat, co);
-                                                       add_v3_v3(data, d);
-                                                       break;
-                                       }
-
-                                       if (gpm) {
-                                               switch (op) {
-                                                       case 
APPLY_DISPLACEMENTS:
-                                                               /* Copy mask 
from gpm to DM */
-                                                               
*CCG_grid_elem_mask(&key, grid, x, y) =
-                                                                   
paint_grid_paint_mask(gpm, key.level, x, y);
-                                                               break;
-                                                       case CALC_DISPLACEMENTS:
-                                                               /* Copy mask 
from DM to gpm */
-                                                               mask = 
*CCG_grid_elem_mask(&key, grid, x, y);
-                                                               gpm->data[y * 
gridSize + x] = CLAMPIS(mask, 0, 1);
-                                                               break;
-                                                       case ADD_DISPLACEMENTS:
-                                                               /* Add mask 
displacement to gpm */
-                                                               gpm->data[y * 
gridSize + x] +=
-                                                                   
*CCG_grid_elem_mask(&key, grid, x, y);
-                                                               break;
-                                               }
-                                       }
-                               }
-                       }
-               }
-       }
-       
-       BLI_end_threaded_malloc();
+       ParallelRangeSettings settings;
+       BLI_parallel_range_settings_defaults(&settings);
+       settings.min_iter_per_thread = CCG_TASK_LIMIT;
+
+       MultiresDispRunData data = {
+           .op = op,
+           .gridData = gridData,
+           .subGridData = subGridData,
+           .key = &key,
+           .mpoly = mpoly,
+           .mdisps = mdisps,
+           .grid_paint_mask = grid_paint_mask,
+           .gridOffset = gridOffset,
+           .gridSize = gridSize,
+           .dGridSize = dGridSize,
+           .dSkip = dSkip
+       };
+
+       BLI_task_parallel_range(0, totpoly, &data, multires_disp_run_cb, 
&settings);
 
        if (op == APPLY_DISPLACEMENTS) {
                ccgSubSurf_stitchFaces(ccgdm->ss, 0, NULL, 0);

_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to