[Bf-blender-cvs] [44d2479dc36] master: Refactor: DRW Mesh Extractor: Join the extractors in a same loop

Jeroen Bakker noreply at git.blender.org
Mon May 31 17:17:14 CEST 2021


Commit: 44d2479dc36fe3409afc660eea369bea8a517987
Author: Jeroen Bakker
Date:   Mon May 31 17:11:01 2021 +0200
Branches: master
https://developer.blender.org/rB44d2479dc36fe3409afc660eea369bea8a517987

Refactor: DRW Mesh Extractor: Join the extractors in a same loop

This patch replaces / redoes the entire MeshExtractors system.
Although they were useful and facilitated the addition of new buffers, they made it difficult to control the threads and added a lot of threading overhead.

Part of the problem was in traversing the same loop type in different threads. The concurrent access of the BMesh Elements slowed the reading.

This patch simplifies the use of threads by merging all the old callbacks from the extracts into a single series of iteration functions.

The type of extraction can be chosen using flags.

This optimized the process by around 34%.

Initial idea and implementation By @mano-wii.
Fine-tuning, cleanup by @atmind.

MASTER:
large_mesh_editing:
- rdata 9ms iter 50ms (frame 155ms)
- Average: 6.462874 FPS

PATCH:
large_mesh_editing:
- rdata 9ms iter 34ms (frame 136ms)
- Average: 7.379491 FPS

Differential Revision: https://developer.blender.org/D11425

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

M	source/blender/draw/intern/draw_cache_extract.h
M	source/blender/draw/intern/draw_cache_extract_mesh.c
M	source/blender/draw/intern/draw_cache_impl_curve.cc
M	source/blender/draw/intern/draw_cache_impl_displist.c
M	source/blender/draw/intern/draw_cache_impl_mesh.c
M	source/blender/draw/intern/draw_cache_inline.h

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

