[Bf-blender-cvs] [b65b93f5d49] tmp-batch-cache-cleanup: Mesh Batch Cache: Refactor: Again

Clément Foucault noreply at git.blender.org
Mon Jul 29 14:26:37 CEST 2019


Commit: b65b93f5d49283a02aebed7b60ce76c0ee4cba85
Author: Clément Foucault
Date:   Sun Jul 28 15:23:41 2019 +0200
Branches: tmp-batch-cache-cleanup
https://developer.blender.org/rBb65b93f5d49283a02aebed7b60ce76c0ee4cba85

Mesh Batch Cache: Refactor: Again

- Use Extract naming convention to name extract functions that fill vbo/ibo
- Separate extract functions into separate file (for clarity)
- Make simpler iter loops to avoid as much overhead as possible
- Separate loose elements looping functions to avoid iteration complexity
  (unfortunately this makes the code more verbose).
- Some iter functions are threadable and tagged as such.
- Add multithreaded iteration for extract functions that supports them.

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

M	source/blender/blenkernel/BKE_mesh.h
M	source/blender/blenkernel/intern/mesh_evaluate.c
M	source/blender/draw/CMakeLists.txt
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_mesh.c

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

diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index 54fbda1fa31..dc5746e83b5 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -480,6 +480,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 17b22a6d095..6121ae449b0 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/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index 8631a9f556b..536f48497a9 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
@@ -130,6 +131,7 @@ set(SRC
   DRW_engine.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_extract.h b/source/blender/draw/intern/draw_cache_extract.h
new file mode 100644
index 00000000000..b6a8e53c6d0
--- /dev/null
+++ b/source/blender/draw/intern/draw_cache_extract.h
@@ -0,0 +1,248 @@
+/*
+ * 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,
+} 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),
+  MBC_EDIT_SELECTION_FACEDOTS = (1 << 18),
+  MBC_ALL_VERTS = (1 << 19),
+  MBC_ALL_EDGES = (1 << 20),
+  MBC_LOOSE_EDGES = (1 << 21),
+  MBC_EDGE_DETECTION = (1 << 22),
+  MBC_WIRE_EDGES = (1 << 23),
+  MBC_WIRE_LOOPS = (1 << 24),
+  MBC_WIRE_LOOPS_UVS = (1 << 25),
+  MBC_SURF_PER_MAT = (1 << 26),
+} DRWBatchFlag;
+
+#define MBC_EDITUV \
+  (MBC_EDITUV_FACES_STRECH_AREA | MBC_EDITUV_FACES_STRECH_ANGLE | MBC_EDITUV_FACES | \
+   MBC_EDITUV_EDGES | MBC_EDITUV_VERTS | MBC_EDITUV_FACEDOTS | MBC_WIRE_LOOPS_UVS)
+
+#define FOREACH_MESH_BUFFER_CACHE(batch_cache, mbc) \
+  for (MeshBufferCache *mbc = &batch_cache->final; \
+       mbc == &batch_cache->final || mbc == &batch_cache->cage; \
+       mbc = (mbc == &batch_cache->final) ? &batch_cache->cage : NULL)
+
+typedef struct MeshBatchCache {
+  MeshBufferCache final, cage;
+
+  struct {
+    /* Surfaces / Render */
+    GPUBatch *surface;
+    GPUBatch *surface_weights;
+    /* Edit mode */
+    GPUBatch *edit_triangles;
+    GPUBatch *edit_vertices;
+    GPUBatch *edit_edges;
+    GPUBatch *edit_vnor;
+    GPUBatch *edit_lnor;
+    GPUBatch *edit_fdots;
+    GPUBatch *edit_mesh_analysis;
+    /* Edit UVs */
+    GPUBatch *edituv_faces_strech_area;
+    GPUBatch *edituv_faces_strech_angle;
+    GPUBatch *edituv_faces;
+    GPUBatch *edituv_edges;
+    GPUBatch *edituv_verts;
+    GPUBatch *edituv_fdots;
+    /* Edit selection */
+    GPUBatch *edit_selection_verts;
+    GPUBatch *edit_selection_edges;
+    GPUBatch *edit_selection_faces;
+    GPUBatch *edit_selection_fdots;
+    /* Common display / Other */
+    GPUBatch *all_verts;
+    GPUBatch *all_edges;
+    GPUBatch *loose_edges;
+    GPUBatch *edge_detection;
+    GPUBatch *wire_edges;     /* Individual edges with face normals. */
+    GPUBatch *wire_loops;     /* Loops around faces. no edges between selected faces */
+    GPUBatch *wire_loops_uvs; /* Same as wire_loops but only has uvs. */
+  } batch;
+
+  GPUBatch **surface_per_mat;
+
+  /* HACK: Temp copy to init the subrange IBOs. */
+  int *tri_mat_start, *tri_mat_end;
+  int edge_loose_start, edge_loose_end;
+
+  /* arrays of bool uniform names (and value) that will be use to
+   * set srgb conversion for auto attributes.*/
+  char *auto_layer_names;
+  int *auto_layer_is_srgb;
+  int auto_layer_len;
+
+  DRWBatchFlag batch_requested;
+  DRWBatchFlag batch_ready;
+
+  /* settings to determine if cache is invalid */
+  int edge_len;
+  int tri_len;
+  int poly_len;
+  int vert_len;
+  int mat_len;
+  bool is_dirty; /* Instantly invalidates cache, skipping mesh check */
+  bool is_editmode;
+  bool is_uvsyncsel;
+
+  struct DRW_MeshWeightState weight_state;
+
+  DRW_MeshCDMask cd_used, cd_needed, cd_used_over_time;
+
+  int lastmatch;
+
+  /* Valid only if edge_detection is up to date. */
+  bool is_manifold;
+
+  bool no_loose_wire;
+} MeshBatchCache;
+
+void mesh_buffer_cache_create_requested(MeshBatchCache *cache,
+                                        MeshBufferCache mbc,
+                                        Mesh *me,
+                                        const bool do_final,
+                                        const bool use_subsurf_fdots,
+                                        const DRW_MeshCDMask *c

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list