[Bf-blender-cvs] [653e3e2689a] master: Subdiv: Avoid repeatedly accessing mesh arrays

Hans Goudey noreply at git.blender.org
Mon Nov 28 15:57:13 CET 2022


Commit: 653e3e2689a4b7fee83425b26beb23aefdcc1d6d
Author: Hans Goudey
Date:   Sun Nov 27 20:11:39 2022 -0600
Branches: master
https://developer.blender.org/rB653e3e2689a4b7fee83425b26beb23aefdcc1d6d

Subdiv: Avoid repeatedly accessing mesh arrays

Fix a performance regression from 05952aa94d33ee by storing pointers
to mesh arrays locally in the subdiv foreach context. In a simple test
of a 1 million face grid, this improved performance by 5% (from 0.31
to 0.295 seconds).

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

M	source/blender/blenkernel/intern/subdiv_foreach.c

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

diff --git a/source/blender/blenkernel/intern/subdiv_foreach.c b/source/blender/blenkernel/intern/subdiv_foreach.c
index faf531b0f5e..e851c969de8 100644
--- a/source/blender/blenkernel/intern/subdiv_foreach.c
+++ b/source/blender/blenkernel/intern/subdiv_foreach.c
@@ -67,6 +67,9 @@ BLI_INLINE int ptex_face_resolution_get(const MPoly *poly, int resolution)
 
 typedef struct SubdivForeachTaskContext {
   const Mesh *coarse_mesh;
+  const MEdge *coarse_edges;
+  const MPoly *coarse_polys;
+  const MLoop *coarse_loops;
   const SubdivToMeshSettings *settings;
   /* Callbacks. */
   const SubdivForeachContext *foreach_context;
@@ -158,16 +161,14 @@ static void subdiv_foreach_ctx_count(SubdivForeachTaskContext *ctx)
   const int num_inner_vertices_per_noquad_patch = (no_quad_patch_resolution - 2) *
                                                   (no_quad_patch_resolution - 2);
   const Mesh *coarse_mesh = ctx->coarse_mesh;
-  const MLoop *coarse_mloop = BKE_mesh_loops(coarse_mesh);
-  const MPoly *coarse_mpoly = BKE_mesh_polys(coarse_mesh);
   ctx->num_subdiv_vertices = coarse_mesh->totvert;
   ctx->num_subdiv_edges = coarse_mesh->totedge * (num_subdiv_vertices_per_coarse_edge + 1);
   /* Calculate extra vertices and edges created by non-loose geometry. */
   for (int poly_index = 0; poly_index < coarse_mesh->totpoly; poly_index++) {
-    const MPoly *coarse_poly = &coarse_mpoly[poly_index];
+    const MPoly *coarse_poly = &ctx->coarse_polys[poly_index];
     const int num_ptex_faces_per_poly = num_ptex_faces_per_poly_get(coarse_poly);
     for (int corner = 0; corner < coarse_poly->totloop; corner++) {
-      const MLoop *loop = &coarse_mloop[coarse_poly->loopstart + corner];
+      const MLoop *loop = &ctx->coarse_loops[coarse_poly->loopstart + corner];
       const bool is_edge_used = BLI_BITMAP_TEST_BOOL(ctx->coarse_edges_used_map, loop->e);
       /* Edges which aren't counted yet. */
       if (!is_edge_used) {
@@ -225,12 +226,11 @@ static void subdiv_foreach_ctx_init_offsets(SubdivForeachTaskContext *ctx)
   ctx->edge_inner_offset = ctx->edge_boundary_offset +
                            coarse_mesh->totedge * num_subdiv_edges_per_coarse_edge;
   /* "Indexed" offsets. */
-  const MPoly *coarse_mpoly = BKE_mesh_polys(coarse_mesh);
   int vertex_offset = 0;
   int edge_offset = 0;
   int polygon_offset = 0;
   for (int poly_index = 0; poly_index < coarse_mesh->totpoly; poly_index++) {
-    const MPoly *coarse_poly = &coarse_mpoly[poly_index];
+    const MPoly *coarse_poly = &ctx->coarse_polys[poly_index];
     const int num_ptex_faces_per_poly = num_ptex_faces_per_poly_get(coarse_poly);
     ctx->subdiv_vertex_offset[poly_index] = vertex_offset;
     ctx->subdiv_edge_offset[poly_index] = edge_offset;
@@ -300,13 +300,10 @@ static void subdiv_foreach_corner_vertices_regular_do(
     bool check_usage)
 {
   const float weights[4][2] = {{0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f}};
-  const Mesh *coarse_mesh = ctx->coarse_mesh;
-  const MLoop *coarse_mloop = BKE_mesh_loops(coarse_mesh);
-  const MPoly *coarse_mpoly = BKE_mesh_polys(coarse_mesh);
-  const int coarse_poly_index = coarse_poly - coarse_mpoly;
+  const int coarse_poly_index = coarse_poly - ctx->coarse_polys;
   const int ptex_face_index = ctx->face_ptex_offset[coarse_poly_index];
   for (int corner = 0; corner < coarse_poly->totloop; corner++) {
-    const MLoop *coarse_loop = &coarse_mloop[coarse_poly->loopstart + corner];
+    const MLoop *coarse_loop = &ctx->coarse_loops[coarse_poly->loopstart + corner];
     if (check_usage &&
         BLI_BITMAP_TEST_AND_SET_ATOMIC(ctx->coarse_vertices_used_map, coarse_loop->v)) {
       continue;
@@ -342,13 +339,10 @@ static void subdiv_foreach_corner_vertices_special_do(
     SubdivForeachVertexFromCornerCb vertex_corner,
     bool check_usage)
 {
-  const Mesh *coarse_mesh = ctx->coarse_mesh;
-  const MLoop *coarse_mloop = BKE_mesh_loops(coarse_mesh);
-  const MPoly *coarse_mpoly = BKE_mesh_polys(coarse_mesh);
-  const int coarse_poly_index = coarse_poly - coarse_mpoly;
+  const int coarse_poly_index = coarse_poly - ctx->coarse_polys;
   int ptex_face_index = ctx->face_ptex_offset[coarse_poly_index];
   for (int corner = 0; corner < coarse_poly->totloop; corner++, ptex_face_index++) {
-    const MLoop *coarse_loop = &coarse_mloop[coarse_poly->loopstart + corner];
+    const MLoop *coarse_loop = &ctx->coarse_loops[coarse_poly->loopstart + corner];
     if (check_usage &&
         BLI_BITMAP_TEST_AND_SET_ATOMIC(ctx->coarse_vertices_used_map, coarse_loop->v)) {
       continue;
@@ -409,9 +403,8 @@ static void subdiv_foreach_every_corner_vertices(SubdivForeachTaskContext *ctx,
     return;
   }
   const Mesh *coarse_mesh = ctx->coarse_mesh;
-  const MPoly *coarse_mpoly = BKE_mesh_polys(coarse_mesh);
   for (int poly_index = 0; poly_index < coarse_mesh->totpoly; poly_index++) {
-    const MPoly *coarse_poly = &coarse_mpoly[poly_index];
+    const MPoly *coarse_poly = &ctx->coarse_polys[poly_index];
     if (coarse_poly->totloop == 4) {
       subdiv_foreach_every_corner_vertices_regular(ctx, tls, coarse_poly);
     }
@@ -433,21 +426,16 @@ static void subdiv_foreach_edge_vertices_regular_do(SubdivForeachTaskContext *ct
   const int resolution_1 = resolution - 1;
   const float inv_resolution_1 = 1.0f / (float)resolution_1;
   const int num_subdiv_vertices_per_coarse_edge = resolution - 2;
-  const Mesh *coarse_mesh = ctx->coarse_mesh;
-  const MEdge *coarse_medge = BKE_mesh_edges(coarse_mesh);
-  const MPoly *coarse_mpoly = BKE_mesh_polys(coarse_mesh);
-  const MLoop *coarse_mloop = BKE_mesh_loops(coarse_mesh);
-  const int coarse_poly_index = coarse_poly - coarse_mpoly;
-  const int poly_index = coarse_poly - coarse_mpoly;
-  const int ptex_face_index = ctx->face_ptex_offset[poly_index];
+  const int coarse_poly_index = coarse_poly - ctx->coarse_polys;
+  const int ptex_face_index = ctx->face_ptex_offset[coarse_poly_index];
   for (int corner = 0; corner < coarse_poly->totloop; corner++) {
-    const MLoop *coarse_loop = &coarse_mloop[coarse_poly->loopstart + corner];
+    const MLoop *coarse_loop = &ctx->coarse_loops[coarse_poly->loopstart + corner];
     const int coarse_edge_index = coarse_loop->e;
     if (check_usage &&
         BLI_BITMAP_TEST_AND_SET_ATOMIC(ctx->coarse_edges_used_map, coarse_edge_index)) {
       continue;
     }
-    const MEdge *coarse_edge = &coarse_medge[coarse_edge_index];
+    const MEdge *coarse_edge = &ctx->coarse_edges[coarse_edge_index];
     const bool flip = (coarse_edge->v2 == coarse_loop->v);
     int subdiv_vertex_index = ctx->vertices_edge_offset +
                               coarse_edge_index * num_subdiv_vertices_per_coarse_edge;
@@ -500,22 +488,17 @@ static void subdiv_foreach_edge_vertices_special_do(SubdivForeachTaskContext *ct
   const int num_subdiv_vertices_per_coarse_edge = resolution - 2;
   const int num_vertices_per_ptex_edge = ((resolution >> 1) + 1);
   const float inv_ptex_resolution_1 = 1.0f / (float)(num_vertices_per_ptex_edge - 1);
-  const Mesh *coarse_mesh = ctx->coarse_mesh;
-  const MEdge *coarse_medge = BKE_mesh_edges(coarse_mesh);
-  const MPoly *coarse_mpoly = BKE_mesh_polys(coarse_mesh);
-  const MLoop *coarse_mloop = BKE_mesh_loops(coarse_mesh);
-  const int coarse_poly_index = coarse_poly - coarse_mpoly;
-  const int poly_index = coarse_poly - coarse_mpoly;
-  const int ptex_face_start_index = ctx->face_ptex_offset[poly_index];
+  const int coarse_poly_index = coarse_poly - ctx->coarse_polys;
+  const int ptex_face_start_index = ctx->face_ptex_offset[coarse_poly_index];
   int ptex_face_index = ptex_face_start_index;
   for (int corner = 0; corner < coarse_poly->totloop; corner++, ptex_face_index++) {
-    const MLoop *coarse_loop = &coarse_mloop[coarse_poly->loopstart + corner];
+    const MLoop *coarse_loop = &ctx->coarse_loops[coarse_poly->loopstart + corner];
     const int coarse_edge_index = coarse_loop->e;
     if (check_usage &&
         BLI_BITMAP_TEST_AND_SET_ATOMIC(ctx->coarse_edges_used_map, coarse_edge_index)) {
       continue;
     }
-    const MEdge *coarse_edge = &coarse_medge[coarse_edge_index];
+    const MEdge *coarse_edge = &ctx->coarse_edges[coarse_edge_index];
     const bool flip = (coarse_edge->v2 == coarse_loop->v);
     int subdiv_vertex_index = ctx->vertices_edge_offset +
                               coarse_edge_index * num_subdiv_vertices_per_coarse_edge;
@@ -597,9 +580,8 @@ static void subdiv_foreach_every_edge_vertices(SubdivForeachTaskContext *ctx, vo
     return;
   }
   const Mesh *coarse_mesh = ctx->coarse_mesh;
-  const MPoly *coarse_mpoly = BKE_mesh_polys(coarse_mesh);
   for (int poly_index = 0; poly_index < coarse_mesh->totpoly; poly_index++) {
-    const MPoly *coarse_poly = &coarse_mpoly[poly_index];
+    const MPoly *coarse_poly = &ctx->coarse_polys[poly_index];
     if (coarse_poly->totloop == 4) {
       subdiv_foreach_every_edge_vertices_regular(ctx, tls, coarse_poly);
     }
@@ -617,9 +599,7 @@ static void subdiv_foreach_inner_vertices_regular(SubdivForeachTaskContext *ctx,
 {
   const int resolution = ctx->settings->resolution;
   const float inv_resolution_1 = 1.0f / (float)(resolution - 1);
-  const Mesh *coarse_mesh = ctx->coarse_mesh;
-  const MPoly *coarse_mpoly = BKE_mesh_polys(coarse_mesh);
-  const int coarse_poly_index = coarse_poly - coarse_mpoly;
+  const int coarse_poly_index = coarse_poly - ctx->coarse_polys;
   const int ptex_face_index = ctx->face_ptex_offset[coarse_poly_index];
   const int start_vertex_index = ctx->subdiv_vertex_offset[coarse_poly_index];
   int subdiv_vertex_index = ctx->vertices_inner_offset + start_vertex_index;
@@ -646,9 +626,7 @@ static void subdiv_foreach_inner_vertices_special(SubdivForeachTaskContext *ctx,
   const int resolution = ctx->settings->resolution;
   const int ptex_face_resolution = ptex_face_resolution_get(coarse_poly, resolution);
   const float inv_ptex_face_resolution_1 = 1.0f / (float)(ptex_face_resolution - 1);
-  const Mesh *coarse_mesh = ctx->coarse_mesh;
-  const MPoly *coarse_mpoly = BKE_mesh_polys(coarse_mesh);
-  const int coarse_poly_index = coarse_poly - coarse_mpoly;
+  const int coarse_poly_index = coarse_poly - ctx->coarse_polys;
   int ptex_face_inde

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list