[Bf-blender-cvs] [d885b1141c7] master: DRW: optimize mesh data extraction

Campbell Barton noreply at git.blender.org
Wed Jul 1 06:57:52 CEST 2020


Commit: d885b1141c7cdf8c75ec7e1983546c2dd9da1004
Author: Campbell Barton
Date:   Wed Jul 1 00:13:39 2020 +1000
Branches: master
https://developer.blender.org/rBd885b1141c7cdf8c75ec7e1983546c2dd9da1004

DRW: optimize mesh data extraction

Change extraction callbacks to take index ranges instead of calling them
for each mesh element (poly, loop, vert & edge).

This gives a minor overall performance gain in my tests, ~5% on average.

Details:

- Use typed parameter structs and macros for looping over elements.
  Without this, changes to these callbacks is time consuming as changes
  need to be made in many places.
- Avoid iterating over polygon-loops when iterating over polygons
  is sufficient.
- Simplify logic to access adjacent loops for faster line extraction.
- Rename 'loop' iterators to 'poly' (as they take polygon ranges)
  the iterator callbacks can operator on either polygon or loop data.
- Use term 'last' for the last index (inclusive),
  use 'end' when this value (not inclusive).

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

M	source/blender/draw/intern/draw_cache_extract.h
M	source/blender/draw/intern/draw_cache_extract_mesh.c

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