diff --git a/source/blender/draw/intern/draw_cache_extract.h b/source/blender/draw/intern/draw_cache_extract.h
index 14cbba82fba..e6b7fb9ddf5 100644
--- a/source/blender/draw/intern/draw_cache_extract.h
+++ b/source/blender/draw/intern/draw_cache_extract.h
@@ -286,7 +286,7 @@ typedef struct MeshBatchCache {
 
 void mesh_buffer_cache_create_requested(struct TaskGraph *task_graph,
                                         MeshBatchCache *cache,
-                                        MeshBufferCache mbc,
+                                        MeshBufferCache *mbc,
                                         MeshBufferExtractionCache *extraction_cache,
                                         Mesh *me,
                                         const bool is_editmode,
diff --git a/source/blender/draw/intern/draw_cache_extract_mesh.c b/source/blender/draw/intern/draw_cache_extract_mesh.c
index 62d8040e88b..1a78ce71d74 100644
--- a/source/blender/draw/intern/draw_cache_extract_mesh.c
+++ b/source/blender/draw/intern/draw_cache_extract_mesh.c
@@ -78,6 +78,13 @@
 #  include "PIL_time_utildefines.h"
 #endif
 
+#define CHUNK_SIZE 8192
+
+/*
+ * Max number of extractions types.
+ */
+#define M_EXTRACT_LEN 38
+
 /* ---------------------------------------------------------------------- */
 /** \name Mesh/BMesh Interface (indirect, partially cached access to complex data).
  * \{ */
@@ -528,7 +535,8 @@ typedef struct ExtractTriBMesh_Params {
   int tri_range[2];
 } ExtractTriBMesh_Params;
 typedef void(ExtractTriBMeshFn)(const MeshRenderData *mr,
-                                const ExtractTriBMesh_Params *params,
+                                BMLoop **elt,
+                                const int elt_index,
                                 void *data);
 
 #define EXTRACT_TRIS_LOOPTRI_FOREACH_BM_BEGIN(elem_tri, index_tri, params) \
@@ -545,7 +553,8 @@ typedef struct ExtractTriMesh_Params {
   int tri_range[2];
 } ExtractTriMesh_Params;
 typedef void(ExtractTriMeshFn)(const MeshRenderData *mr,
-                               const ExtractTriMesh_Params *params,
+                               const MLoopTri *mlt,
+                               const int elt_index,
                                void *data);
 
 #define EXTRACT_TRIS_LOOPTRI_FOREACH_MESH_BEGIN(elem_tri, index_tri, params) \
@@ -568,7 +577,8 @@ typedef struct ExtractPolyBMesh_Params {
   int poly_range[2];
 } ExtractPolyBMesh_Params;
 typedef void(ExtractPolyBMeshFn)(const MeshRenderData *mr,
-                                 const ExtractPolyBMesh_Params *params,
+                                 BMFace *f,
+                                 const int f_index,
                                  void *data);
 
 #define EXTRACT_POLY_FOREACH_BM_BEGIN(elem_poly, index_poly, params, mr) \
@@ -613,7 +623,8 @@ typedef struct ExtractPolyMesh_Params {
   int poly_range[2];
 } ExtractPolyMesh_Params;
 typedef void(ExtractPolyMeshFn)(const MeshRenderData *mr,
-                                const ExtractPolyMesh_Params *params,
+                                const MPoly *mp,
+                                const int mp_index,
                                 void *data);
 
 #define EXTRACT_POLY_FOREACH_MESH_BEGIN(elem_poly, index_poly, params, mr) \
@@ -662,7 +673,8 @@ typedef struct ExtractLEdgeBMesh_Params {
   int ledge_range[2];
 } ExtractLEdgeBMesh_Params;
 typedef void(ExtractLEdgeBMeshFn)(const MeshRenderData *mr,
-                                  const ExtractLEdgeBMesh_Params *params,
+                                  BMEdge *eed,
+                                  const int ledge_index,
                                   void *data);
 
 #define EXTRACT_LEDGE_FOREACH_BM_BEGIN(elem_edge, index_ledge, params) \
@@ -687,7 +699,8 @@ typedef struct ExtractLEdgeMesh_Params {
   int ledge_range[2];
 } ExtractLEdgeMesh_Params;
 typedef void(ExtractLEdgeMeshFn)(const MeshRenderData *mr,
-                                 const ExtractLEdgeMesh_Params *params,
+                                 const MEdge *med,
+                                 const uint ledge_index,
                                  void *data);
 
 #define EXTRACT_LEDGE_FOREACH_MESH_BEGIN(elem_edge, index_ledge, params, mr) \
@@ -717,7 +730,8 @@ typedef struct ExtractLVertBMesh_Params {
   int lvert_range[2];
 } ExtractLVertBMesh_Params;
 typedef void(ExtractLVertBMeshFn)(const MeshRenderData *mr,
-                                  const ExtractLVertBMesh_Params *params,
+                                  BMVert *eve,
+                                  const int lvert_index,
                                   void *data);
 
 #define EXTRACT_LVERT_FOREACH_BM_BEGIN(elem_vert, index_lvert, params) \
@@ -742,7 +756,8 @@ typedef struct ExtractLVertMesh_Params {
   int lvert_range[2];
 } ExtractLVertMesh_Params;
 typedef void(ExtractLVertMeshFn)(const MeshRenderData *mr,
-                                 const ExtractLVertMesh_Params *params,
+                                 const MVert *mv,
+                                 const int lvert_index,
                                  void *data);
 
 #define EXTRACT_LVERT_FOREACH_MESH_BEGIN(elem, index_lvert, params, mr) \
@@ -793,8 +808,98 @@ typedef struct MeshExtract {
   const eMRDataType data_flag;
   /** Used to know if the element callbacks are thread-safe and can be parallelized. */
   const bool use_threading;
+  /**
+   * Offset in bytes of the buffer inside a MeshBufferCache instance. Points to a vertex or index
+   * buffer.
+   */
+  const size_t mesh_buffer_offset;
 } MeshExtract;
 
+static void *mesh_extract_buffer_get(const MeshExtract *extractor, MeshBufferCache *mbc)
+{
+  /* NOTE: POINTER_OFFSET on windows platforms casts internally to `void *`, but on GCC/CLANG to
+   * `MeshBufferCache *`. What shows a different usage versus intent. */
+  void **buffer_ptr = (void **)POINTER_OFFSET(mbc, extractor->mesh_buffer_offset);
+  void *buffer = *buffer_ptr;
+  BLI_assert(buffer);
+  return buffer;
+}
+
+typedef struct MeshExtractRunData {
+  const MeshExtract *extractor;
+  void *buffer;
+  void *user_data;
+} MeshExtractRunData;
+
+typedef struct MeshExtractRunDataArray {
+  int len;
+  MeshExtractRunData items[M_EXTRACT_LEN];
+} MeshExtractRunDataArray;
+
+static void mesh_extract_run_data_array_init(MeshExtractRunDataArray *array)
+{
+  array->len = 0;
+}
+
+static void mesh_extract_run_data_array_add_ex(MeshExtractRunDataArray *array,
+                                               const MeshExtractRunData *run_data)
+{
+  array->items[array->len] = *run_data;
+  array->len++;
+}
+
+static void mesh_extract_run_data_array_add(MeshExtractRunDataArray *array,
+                                            const MeshExtract *extractor)
+{
+  MeshExtractRunData run_data;
+  run_data.extractor = extractor;
+  run_data.buffer = NULL;
+  run_data.user_data = NULL;
+  mesh_extract_run_data_array_add_ex(array, &run_data);
+}
+
+static void mesh_extract_run_data_array_filter_iter_type(const MeshExtractRunDataArray *src,
+                                                         MeshExtractRunDataArray *dst,
+                                                         eMRIterType iter_type)
+{
+  for (int i = 0; i < src->len; i++) {
+
+    const MeshExtractRunData *data = &src->items[i];
+    const MeshExtract *extractor = data->extractor;
+    if ((iter_type & MR_ITER_LOOPTRI) && extractor->iter_looptri_bm) {
+      BLI_assert(extractor->iter_looptri_mesh);
+      mesh_extract_run_data_array_add_ex(dst, data);
+      continue;
+    }
+    if ((iter_type & MR_ITER_POLY) && extractor->iter_poly_bm) {
+      BLI_assert(extractor->iter_poly_mesh);
+      mesh_extract_run_data_array_add_ex(dst, data);
+      continue;
+    }
+    if ((iter_type & MR_ITER_LEDGE) && extractor->iter_ledge_bm) {
+      BLI_assert(extractor->iter_ledge_mesh);
+      mesh_extract_run_data_array_add_ex(dst, data);
+      continue;
+    }
+    if ((iter_type & MR_ITER_LVERT) && extractor->iter_lvert_bm) {
+      BLI_assert(extractor->iter_lvert_mesh);
+      mesh_extract_run_data_array_add_ex(dst, data);
+      continue;
+    }
+  }
+}
+
+static void mesh_extract_run_data_array_filter_threading(
+    const MeshExtractRunDataArray *src, MeshExtractRunDataArray *dst_multi_threaded)
+{
+  for (int i = 0; i < src->len; i++) {
+    const MeshExtract *extractor = src->items[i].extractor;
+    if (extractor->use_threading) {
+      mesh_extract_run_data_array_add(dst_multi_threaded, extractor);
+    }
+  }
+}
+
 BLI_INLINE eMRIterType mesh_extract_iter_type(const MeshExtract *ext)
 {
   eMRIterType type = 0;
@@ -866,69 +971,65 @@ static void *extract_tris_init(const MeshRenderData *mr,
 }
 
 static void extract_tris_iter_looptri_bm(const MeshRenderData *mr,
-                                         const struct ExtractTriBMesh_Params *params,
+                                         BMLoop **elt,
+                                         const int UNUSED(elt_index),
                                          void *_data)
 {
   MeshExtract_Tri_Data *data = _data;
   const int mat_last = mr->mat_len - 1;
-  EXTRACT_TRIS_LOOPTRI_FOREACH_BM_BEGIN(elt, _elt_index, params)
-  {
-    if (!BM_elem_flag_test(elt[0]->f, BM_ELEM_HIDDEN)) {
-      int *mat_tri_ofs = data->tri_mat_end;
-      const int mat = min_ii(elt[0]->f->mat_nr, mat_last);
-      GPU_indexbuf_set_tri_verts(&data->elb,
-                                 mat_tri_ofs[mat]++,
-                                 BM_elem_index_get(elt[0]),
-                                 BM_elem_index_get(elt[1]),
-                                 BM_elem_index_get(elt[2]));
-    }
+
+  if (!BM_elem_flag_test(elt[0]->f, BM_ELEM_HIDDEN)) {
+    int *mat_tri_ofs = data->tri_mat_end;
+    const int mat = min_ii(elt[0]->f->mat_nr, mat_last);
+    GPU_indexbuf_set_tri_verts(&data->elb,
+                               mat_tri_ofs[mat]++,
+                               BM_elem_index_get(elt[0]),
+                               BM_elem_index_get(elt[1]),
+                               BM_elem_index_get(elt[2]));
   }
-  EXTRACT_TRIS_LOOPTRI_FOREACH_BM_END;
 }
 
 static void extract_tris_iter_looptri_mesh(const MeshRenderData *mr,
-                                           const struct ExtractT

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list