[Bf-blender-cvs] [9c010c44f42] master: Mesh Batch Cache: Refactor + Multithread

Clément Foucault noreply at git.blender.org
Wed Aug 14 19:05:33 CEST 2019


Commit: 9c010c44f4201ab114b3facc69d0343525a1779f
Author: Clément Foucault
Date:   Sun Jul 14 16:49:44 2019 +0200
Branches: master
https://developer.blender.org/rB9c010c44f4201ab114b3facc69d0343525a1779f

Mesh Batch Cache: Refactor + Multithread

For clarity sake, the batch cache now uses exclusively per Loop attributes.
While this is a bit of a waste of VRAM (for the few case where per vert
attribs are enough) it reduces the complexity and amount of overall VBO
to update in general situations.

This patch also makes the VertexBuffers filling multithreaded. This make
the update of dense meshes a bit faster. The main bottleneck is the
IndexBuffers update which cannot be multithreaded efficiently (have to
increment a counter and/or do a final sorting pass).

We introduce the concept of "extract" functions/step.
All extract functions are executed in one thread each and if possible,
using multiple thread for looping over all elements.

Reviewed By: brecht

Differential Revision: http://developer.blender.org/D5424

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

M	source/blender/blenkernel/BKE_mesh.h
M	source/blender/blenkernel/intern/mesh_evaluate.c
M	source/blender/blenlib/BLI_math_geom.h
M	source/blender/blenlib/intern/math_geom.c
M	source/blender/draw/CMakeLists.txt
M	source/blender/draw/intern/draw_cache.c
A	source/blender/draw/intern/draw_cache_extract.h
A	source/blender/draw/intern/draw_cache_extract_mesh.c
M	source/blender/draw/intern/draw_cache_impl.h
M	source/blender/draw/intern/draw_cache_impl_mesh.c
M	source/blender/draw/modes/edit_mesh_mode.c
M	source/blender/draw/modes/shaders/edit_mesh_overlay_mesh_analysis_frag.glsl
M	source/blender/draw/modes/shaders/edit_mesh_overlay_mesh_analysis_vert.glsl
M	source/blender/editors/uvedit/uvedit_draw.c
M	source/blender/gpu/GPU_batch.h
M	source/blender/gpu/GPU_element.h
M	source/blender/gpu/GPU_vertex_format.h
M	source/blender/gpu/intern/gpu_batch.c
M	source/blender/gpu/intern/gpu_element.c
M	source/blender/gpu/intern/gpu_vertex_format.c
M	source/blender/gpu/intern/gpu_vertex_format_private.h
M	source/blender/gpu/shaders/gpu_shader_2D_edituvs_stretch_vert.glsl
M	source/blender/makesrna/intern/rna_scene.c

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

diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index 924cfad37d6..94d118bde36 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -486,6 +486,7 @@ void BKE_mesh_calc_poly_center(const struct MPoly *mpoly,
 float BKE_mesh_calc_poly_area(const struct MPoly *mpoly,
                               const struct MLoop *loopstart,
                               const struct MVert *mvarray);
+float BKE_mesh_calc_poly_uv_area(const struct MPoly *mpoly, const struct MLoopUV *uv_array);
 void BKE_mesh_calc_poly_angles(const struct MPoly *mpoly,
                                const struct MLoop *loopstart,
                                const struct MVert *mvarray,
diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c b/source/blender/blenkernel/intern/mesh_evaluate.c
index e28d50cbde4..2ea275cdfb0 100644
--- a/source/blender/blenkernel/intern/mesh_evaluate.c
+++ b/source/blender/blenkernel/intern/mesh_evaluate.c
@@ -2378,6 +2378,24 @@ float BKE_mesh_calc_poly_area(const MPoly *mpoly, const MLoop *loopstart, const
   }
 }
 
+float BKE_mesh_calc_poly_uv_area(const MPoly *mpoly, const MLoopUV *uv_array)
+{
+
+  int i, l_iter = mpoly->loopstart;
+  float area;
+  float(*vertexcos)[2] = BLI_array_alloca(vertexcos, (size_t)mpoly->totloop);
+
+  /* pack vertex cos into an array for area_poly_v2 */
+  for (i = 0; i < mpoly->totloop; i++, l_iter++) {
+    copy_v2_v2(vertexcos[i], uv_array[l_iter].uv);
+  }
+
+  /* finally calculate the area */
+  area = area_poly_v2((const float(*)[2])vertexcos, (unsigned int)mpoly->totloop);
+
+  return area;
+}
+
 /**
  * Calculate the volume and volume-weighted centroid of the volume
  * formed by the polygon and the origin.
diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h
index b1437dbe140..39b1b96d009 100644
--- a/source/blender/blenlib/BLI_math_geom.h
+++ b/source/blender/blenlib/BLI_math_geom.h
@@ -92,6 +92,7 @@ float volume_tetrahedron_signed_v3(const float v1[3],
                                    const float v3[3],
                                    const float v4[3]);
 
+bool is_edge_convex_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3]);
 bool is_quad_convex_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3]);
 bool is_quad_convex_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2]);
 bool is_poly_convex_v2(const float verts[][2], unsigned int nr);
diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c
index bb3d2786ca6..06fd5c70772 100644
--- a/source/blender/blenlib/intern/math_geom.c
+++ b/source/blender/blenlib/intern/math_geom.c
@@ -5729,6 +5729,27 @@ float form_factor_hemi_poly(
   return contrib;
 }
 
+/**
+ * Check if the edge is convex or concave
+ * (depends on face winding)
+ * Copied from BM_edge_is_convex().
+ */
+bool is_edge_convex_v3(const float v1[3],
+                       const float v2[3],
+                       const float f1_no[3],
+                       const float f2_no[3])
+{
+  if (!equals_v3v3(f1_no, f2_no)) {
+    float cross[3];
+    float l_dir[3];
+    cross_v3_v3v3(cross, f1_no, f2_no);
+    /* we assume contiguous normals, otherwise the result isn't meaningful */
+    sub_v3_v3v3(l_dir, v2, v1);
+    return (dot_v3v3(l_dir, cross) > 0.0f);
+  }
+  return false;
+}
+
 /**
  * Evaluate if entire quad is a proper convex quad
  */
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index e34ad155f21..1112a7a87db 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -52,6 +52,7 @@ set(SRC
   intern/draw_anim_viz.c
   intern/draw_armature.c
   intern/draw_cache.c
+  intern/draw_cache_extract_mesh.c
   intern/draw_cache_impl_curve.c
   intern/draw_cache_impl_displist.c
   intern/draw_cache_impl_lattice.c
@@ -135,6 +136,7 @@ set(SRC
   DRW_select_buffer.h
   intern/DRW_render.h
   intern/draw_cache.h
+  intern/draw_cache_extract.h
   intern/draw_cache_impl.h
   intern/draw_cache_inline.h
   intern/draw_common.h
diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c
index e2e98a2db5a..bad4b55eb1a 100644
--- a/source/blender/draw/intern/draw_cache.c
+++ b/source/blender/draw/intern/draw_cache.c
@@ -4033,7 +4033,7 @@ void drw_batch_cache_validate(Object *ob)
 void drw_batch_cache_generate_requested(Object *ob)
 {
   const DRWContextState *draw_ctx = DRW_context_state_get();
-  const ToolSettings *ts = draw_ctx->scene->toolsettings;
+  const Scene *scene = draw_ctx->scene;
   const enum eContextObjectMode mode = CTX_data_mode_enum_ex(
       draw_ctx->object_edit, draw_ctx->obact, draw_ctx->object_mode);
   const bool is_paint_mode = ELEM(
@@ -4047,13 +4047,13 @@ void drw_batch_cache_generate_requested(Object *ob)
   struct Mesh *mesh_eval = ob->runtime.mesh_eval;
   switch (ob->type) {
     case OB_MESH:
-      DRW_mesh_batch_cache_create_requested(ob, (Mesh *)ob->data, ts, is_paint_mode, use_hide);
+      DRW_mesh_batch_cache_create_requested(ob, (Mesh *)ob->data, scene, is_paint_mode, use_hide);
       break;
     case OB_CURVE:
     case OB_FONT:
     case OB_SURF:
       if (mesh_eval) {
-        DRW_mesh_batch_cache_create_requested(ob, mesh_eval, ts, is_paint_mode, use_hide);
+        DRW_mesh_batch_cache_create_requested(ob, mesh_eval, scene, is_paint_mode, use_hide);
       }
       DRW_curve_batch_cache_create_requested(ob);
       break;
diff --git a/source/blender/draw/intern/draw_cache_extract.h b/source/blender/draw/intern/draw_cache_extract.h
new file mode 100644
index 00000000000..5a06210fe8e
--- /dev/null
+++ b/source/blender/draw/intern/draw_cache_extract.h
@@ -0,0 +1,249 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Copyright 2019, Blender Foundation.
+ */
+
+/** \file
+ * \ingroup draw
+ */
+
+#ifndef __DRAW_CACHE_EXTRACT_MESH_H__
+#define __DRAW_CACHE_EXTRACT_MESH_H__
+
+/* Vertex Group Selection and display options */
+typedef struct DRW_MeshWeightState {
+  int defgroup_active;
+  int defgroup_len;
+
+  short flags;
+  char alert_mode;
+
+  /* Set of all selected bones for Multipaint. */
+  bool *defgroup_sel; /* [defgroup_len] */
+  int defgroup_sel_count;
+} DRW_MeshWeightState;
+
+/* DRW_MeshWeightState.flags */
+enum {
+  DRW_MESH_WEIGHT_STATE_MULTIPAINT = (1 << 0),
+  DRW_MESH_WEIGHT_STATE_AUTO_NORMALIZE = (1 << 1),
+};
+
+typedef struct DRW_MeshCDMask {
+  uint32_t uv : 8;
+  uint32_t tan : 8;
+  uint32_t vcol : 8;
+  uint32_t orco : 1;
+  uint32_t tan_orco : 1;
+} DRW_MeshCDMask;
+
+typedef enum eMRIterType {
+  MR_ITER_LOOPTRI = 1 << 0,
+  MR_ITER_LOOP = 1 << 1,
+  MR_ITER_LEDGE = 1 << 2,
+  MR_ITER_LVERT = 1 << 3,
+} eMRIterType;
+
+typedef enum eMRDataType {
+  MR_DATA_POLY_NOR = 1 << 1,
+  MR_DATA_LOOP_NOR = 1 << 2,
+  MR_DATA_LOOPTRI = 1 << 3,
+  /** Force loop normals calculation.  */
+  MR_DATA_TAN_LOOP_NOR = 1 << 4,
+} eMRDataType;
+
+typedef enum eMRExtractType {
+  MR_EXTRACT_BMESH,
+  MR_EXTRACT_MAPPED,
+  MR_EXTRACT_MESH,
+} eMRExtractType;
+
+BLI_INLINE int mesh_render_mat_len_get(Mesh *me)
+{
+  return MAX2(1, me->totcol);
+}
+
+typedef struct MeshBufferCache {
+  /* Every VBO below contains at least enough
+   * data for every loops in the mesh (except fdots).
+   * For some VBOs, it extends to (in this exact order) :
+   * loops + loose_edges*2 + loose_verts */
+  struct {
+    GPUVertBuf *pos_nor;  /* extend */
+    GPUVertBuf *lnor;     /* extend */
+    GPUVertBuf *edge_fac; /* extend */
+    GPUVertBuf *weights;  /* extend */
+    GPUVertBuf *uv_tan;
+    GPUVertBuf *vcol;
+    GPUVertBuf *orco;
+    /* Only for edit mode. */
+    GPUVertBuf *edit_data; /* extend */
+    GPUVertBuf *edituv_data;
+    GPUVertBuf *stretch_area;
+    GPUVertBuf *stretch_angle;
+    GPUVertBuf *mesh_analysis;
+    GPUVertBuf *fdots_pos;
+    GPUVertBuf *fdots_nor;
+    GPUVertBuf *fdots_uv;
+    // GPUVertBuf *fdots_edit_data; /* inside fdots_nor for now. */
+    GPUVertBuf *fdots_edituv_data;
+    /* Selection */
+    GPUVertBuf *vert_idx; /* extend */
+    GPUVertBuf *edge_idx; /* extend */
+    GPUVertBuf *poly_idx;
+    GPUVertBuf *fdot_idx;
+  } vbo;
+  /* Index Buffers:
+   * Only need to be updated when topology changes. */
+  struct {
+    /* Indices to vloops. */
+    GPUIndexBuf *tris;  /* Ordered per material. */
+    GPUIndexBuf *lines; /* Loose edges last. */
+    GPUIndexBuf *points;
+    GPUIndexBuf *fdots;
+    /* 3D overlays. */
+    GPUIndexBuf *lines_paint_mask; /* no loose edges. */
+    GPUIndexBuf *lines_adjacency;
+    /* Uv overlays. (visibility can differ from 3D view) */
+    GPUIndexBuf *edituv_tris;
+    GPUIndexBuf *edituv_lines;
+    GPUIndexBuf *edituv_points;
+    GPUIndexBuf *edituv_fdots;
+  } ibo;
+} MeshBufferCache;
+
+typedef enum DRWBatchFlag {
+  MBC_SURFACE = (1 << 0),
+  MBC_SURFACE_WEIGHTS = (1 << 1),
+  MBC_EDIT_TRIANGLES = (1 << 2),
+  MBC_EDIT_VERTICES = (1 << 3),
+  MBC_EDIT_EDGES = (1 << 4),
+  MBC_EDIT_VNOR = (1 << 5),
+  MBC_EDIT_LNOR = (1 << 6),
+  MBC_EDIT_FACEDOTS = (1 << 7),
+  MBC_EDIT_MESH_ANALYSIS = (1 << 8),
+  MBC_EDITUV_FACES_STRECH_AREA = (1 << 9),
+  MBC_EDITUV_FACES_STRECH_ANGLE = (1 << 10),
+  MBC_EDITUV_FACES = (1 << 11),
+  MBC_EDITUV_EDGES = (1 << 12),
+  MBC_EDITUV_VERTS = (1 << 13),
+  MBC_EDITUV_FACEDOTS = (1 << 14),
+  MBC_EDIT_SELECTION_VERTS = (1 << 15),
+  MBC_EDIT_SELECTION_EDGES = (1 << 16),
+  MBC_EDIT_SELECTION_FACES = (1 << 17),
+ 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list