diff --git a/source/blender/draw/intern/draw_cache_extract.h b/source/blender/draw/intern/draw_cache_extract.h
index 0b1f625dc2c..302f9a0d3a8 100644
--- a/source/blender/draw/intern/draw_cache_extract.h
+++ b/source/blender/draw/intern/draw_cache_extract.h
@@ -63,7 +63,7 @@ typedef struct DRW_MeshCDMask {
 
 typedef enum eMRIterType {
   MR_ITER_LOOPTRI = 1 << 0,
-  MR_ITER_LOOP = 1 << 1,
+  MR_ITER_POLY = 1 << 1,
   MR_ITER_LEDGE = 1 << 2,
   MR_ITER_LVERT = 1 << 3,
 } eMRIterType;
diff --git a/source/blender/draw/intern/draw_cache_extract_mesh.c b/source/blender/draw/intern/draw_cache_extract_mesh.c
index f1a7ab8c9d8..c92722fad7e 100644
--- a/source/blender/draw/intern/draw_cache_extract_mesh.c
+++ b/source/blender/draw/intern/draw_cache_extract_mesh.c
@@ -148,14 +148,14 @@ static void mesh_render_data_update_loose_geom(MeshRenderData *mr,
       BLI_bitmap *lvert_map = BLI_BITMAP_NEW(mr->vert_len, __func__);
 
       mr->ledges = MEM_mallocN(mr->edge_len * sizeof(int), __func__);
-      const MEdge *medge = mr->medge;
-      for (int e = 0; e < mr->edge_len; e++, medge++) {
-        if (medge->flag & ME_LOOSEEDGE) {
-          mr->ledges[mr->edge_loose_len++] = e;
+      const MEdge *med = mr->medge;
+      for (int med_index = 0; med_index < mr->edge_len; med_index++, med++) {
+        if (med->flag & ME_LOOSEEDGE) {
+          mr->ledges[mr->edge_loose_len++] = med_index;
         }
         /* Tag verts as not loose. */
-        BLI_BITMAP_ENABLE(lvert_map, medge->v1);
-        BLI_BITMAP_ENABLE(lvert_map, medge->v2);
+        BLI_BITMAP_ENABLE(lvert_map, med->v1);
+        BLI_BITMAP_ENABLE(lvert_map, med->v2);
       }
       if (mr->edge_loose_len < mr->edge_len) {
         mr->ledges = MEM_reallocN(mr->ledges, mr->edge_loose_len * sizeof(*mr->ledges));
@@ -173,7 +173,7 @@ static void mesh_render_data_update_loose_geom(MeshRenderData *mr,
 
       MEM_freeN(lvert_map);
 
-      mr->loop_loose_len = mr->vert_loose_len + mr->edge_loose_len * 2;
+      mr->loop_loose_len = mr->vert_loose_len + (mr->edge_loose_len * 2);
     }
   }
   else {
@@ -297,7 +297,7 @@ static void mesh_render_data_update_normals(MeshRenderData *mr,
       }
 
       mr->loop_normals = MEM_mallocN(sizeof(*mr->loop_normals) * mr->loop_len, __func__);
-      int clnors_offset = CustomData_get_offset(&mr->bm->ldata, CD_CUSTOMLOOPNORMAL);
+      const int clnors_offset = CustomData_get_offset(&mr->bm->ldata, CD_CUSTOMLOOPNORMAL);
       BM_loops_calc_normal_vcos(mr->bm,
                                 vert_coords,
                                 vert_normals,
@@ -507,45 +507,254 @@ BLI_INLINE const float *bm_face_no_get(const MeshRenderData *mr, const BMFace *e
 /** \} */
 
 /* ---------------------------------------------------------------------- */
-/** \name Mesh Elements Extract Iter
+/** \name Mesh Elements Extract: Loop Triangles
  * \{ */
 
-typedef void *(ExtractInitFn)(const MeshRenderData *mr, void *buffer);
-
+typedef struct ExtractTriBMesh_Params {
+  BMLoop *(*looptris)[3];
+  int tri_range[2];
+} ExtractTriBMesh_Params;
 typedef void(ExtractTriBMeshFn)(const MeshRenderData *mr,
-                                int tri_index,
-                                BMLoop **ltri,
+                                const ExtractTriBMesh_Params *params,
                                 void *data);
+
+#define EXTRACT_TRIS_LOOPTRI_FOREACH_BM_BEGIN(elem_tri, index_tri, params) \
+  CHECK_TYPE(params, const ExtractTriBMesh_Params *); \
+  { \
+    const int _tri_index_end = (params)->tri_range[1]; \
+    BMLoop **elem_tri = (params)->looptris[(params)->tri_range[0]]; \
+    for (int index_tri = (params)->tri_range[0]; index_tri < _tri_index_end; \
+         index_tri += 1, elem_tri += 3)
+#define EXTRACT_TRIS_LOOPTRI_FOREACH_BM_END }
+
+typedef struct ExtractTriMesh_Params {
+  const MLoopTri *mlooptri;
+  int tri_range[2];
+} ExtractTriMesh_Params;
 typedef void(ExtractTriMeshFn)(const MeshRenderData *mr,
-                               int tri_index,
-                               const MLoopTri *mlt,
+                               const ExtractTriMesh_Params *params,
                                void *data);
 
-typedef void(ExtractLoopBMeshFn)(const MeshRenderData *mr, int loop_index, BMLoop *el, void *data);
-typedef void(ExtractLoopMeshFn)(const MeshRenderData *mr,
-                                int loop_index,
-                                const MLoop *mloop,
-                                int poly_index,
-                                const MPoly *mpoly,
+#define EXTRACT_TRIS_LOOPTRI_FOREACH_MESH_BEGIN(elem_tri, index_tri, params) \
+  CHECK_TYPE(params, const ExtractTriMesh_Params *); \
+  { \
+    const int _tri_index_end = (params)->tri_range[1]; \
+    const MLoopTri *elem_tri = &(params)->mlooptri[(params)->tri_range[0]]; \
+    for (int index_tri = (params)->tri_range[0]; index_tri < _tri_index_end; \
+         index_tri += 1, elem_tri += 1)
+#define EXTRACT_TRIS_LOOPTRI_FOREACH_MESH_END }
+
+/** \} */
+
+/* ---------------------------------------------------------------------- */
+/** \name Mesh Elements Extract: Polygons, Loops
+ * \{ */
+
+typedef struct ExtractPolyBMesh_Params {
+  BMLoop *(*looptris)[3];
+  int poly_range[2];
+} ExtractPolyBMesh_Params;
+typedef void(ExtractPolyBMeshFn)(const MeshRenderData *mr,
+                                 const ExtractPolyBMesh_Params *params,
+                                 void *data);
+
+#define EXTRACT_POLY_FOREACH_BM_BEGIN(elem_poly, index_poly, params, mr) \
+  CHECK_TYPE(params, const ExtractPolyBMesh_Params *); \
+  { \
+    BLI_assert((mr->bm->elem_table_dirty & BM_FACE) == 0); \
+    BMFace **_ftable = mr->bm->ftable; \
+    const int _poly_index_end = (params)->poly_range[1]; \
+    for (int index_poly = (params)->poly_range[0]; index_poly < _poly_index_end; \
+         index_poly += 1) { \
+      BMFace *elem_poly = _ftable[index_poly]; \
+      (void)elem_poly;
+
+#define EXTRACT_POLY_FOREACH_BM_END \
+  } \
+  }
+
+/* Iterate over polygon and loop. */
+#define EXTRACT_POLY_AND_LOOP_FOREACH_BM_BEGIN(elem_loop, index_loop, params, mr) \
+  CHECK_TYPE(params, const ExtractPolyBMesh_Params *); \
+  { \
+    BLI_assert((mr->bm->elem_table_dirty & BM_FACE) == 0); \
+    BMFace **_ftable = mr->bm->ftable; \
+    const int _poly_index_end = (params)->poly_range[1]; \
+    for (int index_poly = (params)->poly_range[0]; index_poly < _poly_index_end; \
+         index_poly += 1) { \
+      BMFace *elem_face = _ftable[index_poly]; \
+      BMLoop *elem_loop, *l_first; \
+      elem_loop = l_first = BM_FACE_FIRST_LOOP(elem_face); \
+      do { \
+        const int index_loop = BM_elem_index_get(elem_loop); \
+        (void)index_loop; /* Quiet warning when unused. */
+
+#define EXTRACT_POLY_AND_LOOP_FOREACH_BM_END(elem_loop) \
+  } \
+  while ((elem_loop = elem_loop->next) != l_first) \
+    ; \
+  } \
+  }
+
+typedef struct ExtractPolyMesh_Params {
+  int poly_range[2];
+} ExtractPolyMesh_Params;
+typedef void(ExtractPolyMeshFn)(const MeshRenderData *mr,
+                                const ExtractPolyMesh_Params *params,
                                 void *data);
 
+#define EXTRACT_POLY_FOREACH_MESH_BEGIN(elem_poly, index_poly, params, mr) \
+  CHECK_TYPE(params, const ExtractPolyMesh_Params *); \
+  { \
+    const MPoly *_mpoly = mr->mpoly; \
+    const int _poly_index_end = (params)->poly_range[1]; \
+    for (int index_poly = (params)->poly_range[0]; index_poly < _poly_index_end; \
+         index_poly += 1) { \
+      const MPoly *elem_poly = &_mpoly[index_poly]; \
+      (void)elem_poly;
+
+#define EXTRACT_POLY_FOREACH_MESH_END \
+  } \
+  }
+
+/* Iterate over polygon and loop. */
+#define EXTRACT_POLY_AND_LOOP_FOREACH_MESH_BEGIN( \
+    elem_poly, index_poly, elem_loop, index_loop, params, mr) \
+  CHECK_TYPE(params, const ExtractPolyMesh_Params *); \
+  { \
+    const MPoly *_mpoly = mr->mpoly; \
+    const MLoop *_mloop = mr->mloop; \
+    const int _poly_index_end = (params)->poly_range[1]; \
+    for (int index_poly = (params)->poly_range[0]; index_poly < _poly_index_end; \
+         index_poly += 1) { \
+      const MPoly *elem_poly = &_mpoly[index_poly]; \
+      const int _index_end = elem_poly->loopstart + elem_poly->totloop; \
+      for (int index_loop = elem_poly->loopstart; index_loop < _index_end; index_loop += 1) { \
+        const MLoop *elem_loop = &_mloop[index_loop]; \
+        (void)elem_loop;
+
+#define EXTRACT_POLY_AND_LOOP_FOREACH_MESH_END \
+  } \
+  } \
+  }
+
+/** \} */
+
+/* ---------------------------------------------------------------------- */
+/** \name Mesh Elements Extract: Loose Edges
+ * \{ */
+
+typedef struct ExtractLEdgeBMesh_Params {
+  const int *ledge;
+  int ledge_range[2];
+} ExtractLEdgeBMesh_Params;
 typedef void(ExtractLEdgeBMeshFn)(const MeshRenderData *mr,
-                                  int ledge_index,
-                                  BMEdge *eed,
+                                  const ExtractLEdgeBMesh_Params *params,
                                   void *data);
+
+#define EXTRACT_LEDGE_FOREACH_BM_BEGIN(elem_edge, index_ledge, params) \
+  CHECK_TYPE(params, const ExtractLEdgeBMesh_Params *); \
+  { \
+    BLI_assert((mr->bm->elem_table_dirty & BM_EDGE) == 0); \
+    BMEdge **_etable = mr->bm->etable; \
+    const int *_ledge = (params)->ledge; \
+    const int _ledge_index_end = (params)->ledge_range[1]; \
+    for (int index_ledge = (params)->ledge_range[0]; index_ledge < _ledge_index_end; \
+         index_ledge += 1) { \
+      BMEdge *elem_edge = _etable[_ledge[index_ledge]]; \
+      (void)elem_edge; /* Quiet warning when unused. */ \
+      {
+#define EXTRACT_LEDGE_FOREACH_BM_END \
+  } \
+  } \
+  }
+
+typedef struct ExtractLEdgeMesh_Params {
+  const int *ledge;
+  int ledge_range[2];
+} ExtractLEdgeMesh_Params;
 typedef void(ExtractLEdgeMeshFn)(const MeshRenderData *mr,
-                                 int ledge_index,
-                                 const MEdge *medge,
+                                 const ExtractLEdgeMesh_Params *params,
                                  void *data);
 
+#define EXTRACT_LEDGE_FOREACH_MESH_BEGIN(elem_edge, index_ledge, params, mr) \
+  CHECK_TYPE(params, const ExtractLEdge

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list